#!/bin/bash
# minimal config version
MIN_VERSION="3.0"

CFG=/etc/notamock.cfg
CFGD=/etc/notamock.d

# special config for project
if [ -f './notamock.cfg' ] ; then
        CFG=$(realpath ./notamock.cfg)
        CFGD=''
fi

PLATFORM=$(rpm --eval %distro_release)
UPD=${UPD:-"yes"}
VARIABLES=''
BUILD_args=''
PARALLEL=1
WATCH_LINES=5
BUILDER_NAME=$(hostname)
VERBOSE=yes
unset DOCKER

HLP(){
BT=Lx4cCDuVhMdG6eJbcTKs
echo "$0 - utility to run notamock based abf  builders"
echo "Usage:
    $0 <variables> <parameters>"
echo "Parameters:
    -c | --config        -  specify config file, default is /etc/notamock.cfg
    -h | --help          -  this help
    -t | --token         -  abf token
    -u | --update        -  assemble or rebuild new rootfs
    -b | --builder_name  -  builder ID (hostname in abf terminology)
    -s | --shell         -  shell in build container instead run notamocka script
    -p | --parallel      -  number of builders
    -R | --rootfsonly    -  build rootfs and exit
    -B | --build-space   -  host directory to use for build processes in container
    -w | --watch         -  Monitor processes using the watch command
                            (optional:  specify line count per process, by default $WATCH_LINES)
    -P | --proxy         -  setup angie as proxy to make common rpm cache for builers
    -d | --docker        -  create image for docker
"
echo "Examples:
    $(basename $0) -t $BT         - run container with one builder
    $(basename $0) -t $BT -p 5    - run container with five builders
    $(basename $0) -t $BT -B /tmp - run builder container and set host dir '/tmp' as dir for build processes
    $(basename $0) -t $BT -p 3 --watch 10 --tmux
                                  - run in monitor mode, useful for debug
    Docker:
    # Create docker image with builder name - my_worker
    $(basename $0) --docker -b my_worker

    # Run container in foreground:
    # Runs interactively (-it) with 3 parallel builders (PARALLEL=3)
    # Mounts host directory to container's /tmp:
    # * You can mount ANY directory with sufficient free space using -v /host/path:/tmp
    # * This directory will be used by builders for:
    #   - storing temporary files during RPM builds
    #   - cach of caching proxy (if container build with --proxy)

    docker run -it --rm --privileged
               -e BUILD_TOKEN=\"$BT\"
               -e PARALLEL=\"3\"
               -v /tmp:/tmp notamockd:my_worker

    # Alternative with parameters for notamocka (ENTRYPOINT):
    # Note: When passing parameters this way, the builder name specified during
    # image creation will NOT be used. You must either:
    # 1) Specify it with -b flag explicitly
    # 2) Or random value from container's hostname will be used

    docker run -it --rm --privileged
               -v /tmp:/tmp notamockd:my_worker
               -b my_worker -t $BT -p 3

    # Run container with one builder named \"first\" in background:

    docker run -d --rm --privileged
               -v /tmp:/tmp
               notamockd:my_worker
               -b first -t $BT
    "
exit
}

NOTAMOCKLIB="/usr/share/notamock/libnotamock"
[ -f './libnotamock' ] && NOTAMOCKLIB=./libnotamock
source "$NOTAMOCKLIB"

echo "==> $(basename $0): find parameters"
sep=''
while [ -n "$1" ] ; do
    case "${1}" in
    "-h" | "--help") HLP ;;
    "-c" | "--config")  shift
                        CFG="$1"
                        CFGD='' ;;
    "-t" | "--token") shift ; TOKEN="$1" ;;
    "-u" | "--update") RF_BUILD=yes ;;
    "-b" | "--builder_name") shift ; BUILDER_NAME="$1" ;;
    "-p" | "--parallel") shift ; PARALLEL="$1" ;;
    "-s" | "--shell" ) START='/bin/bash' ;;
    "-R" | "--rootfsonly" ) ROOTFSONLY='yes' ;;
    "-d" | "--docker" )     DOCKER='yes' ;;
    "-r" | "--release") shift ; PLATFORM="$1" ;;
    "-B" | "--build-space") shift ; BUILD_SPACE="$1" ;;
    "-P" | "--proxy") CPROXY='yes' ;;
    "--tmux")   TMUX="yes" ;;
    "--watch" ) WATCH="yes"
                if expr $2 + 1 ; then
                    shift
                    WATCH_LINES="$1"
                fi >/dev/null 2>&1 ;;
    *)  if echo "$1" |grep -q '=' ; then
            VARIABLES="${VARIABLES}${sep}$(echo $1 |sed 's/ /#/g')"
            sep=' '
        else
            echo_exit "Unknown parameter: $1" ${LINENO}
        fi;;
    esac
shift
done
echo "==> $(basename $0): setting up variables from cmdline"

source "$CFG"
VER=${CFG_VERSION:-0.1}
if [ $(echo -e "$VER\n$MIN_VERSION" |sort -V| tail -n1) != "$VER" ] ; then
    echo "Version of config file is less then minimum required for $0.
$VER < $MIN_VERSION
Please update $CFG from /usr/share/notamock/default.notamock.cfg"
        exit
fi

if [ -d "$CFGD" ] ; then
    for a in $(ls -1 ${CFGD}/. |sort ) ; do
        vrun source ${CFGD}/$a
    done
fi

for a in $VARIABLES; do
    echo "==> $(basename $0): variable: $a"
    a=$(echo $a |sed 's/#/ /g')
    if echo "$a" |grep -q '[[:alnum:]]*+=.*$' ; then
        eval $(echo $a |sed -e 's/=/=("/' -e 's/$/")/')
    elif echo "$a" |grep -q '[[:alnum:]]*=.*$' ; then
        eval $(echo $a |sed -e 's/=/="/' -e 's/$/"/')
    fi
done

PM_opts="$PM_opts \
$PM_cfg_opt $PM_config \
$PM_addrep_opt $PM_cache"

[ ! "$DOCKER" ] && [ $(echo "$TOKEN" |wc -c) -lt 10 ] && echo_exit "Need abf token" ${LINENO}
[ "$DOCKER" ] && ! systemctl is-active docker && echo_exit "Docker service inactive" ${LINENO}

# separated rootfs with no basesystem-build for docker container
if [ "$DOCKER" ] ; then
    ROOTFSNAME="${ROOTFSNAME}_docker"
    PM_list="$PM_list_docker"
    echo -e "==> $(basename $0): PM_list for docker container rootfs:\n$PM_list"
fi

# build new rootfs if not exists, or key "-u" enabled
if [ ! -f ${BASE}/${ROOTFSNAME}/bin/bash ] || [ "$RF_BUILD" ] ; then
    build_new_rootfs
elif ! cat /proc/mounts |grep -q "${BASE}/$ROOTFSNAME" ; then
    update_rootfs
fi

mkdir -p $TMPD || echo_exit "Cannot create temporary directory" ${LINENO}

BUILD_DIR=${TMPD}/$BUILDER_NAME
[ -d "$BUILD_DIR" ] && echo_exit "$BUILD_DIR already exists!" ${LINENO}
mkdir -p $BUILD_DIR
echo "==> $(basename $0): Build dir: $BUILD_DIR"
OVERLAY=${BUILD_DIR}/overlay
WORKDIR=${BUILD_DIR}/work
UPPERDIR=${BUILD_DIR}/upper
mkdir -p $OVERLAY $WORKDIR $UPPERDIR

trap 'clear_overlay "/var/lib/notamock" "/tmp/notamock"' EXIT

# wait direct update of rootfs by another notamock process
waitfor "${BASE}/${ROOTFSNAME}.lock" "==> $(basename $0): waiting while another notamock process update rootfs"

LOWERDIR="${BASE}/$ROOTFSNAME"

vrun mount -t overlay overlay -o lowerdir="${LOWERDIR}",upperdir="$UPPERDIR",workdir="$WORKDIR" "$OVERLAY"
[ $? != 0 ] &&  echo_exit "Mounting overlay - error!" ${LINENO}
vrun $PM_update $PM_root_opt "$OVERLAY" $PM_opts

touch  ${OVERLAY}/etc/machine-id

# bind current $BASE to builders rootfs container
mkdir -p "${OVERLAY}/var/lib/notamock"
[ "$DOCKER" ] || mount -o bind $BASE "${OVERLAY}/var/lib/notamock"

# additional environment variables for container
: > "${OVERLAY}/ENV.lst"
for str in $(seq 0 $(( ${#ENV[@]} - 1 )) ) ; do
    echo "==> $(basename $0): set env: ${ENV[$str]}"
    echo "export ${ENV[$str]}" >> "${OVERLAY}/ENV.lst"
done

# add angie if --proxy
[ "$CPROXY" ] && BUILDER_list="$BUILDER_list angie"

vrun $PM_install $PM_opts $PM_root_opt $OVERLAY $BUILDER_list

# notamock conf to use in builders container
if [ "$BUILDER_notamock_cfg" != "INTERNAL" -a -f "$BUILDER_notamock_cfg" ] ; then
    echo "==> $(basename $0): replacing container notamock config to $BUILDER_notamock_cfg"
    cp -f "$BUILDER_notamock_cfg" "${OVERLAY}/etc/notamock.cfg"
fi

if [ ! "$DOCKER" ] && [ "$BUILD_SPACE" ] && [ -d "$BUILD_SPACE" ]; then
    BUILD_SPACE=$(realpath $BUILD_SPACE)
    mkdir -p ${OVERLAY}/mnt/build_space
    mount -o bind  $BUILD_SPACE ${OVERLAY}/mnt/build_space
    echo -e "\n#####################" >> ${OVERLAY}/etc/notamock.cfg
    echo "TMPD=/mnt/build_space" >> ${OVERLAY}/etc/notamock.cfg
elif [ "$BUILD_SPACE" ]  ; then
    clear_overlay '/mnt/build_space'
    echo_exit  "$BUILD_SPACE is not a directory" ${LINENO}
fi
[ "$CHROOT" == 'INTERNAL' ] && CHROOT="chroot_internal"

if ! [ "$START" ] ; then
    START="$(echo -n "/usr/bin/notamocka -b $BUILDER_NAME"
    [ $DOCKER ] || echo -n " -p $PARALLEL"
    [ $TOKEN ] && echo -n " -t $TOKEN"
    [ $TMUX ] && echo -n " --tmux "
    [ $WATCH ] && echo -n " --watch $WATCH_LINES" )"
fi

if [ "$ROOTFSONLY" ] ; then
    echo "Container ready to run"
    echo "$CHROOT $OVERLAY $START"
    exit 0
elif [ "$DOCKER" ] ; then
    echo "FROM scratch" > /tmp/Dockerfile.notamock
    echo "MAINTAINER notamockd <support@rosa.ru>" >> /tmp/Dockerfile.notamock
    echo "COPY ./overlay/ /" >> /tmp/Dockerfile.notamock
    echo 'ENTRYPOINT ["/usr/bin/notamocka"]' >> /tmp/Dockerfile.notamock
    echo "CMD [\"-b\", \"$BUILDER_NAME\"]" >> /tmp/Dockerfile.notamock
    vrun docker build --no-cache -f /tmp/Dockerfile.notamock $BUILD_DIR -t "notamockd:$BUILDER_NAME" && \
    echo "==> $(basename $0): RootFS successfully built: $OVERLAY"
else
    echo "==> $(basename $0): run in container: $START"
    vrun $CHROOT "$OVERLAY" $START
fi
echo "==> $(basename $0): Exit from container: $OVERLAY"
if clear_overlay '/var/lib/notamock' '/mnt/build_space' ; then
    echo "==> $(basename $0): Remove container succesfully"
else
    echo "==> $(basename $0): Remove  container:  $OVERLAY - FALED!"
fi

