Skip to content
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

Allow toolbox containers to be created with a custom hostname #1134

Closed
Closed
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
6 changes: 6 additions & 0 deletions doc/toolbox-create.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ toolbox\-create - Create a new toolbox container
## SYNOPSIS
**toolbox create** [*--authfile AUTHFILE*]
[*--distro DISTRO* | *-d DISTRO*]
[*--hostname HOSTNAME*]
[*--image NAME* | *-i NAME*]
[*--release RELEASE* | *-r RELEASE*]
[*CONTAINER*]
Expand Down Expand Up @@ -95,6 +96,11 @@ Create a toolbox container for a different operating system DISTRO than the
host. Cannot be used with `--image`. Has to be coupled with `--release` unless
the selected DISTRO matches the host.

**--hostname** HOSTNAME

Initializes the netowork hostname of the toolbox container to the specified value.
If not specified, this will default to **toolbox**.

**--image** NAME, **-i** NAME

Change the NAME of the image used to create the toolbox container. This is
Expand Down
27 changes: 24 additions & 3 deletions src/cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"time"

Expand All @@ -45,6 +46,7 @@ var (
authFile string
container string
distro string
hostname string
image string
release string
}
Expand Down Expand Up @@ -85,6 +87,12 @@ func init() {
"",
"Create a toolbox container for a different operating system distribution than the host")

flags.StringVarP(&createFlags.hostname,
"hostname",
"",
"",
"Set the container's hostname (defaults to 'toolbox')")

flags.StringVarP(&createFlags.image,
"image",
"i",
Expand Down Expand Up @@ -113,6 +121,10 @@ func init() {
}

func create(cmd *cobra.Command, args []string) error {
// This regex filters out strings which are not valid hostnames, according to RFC-1123.
// Source: https://stackoverflow.com/a/106223
var hostnameRegexp = regexp.MustCompile(`^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])$`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need to have this regular expression directly in the code? Can't we use some Go package for it?


if utils.IsInsideContainer() {
if !utils.IsInsideToolboxContainer() {
return errors.New("this is not a toolbox container")
Expand Down Expand Up @@ -155,8 +167,13 @@ func create(cmd *cobra.Command, args []string) error {
}
}

if cmd.Flag("hostname").Changed && !hostnameRegexp.MatchString(cmd.Flag("hostname").Value.String()) {
return errors.New("invalid hostname")
}

var container string
var containerArg string
var hostname = cmd.Flag("hostname").Value.String()

if len(args) != 0 {
container = args[0]
Expand All @@ -176,14 +193,14 @@ func create(cmd *cobra.Command, args []string) error {
return err
}

if err := createContainer(container, image, release, true); err != nil {
if err := createContainer(container, image, release, hostname, true); err != nil {
return err
}

return nil
}

func createContainer(container, image, release string, showCommandToEnter bool) error {
func createContainer(container, image, release string, hostname string, showCommandToEnter bool) error {
if container == "" {
panic("container not specified")
}
Expand All @@ -196,6 +213,10 @@ func createContainer(container, image, release string, showCommandToEnter bool)
panic("release not specified")
}

if hostname == "" {
hostname = "toolbox"
}

enterCommand := getEnterCommand(container)

logrus.Debugf("Checking if container %s already exists", container)
Expand Down Expand Up @@ -410,7 +431,7 @@ func createContainer(container, image, release string, showCommandToEnter bool)
createArgs = append(createArgs, xdgRuntimeDirEnv...)

createArgs = append(createArgs, []string{
"--hostname", "toolbox",
"--hostname", hostname,
"--ipc", "host",
"--label", "com.github.containers.toolbox=true",
}...)
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func runCommand(container string,
return nil
}

if err := createContainer(container, image, release, false); err != nil {
if err := createContainer(container, image, release, "", false); err != nil {
return err
}
} else if containersCount == 1 && defaultContainer {
Expand Down
19 changes: 19 additions & 0 deletions test/system/101-create.bats
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,25 @@ teardown() {
assert [ ${#lines[@]} -eq 3 ]
}

@test "create: Create a container with a custom hostname ('test.host-name.local')" {
run $TOOLBOX -y create --hostname test.host-name.local

assert_success
assert_output --partial "Enter with: toolbox enter"

run $TOOLBOX -y run -- hostname

assert_success
assert_output --partial "test.host-name.local"
}

@test "create: Create a container with an invalid hostname ('test.host-name.local.')" {
run $TOOLBOX -y create --hostname test.host-name.local.

assert_failure
assert_line --index 0 "Error: invalid hostname"
}

@test "create: Try to create a container based on non-existent image" {
run $TOOLBOX -y create -i foo.org/bar

Expand Down