diff --git a/.cirrus.yml b/.cirrus.yml index fc8a398452..ec8230a919 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -60,7 +60,7 @@ env: CTR_FQIN: # One of the "Container FQIN's" (above) CI_DESIRED_RUNTIME: crun # As of 2024-05-28 there are no other supported runtimes CI_DESIRED_DATABASE: sqlite # 'sqlite' or 'boltdb' - CI_DESIRED_STORAGE: overlay # overlay or vfs + CI_DESIRED_STORAGE: overlay # overlay, vfs, or composefs (which is actually overlay) # Curl-command prefix for downloading task artifacts, simply add the # the url-encoded task name, artifact name, and path as a suffix. @@ -155,6 +155,7 @@ build_task: <<: *stdenvars DISTRO_NV: ${RAWHIDE_NAME} VM_IMAGE_NAME: ${RAWHIDE_CACHE_IMAGE_NAME} + CI_DESIRED_STORAGE: composefs CTR_FQIN: "" - env: DISTRO_NV: ${DEBIAN_NAME} diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh index ea6d8a0de5..3c93306cec 100644 --- a/contrib/cirrus/lib.sh +++ b/contrib/cirrus/lib.sh @@ -88,7 +88,7 @@ PASSTHROUGH_ENV_EXACT='CGROUP_MANAGER|DEST_BRANCH|DISTRO_NV|GOCACHE|GOPATH|GOSRC # List of envariable patterns which must match AT THE BEGINNING of the name. # Consumed by the passthrough_envars() automation library function. -PASSTHROUGH_ENV_ATSTART='CI|LANG|LC_|TEST' +PASSTHROUGH_ENV_ATSTART='CI|LANG|LC_|STORAGE_OPTIONS_|TEST' # List of envariable patterns which can match ANYWHERE in the name. # Consumed by the passthrough_envars() automation library function. diff --git a/contrib/cirrus/logformatter b/contrib/cirrus/logformatter index 439c82f2fe..36818aeee7 100755 --- a/contrib/cirrus/logformatter +++ b/contrib/cirrus/logformatter @@ -591,10 +591,12 @@ END_HTML # Highlight the important (non-boilerplate) podman command. $line =~ s/\s+--remote\s+/ /g; # --remote takes no args # Strip out the global podman options, but show them on hover - $line =~ s{(\S+\/podman(-remote)?)((\s+--(root|runroot|runtime|tmpdir|storage-opt|conmon|cgroup-manager|\S+-backend|network-config-dir|storage-driver|url) \S+)*)(\s.*)}{ + $line =~ s{(\S+\/podman(-remote)?)((\s+--(root|runroot|runtime|tmpdir|storage-opt|conmon|cgroup-manager|\S+-backend|network-config-dir|pull-option|storage-driver|url) \S+)*)(\s.*)}{ my ($full_path, $remote, $options, $args) = ($1, $2||'', $3, $6); $options =~ s/^\s+//; + # July 2024: "" in composefs pull-option confuses hovertext + $options =~ s/\"//g; # Separate each '--foo bar' with newlines for readability $options =~ s/ --/\n--/g; qq{podman$remote [options]$args}; diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index 640af943e7..eaaf22a3d7 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -41,6 +41,27 @@ done # Bypass git safety/security checks when operating in a throwaway environment showrun git config --global --add safe.directory $GOSRC +# Special case: "composefs" is not a valid setting but it's useful for +# readability in .cirrus.yml. Here we translate that to overlayfs (the +# actual filesystem) along with extra magic envariables. +# Be sure to do this before writing /etc/ci_environment. +export CI_DESIRED_COMPOSEFS= +# shellcheck disable=SC2154 +if [[ "$CI_DESIRED_STORAGE" = "composefs" ]]; then + CI_DESIRED_STORAGE="overlay" + + # composefs is root only + if [[ "$PRIV_NAME" == "root" ]]; then + CI_DESIRED_COMPOSEFS="+composefs" + + # KLUDGE ALERT! Magic options needed for testing composefs. + # This option was intended for passing one arg to --storage-opt + # but we're hijacking it to pass an extra option+arg. And it + # actually works. Just MAKE SURE THERE ARE NO SPACES IN THE {...}! + export STORAGE_OPTIONS_OVERLAY='overlay.use_composefs=true --pull-option {enable_partial_images="true",use_hard_links="false",ostree_repos="",convert_images="true"}' + fi +fi + # Ensure that all lower-level contexts and child-processes have # ready access to higher level orchestration (e.g Cirrus-CI) # variables. @@ -155,7 +176,7 @@ esac # This is (sigh) different because e2e tests have their own special way # of ignoring system defaults. # shellcheck disable=SC2154 -showrun echo "Setting CI_DESIRED_STORAGE [=$CI_DESIRED_STORAGE] for *system* tests" +showrun echo "Setting CI_DESIRED_STORAGE [=$CI_DESIRED_STORAGE$CI_DESIRED_COMPOSEFS] for *system* tests" conf=/etc/containers/storage.conf if [[ -e $conf ]]; then die "FATAL! INTERNAL ERROR! Cannot override $conf" @@ -167,6 +188,18 @@ runroot = "/run/containers/storage" graphroot = "/var/lib/containers/storage" EOF +if [[ -n "$CI_DESIRED_COMPOSEFS" ]]; then + cat <>$conf + +# BEGIN CI-enabled composefs +[storage.options] +pull_options = {enable_partial_images = "true", use_hard_links = "false", ostree_repos="", convert_images = "true"} + +[storage.options.overlay] +use_composefs = "true" +# END CI-enabled composefs +EOF +fi # mount a tmpfs for the container storage to speed up the IO # side effect is we clear all potentially pre existing data so we know we always start "clean" diff --git a/docs/source/markdown/podman.1.md b/docs/source/markdown/podman.1.md index f03689cc00..80e8b50d93 100644 --- a/docs/source/markdown/podman.1.md +++ b/docs/source/markdown/podman.1.md @@ -263,7 +263,7 @@ Set default `--storage-driver` value. #### **STORAGE_OPTS** -Set default `--storage-opts` value. +Set default `--storage-opt` value. #### **TMPDIR** diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index f617c3a586..b7b7e57113 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -266,11 +266,6 @@ func PodmanTestCreateUtil(tempDir string, remote bool) *PodmanTestIntegration { } } - storageOptions := os.Getenv("STORAGE_OPTIONS") - if storageOptions == "" { - storageOptions = STORAGE_OPTIONS - } - cgroupManager := os.Getenv("CGROUP_MANAGER") if cgroupManager == "" { cgroupManager = CGROUP_MANAGER @@ -313,9 +308,17 @@ func PodmanTestCreateUtil(tempDir string, remote bool) *PodmanTestIntegration { if isRootless() { storageFs = ROOTLESS_STORAGE_FS } + + storageOptions := STORAGE_OPTIONS if os.Getenv("STORAGE_FS") != "" { storageFs = os.Getenv("STORAGE_FS") storageOptions = "--storage-driver " + storageFs + + // Look for STORAGE_OPTIONS_OVERLAY / STORAGE_OPTIONS_VFS + extraOptions := os.Getenv("STORAGE_OPTIONS_" + strings.ToUpper(storageFs)) + if extraOptions != "" { + storageOptions += " --storage-opt " + extraOptions + } } p := &PodmanTestIntegration{ diff --git a/test/e2e/config_amd64.go b/test/e2e/config_amd64.go index 27ad021b46..f5c1b69198 100644 --- a/test/e2e/config_amd64.go +++ b/test/e2e/config_amd64.go @@ -1,15 +1,14 @@ package integration var ( - STORAGE_FS = "overlay" //nolint:revive,stylecheck - STORAGE_OPTIONS = "--storage-driver overlay" //nolint:revive,stylecheck - ROOTLESS_STORAGE_FS = "overlay" //nolint:revive,stylecheck - ROOTLESS_STORAGE_OPTIONS = "--storage-driver overlay" //nolint:revive,stylecheck - CACHE_IMAGES = []string{ALPINE, BB, NGINX_IMAGE, REDIS_IMAGE, REGISTRY_IMAGE, INFRA_IMAGE, CITEST_IMAGE, HEALTHCHECK_IMAGE, SYSTEMD_IMAGE} //nolint:revive,stylecheck - NGINX_IMAGE = "quay.io/libpod/alpine_nginx:latest" //nolint:revive,stylecheck - BB_GLIBC = "docker.io/library/busybox:glibc" //nolint:revive,stylecheck - REGISTRY_IMAGE = "quay.io/libpod/registry:2.8.2" //nolint:revive,stylecheck - CITEST_IMAGE = "quay.io/libpod/testimage:20240123" //nolint:revive,stylecheck - SYSTEMD_IMAGE = "quay.io/libpod/systemd-image:20240124" //nolint:revive,stylecheck - CIRROS_IMAGE = "quay.io/libpod/cirros:latest" //nolint:revive,stylecheck + STORAGE_FS = "overlay" //nolint:revive,stylecheck + STORAGE_OPTIONS = "--storage-driver overlay" //nolint:revive,stylecheck + ROOTLESS_STORAGE_FS = "overlay" //nolint:revive,stylecheck + CACHE_IMAGES = []string{ALPINE, BB, NGINX_IMAGE, REDIS_IMAGE, REGISTRY_IMAGE, INFRA_IMAGE, CITEST_IMAGE, HEALTHCHECK_IMAGE, SYSTEMD_IMAGE} //nolint:revive,stylecheck + NGINX_IMAGE = "quay.io/libpod/alpine_nginx:latest" //nolint:revive,stylecheck + BB_GLIBC = "docker.io/library/busybox:glibc" //nolint:revive,stylecheck + REGISTRY_IMAGE = "quay.io/libpod/registry:2.8.2" //nolint:revive,stylecheck + CITEST_IMAGE = "quay.io/libpod/testimage:20240123" //nolint:revive,stylecheck + SYSTEMD_IMAGE = "quay.io/libpod/systemd-image:20240124" //nolint:revive,stylecheck + CIRROS_IMAGE = "quay.io/libpod/cirros:latest" //nolint:revive,stylecheck ) diff --git a/test/e2e/config_arm64.go b/test/e2e/config_arm64.go index 3bb2d3600f..1bf29d7816 100644 --- a/test/e2e/config_arm64.go +++ b/test/e2e/config_arm64.go @@ -1,15 +1,14 @@ package integration var ( - STORAGE_FS = "overlay" //nolint:revive,stylecheck - STORAGE_OPTIONS = "--storage-driver overlay" //nolint:revive,stylecheck - ROOTLESS_STORAGE_FS = "overlay" //nolint:revive,stylecheck - ROOTLESS_STORAGE_OPTIONS = "--storage-driver overlay" //nolint:revive,stylecheck - CACHE_IMAGES = []string{ALPINE, BB, fedoraMinimal, NGINX_IMAGE, REDIS_IMAGE, REGISTRY_IMAGE, INFRA_IMAGE, CITEST_IMAGE, HEALTHCHECK_IMAGE, SYSTEMD_IMAGE} //nolint:revive,stylecheck - NGINX_IMAGE = "quay.io/lsm5/alpine_nginx-aarch64:latest" //nolint:revive,stylecheck - BB_GLIBC = "docker.io/library/busybox:glibc" //nolint:revive,stylecheck - REGISTRY_IMAGE = "quay.io/libpod/registry:2.8.2" //nolint:revive,stylecheck - CITEST_IMAGE = "quay.io/libpod/testimage:20240123" //nolint:revive,stylecheck - SYSTEMD_IMAGE = "quay.io/libpod/systemd-image:20240124" //nolint:revive,stylecheck - CIRROS_IMAGE = "quay.io/libpod/cirros:latest" //nolint:revive,stylecheck + STORAGE_FS = "overlay" //nolint:revive,stylecheck + STORAGE_OPTIONS = "--storage-driver overlay" //nolint:revive,stylecheck + ROOTLESS_STORAGE_FS = "overlay" //nolint:revive,stylecheck + CACHE_IMAGES = []string{ALPINE, BB, fedoraMinimal, NGINX_IMAGE, REDIS_IMAGE, REGISTRY_IMAGE, INFRA_IMAGE, CITEST_IMAGE, HEALTHCHECK_IMAGE, SYSTEMD_IMAGE} //nolint:revive,stylecheck + NGINX_IMAGE = "quay.io/lsm5/alpine_nginx-aarch64:latest" //nolint:revive,stylecheck + BB_GLIBC = "docker.io/library/busybox:glibc" //nolint:revive,stylecheck + REGISTRY_IMAGE = "quay.io/libpod/registry:2.8.2" //nolint:revive,stylecheck + CITEST_IMAGE = "quay.io/libpod/testimage:20240123" //nolint:revive,stylecheck + SYSTEMD_IMAGE = "quay.io/libpod/systemd-image:20240124" //nolint:revive,stylecheck + CIRROS_IMAGE = "quay.io/libpod/cirros:latest" //nolint:revive,stylecheck ) diff --git a/test/e2e/config_ppc64le.go b/test/e2e/config_ppc64le.go index 2a294a9ee7..d89bf1d4f7 100644 --- a/test/e2e/config_ppc64le.go +++ b/test/e2e/config_ppc64le.go @@ -1,13 +1,12 @@ package integration var ( - STORAGE_FS = "overlay" - STORAGE_OPTIONS = "--storage-driver overlay" - ROOTLESS_STORAGE_FS = "overlay" - ROOTLESS_STORAGE_OPTIONS = "--storage-driver overlay" - CACHE_IMAGES = []string{ALPINE, BB, fedoraMinimal, NGINX_IMAGE, REDIS_IMAGE, INFRA_IMAGE, CITEST_IMAGE} - NGINX_IMAGE = "quay.io/libpod/alpine_nginx-ppc64le:latest" - BB_GLIBC = "docker.io/ppc64le/busybox:glibc" - CITEST_IMAGE = "quay.io/libpod/testimage:20240123" - REGISTRY_IMAGE string + STORAGE_FS = "overlay" + STORAGE_OPTIONS = "--storage-driver overlay" + ROOTLESS_STORAGE_FS = "overlay" + CACHE_IMAGES = []string{ALPINE, BB, fedoraMinimal, NGINX_IMAGE, REDIS_IMAGE, INFRA_IMAGE, CITEST_IMAGE} + NGINX_IMAGE = "quay.io/libpod/alpine_nginx-ppc64le:latest" + BB_GLIBC = "docker.io/ppc64le/busybox:glibc" + CITEST_IMAGE = "quay.io/libpod/testimage:20240123" + REGISTRY_IMAGE string ) diff --git a/test/e2e/info_test.go b/test/e2e/info_test.go index 5bf028a207..25b9ca5a30 100644 --- a/test/e2e/info_test.go +++ b/test/e2e/info_test.go @@ -240,6 +240,18 @@ var _ = Describe("Podman Info", func() { session.WaitWithDefaultTimeout() Expect(session).To(ExitCleanly()) Expect(session.OutputToString()).To(Equal(want), ".Store.GraphDriverName from podman info") + + // Confirm desired setting of composefs + if want == "overlay" { + expect := "" + if os.Getenv("CI_DESIRED_COMPOSEFS") != "" { + expect = "true" + } + session = podmanTest.Podman([]string{"info", "--format", `{{index .Store.GraphOptions "overlay.use_composefs"}}`}) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitCleanly()) + Expect(session.OutputToString()).To(Equal(expect), ".Store.GraphOptions -> overlay.use_composefs") + } }) It("Podman info: check lock count", Serial, func() { diff --git a/test/system/005-info.bats b/test/system/005-info.bats index 2edbb26c4a..baf34a8ece 100644 --- a/test/system/005-info.bats +++ b/test/system/005-info.bats @@ -124,6 +124,16 @@ host.slirp4netns.executable | $expr_path fi is "$(podman_storage_driver)" "$CI_DESIRED_STORAGE" "podman storage driver is not CI_DESIRED_STORAGE (from .cirrus.yml)" + + # Confirm desired setting of composefs + if [[ "$CI_DESIRED_STORAGE" = "overlay" ]]; then + expect="" + if [[ -n "$CI_DESIRED_COMPOSEFS" ]]; then + expect="true" + fi + run_podman info --format '{{index .Store.GraphOptions "overlay.use_composefs"}}' + assert "$output" = "$expect" ".Store.GraphOptions -> overlay.use_composefs" + fi } # 2021-04-06 discussed in watercooler: RHEL must never use crun, even if diff --git a/test/system/010-images.bats b/test/system/010-images.bats index 074359c0d1..43dd1bcfe9 100644 --- a/test/system/010-images.bats +++ b/test/system/010-images.bats @@ -360,6 +360,12 @@ driver="$storagedriver" additionalimagestores = [ "$imstore/root" ] EOF + # If composefs (root only) is enabled, we must mirror that setting in our conf + if grep -q 'BEGIN CI-enabled composefs' /etc/containers/storage.conf; then + sed -ne '/BEGIN CI-enabled composefs/,/END CI-enabled composefs/p' /etc/containers/storage.conf \ + | grep -vF '[storage.options]' >>$sconf + fi + skopeo copy containers-storage:$IMAGE \ containers-storage:\[${storagedriver}@${imstore}/root+${imstore}/runroot\]$IMAGE