diff --git a/cmd/quadlet/main.go b/cmd/quadlet/main.go index c85f2e245e..b36997b32a 100644 --- a/cmd/quadlet/main.go +++ b/cmd/quadlet/main.go @@ -146,7 +146,16 @@ func getUnitDirs(rootless bool) []string { } func appendSubPaths(dirs []string, path string, isUserFlag bool, filterPtr func(string, bool) bool) []string { - err := filepath.WalkDir(path, func(_path string, info os.DirEntry, err error) error { + resolvedPath, err := filepath.EvalSymlinks(path) + if err != nil { + Debugf("Error occurred resolving path %q: %s", path, err) + // Despite the failure add the path to the list for logging purposes + // This is the equivalent of adding the path when info==nil below + dirs = append(dirs, path) + return dirs + } + + err = filepath.WalkDir(resolvedPath, func(_path string, info os.DirEntry, err error) error { if info == nil || info.IsDir() { if filterPtr == nil || filterPtr(_path, isUserFlag) { dirs = append(dirs, _path) diff --git a/cmd/quadlet/main_test.go b/cmd/quadlet/main_test.go index 9ee2ea00cd..1f29b74a13 100644 --- a/cmd/quadlet/main_test.go +++ b/cmd/quadlet/main_test.go @@ -79,4 +79,22 @@ func TestUnitDirs(t *testing.T) { unitDirs = getUnitDirs(true) assert.Equal(t, unitDirs, []string{name}, "rootless should use environment variable") + + symLinkTestBaseDir, err := os.MkdirTemp("", "podman-symlinktest") + assert.Nil(t, err) + // remove the temporary directory at the end of the program + defer os.RemoveAll(symLinkTestBaseDir) + + actualDir := filepath.Join(symLinkTestBaseDir, "actual") + err = os.Mkdir(actualDir, 0755) + assert.Nil(t, err) + innerDir := filepath.Join(actualDir, "inner") + err = os.Mkdir(innerDir, 0755) + assert.Nil(t, err) + symlink := filepath.Join(symLinkTestBaseDir, "symlink") + err = os.Symlink(actualDir, symlink) + assert.Nil(t, err) + t.Setenv("QUADLET_UNIT_DIRS", actualDir) + unitDirs = getUnitDirs(true) + assert.Equal(t, unitDirs, []string{actualDir, innerDir}, "directory resolution should follow symlink") } diff --git a/docs/source/markdown/podman-systemd.unit.5.md b/docs/source/markdown/podman-systemd.unit.5.md index a18bfa23a3..fece812e97 100644 --- a/docs/source/markdown/podman-systemd.unit.5.md +++ b/docs/source/markdown/podman-systemd.unit.5.md @@ -6,7 +6,7 @@ podman\-systemd.unit - systemd units using Podman Quadlet ## SYNOPSIS -*name*.container, *name*.volume, *name*.network, `*.kube` +*name*.container, *name*.volume, *name*.network, *name*.kube *name*.image ### Podman unit search path @@ -19,6 +19,11 @@ podman\-systemd.unit - systemd units using Podman Quadlet * /etc/containers/systemd/users/$(UID) * /etc/containers/systemd/users/ +### Using symbolic links + +Quadlet supports using symbolic links for the base of the search paths. +Symbolic links below the search paths are not supported. + ## DESCRIPTION Podman supports starting containers (and creating volumes) via systemd by using a diff --git a/test/e2e/quadlet_test.go b/test/e2e/quadlet_test.go index f2a00b971f..7bb376bb59 100644 --- a/test/e2e/quadlet_test.go +++ b/test/e2e/quadlet_test.go @@ -554,7 +554,14 @@ var _ = Describe("quadlet system generator", func() { current := session.ErrorToStringArray() expected := "No files parsed from [/something]" - Expect(current[0]).To(ContainSubstring(expected)) + found := false + for _, line := range current { + if strings.Contains(line, expected) { + found = true + break + } + } + Expect(found).To(BeTrue()) }) It("Should fail on bad quadlet", func() {