From 1d1be2b959a268210cf25c6aadf83daebaea2632 Mon Sep 17 00:00:00 2001 From: tomsweeneyredhat Date: Mon, 15 Apr 2024 16:27:47 -0400 Subject: [PATCH] [v5.0] Bump c/common to v0.58.2 Bumping c/common to v0.58.2 in preparation for Podman v5.0.2 [NO NEW TESTS NEEDED] Signed-off-by: tomsweeneyredhat --- go.mod | 2 +- go.sum | 4 +- .../internal/rootlessnetns/netns_linux.go | 103 ++++++++++++------ .../common/libnetwork/netavark/config.go | 5 + .../common/libnetwork/netavark/ipam.go | 21 ++++ .../common/libnetwork/netavark/network.go | 8 +- .../containers/common/version/version.go | 2 +- vendor/modules.txt | 2 +- 8 files changed, 105 insertions(+), 42 deletions(-) diff --git a/go.mod b/go.mod index 313eb37655..e47c82ff0c 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/checkpoint-restore/go-criu/v7 v7.0.0 github.com/containernetworking/plugins v1.4.0 github.com/containers/buildah v1.35.3 - github.com/containers/common v0.58.1 + github.com/containers/common v0.58.2 github.com/containers/conmon v2.0.20+incompatible github.com/containers/gvisor-tap-vsock v0.7.3 github.com/containers/image/v5 v5.30.0 diff --git a/go.sum b/go.sum index 0074c74a56..e427aa2262 100644 --- a/go.sum +++ b/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/containers/buildah v1.35.3 h1:Dn8Krwm2PemBNNOMwp7uiMK2e5cW2ZjTdLRzKM789pc= github.com/containers/buildah v1.35.3/go.mod h1:kYi6vTHdbr1gnRo3B/RhTHsY2if/w398+/RvCxAXqkQ= -github.com/containers/common v0.58.1 h1:E1DN9Lr7kgMVQy7AXLv1CYQCiqnweklMiYWbf0KOnqY= -github.com/containers/common v0.58.1/go.mod h1:l3vMqanJGj7tZ3W/i76gEJ128VXgFUO1tLaohJXPvdk= +github.com/containers/common v0.58.2 h1:5nu9lQz4QNSgovNk7NRk33SkqkVNKYoXh7L6gXmACow= +github.com/containers/common v0.58.2/go.mod h1:l3vMqanJGj7tZ3W/i76gEJ128VXgFUO1tLaohJXPvdk= 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/gvisor-tap-vsock v0.7.3 h1:yORnf15sP+sLFhxLNLgmB5/lOhldn9dRMHx/tmYtSOQ= diff --git a/vendor/github.com/containers/common/libnetwork/internal/rootlessnetns/netns_linux.go b/vendor/github.com/containers/common/libnetwork/internal/rootlessnetns/netns_linux.go index 98961935da..44b4d43833 100644 --- a/vendor/github.com/containers/common/libnetwork/internal/rootlessnetns/netns_linux.go +++ b/vendor/github.com/containers/common/libnetwork/internal/rootlessnetns/netns_linux.go @@ -100,18 +100,37 @@ func (n *Netns) getOrCreateNetns() (ns.NetNS, bool, error) { nsPath := n.getPath(rootlessNetnsDir) nsRef, err := ns.GetNS(nsPath) if err == nil { - // TODO check if slirp4netns is alive - return nsRef, false, nil - } - logrus.Debugf("Creating rootless network namespace at %q", nsPath) - // We have to create the netns dir again here because it is possible - // that cleanup() removed it. - if err := os.MkdirAll(n.dir, 0o700); err != nil { - return nil, false, wrapError("", err) - } - netns, err := netns.NewNSAtPath(nsPath) - if err != nil { - return nil, false, wrapError("create netns", err) + pidPath := n.getPath(rootlessNetNsConnPidFile) + pid, err := readPidFile(pidPath) + if err == nil { + // quick check if pasta/slirp4netns are still running + err := unix.Kill(pid, 0) + if err == nil { + // All good, return the netns. + return nsRef, false, nil + } + // Print warnings in case things went wrong, we might be able to recover + // but maybe not so make sure to leave some hints so we can figure out what went wrong. + if errors.Is(err, unix.ESRCH) { + logrus.Warn("rootless netns program no longer running, trying to start it again") + } else { + logrus.Warnf("failed to check if rootless netns program is running: %v, trying to start it again", err) + } + } else { + logrus.Warnf("failed to read rootless netns program pid: %v", err) + } + // In case of errors continue and setup the network cmd again. + } else { + logrus.Debugf("Creating rootless network namespace at %q", nsPath) + // We have to create the netns dir again here because it is possible + // that cleanup() removed it. + if err := os.MkdirAll(n.dir, 0o700); err != nil { + return nil, false, wrapError("", err) + } + nsRef, err = netns.NewNSAtPath(nsPath) + if err != nil { + return nil, false, wrapError("create netns", err) + } } switch strings.ToLower(n.config.Network.DefaultRootlessNetworkCmd) { case "", slirp4netns.BinaryName: @@ -121,7 +140,17 @@ func (n *Netns) getOrCreateNetns() (ns.NetNS, bool, error) { default: err = fmt.Errorf("invalid rootless network command %q", n.config.Network.DefaultRootlessNetworkCmd) } - return netns, true, err + // If pasta or slirp4netns fail here we need to get rid of the netns again to not leak it, + // otherwise the next command thinks the netns was successfully setup. + if err != nil { + if nerr := netns.UnmountNS(nsPath); nerr != nil { + logrus.Error(nerr) + } + _ = nsRef.Close() + return nil, false, err + } + + return nsRef, true, nil } func (n *Netns) cleanup() error { @@ -165,11 +194,7 @@ func (n *Netns) setupPasta(nsPath string) error { if systemd.RunsOnSystemd() { // Treat these as fatal - if pasta failed to write a PID file something is probably wrong. - pidfile, err := os.ReadFile(pidPath) - if err != nil { - return fmt.Errorf("unable to open pasta PID file: %w", err) - } - pid, err := strconv.Atoi(strings.TrimSpace(string(pidfile))) + pid, err := readPidFile(pidPath) if err != nil { return fmt.Errorf("unable to decode pasta PID: %w", err) } @@ -245,16 +270,12 @@ func (n *Netns) setupSlirp4netns(nsPath string) error { func (n *Netns) cleanupRootlessNetns() error { pidFile := n.getPath(rootlessNetNsConnPidFile) - b, err := os.ReadFile(pidFile) + pid, err := readPidFile(pidFile) if err == nil { - var i int - i, err = strconv.Atoi(strings.TrimSpace(string(b))) - if err == nil { - // kill the slirp process so we do not leak it - err = unix.Kill(i, unix.SIGTERM) - if err == unix.ESRCH { - err = nil - } + // kill the slirp/pasta process so we do not leak it + err = unix.Kill(pid, unix.SIGTERM) + if err == unix.ESRCH { + err = nil } } return err @@ -294,6 +315,13 @@ func (n *Netns) setupMounts() error { return wrapError("create new mount namespace", err) } + // Ensure we mount private in our mountns to prevent accidentally + // overwriting the host mounts in case the default propagation is shared. + err = unix.Mount("", "/", "", unix.MS_PRIVATE|unix.MS_REC, "") + if err != nil { + return wrapError("make tree private in new mount namespace", err) + } + xdgRuntimeDir, err := homedir.GetRuntimeDir() if err != nil { return fmt.Errorf("could not get runtime directory: %w", err) @@ -301,7 +329,7 @@ func (n *Netns) setupMounts() error { newXDGRuntimeDir := n.getPath(xdgRuntimeDir) // 1. Mount the netns into the new run to keep them accessible. // Otherwise cni setup will fail because it cannot access the netns files. - err = mountAndMkdirDest(xdgRuntimeDir, newXDGRuntimeDir, none, unix.MS_BIND|unix.MS_SHARED|unix.MS_REC) + err = mountAndMkdirDest(xdgRuntimeDir, newXDGRuntimeDir, none, unix.MS_BIND|unix.MS_REC) if err != nil { return err } @@ -556,15 +584,12 @@ func (n *Netns) Run(lock *lockfile.LockFile, toRun func() error) error { logrus.Errorf("Failed to decrement ref count: %v", err) return inErr } - if count == 0 { + // runInner() already cleans up the netns when it created a new one on errors + // so we only need to do that if there was no error. + if inErr == nil && count == 0 { err = n.cleanup() if err != nil { - err = wrapError("cleanup", err) - if inErr == nil { - return err - } - logrus.Errorf("Failed to cleanup rootless netns: %v", err) - return inErr + return wrapError("cleanup", err) } } @@ -599,3 +624,11 @@ func refCount(dir string, inc int) (int, error) { return currentCount, nil } + +func readPidFile(path string) (int, error) { + b, err := os.ReadFile(path) + if err != nil { + return 0, err + } + return strconv.Atoi(strings.TrimSpace(string(b))) +} diff --git a/vendor/github.com/containers/common/libnetwork/netavark/config.go b/vendor/github.com/containers/common/libnetwork/netavark/config.go index bcd1eaea36..3a77d3ab2f 100644 --- a/vendor/github.com/containers/common/libnetwork/netavark/config.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/config.go @@ -376,6 +376,11 @@ func (n *netavarkNetwork) NetworkRemove(nameOrID string) error { return fmt.Errorf("default network %s cannot be removed", n.defaultNetwork) } + // remove the ipam bucket for this network + if err := n.removeNetworkIPAMBucket(network); err != nil { + return err + } + file := filepath.Join(n.networkConfigDir, network.Name+".json") // make sure to not error for ErrNotExist if err := os.Remove(file); err != nil && !errors.Is(err, os.ErrNotExist) { diff --git a/vendor/github.com/containers/common/libnetwork/netavark/ipam.go b/vendor/github.com/containers/common/libnetwork/netavark/ipam.go index b9a48d456a..d348ada0b2 100644 --- a/vendor/github.com/containers/common/libnetwork/netavark/ipam.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/ipam.go @@ -4,6 +4,7 @@ package netavark import ( "encoding/json" + "errors" "fmt" "net" @@ -357,6 +358,26 @@ func (n *netavarkNetwork) deallocIPs(opts *types.NetworkOptions) error { return err } +func (n *netavarkNetwork) removeNetworkIPAMBucket(network *types.Network) error { + if !requiresIPAMAlloc(network) { + return nil + } + db, err := n.openDB() + if err != nil { + return err + } + defer db.Close() + + return db.Update(func(tx *bbolt.Tx) error { + // Ignore ErrBucketNotFound, can happen if the network never allocated any ips, + // i.e. because no container was started. + if err := tx.DeleteBucket([]byte(network.Name)); err != nil && !errors.Is(err, bbolt.ErrBucketNotFound) { + return err + } + return nil + }) +} + // requiresIPAMAlloc return true when we have to allocate ips for this network // it checks the ipam driver and if subnets are set func requiresIPAMAlloc(network *types.Network) bool { diff --git a/vendor/github.com/containers/common/libnetwork/netavark/network.go b/vendor/github.com/containers/common/libnetwork/netavark/network.go index 9f4ee3135c..d79fdff43a 100644 --- a/vendor/github.com/containers/common/libnetwork/netavark/network.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/network.go @@ -135,7 +135,11 @@ func NewNetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) { } var netns *rootlessnetns.Netns - if unshare.IsRootless() { + // Do not use unshare.IsRootless() here. We only care if we are running re-exec in the userns, + // IsRootless() also returns true if we are root in a userns which is not what we care about and + // causes issues as this slower more complicated rootless-netns logic should not be used as root. + _, useRootlessNetns := os.LookupEnv(unshare.UsernsEnvName) + if useRootlessNetns { netns, err = rootlessnetns.New(conf.NetworkRunDir, rootlessnetns.Netavark, conf.Config) if err != nil { return nil, err @@ -147,7 +151,7 @@ func NewNetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) { networkRunDir: conf.NetworkRunDir, netavarkBinary: conf.NetavarkBinary, aardvarkBinary: conf.AardvarkBinary, - networkRootless: unshare.IsRootless(), + networkRootless: useRootlessNetns, ipamDBPath: filepath.Join(conf.NetworkRunDir, "ipam.db"), firewallDriver: conf.Config.Network.FirewallDriver, defaultNetwork: defaultNetworkName, diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go index 87d93c9d69..88a6160788 100644 --- a/vendor/github.com/containers/common/version/version.go +++ b/vendor/github.com/containers/common/version/version.go @@ -1,4 +1,4 @@ package version // Version is the version of the build. -const Version = "0.58.1" +const Version = "0.58.2" diff --git a/vendor/modules.txt b/vendor/modules.txt index 6f8266db34..4916a9a80d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -171,7 +171,7 @@ github.com/containers/buildah/pkg/sshagent github.com/containers/buildah/pkg/util github.com/containers/buildah/pkg/volumes github.com/containers/buildah/util -# github.com/containers/common v0.58.1 +# github.com/containers/common v0.58.2 ## explicit; go 1.20 github.com/containers/common/internal github.com/containers/common/internal/attributedstring