diff options
Diffstat (limited to 'cmd/podman/start.go')
-rw-r--r-- | cmd/podman/start.go | 126 |
1 files changed, 65 insertions, 61 deletions
diff --git a/cmd/podman/start.go b/cmd/podman/start.go index f6e1d9882..c645a35c4 100644 --- a/cmd/podman/start.go +++ b/cmd/podman/start.go @@ -1,88 +1,85 @@ package main import ( - "encoding/json" "fmt" "os" + "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/libpod" - cc "github.com/containers/libpod/pkg/spec" + opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/spf13/cobra" ) var ( - startFlags = []cli.Flag{ - cli.BoolFlag{ - Name: "attach, a", - Usage: "Attach container's STDOUT and STDERR", - }, - cli.StringFlag{ - Name: "detach-keys", - Usage: "Override the key sequence for detaching a container. Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _.", - }, - cli.BoolFlag{ - Name: "interactive, i", - Usage: "Keep STDIN open even if not attached", - }, - cli.BoolTFlag{ - Name: "sig-proxy", - Usage: "Proxy received signals to the process (default true if attaching, false otherwise)", - }, - LatestFlag, - } + startCommand cliconfig.StartValues startDescription = ` podman start Starts one or more containers. The container name or ID can be used. ` - - startCommand = cli.Command{ - Name: "start", - Usage: "Start one or more containers", - Description: startDescription, - Flags: sortFlags(startFlags), - Action: startCmd, - ArgsUsage: "CONTAINER-NAME [CONTAINER-NAME ...]", - UseShortOptionHandling: true, - OnUsageError: usageErrorHandler, + _startCommand = &cobra.Command{ + Use: "start", + Short: "Start one or more containers", + Long: startDescription, + RunE: func(cmd *cobra.Command, args []string) error { + startCommand.InputArgs = args + startCommand.GlobalFlags = MainGlobalOpts + return startCmd(&startCommand) + }, + Example: `podman start --latest + podman start 860a4b231279 5421ab43b45 + podman start --interactive --attach imageID`, } ) -func startCmd(c *cli.Context) error { - args := c.Args() - if len(args) < 1 && !c.Bool("latest") { +func init() { + startCommand.Command = _startCommand + startCommand.SetUsageTemplate(UsageTemplate()) + flags := startCommand.Flags() + flags.BoolVarP(&startCommand.Attach, "attach", "a", false, "Attach container's STDOUT and STDERR") + flags.StringVar(&startCommand.DetachKeys, "detach-keys", "", "Override the key sequence for detaching a container. Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _") + flags.BoolVarP(&startCommand.Interactive, "interactive", "i", false, "Keep STDIN open even if not attached") + flags.BoolVarP(&startCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") + flags.BoolVar(&startCommand.SigProxy, "sig-proxy", true, "Proxy received signals to the process (default true if attaching, false otherwise)") + markFlagHiddenForRemoteClient("latest", flags) +} + +func startCmd(c *cliconfig.StartValues) error { + if c.Bool("trace") { + span, _ := opentracing.StartSpanFromContext(Ctx, "startCmd") + defer span.Finish() + } + + args := c.InputArgs + if len(args) < 1 && !c.Latest { return errors.Errorf("you must provide at least one container name or id") } - attach := c.Bool("attach") + attach := c.Attach if len(args) > 1 && attach { return errors.Errorf("you cannot start and attach multiple containers at once") } - if err := validateFlags(c, startFlags); err != nil { - return err - } - - sigProxy := c.BoolT("sig-proxy") + sigProxy := c.SigProxy if sigProxy && !attach { - if c.IsSet("sig-proxy") { + if c.Flag("sig-proxy").Changed { return errors.Wrapf(libpod.ErrInvalidArg, "you cannot use sig-proxy without --attach") } else { sigProxy = false } } - runtime, err := libpodruntime.GetRuntime(c) + runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } defer runtime.Shutdown(false) - if c.Bool("latest") { + if c.Latest { lastCtr, err := runtime.GetLatestContainer() if err != nil { return errors.Wrapf(err, "unable to get latest container") @@ -112,12 +109,20 @@ func startCmd(c *cli.Context) error { if attach { inputStream := os.Stdin - if !c.Bool("interactive") { + if !c.Interactive { inputStream = nil } // attach to the container and also start it not already running - err = startAttachCtr(ctr, os.Stdout, os.Stderr, inputStream, c.String("detach-keys"), sigProxy, !ctrRunning) + // If the container is in a pod, also set to recursively start dependencies + err = startAttachCtr(ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, sigProxy, !ctrRunning, ctr.PodID() != "") + if errors.Cause(err) == libpod.ErrDetach { + // User manually detached + // Exit cleanly immediately + exitCode = 0 + return nil + } + if ctrRunning { return err } @@ -127,31 +132,30 @@ func startCmd(c *cli.Context) error { } if ecode, err := ctr.Wait(); err != nil { - logrus.Errorf("unable to get exit code of container %s: %q", ctr.ID(), err) + if errors.Cause(err) == libpod.ErrNoSuchCtr { + // The container may have been removed + // Go looking for an exit file + ctrExitCode, err := readExitFile(runtime.GetConfig().TmpDir, ctr.ID()) + if err != nil { + logrus.Errorf("Cannot get exit code: %v", err) + exitCode = 127 + } else { + exitCode = ctrExitCode + } + } } else { exitCode = int(ecode) } - return ctr.Cleanup(ctx) + return nil } if ctrRunning { fmt.Println(ctr.ID()) continue } // Handle non-attach start - if err := ctr.Start(ctx); err != nil { - var createArtifact cc.CreateConfig - artifact, artifactErr := ctr.GetArtifact("create-config") - if artifactErr == nil { - if jsonErr := json.Unmarshal(artifact, &createArtifact); jsonErr != nil { - logrus.Errorf("unable to detect if container %s should be deleted", ctr.ID()) - } - if createArtifact.Rm { - if rmErr := runtime.RemoveContainer(ctx, ctr, true); rmErr != nil { - logrus.Errorf("unable to remove container %s after it failed to start", ctr.ID()) - } - } - } + // If the container is in a pod, also set to recursively start dependencies + if err := ctr.Start(ctx, ctr.PodID() != ""); err != nil { if lastError != nil { fmt.Fprintln(os.Stderr, lastError) } |