From afdec5a68253d76bca834a84b357909e1a23f940 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Wed, 17 Jun 2026 19:55:34 +0200 Subject: [PATCH 1/8] docs: fix incorrect statement in podman-quadlet-basic-usage The services cannot be enables so we must not document this, instead provide the proper pointer on what to do. Signed-off-by: Paul Holzinger (cherry picked from commit ea87414454bd52cf3cda338e6bbc7bf5b69fce0a) Signed-off-by: Paul Holzinger --- docs/source/markdown/podman-quadlet-basic-usage.7.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/source/markdown/podman-quadlet-basic-usage.7.md b/docs/source/markdown/podman-quadlet-basic-usage.7.md index 2311a8f337..28c55e76e9 100644 --- a/docs/source/markdown/podman-quadlet-basic-usage.7.md +++ b/docs/source/markdown/podman-quadlet-basic-usage.7.md @@ -42,7 +42,7 @@ For rootful use: sudo cp hello.container /etc/containers/systemd/ ``` -## Step 3: Reload and enable the service +## Step 3: Reload and start the service For rootless use: ```bash @@ -53,9 +53,13 @@ systemctl --user start hello.service For rootful use: ```bash sudo systemctl daemon-reload -sudo systemctl enable --now hello.service +sudo systemctl start hello.service ``` +Note quadlet services cannot be enabled as they are a generated systemd unit, +see [podman-systemd.unit(5)](podman-systemd.unit.5.md#enabling-unit-files) for more information. + + ## Expected Output: For rootless, check logs using: From 093d35386e86e15707283e4d42008c55252eacd2 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Mon, 15 Jun 2026 16:23:53 +0200 Subject: [PATCH 2/8] test/e2e: split cli tmpdir from per test tempdir Right now the tmpdir for the test and cli are are the same and worse the root/runroot directories are subdirectories of the tmpdir so tests can create conflicting files. Also for rootless remote builds this cuases problems for all tests which uses the main tmpdir as context dir as they then try to copy the storage files with different uids which will fail. Commit 79e7b0f6fd tried to work around it but it is not enough as much more tests use this pattern. So to fix this once and for all properly separate them. And then fixup a few test cases that depended on the wrong value and make them use the proper root value directly. Signed-off-by: Paul Holzinger (cherry picked from commit 6e20527004a4943a3872f48d00facf5a04b9cbde) Signed-off-by: Paul Holzinger --- test/e2e/common_test.go | 12 ++++++++---- test/e2e/libpod_suite_remote_test.go | 2 +- test/e2e/mount_rootless_test.go | 10 +++++----- test/e2e/play_kube_test.go | 2 +- test/e2e/run_volume_test.go | 2 +- test/utils/utils.go | 2 +- 6 files changed, 17 insertions(+), 13 deletions(-) diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 99e32382bc..0311b11769 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -69,7 +69,7 @@ type PodmanTestIntegration struct { SignaturePolicyPath string CgroupManager string Host HostOS - TmpDir string + CliTmpDir string // value of podman --tmpdir } var ( @@ -363,11 +363,15 @@ func PodmanTestCreateUtil(tempDir string, target PodmanTestCreateUtilTarget) *Po } } + perTestTempDir := filepath.Join(tempDir, "ptemp") + err := os.Mkdir(perTestTempDir, 0o755) + Expect(err).ToNot(HaveOccurred()) + p := &PodmanTestIntegration{ PodmanTest: PodmanTest{ PodmanBinary: podmanBinary, RemotePodmanBinary: podmanRemoteBinary, - TempDir: tempDir, + TempDir: perTestTempDir, RemoteTest: target != PodmanTestCreateUtilTargetLocal, ImageCacheFS: storageFs, ImageCacheDir: ImageCacheDir, @@ -376,7 +380,7 @@ func PodmanTestCreateUtil(tempDir string, target PodmanTestCreateUtilTarget) *Po ConmonBinary: conmonBinary, QuadletBinary: quadletBinary, Root: root, - TmpDir: tempDir, + CliTmpDir: filepath.Join(tempDir, "clitmp"), NetworkConfigDir: networkConfigDir, OCIRuntime: ociRuntime, RunRoot: filepath.Join(tempDir, "runroot"), @@ -1417,7 +1421,7 @@ func (p *PodmanTestIntegration) makeOptions(args []string, options PodmanExecOpt "--conmon", p.ConmonBinary, "--network-config-dir", p.NetworkConfigDir, "--cgroup-manager", p.CgroupManager, - "--tmpdir", p.TmpDir, + "--tmpdir", p.CliTmpDir, "--events-backend", eventsType, ) diff --git a/test/e2e/libpod_suite_remote_test.go b/test/e2e/libpod_suite_remote_test.go index 70ce8bbc8f..107ab00df6 100644 --- a/test/e2e/libpod_suite_remote_test.go +++ b/test/e2e/libpod_suite_remote_test.go @@ -133,7 +133,7 @@ func getRemoteOptions(p *PodmanTestIntegration, args []string) []string { "--conmon", p.ConmonBinary, "--network-config-dir", networkDir, "--cgroup-manager", p.CgroupManager, - "--tmpdir", p.TmpDir, + "--tmpdir", p.CliTmpDir, "--events-backend", "file", } diff --git a/test/e2e/mount_rootless_test.go b/test/e2e/mount_rootless_test.go index 46b096965d..ad3d421356 100644 --- a/test/e2e/mount_rootless_test.go +++ b/test/e2e/mount_rootless_test.go @@ -38,12 +38,12 @@ var _ = Describe("Podman mount", func() { opts := podmanTest.PodmanMakeOptions([]string{"mount", cid}, PodmanExecOptions{}) args = append(args, opts...) - // container root file system location is podmanTest.TempDir/... - // because "--root podmanTest.TempDir/..." + // container root file system location is podmanTest.Root/... + // because "--root podmanTest.Root/..." session := podmanTest.Podman(args) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) - Expect(session.OutputToString()).To(ContainSubstring(podmanTest.TempDir)) + Expect(session.OutputToString()).To(ContainSubstring(podmanTest.Root)) }) It("podman image mount", func() { @@ -61,11 +61,11 @@ var _ = Describe("Podman mount", func() { opts := podmanTest.PodmanMakeOptions([]string{"image", "mount", CITEST_IMAGE}, PodmanExecOptions{}) args = append(args, opts...) - // image location is podmanTest.TempDir/... because "--root podmanTest.TempDir/..." + // image location is podmanTest.Root/... because "--root podmanTest.Root/..." session := podmanTest.Podman(args) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) - Expect(session.OutputToString()).To(ContainSubstring(podmanTest.TempDir)) + Expect(session.OutputToString()).To(ContainSubstring(podmanTest.Root)) // We have to unmount the image again otherwise we leak the tmpdir // as active mount points cannot be removed. diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index 92deee3174..ecda611ee9 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -5694,7 +5694,7 @@ spec: playKube := podmanTest.Podman([]string{"kube", "play", kubeYaml}) playKube.WaitWithDefaultTimeout() - Expect(playKube).Should(ExitWithError(125, fmt.Sprintf("securejoin.OpenInRoot testing/onlythis: openat2 %s/root/volumes/testvol/_data/testing/onlythis: no such file or directory", podmanTest.TempDir))) + Expect(playKube).Should(ExitWithError(125, fmt.Sprintf("securejoin.OpenInRoot testing/onlythis: openat2 %s/volumes/testvol/_data/testing/onlythis: no such file or directory", podmanTest.Root))) }) It("with unsafe hostPath subpaths", func() { diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go index 2a0465e825..eab77368ae 100644 --- a/test/e2e/run_volume_test.go +++ b/test/e2e/run_volume_test.go @@ -135,7 +135,7 @@ var _ = Describe("Podman run with volumes", func() { }) It("podman run with conflicting volumes errors", func() { - mountPath := filepath.Join(podmanTest.TmpDir, "secrets") + mountPath := filepath.Join(podmanTest.TempDir, "secrets") err := os.Mkdir(mountPath, 0o755) Expect(err).ToNot(HaveOccurred()) session := podmanTest.Podman([]string{"run", "-v", mountPath + ":" + dest, "-v", "/tmp" + ":" + dest, ALPINE, "ls"}) diff --git a/test/utils/utils.go b/test/utils/utils.go index 5fb0be861a..edc46755f3 100644 --- a/test/utils/utils.go +++ b/test/utils/utils.go @@ -67,7 +67,7 @@ type PodmanTest struct { RemoteTLSClientKeyFile string RemoteTLSDetails string RemoteTest bool - TempDir string + TempDir string // TempDir is a unique per test directory. } // PodmanSession wraps the gexec.session so we can extend it From 9adc961678a7b33bfaa4499ba77e1fdd4ea7310c Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Mon, 15 Jun 2026 16:26:53 +0200 Subject: [PATCH 3/8] Revert "test/e2e: build in subdirectory" This reverts commit 79e7b0f6fd1fb73e05dc966ea365cfbfa768e7d8. With the proper tmpdir split we no longer need this. Signed-off-by: Paul Holzinger (cherry picked from commit 776bcd74c2bce7a989ff989d9d861d9eacfdb4e9) Signed-off-by: Paul Holzinger --- test/e2e/common_test.go | 9 +++------ test/e2e/container_create_volume_test.go | 15 +++------------ test/e2e/pod_create_test.go | 18 ++++-------------- test/e2e/pull_chunked_test.go | 11 ++--------- 4 files changed, 12 insertions(+), 41 deletions(-) diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 0311b11769..2475958580 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -1551,11 +1551,8 @@ func (s *PodmanSessionIntegration) jq(jqCommand string) (string, error) { } func (p *PodmanTestIntegration) buildImage(dockerfile, imageName string, layers string, label string, extraOptions []string) string { - buildDir := filepath.Join(p.TempDir, "build"+stringid.GenerateRandomID()) - err := os.Mkdir(buildDir, 0o755) - Expect(err).ToNot(HaveOccurred()) - dockerfilePath := filepath.Join(buildDir, "Dockerfile-"+stringid.GenerateRandomID()) - err = os.WriteFile(dockerfilePath, []byte(dockerfile), 0o644) + dockerfilePath := filepath.Join(p.TempDir, "Dockerfile-"+stringid.GenerateRandomID()) + err := os.WriteFile(dockerfilePath, []byte(dockerfile), 0o755) Expect(err).ToNot(HaveOccurred()) cmd := []string{"build", "--pull-never", "--layers=" + layers, "--file", dockerfilePath} if label != "" { @@ -1567,7 +1564,7 @@ func (p *PodmanTestIntegration) buildImage(dockerfile, imageName string, layers if len(extraOptions) > 0 { cmd = append(cmd, extraOptions...) } - cmd = append(cmd, buildDir) + cmd = append(cmd, p.TempDir) session := p.Podman(cmd) session.Wait(240) Expect(session).Should(Exit(0), fmt.Sprintf("BuildImage session output: %q", session.OutputToString())) diff --git a/test/e2e/container_create_volume_test.go b/test/e2e/container_create_volume_test.go index feaa083965..45fc033f1f 100644 --- a/test/e2e/container_create_volume_test.go +++ b/test/e2e/container_create_volume_test.go @@ -10,17 +10,12 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" . "go.podman.io/podman/v6/test/utils" - "go.podman.io/storage/pkg/stringid" ) func buildDataVolumeImage(pTest *PodmanTestIntegration, image, data, dest string) { - buildDir := filepath.Join(pTest.TempDir, "build"+stringid.GenerateRandomID()) - err := os.Mkdir(buildDir, 0o755) - Expect(err).ToNot(HaveOccurred()) - // Create a dummy file for data volume - dummyFile := filepath.Join(buildDir, data) - err = os.WriteFile(dummyFile, []byte(data), 0o644) + dummyFile := filepath.Join(pTest.TempDir, data) + err := os.WriteFile(dummyFile, []byte(data), 0o644) Expect(err).ToNot(HaveOccurred()) // Create a data volume container image but no CMD binary in it @@ -28,11 +23,7 @@ func buildDataVolumeImage(pTest *PodmanTestIntegration, image, data, dest string CMD doesnotexist.sh ADD %s %s/ VOLUME %s/`, data, dest, dest) - - containerFilePath := filepath.Join(buildDir, "Containerfile") - err = os.WriteFile(containerFilePath, []byte(containerFile), 0o644) - Expect(err).ToNot(HaveOccurred()) - pTest.PodmanExitCleanly("build", "--pull-never", "-q", "-t", image, "--layers=false", "--file", containerFilePath) + pTest.BuildImage(containerFile, image, "false") } func createContainersConfFile(pTest *PodmanTestIntegration) { diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go index a7e3a72d71..9f74b16735 100644 --- a/test/e2e/pod_create_test.go +++ b/test/e2e/pod_create_test.go @@ -20,7 +20,6 @@ import ( "go.podman.io/common/pkg/sysinfo" "go.podman.io/podman/v6/pkg/util" . "go.podman.io/podman/v6/test/utils" - "go.podman.io/storage/pkg/stringid" ) var _ = Describe("Podman pod create", func() { @@ -176,12 +175,8 @@ var _ = Describe("Podman pod create", func() { Describe("podman create pod with --hosts-file", func() { BeforeEach(func() { - buildDir := filepath.Join(podmanTest.TempDir, "build"+stringid.GenerateRandomID()) - err := os.Mkdir(buildDir, 0o755) - Expect(err).ToNot(HaveOccurred()) - - imageHosts := filepath.Join(buildDir, "pause_hosts") - err = os.WriteFile(imageHosts, []byte("56.78.12.34 image.example.com"), 0o755) + imageHosts := filepath.Join(podmanTest.TempDir, "pause_hosts") + err := os.WriteFile(imageHosts, []byte("56.78.12.34 image.example.com"), 0o755) Expect(err).ToNot(HaveOccurred()) configHosts := filepath.Join(podmanTest.TempDir, "hosts") @@ -196,16 +191,11 @@ var _ = Describe("Podman pod create", func() { podmanTest.RestartRemoteService() } - containerfile := strings.Join([]string{ + dockerfile := strings.Join([]string{ `FROM ` + INFRA_IMAGE, `COPY pause_hosts /etc/hosts`, }, "\n") - - containerFilePath := filepath.Join(buildDir, "Containerfile") - err = os.WriteFile(containerFilePath, []byte(containerfile), 0o644) - Expect(err).ToNot(HaveOccurred()) - - podmanTest.PodmanExitCleanly("build", "-q", "-t", "foobar.com/hosts_test_pause:latest", "--layers=false", "--no-hosts", buildDir) + podmanTest.BuildImage(dockerfile, "foobar.com/hosts_test_pause:latest", "false", "--no-hosts") }) It("--hosts-file=path", func() { diff --git a/test/e2e/pull_chunked_test.go b/test/e2e/pull_chunked_test.go index 5723f32c1d..3be2573eb0 100644 --- a/test/e2e/pull_chunked_test.go +++ b/test/e2e/pull_chunked_test.go @@ -69,18 +69,11 @@ func pullChunkedTests() { // included in pull_test.go, must use a Ginkgo DSL at registryRef: pullChunkedRegistryPrefix + "chunked-normal", dirPath: filepath.Join(imageDir, "chunked-normal"), } - - buildDir := filepath.Join(podmanTest.TempDir, "build") - err := os.Mkdir(buildDir, 0o755) - Expect(err).ToNot(HaveOccurred()) chunkedNormalContentPath := "chunked-normal-image-content" - err = os.WriteFile(filepath.Join(buildDir, chunkedNormalContentPath), fmt.Appendf(nil, "content-%d", rand.Int64()), 0o600) + err := os.WriteFile(filepath.Join(podmanTest.TempDir, chunkedNormalContentPath), fmt.Appendf(nil, "content-%d", rand.Int64()), 0o600) Expect(err).NotTo(HaveOccurred()) chunkedNormalContainerFile := fmt.Sprintf("FROM scratch\nADD %s /content", chunkedNormalContentPath) - err = os.WriteFile(filepath.Join(buildDir, "Containerfile"), []byte(chunkedNormalContainerFile), 0o600) - Expect(err).NotTo(HaveOccurred()) - podmanTest.PodmanExitCleanly("build", "-q", "-t", chunkedNormal.localTag(), "--layers=true", buildDir) - + podmanTest.BuildImage(chunkedNormalContainerFile, chunkedNormal.localTag(), "true") podmanTest.PodmanExitCleanly("push", "-q", "--tls-verify=false", "--force-compression", "--compression-format=zstd:chunked", chunkedNormal.localTag(), chunkedNormal.registryRef) skopeo := SystemExec("skopeo", []string{"copy", "-q", "--preserve-digests", "--all", "--src-tls-verify=false", chunkedNormal.registryRef, "dir:" + chunkedNormal.dirPath}) skopeo.WaitWithDefaultTimeout() From 3ff2ddc035c1bf8b8646e3cbc5a9db8058f7a190 Mon Sep 17 00:00:00 2001 From: Chanhyeok Seo Date: Fri, 12 Jun 2026 15:03:19 +0900 Subject: [PATCH 4/8] machine: fix virtiofs mount targets on FCOS FCOS symlinks /home to var/home. systemd rejects a mount unit whose Where= path traverses a symlink, breaking default home dir mounts. Resolve known FCOS symlinks before writing the ignition unit. Fixes: #28911 Signed-off-by: Chanhyeok Seo (cherry picked from commit 61dea3749fae172ef4e4c70465bd8d5915c8e5db) Signed-off-by: Paul Holzinger --- pkg/machine/volume_systemd.go | 39 +++++++++++++++- pkg/machine/volume_systemd_test.go | 72 ++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 pkg/machine/volume_systemd_test.go diff --git a/pkg/machine/volume_systemd.go b/pkg/machine/volume_systemd.go index 28dcc08934..dda038948d 100644 --- a/pkg/machine/volume_systemd.go +++ b/pkg/machine/volume_systemd.go @@ -7,6 +7,38 @@ import ( "go.podman.io/podman/v6/pkg/systemd/parser" ) +// fcosDirSymlinks maps FCOS root-level symlinks to their real paths. +// FCOS symlinks several top-level dirs into /var for the read-only rootfs. +// systemd rejects a mount unit whose Where= traverses a symlink, so we +// resolve these before writing the ignition unit. +var fcosDirSymlinks = map[string]string{ + "/home": "/var/home", + "/mnt": "/var/mnt", + "/opt": "/var/opt", + "/root": "/var/roothome", + "/srv": "/var/srv", +} + +// canonicalizeFCOSMountTarget returns the canonical path for target by +// substituting any known FCOS root-level symlink prefix. +func canonicalizeFCOSMountTarget(target string) string { + // Guard check for empty strings or paths not starting with '/' + if len(target) < 2 || target[0] != '/' { + return target + } + + // Find the end of the first path component (e.g. "/home" in "/home/alice"). + end := 1 + for end < len(target) && target[end] != '/' { + end++ + } + + if real, ok := fcosDirSymlinks[target[:end]]; ok { + return real + target[end:] + } + return target +} + // GenerateSystemDFilesForVirtiofsMounts generates the systemd unit files needed // to mount virtiofs volumes inside a FCOS guest VM. It is shared between the // AppleHV, LibKrun, and QEMU providers. @@ -30,10 +62,13 @@ func GenerateSystemDFilesForVirtiofsMounts(mounts []VirtIoFs) ([]ignition.Unit, return nil, err } + // Use the canonical path so systemd accepts the Where= value. + // On FCOS /home is a symlink to var/home; systemd rejects non-canonical paths. + canonicalTarget := canonicalizeFCOSMountTarget(mnt.Target) virtiofsMount := ignition.Unit{ Enabled: ignition.BoolToPtr(true), - Name: fmt.Sprintf("%s.mount", parser.PathEscape(mnt.Target)), - Contents: ignition.StrToPtr(fmt.Sprintf(mountUnitFile, mnt.Tag, mnt.Target)), + Name: fmt.Sprintf("%s.mount", parser.PathEscape(canonicalTarget)), + Contents: ignition.StrToPtr(fmt.Sprintf(mountUnitFile, mnt.Tag, canonicalTarget)), } unitFiles = append(unitFiles, virtiofsMount) diff --git a/pkg/machine/volume_systemd_test.go b/pkg/machine/volume_systemd_test.go new file mode 100644 index 0000000000..7bda6f0487 --- /dev/null +++ b/pkg/machine/volume_systemd_test.go @@ -0,0 +1,72 @@ +package machine + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCanonicalizeFCOSMountTarget(t *testing.T) { + tests := []struct { + input string + expected string + }{ + // Known FCOS symlinks — must be rewritten + {"/home/alice", "/var/home/alice"}, + {"/home/alice/projects", "/var/home/alice/projects"}, + {"/mnt/data", "/var/mnt/data"}, + {"/opt/myapp", "/var/opt/myapp"}, + {"/root", "/var/roothome"}, + {"/root/.config", "/var/roothome/.config"}, + {"/srv/www", "/var/srv/www"}, + // Exact match on a symlinked dir itself + {"/home", "/var/home"}, + {"/mnt", "/var/mnt"}, + // Paths that do NOT start with a known symlink — unchanged + {"/var/home/alice", "/var/home/alice"}, + {"/tmp/foo", "/tmp/foo"}, + {"/data/work", "/data/work"}, + {"/work", "/work"}, + // Prefix collision guard: /homes should NOT match /home + {"/homes/alice", "/homes/alice"}, + {"/rootfs", "/rootfs"}, + } + + for _, tt := range tests { + got := canonicalizeFCOSMountTarget(tt.input) + assert.Equal(t, tt.expected, got, "input: %q", tt.input) + } +} + +func TestGenerateSystemDFilesForVirtiofsmountsCanonicalPath(t *testing.T) { + mounts := []VirtIoFs{ + NewVirtIoFsMount("/home/alice", "/home/alice", false), + NewVirtIoFsMount("/data", "/data", false), + } + + units, err := GenerateSystemDFilesForVirtiofsMounts(mounts) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + // First two units are the mount units; the rest are immutable-root helpers. + mountUnits := units[:2] + + cases := []struct { + wantName string + wantWhere string + }{ + // /home/alice must be rewritten to /var/home/alice + {"var-home-alice.mount", "/var/home/alice"}, + // /data has no FCOS symlink — stays as-is + {"data.mount", "/data"}, + } + + for i, c := range cases { + u := mountUnits[i] + assert.Equal(t, c.wantName, u.Name, "unit[%d].Name", i) + if assert.NotNil(t, u.Contents, "unit[%d].Contents", i) { + assert.Contains(t, *u.Contents, "Where="+c.wantWhere, "unit[%d] missing Where=", i) + } + } +} From 544c24c3920c978f9c59d98dd9da3c96713f3139 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Tue, 16 Jun 2026 18:58:46 +0200 Subject: [PATCH 5/8] validate: disable golangci-lint cache Something with the cache is not working right and results in inconsistent lint result. Even on PRs where there are no source code changes we observe random failures. I have seen at least 4 different instances since we the new CI setup. It is not reasonable to spot fix each new warning (mostly just adding new nolint comments) each time as it affects all PRs at once. It will also be very confusing for new contributors. Fixes: #28893 Signed-off-by: Paul Holzinger (cherry picked from commit c8ce2c60895c96e589ab0c836d5f45a7e090fd55) Signed-off-by: Paul Holzinger --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a32ad160d6..c808aaeb77 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -99,6 +99,7 @@ jobs: with: version: ${{ steps.gv.outputs.version }} install-only: true + skip-cache: true # cache causes flaky results https://github.com/podman-container-tools/podman/issues/28893 - name: Install pre-commit run: pipx install pre-commit From 2f11e2fc8df2cc5b9235bd587bbf9a6df4481f88 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Tue, 16 Jun 2026 14:09:29 +0200 Subject: [PATCH 6/8] update "No New Tests" PR filter list For a while now we trigger CI tests based on if source files, i.e. *.go files were changed. The "No New Tests" filter however checked something else via a exclude list that was not being updated. That means in many cases we needed to add the label when it is clear that these thing should not need tests, i.e. packit or rpm/ changes. To avoid the manual updates of all directories just grep for source files. Fixes: #28849 Signed-off-by: Paul Holzinger (cherry picked from commit 126d3e27ae8ccf3bac170a04895d378c344e79e6) Signed-off-by: Paul Holzinger --- hack/ci/pr-should-include-tests | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/hack/ci/pr-should-include-tests b/hack/ci/pr-should-include-tests index b78cac51bb..9cca62ba3b 100755 --- a/hack/ci/pr-should-include-tests +++ b/hack/ci/pr-should-include-tests @@ -23,25 +23,13 @@ fi # Nothing changed under test subdirectory. # -# This is OK if the only files being touched are "safe" ones. +# This is OK if no source code files were changed. +# Also we allow vendor updated without tests so exclude the vendor files +# and also the version files so release PRs do not need tests. filtered_changes=$(git diff --name-only $base $head | - grep -F -vx .cirrus.yml | - grep -F -vx .pre-commit-config.yaml | - grep -F -vx .gitignore | - grep -F -vx go.mod | - grep -F -vx go.sum | - grep -F -vx podman.spec.rpkg | - grep -F -vx .golangci.yml | - grep -F -vx winmake.ps1 | - grep -E -v '/*Makefile$' | - grep -E -v '^[^/]+\.md$' | - grep -E -v '^.github' | - grep -E -v '^contrib/' | - grep -E -v '^docs/' | - grep -E -v '^hack/' | - grep -E -v '^nix/' | - grep -E -v '^vendor/' | - grep -E -v '^version/') + grep -E -v '^(test/tools/)?vendor/' | + grep -E -v '^version/' | + grep -E -x '.*\.(go|c|h)') if [[ -z "$filtered_changes" ]]; then exit 0 fi From 407c379035c54dddcaadd1c62ed6d4db29a39431 Mon Sep 17 00:00:00 2001 From: Ricardo Branco Date: Tue, 16 Jun 2026 10:39:16 +0200 Subject: [PATCH 7/8] test/system: Fix "command not found" with wait builtin Only on Fedora there's a /bin/wait shell script that calls Bash's builtin(1). This is not the case of openSUSE Tumbleweed with the same Bash version and Debian 13. Otherwise we get errors from bats like: BW01: `run`'s command `wait 872594` exited with code 127, indicating 'Command not found'. Use run's return code checks, e.g. `run -127`, to fix this message. Replace `run wait` with `wait || true` like it's done in other tests. Signed-off-by: Ricardo Branco (cherry picked from commit 2d1868ff60161c657d77ac640cb0bf48f1651b98) Signed-off-by: Paul Holzinger --- test/system/272-system-connection.bats | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/system/272-system-connection.bats b/test/system/272-system-connection.bats index e91e9d83ef..a68669493e 100644 --- a/test/system/272-system-connection.bats +++ b/test/system/272-system-connection.bats @@ -144,7 +144,7 @@ $c2[ ]\+tcp://localhost:54321[ ]\+true[ ]\+true" \ # Stop server. Use 'run' to avoid failing on nonzero exit status run kill $_SERVICE_PID - run wait $_SERVICE_PID + wait $_SERVICE_PID || true _SERVICE_PID= run_podman system connection rm fakeconnect @@ -205,7 +205,7 @@ $c2[ ]\+tcp://localhost:54321[ ]\+true[ ]\+true" \ # Stop server. Use 'run' to avoid failing on nonzero exit status run kill $_SERVICE_PID - run wait $_SERVICE_PID + wait $_SERVICE_PID || true _SERVICE_PID= run_podman system connection rm fakeconnect @@ -270,7 +270,7 @@ $c2[ ]\+tcp://localhost:54321[ ]\+true[ ]\+true" \ # Stop server. Use 'run' to avoid failing on nonzero exit status run kill $_SERVICE_PID - run wait $_SERVICE_PID + wait $_SERVICE_PID || true _SERVICE_PID= run_podman system connection rm fakeconnect From 8aba7f8bc124c621b621ea51d7b5b82b83c21f6a Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Tue, 16 Jun 2026 10:42:42 +0200 Subject: [PATCH 8/8] Update automation image to 2026-06-16 Signed-off-by: Paul Holzinger (cherry picked from commit 5c189e813620e44f281fb683d275e8cc8d7d0a5f) Signed-off-by: Paul Holzinger --- hack/ci/ci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/ci/ci.sh b/hack/ci/ci.sh index 789708d38e..ce079a5aec 100755 --- a/hack/ci/ci.sh +++ b/hack/ci/ci.sh @@ -6,7 +6,7 @@ SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) source "$SCRIPT_DIR/lib.sh" -AUTOMATION_RELEASE="20260520t200858z" +AUTOMATION_RELEASE="20260616t073924z" # TODO should be renovate managed LIMA_VM_NAME=podman-ci REPO_DIR="$SCRIPT_DIR/../.."