From e71c9480cc3d0dfe8b00ae87998fea9fd934ab6e Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Oct 04 2016 08:25:29 +0000 Subject: chrooter --- diff --git a/chrooter/.gitignore b/chrooter/.gitignore new file mode 100644 index 0000000..ef571b5 --- /dev/null +++ b/chrooter/.gitignore @@ -0,0 +1 @@ +/image/ diff --git a/chrooter/build-initial-system.sh b/chrooter/build-initial-system.sh new file mode 100755 index 0000000..ac97ff1 --- /dev/null +++ b/chrooter/build-initial-system.sh @@ -0,0 +1,27 @@ +#!/bin/bash -x + +set -e + +arch=i386 +suite=wheezy +chroot_dir="/var/chroot/$suite" +apt_mirror="ftp://ftp.debian.org/debian/" +docker_image="my/debian-$arch:$suite" + +export DEBIAN_FRONTEND=noninteractive +debootstrap --arch $arch $suite $chroot_dir $apt_mirror + +cat < $chroot_dir/etc/apt/sources.list +deb $apt_mirror $suite main +deb $apt_mirror $suite-updates main +deb http://security.debian.org/ $suite/updates main +EOF + +chroot $chroot_dir apt-get update +chroot $chroot_dir apt-get upgrade -y +chroot $chroot_dir apt-get autoclean +chroot $chroot_dir apt-get clean +chroot $chroot_dir apt-get autoremove + +tar cfz debian-$suite-$arch.tar.gz -C $chroot_dir . +rm -rf $chroot_dir diff --git a/chrooter/build.sh b/chrooter/build.sh new file mode 100755 index 0000000..ff7c574 --- /dev/null +++ b/chrooter/build.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +OLDDIR=`pwd` +SCRIPT_DIR=$(cd `dirname "$0"`; pwd) +cd "$OLDDIR" +BASE_DIR=`dirname "$SCRIPT_DIR"` + +CONFIG_FILE="$BASE_DIR/config.sh" +PACKET_BUILD_DIR="$BUILD_DIR/packet" +SCRIPT_BUILD_DIR="$BUILD_DIR/script" +if [ -f $CONFIG_FILE ]; then + source $CONFIG_FILE +fi +export PACKET_BUILD_DIR +mkdir -p $PACKET_BUILD_DIR + +docker build -t my/builder $DOCKER_BUILD_OPTIONS "$SCRIPT_DIR" diff --git a/chrooter/chrooter.sh b/chrooter/chrooter.sh new file mode 100755 index 0000000..9a28270 --- /dev/null +++ b/chrooter/chrooter.sh @@ -0,0 +1,306 @@ +#!/bin/bash + +set -e + +OLDDIR=`pwd` +BASE_DIR=$(cd `dirname "$0"`; pwd) +cd "$OLDDIR" + +INSTANCE_NAME=`uuidgen` +INSTANCE_NAME="chrooter-$INSTANCE_NAME" +PRIVILEGED= +IMAGE_MOUNT_DIR= +COMMAND_ERROR= + +image_mount_add() { + echo "Mount: $1 -> $2" + sudo mkdir -p "$IMAGE_MOUNT_DIR$2" + sudo mount -R "$1" "$IMAGE_MOUNT_DIR$2" + echo "umount -Rfl \"$IMAGE_MOUNT_DIR$2\"" >> "/tmp/$INSTANCE_NAME.umount.sh" +} + +image_mount() { + echo "Mount image: $1" + + if [ ! -z "$IMAGE_MOUNT_DIR" ]; then + echo "Image already mounted" + return 1 + fi + if [ -z "$1" ]; then + echo "Image name was not set" + return 1 + fi + + local IMAGE_NAME="$(echo $1 | tr "/:" "_")" + local IMAGE_FILE="$BASE_DIR/image/$IMAGE_NAME.tgz" + + echo "Unpack image: $1" + IMAGE_MOUNT_DIR="/tmp/$INSTANCE_NAME" + mkdir -p "$IMAGE_MOUNT_DIR" + cd "$IMAGE_MOUNT_DIR" + sudo tar -xzf $IMAGE_FILE + cd "$OLDDIR" + + echo "Add -.chroot.sh file" + sudo mv "/tmp/$INSTANCE_NAME.chroot.sh" "$IMAGE_MOUNT_DIR" + sudo chmod a+x "$IMAGE_MOUNT_DIR/$INSTANCE_NAME.chroot.sh" + + set -- "${@:2}" + echo "Mount subs: $@" + echo "#!/bin/sh" > "/tmp/$INSTANCE_NAME.umount.sh" + echo "" >> "/tmp/$INSTANCE_NAME.umount.sh" + echo "set -e" >> "/tmp/$INSTANCE_NAME.umount.sh" + chmod a+x "/tmp/$INSTANCE_NAME.umount.sh" + if [ ! -z "$PRIVILEGED" ]; then + echo "Mount /proc and /dev for priveleged feature" + image_mount_add /proc /proc + image_mount_add /dev /dev + fi + for ARG in $@; do + SRC="$(echo "$ARG" | cut -d':' -f 1)" + DEST="$(echo "$ARG" | cut -d':' -f 2-)" + image_mount_add $SRC $DEST + done +} + +image_unmount() { + echo "Unmount image" + + if [ -z "$IMAGE_MOUNT_DIR" ]; then + echo "Image not mounted" + return 1 + fi + + echo "Unmount subs" + sudo "/tmp/$INSTANCE_NAME.umount.sh" + sudo rm -f "/tmp/$INSTANCE_NAME.umount.sh" + + echo "Remove -.chroot.sh file" + sudo rm -f "$IMAGE_MOUNT_DIR/$INSTANCE_NAME.chroot.sh" + + if [ ! -z $1 ]; then + echo "Save image: $1" + + local IMAGE_NAME="$(echo $1 | tr "/:" "_")" + local IMAGE_FILE="$BASE_DIR/image/$IMAGE_NAME.tgz" + local IMAGE_DIR=`dirname "$IMAGE_FILE"` + mkdir -p "$IMAGE_DIR" + + cd "$IMAGE_MOUNT_DIR" + sudo tar -czf $IMAGE_FILE . + cd "$OLDDIR" + fi + + echo "Remove unpacked image" + sudo rm -rf --one-file-system "$IMAGE_MOUNT_DIR" + IMAGE_MOUNT_DIR= +} + +image_command() { + echo "Run command: $@" + + if [ -z "$IMAGE_MOUNT_DIR" ]; then + echo "Image not mounted" + return 1 + fi + + if ! sudo -E chroot "$IMAGE_MOUNT_DIR" "/$INSTANCE_NAME.chroot.sh" $@; then + COMMAND_ERROR=1 + echo "Command returned with error" + fi +} + +chroot_file_begin() { + echo "#!/bin/sh" > "/tmp/$INSTANCE_NAME.chroot.sh" + echo "" >> "/tmp/$INSTANCE_NAME.chroot.sh" +} + +chroot_file_env() { + echo "Set env: $1=\"$2\"" + echo "export $1=\"$2\"" >> "/tmp/$INSTANCE_NAME.chroot.sh" +} + +chroot_file_end() { + echo "\$@" >> "/tmp/$INSTANCE_NAME.chroot.sh" +} + +import() { + echo "Import $2" + + if [ ! "$1" = "-" ]; then + echo "Unknown commandline argument $1" + fi + if [ -z "$2" ]; then + echo "Image name was not set" + return 1 + fi + + + local IMAGE_NAME="$(echo $2 | tr "/:" "_")" + local IMAGE_FILE="$BASE_DIR/image/$IMAGE_NAME.tgz" + local IMAGE_DIR=`dirname "$IMAGE_FILE"` + mkdir -p "$IMAGE_DIR" + cat "/dev/stdin" > $IMAGE_FILE +} + +build() { + echo "Build" + + local IMAGE_NAME= + local WORK_DIR= + + chroot_file_begin + local MODE= + for ARG in $@; do + if [ -z "$WORK_DIR" ]; then + if [ "$MODE" = "-t" ]; then + IMAGE_NAME="$ARG" + echo "Set image name: $IMAGE_NAME" + MODE= + continue + fi + fi + + if [ ! -z "$MODE" ]; then + echo "Unknown commandline argument: $MODE" + fi + + MODE= + if [ ! -z "$WORK_DIR" ]; then + echo "Unknown commandline argument: $ARG" + elif [ "${ARG:0:1}" = "-" ]; then + SUBMODE="$(echo "$ARG" | cut -d'=' -f 1)" + SUBVALUE="$(echo "$ARG" | cut -d'=' -f 2-)" + if [ "$SUBMODE" = "--build-arg" ]; then + ENVKEY="$(echo "$SUBVALUE" | cut -d'=' -f 1)" + ENVVALUE="$(echo "$SUBVALUE" | cut -d'=' -f 2-)" + chroot_file_env "$ENVKEY" "$ENVVALUE" + continue + else + MODE=$ARG + fi + else + WORK_DIR=$ARG + echo "Set work dir: $WORK_DIR" + fi + done + if [ ! -z "$MODE" ]; then + echo "Unknown commandline argument $MODE" + fi + chroot_file_end + + if [ -z "$IMAGE_NAME" ]; then + echo "Image name was not set" + return 1 + fi + + local DOCKERFILE="$WORK_DIR/Dockerfile" + if [ ! -f "$DOCKERFILE" ]; then + echo "Dockerfile not found at: $DOCKERFILE" + return 1 + fi + + echo "Read $DOCKERFILE" + FULLROW= + while read ROW; do + FULLROW="$FULLROW$ROW" + LASTCHAR=$((${#ROW}-1)) + if [ ! "${ROW:LASTCHAR:1}" = "\\" ]; then + if [ "${FULLROW:0:5}" = "FROM " ]; then + image_mount "${FULLROW:5}" + elif [ "${ROW:0:4}" = "RUN " ]; then + image_command "${FULLROW:4}" + elif [ ! "${FULLROW:0:1}" = "#" ]; then + if [ ! -z "$FULLROW" ]; then + echo "Unknown command: $FULLROW" + fi + fi + FULLROW= + fi + if [ ! -z "$COMMAND_ERROR" ]; then + echo "Cancel build" + IMAGE_NAME="" + break + fi + done < "$DOCKERFILE" + + image_unmount "$IMAGE_NAME" +} + +run() { + local IMAGE_NAME= + local COMMAND= + local SUBMOUNT= + + chroot_file_begin + local MODE= + for ARG in $@; do + if [ ! -z "$COMMAND" ]; then + COMMAND="$COMMAND $ARG" + else + if [ "$MODE" = "-e" ]; then + ENVKEY="$(echo "$ARG" | cut -d'=' -f 1)" + ENVVALUE="$(echo "$ARG" | cut -d'=' -f 2-)" + chroot_file_env "$ENVKEY" "$ENVVALUE" + MODE= + continue + elif [ "$MODE" = "-v" ]; then + SUBMOUNT="$SUBMOUNT$ARG " + echo "Add submount: $ARG" + MODE= + continue + elif [ "$MODE" = "--name" ]; then + echo "Set name: $ARG (not uses)" + MODE= + continue + fi + + if [ ! -z "$MODE" ]; then + echo "Unknown commandline argument $MODE" + fi + + MODE= + if [ -z "$MODE" ]; then + if [ "$ARG" = "--privileged=true" ]; then + PRIVILEGED=1 + echo "Set privileged: true" + elif [ "${ARG:0:1}" = "-" ]; then + MODE=$ARG + elif [ -z "$IMAGE_NAME" ]; then + IMAGE_NAME=$ARG + echo "Set image name: $IMAGE_NAME" + elif [ -z "$COMMAND" ]; then + COMMAND=$ARG + fi + fi + fi + done + if [ ! -z "$MODE" ]; then + echo "Unknown commandline argument $MODE" + fi + chroot_file_end + echo "Set command: $COMMAND" + + if [ -z "$COMMAND" ]; then + echo "Command was not set" + return 1 + fi + + image_mount "$IMAGE_NAME" $SUBMOUNT + image_command $COMMAND + image_unmount +} + + +if [ "$1" = "import" ]; then + set -- "${@:2}" + import $@ +elif [ "$1" = "build" ]; then + set -- "${@:2}" + build $@ +elif [ "$1" = "run" ]; then + set -- "${@:2}" + run $@ +else + echo "Unknown command: $1" +fi diff --git a/chrooter/clean-tmp.sh b/chrooter/clean-tmp.sh new file mode 100755 index 0000000..5fef0f7 --- /dev/null +++ b/chrooter/clean-tmp.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +sudo rm -rf --one-file-system /tmp/chrooter-* diff --git a/config.sh.blank b/config.sh.blank index 8c78c9e..74de50d 100644 --- a/config.sh.blank +++ b/config.sh.blank @@ -2,3 +2,7 @@ # PROXY=http://1.2.3.4:1234 # DOCKER_BUILD_OPTIONS="--build-arg=http_proxy=$PROXY --build-arg=https_proxy=$PROXY" # DOCKER_RUN_OPTIONS="-e http_proxy=$PROXY -e https_proxy=$PROXY" + +# docker() { +# $BASE_DIR/chrooter/chrooter.sh $@ +# } \ No newline at end of file diff --git a/docker-builder-i386/build-base.sh b/docker-builder-i386/build-base.sh index 85036c5..9ce1c8d 100755 --- a/docker-builder-i386/build-base.sh +++ b/docker-builder-i386/build-base.sh @@ -6,6 +6,17 @@ arch=i386 suite=wheezy docker_image="my/debian-$arch:$suite" +OLDDIR=`pwd` +SCRIPT_DIR=$(cd `dirname "$0"`; pwd) +cd "$OLDDIR" +BASE_DIR=`dirname "$SCRIPT_DIR"` + +CONFIG_FILE="$BASE_DIR/config.sh" +if [ -f $CONFIG_FILE ]; then + source $CONFIG_FILE +fi + + if [ -f debian-$suite-$arch.tar.gz ]; then docker import - $docker_image < debian-$suite-$arch.tar.gz else diff --git a/docker-builder-i386/build-tgz.sh b/docker-builder-i386/build-tgz.sh index ac97ff1..edcfe71 100755 --- a/docker-builder-i386/build-tgz.sh +++ b/docker-builder-i386/build-tgz.sh @@ -6,7 +6,6 @@ arch=i386 suite=wheezy chroot_dir="/var/chroot/$suite" apt_mirror="ftp://ftp.debian.org/debian/" -docker_image="my/debian-$arch:$suite" export DEBIAN_FRONTEND=noninteractive debootstrap --arch $arch $suite $chroot_dir $apt_mirror diff --git a/docker-builder-i386/run.sh b/docker-builder-i386/run.sh index 6e9d3ab..67fb260 100755 --- a/docker-builder-i386/run.sh +++ b/docker-builder-i386/run.sh @@ -8,9 +8,6 @@ DATA_DIR="$BASE_DIR/docker-builder-data" BUILD_DIR=$DATA_DIR/build -docker stop "builder-i386" || true -docker rm "builder-i386" || true - CONFIG_FILE="$BASE_DIR/config.sh" PACKET_BUILD_DIR="$BUILD_DIR/packet" SCRIPT_BUILD_DIR="$BUILD_DIR/script" @@ -20,6 +17,9 @@ fi export PACKET_BUILD_DIR mkdir -p $PACKET_BUILD_DIR +docker stop "builder-i386" || true +docker rm "builder-i386" || true + docker run -it \ --name "builder-i386" \ $DOCKER_RUN_OPTIONS \ diff --git a/docker-builder/.gitignore b/docker-builder/.gitignore new file mode 100644 index 0000000..f9d29e1 --- /dev/null +++ b/docker-builder/.gitignore @@ -0,0 +1 @@ +/debian-wheezy-amd64.tar.gz diff --git a/docker-builder/build-base.sh b/docker-builder/build-base.sh new file mode 100755 index 0000000..008f91a --- /dev/null +++ b/docker-builder/build-base.sh @@ -0,0 +1,26 @@ +#!/bin/bash -x + +set -e + +arch=amd64 +suite=wheezy +docker_image="debian:7" + +OLDDIR=`pwd` +SCRIPT_DIR=$(cd `dirname "$0"`; pwd) +cd "$OLDDIR" +BASE_DIR=`dirname "$SCRIPT_DIR"` + +CONFIG_FILE="$BASE_DIR/config.sh" +if [ -f $CONFIG_FILE ]; then + source $CONFIG_FILE +fi + + +if [ -f debian-$suite-$arch.tar.gz ]; then + docker import - $docker_image < debian-$suite-$arch.tar.gz +else + echo "File debian-$suite-$arch.tar.gz not found" + echo "You may try to create it by command ./build-tgz.sh" + echo "or download it from http://icystar.com/downloads/debian-wheezy-i386.tar.gz" +fi diff --git a/docker-builder/build-tgz.sh b/docker-builder/build-tgz.sh new file mode 100755 index 0000000..a42455f --- /dev/null +++ b/docker-builder/build-tgz.sh @@ -0,0 +1,38 @@ +#!/bin/bash -x + +set -e + +arch=amd64 +suite=wheezy +chroot_dir="/var/chroot/$suite" +apt_mirror="ftp://ftp.debian.org/debian/" + +OLDDIR=`pwd` +SCRIPT_DIR=$(cd `dirname "$0"`; pwd) +cd "$OLDDIR" +BASE_DIR=`dirname "$SCRIPT_DIR"` + +CONFIG_FILE="$BASE_DIR/config.sh" +if [ -f $CONFIG_FILE ]; then + source $CONFIG_FILE +fi + + +rm -rf $chroot_dir +export DEBIAN_FRONTEND=noninteractive +debootstrap --arch $arch $suite $chroot_dir $apt_mirror + +cat < $chroot_dir/etc/apt/sources.list +deb $apt_mirror $suite main +deb $apt_mirror $suite-updates main +deb http://security.debian.org/ $suite/updates main +EOF + +chroot $chroot_dir apt-get update +chroot $chroot_dir apt-get upgrade -y +chroot $chroot_dir apt-get autoclean +chroot $chroot_dir apt-get clean +chroot $chroot_dir apt-get autoremove + +tar cfz debian-$suite-$arch.tar.gz -C $chroot_dir . +rm -rf $chroot_dir diff --git a/docker-builder/run.sh b/docker-builder/run.sh index bec9efe..e976d64 100755 --- a/docker-builder/run.sh +++ b/docker-builder/run.sh @@ -8,9 +8,6 @@ DATA_DIR="$BASE_DIR/docker-builder-data" BUILD_DIR=$DATA_DIR/build -docker stop "builder" || true -docker rm "builder" || true - CONFIG_FILE="$BASE_DIR/config.sh" PACKET_BUILD_DIR="$BUILD_DIR/packet" SCRIPT_BUILD_DIR="$BUILD_DIR/script" @@ -20,6 +17,9 @@ fi export PACKET_BUILD_DIR mkdir -p $PACKET_BUILD_DIR +docker stop "builder" || true +docker rm "builder" || true + docker run -it \ --name "builder" \ --privileged=true \ diff --git a/restore_owner.sh b/restore_owner.sh index 6b3999e..9de56e8 100755 --- a/restore_owner.sh +++ b/restore_owner.sh @@ -12,3 +12,4 @@ if [ -f $CONFIG_FILE ]; then fi sudo chown -R `id -un`:`id -gn` $PACKET_BUILD_DIR +sudo chown -R `id -un`:`id -gn` "$BASE_DIR/docker/image"