|
|
e71c94 |
#!/bin/bash
|
|
|
e71c94 |
|
|
|
e71c94 |
set -e
|
|
|
e71c94 |
|
|
|
e71c94 |
OLDDIR=`pwd`
|
|
|
e71c94 |
BASE_DIR=$(cd `dirname "$0"`; pwd)
|
|
|
e71c94 |
cd "$OLDDIR"
|
|
|
e71c94 |
|
|
|
e71c94 |
INSTANCE_NAME=`uuidgen`
|
|
|
e71c94 |
INSTANCE_NAME="chrooter-$INSTANCE_NAME"
|
|
|
e71c94 |
PRIVILEGED=
|
|
|
e71c94 |
IMAGE_MOUNT_DIR=
|
|
|
e71c94 |
COMMAND_ERROR=
|
|
|
e71c94 |
|
|
|
e71c94 |
image_mount_add() {
|
|
|
e71c94 |
echo "Mount: $1 -> $2"
|
|
|
e71c94 |
sudo mkdir -p "$IMAGE_MOUNT_DIR$2"
|
|
|
3082cf |
sudo mount --bind "$1" "$IMAGE_MOUNT_DIR$2"
|
|
|
ec0475 |
echo "umount -f \"$IMAGE_MOUNT_DIR$2\" \\" >> "/tmp/$INSTANCE_NAME.umount.sh"
|
|
|
ec0475 |
echo "|| (echo \"next try after 10 seconds\" && sleep 10 && umount -f \"$IMAGE_MOUNT_DIR$2\") \\" >> "/tmp/$INSTANCE_NAME.umount.sh"
|
|
|
ec0475 |
echo "|| (echo \"final try after 10 seconds\" && sleep 10 && umount -f \"$IMAGE_MOUNT_DIR$2\")" >> "/tmp/$INSTANCE_NAME.umount.sh"
|
|
|
e71c94 |
}
|
|
|
e71c94 |
|
|
|
e71c94 |
image_mount() {
|
|
|
e71c94 |
echo "Mount image: $1"
|
|
|
e71c94 |
|
|
|
e71c94 |
if [ ! -z "$IMAGE_MOUNT_DIR" ]; then
|
|
|
e71c94 |
echo "Image already mounted"
|
|
|
e71c94 |
return 1
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
if [ -z "$1" ]; then
|
|
|
e71c94 |
echo "Image name was not set"
|
|
|
e71c94 |
return 1
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
|
|
|
e71c94 |
local IMAGE_NAME="$(echo $1 | tr "/:" "_")"
|
|
|
e71c94 |
local IMAGE_FILE="$BASE_DIR/image/$IMAGE_NAME.tgz"
|
|
|
e71c94 |
|
|
|
e71c94 |
echo "Unpack image: $1"
|
|
|
e71c94 |
IMAGE_MOUNT_DIR="/tmp/$INSTANCE_NAME"
|
|
|
e71c94 |
mkdir -p "$IMAGE_MOUNT_DIR"
|
|
|
e71c94 |
cd "$IMAGE_MOUNT_DIR"
|
|
|
e71c94 |
sudo tar -xzf $IMAGE_FILE
|
|
|
e71c94 |
cd "$OLDDIR"
|
|
|
e71c94 |
|
|
|
e71c94 |
echo "Add -.chroot.sh file"
|
|
|
e71c94 |
sudo mv "/tmp/$INSTANCE_NAME.chroot.sh" "$IMAGE_MOUNT_DIR"
|
|
|
e71c94 |
sudo chmod a+x "$IMAGE_MOUNT_DIR/$INSTANCE_NAME.chroot.sh"
|
|
|
e71c94 |
|
|
|
e71c94 |
set -- "${@:2}"
|
|
|
e71c94 |
echo "Mount subs: $@"
|
|
|
e71c94 |
echo "#!/bin/sh" > "/tmp/$INSTANCE_NAME.umount.sh"
|
|
|
e71c94 |
echo "" >> "/tmp/$INSTANCE_NAME.umount.sh"
|
|
|
e71c94 |
echo "set -e" >> "/tmp/$INSTANCE_NAME.umount.sh"
|
|
|
e71c94 |
chmod a+x "/tmp/$INSTANCE_NAME.umount.sh"
|
|
|
e71c94 |
if [ ! -z "$PRIVILEGED" ]; then
|
|
|
e71c94 |
echo "Mount /proc and /dev for priveleged feature"
|
|
|
e71c94 |
image_mount_add /proc /proc
|
|
|
e71c94 |
image_mount_add /dev /dev
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
for ARG in $@; do
|
|
|
e71c94 |
SRC="$(echo "$ARG" | cut -d':' -f 1)"
|
|
|
e71c94 |
DEST="$(echo "$ARG" | cut -d':' -f 2-)"
|
|
|
e71c94 |
image_mount_add $SRC $DEST
|
|
|
e71c94 |
done
|
|
|
3c7ba5 |
|
|
|
3c7ba5 |
echo "Add /etc/resolv.conf"
|
|
|
3c7ba5 |
sudo mkdir -p $IMAGE_MOUNT_DIR/etc && cp /etc/resolv.conf $IMAGE_MOUNT_DIR/etc
|
|
|
e71c94 |
}
|
|
|
e71c94 |
|
|
|
e71c94 |
image_unmount() {
|
|
|
e71c94 |
echo "Unmount image"
|
|
|
e71c94 |
|
|
|
e71c94 |
if [ -z "$IMAGE_MOUNT_DIR" ]; then
|
|
|
e71c94 |
echo "Image not mounted"
|
|
|
e71c94 |
return 1
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
|
|
|
e71c94 |
echo "Unmount subs"
|
|
|
ec0475 |
sudo "/tmp/$INSTANCE_NAME.umount.sh"
|
|
|
e71c94 |
sudo rm -f "/tmp/$INSTANCE_NAME.umount.sh"
|
|
|
e71c94 |
|
|
|
e71c94 |
echo "Remove -.chroot.sh file"
|
|
|
e71c94 |
sudo rm -f "$IMAGE_MOUNT_DIR/$INSTANCE_NAME.chroot.sh"
|
|
|
e71c94 |
|
|
|
e71c94 |
if [ ! -z $1 ]; then
|
|
|
e71c94 |
echo "Save image: $1"
|
|
|
e71c94 |
|
|
|
e71c94 |
local IMAGE_NAME="$(echo $1 | tr "/:" "_")"
|
|
|
e71c94 |
local IMAGE_FILE="$BASE_DIR/image/$IMAGE_NAME.tgz"
|
|
|
e71c94 |
local IMAGE_DIR=`dirname "$IMAGE_FILE"`
|
|
|
e71c94 |
mkdir -p "$IMAGE_DIR"
|
|
|
e71c94 |
|
|
|
e71c94 |
cd "$IMAGE_MOUNT_DIR"
|
|
|
e71c94 |
sudo tar -czf $IMAGE_FILE .
|
|
|
e71c94 |
cd "$OLDDIR"
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
|
|
|
e71c94 |
echo "Remove unpacked image"
|
|
|
e71c94 |
sudo rm -rf --one-file-system "$IMAGE_MOUNT_DIR"
|
|
|
e71c94 |
IMAGE_MOUNT_DIR=
|
|
|
e71c94 |
}
|
|
|
e71c94 |
|
|
|
e71c94 |
image_command() {
|
|
|
e71c94 |
echo "Run command: $@"
|
|
|
e71c94 |
|
|
|
e71c94 |
if [ -z "$IMAGE_MOUNT_DIR" ]; then
|
|
|
e71c94 |
echo "Image not mounted"
|
|
|
e71c94 |
return 1
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
|
|
|
3082cf |
if ! env -i /usr/bin/sudo -i chroot "$IMAGE_MOUNT_DIR" "/$INSTANCE_NAME.chroot.sh" $@; then
|
|
|
e71c94 |
COMMAND_ERROR=1
|
|
|
e71c94 |
echo "Command returned with error"
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
}
|
|
|
e71c94 |
|
|
|
2619ef |
image_copy() {
|
|
|
2619ef |
echo "Copy into image: $1 $2"
|
|
|
2619ef |
|
|
|
2619ef |
if ! cp "$1" "$IMAGE_MOUNT_DIR/$2"; then
|
|
|
2619ef |
echo "Cannot copy \"$1\" -> \"$IMAGE_MOUNT_DIR/$2\""
|
|
|
2619ef |
return 1
|
|
|
2619ef |
fi
|
|
|
2619ef |
}
|
|
|
2619ef |
|
|
|
e71c94 |
chroot_file_begin() {
|
|
|
e71c94 |
echo "#!/bin/sh" > "/tmp/$INSTANCE_NAME.chroot.sh"
|
|
|
e71c94 |
echo "" >> "/tmp/$INSTANCE_NAME.chroot.sh"
|
|
|
e71c94 |
}
|
|
|
e71c94 |
|
|
|
e71c94 |
chroot_file_env() {
|
|
|
e71c94 |
echo "Set env: $1=\"$2\""
|
|
|
e71c94 |
echo "export $1=\"$2\"" >> "/tmp/$INSTANCE_NAME.chroot.sh"
|
|
|
e71c94 |
}
|
|
|
e71c94 |
|
|
|
e71c94 |
chroot_file_end() {
|
|
|
e71c94 |
echo "\$@" >> "/tmp/$INSTANCE_NAME.chroot.sh"
|
|
|
e71c94 |
}
|
|
|
e71c94 |
|
|
|
e71c94 |
import() {
|
|
|
e71c94 |
echo "Import $2"
|
|
|
e71c94 |
|
|
|
e71c94 |
if [ ! "$1" = "-" ]; then
|
|
|
e71c94 |
echo "Unknown commandline argument $1"
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
if [ -z "$2" ]; then
|
|
|
e71c94 |
echo "Image name was not set"
|
|
|
e71c94 |
return 1
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
|
|
|
e71c94 |
|
|
|
e71c94 |
local IMAGE_NAME="$(echo $2 | tr "/:" "_")"
|
|
|
e71c94 |
local IMAGE_FILE="$BASE_DIR/image/$IMAGE_NAME.tgz"
|
|
|
e71c94 |
local IMAGE_DIR=`dirname "$IMAGE_FILE"`
|
|
|
e71c94 |
mkdir -p "$IMAGE_DIR"
|
|
|
e71c94 |
cat "/dev/stdin" > $IMAGE_FILE
|
|
|
e71c94 |
}
|
|
|
e71c94 |
|
|
|
e71c94 |
build() {
|
|
|
e71c94 |
echo "Build"
|
|
|
e71c94 |
|
|
|
e71c94 |
local IMAGE_NAME=
|
|
|
e71c94 |
local WORK_DIR=
|
|
|
e71c94 |
|
|
|
e71c94 |
chroot_file_begin
|
|
|
e71c94 |
local MODE=
|
|
|
e71c94 |
for ARG in $@; do
|
|
|
e71c94 |
if [ -z "$WORK_DIR" ]; then
|
|
|
e71c94 |
if [ "$MODE" = "-t" ]; then
|
|
|
e71c94 |
IMAGE_NAME="$ARG"
|
|
|
e71c94 |
echo "Set image name: $IMAGE_NAME"
|
|
|
e71c94 |
MODE=
|
|
|
e71c94 |
continue
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
|
|
|
e71c94 |
if [ ! -z "$MODE" ]; then
|
|
|
e71c94 |
echo "Unknown commandline argument: $MODE"
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
|
|
|
e71c94 |
MODE=
|
|
|
e71c94 |
if [ ! -z "$WORK_DIR" ]; then
|
|
|
e71c94 |
echo "Unknown commandline argument: $ARG"
|
|
|
e71c94 |
elif [ "${ARG:0:1}" = "-" ]; then
|
|
|
e71c94 |
SUBMODE="$(echo "$ARG" | cut -d'=' -f 1)"
|
|
|
e71c94 |
SUBVALUE="$(echo "$ARG" | cut -d'=' -f 2-)"
|
|
|
e71c94 |
if [ "$SUBMODE" = "--build-arg" ]; then
|
|
|
e71c94 |
ENVKEY="$(echo "$SUBVALUE" | cut -d'=' -f 1)"
|
|
|
e71c94 |
ENVVALUE="$(echo "$SUBVALUE" | cut -d'=' -f 2-)"
|
|
|
e71c94 |
chroot_file_env "$ENVKEY" "$ENVVALUE"
|
|
|
e71c94 |
continue
|
|
|
e71c94 |
else
|
|
|
e71c94 |
MODE=$ARG
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
else
|
|
|
e71c94 |
WORK_DIR=$ARG
|
|
|
e71c94 |
echo "Set work dir: $WORK_DIR"
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
done
|
|
|
e71c94 |
if [ ! -z "$MODE" ]; then
|
|
|
e71c94 |
echo "Unknown commandline argument $MODE"
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
chroot_file_end
|
|
|
e71c94 |
|
|
|
e71c94 |
if [ -z "$IMAGE_NAME" ]; then
|
|
|
e71c94 |
echo "Image name was not set"
|
|
|
e71c94 |
return 1
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
|
|
|
e71c94 |
local DOCKERFILE="$WORK_DIR/Dockerfile"
|
|
|
e71c94 |
if [ ! -f "$DOCKERFILE" ]; then
|
|
|
e71c94 |
echo "Dockerfile not found at: $DOCKERFILE"
|
|
|
e71c94 |
return 1
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
|
|
|
e71c94 |
echo "Read $DOCKERFILE"
|
|
|
e71c94 |
FULLROW=
|
|
|
e71c94 |
while read ROW; do
|
|
|
e71c94 |
FULLROW="$FULLROW$ROW"
|
|
|
e71c94 |
LASTCHAR=$((${
|
|
|
e71c94 |
if [ ! "${ROW:LASTCHAR:1}" = "\\" ]; then
|
|
|
e71c94 |
if [ "${FULLROW:0:5}" = "FROM " ]; then
|
|
|
e71c94 |
image_mount "${FULLROW:5}"
|
|
|
e71c94 |
elif [ "${ROW:0:4}" = "RUN " ]; then
|
|
|
e71c94 |
image_command "${FULLROW:4}"
|
|
|
2619ef |
elif [ "${ROW:0:5}" = "COPY " ]; then
|
|
|
2619ef |
image_copy ${FULLROW:5}
|
|
|
e71c94 |
elif [ ! "${FULLROW:0:1}" = "#" ]; then
|
|
|
e71c94 |
if [ ! -z "$FULLROW" ]; then
|
|
|
e71c94 |
echo "Unknown command: $FULLROW"
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
FULLROW=
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
if [ ! -z "$COMMAND_ERROR" ]; then
|
|
|
e71c94 |
echo "Cancel build"
|
|
|
e71c94 |
IMAGE_NAME=""
|
|
|
e71c94 |
break
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
done < "$DOCKERFILE"
|
|
|
e71c94 |
|
|
|
e71c94 |
image_unmount "$IMAGE_NAME"
|
|
|
e71c94 |
}
|
|
|
e71c94 |
|
|
|
e71c94 |
run() {
|
|
|
e71c94 |
local IMAGE_NAME=
|
|
|
e71c94 |
local COMMAND=
|
|
|
e71c94 |
local SUBMOUNT=
|
|
|
e71c94 |
|
|
|
e71c94 |
chroot_file_begin
|
|
|
e71c94 |
local MODE=
|
|
|
e71c94 |
for ARG in $@; do
|
|
|
e71c94 |
if [ ! -z "$COMMAND" ]; then
|
|
|
e71c94 |
COMMAND="$COMMAND $ARG"
|
|
|
e71c94 |
else
|
|
|
e71c94 |
if [ "$MODE" = "-e" ]; then
|
|
|
e71c94 |
ENVKEY="$(echo "$ARG" | cut -d'=' -f 1)"
|
|
|
e71c94 |
ENVVALUE="$(echo "$ARG" | cut -d'=' -f 2-)"
|
|
|
e71c94 |
chroot_file_env "$ENVKEY" "$ENVVALUE"
|
|
|
e71c94 |
MODE=
|
|
|
e71c94 |
continue
|
|
|
e71c94 |
elif [ "$MODE" = "-v" ]; then
|
|
|
e71c94 |
SUBMOUNT="$SUBMOUNT$ARG "
|
|
|
e71c94 |
echo "Add submount: $ARG"
|
|
|
e71c94 |
MODE=
|
|
|
e71c94 |
continue
|
|
|
e71c94 |
elif [ "$MODE" = "--name" ]; then
|
|
|
e71c94 |
echo "Set name: $ARG (not uses)"
|
|
|
e71c94 |
MODE=
|
|
|
e71c94 |
continue
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
|
|
|
e71c94 |
if [ ! -z "$MODE" ]; then
|
|
|
e71c94 |
echo "Unknown commandline argument $MODE"
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
|
|
|
e71c94 |
MODE=
|
|
|
e71c94 |
if [ -z "$MODE" ]; then
|
|
|
e71c94 |
if [ "$ARG" = "--privileged=true" ]; then
|
|
|
e71c94 |
PRIVILEGED=1
|
|
|
e71c94 |
echo "Set privileged: true"
|
|
|
e71c94 |
elif [ "${ARG:0:1}" = "-" ]; then
|
|
|
e71c94 |
MODE=$ARG
|
|
|
e71c94 |
elif [ -z "$IMAGE_NAME" ]; then
|
|
|
e71c94 |
IMAGE_NAME=$ARG
|
|
|
e71c94 |
echo "Set image name: $IMAGE_NAME"
|
|
|
e71c94 |
elif [ -z "$COMMAND" ]; then
|
|
|
e71c94 |
COMMAND=$ARG
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
done
|
|
|
e71c94 |
if [ ! -z "$MODE" ]; then
|
|
|
e71c94 |
echo "Unknown commandline argument $MODE"
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
chroot_file_end
|
|
|
e71c94 |
echo "Set command: $COMMAND"
|
|
|
e71c94 |
|
|
|
e71c94 |
if [ -z "$COMMAND" ]; then
|
|
|
e71c94 |
echo "Command was not set"
|
|
|
e71c94 |
return 1
|
|
|
e71c94 |
fi
|
|
|
e71c94 |
|
|
|
e71c94 |
image_mount "$IMAGE_NAME" $SUBMOUNT
|
|
|
e71c94 |
image_command $COMMAND
|
|
|
e71c94 |
image_unmount
|
|
|
e71c94 |
}
|
|
|
e71c94 |
|
|
|
e71c94 |
|
|
|
e71c94 |
if [ "$1" = "import" ]; then
|
|
|
e71c94 |
set -- "${@:2}"
|
|
|
e71c94 |
import $@
|
|
|
e71c94 |
elif [ "$1" = "build" ]; then
|
|
|
e71c94 |
set -- "${@:2}"
|
|
|
e71c94 |
build $@
|
|
|
e71c94 |
elif [ "$1" = "run" ]; then
|
|
|
e71c94 |
set -- "${@:2}"
|
|
|
e71c94 |
run $@
|
|
|
e71c94 |
else
|
|
|
e71c94 |
echo "Unknown command: $1"
|
|
|
ec0475 |
COMMAND_ERROR=1
|
|
|
ec0475 |
fi
|
|
|
ec0475 |
|
|
|
ec0475 |
if [ ! -z "$COMMAND_ERROR" ]; then
|
|
|
ec0475 |
false
|
|
|
e71c94 |
fi
|