Skip to content

cmd/create, cmd/initContainer: Mount the devpts file system at runtime #1257

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/toolbox-init-container.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -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*
Expand Down Expand Up @@ -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
Expand Down
26 changes: 8 additions & 18 deletions src/cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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",
Expand All @@ -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",
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
54 changes: 54 additions & 0 deletions src/cmd/initContainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var (
mediaLink bool
mntLink bool
monitorHost bool
mountDevPts bool
shell string
uid int
user string
Expand Down Expand Up @@ -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",
"",
Expand Down Expand Up @@ -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")

Expand Down Expand Up @@ -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.
//
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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()
}

Expand Down
4 changes: 2 additions & 2 deletions src/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -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{
Expand Down