Skip to content

Commit

Permalink
Update system connection add & remove
Browse files Browse the repository at this point in the history
Add new --farm flag to podman system connection add so that
a user can add a new connection to a farm immediately.
Update system connection remove such that when a connection is
removed, the connection is also removed from any farms that have it.
Add docs and tests for these changes.

Signed-off-by: Urvashi Mohnani <[email protected]>
  • Loading branch information
umohnani8 committed Aug 9, 2023
1 parent 310f971 commit bcebcad
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 0 deletions.
23 changes: 23 additions & 0 deletions cmd/podman/system/connection/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/ssh"
"github.com/containers/podman/v4/cmd/podman/common"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/cmd/podman/system"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -54,6 +55,7 @@ var (
Port int
UDSPath string
Default bool
Farm string
}{}
)

Expand All @@ -76,6 +78,11 @@ func init() {
flags.StringVar(&cOpts.UDSPath, socketPathFlagName, "", "path to podman socket on remote host. (default '/run/podman/podman.sock' or '/run/user/{uid}/podman/podman.sock)")
_ = addCmd.RegisterFlagCompletionFunc(socketPathFlagName, completion.AutocompleteDefault)

farmFlagName := "farm"
flags.StringVarP(&cOpts.Farm, farmFlagName, "f", "", "Add the new connection to the given farm")
_ = addCmd.RegisterFlagCompletionFunc(farmFlagName, common.AutoCompleteFarms)
_ = flags.MarkHidden(farmFlagName)

flags.BoolVarP(&cOpts.Default, "default", "d", false, "Set connection to be default")

registry.Commands = append(registry.Commands, registry.CliCommand{
Expand Down Expand Up @@ -104,6 +111,7 @@ func add(cmd *cobra.Command, args []string) error {
Name: args[0],
Socket: cOpts.UDSPath,
Default: cOpts.Default,
Farm: cOpts.Farm,
}
dest := args[1]
if match, err := regexp.MatchString("^[A-Za-z][A-Za-z0-9+.-]*://", dest); err != nil {
Expand Down Expand Up @@ -195,6 +203,21 @@ func add(cmd *cobra.Command, args []string) error {
} else {
cfg.Engine.ServiceDestinations[args[0]] = dst
}

if cOpts.Farm != "" {
if cfg.Farms.List == nil {
cfg.Farms.List = map[string][]string{
cOpts.Farm: {args[0]},
}
cfg.Farms.Default = cOpts.Farm
} else {
if val, ok := cfg.Farms.List[cOpts.Farm]; ok {
cfg.Farms.List[cOpts.Farm] = append(val, args[0])
} else {
cfg.Farms.List[cOpts.Farm] = []string{args[0]}
}
}
}
return cfg.Write()
}

Expand Down
18 changes: 18 additions & 0 deletions cmd/podman/system/connection/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/containers/podman/v4/cmd/podman/common"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/cmd/podman/system"
"github.com/containers/podman/v4/pkg/util"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -59,6 +60,13 @@ func rm(cmd *cobra.Command, args []string) error {
}
}
cfg.Engine.ActiveService = ""

// Clear all the connections in any existing farms
if cfg.Farms.List != nil {
for k := range cfg.Farms.List {
cfg.Farms.List[k] = []string{}
}
}
return cfg.Write()
}

Expand All @@ -74,5 +82,15 @@ func rm(cmd *cobra.Command, args []string) error {
cfg.Engine.ActiveService = ""
}

// If there are existing farm, remove the deleted connection that might be part of a farm
if cfg.Farms.List != nil {
for k, v := range cfg.Farms.List {
index := util.IndexOfStringInSlice(args[0], v)
if index > -1 {
cfg.Farms.List[k] = append(v[:index], v[index+1:]...)
}
}
}

return cfg.Write()
}
11 changes: 11 additions & 0 deletions pkg/util/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,17 @@ func StringMatchRegexSlice(s string, re []string) bool {
return false
}

// IndexOfStringInSlice returns the index if a string is in a slice, otherwise
// it returns -1 if the string is not found
func IndexOfStringInSlice(s string, sl []string) int {
for i := range sl {
if sl[i] == s {
return i
}
}
return -1
}

// ParseSignal parses and validates a signal name or number.
func ParseSignal(rawSignal string) (syscall.Signal, error) {
// Strip off leading dash, to allow -1 or -HUP
Expand Down
103 changes: 103 additions & 0 deletions test/e2e/system_connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,109 @@ var _ = Describe("podman system connection", func() {
))
})

It("add to new farm", func() {
cfg, err := config.ReadCustomConfig()
Expect(err).ShouldNot(HaveOccurred())
Expect(cfg.Farms.List).Should(BeEmpty())

cmd := []string{"system", "connection", "add",
"--default",
"--identity", "~/.ssh/id_rsa",
"--farm", "farm1",
"QA",
"ssh://[email protected]:2222/run/podman/podman.sock",
}
session := podmanTest.Podman(cmd)
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.Out.Contents()).Should(BeEmpty())

cfg, err = config.ReadCustomConfig()
Expect(err).ShouldNot(HaveOccurred())
Expect(cfg).Should(HaveActiveService("QA"))
Expect(cfg).Should(VerifyService(
"QA",
"ssh://[email protected]:2222/run/podman/podman.sock",
"~/.ssh/id_rsa",
))
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm1", []string{"QA"}))
})

It("add to existing farm", func() {
// create empty farm
cmd := []string{"farm", "create", "empty-farm"}
session := podmanTest.Podman(cmd)
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"empty-farm\" created"))

cfg, err := config.ReadCustomConfig()
Expect(err).ShouldNot(HaveOccurred())
Expect(cfg.Farms.List).Should(HaveKeyWithValue("empty-farm", []string{}))

cmd = []string{"system", "connection", "add",
"--default",
"--identity", "~/.ssh/id_rsa",
"--farm", "empty-farm",
"QA",
"ssh://[email protected]:2222/run/podman/podman.sock",
}
session = podmanTest.Podman(cmd)
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.Out.Contents()).Should(BeEmpty())

cfg, err = config.ReadCustomConfig()
Expect(err).ShouldNot(HaveOccurred())
Expect(cfg).Should(HaveActiveService("QA"))
Expect(cfg).Should(VerifyService(
"QA",
"ssh://[email protected]:2222/run/podman/podman.sock",
"~/.ssh/id_rsa",
))
Expect(cfg.Farms.List).Should(HaveKeyWithValue("empty-farm", []string{"QA"}))
})

It("removing connection should remove from farm also", func() {
cfg, err := config.ReadCustomConfig()
Expect(err).ShouldNot(HaveOccurred())
Expect(cfg.Farms.List).Should(BeEmpty())

cmd := []string{"system", "connection", "add",
"--default",
"--identity", "~/.ssh/id_rsa",
"--farm", "farm1",
"QA",
"ssh://[email protected]:2222/run/podman/podman.sock",
}
session := podmanTest.Podman(cmd)
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.Out.Contents()).Should(BeEmpty())

cfg, err = config.ReadCustomConfig()
Expect(err).ShouldNot(HaveOccurred())
Expect(cfg).Should(HaveActiveService("QA"))
Expect(cfg).Should(VerifyService(
"QA",
"ssh://[email protected]:2222/run/podman/podman.sock",
"~/.ssh/id_rsa",
))
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm1", []string{"QA"}))

// Remove the QA connection
session = podmanTest.Podman([]string{"system", "connection", "remove", "QA"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.Out.Contents()).Should(BeEmpty())

cfg, err = config.ReadCustomConfig()
Expect(err).ShouldNot(HaveOccurred())
Expect(cfg.Engine.ActiveService).Should(BeEmpty())
Expect(cfg.Engine.ServiceDestinations).Should(BeEmpty())
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm1", []string{}))
})

It("remove", func() {
session := podmanTest.Podman([]string{"system", "connection", "add",
"--default",
Expand Down

0 comments on commit bcebcad

Please sign in to comment.