summaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/common/netflags.go102
-rw-r--r--cmd/podman/generate/systemd.go12
-rw-r--r--cmd/podman/images/build.go15
-rw-r--r--cmd/podman/images/scp.go30
-rw-r--r--cmd/podman/images/scp_utils.go3
-rw-r--r--cmd/podman/machine/start.go2
-rw-r--r--cmd/podman/networks/create.go64
-rw-r--r--cmd/podman/networks/list.go1
-rw-r--r--cmd/podman/pods/create.go2
-rw-r--r--cmd/podman/registry/config.go15
-rw-r--r--cmd/podman/root.go18
-rw-r--r--cmd/podman/system/reset.go6
12 files changed, 165 insertions, 105 deletions
diff --git a/cmd/podman/common/netflags.go b/cmd/podman/common/netflags.go
index 255996ac3..9dfe81d62 100644
--- a/cmd/podman/common/netflags.go
+++ b/cmd/podman/common/netflags.go
@@ -103,69 +103,79 @@ func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet) (*enti
opts = &entities.NetOptions{}
}
- opts.AddHosts, err = flags.GetStringSlice("add-host")
- if err != nil {
- return nil, err
- }
- // Verify the additional hosts are in correct format
- for _, host := range opts.AddHosts {
- if _, err := parse.ValidateExtraHost(host); err != nil {
+ if flags.Changed("add-host") {
+ opts.AddHosts, err = flags.GetStringSlice("add-host")
+ if err != nil {
return nil, err
}
+ // Verify the additional hosts are in correct format
+ for _, host := range opts.AddHosts {
+ if _, err := parse.ValidateExtraHost(host); err != nil {
+ return nil, err
+ }
+ }
}
- servers, err := flags.GetStringSlice("dns")
- if err != nil {
- return nil, err
- }
- for _, d := range servers {
- if d == "none" {
- opts.UseImageResolvConf = true
- if len(servers) > 1 {
- return nil, errors.Errorf("%s is not allowed to be specified with other DNS ip addresses", d)
- }
- break
+ if flags.Changed("dns") {
+ servers, err := flags.GetStringSlice("dns")
+ if err != nil {
+ return nil, err
}
- dns := net.ParseIP(d)
- if dns == nil {
- return nil, errors.Errorf("%s is not an ip address", d)
+ for _, d := range servers {
+ if d == "none" {
+ opts.UseImageResolvConf = true
+ if len(servers) > 1 {
+ return nil, errors.Errorf("%s is not allowed to be specified with other DNS ip addresses", d)
+ }
+ break
+ }
+ dns := net.ParseIP(d)
+ if dns == nil {
+ return nil, errors.Errorf("%s is not an ip address", d)
+ }
+ opts.DNSServers = append(opts.DNSServers, dns)
}
- opts.DNSServers = append(opts.DNSServers, dns)
}
- options, err := flags.GetStringSlice("dns-opt")
- if err != nil {
- return nil, err
+ if flags.Changed("dns-opt") {
+ options, err := flags.GetStringSlice("dns-opt")
+ if err != nil {
+ return nil, err
+ }
+ opts.DNSOptions = options
}
- opts.DNSOptions = options
- dnsSearches, err := flags.GetStringSlice("dns-search")
- if err != nil {
- return nil, err
- }
- // Validate domains are good
- for _, dom := range dnsSearches {
- if dom == "." {
- if len(dnsSearches) > 1 {
- return nil, errors.Errorf("cannot pass additional search domains when also specifying '.'")
- }
- continue
- }
- if _, err := parse.ValidateDomain(dom); err != nil {
+ if flags.Changed("dns-search") {
+ dnsSearches, err := flags.GetStringSlice("dns-search")
+ if err != nil {
return nil, err
}
+ // Validate domains are good
+ for _, dom := range dnsSearches {
+ if dom == "." {
+ if len(dnsSearches) > 1 {
+ return nil, errors.Errorf("cannot pass additional search domains when also specifying '.'")
+ }
+ continue
+ }
+ if _, err := parse.ValidateDomain(dom); err != nil {
+ return nil, err
+ }
+ }
+ opts.DNSSearch = dnsSearches
}
- opts.DNSSearch = dnsSearches
- inputPorts, err := flags.GetStringSlice("publish")
- if err != nil {
- return nil, err
- }
- if len(inputPorts) > 0 {
- opts.PublishPorts, err = specgenutil.CreatePortBindings(inputPorts)
+ if flags.Changed("publish") {
+ inputPorts, err := flags.GetStringSlice("publish")
if err != nil {
return nil, err
}
+ if len(inputPorts) > 0 {
+ opts.PublishPorts, err = specgenutil.CreatePortBindings(inputPorts)
+ if err != nil {
+ return nil, err
+ }
+ }
}
opts.NoHosts, err = flags.GetBool("no-hosts")
diff --git a/cmd/podman/generate/systemd.go b/cmd/podman/generate/systemd.go
index 5ad42ebc0..0dab6299d 100644
--- a/cmd/podman/generate/systemd.go
+++ b/cmd/podman/generate/systemd.go
@@ -25,6 +25,9 @@ const (
restartPolicyFlagName = "restart-policy"
restartSecFlagName = "restart-sec"
newFlagName = "new"
+ wantsFlagName = "wants"
+ afterFlagName = "after"
+ requiresFlagName = "requires"
)
var (
@@ -97,6 +100,15 @@ func init() {
flags.StringVar(&format, formatFlagName, "", "Print the created units in specified format (json)")
_ = systemdCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(nil))
+ flags.StringArrayVar(&systemdOptions.Wants, wantsFlagName, nil, "Add (weak) requirement dependencies to the generated unit file")
+ _ = systemdCmd.RegisterFlagCompletionFunc(wantsFlagName, completion.AutocompleteNone)
+
+ flags.StringArrayVar(&systemdOptions.After, afterFlagName, nil, "Add dependencies order to the generated unit file")
+ _ = systemdCmd.RegisterFlagCompletionFunc(afterFlagName, completion.AutocompleteNone)
+
+ flags.StringArrayVar(&systemdOptions.Requires, requiresFlagName, nil, "Similar to wants, but declares stronger requirement dependencies")
+ _ = systemdCmd.RegisterFlagCompletionFunc(requiresFlagName, completion.AutocompleteNone)
+
flags.SetNormalizeFunc(utils.TimeoutAliasFlags)
}
diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go
index f975cd6d5..729951a31 100644
--- a/cmd/podman/images/build.go
+++ b/cmd/podman/images/build.go
@@ -183,12 +183,6 @@ func buildFlags(cmd *cobra.Command) {
completion.CompleteCommandFlags(cmd, fromAndBudFlagsCompletions)
flags.SetNormalizeFunc(buildahCLI.AliasFlags)
if registry.IsRemote() {
- flag = flags.Lookup("isolation")
- buildOpts.Isolation = buildahDefine.OCI
- if err := flag.Value.Set(buildahDefine.OCI); err != nil {
- logrus.Errorf("Unable to set --isolation to %v: %v", buildahDefine.OCI, err)
- }
- flag.DefValue = buildahDefine.OCI
_ = flags.MarkHidden("disable-content-trust")
_ = flags.MarkHidden("cache-from")
_ = flags.MarkHidden("sign-by")
@@ -360,15 +354,18 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil
return nil, errors.Errorf("can only set one of 'pull' or 'pull-always' or 'pull-never'")
}
+ // Allow for --pull, --pull=true, --pull=false, --pull=never, --pull=always
+ // --pull-always and --pull-never. The --pull-never and --pull-always options
+ // will not be documented.
pullPolicy := buildahDefine.PullIfMissing
- if c.Flags().Changed("pull") && flags.Pull {
+ if c.Flags().Changed("pull") && strings.EqualFold(strings.TrimSpace(flags.Pull), "true") {
pullPolicy = buildahDefine.PullAlways
}
- if flags.PullAlways {
+ if flags.PullAlways || strings.EqualFold(strings.TrimSpace(flags.Pull), "always") {
pullPolicy = buildahDefine.PullAlways
}
- if flags.PullNever {
+ if flags.PullNever || strings.EqualFold(strings.TrimSpace(flags.Pull), "never") {
pullPolicy = buildahDefine.PullNever
}
diff --git a/cmd/podman/images/scp.go b/cmd/podman/images/scp.go
index 1481e71c7..d07a5d99d 100644
--- a/cmd/podman/images/scp.go
+++ b/cmd/podman/images/scp.go
@@ -17,7 +17,6 @@ import (
"github.com/containers/podman/v4/cmd/podman/system/connection"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/domain/entities"
- "github.com/containers/podman/v4/pkg/rootless"
"github.com/containers/podman/v4/utils"
scpD "github.com/dtylman/scp"
"github.com/pkg/errors"
@@ -147,6 +146,17 @@ func scp(cmd *cobra.Command, args []string) (finalErr error) {
return err
}
+ allLocal := true // if we are all localhost, do not validate connections but if we are using one localhost and one non we need to use sshd
+ for _, val := range cliConnections {
+ if !strings.Contains(val, "@localhost::") {
+ allLocal = false
+ break
+ }
+ }
+ if allLocal {
+ cliConnections = []string{}
+ }
+
var serv map[string]config.Destination
serv, err = GetServiceInformation(cliConnections, cfg)
if err != nil {
@@ -337,21 +347,9 @@ func GetServiceInformation(cliConnections []string, cfg *config.Config) (map[str
// execPodman executes the podman save/load command given the podman binary
func execPodman(podman string, command []string) error {
- if rootless.IsRootless() {
- cmd := exec.Command(podman)
- utils.CreateSCPCommand(cmd, command[1:])
- logrus.Debug("Executing podman command")
- return cmd.Run()
- }
- machinectl, err := exec.LookPath("machinectl")
- if err != nil {
- cmd := exec.Command("su", "-l", "root", "--command")
- cmd = utils.CreateSCPCommand(cmd, []string{strings.Join(command, " ")})
- return cmd.Run()
- }
- cmd := exec.Command(machinectl, "shell", "-q", "root@.host")
- cmd = utils.CreateSCPCommand(cmd, command)
- logrus.Debug("Executing load command machinectl")
+ cmd := exec.Command(podman)
+ utils.CreateSCPCommand(cmd, command[1:])
+ logrus.Debugf("Executing podman command: %q", cmd)
return cmd.Run()
}
diff --git a/cmd/podman/images/scp_utils.go b/cmd/podman/images/scp_utils.go
index c488616c9..a85687a42 100644
--- a/cmd/podman/images/scp_utils.go
+++ b/cmd/podman/images/scp_utils.go
@@ -17,12 +17,13 @@ func parseImageSCPArg(arg string) (*entities.ImageScpOptions, []string, error) {
cliConnections := []string{}
switch {
- case strings.Contains(arg, "@localhost"): // image transfer between users
+ case strings.Contains(arg, "@localhost::"): // image transfer between users
location.User = strings.Split(arg, "@")[0]
location, err = validateImagePortion(location, arg)
if err != nil {
return nil, nil, err
}
+ cliConnections = append(cliConnections, arg)
case strings.Contains(arg, "::"):
location, err = validateImagePortion(location, arg)
if err != nil {
diff --git a/cmd/podman/machine/start.go b/cmd/podman/machine/start.go
index 0bcf32cd5..16faa25ef 100644
--- a/cmd/podman/machine/start.go
+++ b/cmd/podman/machine/start.go
@@ -1,3 +1,4 @@
+//go:build amd64 || arm64
// +build amd64 arm64
package machine
@@ -64,5 +65,6 @@ func start(cmd *cobra.Command, args []string) error {
if err := vm.Start(vmName, machine.StartOptions{}); err != nil {
return err
}
+ fmt.Printf("Machine %q started successfully\n", vmName)
return nil
}
diff --git a/cmd/podman/networks/create.go b/cmd/podman/networks/create.go
index 9f6470858..3dd393c46 100644
--- a/cmd/podman/networks/create.go
+++ b/cmd/podman/networks/create.go
@@ -47,13 +47,13 @@ func networkCreateFlags(cmd *cobra.Command) {
_ = cmd.RegisterFlagCompletionFunc(optFlagName, completion.AutocompleteNone)
gatewayFlagName := "gateway"
- flags.IPVar(&networkCreateOptions.Gateway, gatewayFlagName, nil, "IPv4 or IPv6 gateway for the subnet")
+ flags.IPSliceVar(&networkCreateOptions.Gateways, gatewayFlagName, nil, "IPv4 or IPv6 gateway for the subnet")
_ = cmd.RegisterFlagCompletionFunc(gatewayFlagName, completion.AutocompleteNone)
flags.BoolVar(&networkCreateOptions.Internal, "internal", false, "restrict external access from this network")
ipRangeFlagName := "ip-range"
- flags.IPNetVar(&networkCreateOptions.Range, ipRangeFlagName, net.IPNet{}, "allocate container IP from range")
+ flags.StringArrayVar(&networkCreateOptions.Ranges, ipRangeFlagName, nil, "allocate container IP from range")
_ = cmd.RegisterFlagCompletionFunc(ipRangeFlagName, completion.AutocompleteNone)
// TODO consider removing this for 4.0
@@ -72,7 +72,7 @@ func networkCreateFlags(cmd *cobra.Command) {
flags.BoolVar(&networkCreateOptions.IPv6, "ipv6", false, "enable IPv6 networking")
subnetFlagName := "subnet"
- flags.IPNetVar(&networkCreateOptions.Subnet, subnetFlagName, net.IPNet{}, "subnet in CIDR format")
+ flags.StringArrayVar(&networkCreateOptions.Subnets, subnetFlagName, nil, "subnets in CIDR format")
_ = cmd.RegisterFlagCompletionFunc(subnetFlagName, completion.AutocompleteNone)
flags.BoolVar(&networkCreateOptions.DisableDNS, "disable-dns", false, "disable dns plugin")
@@ -125,27 +125,35 @@ func networkCreate(cmd *cobra.Command, args []string) error {
}
}
- if networkCreateOptions.Subnet.IP != nil {
- s := types.Subnet{
- Subnet: types.IPNet{IPNet: networkCreateOptions.Subnet},
- Gateway: networkCreateOptions.Gateway,
+ if len(networkCreateOptions.Subnets) > 0 {
+ if len(networkCreateOptions.Gateways) > len(networkCreateOptions.Subnets) {
+ return errors.New("cannot set more gateways than subnets")
}
- if networkCreateOptions.Range.IP != nil {
- startIP, err := util.FirstIPInSubnet(&networkCreateOptions.Range)
+ if len(networkCreateOptions.Ranges) > len(networkCreateOptions.Subnets) {
+ return errors.New("cannot set more ranges than subnets")
+ }
+
+ for i := range networkCreateOptions.Subnets {
+ subnet, err := types.ParseCIDR(networkCreateOptions.Subnets[i])
if err != nil {
- return errors.Wrap(err, "failed to get first ip in range")
+ return err
}
- lastIP, err := util.LastIPInSubnet(&networkCreateOptions.Range)
- if err != nil {
- return errors.Wrap(err, "failed to get last ip in range")
+ s := types.Subnet{
+ Subnet: subnet,
+ }
+ if len(networkCreateOptions.Ranges) > i {
+ leaseRange, err := parseRange(networkCreateOptions.Ranges[i])
+ if err != nil {
+ return err
+ }
+ s.LeaseRange = leaseRange
}
- s.LeaseRange = &types.LeaseRange{
- StartIP: startIP,
- EndIP: lastIP,
+ if len(networkCreateOptions.Gateways) > i {
+ s.Gateway = networkCreateOptions.Gateways[i]
}
+ network.Subnets = append(network.Subnets, s)
}
- network.Subnets = append(network.Subnets, s)
- } else if networkCreateOptions.Range.IP != nil || networkCreateOptions.Gateway != nil {
+ } else if len(networkCreateOptions.Ranges) > 0 || len(networkCreateOptions.Gateways) > 0 {
return errors.New("cannot set gateway or range without subnet")
}
@@ -156,3 +164,23 @@ func networkCreate(cmd *cobra.Command, args []string) error {
fmt.Println(response.Name)
return nil
}
+
+func parseRange(iprange string) (*types.LeaseRange, error) {
+ _, subnet, err := net.ParseCIDR(iprange)
+ if err != nil {
+ return nil, err
+ }
+
+ startIP, err := util.FirstIPInSubnet(subnet)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to get first ip in range")
+ }
+ lastIP, err := util.LastIPInSubnet(subnet)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to get last ip in range")
+ }
+ return &types.LeaseRange{
+ StartIP: startIP,
+ EndIP: lastIP,
+ }, nil
+}
diff --git a/cmd/podman/networks/list.go b/cmd/podman/networks/list.go
index 092cc6424..f14e0ed0f 100644
--- a/cmd/podman/networks/list.go
+++ b/cmd/podman/networks/list.go
@@ -71,7 +71,6 @@ func networkList(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
-
// sort the networks to make sure the order is deterministic
sort.Slice(responses, func(i, j int) bool {
return responses[i].Name < responses[j].Name
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index 8222ec8e2..1cd36008e 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -77,7 +77,7 @@ func init() {
if !registry.IsRemote() {
defInfraImage = containerConfig.Engine.InfraImage
}
- flags.StringVar(&infraImage, infraImageFlagName, defInfraImage, "The image of the infra container to associate with the pod")
+ flags.StringVar(&infraImage, infraImageFlagName, defInfraImage, "Image to use to override builtin infra container")
_ = createCommand.RegisterFlagCompletionFunc(infraImageFlagName, common.AutocompleteImages)
podIDFileFlagName := "pod-id-file"
diff --git a/cmd/podman/registry/config.go b/cmd/podman/registry/config.go
index f5822d33e..15bb7aee0 100644
--- a/cmd/podman/registry/config.go
+++ b/cmd/podman/registry/config.go
@@ -52,6 +52,12 @@ func newPodmanConfig() {
os.Exit(1)
}
+ cfg, err := config.NewConfig("")
+ if err != nil {
+ fmt.Fprint(os.Stderr, "Failed to obtain podman configuration: "+err.Error())
+ os.Exit(1)
+ }
+
var mode entities.EngineMode
switch runtime.GOOS {
case "darwin", "windows":
@@ -64,16 +70,15 @@ func newPodmanConfig() {
} else {
mode = entities.TunnelMode
}
-
default:
fmt.Fprintf(os.Stderr, "%s is not a supported OS", runtime.GOOS)
os.Exit(1)
}
- cfg, err := config.NewConfig("")
- if err != nil {
- fmt.Fprint(os.Stderr, "Failed to obtain podman configuration: "+err.Error())
- os.Exit(1)
+ // If EngineMode==Tunnel has not been set on the command line or environment
+ // but has been set in containers.conf...
+ if mode == entities.ABIMode && cfg.Engine.Remote {
+ mode = entities.TunnelMode
}
cfg.Network.NetworkConfigDir = cfg.Network.CNIPluginDirs[0]
diff --git a/cmd/podman/root.go b/cmd/podman/root.go
index 7989f9cd5..6d768c2e6 100644
--- a/cmd/podman/root.go
+++ b/cmd/podman/root.go
@@ -85,6 +85,14 @@ func init() {
)
rootFlags(rootCmd, registry.PodmanConfig())
+
+ // backwards compat still allow --cni-config-dir
+ rootCmd.Flags().SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName {
+ if name == "cni-config-dir" {
+ name = "network-config-dir"
+ }
+ return pflag.NormalizedName(name)
+ })
rootCmd.SetUsageTemplate(usageTemplate)
}
@@ -371,9 +379,9 @@ func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) {
pFlags.StringVar(&cfg.Engine.NetworkCmdPath, networkCmdPathFlagName, cfg.Engine.NetworkCmdPath, "Path to the command for configuring the network")
_ = cmd.RegisterFlagCompletionFunc(networkCmdPathFlagName, completion.AutocompleteDefault)
- cniConfigDirFlagName := "cni-config-dir"
- pFlags.StringVar(&cfg.Network.NetworkConfigDir, cniConfigDirFlagName, cfg.Network.NetworkConfigDir, "Path of the configuration directory for CNI networks")
- _ = cmd.RegisterFlagCompletionFunc(cniConfigDirFlagName, completion.AutocompleteDefault)
+ networkConfigDirFlagName := "network-config-dir"
+ pFlags.StringVar(&cfg.Network.NetworkConfigDir, networkConfigDirFlagName, cfg.Network.NetworkConfigDir, "Path of the configuration directory for networks")
+ _ = cmd.RegisterFlagCompletionFunc(networkConfigDirFlagName, completion.AutocompleteDefault)
pFlags.StringVar(&cfg.Containers.DefaultMountsFile, "default-mounts-file", cfg.Containers.DefaultMountsFile, "Path to default mounts file")
@@ -407,12 +415,12 @@ func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) {
_ = cmd.RegisterFlagCompletionFunc(runrootFlagName, completion.AutocompleteDefault)
runtimeFlagName := "runtime"
- pFlags.StringVar(&opts.RuntimePath, runtimeFlagName, "", "Path to the OCI-compatible binary used to run containers, default is /usr/bin/runc")
+ pFlags.StringVar(&opts.RuntimePath, runtimeFlagName, cfg.Engine.OCIRuntime, "Path to the OCI-compatible binary used to run containers.")
_ = cmd.RegisterFlagCompletionFunc(runtimeFlagName, completion.AutocompleteDefault)
// -s is deprecated due to conflict with -s on subcommands
storageDriverFlagName := "storage-driver"
- pFlags.StringVar(&opts.StorageDriver, storageDriverFlagName, "", "Select which storage driver is used to manage storage of images and containers (default is overlay)")
+ pFlags.StringVar(&opts.StorageDriver, storageDriverFlagName, "", "Select which storage driver is used to manage storage of images and containers")
_ = cmd.RegisterFlagCompletionFunc(storageDriverFlagName, completion.AutocompleteNone) //TODO: what can we recommend here?
tmpdirFlagName := "tmpdir"
diff --git a/cmd/podman/system/reset.go b/cmd/podman/system/reset.go
index 85ee8557a..07904faaa 100644
--- a/cmd/podman/system/reset.go
+++ b/cmd/podman/system/reset.go
@@ -21,7 +21,7 @@ import (
var (
systemResetDescription = `Reset podman storage back to default state"
- All containers will be stopped and removed, and all images, volumes and container content will be removed.
+ All containers will be stopped and removed, and all images, volumes, networks and container content will be removed.
`
systemResetCommand = &cobra.Command{
Annotations: map[string]string{registry.EngineMode: registry.ABIMode},
@@ -55,11 +55,11 @@ func reset(cmd *cobra.Command, args []string) {
// Prompt for confirmation if --force is not set
if !forceFlag {
reader := bufio.NewReader(os.Stdin)
- fmt.Println(`
-WARNING! This will remove:
+ fmt.Println(`WARNING! This will remove:
- all containers
- all pods
- all images
+ - all networks
- all build cache`)
if len(listCtn) > 0 {
fmt.Println(`WARNING! The following external containers will be purged:`)