#!/bin/bash # Chroot instructions # ArchLinux root via pacstrap, configured with build tools # User: builduser 1000 ROOTFS_BASE='/opt/micobu/rootfs' ROOTFS_DIR='/home/builduser/base' # in rootfs ARTEFACT_BASE='/opt/micobu/rootfs/home/builduser/artefacts' BUILD_TIMEOUT='600' API_KEY='mykey' SERVER_PIPE="/run/user/`id -u`/micobu.pipe" SERVER_LOCK="/run/user/`id -u`/micobu.lock" BUILD_BASE=$ROOTFS_BASE$ROOTFS_DIR function build() { NAME="$1" REPO="$2" HASH="$3" BUILD_DIR="$BUILD_BASE/$NAME" ARTEFACT_DIR="$ARTEFACT_BASE/$NAME/$HASH" MICOBU_TEMP_NAME="$NAME/micobu_$HASH" # Relative to $BUILD_BASE if [ -d "$ARTEFACT_DIR" ]; then echo "$NAME revision $HASH has already been built." echo "Removing old version" rm -rf $ARTEFACT_DIR #return fi echo "[env] Building in $BUILD_DIR." if [ ! -d "$BUILD_DIR" ]; then echo "[git] Performing initial clone" mkdir -p $BUILD_DIR git clone --recurse-submodules "$REPO" "$BUILD_DIR" cd $BUILD_DIR else echo "[git] Updating existing repo." cd $BUILD_DIR git fetch fi git clean -xdf git reset --hard git checkout $HASH DESCRIPTION="`git describe --all --always`" mkdir -p $BUILD_BASE/$MICOBU_TEMP_NAME mkdir -p $ARTEFACT_DIR echo "[sec] Creating jail" META_DATE_START="`date '+%s'`" set +e set -o pipefail firejail --noprofile --chroot=$ROOTFS_BASE --net=none --read-write="$BUILD_BASE/" env -i HOME=$ROOTFS_DIR/$NAME PATH=/bin:/usr/bin MCB_NAME=$NAME MCB_ARTEFACTS=$ROOTFS_DIR/$MICOBU_TEMP_NAME "bash" "-c" "cd ~; timeout $BUILD_TIMEOUT ~/micobu.sh" | tee $ARTEFACT_DIR/log.txt RET=$? set +o pipefail set -e META_DATE_STOP="`date '+%s'`" cat < $ARTEFACT_DIR/meta.json { "name" : "$NAME", "url" : "$REPO", "hash" : "$HASH", "description" : "$DESCRIPTION", "time_start" : "$META_DATE_START", "time_stop" : "$META_DATE_STOP", "result" : "$RET" } EOF cd $BUILD_BASE/$MICOBU_TEMP_NAME if [ "`ls`" == "" ]; then echo "No artefacts generated." else tar cvJf $ARTEFACT_DIR/artefacts.tar.xz * echo "Stored artefacts in $ARTEFACT_DIR" find $ARTEFACT_DIR fi cd $ARTEFACT_DIR cat $ARTEFACT_DIR/meta.json echo "" if [ $RET -eq 0 ]; then echo 'BUILD SUCCEEDED!' else echo "BUILD FAILED (exit code $RET)!" fi return 0 } function build_s() { if [ "$1" != "$API_KEY" ]; then echo "error: invalid key" return fi shift echo Starting build of $@ build $@ rm "$SERVER_LOCK" echo "" > $SERVER_PIPE } set -e rm -f "$SERVER_LOCK" [ ! -p "$SERVER_PIPE" ] && mkfifo "$SERVER_PIPE" a=() while true; do line=`head -n 1 $SERVER_PIPE | sed -n 's/\([a-zA-Z0-9]\+\) \([a-zA-Z0-9]\+\) \([a-zA-Z0-9:\-_\/\.]\+\) \([a-z0-9]\+\)/\1 \2 \3 \4/p'` if [ "$line" != "" ]; then a=("${a[@]}" "$line") fi if [ "$a" != "" ]; then if [ ! -f "$SERVER_LOCK" ]; then echo "Starting build: $a" touch "$SERVER_LOCK" build_s $a & a=("${a[@]:1}") fi fi done