Blame chrooter/chrooter.sh

e71c94
#!/bin/bash
e71c94
e71c94
set -e
e71c94
e71c94
OLDDIR=`pwd`
e71c94
BASE_DIR=$(cd `dirname "$0"`; pwd)
e71c94
cd "$OLDDIR"
e71c94
d7d215
INSTANCE_ID=`uuidgen`
d7d215
INSTANCE_KEY=
e71c94
PRIVILEGED=
9a8dee
COMMANDARCH=
e71c94
IMAGE_MOUNT_DIR=
e71c94
COMMAND_ERROR=
c1cb33
PREFIX="$CHROOTER_PREFIX"
c1cb33
if [ -z "$PREFIX" ]; then
d7d215
	PREFIX="/tmp"
c1cb33
fi
d7d215
FULLPREFIX="$PREFIX/chrooter"
e71c94
d7d215
trap 'raise_error terminated' SIGINT
d7d215
d7d215
raise_error() {
d7d215
	echo "Error: $1"
d7d215
	rm -f "/$FULLPREFIX-$INSTANCE_ID.chroot.sh"
d7d215
	image_unmount
d7d215
	exit 1
d7d215
}
d7d215
d7d215
check_runned() {
d7d215
	if [ ! -z "$INSTANCE_KEY" ]; then
d7d215
		if [ "0" != `mount | grep -c "$FULLPREFIX-$INSTANCE_KEY"` ]; then
d7d215
			raise_error "instance with key '$INSTANCE_KEY', is already running"
d7d215
		fi
d7d215
	fi
d7d215
}
root 993506
e71c94
image_mount_add() {
e71c94
	echo "Mount: $1 -> $2"
a1747c
	sudo mkdir -p "$IMAGE_MOUNT_DIR/root$2"
9a8dee
	sudo mount --bind "$1" "$IMAGE_MOUNT_DIR/root$2"
d7d215
	echo "umount -f \"$IMAGE_MOUNT_DIR/root$2\" || umount -l \"$IMAGE_MOUNT_DIR/root$2\"" >> "$IMAGE_MOUNT_DIR/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
cfe726
	fi
e71c94
	
e71c94
	local IMAGE_NAME="$(echo $1 | tr "/:" "_")"
9a8dee
	local IMAGE_FILE="$BASE_DIR/image/$IMAGE_NAME.iso"
e71c94
	
a1747c
	echo "Prepare image: $1"
d7d215
	IMAGE_MOUNT_DIR="/$FULLPREFIX-$INSTANCE_KEY-$INSTANCE_ID"
9a8dee
	mkdir -p "$IMAGE_MOUNT_DIR/iso"
a1747c
	mkdir -p "$IMAGE_MOUNT_DIR/work"
a1747c
	mkdir -p "$IMAGE_MOUNT_DIR/root"
e71c94
	
e71c94
	echo "Add -.chroot.sh file"
d7d215
	sudo mv "/$FULLPREFIX-$INSTANCE_ID.chroot.sh" "$IMAGE_MOUNT_DIR/work/chroot-$INSTANCE_ID.sh"
d7d215
	sudo chmod a+x "$IMAGE_MOUNT_DIR/work/chroot-$INSTANCE_ID.sh"
a1747c
a1747c
	echo "Mount root"
9a8dee
	sudo mount -r "$IMAGE_FILE" "$IMAGE_MOUNT_DIR/iso"
9a8dee
	sudo mount -wt aufs -o br=$IMAGE_MOUNT_DIR/work:$IMAGE_MOUNT_DIR/iso -o udba=none none $IMAGE_MOUNT_DIR/root/
a1747c
a1747c
	set -- "${@:2}"
e71c94
	echo "Mount subs: $@"
d7d215
	echo "#!/bin/bash" > "$IMAGE_MOUNT_DIR/umount.sh"
d7d215
	chmod a+x "$IMAGE_MOUNT_DIR/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
9a8dee
	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"
a1747c
	sudo cp /etc/resolv.conf $IMAGE_MOUNT_DIR/root/
a1747c
	sudo mkdir -p $IMAGE_MOUNT_DIR/root/etc && sudo cp /etc/resolv.conf $IMAGE_MOUNT_DIR/root/etc/
e71c94
}
e71c94
e71c94
image_unmount() {
e71c94
	echo "Unmount image"
9a8dee
e71c94
	if [ -z "$IMAGE_MOUNT_DIR" ]; then
e71c94
		echo "Image not mounted"
e71c94
		return 1
e71c94
	fi
e71c94
e71c94
	echo "Unmount subs"
d7d215
	sudo "$IMAGE_MOUNT_DIR/umount.sh"
d7d215
	sudo rm -f "$IMAGE_MOUNT_DIR/umount.sh"
e71c94
d7d215
	echo "Remove chroot-.sh file"
d7d215
	sudo rm -f "$IMAGE_MOUNT_DIR/root/chroot-$INSTANCE_ID.sh"
a1747c
e71c94
	if [ ! -z $1 ]; then
e71c94
		echo "Save image: $1"
9a8dee
e71c94
		local IMAGE_NAME="$(echo $1 | tr "/:" "_")"
9a8dee
		local IMAGE_FILE="$BASE_DIR/image/$IMAGE_NAME.iso"
e71c94
		local IMAGE_DIR=`dirname "$IMAGE_FILE"`
e71c94
		mkdir -p "$IMAGE_DIR"
9a8dee
9a8dee
		sudo rm -f "$IMAGE_FILE"
9a8dee
		sudo genisoimage -quiet -R -o "$IMAGE_FILE" "$IMAGE_MOUNT_DIR/root"
e71c94
	fi
a1747c
9a8dee
	sudo umount -R -f "$IMAGE_MOUNT_DIR/root" || umount -R -l "$IMAGE_MOUNT_DIR/root"
9a8dee
	sudo umount -f "$IMAGE_MOUNT_DIR/iso"  || umount -l "$IMAGE_MOUNT_DIR/iso"
a1747c
a1747c
	echo "Remove mount dirs"
e71c94
	sudo rm -rf --one-file-system "$IMAGE_MOUNT_DIR"
e71c94
	IMAGE_MOUNT_DIR=
e71c94
}
e71c94
e71c94
image_command() {
e71c94
	echo "Run command: $@"
9a8dee
e71c94
	if [ -z "$IMAGE_MOUNT_DIR" ]; then
e71c94
		echo "Image not mounted"
e71c94
		return 1
e71c94
	fi
e71c94
9a8dee
	local SETARCH=
9a8dee
	if [ ! -z "$COMMANDARCH" ]; then
9a8dee
		SETARCH=setarch
9a8dee
	fi
9a8dee
d7d215
	if ! env -i /usr/bin/sudo -i $SETARCH $COMMANDARCH chroot "$IMAGE_MOUNT_DIR/root" "/chroot-$INSTANCE_ID.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"
9a8dee
a1747c
	if ! cp "$1" "$IMAGE_MOUNT_DIR/root/$2"; then
a1747c
		echo "Cannot copy \"$1\" -> \"$IMAGE_MOUNT_DIR/root/$2\""
2619ef
		return 1
2619ef
	fi
2619ef
}
2619ef
e71c94
chroot_file_begin() {
d7d215
	echo "#!/bin/sh" > "/$FULLPREFIX-$INSTANCE_ID.chroot.sh"
d7d215
	echo "" >> "/$FULLPREFIX-$INSTANCE_ID.chroot.sh"
e71c94
}
e71c94
e71c94
chroot_file_env() {
9a8dee
	echo "Set env: $1=\"$2\""
d7d215
	echo "export $1=\"$2\"" >> "/$FULLPREFIX-$INSTANCE_ID.chroot.sh"
e71c94
}
e71c94
e71c94
chroot_file_end() {
d7d215
	echo "\$@" >> "/$FULLPREFIX-$INSTANCE_ID.chroot.sh"
e71c94
}
e71c94
e71c94
import() {
e71c94
	echo "Import $2"
9a8dee
e71c94
	if [ ! "$1" = "-" ]; then
9a8dee
		echo "Unknown commandline argument $1"
e71c94
	fi
e71c94
	if [ -z "$2" ]; then
9a8dee
		echo "Image name was not set"
9a8dee
		return 1
e71c94
	fi
9a8dee
9a8dee
e71c94
	local IMAGE_NAME="$(echo $2 | tr "/:" "_")"
d7d215
	INSTANCE_KEY = IMAGE_NAME
d7d215
	check_runned
9a8dee
	local IMAGE_FILE="$BASE_DIR/image/$IMAGE_NAME.iso"
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"
9a8dee
e71c94
	local IMAGE_NAME=
e71c94
	local WORK_DIR=
9a8dee
e71c94
	chroot_file_begin
cfe726
	local MODE=
cfe726
	for ARG in $@; do
cfe726
		if [ -z "$WORK_DIR" ]; then
cfe726
			if [ "$MODE" = "-t" ]; then
cfe726
				IMAGE_NAME="$ARG"
cfe726
				echo "Set image name: $IMAGE_NAME"
cfe726
				MODE=
cfe726
				continue
cfe726
			fi
cfe726
		fi
cfe726
cfe726
		if [ ! -z "$MODE" ]; then
cfe726
			echo "Unknown commandline argument: $MODE"
cfe726
		fi
cfe726
cfe726
		MODE=
cfe726
		if [ ! -z "$WORK_DIR" ]; then
cfe726
			echo "Unknown commandline argument: $ARG"
cfe726
		elif [ "$ARG" = "--privileged=true" ]; then
cfe726
			PRIVILEGED=1
cfe726
			echo "Set privileged: true"
e71c94
		elif [ "${ARG:0:1}" = "-" ]; then
cfe726
			SUBMODE="$(echo "$ARG" | cut -d'=' -f 1)"
cfe726
			SUBVALUE="$(echo "$ARG" | cut -d'=' -f 2-)"
cfe726
			if [ "$SUBMODE" = "--build-arg" ]; then
cfe726
				ENVKEY="$(echo "$SUBVALUE" | cut -d'=' -f 1)"
cfe726
				ENVVALUE="$(echo "$SUBVALUE" | cut -d'=' -f 2-)"
cfe726
				chroot_file_env "$ENVKEY" "$ENVVALUE"
cfe726
				continue
9a8dee
			elif [ "$SUBMODE" = "--buildarch" ]; then
9a8dee
				COMMANDARCH="$SUBVALUE"
9a8dee
				continue
cfe726
			else
cfe726
				MODE=$ARG
cfe726
			fi
cfe726
		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
d7d215
		raise_error "image name was not set"
e71c94
	fi
cfe726
d7d215
	INSTANCE_KEY="$(echo $IMAGE_NAME | tr "/:" "_")"
d7d215
	check_runned
d7d215
a1747c
	local BUILDFILE="$WORK_DIR/Buildfile"
a1747c
	if [ ! -f "$BUILDFILE" ]; then
a1747c
		echo "Buildfile not found at: $BUILDFILE"
e71c94
		return 1
e71c94
	fi
e71c94
a1747c
	echo "Read $BUILDFILE"
e71c94
	FULLROW=
e71c94
	while read ROW; do
e71c94
		FULLROW="$FULLROW$ROW"
e71c94
		LASTCHAR=$((${#ROW}-1))
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
a1747c
	done < "$BUILDFILE"
e71c94
	
e71c94
	image_unmount "$IMAGE_NAME"
e71c94
}
e71c94
e71c94
run() {
e71c94
	local IMAGE_NAME=
e71c94
	local COMMAND=
e71c94
	local SUBMOUNT=
root 993506
e71c94
	chroot_file_begin
root 993506
	local MODE=
root 993506
	for ARG in $@; do
root 993506
		if [ ! -z "$COMMAND" ]; then
root 993506
			COMMAND="$COMMAND $ARG"
root 993506
		else
root 993506
			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
root 993506
			elif [ "$MODE" = "-v" ]; then
e71c94
				SUBMOUNT="$SUBMOUNT$ARG "
root 993506
				echo "Add submount: $ARG"
e71c94
				MODE=
e71c94
				continue
root 993506
			elif [ "$MODE" = "--name" ]; then
d7d215
				echo "Set instance key (name): $ARG"
d7d215
				INSTANCE_KEY="$ARG"
e71c94
				MODE=
e71c94
				continue
root 993506
			fi
root 993506
root 993506
			if [ ! -z "$MODE" ]; then
root 993506
				echo "Unknown commandline argument $MODE"
root 993506
			fi
root 993506
root 993506
			MODE=
root 993506
			if [ -z "$MODE" ]; then
root 993506
				if [ "$ARG" = "--privileged=true" ]; then
root 993506
					PRIVILEGED=1
root 993506
					echo "Set privileged: true"
root 993506
				elif [ "${ARG:0:1}" = "-" ]; then
root 993506
					MODE=$ARG
root 993506
				elif [ -z "$IMAGE_NAME" ]; then
root 993506
					IMAGE_NAME=$ARG
root 993506
					echo "Set image name: $IMAGE_NAME"
root 993506
				elif [ -z "$COMMAND" ]; then
root 993506
					COMMAND=$ARG
root 993506
				fi
root 993506
			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
d7d215
		raise_error "command was not set"
e71c94
	fi
e71c94
d7d215
	check_runned
d7d215
e71c94
	image_mount "$IMAGE_NAME" $SUBMOUNT
e71c94
	image_command $COMMAND
e71c94
	image_unmount
e71c94
}
e71c94
e71c94
e71c94
if [ "$1" = "import" ]; then
9a8dee
	set -- "${@:2}"
9a8dee
	import $@
e71c94
elif [ "$1" = "build" ]; then
9a8dee
	set -- "${@:2}"
9a8dee
	build $@
e71c94
elif [ "$1" = "run" ]; then
9a8dee
	set -- "${@:2}"
9a8dee
	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