Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quadlet - make sure the /etc/containers/systemd/users is traversed in rootless #24815

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions cmd/quadlet/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ func getRootlessDirs(paths *searchPaths, nonNumericFilter, userLevelFilter func(
appendSubPaths(paths, filepath.Join(quadlet.UnitDirAdmin, "users", u.Uid), true, userLevelFilter)
} else {
fmt.Fprintf(os.Stderr, "Warning: %v", err)
// Add the base directory even if the UID was not found
paths.Add(filepath.Join(quadlet.UnitDirAdmin, "users"))
}

paths.Add(filepath.Join(quadlet.UnitDirAdmin, "users"))
}

func getRootDirs(paths *searchPaths, userLevelFilter func(string, bool) bool) {
Expand Down Expand Up @@ -279,6 +279,10 @@ func getNonNumericFilter(resolvedUnitDirAdminUser string, systemUserDirLevel int
// ignore sub dirs under the `users` directory which correspond to a user id
if strings.HasPrefix(path, resolvedUnitDirAdminUser) {
listDirUserPathLevels := strings.Split(path, string(os.PathSeparator))
// Make sure to add the base directory
if len(listDirUserPathLevels) == systemUserDirLevel {
return true
}
if len(listDirUserPathLevels) > systemUserDirLevel {
if !(regexp.MustCompile(`^[0-9]*$`).MatchString(listDirUserPathLevels[systemUserDirLevel])) {
return true
Expand Down
44 changes: 27 additions & 17 deletions cmd/quadlet/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ func TestUnitDirs(t *testing.T) {
appendSubPaths(rootlessPaths, path.Join(configDir, "containers/systemd"), false, nil)
appendSubPaths(rootlessPaths, filepath.Join(quadlet.UnitDirAdmin, "users"), true, nonNumericFilter)
appendSubPaths(rootlessPaths, filepath.Join(quadlet.UnitDirAdmin, "users", u.Uid), true, userLevelFilter)
rootlessPaths.Add(filepath.Join(quadlet.UnitDirAdmin, "users"))

unitDirs = getUnitDirs(true)
assert.Equal(t, rootlessPaths.sorted, unitDirs, "rootless unit dirs should match")
Expand Down Expand Up @@ -222,28 +221,39 @@ func TestUnitDirs(t *testing.T) {
err = os.RemoveAll(quadlet.UnitDirAdmin)
assert.Nil(t, err)

systemdDir := filepath.Join("/", "systemd")
userDir := filepath.Join("/", "users")
err = os.Mkdir(systemdDir, 0755)
assert.Nil(t, err)
err = os.Mkdir(userDir, 0755)
assert.Nil(t, err)
err = os.Symlink(userDir, filepath.Join(systemdDir, "users"))
assert.Nil(t, err)
err = os.Symlink(systemdDir, quadlet.UnitDirAdmin)
assert.Nil(t, err)
createDir := func(path, name string) string {
dirName := filepath.Join(path, name)
err = os.Mkdir(dirName, 0755)
assert.Nil(t, err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not blocking as it is pre existing and done in way to many other places but error checks should be done with
assert.NoError() because that prints a better message when it fails.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I just copy pasted the code. I see that it's being fixed in #24974

return dirName
}

uidDir := filepath.Join(userDir, u.Uid)
err = os.Mkdir(uidDir, 0755)
assert.Nil(t, err)
uidDir2 := filepath.Join(userDir, strconv.Itoa(uidInt+1))
err = os.Mkdir(uidDir2, 0755)
assert.Nil(t, err)
linkDir := func(path, name, target string) {
linkName := filepath.Join(path, name)
err = os.Symlink(target, linkName)
assert.Nil(t, err)
}

systemdDir := createDir("/", "systemd")
userDir := createDir("/", "users")
linkDir(systemdDir, "users", userDir)
linkDir(quadlet.UnitDirAdmin, "", systemdDir)

uidDir := createDir(userDir, u.Uid)
uidDir2 := createDir(userDir, strconv.Itoa(uidInt+1))
userInternalDir := createDir(userDir, "internal")

// Make sure QUADLET_UNIT_DIRS is not set
t.Setenv("QUADLET_UNIT_DIRS", "")
// Test Rootful
unitDirs := getUnitDirs(false)
assert.NotContains(t, unitDirs, userDir, "rootful should not contain rootless")
assert.NotContains(t, unitDirs, userInternalDir, "rootful should not contain rootless")

// Test Rootless
unitDirs = getUnitDirs(true)
assert.NotContains(t, unitDirs, uidDir2, "rootless should not contain other users'")
assert.Contains(t, unitDirs, userInternalDir, "rootless should contain sub-directories of users dir")
assert.Contains(t, unitDirs, uidDir, "rootless should contain the directory for its UID")
}
}
Loading