Skip to content

Commit e41bafc

Browse files
committed
pkg/homedir: new function GetRuntimeDirUser()
[NO NEW TESTS NEEDED] moved from Podman Signed-off-by: Giuseppe Scrivano <[email protected]>
1 parent 22d1e05 commit e41bafc

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

pkg/homedir/homedir_others.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,8 @@ func StickRuntimeDirContents(files []string) ([]string, error) {
2727
func GetConfigHome() (string, error) {
2828
return "", errors.New("homedir.GetRootlessConfigHomeDir() is not supported on this system")
2929
}
30+
31+
// GetRuntimeDirUser is unsupported on non-linux system.
32+
func GetRuntimeDirUser(rootless bool, rootlessUID int) (string, error) {
33+
return "", errors.New("homedir.GetRuntimeDirUser() is not supported on this system")
34+
}

pkg/homedir/homedir_unix.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ import (
1111
"fmt"
1212
"os"
1313
"path/filepath"
14+
"strconv"
1415
"strings"
1516
"sync"
1617
"syscall"
1718

1819
"github.com/containers/storage/pkg/unshare"
20+
"github.com/sirupsen/logrus"
1921
)
2022

2123
// Key returns the env var name for the user's home dir based on
@@ -101,6 +103,8 @@ func stick(f string) error {
101103
var (
102104
rootlessConfigHomeDirOnce sync.Once
103105
rootlessConfigHomeDir string
106+
rootlessRuntimeDirOnce sync.Once
107+
rootlessRuntimeDir string
104108
)
105109

106110
// GetConfigHome returns XDG_CONFIG_HOME.
@@ -134,3 +138,65 @@ func GetConfigHome() (string, error) {
134138

135139
return rootlessConfigHomeDir, nil
136140
}
141+
142+
// GetRuntimeDirUser returns the runtime directory for the specified user.
143+
// If the environment variable is not set, the function will attempt to use common locations.
144+
// rootless: A boolean flag indicating whether rootless the process is running as rootless or not.
145+
// rootlessUID: An integer representing the user ID for the rootless user.
146+
func GetRuntimeDirUser(rootless bool, rootlessUID int) (string, error) {
147+
var rootlessRuntimeDirError error
148+
149+
if !rootless {
150+
return "", nil
151+
}
152+
153+
rootlessRuntimeDirOnce.Do(func() {
154+
runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
155+
156+
if runtimeDir != "" {
157+
rootlessRuntimeDir, rootlessRuntimeDirError = filepath.EvalSymlinks(runtimeDir)
158+
return
159+
}
160+
161+
uid := strconv.Itoa(rootlessUID)
162+
if runtimeDir == "" {
163+
tmpDir := filepath.Join("/run", "user", uid)
164+
if err := os.MkdirAll(tmpDir, 0o700); err != nil {
165+
logrus.Debug(err)
166+
}
167+
st, err := os.Stat(tmpDir)
168+
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && (st.Mode().Perm()&0o700 == 0o700) {
169+
runtimeDir = tmpDir
170+
}
171+
}
172+
if runtimeDir == "" {
173+
tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("storage-run-%s", uid))
174+
if err := os.MkdirAll(tmpDir, 0o700); err != nil {
175+
logrus.Debug(err)
176+
}
177+
st, err := os.Stat(tmpDir)
178+
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && (st.Mode().Perm()&0o700 == 0o700) {
179+
runtimeDir = tmpDir
180+
}
181+
}
182+
if runtimeDir == "" {
183+
home := os.Getenv("HOME")
184+
if home == "" {
185+
rootlessRuntimeDirError = errors.New("neither XDG_RUNTIME_DIR nor HOME was set non-empty")
186+
return
187+
}
188+
resolvedHome, err := filepath.EvalSymlinks(home)
189+
if err != nil {
190+
rootlessRuntimeDirError = fmt.Errorf("cannot resolve %s: %w", home, err)
191+
return
192+
}
193+
runtimeDir = filepath.Join(resolvedHome, "rundir")
194+
}
195+
rootlessRuntimeDir = runtimeDir
196+
})
197+
198+
if rootlessRuntimeDirError != nil {
199+
return "", rootlessRuntimeDirError
200+
}
201+
return rootlessRuntimeDir, nil
202+
}

0 commit comments

Comments
 (0)