From ed7398f2f7fc75837a7e4450c578722aac126c42 Mon Sep 17 00:00:00 2001 From: William Brawner Date: Fri, 10 Nov 2023 22:23:16 -0700 Subject: [PATCH] Add support for creating toolboxes from Containerfile Signed-off-by: William Brawner --- doc/toolbox-create.1.md | 13 +++++++++ src/cmd/create.go | 65 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/doc/toolbox-create.1.md b/doc/toolbox-create.1.md index 8b7db9e..0e94b20 100644 --- a/doc/toolbox-create.1.md +++ b/doc/toolbox-create.1.md @@ -6,6 +6,7 @@ toolbox\-create - Create a new toolbox container ## SYNOPSIS **toolbox create** [*--authfile FILE*] [*--distro DISTRO* | *-d DISTRO*] + [*--file CONTAINERFILE* | *-f CONTAINERFILE*] [*--image NAME* | *-i NAME*] [*--release RELEASE* | *-r RELEASE*] [*CONTAINER*] @@ -95,6 +96,12 @@ 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. +**--file** CONTAINERFILE, **-f** CONTAINERFILE + +Create a toolbox container from a Containerfile. If used with `--image`, then +the built image will be tagged with that value, otherwise the current directory +name will be used. + **--image** NAME, **-i** NAME Change the NAME of the image used to create the toolbox container. This is @@ -136,6 +143,12 @@ $ toolbox create --image bar foo $ toolbox create --authfile ~/auth.json --image registry.example.com/bar ``` +### Create a custom toolbox container from a Containerfile + +``` +$ toolbox create --file Containerfile +``` + ## SEE ALSO `toolbox(1)`, `toolbox-init-container(1)`, `podman(1)`, `podman-create(1)`, `podman-login(1)`, `podman-pull(1)`, `containers-auth.json(5)` diff --git a/src/cmd/create.go b/src/cmd/create.go index c50460a..5a71bb3 100644 --- a/src/cmd/create.go +++ b/src/cmd/create.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "os" + "path" "path/filepath" "strings" "time" @@ -47,6 +48,7 @@ var ( authFile string container string distro string + file string image string release string } @@ -87,6 +89,12 @@ func init() { "", "Create a toolbox container for a different operating system distribution than the host") + flags.StringVarP(&createFlags.file, + "file", + "f", + "", + "Create a toolbox container from the given Containerfile") + flags.StringVarP(&createFlags.image, "image", "i", @@ -168,10 +176,43 @@ func create(cmd *cobra.Command, args []string) error { containerArg = "--container" } + image := createFlags.image + + if cmd.Flag("file").Changed { + if !utils.PathExists(createFlags.file) { + var builder strings.Builder + fmt.Fprintf(&builder, "file %s not found\n", createFlags.authFile) + fmt.Fprintf(&builder, "Run '%s --help' for usage.", executableBase) + + errMsg := builder.String() + return errors.New(errMsg) + } + + var err error + if container == "" { + container, err = dirname() + if err != nil { + return err + } + } + + if image == "" { + image, err = dirname() + if err != nil { + return err + } + } + + err = buildContainerImage(image, createFlags.file) + if err != nil { + return err + } + } + container, image, release, err := resolveContainerAndImageNames(container, containerArg, createFlags.distro, - createFlags.image, + image, createFlags.release) if err != nil { @@ -185,6 +226,20 @@ func create(cmd *cobra.Command, args []string) error { return nil } +func buildContainerImage(image, containerFile string) error { + buildArgs := []string{ + "build", + "--file", + containerFile, + "--tag", + image, + } + if err := shell.Run("podman", nil, nil, nil, buildArgs...); err != nil { + return fmt.Errorf("failed to build image %s", image) + } + return nil +} + func createContainer(container, image, release, authFile string, showCommandToEnter bool) error { if container == "" { panic("container not specified") @@ -781,3 +836,11 @@ func systemdPathBusEscape(path string) string { } return string(n) } + +func dirname() (string, error) { + cwd, err := os.Getwd() + if err != nil { + return "", err + } + return path.Base(cwd), nil +}