From 41c2c6d062b88d22cd9fc120ba3b33e531266a08 Mon Sep 17 00:00:00 2001 From: Antoine Pourchet Date: Mon, 20 May 2019 17:10:10 -0700 Subject: [PATCH 1/4] Chroot seems to work for simple enough builds --- testdata/chroot-simple/Dockerfile | 3 ++ tools/scripts/makisu_chroot.sh | 55 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 testdata/chroot-simple/Dockerfile create mode 100755 tools/scripts/makisu_chroot.sh diff --git a/testdata/chroot-simple/Dockerfile b/testdata/chroot-simple/Dockerfile new file mode 100644 index 00000000..cda8a10a --- /dev/null +++ b/testdata/chroot-simple/Dockerfile @@ -0,0 +1,3 @@ +FROM debian:9 +RUN echo "ASD" > /asd +RUN cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1 diff --git a/tools/scripts/makisu_chroot.sh b/tools/scripts/makisu_chroot.sh new file mode 100755 index 00000000..695f4559 --- /dev/null +++ b/tools/scripts/makisu_chroot.sh @@ -0,0 +1,55 @@ +#! /bin/bash + +set -e + +[ -z "$1" ] && echo "Must at least provide context of build" && exit 1 + +CHROOT=${CHROOT_LOCATION:-$HOME/.makisu-chroot-$RANDOM} +SSL_CERT_DIR=${SSL_CERTS:-/etc/ssl/certs} +CONTEXT=${@: -1} +BUILD_VOLUMES="$CONTEXT:/context,$BUILD_VOLUMES" + +function makisu::prepare_internals () { + mkdir -p $CHROOT/makisu-internal/certs + cp $(which makisu) $CHROOT/makisu-internal/makisu + cat $SSL_CERT_DIR/* > $CHROOT/makisu-internal/certs/cacerts.pem +} + +function makisu::prepare_dev () { + mkdir -p $CHROOT/dev + mknod -m 622 $CHROOT/dev/console c 5 1 + mknod -m 666 $CHROOT/dev/null c 1 3 + mknod -m 666 $CHROOT/dev/zero c 1 5 + mknod -m 666 $CHROOT/dev/ptmx c 5 2 + mknod -m 666 $CHROOT/dev/tty c 5 0 + mknod -m 444 $CHROOT/dev/random c 1 8 + mknod -m 444 $CHROOT/dev/urandom c 1 9 + chown root:tty $CHROOT/dev/{console,ptmx,tty} +} + +function makisu::prepare_etc () { + mkdir -p $CHROOT/etc + cp /etc/*.conf $CHROOT/etc/ +} + +function makisu::prepare_volumes () { + for vol in $(sed "s/,/ /g" <<< $BUILD_VOLUMES); do + from=$(cut -d ':' -f 1 <<< $vol) + to=$(cut -d ':' -f 2 <<< $vol) + echo "Copying volume $from to chroot directory $CHROOT/$to" + mkdir -p $CHROOT/$to + cp -r $from/* $CHROOT/$to + done +} + +echo "Preparing chroot at $CHROOT" +rm -rf $CHROOT + +makisu::prepare_internals +makisu::prepare_etc +makisu::prepare_dev +makisu::prepare_volumes + +makisu_args=${@:1:$#-1} +echo "Starting Makisu: makisu $makisu_args /context" +chroot $CHROOT/ /makisu-internal/makisu $makisu_args /context From c4a6e61519f0183959fa50e8ce9096e092e1186a Mon Sep 17 00:00:00 2001 From: Antoine Pourchet Date: Mon, 20 May 2019 17:39:25 -0700 Subject: [PATCH 2/4] Moved test --- testdata/{ => build-context}/chroot-simple/Dockerfile | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename testdata/{ => build-context}/chroot-simple/Dockerfile (100%) diff --git a/testdata/chroot-simple/Dockerfile b/testdata/build-context/chroot-simple/Dockerfile similarity index 100% rename from testdata/chroot-simple/Dockerfile rename to testdata/build-context/chroot-simple/Dockerfile From bdd2468ba0376b8477cee0c9102f26ba21a4eab8 Mon Sep 17 00:00:00 2001 From: Antoine Pourchet Date: Mon, 20 May 2019 17:48:28 -0700 Subject: [PATCH 3/4] Added fake dockerfile for now --- Dockerfile.chroot | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Dockerfile.chroot diff --git a/Dockerfile.chroot b/Dockerfile.chroot new file mode 100644 index 00000000..11bded1a --- /dev/null +++ b/Dockerfile.chroot @@ -0,0 +1,12 @@ +FROM golang:1.12.1 +COPY --from=gcr.io/makisu-project/makisu:v0.1.10 /makisu-internal/makisu /usr/local/bin/makisu + +ADD . /workspace +WORKDIR /workspace + +ENV SSL_CERT_DIR=/etc/ssl/certs +RUN makisu pull --extract /testdir --registry gcr.io --tag v0.1.10 makisu-project/makisu +RUN ./tools/scripts/makisu_chroot.sh build -t test:121 --modifyfs=true testdata/build-context/symlink +RUN ./tools/scripts/makisu_chroot.sh build -t test:121 --modifyfs=true testdata/build-context/user-change +RUN ./tools/scripts/makisu_chroot.sh build -t test:121 --modifyfs=true testdata/build-context/chroot-simple +RUN ./tools/scripts/makisu_chroot.sh build -t test:121 --modifyfs=true testdata/build-context/go-from-scratch From 7211b1e7ce46f82beb965c068a4e1e48a0be8017 Mon Sep 17 00:00:00 2001 From: Antoine Pourchet Date: Mon, 27 May 2019 13:57:01 -0700 Subject: [PATCH 4/4] Started port to go --- Dockerfile.chroot | 1 - bin/makisu/cmd/build.go | 36 +++++++++++++++++++++++++++++++++- tools/scripts/makisu_chroot.sh | 15 ++++++++++---- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/Dockerfile.chroot b/Dockerfile.chroot index 11bded1a..c73c0fa8 100644 --- a/Dockerfile.chroot +++ b/Dockerfile.chroot @@ -5,7 +5,6 @@ ADD . /workspace WORKDIR /workspace ENV SSL_CERT_DIR=/etc/ssl/certs -RUN makisu pull --extract /testdir --registry gcr.io --tag v0.1.10 makisu-project/makisu RUN ./tools/scripts/makisu_chroot.sh build -t test:121 --modifyfs=true testdata/build-context/symlink RUN ./tools/scripts/makisu_chroot.sh build -t test:121 --modifyfs=true testdata/build-context/user-change RUN ./tools/scripts/makisu_chroot.sh build -t test:121 --modifyfs=true testdata/build-context/chroot-simple diff --git a/bin/makisu/cmd/build.go b/bin/makisu/cmd/build.go index ba55f4ae..6d679bad 100644 --- a/bin/makisu/cmd/build.go +++ b/bin/makisu/cmd/build.go @@ -20,6 +20,7 @@ import ( "os" "path/filepath" "runtime" + "syscall" "time" "github.com/uber/makisu/lib/builder" @@ -67,6 +68,7 @@ type buildCmd struct { compressionLevel string preserveRoot bool + chroot string } func getBuildCmd() *buildCmd { @@ -88,7 +90,6 @@ func getBuildCmd() *buildCmd { log.Errorf("failed to process flags: %s", err) os.Exit(1) } - if err := buildCmd.Build(args[0]); err != nil { log.Error(err) os.Exit(1) @@ -124,6 +125,7 @@ func getBuildCmd() *buildCmd { buildCmd.PersistentFlags().StringVar(&buildCmd.compressionLevel, "compression", "default", "Image compression level, could be 'no', 'speed', 'size', 'default'") buildCmd.PersistentFlags().BoolVar(&buildCmd.preserveRoot, "preserve-root", false, "Copy / in the storage dir and copy it back after build.") + rootCmd.PersistentFlags().StringVar(&buildCmd.chroot, "chroot", "", "Executes the command in a chrooted environment.") buildCmd.MarkFlagRequired("tag") buildCmd.Flags().SortFlags = false @@ -216,6 +218,12 @@ func (cmd *buildCmd) newBuildPlan( func (cmd *buildCmd) Build(contextDir string) error { log.Infof("Starting Makisu build (version=%s)", utils.BuildHash) + if cmd.chroot != "" { + if err := cmd.prepareChroot(contextDir); err != nil { + return fmt.Errorf("failed to prepare chroot environment: %s", err) + } + } + // Create BuildContext. contextDirAbs, err := filepath.Abs(contextDir) if err != nil { @@ -298,3 +306,29 @@ func (cmd *buildCmd) Build(contextDir string) error { log.Infof("Finished building %s", imageName.ShortName()) return nil } + +func (cmd *buildCmd) prepareChroot(context string) error { + if runtime.GOOS != "linux" { + return fmt.Errorf("cannot prepare chroot on %s", runtime.GOOS) + } + + dest, err := filepath.Abs(cmd.chroot) + if err != nil { + return fmt.Errorf("failed to convert chroot path to absolute: %s", err) + } else if _, err := os.Lstat(dest); err == nil || !os.IsNotExist(err) { + return fmt.Errorf("chroot target must not exist: %s", err) + } + + certs := filepath.Join(cmd.chroot, pathutils.DefaultInternalDir, "certs") + if err := os.MkdirAll(certs, 0644); err != nil { + return fmt.Errorf("failed to create chroot cert dir: %s", err) + } + // TODO: copy all certs into the chroot environment. + + dev := filepath.Join(cmd.chroot, "dev") + if err := os.MkdirAll(dev, 0644); err != nil { + return fmt.Errorf("failed to create chroot /dev dir: %s", err) + } + // TODO: Create all nods + return syscall.Chroot(dest) +} diff --git a/tools/scripts/makisu_chroot.sh b/tools/scripts/makisu_chroot.sh index 695f4559..0d14dd02 100755 --- a/tools/scripts/makisu_chroot.sh +++ b/tools/scripts/makisu_chroot.sh @@ -16,15 +16,22 @@ function makisu::prepare_internals () { } function makisu::prepare_dev () { - mkdir -p $CHROOT/dev + mkdir -p $CHROOT/dev $CHROOT/shm mknod -m 622 $CHROOT/dev/console c 5 1 + mknod -m 622 $CHROOT/dev/initctl p + mknod -m 666 $CHROOT/dev/full c 1 7 mknod -m 666 $CHROOT/dev/null c 1 3 - mknod -m 666 $CHROOT/dev/zero c 1 5 mknod -m 666 $CHROOT/dev/ptmx c 5 2 + mknod -m 666 $CHROOT/dev/random c 1 8 mknod -m 666 $CHROOT/dev/tty c 5 0 - mknod -m 444 $CHROOT/dev/random c 1 8 - mknod -m 444 $CHROOT/dev/urandom c 1 9 + mknod -m 666 $CHROOT/dev/tty0 c 4 0 + mknod -m 666 $CHROOT/dev/urandom c 1 9 + mknod -m 666 $CHROOT/dev/zero c 1 5 chown root:tty $CHROOT/dev/{console,ptmx,tty} + + # https://github.com/moby/moby/blob/8e610b2b55bfd1bfa9436ab110d311f5e8a74dcb/contrib/mkimage-crux.sh + # https://github.com/moby/moby/blob/8e610b2b55bfd1bfa9436ab110d311f5e8a74dcb/contrib/mkimage-arch.sh + # https://github.com/moby/moby/blob/d7ab8ad145fad4c63112f34721663021e5b02707/contrib/mkimage-yum.sh } function makisu::prepare_etc () {