diff options
Diffstat (limited to 'cmd/podman')
27 files changed, 258 insertions, 59 deletions
diff --git a/cmd/podman/containers/commit.go b/cmd/podman/containers/commit.go index fb6dccad4..77f74395e 100644 --- a/cmd/podman/containers/commit.go +++ b/cmd/podman/containers/commit.go @@ -3,7 +3,6 @@ package containers import ( "context" "fmt" - "io/ioutil" "os" "strings" @@ -107,7 +106,7 @@ func commit(cmd *cobra.Command, args []string) error { return err } if len(iidFile) > 0 { - if err = ioutil.WriteFile(iidFile, []byte(response.Id), 0644); err != nil { + if err = os.WriteFile(iidFile, []byte(response.Id), 0644); err != nil { return fmt.Errorf("failed to write image ID: %w", err) } } diff --git a/cmd/podman/containers/cp.go b/cmd/podman/containers/cp.go index 93477feb8..9e63169a0 100644 --- a/cmd/podman/containers/cp.go +++ b/cmd/podman/containers/cp.go @@ -3,7 +3,6 @@ package containers import ( "fmt" "io" - "io/ioutil" "os" "os/user" "path/filepath" @@ -379,7 +378,7 @@ func copyToContainer(container string, containerPath string, hostPath string) er // Copy from stdin to a temporary file *before* throwing it // over the wire. This allows for proper client-side error // reporting. - tmpFile, err := ioutil.TempFile("", "") + tmpFile, err := os.CreateTemp("", "") if err != nil { return err } diff --git a/cmd/podman/containers/kill.go b/cmd/podman/containers/kill.go index 86a7e3ff2..3c9bf6b71 100644 --- a/cmd/podman/containers/kill.go +++ b/cmd/podman/containers/kill.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -96,7 +96,7 @@ func kill(_ *cobra.Command, args []string) error { return errors.New("valid signals are 1 through 64") } for _, cidFile := range killCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/containers/pause.go b/cmd/podman/containers/pause.go index 591523cf9..ea5dd3a0c 100644 --- a/cmd/podman/containers/pause.go +++ b/cmd/podman/containers/pause.go @@ -3,7 +3,7 @@ package containers import ( "context" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -92,7 +92,7 @@ func pause(cmd *cobra.Command, args []string) error { ) for _, cidFile := range pauseCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/containers/restart.go b/cmd/podman/containers/restart.go index 0cc7901f9..db2759f0b 100644 --- a/cmd/podman/containers/restart.go +++ b/cmd/podman/containers/restart.go @@ -3,7 +3,7 @@ package containers import ( "context" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -105,7 +105,7 @@ func restart(cmd *cobra.Command, args []string) error { } for _, cidFile := range restartCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/containers/rm.go b/cmd/podman/containers/rm.go index 44d03e9de..da5c24ab8 100644 --- a/cmd/podman/containers/rm.go +++ b/cmd/podman/containers/rm.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -108,7 +108,7 @@ func rm(cmd *cobra.Command, args []string) error { rmOptions.Timeout = &stopTimeout } for _, cidFile := range rmCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/containers/stop.go b/cmd/podman/containers/stop.go index 412c513e1..a1e3a0c46 100644 --- a/cmd/podman/containers/stop.go +++ b/cmd/podman/containers/stop.go @@ -3,7 +3,7 @@ package containers import ( "context" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -105,7 +105,7 @@ func stop(cmd *cobra.Command, args []string) error { stopOptions.Timeout = &stopTimeout } for _, cidFile := range stopCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/containers/unpause.go b/cmd/podman/containers/unpause.go index 988964266..fea05ee22 100644 --- a/cmd/podman/containers/unpause.go +++ b/cmd/podman/containers/unpause.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/cgroups" @@ -99,7 +99,7 @@ func unpause(cmd *cobra.Command, args []string) error { } for _, cidFile := range unpauseCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/generate/spec.go b/cmd/podman/generate/spec.go index bf451ebc5..0c3d7884c 100644 --- a/cmd/podman/generate/spec.go +++ b/cmd/podman/generate/spec.go @@ -2,7 +2,7 @@ package generate import ( "fmt" - "io/ioutil" + "os" "github.com/containers/common/pkg/completion" "github.com/containers/podman/v4/cmd/podman/common" @@ -59,7 +59,7 @@ func spec(cmd *cobra.Command, args []string) error { // if we are looking to print the output, do not mess it up by printing the path // if we are using -v the user probably expects to pipe the output somewhere else if len(opts.FileName) > 0 { - err = ioutil.WriteFile(opts.FileName, report.Data, 0644) + err = os.WriteFile(opts.FileName, report.Data, 0644) if err != nil { return err } diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go index 2b24c1cff..a4d6614e2 100644 --- a/cmd/podman/images/build.go +++ b/cmd/podman/images/build.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -635,7 +634,7 @@ func getDecryptConfig(decryptionKeys []string) (*encconfig.DecryptConfig, error) func parseDockerignore(ignoreFile string) ([]string, error) { excludes := []string{} - ignore, err := ioutil.ReadFile(ignoreFile) + ignore, err := os.ReadFile(ignoreFile) if err != nil { return excludes, err } diff --git a/cmd/podman/images/import.go b/cmd/podman/images/import.go index 8343a0bda..7532bf7a9 100644 --- a/cmd/podman/images/import.go +++ b/cmd/podman/images/import.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "strings" @@ -116,7 +115,7 @@ func importCon(cmd *cobra.Command, args []string) error { } if source == "-" { - outFile, err := ioutil.TempFile("", "podman") + outFile, err := os.CreateTemp("", "podman") if err != nil { return fmt.Errorf("creating file %v", err) } diff --git a/cmd/podman/images/load.go b/cmd/podman/images/load.go index 367b628c7..4aae5217d 100644 --- a/cmd/podman/images/load.go +++ b/cmd/podman/images/load.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "strings" @@ -93,7 +92,7 @@ func load(cmd *cobra.Command, args []string) error { if term.IsTerminal(int(os.Stdin.Fd())) { return errors.New("cannot read from terminal, use command-line redirection or the --input flag") } - outFile, err := ioutil.TempFile(util.Tmpdir(), "podman") + outFile, err := os.CreateTemp(util.Tmpdir(), "podman") if err != nil { return fmt.Errorf("creating file %v", err) } diff --git a/cmd/podman/images/save.go b/cmd/podman/images/save.go index ecff0f841..426684d49 100644 --- a/cmd/podman/images/save.go +++ b/cmd/podman/images/save.go @@ -96,6 +96,11 @@ func saveFlags(cmd *cobra.Command) { flags.BoolVarP(&saveOpts.Quiet, "quiet", "q", false, "Suppress the output") flags.BoolVarP(&saveOpts.MultiImageArchive, "multi-image-archive", "m", containerConfig.Engine.MultiImageArchive, "Interpret additional arguments as images not tags and create a multi-image-archive (only for docker-archive)") + + if !registry.IsRemote() { + flags.StringVar(&saveOpts.SignaturePolicy, "signature-policy", "", "Path to a signature-policy file") + _ = flags.MarkHidden("signature-policy") + } } func save(cmd *cobra.Command, args []string) (finalErr error) { diff --git a/cmd/podman/images/utils_linux.go b/cmd/podman/images/utils_linux.go index 935a45667..a2f471a48 100644 --- a/cmd/podman/images/utils_linux.go +++ b/cmd/podman/images/utils_linux.go @@ -3,7 +3,6 @@ package images import ( "fmt" "io" - "io/ioutil" "os" "path/filepath" @@ -16,7 +15,7 @@ import ( // the caller should use the returned function to clean up the pipeDir func setupPipe() (string, func() <-chan error, error) { errc := make(chan error) - pipeDir, err := ioutil.TempDir(os.TempDir(), "pipeDir") + pipeDir, err := os.MkdirTemp(os.TempDir(), "pipeDir") if err != nil { return "", nil, err } diff --git a/cmd/podman/kube/generate.go b/cmd/podman/kube/generate.go index ee2ea51ae..30b06b0c5 100644 --- a/cmd/podman/kube/generate.go +++ b/cmd/podman/kube/generate.go @@ -3,7 +3,6 @@ package kube import ( "fmt" "io" - "io/ioutil" "os" "github.com/containers/common/pkg/completion" @@ -77,7 +76,7 @@ func generateKube(cmd *cobra.Command, args []string) error { if err != nil { return err } - content, err := ioutil.ReadAll(report.Reader) + content, err := io.ReadAll(report.Reader) if err != nil { return err } @@ -89,7 +88,7 @@ func generateKube(cmd *cobra.Command, args []string) error { if _, err := os.Stat(generateFile); err == nil { return fmt.Errorf("cannot write to %q; file exists", generateFile) } - if err := ioutil.WriteFile(generateFile, content, 0644); err != nil { + if err := os.WriteFile(generateFile, content, 0644); err != nil { return fmt.Errorf("cannot write to %q: %w", generateFile, err) } return nil diff --git a/cmd/podman/kube/play.go b/cmd/podman/kube/play.go index c846ec32c..1163a6ff6 100644 --- a/cmd/podman/kube/play.go +++ b/cmd/podman/kube/play.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "net/http" "os" @@ -284,7 +283,7 @@ func readerFromArg(fileName string) (*bytes.Reader, error) { } defer response.Body.Close() - data, err := ioutil.ReadAll(response.Body) + data, err := io.ReadAll(response.Body) if err != nil { return nil, err } diff --git a/cmd/podman/manifest/push.go b/cmd/podman/manifest/push.go index c8893ff2e..2b4c570a5 100644 --- a/cmd/podman/manifest/push.go +++ b/cmd/podman/manifest/push.go @@ -3,7 +3,6 @@ package manifest import ( "errors" "fmt" - "io/ioutil" "os" "github.com/containers/common/pkg/auth" @@ -149,7 +148,7 @@ func push(cmd *cobra.Command, args []string) error { return err } if manifestPushOpts.DigestFile != "" { - if err := ioutil.WriteFile(manifestPushOpts.DigestFile, []byte(digest), 0644); err != nil { + if err := os.WriteFile(manifestPushOpts.DigestFile, []byte(digest), 0644); err != nil { return err } } diff --git a/cmd/podman/parse/net_test.go b/cmd/podman/parse/net_test.go index a11edc2ca..88bfaa894 100644 --- a/cmd/podman/parse/net_test.go +++ b/cmd/podman/parse/net_test.go @@ -3,7 +3,6 @@ package parse import ( - "io/ioutil" "os" "testing" @@ -15,7 +14,7 @@ var ( ) func createTmpFile(content []byte) (string, error) { - tmpfile, err := ioutil.TempFile(os.TempDir(), "unittest") + tmpfile, err := os.CreateTemp(os.TempDir(), "unittest") if err != nil { return "", err } diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go index 1f8152f32..fc2e07894 100644 --- a/cmd/podman/pods/create.go +++ b/cmd/podman/pods/create.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "os" "runtime" "sort" @@ -300,7 +299,7 @@ func create(cmd *cobra.Command, args []string) error { } if len(podIDFile) > 0 { - if err = ioutil.WriteFile(podIDFile, []byte(response.Id), 0644); err != nil { + if err = os.WriteFile(podIDFile, []byte(response.Id), 0644); err != nil { return fmt.Errorf("failed to write pod ID to file: %w", err) } } diff --git a/cmd/podman/registry/remote.go b/cmd/podman/registry/remote.go index afe32e0b9..02aa31c58 100644 --- a/cmd/podman/registry/remote.go +++ b/cmd/podman/registry/remote.go @@ -32,6 +32,8 @@ func IsRemote() bool { fs.BoolVarP(&remoteFromCLI.Value, "remote", "r", remote, "") connectionFlagName := "connection" fs.StringP(connectionFlagName, "c", "", "") + contextFlagName := "context" + fs.String(contextFlagName, "", "") hostFlagName := "host" fs.StringP(hostFlagName, "H", "", "") urlFlagName := "url" @@ -46,7 +48,7 @@ func IsRemote() bool { } _ = fs.Parse(os.Args[start:]) // --connection or --url implies --remote - remoteFromCLI.Value = remoteFromCLI.Value || fs.Changed(connectionFlagName) || fs.Changed(urlFlagName) || fs.Changed(hostFlagName) + remoteFromCLI.Value = remoteFromCLI.Value || fs.Changed(connectionFlagName) || fs.Changed(urlFlagName) || fs.Changed(hostFlagName) || fs.Changed(contextFlagName) }) return podmanOptions.EngineMode == entities.TunnelMode || remoteFromCLI.Value } diff --git a/cmd/podman/root.go b/cmd/podman/root.go index 2e00777a4..9e3ff48aa 100644 --- a/cmd/podman/root.go +++ b/cmd/podman/root.go @@ -174,11 +174,7 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error { } } - // --connection is not as "special" as --remote so we can wait and process it here - conn := cmd.Root().LocalFlags().Lookup("connection") - if conn != nil && conn.Changed { - cfg.Engine.ActiveService = conn.Value.String() - + setupConnection := func() error { var err error cfg.URI, cfg.Identity, err = cfg.ActiveDestination() if err != nil { @@ -192,6 +188,29 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error { if err := cmd.Root().LocalFlags().Set("identity", cfg.Identity); err != nil { return fmt.Errorf("failed to override --identity flag: %w", err) } + return nil + } + + // --connection is not as "special" as --remote so we can wait and process it here + contextConn := cmd.Root().LocalFlags().Lookup("context") + conn := cmd.Root().LocalFlags().Lookup("connection") + if conn != nil && conn.Changed { + if contextConn != nil && contextConn.Changed { + return fmt.Errorf("use of --connection and --context at the same time is not allowed") + } + cfg.Engine.ActiveService = conn.Value.String() + if err := setupConnection(); err != nil { + return err + } + } + if contextConn != nil && contextConn.Changed { + service := contextConn.Value.String() + if service != "default" { + cfg.Engine.ActiveService = service + if err := setupConnection(); err != nil { + return err + } + } } // Special case if command is hidden completion command ("__complete","__completeNoDesc") @@ -232,10 +251,6 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error { } } - context := cmd.Root().LocalFlags().Lookup("context") - if context.Value.String() != "default" { - return errors.New("podman does not support swarm, the only --context value allowed is \"default\"") - } if !registry.IsRemote() { if cmd.Flag("cpu-profile").Changed { f, err := os.Create(cfg.CPUProfile) @@ -362,7 +377,7 @@ func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) { _ = cmd.RegisterFlagCompletionFunc(sshFlagName, common.AutocompleteSSH) connectionFlagName := "connection" - lFlags.StringVarP(&opts.Engine.ActiveService, connectionFlagName, "c", srv, "Connection to use for remote Podman service") + lFlags.StringP(connectionFlagName, "c", srv, "Connection to use for remote Podman service") _ = cmd.RegisterFlagCompletionFunc(connectionFlagName, common.AutocompleteSystemConnections) urlFlagName := "url" diff --git a/cmd/podman/secrets/create.go b/cmd/podman/secrets/create.go index 01775f563..293da2103 100644 --- a/cmd/podman/secrets/create.go +++ b/cmd/podman/secrets/create.go @@ -10,6 +10,7 @@ import ( "github.com/containers/common/pkg/completion" "github.com/containers/podman/v4/cmd/podman/common" + "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/spf13/cobra" @@ -31,6 +32,7 @@ var ( var ( createOpts = entities.SecretCreateOptions{} env = false + labels []string ) func init() { @@ -38,21 +40,24 @@ func init() { Command: createCmd, Parent: secretCmd, }) + cfg := registry.PodmanConfig() flags := createCmd.Flags() driverFlagName := "driver" - optsFlagName := "driver-opts" - - cfg := registry.PodmanConfig() - flags.StringVarP(&createOpts.Driver, driverFlagName, "d", cfg.Secrets.Driver, "Specify secret driver") - flags.StringToStringVar(&createOpts.DriverOpts, optsFlagName, cfg.Secrets.Opts, "Specify driver specific options") _ = createCmd.RegisterFlagCompletionFunc(driverFlagName, completion.AutocompleteNone) + + optsFlagName := "driver-opts" + flags.StringToStringVar(&createOpts.DriverOpts, optsFlagName, cfg.Secrets.Opts, "Specify driver specific options") _ = createCmd.RegisterFlagCompletionFunc(optsFlagName, completion.AutocompleteNone) envFlagName := "env" flags.BoolVar(&env, envFlagName, false, "Read secret data from environment variable") + + labelFlagName := "label" + flags.StringArrayVarP(&labels, labelFlagName, "l", nil, "Specify labels on the secret") + _ = createCmd.RegisterFlagCompletionFunc(labelFlagName, completion.AutocompleteNone) } func create(cmd *cobra.Command, args []string) error { @@ -87,6 +92,11 @@ func create(cmd *cobra.Command, args []string) error { reader = file } + createOpts.Labels, err = parse.GetAllLabels([]string{}, labels) + if err != nil { + return fmt.Errorf("unable to process labels: %w", err) + } + report, err := registry.ContainerEngine().SecretCreate(context.Background(), name, reader, createOpts) if err != nil { return err diff --git a/cmd/podman/system/connection/add.go b/cmd/podman/system/connection/add.go index f3b61b254..2730ebfb7 100644 --- a/cmd/podman/system/connection/add.go +++ b/cmd/podman/system/connection/add.go @@ -6,6 +6,7 @@ import ( "net/url" "os" "regexp" + "strings" "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/config" @@ -37,6 +38,17 @@ var ( `, } + createCmd = &cobra.Command{ + Use: "create [options] NAME DESTINATION", + Args: cobra.ExactArgs(1), + Short: addCmd.Short, + Long: addCmd.Long, + RunE: create, + ValidArgsFunction: completion.AutocompleteNone, + } + + dockerPath string + cOpts = struct { Identity string Port int @@ -50,7 +62,6 @@ func init() { Command: addCmd, Parent: system.ConnectionCmd, }) - flags := addCmd.Flags() portFlagName := "port" @@ -66,6 +77,21 @@ func init() { _ = addCmd.RegisterFlagCompletionFunc(socketPathFlagName, completion.AutocompleteDefault) flags.BoolVarP(&cOpts.Default, "default", "d", false, "Set connection to be default") + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: createCmd, + Parent: system.ContextCmd, + }) + + flags = createCmd.Flags() + dockerFlagName := "docker" + flags.StringVar(&dockerPath, dockerFlagName, "", "Description of the context") + + _ = createCmd.RegisterFlagCompletionFunc(dockerFlagName, completion.AutocompleteNone) + flags.String("description", "", "Ignored. Just for script compatibility") + flags.String("from", "", "Ignored. Just for script compatibility") + flags.String("kubernetes", "", "Ignored. Just for script compatibility") + flags.String("default-stack-orchestrator", "", "Ignored. Just for script compatibility") } func add(cmd *cobra.Command, args []string) error { @@ -171,3 +197,59 @@ func add(cmd *cobra.Command, args []string) error { } return cfg.Write() } + +func create(cmd *cobra.Command, args []string) error { + dest, err := translateDest(dockerPath) + if err != nil { + return err + } + if match, err := regexp.Match("^[A-Za-z][A-Za-z0-9+.-]*://", []byte(dest)); err != nil { + return fmt.Errorf("invalid destination: %w", err) + } else if !match { + dest = "ssh://" + dest + } + + uri, err := url.Parse(dest) + if err != nil { + return err + } + + cfg, err := config.ReadCustomConfig() + if err != nil { + return err + } + + dst := config.Destination{ + URI: uri.String(), + } + + if cfg.Engine.ServiceDestinations == nil { + cfg.Engine.ServiceDestinations = map[string]config.Destination{ + args[0]: dst, + } + cfg.Engine.ActiveService = args[0] + } else { + cfg.Engine.ServiceDestinations[args[0]] = dst + } + return cfg.Write() +} + +func translateDest(path string) (string, error) { + if path == "" { + return "", nil + } + split := strings.SplitN(path, "=", 2) + if len(split) == 1 { + return split[0], nil + } + if split[0] != "host" { + return "", fmt.Errorf("\"host\" is requited for --docker option") + } + // "host=tcp://myserver:2376,ca=~/ca-file,cert=~/cert-file,key=~/key-file" + vals := strings.Split(split[1], ",") + if len(vals) > 1 { + return "", fmt.Errorf("--docker additional options %q not supported", strings.Join(vals[1:], ",")) + } + // for now we ignore other fields specified on command line + return vals[0], nil +} diff --git a/cmd/podman/system/connection/default.go b/cmd/podman/system/connection/default.go index 81866df55..8d1709e9f 100644 --- a/cmd/podman/system/connection/default.go +++ b/cmd/podman/system/connection/default.go @@ -21,10 +21,24 @@ var ( RunE: defaultRunE, Example: `podman system connection default testing`, } + + useCmd = &cobra.Command{ + Use: "use NAME", + Args: cobra.ExactArgs(1), + Short: dfltCmd.Short, + Long: dfltCmd.Long, + ValidArgsFunction: dfltCmd.ValidArgsFunction, + RunE: dfltCmd.RunE, + Example: `podman context use testing`, + } ) func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: useCmd, + Parent: system.ContextCmd, + }) + registry.Commands = append(registry.Commands, registry.CliCommand{ Command: dfltCmd, Parent: system.ConnectionCmd, }) diff --git a/cmd/podman/system/connection/list.go b/cmd/podman/system/connection/list.go index 2c5f6a310..190a68d52 100644 --- a/cmd/podman/system/connection/list.go +++ b/cmd/podman/system/connection/list.go @@ -8,6 +8,7 @@ import ( "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/config" "github.com/containers/common/pkg/report" + "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/cmd/podman/common" "github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/cmd/podman/system" @@ -29,16 +30,36 @@ var ( RunE: list, TraverseChildren: false, } + inspectCmd = &cobra.Command{ + Use: "inspect [options] [CONTEXT] [CONTEXT...]", + Short: "Inspect destination for a Podman service(s)", + ValidArgsFunction: completion.AutocompleteNone, + RunE: inspect, + } ) func init() { + initFlags := func(cmd *cobra.Command) { + cmd.Flags().StringP("format", "f", "", "Custom Go template for printing connections") + _ = cmd.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(&namedDestination{})) + cmd.Flags().BoolP("quiet", "q", false, "Custom Go template for printing connections") + } + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: listCmd, + Parent: system.ContextCmd, + }) registry.Commands = append(registry.Commands, registry.CliCommand{ Command: listCmd, Parent: system.ConnectionCmd, }) + initFlags(listCmd) - listCmd.Flags().String("format", "", "Custom Go template for printing connections") - _ = listCmd.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(&namedDestination{})) + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: inspectCmd, + Parent: system.ContextCmd, + }) + initFlags(inspectCmd) } type namedDestination struct { @@ -48,13 +69,34 @@ type namedDestination struct { } func list(cmd *cobra.Command, _ []string) error { + return inspect(cmd, nil) +} + +func inspect(cmd *cobra.Command, args []string) error { cfg, err := config.ReadCustomConfig() if err != nil { return err } + format := cmd.Flag("format").Value.String() + if format == "" && args != nil { + format = "json" + } + + quiet, err := cmd.Flags().GetBool("quiet") + if err != nil { + return err + } rows := make([]namedDestination, 0) for k, v := range cfg.Engine.ServiceDestinations { + if args != nil && !util.StringInSlice(k, args) { + continue + } + + if quiet { + fmt.Println(k) + continue + } def := false if k == cfg.Engine.ActiveService { def = true @@ -71,6 +113,10 @@ func list(cmd *cobra.Command, _ []string) error { rows = append(rows, r) } + if quiet { + return nil + } + sort.Slice(rows, func(i, j int) bool { return rows[i].Name < rows[j].Name }) @@ -78,7 +124,7 @@ func list(cmd *cobra.Command, _ []string) error { rpt := report.New(os.Stdout, cmd.Name()) defer rpt.Flush() - if report.IsJSON(cmd.Flag("format").Value.String()) { + if report.IsJSON(format) { buf, err := registry.JSONLibrary().MarshalIndent(rows, "", " ") if err == nil { fmt.Println(string(buf)) @@ -86,8 +132,8 @@ func list(cmd *cobra.Command, _ []string) error { return err } - if cmd.Flag("format").Changed { - rpt, err = rpt.Parse(report.OriginUser, cmd.Flag("format").Value.String()) + if format != "" { + rpt, err = rpt.Parse(report.OriginUser, format) } else { rpt, err = rpt.Parse(report.OriginPodman, "{{range .}}{{.Name}}\t{{.URI}}\t{{.Identity}}\t{{.Default}}\n{{end -}}") diff --git a/cmd/podman/system/connection/remove.go b/cmd/podman/system/connection/remove.go index 29bf98c43..5ff0000d6 100644 --- a/cmd/podman/system/connection/remove.go +++ b/cmd/podman/system/connection/remove.go @@ -31,11 +31,19 @@ var ( func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ Command: rmCmd, + Parent: system.ContextCmd, + }) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: rmCmd, Parent: system.ConnectionCmd, }) flags := rmCmd.Flags() flags.BoolVarP(&rmOpts.All, "all", "a", false, "Remove all connections") + + flags.BoolP("force", "f", false, "Ignored: for Docker compatibility") + _ = flags.MarkHidden("force") } func rm(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/system/context.go b/cmd/podman/system/context.go new file mode 100644 index 000000000..926e4a443 --- /dev/null +++ b/cmd/podman/system/context.go @@ -0,0 +1,28 @@ +package system + +import ( + "github.com/containers/podman/v4/cmd/podman/registry" + "github.com/containers/podman/v4/cmd/podman/validate" + "github.com/spf13/cobra" +) + +var ( + // ContextCmd skips creating engines (PersistentPreRunE/PersistentPostRunE are No-Op's) since + // sub-commands will obtain connection information to said engines + ContextCmd = &cobra.Command{ + Use: "context", + Short: "Manage remote API service destinations", + Long: `Manage remote API service destination information in podman configuration`, + PersistentPreRunE: validate.NoOp, + RunE: validate.SubCommandExists, + PersistentPostRunE: validate.NoOp, + Hidden: true, + TraverseChildren: false, + } +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: ContextCmd, + }) +} |