Skip to content

Commit 2ae9667

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

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

pkg/homedir/homedir_others.go

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

pkg/homedir/homedir_unix.go

Lines changed: 63 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
// GetRootlessConfigHomeDir returns the config home directory when running as non root
@@ -131,3 +135,62 @@ func GetRootlessConfigHomeDir() (string, error) {
131135

132136
return rootlessConfigHomeDir, nil
133137
}
138+
139+
// GetRuntimeDirUser returns the runtime directory
140+
func GetRuntimeDirUser(rootless bool, rootlessUID int) (string, error) {
141+
var rootlessRuntimeDirError error
142+
143+
if !rootless {
144+
return "", nil
145+
}
146+
147+
rootlessRuntimeDirOnce.Do(func() {
148+
runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
149+
150+
if runtimeDir != "" {
151+
rootlessRuntimeDir, rootlessRuntimeDirError = filepath.EvalSymlinks(runtimeDir)
152+
return
153+
}
154+
155+
uid := strconv.Itoa(rootlessUID)
156+
if runtimeDir == "" {
157+
tmpDir := filepath.Join("/run", "user", uid)
158+
if err := os.MkdirAll(tmpDir, 0o700); err != nil {
159+
logrus.Debug(err)
160+
}
161+
st, err := os.Stat(tmpDir)
162+
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && (st.Mode().Perm()&0o700 == 0o700) {
163+
runtimeDir = tmpDir
164+
}
165+
}
166+
if runtimeDir == "" {
167+
tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("storage-run-%s", uid))
168+
if err := os.MkdirAll(tmpDir, 0o700); err != nil {
169+
logrus.Debug(err)
170+
}
171+
st, err := os.Stat(tmpDir)
172+
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && (st.Mode().Perm()&0o700 == 0o700) {
173+
runtimeDir = tmpDir
174+
}
175+
}
176+
if runtimeDir == "" {
177+
home := os.Getenv("HOME")
178+
if home == "" {
179+
rootlessRuntimeDirError = errors.New("neither XDG_RUNTIME_DIR nor HOME was set non-empty")
180+
return
181+
}
182+
resolvedHome, err := filepath.EvalSymlinks(home)
183+
if err != nil {
184+
rootlessRuntimeDirError = fmt.Errorf("cannot resolve %s: %w", home, err)
185+
return
186+
}
187+
runtimeDir = filepath.Join(resolvedHome, "rundir")
188+
}
189+
rootlessRuntimeDir = runtimeDir
190+
})
191+
192+
if rootlessRuntimeDirError != nil {
193+
return "", rootlessRuntimeDirError
194+
}
195+
return rootlessRuntimeDir, nil
196+
}

0 commit comments

Comments
 (0)