From 6b76b5b1f40dffec407dcc534bf0c5e71a7ab529 Mon Sep 17 00:00:00 2001 From: Lokesh Mandvekar Date: Fri, 10 Oct 2025 09:07:54 -0400 Subject: [PATCH 1/4] podman6: Remove cgroupsv1 support Signed-off-by: Lokesh Mandvekar --- cmd/podman/containers/unpause.go | 14 +- cmd/podman/main.go | 2 + cmd/podman/main_linux.go | 18 ++ cmd/podman/main_non_linux.go | 15 + go.mod | 16 +- go.sum | 32 +- libpod/container_internal.go | 20 +- libpod/container_internal_linux.go | 94 ++---- libpod/info_linux.go | 14 +- libpod/runtime_linux.go | 13 +- libpod/runtime_pod_linux.go | 4 +- pkg/domain/infra/runtime_libpod.go | 9 - pkg/specgen/generate/validate_linux.go | 164 +--------- .../github.com/containers/buildah/.cirrus.yml | 4 +- .../github.com/containers/buildah/buildah.go | 4 +- .../containers/buildah/chroot/run_common.go | 10 + .../github.com/containers/buildah/commit.go | 10 + .../containers/buildah/copier/copier.go | 44 +-- .../containers/buildah/copier/xattrs.go | 10 +- .../containers/buildah/docker/types.go | 4 +- .../buildah/imagebuildah/executor.go | 14 +- .../buildah/imagebuildah/stage_executor.go | 2 +- vendor/github.com/containers/buildah/info.go | 17 +- .../buildah/internal/config/override.go | 9 +- .../buildah/internal/mkcw/archive.go | 2 +- .../buildah/internal/mkcw/attest.go | 4 +- .../internal/mkcw/embed/entrypoint_amd64.gz | Bin 375 -> 362 bytes .../containers/buildah/internal/sbom/merge.go | 2 +- .../containers/buildah/pkg/cli/build.go | 2 +- .../containers/buildah/pkg/parse/parse.go | 6 +- .../containers/buildah/run_common.go | 6 + .../github.com/containers/luksy/.cirrus.yml | 4 +- .../docker/pkg/archive/archive_deprecated.go | 259 ---------------- .../docker/pkg/archive/changes_deprecated.go | 56 ---- .../docker/pkg/archive/copy_deprecated.go | 130 -------- .../docker/pkg/archive/diff_deprecated.go | 37 --- .../docker/pkg/archive/path_deprecated.go | 10 - .../docker/docker/pkg/archive/utils.go | 42 --- .../pkg/archive/whiteouts_deprecated.go | 10 - .../docker/pkg/archive/wrap_deprecated.go | 14 - .../docker/docker/pkg/idtools/idtools.go | 223 -------------- .../docker/pkg/idtools/idtools_windows.go | 12 - .../fsouza/go-dockerclient/.golangci.yaml | 21 +- .../go-dockerclient/container_update.go | 2 +- .../fsouza/go-dockerclient/event.go | 8 +- .../github.com/fsouza/go-dockerclient/tar.go | 2 +- .../moby/buildkit/util/stack/stack.pb.go | 2 +- .../common/pkg/cgroups/blkio_linux.go | 123 ++------ .../common/pkg/cgroups/cgroups_linux.go | 289 ++---------------- .../common/pkg/cgroups/cgroups_unsupported.go | 2 +- .../common/pkg/cgroups/cpu_linux.go | 67 ++-- .../common/pkg/cgroups/cpuset_linux.go | 23 +- .../common/pkg/cgroups/memory_linux.go | 78 ++--- .../common/pkg/cgroups/pids_linux.go | 25 +- .../common/pkg/cgroups/systemd_linux.go | 19 +- .../common/pkg/cgroups/utils_linux.go | 31 +- .../go.podman.io/common/pkg/config/default.go | 11 +- .../go.podman.io/common/pkg/config/systemd.go | 4 +- .../common/pkg/sysinfo/sysinfo_linux.go | 24 -- .../common/pkg/systemd/systemd_linux.go | 6 +- vendor/go.podman.io/common/version/version.go | 2 +- .../go.podman.io/image/v5/version/version.go | 2 +- vendor/go.podman.io/storage/VERSION | 2 +- vendor/modules.txt | 28 +- 64 files changed, 348 insertions(+), 1785 deletions(-) create mode 100644 cmd/podman/main_linux.go create mode 100644 cmd/podman/main_non_linux.go delete mode 100644 vendor/github.com/docker/docker/pkg/archive/archive_deprecated.go delete mode 100644 vendor/github.com/docker/docker/pkg/archive/changes_deprecated.go delete mode 100644 vendor/github.com/docker/docker/pkg/archive/copy_deprecated.go delete mode 100644 vendor/github.com/docker/docker/pkg/archive/diff_deprecated.go delete mode 100644 vendor/github.com/docker/docker/pkg/archive/path_deprecated.go delete mode 100644 vendor/github.com/docker/docker/pkg/archive/utils.go delete mode 100644 vendor/github.com/docker/docker/pkg/archive/whiteouts_deprecated.go delete mode 100644 vendor/github.com/docker/docker/pkg/archive/wrap_deprecated.go delete mode 100644 vendor/github.com/docker/docker/pkg/idtools/idtools.go delete mode 100644 vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go diff --git a/cmd/podman/containers/unpause.go b/cmd/podman/containers/unpause.go index 3b7acdab531..270f582b7fe 100644 --- a/cmd/podman/containers/unpause.go +++ b/cmd/podman/containers/unpause.go @@ -2,7 +2,6 @@ package containers import ( "context" - "errors" "fmt" "os" "strings" @@ -12,9 +11,7 @@ import ( "github.com/containers/podman/v5/cmd/podman/utils" "github.com/containers/podman/v5/cmd/podman/validate" "github.com/containers/podman/v5/pkg/domain/entities" - "github.com/containers/podman/v5/pkg/rootless" "github.com/spf13/cobra" - "go.podman.io/common/pkg/cgroups" "go.podman.io/common/pkg/completion" ) @@ -88,18 +85,9 @@ func init() { } func unpause(_ *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) + var errs utils.OutputErrors args = utils.RemoveSlash(args) - if rootless.IsRootless() && !registry.IsRemote() { - cgroupv2, _ := cgroups.IsCgroup2UnifiedMode() - if !cgroupv2 { - return errors.New("unpause is not supported for cgroupv1 rootless containers") - } - } - for _, cidFile := range unpauseCidFiles { content, err := os.ReadFile(cidFile) if err != nil { diff --git a/cmd/podman/main.go b/cmd/podman/main.go index 21585116d42..a12ef43162d 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -53,6 +53,8 @@ func main() { } logiface.SetLogger(logrusLogger{}) + checkSupportedCgroups() + if filepath.Base(os.Args[0]) == registry.PodmanSh || (len(os.Args[0]) > 0 && filepath.Base(os.Args[0][1:]) == registry.PodmanSh) { shell := strings.TrimPrefix(os.Args[0], "-") diff --git a/cmd/podman/main_linux.go b/cmd/podman/main_linux.go new file mode 100644 index 00000000000..fee19873f46 --- /dev/null +++ b/cmd/podman/main_linux.go @@ -0,0 +1,18 @@ +//go:build linux + +package main + +import ( + "github.com/sirupsen/logrus" + "go.podman.io/common/pkg/cgroups" +) + +func checkSupportedCgroups() { + unified, err := cgroups.IsCgroup2UnifiedMode() + if err != nil { + logrus.Fatalf("Error determining cgroups mode") + } + if !unified { + logrus.Fatalf("Cgroups v1 not supported") + } +} diff --git a/cmd/podman/main_non_linux.go b/cmd/podman/main_non_linux.go new file mode 100644 index 00000000000..bef14a364de --- /dev/null +++ b/cmd/podman/main_non_linux.go @@ -0,0 +1,15 @@ +//go:build windows || darwin || freebsd + +package main + +import ( + "github.com/sirupsen/logrus" + "go.podman.io/common/pkg/cgroups" +) + +func checkSupportedCgroups() { + unified, _ := cgroups.IsCgroup2UnifiedMode() + if !unified { + logrus.Debugln("Non-linux environment. Non-fatal cgroups check") + } +} diff --git a/go.mod b/go.mod index 505830e0b71..fe59c13ad56 100644 --- a/go.mod +++ b/go.mod @@ -55,7 +55,7 @@ require ( github.com/opencontainers/runtime-spec v1.2.1 github.com/opencontainers/runtime-tools v0.9.1-0.20250523060157-0ea5ed0382a2 github.com/opencontainers/selinux v1.12.0 - github.com/openshift/imagebuilder v1.2.16-0.20250828154754-e22ebd3ff511 + github.com/openshift/imagebuilder v1.2.17 github.com/rootless-containers/rootlesskit/v2 v2.3.5 github.com/shirou/gopsutil/v4 v4.25.9 github.com/sirupsen/logrus v1.9.3 @@ -66,8 +66,8 @@ require ( github.com/vishvananda/netlink v1.3.1 go.etcd.io/bbolt v1.4.3 go.podman.io/common v0.65.1-0.20251016162239-c4c5e00ad22d - go.podman.io/image/v5 v5.37.1-0.20251016133615-aa970d2c7532 - go.podman.io/storage v1.60.1-0.20251016133615-aa970d2c7532 + go.podman.io/image/v5 v5.38.0 + go.podman.io/storage v1.61.0 golang.org/x/crypto v0.43.0 golang.org/x/net v0.45.0 golang.org/x/sync v0.17.0 @@ -98,7 +98,7 @@ require ( github.com/containernetworking/cni v1.3.0 // indirect github.com/containers/common v0.62.2 // indirect github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect - github.com/containers/luksy v0.0.0-20250714213221-8fccf784694e // indirect + github.com/containers/luksy v0.0.0-20250910190358-2cf5bc928957 // indirect github.com/coreos/go-oidc/v3 v3.14.1 // indirect github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 // indirect @@ -110,7 +110,7 @@ require ( github.com/ebitengine/purego v0.9.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/fsouza/go-dockerclient v1.12.1 // indirect + github.com/fsouza/go-dockerclient v1.12.2 // indirect github.com/go-jose/go-jose/v4 v4.0.5 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -136,7 +136,7 @@ require ( github.com/mdlayher/socket v0.5.1 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect github.com/mistifyio/go-zfs/v3 v3.1.0 // indirect - github.com/moby/buildkit v0.23.2 // indirect + github.com/moby/buildkit v0.25.1 // indirect github.com/moby/go-archive v0.1.0 // indirect github.com/moby/patternmatcher v0.6.0 // indirect github.com/moby/sys/mountinfo v0.7.2 // indirect @@ -192,3 +192,7 @@ require ( gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect tags.cncf.io/container-device-interface/specs-go v1.0.0 // indirect ) + +replace go.podman.io/common => github.com/lsm5/container-libs/common v0.0.0-20251017191154-e63ca540eafe + +replace github.com/containers/buildah => github.com/lsm5/buildah v0.0.0-20251017145416-1c35ea0ae809 diff --git a/go.sum b/go.sum index a77c5fdf137..aeffdd0cb40 100644 --- a/go.sum +++ b/go.sum @@ -55,8 +55,6 @@ github.com/containernetworking/cni v1.3.0 h1:v6EpN8RznAZj9765HhXQrtXgX+ECGebEYEm github.com/containernetworking/cni v1.3.0/go.mod h1:Bs8glZjjFfGPHMw6hQu82RUgEPNGEaBb9KS5KtNMnJ4= github.com/containernetworking/plugins v1.8.0 h1:WjGbV/0UQyo8A4qBsAh6GaDAtu1hevxVxsEuqtBqUFk= github.com/containernetworking/plugins v1.8.0/go.mod h1:JG3BxoJifxxHBhG3hFyxyhid7JgRVBu/wtooGEvWf1c= -github.com/containers/buildah v1.41.1-0.20250829135344-3367a9bc2c9f h1:t2zdi9mHtJoGmRMXa3i+oD/7xlYHIgoA+/Jtd0Ysf6c= -github.com/containers/buildah v1.41.1-0.20250829135344-3367a9bc2c9f/go.mod h1:LtwfkfBed4dUOFTcBG+O+9Vcu5znw/PLYWDJ1mieHic= github.com/containers/common v0.62.2 h1:xO45OOoeq17EZMIDZoSyRqg7GXGcRHa9sXlrr75zH+U= github.com/containers/common v0.62.2/go.mod h1:veFiR9iq2j3CHXtB4YnPHuOkSRdhIQ3bAY8AFMP/5bE= github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg= @@ -67,8 +65,8 @@ github.com/containers/libhvee v0.10.1-0.20250829163521-178d10e67860 h1:YOhl3KCie github.com/containers/libhvee v0.10.1-0.20250829163521-178d10e67860/go.mod h1:/A6jL8HXzYB4aUQEjlyYImaQTgSw2jYZunSVCwqgaCI= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= -github.com/containers/luksy v0.0.0-20250714213221-8fccf784694e h1:nrNp2M6tTNGvLVrJpgqge9GwHgsWBGp2HBKg84BdVd8= -github.com/containers/luksy v0.0.0-20250714213221-8fccf784694e/go.mod h1:kPe8hxQEh1x1Uojxjr//MKkxK5x11sxDoY6rW905OL0= +github.com/containers/luksy v0.0.0-20250910190358-2cf5bc928957 h1:WxixhZ0typ8o668V0V7RVCZb3lNs58UF42RbwlQ4vdE= +github.com/containers/luksy v0.0.0-20250910190358-2cf5bc928957/go.mod h1:fGPsLPRi1etbHfe5o6sdx6ajsW810tI43uyF6ugmP/o= github.com/containers/ocicrypt v1.2.1 h1:0qIOTT9DoYwcKmxSt8QJt+VzMY18onl9jUXsxpVhSmM= github.com/containers/ocicrypt v1.2.1/go.mod h1:aD0AAqfMp0MtwqWgHM1bUwe1anx0VazI108CRrSKINQ= github.com/containers/psgo v1.9.1-0.20250826150930-4ae76f200c86 h1:bYj0TVlkRZtMJYd6SbFOi1gjUJDJmVsYCpJla3URD7Y= @@ -129,8 +127,8 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/fsouza/go-dockerclient v1.12.1 h1:FMoLq+Zhv9Oz/rFmu6JWkImfr6CBgZOPcL+bHW4gS0o= -github.com/fsouza/go-dockerclient v1.12.1/go.mod h1:OqsgJJcpCwqyM3JED7TdfM9QVWS5O7jSYwXxYKmOooY= +github.com/fsouza/go-dockerclient v1.12.2 h1:+pbP/SacoHfqaVZuiudvcdYGd9jzU7y9EcgoBOHivEI= +github.com/fsouza/go-dockerclient v1.12.2/go.mod h1:ZGCkAsnBGjnTRG9wV6QaICPJ5ig2KlaxTccDQy5WQ38= github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= @@ -235,6 +233,10 @@ github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec h1:2tTW6cDth2T github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec/go.mod h1:TmwEoGCwIti7BCeJ9hescZgRtatxRE+A72pCoPfmcfk= github.com/linuxkit/virtsock v0.0.0-20241009230534-cb6a20cc0422 h1:XvRuyDDRvi+UDxHN/M4MW4HxjmNVMmUKQj/+AbgsYgk= github.com/linuxkit/virtsock v0.0.0-20241009230534-cb6a20cc0422/go.mod h1:JLgfq4XMVbvfNlAXla/41lZnp21O72a/wWHGJefAvgQ= +github.com/lsm5/buildah v0.0.0-20251017145416-1c35ea0ae809 h1:Xl7p6J9gfYA7TX0Z7VTNygqpEq7MZdrLX+EhsUdUOPc= +github.com/lsm5/buildah v0.0.0-20251017145416-1c35ea0ae809/go.mod h1:DOj6mclvkxcijXOmZTybYPZpuDv5ZyqoyjZSwfs/ikk= +github.com/lsm5/container-libs/common v0.0.0-20251017191154-e63ca540eafe h1:3zW0BFHDhdhVqZzxLJ0/TqDDkDET+/MPAQZNlvcZLkY= +github.com/lsm5/container-libs/common v0.0.0-20251017191154-e63ca540eafe/go.mod h1:aNd2a0S7pY+fx1X5kpQYuF4hbwLU8ZOccuVrhu7h1Xc= github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMDtTVdcGu0B1GmmC7QJKiCCjyTAWQy0= github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= @@ -263,8 +265,8 @@ github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mistifyio/go-zfs/v3 v3.1.0 h1:FZaylcg0hjUp27i23VcJJQiuBeAZjrC8lPqCGM1CopY= github.com/mistifyio/go-zfs/v3 v3.1.0/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k= -github.com/moby/buildkit v0.23.2 h1:gt/dkfcpgTXKx+B9I310kV767hhVqTvEyxGgI3mqsGQ= -github.com/moby/buildkit v0.23.2/go.mod h1:iEjAfPQKIuO+8y6OcInInvzqTMiKMbb2RdJz1K/95a0= +github.com/moby/buildkit v0.25.1 h1:j7IlVkeNbEo+ZLoxdudYCHpmTsbwKvhgc/6UJ/mY/o8= +github.com/moby/buildkit v0.25.1/go.mod h1:phM8sdqnvgK2y1dPDnbwI6veUCXHOZ6KFSl6E164tkc= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ= @@ -314,8 +316,8 @@ github.com/opencontainers/runtime-tools v0.9.1-0.20250523060157-0ea5ed0382a2 h1: github.com/opencontainers/runtime-tools v0.9.1-0.20250523060157-0ea5ed0382a2/go.mod h1:MXdPzqAA8pHC58USHqNCSjyLnRQ6D+NjbpP+02Z1U/0= github.com/opencontainers/selinux v1.12.0 h1:6n5JV4Cf+4y0KNXW48TLj5DwfXpvWlxXplUkdTrmPb8= github.com/opencontainers/selinux v1.12.0/go.mod h1:BTPX+bjVbWGXw7ZZWUbdENt8w0htPSrlgOOysQaU62U= -github.com/openshift/imagebuilder v1.2.16-0.20250828154754-e22ebd3ff511 h1:8pU6rEt+HyVdXlszfbWIwUDf8THLXvjXX5n+5EkxlW8= -github.com/openshift/imagebuilder v1.2.16-0.20250828154754-e22ebd3ff511/go.mod h1:I9FlC4LVo0z/8GM8wdWVhxmw3tUVNM6tiwb8tRv4jvQ= +github.com/openshift/imagebuilder v1.2.17 h1:xusHiBvK7PpBsEeMGTg61Zx5kSajybjUAbBzVEJKH6g= +github.com/openshift/imagebuilder v1.2.17/go.mod h1:I9FlC4LVo0z/8GM8wdWVhxmw3tUVNM6tiwb8tRv4jvQ= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -471,12 +473,10 @@ go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKr go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= -go.podman.io/common v0.65.1-0.20251016162239-c4c5e00ad22d h1:xk2iM/F/6UTuPD3+MNOqZvju0xYQ14IpvegxQ1sC464= -go.podman.io/common v0.65.1-0.20251016162239-c4c5e00ad22d/go.mod h1:kv0yXx/yrT60lUcVb86hezMGz/lXmyx3epvdFlM9du4= -go.podman.io/image/v5 v5.37.1-0.20251016133615-aa970d2c7532 h1:J7qB0n2DLY9hLCS9z3eubDuBrl6GOiz1iVMufhTRs3k= -go.podman.io/image/v5 v5.37.1-0.20251016133615-aa970d2c7532/go.mod h1:rzI7vFUroTWKtAAVuYCoT2wy8LbcepZgEuhzzRzfui4= -go.podman.io/storage v1.60.1-0.20251016133615-aa970d2c7532 h1:3+RVXZET/LnyhXdQnpIVvjuNs04Jz3IJtC9T++pwqpI= -go.podman.io/storage v1.60.1-0.20251016133615-aa970d2c7532/go.mod h1:A3UBK0XypjNZ6pghRhuxg62+2NIm5lcUGv/7XyMhMUI= +go.podman.io/image/v5 v5.38.0 h1:aUKrCANkPvze1bnhLJsaubcfz0d9v/bSDLnwsXJm6G4= +go.podman.io/image/v5 v5.38.0/go.mod h1:hSIoIUzgBnmc4DjoIdzk63aloqVbD7QXDMkSE/cvG90= +go.podman.io/storage v1.61.0 h1:5hD/oyRYt1f1gxgvect+8syZBQhGhV28dCw2+CZpx0Q= +go.podman.io/storage v1.61.0/go.mod h1:A3UBK0XypjNZ6pghRhuxg62+2NIm5lcUGv/7XyMhMUI= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 268663da796..dce601119a1 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -1361,7 +1361,7 @@ func (c *Container) waitForHealthy(ctx context.Context) error { } // Whether a container should use `all` when stopping -func (c *Container) stopWithAll() (bool, error) { +func (c *Container) stopWithAll() bool { // If the container is running in a PID Namespace, then killing the // primary pid is enough to kill the container. If it is not running in // a pid namespace then the OCI Runtime needs to kill ALL processes in @@ -1373,29 +1373,17 @@ func (c *Container) stopWithAll() (bool, error) { if all { if c.config.NoCgroups { all = false - } else if rootless.IsRootless() { - // Only do this check if we need to - unified, err := cgroups.IsCgroup2UnifiedMode() - if err != nil { - return false, err - } - if !unified { - all = false - } } } - return all, nil + return all } // Internal, non-locking function to stop container func (c *Container) stop(timeout uint) error { logrus.Debugf("Stopping ctr %s (timeout %d)", c.ID(), timeout) - all, err := c.stopWithAll() - if err != nil { - return err - } + all := c.stopWithAll() // OK, the following code looks a bit weird but we have to make sure we can stop // containers with the restart policy always, to do this we have to set @@ -1502,7 +1490,7 @@ func (c *Container) waitForConmonToExitAndSave() error { // could open a pidfd on container PID1 before // this to get the real exit code... But I'm not // that dedicated. - all, _ := c.stopWithAll() + all := c.stopWithAll() if err := c.ociRuntime.StopContainer(c, 0, all); err != nil { logrus.Errorf("Error stopping container %s after Conmon exited prematurely: %v", c.ID(), err) } diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index a0054ebed37..fea5cc115fe 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -3,7 +3,6 @@ package libpod import ( - "errors" "fmt" "io/fs" "os" @@ -30,9 +29,7 @@ import ( "golang.org/x/sys/unix" ) -var ( - bindOptions = []string{define.TypeBind, "rprivate"} -) +var bindOptions = []string{define.TypeBind, "rprivate"} func (c *Container) mountSHM(shmOptions string) error { contextType := "context" @@ -267,11 +264,6 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro g.AddMount(tmpfsMnt) } - unified, err := cgroups.IsCgroup2UnifiedMode() - if err != nil { - return err - } - hasCgroupNs := false for _, ns := range c.config.Spec.Linux.Namespaces { if ns.Type == spec.CgroupNamespace { @@ -280,69 +272,25 @@ func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) erro } } - if unified { - g.RemoveMount("/sys/fs/cgroup") + g.RemoveMount("/sys/fs/cgroup") - var systemdMnt spec.Mount - if hasCgroupNs { - systemdMnt = spec.Mount{ - Destination: "/sys/fs/cgroup", - Type: "cgroup", - Source: "cgroup", - Options: []string{"private", "rw"}, - } - } else { - systemdMnt = spec.Mount{ - Destination: "/sys/fs/cgroup", - Type: define.TypeBind, - Source: "/sys/fs/cgroup", - Options: []string{define.TypeBind, "private", "rw"}, - } + var systemdMnt spec.Mount + if hasCgroupNs { + systemdMnt = spec.Mount{ + Destination: "/sys/fs/cgroup", + Type: "cgroup", + Source: "cgroup", + Options: []string{"private", "rw"}, } - g.AddMount(systemdMnt) } else { - hasSystemdMount := MountExists(mounts, "/sys/fs/cgroup/systemd") - if hasCgroupNs && !hasSystemdMount { - return errors.New("cgroup namespace is not supported with cgroup v1 and systemd mode") - } - mountOptions := []string{define.TypeBind, "rprivate"} - - if !hasSystemdMount { - skipMount := hasSystemdMount - var statfs unix.Statfs_t - if err := unix.Statfs("/sys/fs/cgroup/systemd", &statfs); err != nil { - if errors.Is(err, os.ErrNotExist) { - // If the mount is missing on the host, we cannot bind mount it so - // just skip it. - skipMount = true - } - mountOptions = append(mountOptions, "nodev", "noexec", "nosuid") - } else { - if statfs.Flags&unix.MS_NODEV == unix.MS_NODEV { - mountOptions = append(mountOptions, "nodev") - } - if statfs.Flags&unix.MS_NOEXEC == unix.MS_NOEXEC { - mountOptions = append(mountOptions, "noexec") - } - if statfs.Flags&unix.MS_NOSUID == unix.MS_NOSUID { - mountOptions = append(mountOptions, "nosuid") - } - if statfs.Flags&unix.MS_RDONLY == unix.MS_RDONLY { - mountOptions = append(mountOptions, "ro") - } - } - if !skipMount { - systemdMnt := spec.Mount{ - Destination: "/sys/fs/cgroup/systemd", - Type: define.TypeBind, - Source: "/sys/fs/cgroup/systemd", - Options: mountOptions, - } - g.AddMount(systemdMnt) - g.AddLinuxMaskedPaths("/sys/fs/cgroup/systemd/release_agent") - } + systemdMnt = spec.Mount{ + Destination: "/sys/fs/cgroup", + Type: define.TypeBind, + Source: "/sys/fs/cgroup", + Options: []string{define.TypeBind, "private", "rw"}, } } + g.AddMount(systemdMnt) return nil } @@ -385,16 +333,12 @@ func isRootlessCgroupSet(cgroup string) bool { } func (c *Container) expectPodCgroup() (bool, error) { - unified, err := cgroups.IsCgroup2UnifiedMode() - if err != nil { - return false, err - } cgroupManager := c.CgroupManager() switch { case c.config.NoCgroups: return false, nil case cgroupManager == config.SystemdCgroupsManager: - return !rootless.IsRootless() || unified, nil + return true, nil case cgroupManager == config.CgroupfsCgroupsManager: return !rootless.IsRootless(), nil default: @@ -404,10 +348,6 @@ func (c *Container) expectPodCgroup() (bool, error) { // Get cgroup path in a format suitable for the OCI spec func (c *Container) getOCICgroupPath() (string, error) { - unified, err := cgroups.IsCgroup2UnifiedMode() - if err != nil { - return "", err - } cgroupManager := c.CgroupManager() switch { case c.config.NoCgroups: @@ -425,7 +365,7 @@ func (c *Container) getOCICgroupPath() (string, error) { systemdCgroups := fmt.Sprintf("%s:libpod:%s", path.Base(c.config.CgroupParent), c.ID()) logrus.Debugf("Setting Cgroups for container %s to %s", c.ID(), systemdCgroups) return systemdCgroups, nil - case (rootless.IsRootless() && (cgroupManager == config.CgroupfsCgroupsManager || !unified)): + case (rootless.IsRootless() && (cgroupManager == config.CgroupfsCgroupsManager)): if c.config.CgroupParent == "" || !isRootlessCgroupSet(c.config.CgroupParent) { return "", nil } diff --git a/libpod/info_linux.go b/libpod/info_linux.go index 2ab534070b2..edad644d2b8 100644 --- a/libpod/info_linux.go +++ b/libpod/info_linux.go @@ -30,14 +30,8 @@ func (r *Runtime) setPlatformHostInfo(info *define.HostInfo) error { return fmt.Errorf("getting Seccomp profile path: %w", err) } - // Cgroups version - unified, err := cgroups.IsCgroup2UnifiedMode() - if err != nil { - return fmt.Errorf("reading cgroups mode: %w", err) - } - // Get Map of all available controllers - availableControllers, err := cgroups.AvailableControllers(nil, unified) + availableControllers, err := cgroups.AvailableControllers() if err != nil { return fmt.Errorf("getting available cgroup controllers: %w", err) } @@ -55,12 +49,6 @@ func (r *Runtime) setPlatformHostInfo(info *define.HostInfo) error { } info.Slirp4NetNS = define.SlirpInfo{} - cgroupVersion := "v1" - if unified { - cgroupVersion = "v2" - } - info.CgroupsVersion = cgroupVersion - slirp4netnsPath := r.config.Engine.NetworkCmdPath if slirp4netnsPath == "" { slirp4netnsPath, _ = r.config.FindHelperBinary(slirp4netns.BinaryName, true) diff --git a/libpod/runtime_linux.go b/libpod/runtime_linux.go index 07f9db5e2ac..746070e6f57 100644 --- a/libpod/runtime_linux.go +++ b/libpod/runtime_linux.go @@ -12,21 +12,10 @@ import ( "github.com/containers/podman/v5/pkg/rootless" "github.com/containers/podman/v5/pkg/systemd" "github.com/sirupsen/logrus" - "go.podman.io/common/pkg/cgroups" ) func checkCgroups2UnifiedMode(runtime *Runtime) { - unified, _ := cgroups.IsCgroup2UnifiedMode() - // DELETE ON RHEL9 - if !unified { - _, ok := os.LookupEnv("PODMAN_IGNORE_CGROUPSV1_WARNING") - if !ok { - logrus.Warn("Using cgroups-v1 which is deprecated in favor of cgroups-v2 with Podman v5 and will be removed in a future version. Set environment variable `PODMAN_IGNORE_CGROUPSV1_WARNING` to hide this warning.") - } - } - // DELETE ON RHEL9 - - if unified && rootless.IsRootless() && !systemd.IsSystemdSessionValid(rootless.GetRootlessUID()) { + if rootless.IsRootless() && !systemd.IsSystemdSessionValid(rootless.GetRootlessUID()) { // If user is rootless and XDG_RUNTIME_DIR is found, podman will not proceed with /tmp directory // it will try to use existing XDG_RUNTIME_DIR // if current user has no write access to XDG_RUNTIME_DIR we will fail later diff --git a/libpod/runtime_pod_linux.go b/libpod/runtime_pod_linux.go index 0dec268d445..ff750c1337b 100644 --- a/libpod/runtime_pod_linux.go +++ b/libpod/runtime_pod_linux.go @@ -122,7 +122,7 @@ func (p *Pod) removePodCgroup() error { // hard - instead, just log errors. conmonCgroupPath := filepath.Join(p.state.CgroupPath, "conmon") conmonCgroup, err := cgroups.Load(conmonCgroupPath) - if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless { + if err != nil && err != cgroups.ErrCgroupDeleted { return fmt.Errorf("retrieving pod %s conmon cgroup: %w", p.ID(), err) } if err == nil { @@ -131,7 +131,7 @@ func (p *Pod) removePodCgroup() error { } } cgroup, err := cgroups.Load(p.state.CgroupPath) - if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless { + if err != nil && err != cgroups.ErrCgroupDeleted { return fmt.Errorf("retrieving pod %s cgroup: %w", p.ID(), err) } if err == nil { diff --git a/pkg/domain/infra/runtime_libpod.go b/pkg/domain/infra/runtime_libpod.go index 34cea76b2fd..9a4a08b043d 100644 --- a/pkg/domain/infra/runtime_libpod.go +++ b/pkg/domain/infra/runtime_libpod.go @@ -20,7 +20,6 @@ import ( "github.com/containers/podman/v5/pkg/util" "github.com/sirupsen/logrus" flag "github.com/spf13/pflag" - "go.podman.io/common/pkg/cgroups" "go.podman.io/storage/pkg/idtools" "go.podman.io/storage/types" ) @@ -182,14 +181,6 @@ func getRuntime(ctx context.Context, fs *flag.FlagSet, opts *engineOpts) (*libpo if fs.Changed("cgroup-manager") { options = append(options, libpod.WithCgroupManager(cfg.ContainersConf.Engine.CgroupManager)) - } else { - unified, err := cgroups.IsCgroup2UnifiedMode() - if err != nil { - return nil, err - } - if rootless.IsRootless() && !unified { - options = append(options, libpod.WithCgroupManager("cgroupfs")) - } } // TODO flag to set libpod static dir? diff --git a/pkg/specgen/generate/validate_linux.go b/pkg/specgen/generate/validate_linux.go index 0fa8a915228..658e45dd2de 100644 --- a/pkg/specgen/generate/validate_linux.go +++ b/pkg/specgen/generate/validate_linux.go @@ -3,171 +3,14 @@ package generate import ( - "errors" - "fmt" "os" "path/filepath" - "reflect" - "github.com/containers/podman/v5/pkg/rootless" "github.com/containers/podman/v5/pkg/specgen" - "github.com/opencontainers/runtime-spec/specs-go" "go.podman.io/common/pkg/cgroups" - "go.podman.io/common/pkg/sysinfo" "go.podman.io/storage/pkg/fileutils" ) -// Verify resource limits are sanely set when running on cgroup v1. -func verifyContainerResourcesCgroupV1(s *specgen.SpecGenerator) ([]string, error) { - warnings := []string{} - - sysInfo := sysinfo.New(true) - - // If ResourceLimits is nil, return without warning - resourceNil := &specgen.SpecGenerator{} - resourceNil.ResourceLimits = &specs.LinuxResources{} - if s.ResourceLimits == nil || reflect.DeepEqual(s.ResourceLimits, resourceNil.ResourceLimits) { - return nil, nil - } - - // Cgroups V1 rootless system does not support Resource limits - if rootless.IsRootless() { - s.ResourceLimits = nil - return []string{"Resource limits are not supported and ignored on cgroups V1 rootless systems"}, nil - } - - if s.ResourceLimits.Unified != nil { - return nil, errors.New("cannot use --cgroup-conf without cgroup v2") - } - - // Memory checks - if s.ResourceLimits.Memory != nil { - memory := s.ResourceLimits.Memory - if memory.Limit != nil && !sysInfo.MemoryLimit { - warnings = append(warnings, "Your kernel does not support memory limit capabilities or the cgroup is not mounted. Limitation discarded.") - memory.Limit = nil - memory.Swap = nil - } - if memory.Limit != nil && memory.Swap != nil && !sysInfo.SwapLimit { - warnings = append(warnings, "Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap.") - memory.Swap = nil - } - if memory.Limit != nil && memory.Swap != nil && *memory.Swap < *memory.Limit { - return warnings, errors.New("minimum memoryswap limit should be larger than memory limit, see usage") - } - if memory.Limit == nil && memory.Swap != nil { - return warnings, errors.New("you should always set a memory limit when using a memoryswap limit, see usage") - } - if memory.Swappiness != nil { - if !sysInfo.MemorySwappiness { - warnings = append(warnings, "Your kernel does not support memory swappiness capabilities, or the cgroup is not mounted. Memory swappiness discarded.") - memory.Swappiness = nil - } else if *memory.Swappiness > 100 { - return warnings, fmt.Errorf("invalid value: %v, valid memory swappiness range is 0-100", *memory.Swappiness) - } - } - if memory.Reservation != nil && !sysInfo.MemoryReservation { - warnings = append(warnings, "Your kernel does not support memory soft limit capabilities or the cgroup is not mounted. Limitation discarded.") - memory.Reservation = nil - } - if memory.Limit != nil && memory.Reservation != nil && *memory.Limit < *memory.Reservation { - return warnings, errors.New("minimum memory limit cannot be less than memory reservation limit, see usage") - } - if memory.DisableOOMKiller != nil && *memory.DisableOOMKiller && !sysInfo.OomKillDisable { - warnings = append(warnings, "Your kernel does not support OomKillDisable. OomKillDisable discarded.") - memory.DisableOOMKiller = nil - } - } - - // Pids checks - if s.ResourceLimits.Pids != nil { - // TODO: Should this be 0, or checking that ResourceLimits.Pids - // is set at all? - if s.ResourceLimits.Pids.Limit >= 0 && !sysInfo.PidsLimit { - warnings = append(warnings, "Your kernel does not support pids limit capabilities or the cgroup is not mounted. PIDs limit discarded.") - s.ResourceLimits.Pids = nil - } - } - - // CPU checks - if s.ResourceLimits.CPU != nil { - cpu := s.ResourceLimits.CPU - if cpu.Shares != nil && !sysInfo.CPUShares { - warnings = append(warnings, "Your kernel does not support CPU shares or the cgroup is not mounted. Shares discarded.") - cpu.Shares = nil - } - if cpu.Period != nil && !sysInfo.CPUCfsPeriod { - warnings = append(warnings, "Your kernel does not support CPU cfs period or the cgroup is not mounted. Period discarded.") - cpu.Period = nil - } - if cpu.Period != nil && (*cpu.Period < 1000 || *cpu.Period > 1000000) { - return warnings, errors.New("CPU cfs period cannot be less than 1ms (i.e. 1000) or larger than 1s (i.e. 1000000)") - } - if cpu.Quota != nil && !sysInfo.CPUCfsQuota { - warnings = append(warnings, "Your kernel does not support CPU cfs quota or the cgroup is not mounted. Quota discarded.") - cpu.Quota = nil - } - if cpu.Quota != nil && *cpu.Quota < 1000 { - return warnings, errors.New("CPU cfs quota cannot be less than 1ms (i.e. 1000)") - } - if (cpu.Cpus != "" || cpu.Mems != "") && !sysInfo.Cpuset { - warnings = append(warnings, "Your kernel does not support cpuset or the cgroup is not mounted. CPUset discarded.") - cpu.Cpus = "" - cpu.Mems = "" - } - - cpusAvailable, err := sysInfo.IsCpusetCpusAvailable(cpu.Cpus) - if err != nil { - return warnings, fmt.Errorf("invalid value %s for cpuset cpus", cpu.Cpus) - } - if !cpusAvailable { - return warnings, fmt.Errorf("requested CPUs are not available - requested %s, available: %s", cpu.Cpus, sysInfo.Cpus) - } - - memsAvailable, err := sysInfo.IsCpusetMemsAvailable(cpu.Mems) - if err != nil { - return warnings, fmt.Errorf("invalid value %s for cpuset mems", cpu.Mems) - } - if !memsAvailable { - return warnings, fmt.Errorf("requested memory nodes are not available - requested %s, available: %s", cpu.Mems, sysInfo.Mems) - } - } - - // Blkio checks - if s.ResourceLimits.BlockIO != nil { - blkio := s.ResourceLimits.BlockIO - if blkio.Weight != nil && !sysInfo.BlkioWeight { - warnings = append(warnings, "Your kernel does not support Block I/O weight or the cgroup is not mounted. Weight discarded.") - blkio.Weight = nil - } - if blkio.Weight != nil && (*blkio.Weight > 1000 || *blkio.Weight < 10) { - return warnings, errors.New("range of blkio weight is from 10 to 1000") - } - if len(blkio.WeightDevice) > 0 && !sysInfo.BlkioWeightDevice { - warnings = append(warnings, "Your kernel does not support Block I/O weight_device or the cgroup is not mounted. Weight-device discarded.") - blkio.WeightDevice = nil - } - if len(blkio.ThrottleReadBpsDevice) > 0 && !sysInfo.BlkioReadBpsDevice { - warnings = append(warnings, "Your kernel does not support BPS Block I/O read limit or the cgroup is not mounted. Block I/O BPS read limit discarded") - blkio.ThrottleReadBpsDevice = nil - } - if len(blkio.ThrottleWriteBpsDevice) > 0 && !sysInfo.BlkioWriteBpsDevice { - warnings = append(warnings, "Your kernel does not support BPS Block I/O write limit or the cgroup is not mounted. Block I/O BPS write limit discarded.") - blkio.ThrottleWriteBpsDevice = nil - } - if len(blkio.ThrottleReadIOPSDevice) > 0 && !sysInfo.BlkioReadIOpsDevice { - warnings = append(warnings, "Your kernel does not support IOPS Block read limit or the cgroup is not mounted. Block I/O IOPS read limit discarded.") - blkio.ThrottleReadIOPSDevice = nil - } - if len(blkio.ThrottleWriteIOPSDevice) > 0 && !sysInfo.BlkioWriteIOpsDevice { - warnings = append(warnings, "Your kernel does not support IOPS Block I/O write limit or the cgroup is not mounted. Block I/O IOPS write limit discarded.") - blkio.ThrottleWriteIOPSDevice = nil - } - } - - return warnings, nil -} - // Verify resource limits are sanely set when running on cgroup v2. func verifyContainerResourcesCgroupV2(s *specgen.SpecGenerator) ([]string, error) { warnings := []string{} @@ -225,12 +68,9 @@ func verifyContainerResourcesCgroupV2(s *specgen.SpecGenerator) ([]string, error // Verify resource limits are sanely set, removing any limits that are not // possible with the current cgroups config. func verifyContainerResources(s *specgen.SpecGenerator) ([]string, error) { - cgroup2, err := cgroups.IsCgroup2UnifiedMode() + _, err := cgroups.IsCgroup2UnifiedMode() if err != nil { return []string{}, err } - if cgroup2 { - return verifyContainerResourcesCgroupV2(s) - } - return verifyContainerResourcesCgroupV1(s) + return verifyContainerResourcesCgroupV2(s) } diff --git a/vendor/github.com/containers/buildah/.cirrus.yml b/vendor/github.com/containers/buildah/.cirrus.yml index 832abc07d6f..5debb3203d1 100644 --- a/vendor/github.com/containers/buildah/.cirrus.yml +++ b/vendor/github.com/containers/buildah/.cirrus.yml @@ -35,7 +35,7 @@ env: DEBIAN_NAME: "debian-13" # Image identifiers - IMAGE_SUFFIX: "c20250422t130822z-f42f41d13" + IMAGE_SUFFIX: "c20250910t092246z-f42f41d13" FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}" PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}" DEBIAN_CACHE_IMAGE_NAME: "debian-${IMAGE_SUFFIX}" @@ -124,7 +124,7 @@ vendor_task: # Runs within Cirrus's "community cluster" container: - image: docker.io/library/golang:1.23.3 + image: docker.io/library/golang:1.24.2 cpu: 1 memory: 1 diff --git a/vendor/github.com/containers/buildah/buildah.go b/vendor/github.com/containers/buildah/buildah.go index 9de72ca8dc5..27d67b63316 100644 --- a/vendor/github.com/containers/buildah/buildah.go +++ b/vendor/github.com/containers/buildah/buildah.go @@ -132,8 +132,8 @@ type Builder struct { ImageHistoryComment string `json:"history-comment,omitempty"` // Image metadata and runtime settings, in multiple formats. - OCIv1 v1.Image `json:"ociv1,omitempty"` - Docker docker.V2Image `json:"docker,omitempty"` + OCIv1 v1.Image `json:"ociv1"` + Docker docker.V2Image `json:"docker"` // DefaultMountsFilePath is the file path holding the mounts to be mounted in "host-path:container-path" format. DefaultMountsFilePath string `json:"defaultMountsFilePath,omitempty"` diff --git a/vendor/github.com/containers/buildah/chroot/run_common.go b/vendor/github.com/containers/buildah/chroot/run_common.go index 0e50cf0e8e0..fbd0689f6af 100644 --- a/vendor/github.com/containers/buildah/chroot/run_common.go +++ b/vendor/github.com/containers/buildah/chroot/run_common.go @@ -12,6 +12,7 @@ import ( "os/signal" "path/filepath" "runtime" + "slices" "strconv" "strings" "sync" @@ -743,6 +744,15 @@ func runUsingChrootExecMain() { os.Exit(1) } + // Set $PATH to the value for the container, so that when args[0] is not an absolute path, + // exec.Command() can find it using exec.LookPath(). + for _, env := range slices.Backward(options.Spec.Process.Env) { + if val, ok := strings.CutPrefix(env, "PATH="); ok { + os.Setenv("PATH", val) + break + } + } + // Actually run the specified command. cmd := exec.Command(args[0], args[1:]...) setPdeathsig(cmd) diff --git a/vendor/github.com/containers/buildah/commit.go b/vendor/github.com/containers/buildah/commit.go index 8a053cb4e0e..1ae6c012864 100644 --- a/vendor/github.com/containers/buildah/commit.go +++ b/vendor/github.com/containers/buildah/commit.go @@ -531,6 +531,16 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options if err != nil { return imgID, nil, "", fmt.Errorf("computing digest of manifest of new image %q: %w", transports.ImageName(dest), err) } + if imgID == "" { + parsedManifest, err := manifest.FromBlob(manifestBytes, manifest.GuessMIMEType(manifestBytes)) + if err != nil { + return imgID, nil, "", fmt.Errorf("parsing written manifest to determine the image's ID: %w", err) + } + configInfo := parsedManifest.ConfigInfo() + if configInfo.Size > 2 && configInfo.Digest.Validate() == nil { // don't be returning a digest of "" or "{}" + imgID = configInfo.Digest.Encoded() + } + } var ref reference.Canonical if name := dest.DockerReference(); name != nil { diff --git a/vendor/github.com/containers/buildah/copier/copier.go b/vendor/github.com/containers/buildah/copier/copier.go index 6ffe52d86f6..9aa662cb68b 100644 --- a/vendor/github.com/containers/buildah/copier/copier.go +++ b/vendor/github.com/containers/buildah/copier/copier.go @@ -162,13 +162,13 @@ type request struct { preservedDirectory string Globs []string `json:",omitempty"` // used by stat, get preservedGlobs []string - StatOptions StatOptions `json:",omitempty"` - GetOptions GetOptions `json:",omitempty"` - PutOptions PutOptions `json:",omitempty"` - MkdirOptions MkdirOptions `json:",omitempty"` - RemoveOptions RemoveOptions `json:",omitempty"` - EnsureOptions EnsureOptions `json:",omitempty"` - ConditionalRemoveOptions ConditionalRemoveOptions `json:",omitempty"` + StatOptions StatOptions + GetOptions GetOptions + PutOptions PutOptions + MkdirOptions MkdirOptions + RemoveOptions RemoveOptions + EnsureOptions EnsureOptions + ConditionalRemoveOptions ConditionalRemoveOptions } func (req *request) Excludes() []string { @@ -248,15 +248,15 @@ func (req *request) GIDMap() []idtools.IDMap { // Response encodes a single response. type response struct { - Error string `json:",omitempty"` - Stat statResponse `json:",omitempty"` - Eval evalResponse `json:",omitempty"` - Get getResponse `json:",omitempty"` - Put putResponse `json:",omitempty"` - Mkdir mkdirResponse `json:",omitempty"` - Remove removeResponse `json:",omitempty"` - Ensure ensureResponse `json:",omitempty"` - ConditionalRemove conditionalRemoveResponse `json:",omitempty"` + Error string `json:",omitempty"` + Stat statResponse + Eval evalResponse + Get getResponse + Put putResponse + Mkdir mkdirResponse + Remove removeResponse + Ensure ensureResponse + ConditionalRemove conditionalRemoveResponse } // statResponse encodes a response for a single Stat request. @@ -801,7 +801,7 @@ func copierWithSubprocess(bulkReader io.Reader, bulkWriter io.Writer, req reques } loggedOutput := strings.TrimSuffix(errorBuffer.String(), "\n") if len(loggedOutput) > 0 { - for _, output := range strings.Split(loggedOutput, "\n") { + for output := range strings.SplitSeq(loggedOutput, "\n") { logrus.Debug(output) } } @@ -1588,8 +1588,8 @@ func mapWithPrefixedKeysWithoutKeyPrefix[K any](m map[string]K, p string) map[st } cloned := make(map[string]K, len(m)) for k, v := range m { - if strings.HasPrefix(k, p) { - cloned[strings.TrimPrefix(k, p)] = v + if after, ok := strings.CutPrefix(k, p); ok { + cloned[after] = v } } return cloned @@ -1819,7 +1819,7 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM return fmt.Errorf("%q is not a subdirectory of %q: %w", directory, req.Root, err) } subdir := "" - for _, component := range strings.Split(rel, string(os.PathSeparator)) { + for component := range strings.SplitSeq(rel, string(os.PathSeparator)) { subdir = filepath.Join(subdir, component) path := filepath.Join(req.Root, subdir) if err := os.Mkdir(path, 0o700); err == nil { @@ -2187,7 +2187,7 @@ func copierHandlerPut(bulkReader io.Reader, req request, idMappings *idtools.IDM } func copierHandlerMkdir(req request, idMappings *idtools.IDMappings) (*response, func() error, error) { - errorResponse := func(fmtspec string, args ...any) (*response, func() error, error) { + errorResponse := func(fmtspec string, args ...any) (*response, func() error, error) { //nolint:unparam return &response{Error: fmt.Sprintf(fmtspec, args...), Mkdir: mkdirResponse{}}, nil, nil } dirUID, dirGID := 0, 0 @@ -2219,7 +2219,7 @@ func copierHandlerMkdir(req request, idMappings *idtools.IDMappings) (*response, subdir := "" var created []string - for _, component := range strings.Split(rel, string(os.PathSeparator)) { + for component := range strings.SplitSeq(rel, string(os.PathSeparator)) { subdir = filepath.Join(subdir, component) path := filepath.Join(req.Root, subdir) if err := os.Mkdir(path, 0o700); err == nil { diff --git a/vendor/github.com/containers/buildah/copier/xattrs.go b/vendor/github.com/containers/buildah/copier/xattrs.go index 2e4b944adbf..040a6603e30 100644 --- a/vendor/github.com/containers/buildah/copier/xattrs.go +++ b/vendor/github.com/containers/buildah/copier/xattrs.go @@ -21,6 +21,7 @@ const ( var ( relevantAttributes = []string{"security.capability", imaXattr, "user.*"} // the attributes that we preserve - we discard others + irrelevantAttributes = []string{"user.overlay.*"} // the attributes that we discard, even from the relevantAttributes list initialXattrListSize = 64 * 1024 initialXattrValueSize = 64 * 1024 ) @@ -33,6 +34,13 @@ func isRelevantXattr(attribute string) bool { if err != nil || !matched { continue } + for _, irrelevant := range irrelevantAttributes { + matched, err := filepath.Match(irrelevant, attribute) + if err != nil || !matched { + continue + } + return false + } return true } return false @@ -65,7 +73,7 @@ func Lgetxattrs(path string) (map[string]string, error) { return nil, fmt.Errorf("unable to read list of attributes for %q: size would have been too big", path) } m := make(map[string]string) - for _, attribute := range strings.Split(string(list), string('\000')) { + for attribute := range strings.SplitSeq(string(list), string('\000')) { if isRelevantXattr(attribute) { attributeSize := initialXattrValueSize var attributeValue []byte diff --git a/vendor/github.com/containers/buildah/docker/types.go b/vendor/github.com/containers/buildah/docker/types.go index 997698709d4..352ae4799f4 100644 --- a/vendor/github.com/containers/buildah/docker/types.go +++ b/vendor/github.com/containers/buildah/docker/types.go @@ -124,7 +124,7 @@ type V1Compatibility struct { Created time.Time `json:"created"` ContainerConfig struct { Cmd []string - } `json:"container_config,omitempty"` + } `json:"container_config"` Author string `json:"author,omitempty"` ThrowAway bool `json:"throwaway,omitempty"` } @@ -143,7 +143,7 @@ type V1Image struct { // Container is the id of the container used to commit Container string `json:"container,omitempty"` // ContainerConfig is the configuration of the container that is committed into the image - ContainerConfig Config `json:"container_config,omitempty"` + ContainerConfig Config `json:"container_config"` // DockerVersion specifies the version of Docker that was used to build the image DockerVersion string `json:"docker_version,omitempty"` // Author is the name of the author that was specified when committing the image diff --git a/vendor/github.com/containers/buildah/imagebuildah/executor.go b/vendor/github.com/containers/buildah/imagebuildah/executor.go index 904849a9141..9f4c707df0c 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/executor.go +++ b/vendor/github.com/containers/buildah/imagebuildah/executor.go @@ -836,12 +836,12 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image } case "ADD", "COPY": for _, flag := range child.Flags { // flags for this instruction - if strings.HasPrefix(flag, "--from=") { + if after, ok := strings.CutPrefix(flag, "--from="); ok { // TODO: this didn't undergo variable and // arg expansion, so if the previous stage // was named using argument values, we might // not record the right value here. - rootfs := strings.TrimPrefix(flag, "--from=") + rootfs := after b.rootfsMap[rootfs] = struct{}{} logrus.Debugf("rootfs needed for COPY in stage %d: %q", stageIndex, rootfs) // Populate dependency tree and check @@ -885,8 +885,8 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image // dependency calculation. if strings.HasPrefix(flag, "--mount=") && strings.Contains(flag, "from") { mountFlags := strings.TrimPrefix(flag, "--mount=") - fields := strings.Split(mountFlags, ",") - for _, field := range fields { + fields := strings.SplitSeq(mountFlags, ",") + for field := range fields { if mountFrom, hasFrom := strings.CutPrefix(field, "from="); hasFrom { // Check if this base is a stage if yes // add base to current stage's dependency tree @@ -1086,7 +1086,11 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image } logrus.Debugf("printing final image id %q", imageID) if b.iidfile != "" { - if err = os.WriteFile(b.iidfile, []byte("sha256:"+imageID), 0o644); err != nil { + iid := imageID + if iid != "" { + iid = "sha256:" + iid // only prepend a digest algorithm name if we actually got a value back + } + if err = os.WriteFile(b.iidfile, []byte(iid), 0o644); err != nil { return imageID, ref, fmt.Errorf("failed to write image ID to file %q: %w", b.iidfile, err) } } else { diff --git a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go index 00a96bfbcdd..7a57d80effb 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go +++ b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go @@ -1913,7 +1913,7 @@ func (s *StageExecutor) getCreatedBy(node *parser.Node, addedContentSummary stri switch command { case "ARG": - for _, variable := range strings.Fields(node.Original) { + for variable := range strings.FieldsSeq(node.Original) { if variable != "ARG" { s.argsFromContainerfile = append(s.argsFromContainerfile, variable) } diff --git a/vendor/github.com/containers/buildah/info.go b/vendor/github.com/containers/buildah/info.go index 56a28429c91..b06c30ffdcd 100644 --- a/vendor/github.com/containers/buildah/info.go +++ b/vendor/github.com/containers/buildah/info.go @@ -55,12 +55,11 @@ func hostInfo() map[string]any { if err != nil { logrus.Error(err, "err reading cgroups mode") } - cgroupVersion := "v1" - ociruntime := util.Runtime() - if unified { - cgroupVersion = "v2" + if !unified { + logrus.Fatalf("Did not detect Cgroups v2.") } - info["CgroupVersion"] = cgroupVersion + + ociruntime := util.Runtime() info["OCIRuntime"] = ociruntime mi, err := system.ReadMemInfo() @@ -183,11 +182,11 @@ func getHostDistributionInfo() map[string]string { l := bufio.NewScanner(f) for l.Scan() { - if strings.HasPrefix(l.Text(), "ID=") { - dist["Distribution"] = strings.TrimPrefix(l.Text(), "ID=") + if after, ok := strings.CutPrefix(l.Text(), "ID="); ok { + dist["Distribution"] = after } - if strings.HasPrefix(l.Text(), "VERSION_ID=") { - dist["Version"] = strings.Trim(strings.TrimPrefix(l.Text(), "VERSION_ID="), "\"") + if after, ok := strings.CutPrefix(l.Text(), "VERSION_ID="); ok { + dist["Version"] = strings.Trim(after, "\"") } } return dist diff --git a/vendor/github.com/containers/buildah/internal/config/override.go b/vendor/github.com/containers/buildah/internal/config/override.go index 7d391bdafc5..55933de4684 100644 --- a/vendor/github.com/containers/buildah/internal/config/override.go +++ b/vendor/github.com/containers/buildah/internal/config/override.go @@ -2,6 +2,7 @@ package config import ( "fmt" + "maps" "os" "slices" "strings" @@ -136,9 +137,7 @@ func OverrideOCI(oconfig *v1.ImageConfig, overrideChanges []string, overrideConf if oconfig.Labels == nil { oconfig.Labels = make(map[string]string) } - for k, v := range overrideConfig.Labels { - oconfig.Labels[k] = v - } + maps.Copy(oconfig.Labels, overrideConfig.Labels) } oconfig.StopSignal = overrideConfig.StopSignal } @@ -206,9 +205,7 @@ func OverrideDocker(dconfig *docker.Config, overrideChanges []string, overrideCo if dconfig.Labels == nil { dconfig.Labels = make(map[string]string) } - for k, v := range overrideConfig.Labels { - dconfig.Labels[k] = v - } + maps.Copy(dconfig.Labels, overrideConfig.Labels) } dconfig.StopSignal = overrideConfig.StopSignal dconfig.StopTimeout = overrideConfig.StopTimeout diff --git a/vendor/github.com/containers/buildah/internal/mkcw/archive.go b/vendor/github.com/containers/buildah/internal/mkcw/archive.go index f462a8fa9f1..d1362986583 100644 --- a/vendor/github.com/containers/buildah/internal/mkcw/archive.go +++ b/vendor/github.com/containers/buildah/internal/mkcw/archive.go @@ -543,7 +543,7 @@ func slop(size int64, slop string) int64 { if slop == "" { return size * 5 / 4 } - for _, factor := range strings.Split(slop, "+") { + for factor := range strings.SplitSeq(slop, "+") { factor = strings.TrimSpace(factor) if factor == "" { continue diff --git a/vendor/github.com/containers/buildah/internal/mkcw/attest.go b/vendor/github.com/containers/buildah/internal/mkcw/attest.go index 3b7273976d4..b974ca5242a 100644 --- a/vendor/github.com/containers/buildah/internal/mkcw/attest.go +++ b/vendor/github.com/containers/buildah/internal/mkcw/attest.go @@ -240,8 +240,8 @@ func GenerateMeasurement(workloadConfig WorkloadConfig, firmwareLibrary string) scanner := bufio.NewScanner(&stdout) for scanner.Scan() { line := scanner.Text() - if strings.HasPrefix(line, prefix+":") { - return strings.TrimSpace(strings.TrimPrefix(line, prefix+":")), nil + if after, ok := strings.CutPrefix(line, prefix+":"); ok { + return strings.TrimSpace(after), nil } } return "", fmt.Errorf("generating measurement: no line starting with %q found in output from krunfw_measurement", prefix+":") diff --git a/vendor/github.com/containers/buildah/internal/mkcw/embed/entrypoint_amd64.gz b/vendor/github.com/containers/buildah/internal/mkcw/embed/entrypoint_amd64.gz index 953670818fe136267f5a1624e4298358495fb743..c2399f9e90498614417059bc4e59aa87229a23e9 100644 GIT binary patch literal 362 zcmV-w0hRtAiwFP!000021MQf>O2a@9hG%P{q6h06?7^cf#ghk-T-1U^5EXjenl)Wo zcT2KGg@QMq#m6Wf?34H&Zqr$5f}$wi=7Z$V%+5?Qxy?Ktb&ea1L7)MLFt@raDeVOP z&&`hz@7ssi-(!f%*cg^cD*A+_g96r>o6(XD&7`6ebO#M_(KmT5bO&8Wy?Ar!Z}QH4 z-YWc@P`*8zvQlP^QeIpBMeW(kskgRbe|oSuWu*-SK@bE%5ClOG1o5xTXJU>s{K?ss zpUc@a!ufo$52)IgeO+*UD>KFYL#hg$8I^Kpc~9|tY`84ANw|j1P5h-~+`5fGGNf%bo0jaO&QHFxDxNnXwqt#FYC%DeN8Zb_nYs32iY;U I73dKF0FPF*hyVZp literal 375 zcmV--0f_z|iwFP!000021MQkYO2a@DhF@Z%MHki^%)+G%!IcY&$+@sW+c zvPFuH9Z{g~0X0l+K+8lc%3HLeWVNbmR0Fpzi&k`O!%kgYV@+LX!%mx4uV*U$N!^vM z+obQ)A^-pY000000O0S@o=!X?Q{TvYsDFst)3*!lb^|?oJfHQ9$M*sN000000002~ zBUMkF(Y%L$etAnCd6O#UP6YThf744#mOh9?GChc8nI@TxnaWvLvSO4mQ8K~q^6Wm1 zWu{UwV2^pxALJrtqcY7BHb}dDoyfO|c-bpep+uLsl23|wmMh7VY{Z8}K9q%eCSK&R zP~zA7+_8ID^z!Zb2G_9XwS2GU_w==8zK3OTeqb(PEx%dw`*zJk>qB?$z}9!Zc>c0( Ve6p{xtv^`v{vQyN#K-6%007vKwlx3% diff --git a/vendor/github.com/containers/buildah/internal/sbom/merge.go b/vendor/github.com/containers/buildah/internal/sbom/merge.go index dddea84c51c..57487b083bb 100644 --- a/vendor/github.com/containers/buildah/internal/sbom/merge.go +++ b/vendor/github.com/containers/buildah/internal/sbom/merge.go @@ -202,7 +202,7 @@ func Merge(mergeStrategy define.SBOMMergeStrategy, inputOutputSBOM, inputSBOM, o Dependencies []string `json:"dependencies,omitempty"` } type purlDocument struct { - ImageContents purlImageContents `json:"image_contents,omitempty"` + ImageContents purlImageContents `json:"image_contents"` } purls := []string{} seenPurls := make(map[string]struct{}) diff --git a/vendor/github.com/containers/buildah/pkg/cli/build.go b/vendor/github.com/containers/buildah/pkg/cli/build.go index bdbd1105f84..9449ac883a7 100644 --- a/vendor/github.com/containers/buildah/pkg/cli/build.go +++ b/vendor/github.com/containers/buildah/pkg/cli/build.go @@ -474,7 +474,7 @@ func readBuildArgFile(buildargfile string, args map[string]string) error { if err != nil { return err } - for _, arg := range strings.Split(string(argfile), "\n") { + for arg := range strings.SplitSeq(string(argfile), "\n") { if len(arg) == 0 || arg[0] == '#' { continue } diff --git a/vendor/github.com/containers/buildah/pkg/parse/parse.go b/vendor/github.com/containers/buildah/pkg/parse/parse.go index 053c0434789..911d5dedac1 100644 --- a/vendor/github.com/containers/buildah/pkg/parse/parse.go +++ b/vendor/github.com/containers/buildah/pkg/parse/parse.go @@ -733,7 +733,7 @@ func GetBuildOutput(buildOutput string) (define.BuildOutputOption, error) { isStdout := false typeSelected := "" pathSelected := "" - for _, option := range strings.Split(buildOutput, ",") { + for option := range strings.SplitSeq(buildOutput, ",") { key, value, found := strings.Cut(option, "=") if !found { return define.BuildOutputOption{}, fmt.Errorf("invalid build output options %q, expected format key=value", buildOutput) @@ -789,7 +789,7 @@ func GetConfidentialWorkloadOptions(arg string) (define.ConfidentialWorkloadOpti TempDir: GetTempDir(), } defaults := options - for _, option := range strings.Split(arg, ",") { + for option := range strings.SplitSeq(arg, ",") { var err error switch { case strings.HasPrefix(option, "type="): @@ -936,7 +936,7 @@ func GetAutoOptions(base string) (*storageTypes.AutoUserNsOptions, error) { if len(parts) == 1 { return &options, nil } - for _, o := range strings.Split(parts[1], ",") { + for o := range strings.SplitSeq(parts[1], ",") { v := strings.SplitN(o, "=", 2) if len(v) != 2 { return nil, fmt.Errorf("invalid option specified: %q", o) diff --git a/vendor/github.com/containers/buildah/run_common.go b/vendor/github.com/containers/buildah/run_common.go index 0863ec2fb22..bd501f3bd3d 100644 --- a/vendor/github.com/containers/buildah/run_common.go +++ b/vendor/github.com/containers/buildah/run_common.go @@ -2121,6 +2121,12 @@ func (b *Builder) createMountTargets(spec *specs.Spec) ([]copier.ConditionalRemo // forced permissions mode = &perms } + if mode == nil && destination != cleanedDestination { + // parent directories default to 0o755, for + // the sake of commands running as UID != 0 + perms := os.FileMode(0o755) + mode = &perms + } targets.Paths = append(targets.Paths, copier.EnsurePath{ Path: destination, Typeflag: typeFlag, diff --git a/vendor/github.com/containers/luksy/.cirrus.yml b/vendor/github.com/containers/luksy/.cirrus.yml index 19c6c234007..f9f701dd2f9 100644 --- a/vendor/github.com/containers/luksy/.cirrus.yml +++ b/vendor/github.com/containers/luksy/.cirrus.yml @@ -4,8 +4,8 @@ docker_builder: HOME: /root DEBIAN_FRONTEND: noninteractive CIRRUS_LOG_TIMESTAMP: true - GOVERSION: 1.21 - PATH: /usr/lib/go-1.21/bin:$PATH + GOVERSION: 1.23 + PATH: /usr/lib/go-1.23/bin:$PATH setup_script: | apt-get -q update apt-get -q install -y bats cryptsetup golang-${GOVERSION} diff --git a/vendor/github.com/docker/docker/pkg/archive/archive_deprecated.go b/vendor/github.com/docker/docker/pkg/archive/archive_deprecated.go deleted file mode 100644 index 5bdbdef2003..00000000000 --- a/vendor/github.com/docker/docker/pkg/archive/archive_deprecated.go +++ /dev/null @@ -1,259 +0,0 @@ -// Package archive provides helper functions for dealing with archive files. -package archive - -import ( - "archive/tar" - "io" - "os" - - "github.com/docker/docker/pkg/idtools" - "github.com/moby/go-archive" - "github.com/moby/go-archive/compression" - "github.com/moby/go-archive/tarheader" -) - -// ImpliedDirectoryMode represents the mode (Unix permissions) applied to directories that are implied by files in a -// tar, but that do not have their own header entry. -// -// Deprecated: use [archive.ImpliedDirectoryMode] instead. -const ImpliedDirectoryMode = archive.ImpliedDirectoryMode - -type ( - // Compression is the state represents if compressed or not. - // - // Deprecated: use [compression.Compression] instead. - Compression = compression.Compression - // WhiteoutFormat is the format of whiteouts unpacked - // - // Deprecated: use [archive.WhiteoutFormat] instead. - WhiteoutFormat = archive.WhiteoutFormat - - // TarOptions wraps the tar options. - // - // Deprecated: use [archive.TarOptions] instead. - TarOptions struct { - IncludeFiles []string - ExcludePatterns []string - Compression compression.Compression - NoLchown bool - IDMap idtools.IdentityMapping - ChownOpts *idtools.Identity - IncludeSourceDir bool - // WhiteoutFormat is the expected on disk format for whiteout files. - // This format will be converted to the standard format on pack - // and from the standard format on unpack. - WhiteoutFormat archive.WhiteoutFormat - // When unpacking, specifies whether overwriting a directory with a - // non-directory is allowed and vice versa. - NoOverwriteDirNonDir bool - // For each include when creating an archive, the included name will be - // replaced with the matching name from this map. - RebaseNames map[string]string - InUserNS bool - // Allow unpacking to succeed in spite of failures to set extended - // attributes on the unpacked files due to the destination filesystem - // not supporting them or a lack of permissions. Extended attributes - // were probably in the archive for a reason, so set this option at - // your own peril. - BestEffortXattrs bool - } -) - -// Archiver implements the Archiver interface and allows the reuse of most utility functions of -// this package with a pluggable Untar function. Also, to facilitate the passing of specific id -// mappings for untar, an Archiver can be created with maps which will then be passed to Untar operations. -// -// Deprecated: use [archive.Archiver] instead. -type Archiver struct { - Untar func(io.Reader, string, *TarOptions) error - IDMapping idtools.IdentityMapping -} - -// NewDefaultArchiver returns a new Archiver without any IdentityMapping -// -// Deprecated: use [archive.NewDefaultArchiver] instead. -func NewDefaultArchiver() *Archiver { - return &Archiver{Untar: Untar} -} - -const ( - Uncompressed = compression.None // Deprecated: use [compression.None] instead. - Bzip2 = compression.Bzip2 // Deprecated: use [compression.Bzip2] instead. - Gzip = compression.Gzip // Deprecated: use [compression.Gzip] instead. - Xz = compression.Xz // Deprecated: use [compression.Xz] instead. - Zstd = compression.Zstd // Deprecated: use [compression.Zstd] instead. -) - -const ( - AUFSWhiteoutFormat = archive.AUFSWhiteoutFormat // Deprecated: use [archive.AUFSWhiteoutFormat] instead. - OverlayWhiteoutFormat = archive.OverlayWhiteoutFormat // Deprecated: use [archive.OverlayWhiteoutFormat] instead. -) - -// IsArchivePath checks if the (possibly compressed) file at the given path -// starts with a tar file header. -// -// Deprecated: use [archive.IsArchivePath] instead. -func IsArchivePath(path string) bool { - return archive.IsArchivePath(path) -} - -// DetectCompression detects the compression algorithm of the source. -// -// Deprecated: use [compression.Detect] instead. -func DetectCompression(source []byte) archive.Compression { - return compression.Detect(source) -} - -// DecompressStream decompresses the archive and returns a ReaderCloser with the decompressed archive. -// -// Deprecated: use [compression.DecompressStream] instead. -func DecompressStream(arch io.Reader) (io.ReadCloser, error) { - return compression.DecompressStream(arch) -} - -// CompressStream compresses the dest with specified compression algorithm. -// -// Deprecated: use [compression.CompressStream] instead. -func CompressStream(dest io.Writer, comp compression.Compression) (io.WriteCloser, error) { - return compression.CompressStream(dest, comp) -} - -// TarModifierFunc is a function that can be passed to ReplaceFileTarWrapper. -// -// Deprecated: use [archive.TarModifierFunc] instead. -type TarModifierFunc = archive.TarModifierFunc - -// ReplaceFileTarWrapper converts inputTarStream to a new tar stream. -// -// Deprecated: use [archive.ReplaceFileTarWrapper] instead. -func ReplaceFileTarWrapper(inputTarStream io.ReadCloser, mods map[string]archive.TarModifierFunc) io.ReadCloser { - return archive.ReplaceFileTarWrapper(inputTarStream, mods) -} - -// FileInfoHeaderNoLookups creates a partially-populated tar.Header from fi. -// -// Deprecated: use [tarheader.FileInfoHeaderNoLookups] instead. -func FileInfoHeaderNoLookups(fi os.FileInfo, link string) (*tar.Header, error) { - return tarheader.FileInfoHeaderNoLookups(fi, link) -} - -// FileInfoHeader creates a populated Header from fi. -// -// Deprecated: use [archive.FileInfoHeader] instead. -func FileInfoHeader(name string, fi os.FileInfo, link string) (*tar.Header, error) { - return archive.FileInfoHeader(name, fi, link) -} - -// ReadSecurityXattrToTarHeader reads security.capability xattr from filesystem -// to a tar header -// -// Deprecated: use [archive.ReadSecurityXattrToTarHeader] instead. -func ReadSecurityXattrToTarHeader(path string, hdr *tar.Header) error { - return archive.ReadSecurityXattrToTarHeader(path, hdr) -} - -// Tar creates an archive from the directory at `path`, and returns it as a -// stream of bytes. -// -// Deprecated: use [archive.Tar] instead. -func Tar(path string, compression archive.Compression) (io.ReadCloser, error) { - return archive.TarWithOptions(path, &archive.TarOptions{Compression: compression}) -} - -// TarWithOptions creates an archive with the given options. -// -// Deprecated: use [archive.TarWithOptions] instead. -func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) { - return archive.TarWithOptions(srcPath, toArchiveOpt(options)) -} - -// Tarballer is a lower-level interface to TarWithOptions. -// -// Deprecated: use [archive.Tarballer] instead. -type Tarballer = archive.Tarballer - -// NewTarballer constructs a new tarballer using TarWithOptions. -// -// Deprecated: use [archive.Tarballer] instead. -func NewTarballer(srcPath string, options *TarOptions) (*archive.Tarballer, error) { - return archive.NewTarballer(srcPath, toArchiveOpt(options)) -} - -// Unpack unpacks the decompressedArchive to dest with options. -// -// Deprecated: use [archive.Unpack] instead. -func Unpack(decompressedArchive io.Reader, dest string, options *TarOptions) error { - return archive.Unpack(decompressedArchive, dest, toArchiveOpt(options)) -} - -// Untar reads a stream of bytes from `archive`, parses it as a tar archive, -// and unpacks it into the directory at `dest`. -// -// Deprecated: use [archive.Untar] instead. -func Untar(tarArchive io.Reader, dest string, options *TarOptions) error { - return archive.Untar(tarArchive, dest, toArchiveOpt(options)) -} - -// UntarUncompressed reads a stream of bytes from `tarArchive`, parses it as a tar archive, -// and unpacks it into the directory at `dest`. -// The archive must be an uncompressed stream. -// -// Deprecated: use [archive.UntarUncompressed] instead. -func UntarUncompressed(tarArchive io.Reader, dest string, options *TarOptions) error { - return archive.UntarUncompressed(tarArchive, dest, toArchiveOpt(options)) -} - -// TarUntar is a convenience function which calls Tar and Untar, with the output of one piped into the other. -// If either Tar or Untar fails, TarUntar aborts and returns the error. -func (archiver *Archiver) TarUntar(src, dst string) error { - return (&archive.Archiver{ - Untar: func(reader io.Reader, s string, options *archive.TarOptions) error { - return archiver.Untar(reader, s, &TarOptions{ - IDMap: archiver.IDMapping, - }) - }, - IDMapping: idtools.ToUserIdentityMapping(archiver.IDMapping), - }).TarUntar(src, dst) -} - -// UntarPath untar a file from path to a destination, src is the source tar file path. -func (archiver *Archiver) UntarPath(src, dst string) error { - return (&archive.Archiver{ - Untar: func(reader io.Reader, s string, options *archive.TarOptions) error { - return archiver.Untar(reader, s, &TarOptions{ - IDMap: archiver.IDMapping, - }) - }, - IDMapping: idtools.ToUserIdentityMapping(archiver.IDMapping), - }).UntarPath(src, dst) -} - -// CopyWithTar creates a tar archive of filesystem path `src`, and -// unpacks it at filesystem path `dst`. -// The archive is streamed directly with fixed buffering and no -// intermediary disk IO. -func (archiver *Archiver) CopyWithTar(src, dst string) error { - return (&archive.Archiver{ - Untar: func(reader io.Reader, s string, options *archive.TarOptions) error { - return archiver.Untar(reader, s, nil) - }, - IDMapping: idtools.ToUserIdentityMapping(archiver.IDMapping), - }).CopyWithTar(src, dst) -} - -// CopyFileWithTar emulates the behavior of the 'cp' command-line -// for a single file. It copies a regular file from path `src` to -// path `dst`, and preserves all its metadata. -func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) { - return (&archive.Archiver{ - Untar: func(reader io.Reader, s string, options *archive.TarOptions) error { - return archiver.Untar(reader, s, nil) - }, - IDMapping: idtools.ToUserIdentityMapping(archiver.IDMapping), - }).CopyFileWithTar(src, dst) -} - -// IdentityMapping returns the IdentityMapping of the archiver. -func (archiver *Archiver) IdentityMapping() idtools.IdentityMapping { - return archiver.IDMapping -} diff --git a/vendor/github.com/docker/docker/pkg/archive/changes_deprecated.go b/vendor/github.com/docker/docker/pkg/archive/changes_deprecated.go deleted file mode 100644 index 48c75235c3e..00000000000 --- a/vendor/github.com/docker/docker/pkg/archive/changes_deprecated.go +++ /dev/null @@ -1,56 +0,0 @@ -package archive - -import ( - "io" - - "github.com/docker/docker/pkg/idtools" - "github.com/moby/go-archive" -) - -// ChangeType represents the change -// -// Deprecated: use [archive.ChangeType] instead. -type ChangeType = archive.ChangeType - -const ( - ChangeModify = archive.ChangeModify // Deprecated: use [archive.ChangeModify] instead. - ChangeAdd = archive.ChangeAdd // Deprecated: use [archive.ChangeAdd] instead. - ChangeDelete = archive.ChangeDelete // Deprecated: use [archive.ChangeDelete] instead. -) - -// Change represents a change. -// -// Deprecated: use [archive.Change] instead. -type Change = archive.Change - -// Changes walks the path rw and determines changes for the files in the path, -// with respect to the parent layers -// -// Deprecated: use [archive.Changes] instead. -func Changes(layers []string, rw string) ([]archive.Change, error) { - return archive.Changes(layers, rw) -} - -// FileInfo describes the information of a file. -// -// Deprecated: use [archive.FileInfo] instead. -type FileInfo = archive.FileInfo - -// ChangesDirs compares two directories and generates an array of Change objects describing the changes. -// -// Deprecated: use [archive.ChangesDirs] instead. -func ChangesDirs(newDir, oldDir string) ([]archive.Change, error) { - return archive.ChangesDirs(newDir, oldDir) -} - -// ChangesSize calculates the size in bytes of the provided changes, based on newDir. -// -// Deprecated: use [archive.ChangesSize] instead. -func ChangesSize(newDir string, changes []archive.Change) int64 { - return archive.ChangesSize(newDir, changes) -} - -// ExportChanges produces an Archive from the provided changes, relative to dir. -func ExportChanges(dir string, changes []archive.Change, idMap idtools.IdentityMapping) (io.ReadCloser, error) { - return archive.ExportChanges(dir, changes, idtools.ToUserIdentityMapping(idMap)) -} diff --git a/vendor/github.com/docker/docker/pkg/archive/copy_deprecated.go b/vendor/github.com/docker/docker/pkg/archive/copy_deprecated.go deleted file mode 100644 index 1901e55c531..00000000000 --- a/vendor/github.com/docker/docker/pkg/archive/copy_deprecated.go +++ /dev/null @@ -1,130 +0,0 @@ -package archive - -import ( - "io" - - "github.com/moby/go-archive" - "github.com/moby/go-archive/compression" -) - -var ( - ErrNotDirectory = archive.ErrNotDirectory // Deprecated: use [archive.ErrNotDirectory] instead. - ErrDirNotExists = archive.ErrDirNotExists // Deprecated: use [archive.ErrDirNotExists] instead. - ErrCannotCopyDir = archive.ErrCannotCopyDir // Deprecated: use [archive.ErrCannotCopyDir] instead. - ErrInvalidCopySource = archive.ErrInvalidCopySource // Deprecated: use [archive.ErrInvalidCopySource] instead. -) - -// PreserveTrailingDotOrSeparator returns the given cleaned path. -// -// Deprecated: use [archive.PreserveTrailingDotOrSeparator] instead. -func PreserveTrailingDotOrSeparator(cleanedPath string, originalPath string) string { - return archive.PreserveTrailingDotOrSeparator(cleanedPath, originalPath) -} - -// SplitPathDirEntry splits the given path between its directory name and its -// basename. -// -// Deprecated: use [archive.SplitPathDirEntry] instead. -func SplitPathDirEntry(path string) (dir, base string) { - return archive.SplitPathDirEntry(path) -} - -// TarResource archives the resource described by the given CopyInfo to a Tar -// archive. -// -// Deprecated: use [archive.TarResource] instead. -func TarResource(sourceInfo archive.CopyInfo) (content io.ReadCloser, err error) { - return archive.TarResource(sourceInfo) -} - -// TarResourceRebase is like TarResource but renames the first path element of -// items in the resulting tar archive to match the given rebaseName if not "". -// -// Deprecated: use [archive.TarResourceRebase] instead. -func TarResourceRebase(sourcePath, rebaseName string) (content io.ReadCloser, _ error) { - return archive.TarResourceRebase(sourcePath, rebaseName) -} - -// TarResourceRebaseOpts does not preform the Tar, but instead just creates the rebase -// parameters to be sent to TarWithOptions. -// -// Deprecated: use [archive.TarResourceRebaseOpts] instead. -func TarResourceRebaseOpts(sourceBase string, rebaseName string) *TarOptions { - filter := []string{sourceBase} - return &TarOptions{ - Compression: compression.None, - IncludeFiles: filter, - IncludeSourceDir: true, - RebaseNames: map[string]string{ - sourceBase: rebaseName, - }, - } -} - -// CopyInfo holds basic info about the source or destination path of a copy operation. -// -// Deprecated: use [archive.CopyInfo] instead. -type CopyInfo = archive.CopyInfo - -// CopyInfoSourcePath stats the given path to create a CopyInfo struct. -// struct representing that resource for the source of an archive copy -// operation. -// -// Deprecated: use [archive.CopyInfoSourcePath] instead. -func CopyInfoSourcePath(path string, followLink bool) (archive.CopyInfo, error) { - return archive.CopyInfoSourcePath(path, followLink) -} - -// CopyInfoDestinationPath stats the given path to create a CopyInfo -// struct representing that resource for the destination of an archive copy -// operation. -// -// Deprecated: use [archive.CopyInfoDestinationPath] instead. -func CopyInfoDestinationPath(path string) (info archive.CopyInfo, err error) { - return archive.CopyInfoDestinationPath(path) -} - -// PrepareArchiveCopy prepares the given srcContent archive. -// -// Deprecated: use [archive.PrepareArchiveCopy] instead. -func PrepareArchiveCopy(srcContent io.Reader, srcInfo, dstInfo archive.CopyInfo) (dstDir string, content io.ReadCloser, err error) { - return archive.PrepareArchiveCopy(srcContent, srcInfo, dstInfo) -} - -// RebaseArchiveEntries rewrites the given srcContent archive replacing -// an occurrence of oldBase with newBase at the beginning of entry names. -// -// Deprecated: use [archive.RebaseArchiveEntries] instead. -func RebaseArchiveEntries(srcContent io.Reader, oldBase, newBase string) io.ReadCloser { - return archive.RebaseArchiveEntries(srcContent, oldBase, newBase) -} - -// CopyResource performs an archive copy from the given source path to the -// given destination path. -// -// Deprecated: use [archive.CopyResource] instead. -func CopyResource(srcPath, dstPath string, followLink bool) error { - return archive.CopyResource(srcPath, dstPath, followLink) -} - -// CopyTo handles extracting the given content whose -// entries should be sourced from srcInfo to dstPath. -// -// Deprecated: use [archive.CopyTo] instead. -func CopyTo(content io.Reader, srcInfo archive.CopyInfo, dstPath string) error { - return archive.CopyTo(content, srcInfo, dstPath) -} - -// ResolveHostSourcePath decides real path need to be copied. -// -// Deprecated: use [archive.ResolveHostSourcePath] instead. -func ResolveHostSourcePath(path string, followLink bool) (resolvedPath, rebaseName string, _ error) { - return archive.ResolveHostSourcePath(path, followLink) -} - -// GetRebaseName normalizes and compares path and resolvedPath. -// -// Deprecated: use [archive.GetRebaseName] instead. -func GetRebaseName(path, resolvedPath string) (string, string) { - return archive.GetRebaseName(path, resolvedPath) -} diff --git a/vendor/github.com/docker/docker/pkg/archive/diff_deprecated.go b/vendor/github.com/docker/docker/pkg/archive/diff_deprecated.go deleted file mode 100644 index dd5e0d5ef5c..00000000000 --- a/vendor/github.com/docker/docker/pkg/archive/diff_deprecated.go +++ /dev/null @@ -1,37 +0,0 @@ -package archive - -import ( - "io" - - "github.com/moby/go-archive" -) - -// UnpackLayer unpack `layer` to a `dest`. -// -// Deprecated: use [archive.UnpackLayer] instead. -func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64, err error) { - return archive.UnpackLayer(dest, layer, toArchiveOpt(options)) -} - -// ApplyLayer parses a diff in the standard layer format from `layer`, -// and applies it to the directory `dest`. -// -// Deprecated: use [archive.ApplyLayer] instead. -func ApplyLayer(dest string, layer io.Reader) (int64, error) { - return archive.ApplyLayer(dest, layer) -} - -// ApplyUncompressedLayer parses a diff in the standard layer format from -// `layer`, and applies it to the directory `dest`. -// -// Deprecated: use [archive.ApplyUncompressedLayer] instead. -func ApplyUncompressedLayer(dest string, layer io.Reader, options *TarOptions) (int64, error) { - return archive.ApplyUncompressedLayer(dest, layer, toArchiveOpt(options)) -} - -// IsEmpty checks if the tar archive is empty (doesn't contain any entries). -// -// Deprecated: use [archive.IsEmpty] instead. -func IsEmpty(rd io.Reader) (bool, error) { - return archive.IsEmpty(rd) -} diff --git a/vendor/github.com/docker/docker/pkg/archive/path_deprecated.go b/vendor/github.com/docker/docker/pkg/archive/path_deprecated.go deleted file mode 100644 index 0fa74de68fa..00000000000 --- a/vendor/github.com/docker/docker/pkg/archive/path_deprecated.go +++ /dev/null @@ -1,10 +0,0 @@ -package archive - -import "github.com/moby/go-archive" - -// CheckSystemDriveAndRemoveDriveLetter verifies that a path is the system drive. -// -// Deprecated: use [archive.CheckSystemDriveAndRemoveDriveLetter] instead. -func CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) { - return archive.CheckSystemDriveAndRemoveDriveLetter(path) -} diff --git a/vendor/github.com/docker/docker/pkg/archive/utils.go b/vendor/github.com/docker/docker/pkg/archive/utils.go deleted file mode 100644 index 692cf1602dc..00000000000 --- a/vendor/github.com/docker/docker/pkg/archive/utils.go +++ /dev/null @@ -1,42 +0,0 @@ -package archive - -import ( - "github.com/docker/docker/pkg/idtools" - "github.com/moby/go-archive" -) - -// ToArchiveOpt converts an [TarOptions] to a [archive.TarOptions]. -// -// Deprecated: use [archive.TarOptions] instead, this utility is for internal use to transition to the [github.com/moby/go-archive] module. -func ToArchiveOpt(options *TarOptions) *archive.TarOptions { - return toArchiveOpt(options) -} - -func toArchiveOpt(options *TarOptions) *archive.TarOptions { - if options == nil { - return nil - } - - var chownOpts *archive.ChownOpts - if options.ChownOpts != nil { - chownOpts = &archive.ChownOpts{ - UID: options.ChownOpts.UID, - GID: options.ChownOpts.GID, - } - } - - return &archive.TarOptions{ - IncludeFiles: options.IncludeFiles, - ExcludePatterns: options.ExcludePatterns, - Compression: options.Compression, - NoLchown: options.NoLchown, - IDMap: idtools.ToUserIdentityMapping(options.IDMap), - ChownOpts: chownOpts, - IncludeSourceDir: options.IncludeSourceDir, - WhiteoutFormat: options.WhiteoutFormat, - NoOverwriteDirNonDir: options.NoOverwriteDirNonDir, - RebaseNames: options.RebaseNames, - InUserNS: options.InUserNS, - BestEffortXattrs: options.BestEffortXattrs, - } -} diff --git a/vendor/github.com/docker/docker/pkg/archive/whiteouts_deprecated.go b/vendor/github.com/docker/docker/pkg/archive/whiteouts_deprecated.go deleted file mode 100644 index 0ab8590b146..00000000000 --- a/vendor/github.com/docker/docker/pkg/archive/whiteouts_deprecated.go +++ /dev/null @@ -1,10 +0,0 @@ -package archive - -import "github.com/moby/go-archive" - -const ( - WhiteoutPrefix = archive.WhiteoutPrefix // Deprecated: use [archive.WhiteoutPrefix] instead. - WhiteoutMetaPrefix = archive.WhiteoutMetaPrefix // Deprecated: use [archive.WhiteoutMetaPrefix] instead. - WhiteoutLinkDir = archive.WhiteoutLinkDir // Deprecated: use [archive.WhiteoutLinkDir] instead. - WhiteoutOpaqueDir = archive.WhiteoutOpaqueDir // Deprecated: use [archive.WhiteoutOpaqueDir] instead. -) diff --git a/vendor/github.com/docker/docker/pkg/archive/wrap_deprecated.go b/vendor/github.com/docker/docker/pkg/archive/wrap_deprecated.go deleted file mode 100644 index e5d3fa9a958..00000000000 --- a/vendor/github.com/docker/docker/pkg/archive/wrap_deprecated.go +++ /dev/null @@ -1,14 +0,0 @@ -package archive - -import ( - "io" - - "github.com/moby/go-archive" -) - -// Generate generates a new archive from the content provided as input. -// -// Deprecated: use [archive.Generate] instead. -func Generate(input ...string) (io.Reader, error) { - return archive.Generate(input...) -} diff --git a/vendor/github.com/docker/docker/pkg/idtools/idtools.go b/vendor/github.com/docker/docker/pkg/idtools/idtools.go deleted file mode 100644 index 982f81d4f26..00000000000 --- a/vendor/github.com/docker/docker/pkg/idtools/idtools.go +++ /dev/null @@ -1,223 +0,0 @@ -package idtools - -import ( - "fmt" - "os" - - "github.com/moby/sys/user" -) - -// IDMap contains a single entry for user namespace range remapping. An array -// of IDMap entries represents the structure that will be provided to the Linux -// kernel for creating a user namespace. -// -// Deprecated: use [user.IDMap] instead. -type IDMap struct { - ContainerID int `json:"container_id"` - HostID int `json:"host_id"` - Size int `json:"size"` -} - -// MkdirAllAndChown creates a directory (include any along the path) and then modifies -// ownership to the requested uid/gid. If the directory already exists, this -// function will still change ownership and permissions. -// -// Deprecated: use [user.MkdirAllAndChown] instead. -func MkdirAllAndChown(path string, mode os.FileMode, owner Identity) error { - return user.MkdirAllAndChown(path, mode, owner.UID, owner.GID) -} - -// MkdirAndChown creates a directory and then modifies ownership to the requested uid/gid. -// If the directory already exists, this function still changes ownership and permissions. -// Note that unlike os.Mkdir(), this function does not return IsExist error -// in case path already exists. -// -// Deprecated: use [user.MkdirAndChown] instead. -func MkdirAndChown(path string, mode os.FileMode, owner Identity) error { - return user.MkdirAndChown(path, mode, owner.UID, owner.GID) -} - -// MkdirAllAndChownNew creates a directory (include any along the path) and then modifies -// ownership ONLY of newly created directories to the requested uid/gid. If the -// directories along the path exist, no change of ownership or permissions will be performed -// -// Deprecated: use [user.MkdirAllAndChown] with the [user.WithOnlyNew] option instead. -func MkdirAllAndChownNew(path string, mode os.FileMode, owner Identity) error { - return user.MkdirAllAndChown(path, mode, owner.UID, owner.GID, user.WithOnlyNew) -} - -// GetRootUIDGID retrieves the remapped root uid/gid pair from the set of maps. -// If the maps are empty, then the root uid/gid will default to "real" 0/0 -// -// Deprecated: use [(user.IdentityMapping).RootPair] instead. -func GetRootUIDGID(uidMap, gidMap []IDMap) (int, int, error) { - return getRootUIDGID(uidMap, gidMap) -} - -// getRootUIDGID retrieves the remapped root uid/gid pair from the set of maps. -// If the maps are empty, then the root uid/gid will default to "real" 0/0 -func getRootUIDGID(uidMap, gidMap []IDMap) (int, int, error) { - uid, err := toHost(0, uidMap) - if err != nil { - return -1, -1, err - } - gid, err := toHost(0, gidMap) - if err != nil { - return -1, -1, err - } - return uid, gid, nil -} - -// toContainer takes an id mapping, and uses it to translate a -// host ID to the remapped ID. If no map is provided, then the translation -// assumes a 1-to-1 mapping and returns the passed in id -func toContainer(hostID int, idMap []IDMap) (int, error) { - if idMap == nil { - return hostID, nil - } - for _, m := range idMap { - if (hostID >= m.HostID) && (hostID <= (m.HostID + m.Size - 1)) { - contID := m.ContainerID + (hostID - m.HostID) - return contID, nil - } - } - return -1, fmt.Errorf("Host ID %d cannot be mapped to a container ID", hostID) -} - -// toHost takes an id mapping and a remapped ID, and translates the -// ID to the mapped host ID. If no map is provided, then the translation -// assumes a 1-to-1 mapping and returns the passed in id # -func toHost(contID int, idMap []IDMap) (int, error) { - if idMap == nil { - return contID, nil - } - for _, m := range idMap { - if (contID >= m.ContainerID) && (contID <= (m.ContainerID + m.Size - 1)) { - hostID := m.HostID + (contID - m.ContainerID) - return hostID, nil - } - } - return -1, fmt.Errorf("Container ID %d cannot be mapped to a host ID", contID) -} - -// Identity is either a UID and GID pair or a SID (but not both) -type Identity struct { - UID int - GID int - SID string -} - -// Chown changes the numeric uid and gid of the named file to id.UID and id.GID. -// -// Deprecated: this method is deprecated and will be removed in the next release. -func (id Identity) Chown(name string) error { - return os.Chown(name, id.UID, id.GID) -} - -// IdentityMapping contains a mappings of UIDs and GIDs. -// The zero value represents an empty mapping. -// -// Deprecated: this type is deprecated and will be removed in the next release. -type IdentityMapping struct { - UIDMaps []IDMap `json:"UIDMaps"` - GIDMaps []IDMap `json:"GIDMaps"` -} - -// FromUserIdentityMapping converts a [user.IdentityMapping] to an [idtools.IdentityMapping]. -// -// Deprecated: use [user.IdentityMapping] directly, this is transitioning to user package. -func FromUserIdentityMapping(u user.IdentityMapping) IdentityMapping { - return IdentityMapping{ - UIDMaps: fromUserIDMap(u.UIDMaps), - GIDMaps: fromUserIDMap(u.GIDMaps), - } -} - -func fromUserIDMap(u []user.IDMap) []IDMap { - if u == nil { - return nil - } - m := make([]IDMap, len(u)) - for i := range u { - m[i] = IDMap{ - ContainerID: int(u[i].ID), - HostID: int(u[i].ParentID), - Size: int(u[i].Count), - } - } - return m -} - -// ToUserIdentityMapping converts an [idtools.IdentityMapping] to a [user.IdentityMapping]. -// -// Deprecated: use [user.IdentityMapping] directly, this is transitioning to user package. -func ToUserIdentityMapping(u IdentityMapping) user.IdentityMapping { - return user.IdentityMapping{ - UIDMaps: toUserIDMap(u.UIDMaps), - GIDMaps: toUserIDMap(u.GIDMaps), - } -} - -func toUserIDMap(u []IDMap) []user.IDMap { - if u == nil { - return nil - } - m := make([]user.IDMap, len(u)) - for i := range u { - m[i] = user.IDMap{ - ID: int64(u[i].ContainerID), - ParentID: int64(u[i].HostID), - Count: int64(u[i].Size), - } - } - return m -} - -// RootPair returns a uid and gid pair for the root user. The error is ignored -// because a root user always exists, and the defaults are correct when the uid -// and gid maps are empty. -func (i IdentityMapping) RootPair() Identity { - uid, gid, _ := getRootUIDGID(i.UIDMaps, i.GIDMaps) - return Identity{UID: uid, GID: gid} -} - -// ToHost returns the host UID and GID for the container uid, gid. -// Remapping is only performed if the ids aren't already the remapped root ids -func (i IdentityMapping) ToHost(pair Identity) (Identity, error) { - var err error - target := i.RootPair() - - if pair.UID != target.UID { - target.UID, err = toHost(pair.UID, i.UIDMaps) - if err != nil { - return target, err - } - } - - if pair.GID != target.GID { - target.GID, err = toHost(pair.GID, i.GIDMaps) - } - return target, err -} - -// ToContainer returns the container UID and GID for the host uid and gid -func (i IdentityMapping) ToContainer(pair Identity) (int, int, error) { - uid, err := toContainer(pair.UID, i.UIDMaps) - if err != nil { - return -1, -1, err - } - gid, err := toContainer(pair.GID, i.GIDMaps) - return uid, gid, err -} - -// Empty returns true if there are no id mappings -func (i IdentityMapping) Empty() bool { - return len(i.UIDMaps) == 0 && len(i.GIDMaps) == 0 -} - -// CurrentIdentity returns the identity of the current process -// -// Deprecated: use [os.Getuid] and [os.Getegid] instead. -func CurrentIdentity() Identity { - return Identity{UID: os.Getuid(), GID: os.Getegid()} -} diff --git a/vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go b/vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go deleted file mode 100644 index f83f59f30c3..00000000000 --- a/vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go +++ /dev/null @@ -1,12 +0,0 @@ -package idtools - -const ( - SeTakeOwnershipPrivilege = "SeTakeOwnershipPrivilege" -) - -// TODO(thaJeztah): these magic consts need a source of reference, and should be defined in a canonical location -const ( - ContainerAdministratorSidString = "S-1-5-93-2-1" - - ContainerUserSidString = "S-1-5-93-2-2" -) diff --git a/vendor/github.com/fsouza/go-dockerclient/.golangci.yaml b/vendor/github.com/fsouza/go-dockerclient/.golangci.yaml index cdbf80dec95..f6e588a65a9 100644 --- a/vendor/github.com/fsouza/go-dockerclient/.golangci.yaml +++ b/vendor/github.com/fsouza/go-dockerclient/.golangci.yaml @@ -1,5 +1,24 @@ +version: "2" linters: - disable-all: true + default: none + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + paths: + - third_party$ + - builtin$ + - examples$ +formatters: enable: - gofumpt - goimports + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/vendor/github.com/fsouza/go-dockerclient/container_update.go b/vendor/github.com/fsouza/go-dockerclient/container_update.go index e8de21365b9..d2116dbd738 100644 --- a/vendor/github.com/fsouza/go-dockerclient/container_update.go +++ b/vendor/github.com/fsouza/go-dockerclient/container_update.go @@ -30,7 +30,7 @@ type UpdateContainerOptions struct { // // See https://goo.gl/Y6fXUy for more details. func (c *Client) UpdateContainer(id string, opts UpdateContainerOptions) error { - resp, err := c.do(http.MethodPost, fmt.Sprintf("/containers/"+id+"/update"), doOptions{ + resp, err := c.do(http.MethodPost, fmt.Sprintf("/containers/%s/update", id), doOptions{ data: opts, forceJSON: true, context: opts.Context, diff --git a/vendor/github.com/fsouza/go-dockerclient/event.go b/vendor/github.com/fsouza/go-dockerclient/event.go index ce1fb5021b2..22d64f6ab77 100644 --- a/vendor/github.com/fsouza/go-dockerclient/event.go +++ b/vendor/github.com/fsouza/go-dockerclient/event.go @@ -271,11 +271,13 @@ func (eventState *eventMonitoringState) monitorEvents(c *Client, opts EventsOpti return } if ev == EOFEvent { - eventState.disableEventMonitoring() + go eventState.disableEventMonitoring() return } - eventState.updateLastSeen(ev) - eventState.sendEvent(ev) + go func(ev *APIEvents) { + eventState.updateLastSeen(ev) + eventState.sendEvent(ev) + }(ev) case err = <-eventState.errC: if errors.Is(err, ErrNoListeners) { eventState.disableEventMonitoring() diff --git a/vendor/github.com/fsouza/go-dockerclient/tar.go b/vendor/github.com/fsouza/go-dockerclient/tar.go index b764285b929..0d40c644abd 100644 --- a/vendor/github.com/fsouza/go-dockerclient/tar.go +++ b/vendor/github.com/fsouza/go-dockerclient/tar.go @@ -12,7 +12,7 @@ import ( "path/filepath" "strings" - "github.com/docker/docker/pkg/archive" + "github.com/moby/go-archive" "github.com/moby/patternmatcher" ) diff --git a/vendor/github.com/moby/buildkit/util/stack/stack.pb.go b/vendor/github.com/moby/buildkit/util/stack/stack.pb.go index ef36670a895..5e9ef1894e7 100644 --- a/vendor/github.com/moby/buildkit/util/stack/stack.pb.go +++ b/vendor/github.com/moby/buildkit/util/stack/stack.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 +// protoc-gen-go v1.36.9 // protoc v3.11.4 // source: github.com/moby/buildkit/util/stack/stack.proto diff --git a/vendor/go.podman.io/common/pkg/cgroups/blkio_linux.go b/vendor/go.podman.io/common/pkg/cgroups/blkio_linux.go index 4d85ba4a707..c1b73f2fd81 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/blkio_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/blkio_linux.go @@ -3,10 +3,6 @@ package cgroups import ( - "bufio" - "errors" - "fmt" - "os" "path/filepath" "strconv" "strings" @@ -26,23 +22,16 @@ func getBlkioHandler() *linuxBlkioHandler { // Apply set the specified constraints. func (c *linuxBlkioHandler) Apply(ctr *CgroupControl, res *cgroups.Resources) error { - if ctr.cgroup2 { - man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path)) - if err != nil { - return err - } - return man.Set(res) + man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path)) + if err != nil { + return err } - path := filepath.Join(cgroupRoot, Blkio, ctr.config.Path) - return c.Blkio.Set(path, res) + return man.Set(res) } // Create the cgroup. func (c *linuxBlkioHandler) Create(ctr *CgroupControl) (bool, error) { - if ctr.cgroup2 { - return false, nil - } - return ctr.createCgroupDirectory(Blkio) + return false, nil } // Destroy the cgroup. @@ -54,94 +43,45 @@ func (c *linuxBlkioHandler) Destroy(ctr *CgroupControl) error { func (c *linuxBlkioHandler) Stat(ctr *CgroupControl, m *cgroups.Stats) error { var ioServiceBytesRecursive []cgroups.BlkioStatEntry - if ctr.cgroup2 { - // more details on the io.stat file format:X https://facebookmicrosites.github.io/cgroup2/docs/io-controller.html - values, err := readCgroup2MapFile(ctr, "io.stat") + // more details on the io.stat file format:X https://facebookmicrosites.github.io/cgroup2/docs/io-controller.html + values, err := readCgroup2MapFile(ctr, "io.stat") + if err != nil { + return err + } + for k, v := range values { + d := strings.Split(k, ":") + if len(d) != 2 { + continue + } + minor, err := strconv.ParseUint(d[0], 10, 0) if err != nil { return err } - for k, v := range values { - d := strings.Split(k, ":") - if len(d) != 2 { - continue - } - minor, err := strconv.ParseUint(d[0], 10, 0) - if err != nil { - return err - } - major, err := strconv.ParseUint(d[1], 10, 0) - if err != nil { - return err - } - - for _, item := range v { - d := strings.Split(item, "=") - if len(d) != 2 { - continue - } - op := d[0] - - // Accommodate the cgroup v1 naming - switch op { - case "rbytes": - op = "read" - case "wbytes": - op = "write" - } - - value, err := strconv.ParseUint(d[1], 10, 0) - if err != nil { - return err - } - - entry := cgroups.BlkioStatEntry{ - Op: op, - Major: major, - Minor: minor, - Value: value, - } - ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry) - } - } - } else { - BlkioRoot := ctr.getCgroupv1Path(Blkio) - - p := filepath.Join(BlkioRoot, "blkio.throttle.io_service_bytes_recursive") - f, err := os.Open(p) + major, err := strconv.ParseUint(d[1], 10, 0) if err != nil { - if errors.Is(err, os.ErrNotExist) { - return nil - } - return fmt.Errorf("open %s: %w", p, err) + return err } - defer f.Close() - scanner := bufio.NewScanner(f) - for scanner.Scan() { - line := scanner.Text() - parts := strings.Fields(line) - if len(parts) < 3 { - continue - } - d := strings.Split(parts[0], ":") + for _, item := range v { + d := strings.Split(item, "=") if len(d) != 2 { continue } - minor, err := strconv.ParseUint(d[0], 10, 0) - if err != nil { - return err - } - major, err := strconv.ParseUint(d[1], 10, 0) - if err != nil { - return err + op := d[0] + + // Accommodate the cgroup v1 naming + switch op { + case "rbytes": + op = "read" + case "wbytes": + op = "write" } - op := parts[1] - - value, err := strconv.ParseUint(parts[2], 10, 0) + value, err := strconv.ParseUint(d[1], 10, 0) if err != nil { return err } + entry := cgroups.BlkioStatEntry{ Op: op, Major: major, @@ -150,9 +90,6 @@ func (c *linuxBlkioHandler) Stat(ctr *CgroupControl, m *cgroups.Stats) error { } ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry) } - if err := scanner.Err(); err != nil { - return fmt.Errorf("parse %s: %w", p, err) - } } m.BlkioStats.IoServiceBytesRecursive = ioServiceBytesRecursive return nil diff --git a/vendor/go.podman.io/common/pkg/cgroups/cgroups_linux.go b/vendor/go.podman.io/common/pkg/cgroups/cgroups_linux.go index 1c66a8d9cc4..e7a7cd09524 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/cgroups_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/cgroups_linux.go @@ -8,11 +8,9 @@ import ( "context" "errors" "fmt" - "maps" "math" "os" "path/filepath" - "slices" "strconv" "strings" "sync" @@ -32,9 +30,7 @@ import ( var ( // ErrCgroupDeleted means the cgroup was deleted. ErrCgroupDeleted = errors.New("cgroup deleted") - // ErrCgroupV1Rootless means the cgroup v1 were attempted to be used in rootless environment. - ErrCgroupV1Rootless = errors.New("no support for CGroups V1 in rootless environments") - ErrStatCgroup = errors.New("no cgroup available for gathering user statistics") + ErrStatCgroup = errors.New("no cgroup available for gathering user statistics") isUnifiedOnce sync.Once isUnified bool @@ -43,12 +39,8 @@ var ( // CgroupControl controls a cgroup hierarchy. type CgroupControl struct { - cgroup2 bool config *cgroups.Cgroup systemd bool - // List of additional cgroup subsystems joined that - // do not have a custom handler. - additionalControllers []controller } type controller struct { @@ -92,63 +84,37 @@ func init() { } // getAvailableControllers get the available controllers. -func getAvailableControllers(exclude map[string]controllerHandler, cgroup2 bool) ([]controller, error) { - if cgroup2 { - controllers := []controller{} - controllersFile := filepath.Join(cgroupRoot, "cgroup.controllers") - - // rootless cgroupv2: check available controllers for current user, systemd or servicescope will inherit - if unshare.IsRootless() { - userSlice, err := getCgroupPathForCurrentProcess() - if err != nil { - return controllers, err - } - // userSlice already contains '/' so not adding here - basePath := cgroupRoot + userSlice - controllersFile = filepath.Join(basePath, "cgroup.controllers") - } - controllersFileBytes, err := os.ReadFile(controllersFile) - if err != nil { - return nil, fmt.Errorf("failed while reading controllers for cgroup v2: %w", err) - } - for controllerName := range strings.FieldsSeq(string(controllersFileBytes)) { - c := controller{ - name: controllerName, - symlink: false, - } - controllers = append(controllers, c) - } - return controllers, nil - } - - subsystems, _ := cgroupV1GetAllSubsystems() +func getAvailableControllers() ([]controller, error) { controllers := []controller{} - // cgroupv1 and rootless: No subsystem is available: delegation is unsafe. - if unshare.IsRootless() { - return controllers, nil - } + controllersFile := filepath.Join(cgroupRoot, "cgroup.controllers") - for _, name := range subsystems { - if _, found := exclude[name]; found { - continue - } - fileInfo, err := os.Stat(cgroupRoot + "/" + name) + // rootless cgroupv2: check available controllers for current user, systemd or servicescope will inherit + if unshare.IsRootless() { + userSlice, err := getCgroupPathForCurrentProcess() if err != nil { - continue + return controllers, err } + // userSlice already contains '/' so not adding here + basePath := cgroupRoot + userSlice + controllersFile = filepath.Join(basePath, "cgroup.controllers") + } + controllersFileBytes, err := os.ReadFile(controllersFile) + if err != nil { + return nil, fmt.Errorf("failed while reading controllers for cgroup v2: %w", err) + } + for controllerName := range strings.FieldsSeq(string(controllersFileBytes)) { c := controller{ - name: name, - symlink: !fileInfo.IsDir(), + name: controllerName, + symlink: false, } controllers = append(controllers, c) } - return controllers, nil } // AvailableControllers get string:bool map of all the available controllers. -func AvailableControllers(exclude map[string]controllerHandler, cgroup2 bool) ([]string, error) { - availableControllers, err := getAvailableControllers(exclude, cgroup2) +func AvailableControllers() ([]string, error) { + availableControllers, err := getAvailableControllers() if err != nil { return nil, err } @@ -160,31 +126,6 @@ func AvailableControllers(exclude map[string]controllerHandler, cgroup2 bool) ([ return controllerList, nil } -func cgroupV1GetAllSubsystems() ([]string, error) { - f, err := os.Open("/proc/cgroups") - if err != nil { - return nil, err - } - defer f.Close() - - subsystems := []string{} - - s := bufio.NewScanner(f) - for s.Scan() { - text := s.Text() - if text[0] != '#' { - parts := strings.Fields(text) - if len(parts) >= 4 && parts[3] != "0" { - subsystems = append(subsystems, parts[0]) - } - } - } - if err := s.Err(); err != nil { - return nil, err - } - return subsystems, nil -} - func getCgroupPathForCurrentProcess() (string, error) { path := fmt.Sprintf("/proc/%d/cgroup", os.Getpid()) f, err := os.Open(path) @@ -225,10 +166,8 @@ func (c *CgroupControl) initialize() (err error) { } } }() - if c.cgroup2 { - if err := createCgroupv2Path(filepath.Join(cgroupRoot, c.config.Path)); err != nil { - return fmt.Errorf("creating cgroup path %s: %w", c.config.Path, err) - } + if err := createCgroupv2Path(filepath.Join(cgroupRoot, c.config.Path)); err != nil { + return fmt.Errorf("creating cgroup path %s: %w", c.config.Path, err) } for name, handler := range handlers { created, err := handler.Create(c) @@ -239,20 +178,6 @@ func (c *CgroupControl) initialize() (err error) { createdSoFar[name] = handler } } - - if !c.cgroup2 { - // We won't need to do this for cgroup v2 - for _, ctr := range c.additionalControllers { - if ctr.symlink { - continue - } - path := c.getCgroupv1Path(ctr.name) - if err := os.MkdirAll(path, 0o755); err != nil { - return fmt.Errorf("creating cgroup path for %s: %w", ctr.name, err) - } - } - } - return nil } @@ -297,26 +222,13 @@ func readFileByKeyAsUint64(path, key string) (uint64, error) { // New creates a new cgroup control. func New(path string, resources *cgroups.Resources) (*CgroupControl, error) { - cgroup2, err := IsCgroup2UnifiedMode() - if err != nil { - return nil, err - } control := &CgroupControl{ - cgroup2: cgroup2, config: &cgroups.Cgroup{ Path: path, Resources: resources, }, } - if !cgroup2 { - controllers, err := getAvailableControllers(handlers, false) - if err != nil { - return nil, err - } - control.additionalControllers = controllers - } - if err := control.initialize(); err != nil { return nil, err } @@ -326,12 +238,7 @@ func New(path string, resources *cgroups.Resources) (*CgroupControl, error) { // NewSystemd creates a new cgroup control. func NewSystemd(path string, resources *cgroups.Resources) (*CgroupControl, error) { - cgroup2, err := IsCgroup2UnifiedMode() - if err != nil { - return nil, err - } control := &CgroupControl{ - cgroup2: cgroup2, systemd: true, config: &cgroups.Cgroup{ Path: path, @@ -345,45 +252,12 @@ func NewSystemd(path string, resources *cgroups.Resources) (*CgroupControl, erro // Load loads an existing cgroup control. func Load(path string) (*CgroupControl, error) { - cgroup2, err := IsCgroup2UnifiedMode() - if err != nil { - return nil, err - } control := &CgroupControl{ - cgroup2: cgroup2, systemd: false, config: &cgroups.Cgroup{ Path: path, }, } - if !cgroup2 { - controllers, err := getAvailableControllers(handlers, false) - if err != nil { - return nil, err - } - control.additionalControllers = controllers - } - if !cgroup2 { - oneExists := false - // check that the cgroup exists at least under one controller - for name := range handlers { - p := control.getCgroupv1Path(name) - if err := fileutils.Exists(p); err == nil { - oneExists = true - break - } - } - - // if there is no controller at all, raise an error - if !oneExists { - if unshare.IsRootless() { - return nil, ErrCgroupV1Rootless - } - // compatible with the error code - // used by containerd/cgroups - return nil, ErrCgroupDeleted - } - } return control, nil } @@ -448,26 +322,7 @@ func (c *CgroupControl) DeleteByPathConn(path string, conn *systemdDbus.Conn) er if c.systemd { return systemdDestroyConn(path, conn) } - if c.cgroup2 { - return rmDirRecursively(filepath.Join(cgroupRoot, c.config.Path)) - } - var lastError error - for _, h := range handlers { - if err := h.Destroy(c); err != nil { - lastError = err - } - } - - for _, ctr := range c.additionalControllers { - if ctr.symlink { - continue - } - p := c.getCgroupv1Path(ctr.name) - if err := rmDirRecursively(p); err != nil { - lastError = fmt.Errorf("remove %s: %w", p, err) - } - } - return lastError + return rmDirRecursively(filepath.Join(cgroupRoot, c.config.Path)) } // DeleteByPath deletes the specified cgroup path. @@ -495,32 +350,8 @@ func (c *CgroupControl) Update(resources *cgroups.Resources) error { // AddPid moves the specified pid to the cgroup. func (c *CgroupControl) AddPid(pid int) error { - pidString := []byte(fmt.Sprintf("%d\n", pid)) - - if c.cgroup2 { - path := filepath.Join(cgroupRoot, c.config.Path) - return fs2.CreateCgroupPath(path, c.config) - } - - names := slices.Collect(maps.Keys(handlers)) - - for _, c := range c.additionalControllers { - if !c.symlink { - names = append(names, c.name) - } - } - - for _, n := range names { - // If we aren't using cgroup2, we won't write correctly to unified hierarchy - if !c.cgroup2 && n == "unified" { - continue - } - p := filepath.Join(c.getCgroupv1Path(n), "tasks") - if err := os.WriteFile(p, pidString, 0o644); err != nil { - return fmt.Errorf("write %s: %w", p, err) - } - } - return nil + path := filepath.Join(cgroupRoot, c.config.Path) + return fs2.CreateCgroupPath(path, c.config) } // Stat returns usage statistics for the cgroup. @@ -573,23 +404,6 @@ func readCgroup2MapFile(ctr *CgroupControl, name string) (map[string][]string, e return readCgroupMapPath(p) } -func (c *CgroupControl) createCgroupDirectory(controller string) (bool, error) { - cPath := c.getCgroupv1Path(controller) - err := fileutils.Exists(cPath) - if err == nil { - return false, nil - } - - if !errors.Is(err, os.ErrNotExist) { - return false, err - } - - if err := os.MkdirAll(cPath, 0o755); err != nil { - return false, fmt.Errorf("creating cgroup for %s: %w", controller, err) - } - return true, nil -} - var TestMode bool func createCgroupv2Path(path string) (deferredError error) { @@ -671,32 +485,6 @@ func cleanString(s string) string { return strings.Trim(s, "\n") } -func readAcct(ctr *CgroupControl, name string) (uint64, error) { - p := filepath.Join(ctr.getCgroupv1Path(CPUAcct), name) - return readFileAsUint64(p) -} - -func readAcctList(ctr *CgroupControl, name string) ([]uint64, error) { - p := filepath.Join(ctr.getCgroupv1Path(CPUAcct), name) - data, err := os.ReadFile(p) - if err != nil { - return nil, err - } - r := []uint64{} - for s := range strings.SplitSeq(string(data), " ") { - s = cleanString(s) - if s == "" { - break - } - v, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return nil, fmt.Errorf("parsing %s: %w", s, err) - } - r = append(r, v) - } - return r, nil -} - func cpusetCopyFromParent(path string, cgroupv2 bool) error { for _, file := range []string{"cpuset.cpus", "cpuset.mems"} { if _, err := cpusetCopyFileFromParent(path, file, cgroupv2); err != nil { @@ -739,15 +527,6 @@ func cpusetCopyFileFromParent(dir, file string, cgroupv2 bool) ([]byte, error) { // SystemCPUUsage returns the system usage for all the cgroups. func SystemCPUUsage() (uint64, error) { - cgroupv2, err := IsCgroup2UnifiedMode() - if err != nil { - return 0, err - } - if !cgroupv2 { - p := filepath.Join(cgroupRoot, CPUAcct, "cpuacct.usage") - return readFileAsUint64(p) - } - files, err := os.ReadDir(cgroupRoot) if err != nil { return 0, err @@ -800,11 +579,6 @@ func UserConnection(uid int) (*systemdDbus.Conn, error) { func UserOwnsCurrentSystemdCgroup() (bool, error) { uid := os.Geteuid() - cgroup2, err := IsCgroup2UnifiedMode() - if err != nil { - return false, err - } - f, err := os.Open("/proc/self/cgroup") if err != nil { return false, err @@ -822,20 +596,11 @@ func UserOwnsCurrentSystemdCgroup() (bool, error) { // If we are on a cgroup v2 system and there are cgroup v1 controllers // mounted, ignore them when the current process is at the root cgroup. - if cgroup2 && parts[1] != "" && parts[2] == "/" { + if parts[1] != "" && parts[2] == "/" { continue } - var cgroupPath string - - if cgroup2 { - cgroupPath = filepath.Join(cgroupRoot, parts[2]) - } else { - if parts[1] != "name=systemd" { - continue - } - cgroupPath = filepath.Join(cgroupRoot, "systemd", parts[2]) - } + cgroupPath := filepath.Join(cgroupRoot, parts[2]) st, err := os.Stat(cgroupPath) if err != nil { diff --git a/vendor/go.podman.io/common/pkg/cgroups/cgroups_unsupported.go b/vendor/go.podman.io/common/pkg/cgroups/cgroups_unsupported.go index 5940dc82d94..fc87f168807 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/cgroups_unsupported.go +++ b/vendor/go.podman.io/common/pkg/cgroups/cgroups_unsupported.go @@ -2,7 +2,7 @@ package cgroups -// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode. +// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 unified mode. func IsCgroup2UnifiedMode() (bool, error) { return false, nil } diff --git a/vendor/go.podman.io/common/pkg/cgroups/cpu_linux.go b/vendor/go.podman.io/common/pkg/cgroups/cpu_linux.go index 899a86d5d39..beecd5a0ede 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/cpu_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/cpu_linux.go @@ -3,8 +3,6 @@ package cgroups import ( - "errors" - "os" "path/filepath" "strconv" @@ -23,23 +21,16 @@ func getCPUHandler() *linuxCPUHandler { // Apply set the specified constraints. func (c *linuxCPUHandler) Apply(ctr *CgroupControl, res *cgroups.Resources) error { - if ctr.cgroup2 { - man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path)) - if err != nil { - return err - } - return man.Set(res) + man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path)) + if err != nil { + return err } - path := filepath.Join(cgroupRoot, CPU, ctr.config.Path) - return c.CPU.Set(path, res) + return man.Set(res) } // Create the cgroup. func (c *linuxCPUHandler) Create(ctr *CgroupControl) (bool, error) { - if ctr.cgroup2 { - return false, nil - } - return ctr.createCgroupDirectory(CPU) + return false, nil } // Destroy the cgroup. @@ -51,47 +42,23 @@ func (c *linuxCPUHandler) Destroy(ctr *CgroupControl) error { func (c *linuxCPUHandler) Stat(ctr *CgroupControl, m *cgroups.Stats) error { var err error cpu := cgroups.CpuStats{} - if ctr.cgroup2 { - values, err := readCgroup2MapFile(ctr, "cpu.stat") + values, err := readCgroup2MapFile(ctr, "cpu.stat") + if err != nil { + return err + } + if val, found := values["usage_usec"]; found { + cpu.CpuUsage.TotalUsage, err = strconv.ParseUint(cleanString(val[0]), 10, 64) if err != nil { return err } - if val, found := values["usage_usec"]; found { - cpu.CpuUsage.TotalUsage, err = strconv.ParseUint(cleanString(val[0]), 10, 64) - if err != nil { - return err - } - cpu.CpuUsage.UsageInKernelmode *= 1000 - } - if val, found := values["system_usec"]; found { - cpu.CpuUsage.UsageInKernelmode, err = strconv.ParseUint(cleanString(val[0]), 10, 64) - if err != nil { - return err - } - cpu.CpuUsage.TotalUsage *= 1000 - } - } else { - cpu.CpuUsage.TotalUsage, err = readAcct(ctr, "cpuacct.usage") - if err != nil { - if !errors.Is(err, os.ErrNotExist) { - return err - } - cpu.CpuUsage.TotalUsage = 0 - } - cpu.CpuUsage.UsageInKernelmode, err = readAcct(ctr, "cpuacct.usage_sys") - if err != nil { - if !errors.Is(err, os.ErrNotExist) { - return err - } - cpu.CpuUsage.UsageInKernelmode = 0 - } - cpu.CpuUsage.PercpuUsage, err = readAcctList(ctr, "cpuacct.usage_percpu") + cpu.CpuUsage.UsageInKernelmode *= 1000 + } + if val, found := values["system_usec"]; found { + cpu.CpuUsage.UsageInKernelmode, err = strconv.ParseUint(cleanString(val[0]), 10, 64) if err != nil { - if !errors.Is(err, os.ErrNotExist) { - return err - } - cpu.CpuUsage.PercpuUsage = nil + return err } + cpu.CpuUsage.TotalUsage *= 1000 } m.CpuStats = cpu return nil diff --git a/vendor/go.podman.io/common/pkg/cgroups/cpuset_linux.go b/vendor/go.podman.io/common/pkg/cgroups/cpuset_linux.go index 10b2298e12a..c13f082911a 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/cpuset_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/cpuset_linux.go @@ -20,28 +20,17 @@ func getCpusetHandler() *linuxCpusetHandler { // Apply set the specified constraints. func (c *linuxCpusetHandler) Apply(ctr *CgroupControl, res *cgroups.Resources) error { - if ctr.cgroup2 { - man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path)) - if err != nil { - return err - } - return man.Set(res) + man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path)) + if err != nil { + return err } - path := filepath.Join(cgroupRoot, CPUset, ctr.config.Path) - return c.CPUSet.Set(path, res) + return man.Set(res) } // Create the cgroup. func (c *linuxCpusetHandler) Create(ctr *CgroupControl) (bool, error) { - if ctr.cgroup2 { - path := filepath.Join(cgroupRoot, ctr.config.Path) - return true, cpusetCopyFromParent(path, true) - } - created, err := ctr.createCgroupDirectory(CPUset) - if !created || err != nil { - return created, err - } - return true, cpusetCopyFromParent(ctr.getCgroupv1Path(CPUset), false) + path := filepath.Join(cgroupRoot, ctr.config.Path) + return true, cpusetCopyFromParent(path, true) } // Destroy the cgroup. diff --git a/vendor/go.podman.io/common/pkg/cgroups/memory_linux.go b/vendor/go.podman.io/common/pkg/cgroups/memory_linux.go index 7f619003080..c54cb2c91da 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/memory_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/memory_linux.go @@ -20,23 +20,16 @@ func getMemoryHandler() *linuxMemHandler { // Apply set the specified constraints. func (c *linuxMemHandler) Apply(ctr *CgroupControl, res *cgroups.Resources) error { - if ctr.cgroup2 { - man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path)) - if err != nil { - return err - } - return man.Set(res) + man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path)) + if err != nil { + return err } - path := filepath.Join(cgroupRoot, Memory, ctr.config.Path) - return c.Mem.Set(path, res) + return man.Set(res) } // Create the cgroup. func (c *linuxMemHandler) Create(ctr *CgroupControl) (bool, error) { - if ctr.cgroup2 { - return false, nil - } - return ctr.createCgroupDirectory(Memory) + return false, nil } // Destroy the cgroup. @@ -52,48 +45,25 @@ func (c *linuxMemHandler) Stat(ctr *CgroupControl, m *cgroups.Stats) error { var memoryRoot string var limitFilename string - if ctr.cgroup2 { - memoryRoot = filepath.Join(cgroupRoot, ctr.config.Path) - limitFilename = "memory.max" - - // Read memory.current - current, err := readFileAsUint64(filepath.Join(memoryRoot, "memory.current")) - if err != nil { - return err - } - - // Read inactive_file from memory.stat - inactiveFile, err := readFileByKeyAsUint64(filepath.Join(memoryRoot, "memory.stat"), "inactive_file") - if err != nil { - return err - } - - // Docker calculation: memory.current - memory.stat['inactive_file'] - memUsage.Usage.Usage = 0 - if inactiveFile < current { - memUsage.Usage.Usage = current - inactiveFile - } - } else { - memoryRoot = ctr.getCgroupv1Path(Memory) - limitFilename = "memory.limit_in_bytes" - - // Read memory.usage_in_bytes - usageInBytes, err := readFileAsUint64(filepath.Join(memoryRoot, "memory.usage_in_bytes")) - if err != nil { - return err - } - - // Read total_inactive_file from memory.stat - totalInactiveFile, err := readFileByKeyAsUint64(filepath.Join(memoryRoot, "memory.stat"), "total_inactive_file") - if err != nil { - return err - } - - // Docker calculation: memory.usage_in_bytes - memory.stat['total_inactive_file'] - memUsage.Usage.Usage = 0 - if totalInactiveFile < usageInBytes { - memUsage.Usage.Usage = usageInBytes - totalInactiveFile - } + memoryRoot = filepath.Join(cgroupRoot, ctr.config.Path) + limitFilename = "memory.max" + + // Read memory.current + current, err := readFileAsUint64(filepath.Join(memoryRoot, "memory.current")) + if err != nil { + return err + } + + // Read inactive_file from memory.stat + inactiveFile, err := readFileByKeyAsUint64(filepath.Join(memoryRoot, "memory.stat"), "inactive_file") + if err != nil { + return err + } + + // Docker calculation: memory.current - memory.stat['inactive_file'] + memUsage.Usage.Usage = 0 + if inactiveFile < current { + memUsage.Usage.Usage = current - inactiveFile } memUsage.Usage.Limit, err = readFileAsUint64(filepath.Join(memoryRoot, limitFilename)) diff --git a/vendor/go.podman.io/common/pkg/cgroups/pids_linux.go b/vendor/go.podman.io/common/pkg/cgroups/pids_linux.go index 82202830e02..c7881dccd2a 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/pids_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/pids_linux.go @@ -20,24 +20,16 @@ func getPidsHandler() *linuxPidHandler { // Apply set the specified constraints. func (c *linuxPidHandler) Apply(ctr *CgroupControl, res *cgroups.Resources) error { - if ctr.cgroup2 { - man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path)) - if err != nil { - return err - } - return man.Set(res) + man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path)) + if err != nil { + return err } - - path := filepath.Join(cgroupRoot, Pids, ctr.config.Path) - return c.Pid.Set(path, res) + return man.Set(res) } // Create the cgroup. func (c *linuxPidHandler) Create(ctr *CgroupControl) (bool, error) { - if ctr.cgroup2 { - return false, nil - } - return ctr.createCgroupDirectory(Pids) + return false, nil } // Destroy the cgroup. @@ -52,12 +44,7 @@ func (c *linuxPidHandler) Stat(ctr *CgroupControl, m *cgroups.Stats) error { return nil } - var PIDRoot string - if ctr.cgroup2 { - PIDRoot = filepath.Join(cgroupRoot, ctr.config.Path) - } else { - PIDRoot = ctr.getCgroupv1Path(Pids) - } + PIDRoot := filepath.Join(cgroupRoot, ctr.config.Path) current, err := readFileAsUint64(filepath.Join(PIDRoot, "pids.current")) if err != nil { diff --git a/vendor/go.podman.io/common/pkg/cgroups/systemd_linux.go b/vendor/go.podman.io/common/pkg/cgroups/systemd_linux.go index c0bc6d9d384..15ba00b139c 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/systemd_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/systemd_linux.go @@ -32,13 +32,7 @@ func systemdCreate(resources *cgroups.Resources, path string, c *systemdDbus.Con systemdDbus.PropDescription("cgroup " + name), systemdDbus.PropWants(slice), } - var ioString string - v2, _ := IsCgroup2UnifiedMode() - if v2 { - ioString = "IOAccounting" - } else { - ioString = "BlockIOAccounting" - } + ioString := "IOAccounting" pMap := map[string]bool{ "DefaultDependencies": false, "MemoryAccounting": true, @@ -57,7 +51,7 @@ func systemdCreate(resources *cgroups.Resources, path string, c *systemdDbus.Con properties = append(properties, p) } - uMap, sMap, bMap, iMap, structMap, err := resourcesToProps(resources, v2) + uMap, sMap, bMap, iMap, structMap, err := resourcesToProps(resources, true) if err != nil { lastError = err continue @@ -176,13 +170,8 @@ func resourcesToProps(res *cgroups.Resources, v2 bool) (map[string]uint64, map[s if res.CpuShares != 0 { // convert from shares to weight. weight only supports 1-10000 - v2, _ := IsCgroup2UnifiedMode() - if v2 { - wt := (1 + ((res.CpuShares-2)*9999)/262142) - uMap["CPUWeight"] = wt - } else { - uMap["CPUShares"] = res.CpuShares - } + wt := (1 + ((res.CpuShares-2)*9999)/262142) + uMap["CPUWeight"] = wt } // CPUSet diff --git a/vendor/go.podman.io/common/pkg/cgroups/utils_linux.go b/vendor/go.podman.io/common/pkg/cgroups/utils_linux.go index a1b18a96952..68034cc45c4 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/utils_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/utils_linux.go @@ -15,7 +15,6 @@ import ( "github.com/opencontainers/cgroups" "github.com/sirupsen/logrus" - "go.podman.io/storage/pkg/fileutils" "golang.org/x/sys/unix" ) @@ -207,11 +206,6 @@ func MoveUnderCgroup(cgroup, subtree string, processes []uint32) error { } defer f.Close() - unifiedMode, err := IsCgroup2UnifiedMode() - if err != nil { - return err - } - scanner := bufio.NewScanner(f) for scanner.Scan() { line := scanner.Text() @@ -221,24 +215,12 @@ func MoveUnderCgroup(cgroup, subtree string, processes []uint32) error { } // root cgroup, skip it - if parts[2] == "/" && (!unifiedMode || parts[1] != "") { + if parts[2] == "/" && parts[1] != "" { continue } cgroupRoot := "/sys/fs/cgroup" - // Special case the unified mount on hybrid cgroup and named hierarchies. - // This works on Fedora 31, but we should really parse the mounts to see - // where the cgroup hierarchy is mounted. - if parts[1] == "" && !unifiedMode { - // If it is not using unified mode, the cgroup v2 hierarchy is - // usually mounted under /sys/fs/cgroup/unified - cgroupRoot = filepath.Join(cgroupRoot, "unified") - - // Ignore the unified mount if it doesn't exist - if err := fileutils.Exists(cgroupRoot); err != nil && os.IsNotExist(err) { - continue - } - } else if parts[1] != "" { + if parts[1] != "" { // Assume the controller is mounted at /sys/fs/cgroup/$CONTROLLER. controller := strings.TrimPrefix(parts[1], "name=") cgroupRoot = filepath.Join(cgroupRoot, controller) @@ -292,15 +274,6 @@ var ( // it is running in the root cgroup on a system that uses cgroupv2. func MaybeMoveToSubCgroup() error { maybeMoveToSubCgroupSync.Do(func() { - unifiedMode, err := IsCgroup2UnifiedMode() - if err != nil { - maybeMoveToSubCgroupSyncErr = err - return - } - if !unifiedMode { - maybeMoveToSubCgroupSyncErr = nil - return - } cgroup, err := GetOwnCgroup() if err != nil { maybeMoveToSubCgroupSyncErr = err diff --git a/vendor/go.podman.io/common/pkg/config/default.go b/vendor/go.podman.io/common/pkg/config/default.go index 3bf0bc16929..8548ec5d7a6 100644 --- a/vendor/go.podman.io/common/pkg/config/default.go +++ b/vendor/go.podman.io/common/pkg/config/default.go @@ -15,7 +15,6 @@ import ( "go.podman.io/common/internal/attributedstring" nettypes "go.podman.io/common/libnetwork/types" "go.podman.io/common/pkg/apparmor" - "go.podman.io/common/pkg/cgroupv2" "go.podman.io/storage/pkg/fileutils" "go.podman.io/storage/pkg/homedir" "go.podman.io/storage/pkg/unshare" @@ -230,10 +229,7 @@ func defaultConfig() (*Config, error) { } } - cgroupNS := "host" - if cgroup2, _ := cgroupv2.Enabled(); cgroup2 { - cgroupNS = "private" - } + cgroupNS := "private" return &Config{ Containers: ContainersConfig{ @@ -652,12 +648,7 @@ func (c *Config) PidsLimit() int64 { if c.Engine.CgroupManager != SystemdCgroupsManager { return 0 } - cgroup2, _ := cgroupv2.Enabled() - if !cgroup2 { - return 0 - } } - return c.Containers.PidsLimit } diff --git a/vendor/go.podman.io/common/pkg/config/systemd.go b/vendor/go.podman.io/common/pkg/config/systemd.go index e7c15b59094..120656528f0 100644 --- a/vendor/go.podman.io/common/pkg/config/systemd.go +++ b/vendor/go.podman.io/common/pkg/config/systemd.go @@ -7,7 +7,6 @@ import ( "path/filepath" "sync" - "go.podman.io/common/pkg/cgroupv2" "go.podman.io/common/pkg/systemd" "go.podman.io/storage/pkg/unshare" ) @@ -26,8 +25,7 @@ func defaultCgroupManager() string { if !useSystemd() { return CgroupfsCgroupsManager } - enabled, err := cgroupv2.Enabled() - if err == nil && !enabled && unshare.IsRootless() { + if unshare.IsRootless() { return CgroupfsCgroupsManager } diff --git a/vendor/go.podman.io/common/pkg/sysinfo/sysinfo_linux.go b/vendor/go.podman.io/common/pkg/sysinfo/sysinfo_linux.go index ea98d49481c..efb0a8ce6b3 100644 --- a/vendor/go.podman.io/common/pkg/sysinfo/sysinfo_linux.go +++ b/vendor/go.podman.io/common/pkg/sysinfo/sysinfo_linux.go @@ -9,7 +9,6 @@ import ( "github.com/opencontainers/cgroups" "github.com/sirupsen/logrus" - "go.podman.io/common/pkg/cgroupv2" "go.podman.io/storage/pkg/fileutils" "golang.org/x/sys/unix" ) @@ -41,7 +40,6 @@ func New(quiet bool) *SysInfo { sysInfo.cgroupCPUInfo = checkCgroupCPU(cgMounts, quiet) sysInfo.cgroupBlkioInfo = checkCgroupBlkioInfo(cgMounts, quiet) sysInfo.cgroupCpusetInfo = checkCgroupCpusetInfo(cgMounts, quiet) - sysInfo.cgroupPids = checkCgroupPids(cgMounts, quiet) } _, ok := cgMounts["devices"] @@ -227,28 +225,6 @@ func checkCgroupCpusetInfo(cgMounts map[string]string, quiet bool) cgroupCpusetI } } -// checkCgroupPids reads the pids information from the pids cgroup mount point. -func checkCgroupPids(cgMounts map[string]string, quiet bool) cgroupPids { - cgroup2, err := cgroupv2.Enabled() - if err != nil { - logrus.Errorf("Failed to check cgroups version: %v", err) - return cgroupPids{} - } - if !cgroup2 { - _, ok := cgMounts["pids"] - if !ok { - if !quiet { - logrus.Warn("Unable to find pids cgroup in mounts") - } - return cgroupPids{} - } - } - - return cgroupPids{ - PidsLimit: true, - } -} - func cgroupEnabled(mountPoint, name string) bool { err := fileutils.Exists(path.Join(mountPoint, name)) return err == nil 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 a189cfbe052..82e3b8014cc 100644 --- a/vendor/go.podman.io/common/pkg/systemd/systemd_linux.go +++ b/vendor/go.podman.io/common/pkg/systemd/systemd_linux.go @@ -88,11 +88,7 @@ func MovePauseProcessToScope(pausePidPath string) { } if err != nil { - unified, err2 := cgroups.IsCgroup2UnifiedMode() - if err2 != nil { - logrus.Warnf("Failed to detect if running with cgroup unified: %v", err) - } - if RunsOnSystemd() && unified { + if RunsOnSystemd() { logrus.Warnf("Failed to add pause process to systemd sandbox cgroup: %v", err) } else { logrus.Debugf("Failed to add pause process to systemd sandbox cgroup: %v", err) diff --git a/vendor/go.podman.io/common/version/version.go b/vendor/go.podman.io/common/version/version.go index bdfd10c645a..4a2be1fe1e2 100644 --- a/vendor/go.podman.io/common/version/version.go +++ b/vendor/go.podman.io/common/version/version.go @@ -1,4 +1,4 @@ package version // Version is the version of the build. -const Version = "0.66.0-dev" +const Version = "0.67.0-dev" diff --git a/vendor/go.podman.io/image/v5/version/version.go b/vendor/go.podman.io/image/v5/version/version.go index ac62a17cec9..71a957fc689 100644 --- a/vendor/go.podman.io/image/v5/version/version.go +++ b/vendor/go.podman.io/image/v5/version/version.go @@ -11,7 +11,7 @@ const ( VersionPatch = 0 // VersionDev indicates development branch. Releases will be empty string. - VersionDev = "-dev" + VersionDev = "" ) // Version is the specification version that the package types support. diff --git a/vendor/go.podman.io/storage/VERSION b/vendor/go.podman.io/storage/VERSION index 8a37c6cd9c5..91951fd8ad7 100644 --- a/vendor/go.podman.io/storage/VERSION +++ b/vendor/go.podman.io/storage/VERSION @@ -1 +1 @@ -1.61.0-dev +1.61.0 diff --git a/vendor/modules.txt b/vendor/modules.txt index e863388b57f..8ced72c784a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -78,8 +78,8 @@ github.com/containernetworking/cni/pkg/version # github.com/containernetworking/plugins v1.8.0 ## explicit; go 1.24.2 github.com/containernetworking/plugins/pkg/ns -# github.com/containers/buildah v1.41.1-0.20250829135344-3367a9bc2c9f -## explicit; go 1.23.3 +# github.com/containers/buildah v1.41.1-0.20250829135344-3367a9bc2c9f => github.com/lsm5/buildah v0.0.0-20251017145416-1c35ea0ae809 +## explicit; go 1.24.2 github.com/containers/buildah github.com/containers/buildah/bind github.com/containers/buildah/chroot @@ -128,8 +128,8 @@ github.com/containers/libhvee/pkg/wmiext # github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 ## explicit github.com/containers/libtrust -# github.com/containers/luksy v0.0.0-20250714213221-8fccf784694e -## explicit; go 1.23.0 +# github.com/containers/luksy v0.0.0-20250910190358-2cf5bc928957 +## explicit; go 1.24.0 github.com/containers/luksy # github.com/containers/ocicrypt v1.2.1 ## explicit; go 1.22 @@ -236,9 +236,7 @@ github.com/docker/docker/api/types/time github.com/docker/docker/api/types/versions github.com/docker/docker/api/types/volume github.com/docker/docker/client -github.com/docker/docker/pkg/archive github.com/docker/docker/pkg/homedir -github.com/docker/docker/pkg/idtools github.com/docker/docker/pkg/jsonmessage github.com/docker/docker/pkg/meminfo github.com/docker/docker/pkg/namesgenerator @@ -274,8 +272,8 @@ github.com/felixge/httpsnoop ## explicit; go 1.17 github.com/fsnotify/fsnotify github.com/fsnotify/fsnotify/internal -# github.com/fsouza/go-dockerclient v1.12.1 -## explicit; go 1.23 +# github.com/fsouza/go-dockerclient v1.12.2 +## explicit; go 1.24.0 github.com/fsouza/go-dockerclient # github.com/go-jose/go-jose/v4 v4.0.5 ## explicit; go 1.21 @@ -428,8 +426,8 @@ github.com/miekg/pkcs11 # github.com/mistifyio/go-zfs/v3 v3.1.0 ## explicit; go 1.14 github.com/mistifyio/go-zfs/v3 -# github.com/moby/buildkit v0.23.2 -## explicit; go 1.23.0 +# github.com/moby/buildkit v0.25.1 +## explicit; go 1.24.0 github.com/moby/buildkit/frontend/dockerfile/command github.com/moby/buildkit/frontend/dockerfile/parser github.com/moby/buildkit/frontend/dockerfile/shell @@ -553,7 +551,7 @@ github.com/opencontainers/runtime-tools/validate/capabilities github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label github.com/opencontainers/selinux/pkg/pwalkdir -# github.com/openshift/imagebuilder v1.2.16-0.20250828154754-e22ebd3ff511 +# github.com/openshift/imagebuilder v1.2.17 ## explicit; go 1.23.3 github.com/openshift/imagebuilder github.com/openshift/imagebuilder/dockerfile/command @@ -742,7 +740,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.65.1-0.20251016162239-c4c5e00ad22d +# go.podman.io/common v0.65.1-0.20251016162239-c4c5e00ad22d => github.com/lsm5/container-libs/common v0.0.0-20251017191154-e63ca540eafe ## explicit; go 1.24.2 go.podman.io/common/internal go.podman.io/common/internal/attributedstring @@ -812,7 +810,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.37.1-0.20251016133615-aa970d2c7532 +# go.podman.io/image/v5 v5.38.0 ## explicit; go 1.24.0 go.podman.io/image/v5/copy go.podman.io/image/v5/directory @@ -886,7 +884,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.60.1-0.20251016133615-aa970d2c7532 +# go.podman.io/storage v1.61.0 ## explicit; go 1.24.0 go.podman.io/storage go.podman.io/storage/drivers @@ -1191,3 +1189,5 @@ tags.cncf.io/container-device-interface/pkg/parser # tags.cncf.io/container-device-interface/specs-go v1.0.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-20251017191154-e63ca540eafe +# github.com/containers/buildah => github.com/lsm5/buildah v0.0.0-20251017145416-1c35ea0ae809 From a8817a53491ba74ac640138694bcd01435aeb047 Mon Sep 17 00:00:00 2001 From: Lokesh Mandvekar Date: Fri, 10 Oct 2025 11:21:43 -0400 Subject: [PATCH 2/4] test: remove cgroupsv1 tests and skips Keeping SkipIfCgroupV2 and skip_if_cgroupsv2 just in case we need them in future. Signed-off-by: Lokesh Mandvekar --- test/apiv2/25-containersMore.at | 9 ---- test/apiv2/40-pods.at | 41 +++++------------ test/e2e/common_test.go | 31 +++++-------- test/e2e/containers_conf_test.go | 9 ---- test/e2e/pod_create_test.go | 7 --- test/e2e/pod_stats_test.go | 4 -- test/e2e/run_cgroup_parent_test.go | 2 - test/e2e/run_cpu_test.go | 3 -- test/e2e/run_memory_test.go | 18 -------- test/e2e/run_test.go | 51 ++++++++++----------- test/e2e/stats_test.go | 4 -- test/e2e/systemd_test.go | 5 --- test/e2e/update_test.go | 57 ++---------------------- test/system/030-run.bats | 21 +++------ test/system/170-run-userns.bats | 2 - test/system/200-pod.bats | 2 - test/system/250-systemd.bats | 7 --- test/system/252-quadlet.bats | 1 - test/system/253-podman-quadlet.bats | 1 - test/system/400-unprivileged-access.bats | 1 - test/system/410-selinux.bats | 4 -- test/system/420-cgroups.bats | 3 -- test/system/500-networking.bats | 4 -- test/system/600-completion.bats | 20 +-------- test/system/helpers.bash | 35 --------------- 25 files changed, 60 insertions(+), 282 deletions(-) diff --git a/test/apiv2/25-containersMore.at b/test/apiv2/25-containersMore.at index a7679817add..47a922d6370 100644 --- a/test/apiv2/25-containersMore.at +++ b/test/apiv2/25-containersMore.at @@ -28,15 +28,6 @@ if root || have_cgroupsv2; then .Name=foo t POST libpod/containers/foo/unpause 204 -else - # cgroupsv1 rootless : pause and unpause are not supported in cgroups v1 rootless - t POST libpod/containers/foo/pause 500 \ - .cause="this container does not have a cgroup" \ - .message~".*pause containers on rootless containers with cgroup V1" - - t POST libpod/containers/foo/unpause 500 \ - .cause="container state improper" \ - .message~".*is not paused, can't unpause: container state improper" fi t GET libpod/containers/foo/json 200 \ diff --git a/test/apiv2/40-pods.at b/test/apiv2/40-pods.at index b50cb1686ed..6cc73783a2f 100644 --- a/test/apiv2/40-pods.at +++ b/test/apiv2/40-pods.at @@ -47,14 +47,7 @@ t POST libpod/pods/fakename/start 404 \ .cause="no such pod" \ .message="no pod with name or ID fakename found: no such pod" -if root || have_cgroupsv2; then - t POST libpod/pods/foo/pause 200 -else - # Rootless cgroupsv1 : unsupported - t POST "libpod/pods/foo/pause (rootless cgroups v1)" 500 \ - .cause="this container does not have a cgroup" \ - .message~".*pause pods containing rootless containers with cgroup V1" -fi +t POST libpod/pods/foo/pause 200 t POST libpod/pods/foo/unpause 200 t POST "libpod/pods/foo/unpause (2nd unpause in a row)" 200 t POST "libpod/pods/fakename/unpause" 404\ @@ -108,28 +101,21 @@ t POST libpod/pods/bar/stop?t=1 200 \ t POST libpod/pods/bar/start 200 -if root || have_cgroupsv2; then - t GET libpod/pods/stats?all=true 200 - is $(jq '. | length' <<<"$output") 3 "stats?all=true: number of records found" +t GET libpod/pods/stats?all=true 200 +is $(jq '. | length' <<<"$output") 3 "stats?all=true: number of records found" - t GET libpod/pods/stats?namesOrIDs=foo 200 - is $(jq '. | length' <<<"$output") 1 "stats?namesOrIDs=foo: number of records found" +t GET libpod/pods/stats?namesOrIDs=foo 200 +is $(jq '. | length' <<<"$output") 1 "stats?namesOrIDs=foo: number of records found" - t GET libpod/pods/stats?namesOrIDs=fakename 404 \ - .cause="no such pod" \ +t GET libpod/pods/stats?namesOrIDs=fakename 404 \ + .cause="no such pod" \ .message="unable to get list of pods: no pod with name or ID fakename found: no such pod" - t GET "libpod/pods/stats?all=true&namesOrIDs=foo" 500 \ - .cause="--all, --latest and arguments cannot be used together" \ - .message="--all, --latest and arguments cannot be used together" +t GET "libpod/pods/stats?all=true&namesOrIDs=foo" 500 \ + .cause="--all, --latest and arguments cannot be used together" \ + .message="--all, --latest and arguments cannot be used together" - t DELETE libpod/pods/bar?force=true 200 -else - # Rootless cgroupsv1 : libpod/pods/stats is unsupported - t GET libpod/pods/stats?all=true 500 \ - .cause="pod stats is not supported in rootless mode without cgroups v2" \ - .message~"pod stats is not supported in rootless mode without cgroups v2" -fi +t DELETE libpod/pods/bar?force=true 200 # test the fake name t GET libpod/pods/fakename/top 404 \ @@ -161,10 +147,7 @@ t DELETE libpod/pods/foo 200 t DELETE "libpod/pods/foo (pod has already been deleted)" 404 # Expect this to time out -if root || have_cgroupsv2; then - # Rootless cgroupsv1 : libpod/pods/stats is unsupported - APIV2_TEST_EXPECT_TIMEOUT=5 t GET "libpod/pods/stats?stream=true&delay=1" 999 -fi +APIV2_TEST_EXPECT_TIMEOUT=5 t GET "libpod/pods/stats?stream=true&delay=1" 999 podman pod create --name=specgen diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 2e45559a553..e969c592eef 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -784,7 +784,7 @@ func (p *PodmanTestIntegration) RunTopContainer(name string) *PodmanSessionInteg // runs top. If the name passed != "", it will have a name, command args can also be passed in func (p *PodmanTestIntegration) RunTopContainerWithArgs(name string, args []string) *PodmanSessionIntegration { // In proxy environment, some tests need to the --http-proxy=false option (#16684) - var podmanArgs = []string{"run", "--http-proxy=false"} + podmanArgs := []string{"run", "--http-proxy=false"} if name != "" { podmanArgs = append(podmanArgs, "--name", name) } @@ -803,7 +803,7 @@ func (p *PodmanTestIntegration) RunTopContainerWithArgs(name string, args []stri // RunLsContainer runs a simple container in the background that // simply runs ls. If the name passed != "", it will have a name func (p *PodmanTestIntegration) RunLsContainer(name string) (*PodmanSessionIntegration, int, string) { - var podmanArgs = []string{"run"} + podmanArgs := []string{"run"} if name != "" { podmanArgs = append(podmanArgs, "--name", name) } @@ -822,7 +822,7 @@ func (p *PodmanTestIntegration) RunLsContainer(name string) (*PodmanSessionInteg // RunNginxWithHealthCheck runs the alpine nginx container with an optional name and adds a healthcheck into it func (p *PodmanTestIntegration) RunNginxWithHealthCheck(name string) (*PodmanSessionIntegration, string) { - var podmanArgs = []string{"run"} + podmanArgs := []string{"run"} if name != "" { podmanArgs = append(podmanArgs, "--name", name) } @@ -835,7 +835,7 @@ func (p *PodmanTestIntegration) RunNginxWithHealthCheck(name string) (*PodmanSes // RunContainerWithNetworkTest runs the fedoraMinimal curl with the specified network mode. func (p *PodmanTestIntegration) RunContainerWithNetworkTest(mode string) *PodmanSessionIntegration { - var podmanArgs = []string{"run"} + podmanArgs := []string{"run"} if mode != "" { podmanArgs = append(podmanArgs, "--network", mode) } @@ -845,7 +845,7 @@ func (p *PodmanTestIntegration) RunContainerWithNetworkTest(mode string) *Podman } func (p *PodmanTestIntegration) RunLsContainerInPod(name, pod string) (*PodmanSessionIntegration, int, string) { - var podmanArgs = []string{"run", "--pod", pod} + podmanArgs := []string{"run", "--pod", pod} if name != "" { podmanArgs = append(podmanArgs, "--name", name) } @@ -1006,7 +1006,7 @@ func (s *PodmanSessionIntegration) InspectPodArrToJSON() []define.InspectPodData // CreatePod creates a pod with no infra container // it optionally takes a pod name func (p *PodmanTestIntegration) CreatePod(options map[string][]string) (*PodmanSessionIntegration, int, string) { - var args = []string{"pod", "create", "--infra=false", "--share", ""} + args := []string{"pod", "create", "--infra=false", "--share", ""} for k, values := range options { for _, v := range values { args = append(args, k+"="+v) @@ -1019,7 +1019,7 @@ func (p *PodmanTestIntegration) CreatePod(options map[string][]string) (*PodmanS } func (p *PodmanTestIntegration) CreateVolume(options map[string][]string) (*PodmanSessionIntegration, int, string) { - var args = []string{"volume", "create"} + args := []string{"volume", "create"} for k, values := range options { for _, v := range values { args = append(args, k+"="+v) @@ -1182,17 +1182,6 @@ func isRootless() bool { return os.Geteuid() != 0 } -func isCgroupsV1() bool { - return !CGROUPSV2 -} - -func SkipIfCgroupV1(reason string) { - checkReason(reason) - if isCgroupsV1() { - Skip(reason) - } -} - func SkipIfCgroupV2(reason string) { checkReason(reason) if CGROUPSV2 { @@ -1382,8 +1371,10 @@ func (p *PodmanTestIntegration) makeOptions(args []string, options PodmanExecOpt podmanOptions = append(podmanOptions, strings.Split(p.StorageOptions, " ")...) if !options.NoCache { - cacheOptions := []string{"--storage-opt", - fmt.Sprintf("%s.imagestore=%s", p.PodmanTest.ImageCacheFS, p.PodmanTest.ImageCacheDir)} + cacheOptions := []string{ + "--storage-opt", + fmt.Sprintf("%s.imagestore=%s", p.PodmanTest.ImageCacheFS, p.PodmanTest.ImageCacheDir), + } podmanOptions = append(cacheOptions, podmanOptions...) } podmanOptions = append(podmanOptions, args...) diff --git a/test/e2e/containers_conf_test.go b/test/e2e/containers_conf_test.go index 01c9d3f2348..6339b781ac7 100644 --- a/test/e2e/containers_conf_test.go +++ b/test/e2e/containers_conf_test.go @@ -20,7 +20,6 @@ import ( ) var _ = Describe("Verify podman containers.conf usage", func() { - BeforeEach(func() { confPath, err := filepath.Abs("config/containers.conf") Expect(err).ToNot(HaveOccurred()) @@ -28,7 +27,6 @@ var _ = Describe("Verify podman containers.conf usage", func() { if IsRemote() { podmanTest.RestartRemoteService() } - }) It("limits test", func() { @@ -55,7 +53,6 @@ var _ = Describe("Verify podman containers.conf usage", func() { } else { Expect(session.OutputToString()).To(Not(Equal("500"))) } - }) It("oom-score-adj", func() { @@ -85,15 +82,10 @@ var _ = Describe("Verify podman containers.conf usage", func() { } else { Expect(session.OutputToString()).To(ContainSubstring("0")) } - } - }) It("cgroup_conf in containers.conf", func() { - if isCgroupsV1() { - Skip("Setting cgroup_confs not supported on cgroupv1") - } // FIXME: Needs crun-1.8.2-2 to allow this with --cgroup-manager=cgroupfs, once this is available remove the skip below. SkipIfRootless("--cgroup-manager=cgoupfs and --cgroup-conf not supported in rootless mode with crun") conffile := filepath.Join(podmanTest.TempDir, "container.conf") @@ -812,7 +804,6 @@ var _ = Describe("Verify podman containers.conf usage", func() { } It("podman containers.conf container_name_as_hostname", func() { - // With default containers.conf // Start container with no options diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go index 534d88423ba..8327c21ab4d 100644 --- a/test/e2e/pod_create_test.go +++ b/test/e2e/pod_create_test.go @@ -768,7 +768,6 @@ ENTRYPOINT ["sleep","99999"] // Too complicated to differentiate in test context, so we ignore the first part // and just check for the "no container" substring, which is common to both. Expect(podCreate).Should(ExitWithError(125, `no container with name or ID "randomfakeid" found: no such container`)) - }) It("podman pod create with --userns=keep-id", func() { @@ -1045,7 +1044,6 @@ ENTRYPOINT ["sleep","99999"] session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) Expect(session.OutputToString()).To(Equal("1:3")) - }) It("podman pod create --volumes-from", func() { @@ -1154,7 +1152,6 @@ ENTRYPOINT ["sleep","99999"] inspect := podmanTest.InspectContainer(ctrCreate.OutputToString()) Expect(inspect[0]).To(HaveField("AppArmorProfile", apparmor.Profile)) - }) It("podman pod create --sysctl test", func() { @@ -1192,12 +1189,9 @@ ENTRYPOINT ["sleep","99999"] session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) Expect(session.OutputToString()).NotTo(ContainSubstring("kernel.msgmax = 65535")) - }) It("podman pod create --share-parent test", func() { - SkipIfRootlessCgroupsV1("rootless cannot use cgroups with cgroupsv1") - SkipIfCgroupV1("CgroupMode shows 'host' on CGv1, not CID (issue 15013, wontfix") podCreate := podmanTest.Podman([]string{"pod", "create", "--share-parent=false"}) podCreate.WaitWithDefaultTimeout() Expect(podCreate).Should(ExitCleanly()) @@ -1236,7 +1230,6 @@ ENTRYPOINT ["sleep","99999"] podCreate3 := podmanTest.Podman([]string{"pod", "create", "--share", "cgroup"}) podCreate3.WaitWithDefaultTimeout() Expect(podCreate3).ShouldNot(ExitCleanly()) - }) It("podman pod create infra inheritance test", func() { diff --git a/test/e2e/pod_stats_test.go b/test/e2e/pod_stats_test.go index f2259b9136f..f96b9e14bdb 100644 --- a/test/e2e/pod_stats_test.go +++ b/test/e2e/pod_stats_test.go @@ -9,12 +9,8 @@ import ( ) var _ = Describe("Podman pod stats", func() { - BeforeEach(func() { SkipIfRootlessCgroupsV1("Tests fail with both CGv1 + required --cgroup-manager=cgroupfs") - if isContainerized() { - SkipIfCgroupV1("All tests fail Error: unable to load cgroup at ...: cgroup deleted") - } }) It("podman pod stats should run with no pods", func() { diff --git a/test/e2e/run_cgroup_parent_test.go b/test/e2e/run_cgroup_parent_test.go index fc72c24f55a..e765862616b 100644 --- a/test/e2e/run_cgroup_parent_test.go +++ b/test/e2e/run_cgroup_parent_test.go @@ -16,7 +16,6 @@ import ( const cgroupRoot = "/sys/fs/cgroup" var _ = Describe("Podman run with --cgroup-parent", func() { - BeforeEach(func() { SkipIfRootlessCgroupsV1("cgroup parent is not supported in cgroups v1") }) @@ -48,7 +47,6 @@ var _ = Describe("Podman run with --cgroup-parent", func() { }) Specify("always honor --cgroup-parent", func() { - SkipIfCgroupV1("test not supported in cgroups v1") if Containerized() || podmanTest.CgroupManager == "cgroupfs" { Skip("Requires Systemd cgroup manager support") } diff --git a/test/e2e/run_cpu_test.go b/test/e2e/run_cpu_test.go index e35c40048c8..ba73d5f9047 100644 --- a/test/e2e/run_cpu_test.go +++ b/test/e2e/run_cpu_test.go @@ -12,7 +12,6 @@ import ( ) var _ = Describe("Podman run cpu", func() { - BeforeEach(func() { SkipIfRootlessCgroupsV1("Setting CPU not supported on cgroupv1 for rootless users") @@ -121,7 +120,6 @@ var _ = Describe("Podman run cpu", func() { }) It("podman run invalid cpu-rt-period with cgroupsv2", func() { - SkipIfCgroupV1("testing options that only work in cgroup v2") result := podmanTest.Podman([]string{"run", "--rm", "--cpu-rt-period=5000", ALPINE, "ls"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) @@ -129,7 +127,6 @@ var _ = Describe("Podman run cpu", func() { }) It("podman run invalid cpu-rt-runtime with cgroupsv2", func() { - SkipIfCgroupV1("testing options that only work in cgroup v2") result := podmanTest.Podman([]string{"run", "--rm", "--cpu-rt-runtime=5000", ALPINE, "ls"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) diff --git a/test/e2e/run_memory_test.go b/test/e2e/run_memory_test.go index 4e9cf5c32a4..7a39e9cdb10 100644 --- a/test/e2e/run_memory_test.go +++ b/test/e2e/run_memory_test.go @@ -3,19 +3,12 @@ package integration import ( - "fmt" - . "github.com/containers/podman/v5/test/utils" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) var _ = Describe("Podman run memory", func() { - - BeforeEach(func() { - SkipIfRootlessCgroupsV1("Setting Memory not supported on cgroupv1 for rootless users") - }) - It("podman run memory test", func() { var session *PodmanSessionIntegration @@ -61,17 +54,6 @@ var _ = Describe("Podman run memory", func() { Expect(session.OutputToString()).To(Equal(expect)) }) - for _, limit := range []string{"0", "15", "100"} { - testName := fmt.Sprintf("podman run memory-swappiness test(%s)", limit) - It(testName, func() { - SkipIfCgroupV2("memory-swappiness not supported on cgroupV2") - session := podmanTest.Podman([]string{"run", fmt.Sprintf("--memory-swappiness=%s", limit), ALPINE, "cat", "/sys/fs/cgroup/memory/memory.swappiness"}) - session.WaitWithDefaultTimeout() - Expect(session).Should(ExitCleanly()) - Expect(session.OutputToString()).To(Equal(limit)) - }) - } - It("podman run memory test on oomkilled container", func() { mem := SystemExec("cat", []string{"/proc/sys/vm/overcommit_memory"}) mem.WaitWithDefaultTimeout() diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 2b40ce5abed..e96cdf1b317 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -25,7 +25,6 @@ import ( ) var _ = Describe("Podman run", func() { - It("podman run a container based on local image", func() { session := podmanTest.Podman([]string{"run", ALPINE, "ls"}) session.WaitWithDefaultTimeout() @@ -228,7 +227,6 @@ var _ = Describe("Podman run", func() { Expect(session).Should(Exit(0)) Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull " + BB_GLIBC)) Expect(session.ErrorToString()).To(ContainSubstring("Writing manifest to image destination")) - }) It("podman run --tls-verify", func() { @@ -274,8 +272,10 @@ var _ = Describe("Podman run", func() { Expect(err).ShouldNot(HaveOccurred()) // Change image in predictable way to validate export - csession := podmanTest.Podman([]string{"run", "--name", uniqueString, ALPINE, - "/bin/sh", "-c", fmt.Sprintf("echo %s > %s", uniqueString, testFilePath)}) + csession := podmanTest.Podman([]string{ + "run", "--name", uniqueString, ALPINE, + "/bin/sh", "-c", fmt.Sprintf("echo %s > %s", uniqueString, testFilePath), + }) csession.WaitWithDefaultTimeout() Expect(csession).Should(ExitCleanly()) @@ -292,8 +292,10 @@ var _ = Describe("Podman run", func() { Expect(filepath.Join(rootfs, uls)).Should(BeADirectory()) // Other tests confirm SELinux types, just confirm --rootfs is working. - session := podmanTest.Podman([]string{"run", "-i", "--security-opt", "label=disable", - "--rootfs", rootfs, "cat", testFilePath}) + session := podmanTest.Podman([]string{ + "run", "-i", "--security-opt", "label=disable", + "--rootfs", rootfs, "cat", testFilePath, + }) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) @@ -309,15 +311,19 @@ var _ = Describe("Podman run", func() { } // Test --rootfs with an external overlay // use --rm to remove container and confirm if we did not leak anything - osession := podmanTest.Podman([]string{"run", "-i", "--rm", "--security-opt", "label=disable", - "--rootfs", rootfs + ":O", "cat", testFilePath}) + osession := podmanTest.Podman([]string{ + "run", "-i", "--rm", "--security-opt", "label=disable", + "--rootfs", rootfs + ":O", "cat", testFilePath, + }) osession.WaitWithDefaultTimeout() Expect(osession).Should(ExitCleanly()) Expect(osession.OutputToString()).To(Equal(uniqueString)) // Test podman start stop with overlay - osession = podmanTest.Podman([]string{"run", "--name", "overlay-foo", "--security-opt", "label=disable", - "--rootfs", rootfs + ":O", "echo", "hello"}) + osession = podmanTest.Podman([]string{ + "run", "--name", "overlay-foo", "--security-opt", "label=disable", + "--rootfs", rootfs + ":O", "echo", "hello", + }) osession.WaitWithDefaultTimeout() Expect(osession).Should(ExitCleanly()) Expect(osession.OutputToString()).To(Equal("hello")) @@ -335,15 +341,19 @@ var _ = Describe("Podman run", func() { Expect(osession).Should(ExitCleanly()) // Test --rootfs with an external overlay with --uidmap - osession = podmanTest.Podman([]string{"run", "--uidmap", "0:1234:5678", "--rm", "--security-opt", "label=disable", - "--rootfs", rootfs + ":O", "cat", "/proc/self/uid_map"}) + osession = podmanTest.Podman([]string{ + "run", "--uidmap", "0:1234:5678", "--rm", "--security-opt", "label=disable", + "--rootfs", rootfs + ":O", "cat", "/proc/self/uid_map", + }) osession.WaitWithDefaultTimeout() Expect(osession).Should(ExitCleanly()) Expect(osession.OutputToString()).To(Equal("0 1234 5678")) // Test --rootfs with an external overlay with --userns=auto - osession = podmanTest.Podman([]string{"run", "--userns=auto", "--rm", "--security-opt", "label=disable", - "--rootfs", rootfs + ":O", "cat", "/proc/self/uid_map"}) + osession = podmanTest.Podman([]string{ + "run", "--userns=auto", "--rm", "--security-opt", "label=disable", + "--rootfs", rootfs + ":O", "cat", "/proc/self/uid_map", + }) osession.WaitWithDefaultTimeout() Expect(osession).Should(ExitCleanly()) Expect(osession.OutputToString()).To(ContainSubstring("1024")) @@ -513,8 +523,6 @@ var _ = Describe("Podman run", func() { }) It("podman run security-opt unmask on /sys/fs/cgroup", func() { - - SkipIfCgroupV1("podman umask on /sys/fs/cgroup will fail with cgroups V1") SkipIfRootless("/sys/fs/cgroup rw access is needed") rwOnCgroups := "/sys/fs/cgroup cgroup2 rw" session := podmanTest.Podman([]string{"run", "--security-opt", "unmask=ALL", "--security-opt", "mask=/sys/fs/cgroup", ALPINE, "cat", "/proc/mounts"}) @@ -1665,7 +1673,6 @@ VOLUME %s`, ALPINE, volPath, volPath) session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError(125, "--no-hosts and --hosts-file cannot be set together")) }) - }) It("podman run with restart-policy always restarts containers", func() { @@ -1822,7 +1829,7 @@ VOLUME %s`, ALPINE, volPath, volPath) curCgroupsBytes, err := os.ReadFile("/proc/self/cgroup") Expect(err).ToNot(HaveOccurred()) - var curCgroups = string(curCgroupsBytes) + curCgroups := string(curCgroupsBytes) GinkgoWriter.Printf("Output:\n%s\n", curCgroups) Expect(curCgroups).To(Not(Equal(""))) @@ -1839,7 +1846,7 @@ VOLUME %s`, ALPINE, volPath, volPath) ctrCgroupsBytes, err := os.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid)) Expect(err).ToNot(HaveOccurred()) - var ctrCgroups = string(ctrCgroupsBytes) + ctrCgroups := string(ctrCgroupsBytes) GinkgoWriter.Printf("Output\n:%s\n", ctrCgroups) Expect(curCgroups).To(Not(Equal(ctrCgroups))) }) @@ -1959,11 +1966,9 @@ VOLUME %s`, ALPINE, volPath, volPath) h := strconv.Itoa(t.Hour()) Expect(session.OutputToString()).To(ContainSubstring(z)) Expect(session.OutputToString()).To(ContainSubstring(h)) - }) It("podman run verify pids-limit", func() { - SkipIfCgroupV1("pids-limit not supported on cgroup V1") limit := "4321" session := podmanTest.Podman([]string{"run", "--pids-limit", limit, "--net=none", "--rm", ALPINE, "cat", "/sys/fs/cgroup/pids.max"}) session.WaitWithDefaultTimeout() @@ -2091,7 +2096,6 @@ WORKDIR /madethis`, BB) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) Expect(session.OutputToString()).To(ContainSubstring("mysecret")) - }) It("podman run --secret source=mysecret,type=mount", func() { @@ -2113,7 +2117,6 @@ WORKDIR /madethis`, BB) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) Expect(session.OutputToString()).To(ContainSubstring("mysecret")) - }) It("podman run --secret source=mysecret,type=mount with target", func() { @@ -2135,7 +2138,6 @@ WORKDIR /madethis`, BB) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) Expect(session.OutputToString()).To(ContainSubstring("mysecret_target")) - }) It("podman run --secret source=mysecret,type=mount with target at /tmp", func() { @@ -2157,7 +2159,6 @@ WORKDIR /madethis`, BB) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) Expect(session.OutputToString()).To(ContainSubstring("mysecret_target2")) - }) It("podman run --secret source=mysecret,type=env", func() { diff --git a/test/e2e/stats_test.go b/test/e2e/stats_test.go index 446cd21e8e0..795db22caed 100644 --- a/test/e2e/stats_test.go +++ b/test/e2e/stats_test.go @@ -15,12 +15,8 @@ import ( // TODO: we need to check the output. Currently, we only check the exit codes // which is not enough. var _ = Describe("Podman stats", func() { - BeforeEach(func() { SkipIfRootlessCgroupsV1("stats not supported on cgroupv1 for rootless users") - if isContainerized() { - SkipIfCgroupV1("stats not supported inside cgroupv1 container environment") - } }) It("podman stats with bogus container", func() { diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go index 05c46021e09..f2c50c3a986 100644 --- a/test/e2e/systemd_test.go +++ b/test/e2e/systemd_test.go @@ -15,7 +15,6 @@ import ( ) var _ = Describe("Podman systemd", func() { - It("podman run container with systemd PID1", func() { ctrName := "testSystemd" run := podmanTest.Podman([]string{"run", "--name", ctrName, "-t", "-i", "-d", SYSTEMD_IMAGE, "/sbin/init"}) @@ -42,10 +41,6 @@ var _ = Describe("Podman systemd", func() { Expect(conData).To(HaveLen(1)) Expect(conData[0].Config).To(HaveField("SystemdMode", true)) - // stats not supported w/ CGv1 rootless or containerized - if isCgroupsV1() && (isRootless() || isContainerized()) { - return - } stats := podmanTest.Podman([]string{"stats", "--no-stream", ctrName}) stats.WaitWithDefaultTimeout() Expect(stats).Should(ExitCleanly()) diff --git a/test/e2e/update_test.go b/test/e2e/update_test.go index 167a63ab787..262987a7941 100644 --- a/test/e2e/update_test.go +++ b/test/e2e/update_test.go @@ -12,56 +12,7 @@ import ( ) var _ = Describe("Podman update", func() { - - It("podman update container all options v1", func() { - SkipIfCgroupV2("testing flags that only work in cgroup v1") - SkipIfRootless("many of these handlers are not enabled while rootless in CI") - session := podmanTest.Podman([]string{"run", "-dt", ALPINE}) - session.WaitWithDefaultTimeout() - Expect(session).Should(ExitCleanly()) - - ctrID := session.OutputToString() - - commonArgs := []string{ - "update", - "--cpus", "5", - "--cpuset-cpus", "0", - "--cpu-shares", "123", - "--cpuset-mems", "0", - "--memory", "1G", - "--memory-swap", "2G", - "--memory-reservation", "2G", - "--memory-swappiness", "50", - "--pids-limit", "123", ctrID} - - session = podmanTest.Podman(commonArgs) - session.WaitWithDefaultTimeout() - Expect(session).Should(ExitCleanly()) - - // checking cpu quota from --cpus - podmanTest.CheckFileInContainerSubstring(ctrID, "/sys/fs/cgroup/cpu/cpu.cfs_quota_us", "500000") - - // checking cpuset-cpus - podmanTest.CheckFileInContainer(ctrID, "/sys/fs/cgroup/cpuset/cpuset.cpus", "0") - - // checking cpuset-mems - podmanTest.CheckFileInContainer(ctrID, "/sys/fs/cgroup/cpuset/cpuset.mems", "0") - - // checking memory limit - podmanTest.CheckFileInContainerSubstring(ctrID, "/sys/fs/cgroup/memory/memory.limit_in_bytes", "1073741824") - - // checking memory-swap - podmanTest.CheckFileInContainerSubstring(ctrID, "/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes", "2147483648") - - // checking cpu-shares - podmanTest.CheckFileInContainerSubstring(ctrID, "/sys/fs/cgroup/cpu/cpu.shares", "123") - - // checking pids-limit - podmanTest.CheckFileInContainerSubstring(ctrID, "/sys/fs/cgroup/pids/pids.max", "123") - }) - It("podman update container unspecified pid limit", func() { - SkipIfCgroupV1("testing flags that only work in cgroup v2") SkipIfRootless("many of these handlers are not enabled while rootless in CI") session := podmanTest.Podman([]string{"run", "-dt", "--pids-limit", "-1", ALPINE}) session.WaitWithDefaultTimeout() @@ -72,7 +23,8 @@ var _ = Describe("Podman update", func() { commonArgs := []string{ "update", "--cpus", "5", - ctrID} + ctrID, + } session = podmanTest.Podman(commonArgs) session.WaitWithDefaultTimeout() @@ -85,7 +37,6 @@ var _ = Describe("Podman update", func() { }) It("podman update container all options v2", func() { - SkipIfCgroupV1("testing flags that only work in cgroup v2") SkipIfRootless("many of these handlers are not enabled while rootless in CI") skipWithoutDevNullb0() session := podmanTest.Podman([]string{"run", "-dt", ALPINE}) @@ -109,7 +60,8 @@ var _ = Describe("Podman update", func() { "--device-read-iops", "/dev/nullb0:1000", "--device-write-iops", "/dev/nullb0:1000", "--pids-limit", "123", - ctrID} + ctrID, + } session = podmanTest.Podman(commonArgs) session.WaitWithDefaultTimeout() @@ -174,7 +126,6 @@ var _ = Describe("Podman update", func() { }) It("podman update persists changes", func() { - SkipIfCgroupV1("testing flags that only work in cgroup v2") SkipIfRootless("many of these handlers are not enabled while rootless in CI") memoryInspect := ".HostConfig.Memory" diff --git a/test/system/030-run.bats b/test/system/030-run.bats index 70840d92aa3..692843b1e22 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -122,7 +122,6 @@ EOF # bats test_tags=ci:parallel @test "podman run - uidmapping has no /sys/kernel mounts" { - skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)" skip_if_rootless "cannot umount as rootless" run_podman run --rm --uidmap 0:100:10000 $IMAGE mount @@ -1081,7 +1080,6 @@ EOF # rhbz#1902979 : podman run fails to update /etc/hosts when --uidmap is provided # bats test_tags=ci:parallel @test "podman run update /etc/hosts" { - skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)" HOST=$(random_string 25) run_podman run --uidmap 0:10001:10002 --rm --hostname ${HOST} $IMAGE grep ${HOST} /etc/hosts is "${lines[0]}" ".*${HOST}.*" @@ -1443,21 +1441,14 @@ EOF # bats test_tags=ci:parallel @test "podman run --net=host --cgroupns=host with read only cgroupfs" { - skip_if_rootless_cgroupsv1 - if is_cgroupsv1; then - # verify that the memory controller is mounted read-only - run_podman run --net=host --cgroupns=host --rm $IMAGE cat /proc/self/mountinfo - assert "$output" =~ "/sys/fs/cgroup/memory ro.* cgroup cgroup" - else - # verify that the last /sys/fs/cgroup mount is read-only - run_podman run --net=host --cgroupns=host --rm $IMAGE sh -c "grep ' / /sys/fs/cgroup ' /proc/self/mountinfo | tail -n 1" - assert "$output" =~ "/sys/fs/cgroup ro" + # verify that the last /sys/fs/cgroup mount is read-only + run_podman run --net=host --cgroupns=host --rm $IMAGE sh -c "grep ' / /sys/fs/cgroup ' /proc/self/mountinfo | tail -n 1" + assert "$output" =~ "/sys/fs/cgroup ro" - # verify that it works also with a cgroupns - run_podman run --net=host --cgroupns=private --rm $IMAGE sh -c "grep ' / /sys/fs/cgroup ' /proc/self/mountinfo | tail -n 1" - assert "$output" =~ "/sys/fs/cgroup ro" - fi + # verify that it works also with a cgroupns + run_podman run --net=host --cgroupns=private --rm $IMAGE sh -c "grep ' / /sys/fs/cgroup ' /proc/self/mountinfo | tail -n 1" + assert "$output" =~ "/sys/fs/cgroup ro" } # bats test_tags=ci:parallel diff --git a/test/system/170-run-userns.bats b/test/system/170-run-userns.bats index b56e2c12e4e..267358fd149 100644 --- a/test/system/170-run-userns.bats +++ b/test/system/170-run-userns.bats @@ -33,7 +33,6 @@ function _require_crun() { # bats test_tags=ci:parallel @test "podman --group-add without keep-groups while in a userns" { - skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)" skip_if_rootless "chroot is not allowed in rootless mode" skip_if_remote "--group-add keep-groups not supported in remote mode" run chroot --groups 1234,5678 / ${PODMAN} run --rm --uidmap 0:200000:5000 --group-add 457 $IMAGE id @@ -42,7 +41,6 @@ function _require_crun() { # bats test_tags=ci:parallel @test "rootful pod with custom ID mapping" { - skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)" skip_if_rootless "does not work rootless - rootful feature" random_pod_name=p_$(safename) run_podman pod create --uidmap 0:200000:5000 --name=$random_pod_name diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats index 1887e68ec45..f59223cd250 100644 --- a/test/system/200-pod.bats +++ b/test/system/200-pod.bats @@ -535,7 +535,6 @@ spec: @test "pod resource limits" { skip_if_remote "resource limits only implemented on non-remote" skip_if_rootless "resource limits only work with root" - skip_if_cgroupsv1 "resource limits only meaningful on cgroups V2" # create loopback device lofile=${PODMAN_TMPDIR}/disk.img @@ -762,7 +761,6 @@ function thingy_with_unique_id() { # bats test_tags=ci:parallel @test "podman pod cleans cgroup and keeps limits" { skip_if_remote "we cannot check cgroup settings" - skip_if_rootless_cgroupsv1 "rootless cannot use cgroups on v1" for infra in true false; do run_podman pod create --infra=$infra --memory=256M diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats index 89b8c80aae6..5cadd34becc 100644 --- a/test/system/250-systemd.bats +++ b/test/system/250-systemd.bats @@ -316,13 +316,6 @@ LISTEN_FDNAMES=listen_fdnames" | sort) run_podman rm $cname } -@test "podman --systemd fails on cgroup v1 with a private cgroupns" { - skip_if_cgroupsv2 - - run_podman 126 run --systemd=always --cgroupns=private $IMAGE true - assert "$output" =~ ".*cgroup namespace is not supported with cgroup v1 and systemd mode" -} - # https://github.com/containers/podman/issues/13153 @test "podman rootless-netns processes should be in different cgroup" { is_rootless || skip "only meaningful for rootless" diff --git a/test/system/252-quadlet.bats b/test/system/252-quadlet.bats index 0e9e9d9b83b..67a60578287 100644 --- a/test/system/252-quadlet.bats +++ b/test/system/252-quadlet.bats @@ -20,7 +20,6 @@ function start_time() { function setup() { skip_if_remote "quadlet tests are meaningless over remote" - skip_if_rootless_cgroupsv1 "Can't use --cgroups=split w/ CGv1 (issue 17456, wontfix)" skip_if_journald_unavailable "Needed for RHEL. FIXME: we might be able to re-enable a subset of tests." test -x "$QUADLET" || die "Cannot run quadlet tests without executable \$QUADLET ($QUADLET)" diff --git a/test/system/253-podman-quadlet.bats b/test/system/253-podman-quadlet.bats index af4e787500f..71bfaab3080 100644 --- a/test/system/253-podman-quadlet.bats +++ b/test/system/253-podman-quadlet.bats @@ -10,7 +10,6 @@ load helpers.systemd function setup() { skip_if_remote "podman quadlet is not implemented for remote setup yet" - skip_if_rootless_cgroupsv1 "Can't use --cgroups=split w/ CGv1 (issue 17456, wontfix)" skip_if_journald_unavailable "Needed for RHEL. FIXME: we might be able to re-enable a subset of tests." test -x "$QUADLET" || die "Cannot run quadlet tests without executable \$QUADLET ($QUADLET)" diff --git a/test/system/400-unprivileged-access.bats b/test/system/400-unprivileged-access.bats index a253ad5cc02..9f89dad83e3 100644 --- a/test/system/400-unprivileged-access.bats +++ b/test/system/400-unprivileged-access.bats @@ -7,7 +7,6 @@ load helpers @test "podman container storage is not accessible by unprivileged users" { - skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)" skip_if_rootless "test meaningless without suid" skip_if_remote diff --git a/test/system/410-selinux.bats b/test/system/410-selinux.bats index f360e91446a..e0e1c867f8f 100644 --- a/test/system/410-selinux.bats +++ b/test/system/410-selinux.bats @@ -152,10 +152,6 @@ function check_label() { @test "podman selinux: shared context in (some) namespaces" { skip_if_no_selinux - # rootless users have no usable cgroups with cgroupsv1, so containers - # must use a pid namespace and not join an existing one. - skip_if_rootless_cgroupsv1 - if [[ $(podman_runtime) == "runc" ]]; then skip "some sort of runc bug, not worth fixing (issue 11784, wontfix)" fi diff --git a/test/system/420-cgroups.bats b/test/system/420-cgroups.bats index d0bfd36b664..512dec89e14 100644 --- a/test/system/420-cgroups.bats +++ b/test/system/420-cgroups.bats @@ -9,8 +9,6 @@ load helpers @test "podman run, preserves initial --cgroup-manager" { skip_if_remote "podman-remote does not support --cgroup-manager" - skip_if_rootless_cgroupsv1 - # Find out our default cgroup manager, and from that, get the non-default run_podman info --format '{{.Host.CgroupManager}}' case "$output" in @@ -41,7 +39,6 @@ load helpers # bats test_tags=ci:parallel @test "podman run --cgroups=disabled keeps the current cgroup" { skip_if_remote "podman-remote does not support --cgroups=disabled" - skip_if_rootless_cgroupsv1 runtime=$(podman_runtime) if [[ $runtime != "crun" ]]; then skip "runtime is $runtime; --cgroups=disabled requires crun" diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats index 7fc58713ea6..c96122bf4fe 100644 --- a/test/system/500-networking.bats +++ b/test/system/500-networking.bats @@ -114,7 +114,6 @@ load helpers.network # Issue #5466 - port-forwarding doesn't work with this option and -d # FIXME: random_rfc1918_subnet is not parallel-safe @test "podman networking: port with --userns=keep-id for rootless or --uidmap=* for rootful" { - skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)" for cidr in "" "$(random_rfc1918_subnet).0/24"; do myport=$(random_free_port 52000-52999) if [[ -z $cidr ]]; then @@ -878,7 +877,6 @@ EOF # bats test_tags=ci:parallel @test "podman run /etc/* permissions" { - skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)" userns="--userns=keep-id" if ! is_rootless; then userns="--uidmap=0:1111111:65536 --gidmap=0:1111111:65536" @@ -992,8 +990,6 @@ EOF # Test for https://github.com/containers/podman/issues/18615 # CANNOT BE PARALLELIZED due to strict checking of /run/netns @test "podman network cleanup --userns + --restart" { - skip_if_cgroupsv1 "run --uidmap fails on cgroups v1 (issue 15025, wontfix)" - local net1=net-a-$(safename) # use /29 subnet to limit available ip space, a 29 gives 5 usable addresses (6 - 1 for the gw) local subnet="$(random_rfc1918_subnet).0/29" diff --git a/test/system/600-completion.bats b/test/system/600-completion.bats index 0afc1660789..df07fa8cd88 100644 --- a/test/system/600-completion.bats +++ b/test/system/600-completion.bats @@ -18,17 +18,6 @@ function setup() { basic_setup } -# Returns true if we are able to podman-pause -function _can_pause() { - # Even though we're just trying completion, not an actual unpause, - # podman barfs with: - # Error: unpause is not supported for cgroupv1 rootless containers - if is_rootless && is_cgroupsv1; then - return 1 - fi - return 0 -} - function check_shell_completion() { local count=0 @@ -98,11 +87,6 @@ function check_shell_completion() { ;; *CONTAINER*) - # podman unpause fails early on rootless cgroupsv1 - if [[ $cmd = "unpause" ]] && ! _can_pause; then - continue 2 - fi - name=$random_container_name # special case podman cp suggest containers names with a colon if [[ $cmd = "cp" ]]; then @@ -281,9 +265,7 @@ function _check_no_suggestions() { run_podman create --name created-$random_container_name $IMAGE run_podman run --name running-$random_container_name -d $IMAGE top run_podman run --name pause-$random_container_name -d $IMAGE top - if _can_pause; then - run_podman pause pause-$random_container_name - fi + run_podman pause pause-$random_container_name run_podman run --name exited-$random_container_name -d $IMAGE echo exited # create pods for each state diff --git a/test/system/helpers.bash b/test/system/helpers.bash index 5abfe872d37..6d80681066f 100644 --- a/test/system/helpers.bash +++ b/test/system/helpers.bash @@ -757,11 +757,6 @@ function is_remote() { [[ "$PODMAN" =~ -remote ]] } -function is_cgroupsv1() { - # WARNING: This will break if there's ever a cgroups v3 - ! is_cgroupsv2 -} - # True if cgroups v2 are enabled function is_cgroupsv2() { cgroup_type=$(stat -f -c %T /sys/fs/cgroup) @@ -938,36 +933,6 @@ function skip_if_no_selinux() { fi } -####################### -# skip_if_cgroupsv1 # ...with an optional message -####################### -function skip_if_cgroupsv1() { - if ! is_cgroupsv2; then - skip "${1:-test requires cgroupsv2}" - fi -} - -####################### -# skip_if_cgroupsv2 # ...with an optional message -####################### -function skip_if_cgroupsv2() { - if is_cgroupsv2; then - skip "${1:-test requires cgroupsv1}" - fi -} - -###################### -# skip_if_rootless_cgroupsv1 # ...with an optional message -###################### -function skip_if_rootless_cgroupsv1() { - if is_rootless; then - if ! is_cgroupsv2; then - local msg=$(_add_label_if_missing "$1" "rootless cgroupvs1") - skip "${msg:-not supported as rootless under cgroupsv1}" - fi - fi -} - ################################## # skip_if_journald_unavailable # rhbz#1895105: rootless journald permissions ################################## From e2967b54a977fa95ee6f0e576ee0120b65f48372 Mon Sep 17 00:00:00 2001 From: Lokesh Mandvekar Date: Fri, 10 Oct 2025 14:52:04 -0400 Subject: [PATCH 3/4] docs: Remove Cgroups v1 references Wherever cgroups v2 references were mentioned by name, those have been set to defaults. Signed-off-by: Lokesh Mandvekar --- docs/source/locale/ja/LC_MESSAGES/markdown.po | 11 +++-------- docs/source/markdown/options/cgroupns.md | 2 +- docs/source/markdown/podman-pod-stats.1.md.in | 2 +- docs/source/markdown/podman-stats.1.md.in | 6 +----- 4 files changed, 6 insertions(+), 15 deletions(-) diff --git a/docs/source/locale/ja/LC_MESSAGES/markdown.po b/docs/source/locale/ja/LC_MESSAGES/markdown.po index 649857577dc..7cbce7c8ea5 100644 --- a/docs/source/locale/ja/LC_MESSAGES/markdown.po +++ b/docs/source/locale/ja/LC_MESSAGES/markdown.po @@ -8458,8 +8458,7 @@ msgstr "" #: ../../source/markdown/podman-create.1.md:185 #: ../../source/markdown/podman-run.1.md:204 msgid "" -"If the host uses cgroups v1, the default is set to **host**. On cgroups " -"v2, the default is **private**." +The default is **private**." msgstr "" #: ../../source/markdown/podman-create.1.md:191 @@ -23003,7 +23002,7 @@ msgstr "" #: ../../source/markdown/podman-pod-stats.1.md:11 msgid "" "Display a live stream of containers in one or more pods resource usage " -"statistics. Running rootless is only supported on cgroups v2." +"statistics." msgstr "" #: ../../source/markdown/podman-pod-stats.1.md:17 @@ -30162,11 +30161,7 @@ msgid "update a container with a new cpu quota and period" msgstr "" #: ../../source/markdown/podman-update.1.md:331 -msgid "update a container with all available options for cgroups v2" -msgstr "" - -#: ../../source/markdown/podman-update.1.md:336 -msgid "update a container with all available options for cgroups v1" +msgid "update a container with all available options" msgstr "" #: ../../source/markdown/podman-update.1.md:342 diff --git a/docs/source/markdown/options/cgroupns.md b/docs/source/markdown/options/cgroupns.md index 71fa2486882..675ecf82554 100644 --- a/docs/source/markdown/options/cgroupns.md +++ b/docs/source/markdown/options/cgroupns.md @@ -11,4 +11,4 @@ Set the cgroup namespace mode for the container. - **private**: create a new cgroup namespace. - **ns:**_path_: join the namespace at the specified path. -If the host uses cgroups v1, the default is set to **host**. On cgroups v2, the default is **private**. +The default is **private**. diff --git a/docs/source/markdown/podman-pod-stats.1.md.in b/docs/source/markdown/podman-pod-stats.1.md.in index 943e36c8cd9..4e17a2d520e 100644 --- a/docs/source/markdown/podman-pod-stats.1.md.in +++ b/docs/source/markdown/podman-pod-stats.1.md.in @@ -7,7 +7,7 @@ podman\-pod\-stats - Display a live stream of resource usage stats for container **podman pod stats** [*options*] [*pod*] ## DESCRIPTION -Display a live stream of containers in one or more pods resource usage statistics. Running rootless is only supported on cgroups v2. +Display a live stream of containers in one or more pods resource usage statistics. ## OPTIONS diff --git a/docs/source/markdown/podman-stats.1.md.in b/docs/source/markdown/podman-stats.1.md.in index 1c01e7f433e..e87ba848247 100644 --- a/docs/source/markdown/podman-stats.1.md.in +++ b/docs/source/markdown/podman-stats.1.md.in @@ -11,11 +11,7 @@ podman\-stats - Display a live stream of one or more container's resource usage ## DESCRIPTION Display a live stream of one or more containers' resource usage statistics -Note: Podman stats does not work in rootless environments that use cgroups v1. -Podman stats relies on cgroup information for statistics, and cgroup v1 is not -supported for rootless use cases. - -Note: Rootless environments that use cgroups v2 are not able to report statistics +Note: Rootless environments are not able to report statistics about their networking usage. ## OPTIONS From 3f540c7350274c2ad05dee289d40fb0ce8312518 Mon Sep 17 00:00:00 2001 From: Lokesh Mandvekar Date: Tue, 21 Oct 2025 15:30:41 -0400 Subject: [PATCH 4/4] slirp: remove for Podman6 Signed-off-by: Lokesh Mandvekar --- cmd/podman/common/completion.go | 16 - cmd/podman/root.go | 6 - cmd/podman/system/service_abi.go | 1 - cmd/podman/system/service_abi_common.go | 4 - cmd/podman/system/service_abi_linux.go | 6 - go.mod | 6 +- go.sum | 12 +- libpod/container.go | 6 +- libpod/container_api.go | 2 +- libpod/container_internal_common.go | 15 +- libpod/container_internal_freebsd.go | 4 - libpod/container_internal_linux.go | 35 +- libpod/define/info.go | 10 +- libpod/info_linux.go | 19 - libpod/networking_common.go | 22 +- libpod/networking_freebsd.go | 4 - libpod/networking_linux.go | 15 - libpod/networking_slirp4netns.go | 106 --- libpod/oci_conmon_common.go | 27 - libpod/options.go | 14 - pkg/api/handlers/compat/containers_create.go | 2 +- pkg/domain/infra/abi/network.go | 3 +- pkg/domain/infra/abi/play.go | 9 +- pkg/domain/infra/runtime_libpod.go | 3 - pkg/namespaces/namespaces.go | 8 +- pkg/specgen/generate/container.go | 17 +- pkg/specgen/generate/container_create.go | 5 +- pkg/specgen/generate/namespaces.go | 6 - pkg/specgen/generate/oci_linux.go | 2 +- pkg/specgen/generate/pod_create.go | 6 - pkg/specgen/generate/pod_create_test.go | 17 - pkg/specgen/namespaces.go | 26 +- pkg/specgen/namespaces_test.go | 15 - pkg/specgen/pod_validate.go | 4 +- pkg/specgen/podspecgen.go | 4 +- pkg/specgen/specgen.go | 6 +- .../github.com/containers/buildah/.cirrus.yml | 8 + vendor/github.com/containers/buildah/Makefile | 5 +- vendor/github.com/containers/buildah/add.go | 5 +- .../containers/buildah/run_common.go | 4 +- .../containers/buildah/run_linux.go | 46 -- .../openshift/imagebuilder/builder.go | 8 + .../openshift/imagebuilder/dispatchers.go | 4 +- .../openshift/imagebuilder/imagebuilder.spec | 2 +- .../internal/rootlessnetns/netns_linux.go | 78 +- .../common/libnetwork/slirp4netns/const.go | 17 - .../libnetwork/slirp4netns/const_linux.go | 11 - .../libnetwork/slirp4netns/slirp4netns.go | 743 ------------------ .../common/pkg/cgroups/cgroups_linux.go | 2 +- .../go.podman.io/common/pkg/config/config.go | 9 +- .../common/pkg/config/containers.conf | 36 +- .../common/pkg/config/containers.conf-freebsd | 32 +- .../common/pkg/servicereaper/service.go | 64 -- vendor/go.podman.io/common/pkg/ssh/types.go | 8 - .../common/pkg/systemd/systemd_linux.go | 4 +- vendor/modules.txt | 12 +- 56 files changed, 91 insertions(+), 1470 deletions(-) delete mode 100644 libpod/networking_slirp4netns.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/servicereaper/service.go diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go index 5cad945e298..098eef5cef0 100644 --- a/cmd/podman/common/completion.go +++ b/cmd/podman/common/completion.go @@ -1325,26 +1325,10 @@ func AutocompleteNetworkFlag(cmd *cobra.Command, _ []string, toComplete string) "none": nil, "host": nil, "private": nil, - "slirp4netns:": func(s string) ([]string, cobra.ShellCompDirective) { - skv := keyValueCompletion{ - "allow_host_loopback=": getBoolCompletion, - "cidr=": nil, - "enable_ipv6=": getBoolCompletion, - "mtu=": nil, - "outbound_addr=": nil, - "outbound_addr6=": nil, - "port_handler=": func(_ string) ([]string, cobra.ShellCompDirective) { - return []string{"rootlesskit", "slirp4netns"}, cobra.ShellCompDirectiveNoFileComp - }, - } - return completeKeyValues(s, skv) - }, } networks, _ := getNetworks(cmd, toComplete, completeDefault) suggestions, dir := completeKeyValues(toComplete, kv) - // add slirp4netns here it does not work correct if we add it to the kv map - suggestions = append(suggestions, "slirp4netns") return append(networks, suggestions...), dir } diff --git a/cmd/podman/root.go b/cmd/podman/root.go index 700b80939e3..08958f24acd 100644 --- a/cmd/podman/root.go +++ b/cmd/podman/root.go @@ -583,12 +583,6 @@ func rootFlags(cmd *cobra.Command, podmanConfig *entities.PodmanConfig) { pFlags.StringVar(&podmanConfig.ConmonPath, conmonFlagName, "", "Path of the conmon binary") _ = cmd.RegisterFlagCompletionFunc(conmonFlagName, completion.AutocompleteDefault) - // TODO (6.0): --network-cmd-path is deprecated, remove this option with the next major release - // We need to find all the places that use r.config.Engine.NetworkCmdPath and remove it - networkCmdPathFlagName := "network-cmd-path" - pFlags.StringVar(&podmanConfig.ContainersConf.Engine.NetworkCmdPath, networkCmdPathFlagName, podmanConfig.ContainersConfDefaultsRO.Engine.NetworkCmdPath, "Path to the command for configuring the network") - _ = cmd.RegisterFlagCompletionFunc(networkCmdPathFlagName, completion.AutocompleteDefault) - networkConfigDirFlagName := "network-config-dir" pFlags.StringVar(&podmanConfig.ContainersConf.Network.NetworkConfigDir, networkConfigDirFlagName, podmanConfig.ContainersConfDefaultsRO.Network.NetworkConfigDir, "Path of the configuration directory for networks") _ = cmd.RegisterFlagCompletionFunc(networkConfigDirFlagName, completion.AutocompleteDefault) diff --git a/cmd/podman/system/service_abi.go b/cmd/podman/system/service_abi.go index c8b1cd5531a..eff8cd2c456 100644 --- a/cmd/podman/system/service_abi.go +++ b/cmd/podman/system/service_abi.go @@ -125,7 +125,6 @@ func restService(flags *pflag.FlagSet, cfg *entities.PodmanConfig, opts entities maybeMoveToSubCgroup() - maybeStartServiceReaper() infra.StartWatcher(libpodRuntime) server, err := api.NewServerWithSettings(libpodRuntime, listener, opts) if err != nil { diff --git a/cmd/podman/system/service_abi_common.go b/cmd/podman/system/service_abi_common.go index 697e8b66e84..cf0d19c9d31 100644 --- a/cmd/podman/system/service_abi_common.go +++ b/cmd/podman/system/service_abi_common.go @@ -2,9 +2,5 @@ package system -// Currently, we only need servicereaper on Linux to support slirp4netns. -func maybeStartServiceReaper() { -} - // There is no cgroup on non linux. func maybeMoveToSubCgroup() {} diff --git a/cmd/podman/system/service_abi_linux.go b/cmd/podman/system/service_abi_linux.go index 326f57de732..5c5daffe128 100644 --- a/cmd/podman/system/service_abi_linux.go +++ b/cmd/podman/system/service_abi_linux.go @@ -6,14 +6,8 @@ import ( "github.com/containers/podman/v5/pkg/rootless" "github.com/sirupsen/logrus" "go.podman.io/common/pkg/cgroups" - "go.podman.io/common/pkg/servicereaper" ) -// Currently, we only need servicereaper on Linux to support slirp4netns. -func maybeStartServiceReaper() { - servicereaper.Start() -} - func maybeMoveToSubCgroup() { cgroupv2, _ := cgroups.IsCgroup2UnifiedMode() if rootless.IsRootless() && !cgroupv2 { diff --git a/go.mod b/go.mod index fe59c13ad56..74684ba7ecf 100644 --- a/go.mod +++ b/go.mod @@ -55,7 +55,7 @@ require ( github.com/opencontainers/runtime-spec v1.2.1 github.com/opencontainers/runtime-tools v0.9.1-0.20250523060157-0ea5ed0382a2 github.com/opencontainers/selinux v1.12.0 - github.com/openshift/imagebuilder v1.2.17 + github.com/openshift/imagebuilder v1.2.19 github.com/rootless-containers/rootlesskit/v2 v2.3.5 github.com/shirou/gopsutil/v4 v4.25.9 github.com/sirupsen/logrus v1.9.3 @@ -193,6 +193,6 @@ require ( tags.cncf.io/container-device-interface/specs-go v1.0.0 // indirect ) -replace go.podman.io/common => github.com/lsm5/container-libs/common v0.0.0-20251017191154-e63ca540eafe +replace go.podman.io/common => github.com/lsm5/container-libs/common v0.0.0-20251021180701-90bb6920858f -replace github.com/containers/buildah => github.com/lsm5/buildah v0.0.0-20251017145416-1c35ea0ae809 +replace github.com/containers/buildah => github.com/lsm5/buildah v0.0.0-20251021181103-9374d7fa4e33 diff --git a/go.sum b/go.sum index aeffdd0cb40..aae849c3d03 100644 --- a/go.sum +++ b/go.sum @@ -233,10 +233,10 @@ github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec h1:2tTW6cDth2T github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec/go.mod h1:TmwEoGCwIti7BCeJ9hescZgRtatxRE+A72pCoPfmcfk= github.com/linuxkit/virtsock v0.0.0-20241009230534-cb6a20cc0422 h1:XvRuyDDRvi+UDxHN/M4MW4HxjmNVMmUKQj/+AbgsYgk= github.com/linuxkit/virtsock v0.0.0-20241009230534-cb6a20cc0422/go.mod h1:JLgfq4XMVbvfNlAXla/41lZnp21O72a/wWHGJefAvgQ= -github.com/lsm5/buildah v0.0.0-20251017145416-1c35ea0ae809 h1:Xl7p6J9gfYA7TX0Z7VTNygqpEq7MZdrLX+EhsUdUOPc= -github.com/lsm5/buildah v0.0.0-20251017145416-1c35ea0ae809/go.mod h1:DOj6mclvkxcijXOmZTybYPZpuDv5ZyqoyjZSwfs/ikk= -github.com/lsm5/container-libs/common v0.0.0-20251017191154-e63ca540eafe h1:3zW0BFHDhdhVqZzxLJ0/TqDDkDET+/MPAQZNlvcZLkY= -github.com/lsm5/container-libs/common v0.0.0-20251017191154-e63ca540eafe/go.mod h1:aNd2a0S7pY+fx1X5kpQYuF4hbwLU8ZOccuVrhu7h1Xc= +github.com/lsm5/buildah v0.0.0-20251021181103-9374d7fa4e33 h1:imgY+jsruSreNEA5GW7tXcULJ1JFMjdm49XV2JDBMmY= +github.com/lsm5/buildah v0.0.0-20251021181103-9374d7fa4e33/go.mod h1:t9rFEW8WJROZ2Ir1lkCit0jJuH9LN34Pe7W9fVP8iK4= +github.com/lsm5/container-libs/common v0.0.0-20251021180701-90bb6920858f h1:74iytTBu5OWCtoF5q1eO0uDyJTn/um68tPfgexNFl3U= +github.com/lsm5/container-libs/common v0.0.0-20251021180701-90bb6920858f/go.mod h1:aNd2a0S7pY+fx1X5kpQYuF4hbwLU8ZOccuVrhu7h1Xc= github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMDtTVdcGu0B1GmmC7QJKiCCjyTAWQy0= github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= @@ -316,8 +316,8 @@ github.com/opencontainers/runtime-tools v0.9.1-0.20250523060157-0ea5ed0382a2 h1: github.com/opencontainers/runtime-tools v0.9.1-0.20250523060157-0ea5ed0382a2/go.mod h1:MXdPzqAA8pHC58USHqNCSjyLnRQ6D+NjbpP+02Z1U/0= github.com/opencontainers/selinux v1.12.0 h1:6n5JV4Cf+4y0KNXW48TLj5DwfXpvWlxXplUkdTrmPb8= github.com/opencontainers/selinux v1.12.0/go.mod h1:BTPX+bjVbWGXw7ZZWUbdENt8w0htPSrlgOOysQaU62U= -github.com/openshift/imagebuilder v1.2.17 h1:xusHiBvK7PpBsEeMGTg61Zx5kSajybjUAbBzVEJKH6g= -github.com/openshift/imagebuilder v1.2.17/go.mod h1:I9FlC4LVo0z/8GM8wdWVhxmw3tUVNM6tiwb8tRv4jvQ= +github.com/openshift/imagebuilder v1.2.19 h1:Xqq36KMJgsRU2MPaLRML23Myvk+AaY8pE8VJ6m6Vmy4= +github.com/openshift/imagebuilder v1.2.19/go.mod h1:fdbnfQWjxMBoB/jrvEzUk+UT1zqvtZZj7oQ7GU6RD9I= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/libpod/container.go b/libpod/container.go index 18e153e4c2b..88a773660cb 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -107,9 +107,6 @@ type Container struct { runtime *Runtime ociRuntime OCIRuntime - rootlessSlirpSyncR *os.File - rootlessSlirpSyncW *os.File - rootlessPortSyncR *os.File rootlessPortSyncW *os.File @@ -126,8 +123,7 @@ type Container struct { // This is true if a container is restored from a checkpoint. restoreFromCheckpoint bool - slirp4netnsSubnet *net.IPNet - pastaResult *pasta.SetupResult + pastaResult *pasta.SetupResult } // ContainerState contains the current state of the container diff --git a/libpod/container_api.go b/libpod/container_api.go index f98b64805b6..439b0b097f0 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -928,7 +928,7 @@ func (c *Container) Sync() error { // reloaded, and existing rules have been wiped out. It is expected that some // downtime will result, as the rules are destroyed as part of this process. // At present, this only works on root containers; it may be expanded to restart -// slirp4netns in the future to work with rootless containers as well. +// pasta(?) in the future to work with rootless containers as well. // Requires that the container must be running or created. func (c *Container) ReloadNetwork() error { if !c.batched { diff --git a/libpod/container_internal_common.go b/libpod/container_internal_common.go index 50c436c1af5..8619736fa0d 100644 --- a/libpod/container_internal_common.go +++ b/libpod/container_internal_common.go @@ -2262,7 +2262,7 @@ func (c *Container) addResolvConf() error { // add the nameservers from the networks status nameservers = networkNameServers } else { - // pasta and slirp4netns have a built in DNS forwarder. + // pasta has a built in DNS forwarder. nameservers = c.addSpecialDNS(nameservers) } } @@ -2317,12 +2317,7 @@ func (c *Container) checkForIPv6(netStatus map[string]types.StatusBlock) bool { } } } - - if c.pastaResult != nil { - return c.pastaResult.IPv6 - } - - return c.isSlirp4netnsIPv6() + return c.pastaResult.IPv6 } // Add a new nameserver to the container's resolv.conf, ensuring that it is the @@ -2384,12 +2379,6 @@ func (c *Container) getHostsEntries() (etchosts.HostEntries, error) { if len(c.pastaResult.IPAddresses) > 0 { entries = etchosts.HostEntries{{IP: c.pastaResult.IPAddresses[0].String(), Names: names}} } - case c.config.NetMode.IsSlirp4netns(): - ip, err := getSlirp4netnsIP(c.slirp4netnsSubnet) - if err != nil { - return nil, err - } - entries = etchosts.HostEntries{{IP: ip.String(), Names: names}} default: if c.hasNetNone() { entries = etchosts.HostEntries{{IP: "127.0.0.1", Names: names}} diff --git a/libpod/container_internal_freebsd.go b/libpod/container_internal_freebsd.go index 9edf3361f61..8405a0d3d56 100644 --- a/libpod/container_internal_freebsd.go +++ b/libpod/container_internal_freebsd.go @@ -298,10 +298,6 @@ func (c *Container) addSpecialDNS(nameservers []string) []string { return nameservers } -func (c *Container) isSlirp4netnsIPv6() bool { - return false -} - // check for net=none func (c *Container) hasNetNone() bool { return c.state.NetNS == "" diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index fea5cc115fe..7e99a681a34 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -22,7 +22,6 @@ import ( "github.com/opencontainers/runtime-tools/generate" "github.com/opencontainers/selinux/go-selinux/label" "github.com/sirupsen/logrus" - "go.podman.io/common/libnetwork/slirp4netns" "go.podman.io/common/libnetwork/types" "go.podman.io/common/pkg/cgroups" "go.podman.io/common/pkg/config" @@ -561,7 +560,7 @@ func (c *Container) setCgroupsPath(g *generate.Generator) error { return nil } -// addSpecialDNS adds special dns servers for slirp4netns and pasta +// addSpecialDNS adds special dns servers for pasta func (c *Container) addSpecialDNS(nameservers []string) []string { switch { case c.config.NetMode.IsBridge(): @@ -571,42 +570,10 @@ func (c *Container) addSpecialDNS(nameservers []string) []string { } case c.pastaResult != nil: nameservers = append(nameservers, c.pastaResult.DNSForwardIPs...) - case c.config.NetMode.IsSlirp4netns(): - // slirp4netns has a built in DNS forwarder. - slirp4netnsDNS, err := slirp4netns.GetDNS(c.slirp4netnsSubnet) - if err != nil { - logrus.Warn("Failed to determine Slirp4netns DNS: ", err.Error()) - } else { - nameservers = append(nameservers, slirp4netnsDNS.String()) - } } return nameservers } -func (c *Container) isSlirp4netnsIPv6() bool { - if c.config.NetMode.IsSlirp4netns() { - extraOptions := c.config.NetworkOptions[slirp4netns.BinaryName] - options := make([]string, 0, len(c.runtime.config.Engine.NetworkCmdOptions.Get())+len(extraOptions)) - options = append(options, c.runtime.config.Engine.NetworkCmdOptions.Get()...) - options = append(options, extraOptions...) - - // loop backwards as the last argument wins and we can exit early - // This should be kept in sync with c/common/libnetwork/slirp4netns. - for i := len(options) - 1; i >= 0; i-- { - switch options[i] { - case "enable_ipv6=true": - return true - case "enable_ipv6=false": - return false - } - } - // default is true - return true - } - - return false -} - // check for net=none func (c *Container) hasNetNone() bool { if !c.config.CreateNetNS { diff --git a/libpod/define/info.go b/libpod/define/info.go index 2162a33f05a..26b9009d3e1 100644 --- a/libpod/define/info.go +++ b/libpod/define/info.go @@ -52,13 +52,12 @@ type HostInfo struct { OS string `json:"os"` // RemoteSocket returns the UNIX domain socket the Podman service is listening on RemoteSocket *RemoteSocket `json:"remoteSocket,omitempty"` - // RootlessNetworkCmd returns the default rootless network command (slirp4netns or pasta) + // RootlessNetworkCmd returns the default rootless network command (pasta) RootlessNetworkCmd string `json:"rootlessNetworkCmd"` RuntimeInfo map[string]any `json:"runtimeInfo,omitempty"` // ServiceIsRemote is true when the podman/libpod service is remote to the client ServiceIsRemote bool `json:"serviceIsRemote"` Security SecurityInfo `json:"security"` - Slirp4NetNS SlirpInfo `json:"slirp4netns"` Pasta PastaInfo `json:"pasta"` SwapFree int64 `json:"swapFree"` @@ -76,13 +75,6 @@ type RemoteSocket struct { Exists bool `json:"exists"` } -// SlirpInfo describes the slirp executable that is being used -type SlirpInfo struct { - Executable string `json:"executable"` - Package string `json:"package"` - Version string `json:"version"` -} - // PastaInfo describes the pasta executable that is being used type PastaInfo struct { Executable string `json:"executable"` diff --git a/libpod/info_linux.go b/libpod/info_linux.go index edad644d2b8..1d4cc1a89cc 100644 --- a/libpod/info_linux.go +++ b/libpod/info_linux.go @@ -16,7 +16,6 @@ import ( "github.com/opencontainers/selinux/go-selinux" "github.com/sirupsen/logrus" "go.podman.io/common/libnetwork/pasta" - "go.podman.io/common/libnetwork/slirp4netns" "go.podman.io/common/pkg/apparmor" "go.podman.io/common/pkg/cgroups" "go.podman.io/common/pkg/seccomp" @@ -47,24 +46,6 @@ func (r *Runtime) setPlatformHostInfo(info *define.HostInfo) error { SECCOMPProfilePath: seccompProfilePath, SELinuxEnabled: selinux.GetEnabled(), } - info.Slirp4NetNS = define.SlirpInfo{} - - slirp4netnsPath := r.config.Engine.NetworkCmdPath - if slirp4netnsPath == "" { - slirp4netnsPath, _ = r.config.FindHelperBinary(slirp4netns.BinaryName, true) - } - if slirp4netnsPath != "" { - ver, err := version.Program(slirp4netnsPath) - if err != nil { - logrus.Warnf("Failed to retrieve program version for %s: %v", slirp4netnsPath, err) - } - program := define.SlirpInfo{ - Executable: slirp4netnsPath, - Package: version.Package(slirp4netnsPath), - Version: ver, - } - info.Slirp4NetNS = program - } pastaPath, _ := r.config.FindHelperBinary(pasta.BinaryName, true) if pastaPath != "" { diff --git a/libpod/networking_common.go b/libpod/networking_common.go index 28ee91a6dd0..92d16d047ed 100644 --- a/libpod/networking_common.go +++ b/libpod/networking_common.go @@ -111,8 +111,7 @@ func (r *Runtime) teardownNetwork(ctr *Container) error { return err } - if !ctr.config.NetMode.IsSlirp4netns() && - !ctr.config.NetMode.IsPasta() && len(networks) > 0 { + if !ctr.config.NetMode.IsPasta() && len(networks) > 0 { netOpts := ctr.getNetworkOptions(networks) return r.teardownNetworkBackend(ctr.state.NetNS, netOpts) } @@ -133,8 +132,7 @@ func isBridgeNetMode(n namespaces.NetworkMode) error { // This is mainly used when a reload of firewall rules wipes out existing // firewall configuration. // Efforts will be made to preserve MAC and IP addresses. -// Only works on containers with bridge networking at present, though in the future we could -// extend this to stop + restart slirp4netns +// Only works on containers with bridge networking. func (r *Runtime) reloadContainerNetwork(ctr *Container) (map[string]types.StatusBlock, error) { if ctr.state.NetNS == "" { return nil, fmt.Errorf("container %s network is not configured, refusing to reload: %w", ctr.ID(), define.ErrCtrStateInvalid) @@ -433,14 +431,6 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, _ bool) error { return err } - // Reload ports when there are still connected networks, maybe we removed the network interface with the child ip. - // Reloading without connected networks does not make sense, so we can skip this step. - if rootless.IsRootless() && len(networkStatus) > 0 { - if err := c.reloadRootlessRLKPortMapping(); err != nil { - return err - } - } - // Update resolv.conf if required if statusExist { stringIPs := make([]string, 0, len(oldStatus.DNSServerIPs)) @@ -587,14 +577,6 @@ func (c *Container) NetworkConnect(nameOrID, netName string, netOpts types.PerNe return err } - // The first network needs a port reload to set the correct child ip for the rootlessport process. - // Adding a second network does not require a port reload because the child ip is still valid. - if rootless.IsRootless() && len(networks) == 0 { - if err := c.reloadRootlessRLKPortMapping(); err != nil { - return err - } - } - ipv6 := c.checkForIPv6(networkStatus) // Update resolv.conf if required diff --git a/libpod/networking_freebsd.go b/libpod/networking_freebsd.go index 76b189234ce..20b0163398e 100644 --- a/libpod/networking_freebsd.go +++ b/libpod/networking_freebsd.go @@ -225,7 +225,3 @@ func (c *Container) inspectJoinedNetworkNS(_ string) (q types.StatusBlock, retEr // TODO: extract interface information from the vnet jail return types.StatusBlock{}, nil } - -func (c *Container) reloadRootlessRLKPortMapping() error { - return errors.New("unsupported (*Container).reloadRootlessRLKPortMapping") -} diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 7c58936b2fc..9d28238cccd 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -8,7 +8,6 @@ import ( "github.com/containernetworking/plugins/pkg/ns" "github.com/containers/podman/v5/libpod/define" - "github.com/containers/podman/v5/pkg/rootless" "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" "github.com/vishvananda/netlink" @@ -29,9 +28,6 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS string) (status map[strin } } }() - if ctr.config.NetMode.IsSlirp4netns() { - return nil, r.setupSlirp4netns(ctr, ctrNS) - } if ctr.config.NetMode.IsPasta() { return nil, r.setupPasta(ctr, ctrNS) } @@ -59,17 +55,6 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS string) (status map[strin } }() - // set up rootless port forwarder when rootless with ports and the network status is empty, - // if this is called from network reload the network status will not be empty and we should - // not set up port because they are still active - if rootless.IsRootless() && len(ctr.config.PortMappings) > 0 && ctr.getNetworkStatus() == nil { - // set up port forwarder for rootless netns - // TODO: support slirp4netns port forwarder as well - // make sure to fix this in container.handleRestartPolicy() as well - // Important we have to call this after r.setUpNetwork() so that - // we can use the proper netStatus - err = r.setupRootlessPortMappingViaRLK(ctr, ctrNS, netStatus) - } return netStatus, err } diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go deleted file mode 100644 index 9685f8507af..00000000000 --- a/libpod/networking_slirp4netns.go +++ /dev/null @@ -1,106 +0,0 @@ -//go:build !remote && linux - -package libpod - -import ( - "fmt" - "io" - "net" - "os" - "path/filepath" - - "github.com/containers/podman/v5/pkg/errorhandling" - "github.com/sirupsen/logrus" - "go.podman.io/common/libnetwork/slirp4netns" - "go.podman.io/common/libnetwork/types" -) - -// setupSlirp4netns can be called in rootful as well as in rootless -func (r *Runtime) setupSlirp4netns(ctr *Container, netns string) error { - ports := ctr.convertPortMappings() - - if !ctr.config.PostConfigureNetNS { - var err error - ctr.rootlessSlirpSyncR, ctr.rootlessSlirpSyncW, err = os.Pipe() - if err != nil { - return fmt.Errorf("failed to create rootless network sync pipe: %w", err) - } - if len(ports) > 0 { - ctr.rootlessPortSyncR, ctr.rootlessPortSyncW, err = os.Pipe() - if err != nil { - return fmt.Errorf("failed to create rootless port sync pipe: %w", err) - } - } - } - defer errorhandling.CloseQuiet(ctr.rootlessSlirpSyncR) - if ctr.rootlessPortSyncR != nil { - defer errorhandling.CloseQuiet(ctr.rootlessPortSyncR) - } - - res, err := slirp4netns.Setup(&slirp4netns.SetupOptions{ - Config: r.config, - ContainerID: ctr.ID(), - Netns: netns, - Ports: ports, - ExtraOptions: ctr.config.NetworkOptions[slirp4netns.BinaryName], - Slirp4netnsExitPipeR: ctr.rootlessSlirpSyncR, - RootlessPortExitPipeR: ctr.rootlessPortSyncR, - }) - if err != nil { - return err - } - ctr.slirp4netnsSubnet = res.Subnet - return nil -} - -func (r *Runtime) setupRootlessPortMappingViaRLK(ctr *Container, netnsPath string, netStatus map[string]types.StatusBlock) error { - var err error - if !ctr.config.PostConfigureNetNS { - ctr.rootlessPortSyncR, ctr.rootlessPortSyncW, err = os.Pipe() - if err != nil { - return fmt.Errorf("failed to create rootless port sync pipe: %w", err) - } - } - defer errorhandling.CloseQuiet(ctr.rootlessPortSyncR) - return slirp4netns.SetupRootlessPortMappingViaRLK(&slirp4netns.SetupOptions{ - Config: r.config, - ContainerID: ctr.ID(), - Netns: netnsPath, - Ports: ctr.convertPortMappings(), - RootlessPortExitPipeR: ctr.rootlessPortSyncR, - }, nil, netStatus) -} - -// reloadRootlessRLKPortMapping will trigger a reload for the port mappings in the rootlessport process. -// This should only be called by network connect/disconnect and only as rootless. -func (c *Container) reloadRootlessRLKPortMapping() error { - if len(c.config.PortMappings) == 0 { - return nil - } - childIP := slirp4netns.GetRootlessPortChildIP(nil, c.state.NetworkStatus) - logrus.Debugf("reloading rootless ports for container %s, childIP is %s", c.config.ID, childIP) - - conn, err := openUnixSocket(filepath.Join(c.runtime.config.Engine.TmpDir, "rp", c.config.ID)) - if err != nil { - return fmt.Errorf("could not reload rootless port mappings, port forwarding may no longer work correctly: %w", err) - } - defer conn.Close() - enc := json.NewEncoder(conn) - err = enc.Encode(childIP) - if err != nil { - return fmt.Errorf("port reloading failed: %w", err) - } - b, err := io.ReadAll(conn) - if err != nil { - return fmt.Errorf("port reloading failed: %w", err) - } - data := string(b) - if data != "OK" { - return fmt.Errorf("port reloading failed: %s", data) - } - return nil -} - -func getSlirp4netnsIP(subnet *net.IPNet) (*net.IP, error) { - return slirp4netns.GetIP(subnet) -} diff --git a/libpod/oci_conmon_common.go b/libpod/oci_conmon_common.go index 6bf3576c52c..be037bd1b31 100644 --- a/libpod/oci_conmon_common.go +++ b/libpod/oci_conmon_common.go @@ -1170,33 +1170,6 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co ctr.reservedPorts = nil } - if ctr.config.NetMode.IsSlirp4netns() || rootless.IsRootless() { - if ctr.config.PostConfigureNetNS { - havePortMapping := len(ctr.config.PortMappings) > 0 - if havePortMapping { - ctr.rootlessPortSyncR, ctr.rootlessPortSyncW, err = os.Pipe() - if err != nil { - return 0, fmt.Errorf("failed to create rootless port sync pipe: %w", err) - } - } - ctr.rootlessSlirpSyncR, ctr.rootlessSlirpSyncW, err = os.Pipe() - if err != nil { - return 0, fmt.Errorf("failed to create rootless network sync pipe: %w", err) - } - } - - if ctr.rootlessSlirpSyncW != nil { - defer errorhandling.CloseQuiet(ctr.rootlessSlirpSyncW) - // Leak one end in conmon, the other one will be leaked into slirp4netns - cmd.ExtraFiles = append(cmd.ExtraFiles, ctr.rootlessSlirpSyncW) - } - - if ctr.rootlessPortSyncW != nil { - defer errorhandling.CloseQuiet(ctr.rootlessPortSyncW) - // Leak one end in conmon, the other one will be leaked into rootlessport - cmd.ExtraFiles = append(cmd.ExtraFiles, ctr.rootlessPortSyncW) - } - } var runtimeRestoreStarted time.Time if restoreOptions != nil { runtimeRestoreStarted = time.Now() diff --git a/libpod/options.go b/libpod/options.go index d5055d6c9fe..06bf08fbb2f 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -180,20 +180,6 @@ func WithConmonPath(path string) RuntimeOption { } } -// WithNetworkCmdPath specifies the path to the slirp4netns binary which manages the -// runtime. -func WithNetworkCmdPath(path string) RuntimeOption { - return func(rt *Runtime) error { - if rt.valid { - return define.ErrRuntimeFinalized - } - - rt.config.Engine.NetworkCmdPath = path - - return nil - } -} - // WithNetworkBackend specifies the name of the network backend. func WithNetworkBackend(name string) RuntimeOption { return func(rt *Runtime) error { diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go index 5cd9fe19faa..ffdbdef18f7 100644 --- a/pkg/api/handlers/compat/containers_create.go +++ b/pkg/api/handlers/compat/containers_create.go @@ -291,7 +291,7 @@ func cliOpts(cc handlers.CreateContainerConfig, rtc *config.Config) (*entities.C } } - // special case for NetworkMode, the podman default is slirp4netns for + // special case for NetworkMode, the podman default is pasta for // rootless but for better docker compat we want bridge. Do this only if // the default config in containers.conf wasn't overridden to use another // value than the default "private" one. diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go index 2aa45d99437..6b7f28f7b07 100644 --- a/pkg/domain/infra/abi/network.go +++ b/pkg/domain/infra/abi/network.go @@ -13,7 +13,6 @@ import ( "github.com/containers/podman/v5/libpod/events" "github.com/containers/podman/v5/pkg/domain/entities" "go.podman.io/common/libnetwork/pasta" - "go.podman.io/common/libnetwork/slirp4netns" "go.podman.io/common/libnetwork/types" netutil "go.podman.io/common/libnetwork/util" ) @@ -180,7 +179,7 @@ func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, o } func (ic *ContainerEngine) NetworkCreate(_ context.Context, network types.Network, createOptions *types.NetworkCreateOptions) (*types.Network, error) { - if slices.Contains([]string{"none", "host", "bridge", "private", slirp4netns.BinaryName, pasta.BinaryName, "container", "ns", "default"}, network.Name) { + if slices.Contains([]string{"none", "host", "bridge", "private", pasta.BinaryName, "container", "ns", "default"}, network.Name) { return nil, fmt.Errorf("cannot create network with name %q because it conflicts with a valid network mode", network.Name) } network, err := ic.Libpod.Network().NetworkCreate(network, createOptions) diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index bf41e73a440..8d06e45ae90 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -74,11 +74,10 @@ func (ic *ContainerEngine) createServiceContainer(ctx context.Context, name stri } ctrOpts := entities.ContainerCreateOptions{ // Inherited from infra containers - IsInfra: false, - MemorySwappiness: -1, - ReadOnly: true, - ReadWriteTmpFS: false, - // No need to spin up slirp etc. + IsInfra: false, + MemorySwappiness: -1, + ReadOnly: true, + ReadWriteTmpFS: false, Net: &entities.NetOptions{Network: specgen.Namespace{NSMode: specgen.NoNetwork}}, StopTimeout: rtc.Engine.StopTimeout, HealthLogDestination: define.DefaultHealthCheckLocalDestination, diff --git a/pkg/domain/infra/runtime_libpod.go b/pkg/domain/infra/runtime_libpod.go index 9a4a08b043d..a3966026561 100644 --- a/pkg/domain/infra/runtime_libpod.go +++ b/pkg/domain/infra/runtime_libpod.go @@ -164,9 +164,6 @@ func getRuntime(ctx context.Context, fs *flag.FlagSet, opts *engineOpts) (*libpo if fs.Changed("tmpdir") { options = append(options, libpod.WithTmpDir(cfg.ContainersConf.Engine.TmpDir)) } - if fs.Changed("network-cmd-path") { - options = append(options, libpod.WithNetworkCmdPath(cfg.ContainersConf.Engine.NetworkCmdPath)) - } if fs.Changed("network-backend") { options = append(options, libpod.WithNetworkBackend(cfg.ContainersConf.Network.NetworkBackend)) } diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go index ca2c8ed3b8f..8407218e68d 100644 --- a/pkg/namespaces/namespaces.go +++ b/pkg/namespaces/namespaces.go @@ -16,7 +16,6 @@ const ( podType = "pod" privateType = "private" shareableType = "shareable" - slirpType = "slirp4netns" pastaType = "pasta" ) @@ -202,11 +201,6 @@ func (n NetworkMode) IsBridge() bool { return n == bridgeType } -// IsSlirp4netns indicates if we are running a rootless network stack -func (n NetworkMode) IsSlirp4netns() bool { - return n == slirpType || strings.HasPrefix(string(n), slirpType+":") -} - // IsPasta indicates if we are running a rootless network stack using pasta func (n NetworkMode) IsPasta() bool { return n == pastaType || strings.HasPrefix(string(n), pastaType+":") @@ -230,5 +224,5 @@ func (n NetworkMode) IsPod() bool { // IsUserDefined indicates user-created network func (n NetworkMode) IsUserDefined() bool { - return !n.IsDefault() && !n.IsBridge() && !n.IsHost() && !n.IsNone() && !n.IsContainer() && !n.IsSlirp4netns() && !n.IsPasta() && !n.IsNS() + return !n.IsDefault() && !n.IsBridge() && !n.IsHost() && !n.IsNone() && !n.IsContainer() && !n.IsPasta() && !n.IsNS() } diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go index 4d60cb31424..3596fda7f42 100644 --- a/pkg/specgen/generate/container.go +++ b/pkg/specgen/generate/container.go @@ -443,21 +443,6 @@ func ConfigToSpec(rt *libpod.Runtime, specg *specgen.SpecGenerator, containerID specg.Expose = toExpose specg.PortMappings = conf.PortMappings specg.NetNS = specgen.Namespace{NSMode: specgen.Bridge} - case conf.NetMode.IsSlirp4netns(): - toExpose := make(map[uint16]string, len(conf.ExposedPorts)) - for _, expose := range []map[uint16][]string{conf.ExposedPorts} { - for port, proto := range expose { - toExpose[port] = strings.Join(proto, ",") - } - } - specg.Expose = toExpose - specg.PortMappings = conf.PortMappings - netMode := strings.Split(string(conf.NetMode), ":") - var val string - if len(netMode) > 1 { - val = netMode[1] - } - specg.NetNS = specgen.Namespace{NSMode: specgen.Slirp, Value: val} case conf.NetMode.IsPrivate(): specg.NetNS = specgen.Namespace{NSMode: specgen.Private} case conf.NetMode.IsDefault(): @@ -631,7 +616,7 @@ func CheckName(rt *libpod.Runtime, n string, kind bool) string { // Note: Update `podman run --publish | -p` docs when modifying this function. func isPortMappingCompatibleNetNSMode(nsMode specgen.NamespaceMode) bool { switch nsMode { - case specgen.Bridge, specgen.Slirp, specgen.Pasta: + case specgen.Bridge, specgen.Pasta: return true default: return false diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go index d06cf7559b6..fc3dfc4adf8 100644 --- a/pkg/specgen/generate/container_create.go +++ b/pkg/specgen/generate/container_create.go @@ -23,7 +23,6 @@ import ( "github.com/sirupsen/logrus" "go.podman.io/common/libimage" "go.podman.io/common/libnetwork/pasta" - "go.podman.io/common/libnetwork/slirp4netns" "tags.cncf.io/container-device-interface/pkg/parser" ) @@ -203,9 +202,7 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener return nil, nil, nil, err } switch conf.Network.DefaultRootlessNetworkCmd { - case slirp4netns.BinaryName, "": - s.NetNS.NSMode = specgen.Slirp - case pasta.BinaryName: + case pasta.BinaryName, "": s.NetNS.NSMode = specgen.Pasta default: return nil, nil, nil, fmt.Errorf("invalid default_rootless_network_cmd option %q", diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go index 014d64a1ef1..78de9a1846b 100644 --- a/pkg/specgen/generate/namespaces.go +++ b/pkg/specgen/generate/namespaces.go @@ -322,12 +322,6 @@ func namespaceOptions(s *specgen.SpecGenerator, rt *libpod.Runtime, pod *libpod. } else { toReturn = append(toReturn, libpod.WithNetNSFrom(netCtr)) } - case specgen.Slirp: - val := "slirp4netns" - if s.NetNS.Value != "" { - val = fmt.Sprintf("slirp4netns:%s", s.NetNS.Value) - } - toReturn = append(toReturn, libpod.WithNetNS(portMappings, postConfigureNetNS, val, nil)) case specgen.Pasta: val := "pasta" toReturn = append(toReturn, libpod.WithNetNS(portMappings, postConfigureNetNS, val, nil)) diff --git a/pkg/specgen/generate/oci_linux.go b/pkg/specgen/generate/oci_linux.go index 335a82f2a2a..666c3015d3e 100644 --- a/pkg/specgen/generate/oci_linux.go +++ b/pkg/specgen/generate/oci_linux.go @@ -51,7 +51,7 @@ func canMountSys(isRootless, isNewUserns bool, s *specgen.SpecGenerator) bool { } if isNewUserns { switch s.NetNS.NSMode { - case specgen.Slirp, specgen.Pasta, specgen.Private, specgen.NoNetwork, specgen.Bridge: + case specgen.Pasta, specgen.Private, specgen.NoNetwork, specgen.Bridge: return true default: return false diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go index fedc9019752..964cd5d2657 100644 --- a/pkg/specgen/generate/pod_create.go +++ b/pkg/specgen/generate/pod_create.go @@ -205,12 +205,6 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) { return nil, fmt.Errorf("cannot set host network if network-related configuration is specified: %w", define.ErrInvalidArg) } spec.NetNS.NSMode = specgen.Host - case specgen.Slirp: - logrus.Debugf("Pod will use slirp4netns") - if spec.NetNS.NSMode != specgen.Host { - spec.NetworkOptions = p.NetworkOptions - spec.NetNS.NSMode = specgen.Slirp - } case specgen.Pasta: logrus.Debugf("Pod will use pasta") if spec.NetNS.NSMode != specgen.Host { diff --git a/pkg/specgen/generate/pod_create_test.go b/pkg/specgen/generate/pod_create_test.go index f571519eab6..b2fba94f880 100644 --- a/pkg/specgen/generate/pod_create_test.go +++ b/pkg/specgen/generate/pod_create_test.go @@ -128,23 +128,6 @@ func TestMapSpecNetworkOptions(t *testing.T) { podSpec: createPodSpecWithNetworks(specgen.Host), mustError: true, }, - { - name: "Slirp", - podSpec: createPodSpec(specgen.Slirp), - expectedNSMode: specgen.Slirp, - }, - { - name: "Slirp but if infra spec NS mode is Host", - podSpec: specgen.PodSpecGenerator{ - InfraContainerSpec: &specgen.SpecGenerator{ - ContainerNetworkConfig: specgen.ContainerNetworkConfig{NetNS: specgen.Namespace{NSMode: host}}, - }, - PodNetworkConfig: specgen.PodNetworkConfig{ - NetNS: specgen.Namespace{NSMode: specgen.Slirp}, - }, - }, - expectedNSMode: specgen.Host, - }, { name: "Path", podSpec: createPodSpecWithNetNsPath("/var/run/netns/bla"), diff --git a/pkg/specgen/namespaces.go b/pkg/specgen/namespaces.go index d3cad60f8ea..aa4d1bdec28 100644 --- a/pkg/specgen/namespaces.go +++ b/pkg/specgen/namespaces.go @@ -50,10 +50,6 @@ const ( // should be used. // Only used with the network namespace, invalid otherwise. Bridge NamespaceMode = "bridge" - // Slirp indicates that a slirp4netns network stack should - // be used. - // Only used with the network namespace, invalid otherwise. - Slirp NamespaceMode = "slirp4netns" // Pasta indicates that a pasta network stack should be used. // Only used with the network namespace, invalid otherwise. Pasta NamespaceMode = "pasta" @@ -159,8 +155,6 @@ func validateNetNS(n *Namespace) error { return nil } switch n.NSMode { - case Slirp: - break case Pasta: // Check if we run rootless/in a userns. Do not use rootless.IsRootless() here. // Pasta switches to nobody when running as root which causes it to fail while @@ -182,11 +176,10 @@ func validateNetNS(n *Namespace) error { if len(n.Value) < 1 { return fmt.Errorf("namespace mode %s requires a value", n.NSMode) } - } else if n.NSMode != Slirp { - // All others except must NOT set a string value - if len(n.Value) > 0 { - return fmt.Errorf("namespace value %s cannot be provided with namespace mode %s", n.Value, n.NSMode) - } + } + // All others except must NOT set a string value + if len(n.Value) > 0 { + return fmt.Errorf("namespace value %s cannot be provided with namespace mode %s", n.Value, n.NSMode) } return nil @@ -212,7 +205,7 @@ func (n *Namespace) validate() error { switch n.NSMode { case "", Default, Host, Path, FromContainer, FromPod, Private: // Valid, do nothing - case NoNetwork, Bridge, Slirp, Pasta: + case NoNetwork, Bridge, Pasta: return errors.New("cannot use network modes with non-network namespace") default: return fmt.Errorf("invalid namespace type %s specified", n.NSMode) @@ -350,13 +343,6 @@ func ParseNetworkFlag(networks []string) (Namespace, map[string]types.PerNetwork podmanNetworks := make(map[string]types.PerNetworkOptions) switch { - case ns == string(Slirp), strings.HasPrefix(ns, string(Slirp)+":"): - key, options, hasOptions := strings.Cut(ns, ":") - if hasOptions { - networkOptions = make(map[string][]string) - networkOptions[key] = strings.Split(options, ",") - } - toReturn.NSMode = Slirp case ns == string(FromPod): toReturn.NSMode = FromPod case ns == "" || ns == string(Default) || ns == string(Private): @@ -428,7 +414,7 @@ func ParseNetworkFlag(networks []string) (Namespace, map[string]types.PerNetwork if name == "" { return toReturn, nil, nil, fmt.Errorf("network name cannot be empty: %w", define.ErrInvalidArg) } - if slices.Contains([]string{string(Bridge), string(Slirp), string(Pasta), string(FromPod), string(NoNetwork), + if slices.Contains([]string{string(Bridge), string(Pasta), string(FromPod), string(NoNetwork), string(Default), string(Private), string(Path), string(FromContainer), string(Host)}, name) { return toReturn, nil, nil, fmt.Errorf("can only set extra network names, selected mode %s conflicts with bridge: %w", name, define.ErrInvalidArg) } diff --git a/pkg/specgen/namespaces_test.go b/pkg/specgen/namespaces_test.go index 22b84ee6461..636e2c922be 100644 --- a/pkg/specgen/namespaces_test.go +++ b/pkg/specgen/namespaces_test.go @@ -57,12 +57,6 @@ func TestParseNetworkFlag(t *testing.T) { defaultNetName: {}, }, }, - { - name: "slirp4netns mode", - args: []string{"slirp4netns"}, - nsmode: Namespace{NSMode: Slirp}, - networks: map[string]types.PerNetworkOptions{}, - }, { name: "from pod mode", args: []string{"pod"}, @@ -87,15 +81,6 @@ func TestParseNetworkFlag(t *testing.T) { nsmode: Namespace{NSMode: Path, Value: "/path"}, networks: map[string]types.PerNetworkOptions{}, }, - { - name: "slirp4netns mode with options", - args: []string{"slirp4netns:cidr=10.0.0.0/24"}, - nsmode: Namespace{NSMode: Slirp}, - networks: map[string]types.PerNetworkOptions{}, - options: map[string][]string{ - "slirp4netns": {"cidr=10.0.0.0/24"}, - }, - }, { name: "bridge mode with options 1", args: []string{"bridge:ip=10.0.0.1,mac=11:22:33:44:55:66"}, diff --git a/pkg/specgen/pod_validate.go b/pkg/specgen/pod_validate.go index a2732eeb231..3a905b2840d 100644 --- a/pkg/specgen/pod_validate.go +++ b/pkg/specgen/pod_validate.go @@ -65,9 +65,9 @@ func (p *PodSpecGenerator) Validate() error { return exclusivePodOptions("NoInfra", "NoManageResolvConf") } } - if p.NetNS.NSMode != "" && p.NetNS.NSMode != Bridge && p.NetNS.NSMode != Slirp && p.NetNS.NSMode != Pasta && p.NetNS.NSMode != Default { + if p.NetNS.NSMode != "" && p.NetNS.NSMode != Bridge && p.NetNS.NSMode != Pasta && p.NetNS.NSMode != Default { if len(p.PortMappings) > 0 { - return errors.New("PortMappings can only be used with Bridge, slirp4netns, or pasta networking") + return errors.New("PortMappings can only be used with Bridge, or pasta networking") } } diff --git a/pkg/specgen/podspecgen.go b/pkg/specgen/podspecgen.go index ad1f6267baa..7863dbb4a43 100644 --- a/pkg/specgen/podspecgen.go +++ b/pkg/specgen/podspecgen.go @@ -106,13 +106,13 @@ type PodNetworkConfig struct { // containers in the pod. // Cannot be set to FromContainer and FromPod. // Setting this to anything except default conflicts with NoInfra=true. - // Defaults to Bridge as root and Slirp as rootless. + // Defaults to Bridge as root and Pasta as rootless. // Mandatory. NetNS Namespace `json:"netns"` // PortMappings is a set of ports to map into the infra container. // As, by default, containers share their network with the infra // container, this will forward the ports to the entire pod. - // Only available if NetNS is set to Bridge, Slirp, or Pasta. + // Only available if NetNS is set to Bridge or Pasta. // Optional. PortMappings []types.PortMapping `json:"portmappings,omitempty"` // Map of networks names to ids the container should join to. diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go index a7437ef0a43..7cff432d79e 100644 --- a/pkg/specgen/specgen.go +++ b/pkg/specgen/specgen.go @@ -477,14 +477,14 @@ type ContainerNetworkConfig struct { // Mandatory. NetNS Namespace `json:"netns"` // PortBindings is a set of ports to map into the container. - // Only available if NetNS is set to bridge, slirp, or pasta. + // Only available if NetNS is set to bridge or pasta. // Optional. PortMappings []nettypes.PortMapping `json:"portmappings,omitempty"` // PublishExposedPorts will publish ports specified in the image to // random unused ports (guaranteed to be above 1024) on the host. // This is based on ports set in Expose below, and any ports specified // by the Image (if one is given). - // Only available if NetNS is set to Bridge or Slirp. + // Only available if NetNS is set to Bridge. // Optional. PublishExposedPorts *bool `json:"publish_image_ports,omitempty"` // Expose is a number of ports that will be forwarded to the container @@ -493,7 +493,7 @@ type ContainerNetworkConfig struct { // protocol i.e map[uint16]string. Allowed protocols are "tcp", "udp", and "sctp", or some // combination of the three separated by commas. // If protocol is set to "" we will assume TCP. - // Only available if NetNS is set to Bridge or Slirp, and + // Only available if NetNS is set to Bridge, and // PublishExposedPorts is set. // Optional. Expose map[uint16]string `json:"expose,omitempty"` diff --git a/vendor/github.com/containers/buildah/.cirrus.yml b/vendor/github.com/containers/buildah/.cirrus.yml index 5debb3203d1..66b950241ef 100644 --- a/vendor/github.com/containers/buildah/.cirrus.yml +++ b/vendor/github.com/containers/buildah/.cirrus.yml @@ -32,12 +32,14 @@ env: IMAGE_PROJECT: "libpod-218412" FEDORA_NAME: "fedora-42" PRIOR_FEDORA_NAME: "fedora-41" + RAWHIDE_NAME: "rawhide" DEBIAN_NAME: "debian-13" # Image identifiers IMAGE_SUFFIX: "c20250910t092246z-f42f41d13" FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}" PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}" + RAWHIDE_CACHE_IMAGE_NAME: "rawhide-${IMAGE_SUFFIX}" # Used temporarily for rust-podman-sequoia. After that RPM is available in stable Fedora releases, we can stop testing against Rawhide again. DEBIAN_CACHE_IMAGE_NAME: "debian-${IMAGE_SUFFIX}" IN_PODMAN_IMAGE: "quay.io/libpod/fedora_podman:${IMAGE_SUFFIX}" @@ -79,6 +81,7 @@ meta_task: IMGNAMES: |- ${FEDORA_CACHE_IMAGE_NAME} ${PRIOR_FEDORA_CACHE_IMAGE_NAME} + ${RAWHIDE_CACHE_IMAGE_NAME} ${DEBIAN_CACHE_IMAGE_NAME} build-push-${IMAGE_SUFFIX} BUILDID: "${CIRRUS_BUILD_ID}" @@ -238,6 +241,11 @@ integration_task: DISTRO_NV: "${DEBIAN_NAME}" IMAGE_NAME: "${DEBIAN_CACHE_IMAGE_NAME}" STORAGE_DRIVER: 'overlay' + - env: + DISTRO_NV: "${RAWHIDE_NAME}" + IMAGE_NAME: "${RAWHIDE_CACHE_IMAGE_NAME}" + STORAGE_DRIVER: 'overlay' + TEST_BUILD_TAGS: 'containers_image_sequoia' gce_instance: &integration_gce_instance image_name: "$IMAGE_NAME" diff --git a/vendor/github.com/containers/buildah/Makefile b/vendor/github.com/containers/buildah/Makefile index d7efd999224..42a25d01708 100644 --- a/vendor/github.com/containers/buildah/Makefile +++ b/vendor/github.com/containers/buildah/Makefile @@ -8,7 +8,7 @@ ifeq ($(shell uname -s),FreeBSD) # FreeBSD needs CNI until netavark is supported TAGS += cni endif -BUILDTAGS += $(TAGS) +BUILDTAGS += $(TAGS) $(EXTRA_BUILD_TAGS) PREFIX := /usr/local BINDIR := $(PREFIX)/bin BASHINSTALLDIR = $(PREFIX)/share/bash-completion/completions @@ -37,8 +37,9 @@ SOURCE_DATE_EPOCH ?= $(if $(shell date +%s),$(shell date +%s),$(error "date fail COMMENT := \# CNI_COMMIT := $(shell sed -n 's;^$(COMMENT) github.com/containernetworking/cni \([^ \n]*\).*$$;\1;p' vendor/modules.txt) +SEQUOIA_SONAME_DIR = EXTRA_LDFLAGS ?= -BUILDAH_LDFLAGS := $(GO_LDFLAGS) '-X main.GitCommit=$(GIT_COMMIT) -X main.buildInfo=$(SOURCE_DATE_EPOCH) -X main.cniVersion=$(CNI_COMMIT) $(EXTRA_LDFLAGS)' +BUILDAH_LDFLAGS := $(GO_LDFLAGS) '-X main.GitCommit=$(GIT_COMMIT) -X main.buildInfo=$(SOURCE_DATE_EPOCH) -X main.cniVersion=$(CNI_COMMIT) -X go.podman.io/image/v5/signature/internal/sequoia.sequoiaLibraryDir="$(SEQUOIA_SONAME_DIR)" $(EXTRA_LDFLAGS)' # This isn't what we actually build; it's a superset, used for target # dependencies. Basically: all *.go and *.c files, except *_test.go, diff --git a/vendor/github.com/containers/buildah/add.go b/vendor/github.com/containers/buildah/add.go index 29f6c3f748a..88049015360 100644 --- a/vendor/github.com/containers/buildah/add.go +++ b/vendor/github.com/containers/buildah/add.go @@ -156,7 +156,10 @@ func getURL(src string, chown *idtools.IDPair, mountpoint, renameTarget string, } tlsClientConfig.InsecureSkipVerify = insecureSkipTLSVerify == types.OptionalBoolTrue - tr := &http.Transport{TLSClientConfig: tlsClientConfig} + tr := &http.Transport{ + TLSClientConfig: tlsClientConfig, + Proxy: http.ProxyFromEnvironment, + } httpClient := &http.Client{Transport: tr} response, err := httpClient.Get(src) if err != nil { diff --git a/vendor/github.com/containers/buildah/run_common.go b/vendor/github.com/containers/buildah/run_common.go index bd501f3bd3d..d5af178565b 100644 --- a/vendor/github.com/containers/buildah/run_common.go +++ b/vendor/github.com/containers/buildah/run_common.go @@ -398,8 +398,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("passt"); 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/vendor/github.com/containers/buildah/run_linux.go b/vendor/github.com/containers/buildah/run_linux.go index e84cba9696b..42dcdf0a5cd 100644 --- a/vendor/github.com/containers/buildah/run_linux.go +++ b/vendor/github.com/containers/buildah/run_linux.go @@ -12,7 +12,6 @@ import ( "slices" "strings" "sync" - "syscall" "github.com/containers/buildah/bind" "github.com/containers/buildah/chroot" @@ -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" @@ -693,46 +691,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, @@ -780,8 +738,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: @@ -791,8 +747,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) diff --git a/vendor/github.com/openshift/imagebuilder/builder.go b/vendor/github.com/openshift/imagebuilder/builder.go index a461c6d37da..d41de5ab670 100644 --- a/vendor/github.com/openshift/imagebuilder/builder.go +++ b/vendor/github.com/openshift/imagebuilder/builder.go @@ -403,6 +403,14 @@ func (b *Builder) extractHeadingArgsFromNode(node *parser.Node) error { // Use a separate builder to evaluate the heading args tempBuilder := NewBuilder(b.UserArgs) + // Built-in ARGs are declared implicitly in the heading and should be resolvable in its scope + for k, v := range tempBuilder.BuiltinArgDefaults { + tempBuilder.AllowedArgs[k] = true + if _, ok := tempBuilder.Args[k]; !ok { + tempBuilder.Args[k] = v + } + } + // Evaluate all the heading arg commands for _, c := range args { step := tempBuilder.Step() diff --git a/vendor/github.com/openshift/imagebuilder/dispatchers.go b/vendor/github.com/openshift/imagebuilder/dispatchers.go index 89edefac0f5..3726dc7c9fc 100644 --- a/vendor/github.com/openshift/imagebuilder/dispatchers.go +++ b/vendor/github.com/openshift/imagebuilder/dispatchers.go @@ -562,12 +562,12 @@ func expose(b *Builder, args []string, attributes map[string]bool, flagArgs []st existing := map[string]struct{}{} for k := range b.RunConfig.ExposedPorts { - existing[k.Port()] = struct{}{} + existing[k.Port()+"/"+k.Proto()] = struct{}{} } for _, port := range args { dp := docker.Port(port) - if _, exists := existing[dp.Port()]; !exists { + if _, exists := existing[dp.Port()+"/"+dp.Proto()]; !exists { b.RunConfig.ExposedPorts[docker.Port(fmt.Sprintf("%s/%s", dp.Port(), dp.Proto()))] = struct{}{} } } diff --git a/vendor/github.com/openshift/imagebuilder/imagebuilder.spec b/vendor/github.com/openshift/imagebuilder/imagebuilder.spec index 277209e6c22..ff39b273841 100644 --- a/vendor/github.com/openshift/imagebuilder/imagebuilder.spec +++ b/vendor/github.com/openshift/imagebuilder/imagebuilder.spec @@ -12,7 +12,7 @@ # %global golang_version 1.19 -%{!?version: %global version 1.2.17} +%{!?version: %global version 1.2.19} %{!?release: %global release 1} %global package_name imagebuilder %global product_name Container Image Builder 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 05b3b16dd67..59732ac6913 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" @@ -18,7 +17,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" @@ -38,7 +36,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" // persistentCNIDir is the directory where the CNI files are stored. @@ -114,7 +112,7 @@ func (n *Netns) getOrCreateNetns() (ns.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 are still running err := unix.Kill(pid, 0) if err == nil { if err := n.deserializeInfo(); err != nil { @@ -156,14 +154,12 @@ func (n *Netns) getOrCreateNetns() (ns.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) default: err = fmt.Errorf("invalid rootless network command %q", 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 { @@ -222,7 +218,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) } @@ -253,68 +249,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) @@ -324,7 +258,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 083a4e5fcc9..00000000000 --- a/vendor/go.podman.io/common/libnetwork/slirp4netns/slirp4netns.go +++ /dev/null @@ -1,743 +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/containernetworking/plugins/pkg/ns" - "github.com/sirupsen/logrus" - "go.podman.io/common/libnetwork/types" - "go.podman.io/common/pkg/config" - "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) { - path := opts.Config.Engine.NetworkCmdPath - if path == "" { - 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 := ns.WithNetNSPath(opts.Netns, func(_ ns.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/cgroups/cgroups_linux.go b/vendor/go.podman.io/common/pkg/cgroups/cgroups_linux.go index e7a7cd09524..6a87f3602fa 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/cgroups_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/cgroups_linux.go @@ -554,7 +554,7 @@ func SystemCPUUsage() (uint64, error) { return total, nil } -// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode. +// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 unified mode. func IsCgroup2UnifiedMode() (bool, error) { isUnifiedOnce.Do(func() { var st syscall.Statfs_t diff --git a/vendor/go.podman.io/common/pkg/config/config.go b/vendor/go.podman.io/common/pkg/config/config.go index 8bc23deba1b..a4f2fd23423 100644 --- a/vendor/go.podman.io/common/pkg/config/config.go +++ b/vendor/go.podman.io/common/pkg/config/config.go @@ -403,13 +403,6 @@ type EngineConfig struct { // containers and pods will be visible. The default namespace is "". Namespace string `toml:"namespace,omitempty"` - // NetworkCmdPath is the path to the slirp4netns binary. - NetworkCmdPath string `toml:"network_cmd_path,omitempty"` - - // NetworkCmdOptions is the default options to pass to the slirp4netns binary. - // For example "allow_host_loopback=true" - NetworkCmdOptions attributedstring.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"` @@ -620,7 +613,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 2e392d048e1..e1828510d58 100644 --- a/vendor/go.podman.io/common/pkg/config/containers.conf +++ b/vendor/go.podman.io/common/pkg/config/containers.conf @@ -216,12 +216,12 @@ default_sysctls = [ # #log_driver = "k8s-file" -# Default path for container logs to be stored in. When empty, logs will be stored +# Default path for container logs to be stored in. When empty, logs will be stored # in the container's default storage and removed when the container is removed. -# A subdirectory named with the container ID will be created under the specified +# A subdirectory named with the container ID will be created under the specified # path, and the log file will have the default name `ctr.log` within that directory. # This option can be overridden by the `--log-opt` flag. -# +# #log_path = "" # Maximum size allowed for the container log file. Negative numbers indicate @@ -420,8 +420,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. Only valid option +# is `pasta` (default). # #default_rootless_network_cmd = "pasta" @@ -666,32 +666,6 @@ default_sysctls = [ # #namespace = "" -# Path to the slirp4netns binary -# -#network_cmd_path = "" - -# 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 bd999c339c9..73c312e06fb 100644 --- a/vendor/go.podman.io/common/pkg/config/containers.conf-freebsd +++ b/vendor/go.podman.io/common/pkg/config/containers.conf-freebsd @@ -169,12 +169,12 @@ default_sysctls = [ # #log_driver = "k8s-file" -# Default path for container logs to be stored in. When empty, logs will be stored +# Default path for container logs to be stored in. When empty, logs will be stored # in the container's default storage and removed when the container is removed. -# A subdirectory named with the container ID will be created under the specified +# A subdirectory named with the container ID will be created under the specified # path, and the log file will have the default name `ctr.log` within that directory. # This option can be overridden by the `--log-opt` flag. -# +# #log_path = "" # Maximum size allowed for the container log file. Negative numbers indicate @@ -499,32 +499,6 @@ default_sysctls = [ # #namespace = "" -# Path to the slirp4netns binary -# -#network_cmd_path = "" - -# 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/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/ssh/types.go b/vendor/go.podman.io/common/pkg/ssh/types.go index 3f59fee8c8f..071579d0064 100644 --- a/vendor/go.podman.io/common/pkg/ssh/types.go +++ b/vendor/go.podman.io/common/pkg/ssh/types.go @@ -126,7 +126,6 @@ type HostInfo struct { // ServiceIsRemote is true when the podman/libpod service is remote to the client ServiceIsRemote bool `json:"serviceIsRemote"` Security SecurityInfo `json:"security"` - Slirp4NetNS SlirpInfo `json:"slirp4netns,omitempty"` SwapFree int64 `json:"swapFree"` SwapTotal int64 `json:"swapTotal"` Uptime string `json:"uptime"` @@ -139,13 +138,6 @@ type RemoteSocket struct { Exists bool `json:"exists,omitempty"` } -// SlirpInfo describes the slirp executable that is being used. -type SlirpInfo struct { - Executable string `json:"executable"` - Package string `json:"package"` - Version string `json:"version"` -} - // IDMappings describe the GID and UID mappings. type IDMappings struct { GIDMap []idtools.IDMap `json:"gidmap"` 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 82e3b8014cc..d7c2306317a 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 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/modules.txt b/vendor/modules.txt index 8ced72c784a..dbf5f8af474 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -78,7 +78,7 @@ github.com/containernetworking/cni/pkg/version # github.com/containernetworking/plugins v1.8.0 ## explicit; go 1.24.2 github.com/containernetworking/plugins/pkg/ns -# github.com/containers/buildah v1.41.1-0.20250829135344-3367a9bc2c9f => github.com/lsm5/buildah v0.0.0-20251017145416-1c35ea0ae809 +# github.com/containers/buildah v1.41.1-0.20250829135344-3367a9bc2c9f => github.com/lsm5/buildah v0.0.0-20251021181103-9374d7fa4e33 ## explicit; go 1.24.2 github.com/containers/buildah github.com/containers/buildah/bind @@ -551,7 +551,7 @@ github.com/opencontainers/runtime-tools/validate/capabilities github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label github.com/opencontainers/selinux/pkg/pwalkdir -# github.com/openshift/imagebuilder v1.2.17 +# github.com/openshift/imagebuilder v1.2.19 ## explicit; go 1.23.3 github.com/openshift/imagebuilder github.com/openshift/imagebuilder/dockerfile/command @@ -740,7 +740,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.65.1-0.20251016162239-c4c5e00ad22d => github.com/lsm5/container-libs/common v0.0.0-20251017191154-e63ca540eafe +# go.podman.io/common v0.65.1-0.20251016162239-c4c5e00ad22d => github.com/lsm5/container-libs/common v0.0.0-20251021180701-90bb6920858f ## explicit; go 1.24.2 go.podman.io/common/internal go.podman.io/common/internal/attributedstring @@ -757,7 +757,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 @@ -796,7 +795,6 @@ go.podman.io/common/pkg/secrets/define go.podman.io/common/pkg/secrets/filedriver go.podman.io/common/pkg/secrets/passdriver go.podman.io/common/pkg/secrets/shelldriver -go.podman.io/common/pkg/servicereaper go.podman.io/common/pkg/signal go.podman.io/common/pkg/ssh go.podman.io/common/pkg/strongunits @@ -1189,5 +1187,5 @@ tags.cncf.io/container-device-interface/pkg/parser # tags.cncf.io/container-device-interface/specs-go v1.0.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-20251017191154-e63ca540eafe -# github.com/containers/buildah => github.com/lsm5/buildah v0.0.0-20251017145416-1c35ea0ae809 +# go.podman.io/common => github.com/lsm5/container-libs/common v0.0.0-20251021180701-90bb6920858f +# github.com/containers/buildah => github.com/lsm5/buildah v0.0.0-20251021181103-9374d7fa4e33