Vendor latest c/common and fix tests

This vendors the latest c/common version, including making Pasta
the default rootless network provider. That broke a number of
tests, which have been fixed as part of this PR.

Also includes a change to network stats logic, which simplifies
the code a bit and makes it actually work with Pasta.

Signed-off-by: Matt Heon <mheon@redhat.com>
This commit is contained in:
Matt Heon 2024-02-08 09:21:41 -05:00
parent 15d7179ada
commit 4c1c4c082a
18 changed files with 175 additions and 100 deletions

2
go.mod
View File

@ -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.20240201124221-b850c711ff5c github.com/containers/buildah v1.34.1-0.20240201124221-b850c711ff5c
github.com/containers/common v0.57.1-0.20240229151045-1c65e0de241a github.com/containers/common v0.57.1-0.20240229165734-cec09922602e
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.20240227090231-5bef5e1e1506 github.com/containers/image/v5 v5.29.3-0.20240227090231-5bef5e1e1506

4
go.sum
View File

@ -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.20240201124221-b850c711ff5c h1:r+1vFyTAoXptJrsPsnOMI3G0jm4+BCfXAcIyuA33lzo= github.com/containers/buildah v1.34.1-0.20240201124221-b850c711ff5c h1:r+1vFyTAoXptJrsPsnOMI3G0jm4+BCfXAcIyuA33lzo=
github.com/containers/buildah v1.34.1-0.20240201124221-b850c711ff5c/go.mod h1:Hw4qo2URFpWvZ2tjLstoQMpNC6+gR4PtxQefvV/UKaA= github.com/containers/buildah v1.34.1-0.20240201124221-b850c711ff5c/go.mod h1:Hw4qo2URFpWvZ2tjLstoQMpNC6+gR4PtxQefvV/UKaA=
github.com/containers/common v0.57.1-0.20240229151045-1c65e0de241a h1:N/AOv7bQBTD/+inld7Qpc2WzxtpbsPgPDB/gg7JGQKA= github.com/containers/common v0.57.1-0.20240229165734-cec09922602e h1:TPgCd6bWFyliJxCXEiCI1LnbB3kBUkpx1dw51ngDjWI=
github.com/containers/common v0.57.1-0.20240229151045-1c65e0de241a/go.mod h1:8irlyBcVooYx0F+YmoY7PQPAIgdJvCj17bvL7PqeaxI= github.com/containers/common v0.57.1-0.20240229165734-cec09922602e/go.mod h1:8irlyBcVooYx0F+YmoY7PQPAIgdJvCj17bvL7PqeaxI=
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=

View File

@ -191,7 +191,7 @@ func getContainerNetNS(ctr *Container) (string, *Container, error) {
func getContainerNetIO(ctr *Container) (map[string]define.ContainerNetworkStats, error) { func getContainerNetIO(ctr *Container) (map[string]define.ContainerNetworkStats, error) {
perNetworkStats := make(map[string]define.ContainerNetworkStats) perNetworkStats := make(map[string]define.ContainerNetworkStats)
netNSPath, otherCtr, netPathErr := getContainerNetNS(ctr) netNSPath, _, netPathErr := getContainerNetNS(ctr)
if netPathErr != nil { if netPathErr != nil {
return nil, netPathErr return nil, netPathErr
} }
@ -201,30 +201,28 @@ func getContainerNetIO(ctr *Container) (map[string]define.ContainerNetworkStats,
return nil, nil return nil, nil
} }
netMode := ctr.config.NetMode
netStatus := ctr.getNetworkStatus()
if otherCtr != nil {
netMode = otherCtr.config.NetMode
netStatus = otherCtr.getNetworkStatus()
}
if netMode.IsSlirp4netns() {
// create a fake status with correct interface name for the logic below
netStatus = map[string]types.StatusBlock{
"slirp4netns": {
Interfaces: map[string]types.NetInterface{"tap0": {}},
},
}
}
err := ns.WithNetNSPath(netNSPath, func(_ ns.NetNS) error { err := ns.WithNetNSPath(netNSPath, func(_ ns.NetNS) error {
for _, status := range netStatus { links, err := netlink.LinkList()
for dev := range status.Interfaces {
link, err := netlink.LinkByName(dev)
if err != nil { if err != nil {
return err return fmt.Errorf("retrieving all network interfaces: %w", err)
} }
stats := link.Attrs().Statistics for _, link := range links {
if stats != nil { attributes := link.Attrs()
newStats := define.ContainerNetworkStats{ if attributes.Flags&net.FlagLoopback != 0 {
continue
}
if attributes.Statistics != nil {
perNetworkStats[attributes.Name] = getNetStatsFromNetlinkStats(attributes.Statistics)
}
}
return nil
})
return perNetworkStats, err
}
func getNetStatsFromNetlinkStats(stats *netlink.LinkStatistics) define.ContainerNetworkStats {
return define.ContainerNetworkStats{
RxBytes: stats.RxBytes, RxBytes: stats.RxBytes,
RxDropped: stats.RxDropped, RxDropped: stats.RxDropped,
RxErrors: stats.RxErrors, RxErrors: stats.RxErrors,
@ -234,14 +232,6 @@ func getContainerNetIO(ctr *Container) (map[string]define.ContainerNetworkStats,
TxErrors: stats.TxErrors, TxErrors: stats.TxErrors,
TxPackets: stats.TxPackets, TxPackets: stats.TxPackets,
} }
perNetworkStats[dev] = newStats
}
}
}
return nil
})
return perNetworkStats, err
} }
// joinedNetworkNSPath returns netns path and bool if netns was set // joinedNetworkNSPath returns netns path and bool if netns was set

View File

@ -69,7 +69,7 @@ t GET libpod/containers/json?all=true 200 \
.[0].IsInfra=false .[0].IsInfra=false
# Test compat API for Network Settings (.Network is N/A when rootless) # Test compat API for Network Settings (.Network is N/A when rootless)
network_expect="Networks.slirp4netns.NetworkID=slirp4netns" network_expect="Networks.pasta.NetworkID=pasta"
if root; then if root; then
network_expect="Networks.podman.NetworkID=podman" network_expect="Networks.podman.NetworkID=podman"
fi fi

View File

@ -9,14 +9,6 @@ import (
. "github.com/onsi/gomega/gexec" . "github.com/onsi/gomega/gexec"
) )
// podman unshare --rootless-netns leaks the process by design.
// Running a container will cause the cleanup to kick in when this container gets stopped.
func cleanupRootlessSlirp4netns(p *PodmanTestIntegration) {
session := p.Podman([]string{"run", "--network", "bridge", ALPINE, "true"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
}
var _ = Describe("Podman unshare", func() { var _ = Describe("Podman unshare", func() {
BeforeEach(func() { BeforeEach(func() {
if _, err := os.Stat("/proc/self/uid_map"); err != nil { if _, err := os.Stat("/proc/self/uid_map"); err != nil {
@ -37,15 +29,6 @@ var _ = Describe("Podman unshare", func() {
Expect(session.OutputToString()).ToNot(ContainSubstring(userNS)) Expect(session.OutputToString()).ToNot(ContainSubstring(userNS))
}) })
It("podman unshare --rootless-netns", func() {
SkipIfRemote("podman-remote unshare is not supported")
defer cleanupRootlessSlirp4netns(podmanTest)
session := podmanTest.Podman([]string{"unshare", "--rootless-netns", "ip", "addr"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(ContainSubstring("tap0"))
})
It("podman unshare exit codes", func() { It("podman unshare exit codes", func() {
SkipIfRemote("podman-remote unshare is not supported") SkipIfRemote("podman-remote unshare is not supported")
session := podmanTest.Podman([]string{"unshare", "false"}) session := podmanTest.Podman([]string{"unshare", "false"})

View File

@ -5,6 +5,7 @@
load helpers load helpers
load helpers.systemd load helpers.systemd
load helpers.network
SERVICE_NAME="podman_test_$(random_string)" SERVICE_NAME="podman_test_$(random_string)"
@ -294,7 +295,7 @@ LISTEN_FDNAMES=listen_fdnames" | sort)
} }
# https://github.com/containers/podman/issues/13153 # https://github.com/containers/podman/issues/13153
@test "podman rootless-netns slirp4netns process should be in different cgroup" { @test "podman rootless-netns pasta processes should be in different cgroup" {
is_rootless || skip "only meaningful for rootless" is_rootless || skip "only meaningful for rootless"
cname=$(random_string) cname=$(random_string)
@ -314,9 +315,11 @@ LISTEN_FDNAMES=listen_fdnames" | sort)
# stop systemd container # stop systemd container
service_cleanup service_cleanup
pasta_iface=$(default_ifname)
# now check that the rootless netns slirp4netns process is still alive and working # now check that the rootless netns slirp4netns process is still alive and working
run_podman unshare --rootless-netns ip addr run_podman unshare --rootless-netns ip addr
is "$output" ".*tap0.*" "slirp4netns interface exists in the netns" is "$output" ".*$pasta_iface.*" "pasta interface exists in the netns"
run_podman exec $cname2 nslookup google.com run_podman exec $cname2 nslookup google.com
run_podman rm -f -t0 $cname2 run_podman rm -f -t0 $cname2

View File

@ -144,6 +144,8 @@ function remove_secret() {
} }
@test "quadlet - basic" { @test "quadlet - basic" {
# Network=none is to work around a Pasta bug, can be removed once a patched Pasta is available.
# Ref https://github.com/containers/podman/pull/21563#issuecomment-1965145324
local quadlet_file=$PODMAN_TMPDIR/basic_$(random_string).container local quadlet_file=$PODMAN_TMPDIR/basic_$(random_string).container
cat > $quadlet_file <<EOF cat > $quadlet_file <<EOF
[Container] [Container]
@ -151,6 +153,7 @@ Image=$IMAGE
Exec=sh -c "echo STARTED CONTAINER; echo "READY=1" | socat -u STDIN unix-sendto:\$NOTIFY_SOCKET; sleep inf" Exec=sh -c "echo STARTED CONTAINER; echo "READY=1" | socat -u STDIN unix-sendto:\$NOTIFY_SOCKET; sleep inf"
Notify=yes Notify=yes
LogDriver=passthrough LogDriver=passthrough
Network=none
EOF EOF
# FIXME: Temporary until podman fully removes cgroupsv1 support; see #21431 # FIXME: Temporary until podman fully removes cgroupsv1 support; see #21431

View File

@ -4,8 +4,17 @@
# #
load helpers load helpers
load helpers.registry
load helpers.systemd load helpers.systemd
function setup_file() {
# We have to stop the background registry here. These tests kill the podman pause
# process which means commands after that are in a new one and when the cleanup
# later tries to stop the registry container it will be in the wrong ns and can fail.
# https://github.com/containers/podman/pull/21563#issuecomment-1960047648
stop_registry
}
SERVICE_NAME="podman_test_$(random_string)" SERVICE_NAME="podman_test_$(random_string)"
SERVICE_SOCK_ADDR="/run/podman/$SERVICE_NAME.sock" SERVICE_SOCK_ADDR="/run/podman/$SERVICE_NAME.sock"

View File

@ -857,7 +857,7 @@ EOF
cid=${output} cid=${output}
run_podman inspect --format '{{ .NetworkSettings.Networks }}' $cid run_podman inspect --format '{{ .NetworkSettings.Networks }}' $cid
if is_rootless; then if is_rootless; then
is "$output" "map\[slirp4netns:.*" "NeworkSettings should contain one network named slirp4netns" is "$output" "map\[pasta:.*" "NeworkSettings should contain one network named pasta"
else else
is "$output" "map\[podman:.*" "NeworkSettings should contain one network named podman" is "$output" "map\[podman:.*" "NeworkSettings should contain one network named podman"
fi fi

View File

@ -18,21 +18,6 @@ function setup() {
XFER_FILE="${PODMAN_TMPDIR}/pasta.bin" XFER_FILE="${PODMAN_TMPDIR}/pasta.bin"
} }
function default_ifname() {
local ip_ver="${1}"
local expr='[.[] | select(.dst == "default").dev] | .[0]'
ip -j -"${ip_ver}" route show | jq -rM "${expr}"
}
function default_addr() {
local ip_ver="${1}"
local ifname="${2:-$(default_ifname "${ip_ver}")}"
local expr='.[0] | .addr_info[0].local'
ip -j -"${ip_ver}" addr show "${ifname}" | jq -rM "${expr}"
}
# _set_opt() - meta-helper for pasta_test_do. # _set_opt() - meta-helper for pasta_test_do.
# #
# Sets an option, but panics if option is already set (e.g. UDP+TCP, IPv4/v6) # Sets an option, but panics if option is already set (e.g. UDP+TCP, IPv4/v6)
@ -789,3 +774,14 @@ EOF
CONTAINERS_CONF_OVERRIDE=$containersconf run_podman run --net=pasta:--ns-mac-addr,"$mac2" $IMAGE ip link show myname CONTAINERS_CONF_OVERRIDE=$containersconf run_podman run --net=pasta:--ns-mac-addr,"$mac2" $IMAGE ip link show myname
assert "$output" =~ "$mac2" "mac address from cli is set on custom interface" assert "$output" =~ "$mac2" "mac address from cli is set on custom interface"
} }
### Rootless unshare testins
@test "Podman unshare --rootless-netns with Pasta" {
skip_if_remote "unshare is local-only"
pasta_iface=$(default_ifname)
run_podman unshare --rootless-netns ip addr
is "$output" ".*${pasta_iface}.*"
}

View File

@ -4,8 +4,17 @@
# #
load helpers load helpers
load helpers.registry
load helpers.sig-proxy load helpers.sig-proxy
function setup_file() {
# We have to stop the background registry here. These tests kill the podman pause
# process which means commands after that are in a new one and when the cleanup
# later tries to stop the registry container it will be in the wrong ns and can fail.
# https://github.com/containers/podman/pull/21563#issuecomment-1960047648
stop_registry
}
function _check_pause_process() { function _check_pause_process() {
pause_pid= pause_pid=
if [[ -z "$pause_pid_file" ]]; then if [[ -z "$pause_pid_file" ]]; then

View File

@ -369,3 +369,20 @@ function tcp_port_probe() {
: | nc "${address}" "${1}" : | nc "${address}" "${1}"
} }
### Pasta Helpers ##############################################################
function default_ifname() {
local ip_ver="${1}"
local expr='[.[] | select(.dst == "default").dev] | .[0]'
ip -j -"${ip_ver}" route show | jq -rM "${expr}"
}
function default_addr() {
local ip_ver="${1}"
local ifname="${2:-$(default_ifname "${ip_ver}")}"
local expr='.[0] | .addr_info[0].local'
ip -j -"${ip_ver}" addr show "${ifname}" | jq -rM "${expr}"
}

View File

@ -18,6 +18,8 @@ const (
EventTypeUnknown EventType = iota EventTypeUnknown EventType = iota
// EventTypeImagePull represents an image pull. // EventTypeImagePull represents an image pull.
EventTypeImagePull EventTypeImagePull
// EventTypeImagePullError represents an image pull failed.
EventTypeImagePullError
// EventTypeImagePush represents an image push. // EventTypeImagePush represents an image push.
EventTypeImagePush EventTypeImagePush
// EventTypeImageRemove represents an image removal. // EventTypeImageRemove represents an image removal.
@ -46,6 +48,8 @@ type Event struct {
Time time.Time Time time.Time
// Type of the event. // Type of the event.
Type EventType Type EventType
// Error in case of failure.
Error error
} }
// writeEvent writes the specified event to the Runtime's event channel. The // writeEvent writes the specified event to the Runtime's event channel. The

View File

@ -53,9 +53,16 @@ type PullOptions struct {
// The error is storage.ErrImageUnknown iff the pull policy is set to "never" // The error is storage.ErrImageUnknown iff the pull policy is set to "never"
// and no local image has been found. This allows for an easier integration // and no local image has been found. This allows for an easier integration
// into some users of this package (e.g., Buildah). // into some users of this package (e.g., Buildah).
func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullPolicy, options *PullOptions) ([]*Image, error) { func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullPolicy, options *PullOptions) (_ []*Image, pullError error) {
logrus.Debugf("Pulling image %s (policy: %s)", name, pullPolicy) logrus.Debugf("Pulling image %s (policy: %s)", name, pullPolicy)
if r.eventChannel != nil {
defer func() {
if pullError != nil {
// Note that we use the input name here to preserve the transport data.
r.writeEvent(&Event{Name: name, Time: time.Now(), Type: EventTypeImagePullError, Error: pullError})
}
}()
}
if options == nil { if options == nil {
options = &PullOptions{} options = &PullOptions{}
} }
@ -150,28 +157,25 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP
options.Variant = r.systemContext.VariantChoice options.Variant = r.systemContext.VariantChoice
} }
var ( var pulledImages []string
pulledImages []string
pullError error
)
// Dispatch the copy operation. // Dispatch the copy operation.
switch ref.Transport().Name() { switch ref.Transport().Name() {
// DOCKER REGISTRY // DOCKER REGISTRY
case registryTransport.Transport.Name(): case registryTransport.Transport.Name():
pulledImages, pullError = r.copyFromRegistry(ctx, ref, possiblyUnqualifiedName, pullPolicy, options) pulledImages, err = r.copyFromRegistry(ctx, ref, possiblyUnqualifiedName, pullPolicy, options)
// DOCKER ARCHIVE // DOCKER ARCHIVE
case dockerArchiveTransport.Transport.Name(): case dockerArchiveTransport.Transport.Name():
pulledImages, pullError = r.copyFromDockerArchive(ctx, ref, &options.CopyOptions) pulledImages, err = r.copyFromDockerArchive(ctx, ref, &options.CopyOptions)
// ALL OTHER TRANSPORTS // ALL OTHER TRANSPORTS
default: default:
pulledImages, pullError = r.copyFromDefault(ctx, ref, &options.CopyOptions) pulledImages, err = r.copyFromDefault(ctx, ref, &options.CopyOptions)
} }
if pullError != nil { if err != nil {
return nil, pullError return nil, err
} }
localImages := []*Image{} localImages := []*Image{}

View File

@ -8,9 +8,9 @@ import (
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"syscall"
"github.com/containernetworking/plugins/pkg/ns" "github.com/containernetworking/plugins/pkg/ns"
"github.com/containers/common/libnetwork/pasta"
"github.com/containers/common/libnetwork/resolvconf" "github.com/containers/common/libnetwork/resolvconf"
"github.com/containers/common/libnetwork/slirp4netns" "github.com/containers/common/libnetwork/slirp4netns"
"github.com/containers/common/pkg/config" "github.com/containers/common/pkg/config"
@ -31,8 +31,8 @@ const (
// refCountFile file name for the ref count file // refCountFile file name for the ref count file
refCountFile = "ref-count" refCountFile = "ref-count"
// rootlessNetNsSilrp4netnsPidFile is the name of the rootless netns slirp4netns pid file // rootlessNetNsConnPidFile is the name of the rootless netns slirp4netns/pasta pid file
rootlessNetNsSilrp4netnsPidFile = "rootless-netns-slirp4netns.pid" rootlessNetNsConnPidFile = "rootless-netns-conn.pid"
// persistentCNIDir is the directory where the CNI files are stored // persistentCNIDir is the directory where the CNI files are stored
persistentCNIDir = "/var/lib/cni" persistentCNIDir = "/var/lib/cni"
@ -113,7 +113,14 @@ func (n *Netns) getOrCreateNetns() (ns.NetNS, bool, error) {
if err != nil { if err != nil {
return nil, false, wrapError("create netns", err) return nil, false, wrapError("create netns", err)
} }
switch strings.ToLower(n.config.Network.DefaultRootlessNetworkCmd) {
case "", slirp4netns.BinaryName:
err = n.setupSlirp4netns(nsPath) err = n.setupSlirp4netns(nsPath)
case pasta.BinaryName:
err = n.setupPasta(nsPath)
default:
err = fmt.Errorf("invalid rootless network command %q", n.config.Network.DefaultRootlessNetworkCmd)
}
return netns, true, err return netns, true, err
} }
@ -133,8 +140,8 @@ func (n *Netns) cleanup() error {
if err := netns.UnmountNS(nsPath); err != nil { if err := netns.UnmountNS(nsPath); err != nil {
multiErr = multierror.Append(multiErr, err) multiErr = multierror.Append(multiErr, err)
} }
if err := n.cleanupSlirp4netns(); err != nil { if err := n.cleanupRootlessNetns(); err != nil {
multiErr = multierror.Append(multiErr, wrapError("kill slirp4netns", err)) multiErr = multierror.Append(multiErr, wrapError("kill network process", err))
} }
if err := os.RemoveAll(n.dir); err != nil { if err := os.RemoveAll(n.dir); err != nil {
multiErr = multierror.Append(multiErr, wrapError("remove rootless netns dir", err)) multiErr = multierror.Append(multiErr, wrapError("remove rootless netns dir", err))
@ -143,6 +150,53 @@ func (n *Netns) cleanup() error {
return multiErr.ErrorOrNil() return multiErr.ErrorOrNil()
} }
func (n *Netns) setupPasta(nsPath string) error {
pidPath := n.getPath(rootlessNetNsConnPidFile)
pastaOpts := pasta.SetupOptions{
Config: n.config,
Netns: nsPath,
ExtraOptions: []string{"--pid", pidPath},
}
if err := pasta.Setup(&pastaOpts); err != nil {
return fmt.Errorf("setting up Pasta: %w", err)
}
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)))
if err != nil {
return fmt.Errorf("unable to decode pasta PID: %w", err)
}
if err := systemd.MoveRootlessNetnsSlirpProcessToUserSlice(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)
}
}
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},
},
// TODO: Need a way to determine if there is a valid v6 address on any
// external interface of the system.
IPv6Enabled: false,
KeepHostServers: true,
Nameservers: []string{},
}); err != nil {
return wrapError("create resolv.conf", err)
}
return nil
}
func (n *Netns) setupSlirp4netns(nsPath string) error { func (n *Netns) setupSlirp4netns(nsPath string) error {
res, err := slirp4netns.Setup(&slirp4netns.SetupOptions{ res, err := slirp4netns.Setup(&slirp4netns.SetupOptions{
Config: n.config, Config: n.config,
@ -155,7 +209,7 @@ func (n *Netns) setupSlirp4netns(nsPath string) error {
// create pid file for the slirp4netns process // create pid file for the slirp4netns process
// this is need to kill the process in the cleanup // this is need to kill the process in the cleanup
pid := strconv.Itoa(res.Pid) pid := strconv.Itoa(res.Pid)
err = os.WriteFile(n.getPath(rootlessNetNsSilrp4netnsPidFile), []byte(pid), 0o600) err = os.WriteFile(n.getPath(rootlessNetNsConnPidFile), []byte(pid), 0o600)
if err != nil { if err != nil {
return wrapError("write slirp4netns pid file", err) return wrapError("write slirp4netns pid file", err)
} }
@ -190,15 +244,18 @@ func (n *Netns) setupSlirp4netns(nsPath string) error {
return nil return nil
} }
func (n *Netns) cleanupSlirp4netns() error { func (n *Netns) cleanupRootlessNetns() error {
pidFile := n.getPath(rootlessNetNsSilrp4netnsPidFile) pidFile := n.getPath(rootlessNetNsConnPidFile)
b, err := os.ReadFile(pidFile) b, err := os.ReadFile(pidFile)
if err == nil { if err == nil {
var i int var i int
i, err = strconv.Atoi(string(b)) i, err = strconv.Atoi(strings.TrimSpace(string(b)))
if err == nil { if err == nil {
// kill the slirp process so we do not leak it // kill the slirp process so we do not leak it
err = syscall.Kill(i, syscall.SIGTERM) err = unix.Kill(i, unix.SIGTERM)
if err == unix.ESRCH {
err = nil
}
} }
} }
return err return err

View File

@ -384,9 +384,9 @@ default_sysctls = [
# Configure which rootless network program to use by default. Valid options are # Configure which rootless network program to use by default. Valid options are
# `slirp4netns` (default) and `pasta`. # `slirp4netns` and `pasta` (default).
# #
#default_rootless_network_cmd = "slirp4netns" #default_rootless_network_cmd = "pasta"
# Path to the directory where network configuration files are located. # Path to the directory where network configuration files are located.
# For the CNI backend the default is "/etc/cni/net.d" as root # For the CNI backend the default is "/etc/cni/net.d" as root

View File

@ -257,7 +257,7 @@ func defaultConfig() (*Config, error) {
DefaultNetwork: "podman", DefaultNetwork: "podman",
DefaultSubnet: DefaultSubnet, DefaultSubnet: DefaultSubnet,
DefaultSubnetPools: DefaultSubnetPools, DefaultSubnetPools: DefaultSubnetPools,
DefaultRootlessNetworkCmd: "slirp4netns", DefaultRootlessNetworkCmd: "pasta",
DNSBindPort: 0, DNSBindPort: 0,
CNIPluginDirs: attributedstring.NewSlice(DefaultCNIPluginDirs), CNIPluginDirs: attributedstring.NewSlice(DefaultCNIPluginDirs),
NetavarkPluginDirs: attributedstring.NewSlice(DefaultNetavarkPluginDirs), NetavarkPluginDirs: attributedstring.NewSlice(DefaultNetavarkPluginDirs),

2
vendor/modules.txt vendored
View File

@ -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.20240229151045-1c65e0de241a # github.com/containers/common v0.57.1-0.20240229165734-cec09922602e
## 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