Don't rely on XDG_RUNTIME_DIR when running as root
This is one more step towards enabling toolbox(1) to be run as root. When invoked as 'sudo toolbox' there's no XDG_RUNTIME_DIR available for the root user. Neither the environment variable nor the directory are present. XDG_RUNTIME_DIR is used for two reasons. First, to place the 'lock' file to synchronize Podman migrations and the initialization stamp file to synchronize the container's entry point with the user-facing 'enter' command running on the host. Second, it's used to propagate things like the user D-Bus, Pipewire and Wayland sockets. The first use-case is important for toolbox(1) itself to work. When running as root, XDG_RUNTIME_DIR is replaced with /run/toolbox for this purpose. The second use-case is mostly ignored because sudo(8) doesn't create a full-fledged user session. Graphical applications can still work by connecting to a X11 server over the local abstract socket or the file system socket in /tmp/.X11-unix. https://github.com/containers/toolbox/issues/267
This commit is contained in:
parent
de2101464c
commit
25b647d635
|
|
@ -191,9 +191,23 @@ func createContainer(container, image, release string, showCommandToEnter bool)
|
|||
toolboxPathEnvArg := "TOOLBOX_PATH=" + toolboxPath
|
||||
toolboxPathMountArg := toolboxPath + ":/usr/bin/toolbox:ro"
|
||||
|
||||
xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR")
|
||||
xdgRuntimeDirEnvArg := "XDG_RUNTIME_DIR=" + xdgRuntimeDir
|
||||
xdgRuntimeDirMountArg := xdgRuntimeDir + ":" + xdgRuntimeDir
|
||||
var runtimeDirectory string
|
||||
var xdgRuntimeDirEnv []string
|
||||
|
||||
if currentUser.Uid == "0" {
|
||||
runtimeDirectory, err = utils.GetRuntimeDirectory(currentUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR")
|
||||
xdgRuntimeDirEnvArg := "XDG_RUNTIME_DIR=" + xdgRuntimeDir
|
||||
xdgRuntimeDirEnv = []string{"--env", xdgRuntimeDirEnvArg}
|
||||
|
||||
runtimeDirectory = xdgRuntimeDir
|
||||
}
|
||||
|
||||
runtimeDirectoryMountArg := runtimeDirectory + ":" + runtimeDirectory
|
||||
|
||||
logrus.Debug("Checking if 'podman create' supports '--mount type=devpts'")
|
||||
|
||||
|
|
@ -337,12 +351,16 @@ func createContainer(container, image, release string, showCommandToEnter bool)
|
|||
"create",
|
||||
"--dns", "none",
|
||||
"--env", toolboxPathEnvArg,
|
||||
"--env", xdgRuntimeDirEnvArg,
|
||||
}
|
||||
|
||||
createArgs = append(createArgs, xdgRuntimeDirEnv...)
|
||||
|
||||
createArgs = append(createArgs, []string{
|
||||
"--hostname", "toolbox",
|
||||
"--ipc", "host",
|
||||
"--label", "com.github.containers.toolbox=true",
|
||||
"--label", "com.github.debarshiray.toolbox=true",
|
||||
}
|
||||
}...)
|
||||
|
||||
createArgs = append(createArgs, devPtsMount...)
|
||||
|
||||
|
|
@ -370,7 +388,7 @@ func createContainer(container, image, release string, showCommandToEnter bool)
|
|||
"--volume", homeDirMountArg,
|
||||
"--volume", toolboxPathMountArg,
|
||||
"--volume", usrMountArg,
|
||||
"--volume", xdgRuntimeDirMountArg,
|
||||
"--volume", runtimeDirectoryMountArg,
|
||||
}...)
|
||||
|
||||
createArgs = append(createArgs, kcmSocketMount...)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -127,15 +128,7 @@ func initContainer(cmd *cobra.Command, args []string) error {
|
|||
return errors.New(errMsg)
|
||||
}
|
||||
|
||||
runtimeDirectory := os.Getenv("XDG_RUNTIME_DIR")
|
||||
if runtimeDirectory == "" {
|
||||
logrus.Debug("XDG_RUNTIME_DIR is unset")
|
||||
|
||||
runtimeDirectory = fmt.Sprintf("/run/user/%d", initContainerFlags.uid)
|
||||
os.Setenv("XDG_RUNTIME_DIR", runtimeDirectory)
|
||||
|
||||
logrus.Debugf("XDG_RUNTIME_DIR set to %s", runtimeDirectory)
|
||||
}
|
||||
utils.EnsureXdgRuntimeDirIsSet(initContainerFlags.uid)
|
||||
|
||||
logrus.Debug("Creating /run/.toolboxenv")
|
||||
|
||||
|
|
@ -285,16 +278,15 @@ func initContainer(cmd *cobra.Command, args []string) error {
|
|||
|
||||
logrus.Debug("Finished initializing container")
|
||||
|
||||
toolboxRuntimeDirectory := runtimeDirectory + "/toolbox"
|
||||
logrus.Debugf("Creating runtime directory %s", toolboxRuntimeDirectory)
|
||||
|
||||
if err := os.MkdirAll(toolboxRuntimeDirectory, 0700); err != nil {
|
||||
return fmt.Errorf("failed to create runtime directory %s", toolboxRuntimeDirectory)
|
||||
uidString := strconv.Itoa(initContainerFlags.uid)
|
||||
targetUser, err := user.LookupId(uidString)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to lookup user ID %s: %w", uidString, err)
|
||||
}
|
||||
|
||||
if err := os.Chown(toolboxRuntimeDirectory, initContainerFlags.uid, initContainerFlags.uid); err != nil {
|
||||
return fmt.Errorf("failed to change ownership of the runtime directory %s",
|
||||
toolboxRuntimeDirectory)
|
||||
toolboxRuntimeDirectory, err := utils.GetRuntimeDirectory(targetUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pid := os.Getpid()
|
||||
|
|
|
|||
|
|
@ -226,10 +226,9 @@ func migrate() error {
|
|||
return fmt.Errorf("failed to create configuration directory")
|
||||
}
|
||||
|
||||
runtimeDirectory := os.Getenv("XDG_RUNTIME_DIR")
|
||||
toolboxRuntimeDirectory := runtimeDirectory + "/toolbox"
|
||||
if err := os.MkdirAll(toolboxRuntimeDirectory, 0700); err != nil {
|
||||
return fmt.Errorf("failed to create runtime directory %s", toolboxRuntimeDirectory)
|
||||
toolboxRuntimeDirectory, err := utils.GetRuntimeDirectory(currentUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
migrateLock := toolboxRuntimeDirectory + "/migrate.lock"
|
||||
|
|
|
|||
|
|
@ -238,8 +238,11 @@ func runCommand(container string,
|
|||
|
||||
logrus.Debugf("Waiting for container %s to finish initializing", container)
|
||||
|
||||
runtimeDirectory := os.Getenv("XDG_RUNTIME_DIR")
|
||||
toolboxRuntimeDirectory := runtimeDirectory + "/toolbox"
|
||||
toolboxRuntimeDirectory, err := utils.GetRuntimeDirectory(currentUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
initializedStamp := fmt.Sprintf("%s/container-initialized-%d", toolboxRuntimeDirectory, entryPointPID)
|
||||
|
||||
logrus.Debugf("Checking if initialization stamp %s exists", initializedStamp)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
|
|
@ -174,6 +175,17 @@ func CreateErrorInvalidRelease(executableBase string) error {
|
|||
return errors.New(errMsg)
|
||||
}
|
||||
|
||||
func EnsureXdgRuntimeDirIsSet(uid int) {
|
||||
if xdgRuntimeDir, ok := os.LookupEnv("XDG_RUNTIME_DIR"); !ok {
|
||||
logrus.Debug("XDG_RUNTIME_DIR is unset")
|
||||
|
||||
xdgRuntimeDir = fmt.Sprintf("/run/user/%d", uid)
|
||||
os.Setenv("XDG_RUNTIME_DIR", xdgRuntimeDir)
|
||||
|
||||
logrus.Debugf("XDG_RUNTIME_DIR set to %s", xdgRuntimeDir)
|
||||
}
|
||||
}
|
||||
|
||||
func ForwardToHost() (int, error) {
|
||||
envOptions := GetEnvOptionsForPreservedVariables()
|
||||
toolboxPath := os.Getenv("TOOLBOX_PATH")
|
||||
|
|
@ -336,6 +348,40 @@ func GetMountOptions(target string) (string, error) {
|
|||
return mountOptions, nil
|
||||
}
|
||||
|
||||
func GetRuntimeDirectory(targetUser *user.User) (string, error) {
|
||||
uid, err := strconv.Atoi(targetUser.Uid)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to convert user ID to integer: %w", err)
|
||||
}
|
||||
|
||||
var runtimeDirectory string
|
||||
|
||||
if uid == 0 {
|
||||
runtimeDirectory = "/run"
|
||||
} else {
|
||||
runtimeDirectory = os.Getenv("XDG_RUNTIME_DIR")
|
||||
}
|
||||
|
||||
toolboxRuntimeDirectory := path.Join(runtimeDirectory, "toolbox")
|
||||
logrus.Debugf("Creating runtime directory %s", toolboxRuntimeDirectory)
|
||||
|
||||
if err := os.MkdirAll(toolboxRuntimeDirectory, 0700); err != nil {
|
||||
wrapped_err := fmt.Errorf("failed to create runtime directory %s: %w",
|
||||
toolboxRuntimeDirectory,
|
||||
err)
|
||||
return "", wrapped_err
|
||||
}
|
||||
|
||||
if err := os.Chown(toolboxRuntimeDirectory, uid, uid); err != nil {
|
||||
wrapped_err := fmt.Errorf("failed to change ownership of the runtime directory %s: %w",
|
||||
toolboxRuntimeDirectory,
|
||||
err)
|
||||
return "", wrapped_err
|
||||
}
|
||||
|
||||
return toolboxRuntimeDirectory, nil
|
||||
}
|
||||
|
||||
// HumanDuration accepts a Unix time value and converts it into a human readable
|
||||
// string.
|
||||
//
|
||||
|
|
|
|||
Loading…
Reference in New Issue