aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/system/connection/add.go77
-rw-r--r--cmd/podman/system/connection/list.go5
-rw-r--r--docs/source/markdown/podman-system-connection-add.1.md6
-rw-r--r--test/e2e/system_connection_test.go64
4 files changed, 131 insertions, 21 deletions
diff --git a/cmd/podman/system/connection/add.go b/cmd/podman/system/connection/add.go
index ecfeb6608..912193d0b 100644
--- a/cmd/podman/system/connection/add.go
+++ b/cmd/podman/system/connection/add.go
@@ -23,22 +23,24 @@ import (
"golang.org/x/crypto/ssh/agent"
)
-const schemaPattern = "^[A-Za-z][A-Za-z0-9+.-]*:"
-
var (
addCmd = &cobra.Command{
Use: "add [options] NAME DESTINATION",
Args: cobra.ExactArgs(2),
Short: "Record destination for the Podman service",
Long: `Add destination to podman configuration.
- "destination" is of the form [user@]hostname or
- an URI of the form ssh://[user@]hostname[:port]
+ "destination" is one of the form:
+ [user@]hostname (will default to ssh)
+ ssh://[user@]hostname[:port][/path] (will obtain socket path from service, if not given.)
+ tcp://hostname:port (not secured)
+ unix://path (absolute path required)
`,
RunE: add,
ValidArgsFunction: completion.AutocompleteNone,
Example: `podman system connection add laptop server.fubar.com
podman system connection add --identity ~/.ssh/dev_rsa testing ssh://root@server.fubar.com:2222
podman system connection add --identity ~/.ssh/dev_rsa --port 22 production root@server.fubar.com
+ podman system connection add debug tcp://localhost:8080
`,
}
@@ -74,9 +76,9 @@ func init() {
}
func add(cmd *cobra.Command, args []string) error {
- // Default to ssh: schema if none given
+ // Default to ssh schema if none given
dest := args[1]
- if match, err := regexp.Match(schemaPattern, []byte(dest)); err != nil {
+ if match, err := regexp.Match("^[A-Za-z][A-Za-z0-9+.-]*://", []byte(dest)); err != nil {
return errors.Wrapf(err, "invalid destination")
} else if !match {
dest = "ssh://" + dest
@@ -87,28 +89,63 @@ func add(cmd *cobra.Command, args []string) error {
return err
}
- if uri.User.Username() == "" {
- if uri.User, err = getUserInfo(uri); err != nil {
- return err
- }
- }
-
if cmd.Flags().Changed("socket-path") {
uri.Path = cmd.Flag("socket-path").Value.String()
}
- if cmd.Flags().Changed("port") {
- uri.Host = net.JoinHostPort(uri.Hostname(), cmd.Flag("port").Value.String())
- }
+ switch uri.Scheme {
+ case "ssh":
+ if uri.User.Username() == "" {
+ if uri.User, err = getUserInfo(uri); err != nil {
+ return err
+ }
+ }
- if uri.Port() == "" {
- uri.Host = net.JoinHostPort(uri.Hostname(), cmd.Flag("port").DefValue)
- }
+ if cmd.Flags().Changed("port") {
+ uri.Host = net.JoinHostPort(uri.Hostname(), cmd.Flag("port").Value.String())
+ }
- if uri.Path == "" || uri.Path == "/" {
- if uri.Path, err = getUDS(cmd, uri); err != nil {
+ if uri.Port() == "" {
+ uri.Host = net.JoinHostPort(uri.Hostname(), cmd.Flag("port").DefValue)
+ }
+
+ if uri.Path == "" || uri.Path == "/" {
+ if uri.Path, err = getUDS(cmd, uri); err != nil {
+ return err
+ }
+ }
+ case "unix":
+ if cmd.Flags().Changed("identity") {
+ return errors.New("--identity option not supported for unix scheme")
+ }
+
+ if cmd.Flags().Changed("socket-path") {
+ uri.Path = cmd.Flag("socket-path").Value.String()
+ }
+
+ info, err := os.Stat(uri.Path)
+ switch {
+ case errors.Is(err, os.ErrNotExist):
+ logrus.Warnf("%q does not exists", uri.Path)
+ case errors.Is(err, os.ErrPermission):
+ logrus.Warnf("You do not have permission to read %q", uri.Path)
+ case err != nil:
return err
+ case info.Mode()&os.ModeSocket == 0:
+ return fmt.Errorf("%q exists and is not a unix domain socket", uri.Path)
+ }
+ case "tcp":
+ if cmd.Flags().Changed("socket-path") {
+ return errors.New("--socket-path option not supported for tcp scheme")
+ }
+ if cmd.Flags().Changed("identity") {
+ return errors.New("--identity option not supported for tcp scheme")
+ }
+ if uri.Port() == "" {
+ return errors.New("tcp scheme requires a port either via --port or in destination URL")
}
+ default:
+ logrus.Warnf("%q unknown scheme, no validation provided", uri.Scheme)
}
cfg, err := config.ReadCustomConfig()
diff --git a/cmd/podman/system/connection/list.go b/cmd/podman/system/connection/list.go
index 2f74215c1..de85ce3fa 100644
--- a/cmd/podman/system/connection/list.go
+++ b/cmd/podman/system/connection/list.go
@@ -3,6 +3,7 @@ package connection
import (
"fmt"
"os"
+ "sort"
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/config"
@@ -77,6 +78,10 @@ func list(cmd *cobra.Command, _ []string) error {
rows = append(rows, r)
}
+ sort.Slice(rows, func(i, j int) bool {
+ return rows[i].Name < rows[j].Name
+ })
+
format := "{{.Name}}\t{{.Identity}}\t{{.URI}}\n"
switch {
case report.IsJSON(cmd.Flag("format").Value.String()):
diff --git a/docs/source/markdown/podman-system-connection-add.1.md b/docs/source/markdown/podman-system-connection-add.1.md
index 32c16d6a1..ad9acb4d8 100644
--- a/docs/source/markdown/podman-system-connection-add.1.md
+++ b/docs/source/markdown/podman-system-connection-add.1.md
@@ -10,6 +10,8 @@ podman\-system\-connection\-add - Record destination for the Podman service
Record ssh destination for remote podman service(s). The ssh destination is given as one of:
- [user@]hostname[:port]
- ssh://[user@]hostname[:port]
+ - unix://path
+ - tcp://hostname:port
The user will be prompted for the remote ssh login password or key file pass phrase as required. The `ssh-agent` is supported if it is running.
@@ -38,6 +40,10 @@ Path to the Podman service unix domain socket on the ssh destination host
$ podman system connection add QA podman.example.com
$ podman system connection add --identity ~/.ssh/dev_rsa production ssh://root@server.example.com:2222
+
+$ podman system connection add unix:///run/podman/podman.sock
+
+$ podman system connection add tcp://localhost:8080
```
## SEE ALSO
podman-system(1) , podman-system-connection(1) , containers.conf(5)
diff --git a/test/e2e/system_connection_test.go b/test/e2e/system_connection_test.go
index 7c922a648..21398887a 100644
--- a/test/e2e/system_connection_test.go
+++ b/test/e2e/system_connection_test.go
@@ -53,7 +53,7 @@ var _ = Describe("podman system connection", func() {
GinkgoWriter.Write([]byte(timedResult))
})
- It("add", func() {
+ It("add ssh://", func() {
cmd := []string{"system", "connection", "add",
"--default",
"--identity", "~/.ssh/id_rsa",
@@ -94,6 +94,68 @@ var _ = Describe("podman system connection", func() {
))
})
+ It("add UDS", func() {
+ cmd := []string{"system", "connection", "add",
+ "QA-UDS",
+ "unix:///run/podman/podman.sock",
+ }
+ session := podmanTest.Podman(cmd)
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.Out).Should(Say(""))
+
+ cfg, err := config.ReadCustomConfig()
+ Expect(err).ShouldNot(HaveOccurred())
+ Expect(cfg.Engine.ActiveService).To(Equal("QA-UDS"))
+ Expect(cfg.Engine.ServiceDestinations["QA-UDS"]).To(Equal(
+ config.Destination{
+ URI: "unix:///run/podman/podman.sock",
+ Identity: "",
+ },
+ ))
+
+ cmd = []string{"system", "connection", "add",
+ "QA-UDS1",
+ "--socket-path", "/run/user/podman/podman.sock",
+ "unix:///run/podman/podman.sock",
+ }
+ session = podmanTest.Podman(cmd)
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.Out).Should(Say(""))
+
+ cfg, err = config.ReadCustomConfig()
+ Expect(err).ShouldNot(HaveOccurred())
+ Expect(cfg.Engine.ActiveService).To(Equal("QA-UDS"))
+ Expect(cfg.Engine.ServiceDestinations["QA-UDS1"]).To(Equal(
+ config.Destination{
+ URI: "unix:///run/user/podman/podman.sock",
+ Identity: "",
+ },
+ ))
+ })
+
+ It("add tcp", func() {
+ cmd := []string{"system", "connection", "add",
+ "QA-TCP",
+ "tcp://localhost:8080",
+ }
+ session := podmanTest.Podman(cmd)
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.Out).Should(Say(""))
+
+ cfg, err := config.ReadCustomConfig()
+ Expect(err).ShouldNot(HaveOccurred())
+ Expect(cfg.Engine.ActiveService).To(Equal("QA-TCP"))
+ Expect(cfg.Engine.ServiceDestinations["QA-TCP"]).To(Equal(
+ config.Destination{
+ URI: "tcp://localhost:8080",
+ Identity: "",
+ },
+ ))
+ })
+
It("remove", func() {
cmd := []string{"system", "connection", "add",
"--default",