diff options
Diffstat (limited to 'cmd/podman')
-rw-r--r-- | cmd/podman/commands.go | 5 | ||||
-rw-r--r-- | cmd/podman/common.go | 4 | ||||
-rw-r--r-- | cmd/podman/container.go | 51 | ||||
-rw-r--r-- | cmd/podman/cp.go | 15 | ||||
-rw-r--r-- | cmd/podman/errors.go | 5 | ||||
-rw-r--r-- | cmd/podman/errors_remote.go | 43 | ||||
-rw-r--r-- | cmd/podman/image.go | 46 | ||||
-rw-r--r-- | cmd/podman/images.go | 30 | ||||
-rw-r--r-- | cmd/podman/main.go | 1 | ||||
-rw-r--r-- | cmd/podman/pod_start.go | 2 | ||||
-rw-r--r-- | cmd/podman/ps.go | 38 | ||||
-rw-r--r-- | cmd/podman/rmi.go | 12 | ||||
-rw-r--r-- | cmd/podman/stop.go | 67 | ||||
-rw-r--r-- | cmd/podman/system_prune.go | 1 | ||||
-rw-r--r-- | cmd/podman/varlink/io.podman.varlink | 5 |
15 files changed, 201 insertions, 124 deletions
diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go index 2f9a9cfe2..c261e54e2 100644 --- a/cmd/podman/commands.go +++ b/cmd/podman/commands.go @@ -32,7 +32,6 @@ func getMainCommands() []*cobra.Command { _searchCommand, _startCommand, _statsCommand, - _stopCommand, _topCommand, _umountCommand, _unpauseCommand, @@ -55,9 +54,6 @@ func getImageSubCommands() []*cobra.Command { // Commands that the local client implements func getContainerSubCommands() []*cobra.Command { - var _listSubCommand = _psCommand - _listSubCommand.Use = "list" - return []*cobra.Command{ _attachCommand, _checkpointCommand, @@ -68,7 +64,6 @@ func getContainerSubCommands() []*cobra.Command { _execCommand, _exportCommand, _killCommand, - &_listSubCommand, _logsCommand, _mountCommand, _pauseCommand, diff --git a/cmd/podman/common.go b/cmd/podman/common.go index d3387b8f4..c9e937825 100644 --- a/cmd/podman/common.go +++ b/cmd/podman/common.go @@ -311,8 +311,8 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { "kernel-memory", "", "Kernel memory limit (format: `<number>[<unit>]`, where unit = b, k, m or g)", ) - createFlags.StringSlice( - "label", []string{}, + createFlags.StringSliceP( + "label", "l", []string{}, "Set metadata on container (default [])", ) createFlags.StringSlice( diff --git a/cmd/podman/container.go b/cmd/podman/container.go index 338bb005c..0bcdf533a 100644 --- a/cmd/podman/container.go +++ b/cmd/podman/container.go @@ -1,27 +1,50 @@ package main import ( + "strings" + "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/spf13/cobra" ) -var containerDescription = "Manage containers" -var containerCommand = cliconfig.PodmanCommand{ - Command: &cobra.Command{ - Use: "container", - Short: "Manage Containers", - Long: containerDescription, - TraverseChildren: true, - }, -} +var ( + containerDescription = "Manage containers" + containerCommand = cliconfig.PodmanCommand{ + Command: &cobra.Command{ + Use: "container", + Short: "Manage Containers", + Long: containerDescription, + TraverseChildren: true, + }, + } -// Commands that are universally implemented. -var containerCommands = []*cobra.Command{ - _containerExistsCommand, - _inspectCommand, -} + listSubCommand cliconfig.PsValues + _listSubCommand = &cobra.Command{ + Use: strings.Replace(_psCommand.Use, "ps", "list", 1), + Args: noSubArgs, + Short: _psCommand.Short, + Long: _psCommand.Long, + Aliases: []string{"ls"}, + RunE: func(cmd *cobra.Command, args []string) error { + listSubCommand.InputArgs = args + listSubCommand.GlobalFlags = MainGlobalOpts + return psCmd(&listSubCommand) + }, + Example: strings.Replace(_psCommand.Example, "podman ps", "podman container list", -1), + } + + // Commands that are universally implemented. + containerCommands = []*cobra.Command{ + _containerExistsCommand, + _inspectCommand, + _listSubCommand, + } +) func init() { + listSubCommand.Command = _listSubCommand + psInit(&listSubCommand) + containerCommand.AddCommand(containerCommands...) containerCommand.AddCommand(getContainerSubCommands()...) containerCommand.SetUsageTemplate(UsageTemplate()) diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go index 30b6d75d2..5958370b6 100644 --- a/cmd/podman/cp.go +++ b/cmd/podman/cp.go @@ -240,7 +240,6 @@ func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, ch // return functions for copying items copyFileWithTar := chrootarchive.CopyFileWithTarAndChown(chownOpts, digest.Canonical.Digester().Hash(), idMappingOpts.UIDMap, idMappingOpts.GIDMap) copyWithTar := chrootarchive.CopyWithTarAndChown(chownOpts, digest.Canonical.Digester().Hash(), idMappingOpts.UIDMap, idMappingOpts.GIDMap) - untarPath := chrootarchive.UntarPathAndChown(chownOpts, digest.Canonical.Digester().Hash(), idMappingOpts.UIDMap, idMappingOpts.GIDMap) if srcfi.IsDir() { @@ -263,17 +262,11 @@ func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, ch if destfi != nil && destfi.IsDir() { destPath = filepath.Join(destPath, filepath.Base(srcPath)) } - // Copy the file, preserving attributes. - logrus.Debugf("copying %q to %q", srcPath, destPath) - if err = copyFileWithTar(srcPath, destPath); err != nil { - return errors.Wrapf(err, "error copying %q to %q", srcPath, destPath) - } - return nil } - // We're extracting an archive into the destination directory. - logrus.Debugf("extracting contents of %q into %q", srcPath, destPath) - if err = untarPath(srcPath, destPath); err != nil { - return errors.Wrapf(err, "error extracting %q into %q", srcPath, destPath) + // Copy the file, preserving attributes. + logrus.Debugf("copying %q to %q", srcPath, destPath) + if err = copyFileWithTar(srcPath, destPath); err != nil { + return errors.Wrapf(err, "error copying %q to %q", srcPath, destPath) } return nil } diff --git a/cmd/podman/errors.go b/cmd/podman/errors.go index 2572b8779..9731037f4 100644 --- a/cmd/podman/errors.go +++ b/cmd/podman/errors.go @@ -1,3 +1,5 @@ +// +build !remoteclient + package main import ( @@ -13,7 +15,8 @@ func outputError(err error) { if MainGlobalOpts.LogLevel == "debug" { logrus.Errorf(err.Error()) } else { - if ee, ok := err.(*exec.ExitError); ok { + ee, ok := err.(*exec.ExitError) + if ok { if status, ok := ee.Sys().(syscall.WaitStatus); ok { exitCode = status.ExitStatus() } diff --git a/cmd/podman/errors_remote.go b/cmd/podman/errors_remote.go new file mode 100644 index 000000000..ab255ea56 --- /dev/null +++ b/cmd/podman/errors_remote.go @@ -0,0 +1,43 @@ +// +build remoteclient + +package main + +import ( + "fmt" + "os" + "os/exec" + "syscall" + + "github.com/containers/libpod/cmd/podman/varlink" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +func outputError(err error) { + if MainGlobalOpts.LogLevel == "debug" { + logrus.Errorf(err.Error()) + } else { + if ee, ok := err.(*exec.ExitError); ok { + if status, ok := ee.Sys().(syscall.WaitStatus); ok { + exitCode = status.ExitStatus() + } + } + var ne error + switch e := err.(type) { + // For some reason golang wont let me list them with commas so listing them all. + case *iopodman.ImageNotFound: + ne = errors.New(e.Reason) + case *iopodman.ContainerNotFound: + ne = errors.New(e.Reason) + case *iopodman.PodNotFound: + ne = errors.New(e.Reason) + case *iopodman.VolumeNotFound: + ne = errors.New(e.Reason) + case *iopodman.ErrorOccurred: + ne = errors.New(e.Reason) + default: + ne = err + } + fmt.Fprintln(os.Stderr, "Error:", ne.Error()) + } +} diff --git a/cmd/podman/image.go b/cmd/podman/image.go index 0777425eb..57be7fe14 100644 --- a/cmd/podman/image.go +++ b/cmd/podman/image.go @@ -16,14 +16,39 @@ var ( Long: imageDescription, }, } - _imagesSubCommand = _imagesCommand - _rmSubCommand = _rmiCommand + imagesSubCommand cliconfig.ImagesValues + _imagesSubCommand = &cobra.Command{ + Use: strings.Replace(_imagesCommand.Use, "images", "list", 1), + Short: _imagesCommand.Short, + Long: _imagesCommand.Long, + Aliases: []string{"ls"}, + RunE: func(cmd *cobra.Command, args []string) error { + imagesSubCommand.InputArgs = args + imagesSubCommand.GlobalFlags = MainGlobalOpts + return imagesCmd(&imagesSubCommand) + }, + Example: strings.Replace(_imagesCommand.Example, "podman images", "podman image list", -1), + } + + rmSubCommand cliconfig.RmiValues + _rmSubCommand = &cobra.Command{ + Use: strings.Replace(_rmiCommand.Use, "rmi", "rm", 1), + Short: _rmiCommand.Short, + Long: _rmiCommand.Long, + RunE: func(cmd *cobra.Command, args []string) error { + rmSubCommand.InputArgs = args + rmSubCommand.GlobalFlags = MainGlobalOpts + return rmiCmd(&rmSubCommand) + }, + Example: strings.Replace(_rmiCommand.Example, "podman rmi", "podman image rm", -1), + } ) //imageSubCommands are implemented both in local and remote clients var imageSubCommands = []*cobra.Command{ _buildCommand, _historyCommand, + _imagesSubCommand, _imageExistsCommand, _importCommand, _inspectCommand, @@ -31,23 +56,20 @@ var imageSubCommands = []*cobra.Command{ _pruneImagesCommand, _pullCommand, _pushCommand, + _rmSubCommand, _saveCommand, _tagCommand, } func init() { + rmSubCommand.Command = _rmSubCommand + rmiInit(&rmSubCommand) + + imagesSubCommand.Command = _imagesSubCommand + imagesInit(&imagesSubCommand) + imageCommand.SetUsageTemplate(UsageTemplate()) imageCommand.AddCommand(imageSubCommands...) imageCommand.AddCommand(getImageSubCommands()...) - // Setup of "images" to appear as "list" - _imagesSubCommand.Use = strings.Replace(_imagesSubCommand.Use, "images", "list", 1) - _imagesSubCommand.Aliases = []string{"ls"} - _imagesSubCommand.Example = strings.Replace(_imagesSubCommand.Example, "podman images", "podman image list", -1) - imageCommand.AddCommand(&_imagesSubCommand) - - // It makes no sense to keep 'podman images rmi'; just use 'rm' - _rmSubCommand.Use = strings.Replace(_rmSubCommand.Use, "rmi", "rm", 1) - _rmSubCommand.Example = strings.Replace(_rmSubCommand.Example, "podman rmi", "podman image rm", -1) - imageCommand.AddCommand(&_rmSubCommand) } diff --git a/cmd/podman/images.go b/cmd/podman/images.go index e6f4d9a60..26e51bef7 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -102,22 +102,26 @@ var ( } ) -func init() { - imagesCommand.Command = &_imagesCommand - imagesCommand.SetUsageTemplate(UsageTemplate()) - - flags := imagesCommand.Flags() - flags.BoolVarP(&imagesCommand.All, "all", "a", false, "Show all images (default hides intermediate images)") - flags.BoolVar(&imagesCommand.Digests, "digests", false, "Show digests") - flags.StringSliceVarP(&imagesCommand.Filter, "filter", "f", []string{}, "Filter output based on conditions provided (default [])") - flags.StringVar(&imagesCommand.Format, "format", "", "Change the output format to JSON or a Go template") - flags.BoolVarP(&imagesCommand.Noheading, "noheading", "n", false, "Do not print column headings") +func imagesInit(command *cliconfig.ImagesValues) { + command.SetUsageTemplate(UsageTemplate()) + + flags := command.Flags() + flags.BoolVarP(&command.All, "all", "a", false, "Show all images (default hides intermediate images)") + flags.BoolVar(&command.Digests, "digests", false, "Show digests") + flags.StringSliceVarP(&command.Filter, "filter", "f", []string{}, "Filter output based on conditions provided (default [])") + flags.StringVar(&command.Format, "format", "", "Change the output format to JSON or a Go template") + flags.BoolVarP(&command.Noheading, "noheading", "n", false, "Do not print column headings") // TODO Need to learn how to deal with second name being a string instead of a char. // This needs to be "no-trunc, notruncate" - flags.BoolVar(&imagesCommand.NoTrunc, "no-trunc", false, "Do not truncate output") - flags.BoolVarP(&imagesCommand.Quiet, "quiet", "q", false, "Display only image IDs") - flags.StringVar(&imagesCommand.Sort, "sort", "created", "Sort by created, id, repository, size, or tag") + flags.BoolVar(&command.NoTrunc, "no-trunc", false, "Do not truncate output") + flags.BoolVarP(&command.Quiet, "quiet", "q", false, "Display only image IDs") + flags.StringVar(&command.Sort, "sort", "created", "Sort by created, id, repository, size, or tag") + +} +func init() { + imagesCommand.Command = &_imagesCommand + imagesInit(&imagesCommand) } func imagesCmd(c *cliconfig.ImagesValues) error { diff --git a/cmd/podman/main.go b/cmd/podman/main.go index 98e2f23ca..b3faf05c0 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -49,6 +49,7 @@ var mainCommands = []*cobra.Command{ _pushCommand, &_rmiCommand, _saveCommand, + _stopCommand, _tagCommand, _versionCommand, imageCommand.Command, diff --git a/cmd/podman/pod_start.go b/cmd/podman/pod_start.go index eef9d2a71..ca8ad08cf 100644 --- a/cmd/podman/pod_start.go +++ b/cmd/podman/pod_start.go @@ -18,7 +18,7 @@ var ( Starts one or more pods. The pod name or ID can be used. ` _podStartCommand = &cobra.Command{ - Use: "start POD [POD...]", + Use: "start [flags] POD [POD...]", Short: "Start one or more pods", Long: podStartDescription, RunE: func(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go index acb5fd7da..0dedd850d 100644 --- a/cmd/podman/ps.go +++ b/cmd/podman/ps.go @@ -173,27 +173,31 @@ var ( } ) -func init() { - psCommand.Command = &_psCommand - psCommand.SetUsageTemplate(UsageTemplate()) - flags := psCommand.Flags() - flags.BoolVarP(&psCommand.All, "all", "a", false, "Show all the containers, default is only running containers") - flags.StringSliceVarP(&psCommand.Filter, "filter", "f", []string{}, "Filter output based on conditions given") - flags.StringVar(&psCommand.Format, "format", "", "Pretty-print containers to JSON or using a Go template") - flags.IntVarP(&psCommand.Last, "last", "n", -1, "Print the n last created containers (all states)") - flags.BoolVarP(&psCommand.Latest, "latest", "l", false, "Show the latest container created (all states)") - flags.BoolVar(&psCommand.Namespace, "namespace", false, "Display namespace information") - flags.BoolVar(&psCommand.Namespace, "ns", false, "Display namespace information") - flags.BoolVar(&psCommand.NoTrunct, "no-trunc", false, "Display the extended information") - flags.BoolVarP(&psCommand.Pod, "pod", "p", false, "Print the ID and name of the pod the containers are associated with") - flags.BoolVarP(&psCommand.Quiet, "quiet", "q", false, "Print the numeric IDs of the containers only") - flags.BoolVarP(&psCommand.Size, "size", "s", false, "Display the total file sizes") - flags.StringVar(&psCommand.Sort, "sort", "created", "Sort output by command, created, id, image, names, runningfor, size, or status") - flags.BoolVar(&psCommand.Sync, "sync", false, "Sync container state with OCI runtime") +func psInit(command *cliconfig.PsValues) { + command.SetUsageTemplate(UsageTemplate()) + flags := command.Flags() + flags.BoolVarP(&command.All, "all", "a", false, "Show all the containers, default is only running containers") + flags.StringSliceVarP(&command.Filter, "filter", "f", []string{}, "Filter output based on conditions given") + flags.StringVar(&command.Format, "format", "", "Pretty-print containers to JSON or using a Go template") + flags.IntVarP(&command.Last, "last", "n", -1, "Print the n last created containers (all states)") + flags.BoolVarP(&command.Latest, "latest", "l", false, "Show the latest container created (all states)") + flags.BoolVar(&command.Namespace, "namespace", false, "Display namespace information") + flags.BoolVar(&command.Namespace, "ns", false, "Display namespace information") + flags.BoolVar(&command.NoTrunct, "no-trunc", false, "Display the extended information") + flags.BoolVarP(&command.Pod, "pod", "p", false, "Print the ID and name of the pod the containers are associated with") + flags.BoolVarP(&command.Quiet, "quiet", "q", false, "Print the numeric IDs of the containers only") + flags.BoolVarP(&command.Size, "size", "s", false, "Display the total file sizes") + flags.StringVar(&command.Sort, "sort", "created", "Sort output by command, created, id, image, names, runningfor, size, or status") + flags.BoolVar(&command.Sync, "sync", false, "Sync container state with OCI runtime") markFlagHiddenForRemoteClient("latest", flags) } +func init() { + psCommand.Command = &_psCommand + psInit(&psCommand) +} + func psCmd(c *cliconfig.PsValues) error { if c.Bool("trace") { span, _ := opentracing.StartSpanFromContext(Ctx, "psCmd") diff --git a/cmd/podman/rmi.go b/cmd/podman/rmi.go index 5b8bf1ea3..511668df7 100644 --- a/cmd/podman/rmi.go +++ b/cmd/podman/rmi.go @@ -29,12 +29,16 @@ var ( } ) +func rmiInit(command *cliconfig.RmiValues) { + command.SetUsageTemplate(UsageTemplate()) + flags := command.Flags() + flags.BoolVarP(&command.All, "all", "a", false, "Remove all images") + flags.BoolVarP(&command.Force, "force", "f", false, "Force Removal of the image") +} + func init() { rmiCommand.Command = &_rmiCommand - rmiCommand.SetUsageTemplate(UsageTemplate()) - flags := rmiCommand.Flags() - flags.BoolVarP(&rmiCommand.All, "all", "a", false, "Remove all images") - flags.BoolVarP(&rmiCommand.Force, "force", "f", false, "Force Removal of the image") + rmiInit(&rmiCommand) } func rmiCmd(c *cliconfig.RmiValues) error { diff --git a/cmd/podman/stop.go b/cmd/podman/stop.go index ab9a2cf38..7bd160494 100644 --- a/cmd/podman/stop.go +++ b/cmd/podman/stop.go @@ -2,15 +2,14 @@ package main import ( "fmt" + "reflect" "github.com/containers/libpod/cmd/podman/cliconfig" - "github.com/containers/libpod/cmd/podman/libpodruntime" - "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/adapter" "github.com/containers/libpod/pkg/rootless" - opentracing "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go" "github.com/pkg/errors" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -52,63 +51,43 @@ func init() { markFlagHiddenForRemoteClient("latest", flags) } +// stopCmd stops a container or containers func stopCmd(c *cliconfig.StopValues) error { + if c.Flag("timeout").Changed && c.Flag("time").Changed { + return errors.New("the --timeout and --time flags are mutually exclusive") + } + if c.Bool("trace") { span, _ := opentracing.StartSpanFromContext(Ctx, "stopCmd") defer span.Finish() } rootless.SetSkipStorageSetup(true) - runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) + runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "could not get runtime") } defer runtime.Shutdown(false) - containers, err := getAllOrLatestContainers(&c.PodmanCommand, runtime, libpod.ContainerStateRunning, "running") + ok, failures, err := runtime.StopContainers(getContext(), c) if err != nil { - if len(containers) == 0 { - return err - } - fmt.Println(err.Error()) + return err } - if c.Flag("timeout").Changed && c.Flag("time").Changed { - return errors.New("the --timeout and --time flags are mutually exclusive") + for _, id := range ok { + fmt.Println(id) } - var stopFuncs []shared.ParallelWorkerInput - for _, ctr := range containers { - con := ctr - var stopTimeout uint - if c.Flag("timeout").Changed || c.Flag("time").Changed { - stopTimeout = c.Timeout - } else { - stopTimeout = ctr.StopTimeout() - logrus.Debugf("Set timeout to container %s default (%d)", ctr.ID(), stopTimeout) - } - f := func() error { - if err := con.StopWithTimeout(stopTimeout); err != nil { - if errors.Cause(err) == libpod.ErrCtrStopped { - logrus.Debugf("Container %s already stopped", con.ID()) - return nil - } - return err - } - return nil - } - stopFuncs = append(stopFuncs, shared.ParallelWorkerInput{ - ContainerID: con.ID(), - ParallelFunc: f, - }) - } + if len(failures) > 0 { + keys := reflect.ValueOf(failures).MapKeys() + lastKey := keys[len(keys)-1].String() + lastErr := failures[lastKey] + delete(failures, lastKey) - maxWorkers := shared.Parallelize("stop") - if c.GlobalIsSet("max-workers") { - maxWorkers = c.GlobalFlags.MaxWorks + for _, err := range failures { + outputError(err) + } + return lastErr } - logrus.Debugf("Setting maximum workers to %d", maxWorkers) - - stopErrors, errCount := shared.ParallelExecuteWorkerPool(maxWorkers, stopFuncs) - return printParallelOutput(stopErrors, errCount) + return nil } diff --git a/cmd/podman/system_prune.go b/cmd/podman/system_prune.go index a823dcad1..f566387fa 100644 --- a/cmd/podman/system_prune.go +++ b/cmd/podman/system_prune.go @@ -23,6 +23,7 @@ var ( ` _pruneSystemCommand = &cobra.Command{ Use: "prune", + Args: noSubArgs, Short: "Remove unused data", Long: pruneSystemDescription, RunE: func(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index 618af3481..73e6c15f9 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -459,6 +459,11 @@ method ListContainers() -> (containers: []Container) # [InspectContainer](#InspectContainer). method GetContainer(id: string) -> (container: Container) +# GetContainersByContext allows you to get a list of container ids depending on all, latest, or a list of +# container names. The definition of latest container means the latest by creation date. In a multi- +# user environment, results might differ from what you expect. +method GetContainersByContext(all: bool, latest: bool, args: []string) -> (containers: []string) + # CreateContainer creates a new container from an image. It uses a [Create](#Create) type for input. The minimum # input required for CreateContainer is an image name. If the image name is not found, an [ImageNotFound](#ImageNotFound) # error will be returned. Otherwise, the ID of the newly created container will be returned. |