mirror of
https://github.com/containers/podman.git
synced 2025-07-15 03:02:52 +08:00
rework system connection and farm storage
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>
This commit is contained in:
@ -837,15 +837,15 @@ func AutoCompleteFarms(cmd *cobra.Command, args []string, toComplete string) ([]
|
|||||||
if !validCurrentCmdLine(cmd, args, toComplete) {
|
if !validCurrentCmdLine(cmd, args, toComplete) {
|
||||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||||
}
|
}
|
||||||
suggestions := []string{}
|
farms, err := podmanConfig.ContainersConfDefaultsRO.GetAllFarms()
|
||||||
cfg, err := config.ReadCustomConfig()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cobra.CompErrorln(err.Error())
|
cobra.CompErrorln(err.Error())
|
||||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||||
}
|
}
|
||||||
|
|
||||||
for k := range cfg.Farms.List {
|
suggestions := make([]string, 0, len(farms))
|
||||||
suggestions = append(suggestions, k)
|
for _, farm := range farms {
|
||||||
|
suggestions = append(suggestions, farm.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return suggestions, cobra.ShellCompDirectiveNoFileComp
|
return suggestions, cobra.ShellCompDirectiveNoFileComp
|
||||||
@ -856,16 +856,17 @@ func AutocompleteSystemConnections(cmd *cobra.Command, args []string, toComplete
|
|||||||
if !validCurrentCmdLine(cmd, args, toComplete) {
|
if !validCurrentCmdLine(cmd, args, toComplete) {
|
||||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||||
}
|
}
|
||||||
suggestions := []string{}
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
cons, err := podmanConfig.ContainersConfDefaultsRO.GetAllConnections()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cobra.CompErrorln(err.Error())
|
cobra.CompErrorln(err.Error())
|
||||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
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
|
// 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
|
return suggestions, cobra.ShellCompDirectiveNoFileComp
|
||||||
|
@ -14,7 +14,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/config"
|
|
||||||
"github.com/containers/podman/v4/cmd/podman/registry"
|
"github.com/containers/podman/v4/cmd/podman/registry"
|
||||||
"github.com/containers/podman/v4/pkg/errorhandling"
|
"github.com/containers/podman/v4/pkg/errorhandling"
|
||||||
"github.com/containers/podman/v4/pkg/machine"
|
"github.com/containers/podman/v4/pkg/machine"
|
||||||
@ -114,15 +113,10 @@ func composeDockerHost() (string, error) {
|
|||||||
return registry.DefaultAPIAddress(), nil
|
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 {
|
if err != nil {
|
||||||
return "", err
|
logrus.Info(err)
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: podman --connection=foo and --url=... are injected
|
|
||||||
// into the default connection below in `root.go`.
|
|
||||||
defaultConnection := cfg.Engine.ActiveService
|
|
||||||
if defaultConnection == "" {
|
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
// If no default connection is set on Linux or FreeBSD,
|
// If no default connection is set on Linux or FreeBSD,
|
||||||
// we just use the local socket by default - just as
|
// we just use the local socket by default - just as
|
||||||
@ -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)
|
parsedConnection, err := url.Parse(connection.URI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("preparing connection to remote machine: %w", err)
|
return "", fmt.Errorf("preparing connection to remote machine: %w", err)
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/completion"
|
"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/common"
|
||||||
"github.com/containers/podman/v4/cmd/podman/registry"
|
"github.com/containers/podman/v4/cmd/podman/registry"
|
||||||
"github.com/containers/podman/v4/cmd/podman/utils"
|
"github.com/containers/podman/v4/cmd/podman/utils"
|
||||||
@ -50,14 +49,8 @@ func init() {
|
|||||||
cleanupFlag := "cleanup"
|
cleanupFlag := "cleanup"
|
||||||
flags.BoolVar(&buildOpts.buildOptions.Cleanup, cleanupFlag, false, "Remove built images from farm nodes on success")
|
flags.BoolVar(&buildOpts.buildOptions.Cleanup, cleanupFlag, false, "Remove built images from farm nodes on success")
|
||||||
|
|
||||||
podmanConfig := registry.PodmanConfig()
|
|
||||||
farmFlagName := "farm"
|
farmFlagName := "farm"
|
||||||
// If remote, don't read the client's containers.conf file
|
flags.StringVar(&buildOpts.farm, farmFlagName, "", "Farm to use for builds")
|
||||||
defaultFarm := ""
|
|
||||||
if !registry.IsRemote() {
|
|
||||||
defaultFarm = podmanConfig.ContainersConfDefaultsRO.Farms.Default
|
|
||||||
}
|
|
||||||
flags.StringVar(&buildOpts.farm, farmFlagName, defaultFarm, "Farm to use for builds")
|
|
||||||
_ = buildCommand.RegisterFlagCompletionFunc(farmFlagName, common.AutoCompleteFarms)
|
_ = buildCommand.RegisterFlagCompletionFunc(farmFlagName, common.AutoCompleteFarms)
|
||||||
|
|
||||||
localFlagName := "local"
|
localFlagName := "local"
|
||||||
@ -122,23 +115,9 @@ func build(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
opts.SkipTLSVerify = !tlsVerify
|
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()
|
localEngine := registry.ImageEngine()
|
||||||
ctx := registry.Context()
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("initializing: %w", err)
|
return fmt.Errorf("initializing: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -41,43 +41,39 @@ func create(cmd *cobra.Command, args []string) error {
|
|||||||
farmName := args[0]
|
farmName := args[0]
|
||||||
connections := args[1:]
|
connections := args[1:]
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
err := config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
||||||
if err != nil {
|
if _, ok := cfg.Farm.List[farmName]; ok {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := cfg.Farms.List[farmName]; ok {
|
|
||||||
// if farm exists return an error
|
// if farm exists return an error
|
||||||
return fmt.Errorf("farm with name %q already exists", farmName)
|
return fmt.Errorf("farm with name %q already exists", farmName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can create an empty farm without any connections
|
// Can create an empty farm without any connections
|
||||||
if len(connections) == 0 {
|
if len(connections) == 0 {
|
||||||
cfg.Farms.List[farmName] = []string{}
|
cfg.Farm.List[farmName] = []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range connections {
|
for _, c := range connections {
|
||||||
if _, ok := cfg.Engine.ServiceDestinations[c]; ok {
|
if _, ok := cfg.Connection.Connections[c]; ok {
|
||||||
if slices.Contains(cfg.Farms.List[farmName], c) {
|
if slices.Contains(cfg.Farm.List[farmName], c) {
|
||||||
// Don't add duplicate connections to a farm
|
// Don't add duplicate connections to a farm
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
cfg.Farms.List[farmName] = append(cfg.Farms.List[farmName], c)
|
cfg.Farm.List[farmName] = append(cfg.Farm.List[farmName], c)
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("cannot create farm, %q is not a system connection", c)
|
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 this is the first farm being created, set it as the default farm
|
||||||
if len(cfg.Farms.List) == 1 {
|
if len(cfg.Farm.List) == 1 {
|
||||||
cfg.Farms.Default = farmName
|
cfg.Farm.Default = farmName
|
||||||
}
|
}
|
||||||
|
|
||||||
err = cfg.Write()
|
return nil
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Farm %q created\n", farmName)
|
fmt.Printf("Farm %q created\n", farmName)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -46,50 +46,29 @@ func init() {
|
|||||||
|
|
||||||
formatFlagName := "format"
|
formatFlagName := "format"
|
||||||
flags.StringVar(&lsOpts.Format, formatFlagName, "", "Format farm output using Go template")
|
flags.StringVar(&lsOpts.Format, formatFlagName, "", "Format farm output using Go template")
|
||||||
_ = lsCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&farmOut{}))
|
_ = lsCommand.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&config.Farm{}))
|
||||||
}
|
|
||||||
|
|
||||||
type farmOut struct {
|
|
||||||
Name string
|
|
||||||
Connections []string
|
|
||||||
Default bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func list(cmd *cobra.Command, args []string) error {
|
func list(cmd *cobra.Command, args []string) error {
|
||||||
cfg, err := config.ReadCustomConfig()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
format := lsOpts.Format
|
format := lsOpts.Format
|
||||||
if format == "" && len(args) > 0 {
|
if format == "" && len(args) > 0 {
|
||||||
format = "json"
|
format = "json"
|
||||||
}
|
}
|
||||||
|
|
||||||
rows := make([]farmOut, 0)
|
farms, err := registry.PodmanConfig().ContainersConfDefaultsRO.GetAllFarms()
|
||||||
for k, v := range cfg.Farms.List {
|
if err != nil {
|
||||||
defaultFarm := false
|
return err
|
||||||
if k == cfg.Farms.Default {
|
|
||||||
defaultFarm = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r := farmOut{
|
sort.Slice(farms, func(i, j int) bool {
|
||||||
Name: k,
|
return farms[i].Name < farms[j].Name
|
||||||
Connections: v,
|
|
||||||
Default: defaultFarm,
|
|
||||||
}
|
|
||||||
rows = append(rows, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Slice(rows, func(i, j int) bool {
|
|
||||||
return rows[i].Name < rows[j].Name
|
|
||||||
})
|
})
|
||||||
|
|
||||||
rpt := report.New(os.Stdout, cmd.Name())
|
rpt := report.New(os.Stdout, cmd.Name())
|
||||||
defer rpt.Flush()
|
defer rpt.Flush()
|
||||||
|
|
||||||
if report.IsJSON(format) {
|
if report.IsJSON(format) {
|
||||||
buf, err := registry.JSONLibrary().MarshalIndent(rows, "", " ")
|
buf, err := registry.JSONLibrary().MarshalIndent(farms, "", " ")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fmt.Println(string(buf))
|
fmt.Println(string(buf))
|
||||||
}
|
}
|
||||||
@ -100,7 +79,7 @@ func list(cmd *cobra.Command, args []string) error {
|
|||||||
rpt, err = rpt.Parse(report.OriginUser, format)
|
rpt, err = rpt.Parse(report.OriginUser, format)
|
||||||
} else {
|
} else {
|
||||||
rpt, err = rpt.Parse(report.OriginPodman,
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -111,11 +90,12 @@ func list(cmd *cobra.Command, args []string) error {
|
|||||||
"Default": "Default",
|
"Default": "Default",
|
||||||
"Connections": "Connections",
|
"Connections": "Connections",
|
||||||
"Name": "Name",
|
"Name": "Name",
|
||||||
|
"ReadWrite": "ReadWrite",
|
||||||
}})
|
}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rpt.Execute(rows)
|
return rpt.Execute(farms)
|
||||||
}
|
}
|
||||||
|
@ -43,18 +43,11 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func rm(cmd *cobra.Command, args []string) error {
|
func rm(cmd *cobra.Command, args []string) error {
|
||||||
cfg, err := config.ReadCustomConfig()
|
deletedFarms := []string{}
|
||||||
if err != nil {
|
err := config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if rmOpts.All {
|
if rmOpts.All {
|
||||||
cfg.Farms.List = make(map[string][]string)
|
cfg.Farm.List = make(map[string][]string)
|
||||||
cfg.Farms.Default = ""
|
cfg.Farm.Default = ""
|
||||||
if err := cfg.Write(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Println("All farms have been deleted")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,20 +56,19 @@ func rm(cmd *cobra.Command, args []string) error {
|
|||||||
return errors.New("requires at lease 1 arg(s), received 0")
|
return errors.New("requires at lease 1 arg(s), received 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cfg.Farms.List) == 0 {
|
if len(cfg.Farm.List) == 0 {
|
||||||
return errors.New("no existing farms; nothing to remove")
|
return errors.New("no existing farms; nothing to remove")
|
||||||
}
|
}
|
||||||
|
|
||||||
deletedFarms := []string{}
|
|
||||||
for _, k := range args {
|
for _, k := range args {
|
||||||
if _, ok := cfg.Farms.List[k]; !ok {
|
if _, ok := cfg.Farm.List[k]; !ok {
|
||||||
logrus.Warnf("farm %q doesn't exist; nothing to remove", k)
|
logrus.Warnf("farm %q doesn't exist; nothing to remove", k)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
delete(cfg.Farms.List, k)
|
delete(cfg.Farm.List, k)
|
||||||
deletedFarms = append(deletedFarms, k)
|
deletedFarms = append(deletedFarms, k)
|
||||||
if k == cfg.Farms.Default {
|
if k == cfg.Farm.Default {
|
||||||
cfg.Farms.Default = ""
|
cfg.Farm.Default = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Return error if none of the given farms were deleted
|
// Return error if none of the given farms were deleted
|
||||||
@ -85,15 +77,21 @@ func rm(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set a new default farm if the current default farm has been removed
|
// Set a new default farm if the current default farm has been removed
|
||||||
if cfg.Farms.Default == "" && cfg.Farms.List != nil {
|
if cfg.Farm.Default == "" && cfg.Farm.List != nil {
|
||||||
for k := range cfg.Farms.List {
|
for k := range cfg.Farm.List {
|
||||||
cfg.Farms.Default = k
|
cfg.Farm.Default = k
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := cfg.Write(); err != nil {
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if rmOpts.All {
|
||||||
|
fmt.Println("All farms have been deleted")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
for _, k := range deletedFarms {
|
for _, k := range deletedFarms {
|
||||||
fmt.Printf("Farm %q deleted\n", k)
|
fmt.Printf("Farm %q deleted\n", k)
|
||||||
|
@ -63,37 +63,33 @@ func farmUpdate(cmd *cobra.Command, args []string) error {
|
|||||||
return fmt.Errorf("nothing to update for farm %q, please use the --add, --remove, or --default flags to update a farm", farmName)
|
return fmt.Errorf("nothing to update for farm %q, please use the --add, --remove, or --default flags to update a farm", farmName)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
err := config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
||||||
if err != nil {
|
if len(cfg.Farm.List) == 0 {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cfg.Farms.List) == 0 {
|
|
||||||
return errors.New("no farms are created at this time, there is nothing to update")
|
return errors.New("no farms are created at this time, there is nothing to update")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := cfg.Farms.List[farmName]; !ok {
|
if _, ok := cfg.Farm.List[farmName]; !ok {
|
||||||
return fmt.Errorf("cannot update farm, %q farm doesn't exist", farmName)
|
return fmt.Errorf("cannot update farm, %q farm doesn't exist", farmName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if defChanged {
|
if defChanged {
|
||||||
// Change the default to the given farm if --default=true
|
// Change the default to the given farm if --default=true
|
||||||
if updateOpts.Default {
|
if updateOpts.Default {
|
||||||
cfg.Farms.Default = farmName
|
cfg.Farm.Default = farmName
|
||||||
} else {
|
} else {
|
||||||
// if --default=false, user doesn't want any farms to be default so clear the DefaultFarm
|
// if --default=false, user doesn't want any farms to be default so clear the DefaultFarm
|
||||||
cfg.Farms.Default = ""
|
cfg.Farm.Default = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if val, ok := cfg.Farms.List[farmName]; ok {
|
if val, ok := cfg.Farm.List[farmName]; ok {
|
||||||
cMap := make(map[string]int)
|
cMap := make(map[string]int)
|
||||||
for _, c := range val {
|
for _, c := range val {
|
||||||
cMap[c] = 0
|
cMap[c] = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, cRemove := range updateOpts.Remove {
|
for _, cRemove := range updateOpts.Remove {
|
||||||
connections := cfg.Farms.List[farmName]
|
connections := cfg.Farm.List[farmName]
|
||||||
if slices.Contains(connections, cRemove) {
|
if slices.Contains(connections, cRemove) {
|
||||||
delete(cMap, cRemove)
|
delete(cMap, cRemove)
|
||||||
} else {
|
} else {
|
||||||
@ -102,7 +98,7 @@ func farmUpdate(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, cAdd := range updateOpts.Add {
|
for _, cAdd := range updateOpts.Add {
|
||||||
if _, ok := cfg.Engine.ServiceDestinations[cAdd]; ok {
|
if _, ok := cfg.Connection.Connections[cAdd]; ok {
|
||||||
if _, ok := cMap[cAdd]; !ok {
|
if _, ok := cMap[cAdd]; !ok {
|
||||||
cMap[cAdd] = 0
|
cMap[cAdd] = 0
|
||||||
}
|
}
|
||||||
@ -115,10 +111,11 @@ func farmUpdate(cmd *cobra.Command, args []string) error {
|
|||||||
for k := range cMap {
|
for k := range cMap {
|
||||||
updatedConnections = append(updatedConnections, k)
|
updatedConnections = append(updatedConnections, k)
|
||||||
}
|
}
|
||||||
cfg.Farms.List[farmName] = updatedConnections
|
cfg.Farm.List[farmName] = updatedConnections
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
if err := cfg.Write(); err != nil {
|
})
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Printf("Farm %q updated\n", farmName)
|
fmt.Printf("Farm %q updated\n", farmName)
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/completion"
|
"github.com/containers/common/pkg/completion"
|
||||||
"github.com/containers/common/pkg/config"
|
|
||||||
"github.com/containers/common/pkg/report"
|
"github.com/containers/common/pkg/report"
|
||||||
"github.com/containers/podman/v4/cmd/podman/common"
|
"github.com/containers/podman/v4/cmd/podman/common"
|
||||||
"github.com/containers/podman/v4/cmd/podman/registry"
|
"github.com/containers/podman/v4/cmd/podman/registry"
|
||||||
@ -108,16 +107,18 @@ func hostInfo() (*entities.MachineHostInfo, error) {
|
|||||||
|
|
||||||
host.NumberOfMachines = len(listResponse)
|
host.NumberOfMachines = len(listResponse)
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
defaultCon := ""
|
||||||
if err != nil {
|
con, err := registry.PodmanConfig().ContainersConfDefaultsRO.GetConnection("", true)
|
||||||
return nil, err
|
if err == nil {
|
||||||
|
// ignore the error here we only want to know if we have a default connection to show it in list
|
||||||
|
defaultCon = con.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default state of machine is stopped
|
// Default state of machine is stopped
|
||||||
host.MachineState = "Stopped"
|
host.MachineState = "Stopped"
|
||||||
for _, vm := range listResponse {
|
for _, vm := range listResponse {
|
||||||
// Set default machine if found
|
// Set default machine if found
|
||||||
if vm.Name == cfg.Engine.ActiveService {
|
if vm.Name == defaultCon {
|
||||||
host.DefaultMachine = vm.Name
|
host.DefaultMachine = vm.Name
|
||||||
}
|
}
|
||||||
// If machine is running or starting, it is automatically the current machine
|
// If machine is running or starting, it is automatically the current machine
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/completion"
|
"github.com/containers/common/pkg/completion"
|
||||||
"github.com/containers/common/pkg/config"
|
|
||||||
"github.com/containers/podman/v4/cmd/podman/registry"
|
"github.com/containers/podman/v4/cmd/podman/registry"
|
||||||
"github.com/containers/podman/v4/libpod/events"
|
"github.com/containers/podman/v4/libpod/events"
|
||||||
"github.com/containers/podman/v4/pkg/machine"
|
"github.com/containers/podman/v4/pkg/machine"
|
||||||
@ -150,17 +149,20 @@ func initMachine(cmd *cobra.Command, args []string) error {
|
|||||||
return fmt.Errorf("%s: %w", initOpts.Name, machine.ErrVMAlreadyExists)
|
return fmt.Errorf("%s: %w", initOpts.Name, machine.ErrVMAlreadyExists)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
// check if a system connection already exists
|
||||||
|
cons, err := registry.PodmanConfig().ContainersConfDefaultsRO.GetAllConnections()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
for _, con := range cons {
|
||||||
// check if a system connection already exists
|
if con.ReadWrite {
|
||||||
for _, connection := range []string{initOpts.Name, fmt.Sprintf("%s-root", initOpts.Name)} {
|
for _, connection := range []string{initOpts.Name, fmt.Sprintf("%s-root", initOpts.Name)} {
|
||||||
if _, valueFound := cfg.Engine.ServiceDestinations[connection]; valueFound {
|
if con.Name == connection {
|
||||||
return fmt.Errorf("system connection %q already exists. consider a different machine name or remove the connection with `podman system connection rm`", connection)
|
return fmt.Errorf("system connection %q already exists. consider a different machine name or remove the connection with `podman system connection rm`", connection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for idx, vol := range initOpts.Volumes {
|
for idx, vol := range initOpts.Volumes {
|
||||||
initOpts.Volumes[idx] = os.ExpandEnv(vol)
|
initOpts.Volumes[idx] = os.ExpandEnv(vol)
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/completion"
|
"github.com/containers/common/pkg/completion"
|
||||||
"github.com/containers/common/pkg/config"
|
|
||||||
"github.com/containers/common/pkg/report"
|
"github.com/containers/common/pkg/report"
|
||||||
"github.com/containers/podman/v4/cmd/podman/common"
|
"github.com/containers/podman/v4/cmd/podman/common"
|
||||||
"github.com/containers/podman/v4/cmd/podman/registry"
|
"github.com/containers/podman/v4/cmd/podman/registry"
|
||||||
@ -79,12 +78,15 @@ func list(cmd *cobra.Command, args []string) error {
|
|||||||
return listResponse[i].Running
|
return listResponse[i].Running
|
||||||
})
|
})
|
||||||
|
|
||||||
if report.IsJSON(listFlag.format) {
|
defaultCon := ""
|
||||||
machineReporter, err := toMachineFormat(listResponse)
|
con, err := registry.PodmanConfig().ContainersConfDefaultsRO.GetConnection("", true)
|
||||||
if err != nil {
|
if err == nil {
|
||||||
return err
|
// ignore the error here we only want to know if we have a default connection to show it in list
|
||||||
|
defaultCon = con.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if report.IsJSON(listFlag.format) {
|
||||||
|
machineReporter := toMachineFormat(listResponse, defaultCon)
|
||||||
b, err := json.MarshalIndent(machineReporter, "", " ")
|
b, err := json.MarshalIndent(machineReporter, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -93,11 +95,7 @@ func list(cmd *cobra.Command, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
machineReporter, err := toHumanFormat(listResponse)
|
machineReporter := toHumanFormat(listResponse, defaultCon)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return outputTemplate(cmd, machineReporter)
|
return outputTemplate(cmd, machineReporter)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,16 +151,11 @@ func streamName(imageStream string) string {
|
|||||||
return imageStream
|
return imageStream
|
||||||
}
|
}
|
||||||
|
|
||||||
func toMachineFormat(vms []*machine.ListResponse) ([]*entities.ListReporter, error) {
|
func toMachineFormat(vms []*machine.ListResponse, defaultCon string) []*entities.ListReporter {
|
||||||
cfg, err := config.ReadCustomConfig()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
machineResponses := make([]*entities.ListReporter, 0, len(vms))
|
machineResponses := make([]*entities.ListReporter, 0, len(vms))
|
||||||
for _, vm := range vms {
|
for _, vm := range vms {
|
||||||
response := new(entities.ListReporter)
|
response := new(entities.ListReporter)
|
||||||
response.Default = vm.Name == cfg.Engine.ActiveService
|
response.Default = vm.Name == defaultCon
|
||||||
response.Name = vm.Name
|
response.Name = vm.Name
|
||||||
response.Running = vm.Running
|
response.Running = vm.Running
|
||||||
response.LastUp = strTime(vm.LastUp)
|
response.LastUp = strTime(vm.LastUp)
|
||||||
@ -180,19 +173,14 @@ func toMachineFormat(vms []*machine.ListResponse) ([]*entities.ListReporter, err
|
|||||||
|
|
||||||
machineResponses = append(machineResponses, response)
|
machineResponses = append(machineResponses, response)
|
||||||
}
|
}
|
||||||
return machineResponses, nil
|
return machineResponses
|
||||||
}
|
}
|
||||||
|
|
||||||
func toHumanFormat(vms []*machine.ListResponse) ([]*entities.ListReporter, error) {
|
func toHumanFormat(vms []*machine.ListResponse, defaultCon string) []*entities.ListReporter {
|
||||||
cfg, err := config.ReadCustomConfig()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
humanResponses := make([]*entities.ListReporter, 0, len(vms))
|
humanResponses := make([]*entities.ListReporter, 0, len(vms))
|
||||||
for _, vm := range vms {
|
for _, vm := range vms {
|
||||||
response := new(entities.ListReporter)
|
response := new(entities.ListReporter)
|
||||||
if vm.Name == cfg.Engine.ActiveService {
|
if vm.Name == defaultCon {
|
||||||
response.Name = vm.Name + "*"
|
response.Name = vm.Name + "*"
|
||||||
response.Default = true
|
response.Default = true
|
||||||
} else {
|
} else {
|
||||||
@ -218,5 +206,5 @@ func toHumanFormat(vms []*machine.ListResponse) ([]*entities.ListReporter, error
|
|||||||
|
|
||||||
humanResponses = append(humanResponses, response)
|
humanResponses = append(humanResponses, response)
|
||||||
}
|
}
|
||||||
return humanResponses, nil
|
return humanResponses
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/completion"
|
"github.com/containers/common/pkg/completion"
|
||||||
"github.com/containers/common/pkg/config"
|
|
||||||
"github.com/containers/podman/v4/cmd/podman/registry"
|
"github.com/containers/podman/v4/cmd/podman/registry"
|
||||||
"github.com/containers/podman/v4/cmd/podman/utils"
|
"github.com/containers/podman/v4/cmd/podman/utils"
|
||||||
"github.com/containers/podman/v4/pkg/machine"
|
"github.com/containers/podman/v4/pkg/machine"
|
||||||
@ -93,12 +92,12 @@ func ssh(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func remoteConnectionUsername() (string, error) {
|
func remoteConnectionUsername() (string, error) {
|
||||||
cfg, err := config.ReadCustomConfig()
|
con, err := registry.PodmanConfig().ContainersConfDefaultsRO.GetConnection("", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
dest := cfg.Engine.ServiceDestinations[cfg.Engine.ActiveService].URI
|
|
||||||
uri, err := url.Parse(dest)
|
uri, err := url.Parse(con.URI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ func Execute() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// readRemoteCliFlags reads cli flags related to operating podman remotely
|
// readRemoteCliFlags reads cli flags related to operating podman remotely
|
||||||
func readRemoteCliFlags(cmd *cobra.Command, podmanConfig *entities.PodmanConfig) (err error) {
|
func readRemoteCliFlags(cmd *cobra.Command, podmanConfig *entities.PodmanConfig) error {
|
||||||
conf := podmanConfig.ContainersConfDefaultsRO
|
conf := podmanConfig.ContainersConfDefaultsRO
|
||||||
contextConn, host := cmd.Root().LocalFlags().Lookup("context"), cmd.Root().LocalFlags().Lookup("host")
|
contextConn, host := cmd.Root().LocalFlags().Lookup("context"), cmd.Root().LocalFlags().Lookup("host")
|
||||||
conn, url := cmd.Root().LocalFlags().Lookup("connection"), cmd.Root().LocalFlags().Lookup("url")
|
conn, url := cmd.Root().LocalFlags().Lookup("connection"), cmd.Root().LocalFlags().Lookup("url")
|
||||||
@ -151,35 +151,32 @@ func readRemoteCliFlags(cmd *cobra.Command, podmanConfig *entities.PodmanConfig)
|
|||||||
switch {
|
switch {
|
||||||
case conn != nil && conn.Changed:
|
case conn != nil && conn.Changed:
|
||||||
if contextConn != nil && contextConn.Changed {
|
if contextConn != nil && contextConn.Changed {
|
||||||
err = fmt.Errorf("use of --connection and --context at the same time is not allowed")
|
return fmt.Errorf("use of --connection and --context at the same time is not allowed")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if dest, ok := conf.Engine.ServiceDestinations[conn.Value.String()]; ok {
|
con, err := conf.GetConnection(conn.Value.String(), false)
|
||||||
podmanConfig.URI = dest.URI
|
if err != nil {
|
||||||
podmanConfig.Identity = dest.Identity
|
return err
|
||||||
podmanConfig.MachineMode = dest.IsMachine
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
err = fmt.Errorf("connection %q not found", conn.Value.String())
|
podmanConfig.URI = con.URI
|
||||||
return
|
podmanConfig.Identity = con.Identity
|
||||||
|
podmanConfig.MachineMode = con.IsMachine
|
||||||
case url.Changed:
|
case url.Changed:
|
||||||
podmanConfig.URI = url.Value.String()
|
podmanConfig.URI = url.Value.String()
|
||||||
return
|
|
||||||
case contextConn != nil && contextConn.Changed:
|
case contextConn != nil && contextConn.Changed:
|
||||||
service := contextConn.Value.String()
|
service := contextConn.Value.String()
|
||||||
if service != "default" {
|
if service != "default" {
|
||||||
if dest, ok := conf.Engine.ServiceDestinations[contextConn.Value.String()]; ok {
|
con, err := conf.GetConnection(service, false)
|
||||||
podmanConfig.URI = dest.URI
|
if err != nil {
|
||||||
podmanConfig.Identity = dest.Identity
|
return err
|
||||||
podmanConfig.MachineMode = dest.IsMachine
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
return fmt.Errorf("connection %q not found", service)
|
podmanConfig.URI = con.URI
|
||||||
|
podmanConfig.Identity = con.Identity
|
||||||
|
podmanConfig.MachineMode = con.IsMachine
|
||||||
}
|
}
|
||||||
case host.Changed:
|
case host.Changed:
|
||||||
podmanConfig.URI = host.Value.String()
|
podmanConfig.URI = host.Value.String()
|
||||||
}
|
}
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// setupRemoteConnection returns information about the active service destination
|
// setupRemoteConnection returns information about the active service destination
|
||||||
@ -191,29 +188,31 @@ func readRemoteCliFlags(cmd *cobra.Command, podmanConfig *entities.PodmanConfig)
|
|||||||
func setupRemoteConnection(podmanConfig *entities.PodmanConfig) error {
|
func setupRemoteConnection(podmanConfig *entities.PodmanConfig) error {
|
||||||
conf := podmanConfig.ContainersConfDefaultsRO
|
conf := podmanConfig.ContainersConfDefaultsRO
|
||||||
connEnv, hostEnv, sshkeyEnv := os.Getenv("CONTAINER_CONNECTION"), os.Getenv("CONTAINER_HOST"), os.Getenv("CONTAINER_SSHKEY")
|
connEnv, hostEnv, sshkeyEnv := os.Getenv("CONTAINER_CONNECTION"), os.Getenv("CONTAINER_HOST"), os.Getenv("CONTAINER_SSHKEY")
|
||||||
dest, destFound := conf.Engine.ServiceDestinations[conf.Engine.ActiveService]
|
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case connEnv != "":
|
case connEnv != "":
|
||||||
if ConnEnvDest, ok := conf.Engine.ServiceDestinations[connEnv]; ok {
|
con, err := conf.GetConnection(connEnv, false)
|
||||||
podmanConfig.URI = ConnEnvDest.URI
|
if err != nil {
|
||||||
podmanConfig.Identity = ConnEnvDest.Identity
|
return err
|
||||||
podmanConfig.MachineMode = ConnEnvDest.IsMachine
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
return fmt.Errorf("connection %q not found", connEnv)
|
podmanConfig.URI = con.URI
|
||||||
|
podmanConfig.Identity = con.Identity
|
||||||
|
podmanConfig.MachineMode = con.IsMachine
|
||||||
case hostEnv != "":
|
case hostEnv != "":
|
||||||
if sshkeyEnv != "" {
|
if sshkeyEnv != "" {
|
||||||
podmanConfig.Identity = sshkeyEnv
|
podmanConfig.Identity = sshkeyEnv
|
||||||
}
|
}
|
||||||
podmanConfig.URI = hostEnv
|
podmanConfig.URI = hostEnv
|
||||||
case destFound:
|
|
||||||
podmanConfig.URI = dest.URI
|
|
||||||
podmanConfig.Identity = dest.Identity
|
|
||||||
podmanConfig.MachineMode = dest.IsMachine
|
|
||||||
default:
|
default:
|
||||||
|
con, err := conf.GetConnection("", true)
|
||||||
|
if err == nil {
|
||||||
|
podmanConfig.URI = con.URI
|
||||||
|
podmanConfig.Identity = con.Identity
|
||||||
|
podmanConfig.MachineMode = con.IsMachine
|
||||||
|
} else {
|
||||||
podmanConfig.URI = registry.DefaultAPIAddress()
|
podmanConfig.URI = registry.DefaultAPIAddress()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,49 +176,39 @@ func add(cmd *cobra.Command, args []string) error {
|
|||||||
logrus.Warnf("%q unknown scheme, no validation provided", uri.Scheme)
|
logrus.Warnf("%q unknown scheme, no validation provided", uri.Scheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if cmd.Flags().Changed("default") {
|
|
||||||
if cOpts.Default {
|
|
||||||
cfg.Engine.ActiveService = args[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dst := config.Destination{
|
dst := config.Destination{
|
||||||
URI: uri.String(),
|
URI: uri.String(),
|
||||||
|
Identity: cOpts.Identity,
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.Flags().Changed("identity") {
|
connection := args[0]
|
||||||
dst.Identity = cOpts.Identity
|
return config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
||||||
|
if cOpts.Default {
|
||||||
|
cfg.Connection.Default = connection
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Engine.ServiceDestinations == nil {
|
if cfg.Connection.Connections == nil {
|
||||||
cfg.Engine.ServiceDestinations = map[string]config.Destination{
|
cfg.Connection.Connections = map[string]config.Destination{
|
||||||
args[0]: dst,
|
connection: dst,
|
||||||
}
|
}
|
||||||
cfg.Engine.ActiveService = args[0]
|
cfg.Connection.Default = connection
|
||||||
} else {
|
} else {
|
||||||
cfg.Engine.ServiceDestinations[args[0]] = dst
|
cfg.Connection.Connections[connection] = dst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create or update an existing farm with the connection being added
|
||||||
if cOpts.Farm != "" {
|
if cOpts.Farm != "" {
|
||||||
if cfg.Farms.List == nil {
|
if len(cfg.Farm.List) == 0 {
|
||||||
cfg.Farms.List = map[string][]string{
|
cfg.Farm.Default = cOpts.Farm
|
||||||
cOpts.Farm: {args[0]},
|
|
||||||
}
|
}
|
||||||
cfg.Farms.Default = cOpts.Farm
|
if val, ok := cfg.Farm.List[cOpts.Farm]; ok {
|
||||||
|
cfg.Farm.List[cOpts.Farm] = append(val, connection)
|
||||||
} else {
|
} else {
|
||||||
if val, ok := cfg.Farms.List[cOpts.Farm]; ok {
|
cfg.Farm.List[cOpts.Farm] = []string{connection}
|
||||||
cfg.Farms.List[cOpts.Farm] = append(val, args[0])
|
|
||||||
} else {
|
|
||||||
cfg.Farms.List[cOpts.Farm] = []string{args[0]}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return nil
|
||||||
return cfg.Write()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func create(cmd *cobra.Command, args []string) error {
|
func create(cmd *cobra.Command, args []string) error {
|
||||||
@ -237,24 +227,21 @@ func create(cmd *cobra.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
dst := config.Destination{
|
dst := config.Destination{
|
||||||
URI: uri.String(),
|
URI: uri.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Engine.ServiceDestinations == nil {
|
return config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
||||||
cfg.Engine.ServiceDestinations = map[string]config.Destination{
|
if cfg.Connection.Connections == nil {
|
||||||
|
cfg.Connection.Connections = map[string]config.Destination{
|
||||||
args[0]: dst,
|
args[0]: dst,
|
||||||
}
|
}
|
||||||
cfg.Engine.ActiveService = args[0]
|
cfg.Connection.Default = args[0]
|
||||||
} else {
|
} else {
|
||||||
cfg.Engine.ServiceDestinations[args[0]] = dst
|
cfg.Connection.Connections[args[0]] = dst
|
||||||
}
|
}
|
||||||
return cfg.Write()
|
return nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func translateDest(path string) (string, error) {
|
func translateDest(path string) (string, error) {
|
||||||
|
@ -45,15 +45,13 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func defaultRunE(cmd *cobra.Command, args []string) error {
|
func defaultRunE(cmd *cobra.Command, args []string) error {
|
||||||
cfg, err := config.ReadCustomConfig()
|
connection := args[0]
|
||||||
if err != nil {
|
return config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
||||||
return err
|
if _, found := cfg.Connection.Connections[connection]; !found {
|
||||||
|
return fmt.Errorf("%q destination is not defined. See \"podman system connection add ...\" to create a connection", connection)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, found := cfg.Engine.ServiceDestinations[args[0]]; !found {
|
cfg.Connection.Default = connection
|
||||||
return fmt.Errorf("%q destination is not defined. See \"podman system connection add ...\" to create a connection", args[0])
|
return nil
|
||||||
}
|
})
|
||||||
|
|
||||||
cfg.Engine.ActiveService = args[0]
|
|
||||||
return cfg.Write()
|
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ var (
|
|||||||
func init() {
|
func init() {
|
||||||
initFlags := func(cmd *cobra.Command) {
|
initFlags := func(cmd *cobra.Command) {
|
||||||
cmd.Flags().StringP("format", "f", "", "Custom Go template for printing connections")
|
cmd.Flags().StringP("format", "f", "", "Custom Go template for printing connections")
|
||||||
_ = cmd.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(&namedDestination{}))
|
_ = cmd.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(&config.Connection{}))
|
||||||
cmd.Flags().BoolP("quiet", "q", false, "Custom Go template for printing connections")
|
cmd.Flags().BoolP("quiet", "q", false, "Custom Go template for printing connections")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,22 +62,11 @@ func init() {
|
|||||||
initFlags(inspectCmd)
|
initFlags(inspectCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
type namedDestination struct {
|
|
||||||
Name string
|
|
||||||
config.Destination
|
|
||||||
Default bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func list(cmd *cobra.Command, _ []string) error {
|
func list(cmd *cobra.Command, _ []string) error {
|
||||||
return inspect(cmd, nil)
|
return inspect(cmd, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func inspect(cmd *cobra.Command, args []string) error {
|
func inspect(cmd *cobra.Command, args []string) error {
|
||||||
cfg, err := config.ReadCustomConfig()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
format := cmd.Flag("format").Value.String()
|
format := cmd.Flag("format").Value.String()
|
||||||
if format == "" && args != nil {
|
if format == "" && args != nil {
|
||||||
format = "json"
|
format = "json"
|
||||||
@ -87,31 +76,23 @@ func inspect(cmd *cobra.Command, args []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
rows := make([]namedDestination, 0)
|
|
||||||
for k, v := range cfg.Engine.ServiceDestinations {
|
cons, err := registry.PodmanConfig().ContainersConfDefaultsRO.GetAllConnections()
|
||||||
if args != nil && !slices.Contains(args, k) {
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rows := make([]config.Connection, 0, len(cons))
|
||||||
|
for _, con := range cons {
|
||||||
|
if args != nil && !slices.Contains(args, con.Name) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if quiet {
|
if quiet {
|
||||||
fmt.Println(k)
|
fmt.Println(con.Name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
def := false
|
|
||||||
if k == cfg.Engine.ActiveService {
|
|
||||||
def = true
|
|
||||||
}
|
|
||||||
|
|
||||||
r := namedDestination{
|
rows = append(rows, con)
|
||||||
Name: k,
|
|
||||||
Destination: config.Destination{
|
|
||||||
Identity: v.Identity,
|
|
||||||
URI: v.URI,
|
|
||||||
IsMachine: v.IsMachine,
|
|
||||||
},
|
|
||||||
Default: def,
|
|
||||||
}
|
|
||||||
rows = append(rows, r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if quiet {
|
if quiet {
|
||||||
@ -137,7 +118,7 @@ func inspect(cmd *cobra.Command, args []string) error {
|
|||||||
rpt, err = rpt.Parse(report.OriginUser, format)
|
rpt, err = rpt.Parse(report.OriginUser, format)
|
||||||
} else {
|
} else {
|
||||||
rpt, err = rpt.Parse(report.OriginPodman,
|
rpt, err = rpt.Parse(report.OriginPodman,
|
||||||
"{{range .}}{{.Name}}\t{{.URI}}\t{{.Identity}}\t{{.Default}}\n{{end -}}")
|
"{{range .}}{{.Name}}\t{{.URI}}\t{{.Identity}}\t{{.Default}}\t{{.ReadWrite}}\n{{end -}}")
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -149,6 +130,7 @@ func inspect(cmd *cobra.Command, args []string) error {
|
|||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Name": "Name",
|
"Name": "Name",
|
||||||
"URI": "URI",
|
"URI": "URI",
|
||||||
|
"ReadWrite": "ReadWrite",
|
||||||
}})
|
}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -48,43 +48,35 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func rm(cmd *cobra.Command, args []string) error {
|
func rm(cmd *cobra.Command, args []string) error {
|
||||||
cfg, err := config.ReadCustomConfig()
|
return config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if rmOpts.All {
|
if rmOpts.All {
|
||||||
for k := range cfg.Engine.ServiceDestinations {
|
cfg.Connection.Connections = nil
|
||||||
delete(cfg.Engine.ServiceDestinations, k)
|
cfg.Connection.Default = ""
|
||||||
}
|
|
||||||
cfg.Engine.ActiveService = ""
|
|
||||||
|
|
||||||
// Clear all the connections in any existing farms
|
// Clear all the connections in any existing farms
|
||||||
for k := range cfg.Farms.List {
|
for k := range cfg.Farm.List {
|
||||||
cfg.Farms.List[k] = []string{}
|
cfg.Farm.List[k] = []string{}
|
||||||
}
|
}
|
||||||
return cfg.Write()
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return errors.New("accepts 1 arg(s), received 0")
|
return errors.New("accepts 1 arg(s), received 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Engine.ServiceDestinations != nil {
|
delete(cfg.Connection.Connections, args[0])
|
||||||
delete(cfg.Engine.ServiceDestinations, args[0])
|
if cfg.Connection.Default == args[0] {
|
||||||
}
|
cfg.Connection.Default = ""
|
||||||
|
|
||||||
if cfg.Engine.ActiveService == args[0] {
|
|
||||||
cfg.Engine.ActiveService = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are existing farm, remove the deleted connection that might be part of a farm
|
// If there are existing farm, remove the deleted connection that might be part of a farm
|
||||||
for k, v := range cfg.Farms.List {
|
for k, v := range cfg.Farm.List {
|
||||||
index := slices.Index(v, args[0])
|
index := slices.Index(v, args[0])
|
||||||
if index > -1 {
|
if index > -1 {
|
||||||
cfg.Farms.List[k] = append(v[:index], v[index+1:]...)
|
cfg.Farm.List[k] = append(v[:index], v[index+1:]...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg.Write()
|
return nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -33,21 +33,18 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func rename(cmd *cobra.Command, args []string) error {
|
func rename(cmd *cobra.Command, args []string) error {
|
||||||
cfg, err := config.ReadCustomConfig()
|
return config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
||||||
if err != nil {
|
if _, found := cfg.Connection.Connections[args[0]]; !found {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, found := cfg.Engine.ServiceDestinations[args[0]]; !found {
|
|
||||||
return fmt.Errorf("%q destination is not defined. See \"podman system connection add ...\" to create a connection", args[0])
|
return fmt.Errorf("%q destination is not defined. See \"podman system connection add ...\" to create a connection", args[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.Engine.ServiceDestinations[args[1]] = cfg.Engine.ServiceDestinations[args[0]]
|
cfg.Connection.Connections[args[1]] = cfg.Connection.Connections[args[0]]
|
||||||
delete(cfg.Engine.ServiceDestinations, args[0])
|
delete(cfg.Connection.Connections, args[0])
|
||||||
|
|
||||||
if cfg.Engine.ActiveService == args[0] {
|
if cfg.Connection.Default == args[0] {
|
||||||
cfg.Engine.ActiveService = args[1]
|
cfg.Connection.Default = args[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg.Write()
|
return nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -19,17 +19,18 @@ Change the default output format. This can be of a supported type like 'json' o
|
|||||||
Valid placeholders for the Go template listed below:
|
Valid placeholders for the Go template listed below:
|
||||||
|
|
||||||
| **Placeholder** | **Description** |
|
| **Placeholder** | **Description** |
|
||||||
| --------------- | ------------------------------------------ |
|
| --------------- | --------------------------------------------------------------------- |
|
||||||
| .Connections | List of all system connections in the farm |
|
| .Connections | List of all system connections in the farm |
|
||||||
| .Default | Indicates whether farm is the default |
|
| .Default | Indicates whether farm is the default |
|
||||||
| .Name | Farm name |
|
| .Name | Farm name |
|
||||||
|
| .ReadWrite | Indicates if this farm can be modified using the podman farm commands |
|
||||||
|
|
||||||
## EXAMPLE
|
## EXAMPLE
|
||||||
```
|
```
|
||||||
$ podman farm list
|
$ podman farm list
|
||||||
Name Connections Default
|
Name Connections Default ReadWrite
|
||||||
farm1 [f38 f37] false
|
farm1 [f38 f37] false true
|
||||||
farm2 [f37] true
|
farm2 [f37] true true
|
||||||
```
|
```
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
**[podman(1)](podman.1.md)**, **[podman-farm(1)](podman-farm.1.md)**
|
**[podman(1)](podman.1.md)**, **[podman-farm(1)](podman-farm.1.md)**
|
||||||
|
@ -23,6 +23,7 @@ Valid placeholders for the Go template listed below:
|
|||||||
| .Default | Indicates whether connection is the default |
|
| .Default | Indicates whether connection is the default |
|
||||||
| .Identity | Path to file containing SSH identity |
|
| .Identity | Path to file containing SSH identity |
|
||||||
| .Name | Connection Name/Identifier |
|
| .Name | Connection Name/Identifier |
|
||||||
|
| .ReadWrite | Indicates if this connection can be modified using the system connection commands |
|
||||||
| .URI | URI to podman service. Valid schemes are ssh://[user@]*host*[:port]*Unix domain socket*[?secure=True], unix://*Unix domain socket*, and tcp://localhost[:*port*] |
|
| .URI | URI to podman service. Valid schemes are ssh://[user@]*host*[:port]*Unix domain socket*[?secure=True], unix://*Unix domain socket*, and tcp://localhost[:*port*] |
|
||||||
|
|
||||||
#### **--quiet**, **-q**
|
#### **--quiet**, **-q**
|
||||||
@ -32,9 +33,9 @@ Only show connection names
|
|||||||
## EXAMPLE
|
## EXAMPLE
|
||||||
```
|
```
|
||||||
$ podman system connection list
|
$ podman system connection list
|
||||||
Name URI Identity Default
|
Name URI Identity Default ReadWrite
|
||||||
devl ssh://root@example.com:/run/podman/podman.sock ~/.ssh/id_rsa True
|
deva ssh://root@example.com:/run/podman/podman.sock ~/.ssh/id_rsa true true
|
||||||
devl ssh://user@example.com:/run/user/1000/podman/podman.sock ~/.ssh/id_rsa False
|
devb ssh://user@example.com:/run/user/1000/podman/podman.sock ~/.ssh/id_rsa false true
|
||||||
```
|
```
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
**[podman(1)](podman.1.md)**, **[podman-system(1)](podman-system.1.md)**, **[podman-system-connection(1)](podman-system-connection.1.md)**
|
**[podman(1)](podman.1.md)**, **[podman-system(1)](podman-system.1.md)**, **[podman-system-connection(1)](podman-system-connection.1.md)**
|
||||||
|
@ -252,6 +252,11 @@ Set default `--url` value to access Podman service. Automatically enables --remo
|
|||||||
|
|
||||||
Set default `--identity` path to ssh key file value used to access Podman service.
|
Set default `--identity` path to ssh key file value used to access Podman service.
|
||||||
|
|
||||||
|
#### **PODMAN_CONNECTIONS_CONF**
|
||||||
|
|
||||||
|
The path to the file where the system connections and farms created with `podman system connection add`
|
||||||
|
and `podman farm add` are stored, by default it uses `~/.config/containers/podman-connections.conf`.
|
||||||
|
|
||||||
#### **STORAGE_DRIVER**
|
#### **STORAGE_DRIVER**
|
||||||
|
|
||||||
Set default `--storage-driver` value.
|
Set default `--storage-driver` value.
|
||||||
|
6
go.mod
6
go.mod
@ -11,14 +11,14 @@ require (
|
|||||||
github.com/checkpoint-restore/go-criu/v7 v7.0.0
|
github.com/checkpoint-restore/go-criu/v7 v7.0.0
|
||||||
github.com/containernetworking/plugins v1.4.0
|
github.com/containernetworking/plugins v1.4.0
|
||||||
github.com/containers/buildah v1.33.2-0.20231121195905-d1a1c53c8e1c
|
github.com/containers/buildah v1.33.2-0.20231121195905-d1a1c53c8e1c
|
||||||
github.com/containers/common v0.57.1-0.20240129201029-3310a75e3608
|
github.com/containers/common v0.57.1-0.20240130143645-b26099256b92
|
||||||
github.com/containers/conmon v2.0.20+incompatible
|
github.com/containers/conmon v2.0.20+incompatible
|
||||||
github.com/containers/gvisor-tap-vsock v0.7.2
|
github.com/containers/gvisor-tap-vsock v0.7.2
|
||||||
github.com/containers/image/v5 v5.29.2-0.20240129204525-816800b5daf7
|
github.com/containers/image/v5 v5.29.2-0.20240130233108-e66a1ade2efc
|
||||||
github.com/containers/libhvee v0.6.0
|
github.com/containers/libhvee v0.6.0
|
||||||
github.com/containers/ocicrypt v1.1.9
|
github.com/containers/ocicrypt v1.1.9
|
||||||
github.com/containers/psgo v1.8.0
|
github.com/containers/psgo v1.8.0
|
||||||
github.com/containers/storage v1.52.1-0.20240129173630-7a525ce0e2bc
|
github.com/containers/storage v1.52.1-0.20240130205044-62997abeaf2f
|
||||||
github.com/coreos/go-systemd/v22 v22.5.1-0.20231103132048-7d375ecc2b09
|
github.com/coreos/go-systemd/v22 v22.5.1-0.20231103132048-7d375ecc2b09
|
||||||
github.com/coreos/stream-metadata-go v0.4.4
|
github.com/coreos/stream-metadata-go v0.4.4
|
||||||
github.com/crc-org/vfkit v0.5.0
|
github.com/crc-org/vfkit v0.5.0
|
||||||
|
12
go.sum
12
go.sum
@ -257,14 +257,14 @@ github.com/containernetworking/plugins v1.4.0 h1:+w22VPYgk7nQHw7KT92lsRmuToHvb7w
|
|||||||
github.com/containernetworking/plugins v1.4.0/go.mod h1:UYhcOyjefnrQvKvmmyEKsUA+M9Nfn7tqULPpH0Pkcj0=
|
github.com/containernetworking/plugins v1.4.0/go.mod h1:UYhcOyjefnrQvKvmmyEKsUA+M9Nfn7tqULPpH0Pkcj0=
|
||||||
github.com/containers/buildah v1.33.2-0.20231121195905-d1a1c53c8e1c h1:E7nxvH3N3kpyson0waJv1X+eY9hAs+x2zQswsK+//yY=
|
github.com/containers/buildah v1.33.2-0.20231121195905-d1a1c53c8e1c h1:E7nxvH3N3kpyson0waJv1X+eY9hAs+x2zQswsK+//yY=
|
||||||
github.com/containers/buildah v1.33.2-0.20231121195905-d1a1c53c8e1c/go.mod h1:oMNfVrZGEfWVOxXTNOYPMdZzDfSo2umURK/TO0d8TRk=
|
github.com/containers/buildah v1.33.2-0.20231121195905-d1a1c53c8e1c/go.mod h1:oMNfVrZGEfWVOxXTNOYPMdZzDfSo2umURK/TO0d8TRk=
|
||||||
github.com/containers/common v0.57.1-0.20240129201029-3310a75e3608 h1:P+3HLEBeuFr/XcFtyZIS8uk5zdbcvtrHKCSzHlUUbdY=
|
github.com/containers/common v0.57.1-0.20240130143645-b26099256b92 h1:Q60+ofGhDjVxY5lvYmmcVN8aeS9gtQ6pAn/pyLh7rRM=
|
||||||
github.com/containers/common v0.57.1-0.20240129201029-3310a75e3608/go.mod h1:Na7hGh5WnmB0RdGkKyb6JQb6DtKrs5qoIGrPucuR8t0=
|
github.com/containers/common v0.57.1-0.20240130143645-b26099256b92/go.mod h1:Na7hGh5WnmB0RdGkKyb6JQb6DtKrs5qoIGrPucuR8t0=
|
||||||
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
|
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
|
||||||
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
|
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
|
||||||
github.com/containers/gvisor-tap-vsock v0.7.2 h1:6CyU5D85C0/DciRRd7W0bPljK4FAS+DPrrHEQMHfZKY=
|
github.com/containers/gvisor-tap-vsock v0.7.2 h1:6CyU5D85C0/DciRRd7W0bPljK4FAS+DPrrHEQMHfZKY=
|
||||||
github.com/containers/gvisor-tap-vsock v0.7.2/go.mod h1:6NiTxh2GCVxZQLPzfuEB78/Osp2Usd9uf6nLdd6PiUY=
|
github.com/containers/gvisor-tap-vsock v0.7.2/go.mod h1:6NiTxh2GCVxZQLPzfuEB78/Osp2Usd9uf6nLdd6PiUY=
|
||||||
github.com/containers/image/v5 v5.29.2-0.20240129204525-816800b5daf7 h1:xnnFpYdUjDn2MZYXmvcopGEvWVO/J0V8OexEnlnIGf0=
|
github.com/containers/image/v5 v5.29.2-0.20240130233108-e66a1ade2efc h1:3I5+mrrG7Fuv4aA13t1hAMQcjN3rTAQInfbxa5P+XH4=
|
||||||
github.com/containers/image/v5 v5.29.2-0.20240129204525-816800b5daf7/go.mod h1:op1w+ftmdbE3UNW/6as8mruL1i5AMq6nH+btNOykMcU=
|
github.com/containers/image/v5 v5.29.2-0.20240130233108-e66a1ade2efc/go.mod h1:oMMRA6avp1Na54lVPCj/OvcfXDMLlzfy3H7xeRiWmmI=
|
||||||
github.com/containers/libhvee v0.6.0 h1:tUzwSz8R0GjR6IctgDnkTMjdtCk5Mxhpai4Vyv6UeF4=
|
github.com/containers/libhvee v0.6.0 h1:tUzwSz8R0GjR6IctgDnkTMjdtCk5Mxhpai4Vyv6UeF4=
|
||||||
github.com/containers/libhvee v0.6.0/go.mod h1:f/q1wCdQqOLiK3IZqqBfOD7exMZYBU5pDYsrMa/pSFg=
|
github.com/containers/libhvee v0.6.0/go.mod h1:f/q1wCdQqOLiK3IZqqBfOD7exMZYBU5pDYsrMa/pSFg=
|
||||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
|
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
|
||||||
@ -279,8 +279,8 @@ github.com/containers/ocicrypt v1.1.9/go.mod h1:dTKx1918d8TDkxXvarscpNVY+lyPakPN
|
|||||||
github.com/containers/psgo v1.8.0 h1:2loGekmGAxM9ir5OsXWEfGwFxorMPYnc6gEDsGFQvhY=
|
github.com/containers/psgo v1.8.0 h1:2loGekmGAxM9ir5OsXWEfGwFxorMPYnc6gEDsGFQvhY=
|
||||||
github.com/containers/psgo v1.8.0/go.mod h1:T8ZxnX3Ur4RvnhxFJ7t8xJ1F48RhiZB4rSrOaR/qGHc=
|
github.com/containers/psgo v1.8.0/go.mod h1:T8ZxnX3Ur4RvnhxFJ7t8xJ1F48RhiZB4rSrOaR/qGHc=
|
||||||
github.com/containers/storage v1.43.0/go.mod h1:uZ147thiIFGdVTjMmIw19knttQnUCl3y9zjreHrg11s=
|
github.com/containers/storage v1.43.0/go.mod h1:uZ147thiIFGdVTjMmIw19knttQnUCl3y9zjreHrg11s=
|
||||||
github.com/containers/storage v1.52.1-0.20240129173630-7a525ce0e2bc h1:Cfv5hg2OtNZnIZLfOVmLjObX0DuJb+aqkTl+2+dNweA=
|
github.com/containers/storage v1.52.1-0.20240130205044-62997abeaf2f h1:BJSLHe7f1tgu53d8mGIK/y2KhEev5lggWlIk1rWYT7k=
|
||||||
github.com/containers/storage v1.52.1-0.20240129173630-7a525ce0e2bc/go.mod h1:T/ZMocbhShnMLIF0pdkiLPwpkwlGlyUWJeSXnfC/uew=
|
github.com/containers/storage v1.52.1-0.20240130205044-62997abeaf2f/go.mod h1:T/ZMocbhShnMLIF0pdkiLPwpkwlGlyUWJeSXnfC/uew=
|
||||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||||
|
@ -33,11 +33,6 @@ func ExecuteTransfer(src, dst string, parentFlags []string, quiet bool, sshMode
|
|||||||
return nil, nil, nil, nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
confR, err := config.New(nil) // create a hand made config for the remote engine since we might use remote and native at once
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, nil, fmt.Errorf("could not make config: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
locations := []*entities.ImageScpOptions{}
|
locations := []*entities.ImageScpOptions{}
|
||||||
cliConnections := []string{}
|
cliConnections := []string{}
|
||||||
args := []string{src}
|
args := []string{src}
|
||||||
@ -84,17 +79,15 @@ func ExecuteTransfer(src, dst string, parentFlags []string, quiet bool, sshMode
|
|||||||
cliConnections = []string{}
|
cliConnections = []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig() // get ready to set ssh destination if necessary
|
cfg, err := config.Default()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
var serv map[string]config.Destination
|
err = GetServiceInformation(&sshInfo, cliConnections, cfg)
|
||||||
serv, err = GetServiceInformation(&sshInfo, cliConnections, cfg)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, nil, err
|
return nil, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
confR.Engine = config.EngineConfig{Remote: true, CgroupManager: "cgroupfs", ServiceDestinations: serv} // pass the service dest (either remote or something else) to engine
|
|
||||||
saveCmd, loadCmd := CreateCommands(source, dest, parentFlags, podman)
|
saveCmd, loadCmd := CreateCommands(source, dest, parentFlags, podman)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
@ -401,15 +394,15 @@ func RemoteArgLength(input string, side int) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetServiceInformation takes the parsed list of hosts to connect to and validates the information
|
// GetServiceInformation takes the parsed list of hosts to connect to and validates the information
|
||||||
func GetServiceInformation(sshInfo *entities.ImageScpConnections, cliConnections []string, cfg *config.Config) (map[string]config.Destination, error) {
|
func GetServiceInformation(sshInfo *entities.ImageScpConnections, cliConnections []string, cfg *config.Config) error {
|
||||||
var serv map[string]config.Destination
|
|
||||||
var urlS string
|
var urlS string
|
||||||
var iden string
|
var iden string
|
||||||
for i, val := range cliConnections {
|
for i, val := range cliConnections {
|
||||||
connection, _, _ := strings.Cut(val, "::")
|
connection, _, _ := strings.Cut(val, "::")
|
||||||
sshInfo.Connections = append(sshInfo.Connections, connection)
|
sshInfo.Connections = append(sshInfo.Connections, connection)
|
||||||
conn, found := cfg.Engine.ServiceDestinations[sshInfo.Connections[i]]
|
conn, err := cfg.GetConnection(sshInfo.Connections[i], false)
|
||||||
if found {
|
if err == nil {
|
||||||
|
// connection found
|
||||||
urlS = conn.URI
|
urlS = conn.URI
|
||||||
iden = conn.Identity
|
iden = conn.Identity
|
||||||
} else { // no match, warn user and do a manual connection.
|
} else { // no match, warn user and do a manual connection.
|
||||||
@ -419,17 +412,17 @@ func GetServiceInformation(sshInfo *entities.ImageScpConnections, cliConnections
|
|||||||
}
|
}
|
||||||
urlFinal, err := url.Parse(urlS) // create an actual url to pass to exec command
|
urlFinal, err := url.Parse(urlS) // create an actual url to pass to exec command
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if urlFinal.User.Username() == "" {
|
if urlFinal.User.Username() == "" {
|
||||||
if urlFinal.User, err = GetUserInfo(urlFinal); err != nil {
|
if urlFinal.User, err = GetUserInfo(urlFinal); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sshInfo.URI = append(sshInfo.URI, urlFinal)
|
sshInfo.URI = append(sshInfo.URI, urlFinal)
|
||||||
sshInfo.Identities = append(sshInfo.Identities, iden)
|
sshInfo.Identities = append(sshInfo.Identities, iden)
|
||||||
}
|
}
|
||||||
return serv, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUserInfo(uri *url.URL) (*url.Userinfo, error) {
|
func GetUserInfo(uri *url.URL) (*url.Userinfo, error) {
|
||||||
|
@ -32,7 +32,7 @@ type Schedule struct {
|
|||||||
platformBuilders map[string]string // target->connection
|
platformBuilders map[string]string // target->connection
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFarmWithBuilders(_ context.Context, name string, destinations *map[string]config.Destination, localEngine entities.ImageEngine, buildLocal bool) (*Farm, error) {
|
func newFarmWithBuilders(_ context.Context, name string, cons []config.Connection, localEngine entities.ImageEngine, buildLocal bool) (*Farm, error) {
|
||||||
farm := &Farm{
|
farm := &Farm{
|
||||||
builders: make(map[string]entities.ImageEngine),
|
builders: make(map[string]entities.ImageEngine),
|
||||||
localEngine: localEngine,
|
localEngine: localEngine,
|
||||||
@ -43,22 +43,22 @@ func newFarmWithBuilders(_ context.Context, name string, destinations *map[strin
|
|||||||
builderGroup multierror.Group
|
builderGroup multierror.Group
|
||||||
)
|
)
|
||||||
// Set up the remote connections to handle the builds
|
// Set up the remote connections to handle the builds
|
||||||
for name, dest := range *destinations {
|
for _, con := range cons {
|
||||||
name, dest := name, dest
|
con := con
|
||||||
builderGroup.Go(func() error {
|
builderGroup.Go(func() error {
|
||||||
fmt.Printf("Connecting to %q\n", name)
|
fmt.Printf("Connecting to %q\n", con.Name)
|
||||||
engine, err := infra.NewImageEngine(&entities.PodmanConfig{
|
engine, err := infra.NewImageEngine(&entities.PodmanConfig{
|
||||||
EngineMode: entities.TunnelMode,
|
EngineMode: entities.TunnelMode,
|
||||||
URI: dest.URI,
|
URI: con.URI,
|
||||||
Identity: dest.Identity,
|
Identity: con.Identity,
|
||||||
MachineMode: dest.IsMachine,
|
MachineMode: con.IsMachine,
|
||||||
FarmNodeName: name,
|
FarmNodeName: con.Name,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("initializing image engine at %q: %w", dest.URI, err)
|
return fmt.Errorf("initializing image engine at %q: %w", con.URI, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer fmt.Printf("Builder %q ready\n", name)
|
defer fmt.Printf("Builder %q ready\n", con.Name)
|
||||||
builderMutex.Lock()
|
builderMutex.Lock()
|
||||||
defer builderMutex.Unlock()
|
defer builderMutex.Unlock()
|
||||||
farm.builders[name] = engine
|
farm.builders[name] = engine
|
||||||
@ -90,12 +90,12 @@ func newFarmWithBuilders(_ context.Context, name string, destinations *map[strin
|
|||||||
|
|
||||||
func NewFarm(ctx context.Context, name string, localEngine entities.ImageEngine, buildLocal bool) (*Farm, error) {
|
func NewFarm(ctx context.Context, name string, localEngine entities.ImageEngine, buildLocal bool) (*Farm, error) {
|
||||||
// Get the destinations of the connections specified in the farm
|
// Get the destinations of the connections specified in the farm
|
||||||
destinations, err := getFarmDestinations(name)
|
name, destinations, err := getFarmDestinations(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return newFarmWithBuilders(ctx, name, &destinations, localEngine, buildLocal)
|
return newFarmWithBuilders(ctx, name, destinations, localEngine, buildLocal)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done performs any necessary end-of-process cleanup for the farm's members.
|
// Done performs any necessary end-of-process cleanup for the farm's members.
|
||||||
@ -460,22 +460,21 @@ func (f *Farm) Build(ctx context.Context, schedule Schedule, options entities.Bu
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFarmDestinations(name string) (map[string]config.Destination, error) {
|
func getFarmDestinations(name string) (string, []config.Connection, error) {
|
||||||
dest := make(map[string]config.Destination)
|
cfg, err := config.Default()
|
||||||
cfg, err := config.ReadCustomConfig()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dest, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no farm name is given, then grab all the service destinations available
|
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return cfg.Engine.ServiceDestinations, nil
|
if name, cons, err := cfg.GetDefaultFarmConnections(); err == nil {
|
||||||
|
// Use default farm if is there is one
|
||||||
|
return name, cons, nil
|
||||||
}
|
}
|
||||||
|
// If no farm name is given, then grab all the service destinations available
|
||||||
// Go through the connections in the farm and get their destination
|
cons, err := cfg.GetAllConnections()
|
||||||
for _, c := range cfg.Farms.List[name] {
|
return name, cons, err
|
||||||
dest[c] = cfg.Engine.ServiceDestinations[c]
|
|
||||||
}
|
}
|
||||||
|
cons, err := cfg.GetFarmConnections(name)
|
||||||
return dest, nil
|
return name, cons, err
|
||||||
}
|
}
|
||||||
|
@ -17,93 +17,81 @@ func AddConnection(uri fmt.Stringer, name, identity string, isDefault bool) erro
|
|||||||
if len(identity) < 1 {
|
if len(identity) < 1 {
|
||||||
return errors.New("identity must be defined")
|
return errors.New("identity must be defined")
|
||||||
}
|
}
|
||||||
cfg, err := config.ReadCustomConfig()
|
|
||||||
if err != nil {
|
return config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
||||||
return err
|
if _, ok := cfg.Connection.Connections[name]; ok {
|
||||||
}
|
|
||||||
if _, ok := cfg.Engine.ServiceDestinations[name]; ok {
|
|
||||||
return errors.New("cannot overwrite connection")
|
return errors.New("cannot overwrite connection")
|
||||||
}
|
}
|
||||||
if isDefault {
|
|
||||||
cfg.Engine.ActiveService = name
|
|
||||||
}
|
|
||||||
dst := config.Destination{
|
dst := config.Destination{
|
||||||
URI: uri.String(),
|
URI: uri.String(),
|
||||||
IsMachine: true,
|
IsMachine: true,
|
||||||
|
Identity: identity,
|
||||||
}
|
}
|
||||||
dst.Identity = identity
|
|
||||||
if cfg.Engine.ServiceDestinations == nil {
|
if isDefault {
|
||||||
cfg.Engine.ServiceDestinations = map[string]config.Destination{
|
cfg.Connection.Default = name
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.Connection.Connections == nil {
|
||||||
|
cfg.Connection.Connections = map[string]config.Destination{
|
||||||
name: dst,
|
name: dst,
|
||||||
}
|
}
|
||||||
cfg.Engine.ActiveService = name
|
cfg.Connection.Default = name
|
||||||
} else {
|
} else {
|
||||||
cfg.Engine.ServiceDestinations[name] = dst
|
cfg.Connection.Connections[name] = dst
|
||||||
}
|
|
||||||
return cfg.Write()
|
|
||||||
}
|
|
||||||
|
|
||||||
func AnyConnectionDefault(name ...string) (bool, error) {
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
for _, n := range name {
|
|
||||||
if n == cfg.Engine.ActiveService {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false, nil
|
return nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func ChangeConnectionURI(name string, uri fmt.Stringer) error {
|
func ChangeConnectionURI(name string, uri fmt.Stringer) error {
|
||||||
cfg, err := config.ReadCustomConfig()
|
return config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
||||||
if err != nil {
|
dst, ok := cfg.Connection.Connections[name]
|
||||||
return err
|
|
||||||
}
|
|
||||||
dst, ok := cfg.Engine.ServiceDestinations[name]
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("connection not found")
|
return errors.New("connection not found")
|
||||||
}
|
}
|
||||||
dst.URI = uri.String()
|
dst.URI = uri.String()
|
||||||
cfg.Engine.ServiceDestinations[name] = dst
|
cfg.Connection.Connections[name] = dst
|
||||||
|
|
||||||
return cfg.Write()
|
return nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func ChangeDefault(name string) error {
|
// UpdateConnectionIfDefault updates the default connection to the rootful/rootless when depending
|
||||||
cfg, err := config.ReadCustomConfig()
|
// on the bool but only if other rootful/less connection was already the default.
|
||||||
if err != nil {
|
// Returns true if it modified the default
|
||||||
return err
|
func UpdateConnectionIfDefault(rootful bool, name, rootfulName string) error {
|
||||||
|
return config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
||||||
|
if name == cfg.Connection.Default && rootful {
|
||||||
|
cfg.Connection.Default = rootfulName
|
||||||
|
} else if rootfulName == cfg.Connection.Default && !rootful {
|
||||||
|
cfg.Connection.Default = name
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
cfg.Engine.ActiveService = name
|
})
|
||||||
|
|
||||||
return cfg.Write()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemoveConnections(names ...string) error {
|
func RemoveConnections(names ...string) error {
|
||||||
cfg, err := config.ReadCustomConfig()
|
return config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
if _, ok := cfg.Engine.ServiceDestinations[name]; ok {
|
if _, ok := cfg.Connection.Connections[name]; ok {
|
||||||
delete(cfg.Engine.ServiceDestinations, name)
|
delete(cfg.Connection.Connections, name)
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("unable to find connection named %q", name)
|
return fmt.Errorf("unable to find connection named %q", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Engine.ActiveService == name {
|
if cfg.Connection.Default == name {
|
||||||
cfg.Engine.ActiveService = ""
|
cfg.Connection.Default = ""
|
||||||
for service := range cfg.Engine.ServiceDestinations {
|
}
|
||||||
cfg.Engine.ActiveService = service
|
}
|
||||||
|
for service := range cfg.Connection.Connections {
|
||||||
|
cfg.Connection.Default = service
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
return nil
|
||||||
}
|
})
|
||||||
return cfg.Write()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// removeFilesAndConnections removes any files and connections with the given names
|
// removeFilesAndConnections removes any files and connections with the given names
|
||||||
|
@ -158,22 +158,7 @@ following command in your terminal session:
|
|||||||
// SetRootful modifies the machine's default connection to be either rootful or
|
// SetRootful modifies the machine's default connection to be either rootful or
|
||||||
// rootless
|
// rootless
|
||||||
func SetRootful(rootful bool, name, rootfulName string) error {
|
func SetRootful(rootful bool, name, rootfulName string) error {
|
||||||
changeCon, err := AnyConnectionDefault(name, rootfulName)
|
return UpdateConnectionIfDefault(rootful, name, rootfulName)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if changeCon {
|
|
||||||
newDefault := name
|
|
||||||
if rootful {
|
|
||||||
newDefault += "-root"
|
|
||||||
}
|
|
||||||
err := ChangeDefault(newDefault)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteConfig writes the machine's JSON config file
|
// WriteConfig writes the machine's JSON config file
|
||||||
|
@ -122,6 +122,7 @@ var (
|
|||||||
// invalid containers.conf files to fail the cleanup.
|
// invalid containers.conf files to fail the cleanup.
|
||||||
os.Unsetenv("CONTAINERS_CONF")
|
os.Unsetenv("CONTAINERS_CONF")
|
||||||
os.Unsetenv("CONTAINERS_CONF_OVERRIDE")
|
os.Unsetenv("CONTAINERS_CONF_OVERRIDE")
|
||||||
|
os.Unsetenv("PODMAN_CONNECTIONS_CONF")
|
||||||
podmanTest.Cleanup()
|
podmanTest.Cleanup()
|
||||||
f := CurrentSpecReport()
|
f := CurrentSpecReport()
|
||||||
processTestResult(f)
|
processTestResult(f)
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/config"
|
|
||||||
. "github.com/containers/podman/v4/test/utils"
|
. "github.com/containers/podman/v4/test/utils"
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
@ -13,21 +12,20 @@ import (
|
|||||||
|
|
||||||
func setupContainersConfWithSystemConnections() {
|
func setupContainersConfWithSystemConnections() {
|
||||||
// make sure connections are not written to real user config on host
|
// make sure connections are not written to real user config on host
|
||||||
file := filepath.Join(podmanTest.TempDir, "containersconf")
|
file := filepath.Join(podmanTest.TempDir, "containers.conf")
|
||||||
f, err := os.Create(file)
|
f, err := os.Create(file)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
connections := `
|
|
||||||
[engine]
|
|
||||||
active_service = "QA"
|
|
||||||
[engine.service_destinations]
|
|
||||||
[engine.service_destinations.QA]
|
|
||||||
uri = "ssh://root@podman.test:2222/run/podman/podman.sock"
|
|
||||||
[engine.service_destinations.QB]
|
|
||||||
uri = "ssh://root@podman.test:3333/run/podman/podman.sock"`
|
|
||||||
_, err = f.WriteString(connections)
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
f.Close()
|
f.Close()
|
||||||
os.Setenv("CONTAINERS_CONF", file)
|
os.Setenv("CONTAINERS_CONF", file)
|
||||||
|
|
||||||
|
file = filepath.Join(podmanTest.TempDir, "connections.conf")
|
||||||
|
f, err = os.Create(file)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
connections := `{"connection":{"default":"QA","connections":{"QA":{"uri":"ssh://root@podman.test:2222/run/podman/podman.sock"},"QB":{"uri":"ssh://root@podman.test:3333/run/podman/podman.sock"}}}}`
|
||||||
|
_, err = f.WriteString(connections)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
f.Close()
|
||||||
|
os.Setenv("PODMAN_CONNECTIONS_CONF", file)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = Describe("podman farm", func() {
|
var _ = Describe("podman farm", func() {
|
||||||
@ -36,19 +34,12 @@ var _ = Describe("podman farm", func() {
|
|||||||
|
|
||||||
Context("without running API service", func() {
|
Context("without running API service", func() {
|
||||||
It("verify system connections exist", func() {
|
It("verify system connections exist", func() {
|
||||||
cfg, err := config.ReadCustomConfig()
|
session := podmanTest.Podman(systemConnectionListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg).Should(HaveActiveService("QA"))
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg).Should(VerifyService(
|
Expect(string(session.Out.Contents())).To(Equal(`QA ssh://root@podman.test:2222/run/podman/podman.sock true true
|
||||||
"QA",
|
QB ssh://root@podman.test:3333/run/podman/podman.sock false true
|
||||||
"ssh://root@podman.test:2222/run/podman/podman.sock",
|
`))
|
||||||
"",
|
|
||||||
))
|
|
||||||
Expect(cfg).Should(VerifyService(
|
|
||||||
"QB",
|
|
||||||
"ssh://root@podman.test:3333/run/podman/podman.sock",
|
|
||||||
"",
|
|
||||||
))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("create farm", func() {
|
It("create farm", func() {
|
||||||
@ -73,12 +64,13 @@ var _ = Describe("podman farm", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm3\" created"))
|
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm3\" created"))
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
session = podmanTest.Podman(farmListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg.Farms.Default).Should(Equal("farm1"))
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm1", []string{"QA", "QB"}))
|
Expect(string(session.Out.Contents())).To(Equal(`farm1 [QA QB] true true
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm2", []string{"QA"}))
|
farm2 [QA] false true
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm3", []string{}))
|
farm3 [] false true
|
||||||
|
`))
|
||||||
|
|
||||||
// create existing farm should exit with error
|
// create existing farm should exit with error
|
||||||
cmd = []string{"farm", "create", "farm3"}
|
cmd = []string{"farm", "create", "farm3"}
|
||||||
@ -109,12 +101,13 @@ var _ = Describe("podman farm", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm3\" created"))
|
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm3\" created"))
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
session = podmanTest.Podman(farmListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg.Farms.Default).Should(Equal("farm1"))
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm1", []string{"QA", "QB"}))
|
Expect(string(session.Out.Contents())).To(Equal(`farm1 [QA QB] true true
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm2", []string{"QA"}))
|
farm2 [QA] false true
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm3", []string{}))
|
farm3 [] false true
|
||||||
|
`))
|
||||||
|
|
||||||
// update farm1 to remove the QA connection from it
|
// update farm1 to remove the QA connection from it
|
||||||
cmd = []string{"farm", "update", "--remove", "QA,QB", "farm1"}
|
cmd = []string{"farm", "update", "--remove", "QA,QB", "farm1"}
|
||||||
@ -137,12 +130,13 @@ var _ = Describe("podman farm", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm2\" updated"))
|
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm2\" updated"))
|
||||||
|
|
||||||
cfg, err = config.ReadCustomConfig()
|
session = podmanTest.Podman(farmListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg.Farms.Default).Should(Equal("farm2"))
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm1", []string{}))
|
Expect(string(session.Out.Contents())).To(Equal(`farm1 [] false true
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm2", []string{"QA"}))
|
farm2 [QA] true true
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm3", []string{"QB"}))
|
farm3 [QB] false true
|
||||||
|
`))
|
||||||
|
|
||||||
// update farm2 to not be the default, no farms should be the default
|
// update farm2 to not be the default, no farms should be the default
|
||||||
cmd = []string{"farm", "update", "--default=false", "farm2"}
|
cmd = []string{"farm", "update", "--default=false", "farm2"}
|
||||||
@ -151,9 +145,13 @@ var _ = Describe("podman farm", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm2\" updated"))
|
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm2\" updated"))
|
||||||
|
|
||||||
cfg, err = config.ReadCustomConfig()
|
session = podmanTest.Podman(farmListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg.Farms.Default).Should(BeEmpty())
|
Expect(session).Should(ExitCleanly())
|
||||||
|
Expect(string(session.Out.Contents())).To(Equal(`farm1 [] false true
|
||||||
|
farm2 [QA] false true
|
||||||
|
farm3 [QB] false true
|
||||||
|
`))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("update farm with non-existing connections", func() {
|
It("update farm with non-existing connections", func() {
|
||||||
@ -171,11 +169,12 @@ var _ = Describe("podman farm", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm2\" created"))
|
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm2\" created"))
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
session = podmanTest.Podman(farmListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg.Farms.Default).Should(Equal("farm1"))
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm1", []string{"QA", "QB"}))
|
Expect(string(session.Out.Contents())).To(Equal(`farm1 [QA QB] true true
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm2", []string{"QA"}))
|
farm2 [QA] false true
|
||||||
|
`))
|
||||||
|
|
||||||
// update farm1 to add no-node connection to it
|
// update farm1 to add no-node connection to it
|
||||||
cmd = []string{"farm", "update", "--add", "no-node", "farm1"}
|
cmd = []string{"farm", "update", "--add", "no-node", "farm1"}
|
||||||
@ -189,12 +188,13 @@ var _ = Describe("podman farm", func() {
|
|||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session).Should(ExitWithError())
|
Expect(session).Should(ExitWithError())
|
||||||
|
|
||||||
// read config again to ensure that nothing has changed
|
// check again to ensure that nothing has changed
|
||||||
cfg, err = config.ReadCustomConfig()
|
session = podmanTest.Podman(farmListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg.Farms.Default).Should(Equal("farm1"))
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm1", []string{"QA", "QB"}))
|
Expect(string(session.Out.Contents())).To(Equal(`farm1 [QA QB] true true
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm2", []string{"QA"}))
|
farm2 [QA] false true
|
||||||
|
`))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("update non-existent farm", func() {
|
It("update non-existent farm", func() {
|
||||||
@ -205,11 +205,6 @@ var _ = Describe("podman farm", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm1\" created"))
|
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm1\" created"))
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
|
||||||
Expect(cfg.Farms.Default).Should(Equal("farm1"))
|
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm1", []string{"QA", "QB"}))
|
|
||||||
|
|
||||||
// update non-existent farm to add QA connection to it
|
// update non-existent farm to add QA connection to it
|
||||||
cmd = []string{"farm", "update", "--add", "no-node", "non-existent"}
|
cmd = []string{"farm", "update", "--add", "no-node", "non-existent"}
|
||||||
session = podmanTest.Podman(cmd)
|
session = podmanTest.Podman(cmd)
|
||||||
@ -222,11 +217,10 @@ var _ = Describe("podman farm", func() {
|
|||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session).Should(ExitWithError())
|
Expect(session).Should(ExitWithError())
|
||||||
|
|
||||||
// read config again and ensure nothing has changed
|
session = podmanTest.Podman(farmListCmd)
|
||||||
cfg, err = config.ReadCustomConfig()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg.Farms.Default).Should(Equal("farm1"))
|
Expect(session.OutputToString()).To(Equal(`farm1 [QA QB] true true`))
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm1", []string{"QA", "QB"}))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("remove farms", func() {
|
It("remove farms", func() {
|
||||||
@ -244,11 +238,12 @@ var _ = Describe("podman farm", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm2\" created"))
|
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm2\" created"))
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
session = podmanTest.Podman(farmListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg.Farms.Default).Should(Equal("farm1"))
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm1", []string{"QA", "QB"}))
|
Expect(string(session.Out.Contents())).To(Equal(`farm1 [QA QB] true true
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm2", []string{"QA"}))
|
farm2 [QA] false true
|
||||||
|
`))
|
||||||
|
|
||||||
// remove farm1 and a non-existent farm
|
// remove farm1 and a non-existent farm
|
||||||
// farm 1 should be removed and a warning printed for nonexistent-farm
|
// farm 1 should be removed and a warning printed for nonexistent-farm
|
||||||
@ -259,11 +254,10 @@ var _ = Describe("podman farm", func() {
|
|||||||
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm1\" deleted"))
|
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm1\" deleted"))
|
||||||
Expect(session.ErrorToString()).Should(ContainSubstring("doesn't exist; nothing to remove"))
|
Expect(session.ErrorToString()).Should(ContainSubstring("doesn't exist; nothing to remove"))
|
||||||
|
|
||||||
cfg, err = config.ReadCustomConfig()
|
session = podmanTest.Podman(farmListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg.Farms.Default).Should(Equal("farm2"))
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm2", []string{"QA"}))
|
Expect(session.OutputToString()).To(Equal(`farm2 [QA] true true`))
|
||||||
Expect(cfg.Farms.List).Should(Not(HaveKey("farm1")))
|
|
||||||
|
|
||||||
// remove all non-existent farms and expect an error
|
// remove all non-existent farms and expect an error
|
||||||
cmd = []string{"farm", "rm", "foo", "bar"}
|
cmd = []string{"farm", "rm", "foo", "bar"}
|
||||||
@ -287,12 +281,6 @@ var _ = Describe("podman farm", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm2\" created"))
|
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"farm2\" created"))
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
|
||||||
Expect(cfg.Farms.Default).Should(Equal("farm1"))
|
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm1", []string{"QA", "QB"}))
|
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm2", []string{"QA"}))
|
|
||||||
|
|
||||||
// remove --all
|
// remove --all
|
||||||
cmd = []string{"farm", "rm", "--all"}
|
cmd = []string{"farm", "rm", "--all"}
|
||||||
session = podmanTest.Podman(cmd)
|
session = podmanTest.Podman(cmd)
|
||||||
@ -300,10 +288,10 @@ var _ = Describe("podman farm", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(ContainSubstring("All farms have been deleted"))
|
Expect(session.Out.Contents()).Should(ContainSubstring("All farms have been deleted"))
|
||||||
|
|
||||||
cfg, err = config.ReadCustomConfig()
|
session = podmanTest.Podman(farmListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg.Farms.Default).Should(BeEmpty())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg.Farms.List).Should(BeEmpty())
|
Expect(session.OutputToString()).To(Equal(""))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/config"
|
|
||||||
. "github.com/containers/podman/v4/test/utils"
|
. "github.com/containers/podman/v4/test/utils"
|
||||||
"github.com/containers/storage/pkg/homedir"
|
"github.com/containers/storage/pkg/homedir"
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
@ -13,7 +12,7 @@ import (
|
|||||||
|
|
||||||
var _ = Describe("podman image scp", func() {
|
var _ = Describe("podman image scp", func() {
|
||||||
|
|
||||||
BeforeEach(setupEmptyContainersConf)
|
BeforeEach(setupConnectionsConf)
|
||||||
|
|
||||||
It("podman image scp bogus image", func() {
|
It("podman image scp bogus image", func() {
|
||||||
scp := podmanTest.Podman([]string{"image", "scp", "FOOBAR"})
|
scp := podmanTest.Podman([]string{"image", "scp", "FOOBAR"})
|
||||||
@ -34,15 +33,6 @@ var _ = Describe("podman image scp", func() {
|
|||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
|
||||||
Expect(cfg.Engine).Should(HaveField("ActiveService", "QA"))
|
|
||||||
Expect(cfg.Engine.ServiceDestinations).To(HaveKeyWithValue("QA",
|
|
||||||
config.Destination{
|
|
||||||
URI: "ssh://root@podman.test:2222/run/podman/podman.sock",
|
|
||||||
},
|
|
||||||
))
|
|
||||||
|
|
||||||
scp := podmanTest.Podman([]string{"image", "scp", ALPINE, "QA::"})
|
scp := podmanTest.Podman([]string{"image", "scp", ALPINE, "QA::"})
|
||||||
scp.WaitWithDefaultTimeout()
|
scp.WaitWithDefaultTimeout()
|
||||||
// exit with error because we cannot make an actual ssh connection
|
// exit with error because we cannot make an actual ssh connection
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"os/user"
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/config"
|
|
||||||
. "github.com/containers/podman/v4/test/utils"
|
. "github.com/containers/podman/v4/test/utils"
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
@ -16,18 +15,24 @@ import (
|
|||||||
. "github.com/onsi/gomega/gexec"
|
. "github.com/onsi/gomega/gexec"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupEmptyContainersConf() {
|
func setupConnectionsConf() {
|
||||||
// make sure connections are not written to real user config on host
|
// make sure connections are not written to real user config on host
|
||||||
file := filepath.Join(podmanTest.TempDir, "containersconf")
|
file := filepath.Join(podmanTest.TempDir, "containers.conf")
|
||||||
f, err := os.Create(file)
|
f, err := os.Create(file)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
f.Close()
|
f.Close()
|
||||||
os.Setenv("CONTAINERS_CONF", file)
|
os.Setenv("CONTAINERS_CONF", file)
|
||||||
|
|
||||||
|
file = filepath.Join(podmanTest.TempDir, "connections.conf")
|
||||||
|
os.Setenv("PODMAN_CONNECTIONS_CONF", file)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var systemConnectionListCmd = []string{"system", "connection", "ls", "--format", "{{.Name}} {{.URI}} {{.Identity}} {{.Default}} {{.ReadWrite}}"}
|
||||||
|
var farmListCmd = []string{"farm", "ls", "--format", "{{.Name}} {{.Connections}} {{.Default}} {{.ReadWrite}}"}
|
||||||
|
|
||||||
var _ = Describe("podman system connection", func() {
|
var _ = Describe("podman system connection", func() {
|
||||||
|
|
||||||
BeforeEach(setupEmptyContainersConf)
|
BeforeEach(setupConnectionsConf)
|
||||||
|
|
||||||
Context("without running API service", func() {
|
Context("without running API service", func() {
|
||||||
It("add ssh://", func() {
|
It("add ssh://", func() {
|
||||||
@ -42,14 +47,10 @@ var _ = Describe("podman system connection", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(BeEmpty())
|
Expect(session.Out.Contents()).Should(BeEmpty())
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
session = podmanTest.Podman(systemConnectionListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg).Should(HaveActiveService("QA"))
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg).Should(VerifyService(
|
Expect(session.OutputToString()).To(Equal("QA ssh://root@podman.test:2222/run/podman/podman.sock ~/.ssh/id_rsa true true"))
|
||||||
"QA",
|
|
||||||
"ssh://root@podman.test:2222/run/podman/podman.sock",
|
|
||||||
"~/.ssh/id_rsa",
|
|
||||||
))
|
|
||||||
|
|
||||||
cmd = []string{"system", "connection", "rename",
|
cmd = []string{"system", "connection", "rename",
|
||||||
"QA",
|
"QA",
|
||||||
@ -59,7 +60,10 @@ var _ = Describe("podman system connection", func() {
|
|||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
|
|
||||||
Expect(config.ReadCustomConfig()).Should(HaveActiveService("QE"))
|
session = podmanTest.Podman(systemConnectionListCmd)
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session).Should(ExitCleanly())
|
||||||
|
Expect(session.OutputToString()).To(Equal("QE ssh://root@podman.test:2222/run/podman/podman.sock ~/.ssh/id_rsa true true"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("add UDS", func() {
|
It("add UDS", func() {
|
||||||
@ -74,11 +78,10 @@ var _ = Describe("podman system connection", func() {
|
|||||||
// stderr will probably warn (ENOENT or EACCESS) about socket
|
// stderr will probably warn (ENOENT or EACCESS) about socket
|
||||||
// but it's too unreliable to test for.
|
// but it's too unreliable to test for.
|
||||||
|
|
||||||
Expect(config.ReadCustomConfig()).Should(VerifyService(
|
session = podmanTest.Podman(systemConnectionListCmd)
|
||||||
"QA-UDS",
|
session.WaitWithDefaultTimeout()
|
||||||
"unix:///run/podman/podman.sock",
|
Expect(session).Should(ExitCleanly())
|
||||||
"",
|
Expect(session.OutputToString()).To(Equal("QA-UDS unix:///run/podman/podman.sock true true"))
|
||||||
))
|
|
||||||
|
|
||||||
cmd = []string{"system", "connection", "add",
|
cmd = []string{"system", "connection", "add",
|
||||||
"QA-UDS1",
|
"QA-UDS1",
|
||||||
@ -90,12 +93,12 @@ var _ = Describe("podman system connection", func() {
|
|||||||
Expect(session).Should(Exit(0))
|
Expect(session).Should(Exit(0))
|
||||||
Expect(session.Out.Contents()).Should(BeEmpty())
|
Expect(session.Out.Contents()).Should(BeEmpty())
|
||||||
|
|
||||||
Expect(config.ReadCustomConfig()).Should(HaveActiveService("QA-UDS"))
|
session = podmanTest.Podman(systemConnectionListCmd)
|
||||||
Expect(config.ReadCustomConfig()).Should(VerifyService(
|
session.WaitWithDefaultTimeout()
|
||||||
"QA-UDS1",
|
Expect(session).Should(ExitCleanly())
|
||||||
"unix:///run/user/podman/podman.sock",
|
Expect(string(session.Out.Contents())).To(Equal(`QA-UDS unix:///run/podman/podman.sock true true
|
||||||
"",
|
QA-UDS1 unix:///run/user/podman/podman.sock false true
|
||||||
))
|
`))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("add tcp", func() {
|
It("add tcp", func() {
|
||||||
@ -108,18 +111,13 @@ var _ = Describe("podman system connection", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(BeEmpty())
|
Expect(session.Out.Contents()).Should(BeEmpty())
|
||||||
|
|
||||||
Expect(config.ReadCustomConfig()).Should(VerifyService(
|
session = podmanTest.Podman(systemConnectionListCmd)
|
||||||
"QA-TCP",
|
session.WaitWithDefaultTimeout()
|
||||||
"tcp://localhost:8888",
|
Expect(session).Should(ExitCleanly())
|
||||||
"",
|
Expect(session.OutputToString()).To(Equal("QA-TCP tcp://localhost:8888 true true"))
|
||||||
))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("add to new farm", 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",
|
cmd := []string{"system", "connection", "add",
|
||||||
"--default",
|
"--default",
|
||||||
"--identity", "~/.ssh/id_rsa",
|
"--identity", "~/.ssh/id_rsa",
|
||||||
@ -132,15 +130,14 @@ var _ = Describe("podman system connection", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(BeEmpty())
|
Expect(session.Out.Contents()).Should(BeEmpty())
|
||||||
|
|
||||||
cfg, err = config.ReadCustomConfig()
|
session = podmanTest.Podman(systemConnectionListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg).Should(HaveActiveService("QA"))
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg).Should(VerifyService(
|
Expect(session.OutputToString()).To(Equal("QA ssh://root@podman.test:2222/run/podman/podman.sock ~/.ssh/id_rsa true true"))
|
||||||
"QA",
|
session = podmanTest.Podman(farmListCmd)
|
||||||
"ssh://root@podman.test:2222/run/podman/podman.sock",
|
session.WaitWithDefaultTimeout()
|
||||||
"~/.ssh/id_rsa",
|
Expect(session).Should(ExitCleanly())
|
||||||
))
|
Expect(session.OutputToString()).To(Equal("farm1 [QA] true true"))
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm1", []string{"QA"}))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("add to existing farm", func() {
|
It("add to existing farm", func() {
|
||||||
@ -151,10 +148,6 @@ var _ = Describe("podman system connection", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(ContainSubstring("Farm \"empty-farm\" created"))
|
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",
|
cmd = []string{"system", "connection", "add",
|
||||||
"--default",
|
"--default",
|
||||||
"--identity", "~/.ssh/id_rsa",
|
"--identity", "~/.ssh/id_rsa",
|
||||||
@ -167,22 +160,17 @@ var _ = Describe("podman system connection", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(BeEmpty())
|
Expect(session.Out.Contents()).Should(BeEmpty())
|
||||||
|
|
||||||
cfg, err = config.ReadCustomConfig()
|
session = podmanTest.Podman(systemConnectionListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg).Should(HaveActiveService("QA"))
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg).Should(VerifyService(
|
Expect(session.OutputToString()).To(Equal("QA ssh://root@podman.test:2222/run/podman/podman.sock ~/.ssh/id_rsa true true"))
|
||||||
"QA",
|
session = podmanTest.Podman(farmListCmd)
|
||||||
"ssh://root@podman.test:2222/run/podman/podman.sock",
|
session.WaitWithDefaultTimeout()
|
||||||
"~/.ssh/id_rsa",
|
Expect(session).Should(ExitCleanly())
|
||||||
))
|
Expect(session.OutputToString()).To(Equal("empty-farm [QA] true true"))
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("empty-farm", []string{"QA"}))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("removing connection should remove from farm also", func() {
|
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",
|
cmd := []string{"system", "connection", "add",
|
||||||
"--default",
|
"--default",
|
||||||
"--identity", "~/.ssh/id_rsa",
|
"--identity", "~/.ssh/id_rsa",
|
||||||
@ -195,15 +183,14 @@ var _ = Describe("podman system connection", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(BeEmpty())
|
Expect(session.Out.Contents()).Should(BeEmpty())
|
||||||
|
|
||||||
cfg, err = config.ReadCustomConfig()
|
session = podmanTest.Podman(systemConnectionListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg).Should(HaveActiveService("QA"))
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg).Should(VerifyService(
|
Expect(session.OutputToString()).To(Equal("QA ssh://root@podman.test:2222/run/podman/podman.sock ~/.ssh/id_rsa true true"))
|
||||||
"QA",
|
session = podmanTest.Podman(farmListCmd)
|
||||||
"ssh://root@podman.test:2222/run/podman/podman.sock",
|
session.WaitWithDefaultTimeout()
|
||||||
"~/.ssh/id_rsa",
|
Expect(session).Should(ExitCleanly())
|
||||||
))
|
Expect(session.OutputToString()).To(Equal("farm1 [QA] true true"))
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm1", []string{"QA"}))
|
|
||||||
|
|
||||||
// Remove the QA connection
|
// Remove the QA connection
|
||||||
session = podmanTest.Podman([]string{"system", "connection", "remove", "QA"})
|
session = podmanTest.Podman([]string{"system", "connection", "remove", "QA"})
|
||||||
@ -211,11 +198,14 @@ var _ = Describe("podman system connection", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(BeEmpty())
|
Expect(session.Out.Contents()).Should(BeEmpty())
|
||||||
|
|
||||||
cfg, err = config.ReadCustomConfig()
|
session = podmanTest.Podman(systemConnectionListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg.Engine.ActiveService).Should(BeEmpty())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg.Engine.ServiceDestinations).Should(BeEmpty())
|
Expect(session.OutputToString()).To(Equal(""))
|
||||||
Expect(cfg.Farms.List).Should(HaveKeyWithValue("farm1", []string{}))
|
session = podmanTest.Podman(farmListCmd)
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session).Should(ExitCleanly())
|
||||||
|
Expect(session.OutputToString()).To(Equal("farm1 [] true true"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("remove", func() {
|
It("remove", func() {
|
||||||
@ -235,10 +225,10 @@ var _ = Describe("podman system connection", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(BeEmpty())
|
Expect(session.Out.Contents()).Should(BeEmpty())
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
session = podmanTest.Podman(systemConnectionListCmd)
|
||||||
Expect(err).ShouldNot(HaveOccurred())
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(cfg.Engine.ActiveService).Should(BeEmpty())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(cfg.Engine.ServiceDestinations).Should(BeEmpty())
|
Expect(session.OutputToString()).To(Equal(""))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -261,6 +251,7 @@ var _ = Describe("podman system connection", func() {
|
|||||||
session = podmanTest.Podman([]string{"system", "connection", "list"})
|
session = podmanTest.Podman([]string{"system", "connection", "list"})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
|
Expect(session.OutputToStringArray()).To(HaveLen(1))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("default", func() {
|
It("default", func() {
|
||||||
@ -282,19 +273,18 @@ var _ = Describe("podman system connection", func() {
|
|||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out.Contents()).Should(BeEmpty())
|
Expect(session.Out.Contents()).Should(BeEmpty())
|
||||||
|
|
||||||
Expect(config.ReadCustomConfig()).Should(HaveActiveService("devl"))
|
session = podmanTest.Podman(systemConnectionListCmd)
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session).Should(ExitCleanly())
|
||||||
|
Expect(string(session.Out.Contents())).To(Equal(`devl ssh://root@podman.test:2222/run/podman/podman.sock ~/.ssh/id_rsa true true
|
||||||
|
qe ssh://root@podman.test:2222/run/podman/podman.sock ~/.ssh/id_rsa false true
|
||||||
|
`))
|
||||||
|
|
||||||
cmd = []string{"system", "connection", "list"}
|
cmd = []string{"system", "connection", "list"}
|
||||||
session = podmanTest.Podman(cmd)
|
session = podmanTest.Podman(cmd)
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session).Should(ExitCleanly())
|
Expect(session).Should(ExitCleanly())
|
||||||
Expect(session.Out).Should(Say("Name *URI *Identity *Default"))
|
Expect(session.Out).Should(Say("Name *URI *Identity *Default"))
|
||||||
|
|
||||||
cmd = []string{"system", "connection", "list", "--format", "{{.Name}}"}
|
|
||||||
session = podmanTest.Podman(cmd)
|
|
||||||
session.WaitWithDefaultTimeout()
|
|
||||||
Expect(session).Should(ExitCleanly())
|
|
||||||
Expect(session.OutputToString()).Should(Equal("devl qe"))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("failed default", func() {
|
It("failed default", func() {
|
||||||
@ -382,12 +372,12 @@ var _ = Describe("podman system connection", func() {
|
|||||||
Path: fmt.Sprintf("/run/user/%s/podman/podman.sock", u.Uid),
|
Path: fmt.Sprintf("/run/user/%s/podman/podman.sock", u.Uid),
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect(config.ReadCustomConfig()).Should(HaveActiveService("QA"))
|
cmd = exec.Command(podmanTest.RemotePodmanBinary, systemConnectionListCmd...)
|
||||||
Expect(config.ReadCustomConfig()).Should(VerifyService(
|
lsSession, err := Start(cmd, GinkgoWriter, GinkgoWriter)
|
||||||
"QA",
|
Expect(err).ToNot(HaveOccurred())
|
||||||
uri.String(),
|
lsSession.Wait(DefaultWaitTimeout)
|
||||||
filepath.Join(u.HomeDir, ".ssh", "id_ed25519"),
|
Expect(lsSession).Should(Exit(0))
|
||||||
))
|
Expect(string(lsSession.Out.Contents())).To(Equal("QA " + uri.String() + " " + filepath.Join(u.HomeDir, ".ssh", "id_ed25519") + " true true\n"))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -51,7 +51,7 @@ function _run_podman_remote() {
|
|||||||
# Very basic test, does not actually connect at any time
|
# Very basic test, does not actually connect at any time
|
||||||
@test "podman system connection - basic add / ls / remove" {
|
@test "podman system connection - basic add / ls / remove" {
|
||||||
run_podman system connection ls
|
run_podman system connection ls
|
||||||
is "$output" "Name URI Identity Default" \
|
is "$output" "Name URI Identity Default ReadWrite" \
|
||||||
"system connection ls: no connections"
|
"system connection ls: no connections"
|
||||||
|
|
||||||
c1="c1_$(random_string 15)"
|
c1="c1_$(random_string 15)"
|
||||||
@ -61,8 +61,8 @@ function _run_podman_remote() {
|
|||||||
run_podman context create --docker "host=tcp://localhost:54321" $c2
|
run_podman context create --docker "host=tcp://localhost:54321" $c2
|
||||||
run_podman system connection ls
|
run_podman system connection ls
|
||||||
is "$output" \
|
is "$output" \
|
||||||
".*$c1[ ]\+tcp://localhost:12345[ ]\+true
|
".*$c1[ ]\+tcp://localhost:12345[ ]\+true[ ]\+true
|
||||||
$c2[ ]\+tcp://localhost:54321[ ]\+false" \
|
$c2[ ]\+tcp://localhost:54321[ ]\+false[ ]\+true" \
|
||||||
"system connection ls"
|
"system connection ls"
|
||||||
run_podman system connection ls -q
|
run_podman system connection ls -q
|
||||||
is "$(echo $(sort <<<$output))" \
|
is "$(echo $(sort <<<$output))" \
|
||||||
@ -75,14 +75,14 @@ $c2[ ]\+tcp://localhost:54321[ ]\+false" \
|
|||||||
run_podman context use $c2
|
run_podman context use $c2
|
||||||
run_podman system connection ls
|
run_podman system connection ls
|
||||||
is "$output" \
|
is "$output" \
|
||||||
".*$c1[ ]\+tcp://localhost:12345[ ]\+false
|
".*$c1[ ]\+tcp://localhost:12345[ ]\+false[ ]\+true
|
||||||
$c2[ ]\+tcp://localhost:54321[ ]\+true" \
|
$c2[ ]\+tcp://localhost:54321[ ]\+true[ ]\+true" \
|
||||||
"system connection ls"
|
"system connection ls"
|
||||||
|
|
||||||
# Remove default connection; the remaining one should still not be default
|
# Remove default connection; the remaining one should still not be default
|
||||||
run_podman system connection rm $c2
|
run_podman system connection rm $c2
|
||||||
run_podman context ls
|
run_podman context ls
|
||||||
is "$output" ".*$c1[ ]\+tcp://localhost:12345[ ]\+false" \
|
is "$output" ".*$c1[ ]\+tcp://localhost:12345[ ]\+false[ ]\+true" \
|
||||||
"system connection ls (after removing default connection)"
|
"system connection ls (after removing default connection)"
|
||||||
|
|
||||||
run_podman context rm $c1
|
run_podman context rm $c1
|
||||||
|
@ -3,116 +3,12 @@ package utils
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
|
||||||
|
|
||||||
"github.com/containers/common/pkg/config"
|
|
||||||
. "github.com/onsi/gomega" //nolint:revive,stylecheck
|
|
||||||
"github.com/onsi/gomega/format"
|
"github.com/onsi/gomega/format"
|
||||||
"github.com/onsi/gomega/gexec"
|
"github.com/onsi/gomega/gexec"
|
||||||
"github.com/onsi/gomega/matchers"
|
|
||||||
"github.com/onsi/gomega/types"
|
"github.com/onsi/gomega/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HaveActiveService verifies the given service is the active service.
|
|
||||||
func HaveActiveService(name interface{}) OmegaMatcher {
|
|
||||||
return WithTransform(
|
|
||||||
func(cfg *config.Config) string {
|
|
||||||
return cfg.Engine.ActiveService
|
|
||||||
},
|
|
||||||
Equal(name))
|
|
||||||
}
|
|
||||||
|
|
||||||
type ServiceMatcher struct {
|
|
||||||
types.GomegaMatcher
|
|
||||||
Name interface{}
|
|
||||||
URI interface{}
|
|
||||||
Identity interface{}
|
|
||||||
failureMessage string
|
|
||||||
negatedFailureMessage string
|
|
||||||
}
|
|
||||||
|
|
||||||
func VerifyService(name, uri, identity interface{}) OmegaMatcher {
|
|
||||||
return &ServiceMatcher{
|
|
||||||
Name: name,
|
|
||||||
URI: uri,
|
|
||||||
Identity: identity,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (matcher *ServiceMatcher) Match(actual interface{}) (success bool, err error) {
|
|
||||||
cfg, ok := actual.(*config.Config)
|
|
||||||
if !ok {
|
|
||||||
return false, fmt.Errorf("ServiceMatcher matcher expects a config.Config")
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = url.Parse(matcher.URI.(string)); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
success, err = HaveKey(matcher.Name).Match(cfg.Engine.ServiceDestinations)
|
|
||||||
if !success || err != nil {
|
|
||||||
matcher.failureMessage = HaveKey(matcher.Name).FailureMessage(cfg.Engine.ServiceDestinations)
|
|
||||||
matcher.negatedFailureMessage = HaveKey(matcher.Name).NegatedFailureMessage(cfg.Engine.ServiceDestinations)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
sd := cfg.Engine.ServiceDestinations[matcher.Name.(string)]
|
|
||||||
success, err = Equal(matcher.URI).Match(sd.URI)
|
|
||||||
if !success || err != nil {
|
|
||||||
matcher.failureMessage = Equal(matcher.URI).FailureMessage(sd.URI)
|
|
||||||
matcher.negatedFailureMessage = Equal(matcher.URI).NegatedFailureMessage(sd.URI)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
success, err = Equal(matcher.Identity).Match(sd.Identity)
|
|
||||||
if !success || err != nil {
|
|
||||||
matcher.failureMessage = Equal(matcher.Identity).FailureMessage(sd.Identity)
|
|
||||||
matcher.negatedFailureMessage = Equal(matcher.Identity).NegatedFailureMessage(sd.Identity)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (matcher *ServiceMatcher) FailureMessage(_ interface{}) string {
|
|
||||||
return matcher.failureMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
func (matcher *ServiceMatcher) NegatedFailureMessage(_ interface{}) string {
|
|
||||||
return matcher.negatedFailureMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
type URLMatcher struct {
|
|
||||||
matchers.EqualMatcher
|
|
||||||
}
|
|
||||||
|
|
||||||
// VerifyURL matches when actual is a valid URL and matches expected.
|
|
||||||
func VerifyURL(uri interface{}) OmegaMatcher {
|
|
||||||
return &URLMatcher{matchers.EqualMatcher{Expected: uri}}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (matcher *URLMatcher) Match(actual interface{}) (bool, error) {
|
|
||||||
e, ok := matcher.Expected.(string)
|
|
||||||
if !ok {
|
|
||||||
return false, fmt.Errorf("VerifyURL requires string inputs %T is not supported", matcher.Expected)
|
|
||||||
}
|
|
||||||
eURI, err := url.Parse(e)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
a, ok := actual.(string)
|
|
||||||
if !ok {
|
|
||||||
return false, fmt.Errorf("VerifyURL requires string inputs %T is not supported", actual)
|
|
||||||
}
|
|
||||||
aURI, err := url.Parse(a)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return (&matchers.EqualMatcher{Expected: eURI}).Match(aURI)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ExitMatcher struct {
|
type ExitMatcher struct {
|
||||||
types.GomegaMatcher
|
types.GomegaMatcher
|
||||||
Expected int
|
Expected int
|
||||||
|
86
vendor/github.com/containers/common/pkg/config/config.go
generated
vendored
86
vendor/github.com/containers/common/pkg/config/config.go
generated
vendored
@ -9,11 +9,9 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
|
||||||
"github.com/containers/common/internal/attributedstring"
|
"github.com/containers/common/internal/attributedstring"
|
||||||
"github.com/containers/common/libnetwork/types"
|
"github.com/containers/common/libnetwork/types"
|
||||||
"github.com/containers/common/pkg/capabilities"
|
"github.com/containers/common/pkg/capabilities"
|
||||||
"github.com/containers/storage/pkg/ioutils"
|
|
||||||
"github.com/containers/storage/pkg/unshare"
|
"github.com/containers/storage/pkg/unshare"
|
||||||
units "github.com/docker/go-units"
|
units "github.com/docker/go-units"
|
||||||
selinux "github.com/opencontainers/selinux/go-selinux"
|
selinux "github.com/opencontainers/selinux/go-selinux"
|
||||||
@ -667,9 +665,9 @@ type MachineConfig struct {
|
|||||||
// FarmConfig represents the "farm" TOML config tables
|
// FarmConfig represents the "farm" TOML config tables
|
||||||
type FarmConfig struct {
|
type FarmConfig struct {
|
||||||
// Default is the default farm to be used when farming out builds
|
// Default is the default farm to be used when farming out builds
|
||||||
Default string `toml:"default,omitempty"`
|
Default string `json:",omitempty" toml:"default,omitempty"`
|
||||||
// List is a map of farms created where key=farm-name and value=list of connections
|
// List is a map of farms created where key=farm-name and value=list of connections
|
||||||
List map[string][]string `toml:"list,omitempty"`
|
List map[string][]string `json:",omitempty" toml:"list,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destination represents destination for remote service
|
// Destination represents destination for remote service
|
||||||
@ -678,10 +676,10 @@ type Destination struct {
|
|||||||
URI string `toml:"uri"`
|
URI string `toml:"uri"`
|
||||||
|
|
||||||
// Identity file with ssh key, optional
|
// Identity file with ssh key, optional
|
||||||
Identity string `toml:"identity,omitempty"`
|
Identity string `json:",omitempty" toml:"identity,omitempty"`
|
||||||
|
|
||||||
// isMachine describes if the remote destination is a machine.
|
// isMachine describes if the remote destination is a machine.
|
||||||
IsMachine bool `toml:"is_machine,omitempty"`
|
IsMachine bool `json:",omitempty" toml:"is_machine,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consumes container image's os and arch and returns if any dedicated runtime was
|
// Consumes container image's os and arch and returns if any dedicated runtime was
|
||||||
@ -1008,82 +1006,6 @@ func IsValidDeviceMode(mode string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func rootlessConfigPath() (string, error) {
|
|
||||||
if configHome := os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
|
|
||||||
return filepath.Join(configHome, _configPath), nil
|
|
||||||
}
|
|
||||||
home, err := unshare.HomeDir()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return filepath.Join(home, UserOverrideContainersConfig), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Path() string {
|
|
||||||
if path := os.Getenv("CONTAINERS_CONF"); path != "" {
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
if unshare.IsRootless() {
|
|
||||||
if rpath, err := rootlessConfigPath(); err == nil {
|
|
||||||
return rpath
|
|
||||||
}
|
|
||||||
return "$HOME/" + UserOverrideContainersConfig
|
|
||||||
}
|
|
||||||
return OverrideContainersConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadCustomConfig reads the custom config and only generates a config based on it
|
|
||||||
// If the custom config file does not exists, function will return an empty config
|
|
||||||
func ReadCustomConfig() (*Config, error) {
|
|
||||||
path, err := customConfigFile()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
newConfig := &Config{}
|
|
||||||
if _, err := os.Stat(path); err == nil {
|
|
||||||
if err := readConfigFromFile(path, newConfig); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if !errors.Is(err, os.ErrNotExist) {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Let's always initialize the farm list so it is never nil
|
|
||||||
if newConfig.Farms.List == nil {
|
|
||||||
newConfig.Farms.List = make(map[string][]string)
|
|
||||||
}
|
|
||||||
return newConfig, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write writes the configuration to the default file
|
|
||||||
func (c *Config) Write() error {
|
|
||||||
var err error
|
|
||||||
path, err := customConfigFile()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := &ioutils.AtomicFileWriterOptions{ExplicitCommit: true}
|
|
||||||
configFile, err := ioutils.NewAtomicFileWriterWithOpts(path, 0o644, opts)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer configFile.Close()
|
|
||||||
|
|
||||||
enc := toml.NewEncoder(configFile)
|
|
||||||
if err := enc.Encode(c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no errors commit the changes to the config file
|
|
||||||
return configFile.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reload clean the cached config and reloads the configuration from containers.conf files
|
// Reload clean the cached config and reloads the configuration from containers.conf files
|
||||||
// This function is meant to be used for long-running processes that need to reload potential changes made to
|
// This function is meant to be used for long-running processes that need to reload potential changes made to
|
||||||
// the cached containers.conf files.
|
// the cached containers.conf files.
|
||||||
|
16
vendor/github.com/containers/common/pkg/config/config_darwin.go
generated
vendored
16
vendor/github.com/containers/common/pkg/config/config_darwin.go
generated
vendored
@ -1,9 +1,5 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// OverrideContainersConfig holds the default config path overridden by the root user
|
// OverrideContainersConfig holds the default config path overridden by the root user
|
||||||
OverrideContainersConfig = "/etc/" + _configPath
|
OverrideContainersConfig = "/etc/" + _configPath
|
||||||
@ -16,18 +12,6 @@ const (
|
|||||||
DefaultSignaturePolicyPath = "/etc/containers/policy.json"
|
DefaultSignaturePolicyPath = "/etc/containers/policy.json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// podman remote clients on darwin cannot use unshare.isRootless() to determine the configuration file locations.
|
|
||||||
func customConfigFile() (string, error) {
|
|
||||||
if path, found := os.LookupEnv("CONTAINERS_CONF"); found {
|
|
||||||
return path, nil
|
|
||||||
}
|
|
||||||
return rootlessConfigPath()
|
|
||||||
}
|
|
||||||
|
|
||||||
func ifRootlessConfigPath() (string, error) {
|
|
||||||
return rootlessConfigPath()
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultHelperBinariesDir = []string{
|
var defaultHelperBinariesDir = []string{
|
||||||
// Relative to the binary directory
|
// Relative to the binary directory
|
||||||
"$BINDIR/../libexec/podman",
|
"$BINDIR/../libexec/podman",
|
||||||
|
16
vendor/github.com/containers/common/pkg/config/config_freebsd.go
generated
vendored
16
vendor/github.com/containers/common/pkg/config/config_freebsd.go
generated
vendored
@ -1,9 +1,5 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// OverrideContainersConfig holds the default config path overridden by the root user
|
// OverrideContainersConfig holds the default config path overridden by the root user
|
||||||
OverrideContainersConfig = "/usr/local/etc/" + _configPath
|
OverrideContainersConfig = "/usr/local/etc/" + _configPath
|
||||||
@ -16,18 +12,6 @@ const (
|
|||||||
DefaultSignaturePolicyPath = "/usr/local/etc/containers/policy.json"
|
DefaultSignaturePolicyPath = "/usr/local/etc/containers/policy.json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// podman remote clients on freebsd cannot use unshare.isRootless() to determine the configuration file locations.
|
|
||||||
func customConfigFile() (string, error) {
|
|
||||||
if path, found := os.LookupEnv("CONTAINERS_CONF"); found {
|
|
||||||
return path, nil
|
|
||||||
}
|
|
||||||
return rootlessConfigPath()
|
|
||||||
}
|
|
||||||
|
|
||||||
func ifRootlessConfigPath() (string, error) {
|
|
||||||
return rootlessConfigPath()
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultHelperBinariesDir = []string{
|
var defaultHelperBinariesDir = []string{
|
||||||
"/usr/local/bin",
|
"/usr/local/bin",
|
||||||
"/usr/local/libexec/podman",
|
"/usr/local/libexec/podman",
|
||||||
|
28
vendor/github.com/containers/common/pkg/config/config_linux.go
generated
vendored
28
vendor/github.com/containers/common/pkg/config/config_linux.go
generated
vendored
@ -1,9 +1,6 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/containers/storage/pkg/unshare"
|
|
||||||
selinux "github.com/opencontainers/selinux/go-selinux"
|
selinux "github.com/opencontainers/selinux/go-selinux"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -23,31 +20,6 @@ func selinuxEnabled() bool {
|
|||||||
return selinux.GetEnabled()
|
return selinux.GetEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
func customConfigFile() (string, error) {
|
|
||||||
if path, found := os.LookupEnv("CONTAINERS_CONF"); found {
|
|
||||||
return path, nil
|
|
||||||
}
|
|
||||||
if unshare.GetRootlessUID() > 0 {
|
|
||||||
path, err := rootlessConfigPath()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return path, nil
|
|
||||||
}
|
|
||||||
return OverrideContainersConfig, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ifRootlessConfigPath() (string, error) {
|
|
||||||
if unshare.GetRootlessUID() > 0 {
|
|
||||||
path, err := rootlessConfigPath()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return path, nil
|
|
||||||
}
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultHelperBinariesDir = []string{
|
var defaultHelperBinariesDir = []string{
|
||||||
"/usr/local/libexec/podman",
|
"/usr/local/libexec/podman",
|
||||||
"/usr/local/lib/podman",
|
"/usr/local/lib/podman",
|
||||||
|
25
vendor/github.com/containers/common/pkg/config/config_unix.go
generated
vendored
Normal file
25
vendor/github.com/containers/common/pkg/config/config_unix.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//go:build !windows
|
||||||
|
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/containers/storage/pkg/unshare"
|
||||||
|
)
|
||||||
|
|
||||||
|
// userConfigPath returns the path to the users local config that is
|
||||||
|
// not shared with other users. It uses $XDG_CONFIG_HOME/containers...
|
||||||
|
// if set or $HOME/.config/containers... if not.
|
||||||
|
func userConfigPath() (string, error) {
|
||||||
|
if configHome := os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
|
||||||
|
return filepath.Join(configHome, _configPath), nil
|
||||||
|
}
|
||||||
|
home, err := unshare.HomeDir()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return filepath.Join(home, UserOverrideContainersConfig), nil
|
||||||
|
}
|
12
vendor/github.com/containers/common/pkg/config/config_windows.go
generated
vendored
12
vendor/github.com/containers/common/pkg/config/config_windows.go
generated
vendored
@ -17,15 +17,9 @@ const (
|
|||||||
_typeBind = "bind"
|
_typeBind = "bind"
|
||||||
)
|
)
|
||||||
|
|
||||||
// podman remote clients on windows cannot use unshare.isRootless() to determine the configuration file locations.
|
// userConfigPath returns the path to the users local config that is
|
||||||
func customConfigFile() (string, error) {
|
// not shared with other users. It uses $APPDATA/containers...
|
||||||
if path, found := os.LookupEnv("CONTAINERS_CONF"); found {
|
func userConfigPath() (string, error) {
|
||||||
return path, nil
|
|
||||||
}
|
|
||||||
return os.Getenv("APPDATA") + "\\containers\\containers.conf", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ifRootlessConfigPath() (string, error) {
|
|
||||||
return os.Getenv("APPDATA") + "\\containers\\containers.conf", nil
|
return os.Getenv("APPDATA") + "\\containers\\containers.conf", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
286
vendor/github.com/containers/common/pkg/config/connections.go
generated
vendored
Normal file
286
vendor/github.com/containers/common/pkg/config/connections.go
generated
vendored
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/containers/storage/pkg/ioutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
const connectionsFile = "podman-connections.conf"
|
||||||
|
|
||||||
|
// connectionsConfigFile returns the path to the rw connections config file
|
||||||
|
func connectionsConfigFile() (string, error) {
|
||||||
|
if path, found := os.LookupEnv("PODMAN_CONNECTIONS_CONF"); found {
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
path, err := userConfigPath()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
// file is stored next to containers.conf
|
||||||
|
return filepath.Join(filepath.Dir(path), connectionsFile), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConnectionConfig struct {
|
||||||
|
Default string `json:",omitempty"`
|
||||||
|
Connections map[string]Destination `json:",omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConnectionsFile struct {
|
||||||
|
Connection ConnectionConfig `json:",omitempty"`
|
||||||
|
Farm FarmConfig `json:",omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Connection struct {
|
||||||
|
// Name of the connection
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// Destination for this connection
|
||||||
|
Destination
|
||||||
|
|
||||||
|
// Default if this connection is the default
|
||||||
|
Default bool
|
||||||
|
|
||||||
|
// ReadWrite if true the connection is stored in the connections file
|
||||||
|
ReadWrite bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type Farm struct {
|
||||||
|
// Name of the farm
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// Connections
|
||||||
|
Connections []string
|
||||||
|
|
||||||
|
// Default if this is the default farm
|
||||||
|
Default bool
|
||||||
|
|
||||||
|
// ReadWrite if true the farm is stored in the connections file
|
||||||
|
ReadWrite bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func readConnectionConf() (*ConnectionsFile, string, error) {
|
||||||
|
path, err := connectionsConfigFile()
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
conf := new(ConnectionsFile)
|
||||||
|
f, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
// return empty config if file does not exists
|
||||||
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
|
return conf, path, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
err = json.NewDecoder(f).Decode(conf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", fmt.Errorf("parse %q: %w", path, err)
|
||||||
|
}
|
||||||
|
return conf, path, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeConnectionConf(path string, conf *ConnectionsFile) error {
|
||||||
|
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := &ioutils.AtomicFileWriterOptions{ExplicitCommit: true}
|
||||||
|
configFile, err := ioutils.NewAtomicFileWriterWithOpts(path, 0o644, opts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer configFile.Close()
|
||||||
|
|
||||||
|
err = json.NewEncoder(configFile).Encode(conf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no errors commit the changes to the config file
|
||||||
|
return configFile.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditConnectionConfig must be used to edit the connections config.
|
||||||
|
// The function will read and write the file automatically and the
|
||||||
|
// callback function just needs to modify the cfg as needed.
|
||||||
|
func EditConnectionConfig(callback func(cfg *ConnectionsFile) error) error {
|
||||||
|
conf, path, err := readConnectionConf()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("read connections file: %w", err)
|
||||||
|
}
|
||||||
|
if conf.Farm.List == nil {
|
||||||
|
conf.Farm.List = make(map[string][]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := callback(conf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return writeConnectionConf(path, conf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeConnection(name string, dst Destination, def, readWrite bool) *Connection {
|
||||||
|
return &Connection{
|
||||||
|
Name: name,
|
||||||
|
Destination: dst,
|
||||||
|
Default: def,
|
||||||
|
ReadWrite: readWrite,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConnection return the connection for the given name or if def is set to true then return the default connection.
|
||||||
|
func (c *Config) GetConnection(name string, def bool) (*Connection, error) {
|
||||||
|
conConf, _, err := readConnectionConf()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defaultCon := conConf.Connection.Default
|
||||||
|
if defaultCon == "" {
|
||||||
|
defaultCon = c.Engine.ActiveService
|
||||||
|
}
|
||||||
|
if def {
|
||||||
|
if defaultCon == "" {
|
||||||
|
return nil, errors.New("no default connection found")
|
||||||
|
}
|
||||||
|
name = defaultCon
|
||||||
|
} else {
|
||||||
|
def = defaultCon == name
|
||||||
|
}
|
||||||
|
|
||||||
|
if dst, ok := conConf.Connection.Connections[name]; ok {
|
||||||
|
return makeConnection(name, dst, def, true), nil
|
||||||
|
}
|
||||||
|
if dst, ok := c.Engine.ServiceDestinations[name]; ok {
|
||||||
|
return makeConnection(name, dst, def, false), nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("connection %q not found", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllConnections return all configured connections
|
||||||
|
func (c *Config) GetAllConnections() ([]Connection, error) {
|
||||||
|
conConf, _, err := readConnectionConf()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultCon := conConf.Connection.Default
|
||||||
|
if defaultCon == "" {
|
||||||
|
defaultCon = c.Engine.ActiveService
|
||||||
|
}
|
||||||
|
|
||||||
|
connections := make([]Connection, 0, len(conConf.Connection.Connections))
|
||||||
|
for name, dst := range conConf.Connection.Connections {
|
||||||
|
def := defaultCon == name
|
||||||
|
connections = append(connections, *makeConnection(name, dst, def, true))
|
||||||
|
}
|
||||||
|
for name, dst := range c.Engine.ServiceDestinations {
|
||||||
|
if _, ok := conConf.Connection.Connections[name]; ok {
|
||||||
|
// connection name is overwritten by connections file
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
def := defaultCon == name
|
||||||
|
connections = append(connections, *makeConnection(name, dst, def, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
return connections, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getConnections(cons []string, dests map[string]Destination) ([]Connection, error) {
|
||||||
|
connections := make([]Connection, 0, len(cons))
|
||||||
|
for _, name := range cons {
|
||||||
|
if dst, ok := dests[name]; ok {
|
||||||
|
connections = append(connections, *makeConnection(name, dst, false, false))
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("connection %q not found", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return connections, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFarmConnections return all the connections for the given farm.
|
||||||
|
func (c *Config) GetFarmConnections(name string) ([]Connection, error) {
|
||||||
|
_, cons, err := c.getFarmConnections(name, false)
|
||||||
|
return cons, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDefaultFarmConnections returns the name of the default farm
|
||||||
|
// and the connections.
|
||||||
|
func (c *Config) GetDefaultFarmConnections() (string, []Connection, error) {
|
||||||
|
return c.getFarmConnections("", true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getFarmConnections returns all connections for the given farm,
|
||||||
|
// if def is true it will use the default farm instead of the name.
|
||||||
|
// Returns the name of the farm and the connections for it.
|
||||||
|
func (c *Config) getFarmConnections(name string, def bool) (string, []Connection, error) {
|
||||||
|
conConf, _, err := readConnectionConf()
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
defaultFarm := conConf.Farm.Default
|
||||||
|
if defaultFarm == "" {
|
||||||
|
defaultFarm = c.Farms.Default
|
||||||
|
}
|
||||||
|
if def {
|
||||||
|
if defaultFarm == "" {
|
||||||
|
return "", nil, errors.New("no default farm found")
|
||||||
|
}
|
||||||
|
name = defaultFarm
|
||||||
|
}
|
||||||
|
|
||||||
|
if cons, ok := conConf.Farm.List[name]; ok {
|
||||||
|
cons, err := getConnections(cons, conConf.Connection.Connections)
|
||||||
|
return name, cons, err
|
||||||
|
}
|
||||||
|
if cons, ok := c.Farms.List[name]; ok {
|
||||||
|
cons, err := getConnections(cons, c.Engine.ServiceDestinations)
|
||||||
|
return name, cons, err
|
||||||
|
}
|
||||||
|
return "", nil, fmt.Errorf("farm %q not found", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeFarm(name string, cons []string, def, readWrite bool) Farm {
|
||||||
|
return Farm{
|
||||||
|
Name: name,
|
||||||
|
Connections: cons,
|
||||||
|
Default: def,
|
||||||
|
ReadWrite: readWrite,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllFarms returns all configured farms
|
||||||
|
func (c *Config) GetAllFarms() ([]Farm, error) {
|
||||||
|
conConf, _, err := readConnectionConf()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defaultFarm := conConf.Farm.Default
|
||||||
|
if defaultFarm == "" {
|
||||||
|
defaultFarm = c.Farms.Default
|
||||||
|
}
|
||||||
|
|
||||||
|
farms := make([]Farm, 0, len(conConf.Farm.List))
|
||||||
|
for name, cons := range conConf.Farm.List {
|
||||||
|
def := defaultFarm == name
|
||||||
|
farms = append(farms, makeFarm(name, cons, def, true))
|
||||||
|
}
|
||||||
|
for name, cons := range c.Farms.List {
|
||||||
|
if _, ok := conConf.Farm.List[name]; ok {
|
||||||
|
// farm name is overwritten by connections file
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
def := defaultFarm == name
|
||||||
|
farms = append(farms, makeFarm(name, cons, def, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
return farms, nil
|
||||||
|
}
|
3
vendor/github.com/containers/common/pkg/config/containers.conf
generated
vendored
3
vendor/github.com/containers/common/pkg/config/containers.conf
generated
vendored
@ -10,7 +10,8 @@
|
|||||||
# locations in the following order:
|
# locations in the following order:
|
||||||
# 1. /usr/share/containers/containers.conf
|
# 1. /usr/share/containers/containers.conf
|
||||||
# 2. /etc/containers/containers.conf
|
# 2. /etc/containers/containers.conf
|
||||||
# 3. $HOME/.config/containers/containers.conf (Rootless containers ONLY)
|
# 3. $XDG_CONFIG_HOME/containers/containers.conf or
|
||||||
|
# $HOME/.config/containers/containers.conf if $XDG_CONFIG_HOME is not set
|
||||||
# Items specified in the latter containers.conf, if they exist, override the
|
# Items specified in the latter containers.conf, if they exist, override the
|
||||||
# previous containers.conf settings, or the default settings.
|
# previous containers.conf settings, or the default settings.
|
||||||
|
|
||||||
|
39
vendor/github.com/containers/common/pkg/config/new.go
generated
vendored
39
vendor/github.com/containers/common/pkg/config/new.go
generated
vendored
@ -21,7 +21,6 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// FIXME: update code base and tests to use the two constants below.
|
|
||||||
containersConfEnv = "CONTAINERS_CONF"
|
containersConfEnv = "CONTAINERS_CONF"
|
||||||
containersConfOverrideEnv = containersConfEnv + "_OVERRIDE"
|
containersConfOverrideEnv = containersConfEnv + "_OVERRIDE"
|
||||||
)
|
)
|
||||||
@ -79,15 +78,34 @@ func newLocked(options *Options) (*Config, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("finding config on system: %w", err)
|
return nil, fmt.Errorf("finding config on system: %w", err)
|
||||||
}
|
}
|
||||||
|
// connectionsPath, err := connectionsConfigFile()
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
for _, path := range configs {
|
for _, path := range configs {
|
||||||
|
// var dests []*Destination
|
||||||
|
// if path == connectionsPath {
|
||||||
|
// // Store the dest pointers so we know after the load if there are new pointers
|
||||||
|
// // the connection changed and thus is read write.
|
||||||
|
// dests = maps.Values(config.Engine.ServiceDestinations)
|
||||||
|
// }
|
||||||
|
|
||||||
// Merge changes in later configs with the previous configs.
|
// Merge changes in later configs with the previous configs.
|
||||||
// Each config file that specified fields, will override the
|
// Each config file that specified fields, will override the
|
||||||
// previous fields.
|
// previous fields.
|
||||||
if err = readConfigFromFile(path, config); err != nil {
|
if err = readConfigFromFile(path, config, true); err != nil {
|
||||||
return nil, fmt.Errorf("reading system config %q: %w", path, err)
|
return nil, fmt.Errorf("reading system config %q: %w", path, err)
|
||||||
}
|
}
|
||||||
logrus.Debugf("Merged system config %q", path)
|
logrus.Debugf("Merged system config %q", path)
|
||||||
logrus.Tracef("%+v", config)
|
logrus.Tracef("%+v", config)
|
||||||
|
|
||||||
|
// // if there is a new dest now we know it is read write as it was in the connections.conf file
|
||||||
|
// for _, dest := range config.Engine.ServiceDestinations {
|
||||||
|
// if !slices.Contains(dests, dest) {
|
||||||
|
// dest.ReadWrite = true
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
modules, err := options.modules()
|
modules, err := options.modules()
|
||||||
@ -115,7 +133,7 @@ func newLocked(options *Options) (*Config, error) {
|
|||||||
}
|
}
|
||||||
// readConfigFromFile reads in container config in the specified
|
// readConfigFromFile reads in container config in the specified
|
||||||
// file and then merge changes with the current default.
|
// file and then merge changes with the current default.
|
||||||
if err := readConfigFromFile(add, config); err != nil {
|
if err := readConfigFromFile(add, config, false); err != nil {
|
||||||
return nil, fmt.Errorf("reading additional config %q: %w", add, err)
|
return nil, fmt.Errorf("reading additional config %q: %w", add, err)
|
||||||
}
|
}
|
||||||
logrus.Debugf("Merged additional config %q", add)
|
logrus.Debugf("Merged additional config %q", add)
|
||||||
@ -157,12 +175,8 @@ func systemConfigs() (configs []string, finalErr error) {
|
|||||||
}
|
}
|
||||||
return append(configs, path), nil
|
return append(configs, path), nil
|
||||||
}
|
}
|
||||||
if _, err := os.Stat(DefaultContainersConfig); err == nil {
|
|
||||||
configs = append(configs, DefaultContainersConfig)
|
configs = append(configs, DefaultContainersConfig)
|
||||||
}
|
|
||||||
if _, err := os.Stat(OverrideContainersConfig); err == nil {
|
|
||||||
configs = append(configs, OverrideContainersConfig)
|
configs = append(configs, OverrideContainersConfig)
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
configs, err = addConfigs(OverrideContainersConfig+".d", configs)
|
configs, err = addConfigs(OverrideContainersConfig+".d", configs)
|
||||||
@ -170,19 +184,15 @@ func systemConfigs() (configs []string, finalErr error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
path, err := ifRootlessConfigPath()
|
path, err := userConfigPath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if path != "" {
|
|
||||||
if _, err := os.Stat(path); err == nil {
|
|
||||||
configs = append(configs, path)
|
configs = append(configs, path)
|
||||||
}
|
|
||||||
configs, err = addConfigs(path+".d", configs)
|
configs, err = addConfigs(path+".d", configs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return configs, nil
|
return configs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,10 +235,13 @@ func addConfigs(dirPath string, configs []string) ([]string, error) {
|
|||||||
// unmarshal its content into a Config. The config param specifies the previous
|
// unmarshal its content into a Config. The config param specifies the previous
|
||||||
// default config. If the path, only specifies a few fields in the Toml file
|
// default config. If the path, only specifies a few fields in the Toml file
|
||||||
// the defaults from the config parameter will be used for all other fields.
|
// the defaults from the config parameter will be used for all other fields.
|
||||||
func readConfigFromFile(path string, config *Config) error {
|
func readConfigFromFile(path string, config *Config, ignoreErrNotExist bool) error {
|
||||||
logrus.Tracef("Reading configuration file %q", path)
|
logrus.Tracef("Reading configuration file %q", path)
|
||||||
meta, err := toml.DecodeFile(path, config)
|
meta, err := toml.DecodeFile(path, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if ignoreErrNotExist && errors.Is(err, fs.ErrNotExist) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return fmt.Errorf("decode configuration %v: %w", path, err)
|
return fmt.Errorf("decode configuration %v: %w", path, err)
|
||||||
}
|
}
|
||||||
keys := meta.Undecoded()
|
keys := meta.Undecoded()
|
||||||
|
104
vendor/github.com/containers/common/pkg/manifests/manifests.go
generated
vendored
104
vendor/github.com/containers/common/pkg/manifests/manifests.go
generated
vendored
@ -19,6 +19,7 @@ type List interface {
|
|||||||
Remove(instanceDigest digest.Digest) error
|
Remove(instanceDigest digest.Digest) error
|
||||||
SetURLs(instanceDigest digest.Digest, urls []string) error
|
SetURLs(instanceDigest digest.Digest, urls []string) error
|
||||||
URLs(instanceDigest digest.Digest) ([]string, error)
|
URLs(instanceDigest digest.Digest) ([]string, error)
|
||||||
|
ClearAnnotations(instanceDigest *digest.Digest) error
|
||||||
SetAnnotations(instanceDigest *digest.Digest, annotations map[string]string) error
|
SetAnnotations(instanceDigest *digest.Digest, annotations map[string]string) error
|
||||||
Annotations(instanceDigest *digest.Digest) (map[string]string, error)
|
Annotations(instanceDigest *digest.Digest) (map[string]string, error)
|
||||||
SetOS(instanceDigest digest.Digest, os string) error
|
SetOS(instanceDigest digest.Digest, os string) error
|
||||||
@ -100,18 +101,21 @@ func (l *list) AddInstance(manifestDigest digest.Digest, manifestSize int64, man
|
|||||||
Platform: schema2platform,
|
Platform: schema2platform,
|
||||||
})
|
})
|
||||||
|
|
||||||
ociv1platform := v1.Platform{
|
ociv1platform := &v1.Platform{
|
||||||
Architecture: architecture,
|
Architecture: architecture,
|
||||||
OS: osName,
|
OS: osName,
|
||||||
OSVersion: osVersion,
|
OSVersion: osVersion,
|
||||||
OSFeatures: osFeatures,
|
OSFeatures: osFeatures,
|
||||||
Variant: variant,
|
Variant: variant,
|
||||||
}
|
}
|
||||||
|
if ociv1platform.Architecture == "" && ociv1platform.OS == "" && ociv1platform.OSVersion == "" && ociv1platform.Variant == "" && len(ociv1platform.OSFeatures) == 0 {
|
||||||
|
ociv1platform = nil
|
||||||
|
}
|
||||||
l.oci.Manifests = append(l.oci.Manifests, v1.Descriptor{
|
l.oci.Manifests = append(l.oci.Manifests, v1.Descriptor{
|
||||||
MediaType: manifestType,
|
MediaType: manifestType,
|
||||||
Size: manifestSize,
|
Size: manifestSize,
|
||||||
Digest: manifestDigest,
|
Digest: manifestDigest,
|
||||||
Platform: &ociv1platform,
|
Platform: ociv1platform,
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -170,7 +174,13 @@ func (l *list) SetURLs(instanceDigest digest.Digest, urls []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
oci.URLs = append([]string{}, urls...)
|
oci.URLs = append([]string{}, urls...)
|
||||||
|
if len(oci.URLs) == 0 {
|
||||||
|
oci.URLs = nil
|
||||||
|
}
|
||||||
docker.URLs = append([]string{}, urls...)
|
docker.URLs = append([]string{}, urls...)
|
||||||
|
if len(docker.URLs) == 0 {
|
||||||
|
docker.URLs = nil
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +193,24 @@ func (l *list) URLs(instanceDigest digest.Digest) ([]string, error) {
|
|||||||
return append([]string{}, oci.URLs...), nil
|
return append([]string{}, oci.URLs...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAnnotations sets annotations on the image index, or on a specific manifest.
|
// ClearAnnotations removes all annotations from the image index, or from a
|
||||||
|
// specific manifest.
|
||||||
|
// The field is specific to the OCI image index format, and is not present in Docker manifest lists.
|
||||||
|
func (l *list) ClearAnnotations(instanceDigest *digest.Digest) error {
|
||||||
|
a := &l.oci.Annotations
|
||||||
|
if instanceDigest != nil {
|
||||||
|
oci, err := l.findOCIv1(*instanceDigest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
a = &oci.Annotations
|
||||||
|
}
|
||||||
|
*a = nil
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAnnotations sets annotations on the image index, or on a specific
|
||||||
|
// manifest.
|
||||||
// The field is specific to the OCI image index format, and is not present in Docker manifest lists.
|
// The field is specific to the OCI image index format, and is not present in Docker manifest lists.
|
||||||
func (l *list) SetAnnotations(instanceDigest *digest.Digest, annotations map[string]string) error {
|
func (l *list) SetAnnotations(instanceDigest *digest.Digest, annotations map[string]string) error {
|
||||||
a := &l.oci.Annotations
|
a := &l.oci.Annotations
|
||||||
@ -194,10 +221,15 @@ func (l *list) SetAnnotations(instanceDigest *digest.Digest, annotations map[str
|
|||||||
}
|
}
|
||||||
a = &oci.Annotations
|
a = &oci.Annotations
|
||||||
}
|
}
|
||||||
|
if *a == nil {
|
||||||
(*a) = make(map[string]string)
|
(*a) = make(map[string]string)
|
||||||
|
}
|
||||||
for k, v := range annotations {
|
for k, v := range annotations {
|
||||||
(*a)[k] = v
|
(*a)[k] = v
|
||||||
}
|
}
|
||||||
|
if len(*a) == 0 {
|
||||||
|
*a = nil
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +262,13 @@ func (l *list) SetOS(instanceDigest digest.Digest, os string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
docker.Platform.OS = os
|
docker.Platform.OS = os
|
||||||
|
if oci.Platform == nil {
|
||||||
|
oci.Platform = &v1.Platform{}
|
||||||
|
}
|
||||||
oci.Platform.OS = os
|
oci.Platform.OS = os
|
||||||
|
if oci.Platform.Architecture == "" && oci.Platform.OS == "" && oci.Platform.OSVersion == "" && oci.Platform.Variant == "" && len(oci.Platform.OSFeatures) == 0 {
|
||||||
|
oci.Platform = nil
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +278,11 @@ func (l *list) OS(instanceDigest digest.Digest) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return oci.Platform.OS, nil
|
platform := oci.Platform
|
||||||
|
if platform == nil {
|
||||||
|
platform = &v1.Platform{}
|
||||||
|
}
|
||||||
|
return platform.OS, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetArchitecture sets the Architecture field in the platform information associated with the instance with the specified digest.
|
// SetArchitecture sets the Architecture field in the platform information associated with the instance with the specified digest.
|
||||||
@ -254,7 +296,13 @@ func (l *list) SetArchitecture(instanceDigest digest.Digest, arch string) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
docker.Platform.Architecture = arch
|
docker.Platform.Architecture = arch
|
||||||
|
if oci.Platform == nil {
|
||||||
|
oci.Platform = &v1.Platform{}
|
||||||
|
}
|
||||||
oci.Platform.Architecture = arch
|
oci.Platform.Architecture = arch
|
||||||
|
if oci.Platform.Architecture == "" && oci.Platform.OS == "" && oci.Platform.OSVersion == "" && oci.Platform.Variant == "" && len(oci.Platform.OSFeatures) == 0 {
|
||||||
|
oci.Platform = nil
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +312,11 @@ func (l *list) Architecture(instanceDigest digest.Digest) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return oci.Platform.Architecture, nil
|
platform := oci.Platform
|
||||||
|
if platform == nil {
|
||||||
|
platform = &v1.Platform{}
|
||||||
|
}
|
||||||
|
return platform.Architecture, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetOSVersion sets the OSVersion field in the platform information associated with the instance with the specified digest.
|
// SetOSVersion sets the OSVersion field in the platform information associated with the instance with the specified digest.
|
||||||
@ -278,7 +330,13 @@ func (l *list) SetOSVersion(instanceDigest digest.Digest, osVersion string) erro
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
docker.Platform.OSVersion = osVersion
|
docker.Platform.OSVersion = osVersion
|
||||||
|
if oci.Platform == nil {
|
||||||
|
oci.Platform = &v1.Platform{}
|
||||||
|
}
|
||||||
oci.Platform.OSVersion = osVersion
|
oci.Platform.OSVersion = osVersion
|
||||||
|
if oci.Platform.Architecture == "" && oci.Platform.OS == "" && oci.Platform.OSVersion == "" && oci.Platform.Variant == "" && len(oci.Platform.OSFeatures) == 0 {
|
||||||
|
oci.Platform = nil
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,7 +346,11 @@ func (l *list) OSVersion(instanceDigest digest.Digest) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return oci.Platform.OSVersion, nil
|
platform := oci.Platform
|
||||||
|
if platform == nil {
|
||||||
|
platform = &v1.Platform{}
|
||||||
|
}
|
||||||
|
return platform.OSVersion, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetVariant sets the Variant field in the platform information associated with the instance with the specified digest.
|
// SetVariant sets the Variant field in the platform information associated with the instance with the specified digest.
|
||||||
@ -302,7 +364,13 @@ func (l *list) SetVariant(instanceDigest digest.Digest, variant string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
docker.Platform.Variant = variant
|
docker.Platform.Variant = variant
|
||||||
|
if oci.Platform == nil {
|
||||||
|
oci.Platform = &v1.Platform{}
|
||||||
|
}
|
||||||
oci.Platform.Variant = variant
|
oci.Platform.Variant = variant
|
||||||
|
if oci.Platform.Architecture == "" && oci.Platform.OS == "" && oci.Platform.OSVersion == "" && oci.Platform.Variant == "" && len(oci.Platform.OSFeatures) == 0 {
|
||||||
|
oci.Platform = nil
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +380,11 @@ func (l *list) Variant(instanceDigest digest.Digest) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return oci.Platform.Variant, nil
|
platform := oci.Platform
|
||||||
|
if platform == nil {
|
||||||
|
platform = &v1.Platform{}
|
||||||
|
}
|
||||||
|
return platform.Variant, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFeatures sets the features list in the platform information associated with the instance with the specified digest.
|
// SetFeatures sets the features list in the platform information associated with the instance with the specified digest.
|
||||||
@ -323,6 +395,9 @@ func (l *list) SetFeatures(instanceDigest digest.Digest, features []string) erro
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
docker.Platform.Features = append([]string{}, features...)
|
docker.Platform.Features = append([]string{}, features...)
|
||||||
|
if len(docker.Platform.Features) == 0 {
|
||||||
|
docker.Platform.Features = nil
|
||||||
|
}
|
||||||
// no OCI equivalent
|
// no OCI equivalent
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -348,7 +423,16 @@ func (l *list) SetOSFeatures(instanceDigest digest.Digest, osFeatures []string)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
docker.Platform.OSFeatures = append([]string{}, osFeatures...)
|
docker.Platform.OSFeatures = append([]string{}, osFeatures...)
|
||||||
|
if oci.Platform == nil {
|
||||||
|
oci.Platform = &v1.Platform{}
|
||||||
|
}
|
||||||
oci.Platform.OSFeatures = append([]string{}, osFeatures...)
|
oci.Platform.OSFeatures = append([]string{}, osFeatures...)
|
||||||
|
if len(oci.Platform.OSFeatures) == 0 {
|
||||||
|
oci.Platform.OSFeatures = nil
|
||||||
|
}
|
||||||
|
if oci.Platform.Architecture == "" && oci.Platform.OS == "" && oci.Platform.OSVersion == "" && oci.Platform.Variant == "" && len(oci.Platform.OSFeatures) == 0 {
|
||||||
|
oci.Platform = nil
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,7 +442,11 @@ func (l *list) OSFeatures(instanceDigest digest.Digest) ([]string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return append([]string{}, oci.Platform.OSFeatures...), nil
|
platform := oci.Platform
|
||||||
|
if platform == nil {
|
||||||
|
platform = &v1.Platform{}
|
||||||
|
}
|
||||||
|
return append([]string{}, platform.OSFeatures...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMediaType sets the MediaType field in the instance with the specified digest.
|
// SetMediaType sets the MediaType field in the instance with the specified digest.
|
||||||
|
30
vendor/github.com/containers/common/pkg/ssh/connection_golang.go
generated
vendored
30
vendor/github.com/containers/common/pkg/ssh/connection_golang.go
generated
vendored
@ -53,32 +53,32 @@ func golangConnectionCreate(options ConnectionCreateOptions) error {
|
|||||||
dst.URI += uri.Path
|
dst.URI += uri.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
// TODO this really should not live here, it must be in podman where we write the other connections as well.
|
||||||
if err != nil {
|
// This duplicates the code for no reason and I have a really hard time to make any sense of why this code
|
||||||
return err
|
// was added in the first place.
|
||||||
}
|
return config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
||||||
if cfg.Engine.ServiceDestinations == nil {
|
if cfg.Connection.Connections == nil {
|
||||||
cfg.Engine.ServiceDestinations = map[string]config.Destination{
|
cfg.Connection.Connections = map[string]config.Destination{
|
||||||
options.Name: *dst,
|
options.Name: *dst,
|
||||||
}
|
}
|
||||||
cfg.Engine.ActiveService = options.Name
|
cfg.Connection.Default = options.Name
|
||||||
} else {
|
} else {
|
||||||
cfg.Engine.ServiceDestinations[options.Name] = *dst
|
cfg.Connection.Connections[options.Name] = *dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create or update an existing farm with the connection being added
|
// Create or update an existing farm with the connection being added
|
||||||
if options.Farm != "" {
|
if options.Farm != "" {
|
||||||
if len(cfg.Farms.List) == 0 {
|
if len(cfg.Farm.List) == 0 {
|
||||||
cfg.Farms.Default = options.Farm
|
cfg.Farm.Default = options.Farm
|
||||||
}
|
}
|
||||||
if val, ok := cfg.Farms.List[options.Farm]; ok {
|
if val, ok := cfg.Farm.List[options.Farm]; ok {
|
||||||
cfg.Farms.List[options.Farm] = append(val, options.Name)
|
cfg.Farm.List[options.Farm] = append(val, options.Name)
|
||||||
} else {
|
} else {
|
||||||
cfg.Farms.List[options.Farm] = []string{options.Name}
|
cfg.Farm.List[options.Farm] = []string{options.Name}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
return cfg.Write()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func golangConnectionDial(options ConnectionDialOptions) (*ConnectionDialReport, error) {
|
func golangConnectionDial(options ConnectionDialOptions) (*ConnectionDialReport, error) {
|
||||||
|
34
vendor/github.com/containers/common/pkg/ssh/connection_native.go
generated
vendored
34
vendor/github.com/containers/common/pkg/ssh/connection_native.go
generated
vendored
@ -72,24 +72,32 @@ func nativeConnectionCreate(options ConnectionCreateOptions) error {
|
|||||||
return fmt.Errorf("remote podman %q failed to report its UDS socket", uri.Host)
|
return fmt.Errorf("remote podman %q failed to report its UDS socket", uri.Host)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := config.ReadCustomConfig()
|
// TODO this really should not live here, it must be in podman where we write the other connections as well.
|
||||||
if err != nil {
|
// This duplicates the code for no reason and I have a really hard time to make any sense of why this code
|
||||||
return err
|
// was added in the first place.
|
||||||
}
|
return config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
||||||
if options.Default {
|
if cfg.Connection.Connections == nil {
|
||||||
cfg.Engine.ActiveService = options.Name
|
cfg.Connection.Connections = map[string]config.Destination{
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.Engine.ServiceDestinations == nil {
|
|
||||||
cfg.Engine.ServiceDestinations = map[string]config.Destination{
|
|
||||||
options.Name: *dst,
|
options.Name: *dst,
|
||||||
}
|
}
|
||||||
cfg.Engine.ActiveService = options.Name
|
cfg.Connection.Default = options.Name
|
||||||
} else {
|
} else {
|
||||||
cfg.Engine.ServiceDestinations[options.Name] = *dst
|
cfg.Connection.Connections[options.Name] = *dst
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg.Write()
|
// Create or update an existing farm with the connection being added
|
||||||
|
if options.Farm != "" {
|
||||||
|
if len(cfg.Farm.List) == 0 {
|
||||||
|
cfg.Farm.Default = options.Farm
|
||||||
|
}
|
||||||
|
if val, ok := cfg.Farm.List[options.Farm]; ok {
|
||||||
|
cfg.Farm.List[options.Farm] = append(val, options.Name)
|
||||||
|
} else {
|
||||||
|
cfg.Farm.List[options.Farm] = []string{options.Name}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func nativeConnectionExec(options ConnectionExecOptions) (*ConnectionExecReport, error) {
|
func nativeConnectionExec(options ConnectionExecOptions) (*ConnectionExecReport, error) {
|
||||||
|
4
vendor/github.com/containers/image/v5/version/version.go
generated
vendored
4
vendor/github.com/containers/image/v5/version/version.go
generated
vendored
@ -6,9 +6,9 @@ const (
|
|||||||
// VersionMajor is for an API incompatible changes
|
// VersionMajor is for an API incompatible changes
|
||||||
VersionMajor = 5
|
VersionMajor = 5
|
||||||
// VersionMinor is for functionality in a backwards-compatible manner
|
// VersionMinor is for functionality in a backwards-compatible manner
|
||||||
VersionMinor = 29
|
VersionMinor = 30
|
||||||
// VersionPatch is for backwards-compatible bug fixes
|
// VersionPatch is for backwards-compatible bug fixes
|
||||||
VersionPatch = 2
|
VersionPatch = 0
|
||||||
|
|
||||||
// VersionDev indicates development branch. Releases will be empty string.
|
// VersionDev indicates development branch. Releases will be empty string.
|
||||||
VersionDev = "-dev"
|
VersionDev = "-dev"
|
||||||
|
2
vendor/github.com/containers/storage/Makefile
generated
vendored
2
vendor/github.com/containers/storage/Makefile
generated
vendored
@ -41,7 +41,7 @@ containers-storage: ## build using gc on the host
|
|||||||
$(GO) build -compiler gc $(BUILDFLAGS) ./cmd/containers-storage
|
$(GO) build -compiler gc $(BUILDFLAGS) ./cmd/containers-storage
|
||||||
|
|
||||||
codespell:
|
codespell:
|
||||||
codespell -S Makefile,build,buildah,buildah.spec,imgtype,copy,AUTHORS,bin,vendor,.git,go.sum,CHANGELOG.md,changelog.txt,seccomp.json,.cirrus.yml,"*.xz,*.gz,*.tar,*.tgz,*ico,*.png,*.1,*.5,*.orig,*.rej" -L worl,flate,uint,iff,od,ERRO -w
|
codespell -S Makefile,build,buildah,buildah.spec,imgtype,copy,AUTHORS,bin,vendor,.git,go.sum,CHANGELOG.md,changelog.txt,seccomp.json,.cirrus.yml,"*.xz,*.gz,*.tar,*.tgz,*ico,*.png,*.1,*.5,*.orig,*.rej" -L plack,worl,flate,uint,iff,od,ERRO -w
|
||||||
|
|
||||||
binary local-binary: containers-storage
|
binary local-binary: containers-storage
|
||||||
|
|
||||||
|
28
vendor/github.com/containers/storage/pkg/chunked/storage_linux.go
generated
vendored
28
vendor/github.com/containers/storage/pkg/chunked/storage_linux.go
generated
vendored
@ -73,11 +73,9 @@ type chunkedDiffer struct {
|
|||||||
zstdReader *zstd.Decoder
|
zstdReader *zstd.Decoder
|
||||||
rawReader io.Reader
|
rawReader io.Reader
|
||||||
|
|
||||||
// contentDigest is the digest of the uncompressed content
|
// tocDigest is the digest of the TOC document when the layer
|
||||||
// (diffID) when the layer is fully retrieved. If the layer
|
// is partially pulled.
|
||||||
// is not fully retrieved, instead of using the digest of the
|
tocDigest digest.Digest
|
||||||
// uncompressed content, it refers to the digest of the TOC.
|
|
||||||
contentDigest digest.Digest
|
|
||||||
|
|
||||||
// convertedToZstdChunked is set to true if the layer needs to
|
// convertedToZstdChunked is set to true if the layer needs to
|
||||||
// be converted to the zstd:chunked format before it can be
|
// be converted to the zstd:chunked format before it can be
|
||||||
@ -292,7 +290,7 @@ func makeZstdChunkedDiffer(ctx context.Context, store storage.Store, blobSize in
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
contentDigest, err := digest.Parse(annotations[internal.ManifestChecksumKey])
|
tocDigest, err := digest.Parse(annotations[internal.ManifestChecksumKey])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse TOC digest %q: %w", annotations[internal.ManifestChecksumKey], err)
|
return nil, fmt.Errorf("parse TOC digest %q: %w", annotations[internal.ManifestChecksumKey], err)
|
||||||
}
|
}
|
||||||
@ -300,7 +298,7 @@ func makeZstdChunkedDiffer(ctx context.Context, store storage.Store, blobSize in
|
|||||||
return &chunkedDiffer{
|
return &chunkedDiffer{
|
||||||
fsVerityDigests: make(map[string]string),
|
fsVerityDigests: make(map[string]string),
|
||||||
blobSize: blobSize,
|
blobSize: blobSize,
|
||||||
contentDigest: contentDigest,
|
tocDigest: tocDigest,
|
||||||
copyBuffer: makeCopyBuffer(),
|
copyBuffer: makeCopyBuffer(),
|
||||||
fileType: fileTypeZstdChunked,
|
fileType: fileTypeZstdChunked,
|
||||||
layersCache: layersCache,
|
layersCache: layersCache,
|
||||||
@ -322,7 +320,7 @@ func makeEstargzChunkedDiffer(ctx context.Context, store storage.Store, blobSize
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
contentDigest, err := digest.Parse(annotations[estargz.TOCJSONDigestAnnotation])
|
tocDigest, err := digest.Parse(annotations[estargz.TOCJSONDigestAnnotation])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("parse TOC digest %q: %w", annotations[estargz.TOCJSONDigestAnnotation], err)
|
return nil, fmt.Errorf("parse TOC digest %q: %w", annotations[estargz.TOCJSONDigestAnnotation], err)
|
||||||
}
|
}
|
||||||
@ -330,7 +328,7 @@ func makeEstargzChunkedDiffer(ctx context.Context, store storage.Store, blobSize
|
|||||||
return &chunkedDiffer{
|
return &chunkedDiffer{
|
||||||
fsVerityDigests: make(map[string]string),
|
fsVerityDigests: make(map[string]string),
|
||||||
blobSize: blobSize,
|
blobSize: blobSize,
|
||||||
contentDigest: contentDigest,
|
tocDigest: tocDigest,
|
||||||
copyBuffer: makeCopyBuffer(),
|
copyBuffer: makeCopyBuffer(),
|
||||||
fileType: fileTypeEstargz,
|
fileType: fileTypeEstargz,
|
||||||
layersCache: layersCache,
|
layersCache: layersCache,
|
||||||
@ -1613,6 +1611,9 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions, diff
|
|||||||
// stream to use for reading the zstd:chunked or Estargz file.
|
// stream to use for reading the zstd:chunked or Estargz file.
|
||||||
stream := c.stream
|
stream := c.stream
|
||||||
|
|
||||||
|
var uncompressedDigest digest.Digest
|
||||||
|
tocDigest := c.tocDigest
|
||||||
|
|
||||||
if c.convertToZstdChunked {
|
if c.convertToZstdChunked {
|
||||||
fd, err := unix.Open(dest, unix.O_TMPFILE|unix.O_RDWR|unix.O_CLOEXEC, 0o600)
|
fd, err := unix.Open(dest, unix.O_TMPFILE|unix.O_RDWR|unix.O_CLOEXEC, 0o600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1663,13 +1664,13 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions, diff
|
|||||||
c.fileType = fileTypeZstdChunked
|
c.fileType = fileTypeZstdChunked
|
||||||
c.manifest = manifest
|
c.manifest = manifest
|
||||||
c.tarSplit = tarSplit
|
c.tarSplit = tarSplit
|
||||||
|
|
||||||
// since we retrieved the whole file and it was validated, use the diffID instead of the TOC digest.
|
|
||||||
c.contentDigest = diffID
|
|
||||||
c.tocOffset = tocOffset
|
c.tocOffset = tocOffset
|
||||||
|
|
||||||
// the file was generated by us and the digest for each file was already computed, no need to validate it again.
|
// the file was generated by us and the digest for each file was already computed, no need to validate it again.
|
||||||
c.skipValidation = true
|
c.skipValidation = true
|
||||||
|
// since we retrieved the whole file and it was validated, do not use the TOC digest, but set the uncompressed digest.
|
||||||
|
tocDigest = ""
|
||||||
|
uncompressedDigest = diffID
|
||||||
}
|
}
|
||||||
|
|
||||||
lcd := chunkedLayerData{
|
lcd := chunkedLayerData{
|
||||||
@ -1698,7 +1699,8 @@ func (c *chunkedDiffer) ApplyDiff(dest string, options *archive.TarOptions, diff
|
|||||||
Artifacts: map[string]interface{}{
|
Artifacts: map[string]interface{}{
|
||||||
tocKey: toc,
|
tocKey: toc,
|
||||||
},
|
},
|
||||||
TOCDigest: c.contentDigest,
|
TOCDigest: tocDigest,
|
||||||
|
UncompressedDigest: uncompressedDigest,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !parseBooleanPullOption(c.storeOpts, "enable_partial_images", false) {
|
if !parseBooleanPullOption(c.storeOpts, "enable_partial_images", false) {
|
||||||
|
6
vendor/modules.txt
vendored
6
vendor/modules.txt
vendored
@ -167,7 +167,7 @@ github.com/containers/buildah/pkg/sshagent
|
|||||||
github.com/containers/buildah/pkg/util
|
github.com/containers/buildah/pkg/util
|
||||||
github.com/containers/buildah/pkg/volumes
|
github.com/containers/buildah/pkg/volumes
|
||||||
github.com/containers/buildah/util
|
github.com/containers/buildah/util
|
||||||
# github.com/containers/common v0.57.1-0.20240129201029-3310a75e3608
|
# github.com/containers/common v0.57.1-0.20240130143645-b26099256b92
|
||||||
## explicit; go 1.20
|
## explicit; go 1.20
|
||||||
github.com/containers/common/internal/attributedstring
|
github.com/containers/common/internal/attributedstring
|
||||||
github.com/containers/common/libimage
|
github.com/containers/common/libimage
|
||||||
@ -236,7 +236,7 @@ github.com/containers/conmon/runner/config
|
|||||||
# github.com/containers/gvisor-tap-vsock v0.7.2
|
# github.com/containers/gvisor-tap-vsock v0.7.2
|
||||||
## explicit; go 1.20
|
## explicit; go 1.20
|
||||||
github.com/containers/gvisor-tap-vsock/pkg/types
|
github.com/containers/gvisor-tap-vsock/pkg/types
|
||||||
# github.com/containers/image/v5 v5.29.2-0.20240129204525-816800b5daf7
|
# github.com/containers/image/v5 v5.29.2-0.20240130233108-e66a1ade2efc
|
||||||
## explicit; go 1.19
|
## explicit; go 1.19
|
||||||
github.com/containers/image/v5/copy
|
github.com/containers/image/v5/copy
|
||||||
github.com/containers/image/v5/directory
|
github.com/containers/image/v5/directory
|
||||||
@ -346,7 +346,7 @@ github.com/containers/psgo/internal/dev
|
|||||||
github.com/containers/psgo/internal/host
|
github.com/containers/psgo/internal/host
|
||||||
github.com/containers/psgo/internal/proc
|
github.com/containers/psgo/internal/proc
|
||||||
github.com/containers/psgo/internal/process
|
github.com/containers/psgo/internal/process
|
||||||
# github.com/containers/storage v1.52.1-0.20240129173630-7a525ce0e2bc
|
# github.com/containers/storage v1.52.1-0.20240130205044-62997abeaf2f
|
||||||
## explicit; go 1.20
|
## explicit; go 1.20
|
||||||
github.com/containers/storage
|
github.com/containers/storage
|
||||||
github.com/containers/storage/drivers
|
github.com/containers/storage/drivers
|
||||||
|
Reference in New Issue
Block a user