spiegel_podman/cmd/podman/containers/start.go
Paul Holzinger cf4967de4d Improve the shell completion api
One main advantage of the new shell completion logic is that
we can easly parse flags and adjust based on the given flags
the suggestions. For example some commands accept the
`--latest` flag only if no arguments are given.

This commit implements this logic in a simple maintainable way
since it reuses the already existing `Args` function in the
cmd struct.

I also refactored the `getXXX` function to match based on the
namei/id which could speed up the shell completion with many
containers, images, etc...

I also added the degraded status to the valid pod status
filters which was implemented in #8081.

Signed-off-by: Paul Holzinger <paul.holzinger@web.de>
2020-11-16 16:14:42 +01:00

130 lines
4.3 KiB
Go

package containers
import (
"fmt"
"os"
"github.com/containers/podman/v2/cmd/podman/common"
"github.com/containers/podman/v2/cmd/podman/registry"
"github.com/containers/podman/v2/cmd/podman/utils"
"github.com/containers/podman/v2/cmd/podman/validate"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
var (
startDescription = `Starts one or more containers. The container name or ID can be used.`
startCommand = &cobra.Command{
Use: "start [options] CONTAINER [CONTAINER...]",
Short: "Start one or more containers",
Long: startDescription,
RunE: start,
Args: validateStart,
ValidArgsFunction: common.AutocompleteContainersStartable,
Example: `podman start --latest
podman start 860a4b231279 5421ab43b45
podman start --interactive --attach imageID`,
}
containerStartCommand = &cobra.Command{
Use: startCommand.Use,
Short: startCommand.Short,
Long: startCommand.Long,
RunE: startCommand.RunE,
Args: startCommand.Args,
ValidArgsFunction: startCommand.ValidArgsFunction,
Example: `podman container start --latest
podman container start 860a4b231279 5421ab43b45
podman container start --interactive --attach imageID`,
}
)
var (
startOptions entities.ContainerStartOptions
)
func startFlags(cmd *cobra.Command) {
flags := cmd.Flags()
flags.BoolVarP(&startOptions.Attach, "attach", "a", false, "Attach container's STDOUT and STDERR")
detachKeysFlagName := "detach-keys"
flags.StringVar(&startOptions.DetachKeys, detachKeysFlagName, containerConfig.DetachKeys(), "Select the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-z`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`")
_ = cmd.RegisterFlagCompletionFunc(detachKeysFlagName, common.AutocompleteDetachKeys)
flags.BoolVarP(&startOptions.Interactive, "interactive", "i", false, "Keep STDIN open even if not attached")
flags.BoolVar(&startOptions.SigProxy, "sig-proxy", false, "Proxy received signals to the process (default true if attaching, false otherwise)")
if registry.IsRemote() {
_ = flags.MarkHidden("sig-proxy")
}
}
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
Command: startCommand,
})
startFlags(startCommand)
validate.AddLatestFlag(startCommand, &startOptions.Latest)
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
Command: containerStartCommand,
Parent: containerCmd,
})
startFlags(containerStartCommand)
validate.AddLatestFlag(containerStartCommand, &startOptions.Latest)
}
func validateStart(cmd *cobra.Command, args []string) error {
if len(args) == 0 && !startOptions.Latest {
return errors.New("start requires at least one argument")
}
if len(args) > 0 && startOptions.Latest {
return errors.Errorf("--latest and containers cannot be used together")
}
if len(args) > 1 && startOptions.Attach {
return errors.Errorf("you cannot start and attach multiple containers at once")
}
return nil
}
func start(cmd *cobra.Command, args []string) error {
var errs utils.OutputErrors
sigProxy := startOptions.SigProxy || startOptions.Attach
if cmd.Flag("sig-proxy").Changed {
sigProxy = startOptions.SigProxy
}
startOptions.SigProxy = sigProxy
if sigProxy && !startOptions.Attach {
return errors.Wrapf(define.ErrInvalidArg, "you cannot use sig-proxy without --attach")
}
if startOptions.Attach {
startOptions.Stdin = os.Stdin
startOptions.Stderr = os.Stderr
startOptions.Stdout = os.Stdout
}
responses, err := registry.ContainerEngine().ContainerStart(registry.GetContext(), args, startOptions)
if err != nil {
return err
}
for _, r := range responses {
if r.Err == nil {
if startOptions.Attach {
// Implement the exitcode when the only one container is enabled attach
registry.SetExitCode(r.ExitCode)
} else {
fmt.Println(r.RawInput)
}
} else {
errs = append(errs, r.Err)
}
}
return errs.PrintErrors()
}