summaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/common/completion.go48
-rw-r--r--cmd/podman/common/create_opts.go110
-rw-r--r--cmd/podman/common/specgen.go2
-rw-r--r--cmd/podman/containers/create.go15
-rw-r--r--cmd/podman/images/build.go25
-rw-r--r--cmd/podman/images/buildx.go29
-rw-r--r--cmd/podman/images/scp.go2
-rw-r--r--cmd/podman/pods/create.go10
-rw-r--r--cmd/podman/registry/config.go7
-rw-r--r--cmd/podman/shell_completion_test.go4
10 files changed, 197 insertions, 55 deletions
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go
index 08b2f6235..9a4524b46 100644
--- a/cmd/podman/common/completion.go
+++ b/cmd/podman/common/completion.go
@@ -323,6 +323,18 @@ func prefixSlice(pre string, slice []string) []string {
return slice
}
+func suffixCompSlice(suf string, slice []string) []string {
+ for i := range slice {
+ split := strings.SplitN(slice[i], "\t", 2)
+ if len(split) > 1 {
+ slice[i] = split[0] + suf + "\t" + split[1]
+ } else {
+ slice[i] = slice[i] + suf
+ }
+ }
+ return slice
+}
+
func completeKeyValues(toComplete string, k keyValueCompletion) ([]string, cobra.ShellCompDirective) {
suggestions := make([]string, 0, len(k))
directive := cobra.ShellCompDirectiveNoFileComp
@@ -664,6 +676,42 @@ func AutocompleteSystemConnections(cmd *cobra.Command, args []string, toComplete
return suggestions, cobra.ShellCompDirectiveNoFileComp
}
+// AutocompleteScp returns a list of connections, images, or both, depending on the amount of arguments
+func AutocompleteScp(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ if !validCurrentCmdLine(cmd, args, toComplete) {
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
+ switch len(args) {
+ case 0:
+ split := strings.SplitN(toComplete, "::", 2)
+ if len(split) > 1 {
+ imageSuggestions, _ := getImages(cmd, split[1])
+ return prefixSlice(split[0]+"::", imageSuggestions), cobra.ShellCompDirectiveNoFileComp
+ }
+ connectionSuggestions, _ := AutocompleteSystemConnections(cmd, args, toComplete)
+ imageSuggestions, _ := getImages(cmd, toComplete)
+ totalSuggestions := append(suffixCompSlice("::", connectionSuggestions), imageSuggestions...)
+ directive := cobra.ShellCompDirectiveNoFileComp
+ // if we have connections do not add a space after the completion
+ if len(connectionSuggestions) > 0 {
+ directive = cobra.ShellCompDirectiveNoFileComp | cobra.ShellCompDirectiveNoSpace
+ }
+ return totalSuggestions, directive
+ case 1:
+ split := strings.SplitN(args[0], "::", 2)
+ if len(split) > 1 {
+ if len(split[1]) > 0 {
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
+ imageSuggestions, _ := getImages(cmd, toComplete)
+ return imageSuggestions, cobra.ShellCompDirectiveNoFileComp
+ }
+ connectionSuggestions, _ := AutocompleteSystemConnections(cmd, args, toComplete)
+ return suffixCompSlice("::", connectionSuggestions), cobra.ShellCompDirectiveNoFileComp
+ }
+ return nil, cobra.ShellCompDirectiveNoFileComp
+}
+
/* -------------- Flags ----------------- */
// AutocompleteDetachKeys - Autocomplete detach-keys options.
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index 0a969bfd2..0fdf3ce08 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -356,51 +356,55 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c
CPUSetMems: cc.HostConfig.CpusetMems,
// Detach: false, // don't need
// DetachKeys: "", // don't need
- Devices: devices,
- DeviceCGroupRule: nil,
- DeviceReadBPs: readBps,
- DeviceReadIOPs: readIops,
- DeviceWriteBPs: writeBps,
- DeviceWriteIOPs: writeIops,
- Entrypoint: entrypoint,
- Env: cc.Config.Env,
- Expose: expose,
- GroupAdd: cc.HostConfig.GroupAdd,
- Hostname: cc.Config.Hostname,
- ImageVolume: "bind",
- Init: init,
- Interactive: cc.Config.OpenStdin,
- IPC: string(cc.HostConfig.IpcMode),
- Label: stringMaptoArray(cc.Config.Labels),
- LogDriver: cc.HostConfig.LogConfig.Type,
- LogOptions: stringMaptoArray(cc.HostConfig.LogConfig.Config),
- Name: cc.Name,
- OOMScoreAdj: cc.HostConfig.OomScoreAdj,
- Arch: "",
- OS: "",
- Variant: "",
- PID: string(cc.HostConfig.PidMode),
- PIDsLimit: cc.HostConfig.PidsLimit,
- Privileged: cc.HostConfig.Privileged,
- PublishAll: cc.HostConfig.PublishAllPorts,
- Quiet: false,
- ReadOnly: cc.HostConfig.ReadonlyRootfs,
- ReadOnlyTmpFS: true, // podman default
- Rm: cc.HostConfig.AutoRemove,
- SecurityOpt: cc.HostConfig.SecurityOpt,
- StopSignal: cc.Config.StopSignal,
- StorageOpt: stringMaptoArray(cc.HostConfig.StorageOpt),
- Sysctl: stringMaptoArray(cc.HostConfig.Sysctls),
- Systemd: "true", // podman default
- TmpFS: parsedTmp,
- TTY: cc.Config.Tty,
- User: cc.Config.User,
- UserNS: string(cc.HostConfig.UsernsMode),
- UTS: string(cc.HostConfig.UTSMode),
- Mount: mounts,
- VolumesFrom: cc.HostConfig.VolumesFrom,
- Workdir: cc.Config.WorkingDir,
- Net: &netInfo,
+ Devices: devices,
+ DeviceCGroupRule: nil,
+ DeviceReadBPs: readBps,
+ DeviceReadIOPs: readIops,
+ DeviceWriteBPs: writeBps,
+ DeviceWriteIOPs: writeIops,
+ Entrypoint: entrypoint,
+ Env: cc.Config.Env,
+ Expose: expose,
+ GroupAdd: cc.HostConfig.GroupAdd,
+ Hostname: cc.Config.Hostname,
+ ImageVolume: "bind",
+ Init: init,
+ Interactive: cc.Config.OpenStdin,
+ IPC: string(cc.HostConfig.IpcMode),
+ Label: stringMaptoArray(cc.Config.Labels),
+ LogDriver: cc.HostConfig.LogConfig.Type,
+ LogOptions: stringMaptoArray(cc.HostConfig.LogConfig.Config),
+ Name: cc.Name,
+ OOMScoreAdj: cc.HostConfig.OomScoreAdj,
+ Arch: "",
+ OS: "",
+ Variant: "",
+ PID: string(cc.HostConfig.PidMode),
+ PIDsLimit: cc.HostConfig.PidsLimit,
+ Privileged: cc.HostConfig.Privileged,
+ PublishAll: cc.HostConfig.PublishAllPorts,
+ Quiet: false,
+ ReadOnly: cc.HostConfig.ReadonlyRootfs,
+ ReadOnlyTmpFS: true, // podman default
+ Rm: cc.HostConfig.AutoRemove,
+ SecurityOpt: cc.HostConfig.SecurityOpt,
+ StopSignal: cc.Config.StopSignal,
+ StorageOpt: stringMaptoArray(cc.HostConfig.StorageOpt),
+ Sysctl: stringMaptoArray(cc.HostConfig.Sysctls),
+ Systemd: "true", // podman default
+ TmpFS: parsedTmp,
+ TTY: cc.Config.Tty,
+ User: cc.Config.User,
+ UserNS: string(cc.HostConfig.UsernsMode),
+ UTS: string(cc.HostConfig.UTSMode),
+ Mount: mounts,
+ VolumesFrom: cc.HostConfig.VolumesFrom,
+ Workdir: cc.Config.WorkingDir,
+ Net: &netInfo,
+ HealthInterval: DefaultHealthCheckInterval,
+ HealthRetries: DefaultHealthCheckRetries,
+ HealthTimeout: DefaultHealthCheckTimeout,
+ HealthStartPeriod: DefaultHealthCheckStartPeriod,
}
if !rootless.IsRootless() {
var ulimits []string
@@ -527,10 +531,18 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c
finCmd = finCmd[:len(finCmd)-1]
}
cliOpts.HealthCmd = finCmd
- cliOpts.HealthInterval = cc.Config.Healthcheck.Interval.String()
- cliOpts.HealthRetries = uint(cc.Config.Healthcheck.Retries)
- cliOpts.HealthStartPeriod = cc.Config.Healthcheck.StartPeriod.String()
- cliOpts.HealthTimeout = cc.Config.Healthcheck.Timeout.String()
+ if cc.Config.Healthcheck.Interval > 0 {
+ cliOpts.HealthInterval = cc.Config.Healthcheck.Interval.String()
+ }
+ if cc.Config.Healthcheck.Retries > 0 {
+ cliOpts.HealthRetries = uint(cc.Config.Healthcheck.Retries)
+ }
+ if cc.Config.Healthcheck.StartPeriod > 0 {
+ cliOpts.HealthStartPeriod = cc.Config.Healthcheck.StartPeriod.String()
+ }
+ if cc.Config.Healthcheck.Timeout > 0 {
+ cliOpts.HealthTimeout = cc.Config.Healthcheck.Timeout.String()
+ }
}
// specgen assumes the image name is arg[0]
diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go
index 8d6a21cb7..59d32f568 100644
--- a/cmd/podman/common/specgen.go
+++ b/cmd/podman/common/specgen.go
@@ -685,7 +685,7 @@ func makeHealthCheckFromCli(inCmd, interval string, retries uint, timeout, start
concat := ""
if cmdArr[0] == "CMD" || cmdArr[0] == "none" { // this is for compat, we are already split properly for most compat cases
cmdArr = strings.Fields(inCmd)
- } else if cmdArr[0] != "CMD-SHELL" { // this is for podman side of things, wont contain the keywords
+ } else if cmdArr[0] != "CMD-SHELL" { // this is for podman side of things, won't contain the keywords
if isArr && len(cmdArr) > 1 { // an array of consecutive commands
cmdArr = append([]string{"CMD"}, cmdArr...)
} else { // one singular command
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index 895736144..a57488af2 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -13,6 +13,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/utils"
+ "github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/util"
@@ -105,8 +106,8 @@ func create(cmd *cobra.Command, args []string) error {
if !cmd.Flags().Changed("pod") {
return errors.New("must specify pod value with init-ctr")
}
- if !util.StringInSlice(initctr, []string{"always", "oneshot"}) {
- return errors.New("init-ctr value must be 'always' or 'oneshot'")
+ if !util.StringInSlice(initctr, []string{define.AlwaysInitContainer, define.OneShotInitContainer}) {
+ return errors.Errorf("init-ctr value must be '%s' or '%s'", define.AlwaysInitContainer, define.OneShotInitContainer)
}
cliVals.InitContainerType = initctr
}
@@ -184,6 +185,9 @@ func createInit(c *cobra.Command) error {
if c.Flag("cpu-quota").Changed && c.Flag("cpus").Changed {
return errors.Errorf("--cpu-quota and --cpus cannot be set together")
}
+ if c.Flag("pod").Changed && !strings.HasPrefix(c.Flag("pod").Value.String(), "new:") && c.Flag("userns").Changed {
+ return errors.Errorf("--userns and --pod cannot be set together")
+ }
noHosts, err := c.Flags().GetBool("no-hosts")
if err != nil {
@@ -309,6 +313,12 @@ func createPodIfNecessary(s *specgen.SpecGenerator, netOpts *entities.NetOptions
if len(podName) < 1 {
return nil, errors.Errorf("new pod name must be at least one character")
}
+
+ userns, err := specgen.ParseUserNamespace(cliVals.UserNS)
+ if err != nil {
+ return nil, err
+ }
+
createOptions := entities.PodCreateOptions{
Name: podName,
Infra: true,
@@ -318,6 +328,7 @@ func createPodIfNecessary(s *specgen.SpecGenerator, netOpts *entities.NetOptions
Cpus: cliVals.CPUS,
CpusetCpus: cliVals.CPUSetCPUs,
Pid: cliVals.PID,
+ Userns: userns,
}
// Unset config values we passed to the pod to prevent them being used twice for the container and pod.
s.ContainerBasicConfig.Hostname = ""
diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go
index 3aeba6fb0..a1a28b809 100644
--- a/cmd/podman/images/build.go
+++ b/cmd/podman/images/build.go
@@ -67,6 +67,18 @@ var (
podman image build --layers --force-rm --tag imageName .`,
}
+ buildxBuildCmd = &cobra.Command{
+ Args: buildCmd.Args,
+ Use: buildCmd.Use,
+ Short: buildCmd.Short,
+ Long: buildCmd.Long,
+ RunE: buildCmd.RunE,
+ ValidArgsFunction: buildCmd.ValidArgsFunction,
+ Example: `podman buildx build .
+ podman buildx build --creds=username:password -t imageName -f Containerfile.simple .
+ podman buildx build --layers --force-rm --tag imageName .`,
+ }
+
buildOpts = buildFlagsWrapper{}
)
@@ -91,11 +103,24 @@ func init() {
Parent: imageCmd,
})
buildFlags(imageBuildCmd)
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Command: buildxBuildCmd,
+ Parent: buildxCmd,
+ })
+ buildFlags(buildxBuildCmd)
}
func buildFlags(cmd *cobra.Command) {
flags := cmd.Flags()
+ // buildx build --load ignored, but added for compliance
+ flags.Bool("load", false, "buildx --load")
+ _ = flags.MarkHidden("load")
+
+ // buildx build --progress ignored, but added for compliance
+ flags.String("progress", "auto", "buildx --progress")
+ _ = flags.MarkHidden("progress")
+
// Podman flags
flags.BoolVarP(&buildOpts.SquashAll, "squash-all", "", false, "Squash all layers into a single layer")
diff --git a/cmd/podman/images/buildx.go b/cmd/podman/images/buildx.go
new file mode 100644
index 000000000..5c8e5aaa0
--- /dev/null
+++ b/cmd/podman/images/buildx.go
@@ -0,0 +1,29 @@
+package images
+
+import (
+ "github.com/containers/podman/v3/cmd/podman/registry"
+ "github.com/containers/podman/v3/cmd/podman/validate"
+ "github.com/spf13/cobra"
+)
+
+var (
+ // Command: podman _buildx_
+ // This is a hidden command, which was added to make converting
+ // from Docker to Podman easier.
+ // For now podman buildx build just calls into podman build
+ // If we are adding new buildx features, we will add them by default
+ // to podman build.
+ buildxCmd = &cobra.Command{
+ Use: "buildx",
+ Short: "Build images",
+ Long: "Build images",
+ RunE: validate.SubCommandExists,
+ Hidden: true,
+ }
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Command: buildxCmd,
+ })
+}
diff --git a/cmd/podman/images/scp.go b/cmd/podman/images/scp.go
index a47d01995..176563440 100644
--- a/cmd/podman/images/scp.go
+++ b/cmd/podman/images/scp.go
@@ -33,7 +33,7 @@ var (
Short: "securely copy images",
RunE: scp,
Args: cobra.RangeArgs(1, 2),
- ValidArgsFunction: common.AutocompleteImages,
+ ValidArgsFunction: common.AutocompleteScp,
Example: `podman image scp myimage:latest otherhost::`,
}
)
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index abc47164b..bf5b9e350 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -48,6 +48,7 @@ var (
podIDFile string
replace bool
share string
+ userns string
)
func init() {
@@ -72,6 +73,10 @@ func init() {
flags.StringVar(&createOptions.CGroupParent, cgroupParentflagName, "", "Set parent cgroup for the pod")
_ = createCommand.RegisterFlagCompletionFunc(cgroupParentflagName, completion.AutocompleteDefault)
+ usernsFlagName := "userns"
+ flags.StringVar(&userns, usernsFlagName, os.Getenv("PODMAN_USERNS"), "User namespace to use")
+ _ = createCommand.RegisterFlagCompletionFunc(usernsFlagName, common.AutocompleteUserNamespace)
+
flags.BoolVar(&createOptions.Infra, "infra", true, "Create an infra container associated with the pod to share namespaces with")
infraConmonPidfileFlagName := "infra-conmon-pidfile"
@@ -178,6 +183,11 @@ func create(cmd *cobra.Command, args []string) error {
}
}
+ createOptions.Userns, err = specgen.ParseUserNamespace(userns)
+ if err != nil {
+ return err
+ }
+
if cmd.Flag("pod-id-file").Changed {
podIDFD, err = util.OpenExclusiveFile(podIDFile)
if err != nil && os.IsExist(err) {
diff --git a/cmd/podman/registry/config.go b/cmd/podman/registry/config.go
index b512ba341..50e488b02 100644
--- a/cmd/podman/registry/config.go
+++ b/cmd/podman/registry/config.go
@@ -89,7 +89,12 @@ func newPodmanConfig() {
// use for the containers.conf configuration file.
func setXdgDirs() error {
if !rootless.IsRootless() {
- return nil
+ // unset XDG_RUNTIME_DIR for root
+ // Sometimes XDG_RUNTIME_DIR is set to /run/user/0 sometimes it is unset,
+ // the inconsistency is causing issues for the dnsname plugin.
+ // It is already set to an empty string for conmon so lets do the same
+ // for podman. see #10806 and #10745
+ return os.Unsetenv("XDG_RUNTIME_DIR")
}
// Setup XDG_RUNTIME_DIR
diff --git a/cmd/podman/shell_completion_test.go b/cmd/podman/shell_completion_test.go
index 9bd821d8d..792beeb19 100644
--- a/cmd/podman/shell_completion_test.go
+++ b/cmd/podman/shell_completion_test.go
@@ -33,7 +33,9 @@ func TestShellCompletionFunctions(t *testing.T) {
func checkCommand(t *testing.T, cmd *cobra.Command) {
if cmd.HasSubCommands() {
for _, childCmd := range cmd.Commands() {
- checkCommand(t, childCmd)
+ if !childCmd.Hidden {
+ checkCommand(t, childCmd)
+ }
}
// if not check if completion for that command is provided