diff --git a/doc/toolbox-init-container.1.md b/doc/toolbox-init-container.1.md index 63d5b54a3..89447cfdb 100644 --- a/doc/toolbox-init-container.1.md +++ b/doc/toolbox-init-container.1.md @@ -9,6 +9,7 @@ toolbox\-init\-container - Initialize a running container *--home-link* *--media-link* *--mnt-link* + *--mount-devpts* *--shell SHELL* *--uid UID* *--user USER* @@ -82,6 +83,10 @@ synchronized with their counterparts on the host, and various subsets of the host's file system hierarchy are always bind mounted to their corresponding locations inside the toolbox container. +**--mount-devpts** + +Mount a `devpts` file system at `/dev/pts`. + **--shell** SHELL Create a user inside the toolbox container whose login shell is SHELL. This diff --git a/src/cmd/create.go b/src/cmd/create.go index 2c229941a..71567c48a 100644 --- a/src/cmd/create.go +++ b/src/cmd/create.go @@ -245,15 +245,6 @@ func createContainer(container, image, release, authFile string, showCommandToEn runtimeDirectoryMountArg := runtimeDirectory + ":" + runtimeDirectory - logrus.Debug("Checking if 'podman create' supports '--mount type=devpts'") - - var devPtsMount []string - - if podman.CheckVersion("2.1.0") { - logrus.Debug("'podman create' supports '--mount type=devpts'") - devPtsMount = []string{"--mount", "type=devpts,destination=/dev/pts"} - } - var usernsArg string if currentUser.Uid == "0" { usernsArg = "host" @@ -345,7 +336,7 @@ func createContainer(container, image, release, authFile string, showCommandToEn runMediaMount = []string{"--volume", "/run/media:/run/media:rslave"} } - logrus.Debug("Looking for toolbox.sh") + logrus.Debug("Looking up toolbox.sh") var toolboxShMount []string @@ -390,6 +381,10 @@ func createContainer(container, image, release, authFile string, showCommandToEn entryPoint = append(entryPoint, mediaLink...) entryPoint = append(entryPoint, mntLink...) + entryPoint = append(entryPoint, []string{ + "--mount-devpts", + }...) + createArgs := []string{ "--log-level", logLevelString, "create", @@ -404,11 +399,6 @@ func createContainer(container, image, release, authFile string, showCommandToEn "--hostname", "toolbox", "--ipc", "host", "--label", "com.github.containers.toolbox=true", - }...) - - createArgs = append(createArgs, devPtsMount...) - - createArgs = append(createArgs, []string{ "--name", container, "--network", "host", "--no-hosts", @@ -634,7 +624,7 @@ func getServiceSocket(serviceName string, unitName string) (string, error) { func pullImage(image, release, authFile string) (bool, error) { if ok := utils.ImageReferenceCanBeID(image); ok { - logrus.Debugf("Looking for image %s", image) + logrus.Debugf("Looking up image %s", image) if _, err := podman.ImageExists(image); err == nil { return true, nil @@ -645,7 +635,7 @@ func pullImage(image, release, authFile string) (bool, error) { if !hasDomain { imageLocal := "localhost/" + image - logrus.Debugf("Looking for image %s", imageLocal) + logrus.Debugf("Looking up image %s", imageLocal) if _, err := podman.ImageExists(imageLocal); err == nil { return true, nil @@ -664,7 +654,7 @@ func pullImage(image, release, authFile string) (bool, error) { } } - logrus.Debugf("Looking for image %s", imageFull) + logrus.Debugf("Looking up image %s", imageFull) if _, err := podman.ImageExists(imageFull); err == nil { return true, nil diff --git a/src/cmd/initContainer.go b/src/cmd/initContainer.go index 222aa42e1..938377890 100644 --- a/src/cmd/initContainer.go +++ b/src/cmd/initContainer.go @@ -42,6 +42,7 @@ var ( mediaLink bool mntLink bool monitorHost bool + mountDevPts bool shell string uid int user string @@ -114,6 +115,11 @@ func init() { panic(panicMsg) } + flags.BoolVar(&initContainerFlags.mountDevPts, + "mount-devpts", + false, + "Mount a devpts file system at /dev/pts") + flags.StringVar(&initContainerFlags.shell, "shell", "", @@ -256,6 +262,12 @@ func initContainer(cmd *cobra.Command, args []string) error { } } + if initContainerFlags.mountDevPts { + if err := mountDevPts(); err != nil { + return err + } + } + if utils.PathExists("/etc/krb5.conf.d") && !utils.PathExists("/etc/krb5.conf.d/kcm_default_ccache") { logrus.Debug("Setting KCM as the default Kerberos credential cache") @@ -522,6 +534,48 @@ func mountBind(containerPath, source, flags string) error { return nil } +func mountDevPts() error { + optionsArgs := []string{ + "noexec", + "nosuid", + } + + const ttyGroup = "tty" + logrus.Debugf("Looking up group %s", ttyGroup) + + if _, err := user.LookupGroup(ttyGroup); err != nil { + logrus.Debugf("Looking up group %s failed: %s", ttyGroup, err) + } else { + const optionsGIDArg = "gid=" + ttyGroup + optionsArgs = append(optionsArgs, []string{ + optionsGIDArg, + }...) + } + + optionsArgs = append(optionsArgs, []string{ + "mode=620", + "ptmxmode=666", + }...) + + optionsArg := strings.Join(optionsArgs, ",") + + const devPtsFS = "devpts" + const devPtsMountPoint = "/dev/pts" + + mountArgs := []string{ + "--types", devPtsFS, + "--options", optionsArg, + devPtsFS, + devPtsMountPoint, + } + + if err := shell.Run("mount", nil, nil, nil, mountArgs...); err != nil { + return fmt.Errorf("failed to mount a %s file system at %s: %w", devPtsFS, devPtsMountPoint, err) + } + + return nil +} + // redirectPath serves for creating symbolic links for crucial system // configuration files to their counterparts on the host's file system. // diff --git a/src/cmd/root.go b/src/cmd/root.go index aee9fe026..fef4ab371 100644 --- a/src/cmd/root.go +++ b/src/cmd/root.go @@ -389,7 +389,7 @@ func setUpLoggers() error { } func validateSubIDRanges(cmd *cobra.Command, args []string, user *user.User) (bool, error) { - logrus.Debugf("Looking for sub-GID and sub-UID ranges for user %s", user.Username) + logrus.Debugf("Looking up sub-GID and sub-UID ranges for user %s", user.Username) if user.Uid == "0" { logrus.Debugf("Look-up not needed: user %s doesn't need them", user.Username) @@ -407,7 +407,7 @@ func validateSubIDRanges(cmd *cobra.Command, args []string, user *user.User) (bo } if _, err := utils.ValidateSubIDRanges(user); err != nil { - logrus.Debugf("Looking for sub-GID and sub-UID ranges: %s", err) + logrus.Debugf("Looking up sub-GID and sub-UID ranges failed: %s", err) return false, newSubIDError() } diff --git a/src/cmd/run.go b/src/cmd/run.go index cf859afdf..1457b6d3a 100644 --- a/src/cmd/run.go +++ b/src/cmd/run.go @@ -556,7 +556,7 @@ func getEntryPointAndPID(container string) (string, int, error) { } func isCommandPresent(container, command string) (bool, error) { - logrus.Debugf("Looking for command %s in container %s", command, container) + logrus.Debugf("Looking up command %s in container %s", command, container) logLevelString := podman.LogLevel.String() args := []string{ @@ -575,7 +575,7 @@ func isCommandPresent(container, command string) (bool, error) { } func isPathPresent(container, path string) (bool, error) { - logrus.Debugf("Looking for path %s in container %s", path, container) + logrus.Debugf("Looking up path %s in container %s", path, container) logLevelString := podman.LogLevel.String() args := []string{