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:
parent
f779c798f0
commit
d4213c2358
4 changed files with 32 additions and 6 deletions
|
@ -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
|
||||
|
|
|
@ -144,6 +144,7 @@ func enter(cmd *cobra.Command, args []string) error {
|
|||
defaultContainer,
|
||||
image,
|
||||
release,
|
||||
0,
|
||||
command,
|
||||
emitEscapeSequence,
|
||||
true,
|
||||
|
|
|
@ -92,6 +92,7 @@ func rootRunImpl(cmd *cobra.Command, args []string) error {
|
|||
true,
|
||||
image,
|
||||
release,
|
||||
0,
|
||||
command,
|
||||
emitEscapeSequence,
|
||||
true,
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue