From c1f8dab2b30a50403c67baf938ac17504d4d8805 Mon Sep 17 00:00:00 2001 From: Lokesh Mandvekar Date: Fri, 24 Apr 2026 12:00:00 -0400 Subject: [PATCH 1/4] vendor update Signed-off-by: Lokesh Mandvekar --- go.mod | 6 + go.sum | 12 +- .../libcontainer/devices/device_deprecated.go | 20 - .../runc/libcontainer/devices/device_unix.go | 112 --- .../internal/rootlessnetns/netns_linux.go | 82 +- .../common/libnetwork/slirp4netns/const.go | 17 - .../libnetwork/slirp4netns/const_linux.go | 11 - .../libnetwork/slirp4netns/slirp4netns.go | 740 ------------------ .../go.podman.io/common/pkg/config/config.go | 6 +- .../common/pkg/config/containers.conf | 26 +- .../common/pkg/config/containers.conf-freebsd | 22 - .../common/pkg/parse/parse_unix.go | 2 +- .../pkg/rootlessport/rootlessport_linux.go | 26 - .../common/pkg/servicereaper/service.go | 64 -- .../common/pkg/systemd/systemd_linux.go | 4 +- .../storage/drivers/btrfs/btrfs.go | 82 +- .../storage/drivers/overlay/overlay.go | 80 +- vendor/modules.txt | 13 +- 18 files changed, 108 insertions(+), 1217 deletions(-) delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/devices/device_deprecated.go delete mode 100644 vendor/github.com/opencontainers/runc/libcontainer/devices/device_unix.go delete mode 100644 vendor/go.podman.io/common/libnetwork/slirp4netns/const.go delete mode 100644 vendor/go.podman.io/common/libnetwork/slirp4netns/const_linux.go delete mode 100644 vendor/go.podman.io/common/libnetwork/slirp4netns/slirp4netns.go delete mode 100644 vendor/go.podman.io/common/pkg/rootlessport/rootlessport_linux.go delete mode 100644 vendor/go.podman.io/common/pkg/servicereaper/service.go diff --git a/go.mod b/go.mod index 130d2dc3eda..69b1a332e5c 100644 --- a/go.mod +++ b/go.mod @@ -135,3 +135,9 @@ require ( sigs.k8s.io/yaml v1.6.0 // indirect tags.cncf.io/container-device-interface/specs-go v1.1.0 // indirect ) + +replace go.podman.io/common => github.com/lsm5/container-libs/common v0.0.0-20260424152608-5b5912370b8d + +replace go.podman.io/image/v5 => github.com/lsm5/container-libs/image/v5 v5.0.0-20260424152608-5b5912370b8d + +replace go.podman.io/storage => github.com/lsm5/container-libs/storage v0.0.0-20260424152608-5b5912370b8d diff --git a/go.sum b/go.sum index 81cc12a19aa..da99a3ec5c3 100644 --- a/go.sum +++ b/go.sum @@ -139,6 +139,12 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lsm5/container-libs/common v0.0.0-20260424152608-5b5912370b8d h1:C7jjVSpfNLtFa9jmng88svBxw2q1qn42rgyExpPb6Jo= +github.com/lsm5/container-libs/common v0.0.0-20260424152608-5b5912370b8d/go.mod h1:iSyDl7NIIpWhCtvEIPpHWosWL/XygqeffWZU0WX0Io8= +github.com/lsm5/container-libs/image/v5 v5.0.0-20260424152608-5b5912370b8d h1:jId7IBF0v9clQv7lGi9ygkHzWSIx50bjI5Fr7MKCnSU= +github.com/lsm5/container-libs/image/v5 v5.0.0-20260424152608-5b5912370b8d/go.mod h1:sAszAH18v4KPpzPZdav9ovjEBcIDkmqdhbJV9SmnzfE= +github.com/lsm5/container-libs/storage v0.0.0-20260424152608-5b5912370b8d h1:nAprhfHIolVfNboGaaFsRdYxk0vf+yWIJ6er6d9jFnc= +github.com/lsm5/container-libs/storage v0.0.0-20260424152608-5b5912370b8d/go.mod h1:13aOBf6782/fbAzH7QNEqlVzFu+X4sS4MxDM/VdJGZU= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw= @@ -285,12 +291,6 @@ go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfC go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= -go.podman.io/common v0.67.2-0.20260423135811-cbaa5f41e643 h1:WwUcVKPEUoSDiQ22osdYGqM3q9IDB4viqSASPCdw1K0= -go.podman.io/common v0.67.2-0.20260423135811-cbaa5f41e643/go.mod h1:kBztCGxEhou0OO0O4yJXAKC3JEQTmOxCJPni90+sQKY= -go.podman.io/image/v5 v5.39.3-0.20260423135811-cbaa5f41e643 h1:1LuhuiiXHHteVXULDV/x9qxJtFozQPLEYKHCbYdOuP0= -go.podman.io/image/v5 v5.39.3-0.20260423135811-cbaa5f41e643/go.mod h1:sAszAH18v4KPpzPZdav9ovjEBcIDkmqdhbJV9SmnzfE= -go.podman.io/storage v1.62.1-0.20260423135811-cbaa5f41e643 h1:/zmZ36KkCZumHK0EDH5QpSjyM3fY09YuyIfqoXxEI48= -go.podman.io/storage v1.62.1-0.20260423135811-cbaa5f41e643/go.mod h1:13aOBf6782/fbAzH7QNEqlVzFu+X4sS4MxDM/VdJGZU= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= diff --git a/vendor/github.com/opencontainers/runc/libcontainer/devices/device_deprecated.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/device_deprecated.go deleted file mode 100644 index 9483f054dcd..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/devices/device_deprecated.go +++ /dev/null @@ -1,20 +0,0 @@ -package devices - -import "github.com/opencontainers/cgroups/devices/config" - -// Deprecated: use [github.com/opencontainers/cgroups/devices/config]. -const ( - Wildcard = config.Wildcard - WildcardDevice = config.WildcardDevice - BlockDevice = config.BlockDevice - CharDevice = config.CharDevice - FifoDevice = config.FifoDevice -) - -// Deprecated: use [github.com/opencontainers/cgroups/devices/config]. -type ( - Device = config.Device - Permissions = config.Permissions - Type = config.Type - Rule = config.Rule -) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/devices/device_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/device_unix.go deleted file mode 100644 index 409e58e963d..00000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/devices/device_unix.go +++ /dev/null @@ -1,112 +0,0 @@ -//go:build !windows - -package devices - -import ( - "errors" - "os" - "path/filepath" - - "golang.org/x/sys/unix" -) - -// ErrNotADevice denotes that a file is not a valid linux device. -var ErrNotADevice = errors.New("not a device node") - -// Testing dependencies -var ( - unixLstat = unix.Lstat - osReadDir = os.ReadDir -) - -// DeviceFromPath takes the path to a device and its cgroup_permissions (which -// cannot be easily queried) to look up the information about a linux device -// and returns that information as a Device struct. -func DeviceFromPath(path, permissions string) (*Device, error) { - var stat unix.Stat_t - err := unixLstat(path, &stat) - if err != nil { - return nil, err - } - - var ( - devType Type - mode = stat.Mode - devNumber = uint64(stat.Rdev) //nolint:unconvert // Rdev is uint32 on e.g. MIPS. - major = unix.Major(devNumber) - minor = unix.Minor(devNumber) - ) - switch mode & unix.S_IFMT { - case unix.S_IFBLK: - devType = BlockDevice - case unix.S_IFCHR: - devType = CharDevice - case unix.S_IFIFO: - devType = FifoDevice - default: - return nil, ErrNotADevice - } - return &Device{ - Rule: Rule{ - Type: devType, - Major: int64(major), - Minor: int64(minor), - Permissions: Permissions(permissions), - }, - Path: path, - FileMode: os.FileMode(mode &^ unix.S_IFMT), - Uid: stat.Uid, - Gid: stat.Gid, - }, nil -} - -// HostDevices returns all devices that can be found under /dev directory. -func HostDevices() ([]*Device, error) { - return GetDevices("/dev") -} - -// GetDevices recursively traverses a directory specified by path -// and returns all devices found there. -func GetDevices(path string) ([]*Device, error) { - files, err := osReadDir(path) - if err != nil { - return nil, err - } - var out []*Device - for _, f := range files { - switch { - case f.IsDir(): - switch f.Name() { - // ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825 - // ".udev" added to address https://github.com/opencontainers/runc/issues/2093 - case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts", ".udev": - continue - default: - sub, err := GetDevices(filepath.Join(path, f.Name())) - if err != nil { - return nil, err - } - - out = append(out, sub...) - continue - } - case f.Name() == "console": - continue - } - device, err := DeviceFromPath(filepath.Join(path, f.Name()), "rwm") - if err != nil { - if errors.Is(err, ErrNotADevice) { - continue - } - if errors.Is(err, os.ErrNotExist) { - continue - } - return nil, err - } - if device.Type == FifoDevice { - continue - } - out = append(out, device) - } - return out, nil -} diff --git a/vendor/go.podman.io/common/libnetwork/internal/rootlessnetns/netns_linux.go b/vendor/go.podman.io/common/libnetwork/internal/rootlessnetns/netns_linux.go index 687b421029a..a94da488979 100644 --- a/vendor/go.podman.io/common/libnetwork/internal/rootlessnetns/netns_linux.go +++ b/vendor/go.podman.io/common/libnetwork/internal/rootlessnetns/netns_linux.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io/fs" - "net" "os" "path/filepath" "strconv" @@ -17,7 +16,6 @@ import ( "github.com/sirupsen/logrus" "go.podman.io/common/libnetwork/pasta" "go.podman.io/common/libnetwork/resolvconf" - "go.podman.io/common/libnetwork/slirp4netns" "go.podman.io/common/libnetwork/types" "go.podman.io/common/pkg/config" "go.podman.io/common/pkg/netns" @@ -37,7 +35,7 @@ const ( // infoCacheFile file name for the cache file used to store the rootless netns info. infoCacheFile = "info.json" - // rootlessNetNsConnPidFile is the name of the rootless netns slirp4netns/pasta pid file. + // rootlessNetNsConnPidFile is the name of the rootless netns pasta pid file. rootlessNetNsConnPidFile = "rootless-netns-conn.pid" tmpfs = "tmpfs" @@ -107,7 +105,7 @@ func (n *Netns) getOrCreateNetns() (netns.NetNS, bool, error) { pidPath := n.getPath(rootlessNetNsConnPidFile) pid, err := readPidFile(pidPath) if err == nil { - // quick check if pasta/slirp4netns are still running + // quick check if pasta is still running err := unix.Kill(pid, 0) if err == nil { if err := n.deserializeInfo(); err != nil { @@ -149,14 +147,14 @@ func (n *Netns) getOrCreateNetns() (netns.NetNS, bool, error) { } } switch strings.ToLower(n.config.Network.DefaultRootlessNetworkCmd) { - case "", slirp4netns.BinaryName: - err = n.setupSlirp4netns(nsPath) - case pasta.BinaryName: + case "", pasta.BinaryName: err = n.setupPasta(nsPath) + case "slirp4netns": + err = errors.New("slirp4netns is no longer supported as of Podman 6. Please update containers.conf to use 'pasta' (default) or remove the default_rootless_network_cmd setting") default: - err = fmt.Errorf("invalid rootless network command %q", n.config.Network.DefaultRootlessNetworkCmd) + err = fmt.Errorf("invalid rootless network command %q (supported: pasta)", n.config.Network.DefaultRootlessNetworkCmd) } - // If pasta or slirp4netns fail here we need to get rid of the netns again to not leak it, + // If pasta fails 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 { @@ -215,7 +213,7 @@ func (n *Netns) setupPasta(nsPath string) error { return fmt.Errorf("unable to decode pasta PID: %w", err) } - if err := systemd.MoveRootlessNetnsSlirpProcessToUserSlice(pid); err != nil { + if err := systemd.MoveRootlessNetnsProcessToUserSlice(pid); err != nil { // only log this, it is not fatal but can lead to issues when running podman inside systemd units logrus.Errorf("failed to move the rootless netns pasta process to the systemd user.slice: %v", err) } @@ -246,68 +244,6 @@ func (n *Netns) setupPasta(nsPath string) error { return nil } -func (n *Netns) setupSlirp4netns(nsPath string) error { - res, err := slirp4netns.Setup(&slirp4netns.SetupOptions{ - Config: n.config, - ContainerID: "rootless-netns", - Netns: nsPath, - }) - if err != nil { - return wrapError("start slirp4netns", err) - } - // create pid file for the slirp4netns process - // this is need to kill the process in the cleanup - pid := strconv.Itoa(res.Pid) - err = os.WriteFile(n.getPath(rootlessNetNsConnPidFile), []byte(pid), 0o600) - if err != nil { - return wrapError("write slirp4netns pid file", err) - } - - if systemd.RunsOnSystemd() { - // move to systemd scope to prevent systemd from killing it - err = systemd.MoveRootlessNetnsSlirpProcessToUserSlice(res.Pid) - if err != nil { - // only log this, it is not fatal but can lead to issues when running podman inside systemd units - logrus.Errorf("failed to move the rootless netns slirp4netns process to the systemd user.slice: %v", err) - } - } - - // build a new resolv.conf file which uses the slirp4netns dns server address - resolveIP, err := slirp4netns.GetDNS(res.Subnet) - if err != nil { - return wrapError("determine default slirp4netns DNS address", err) - } - nameservers := []string{resolveIP.String()} - - netnsIP, err := slirp4netns.GetIP(res.Subnet) - if err != nil { - return wrapError("determine default slirp4netns ip address", err) - } - - if err := resolvconf.New(&resolvconf.Params{ - Path: n.getPath(resolvConfName), - // fake the netns since we want to filter localhost - Namespaces: []specs.LinuxNamespace{ - {Type: specs.NetworkNamespace}, - }, - IPv6Enabled: res.IPv6, - KeepHostServers: true, - Nameservers: nameservers, - }); err != nil { - return wrapError("create resolv.conf", err) - } - - n.info = &types.RootlessNetnsInfo{ - IPAddresses: []net.IP{*netnsIP}, - DnsForwardIps: nameservers, - } - if err := n.serializeInfo(); err != nil { - return wrapError("serialize info", err) - } - - return nil -} - func (n *Netns) cleanupRootlessNetns() error { pidFile := n.getPath(rootlessNetNsConnPidFile) pid, err := readPidFile(pidFile) @@ -317,7 +253,7 @@ func (n *Netns) cleanupRootlessNetns() error { return nil } if err == nil { - // kill the slirp/pasta process so we do not leak it + // kill the pasta process so we do not leak it err = unix.Kill(pid, unix.SIGTERM) if err == unix.ESRCH { err = nil diff --git a/vendor/go.podman.io/common/libnetwork/slirp4netns/const.go b/vendor/go.podman.io/common/libnetwork/slirp4netns/const.go deleted file mode 100644 index 82f3bff3a0b..00000000000 --- a/vendor/go.podman.io/common/libnetwork/slirp4netns/const.go +++ /dev/null @@ -1,17 +0,0 @@ -package slirp4netns - -import "net" - -const ( - BinaryName = "slirp4netns" -) - -// SetupResult return type from Setup(). -type SetupResult struct { - // Pid of the created slirp4netns process - Pid int - // Subnet which is used by slirp4netns - Subnet *net.IPNet - // IPv6 whenever Ipv6 is enabled in slirp4netns - IPv6 bool -} diff --git a/vendor/go.podman.io/common/libnetwork/slirp4netns/const_linux.go b/vendor/go.podman.io/common/libnetwork/slirp4netns/const_linux.go deleted file mode 100644 index 8e2742fe3fe..00000000000 --- a/vendor/go.podman.io/common/libnetwork/slirp4netns/const_linux.go +++ /dev/null @@ -1,11 +0,0 @@ -package slirp4netns - -const ( - ipv6ConfDefaultAcceptDadSysctl = "/proc/sys/net/ipv6/conf/default/accept_dad" - - // defaultMTU the default MTU override. - defaultMTU = 65520 - - // default slirp4ns subnet. - defaultSubnet = "10.0.2.0/24" -) diff --git a/vendor/go.podman.io/common/libnetwork/slirp4netns/slirp4netns.go b/vendor/go.podman.io/common/libnetwork/slirp4netns/slirp4netns.go deleted file mode 100644 index 74126c608ca..00000000000 --- a/vendor/go.podman.io/common/libnetwork/slirp4netns/slirp4netns.go +++ /dev/null @@ -1,740 +0,0 @@ -//go:build linux - -package slirp4netns - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "io" - "net" - "os" - "os/exec" - "path/filepath" - "strconv" - "strings" - "sync" - "syscall" - "time" - - "github.com/sirupsen/logrus" - "go.podman.io/common/libnetwork/types" - "go.podman.io/common/pkg/config" - "go.podman.io/common/pkg/netns" - "go.podman.io/common/pkg/rootlessport" - "go.podman.io/common/pkg/servicereaper" - "go.podman.io/common/pkg/util" -) - -type slirpFeatures struct { - HasDisableHostLoopback bool - HasMTU bool - HasEnableSandbox bool - HasEnableSeccomp bool - HasCIDR bool - HasOutboundAddr bool - HasIPv6 bool -} - -type slirp4netnsCmdArg struct { - Proto string `json:"proto,omitempty"` - HostAddr string `json:"host_addr"` - HostPort uint16 `json:"host_port"` - GuestAddr string `json:"guest_addr"` - GuestPort uint16 `json:"guest_port"` -} - -type slirp4netnsCmd struct { - Execute string `json:"execute"` - Args slirp4netnsCmdArg `json:"arguments"` -} - -type networkOptions struct { - cidr string - disableHostLoopback bool - enableIPv6 bool - isSlirpHostForward bool - noPivotRoot bool - mtu int - outboundAddr string - outboundAddr6 string -} - -type SetupOptions struct { - // Config used to get slip4netns path and other default options - Config *config.Config - // ContainerID is the ID of the container - ContainerID string - // Netns path to the netns - Netns string - // Ports the should be forwarded - Ports []types.PortMapping - // ExtraOptions for slirp4netns that were set on the cli - ExtraOptions []string - // Slirp4netnsExitPipeR pipe used to exit the slirp4netns process. - // This is must be the reading end, the writer must be kept open until you want the - // process to exit. For podman, conmon will hold the pipe open. - // It can be set to nil in which case we do not use the pipe exit and the caller - // must use the returned pid to kill the process after it is done. - Slirp4netnsExitPipeR *os.File - // RootlessPortSyncPipe pipe used to exit the rootlessport process. - // Same as Slirp4netnsExitPipeR, except this is only used when ports are given. - RootlessPortExitPipeR *os.File - // Pdeathsig is the signal which is send to slirp4netns process if the calling thread - // exits. The caller is responsible for locking the thread with runtime.LockOSThread(). - Pdeathsig syscall.Signal -} - -type logrusDebugWriter struct { - prefix string -} - -func (w *logrusDebugWriter) Write(p []byte) (int, error) { - logrus.Debugf("%s%s", w.prefix, string(p)) - return len(p), nil -} - -func checkSlirpFlags(path string) (*slirpFeatures, error) { - cmd := exec.Command(path, "--help") - out, err := cmd.CombinedOutput() - if err != nil { - return nil, fmt.Errorf("slirp4netns %q: %w", out, err) - } - return &slirpFeatures{ - HasDisableHostLoopback: strings.Contains(string(out), "--disable-host-loopback"), - HasMTU: strings.Contains(string(out), "--mtu"), - HasEnableSandbox: strings.Contains(string(out), "--enable-sandbox"), - HasEnableSeccomp: strings.Contains(string(out), "--enable-seccomp"), - HasCIDR: strings.Contains(string(out), "--cidr"), - HasOutboundAddr: strings.Contains(string(out), "--outbound-addr"), - HasIPv6: strings.Contains(string(out), "--enable-ipv6"), - }, nil -} - -func parseNetworkOptions(config *config.Config, extraOptions []string) (*networkOptions, error) { - options := make([]string, 0, len(config.Engine.NetworkCmdOptions.Get())+len(extraOptions)) - options = append(options, config.Engine.NetworkCmdOptions.Get()...) - options = append(options, extraOptions...) - opts := &networkOptions{ - // overwrite defaults - disableHostLoopback: true, - mtu: defaultMTU, - noPivotRoot: config.Engine.NoPivotRoot, - enableIPv6: true, - } - for _, o := range options { - option, value, ok := strings.Cut(o, "=") - if !ok { - return nil, fmt.Errorf("unknown option for slirp4netns: %q", o) - } - switch option { - case "cidr": - ipv4, _, err := net.ParseCIDR(value) - if err != nil || ipv4.To4() == nil { - return nil, fmt.Errorf("invalid cidr %q", value) - } - opts.cidr = value - case "port_handler": - switch value { - case "slirp4netns": - opts.isSlirpHostForward = true - case "rootlesskit": - opts.isSlirpHostForward = false - default: - return nil, fmt.Errorf("unknown port_handler for slirp4netns: %q", value) - } - case "allow_host_loopback": - switch value { - case "true": - opts.disableHostLoopback = false - case "false": - opts.disableHostLoopback = true - default: - return nil, fmt.Errorf("invalid value of allow_host_loopback for slirp4netns: %q", value) - } - case "enable_ipv6": - switch value { - case "true": - opts.enableIPv6 = true - case "false": - opts.enableIPv6 = false - default: - return nil, fmt.Errorf("invalid value of enable_ipv6 for slirp4netns: %q", value) - } - case "outbound_addr": - ipv4 := net.ParseIP(value) - if ipv4 == nil || ipv4.To4() == nil { - _, err := net.InterfaceByName(value) - if err != nil { - return nil, fmt.Errorf("invalid outbound_addr %q", value) - } - } - opts.outboundAddr = value - case "outbound_addr6": - ipv6 := net.ParseIP(value) - if ipv6 == nil || ipv6.To4() != nil { - _, err := net.InterfaceByName(value) - if err != nil { - return nil, fmt.Errorf("invalid outbound_addr6: %q", value) - } - } - opts.outboundAddr6 = value - case "mtu": - var err error - opts.mtu, err = strconv.Atoi(value) - if opts.mtu < 68 || err != nil { - return nil, fmt.Errorf("invalid mtu %q", value) - } - default: - return nil, fmt.Errorf("unknown option for slirp4netns: %q", o) - } - } - return opts, nil -} - -func createBasicSlirpCmdArgs(options *networkOptions, features *slirpFeatures) ([]string, error) { - cmdArgs := []string{} - if options.disableHostLoopback && features.HasDisableHostLoopback { - cmdArgs = append(cmdArgs, "--disable-host-loopback") - } - if options.mtu > -1 && features.HasMTU { - cmdArgs = append(cmdArgs, "--mtu="+strconv.Itoa(options.mtu)) - } - if !options.noPivotRoot && features.HasEnableSandbox { - cmdArgs = append(cmdArgs, "--enable-sandbox") - } - if features.HasEnableSeccomp { - cmdArgs = append(cmdArgs, "--enable-seccomp") - } - - if options.cidr != "" { - if !features.HasCIDR { - return nil, errors.New("cidr not supported") - } - cmdArgs = append(cmdArgs, "--cidr="+options.cidr) - } - - if options.enableIPv6 { - if !features.HasIPv6 { - return nil, errors.New("enable_ipv6 not supported") - } - cmdArgs = append(cmdArgs, "--enable-ipv6") - } - - if options.outboundAddr != "" { - if !features.HasOutboundAddr { - return nil, errors.New("outbound_addr not supported") - } - cmdArgs = append(cmdArgs, "--outbound-addr="+options.outboundAddr) - } - - if options.outboundAddr6 != "" { - if !features.HasOutboundAddr || !features.HasIPv6 { - return nil, errors.New("outbound_addr6 not supported") - } - if !options.enableIPv6 { - return nil, errors.New("enable_ipv6=true is required for outbound_addr6") - } - cmdArgs = append(cmdArgs, "--outbound-addr6="+options.outboundAddr6) - } - - return cmdArgs, nil -} - -// Setup can be called in rootful as well as in rootless. -// Spawns the slirp4netns process and setup port forwarding if ports are given. -func Setup(opts *SetupOptions) (*SetupResult, error) { - var err error - path, err := opts.Config.FindHelperBinary(BinaryName, true) - if err != nil { - return nil, fmt.Errorf("could not find slirp4netns, the network namespace can't be configured: %w", err) - } - - syncR, syncW, err := os.Pipe() - if err != nil { - return nil, fmt.Errorf("failed to open pipe: %w", err) - } - defer closeQuiet(syncR) - defer closeQuiet(syncW) - - havePortMapping := len(opts.Ports) > 0 - logPath := filepath.Join(opts.Config.Engine.TmpDir, fmt.Sprintf("slirp4netns-%s.log", opts.ContainerID)) - - netOptions, err := parseNetworkOptions(opts.Config, opts.ExtraOptions) - if err != nil { - return nil, err - } - slirpFeatures, err := checkSlirpFlags(path) - if err != nil { - return nil, fmt.Errorf("checking slirp4netns binary %s: %q: %w", path, err, err) - } - cmdArgs, err := createBasicSlirpCmdArgs(netOptions, slirpFeatures) - if err != nil { - return nil, err - } - - // the slirp4netns arguments being passed are described as follows: - // from the slirp4netns documentation: https://github.com/rootless-containers/slirp4netns - // -c, --configure Brings up the tap interface - // -e, --exit-fd=FD specify the FD for terminating slirp4netns - // -r, --ready-fd=FD specify the FD to write to when the initialization steps are finished - cmdArgs = append(cmdArgs, "-c", "-r", "3") - if opts.Slirp4netnsExitPipeR != nil { - cmdArgs = append(cmdArgs, "-e", "4") - } - - var apiSocket string - if havePortMapping && netOptions.isSlirpHostForward { - apiSocket = filepath.Join(opts.Config.Engine.TmpDir, opts.ContainerID+".net") - cmdArgs = append(cmdArgs, "--api-socket", apiSocket) - } - - cmdArgs = append(cmdArgs, "--netns-type=path", opts.Netns, "tap0") - - cmd := exec.Command(path, cmdArgs...) - logrus.Debugf("slirp4netns command: %s", strings.Join(cmd.Args, " ")) - cmd.SysProcAttr = &syscall.SysProcAttr{ - Setpgid: true, - Pdeathsig: opts.Pdeathsig, - } - - // workaround for https://github.com/rootless-containers/slirp4netns/pull/153 - if !netOptions.noPivotRoot && slirpFeatures.HasEnableSandbox { - cmd.SysProcAttr.Cloneflags = syscall.CLONE_NEWNS - cmd.SysProcAttr.Unshareflags = syscall.CLONE_NEWNS - } - - // Leak one end of the pipe in slirp4netns, the other will be sent to conmon - cmd.ExtraFiles = append(cmd.ExtraFiles, syncW) - if opts.Slirp4netnsExitPipeR != nil { - cmd.ExtraFiles = append(cmd.ExtraFiles, opts.Slirp4netnsExitPipeR) - } - - logFile, err := os.Create(logPath) - if err != nil { - return nil, fmt.Errorf("failed to open slirp4netns log file %s: %w", logPath, err) - } - defer logFile.Close() - // Unlink immediately the file so we won't need to worry about cleaning it up later. - // It is still accessible through the open fd logFile. - if err := os.Remove(logPath); err != nil { - return nil, fmt.Errorf("delete file %s: %w", logPath, err) - } - cmd.Stdout = logFile - cmd.Stderr = logFile - - var slirpReadyWg, netnsReadyWg *sync.WaitGroup - if netOptions.enableIPv6 { - // use two wait groups to make sure we set the sysctl before - // starting slirp and reset it only after slirp is ready - slirpReadyWg = &sync.WaitGroup{} - netnsReadyWg = &sync.WaitGroup{} - slirpReadyWg.Add(1) - netnsReadyWg.Add(1) - - go func() { - err := netns.WithNetNSPath(opts.Netns, func(_ netns.NetNS) error { - // Duplicate Address Detection slows the ipv6 setup down for 1-2 seconds. - // Since slirp4netns is run in its own namespace and not directly routed - // we can skip this to make the ipv6 address immediately available. - // We change the default to make sure the slirp tap interface gets the - // correct value assigned so DAD is disabled for it - // Also make sure to change this value back to the original after slirp4netns - // is ready in case users rely on this sysctl. - orgValue, err := os.ReadFile(ipv6ConfDefaultAcceptDadSysctl) - if err != nil { - netnsReadyWg.Done() - // on ipv6 disabled systems the sysctl does not exist - // so we should not error - if errors.Is(err, os.ErrNotExist) { - return nil - } - return err - } - err = os.WriteFile(ipv6ConfDefaultAcceptDadSysctl, []byte("0"), 0o644) - netnsReadyWg.Done() - if err != nil { - return err - } - - // wait until slirp4nets is ready before resetting this value - slirpReadyWg.Wait() - return os.WriteFile(ipv6ConfDefaultAcceptDadSysctl, orgValue, 0o644) - }) - if err != nil { - logrus.Warnf("failed to set net.ipv6.conf.default.accept_dad sysctl: %v", err) - } - }() - - // wait until we set the sysctl - netnsReadyWg.Wait() - } - - if err := cmd.Start(); err != nil { - if netOptions.enableIPv6 { - slirpReadyWg.Done() - } - return nil, fmt.Errorf("failed to start slirp4netns process: %w", err) - } - defer func() { - servicereaper.AddPID(cmd.Process.Pid) - if err := cmd.Process.Release(); err != nil { - logrus.Errorf("Unable to release command process: %q", err) - } - }() - - err = waitForSync(syncR, cmd, logFile, 1*time.Second) - if netOptions.enableIPv6 { - slirpReadyWg.Done() - } - if err != nil { - return nil, err - } - - // Set a default slirp subnet. Parsing a string with the net helper is easier than building the struct myself - _, slirpSubnet, _ := net.ParseCIDR(defaultSubnet) - - // Set slirp4netnsSubnet addresses now that we are pretty sure the command executed - if netOptions.cidr != "" { - ipv4, ipv4network, err := net.ParseCIDR(netOptions.cidr) - if err != nil || ipv4.To4() == nil { - return nil, fmt.Errorf("invalid cidr %q", netOptions.cidr) - } - slirpSubnet = ipv4network - } - - if havePortMapping { - if netOptions.isSlirpHostForward { - err = setupRootlessPortMappingViaSlirp(opts.Ports, cmd, apiSocket) - } else { - err = SetupRootlessPortMappingViaRLK(opts, slirpSubnet, nil) - } - if err != nil { - return nil, err - } - } - - return &SetupResult{ - Pid: cmd.Process.Pid, - Subnet: slirpSubnet, - IPv6: netOptions.enableIPv6, - }, nil -} - -// GetIP returns the slirp ipv4 address based on subnet. If subnet is null use default subnet. -// Reference: https://github.com/rootless-containers/slirp4netns/blob/master/slirp4netns.1.md#description -func GetIP(subnet *net.IPNet) (*net.IP, error) { - _, slirpSubnet, _ := net.ParseCIDR(defaultSubnet) - if subnet != nil { - slirpSubnet = subnet - } - expectedIP, err := addToIP(slirpSubnet, uint32(100)) - if err != nil { - return nil, fmt.Errorf("calculating expected ip for slirp4netns: %w", err) - } - return expectedIP, nil -} - -// GetGateway returns the slirp gateway ipv4 address based on subnet. -// Reference: https://github.com/rootless-containers/slirp4netns/blob/master/slirp4netns.1.md#description -func GetGateway(subnet *net.IPNet) (*net.IP, error) { - _, slirpSubnet, _ := net.ParseCIDR(defaultSubnet) - if subnet != nil { - slirpSubnet = subnet - } - expectedGatewayIP, err := addToIP(slirpSubnet, uint32(2)) - if err != nil { - return nil, fmt.Errorf("calculating expected gateway ip for slirp4netns: %w", err) - } - return expectedGatewayIP, nil -} - -// GetDNS returns slirp DNS ipv4 address based on subnet. -// Reference: https://github.com/rootless-containers/slirp4netns/blob/master/slirp4netns.1.md#description -func GetDNS(subnet *net.IPNet) (*net.IP, error) { - _, slirpSubnet, _ := net.ParseCIDR(defaultSubnet) - if subnet != nil { - slirpSubnet = subnet - } - expectedDNSIP, err := addToIP(slirpSubnet, uint32(3)) - if err != nil { - return nil, fmt.Errorf("calculating expected dns ip for slirp4netns: %w", err) - } - return expectedDNSIP, nil -} - -// Helper function to calculate slirp ip address offsets -// Adapted from: https://github.com/signalsciences/ipv4/blob/master/int.go#L12-L24 -func addToIP(subnet *net.IPNet, offset uint32) (*net.IP, error) { - // I have no idea why I have to do this, but if I don't ip is 0 - ipFixed := subnet.IP.To4() - - ipInteger := uint32(ipFixed[3]) | uint32(ipFixed[2])<<8 | uint32(ipFixed[1])<<16 | uint32(ipFixed[0])<<24 - ipNewRaw := ipInteger + offset - // Avoid overflows - if ipNewRaw < ipInteger { - return nil, fmt.Errorf("integer overflow while calculating ip address offset, %s + %d", ipFixed, offset) - } - ipNew := net.IPv4(byte(ipNewRaw>>24), byte(ipNewRaw>>16&0xFF), byte(ipNewRaw>>8)&0xFF, byte(ipNewRaw&0xFF)) - if !subnet.Contains(ipNew) { - return nil, fmt.Errorf("calculated ip address %s is not within given subnet %s", ipNew.String(), subnet.String()) - } - return &ipNew, nil -} - -func waitForSync(syncR *os.File, cmd *exec.Cmd, logFile io.ReadSeeker, timeout time.Duration) error { - prog := filepath.Base(cmd.Path) - if len(cmd.Args) > 0 { - prog = cmd.Args[0] - } - b := make([]byte, 16) - for { - if err := syncR.SetDeadline(time.Now().Add(timeout)); err != nil { - return fmt.Errorf("setting %s pipe timeout: %w", prog, err) - } - // FIXME: return err as soon as proc exits, without waiting for timeout - _, err := syncR.Read(b) - if err == nil { - break - } - if errors.Is(err, os.ErrDeadlineExceeded) { - // Check if the process is still running. - var status syscall.WaitStatus - pid, err := syscall.Wait4(cmd.Process.Pid, &status, syscall.WNOHANG, nil) - if err != nil { - return fmt.Errorf("failed to read %s process status: %w", prog, err) - } - if pid != cmd.Process.Pid { - continue - } - if status.Exited() { - // Seek at the beginning of the file and read all its content - if _, err := logFile.Seek(0, 0); err != nil { - logrus.Errorf("Could not seek log file: %q", err) - } - logContent, err := io.ReadAll(logFile) - if err != nil { - return fmt.Errorf("%s failed: %w", prog, err) - } - return fmt.Errorf("%s failed: %q", prog, logContent) - } - if status.Signaled() { - return fmt.Errorf("%s killed by signal", prog) - } - continue - } - return fmt.Errorf("failed to read from %s sync pipe: %w", prog, err) - } - return nil -} - -func SetupRootlessPortMappingViaRLK(opts *SetupOptions, slirpSubnet *net.IPNet, netStatus map[string]types.StatusBlock) error { - syncR, syncW, err := os.Pipe() - if err != nil { - return fmt.Errorf("failed to open pipe: %w", err) - } - defer closeQuiet(syncR) - defer closeQuiet(syncW) - - logPath := filepath.Join(opts.Config.Engine.TmpDir, fmt.Sprintf("rootlessport-%s.log", opts.ContainerID)) - logFile, err := os.Create(logPath) - if err != nil { - return fmt.Errorf("failed to open rootlessport log file %s: %w", logPath, err) - } - defer logFile.Close() - // Unlink immediately the file so we won't need to worry about cleaning it up later. - // It is still accessible through the open fd logFile. - if err := os.Remove(logPath); err != nil { - return fmt.Errorf("delete file %s: %w", logPath, err) - } - - childIP := GetRootlessPortChildIP(slirpSubnet, netStatus) - cfg := rootlessport.Config{ - Mappings: opts.Ports, - NetNSPath: opts.Netns, - ExitFD: 3, - ReadyFD: 4, - TmpDir: opts.Config.Engine.TmpDir, - ChildIP: childIP, - ContainerID: opts.ContainerID, - RootlessCNI: netStatus != nil, - } - cfgJSON, err := json.Marshal(cfg) - if err != nil { - return err - } - cfgR := bytes.NewReader(cfgJSON) - var stdout bytes.Buffer - path, err := opts.Config.FindHelperBinary(rootlessport.BinaryName, false) - if err != nil { - return err - } - cmd := exec.Command(path) - cmd.Args = []string{rootlessport.BinaryName} - - // Leak one end of the pipe in rootlessport process, the other will be sent to conmon - cmd.ExtraFiles = append(cmd.ExtraFiles, opts.RootlessPortExitPipeR, syncW) - cmd.Stdin = cfgR - // stdout is for human-readable error, stderr is for debug log - cmd.Stdout = &stdout - cmd.Stderr = io.MultiWriter(logFile, &logrusDebugWriter{"rootlessport: "}) - cmd.SysProcAttr = &syscall.SysProcAttr{ - Setpgid: true, - } - if err := cmd.Start(); err != nil { - return fmt.Errorf("failed to start rootlessport process: %w", err) - } - defer func() { - servicereaper.AddPID(cmd.Process.Pid) - if err := cmd.Process.Release(); err != nil { - logrus.Errorf("Unable to release rootlessport process: %q", err) - } - }() - if err := waitForSync(syncR, cmd, logFile, 3*time.Second); err != nil { - stdoutStr := stdout.String() - if stdoutStr != "" { - // err contains full debug log and too verbose, so return stdoutStr - logrus.Debug(err) - return errors.New("rootlessport " + strings.TrimSuffix(stdoutStr, "\n")) - } - return err - } - logrus.Debug("rootlessport is ready") - return nil -} - -func setupRootlessPortMappingViaSlirp(ports []types.PortMapping, cmd *exec.Cmd, apiSocket string) (err error) { - const pidWaitTimeout = 60 * time.Second - chWait := make(chan error) - go func() { - interval := 25 * time.Millisecond - for i := time.Duration(0); i < pidWaitTimeout; i += interval { - // Check if the process is still running. - var status syscall.WaitStatus - pid, err := syscall.Wait4(cmd.Process.Pid, &status, syscall.WNOHANG, nil) - if err != nil { - break - } - if pid != cmd.Process.Pid { - continue - } - if status.Exited() || status.Signaled() { - chWait <- fmt.Errorf("slirp4netns exited with status %d", status.ExitStatus()) - } - time.Sleep(interval) - } - }() - defer close(chWait) - - // wait that API socket file appears before trying to use it. - if _, err := util.WaitForFile(apiSocket, chWait, pidWaitTimeout); err != nil { - return fmt.Errorf("waiting for slirp4nets to create the api socket file %s: %w", apiSocket, err) - } - - // for each port we want to add we need to open a connection to the slirp4netns control socket - // and send the add_hostfwd command. - for _, port := range ports { - for protocol := range strings.SplitSeq(port.Protocol, ",") { - hostIP := port.HostIP - if hostIP == "" { - hostIP = "0.0.0.0" - } - for i := range port.Range { - if err := openSlirp4netnsPort(apiSocket, protocol, hostIP, port.HostPort+i, port.ContainerPort+i); err != nil { - return err - } - } - } - } - logrus.Debug("slirp4netns port-forwarding setup via add_hostfwd is ready") - return nil -} - -// openSlirp4netnsPort sends the slirp4netns pai quey to the given socket. -func openSlirp4netnsPort(apiSocket, proto, hostip string, hostport, guestport uint16) error { - conn, err := net.Dial("unix", apiSocket) - if err != nil { - return fmt.Errorf("cannot open connection to %s: %w", apiSocket, err) - } - defer func() { - if err := conn.Close(); err != nil { - logrus.Errorf("Unable to close slirp4netns connection: %q", err) - } - }() - apiCmd := slirp4netnsCmd{ - Execute: "add_hostfwd", - Args: slirp4netnsCmdArg{ - Proto: proto, - HostAddr: hostip, - HostPort: hostport, - GuestPort: guestport, - }, - } - // create the JSON payload and send it. Mark the end of request shutting down writes - // to the socket, as requested by slirp4netns. - data, err := json.Marshal(&apiCmd) - if err != nil { - return fmt.Errorf("cannot marshal JSON for slirp4netns: %w", err) - } - if _, err := fmt.Fprintf(conn, "%s\n", data); err != nil { - return fmt.Errorf("cannot write to control socket %s: %w", apiSocket, err) - } - //nolint:errcheck // This cast should never fail, if it does we get a interface - // conversion panic and a stack trace on how we ended up here which is more - // valuable than returning a human friendly error test as we don't know how it - // happened. - if err := conn.(*net.UnixConn).CloseWrite(); err != nil { - return fmt.Errorf("cannot shutdown the socket %s: %w", apiSocket, err) - } - buf := make([]byte, 2048) - readLength, err := conn.Read(buf) - if err != nil { - return fmt.Errorf("cannot read from control socket %s: %w", apiSocket, err) - } - // if there is no 'error' key in the received JSON data, then the operation was - // successful. - var y map[string]any - if err := json.Unmarshal(buf[0:readLength], &y); err != nil { - return fmt.Errorf("parsing error status from slirp4netns: %w", err) - } - if e, found := y["error"]; found { - return fmt.Errorf("from slirp4netns while setting up port redirection: %v", e) - } - return nil -} - -func GetRootlessPortChildIP(slirpSubnet *net.IPNet, netStatus map[string]types.StatusBlock) string { - if slirpSubnet != nil { - slirp4netnsIP, err := GetIP(slirpSubnet) - if err != nil { - return "" - } - return slirp4netnsIP.String() - } - - var ipv6 net.IP - for _, status := range netStatus { - for _, netInt := range status.Interfaces { - for _, netAddress := range netInt.Subnets { - ipv4 := netAddress.IPNet.IP.To4() - if ipv4 != nil { - return ipv4.String() - } - ipv6 = netAddress.IPNet.IP - } - } - } - if ipv6 != nil { - return ipv6.String() - } - return "" -} - -// closeQuiet closes a file and logs any error. Should only be used within -// a defer. -func closeQuiet(f *os.File) { - if err := f.Close(); err != nil { - logrus.Errorf("Unable to close file %s: %q", f.Name(), err) - } -} diff --git a/vendor/go.podman.io/common/pkg/config/config.go b/vendor/go.podman.io/common/pkg/config/config.go index 2ab26134954..deebbd9b6eb 100644 --- a/vendor/go.podman.io/common/pkg/config/config.go +++ b/vendor/go.podman.io/common/pkg/config/config.go @@ -402,10 +402,6 @@ type EngineConfig struct { // containers and pods will be visible. The default namespace is "". Namespace string `toml:"namespace,omitempty"` - // NetworkCmdOptions is the default options to pass to the slirp4netns binary. - // For example "allow_host_loopback=true" - NetworkCmdOptions configfile.Slice `toml:"network_cmd_options,omitempty"` - // NoPivotRoot sets whether to set no-pivot-root in the OCI runtime. NoPivotRoot bool `toml:"no_pivot_root,omitempty"` @@ -609,7 +605,7 @@ type NetworkConfig struct { DefaultSubnetPools []SubnetPool `toml:"default_subnet_pools,omitempty"` // DefaultRootlessNetworkCmd is used to set the default rootless network - // program, either "slirp4nents" (default) or "pasta". + // program, currently only "pasta". DefaultRootlessNetworkCmd string `toml:"default_rootless_network_cmd,omitempty"` // NetworkConfigDir is where network configuration files are stored. diff --git a/vendor/go.podman.io/common/pkg/config/containers.conf b/vendor/go.podman.io/common/pkg/config/containers.conf index 49fd38390b8..d092448bb16 100644 --- a/vendor/go.podman.io/common/pkg/config/containers.conf +++ b/vendor/go.podman.io/common/pkg/config/containers.conf @@ -405,8 +405,8 @@ default_sysctls = [ -# Configure which rootless network program to use by default. Valid options are -# `slirp4netns` and `pasta` (default). +# Configure which rootless network program to use by default. The only valid option is +# `pasta` (default). # #default_rootless_network_cmd = "pasta" @@ -663,28 +663,6 @@ default_sysctls = [ # #namespace = "" -# Default options to pass to the slirp4netns binary. -# Valid options values are: -# -# - allow_host_loopback=true|false: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`). -# Default is false. -# - mtu=MTU: Specify the MTU to use for this network. (Default is `65520`). -# - cidr=CIDR: Specify ip range to use for this network. (Default is `10.0.2.0/24`). -# - enable_ipv6=true|false: Enable IPv6. Default is true. (Required for `outbound_addr6`). -# - outbound_addr=INTERFACE: Specify the outbound interface slirp should bind to (ipv4 traffic only). -# - outbound_addr=IPv4: Specify the outbound ipv4 address slirp should bind to. -# - outbound_addr6=INTERFACE: Specify the outbound interface slirp should bind to (ipv6 traffic only). -# - outbound_addr6=IPv6: Specify the outbound ipv6 address slirp should bind to. -# - port_handler=rootlesskit: Use rootlesskit for port forwarding. Default. -# Note: Rootlesskit changes the source IP address of incoming packets to a IP address in the container -# network namespace, usually `10.0.2.100`. If your application requires the real source IP address, -# e.g. web server logs, use the slirp4netns port handler. The rootlesskit port handler is also used for -# rootless containers when connected to user-defined networks. -# - port_handler=slirp4netns: Use the slirp4netns port forwarding, it is slower than rootlesskit but -# preserves the correct source IP address. This port handler cannot be used for user-defined networks. -# -#network_cmd_options = [] - # Whether to use chroot instead of pivot_root in the runtime # #no_pivot_root = false diff --git a/vendor/go.podman.io/common/pkg/config/containers.conf-freebsd b/vendor/go.podman.io/common/pkg/config/containers.conf-freebsd index 620bd0ca4f1..bc14ac75214 100644 --- a/vendor/go.podman.io/common/pkg/config/containers.conf-freebsd +++ b/vendor/go.podman.io/common/pkg/config/containers.conf-freebsd @@ -496,28 +496,6 @@ default_sysctls = [ # #namespace = "" -# Default options to pass to the slirp4netns binary. -# Valid options values are: -# -# - allow_host_loopback=true|false: Allow the slirp4netns to reach the host loopback IP (`10.0.2.2`). -# Default is false. -# - mtu=MTU: Specify the MTU to use for this network. (Default is `65520`). -# - cidr=CIDR: Specify ip range to use for this network. (Default is `10.0.2.0/24`). -# - enable_ipv6=true|false: Enable IPv6. Default is true. (Required for `outbound_addr6`). -# - outbound_addr=INTERFACE: Specify the outbound interface slirp should bind to (ipv4 traffic only). -# - outbound_addr=IPv4: Specify the outbound ipv4 address slirp should bind to. -# - outbound_addr6=INTERFACE: Specify the outbound interface slirp should bind to (ipv6 traffic only). -# - outbound_addr6=IPv6: Specify the outbound ipv6 address slirp should bind to. -# - port_handler=rootlesskit: Use rootlesskit for port forwarding. Default. -# Note: Rootlesskit changes the source IP address of incoming packets to a IP address in the container -# network namespace, usually `10.0.2.100`. If your application requires the real source IP address, -# e.g. web server logs, use the slirp4netns port handler. The rootlesskit port handler is also used for -# rootless containers when connected to user-defined networks. -# - port_handler=slirp4netns: Use the slirp4netns port forwarding, it is slower than rootlesskit but -# preserves the correct source IP address. This port handler cannot be used for user-defined networks. -# -#network_cmd_options = [] - # Whether to use chroot instead of pivot_root in the runtime # #no_pivot_root = false diff --git a/vendor/go.podman.io/common/pkg/parse/parse_unix.go b/vendor/go.podman.io/common/pkg/parse/parse_unix.go index ae534aec3cd..67089e9371b 100644 --- a/vendor/go.podman.io/common/pkg/parse/parse_unix.go +++ b/vendor/go.podman.io/common/pkg/parse/parse_unix.go @@ -7,8 +7,8 @@ import ( "os" "path/filepath" + "github.com/moby/sys/devices" "github.com/opencontainers/cgroups/devices/config" - "github.com/opencontainers/runc/libcontainer/devices" "go.podman.io/storage/pkg/unshare" ) diff --git a/vendor/go.podman.io/common/pkg/rootlessport/rootlessport_linux.go b/vendor/go.podman.io/common/pkg/rootlessport/rootlessport_linux.go deleted file mode 100644 index 78829b9fb61..00000000000 --- a/vendor/go.podman.io/common/pkg/rootlessport/rootlessport_linux.go +++ /dev/null @@ -1,26 +0,0 @@ -//go:build linux - -// Rootlessport Config type for use in podman/cmd/rootlessport. -package rootlessport - -import ( - "go.podman.io/common/libnetwork/types" -) - -const ( - // BinaryName is the binary name for the parent process. - BinaryName = "rootlessport" -) - -// Config needs to be provided to the process via stdin as a JSON string. -// stdin needs to be closed after the message has been written. -type Config struct { - Mappings []types.PortMapping - NetNSPath string - ExitFD int - ReadyFD int - TmpDir string - ChildIP string - ContainerID string - RootlessCNI bool -} diff --git a/vendor/go.podman.io/common/pkg/servicereaper/service.go b/vendor/go.podman.io/common/pkg/servicereaper/service.go deleted file mode 100644 index 12a29669b29..00000000000 --- a/vendor/go.podman.io/common/pkg/servicereaper/service.go +++ /dev/null @@ -1,64 +0,0 @@ -//go:build linux || freebsd - -package servicereaper - -import ( - "os" - "os/signal" - "sync" - "syscall" - - "github.com/sirupsen/logrus" -) - -type service struct { - pidMap map[int]bool - mutex *sync.Mutex -} - -var s = service{ - pidMap: map[int]bool{}, - mutex: &sync.Mutex{}, -} - -func AddPID(pid int) { - s.mutex.Lock() - s.pidMap[pid] = true - s.mutex.Unlock() -} - -func Start() { - // create signal channel and only wait for SIGCHLD - sigc := make(chan os.Signal, 1) - signal.Notify(sigc, syscall.SIGCHLD) - // wait and reap in an extra goroutine - go reaper(sigc) -} - -func reaper(sigc chan os.Signal) { - for { - // block until we receive SIGCHLD - <-sigc - s.mutex.Lock() - for pid := range s.pidMap { - var status syscall.WaitStatus - waitpid, err := syscall.Wait4(pid, &status, syscall.WNOHANG, nil) - if err != nil { - // do not log error for ECHILD - if err != syscall.ECHILD { - logrus.Warnf("Wait for pid %d failed: %v ", pid, err) - } - delete(s.pidMap, pid) - continue - } - // if pid == 0 nothing happened - if waitpid == 0 { - continue - } - if status.Exited() || status.Signaled() { - delete(s.pidMap, pid) - } - } - s.mutex.Unlock() - } -} diff --git a/vendor/go.podman.io/common/pkg/systemd/systemd_linux.go b/vendor/go.podman.io/common/pkg/systemd/systemd_linux.go index ab6606f56ba..2e862e89782 100644 --- a/vendor/go.podman.io/common/pkg/systemd/systemd_linux.go +++ b/vendor/go.podman.io/common/pkg/systemd/systemd_linux.go @@ -58,9 +58,9 @@ func moveProcessToScope(pid int, slice, scope string) error { return err } -// MoveRootlessNetnsSlirpProcessToUserSlice moves the slirp4netns process for the rootless netns +// MoveRootlessNetnsProcessToUserSlice moves the pasta process for the rootless netns // into a different scope so that systemd does not kill it with a container. -func MoveRootlessNetnsSlirpProcessToUserSlice(pid int) error { +func MoveRootlessNetnsProcessToUserSlice(pid int) error { randBytes := make([]byte, 4) _, err := rand.Read(randBytes) if err != nil { diff --git a/vendor/go.podman.io/storage/drivers/btrfs/btrfs.go b/vendor/go.podman.io/storage/drivers/btrfs/btrfs.go index 4ba23c544e0..7b80c95131f 100644 --- a/vendor/go.podman.io/storage/drivers/btrfs/btrfs.go +++ b/vendor/go.podman.io/storage/drivers/btrfs/btrfs.go @@ -483,15 +483,20 @@ func (d *Driver) CreateFromTemplate(id, template string, templateIDMappings *idt // CreateReadWrite creates a layer that is writable for use as a container // file system. func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error { - return d.create(id, parent, opts, true) + return d.create(id, parent, opts, false) } // Create the filesystem with given id. func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error { - return d.create(id, parent, opts, false) + return d.create(id, parent, opts, true) } -func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, applyDriverDefaultQuota bool) error { +func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, readOnly bool) error { + quota, err := d.parseStorageOpt(opts, readOnly) + if err != nil { + return err + } + quotas := d.quotasDir() subvolumes := d.subvolumesDir() if err := os.MkdirAll(subvolumes, 0o700); err != nil { @@ -518,34 +523,14 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, applyDr } } - var storageOpt map[string]string - if opts != nil { - storageOpt = opts.StorageOpt - } - - var quotaSize uint64 - var needQuota bool - if _, ok := storageOpt["size"]; ok { - driver := &Driver{} - if err := d.parseStorageOpt(storageOpt, driver); err != nil { - return err - } - quotaSize = driver.options.size - needQuota = true - } - if !needQuota && applyDriverDefaultQuota && d.options.size > 0 { - quotaSize = d.options.size - needQuota = true - } - if needQuota { - layerDriver := &Driver{options: btrfsOptions{size: quotaSize}} - if err := d.setStorageSize(path.Join(subvolumes, id), layerDriver); err != nil { + if quota != nil { + if err := d.setStorageSize(path.Join(subvolumes, id), *quota); err != nil { return err } if err := os.MkdirAll(quotas, 0o700); err != nil { return err } - if err := os.WriteFile(path.Join(quotas, id), []byte(fmt.Sprint(quotaSize)), 0o644); err != nil { + if err := os.WriteFile(path.Join(quotas, id), []byte(fmt.Sprint(quota.size)), 0o644); err != nil { return err } } @@ -558,8 +543,27 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, applyDr return label.Relabel(path.Join(subvolumes, id), mountLabel, false) } -// Parse btrfs storage options -func (d *Driver) parseStorageOpt(storageOpt map[string]string, driver *Driver) error { +// layerQuota contains per-layer quota settings. +type layerQuota struct { + size uint64 +} + +// parseStorageOpt parses CreateOpts.StorageOpt. +// Returns a *layerQuota if a quota should be applied, nil otherwise. +func (d *Driver) parseStorageOpt(opts *graphdriver.CreateOpts, readOnly bool) (*layerQuota, error) { + var storageOpt map[string]string = nil // Iterating over a nil map is safe + if opts != nil { + storageOpt = opts.StorageOpt + } + + res := layerQuota{} + needQuota := false + + if !readOnly && d.options.size > 0 { + res.size = d.options.size + needQuota = true + } + // Read size to change the subvolume disk quota per container for key, val := range storageOpt { key := strings.ToLower(key) @@ -567,23 +571,27 @@ func (d *Driver) parseStorageOpt(storageOpt map[string]string, driver *Driver) e case "size": size, err := units.RAMInBytes(val) if err != nil { - return err + return nil, err } - driver.options.size = uint64(size) + res.size = uint64(size) + needQuota = true default: - return fmt.Errorf("unknown option %s (%q)", key, storageOpt) + return nil, fmt.Errorf("unknown option %s (%q)", key, storageOpt) } } - return nil + if needQuota { + return &res, nil + } + return nil, nil } // Set btrfs storage size -func (d *Driver) setStorageSize(dir string, driver *Driver) error { - if driver.options.size <= 0 { - return fmt.Errorf("btrfs: invalid storage size: %s", units.HumanSize(float64(driver.options.size))) +func (d *Driver) setStorageSize(dir string, quota layerQuota) error { + if quota.size <= 0 { + return fmt.Errorf("btrfs: invalid storage size: %s", units.HumanSize(float64(quota.size))) } - if d.options.minSpace > 0 && driver.options.size < d.options.minSpace { + if d.options.minSpace > 0 && quota.size < d.options.minSpace { return fmt.Errorf("btrfs: storage size cannot be less than %s", units.HumanSize(float64(d.options.minSpace))) } @@ -591,7 +599,7 @@ func (d *Driver) setStorageSize(dir string, driver *Driver) error { return err } - if err := subvolLimitQgroup(dir, driver.options.size); err != nil { + if err := subvolLimitQgroup(dir, quota.size); err != nil { return err } diff --git a/vendor/go.podman.io/storage/drivers/overlay/overlay.go b/vendor/go.podman.io/storage/drivers/overlay/overlay.go index 6a0eb210465..7647bf24540 100644 --- a/vendor/go.podman.io/storage/drivers/overlay/overlay.go +++ b/vendor/go.podman.io/storage/drivers/overlay/overlay.go @@ -991,46 +991,16 @@ func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts return fmt.Errorf("--storage-opt is supported only for overlay over xfs with 'pquota' mount option") } - if opts == nil { - opts = &graphdriver.CreateOpts{ - StorageOpt: map[string]string{}, - } - } - if d.options.forceMask != nil && d.options.mountProgram == "" { return fmt.Errorf("overlay: force_mask option for writeable layers is only supported with a mount_program") } - if _, ok := opts.StorageOpt["size"]; !ok { - if opts.StorageOpt == nil { - opts.StorageOpt = map[string]string{} - } - opts.StorageOpt["size"] = strconv.FormatUint(d.options.quota.Size, 10) - } - - if _, ok := opts.StorageOpt["inodes"]; !ok { - if opts.StorageOpt == nil { - opts.StorageOpt = map[string]string{} - } - opts.StorageOpt["inodes"] = strconv.FormatUint(d.options.quota.Inodes, 10) - } - return d.create(id, parent, opts, false) } // Create is used to create the upper, lower, and merge directories required for overlay fs for a given id. // The parent filesystem is used to configure these directories for the overlay. func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr error) { - if opts != nil && len(opts.StorageOpt) != 0 { - if _, ok := opts.StorageOpt["size"]; ok { - return fmt.Errorf("--storage-opt size is only supported for ReadWrite Layers") - } - - if _, ok := opts.StorageOpt["inodes"]; ok { - return fmt.Errorf("--storage-opt inodes is only supported for ReadWrite Layers") - } - } - return d.create(id, parent, opts, true) } @@ -1078,6 +1048,11 @@ func (d *Driver) getLayerPermissions(parent string, uidMaps, gidMaps []idtools.I } func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, readOnly bool) (retErr error) { + quota, err := d.parseStorageOpt(opts, readOnly) // Do this even for read-only layers, to allow rejecting quota options + if err != nil { + return err + } + dir, homedir, _ := d.dir2(id, readOnly) disableQuota := readOnly @@ -1127,19 +1102,6 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, readOnl }() if d.quotaCtl != nil && !disableQuota { - quota := quota.Quota{} - if opts != nil && len(opts.StorageOpt) > 0 { - driver := &Driver{} - if err := d.parseStorageOpt(opts.StorageOpt, driver); err != nil { - return err - } - if driver.options.quota.Size > 0 { - quota.Size = driver.options.quota.Size - } - if driver.options.quota.Inodes > 0 { - quota.Inodes = driver.options.quota.Inodes - } - } // Set container disk quota limit // If it is set to 0, we will track the disk usage, but not enforce a limit if err := d.quotaCtl.SetQuota(dir, quota); err != nil { @@ -1226,29 +1188,47 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, readOnl } // Parse overlay storage options -func (d *Driver) parseStorageOpt(storageOpt map[string]string, driver *Driver) error { +func (d *Driver) parseStorageOpt(opts *graphdriver.CreateOpts, readOnly bool) (quota.Quota, error) { + var storageOpt map[string]string = nil // Iterating over a nil map is safe + if opts != nil { + storageOpt = opts.StorageOpt + } + + res := quota.Quota{} + + if !readOnly { + res.Size = d.options.quota.Size + res.Inodes = d.options.quota.Inodes + } + // Read size to set the disk project quota per container for key, val := range storageOpt { key := strings.ToLower(key) switch key { case "size": + if readOnly { + return quota.Quota{}, fmt.Errorf("--storage-opt size is only supported for ReadWrite Layers") + } size, err := units.RAMInBytes(val) if err != nil { - return err + return quota.Quota{}, err } - driver.options.quota.Size = uint64(size) + res.Size = uint64(size) case "inodes": + if readOnly { + return quota.Quota{}, fmt.Errorf("--storage-opt inodes is only supported for ReadWrite Layers") + } inodes, err := strconv.ParseUint(val, 10, 64) if err != nil { - return err + return quota.Quota{}, err } - driver.options.quota.Inodes = inodes + res.Inodes = inodes default: - return fmt.Errorf("unknown option %s", key) + return quota.Quota{}, fmt.Errorf("unknown option %s", key) } } - return nil + return res, nil } func (d *Driver) getLower(parent string) (string, error) { diff --git a/vendor/modules.txt b/vendor/modules.txt index 342a75f124d..7b79004865a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -319,7 +319,6 @@ github.com/opencontainers/image-spec/specs-go/v1 github.com/opencontainers/runc/internal/linux github.com/opencontainers/runc/internal/pathrs github.com/opencontainers/runc/libcontainer/apparmor -github.com/opencontainers/runc/libcontainer/devices # github.com/opencontainers/runtime-spec v1.3.0 ## explicit github.com/opencontainers/runtime-spec/specs-go @@ -458,7 +457,7 @@ go.opentelemetry.io/otel/trace go.opentelemetry.io/otel/trace/embedded go.opentelemetry.io/otel/trace/internal/telemetry go.opentelemetry.io/otel/trace/noop -# go.podman.io/common v0.67.2-0.20260423135811-cbaa5f41e643 +# go.podman.io/common v0.67.2-0.20260423135811-cbaa5f41e643 => github.com/lsm5/container-libs/common v0.0.0-20260424152608-5b5912370b8d ## explicit; go 1.25.6 go.podman.io/common/internal go.podman.io/common/libimage @@ -473,7 +472,6 @@ go.podman.io/common/libnetwork/netavark go.podman.io/common/libnetwork/network go.podman.io/common/libnetwork/pasta go.podman.io/common/libnetwork/resolvconf -go.podman.io/common/libnetwork/slirp4netns go.podman.io/common/libnetwork/types go.podman.io/common/libnetwork/util go.podman.io/common/pkg/apparmor @@ -497,9 +495,7 @@ go.podman.io/common/pkg/netns go.podman.io/common/pkg/parse go.podman.io/common/pkg/password go.podman.io/common/pkg/retry -go.podman.io/common/pkg/rootlessport go.podman.io/common/pkg/seccomp -go.podman.io/common/pkg/servicereaper go.podman.io/common/pkg/signal go.podman.io/common/pkg/subscriptions go.podman.io/common/pkg/supplemented @@ -509,7 +505,7 @@ go.podman.io/common/pkg/umask go.podman.io/common/pkg/util go.podman.io/common/pkg/version go.podman.io/common/version -# go.podman.io/image/v5 v5.39.3-0.20260423135811-cbaa5f41e643 +# go.podman.io/image/v5 v5.39.3-0.20260423135811-cbaa5f41e643 => github.com/lsm5/container-libs/image/v5 v5.0.0-20260424152608-5b5912370b8d ## explicit; go 1.25.6 go.podman.io/image/v5/copy go.podman.io/image/v5/directory @@ -578,7 +574,7 @@ go.podman.io/image/v5/transports go.podman.io/image/v5/transports/alltransports go.podman.io/image/v5/types go.podman.io/image/v5/version -# go.podman.io/storage v1.62.1-0.20260423135811-cbaa5f41e643 +# go.podman.io/storage v1.62.1-0.20260423135811-cbaa5f41e643 => github.com/lsm5/container-libs/storage v0.0.0-20260424152608-5b5912370b8d ## explicit; go 1.25.0 go.podman.io/storage go.podman.io/storage/drivers @@ -825,3 +821,6 @@ tags.cncf.io/container-device-interface/pkg/parser # tags.cncf.io/container-device-interface/specs-go v1.1.0 ## explicit; go 1.19 tags.cncf.io/container-device-interface/specs-go +# go.podman.io/common => github.com/lsm5/container-libs/common v0.0.0-20260424152608-5b5912370b8d +# go.podman.io/image/v5 => github.com/lsm5/container-libs/image/v5 v5.0.0-20260424152608-5b5912370b8d +# go.podman.io/storage => github.com/lsm5/container-libs/storage v0.0.0-20260424152608-5b5912370b8d From e29b3d702a617f086ae924927b7510acae497fba Mon Sep 17 00:00:00 2001 From: Lokesh Mandvekar Date: Fri, 24 Apr 2026 12:00:00 -0400 Subject: [PATCH 2/4] Remove slirp for podman6 Signed-off-by: Lokesh Mandvekar --- run_common.go | 4 ++-- run_linux.go | 46 ---------------------------------------------- 2 files changed, 2 insertions(+), 48 deletions(-) diff --git a/run_common.go b/run_common.go index 6f760b07e23..5de7df2a805 100644 --- a/run_common.go +++ b/run_common.go @@ -389,8 +389,8 @@ func checkAndOverrideIsolationOptions(isolation define.Isolation, options *RunOp case IsolationOCIRootless: // only change the netns if the caller did not set it if ns := options.NamespaceOptions.Find(string(specs.NetworkNamespace)); ns == nil { - if _, err := exec.LookPath("slirp4netns"); err != nil { - // if slirp4netns is not installed we have to use the hosts net namespace + if _, err := exec.LookPath("pasta"); err != nil { + // if pasta is not installed we have to use the hosts net namespace options.NamespaceOptions.AddOrReplace(define.NamespaceOption{Name: string(specs.NetworkNamespace), Host: true}) } } diff --git a/run_linux.go b/run_linux.go index ba04bca4f58..047c96154f3 100644 --- a/run_linux.go +++ b/run_linux.go @@ -12,7 +12,6 @@ import ( "slices" "strings" "sync" - "syscall" "github.com/docker/go-units" "github.com/opencontainers/runtime-spec/specs-go" @@ -33,7 +32,6 @@ import ( "go.podman.io/common/libnetwork/etchosts" "go.podman.io/common/libnetwork/pasta" "go.podman.io/common/libnetwork/resolvconf" - "go.podman.io/common/libnetwork/slirp4netns" nettypes "go.podman.io/common/libnetwork/types" netUtil "go.podman.io/common/libnetwork/util" "go.podman.io/common/pkg/capabilities" @@ -689,46 +687,6 @@ func addCommonOptsToSpec(commonOpts *define.CommonBuildOptions, g *generate.Gene return nil } -func setupSlirp4netnsNetwork(config *config.Config, netns, cid string, options, hostnames []string) (func(), *netResult, error) { - // we need the TmpDir for the slirp4netns code - if err := os.MkdirAll(config.Engine.TmpDir, 0o751); err != nil { - return nil, nil, fmt.Errorf("failed to create tempdir: %w", err) - } - res, err := slirp4netns.Setup(&slirp4netns.SetupOptions{ - Config: config, - ContainerID: cid, - Netns: netns, - ExtraOptions: options, - Pdeathsig: syscall.SIGKILL, - }) - if err != nil { - return nil, nil, err - } - - ip, err := slirp4netns.GetIP(res.Subnet) - if err != nil { - return nil, nil, fmt.Errorf("get slirp4netns ip: %w", err) - } - - dns, err := slirp4netns.GetDNS(res.Subnet) - if err != nil { - return nil, nil, fmt.Errorf("get slirp4netns dns ip: %w", err) - } - - result := &netResult{ - entries: etchosts.HostEntries{{IP: ip.String(), Names: hostnames}}, - dnsServers: []string{dns.String()}, - ipv6: res.IPv6, - keepHostResolvers: true, - } - - return func() { - syscall.Kill(res.Pid, syscall.SIGKILL) //nolint:errcheck - var status syscall.WaitStatus - syscall.Wait4(res.Pid, &status, 0, nil) //nolint:errcheck - }, result, nil -} - func setupPasta(config *config.Config, netns string, options, hostnames []string) (func(), *netResult, error) { res, err := pasta.Setup(&pasta.SetupOptions{ Config: config, @@ -776,8 +734,6 @@ func (b *Builder) runConfigureNetwork(pid int, isolation define.Isolation, optio } if isolation == IsolationOCIRootless && name == "" { switch defConfig.Network.DefaultRootlessNetworkCmd { - case slirp4netns.BinaryName, "": - name = slirp4netns.BinaryName case pasta.BinaryName: name = pasta.BinaryName default: @@ -787,8 +743,6 @@ func (b *Builder) runConfigureNetwork(pid int, isolation define.Isolation, optio } switch { - case name == slirp4netns.BinaryName: - return setupSlirp4netnsNetwork(defConfig, netns, containerName, netOpts, hostnames) case name == pasta.BinaryName: return setupPasta(defConfig, netns, netOpts, hostnames) From d379edd964aaf8e337b5e3f13dd1008576b6bc0c Mon Sep 17 00:00:00 2001 From: Lokesh Mandvekar Date: Fri, 24 Apr 2026 12:00:00 -0400 Subject: [PATCH 3/4] tests: Remove slirp for podman6 Signed-off-by: Lokesh Mandvekar --- contrib/cirrus/logcollector.sh | 1 - tests/bud.bats | 16 ---------------- tests/run.bats | 8 ++------ tests/tmt/system.fmf | 1 - 4 files changed, 2 insertions(+), 24 deletions(-) diff --git a/contrib/cirrus/logcollector.sh b/contrib/cirrus/logcollector.sh index 419b16eb5dc..fa13acef6f3 100755 --- a/contrib/cirrus/logcollector.sh +++ b/contrib/cirrus/logcollector.sh @@ -35,7 +35,6 @@ case $1 in podman runc skopeo - slirp4netns ) case $OS_RELEASE_ID in fedora*) diff --git a/tests/bud.bats b/tests/bud.bats index c93c283e9d0..d7b9f71af84 100644 --- a/tests/bud.bats +++ b/tests/bud.bats @@ -7715,22 +7715,6 @@ _EOF fi } -@test "bud with --network slirp4netns" { - skip_if_no_runtime - skip_if_in_container - skip_if_chroot - - _prefetch alpine - - run_buildah bud $WITH_POLICY_JSON --network slirp4netns $BUDFILES/network - # default subnet is 10.0.2.100/24 - assert "$output" =~ "10.0.2.100/24" "ip addr shows default subnet" - - run_buildah bud $WITH_POLICY_JSON --network slirp4netns:cidr=192.168.255.0/24,mtu=2000 $BUDFILES/network - assert "$output" =~ "192.168.255.100/24" "ip addr shows custom subnet" - assert "$output" =~ "mtu 2000" "ip addr shows mtu 2000" -} - @test "bud with --network pasta" { skip_if_no_runtime skip_if_chroot diff --git a/tests/run.bats b/tests/run.bats index b70c73684a0..13908a5489c 100644 --- a/tests/run.bats +++ b/tests/run.bats @@ -730,10 +730,6 @@ function configure_and_check_user() { expect_output --substring "(10.88.*|10.0.2.100)[[:blank:]]$cid" assert "$output" !~ "(10.88.*|10.0.2.100)[[:blank:]]host1 $cid" "Container IP should not contain host1" - # check slirp4netns sets correct hostname with another cidr - run_buildah run --network slirp4netns:cidr=192.168.2.0/24 --hostname $hostname $cid cat /etc/hosts - expect_output --substring "192.168.2.100[[:blank:]]$hostname $cid" - run_buildah run --network=container $cid cat /etc/hosts m=$(buildah mount $cid) run cat $m/etc/hosts @@ -816,9 +812,9 @@ function configure_and_check_user() { # filter out 127... nameservers run grep -v "nameserver 127." <<< "$output" nameservers="$output" - # in case of rootless add extra slirp4netns nameserver + # in case of rootless add extra pasta nameserver if is_rootless; then - nameservers="nameserver 10.0.2.3 + nameservers="nameserver 169.254.1.1 $output" fi run_buildah from --quiet --pull=false $WITH_POLICY_JSON alpine diff --git a/tests/tmt/system.fmf b/tests/tmt/system.fmf index 835f959a35b..dc84a01a7c0 100644 --- a/tests/tmt/system.fmf +++ b/tests/tmt/system.fmf @@ -1,7 +1,6 @@ require: - buildah-tests - git-daemon - - slirp4netns environment: BUILDAH_BINARY: /usr/bin/buildah From 30c7b52924c053288e19101367870c109f75e3c0 Mon Sep 17 00:00:00 2001 From: Lokesh Mandvekar Date: Fri, 24 Apr 2026 12:00:00 -0400 Subject: [PATCH 4/4] docs: Remove slirp for podman6 Signed-off-by: Lokesh Mandvekar --- docs/buildah-build.1.md | 14 ++------------ docs/buildah-from.1.md | 14 ++------------ docs/buildah-run.1.md | 14 ++------------ 3 files changed, 6 insertions(+), 36 deletions(-) diff --git a/docs/buildah-build.1.md b/docs/buildah-build.1.md index f3ee2144cc6..8ca32812894 100644 --- a/docs/buildah-build.1.md +++ b/docs/buildah-build.1.md @@ -664,15 +664,6 @@ Valid _mode_ values are: - **ns:**_path_: path to a network namespace to join; - **private**: create a new namespace for the container (default) - **\**: Join the network with the given name or ID, e.g. use `--network mynet` to join the network with the name mynet. Only supported for rootful users. -- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf: - - **allow_host_loopback=true|false**: Allow slirp4netns to reach the host loopback IP (default is 10.0.2.2 or the second IP from slirp4netns cidr subnet when changed, see the cidr option below). The default is false. - - **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`). - - **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`). - - **enable_ipv6=true|false**: Enable IPv6. Default is true. (Required for `outbound_addr6`). - - **outbound_addr=INTERFACE**: Specify the outbound interface slirp binds to (ipv4 traffic only). - - **outbound_addr=IPv4**: Specify the outbound ipv4 address slirp binds to. - - **outbound_addr6=INTERFACE**: Specify the outbound interface slirp binds to (ipv6 traffic only). - - **outbound_addr6=IPv6**: Specify the outbound ipv6 address slirp binds to. - **pasta[:OPTIONS,...]**: use **pasta**(1) to create a user-mode networking stack. \ This is only supported in rootless mode. \ @@ -698,13 +689,12 @@ Valid _mode_ values are: - **pasta:--mtu,1500**: Specify a 1500 bytes MTU for the _tap_ interface in the container. - **pasta:--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,--dns-forward,10.0.2.3,-m,1500,--no-ndp,--no-dhcpv6,--no-dhcp**, - equivalent to default slirp4netns(1) options: disable IPv6, assign + disable IPv6, assign `10.0.2.0/24` to the `tap0` interface in the container, with gateway `10.0.2.3`, enable DNS forwarder reachable at `10.0.2.3`, set MTU to 1500 bytes, disable NDP, DHCPv6 and DHCP support. - **pasta:-I,tap0,--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,--dns-forward,10.0.2.3,--no-ndp,--no-dhcpv6,--no-dhcp**, - equivalent to default slirp4netns(1) options with Podman overrides: same as - above, but leave the MTU to 65520 bytes + same as above, but leave the MTU to 65520 bytes - **pasta:-t,auto,-u,auto,-T,auto,-U,auto**: enable automatic port forwarding based on observed bound ports from both host and container sides - **pasta:-T,5201**: enable forwarding of TCP port 5201 from container to diff --git a/docs/buildah-from.1.md b/docs/buildah-from.1.md index 33be7d65804..04cdd31cd11 100644 --- a/docs/buildah-from.1.md +++ b/docs/buildah-from.1.md @@ -307,15 +307,6 @@ Valid _mode_ values are: - **ns:**_path_: path to a network namespace to join; - **private**: create a new namespace for the container (default) - **\**: Join the network with the given name or ID, e.g. use `--network mynet` to join the network with the name mynet. Only supported for rootful users. -- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf: - - **allow_host_loopback=true|false**: Allow slirp4netns to reach the host loopback IP (default is 10.0.2.2 or the second IP from slirp4netns cidr subnet when changed, see the cidr option below). The default is false. - - **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`). - - **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`). - - **enable_ipv6=true|false**: Enable IPv6. Default is true. (Required for `outbound_addr6`). - - **outbound_addr=INTERFACE**: Specify the outbound interface slirp binds to (ipv4 traffic only). - - **outbound_addr=IPv4**: Specify the outbound ipv4 address slirp binds to. - - **outbound_addr6=INTERFACE**: Specify the outbound interface slirp binds to (ipv6 traffic only). - - **outbound_addr6=IPv6**: Specify the outbound ipv6 address slirp binds to. - **pasta[:OPTIONS,...]**: use **pasta**(1) to create a user-mode networking stack. \ This is only supported in rootless mode. \ @@ -341,13 +332,12 @@ Valid _mode_ values are: - **pasta:--mtu,1500**: Specify a 1500 bytes MTU for the _tap_ interface in the container. - **pasta:--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,--dns-forward,10.0.2.3,-m,1500,--no-ndp,--no-dhcpv6,--no-dhcp**, - equivalent to default slirp4netns(1) options: disable IPv6, assign + disable IPv6, assign `10.0.2.0/24` to the `tap0` interface in the container, with gateway `10.0.2.3`, enable DNS forwarder reachable at `10.0.2.3`, set MTU to 1500 bytes, disable NDP, DHCPv6 and DHCP support. - **pasta:-I,tap0,--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,--dns-forward,10.0.2.3,--no-ndp,--no-dhcpv6,--no-dhcp**, - equivalent to default slirp4netns(1) options with Podman overrides: same as - above, but leave the MTU to 65520 bytes + same as above, but leave the MTU to 65520 bytes - **pasta:-t,auto,-u,auto,-T,auto,-U,auto**: enable automatic port forwarding based on observed bound ports from both host and container sides - **pasta:-T,5201**: enable forwarding of TCP port 5201 from container to diff --git a/docs/buildah-run.1.md b/docs/buildah-run.1.md index 078bb0f2b8d..146ca02c3d6 100644 --- a/docs/buildah-run.1.md +++ b/docs/buildah-run.1.md @@ -195,15 +195,6 @@ Valid _mode_ values are: - **ns:**_path_: path to a network namespace to join; - **private**: create a new namespace for the container (default) - **\**: Join the network with the given name or ID, e.g. use `--network mynet` to join the network with the name mynet. Only supported for rootful users. -- **slirp4netns[:OPTIONS,...]**: use **slirp4netns**(1) to create a user network stack. This is the default for rootless containers. It is possible to specify these additional options, they can also be set with `network_cmd_options` in containers.conf: - - **allow_host_loopback=true|false**: Allow slirp4netns to reach the host loopback IP (default is 10.0.2.2 or the second IP from slirp4netns cidr subnet when changed, see the cidr option below). The default is false. - - **mtu=MTU**: Specify the MTU to use for this network. (Default is `65520`). - - **cidr=CIDR**: Specify ip range to use for this network. (Default is `10.0.2.0/24`). - - **enable_ipv6=true|false**: Enable IPv6. Default is true. (Required for `outbound_addr6`). - - **outbound_addr=INTERFACE**: Specify the outbound interface slirp binds to (ipv4 traffic only). - - **outbound_addr=IPv4**: Specify the outbound ipv4 address slirp binds to. - - **outbound_addr6=INTERFACE**: Specify the outbound interface slirp binds to (ipv6 traffic only). - - **outbound_addr6=IPv6**: Specify the outbound ipv6 address slirp binds to. - **pasta[:OPTIONS,...]**: use **pasta**(1) to create a user-mode networking stack. \ This is only supported in rootless mode. \ @@ -229,13 +220,12 @@ Valid _mode_ values are: - **pasta:--mtu,1500**: Specify a 1500 bytes MTU for the _tap_ interface in the container. - **pasta:--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,--dns-forward,10.0.2.3,-m,1500,--no-ndp,--no-dhcpv6,--no-dhcp**, - equivalent to default slirp4netns(1) options: disable IPv6, assign + disable IPv6, assign `10.0.2.0/24` to the `tap0` interface in the container, with gateway `10.0.2.3`, enable DNS forwarder reachable at `10.0.2.3`, set MTU to 1500 bytes, disable NDP, DHCPv6 and DHCP support. - **pasta:-I,tap0,--ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,--dns-forward,10.0.2.3,--no-ndp,--no-dhcpv6,--no-dhcp**, - equivalent to default slirp4netns(1) options with Podman overrides: same as - above, but leave the MTU to 65520 bytes + same as above, but leave the MTU to 65520 bytes - **pasta:-t,auto,-u,auto,-T,auto,-U,auto**: enable automatic port forwarding based on observed bound ports from both host and container sides - **pasta:-T,5201**: enable forwarding of TCP port 5201 from container to