Skip to content

Commit

Permalink
rework system connection and farm storage
Browse files Browse the repository at this point in the history
We now no longer write containers.conf, instead system connections and
farms are written to a new file called podman-connections.conf.

This is a major rework and I had to change a lot of things to get this
to compile again with my c/common changes.

It is a breaking change for users as connections/farms added before this
commit can now no longer be removed or modified directly. However because
the logic keeps reading from containers.conf the old connections can
still be used to connect to a remote host.

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
  • Loading branch information
Luap99 committed Jan 31, 2024
1 parent 1698fa0 commit 74454bf
Show file tree
Hide file tree
Showing 48 changed files with 1,082 additions and 1,080 deletions.
17 changes: 9 additions & 8 deletions cmd/podman/common/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -837,15 +837,15 @@ func AutoCompleteFarms(cmd *cobra.Command, args []string, toComplete string) ([]
if !validCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
suggestions := []string{}
cfg, err := config.ReadCustomConfig()
farms, err := podmanConfig.ContainersConfDefaultsRO.GetAllFarms()
if err != nil {
cobra.CompErrorln(err.Error())
return nil, cobra.ShellCompDirectiveNoFileComp
}

for k := range cfg.Farms.List {
suggestions = append(suggestions, k)
suggestions := make([]string, 0, len(farms))
for _, farm := range farms {
suggestions = append(suggestions, farm.Name)
}

return suggestions, cobra.ShellCompDirectiveNoFileComp
Expand All @@ -856,16 +856,17 @@ func AutocompleteSystemConnections(cmd *cobra.Command, args []string, toComplete
if !validCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp
}
suggestions := []string{}
cfg, err := config.ReadCustomConfig()

cons, err := podmanConfig.ContainersConfDefaultsRO.GetAllConnections()
if err != nil {
cobra.CompErrorln(err.Error())
return nil, cobra.ShellCompDirectiveNoFileComp
}

for k, v := range cfg.Engine.ServiceDestinations {
suggestions := make([]string, 0, len(cons))
for _, con := range cons {
// the URI will be show as description in shells like zsh
suggestions = append(suggestions, k+"\t"+v.URI)
suggestions = append(suggestions, con.Name+"\t"+con.URI)
}

return suggestions, cobra.ShellCompDirectiveNoFileComp
Expand Down
16 changes: 3 additions & 13 deletions cmd/podman/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"strings"
"text/template"

"github.com/containers/common/pkg/config"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/pkg/errorhandling"
"github.com/containers/podman/v4/pkg/machine"
Expand Down Expand Up @@ -114,15 +113,10 @@ func composeDockerHost() (string, error) {
return registry.DefaultAPIAddress(), nil
}

cfg, err := config.ReadCustomConfig()
// TODO need to add support for --connection and --url
connection, err := registry.PodmanConfig().ContainersConfDefaultsRO.GetConnection("", true)
if err != nil {
return "", err
}

// NOTE: podman --connection=foo and --url=... are injected
// into the default connection below in `root.go`.
defaultConnection := cfg.Engine.ActiveService
if defaultConnection == "" {
logrus.Info(err)
switch runtime.GOOS {
// If no default connection is set on Linux or FreeBSD,
// we just use the local socket by default - just as
Expand All @@ -137,10 +131,6 @@ func composeDockerHost() (string, error) {
}
}

connection, ok := cfg.Engine.ServiceDestinations[defaultConnection]
if !ok {
return "", fmt.Errorf("internal error: default connection %q not found in database", defaultConnection)
}
parsedConnection, err := url.Parse(connection.URI)
if err != nil {
return "", fmt.Errorf("preparing connection to remote machine: %w", err)
Expand Down
25 changes: 2 additions & 23 deletions cmd/podman/farm/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"strings"

"github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/config"
"github.com/containers/podman/v4/cmd/podman/common"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/cmd/podman/utils"
Expand Down Expand Up @@ -50,14 +49,8 @@ func init() {
cleanupFlag := "cleanup"
flags.BoolVar(&buildOpts.buildOptions.Cleanup, cleanupFlag, false, "Remove built images from farm nodes on success")

podmanConfig := registry.PodmanConfig()
farmFlagName := "farm"
// If remote, don't read the client's containers.conf file
defaultFarm := ""
if !registry.IsRemote() {
defaultFarm = podmanConfig.ContainersConfDefaultsRO.Farms.Default
}
flags.StringVar(&buildOpts.farm, farmFlagName, defaultFarm, "Farm to use for builds")
flags.StringVar(&buildOpts.farm, farmFlagName, "", "Farm to use for builds")
_ = buildCommand.RegisterFlagCompletionFunc(farmFlagName, common.AutoCompleteFarms)

localFlagName := "local"
Expand Down Expand Up @@ -122,23 +115,9 @@ func build(cmd *cobra.Command, args []string) error {
}
opts.SkipTLSVerify = !tlsVerify

cfg, err := config.ReadCustomConfig()
if err != nil {
return err
}

defaultFarm := cfg.Farms.Default
if cmd.Flags().Changed("farm") {
f, err := cmd.Flags().GetString("farm")
if err != nil {
return err
}
defaultFarm = f
}

localEngine := registry.ImageEngine()
ctx := registry.Context()
farm, err := farm.NewFarm(ctx, defaultFarm, localEngine, buildOpts.local)
farm, err := farm.NewFarm(ctx, buildOpts.farm, localEngine, buildOpts.local)
if err != nil {
return fmt.Errorf("initializing: %w", err)
}
Expand Down
52 changes: 24 additions & 28 deletions cmd/podman/farm/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,43 +41,39 @@ func create(cmd *cobra.Command, args []string) error {
farmName := args[0]
connections := args[1:]

cfg, err := config.ReadCustomConfig()
if err != nil {
return err
}

if _, ok := cfg.Farms.List[farmName]; ok {
// if farm exists return an error
return fmt.Errorf("farm with name %q already exists", farmName)
}
err := config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
if _, ok := cfg.Farm.List[farmName]; ok {
// if farm exists return an error
return fmt.Errorf("farm with name %q already exists", farmName)
}

// Can create an empty farm without any connections
if len(connections) == 0 {
cfg.Farms.List[farmName] = []string{}
}
// Can create an empty farm without any connections
if len(connections) == 0 {
cfg.Farm.List[farmName] = []string{}
}

for _, c := range connections {
if _, ok := cfg.Engine.ServiceDestinations[c]; ok {
if slices.Contains(cfg.Farms.List[farmName], c) {
// Don't add duplicate connections to a farm
continue
for _, c := range connections {
if _, ok := cfg.Connection.Connections[c]; ok {
if slices.Contains(cfg.Farm.List[farmName], c) {
// Don't add duplicate connections to a farm
continue
}
cfg.Farm.List[farmName] = append(cfg.Farm.List[farmName], c)
} else {
return fmt.Errorf("cannot create farm, %q is not a system connection", c)
}
cfg.Farms.List[farmName] = append(cfg.Farms.List[farmName], c)
} else {
return fmt.Errorf("cannot create farm, %q is not a system connection", c)
}
}

// If this is the first farm being created, set it as the default farm
if len(cfg.Farms.List) == 1 {
cfg.Farms.Default = farmName
}
// If this is the first farm being created, set it as the default farm
if len(cfg.Farm.List) == 1 {
cfg.Farm.Default = farmName
}

err = cfg.Write()
return nil
})
if err != nil {
return err
}

fmt.Printf("Farm %q created\n", farmName)
return nil
}
40 changes: 10 additions & 30 deletions cmd/podman/farm/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,50 +46,29 @@ func init() {

formatFlagName := "format"
flags.StringVar(&lsOpts.Format, formatFlagName, "", "Format farm output using Go template")
_ = lsCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&farmOut{}))
}

type farmOut struct {
Name string
Connections []string
Default bool
_ = lsCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&config.Farm{}))
}

func list(cmd *cobra.Command, args []string) error {
cfg, err := config.ReadCustomConfig()
if err != nil {
return err
}

format := lsOpts.Format
if format == "" && len(args) > 0 {
format = "json"
}

rows := make([]farmOut, 0)
for k, v := range cfg.Farms.List {
defaultFarm := false
if k == cfg.Farms.Default {
defaultFarm = true
}

r := farmOut{
Name: k,
Connections: v,
Default: defaultFarm,
}
rows = append(rows, r)
farms, err := registry.PodmanConfig().ContainersConfDefaultsRO.GetAllFarms()
if err != nil {
return err
}

sort.Slice(rows, func(i, j int) bool {
return rows[i].Name < rows[j].Name
sort.Slice(farms, func(i, j int) bool {
return farms[i].Name < farms[j].Name
})

rpt := report.New(os.Stdout, cmd.Name())
defer rpt.Flush()

if report.IsJSON(format) {
buf, err := registry.JSONLibrary().MarshalIndent(rows, "", " ")
buf, err := registry.JSONLibrary().MarshalIndent(farms, "", " ")
if err == nil {
fmt.Println(string(buf))
}
Expand All @@ -100,7 +79,7 @@ func list(cmd *cobra.Command, args []string) error {
rpt, err = rpt.Parse(report.OriginUser, format)
} else {
rpt, err = rpt.Parse(report.OriginPodman,
"{{range .}}{{.Name}}\t{{.Connections}}\t{{.Default}}\n{{end -}}")
"{{range .}}{{.Name}}\t{{.Connections}}\t{{.Default}}\t{{.ReadWrite}}\n{{end -}}")
}
if err != nil {
return err
Expand All @@ -111,11 +90,12 @@ func list(cmd *cobra.Command, args []string) error {
"Default": "Default",
"Connections": "Connections",
"Name": "Name",
"ReadWrite": "ReadWrite",
}})
if err != nil {
return err
}
}

return rpt.Execute(rows)
return rpt.Execute(farms)
}
80 changes: 39 additions & 41 deletions cmd/podman/farm/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,57 +43,55 @@ func init() {
}

func rm(cmd *cobra.Command, args []string) error {
cfg, err := config.ReadCustomConfig()
if err != nil {
return err
}

if rmOpts.All {
cfg.Farms.List = make(map[string][]string)
cfg.Farms.Default = ""
if err := cfg.Write(); err != nil {
return err
deletedFarms := []string{}
err := config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
if rmOpts.All {
cfg.Farm.List = make(map[string][]string)
cfg.Farm.Default = ""
return nil
}
fmt.Println("All farms have been deleted")
return nil
}

// If the --all is not set, we require at least one arg
if len(args) == 0 {
return errors.New("requires at lease 1 arg(s), received 0")
}
// If the --all is not set, we require at least one arg
if len(args) == 0 {
return errors.New("requires at lease 1 arg(s), received 0")
}

if len(cfg.Farms.List) == 0 {
return errors.New("no existing farms; nothing to remove")
}
if len(cfg.Farm.List) == 0 {
return errors.New("no existing farms; nothing to remove")
}

deletedFarms := []string{}
for _, k := range args {
if _, ok := cfg.Farms.List[k]; !ok {
logrus.Warnf("farm %q doesn't exist; nothing to remove", k)
continue
for _, k := range args {
if _, ok := cfg.Farm.List[k]; !ok {
logrus.Warnf("farm %q doesn't exist; nothing to remove", k)
continue
}
delete(cfg.Farm.List, k)
deletedFarms = append(deletedFarms, k)
if k == cfg.Farm.Default {
cfg.Farm.Default = ""
}
}
delete(cfg.Farms.List, k)
deletedFarms = append(deletedFarms, k)
if k == cfg.Farms.Default {
cfg.Farms.Default = ""
// Return error if none of the given farms were deleted
if len(deletedFarms) == 0 {
return fmt.Errorf("failed to delete farms %q", args)
}
}
// Return error if none of the given farms were deleted
if len(deletedFarms) == 0 {
return fmt.Errorf("failed to delete farms %q", args)
}

// Set a new default farm if the current default farm has been removed
if cfg.Farms.Default == "" && cfg.Farms.List != nil {
for k := range cfg.Farms.List {
cfg.Farms.Default = k
break
// Set a new default farm if the current default farm has been removed
if cfg.Farm.Default == "" && cfg.Farm.List != nil {
for k := range cfg.Farm.List {
cfg.Farm.Default = k
break
}
}
}
if err := cfg.Write(); err != nil {
return nil
})
if err != nil {
return err
}
if rmOpts.All {
fmt.Println("All farms have been deleted")
return nil
}

for _, k := range deletedFarms {
fmt.Printf("Farm %q deleted\n", k)
Expand Down
Loading

0 comments on commit 74454bf

Please sign in to comment.