Support leaking additional file descriptors to the container

This mirrors the --preserve-fds option of Podman.

Converting an unsigned 'uint', which is what Podman uses for its
--preserve-fds option, to a string is surprisingly annoying.
strconv.Itoa [1] takes a signed 'int', which would require a cast, and
there's no unsigned counterpart.  There's strconv.FormatUint [2] which
takes an unsigned 'uint64', which is better, but would still require a
cast.

So, fmt.Sprint [3] it is, if the cast is to be avoided.  It's more
expensive than the other two functions, but there's no need to worry
unless it's proven to be a performance bottle neck.

Some changes by Debarshi Ray.

[1] https://pkg.go.dev/strconv#Itoa

[2] https://pkg.go.dev/strconv#FormatUint

[3] https://pkg.go.dev/fmt#Sprint

https://github.com/containers/toolbox/issues/1066

Signed-off-by: Allison Karlitskaya <allison.karlitskaya@redhat.com>
This commit is contained in:
Allison Karlitskaya 2022-06-16 23:35:15 +02:00 committed by Debarshi Ray
parent f779c798f0
commit d4213c2358
4 changed files with 32 additions and 6 deletions

View file

@ -6,6 +6,7 @@ toolbox\-run - Run a command in an existing toolbox container
## SYNOPSIS
**toolbox run** [*--container NAME* | *-c NAME*]
[*--distro DISTRO* | *-d DISTRO*]
[*--preserve-fds N*]
[*--release RELEASE* | *-r RELEASE*]
[*COMMAND*]
@ -37,6 +38,11 @@ Run command inside a toolbox container for a different operating system DISTRO
than the host. Has to be coupled with `--release` unless the selected DISTRO
matches the host system.
**--preserve-fds** N
Pass down to command N additional file descriptors (in addition to 0, 1,
2). The total number of file descriptors will be 3+N.
**--release** RELEASE, **-r** RELEASE
Run command inside a toolbox container for a different operating system

View file

@ -144,6 +144,7 @@ func enter(cmd *cobra.Command, args []string) error {
defaultContainer,
image,
release,
0,
command,
emitEscapeSequence,
true,

View file

@ -92,6 +92,7 @@ func rootRunImpl(cmd *cobra.Command, args []string) error {
true,
image,
release,
0,
command,
emitEscapeSequence,
true,

View file

@ -34,9 +34,10 @@ import (
var (
runFlags struct {
container string
distro string
release string
container string
distro string
preserveFDs uint
release string
}
runFallbackCommands = [][]string{{"/bin/bash", "-l"}}
@ -66,6 +67,11 @@ func init() {
"",
"Run command inside a toolbox container for a different operating system distribution than the host")
flags.UintVar(&runFlags.preserveFDs,
"preserve-fds",
0,
"Pass down to command N additional file descriptors (in addition to 0, 1, 2)")
flags.StringVarP(&runFlags.release,
"release",
"r",
@ -134,6 +140,7 @@ func run(cmd *cobra.Command, args []string) error {
defaultContainer,
image,
release,
runFlags.preserveFDs,
command,
false,
false,
@ -156,6 +163,7 @@ func run(cmd *cobra.Command, args []string) error {
func runCommand(container string,
defaultContainer bool,
image, release string,
preserveFDs uint,
command []string,
emitEscapeSequence, fallbackToBash, pedantic bool) error {
if !pedantic {
@ -277,14 +285,21 @@ func runCommand(container string,
logrus.Debugf("Container %s is initialized", container)
if err := runCommandWithFallbacks(container, command, emitEscapeSequence, fallbackToBash); err != nil {
if err := runCommandWithFallbacks(container,
preserveFDs,
command,
emitEscapeSequence,
fallbackToBash); err != nil {
return err
}
return nil
}
func runCommandWithFallbacks(container string, command []string, emitEscapeSequence, fallbackToBash bool) error {
func runCommandWithFallbacks(container string,
preserveFDs uint,
command []string,
emitEscapeSequence, fallbackToBash bool) error {
logrus.Debug("Checking if 'podman exec' supports disabling the detach keys")
var detachKeysSupported bool
@ -295,6 +310,7 @@ func runCommandWithFallbacks(container string, command []string, emitEscapeSeque
}
envOptions := utils.GetEnvOptionsForPreservedVariables()
preserveFDsString := fmt.Sprint(preserveFDs)
var stderr io.Writer
var ttyNeeded bool
@ -320,6 +336,7 @@ func runCommandWithFallbacks(container string, command []string, emitEscapeSeque
for {
execArgs := constructExecArgs(container,
preserveFDsString,
command,
detachKeysSupported,
envOptions,
@ -459,7 +476,7 @@ func constructCapShArgs(command []string, useLoginShell bool) []string {
return capShArgs
}
func constructExecArgs(container string,
func constructExecArgs(container, preserveFDs string,
command []string,
detachKeysSupported bool,
envOptions []string,
@ -483,6 +500,7 @@ func constructExecArgs(container string,
execArgs = append(execArgs, []string{
"--interactive",
"--preserve-fds", preserveFDs,
}...)
if ttyNeeded {