From 2ae96678f37438fa9e427a7b3b8139860b60266e Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 30 Oct 2023 10:12:55 +0100 Subject: [PATCH] pkg/homedir: new function GetRuntimeDirUser() [NO NEW TESTS NEEDED] moved from Podman Signed-off-by: Giuseppe Scrivano --- pkg/homedir/homedir_others.go | 5 +++ pkg/homedir/homedir_unix.go | 63 +++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/pkg/homedir/homedir_others.go b/pkg/homedir/homedir_others.go index 34ae0e3e8d..b52f5ba8f2 100644 --- a/pkg/homedir/homedir_others.go +++ b/pkg/homedir/homedir_others.go @@ -24,3 +24,8 @@ func StickRuntimeDirContents(files []string) ([]string, error) { func GetRootlessConfigHomeDir() (string, error) { return "", errors.New("homedir.GetRootlessConfigHomeDir() is not supported on this system") } + +// GetRuntimeDirUser is unsupported on non-linux system. +func GetRuntimeDirUser(rootless bool, rootlessUID int) (string, error) { + return "", errors.New("homedir.GetRuntimeDirUser() is not supported on this system") +} diff --git a/pkg/homedir/homedir_unix.go b/pkg/homedir/homedir_unix.go index 8adcedd250..b86651e304 100644 --- a/pkg/homedir/homedir_unix.go +++ b/pkg/homedir/homedir_unix.go @@ -11,11 +11,13 @@ import ( "fmt" "os" "path/filepath" + "strconv" "strings" "sync" "syscall" "github.com/containers/storage/pkg/unshare" + "github.com/sirupsen/logrus" ) // Key returns the env var name for the user's home dir based on @@ -101,6 +103,8 @@ func stick(f string) error { var ( rootlessConfigHomeDirOnce sync.Once rootlessConfigHomeDir string + rootlessRuntimeDirOnce sync.Once + rootlessRuntimeDir string ) // GetRootlessConfigHomeDir returns the config home directory when running as non root @@ -131,3 +135,62 @@ func GetRootlessConfigHomeDir() (string, error) { return rootlessConfigHomeDir, nil } + +// GetRuntimeDirUser returns the runtime directory +func GetRuntimeDirUser(rootless bool, rootlessUID int) (string, error) { + var rootlessRuntimeDirError error + + if !rootless { + return "", nil + } + + rootlessRuntimeDirOnce.Do(func() { + runtimeDir := os.Getenv("XDG_RUNTIME_DIR") + + if runtimeDir != "" { + rootlessRuntimeDir, rootlessRuntimeDirError = filepath.EvalSymlinks(runtimeDir) + return + } + + uid := strconv.Itoa(rootlessUID) + if runtimeDir == "" { + tmpDir := filepath.Join("/run", "user", uid) + if err := os.MkdirAll(tmpDir, 0o700); err != nil { + logrus.Debug(err) + } + st, err := os.Stat(tmpDir) + if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && (st.Mode().Perm()&0o700 == 0o700) { + runtimeDir = tmpDir + } + } + if runtimeDir == "" { + tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("storage-run-%s", uid)) + if err := os.MkdirAll(tmpDir, 0o700); err != nil { + logrus.Debug(err) + } + st, err := os.Stat(tmpDir) + if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && (st.Mode().Perm()&0o700 == 0o700) { + runtimeDir = tmpDir + } + } + if runtimeDir == "" { + home := os.Getenv("HOME") + if home == "" { + rootlessRuntimeDirError = errors.New("neither XDG_RUNTIME_DIR nor HOME was set non-empty") + return + } + resolvedHome, err := filepath.EvalSymlinks(home) + if err != nil { + rootlessRuntimeDirError = fmt.Errorf("cannot resolve %s: %w", home, err) + return + } + runtimeDir = filepath.Join(resolvedHome, "rundir") + } + rootlessRuntimeDir = runtimeDir + }) + + if rootlessRuntimeDirError != nil { + return "", rootlessRuntimeDirError + } + return rootlessRuntimeDir, nil +}