diff options
Diffstat (limited to 'cmd')
36 files changed, 142 insertions, 197 deletions
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go index 285cab1b9..3720e9608 100644 --- a/cmd/podman/common/completion.go +++ b/cmd/podman/common/completion.go @@ -1171,7 +1171,7 @@ func getMethodNames(f reflect.Value, prefix string) []formatSuggestion { if kind == reflect.Struct || kind == reflect.Map { suffix = "." } - // From a template users POV it is not importent when the use a struct field or method. + // From a template users POV it is not important when the use a struct field or method. // They only notice the difference when the function requires arguments. // So lets be nice and let the user know that this method requires arguments via the help text. // Note since this is actually a method on a type the first argument is always fix so we should skip it. diff --git a/cmd/podman/containers/checkpoint.go b/cmd/podman/containers/checkpoint.go index 40d689c4d..e0891f7a1 100644 --- a/cmd/podman/containers/checkpoint.go +++ b/cmd/podman/containers/checkpoint.go @@ -31,7 +31,7 @@ var ( Long: checkpointDescription, RunE: checkpoint, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, false) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "") }, ValidArgsFunction: common.AutocompleteContainersRunning, Example: `podman container checkpoint --keep ctrID diff --git a/cmd/podman/containers/cleanup.go b/cmd/podman/containers/cleanup.go index aa2734607..a63e413fe 100644 --- a/cmd/podman/containers/cleanup.go +++ b/cmd/podman/containers/cleanup.go @@ -27,7 +27,7 @@ var ( Long: cleanupDescription, RunE: cleanup, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, false) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "") }, ValidArgsFunction: common.AutocompleteContainersExited, Example: `podman container cleanup --latest diff --git a/cmd/podman/containers/diff.go b/cmd/podman/containers/diff.go index e1a8ea729..15d3a3eff 100644 --- a/cmd/podman/containers/diff.go +++ b/cmd/podman/containers/diff.go @@ -32,13 +32,9 @@ func init() { Parent: containerCmd, }) - diffOpts = &entities.DiffOptions{} + diffOpts = new(entities.DiffOptions) flags := diffCmd.Flags() - // FIXME: Why does this exists? It is not used anywhere. - flags.BoolVar(&diffOpts.Archive, "archive", true, "Save the diff as a tar archive") - _ = flags.MarkHidden("archive") - formatFlagName := "format" flags.StringVar(&diffOpts.Format, formatFlagName, "", "Change the output format (json)") _ = diffCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(nil)) diff --git a/cmd/podman/containers/init.go b/cmd/podman/containers/init.go index 7336a2332..649cdf1c9 100644 --- a/cmd/podman/containers/init.go +++ b/cmd/podman/containers/init.go @@ -21,7 +21,7 @@ var ( Long: initDescription, RunE: initContainer, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, false) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "") }, ValidArgsFunction: common.AutocompleteContainersCreated, Example: `podman init --latest diff --git a/cmd/podman/containers/kill.go b/cmd/podman/containers/kill.go index e994fbf2c..eddefd196 100644 --- a/cmd/podman/containers/kill.go +++ b/cmd/podman/containers/kill.go @@ -25,7 +25,7 @@ var ( Long: killDescription, RunE: kill, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, true) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "cidfile") }, ValidArgsFunction: common.AutocompleteContainersRunning, Example: `podman kill mywebserver @@ -35,7 +35,7 @@ var ( containerKillCommand = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, true) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "cidfile") }, Use: killCommand.Use, Short: killCommand.Short, diff --git a/cmd/podman/containers/mount.go b/cmd/podman/containers/mount.go index 18177e3ce..16eb5d452 100644 --- a/cmd/podman/containers/mount.go +++ b/cmd/podman/containers/mount.go @@ -33,7 +33,7 @@ var ( Long: mountDescription, RunE: mount, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, true, false) + return validate.CheckAllLatestAndIDFile(cmd, args, true, "") }, ValidArgsFunction: common.AutocompleteContainers, } diff --git a/cmd/podman/containers/port.go b/cmd/podman/containers/port.go index 22d1d16d3..f10bdd5b4 100644 --- a/cmd/podman/containers/port.go +++ b/cmd/podman/containers/port.go @@ -23,7 +23,7 @@ var ( Long: portDescription, RunE: port, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, true, false) + return validate.CheckAllLatestAndIDFile(cmd, args, true, "") }, ValidArgsFunction: common.AutocompleteContainerOneArg, Example: `podman port --all @@ -37,7 +37,7 @@ var ( Long: portDescription, RunE: portCommand.RunE, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, true, false) + return validate.CheckAllLatestAndIDFile(cmd, args, true, "") }, ValidArgsFunction: portCommand.ValidArgsFunction, Example: `podman container port --all diff --git a/cmd/podman/containers/restart.go b/cmd/podman/containers/restart.go index 69d8d71ea..25bbb61e3 100644 --- a/cmd/podman/containers/restart.go +++ b/cmd/podman/containers/restart.go @@ -26,7 +26,7 @@ var ( Long: restartDescription, RunE: restart, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, false) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "") }, ValidArgsFunction: common.AutocompleteContainers, Example: `podman restart ctrID diff --git a/cmd/podman/containers/restore.go b/cmd/podman/containers/restore.go index eeda5a05f..1e4745354 100644 --- a/cmd/podman/containers/restore.go +++ b/cmd/podman/containers/restore.go @@ -28,7 +28,7 @@ var ( Long: restoreDescription, RunE: restore, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, true, false) + return validate.CheckAllLatestAndIDFile(cmd, args, true, "") }, ValidArgsFunction: common.AutocompleteContainersAndImages, Example: `podman container restore ctrID diff --git a/cmd/podman/containers/rm.go b/cmd/podman/containers/rm.go index 420e3c38d..bcbe86947 100644 --- a/cmd/podman/containers/rm.go +++ b/cmd/podman/containers/rm.go @@ -28,7 +28,7 @@ var ( Long: rmDescription, RunE: rm, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, true) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "cidfile") }, ValidArgsFunction: common.AutocompleteContainers, Example: `podman rm imageID @@ -123,9 +123,7 @@ func rm(cmd *cobra.Command, args []string) error { // removeContainers will set the exit code according to the `podman-rm` man // page. func removeContainers(namesOrIDs []string, rmOptions entities.RmOptions, setExit bool) error { - var ( - errs utils.OutputErrors - ) + var errs utils.OutputErrors responses, err := registry.ContainerEngine().ContainerRm(context.Background(), namesOrIDs, rmOptions) if err != nil { if setExit { @@ -135,8 +133,9 @@ func removeContainers(namesOrIDs []string, rmOptions entities.RmOptions, setExit } for _, r := range responses { if r.Err != nil { - // TODO this will not work with the remote client - if errors.Cause(err) == define.ErrWillDeadlock { + // When using the API, errors.Cause(err) will never equal constant define.ErrWillDeadLock + if errors.Cause(r.Err) == define.ErrWillDeadlock || + errors.Cause(r.Err).Error() == define.ErrWillDeadlock.Error() { logrus.Errorf("Potential deadlock detected - please run 'podman system renumber' to resolve") } if setExit { diff --git a/cmd/podman/containers/stop.go b/cmd/podman/containers/stop.go index af2250abb..def608fea 100644 --- a/cmd/podman/containers/stop.go +++ b/cmd/podman/containers/stop.go @@ -26,7 +26,7 @@ var ( Long: stopDescription, RunE: stop, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, true) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "cidfile") }, ValidArgsFunction: common.AutocompleteContainersRunning, Example: `podman stop ctrID @@ -40,7 +40,7 @@ var ( Long: stopCommand.Long, RunE: stopCommand.RunE, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, true) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "cidfile") }, ValidArgsFunction: stopCommand.ValidArgsFunction, Example: `podman container stop ctrID diff --git a/cmd/podman/containers/unmount.go b/cmd/podman/containers/unmount.go index 26b8cfcc5..6869de2e2 100644 --- a/cmd/podman/containers/unmount.go +++ b/cmd/podman/containers/unmount.go @@ -27,7 +27,7 @@ var ( Long: description, RunE: unmount, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, false) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "") }, ValidArgsFunction: common.AutocompleteContainers, Example: `podman unmount ctrID @@ -43,7 +43,7 @@ var ( Long: unmountCommand.Long, RunE: unmountCommand.RunE, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, false) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "") }, ValidArgsFunction: common.AutocompleteContainers, Example: `podman container unmount ctrID diff --git a/cmd/podman/diff.go b/cmd/podman/diff.go index 7b78c8312..ec98fb5b5 100644 --- a/cmd/podman/diff.go +++ b/cmd/podman/diff.go @@ -35,9 +35,6 @@ func init() { Command: diffCmd, }) flags := diffCmd.Flags() - // FIXME: Why does this exists? It is not used anywhere. - flags.BoolVar(&diffOpts.Archive, "archive", true, "Save the diff as a tar archive") - _ = flags.MarkHidden("archive") formatFlagName := "format" flags.StringVar(&diffOpts.Format, formatFlagName, "", "Change the output format (json)") diff --git a/cmd/podman/diff/diff.go b/cmd/podman/diff/diff.go index a26502de9..15c55852a 100644 --- a/cmd/podman/diff/diff.go +++ b/cmd/podman/diff/diff.go @@ -13,7 +13,7 @@ import ( "github.com/spf13/cobra" ) -func Diff(cmd *cobra.Command, args []string, options entities.DiffOptions) error { +func Diff(_ *cobra.Command, args []string, options entities.DiffOptions) error { results, err := registry.ContainerEngine().Diff(registry.GetContext(), args, options) if err != nil { return err @@ -63,7 +63,7 @@ func changesToTable(diffs *entities.DiffReport) error { return nil } -// IDOrLatestArgs used to validate a nameOrId was provided or the "--latest" flag +// ValidateContainerDiffArgs used to validate a nameOrId was provided or the "--latest" flag func ValidateContainerDiffArgs(cmd *cobra.Command, args []string) error { given, _ := cmd.Flags().GetBool("latest") if len(args) > 0 && !given { diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go index 3ea60e18a..940ea6e42 100644 --- a/cmd/podman/images/build.go +++ b/cmd/podman/images/build.go @@ -197,9 +197,8 @@ func buildFlags(cmd *cobra.Command) { // build executes the build command. func build(cmd *cobra.Command, args []string) error { if (cmd.Flags().Changed("squash") && cmd.Flags().Changed("layers")) || - (cmd.Flags().Changed("squash-all") && cmd.Flags().Changed("layers")) || (cmd.Flags().Changed("squash-all") && cmd.Flags().Changed("squash")) { - return errors.New("cannot specify --squash, --squash-all and --layers options together") + return errors.New("cannot specify --squash with --layers and --squash-all with --squash") } if cmd.Flag("output").Changed && registry.IsRemote() { @@ -418,7 +417,13 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil // Squash-all invoked, squash both new and old layers into one. if c.Flags().Changed("squash-all") { flags.Squash = true - flags.Layers = false + if !c.Flags().Changed("layers") { + // Buildah supports using layers and --squash together + // after https://github.com/containers/buildah/pull/3674 + // so podman must honor if user wants to still use layers + // with --squash-all. + flags.Layers = false + } } var stdin io.Reader @@ -442,22 +447,6 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil return nil, err } - // `buildah bud --layers=false` acts like `docker build --squash` does. - // That is all of the new layers created during the build process are - // condensed into one, any layers present prior to this build are retained - // without condensing. `buildah bud --squash` squashes both new and old - // layers down into one. Translate Podman commands into Buildah. - // Squash invoked, retain old layers, squash new layers into one. - if c.Flags().Changed("squash") && flags.Squash { - flags.Squash = false - flags.Layers = false - } - // Squash-all invoked, squash both new and old layers into one. - if c.Flags().Changed("squash-all") { - flags.Squash = true - flags.Layers = false - } - compression := buildahDefine.Gzip if flags.DisableCompression { compression = buildahDefine.Uncompressed @@ -513,9 +502,26 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil return nil, errors.Wrapf(err, "unable to obtain decrypt config") } + additionalBuildContext := make(map[string]*buildahDefine.AdditionalBuildContext) + if c.Flag("build-context").Changed { + for _, contextString := range flags.BuildContext { + av := strings.SplitN(contextString, "=", 2) + if len(av) > 1 { + parseAdditionalBuildContext, err := parse.GetAdditionalBuildContext(av[1]) + if err != nil { + return nil, errors.Wrapf(err, "while parsing additional build context") + } + additionalBuildContext[av[0]] = &parseAdditionalBuildContext + } else { + return nil, fmt.Errorf("while parsing additional build context: %q, accepts value in the form of key=value", av) + } + } + } + opts := buildahDefine.BuildOptions{ AddCapabilities: flags.CapAdd, AdditionalTags: tags, + AdditionalBuildContexts: additionalBuildContext, AllPlatforms: flags.AllPlatforms, Annotations: flags.Annotation, Args: args, @@ -525,6 +531,7 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil Compression: compression, ConfigureNetwork: networkPolicy, ContextDirectory: contextDir, + CPPFlags: flags.CPPFlags, DefaultMountsFilePath: containerConfig.Containers.DefaultMountsFile, Devices: flags.Devices, DropCapabilities: flags.CapDrop, diff --git a/cmd/podman/images/diff.go b/cmd/podman/images/diff.go index 13a8f1d9d..a017d569d 100644 --- a/cmd/podman/images/diff.go +++ b/cmd/podman/images/diff.go @@ -34,9 +34,7 @@ func init() { } func diffFlags(flags *pflag.FlagSet) { - diffOpts = &entities.DiffOptions{} - flags.BoolVar(&diffOpts.Archive, "archive", true, "Save the diff as a tar archive") - _ = flags.MarkDeprecated("archive", "Provided for backwards compatibility, has no impact on output.") + diffOpts = new(entities.DiffOptions) formatFlagName := "format" flags.StringVar(&diffOpts.Format, formatFlagName, "", "Change the output format (json)") diff --git a/cmd/podman/machine/init.go b/cmd/podman/machine/init.go index 6c31f3531..612c36057 100644 --- a/cmd/podman/machine/init.go +++ b/cmd/podman/machine/init.go @@ -25,16 +25,14 @@ var ( Example: `podman machine init myvm`, ValidArgsFunction: completion.AutocompleteNone, } -) -var ( initOpts = machine.InitOptions{} defaultMachineName = machine.DefaultMachineName now bool ) // maxMachineNameSize is set to thirty to limit huge machine names primarily -// because macos has a much smaller file size limit. +// because macOS has a much smaller file size limit. const maxMachineNameSize = 30 func init() { @@ -111,8 +109,7 @@ func init() { flags.BoolVar(&initOpts.Rootful, rootfulFlagName, false, "Whether this machine should prefer rootful container execution") } -// TODO should we allow for a users to append to the qemu cmdline? -func initMachine(cmd *cobra.Command, args []string) error { +func initMachine(_ *cobra.Command, args []string) error { var ( err error vm machine.VM @@ -122,7 +119,7 @@ func initMachine(cmd *cobra.Command, args []string) error { initOpts.Name = defaultMachineName if len(args) > 0 { if len(args[0]) > maxMachineNameSize { - return errors.New("machine name must be 30 characters or less") + return errors.Errorf("machine name %q must be %d characters or less", args[0], maxMachineNameSize) } initOpts.Name = args[0] } diff --git a/cmd/podman/machine/ssh.go b/cmd/podman/machine/ssh.go index 4a86da67a..8261f3607 100644 --- a/cmd/podman/machine/ssh.go +++ b/cmd/podman/machine/ssh.go @@ -9,6 +9,7 @@ import ( "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/config" "github.com/containers/podman/v4/cmd/podman/registry" + "github.com/containers/podman/v4/cmd/podman/utils" "github.com/containers/podman/v4/pkg/machine" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -89,7 +90,8 @@ func ssh(cmd *cobra.Command, args []string) error { if err != nil { return errors.Wrapf(err, "vm %s not found", vmName) } - return vm.SSH(vmName, sshOpts) + err = vm.SSH(vmName, sshOpts) + return utils.HandleOSExecError(err) } func remoteConnectionUsername() (string, error) { diff --git a/cmd/podman/networks/reload.go b/cmd/podman/networks/reload.go index 7b6323187..66248e9fb 100644 --- a/cmd/podman/networks/reload.go +++ b/cmd/podman/networks/reload.go @@ -21,7 +21,7 @@ var ( Long: networkReloadDescription, RunE: networkReload, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, false) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "") }, ValidArgsFunction: common.AutocompleteContainers, Example: `podman network reload --latest diff --git a/cmd/podman/parse/net.go b/cmd/podman/parse/net.go index 870690db3..b616e1029 100644 --- a/cmd/podman/parse/net.go +++ b/cmd/podman/parse/net.go @@ -18,6 +18,8 @@ import ( const ( Protocol_TCP Protocol = 0 Protocol_UDP Protocol = 1 + LabelType string = "label" + ENVType string = "env" ) type Protocol int32 @@ -89,9 +91,7 @@ func GetAllLabels(labelFile, inputLabels []string) (map[string]string, error) { // There's an argument that we SHOULD be doing that parsing for // all environment variables, even those sourced from files, but // that would require a substantial rework. - if err := parseEnvFile(labels, file); err != nil { - // FIXME: parseEnvFile is using parseEnv, so we need to add extra - // logic for labels. + if err := parseEnvOrLabelFile(labels, file, LabelType); err != nil { return nil, err } } @@ -109,7 +109,7 @@ func GetAllLabels(labelFile, inputLabels []string) (map[string]string, error) { return labels, nil } -func parseEnv(env map[string]string, line string) error { +func parseEnvOrLabel(env map[string]string, line, configType string) error { data := strings.SplitN(line, "=", 2) // catch invalid variables such as "=" or "=A" @@ -137,7 +137,7 @@ func parseEnv(env map[string]string, line string) error { env[part[0]] = part[1] } } - } else { + } else if configType == ENVType { // if only a pass-through variable is given, clean it up. if val, ok := os.LookupEnv(name); ok { env[name] = val @@ -147,8 +147,9 @@ func parseEnv(env map[string]string, line string) error { return nil } -// parseEnvFile reads a file with environment variables enumerated by lines -func parseEnvFile(env map[string]string, filename string) error { +// parseEnvOrLabelFile reads a file with environment variables enumerated by lines +// configType should be set to either "label" or "env" based on what type is being parsed +func parseEnvOrLabelFile(envOrLabel map[string]string, filename, configType string) error { fh, err := os.Open(filename) if err != nil { return err @@ -161,7 +162,7 @@ func parseEnvFile(env map[string]string, filename string) error { line := strings.TrimLeft(scanner.Text(), whiteSpaces) // line is not empty, and not starting with '#' if len(line) > 0 && !strings.HasPrefix(line, "#") { - if err := parseEnv(env, line); err != nil { + if err := parseEnvOrLabel(envOrLabel, line, configType); err != nil { return err } } diff --git a/cmd/podman/pods/kill.go b/cmd/podman/pods/kill.go index 7216e08bb..5d3b15dc3 100644 --- a/cmd/podman/pods/kill.go +++ b/cmd/podman/pods/kill.go @@ -22,7 +22,7 @@ var ( Long: podKillDescription, RunE: kill, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, false) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "") }, ValidArgsFunction: common.AutocompletePodsRunning, Example: `podman pod kill podID diff --git a/cmd/podman/pods/pause.go b/cmd/podman/pods/pause.go index adc54d171..389fb8415 100644 --- a/cmd/podman/pods/pause.go +++ b/cmd/podman/pods/pause.go @@ -22,7 +22,7 @@ var ( Long: podPauseDescription, RunE: pause, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, false) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "") }, ValidArgsFunction: common.AutocompletePodsRunning, Example: `podman pod pause podID1 podID2 diff --git a/cmd/podman/pods/ps.go b/cmd/podman/pods/ps.go index a89448275..aa42e1983 100644 --- a/cmd/podman/pods/ps.go +++ b/cmd/podman/pods/ps.go @@ -49,7 +49,6 @@ func init() { flags.BoolVar(&psInput.CtrNames, "ctr-names", false, "Display the container names") flags.BoolVar(&psInput.CtrIds, "ctr-ids", false, "Display the container UUIDs. If no-trunc is not set they will be truncated") flags.BoolVar(&psInput.CtrStatus, "ctr-status", false, "Display the container status") - // TODO should we make this a [] ? filterFlagName := "filter" flags.StringSliceVarP(&inputFilters, filterFlagName, "f", []string{}, "Filter output based on conditions given") diff --git a/cmd/podman/pods/restart.go b/cmd/podman/pods/restart.go index 6d624806a..a8e31ce07 100644 --- a/cmd/podman/pods/restart.go +++ b/cmd/podman/pods/restart.go @@ -22,7 +22,7 @@ var ( Long: podRestartDescription, RunE: restart, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, false) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "") }, ValidArgsFunction: common.AutocompletePods, Example: `podman pod restart podID1 podID2 diff --git a/cmd/podman/pods/rm.go b/cmd/podman/pods/rm.go index 52a815534..16b7191c9 100644 --- a/cmd/podman/pods/rm.go +++ b/cmd/podman/pods/rm.go @@ -35,7 +35,7 @@ var ( Long: podRmDescription, RunE: rm, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndPodIDFile(cmd, args, false, true) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "pod-id-file") }, ValidArgsFunction: common.AutocompletePods, Example: `podman pod rm mywebserverpod diff --git a/cmd/podman/pods/start.go b/cmd/podman/pods/start.go index b668cdd61..9436d34a5 100644 --- a/cmd/podman/pods/start.go +++ b/cmd/podman/pods/start.go @@ -31,7 +31,7 @@ var ( Long: podStartDescription, RunE: start, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndPodIDFile(cmd, args, false, true) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "pod-id-file") }, ValidArgsFunction: common.AutocompletePods, Example: `podman pod start podID diff --git a/cmd/podman/pods/stop.go b/cmd/podman/pods/stop.go index c8c3d2732..e8f82bee9 100644 --- a/cmd/podman/pods/stop.go +++ b/cmd/podman/pods/stop.go @@ -36,7 +36,7 @@ var ( Long: podStopDescription, RunE: stop, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndPodIDFile(cmd, args, false, true) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "pod-id-file") }, ValidArgsFunction: common.AutocompletePodsRunning, Example: `podman pod stop mywebserverpod diff --git a/cmd/podman/pods/unpause.go b/cmd/podman/pods/unpause.go index a308a82c3..8a0a24e98 100644 --- a/cmd/podman/pods/unpause.go +++ b/cmd/podman/pods/unpause.go @@ -22,7 +22,7 @@ var ( Long: podUnpauseDescription, RunE: unpause, Args: func(cmd *cobra.Command, args []string) error { - return validate.CheckAllLatestAndCIDFile(cmd, args, false, false) + return validate.CheckAllLatestAndIDFile(cmd, args, false, "") }, // TODO have a function which shows only pods which could be unpaused // for now show all diff --git a/cmd/podman/system/unshare.go b/cmd/podman/system/unshare.go index 0ae5b81ad..1ed08eac3 100644 --- a/cmd/podman/system/unshare.go +++ b/cmd/podman/system/unshare.go @@ -2,10 +2,10 @@ package system import ( "os" - "os/exec" "github.com/containers/common/pkg/completion" "github.com/containers/podman/v4/cmd/podman/registry" + "github.com/containers/podman/v4/cmd/podman/utils" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/rootless" "github.com/pkg/errors" @@ -60,22 +60,5 @@ func unshare(cmd *cobra.Command, args []string) error { } err := registry.ContainerEngine().Unshare(registry.Context(), args, unshareOptions) - if err != nil { - if exitError, ok := err.(*exec.ExitError); ok { - // the user command inside the unshare env has failed - // we set the exit code, do not return the error to the user - // otherwise "exit status X" will be printed - registry.SetExitCode(exitError.ExitCode()) - return nil - } - // cmd.Run() can return fs.ErrNotExist, fs.ErrPermission or exec.ErrNotFound - // follow podman run/exec standard with the exit codes - if errors.Is(err, os.ErrNotExist) || errors.Is(err, exec.ErrNotFound) { - registry.SetExitCode(127) - } else if errors.Is(err, os.ErrPermission) { - registry.SetExitCode(126) - } - return err - } - return nil + return utils.HandleOSExecError(err) } diff --git a/cmd/podman/utils/error.go b/cmd/podman/utils/error.go index 2aaa71373..3efff0301 100644 --- a/cmd/podman/utils/error.go +++ b/cmd/podman/utils/error.go @@ -4,10 +4,12 @@ import ( "errors" "fmt" "os" + "os/exec" "strconv" "strings" buildahCLI "github.com/containers/buildah/pkg/cli" + "github.com/containers/podman/v4/cmd/podman/registry" ) type OutputErrors []error @@ -43,3 +45,33 @@ func ExitCodeFromBuildError(errorMsg string) (int, error) { } return buildahCLI.ExecErrorCodeGeneric, errors.New("message does not contains a valid exit code") } + +// HandleOSExecError checks the given error for an exec.ExitError error and +// sets the same podman exit code as the error. +// No error will be returned in this case to make sure things like podman +// unshare false work correctly without extra output. +// When the exec file does not exists we set the exit code to 127, for +// permission errors 126 is used as exit code. In this case we still return +// the error so the user gets an error message. +// If the error is nil it returns nil. +func HandleOSExecError(err error) error { + if err == nil { + return nil + } + var exitError *exec.ExitError + if errors.As(err, &exitError) { + // the user command inside the unshare/ssh env has failed + // we set the exit code, do not return the error to the user + // otherwise "exit status X" will be printed + registry.SetExitCode(exitError.ExitCode()) + return nil + } + // cmd.Run() can return fs.ErrNotExist, fs.ErrPermission or exec.ErrNotFound + // follow podman run/exec standard with the exit codes + if errors.Is(err, os.ErrNotExist) || errors.Is(err, exec.ErrNotFound) { + registry.SetExitCode(127) + } else if errors.Is(err, os.ErrPermission) { + registry.SetExitCode(126) + } + return err +} diff --git a/cmd/podman/utils/signals_linux.go b/cmd/podman/utils/signals_linux.go deleted file mode 100644 index dd0507c0e..000000000 --- a/cmd/podman/utils/signals_linux.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !windows -// +build !windows - -package utils - -import ( - "os" - - "golang.org/x/sys/unix" -) - -// Platform specific signal synonyms -var ( - SIGHUP os.Signal = unix.SIGHUP -) diff --git a/cmd/podman/utils/signals_windows.go b/cmd/podman/utils/signals_windows.go deleted file mode 100644 index e6fcc1b32..000000000 --- a/cmd/podman/utils/signals_windows.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build windows -// +build windows - -package utils - -import ( - "os" - - "golang.org/x/sys/windows" -) - -// Platform specific signal synonyms -var ( - SIGHUP os.Signal = windows.SIGHUP -) diff --git a/cmd/podman/validate/args.go b/cmd/podman/validate/args.go index 669456bd3..b9b468d34 100644 --- a/cmd/podman/validate/args.go +++ b/cmd/podman/validate/args.go @@ -50,89 +50,44 @@ func IDOrLatestArgs(cmd *cobra.Command, args []string) error { return nil } -// TODO: the two functions CheckAllLatestAndCIDFile and CheckAllLatestAndPodIDFile are almost identical. -// It may be worth looking into generalizing the two a bit more and share code but time is scarce and -// we only live once. - -// CheckAllLatestAndCIDFile checks that --all and --latest are used correctly. -// If cidfile is set, also check for the --cidfile flag. +// CheckAllLatestAndCIDFile checks that --all and --latest are used correctly for containers and pods +// If idFileFlag is set is set, also checks for the --cidfile or --pod-id-file flag. +// Note: this has been deprecated, use CheckAllLatestAndIDFile instead func CheckAllLatestAndCIDFile(c *cobra.Command, args []string, ignoreArgLen bool, cidfile bool) error { - var specifiedLatest bool - argLen := len(args) - if !registry.IsRemote() { - specifiedLatest, _ = c.Flags().GetBool("latest") - if c.Flags().Lookup("all") == nil || c.Flags().Lookup("latest") == nil { - if !cidfile { - return errors.New("unable to lookup values for 'latest' or 'all'") - } else if c.Flags().Lookup("cidfile") == nil { - return errors.New("unable to lookup values for 'latest', 'all' or 'cidfile'") - } - } - } - - specifiedAll, _ := c.Flags().GetBool("all") - specifiedCIDFile := false - if cid, _ := c.Flags().GetStringArray("cidfile"); len(cid) > 0 { - specifiedCIDFile = true - } - - if specifiedCIDFile && (specifiedAll || specifiedLatest) { - return errors.Errorf("--all, --latest and --cidfile cannot be used together") - } else if specifiedAll && specifiedLatest { - return errors.Errorf("--all and --latest cannot be used together") - } - - if (argLen > 0) && specifiedAll { - return errors.Errorf("no arguments are needed with --all") - } - - if ignoreArgLen { - return nil - } - - if argLen > 0 { - if specifiedLatest { - return errors.Errorf("--latest and containers cannot be used together") - } else if cidfile && (specifiedLatest || specifiedCIDFile) { - return errors.Errorf("no arguments are needed with --latest or --cidfile") - } - } - - if specifiedCIDFile { - return nil - } - - if argLen < 1 && !specifiedAll && !specifiedLatest && !specifiedCIDFile { - return errors.Errorf("you must provide at least one name or id") - } - return nil + return CheckAllLatestAndIDFile(c, args, ignoreArgLen, "cidfile") } // CheckAllLatestAndPodIDFile checks that --all and --latest are used correctly. // If withIDFile is set, also check for the --pod-id-file flag. +// Note: this has been deprecated, use CheckAllLatestAndIDFile instead func CheckAllLatestAndPodIDFile(c *cobra.Command, args []string, ignoreArgLen bool, withIDFile bool) error { + return CheckAllLatestAndIDFile(c, args, ignoreArgLen, "pod-id-file") +} + +// CheckAllLatestAndIDFile checks that --all and --latest are used correctly for containers and pods +// If idFileFlag is set is set, also checks for the --cidfile or --pod-id-file flag. +func CheckAllLatestAndIDFile(c *cobra.Command, args []string, ignoreArgLen bool, idFileFlag string) error { var specifiedLatest bool argLen := len(args) if !registry.IsRemote() { - // remote clients have no latest flag specifiedLatest, _ = c.Flags().GetBool("latest") if c.Flags().Lookup("all") == nil || c.Flags().Lookup("latest") == nil { - if !withIDFile { + if idFileFlag == "" { return errors.New("unable to lookup values for 'latest' or 'all'") - } else if c.Flags().Lookup("pod-id-file") == nil { - return errors.New("unable to lookup values for 'latest', 'all' or 'pod-id-file'") + } else if c.Flags().Lookup(idFileFlag) == nil { + return errors.Errorf("unable to lookup values for 'latest', 'all', or '%s'", idFileFlag) } } } specifiedAll, _ := c.Flags().GetBool("all") - specifiedPodIDFile := false - if pid, _ := c.Flags().GetStringArray("pod-id-file"); len(pid) > 0 { - specifiedPodIDFile = true + specifiedIDFile := false + if cid, _ := c.Flags().GetStringArray(idFileFlag); len(cid) > 0 { + specifiedIDFile = true } - if specifiedPodIDFile && (specifiedAll || specifiedLatest) { - return errors.Errorf("--all, --latest and --pod-id-file cannot be used together") + if specifiedIDFile && (specifiedAll || specifiedLatest) { + return errors.Errorf("--all, --latest, and --%s cannot be used together", idFileFlag) } else if specifiedAll && specifiedLatest { return errors.Errorf("--all and --latest cannot be used together") } @@ -147,17 +102,17 @@ func CheckAllLatestAndPodIDFile(c *cobra.Command, args []string, ignoreArgLen bo if argLen > 0 { if specifiedLatest { - return errors.Errorf("--latest and pods cannot be used together") - } else if withIDFile && (specifiedLatest || specifiedPodIDFile) { - return errors.Errorf("no arguments are needed with --latest or --pod-id-file") + return errors.Errorf("--latest and containers cannot be used together") + } else if idFileFlag != "" && (specifiedLatest || specifiedIDFile) { + return errors.Errorf("no arguments are needed with --latest or --%s", idFileFlag) } } - if specifiedPodIDFile { + if specifiedIDFile { return nil } - if argLen < 1 && !specifiedAll && !specifiedLatest && !specifiedPodIDFile { + if argLen < 1 && !specifiedAll && !specifiedLatest && !specifiedIDFile { return errors.Errorf("you must provide at least one name or id") } return nil diff --git a/cmd/podman/volumes/export.go b/cmd/podman/volumes/export.go index 5086323f9..113f79a0b 100644 --- a/cmd/podman/volumes/export.go +++ b/cmd/podman/volumes/export.go @@ -8,6 +8,7 @@ import ( "github.com/containers/podman/v4/cmd/podman/common" "github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/pkg/domain/entities" + "github.com/containers/podman/v4/pkg/errorhandling" "github.com/containers/podman/v4/utils" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -58,10 +59,13 @@ func export(cmd *cobra.Command, args []string) error { return errors.New("expects output path, use --output=[path]") } inspectOpts.Type = common.VolumeType - volumeData, _, err := containerEngine.VolumeInspect(ctx, args, inspectOpts) + volumeData, errs, err := containerEngine.VolumeInspect(ctx, args, inspectOpts) if err != nil { return err } + if len(errs) > 0 { + return errorhandling.JoinErrors(errs) + } if len(volumeData) < 1 { return errors.New("no volume data found") } diff --git a/cmd/podman/volumes/import.go b/cmd/podman/volumes/import.go index 988c5536d..76a311643 100644 --- a/cmd/podman/volumes/import.go +++ b/cmd/podman/volumes/import.go @@ -8,6 +8,7 @@ import ( "github.com/containers/podman/v4/cmd/podman/parse" "github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/pkg/domain/entities" + "github.com/containers/podman/v4/pkg/errorhandling" "github.com/containers/podman/v4/utils" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -60,10 +61,14 @@ func importVol(cmd *cobra.Command, args []string) error { } inspectOpts.Type = common.VolumeType - volumeData, _, err := containerEngine.VolumeInspect(ctx, volumes, inspectOpts) + inspectOpts.Type = common.VolumeType + volumeData, errs, err := containerEngine.VolumeInspect(ctx, volumes, inspectOpts) if err != nil { return err } + if len(errs) > 0 { + return errorhandling.JoinErrors(errs) + } if len(volumeData) < 1 { return errors.New("no volume data found") } |