summaryrefslogtreecommitdiff
path: root/cmd/podman/system
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2022-09-09 09:06:18 -0400
committerDaniel J Walsh <dwalsh@redhat.com>2022-09-15 08:17:15 -0400
commit3508bd22fe355630453d497d905e480974a84b96 (patch)
tree42874103bb7d0329796598fc251e6e8f4fac1bdc /cmd/podman/system
parent4fc18d07a6b206476421ed134f0eeec1221936c2 (diff)
downloadpodman-3508bd22fe355630453d497d905e480974a84b96.tar.gz
podman-3508bd22fe355630453d497d905e480974a84b96.tar.bz2
podman-3508bd22fe355630453d497d905e480974a84b96.zip
Add support for podman context as alias to podman system connection
Alias podman --context -> podman --connection podman context use -> podman system connection default podman context rm -> podman system connection rm podman context create -> podman system connection add podman context ls ->podman system connection ls podman context inspect ->podman system connection ls --json (For specified connections) Podman context is a hidden command, but can be used for existing scripts that assume Docker under the covers. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Diffstat (limited to 'cmd/podman/system')
-rw-r--r--cmd/podman/system/connection/add.go84
-rw-r--r--cmd/podman/system/connection/default.go14
-rw-r--r--cmd/podman/system/connection/list.go56
-rw-r--r--cmd/podman/system/connection/remove.go8
-rw-r--r--cmd/podman/system/context.go28
5 files changed, 184 insertions, 6 deletions
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,
+ })
+}