mirror of
https://github.com/containers/podman.git
synced 2025-10-20 20:54:45 +08:00
Resurrect auto-port reassignment, but for all providers
- Updates common to pull in new locked edit [NO NEW TESTS NEEDED] Signed-off-by: Jason T. Greene <jason.greene@redhat.com>
This commit is contained in:
2
go.mod
2
go.mod
@ -11,7 +11,7 @@ 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.34.1-0.20240229193131-f5d7689ef4cd
|
github.com/containers/buildah v1.34.1-0.20240229193131-f5d7689ef4cd
|
||||||
github.com/containers/common v0.57.1-0.20240229165734-cec09922602e
|
github.com/containers/common v0.57.1-0.20240304165751-a0d555c70d52
|
||||||
github.com/containers/conmon v2.0.20+incompatible
|
github.com/containers/conmon v2.0.20+incompatible
|
||||||
github.com/containers/gvisor-tap-vsock v0.7.3
|
github.com/containers/gvisor-tap-vsock v0.7.3
|
||||||
github.com/containers/image/v5 v5.29.3-0.20240229213915-cdc68020a24f
|
github.com/containers/image/v5 v5.29.3-0.20240229213915-cdc68020a24f
|
||||||
|
4
go.sum
4
go.sum
@ -76,8 +76,8 @@ 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.34.1-0.20240229193131-f5d7689ef4cd h1:4cHNzaywyyJsCAtwUKMZm8r/wqm/WuNC70GfnI3kh18=
|
github.com/containers/buildah v1.34.1-0.20240229193131-f5d7689ef4cd h1:4cHNzaywyyJsCAtwUKMZm8r/wqm/WuNC70GfnI3kh18=
|
||||||
github.com/containers/buildah v1.34.1-0.20240229193131-f5d7689ef4cd/go.mod h1:3fn5edBIPpIOPJYdnxBdTF7bjnBHhqZwYK5a6ApNdyk=
|
github.com/containers/buildah v1.34.1-0.20240229193131-f5d7689ef4cd/go.mod h1:3fn5edBIPpIOPJYdnxBdTF7bjnBHhqZwYK5a6ApNdyk=
|
||||||
github.com/containers/common v0.57.1-0.20240229165734-cec09922602e h1:TPgCd6bWFyliJxCXEiCI1LnbB3kBUkpx1dw51ngDjWI=
|
github.com/containers/common v0.57.1-0.20240304165751-a0d555c70d52 h1:+rq1qOOEv/2Sa1A9Tmv7yKuOzea8W2n6kFUH+bon61Y=
|
||||||
github.com/containers/common v0.57.1-0.20240229165734-cec09922602e/go.mod h1:8irlyBcVooYx0F+YmoY7PQPAIgdJvCj17bvL7PqeaxI=
|
github.com/containers/common v0.57.1-0.20240304165751-a0d555c70d52/go.mod h1:h92alKzSekxVC+VDaX4gt7RJpXvJKF79a9TnULZ5ZDc=
|
||||||
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.3 h1:yORnf15sP+sLFhxLNLgmB5/lOhldn9dRMHx/tmYtSOQ=
|
github.com/containers/gvisor-tap-vsock v0.7.3 h1:yORnf15sP+sLFhxLNLgmB5/lOhldn9dRMHx/tmYtSOQ=
|
||||||
|
@ -313,6 +313,11 @@ func (a AppleHVStubber) StopHostNetworking(_ *vmconfigs.MachineConfig, _ define.
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a AppleHVStubber) UpdateSSHPort(mc *vmconfigs.MachineConfig, port int) error {
|
||||||
|
// managed by gvproxy on this backend, so nothing to do
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a AppleHVStubber) VMType() define.VMType {
|
func (a AppleHVStubber) VMType() define.VMType {
|
||||||
return define.AppleHvVirt
|
return define.AppleHvVirt
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//go:build amd64 || arm64
|
||||||
|
|
||||||
package connection
|
package connection
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -14,19 +16,8 @@ func AddSSHConnectionsToPodmanSocket(uid, port int, identityPath, name, remoteUs
|
|||||||
fmt.Println("An ignition path was provided. No SSH connection was added to Podman")
|
fmt.Println("An ignition path was provided. No SSH connection was added to Podman")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
uri := makeSSHURL(LocalhostIP, fmt.Sprintf("/run/user/%d/podman/podman.sock", uid), strconv.Itoa(port), remoteUsername)
|
|
||||||
uriRoot := makeSSHURL(LocalhostIP, "/run/podman/podman.sock", strconv.Itoa(port), "root")
|
|
||||||
|
|
||||||
cons := []connection{
|
cons := createConnections(name, uid, port, remoteUsername)
|
||||||
{
|
|
||||||
name: name,
|
|
||||||
uri: uri,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: name + "-root",
|
|
||||||
uri: uriRoot,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// The first connection defined when connections is empty will become the default
|
// The first connection defined when connections is empty will become the default
|
||||||
// regardless of IsDefault, so order according to rootful
|
// regardless of IsDefault, so order according to rootful
|
||||||
@ -36,3 +27,19 @@ func AddSSHConnectionsToPodmanSocket(uid, port int, identityPath, name, remoteUs
|
|||||||
|
|
||||||
return addConnection(cons, identityPath, opts.IsDefault)
|
return addConnection(cons, identityPath, opts.IsDefault)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createConnections(name string, uid, port int, remoteUsername string) []connection {
|
||||||
|
uri := makeSSHURL(LocalhostIP, fmt.Sprintf("/run/user/%d/podman/podman.sock", uid), strconv.Itoa(port), remoteUsername)
|
||||||
|
uriRoot := makeSSHURL(LocalhostIP, "/run/podman/podman.sock", strconv.Itoa(port), "root")
|
||||||
|
|
||||||
|
return []connection{
|
||||||
|
{
|
||||||
|
name: name,
|
||||||
|
uri: uri,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: name + "-root",
|
||||||
|
uri: uriRoot,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -55,14 +55,17 @@ func addConnection(cons []connection, identity string, isDefault bool) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func ChangeConnectionURI(name string, uri fmt.Stringer) error {
|
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 {
|
return config.EditConnectionConfig(func(cfg *config.ConnectionsFile) error {
|
||||||
dst, ok := cfg.Connection.Connections[name]
|
for _, con := range cons {
|
||||||
if !ok {
|
dst := config.Destination{
|
||||||
return errors.New("connection not found")
|
IsMachine: true,
|
||||||
|
URI: con.uri.String(),
|
||||||
|
Identity: identityPath,
|
||||||
|
}
|
||||||
|
cfg.Connection.Connections[name] = dst
|
||||||
}
|
}
|
||||||
dst.URI = uri.String()
|
|
||||||
cfg.Connection.Connections[name] = dst
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -446,6 +446,11 @@ func (h HyperVStubber) PostStartNetworking(mc *vmconfigs.MachineConfig, noInfo b
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h HyperVStubber) UpdateSSHPort(mc *vmconfigs.MachineConfig, port int) error {
|
||||||
|
// managed by gvproxy on this backend, so nothing to do
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (h HyperVStubber) GetDisk(userInputPath string, dirs *define.MachineDirs, mc *vmconfigs.MachineConfig) error {
|
func (h HyperVStubber) GetDisk(userInputPath string, dirs *define.MachineDirs, mc *vmconfigs.MachineConfig) error {
|
||||||
return diskpull.GetDisk(userInputPath, dirs, mc.ImagePath, h.VMType(), mc.Name)
|
return diskpull.GetDisk(userInputPath, dirs, mc.ImagePath, h.VMType(), mc.Name)
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//go:build amd64 || arm64
|
||||||
|
|
||||||
package ignition
|
package ignition
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//go:build !darwin
|
//go:build linux || freebsd
|
||||||
|
|
||||||
package qemu
|
package qemu
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//go:build windows && amd64
|
//go:build tempoff
|
||||||
|
|
||||||
package qemu
|
package qemu
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//go:build !darwin
|
//go:build linux || freebsd
|
||||||
|
|
||||||
package qemu
|
package qemu
|
||||||
|
|
||||||
@ -352,6 +352,11 @@ func (q *QEMUStubber) PostStartNetworking(mc *vmconfigs.MachineConfig, noInfo bo
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (q *QEMUStubber) UpdateSSHPort(mc *vmconfigs.MachineConfig, port int) error {
|
||||||
|
// managed by gvproxy on this backend, so nothing to do
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (q *QEMUStubber) GetDisk(userInputPath string, dirs *define.MachineDirs, mc *vmconfigs.MachineConfig) error {
|
func (q *QEMUStubber) GetDisk(userInputPath string, dirs *define.MachineDirs, mc *vmconfigs.MachineConfig) error {
|
||||||
return diskpull.GetDisk(userInputPath, dirs, mc.ImagePath, q.VMType(), mc.Name)
|
return diskpull.GetDisk(userInputPath, dirs, mc.ImagePath, q.VMType(), mc.Name)
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,10 @@ import (
|
|||||||
"github.com/containers/common/pkg/config"
|
"github.com/containers/common/pkg/config"
|
||||||
gvproxy "github.com/containers/gvisor-tap-vsock/pkg/types"
|
gvproxy "github.com/containers/gvisor-tap-vsock/pkg/types"
|
||||||
"github.com/containers/podman/v5/pkg/machine"
|
"github.com/containers/podman/v5/pkg/machine"
|
||||||
|
"github.com/containers/podman/v5/pkg/machine/connection"
|
||||||
"github.com/containers/podman/v5/pkg/machine/define"
|
"github.com/containers/podman/v5/pkg/machine/define"
|
||||||
"github.com/containers/podman/v5/pkg/machine/env"
|
"github.com/containers/podman/v5/pkg/machine/env"
|
||||||
|
"github.com/containers/podman/v5/pkg/machine/ports"
|
||||||
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
|
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@ -91,6 +93,14 @@ func startHostForwarder(mc *vmconfigs.MachineConfig, provider vmconfigs.VMProvid
|
|||||||
}
|
}
|
||||||
|
|
||||||
func startNetworking(mc *vmconfigs.MachineConfig, provider vmconfigs.VMProvider) (string, machine.APIForwardingState, error) {
|
func startNetworking(mc *vmconfigs.MachineConfig, provider vmconfigs.VMProvider) (string, machine.APIForwardingState, error) {
|
||||||
|
// Check if SSH port is in use, and reassign if necessary
|
||||||
|
if !ports.IsLocalPortAvailable(mc.SSH.Port) {
|
||||||
|
logrus.Warnf("detected port conflict on machine ssh port [%d], reassigning", mc.SSH.Port)
|
||||||
|
if err := reassignSSHPort(mc, provider); err != nil {
|
||||||
|
return "", 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Provider has its own networking code path (e.g. WSL)
|
// Provider has its own networking code path (e.g. WSL)
|
||||||
if provider.UseProviderNetworkSetup() {
|
if provider.UseProviderNetworkSetup() {
|
||||||
return "", 0, provider.StartNetworking(mc, nil)
|
return "", 0, provider.StartNetworking(mc, nil)
|
||||||
@ -153,6 +163,53 @@ func conductVMReadinessCheck(mc *vmconfigs.MachineConfig, maxBackoffs int, backo
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func reassignSSHPort(mc *vmconfigs.MachineConfig, provider vmconfigs.VMProvider) error {
|
||||||
|
newPort, err := ports.AllocateMachinePort()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
success := false
|
||||||
|
defer func() {
|
||||||
|
if !success {
|
||||||
|
if err := ports.ReleaseMachinePort(newPort); err != nil {
|
||||||
|
logrus.Warnf("could not release port allocation as part of failure rollback (%d): %s", newPort, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Write a transient invalid port, to force a retry on failure
|
||||||
|
oldPort := mc.SSH.Port
|
||||||
|
mc.SSH.Port = 0
|
||||||
|
if err := mc.Write(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ports.ReleaseMachinePort(oldPort); err != nil {
|
||||||
|
logrus.Warnf("could not release current ssh port allocation (%d): %s", oldPort, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the backend's settings if relevant (e.g. WSL)
|
||||||
|
if err := provider.UpdateSSHPort(mc, newPort); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
mc.SSH.Port = newPort
|
||||||
|
if err := connection.UpdateConnectionPairPort(mc.Name, newPort, mc.HostUser.UID, mc.SSH.RemoteUsername, mc.SSH.IdentityPath); err != nil {
|
||||||
|
return fmt.Errorf("could not update remote connection configuration: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write updated port back
|
||||||
|
if err := mc.Write(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// inform defer routine not to release the port
|
||||||
|
success = true
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func isListening(port int) bool {
|
func isListening(port int) bool {
|
||||||
// Check if we can dial it
|
// Check if we can dial it
|
||||||
conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", "127.0.0.1", port), 10*time.Millisecond)
|
conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", "127.0.0.1", port), 10*time.Millisecond)
|
||||||
|
@ -96,6 +96,7 @@ type VMProvider interface { //nolint:interfacebloat
|
|||||||
UserModeNetworkEnabled(mc *MachineConfig) bool
|
UserModeNetworkEnabled(mc *MachineConfig) bool
|
||||||
UseProviderNetworkSetup() bool
|
UseProviderNetworkSetup() bool
|
||||||
RequireExclusiveActive() bool
|
RequireExclusiveActive() bool
|
||||||
|
UpdateSSHPort(mc *MachineConfig, port int) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// HostUser describes the host user
|
// HostUser describes the host user
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
"github.com/containers/podman/v5/pkg/machine/connection"
|
"github.com/containers/podman/v5/pkg/machine/connection"
|
||||||
"github.com/containers/podman/v5/pkg/machine/define"
|
"github.com/containers/podman/v5/pkg/machine/define"
|
||||||
"github.com/containers/podman/v5/pkg/machine/lock"
|
"github.com/containers/podman/v5/pkg/machine/lock"
|
||||||
"github.com/containers/podman/v5/utils"
|
"github.com/containers/podman/v5/pkg/machine/ports"
|
||||||
"github.com/containers/storage/pkg/ioutils"
|
"github.com/containers/storage/pkg/ioutils"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@ -78,8 +78,7 @@ func NewMachineConfig(opts define.InitOptions, dirs *define.MachineDirs, sshIden
|
|||||||
}
|
}
|
||||||
mc.Resources = mrc
|
mc.Resources = mrc
|
||||||
|
|
||||||
// TODO WSL had a locking port mechanism, we should consider this.
|
sshPort, err := ports.AllocateMachinePort()
|
||||||
sshPort, err := utils.GetRandomPort()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -204,6 +203,11 @@ func (mc *MachineConfig) Remove(saveIgnition, saveImage bool) ([]string, func()
|
|||||||
if err := mc.configPath.Delete(); err != nil {
|
if err := mc.configPath.Delete(); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := ports.ReleaseMachinePort(mc.SSH.Port); err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
|
||||||
return errorhandling.JoinErrors(errs)
|
return errorhandling.JoinErrors(errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/podman/v5/pkg/machine/ocipull"
|
"github.com/containers/podman/v5/pkg/machine/ocipull"
|
||||||
"github.com/containers/podman/v5/pkg/machine/ports"
|
|
||||||
"github.com/containers/podman/v5/pkg/machine/shim/diskpull"
|
"github.com/containers/podman/v5/pkg/machine/shim/diskpull"
|
||||||
"github.com/containers/podman/v5/pkg/machine/stdpull"
|
"github.com/containers/podman/v5/pkg/machine/stdpull"
|
||||||
"github.com/containers/podman/v5/pkg/machine/wsl/wutil"
|
"github.com/containers/podman/v5/pkg/machine/wsl/wutil"
|
||||||
@ -111,7 +110,7 @@ func (w WSLStubber) Remove(mc *vmconfigs.MachineConfig) ([]string, func() error,
|
|||||||
if err := runCmdPassThrough(wutil.FindWSL(), "--unregister", machine.ToDist(mc.Name)); err != nil {
|
if err := runCmdPassThrough(wutil.FindWSL(), "--unregister", machine.ToDist(mc.Name)); err != nil {
|
||||||
logrus.Error(err)
|
logrus.Error(err)
|
||||||
}
|
}
|
||||||
return ports.ReleaseMachinePort(mc.SSH.Port)
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return []string{}, wslRemoveFunc, nil
|
return []string{}, wslRemoveFunc, nil
|
||||||
@ -205,15 +204,6 @@ func (w WSLStubber) PostStartNetworking(mc *vmconfigs.MachineConfig, noInfo bool
|
|||||||
func (w WSLStubber) StartVM(mc *vmconfigs.MachineConfig) (func() error, func() error, error) {
|
func (w WSLStubber) StartVM(mc *vmconfigs.MachineConfig) (func() error, func() error, error) {
|
||||||
dist := machine.ToDist(mc.Name)
|
dist := machine.ToDist(mc.Name)
|
||||||
|
|
||||||
// TODO The original code checked to see if the SSH port was actually open and re-assigned if it was
|
|
||||||
// we could consider this but it should be higher up the stack
|
|
||||||
// if !machine.IsLocalPortAvailable(v.Port) {
|
|
||||||
// logrus.Warnf("SSH port conflict detected, reassigning a new port")
|
|
||||||
// if err := v.reassignSshPort(); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
err := wslInvoke(dist, "/root/bootstrap")
|
err := wslInvoke(dist, "/root/bootstrap")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("the WSL bootstrap script failed: %w", err)
|
err = fmt.Errorf("the WSL bootstrap script failed: %w", err)
|
||||||
@ -279,6 +269,16 @@ func (w WSLStubber) StopHostNetworking(mc *vmconfigs.MachineConfig, vmType defin
|
|||||||
return stopUserModeNetworking(mc)
|
return stopUserModeNetworking(mc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w WSLStubber) UpdateSSHPort(mc *vmconfigs.MachineConfig, port int) error {
|
||||||
|
dist := machine.ToDist(mc.Name)
|
||||||
|
|
||||||
|
if err := wslInvoke(dist, "sh", "-c", fmt.Sprintf(changePort, port)); err != nil {
|
||||||
|
return fmt.Errorf("could not change SSH port for guest OS: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (w WSLStubber) VMType() define.VMType {
|
func (w WSLStubber) VMType() define.VMType {
|
||||||
return define.WSLVirt
|
return define.WSLVirt
|
||||||
}
|
}
|
||||||
|
144
vendor/github.com/containers/common/pkg/cgroups/cgroups_linux.go
generated
vendored
144
vendor/github.com/containers/common/pkg/cgroups/cgroups_linux.go
generated
vendored
@ -13,6 +13,9 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/containers/storage/pkg/unshare"
|
"github.com/containers/storage/pkg/unshare"
|
||||||
systemdDbus "github.com/coreos/go-systemd/v22/dbus"
|
systemdDbus "github.com/coreos/go-systemd/v22/dbus"
|
||||||
@ -22,6 +25,7 @@ import (
|
|||||||
"github.com/opencontainers/runc/libcontainer/configs"
|
"github.com/opencontainers/runc/libcontainer/configs"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/exp/maps"
|
"golang.org/x/exp/maps"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -30,6 +34,10 @@ var (
|
|||||||
// ErrCgroupV1Rootless means the cgroup v1 were attempted to be used in rootless environment
|
// ErrCgroupV1Rootless means the cgroup v1 were attempted to be used in rootless environment
|
||||||
ErrCgroupV1Rootless = errors.New("no support for CGroups V1 in rootless environments")
|
ErrCgroupV1Rootless = errors.New("no support for CGroups V1 in rootless environments")
|
||||||
ErrStatCgroup = errors.New("no cgroup available for gathering user statistics")
|
ErrStatCgroup = errors.New("no cgroup available for gathering user statistics")
|
||||||
|
|
||||||
|
isUnifiedOnce sync.Once
|
||||||
|
isUnified bool
|
||||||
|
isUnifiedErr error
|
||||||
)
|
)
|
||||||
|
|
||||||
// CgroupControl controls a cgroup hierarchy
|
// CgroupControl controls a cgroup hierarchy
|
||||||
@ -731,3 +739,139 @@ func SystemCPUUsage() (uint64, error) {
|
|||||||
}
|
}
|
||||||
return total, nil
|
return total, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode.
|
||||||
|
func IsCgroup2UnifiedMode() (bool, error) {
|
||||||
|
isUnifiedOnce.Do(func() {
|
||||||
|
var st syscall.Statfs_t
|
||||||
|
if err := syscall.Statfs("/sys/fs/cgroup", &st); err != nil {
|
||||||
|
isUnified, isUnifiedErr = false, err
|
||||||
|
} else {
|
||||||
|
isUnified, isUnifiedErr = st.Type == unix.CGROUP2_SUPER_MAGIC, nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return isUnified, isUnifiedErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserConnection returns an user connection to D-BUS
|
||||||
|
func UserConnection(uid int) (*systemdDbus.Conn, error) {
|
||||||
|
return systemdDbus.NewConnection(func() (*dbus.Conn, error) {
|
||||||
|
return dbusAuthConnection(uid, dbus.SessionBusPrivateNoAutoStartup)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserOwnsCurrentSystemdCgroup checks whether the current EUID owns the
|
||||||
|
// current cgroup.
|
||||||
|
func UserOwnsCurrentSystemdCgroup() (bool, error) {
|
||||||
|
uid := os.Geteuid()
|
||||||
|
|
||||||
|
cgroup2, err := IsCgroup2UnifiedMode()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.Open("/proc/self/cgroup")
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(f)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
parts := strings.SplitN(line, ":", 3)
|
||||||
|
|
||||||
|
if len(parts) < 3 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var cgroupPath string
|
||||||
|
|
||||||
|
if cgroup2 {
|
||||||
|
cgroupPath = filepath.Join(cgroupRoot, parts[2])
|
||||||
|
} else {
|
||||||
|
if parts[1] != "name=systemd" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cgroupPath = filepath.Join(cgroupRoot, "systemd", parts[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
st, err := os.Stat(cgroupPath)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
s := st.Sys()
|
||||||
|
if s == nil {
|
||||||
|
return false, fmt.Errorf("stat cgroup path %s", cgroupPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
if int(s.(*syscall.Stat_t).Uid) != uid {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return false, fmt.Errorf("parsing file /proc/self/cgroup: %w", err)
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// rmDirRecursively delete recursively a cgroup directory.
|
||||||
|
// It differs from os.RemoveAll as it doesn't attempt to unlink files.
|
||||||
|
// On cgroupfs we are allowed only to rmdir empty directories.
|
||||||
|
func rmDirRecursively(path string) error {
|
||||||
|
killProcesses := func(signal syscall.Signal) {
|
||||||
|
if signal == unix.SIGKILL {
|
||||||
|
if err := os.WriteFile(filepath.Join(path, "cgroup.kill"), []byte("1"), 0o600); err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// kill all the processes that are still part of the cgroup
|
||||||
|
if procs, err := os.ReadFile(filepath.Join(path, "cgroup.procs")); err == nil {
|
||||||
|
for _, pidS := range strings.Split(string(procs), "\n") {
|
||||||
|
if pid, err := strconv.Atoi(pidS); err == nil {
|
||||||
|
_ = unix.Kill(pid, signal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.Remove(path); err == nil || errors.Is(err, os.ErrNotExist) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
entries, err := os.ReadDir(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, i := range entries {
|
||||||
|
if i.IsDir() {
|
||||||
|
if err := rmDirRecursively(filepath.Join(path, i.Name())); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attempts := 0
|
||||||
|
for {
|
||||||
|
err := os.Remove(path)
|
||||||
|
if err == nil || errors.Is(err, os.ErrNotExist) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if errors.Is(err, unix.EBUSY) {
|
||||||
|
// send a SIGTERM after 3 second
|
||||||
|
if attempts == 300 {
|
||||||
|
killProcesses(unix.SIGTERM)
|
||||||
|
}
|
||||||
|
// send SIGKILL after 8 seconds
|
||||||
|
if attempts == 800 {
|
||||||
|
killProcesses(unix.SIGKILL)
|
||||||
|
}
|
||||||
|
// give up after 10 seconds
|
||||||
|
if attempts < 1000 {
|
||||||
|
time.Sleep(time.Millisecond * 10)
|
||||||
|
attempts++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Errorf("remove %s: %w", path, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
162
vendor/github.com/containers/common/pkg/cgroups/cgroups_supported.go
generated
vendored
162
vendor/github.com/containers/common/pkg/cgroups/cgroups_supported.go
generated
vendored
@ -1,162 +0,0 @@
|
|||||||
//go:build linux
|
|
||||||
|
|
||||||
package cgroups
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
systemdDbus "github.com/coreos/go-systemd/v22/dbus"
|
|
||||||
"github.com/godbus/dbus/v5"
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
isUnifiedOnce sync.Once
|
|
||||||
isUnified bool
|
|
||||||
isUnifiedErr error
|
|
||||||
)
|
|
||||||
|
|
||||||
// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode.
|
|
||||||
func IsCgroup2UnifiedMode() (bool, error) {
|
|
||||||
isUnifiedOnce.Do(func() {
|
|
||||||
var st syscall.Statfs_t
|
|
||||||
if err := syscall.Statfs("/sys/fs/cgroup", &st); err != nil {
|
|
||||||
isUnified, isUnifiedErr = false, err
|
|
||||||
} else {
|
|
||||||
isUnified, isUnifiedErr = st.Type == unix.CGROUP2_SUPER_MAGIC, nil
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return isUnified, isUnifiedErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserConnection returns an user connection to D-BUS
|
|
||||||
func UserConnection(uid int) (*systemdDbus.Conn, error) {
|
|
||||||
return systemdDbus.NewConnection(func() (*dbus.Conn, error) {
|
|
||||||
return dbusAuthConnection(uid, dbus.SessionBusPrivateNoAutoStartup)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserOwnsCurrentSystemdCgroup checks whether the current EUID owns the
|
|
||||||
// current cgroup.
|
|
||||||
func UserOwnsCurrentSystemdCgroup() (bool, error) {
|
|
||||||
uid := os.Geteuid()
|
|
||||||
|
|
||||||
cgroup2, err := IsCgroup2UnifiedMode()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := os.Open("/proc/self/cgroup")
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(f)
|
|
||||||
for scanner.Scan() {
|
|
||||||
line := scanner.Text()
|
|
||||||
parts := strings.SplitN(line, ":", 3)
|
|
||||||
|
|
||||||
if len(parts) < 3 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var cgroupPath string
|
|
||||||
|
|
||||||
if cgroup2 {
|
|
||||||
cgroupPath = filepath.Join(cgroupRoot, parts[2])
|
|
||||||
} else {
|
|
||||||
if parts[1] != "name=systemd" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
cgroupPath = filepath.Join(cgroupRoot, "systemd", parts[2])
|
|
||||||
}
|
|
||||||
|
|
||||||
st, err := os.Stat(cgroupPath)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
s := st.Sys()
|
|
||||||
if s == nil {
|
|
||||||
return false, fmt.Errorf("stat cgroup path %s", cgroupPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
if int(s.(*syscall.Stat_t).Uid) != uid {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := scanner.Err(); err != nil {
|
|
||||||
return false, fmt.Errorf("parsing file /proc/self/cgroup: %w", err)
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// rmDirRecursively delete recursively a cgroup directory.
|
|
||||||
// It differs from os.RemoveAll as it doesn't attempt to unlink files.
|
|
||||||
// On cgroupfs we are allowed only to rmdir empty directories.
|
|
||||||
func rmDirRecursively(path string) error {
|
|
||||||
killProcesses := func(signal syscall.Signal) {
|
|
||||||
if signal == unix.SIGKILL {
|
|
||||||
if err := os.WriteFile(filepath.Join(path, "cgroup.kill"), []byte("1"), 0o600); err == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// kill all the processes that are still part of the cgroup
|
|
||||||
if procs, err := os.ReadFile(filepath.Join(path, "cgroup.procs")); err == nil {
|
|
||||||
for _, pidS := range strings.Split(string(procs), "\n") {
|
|
||||||
if pid, err := strconv.Atoi(pidS); err == nil {
|
|
||||||
_ = unix.Kill(pid, signal)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.Remove(path); err == nil || errors.Is(err, os.ErrNotExist) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
entries, err := os.ReadDir(path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, i := range entries {
|
|
||||||
if i.IsDir() {
|
|
||||||
if err := rmDirRecursively(filepath.Join(path, i.Name())); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
attempts := 0
|
|
||||||
for {
|
|
||||||
err := os.Remove(path)
|
|
||||||
if err == nil || errors.Is(err, os.ErrNotExist) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if errors.Is(err, unix.EBUSY) {
|
|
||||||
// send a SIGTERM after 3 second
|
|
||||||
if attempts == 300 {
|
|
||||||
killProcesses(unix.SIGTERM)
|
|
||||||
}
|
|
||||||
// send SIGKILL after 8 seconds
|
|
||||||
if attempts == 800 {
|
|
||||||
killProcesses(unix.SIGKILL)
|
|
||||||
}
|
|
||||||
// give up after 10 seconds
|
|
||||||
if attempts < 1000 {
|
|
||||||
time.Sleep(time.Millisecond * 10)
|
|
||||||
attempts++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Errorf("remove %s: %w", path, err)
|
|
||||||
}
|
|
||||||
}
|
|
8
vendor/github.com/containers/common/pkg/cgroups/cgroups_unsupported.go
generated
vendored
8
vendor/github.com/containers/common/pkg/cgroups/cgroups_unsupported.go
generated
vendored
@ -3,10 +3,7 @@
|
|||||||
package cgroups
|
package cgroups
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
systemdDbus "github.com/coreos/go-systemd/v22/dbus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode.
|
// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode.
|
||||||
@ -23,8 +20,3 @@ func UserOwnsCurrentSystemdCgroup() (bool, error) {
|
|||||||
func rmDirRecursively(path string) error {
|
func rmDirRecursively(path string) error {
|
||||||
return os.RemoveAll(path)
|
return os.RemoveAll(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserConnection returns an user connection to D-BUS
|
|
||||||
func UserConnection(uid int) (*systemdDbus.Conn, error) {
|
|
||||||
return nil, fmt.Errorf("systemd d-bus is not supported on this platform")
|
|
||||||
}
|
|
||||||
|
80
vendor/github.com/containers/common/pkg/cgroups/systemd.go
generated
vendored
80
vendor/github.com/containers/common/pkg/cgroups/systemd.go
generated
vendored
@ -1,80 +0,0 @@
|
|||||||
//go:build !linux
|
|
||||||
|
|
||||||
package cgroups
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
systemdDbus "github.com/coreos/go-systemd/v22/dbus"
|
|
||||||
"github.com/godbus/dbus/v5"
|
|
||||||
)
|
|
||||||
|
|
||||||
func systemdCreate(path string, c *systemdDbus.Conn) error {
|
|
||||||
slice, name := filepath.Split(path)
|
|
||||||
slice = strings.TrimSuffix(slice, "/")
|
|
||||||
|
|
||||||
var lastError error
|
|
||||||
for i := 0; i < 2; i++ {
|
|
||||||
properties := []systemdDbus.Property{
|
|
||||||
systemdDbus.PropDescription(fmt.Sprintf("cgroup %s", name)),
|
|
||||||
systemdDbus.PropWants(slice),
|
|
||||||
}
|
|
||||||
pMap := map[string]bool{
|
|
||||||
"DefaultDependencies": false,
|
|
||||||
"MemoryAccounting": true,
|
|
||||||
"CPUAccounting": true,
|
|
||||||
"BlockIOAccounting": true,
|
|
||||||
}
|
|
||||||
if i == 0 {
|
|
||||||
pMap["Delegate"] = true
|
|
||||||
}
|
|
||||||
for k, v := range pMap {
|
|
||||||
p := systemdDbus.Property{
|
|
||||||
Name: k,
|
|
||||||
Value: dbus.MakeVariant(v),
|
|
||||||
}
|
|
||||||
properties = append(properties, p)
|
|
||||||
}
|
|
||||||
|
|
||||||
ch := make(chan string)
|
|
||||||
_, err := c.StartTransientUnitContext(context.TODO(), name, "replace", properties, ch)
|
|
||||||
if err != nil {
|
|
||||||
lastError = err
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
<-ch
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return lastError
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
systemdDestroyConn is copied from containerd/cgroups/systemd.go file, that
|
|
||||||
has the following license:
|
|
||||||
Copyright The containerd Authors.
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
func systemdDestroyConn(path string, c *systemdDbus.Conn) error {
|
|
||||||
name := filepath.Base(path)
|
|
||||||
|
|
||||||
ch := make(chan string)
|
|
||||||
_, err := c.StopUnitContext(context.TODO(), name, "replace", ch)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
<-ch
|
|
||||||
return nil
|
|
||||||
}
|
|
54
vendor/github.com/containers/common/pkg/config/connections.go
generated
vendored
54
vendor/github.com/containers/common/pkg/config/connections.go
generated
vendored
@ -9,6 +9,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/containers/storage/pkg/ioutils"
|
"github.com/containers/storage/pkg/ioutils"
|
||||||
|
"github.com/containers/storage/pkg/lockfile"
|
||||||
)
|
)
|
||||||
|
|
||||||
const connectionsFile = "podman-connections.json"
|
const connectionsFile = "podman-connections.json"
|
||||||
@ -64,28 +65,24 @@ type Farm struct {
|
|||||||
ReadWrite bool
|
ReadWrite bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func readConnectionConf() (*ConnectionsFile, string, error) {
|
func readConnectionConf(path string) (*ConnectionsFile, error) {
|
||||||
path, err := connectionsConfigFile()
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", err
|
|
||||||
}
|
|
||||||
conf := new(ConnectionsFile)
|
conf := new(ConnectionsFile)
|
||||||
f, err := os.Open(path)
|
f, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// return empty config if file does not exists
|
// return empty config if file does not exists
|
||||||
if errors.Is(err, fs.ErrNotExist) {
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
return conf, path, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
err = json.NewDecoder(f).Decode(conf)
|
err = json.NewDecoder(f).Decode(conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", fmt.Errorf("parse %q: %w", path, err)
|
return nil, fmt.Errorf("parse %q: %w", path, err)
|
||||||
}
|
}
|
||||||
return conf, path, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeConnectionConf(path string, conf *ConnectionsFile) error {
|
func writeConnectionConf(path string, conf *ConnectionsFile) error {
|
||||||
@ -113,7 +110,20 @@ func writeConnectionConf(path string, conf *ConnectionsFile) error {
|
|||||||
// The function will read and write the file automatically and the
|
// The function will read and write the file automatically and the
|
||||||
// callback function just needs to modify the cfg as needed.
|
// callback function just needs to modify the cfg as needed.
|
||||||
func EditConnectionConfig(callback func(cfg *ConnectionsFile) error) error {
|
func EditConnectionConfig(callback func(cfg *ConnectionsFile) error) error {
|
||||||
conf, path, err := readConnectionConf()
|
path, err := connectionsConfigFile()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
lockPath := path + ".lock"
|
||||||
|
lock, err := lockfile.GetLockFile(lockPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("obtain lock file: %w", err)
|
||||||
|
}
|
||||||
|
lock.Lock()
|
||||||
|
defer lock.Unlock()
|
||||||
|
|
||||||
|
conf, err := readConnectionConf(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("read connections file: %w", err)
|
return fmt.Errorf("read connections file: %w", err)
|
||||||
}
|
}
|
||||||
@ -139,7 +149,11 @@ func makeConnection(name string, dst Destination, def, readWrite bool) *Connecti
|
|||||||
|
|
||||||
// GetConnection return the connection for the given name or if def is set to true then return the default connection.
|
// 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) {
|
func (c *Config) GetConnection(name string, def bool) (*Connection, error) {
|
||||||
conConf, _, err := readConnectionConf()
|
path, err := connectionsConfigFile()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
conConf, err := readConnectionConf(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -167,7 +181,11 @@ func (c *Config) GetConnection(name string, def bool) (*Connection, error) {
|
|||||||
|
|
||||||
// GetAllConnections return all configured connections
|
// GetAllConnections return all configured connections
|
||||||
func (c *Config) GetAllConnections() ([]Connection, error) {
|
func (c *Config) GetAllConnections() ([]Connection, error) {
|
||||||
conConf, _, err := readConnectionConf()
|
path, err := connectionsConfigFile()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
conConf, err := readConnectionConf(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -222,7 +240,11 @@ func (c *Config) GetDefaultFarmConnections() (string, []Connection, error) {
|
|||||||
// if def is true it will use the default farm instead of the name.
|
// 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.
|
// Returns the name of the farm and the connections for it.
|
||||||
func (c *Config) getFarmConnections(name string, def bool) (string, []Connection, error) {
|
func (c *Config) getFarmConnections(name string, def bool) (string, []Connection, error) {
|
||||||
conConf, _, err := readConnectionConf()
|
path, err := connectionsConfigFile()
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
conConf, err := readConnectionConf(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
@ -259,7 +281,11 @@ func makeFarm(name string, cons []string, def, readWrite bool) Farm {
|
|||||||
|
|
||||||
// GetAllFarms returns all configured farms
|
// GetAllFarms returns all configured farms
|
||||||
func (c *Config) GetAllFarms() ([]Farm, error) {
|
func (c *Config) GetAllFarms() ([]Farm, error) {
|
||||||
conConf, _, err := readConnectionConf()
|
path, err := connectionsConfigFile()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
conConf, err := readConnectionConf(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -171,7 +171,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.20240229165734-cec09922602e
|
# github.com/containers/common v0.57.1-0.20240304165751-a0d555c70d52
|
||||||
## explicit; go 1.20
|
## explicit; go 1.20
|
||||||
github.com/containers/common/internal
|
github.com/containers/common/internal
|
||||||
github.com/containers/common/internal/attributedstring
|
github.com/containers/common/internal/attributedstring
|
||||||
|
Reference in New Issue
Block a user