mirror of
https://github.com/containers/podman.git
synced 2025-06-28 14:29:04 +08:00
Move rootless directory handling to the libpod/pkg/util directory
This should allow us to share this code with buildah. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
@ -1,21 +1,16 @@
|
|||||||
package libpodruntime
|
package libpodruntime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/containers/libpod/libpod"
|
"github.com/containers/libpod/libpod"
|
||||||
"github.com/containers/libpod/pkg/rootless"
|
"github.com/containers/libpod/pkg/rootless"
|
||||||
"github.com/containers/libpod/pkg/util"
|
"github.com/containers/libpod/pkg/util"
|
||||||
"github.com/containers/storage"
|
"github.com/containers/storage"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetRuntime generates a new libpod runtime configured by command line options
|
// GetRuntime generates a new libpod runtime configured by command line options
|
||||||
func GetRuntime(c *cli.Context) (*libpod.Runtime, error) {
|
func GetRuntime(c *cli.Context) (*libpod.Runtime, error) {
|
||||||
storageOpts, err := GetDefaultStoreOptions()
|
storageOpts, err := util.GetDefaultStoreOptions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -28,7 +23,7 @@ func GetContainerRuntime(c *cli.Context) (*libpod.Runtime, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
storageOpts, err := GetDefaultStoreOptions()
|
storageOpts, err := util.GetDefaultStoreOptions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -37,51 +32,6 @@ func GetContainerRuntime(c *cli.Context) (*libpod.Runtime, error) {
|
|||||||
return GetRuntimeWithStorageOpts(c, &storageOpts)
|
return GetRuntimeWithStorageOpts(c, &storageOpts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRootlessStorageOpts() (storage.StoreOptions, error) {
|
|
||||||
var opts storage.StoreOptions
|
|
||||||
|
|
||||||
rootlessRuntime, err := libpod.GetRootlessRuntimeDir()
|
|
||||||
if err != nil {
|
|
||||||
return opts, err
|
|
||||||
}
|
|
||||||
opts.RunRoot = filepath.Join(rootlessRuntime, "run")
|
|
||||||
|
|
||||||
dataDir := os.Getenv("XDG_DATA_HOME")
|
|
||||||
if dataDir == "" {
|
|
||||||
home := os.Getenv("HOME")
|
|
||||||
if home == "" {
|
|
||||||
return opts, fmt.Errorf("neither XDG_DATA_HOME nor HOME was set non-empty")
|
|
||||||
}
|
|
||||||
// runc doesn't like symlinks in the rootfs path, and at least
|
|
||||||
// on CoreOS /home is a symlink to /var/home, so resolve any symlink.
|
|
||||||
resolvedHome, err := filepath.EvalSymlinks(home)
|
|
||||||
if err != nil {
|
|
||||||
return opts, errors.Wrapf(err, "cannot resolve %s", home)
|
|
||||||
}
|
|
||||||
dataDir = filepath.Join(resolvedHome, ".local", "share")
|
|
||||||
}
|
|
||||||
opts.GraphRoot = filepath.Join(dataDir, "containers", "storage")
|
|
||||||
opts.GraphDriverName = "vfs"
|
|
||||||
return opts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetDefaultStoreOptions() (storage.StoreOptions, error) {
|
|
||||||
storageOpts := storage.DefaultStoreOptions
|
|
||||||
if rootless.IsRootless() {
|
|
||||||
var err error
|
|
||||||
storageOpts, err = GetRootlessStorageOpts()
|
|
||||||
if err != nil {
|
|
||||||
return storageOpts, err
|
|
||||||
}
|
|
||||||
|
|
||||||
storageConf := filepath.Join(os.Getenv("HOME"), ".config/containers/storage.conf")
|
|
||||||
if _, err := os.Stat(storageConf); err == nil {
|
|
||||||
storage.ReloadConfigurationFile(storageConf, &storageOpts)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return storageOpts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRuntime generates a new libpod runtime configured by command line options
|
// GetRuntime generates a new libpod runtime configured by command line options
|
||||||
func GetRuntimeWithStorageOpts(c *cli.Context, storageOpts *storage.StoreOptions) (*libpod.Runtime, error) {
|
func GetRuntimeWithStorageOpts(c *cli.Context, storageOpts *storage.StoreOptions) (*libpod.Runtime, error) {
|
||||||
options := []libpod.RuntimeOption{}
|
options := []libpod.RuntimeOption{}
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
|
|
||||||
"github.com/containers/libpod/pkg/ctime"
|
"github.com/containers/libpod/pkg/ctime"
|
||||||
"github.com/containers/libpod/pkg/rootless"
|
"github.com/containers/libpod/pkg/rootless"
|
||||||
|
"github.com/containers/libpod/pkg/util"
|
||||||
"github.com/coreos/go-systemd/activation"
|
"github.com/coreos/go-systemd/activation"
|
||||||
"github.com/cri-o/ocicni/pkg/ocicni"
|
"github.com/cri-o/ocicni/pkg/ocicni"
|
||||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
@ -230,7 +231,7 @@ func bindPorts(ports []ocicni.PortMapping) ([]*os.File, error) {
|
|||||||
func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string, restoreContainer bool) (err error) {
|
func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string, restoreContainer bool) (err error) {
|
||||||
var stderrBuf bytes.Buffer
|
var stderrBuf bytes.Buffer
|
||||||
|
|
||||||
runtimeDir, err := GetRootlessRuntimeDir()
|
runtimeDir, err := util.GetRootlessRuntimeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -446,7 +447,7 @@ func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string, res
|
|||||||
func (r *OCIRuntime) updateContainerStatus(ctr *Container) error {
|
func (r *OCIRuntime) updateContainerStatus(ctr *Container) error {
|
||||||
state := new(spec.State)
|
state := new(spec.State)
|
||||||
|
|
||||||
runtimeDir, err := GetRootlessRuntimeDir()
|
runtimeDir, err := util.GetRootlessRuntimeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -556,7 +557,7 @@ func (r *OCIRuntime) updateContainerStatus(ctr *Container) error {
|
|||||||
// Sets time the container was started, but does not save it.
|
// Sets time the container was started, but does not save it.
|
||||||
func (r *OCIRuntime) startContainer(ctr *Container) error {
|
func (r *OCIRuntime) startContainer(ctr *Container) error {
|
||||||
// TODO: streams should probably *not* be our STDIN/OUT/ERR - redirect to buffers?
|
// TODO: streams should probably *not* be our STDIN/OUT/ERR - redirect to buffers?
|
||||||
runtimeDir, err := GetRootlessRuntimeDir()
|
runtimeDir, err := util.GetRootlessRuntimeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -573,7 +574,7 @@ func (r *OCIRuntime) startContainer(ctr *Container) error {
|
|||||||
// killContainer sends the given signal to the given container
|
// killContainer sends the given signal to the given container
|
||||||
func (r *OCIRuntime) killContainer(ctr *Container, signal uint) error {
|
func (r *OCIRuntime) killContainer(ctr *Container, signal uint) error {
|
||||||
logrus.Debugf("Sending signal %d to container %s", signal, ctr.ID())
|
logrus.Debugf("Sending signal %d to container %s", signal, ctr.ID())
|
||||||
runtimeDir, err := GetRootlessRuntimeDir()
|
runtimeDir, err := util.GetRootlessRuntimeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -636,7 +637,7 @@ func (r *OCIRuntime) stopContainer(ctr *Container, timeout uint) error {
|
|||||||
args = []string{"kill", "--all", ctr.ID(), "KILL"}
|
args = []string{"kill", "--all", ctr.ID(), "KILL"}
|
||||||
}
|
}
|
||||||
|
|
||||||
runtimeDir, err := GetRootlessRuntimeDir()
|
runtimeDir, err := util.GetRootlessRuntimeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -667,7 +668,7 @@ func (r *OCIRuntime) deleteContainer(ctr *Container) error {
|
|||||||
|
|
||||||
// pauseContainer pauses the given container
|
// pauseContainer pauses the given container
|
||||||
func (r *OCIRuntime) pauseContainer(ctr *Container) error {
|
func (r *OCIRuntime) pauseContainer(ctr *Container) error {
|
||||||
runtimeDir, err := GetRootlessRuntimeDir()
|
runtimeDir, err := util.GetRootlessRuntimeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -677,7 +678,7 @@ func (r *OCIRuntime) pauseContainer(ctr *Container) error {
|
|||||||
|
|
||||||
// unpauseContainer unpauses the given container
|
// unpauseContainer unpauses the given container
|
||||||
func (r *OCIRuntime) unpauseContainer(ctr *Container) error {
|
func (r *OCIRuntime) unpauseContainer(ctr *Container) error {
|
||||||
runtimeDir, err := GetRootlessRuntimeDir()
|
runtimeDir, err := util.GetRootlessRuntimeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -698,7 +699,7 @@ func (r *OCIRuntime) execContainer(c *Container, cmd, capAdd, env []string, tty
|
|||||||
return nil, errors.Wrapf(ErrEmptyID, "must provide a session ID for exec")
|
return nil, errors.Wrapf(ErrEmptyID, "must provide a session ID for exec")
|
||||||
}
|
}
|
||||||
|
|
||||||
runtimeDir, err := GetRootlessRuntimeDir()
|
runtimeDir, err := util.GetRootlessRuntimeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -780,7 +781,7 @@ func (r *OCIRuntime) execStopContainer(ctr *Container, timeout uint) error {
|
|||||||
if len(execSessions) == 0 {
|
if len(execSessions) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
runtimeDir, err := GetRootlessRuntimeDir()
|
runtimeDir, err := util.GetRootlessRuntimeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
package libpod
|
package libpod
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
is "github.com/containers/image/storage"
|
is "github.com/containers/image/storage"
|
||||||
@ -17,6 +15,7 @@ import (
|
|||||||
"github.com/containers/libpod/pkg/hooks"
|
"github.com/containers/libpod/pkg/hooks"
|
||||||
sysreg "github.com/containers/libpod/pkg/registries"
|
sysreg "github.com/containers/libpod/pkg/registries"
|
||||||
"github.com/containers/libpod/pkg/rootless"
|
"github.com/containers/libpod/pkg/rootless"
|
||||||
|
"github.com/containers/libpod/pkg/util"
|
||||||
"github.com/containers/storage"
|
"github.com/containers/storage"
|
||||||
"github.com/cri-o/ocicni/pkg/ocicni"
|
"github.com/cri-o/ocicni/pkg/ocicni"
|
||||||
"github.com/docker/docker/pkg/namesgenerator"
|
"github.com/docker/docker/pkg/namesgenerator"
|
||||||
@ -215,46 +214,12 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetRootlessRuntimeDir returns the runtime directory when running as non root
|
|
||||||
func GetRootlessRuntimeDir() (string, error) {
|
|
||||||
runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
|
|
||||||
uid := fmt.Sprintf("%d", rootless.GetRootlessUID())
|
|
||||||
if runtimeDir == "" {
|
|
||||||
tmpDir := filepath.Join("/run", "user", uid)
|
|
||||||
os.MkdirAll(tmpDir, 0700)
|
|
||||||
st, err := os.Stat(tmpDir)
|
|
||||||
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Getuid() && st.Mode().Perm() == 0700 {
|
|
||||||
runtimeDir = tmpDir
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if runtimeDir == "" {
|
|
||||||
tmpDir := filepath.Join(os.TempDir(), "user", uid)
|
|
||||||
os.MkdirAll(tmpDir, 0700)
|
|
||||||
st, err := os.Stat(tmpDir)
|
|
||||||
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Getuid() && st.Mode().Perm() == 0700 {
|
|
||||||
runtimeDir = tmpDir
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if runtimeDir == "" {
|
|
||||||
home := os.Getenv("HOME")
|
|
||||||
if home == "" {
|
|
||||||
return "", fmt.Errorf("neither XDG_RUNTIME_DIR nor HOME was set non-empty")
|
|
||||||
}
|
|
||||||
resolvedHome, err := filepath.EvalSymlinks(home)
|
|
||||||
if err != nil {
|
|
||||||
return "", errors.Wrapf(err, "cannot resolve %s", home)
|
|
||||||
}
|
|
||||||
runtimeDir = filepath.Join(resolvedHome, "rundir")
|
|
||||||
}
|
|
||||||
return runtimeDir, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getDefaultTmpDir() (string, error) {
|
func getDefaultTmpDir() (string, error) {
|
||||||
if !rootless.IsRootless() {
|
if !rootless.IsRootless() {
|
||||||
return "/var/run/libpod", nil
|
return "/var/run/libpod", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
rootlessRuntimeDir, err := GetRootlessRuntimeDir()
|
rootlessRuntimeDir, err := util.GetRootlessRuntimeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -269,7 +234,7 @@ func SetXdgRuntimeDir(val string) error {
|
|||||||
}
|
}
|
||||||
if val == "" {
|
if val == "" {
|
||||||
var err error
|
var err error
|
||||||
val, err = GetRootlessRuntimeDir()
|
val, err = util.GetRootlessRuntimeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -309,7 +274,7 @@ func NewRuntime(options ...RuntimeOption) (runtime *Runtime, err error) {
|
|||||||
foundConfig = false
|
foundConfig = false
|
||||||
}
|
}
|
||||||
|
|
||||||
runtimeDir, err := GetRootlessRuntimeDir()
|
runtimeDir, err := util.GetRootlessRuntimeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,13 @@ package util
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/containers/image/types"
|
"github.com/containers/image/types"
|
||||||
|
"github.com/containers/libpod/pkg/rootless"
|
||||||
"github.com/containers/storage"
|
"github.com/containers/storage"
|
||||||
"github.com/containers/storage/pkg/idtools"
|
"github.com/containers/storage/pkg/idtools"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
@ -210,3 +213,82 @@ func ParseIDMapping(UIDMapSlice, GIDMapSlice []string, subUIDMap, subGIDMap stri
|
|||||||
}
|
}
|
||||||
return &options, nil
|
return &options, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetRootlessRuntimeDir returns the runtime directory when running as non root
|
||||||
|
func GetRootlessRuntimeDir() (string, error) {
|
||||||
|
runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
|
||||||
|
uid := fmt.Sprintf("%d", rootless.GetRootlessUID())
|
||||||
|
if runtimeDir == "" {
|
||||||
|
tmpDir := filepath.Join("/run", "user", uid)
|
||||||
|
os.MkdirAll(tmpDir, 0700)
|
||||||
|
st, err := os.Stat(tmpDir)
|
||||||
|
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Getuid() && st.Mode().Perm() == 0700 {
|
||||||
|
runtimeDir = tmpDir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if runtimeDir == "" {
|
||||||
|
tmpDir := filepath.Join(os.TempDir(), "user", uid)
|
||||||
|
os.MkdirAll(tmpDir, 0700)
|
||||||
|
st, err := os.Stat(tmpDir)
|
||||||
|
if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Getuid() && st.Mode().Perm() == 0700 {
|
||||||
|
runtimeDir = tmpDir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if runtimeDir == "" {
|
||||||
|
home := os.Getenv("HOME")
|
||||||
|
if home == "" {
|
||||||
|
return "", fmt.Errorf("neither XDG_RUNTIME_DIR nor HOME was set non-empty")
|
||||||
|
}
|
||||||
|
resolvedHome, err := filepath.EvalSymlinks(home)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrapf(err, "cannot resolve %s", home)
|
||||||
|
}
|
||||||
|
runtimeDir = filepath.Join(resolvedHome, "rundir")
|
||||||
|
}
|
||||||
|
return runtimeDir, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRootlessStorageOpts() (storage.StoreOptions, error) {
|
||||||
|
var opts storage.StoreOptions
|
||||||
|
|
||||||
|
rootlessRuntime, err := GetRootlessRuntimeDir()
|
||||||
|
if err != nil {
|
||||||
|
return opts, err
|
||||||
|
}
|
||||||
|
opts.RunRoot = filepath.Join(rootlessRuntime, "run")
|
||||||
|
|
||||||
|
dataDir := os.Getenv("XDG_DATA_HOME")
|
||||||
|
if dataDir == "" {
|
||||||
|
home := os.Getenv("HOME")
|
||||||
|
if home == "" {
|
||||||
|
return opts, fmt.Errorf("neither XDG_DATA_HOME nor HOME was set non-empty")
|
||||||
|
}
|
||||||
|
// runc doesn't like symlinks in the rootfs path, and at least
|
||||||
|
// on CoreOS /home is a symlink to /var/home, so resolve any symlink.
|
||||||
|
resolvedHome, err := filepath.EvalSymlinks(home)
|
||||||
|
if err != nil {
|
||||||
|
return opts, errors.Wrapf(err, "cannot resolve %s", home)
|
||||||
|
}
|
||||||
|
dataDir = filepath.Join(resolvedHome, ".local", "share")
|
||||||
|
}
|
||||||
|
opts.GraphRoot = filepath.Join(dataDir, "containers", "storage")
|
||||||
|
opts.GraphDriverName = "vfs"
|
||||||
|
return opts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDefaultStoreOptions() (storage.StoreOptions, error) {
|
||||||
|
storageOpts := storage.DefaultStoreOptions
|
||||||
|
if rootless.IsRootless() {
|
||||||
|
var err error
|
||||||
|
storageOpts, err = GetRootlessStorageOpts()
|
||||||
|
if err != nil {
|
||||||
|
return storageOpts, err
|
||||||
|
}
|
||||||
|
|
||||||
|
storageConf := filepath.Join(os.Getenv("HOME"), ".config/containers/storage.conf")
|
||||||
|
if _, err := os.Stat(storageConf); err == nil {
|
||||||
|
storage.ReloadConfigurationFile(storageConf, &storageOpts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return storageOpts, nil
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user