github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/util/utils_supported.go (about)

     1  //go:build !windows
     2  // +build !windows
     3  
     4  package util
     5  
     6  // TODO once rootless function is consolidated under libpod, we
     7  //  should work to take darwin from this
     8  
     9  import (
    10  	"fmt"
    11  	"os"
    12  	"path/filepath"
    13  	"syscall"
    14  
    15  	"github.com/hanks177/podman/v4/pkg/rootless"
    16  	"github.com/pkg/errors"
    17  	"github.com/sirupsen/logrus"
    18  )
    19  
    20  // GetRuntimeDir returns the runtime directory
    21  func GetRuntimeDir() (string, error) {
    22  	var rootlessRuntimeDirError error
    23  
    24  	if !rootless.IsRootless() {
    25  		return "", nil
    26  	}
    27  
    28  	rootlessRuntimeDirOnce.Do(func() {
    29  		runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
    30  		uid := fmt.Sprintf("%d", rootless.GetRootlessUID())
    31  		if runtimeDir == "" {
    32  			tmpDir := filepath.Join("/run", "user", uid)
    33  			if err := os.MkdirAll(tmpDir, 0700); err != nil {
    34  				logrus.Debug(err)
    35  			}
    36  			st, err := os.Stat(tmpDir)
    37  			if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && (st.Mode().Perm()&0700 == 0700) {
    38  				runtimeDir = tmpDir
    39  			}
    40  		}
    41  		if runtimeDir == "" {
    42  			tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("podman-run-%s", uid))
    43  			if err := os.MkdirAll(tmpDir, 0700); err != nil {
    44  				logrus.Debug(err)
    45  			}
    46  			st, err := os.Stat(tmpDir)
    47  			if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && (st.Mode().Perm()&0700 == 0700) {
    48  				runtimeDir = tmpDir
    49  			}
    50  		}
    51  		if runtimeDir == "" {
    52  			home := os.Getenv("HOME")
    53  			if home == "" {
    54  				rootlessRuntimeDirError = fmt.Errorf("neither XDG_RUNTIME_DIR nor HOME was set non-empty")
    55  				return
    56  			}
    57  			resolvedHome, err := filepath.EvalSymlinks(home)
    58  			if err != nil {
    59  				rootlessRuntimeDirError = errors.Wrapf(err, "cannot resolve %s", home)
    60  				return
    61  			}
    62  			runtimeDir = filepath.Join(resolvedHome, "rundir")
    63  		}
    64  		rootlessRuntimeDir = runtimeDir
    65  	})
    66  
    67  	if rootlessRuntimeDirError != nil {
    68  		return "", rootlessRuntimeDirError
    69  	}
    70  	return rootlessRuntimeDir, nil
    71  }
    72  
    73  // GetRootlessConfigHomeDir returns the config home directory when running as non root
    74  func GetRootlessConfigHomeDir() (string, error) {
    75  	var rootlessConfigHomeDirError error
    76  
    77  	rootlessConfigHomeDirOnce.Do(func() {
    78  		cfgHomeDir := os.Getenv("XDG_CONFIG_HOME")
    79  		if cfgHomeDir == "" {
    80  			home := os.Getenv("HOME")
    81  			resolvedHome, err := filepath.EvalSymlinks(home)
    82  			if err != nil {
    83  				rootlessConfigHomeDirError = errors.Wrapf(err, "cannot resolve %s", home)
    84  				return
    85  			}
    86  			tmpDir := filepath.Join(resolvedHome, ".config")
    87  			st, err := os.Stat(tmpDir)
    88  			if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() >= 0700 {
    89  				cfgHomeDir = tmpDir
    90  			}
    91  		}
    92  		rootlessConfigHomeDir = cfgHomeDir
    93  	})
    94  
    95  	if rootlessConfigHomeDirError != nil {
    96  		return "", rootlessConfigHomeDirError
    97  	}
    98  
    99  	return rootlessConfigHomeDir, nil
   100  }
   101  
   102  // GetRootlessPauseProcessPidPath returns the path to the file that holds the pid for
   103  // the pause process.
   104  // DEPRECATED - switch to GetRootlessPauseProcessPidPathGivenDir
   105  func GetRootlessPauseProcessPidPath() (string, error) {
   106  	runtimeDir, err := GetRuntimeDir()
   107  	if err != nil {
   108  		return "", err
   109  	}
   110  	return filepath.Join(runtimeDir, "libpod", "pause.pid"), nil
   111  }
   112  
   113  // GetRootlessPauseProcessPidPathGivenDir returns the path to the file that
   114  // holds the PID of the pause process, given the location of Libpod's temporary
   115  // files.
   116  func GetRootlessPauseProcessPidPathGivenDir(libpodTmpDir string) (string, error) {
   117  	if libpodTmpDir == "" {
   118  		return "", errors.Errorf("must provide non-empty temporary directory")
   119  	}
   120  	return filepath.Join(libpodTmpDir, "pause.pid"), nil
   121  }