Merge pull request #23970 from ygalblum/simplify-get-units-dir

Quadlet - Split getUnitDirs to small functions
This commit is contained in:
openshift-merge-bot[bot]
2024-09-17 06:40:41 +00:00
committed by GitHub
2 changed files with 102 additions and 68 deletions

View File

@@ -56,12 +56,6 @@ var (
} }
) )
var (
unitDirAdminUser string
resolvedUnitDirAdminUser string
systemUserDirLevel int
)
// We log directly to /dev/kmsg, because that is the only way to get information out // We log directly to /dev/kmsg, because that is the only way to get information out
// of the generator into the system logs. // of the generator into the system logs.
func logToKmsg(s string) bool { func logToKmsg(s string) bool {
@@ -115,31 +109,42 @@ func Debugf(format string, a ...interface{}) {
// For user generators these can live in $XDG_RUNTIME_DIR/containers/systemd, /etc/containers/systemd/users, /etc/containers/systemd/users/$UID, and $XDG_CONFIG_HOME/containers/systemd // For user generators these can live in $XDG_RUNTIME_DIR/containers/systemd, /etc/containers/systemd/users, /etc/containers/systemd/users/$UID, and $XDG_CONFIG_HOME/containers/systemd
func getUnitDirs(rootless bool) []string { func getUnitDirs(rootless bool) []string {
// Allow overriding source dir, this is mainly for the CI tests // Allow overriding source dir, this is mainly for the CI tests
unitDirsEnv := os.Getenv("QUADLET_UNIT_DIRS") if varExist, dirs := getDirsFromEnv(); varExist {
dirs := make([]string, 0)
unitDirAdminUser = filepath.Join(quadlet.UnitDirAdmin, "users")
var err error
if resolvedUnitDirAdminUser, err = filepath.EvalSymlinks(unitDirAdminUser); err != nil {
if !errors.Is(err, fs.ErrNotExist) {
Debugf("Error occurred resolving path %q: %s", unitDirAdminUser, err)
}
resolvedUnitDirAdminUser = unitDirAdminUser
}
systemUserDirLevel = len(strings.Split(resolvedUnitDirAdminUser, string(os.PathSeparator)))
if len(unitDirsEnv) > 0 {
for _, eachUnitDir := range strings.Split(unitDirsEnv, ":") {
if !filepath.IsAbs(eachUnitDir) {
Logf("%s not a valid file path", eachUnitDir)
return nil
}
dirs = appendSubPaths(dirs, eachUnitDir, false, nil)
}
return dirs return dirs
} }
resolvedUnitDirAdminUser := resolveUnitDirAdminUser()
userLevelFilter := getUserLevelFilter(resolvedUnitDirAdminUser)
if rootless { if rootless {
systemUserDirLevel := len(strings.Split(resolvedUnitDirAdminUser, string(os.PathSeparator)))
nonNumericFilter := getNonNumericFilter(resolvedUnitDirAdminUser, systemUserDirLevel)
return getRootlessDirs(nonNumericFilter, userLevelFilter)
}
return getRootDirs(userLevelFilter)
}
func getDirsFromEnv() (bool, []string) {
unitDirsEnv := os.Getenv("QUADLET_UNIT_DIRS")
if len(unitDirsEnv) == 0 {
return false, nil
}
dirs := make([]string, 0)
for _, eachUnitDir := range strings.Split(unitDirsEnv, ":") {
if !filepath.IsAbs(eachUnitDir) {
Logf("%s not a valid file path", eachUnitDir)
return true, nil
}
dirs = appendSubPaths(dirs, eachUnitDir, false, nil)
}
return true, dirs
}
func getRootlessDirs(nonNumericFilter, userLevelFilter func(string, bool) bool) []string {
dirs := make([]string, 0)
runtimeDir, found := os.LookupEnv("XDG_RUNTIME_DIR") runtimeDir, found := os.LookupEnv("XDG_RUNTIME_DIR")
if found { if found {
dirs = appendSubPaths(dirs, path.Join(runtimeDir, "containers/systemd"), false, nil) dirs = appendSubPaths(dirs, path.Join(runtimeDir, "containers/systemd"), false, nil)
@@ -151,6 +156,7 @@ func getUnitDirs(rootless bool) []string {
return nil return nil
} }
dirs = appendSubPaths(dirs, path.Join(configDir, "containers/systemd"), false, nil) dirs = appendSubPaths(dirs, path.Join(configDir, "containers/systemd"), false, nil)
u, err := user.Current() u, err := user.Current()
if err == nil { if err == nil {
dirs = appendSubPaths(dirs, filepath.Join(quadlet.UnitDirAdmin, "users"), true, nonNumericFilter) dirs = appendSubPaths(dirs, filepath.Join(quadlet.UnitDirAdmin, "users"), true, nonNumericFilter)
@@ -158,14 +164,31 @@ func getUnitDirs(rootless bool) []string {
} else { } else {
fmt.Fprintf(os.Stderr, "Warning: %v", err) fmt.Fprintf(os.Stderr, "Warning: %v", err)
} }
return append(dirs, filepath.Join(quadlet.UnitDirAdmin, "users")) return append(dirs, filepath.Join(quadlet.UnitDirAdmin, "users"))
} }
func getRootDirs(userLevelFilter func(string, bool) bool) []string {
dirs := make([]string, 0)
dirs = appendSubPaths(dirs, quadlet.UnitDirTemp, false, userLevelFilter) dirs = appendSubPaths(dirs, quadlet.UnitDirTemp, false, userLevelFilter)
dirs = appendSubPaths(dirs, quadlet.UnitDirAdmin, false, userLevelFilter) dirs = appendSubPaths(dirs, quadlet.UnitDirAdmin, false, userLevelFilter)
return appendSubPaths(dirs, quadlet.UnitDirDistro, false, nil) return appendSubPaths(dirs, quadlet.UnitDirDistro, false, nil)
} }
func resolveUnitDirAdminUser() string {
unitDirAdminUser := filepath.Join(quadlet.UnitDirAdmin, "users")
var err error
var resolvedUnitDirAdminUser string
if resolvedUnitDirAdminUser, err = filepath.EvalSymlinks(unitDirAdminUser); err != nil {
if !errors.Is(err, fs.ErrNotExist) {
Debugf("Error occurred resolving path %q: %s", unitDirAdminUser, err)
}
resolvedUnitDirAdminUser = unitDirAdminUser
}
return resolvedUnitDirAdminUser
}
func appendSubPaths(dirs []string, path string, isUserFlag bool, filterPtr func(string, bool) bool) []string { func appendSubPaths(dirs []string, path string, isUserFlag bool, filterPtr func(string, bool) bool) []string {
resolvedPath, err := filepath.EvalSymlinks(path) resolvedPath, err := filepath.EvalSymlinks(path)
if err != nil { if err != nil {
@@ -197,11 +220,12 @@ func appendSubPaths(dirs []string, path string, isUserFlag bool, filterPtr func(
return dirs return dirs
} }
func nonNumericFilter(_path string, isUserFlag bool) bool { func getNonNumericFilter(resolvedUnitDirAdminUser string, systemUserDirLevel int) func(string, bool) bool {
return func(path string, isUserFlag bool) bool {
// when running in rootless, recursive walk directories that are non numeric // when running in rootless, recursive walk directories that are non numeric
// ignore sub dirs under the `users` directory which correspond to a user id // ignore sub dirs under the `users` directory which correspond to a user id
if strings.HasPrefix(_path, resolvedUnitDirAdminUser) { if strings.HasPrefix(path, resolvedUnitDirAdminUser) {
listDirUserPathLevels := strings.Split(_path, string(os.PathSeparator)) listDirUserPathLevels := strings.Split(path, string(os.PathSeparator))
if len(listDirUserPathLevels) > systemUserDirLevel { if len(listDirUserPathLevels) > systemUserDirLevel {
if !(regexp.MustCompile(`^[0-9]*$`).MatchString(listDirUserPathLevels[systemUserDirLevel])) { if !(regexp.MustCompile(`^[0-9]*$`).MatchString(listDirUserPathLevels[systemUserDirLevel])) {
return true return true
@@ -212,8 +236,10 @@ func nonNumericFilter(_path string, isUserFlag bool) bool {
} }
return false return false
} }
}
func userLevelFilter(_path string, isUserFlag bool) bool { func getUserLevelFilter(resolvedUnitDirAdminUser string) func(string, bool) bool {
return func(_path string, isUserFlag bool) bool {
// if quadlet generator is run rootless, do not recurse other user sub dirs // if quadlet generator is run rootless, do not recurse other user sub dirs
// if quadlet generator is run as root, ignore users sub dirs // if quadlet generator is run as root, ignore users sub dirs
if strings.HasPrefix(_path, resolvedUnitDirAdminUser) { if strings.HasPrefix(_path, resolvedUnitDirAdminUser) {
@@ -225,6 +251,7 @@ func userLevelFilter(_path string, isUserFlag bool) bool {
} }
return false return false
} }
}
func isExtSupported(filename string) bool { func isExtSupported(filename string) bool {
ext := filepath.Ext(filename) ext := filepath.Ext(filename)

View File

@@ -10,6 +10,7 @@ import (
"path" "path"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings"
"syscall" "syscall"
"testing" "testing"
@@ -60,6 +61,9 @@ func TestUnitDirs(t *testing.T) {
if os.Getenv("_UNSHARED") != "true" { if os.Getenv("_UNSHARED") != "true" {
unitDirs := getUnitDirs(false) unitDirs := getUnitDirs(false)
resolvedUnitDirAdminUser := resolveUnitDirAdminUser()
userLevelFilter := getUserLevelFilter(resolvedUnitDirAdminUser)
rootDirs := []string{} rootDirs := []string{}
rootDirs = appendSubPaths(rootDirs, quadlet.UnitDirTemp, false, userLevelFilter) rootDirs = appendSubPaths(rootDirs, quadlet.UnitDirTemp, false, userLevelFilter)
rootDirs = appendSubPaths(rootDirs, quadlet.UnitDirAdmin, false, userLevelFilter) rootDirs = appendSubPaths(rootDirs, quadlet.UnitDirAdmin, false, userLevelFilter)
@@ -71,6 +75,9 @@ func TestUnitDirs(t *testing.T) {
rootlessDirs := []string{} rootlessDirs := []string{}
systemUserDirLevel := len(strings.Split(resolvedUnitDirAdminUser, string(os.PathSeparator)))
nonNumericFilter := getNonNumericFilter(resolvedUnitDirAdminUser, systemUserDirLevel)
runtimeDir, found := os.LookupEnv("XDG_RUNTIME_DIR") runtimeDir, found := os.LookupEnv("XDG_RUNTIME_DIR")
if found { if found {
rootlessDirs = appendSubPaths(rootlessDirs, path.Join(runtimeDir, "containers/systemd"), false, nil) rootlessDirs = appendSubPaths(rootlessDirs, path.Join(runtimeDir, "containers/systemd"), false, nil)