Skip to content
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
13 changes: 13 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
0.4
===

### Enhancements

* Added the '--env' option to 'run' to pass environment variables to the
Toolbx container
* Added the '--use-fallback-shell' option to 'run' to fall back to /bin/bash
and /bin/sh if the specified command is not found
* Added the '--workdir' option to 'run' to override the working directory used
inside the Toolbx container


0.3
===

Expand Down
19 changes: 19 additions & 0 deletions doc/toolbox-run.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ toolbox\-run - Run a command in an existing Toolbx container
## SYNOPSIS
**toolbox run** [*--container NAME* | *-c NAME*]
[*--distro DISTRO* | *-d DISTRO*]
[*--env KEY=VALUE*]
[*--preserve-fds N*]
[*--release RELEASE* | *-r RELEASE*]
[*--use-fallback-shell*]
[*--workdir DIR*]
[*COMMAND*]

## DESCRIPTION
Expand Down Expand Up @@ -38,6 +41,12 @@ Run command inside a Toolbx container for a different operating system DISTRO
than the host. Has to be coupled with `--release` unless the selected DISTRO
matches the host system.

**--env** KEY=VALUE

Set an environment variable in the form of KEY=VALUE for use inside the Toolbx
container. This option can be specified multiple times to set multiple
environment variables.

**--preserve-fds** N

Pass down to command N additional file descriptors (in addition to 0, 1, 2).
Expand All @@ -48,6 +57,16 @@ The total number of file descriptors will be 3+N.
Run command inside a Toolbx container for a different operating system RELEASE
than the host.

**--use-fallback-shell**

Fall back to /bin/bash and /bin/sh if the specified command is not found inside
the Toolbx container.

**--workdir** DIR

Override the working directory used inside the Toolbx container. The value must
be an absolute path.

## EXIT STATUS

The exit code gives information about why the command within the container
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/enter.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func enter(cmd *cobra.Command, args []string) error {

command := []string{userShell, "-l"}

if err := runCommand(container, defaultContainer, image, release, 0, command, true, true, false); err != nil {
if err := runCommand(container, defaultContainer, image, release, 0, command, nil, true, true, false); err != nil {
return err
}

Expand Down
48 changes: 41 additions & 7 deletions src/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,16 @@ type entryPointError struct {

var (
runFlags struct {
container string
distro string
preserveFDs uint
release string
container string
distro string
env []string
preserveFDs uint
release string
useFallbackShell bool
workDir string
}

runFallbackCommands = [][]string{{"/bin/bash", "-l"}}
runFallbackCommands = [][]string{{"/bin/bash", "-l"}, {"/bin/sh", "-l"}}
runFallbackWorkDirs = []string{"" /* $HOME */}
)

Expand Down Expand Up @@ -96,6 +99,21 @@ func init() {
"",
"Run command inside a Toolbx container for a different operating system release than the host")

flags.StringArrayVar(&runFlags.env,
"env",
nil,
"Set environment variables in the form of KEY=VALUE for use inside the Toolbx container")

flags.BoolVar(&runFlags.useFallbackShell,
"use-fallback-shell",
false,
"Fall back to /bin/bash and /bin/sh if the command is not found")

flags.StringVar(&runFlags.workDir,
"workdir",
"",
"Override the working directory used inside the Toolbx container")

runCmd.SetHelpFunc(runHelp)

if err := runCmd.RegisterFlagCompletionFunc("container", completionContainerNames); err != nil {
Expand Down Expand Up @@ -141,6 +159,20 @@ func run(cmd *cobra.Command, args []string) error {

command := args

if runFlags.workDir != "" {
if !filepath.IsAbs(runFlags.workDir) {
var builder strings.Builder
fmt.Fprintf(&builder, "invalid argument for '--workdir'\n")
fmt.Fprintf(&builder, "The working directory must be an absolute path.\n")
fmt.Fprintf(&builder, "Run '%s --help' for usage.", executableBase)

errMsg := builder.String()
return errors.New(errMsg)
}

workingDirectory = runFlags.workDir
}

container, image, release, err := resolveContainerAndImageNames(runFlags.container,
"--container",
runFlags.distro,
Expand All @@ -157,8 +189,9 @@ func run(cmd *cobra.Command, args []string) error {
release,
runFlags.preserveFDs,
command,
runFlags.env,
false,
false,
runFlags.useFallbackShell,
true); err != nil {
return err
}
Expand All @@ -170,7 +203,7 @@ func runCommand(container string,
defaultContainer bool,
image, release string,
preserveFDs uint,
command []string,
command, extraEnviron []string,
emitEscapeSequence, fallbackToBash, pedantic bool) error {

if !pedantic {
Expand Down Expand Up @@ -347,6 +380,7 @@ func runCommand(container string,
logrus.Debugf("Container %s is initialized", container)

environ := append(cdiEnviron, p11KitServerEnviron...)
environ = append(environ, extraEnviron...)
if err := runCommandWithFallbacks(container,
preserveFDs,
command,
Expand Down
52 changes: 52 additions & 0 deletions test/system/104-run.bats
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,58 @@ teardown() {
assert [ ${#stderr_lines[@]} -eq 2 ]
}

@test "run: Ensure that --env passes an environment variable to the container" {
create_default_container

run --keep-empty-lines "$TOOLBX" run --env FOO=bar printenv FOO

assert_success
assert_line --index 0 "bar"
assert [ ${#lines[@]} -eq 1 ]
}

@test "run: Ensure that multiple --env flags work" {
create_default_container

run --keep-empty-lines "$TOOLBX" run --env FOO=bar --env BAZ=qux /bin/sh -c 'printenv FOO && printenv BAZ'

assert_success
assert_line --index 0 "bar"
assert_line --index 1 "qux"
assert [ ${#lines[@]} -eq 2 ]
}

@test "run: Ensure that --workdir sets the working directory" {
create_default_container

run --keep-empty-lines "$TOOLBX" run --workdir /tmp pwd

assert_success
assert_line --index 0 "/tmp"
assert [ ${#lines[@]} -eq 1 ]
}

@test "run: Try --workdir with a relative path" {
run --keep-empty-lines --separate-stderr "$TOOLBX" run --workdir relative/path true

assert_failure
assert [ ${#lines[@]} -eq 0 ]
lines=("${stderr_lines[@]}")
assert_line --index 0 "Error: invalid argument for '--workdir'"
assert_line --index 1 "The working directory must be an absolute path."
assert_line --index 2 "Run 'toolbox --help' for usage."
assert [ ${#stderr_lines[@]} -eq 3 ]
}

@test "run: Ensure that --use-fallback-shell works with an existing command" {
create_default_container

run --keep-empty-lines "$TOOLBX" run --use-fallback-shell true

assert_success
assert_output ""
}

@test "run: Try an old unsupported container" {
local default_image
default_image="$(get_default_image)"
Expand Down