From ea5620182f6dc1fabc33e1a8d453d070fba0952c Mon Sep 17 00:00:00 2001 From: TomSweeneyRedHat Date: Wed, 20 Dec 2017 17:54:13 -0500 Subject: Initial podman build Signed-off-by: TomSweeneyRedHat Closes: #162 Approved by: rhatdan --- README.md | 1 + cmd/podman/build.go | 128 ++++++++++ cmd/podman/main.go | 1 + completions/bash/podman | 43 ++++ docs/podman-build.1.md | 103 ++++++++ test/build/from-multiple-files/Dockerfile1.alpine | 2 + test/build/from-multiple-files/Dockerfile1.scratch | 2 + test/build/from-multiple-files/Dockerfile2.glob | 2 + test/build/from-multiple-files/Dockerfile2.nofrom | 1 + .../build/from-multiple-files/Dockerfile2.withfrom | 2 + test/build/from-scratch/Dockerfile | 1 + test/build/http-context-subdir/context.tar | Bin 0 -> 10240 bytes test/build/http-context/context.tar | Bin 0 -> 10240 bytes test/build/preserve-volumes/Dockerfile | 22 ++ test/build/volume-perms/Dockerfile | 6 + test/helpers.bash | 97 ++++++++ test/podman_build.bats | 265 +++++++++++++++++++++ test/test_podman_build.sh | 172 +++++++++++++ transfer.md | 2 +- 19 files changed, 849 insertions(+), 1 deletion(-) create mode 100644 cmd/podman/build.go create mode 100644 docs/podman-build.1.md create mode 100644 test/build/from-multiple-files/Dockerfile1.alpine create mode 100644 test/build/from-multiple-files/Dockerfile1.scratch create mode 100644 test/build/from-multiple-files/Dockerfile2.glob create mode 100644 test/build/from-multiple-files/Dockerfile2.nofrom create mode 100644 test/build/from-multiple-files/Dockerfile2.withfrom create mode 100644 test/build/from-scratch/Dockerfile create mode 100644 test/build/http-context-subdir/context.tar create mode 100644 test/build/http-context/context.tar create mode 100644 test/build/preserve-volumes/Dockerfile create mode 100644 test/build/volume-perms/Dockerfile create mode 100644 test/podman_build.bats create mode 100644 test/test_podman_build.sh diff --git a/README.md b/README.md index d7d63d382..b42bd4fe1 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ libpod is currently in active development. | :------------------------------------------------------- | :------------------------------------------------------------------------ | :----| | [podman(1)](/docs/podman.1.md) | Simple management tool for pods and images || | [podman-attach(1)](/docs/podman-attach.1.md) | Attach to a running container || +| [podman-build(1)](/docs/podman-build.1.md) | Build an image using instructions from Dockerfiles || | [podman-commit(1)](/docs/podman-commit.1.md) | Create new image based on the changed container || | [podman-cp(1)](/docs/podman-cp.1.md) | Instead of providing a `podman cp` command, the man page `podman-cp` describes how to use the `podman mount` command to have even more flexibility and functionality|| | [podman-create(1)](/docs/podman-create.1.md) | Create a new container || diff --git a/cmd/podman/build.go b/cmd/podman/build.go new file mode 100644 index 000000000..0defb5e79 --- /dev/null +++ b/cmd/podman/build.go @@ -0,0 +1,128 @@ +package main + +import ( + "os" + "os/exec" + "strconv" + + "github.com/pkg/errors" + "github.com/urfave/cli" +) + +var ( + buildFlags = []cli.Flag{ + cli.StringSliceFlag{ + Name: "build-arg", + Usage: "`argument=value` to supply to the builder", + }, + cli.StringSliceFlag{ + Name: "file, f", + Usage: "`pathname or URL` of a Dockerfile", + }, + cli.StringFlag{ + Name: "format", + Usage: "`format` of the built image's manifest and metadata", + }, + cli.BoolFlag{ + Name: "pull-always", + Usage: "pull the image, even if a version is present", + }, + cli.BoolFlag{ + Name: "quiet, q", + Usage: "refrain from announcing build instructions and image read/write progress", + }, + cli.StringFlag{ + Name: "runtime", + Usage: "`path` to an alternate runtime", + }, + cli.StringSliceFlag{ + Name: "runtime-flag", + Usage: "add global flags for the container runtime", + }, + cli.StringFlag{ + Name: "signature-policy", + Usage: "`pathname` of signature policy file (not usually used)", + }, + cli.StringSliceFlag{ + Name: "tag, t", + Usage: "`tag` to apply to the built image", + }, + cli.BoolFlag{ + Name: "tls-verify", + Usage: "require HTTPS and verify certificates when accessing the registry", + }, + } + buildDescription = "podman build launches the Buildah command to build an OCI Image. Buildah must be installed for this command to work." + buildCommand = cli.Command{ + Name: "build", + Aliases: []string{"build"}, + Usage: "Build an image using instructions in a Dockerfile", + Description: buildDescription, + Flags: buildFlags, + Action: buildCmd, + ArgsUsage: "CONTEXT-DIRECTORY | URL", + } +) + +func buildCmd(c *cli.Context) error { + + budCmdArgs := []string{"bud"} + + for _, buildArg := range c.StringSlice("build-arg") { + budCmdArgs = append(budCmdArgs, "--build-arg", buildArg) + } + for _, fileName := range c.StringSlice("file") { + budCmdArgs = append(budCmdArgs, "--file", fileName) + } + if c.IsSet("format") { + budCmdArgs = append(budCmdArgs, "--format", c.String("format")) + } + if c.IsSet("pull-always") { + budCmdArgs = append(budCmdArgs, "--pull-always") + } + if c.IsSet("quiet") { + quietParam := "--quiet=" + strconv.FormatBool(c.Bool("quiet")) + budCmdArgs = append(budCmdArgs, quietParam) + } + if c.IsSet("runtime") { + budCmdArgs = append(budCmdArgs, "--runtime", c.String("runtime")) + } + for _, runtimeArg := range c.StringSlice("runtime-flag") { + budCmdArgs = append(budCmdArgs, "--runtime-flag", runtimeArg) + } + if c.IsSet("signature-policy") { + budCmdArgs = append(budCmdArgs, "--signature-policy", c.String("signature-policy")) + } + for _, tagArg := range c.StringSlice("tag") { + budCmdArgs = append(budCmdArgs, "--tag", tagArg) + } + if c.IsSet("tls-verify") { + tlsParam := "--tls-verify=" + strconv.FormatBool(c.Bool("tls-verify")) + budCmdArgs = append(budCmdArgs, tlsParam) + } + + if len(c.Args()) > 0 { + budCmdArgs = append(budCmdArgs, c.Args()...) + } + + buildah := "buildah" + + if _, err := exec.LookPath(buildah); err != nil { + return errors.Wrapf(err, "buildah not found in PATH") + } + if _, err := exec.Command(buildah).Output(); err != nil { + return errors.Wrapf(err, "buildah is not operational on this server") + } + + cmd := exec.Command(buildah, budCmdArgs...) + + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + if err := cmd.Run(); err != nil { + return errors.Wrapf(err, "error running the buildah build-using-dockerfile (bud) command") + } + + return nil +} diff --git a/cmd/podman/main.go b/cmd/podman/main.go index d3cb86798..011303349 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -36,6 +36,7 @@ func main() { app.Commands = []cli.Command{ attachCommand, commitCommand, + buildCommand, createCommand, diffCommand, execCommand, diff --git a/completions/bash/podman b/completions/bash/podman index 37f70e24a..abb629bc9 100644 --- a/completions/bash/podman +++ b/completions/bash/podman @@ -684,6 +684,48 @@ _podman_commit() { esac } +_podman_build() { + local boolean_options=" + --build + --help + -h + --pull + --pull-always + --quiet + -q + --tls-verify + " + + local options_with_args=" + --signature-policy + --runtime + --runtime-flag + --tag + -t + --file + -f + --build-arg + --format + " + + local all_options="$options_with_args $boolean_options" + + case "$prev" in + --runtime) + COMPREPLY=($(compgen -W 'runc runv' -- "$cur")) + ;; + $(__buildah_to_extglob "$options_with_args")) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) + ;; + esac +} + _podman_diff() { local options_with_args=" --format @@ -1481,6 +1523,7 @@ _podman_podman() { " commands=" attach + build commit create diff diff --git a/docs/podman-build.1.md b/docs/podman-build.1.md new file mode 100644 index 000000000..8b991e2cf --- /dev/null +++ b/docs/podman-build.1.md @@ -0,0 +1,103 @@ +% podman(1) podman-build - Simple tool to build a container image +% Tom Sweeney +# podman-build "7" "December 2017" "podman" + +## NAME +podman-build - Build a container image using a Dockerfile. + +## SYNOPSIS +**podman** **build** [*options* [...]] [**context**] + +## DESCRIPTION +**podman build** Builds an image using instructions from one or more Dockerfiles and a specified +build context directory. The build context directory can be specified as the +**http** or **https** URL of an archive which will be retrieved and extracted +to a temporary location. This command passes the parameters entered in by the user to the +**buildah bud** command https://github.com/projectatomic/buildah/blob/master/docs/buildah-bud.md +to do the actual building. + +**podman [GLOBAL OPTIONS]** + +**podman build [GLOBAL OPTIONS]** + +**podman build [OPTIONS] NAME[:TAG|@DIGEST]** + +## OPTIONS + +**--build-arg** *arg=value* + +Specifies a build argument and its value, which will be interpolated in +instructions read from the Dockerfiles in the same way that environment +variables are, but which will not be added to environment variable list in the +resulting image's configuration. + +**-f, --file** *Dockerfile* + +Specifies a Dockerfile which contains instructions for building the image, +either a local file or an **http** or **https** URL. If more than one +Dockerfile is specified, *FROM* instructions will only be accepted from the +first specified file. + +If a build context is not specified, and at least one Dockerfile is a +local file, the directory in which it resides will be used as the build +context. + +**--format** + +Control the format for the built image's manifest and configuration data. +Recognized formats include *oci* (OCI image-spec v1.0, the default) and +*docker* (version 2, using schema format 2 for the manifest). + +**--pull-always** + +Pull the image even if a version of the image is already present. + +**--quiet** + +Suppress output messages which indicate which instruction is being processed, +and of progress when pulling images from a registry, and when writing the +output image. + +**--runtime** *path* + +The *path* to an alternate OCI-compatible runtime, which will be used to run +commands specified by the **RUN** instruction. + +**--runtime-flag** *flag* + +Adds global flags for the container rutime. + +**--signature-policy** *signaturepolicy* + +Pathname of a signature policy file to use. It is not recommended that this +option be used, as the default behavior of using the system-wide default policy +(frequently */etc/containers/policy.json*) is most often preferred. + +**-t, --tag** *imageName* + +Specifies the name which will be assigned to the resulting image if the build +process completes successfully. + +**--tls-verify** *bool-value* + +Require HTTPS and verify certificates when talking to container registries (defaults to true) + +## EXAMPLES + +podman build . + +podman build -f Dockerfile.simple . + +podman build -f Dockerfile.simple -f Dockerfile.notsosimple + +podman build -t imageName . + +podman build --tls-verify=true -t imageName -f Dockerfile.simple + +podman build --tls-verify=false -t imageName . + +## SEE ALSO +podman(1), buildah(1) + +## HISTORY +December 2017, Originally compiled by Tom Sweeney diff --git a/test/build/from-multiple-files/Dockerfile1.alpine b/test/build/from-multiple-files/Dockerfile1.alpine new file mode 100644 index 000000000..c6e3fc405 --- /dev/null +++ b/test/build/from-multiple-files/Dockerfile1.alpine @@ -0,0 +1,2 @@ +FROM alpine +COPY Dockerfile1.alpine /Dockerfile1 diff --git a/test/build/from-multiple-files/Dockerfile1.scratch b/test/build/from-multiple-files/Dockerfile1.scratch new file mode 100644 index 000000000..4f9ab8a60 --- /dev/null +++ b/test/build/from-multiple-files/Dockerfile1.scratch @@ -0,0 +1,2 @@ +FROM scratch +COPY Dockerfile1.scratch /Dockerfile1 diff --git a/test/build/from-multiple-files/Dockerfile2.glob b/test/build/from-multiple-files/Dockerfile2.glob new file mode 100644 index 000000000..1d843ba07 --- /dev/null +++ b/test/build/from-multiple-files/Dockerfile2.glob @@ -0,0 +1,2 @@ +FROM alpine +COPY Dockerfile* / diff --git a/test/build/from-multiple-files/Dockerfile2.nofrom b/test/build/from-multiple-files/Dockerfile2.nofrom new file mode 100644 index 000000000..0473c91d8 --- /dev/null +++ b/test/build/from-multiple-files/Dockerfile2.nofrom @@ -0,0 +1 @@ +COPY Dockerfile2.nofrom / diff --git a/test/build/from-multiple-files/Dockerfile2.withfrom b/test/build/from-multiple-files/Dockerfile2.withfrom new file mode 100644 index 000000000..fa3b96908 --- /dev/null +++ b/test/build/from-multiple-files/Dockerfile2.withfrom @@ -0,0 +1,2 @@ +FROM alpine +COPY Dockerfile2.withfrom / diff --git a/test/build/from-scratch/Dockerfile b/test/build/from-scratch/Dockerfile new file mode 100644 index 000000000..c35f1b5f5 --- /dev/null +++ b/test/build/from-scratch/Dockerfile @@ -0,0 +1 @@ +FROM scratch diff --git a/test/build/http-context-subdir/context.tar b/test/build/http-context-subdir/context.tar new file mode 100644 index 000000000..533ae524e Binary files /dev/null and b/test/build/http-context-subdir/context.tar differ diff --git a/test/build/http-context/context.tar b/test/build/http-context/context.tar new file mode 100644 index 000000000..2e5f3a515 Binary files /dev/null and b/test/build/http-context/context.tar differ diff --git a/test/build/preserve-volumes/Dockerfile b/test/build/preserve-volumes/Dockerfile new file mode 100644 index 000000000..922f565d7 --- /dev/null +++ b/test/build/preserve-volumes/Dockerfile @@ -0,0 +1,22 @@ +FROM alpine +RUN mkdir -p /vol/subvol/subsubvol +RUN dd if=/dev/zero bs=512 count=1 of=/vol/subvol/subsubvol/subsubvolfile +VOLUME /vol/subvol +# At this point, the contents below /vol/subvol should be frozen. +RUN dd if=/dev/zero bs=512 count=1 of=/vol/subvol/subvolfile +# In particular, /vol/subvol/subvolfile should be wiped out. +RUN dd if=/dev/zero bs=512 count=1 of=/vol/volfile +# However, /vol/volfile should exist. +VOLUME /vol +# And this should be redundant. +VOLUME /vol/subvol +# And now we've frozen /vol. +RUN dd if=/dev/zero bs=512 count=1 of=/vol/anothervolfile +# Which means that in the image we're about to commit, /vol/anothervolfile +# shouldn't exist, either. + +# ADD files which should persist. +ADD Dockerfile /vol/Dockerfile +RUN stat /vol/Dockerfile +ADD Dockerfile /vol/Dockerfile2 +RUN stat /vol/Dockerfile2 diff --git a/test/build/volume-perms/Dockerfile b/test/build/volume-perms/Dockerfile new file mode 100644 index 000000000..4dced7738 --- /dev/null +++ b/test/build/volume-perms/Dockerfile @@ -0,0 +1,6 @@ +FROM alpine +VOLUME /vol/subvol +# At this point, the directory should exist, with default permissions 0755, the +# contents below /vol/subvol should be frozen, and we shouldn't get an error +# from trying to write to it because we it was created automatically. +RUN dd if=/dev/zero bs=512 count=1 of=/vol/subvol/subvolfile diff --git a/test/helpers.bash b/test/helpers.bash index 2ac203027..16f3483f6 100644 --- a/test/helpers.bash +++ b/test/helpers.bash @@ -132,6 +132,57 @@ for key in ${!IMAGES[@]}; do done +### +# Buildah related variables +### +BUILDAH_BINARY=${BUILDAH_BINARY:-$(dirname ${BASH_SOURCE})/../buildah} +BUILDAH_IMGTYPE_BINARY=${BUILDAH_IMGTYPE_BINARY:-$(dirname ${BASH_SOURCE})/../imgtype} +BUILDAH_TESTSDIR=${BUILDAH_TESTSDIR:-$(dirname ${BASH_SOURCE})} +BUILDAH_STORAGE_DRIVER=${BUILDAH_STORAGE_DRIVER:-vfs} +#BUILDAH_PATH=$(dirname ${BASH_SOURCE})/..:${BUILDAH_PATH} + +# Make sure we have a copy of the redis:alpine image. +if ! [ -d "$ARTIFACTS_PATH"/redis-image ]; then + mkdir -p "$ARTIFACTS_PATH"/redis-image + if ! "$COPYIMG_BINARY" --import-from=docker://redis:alpine --export-to=dir:"$ARTIFACTS_PATH"/redis-image --signature-policy="$INTEGRATION_ROOT"/policy.json ; then + echo "Error pulling docker://redis" + rm -fr "$ARTIFACTS_PATH"/redis-image + exit 1 + fi +fi + +# TODO: remove the code below for pulling redis:alpine using a canonical reference once +# https://github.com/kubernetes-incubator/cri-o/issues/531 is complete and we can +# pull the image using a tagged reference and then subsequently find the image without +# having to explicitly record the canonical reference as one of the image's names +if ! [ -d "$ARTIFACTS_PATH"/redis-image-digest ]; then + mkdir -p "$ARTIFACTS_PATH"/redis-image-digest + if ! "$COPYIMG_BINARY" --import-from=docker://redis@sha256:03789f402b2ecfb98184bf128d180f398f81c63364948ff1454583b02442f73b --export-to=dir:"$ARTIFACTS_PATH"/redis-image-digest --signature-policy="$INTEGRATION_ROOT"/policy.json ; then + echo "Error pulling docker://redis@sha256:03789f402b2ecfb98184bf128d180f398f81c63364948ff1454583b02442f73b" + rm -fr "$ARTIFACTS_PATH"/redis-image-digest + exit 1 + fi +fi + +# Make sure we have a copy of the runcom/stderr-test image. +if ! [ -d "$ARTIFACTS_PATH"/stderr-test ]; then + mkdir -p "$ARTIFACTS_PATH"/stderr-test + if ! "$COPYIMG_BINARY" --import-from=docker://runcom/stderr-test:latest --export-to=dir:"$ARTIFACTS_PATH"/stderr-test --signature-policy="$INTEGRATION_ROOT"/policy.json ; then + echo "Error pulling docker://stderr-test" + rm -fr "$ARTIFACTS_PATH"/stderr-test + exit 1 + fi +fi + +# Make sure we have a copy of the busybox:latest image. +if ! [ -d "$ARTIFACTS_PATH"/busybox-image ]; then + mkdir -p "$ARTIFACTS_PATH"/busybox-image + if ! "$COPYIMG_BINARY" --import-from=docker://busybox --export-to=dir:"$ARTIFACTS_PATH"/busybox-image --signature-policy="$INTEGRATION_ROOT"/policy.json ; then + echo "Error pulling docker://busybox" + rm -fr "$ARTIFACTS_PATH"/busybox-image + exit 1 + fi +fi # Communicate with Docker on the host machine. # Should rarely use this. @@ -260,3 +311,49 @@ function copy_images() { "$COPYIMG_BINARY" --root "$TESTDIR/crio" $STORAGE_OPTIONS --runroot "$TESTDIR/crio-run" --image-name=${IMAGES[${key}]} --import-from=dir:"$ARTIFACTS_PATH"/${key} --add-name=${IMAGES[${key}]} done } + +### +# Buildah Functions +### +function setup() { + suffix=$(dd if=/dev/urandom bs=12 count=1 status=none | base64 | tr +/ABCDEFGHIJKLMNOPQRSTUVWXYZ _.abcdefghijklmnopqrstuvwxyz) + TESTDIR=${BATS_TMPDIR}/tmp.${suffix} + rm -fr ${TESTDIR} + mkdir -p ${TESTDIR}/{root,runroot} +} + +function starthttpd() { + pushd ${2:-${TESTDIR}} > /dev/null + cp ${BUILDAH_TESTSDIR}/serve.go . + go build serve.go + HTTP_SERVER_PORT=$((RANDOM+32768)) + ./serve ${HTTP_SERVER_PORT} ${1:-${BATS_TMPDIR}} & + HTTP_SERVER_PID=$! + popd > /dev/null +} + +function stophttpd() { + if test -n "$HTTP_SERVER_PID" ; then + kill -HUP ${HTTP_SERVER_PID} + unset HTTP_SERVER_PID + unset HTTP_SERVER_PORT + fi + true +} + +function teardown() { + stophttpd + rm -fr ${TESTDIR} +} + +function createrandom() { + dd if=/dev/urandom bs=1 count=${2:-256} of=${1:-${BATS_TMPDIR}/randomfile} status=none +} + +function buildah() { + ${BUILDAH_BINARY} --debug --root ${TESTDIR}/root --runroot ${TESTDIR}/runroot --storage-driver ${BUILDAH_STORAGE_DRIVER} "$@" +} + +function imgtype() { + ${BUILDAH_IMGTYPE_BINARY} -root ${TESTDIR}/root -runroot ${TESTDIR}/runroot -storage-driver ${BUILDAH_STORAGE_DRIVER} "$@" +} diff --git a/test/podman_build.bats b/test/podman_build.bats new file mode 100644 index 000000000..159737019 --- /dev/null +++ b/test/podman_build.bats @@ -0,0 +1,265 @@ +#!/usr/bin/env bats + +load helpers + +@test "build-from-scratch" { + if ! which buildah ; then + skip "Buildah not installed" + fi + target=scratch-image + kpod build --signature-policy ${BUILDAH_TESTSDIR}/policy.json -t ${target} ${BUILDAH_TESTSDIR}/build/from-scratch + cid=$(buildah from ${target}) + kpod rm ${cid} + kpod rmi $(buildah --debug=false images -q) + run buildah --debug=false images -q + [ "$output" = "" ] + [ "$status" -eq 0 ] +} + +@test "build-from-multiple-files-one-from" { + if ! which buildah ; then + skip "Buildah not installed" + fi + target=scratch-image + kpod build --signature-policy ${BUILDAH_TESTSDIR}/policy.json -t ${target} -f ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile1.scratch -f ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile2.nofrom + cid=$(buildah from ${target}) + root=$(buildah mount ${cid}) + cmp $root/Dockerfile1 ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile1.scratch + cmp $root/Dockerfile2.nofrom ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile2.nofrom + run test -s $root/etc/passwd + [ "$status" -ne 0 ] + kpod rm ${cid} + kpod rmi $(buildah --debug=false images -q) + run buildah --debug=false images -q + [ "$status" -eq 0 ] + [ "$output" = "" ] + + target=alpine-image + kpod build --signature-policy ${BUILDAH_TESTSDIR}/policy.json -t ${target} -f ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile1.alpine -f ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile2.nofrom + cid=$(buildah from ${target}) + root=$(buildah mount ${cid}) + cmp $root/Dockerfile1 ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile1.alpine + cmp $root/Dockerfile2.nofrom ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile2.nofrom + run test -s $root/etc/passwd + [ "$status" -eq 0 ] + kpod rm ${cid} + kpod rmi $(buildah --debug=false images -q) + run buildah --debug=false images -q + [ "$status" -eq 0 ] + [ "$output" = "" ] +} + +@test "build-from-multiple-files-two-froms" { + if ! which buildah ; then + skip "Buildah not installed" + fi + target=scratch-image + kpod build --signature-policy ${BUILDAH_TESTSDIR}/policy.json -t ${target} -f ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile1.scratch -f ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile2.withfrom + cid=$(buildah from ${target}) + root=$(buildah mount ${cid}) + cmp $root/Dockerfile1 ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile1.scratch + cmp $root/Dockerfile2.withfrom ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile2.withfrom + run test -s $root/etc/passwd + [ "$status" -ne 0 ] + kpod rm ${cid} + kpod rmi $(buildah --debug=false images -q) + run buildah --debug=false images -q + [ "$status" -eq 0 ] + [ "$output" = "" ] + + target=alpine-image + kpod build --signature-policy ${BUILDAH_TESTSDIR}/policy.json -t ${target} -f ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile1.alpine -f ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile2.withfrom + cid=$(buildah from ${target}) + root=$(buildah mount ${cid}) + cmp $root/Dockerfile1 ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile1.alpine + cmp $root/Dockerfile2.withfrom ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile2.withfrom + run test -s $root/etc/passwd + [ "$status" -eq 0 ] + kpod rm ${cid} + kpod rmi $(buildah --debug=false images -q) + run buildah --debug=false images -q + [ "$status" -eq 0 ] + [ "$output" = "" ] +} + +@test "build-preserve-subvolumes" { + if ! which buildah ; then + skip "Buildah not installed" + fi + # This Dockerfile needs us to be able to handle a working RUN instruction. + if ! which runc ; then + skip + fi + target=volume-image + kpod build --signature-policy ${BUILDAH_TESTSDIR}/policy.json -t ${target} ${BUILDAH_TESTSDIR}/build/preserve-volumes + cid=$(buildah from ${target}) + root=$(buildah mount ${cid}) + test -s $root/vol/subvol/subsubvol/subsubvolfile + run test -s $root/vol/subvol/subvolfile + [ "$status" -ne 0 ] + test -s $root/vol/volfile + test -s $root/vol/Dockerfile + test -s $root/vol/Dockerfile2 + run test -s $root/vol/anothervolfile + [ "$status" -ne 0 ] + kpod rm ${cid} + kpod rmi $(buildah --debug=false images -q) + run buildah --debug=false images -q + [ "$output" = "" ] +} + +@test "build-http-Dockerfile" { + if ! which buildah ; then + skip "Buildah not installed" + fi + starthttpd ${BUILDAH_TESTSDIR}/build/from-scratch + target=scratch-image + kpod build --signature-policy ${BUILDAH_TESTSDIR}/policy.json -t ${target} -f http://0.0.0.0:${HTTP_SERVER_PORT}/Dockerfile . + stophttpd + cid=$(buildah from ${target}) + kpod rm ${cid} + kpod rmi $(buildah --debug=false images -q) + run buildah --debug=false images -q + [ "$output" = "" ] +} + +@test "build-http-context-with-Dockerfile" { + if ! which buildah ; then + skip "Buildah not installed" + fi + starthttpd ${BUILDAH_TESTSDIR}/build/http-context + target=scratch-image + kpod build --signature-policy ${BUILDAH_TESTSDIR}/policy.json -t ${target} http://0.0.0.0:${HTTP_SERVER_PORT}/context.tar + stophttpd + cid=$(buildah from ${target}) + kpod rm ${cid} + kpod rmi $(buildah --debug=false images -q) + run buildah --debug=false images -q + [ "$output" = "" ] +} + +@test "build-http-context-dir-with-Dockerfile-pre" { + if ! which buildah ; then + skip "Buildah not installed" + fi + starthttpd ${BUILDAH_TESTSDIR}/build/http-context-subdir + target=scratch-image + kpod build --signature-policy ${BUILDAH_TESTSDIR}/policy.json -t ${target} -f context/Dockerfile http://0.0.0.0:${HTTP_SERVER_PORT}/context.tar + stophttpd + cid=$(buildah from ${target}) + kpod rm ${cid} + kpod rmi $(buildah --debug=false images -q) + run buildah --debug=false images -q + [ "$output" = "" ] +} + +@test "build-http-context-dir-with-Dockerfile-post" { + if ! which buildah ; then + skip "Buildah not installed" + fi + starthttpd ${BUILDAH_TESTSDIR}/build/http-context-subdir + target=scratch-image + kpod build http://0.0.0.0:${HTTP_SERVER_PORT}/context.tar --signature-policy ${BUILDAH_TESTSDIR}/policy.json -t ${target} -f context/Dockerfile + stophttpd + cid=$(buildah from ${target}) + kpod rm ${cid} + kpod rmi $(buildah --debug=false images -q) + run buildah --debug=false images -q + [ "$output" = "" ] +} + +@test "build-git-context" { + if ! which buildah ; then + skip "Buildah not installed" + fi + # We need git and ssh to be around to handle cloning a repository. + if ! which git ; then + skip + fi + if ! which ssh ; then + skip + fi + target=giturl-image + # Any repo should do, but this one is small and is FROM: scratch. + gitrepo=git://github.com/projectatomic/nulecule-library + kpod build --signature-policy ${BUILDAH_TESTSDIR}/policy.json -t ${target} "${gitrepo}" + cid=$(buildah from ${target}) + kpod rm ${cid} + kpod rmi $(buildah --debug=false images -q) + run buildah --debug=false images -q + [ "$output" = "" ] +} + +@test "build-github-context" { + if ! which buildah ; then + skip "Buildah not installed" + fi + target=github-image + # Any repo should do, but this one is small and is FROM: scratch. + gitrepo=github.com/projectatomic/nulecule-library + kpod build --signature-policy ${BUILDAH_TESTSDIR}/policy.json -t ${target} "${gitrepo}" + cid=$(buildah from ${target}) + kpod rm ${cid} + buildah --debug=false images -q + kpod rmi $(buildah --debug=false images -q) + run buildah --debug=false images -q + [ "$output" = "" ] +} + +@test "build-additional-tags" { + if ! which buildah ; then + skip "Buildah not installed" + fi + target=scratch-image + target2=another-scratch-image + target3=so-many-scratch-images + kpod build --signature-policy ${BUILDAH_TESTSDIR}/policy.json -t ${target} -t ${target2} -t ${target3} ${BUILDAH_TESTSDIR}/build/from-scratch + run buildah --debug=false images + cid=$(buildah from ${target}) + kpod rm ${cid} + cid=$(buildah from library/${target2}) + kpod rm ${cid} + cid=$(buildah from ${target3}:latest) + kpod rm ${cid} + kpod rmi -f $(buildah --debug=false images -q) + run buildah --debug=false images -q + [ "$output" = "" ] +} + +@test "build-volume-perms" { + if ! which buildah ; then + skip "Buildah not installed" + fi + # This Dockerfile needs us to be able to handle a working RUN instruction. + if ! which runc ; then + skip + fi + target=volume-image + kpod build --signature-policy ${BUILDAH_TESTSDIR}/policy.json -t ${target} ${BUILDAH_TESTSDIR}/build/volume-perms + cid=$(buildah from ${target}) + root=$(buildah mount ${cid}) + run test -s $root/vol/subvol/subvolfile + [ "$status" -ne 0 ] + run stat -c %f $root/vol/subvol + [ "$output" = 41ed ] + kpod rm ${cid} + kpod rmi $(buildah --debug=false images -q) + run buildah --debug=false images -q + [ "$output" = "" ] +} + +@test "build-from-glob" { + if ! which buildah ; then + skip "Buildah not installed" + fi + target=alpine-image + kpod build --signature-policy ${BUILDAH_TESTSDIR}/policy.json -t ${target} -f Dockerfile2.glob ${BUILDAH_TESTSDIR}/build/from-multiple-files + cid=$(buildah from ${target}) + root=$(buildah mount ${cid}) + cmp $root/Dockerfile1.alpine ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile1.alpine + cmp $root/Dockerfile2.withfrom ${BUILDAH_TESTSDIR}/build/from-multiple-files/Dockerfile2.withfrom + kpod rm ${cid} + kpod rmi $(buildah --debug=false images -q) + run buildah --debug=false images -q + [ "$output" = "" ] +} diff --git a/test/test_podman_build.sh b/test/test_podman_build.sh new file mode 100644 index 000000000..a595e52c0 --- /dev/null +++ b/test/test_podman_build.sh @@ -0,0 +1,172 @@ +#!/bin/bash +# +# test_podman_build.sh +# +# Used to test 'podman build' functionality "by hand" +# until we're able to install Buildah in the Travis CI +# test system. +# +# Requires podman and Buildah to be installed on the +# system. This needs to be run from the libpod +# directory after cloning the libpod repo. +# +# To run: +# /bin/bash -v test_podman_build.sh +# + +HOME=`pwd` + +######## +# test "build-from-scratch" +######## + TARGET=scratch-image + podman build -q=True -t $TARGET $HOME/test/build/from-scratch + CID=$(buildah from $TARGET) + buildah rm $CID + podman build -q=False --build-arg HOME=/ --build-arg VERSION=0.1 -t $TARGET $HOME/test/build/from-scratch + CID=$(buildah from $TARGET) + buildah rm $CID + podman build --quiet=True -t $TARGET $HOME/test/build/from-scratch + CID=$(buildah from $TARGET) + buildah rm $CID + podman rmi -f $(podman images -q) + podman images -q + + +######## +# test "build-preserve-subvolumes" +######## + TARGET=volume-image + podman build -t $TARGET $HOME/test/build/preserve-volumes + CID=$(buildah from $TARGET) + ROOT=$(buildah mount $CID) + test -s $ROOT/vol/subvol/subsubvol/subsubvolfile + test -s $ROOT/vol/subvol/subvolfile + test -s $ROOT/vol/volfile + test -s $ROOT/vol/Dockerfile + test -s $ROOT/vol/Dockerfile2 + test -s $ROOT/vol/anothervolfile + buildah rm $CID + podman rmi $(buildah --debug=false images -q) + buildah --debug=false images -q + +######## +# test "build-git-context" +######## + TARGET=giturl-image + # Any repo should do, but this one is small and is FROM: scratch. + GITREPO=git://github.com/projectatomic/nulecule-library + podman build -t $TARGET "$GITREPO" + CID=$(buildah from $TARGET) + buildah rm $CID + podman rmi $(buildah --debug=false images -q) + podman images -q + + +######## +# test "build-github-context" +######## + TARGET=github-image + # Any repo should do, but this one is small and is FROM: scratch. + GITREPO=github.com/projectatomic/nulecule-library + podman build -t $TARGET "$GITREPO" + CID=$(buildah from $TARGET) + buildah rm $CID + buildah --debug=false images -q + podman rmi $(buildah --debug=false images -q) + podman images -q + + +######## +# test "build-additional-tags" +######## + TARGET=scratch-image + TARGET2=another-scratch-image + TARGET3=so-many-scratch-images + podman build -t $TARGET -t $TARGET2 -t $TARGET3 -f $HOME/test/build/from-scratch/Dockerfile + buildah --debug=false images + CID=$(buildah from $TARGET) + buildah rm $CID + CID=$(buildah from library/$TARGET2) + buildah rm $CID + CID=$(buildah from $TARGET3:latest) + buildah rm $CID + podman rmi -f $(buildah --debug=false images -q) + podman images -q + + +######## +# test "build-volume-perms" +######## + TARGET=volume-image + podman build -t $TARGET $HOME/test/build/volume-perms + CID=$(buildah from $TARGET) + ROOT=$(buildah mount $CID) + test -s $ROOT/vol/subvol/subvolfile + stat -c %f $ROOT/vol/subvol + #Output s/b 41ed + buildah rm $CID + podman rmi $(buildah --debug=false images -q) + podman images -q + + +######## +# test "build-from-glob" +######## + TARGET=alpine-image + podman build -t $TARGET -file Dockerfile2.glob $HOME/test/build/from-multiple-files + CID=$(buildah from $TARGET) + ROOT=$(buildah mount $CID) + cmp $ROOT/Dockerfile1.alpine $HOME/test/build/from-multiple-files/Dockerfile1.alpine + cmp $ROOT/Dockerfile2.withfrom $HOME/test/build/from-multiple-files/Dockerfile2.withfrom + buildah rm $CID + podman rmi $(buildah --debug=false images -q) + podman images -q + + +######## +# test "build-from-multiple-files-one-from" +######## + TARGET=scratch-image + podman build -t $TARGET -file $HOME/test/build/from-multiple-files/Dockerfile1.scratch -file $HOME/test/build/from-multiple-files/Dockerfile2.nofrom + CID=$(buildah from $TARGET) + ROOT=$(buildah mount $CID) + cmp $ROOT/Dockerfile1 $HOME/test/build/from-multiple-files/Dockerfile1.scratch + cmp $ROOT/Dockerfile2.nofrom $HOME/test/build/from-multiple-files/Dockerfile2.nofrom + buildah rm $CID + podman rmi $(buildah --debug=false images -q) + buildah --debug=false images -q + + TARGET=alpine-image + podman build -t $TARGET -file $HOME/test/build/from-multiple-files/Dockerfile1.alpine -file $HOME/test/build/from-multiple-files/Dockerfile2.nofrom + CID=$(buildah from $TARGET) + ROOT=$(buildah mount $CID) + buildah rm $CID + podman rmi $(buildah --debug=false images -q) + buildah --debug=false images -q + + +######## +# test "build-from-multiple-files-two-froms" +######## + TARGET=scratch-image + podman build -t $TARGET -file $HOME/test/build/from-multiple-files/Dockerfile1.scratch -file $HOME/test/build/from-multiple-files/Dockerfile2.withfrom + CID=$(buildah from $TARGET) + ROOT=$(buildah mount $CID) + cmp $ROOT/Dockerfile1 $HOME/test/build/from-multiple-files/Dockerfile1.scratch + cmp $ROOT/Dockerfile2.withfrom $HOME/test/build/from-multiple-files/Dockerfile2.withfrom + test -s $ROOT/etc/passwd + buildah rm $CID + podman rmi $(buildah --debug=false images -q) + buildah --debug=false images -q + + TARGET=alpine-image + podman build -t $TARGET -file $HOME/test/build/from-multiple-files/Dockerfile1.alpine -file $HOME/test/build/from-multiple-files/Dockerfile2.withfrom + CID=$(buildah from $TARGET) + ROOT=$(buildah mount $CID) + cmp $ROOT/Dockerfile1 $HOME/test/build/from-multiple-files/Dockerfile1.alpine + cmp $ROOT/Dockerfile2.withfrom $HOME/test/build/from-multiple-files/Dockerfile2.withfrom + test -s $ROOT/etc/passwd + buildah rm $CID + podman rmi $(buildah --debug=false images -q) + buildah --debug=false images -q diff --git a/transfer.md b/transfer.md index 1a2820cf3..101140905 100644 --- a/transfer.md +++ b/transfer.md @@ -39,7 +39,7 @@ There are other equivalents for these tools | Existing Step | PODMAN (and friends) | | :--- | :--- | | `docker attach` | [`podman exec`](./docs/podman-attach.1.md)| -| `docker build` | [`buildah bud`](https://github.com/projectatomic/buildah/blob/master/docs/buildah-bud.md) | +| `docker build` | [`podman build`](./docs/podman-build.1.md) | | `docker commit` | [`podman commit`](./docs/podman-commit.1.md)| | `docker cp` | [`podman mount`](./docs/podman-cp.1.md) **** | | `docker create` | [`podman create`](./docs/podman-create.1.md) | -- cgit v1.2.3-54-g00ecf