From 9536560b4f3a38fbba4ac61c357dd3627fb6cf4e Mon Sep 17 00:00:00 2001 From: Brent Baude Date: Sat, 21 Mar 2020 13:47:07 -0500 Subject: podmanv2 add core container commands add core container commands for podmanv2: kill, pause, restart, rm, stop, unpause Signed-off-by: Brent Baude --- cmd/podmanV2/containers/kill.go | 71 +++++++++++++++++++++++++++++ cmd/podmanV2/containers/pause.go | 63 ++++++++++++++++++++++++++ cmd/podmanV2/containers/restart.go | 78 ++++++++++++++++++++++++++++++++ cmd/podmanV2/containers/rm.go | 93 ++++++++++++++++++++++++++++++++++++++ cmd/podmanV2/containers/stop.go | 87 +++++++++++++++++++++++++++++++++++ cmd/podmanV2/containers/unpause.go | 60 ++++++++++++++++++++++++ cmd/podmanV2/containers/utils.go | 1 + cmd/podmanV2/containers/wait.go | 33 +++++++------- cmd/podmanV2/parse/parse.go | 45 ++++++++++++++++++ cmd/podmanV2/root.go | 5 +- cmd/podmanV2/utils/error.go | 16 +++++++ cmd/podmanV2/utils/remote.go | 10 ++++ 12 files changed, 543 insertions(+), 19 deletions(-) create mode 100644 cmd/podmanV2/containers/kill.go create mode 100644 cmd/podmanV2/containers/pause.go create mode 100644 cmd/podmanV2/containers/restart.go create mode 100644 cmd/podmanV2/containers/rm.go create mode 100644 cmd/podmanV2/containers/stop.go create mode 100644 cmd/podmanV2/containers/unpause.go create mode 100644 cmd/podmanV2/containers/utils.go create mode 100644 cmd/podmanV2/utils/error.go create mode 100644 cmd/podmanV2/utils/remote.go (limited to 'cmd/podmanV2') diff --git a/cmd/podmanV2/containers/kill.go b/cmd/podmanV2/containers/kill.go new file mode 100644 index 000000000..b02dcf9da --- /dev/null +++ b/cmd/podmanV2/containers/kill.go @@ -0,0 +1,71 @@ +package containers + +import ( + "context" + "fmt" + + "github.com/containers/libpod/cmd/podmanV2/parse" + "github.com/containers/libpod/cmd/podmanV2/registry" + "github.com/containers/libpod/cmd/podmanV2/utils" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/containers/libpod/pkg/signal" + "github.com/spf13/cobra" +) + +var ( + killDescription = "The main process inside each container specified will be sent SIGKILL, or any signal specified with option --signal." + killCommand = &cobra.Command{ + Use: "kill [flags] CONTAINER [CONTAINER...]", + Short: "Kill one or more running containers with a specific signal", + Long: killDescription, + RunE: kill, + Args: func(cmd *cobra.Command, args []string) error { + return parse.CheckAllLatestAndCIDFile(cmd, args, false, false) + }, + Example: `podman kill mywebserver + podman kill 860a4b23 + podman kill --signal TERM ctrID`, + } +) + +var ( + killOptions = entities.KillOptions{} +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: killCommand, + }) + flags := killCommand.Flags() + flags.BoolVarP(&killOptions.All, "all", "a", false, "Signal all running containers") + flags.StringVarP(&killOptions.Signal, "signal", "s", "KILL", "Signal to send to the container") + flags.BoolVarP(&killOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") + if utils.IsRemote() { + _ = flags.MarkHidden("latest") + } +} + +func kill(cmd *cobra.Command, args []string) error { + var ( + err error + errs utils.OutputErrors + ) + // Check if the signalString provided by the user is valid + // Invalid signals will return err + if _, err = signal.ParseSignalNameOrNumber(killOptions.Signal); err != nil { + return err + } + responses, err := registry.ContainerEngine().ContainerKill(context.Background(), args, killOptions) + if err != nil { + return err + } + for _, r := range responses { + if r.Err == nil { + fmt.Println(r.Id) + } else { + errs = append(errs, r.Err) + } + } + return errs.PrintErrors() +} diff --git a/cmd/podmanV2/containers/pause.go b/cmd/podmanV2/containers/pause.go new file mode 100644 index 000000000..3f3e7c38d --- /dev/null +++ b/cmd/podmanV2/containers/pause.go @@ -0,0 +1,63 @@ +package containers + +import ( + "context" + "fmt" + + "github.com/containers/libpod/cmd/podmanV2/registry" + "github.com/containers/libpod/cmd/podmanV2/utils" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/containers/libpod/pkg/rootless" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +var ( + pauseDescription = `Pauses one or more running containers. The container name or ID can be used.` + pauseCommand = &cobra.Command{ + Use: "pause [flags] CONTAINER [CONTAINER...]", + Short: "Pause all the processes in one or more containers", + Long: pauseDescription, + RunE: pause, + Example: `podman pause mywebserver + podman pause 860a4b23 + podman pause -a`, + } + + pauseOpts = entities.PauseUnPauseOptions{} +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: pauseCommand, + }) + flags := pauseCommand.Flags() + flags.BoolVarP(&pauseOpts.All, "all", "a", false, "Pause all running containers") + pauseCommand.SetHelpTemplate(registry.HelpTemplate()) + pauseCommand.SetUsageTemplate(registry.UsageTemplate()) +} + +func pause(cmd *cobra.Command, args []string) error { + var ( + errs utils.OutputErrors + ) + if rootless.IsRootless() && !utils.IsRemote() { + return errors.New("pause is not supported for rootless containers") + } + if len(args) < 1 && !pauseOpts.All { + return errors.Errorf("you must provide at least one container name or id") + } + responses, err := registry.ContainerEngine().ContainerPause(context.Background(), args, pauseOpts) + if err != nil { + return err + } + for _, r := range responses { + if r.Err == nil { + fmt.Println(r.Id) + } else { + errs = append(errs, r.Err) + } + } + return errs.PrintErrors() +} diff --git a/cmd/podmanV2/containers/restart.go b/cmd/podmanV2/containers/restart.go new file mode 100644 index 000000000..ee9c34361 --- /dev/null +++ b/cmd/podmanV2/containers/restart.go @@ -0,0 +1,78 @@ +package containers + +import ( + "context" + "fmt" + + "github.com/containers/libpod/cmd/podmanV2/parse" + "github.com/containers/libpod/cmd/podmanV2/registry" + "github.com/containers/libpod/cmd/podmanV2/utils" + "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +var ( + restartDescription = `Restarts one or more running containers. The container ID or name can be used. + + A timeout before forcibly stopping can be set, but defaults to 10 seconds.` + restartCommand = &cobra.Command{ + Use: "restart [flags] CONTAINER [CONTAINER...]", + Short: "Restart one or more containers", + Long: restartDescription, + RunE: restart, + Args: func(cmd *cobra.Command, args []string) error { + return parse.CheckAllLatestAndCIDFile(cmd, args, false, false) + }, + Example: `podman restart ctrID + podman restart --latest + podman restart ctrID1 ctrID2`, + } +) + +var ( + restartOptions = entities.RestartOptions{} + restartTimeout uint +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: restartCommand, + }) + flags := restartCommand.Flags() + flags.BoolVarP(&restartOptions.All, "all", "a", false, "Restart all non-running containers") + flags.BoolVarP(&restartOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") + flags.BoolVar(&restartOptions.Running, "running", false, "Restart only running containers when --all is used") + flags.UintVarP(&restartTimeout, "timeout", "t", define.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") + flags.UintVar(&restartTimeout, "time", define.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") + if utils.IsRemote() { + _ = flags.MarkHidden("latest") + } +} + +func restart(cmd *cobra.Command, args []string) error { + var ( + errs utils.OutputErrors + ) + if len(args) < 1 && !restartOptions.Latest && !restartOptions.All { + return errors.Wrapf(define.ErrInvalidArg, "you must provide at least one container name or ID") + } + + if cmd.Flag("timeout").Changed || cmd.Flag("time").Changed { + restartOptions.Timeout = &restartTimeout + } + responses, err := registry.ContainerEngine().ContainerRestart(context.Background(), args, restartOptions) + if err != nil { + return err + } + for _, r := range responses { + if r.Err == nil { + fmt.Println(r.Id) + } else { + errs = append(errs, r.Err) + } + } + return errs.PrintErrors() +} diff --git a/cmd/podmanV2/containers/rm.go b/cmd/podmanV2/containers/rm.go new file mode 100644 index 000000000..af7a38fb1 --- /dev/null +++ b/cmd/podmanV2/containers/rm.go @@ -0,0 +1,93 @@ +package containers + +import ( + "context" + "fmt" + + "github.com/containers/libpod/cmd/podmanV2/parse" + "github.com/containers/libpod/cmd/podmanV2/registry" + "github.com/containers/libpod/cmd/podmanV2/utils" + "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var ( + rmDescription = `Removes one or more containers from the host. The container name or ID can be used. + + Command does not remove images. Running or unusable containers will not be removed without the -f option.` + rmCommand = &cobra.Command{ + Use: "rm [flags] CONTAINER [CONTAINER...]", + Short: "Remove one or more containers", + Long: rmDescription, + RunE: rm, + Args: func(cmd *cobra.Command, args []string) error { + return parse.CheckAllLatestAndCIDFile(cmd, args, false, true) + }, + Example: `podman rm imageID + podman rm mywebserver myflaskserver 860a4b23 + podman rm --force --all + podman rm -f c684f0d469f2`, + } +) + +var ( + rmOptions = entities.RmOptions{} +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: rmCommand, + }) + flags := rmCommand.Flags() + flags.BoolVarP(&rmOptions.All, "all", "a", false, "Remove all containers") + flags.BoolVarP(&rmOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified container is missing") + flags.BoolVarP(&rmOptions.Force, "force", "f", false, "Force removal of a running or unusable container. The default is false") + flags.BoolVarP(&rmOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") + flags.BoolVar(&rmOptions.Storage, "storage", false, "Remove container from storage library") + flags.BoolVarP(&rmOptions.Volumes, "volumes", "v", false, "Remove anonymous volumes associated with the container") + flags.StringArrayVarP(&rmOptions.CIDFiles, "cidfile", "", nil, "Read the container ID from the file") + if utils.IsRemote() { + _ = flags.MarkHidden("latest") + _ = flags.MarkHidden("ignore") + _ = flags.MarkHidden("cidfile") + _ = flags.MarkHidden("storage") + } + +} + +func rm(cmd *cobra.Command, args []string) error { + var ( + errs utils.OutputErrors + ) + // Storage conflicts with --all/--latest/--volumes/--cidfile/--ignore + if rmOptions.Storage { + if rmOptions.All || rmOptions.Ignore || rmOptions.Latest || rmOptions.Volumes || rmOptions.CIDFiles != nil { + return errors.Errorf("--storage conflicts with --volumes, --all, --latest, --ignore and --cidfile") + } + } + responses, err := registry.ContainerEngine().ContainerRm(context.Background(), args, rmOptions) + if err != nil { + // TODO exitcode is a global main variable to track exit codes. + // we need this enabled + //if len(c.InputArgs) < 2 { + // exitCode = setExitCode(err) + //} + return err + } + for _, r := range responses { + if r.Err != nil { + // TODO this will not work with the remote client + if errors.Cause(err) == define.ErrWillDeadlock { + logrus.Errorf("Potential deadlock detected - please run 'podman system renumber' to resolve") + } + errs = append(errs, r.Err) + } else { + fmt.Println(r.Id) + } + } + return errs.PrintErrors() +} diff --git a/cmd/podmanV2/containers/stop.go b/cmd/podmanV2/containers/stop.go new file mode 100644 index 000000000..066202298 --- /dev/null +++ b/cmd/podmanV2/containers/stop.go @@ -0,0 +1,87 @@ +package containers + +import ( + "context" + "fmt" + + "github.com/containers/libpod/cmd/podmanV2/parse" + "github.com/containers/libpod/cmd/podmanV2/registry" + "github.com/containers/libpod/cmd/podmanV2/utils" + "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +var ( + stopDescription = `Stops one or more running containers. The container name or ID can be used. + + A timeout to forcibly stop the container can also be set but defaults to 10 seconds otherwise.` + stopCommand = &cobra.Command{ + Use: "stop [flags] CONTAINER [CONTAINER...]", + Short: "Stop one or more containers", + Long: stopDescription, + RunE: stop, + Args: func(cmd *cobra.Command, args []string) error { + return parse.CheckAllLatestAndCIDFile(cmd, args, false, true) + }, + Example: `podman stop ctrID + podman stop --latest + podman stop --timeout 2 mywebserver 6e534f14da9d`, + } +) + +var ( + stopOptions = entities.StopOptions{} + stopTimeout uint +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: stopCommand, + }) + flags := stopCommand.Flags() + flags.BoolVarP(&stopOptions.All, "all", "a", false, "Stop all running containers") + flags.BoolVarP(&stopOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified container is missing") + flags.StringArrayVarP(&stopOptions.CIDFiles, "cidfile", "", nil, "Read the container ID from the file") + flags.BoolVarP(&stopOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") + flags.UintVar(&stopTimeout, "time", define.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") + flags.UintVarP(&stopTimeout, "timeout", "t", define.CtrRemoveTimeout, "Seconds to wait for stop before killing the container") + if registry.EngineOpts.EngineMode == entities.ABIMode { + _ = flags.MarkHidden("latest") + _ = flags.MarkHidden("cidfile") + _ = flags.MarkHidden("ignore") + } +} + +func stop(cmd *cobra.Command, args []string) error { + var ( + errs utils.OutputErrors + ) + if cmd.Flag("timeout").Changed && cmd.Flag("time").Changed { + return errors.New("the --timeout and --time flags are mutually exclusive") + } + stopOptions.Timeout = define.CtrRemoveTimeout + if cmd.Flag("timeout").Changed || cmd.Flag("time").Changed { + stopOptions.Timeout = stopTimeout + } + + // TODO How do we access global attributes? + //if c.Bool("trace") { + // span, _ := opentracing.StartSpanFromContext(Ctx, "stopCmd") + // defer span.Finish() + //} + responses, err := registry.ContainerEngine().ContainerStop(context.Background(), args, stopOptions) + if err != nil { + return err + } + for _, r := range responses { + if r.Err == nil { + fmt.Println(r.Id) + } else { + errs = append(errs, r.Err) + } + } + return errs.PrintErrors() +} diff --git a/cmd/podmanV2/containers/unpause.go b/cmd/podmanV2/containers/unpause.go new file mode 100644 index 000000000..697132a53 --- /dev/null +++ b/cmd/podmanV2/containers/unpause.go @@ -0,0 +1,60 @@ +package containers + +import ( + "context" + "fmt" + + "github.com/containers/libpod/cmd/podmanV2/registry" + "github.com/containers/libpod/cmd/podmanV2/utils" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/containers/libpod/pkg/rootless" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +var ( + unpauseDescription = `Unpauses one or more previously paused containers. The container name or ID can be used.` + unpauseCommand = &cobra.Command{ + Use: "unpause [flags] CONTAINER [CONTAINER...]", + Short: "Unpause the processes in one or more containers", + Long: unpauseDescription, + RunE: unpause, + Example: `podman unpause ctrID + podman unpause --all`, + } + unPauseOptions = entities.PauseUnPauseOptions{} +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: unpauseCommand, + Parent: containerCmd, + }) + flags := unpauseCommand.Flags() + flags.BoolVarP(&unPauseOptions.All, "all", "a", false, "Pause all running containers") +} + +func unpause(cmd *cobra.Command, args []string) error { + var ( + errs utils.OutputErrors + ) + if rootless.IsRootless() && !utils.IsRemote() { + return errors.New("unpause is not supported for rootless containers") + } + if len(args) < 1 && !unPauseOptions.All { + return errors.Errorf("you must provide at least one container name or id") + } + responses, err := registry.ContainerEngine().ContainerUnpause(context.Background(), args, unPauseOptions) + if err != nil { + return err + } + for _, r := range responses { + if r.Err == nil { + fmt.Println(r.Id) + } else { + errs = append(errs, r.Err) + } + } + return errs.PrintErrors() +} diff --git a/cmd/podmanV2/containers/utils.go b/cmd/podmanV2/containers/utils.go new file mode 100644 index 000000000..0c09d3e40 --- /dev/null +++ b/cmd/podmanV2/containers/utils.go @@ -0,0 +1 @@ +package containers diff --git a/cmd/podmanV2/containers/wait.go b/cmd/podmanV2/containers/wait.go index 27acb3348..cded8e571 100644 --- a/cmd/podmanV2/containers/wait.go +++ b/cmd/podmanV2/containers/wait.go @@ -5,7 +5,9 @@ import ( "fmt" "time" + "github.com/containers/libpod/cmd/podmanV2/parse" "github.com/containers/libpod/cmd/podmanV2/registry" + "github.com/containers/libpod/cmd/podmanV2/utils" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/domain/entities" "github.com/pkg/errors" @@ -20,6 +22,9 @@ var ( Short: "Block on one or more containers", Long: waitDescription, RunE: wait, + Args: func(cmd *cobra.Command, args []string) error { + return parse.CheckAllLatestAndCIDFile(cmd, args, false, false) + }, Example: `podman wait --latest podman wait --interval 5000 ctrID podman wait ctrID1 ctrID2`, @@ -27,7 +32,7 @@ var ( ) var ( - waitFlags = entities.WaitOptions{} + waitOptions = entities.WaitOptions{} waitCondition string ) @@ -35,12 +40,11 @@ func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, Command: waitCommand, - Parent: containerCmd, }) flags := waitCommand.Flags() - flags.DurationVarP(&waitFlags.Interval, "interval", "i", time.Duration(250), "Milliseconds to wait before polling for completion") - flags.BoolVarP(&waitFlags.Latest, "latest", "l", false, "Act on the latest container podman is aware of") + flags.DurationVarP(&waitOptions.Interval, "interval", "i", time.Duration(250), "Milliseconds to wait before polling for completion") + flags.BoolVarP(&waitOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of") flags.StringVar(&waitCondition, "condition", "stopped", "Condition to wait on") if registry.EngineOpts.EngineMode == entities.ABIMode { // TODO: This is the same as V1. We could skip creating the flag altogether in V2... @@ -50,33 +54,28 @@ func init() { func wait(cmd *cobra.Command, args []string) error { var ( - err error + err error + errs utils.OutputErrors ) - if waitFlags.Latest && len(args) > 0 { - return errors.New("cannot combine latest flag and arguments") - } - if waitFlags.Interval == 0 { + if waitOptions.Interval == 0 { return errors.New("interval must be greater then 0") } - waitFlags.Condition, err = define.StringToContainerStatus(waitCondition) + waitOptions.Condition, err = define.StringToContainerStatus(waitCondition) if err != nil { return err } - responses, err := registry.ContainerEngine().ContainerWait(context.Background(), args, waitFlags) + responses, err := registry.ContainerEngine().ContainerWait(context.Background(), args, waitOptions) if err != nil { return err } for _, r := range responses { if r.Error == nil { fmt.Println(r.Id) + } else { + errs = append(errs, r.Error) } } - for _, r := range responses { - if r.Error != nil { - fmt.Println(err) - } - } - return nil + return errs.PrintErrors() } diff --git a/cmd/podmanV2/parse/parse.go b/cmd/podmanV2/parse/parse.go index 03cda268c..10d2146fa 100644 --- a/cmd/podmanV2/parse/parse.go +++ b/cmd/podmanV2/parse/parse.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/pkg/errors" + "github.com/spf13/cobra" ) const ( @@ -186,3 +187,47 @@ func ValidURL(urlStr string) error { } return nil } + +// checkAllLatestAndCIDFile checks that --all and --latest are used correctly. +// If cidfile is set, also check for the --cidfile flag. +func CheckAllLatestAndCIDFile(c *cobra.Command, args []string, ignoreArgLen bool, cidfile bool) error { + argLen := len(args) + 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") + specifiedLatest, _ := c.Flags().GetBool("latest") + 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 ignoreArgLen { + return nil + } + if (argLen > 0) && (specifiedAll || specifiedLatest) { + return errors.Errorf("no arguments are needed with --all or --latest") + } else if cidfile && (argLen > 0) && (specifiedAll || specifiedLatest || specifiedCIDFile) { + return errors.Errorf("no arguments are needed with --all, --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 +} diff --git a/cmd/podmanV2/root.go b/cmd/podmanV2/root.go index 24b083b9f..b0dd7643f 100644 --- a/cmd/podmanV2/root.go +++ b/cmd/podmanV2/root.go @@ -23,8 +23,9 @@ var rootCmd = &cobra.Command{ func init() { // Override default --help information of `--version` global flag} var dummyVersion bool - rootCmd.PersistentFlags().BoolVarP(&dummyVersion, "version", "v", false, "Version of podman") - rootCmd.PersistentFlags().StringVarP(®istry.EngineOpts.Uri, "remote", "r", "", "URL to access podman service") + // TODO had to disable shorthand -v for version due to -v rm with volume + rootCmd.PersistentFlags().BoolVar(&dummyVersion, "version", false, "Version of Podman") + rootCmd.PersistentFlags().StringVarP(®istry.EngineOpts.Uri, "remote", "r", "", "URL to access Podman service") rootCmd.PersistentFlags().StringSliceVar(®istry.EngineOpts.Identities, "identity", []string{}, "path to SSH identity file") } diff --git a/cmd/podmanV2/utils/error.go b/cmd/podmanV2/utils/error.go new file mode 100644 index 000000000..3464f0779 --- /dev/null +++ b/cmd/podmanV2/utils/error.go @@ -0,0 +1,16 @@ +package utils + +import "fmt" + +type OutputErrors []error + +func (o OutputErrors) PrintErrors() (lastError error) { + if len(o) == 0 { + return + } + lastError = o[len(o)-1] + for e := 0; e < len(o)-1; e++ { + fmt.Println(o[e]) + } + return +} diff --git a/cmd/podmanV2/utils/remote.go b/cmd/podmanV2/utils/remote.go new file mode 100644 index 000000000..d0c8a272d --- /dev/null +++ b/cmd/podmanV2/utils/remote.go @@ -0,0 +1,10 @@ +package utils + +import ( + "github.com/containers/libpod/cmd/podmanV2/registry" + "github.com/containers/libpod/pkg/domain/entities" +) + +func IsRemote() bool { + return registry.EngineOpts.EngineMode == entities.TunnelMode +} -- cgit v1.2.3-54-g00ecf