mirror of
https://github.com/containers/podman.git
synced 2025-08-23 17:22:30 +08:00

Modify `RemoveConnections` to verify the new default system connection's rootful state matches the rootful-ness of the podman machine it is associated with. Signed-off-by: Jake Correnti <jakecorrenti+github@proton.me>
164 lines
4.2 KiB
Go
164 lines
4.2 KiB
Go
//go:build amd64 || arm64
|
|
|
|
package connection
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"net/url"
|
|
|
|
"github.com/containers/common/pkg/config"
|
|
"github.com/containers/podman/v5/pkg/machine/define"
|
|
)
|
|
|
|
const LocalhostIP = "127.0.0.1"
|
|
|
|
type connection struct {
|
|
name string
|
|
uri *url.URL
|
|
}
|
|
|
|
func addConnection(cons []connection, identity string, isDefault bool) error {
|
|
if len(identity) < 1 {
|
|
return errors.New("identity must be defined")
|
|
}
|
|
|
|
return config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
|
for i, con := range cons {
|
|
if _, ok := cfg.Connection.Connections[con.name]; ok {
|
|
return fmt.Errorf("cannot overwrite connection %q", con.name)
|
|
}
|
|
|
|
dst := config.Destination{
|
|
URI: con.uri.String(),
|
|
IsMachine: true,
|
|
Identity: identity,
|
|
}
|
|
|
|
if isDefault && i == 0 {
|
|
cfg.Connection.Default = con.name
|
|
}
|
|
|
|
if cfg.Connection.Connections == nil {
|
|
cfg.Connection.Connections = map[string]config.Destination{
|
|
con.name: dst,
|
|
}
|
|
cfg.Connection.Default = con.name
|
|
} else {
|
|
cfg.Connection.Connections[con.name] = dst
|
|
}
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func UpdateConnectionPairPort(name string, port, uid int, remoteUsername string, identityPath string) error {
|
|
cons := createConnections(name, uid, port, remoteUsername)
|
|
return config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
|
for _, con := range cons {
|
|
dst := config.Destination{
|
|
IsMachine: true,
|
|
URI: con.uri.String(),
|
|
Identity: identityPath,
|
|
}
|
|
cfg.Connection.Connections[con.name] = dst
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// UpdateConnectionIfDefault updates the default connection to the rootful/rootless when depending
|
|
// on the bool but only if other rootful/less connection was already the default.
|
|
// Returns true if it modified the default
|
|
func UpdateConnectionIfDefault(rootful bool, name, rootfulName string) error {
|
|
return config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
|
updateConnection(cfg, rootful, name, rootfulName)
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func updateConnection(cfg *config.ConnectionsFile, rootful bool, name, rootfulName string) {
|
|
if name == cfg.Connection.Default && rootful {
|
|
cfg.Connection.Default = rootfulName
|
|
} else if rootfulName == cfg.Connection.Default && !rootful {
|
|
cfg.Connection.Default = name
|
|
}
|
|
}
|
|
|
|
func RemoveConnections(machines map[string]bool, names ...string) error {
|
|
var dest config.Destination
|
|
var service string
|
|
|
|
if err := config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
|
err := setNewDefaultConnection(cfg, &dest, &service, names...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
rootful, ok := machines[service]
|
|
if dest.IsMachine && ok {
|
|
updateConnection(cfg, rootful, service, service+"-root")
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// setNewDefaultConnection iterates through the available system connections and
|
|
// sets the first available connection as the new default
|
|
func setNewDefaultConnection(cfg *config.ConnectionsFile, dest *config.Destination, service *string, names ...string) error {
|
|
// delete the connection associated with the names and if that connection is
|
|
// the default, reset the default connection
|
|
for _, name := range names {
|
|
if _, ok := cfg.Connection.Connections[name]; ok {
|
|
delete(cfg.Connection.Connections, name)
|
|
} else {
|
|
return fmt.Errorf("unable to find connection named %q", name)
|
|
}
|
|
|
|
if cfg.Connection.Default == name {
|
|
cfg.Connection.Default = ""
|
|
}
|
|
}
|
|
|
|
// If there is a podman-machine-default system connection, immediately set that as the new default
|
|
if c, ok := cfg.Connection.Connections[define.DefaultMachineName]; ok {
|
|
cfg.Connection.Default = define.DefaultMachineName
|
|
*dest = c
|
|
*service = define.DefaultMachineName
|
|
return nil
|
|
}
|
|
|
|
// set the new default system connection to the first in the map
|
|
for con, d := range cfg.Connection.Connections {
|
|
cfg.Connection.Default = con
|
|
*dest = d
|
|
*service = con
|
|
break
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// makeSSHURL creates a URL from the given input
|
|
func makeSSHURL(host, path, port, userName string) *url.URL {
|
|
var hostname string
|
|
if len(port) > 0 {
|
|
hostname = net.JoinHostPort(host, port)
|
|
} else {
|
|
hostname = host
|
|
}
|
|
userInfo := url.User(userName)
|
|
return &url.URL{
|
|
Scheme: "ssh",
|
|
User: userInfo,
|
|
Host: hostname,
|
|
Path: path,
|
|
}
|
|
}
|