# DO NOT EDIT THIS FILE
#
# This is a Docker launcher file. To set up the configuration, use command line arguments to compile.sh
# or use pass a config file as a parameter ./compile docker [example] BUILD_KERNEL="yes" ...

[[ ! -c /dev/loop-control ]] && display_alert "/dev/loop-control does not exist, image building may not work" "" "wrn"

# second argument can be a build parameter or a config file
# create user accessible directories and set their owner group and permissions
# if they are created from Docker they will be owned by root and require root permissions to change/delete
mkdir -p $SRC/{output,userpatches}
grep -q '^docker:' /etc/group && chgrp --quiet docker $SRC/{output,userpatches}
chmod --quiet g+w,g+s $SRC/{output,userpatches}
VERSION=$(cat $SRC/VERSION)
if grep -q $VERSION <(grep armbian <(docker images)); then
  display_alert "Using existed a armbian Docker container"
else
  # build a new container based on provided Dockerfile
  display_alert "Docker container not found or out of date"
  display_alert "Building a Docker container"
  if ! docker build -t armbian:$VERSION . ; then
    STATUS=$?
    # Adding a newline, so the alert won't be shown in the same line as the error
    echo
    display_alert "Docker container build exited with code: " "$STATUS" "err"
    exit 1
  fi
fi

DOCKER_FLAGS=()

# Running this container in privileged mode is a simple way to solve loop device access issues
# Required for USB FEL or when writing image directly to the block device, when CARD_DEVICE is defined
#DOCKER_FLAGS+=(--privileged)

# add only required capabilities instead (though MKNOD should be already present)
# CAP_SYS_PTRACE is required for systemd-detect-virt in some cases
DOCKER_FLAGS+=(--cap-add=SYS_ADMIN --cap-add=MKNOD --cap-add=SYS_PTRACE)

# mounting things inside the container on Ubuntu won't work without this
# https://github.com/moby/moby/issues/16429#issuecomment-217126586
DOCKER_FLAGS+=(--security-opt=apparmor:unconfined)

# remove resulting container after exit to minimize clutter
# bad side effect - named volumes are considered not attached to anything and are removed on "docker volume prune"
DOCKER_FLAGS+=(--rm)

# pass through loop devices
for d in /dev/loop*; do
	DOCKER_FLAGS+=(--device=$d)
done

# accessing dynamically created devices won't work by default
# and --device doesn't accept devices that don't exist at the time "docker run" is executed
# https://github.com/moby/moby/issues/27886
# --device-cgroup-rule requires new Docker version

# Test for --device-cgroup-rule support. If supported, appends it
# Otherwise, let it go and let user know that only kernel and u-boot for you
if docker run --help | grep device-cgroup-rule > /dev/null 2>&1; then
  # allow loop devices (not required)
  DOCKER_FLAGS+=(--device-cgroup-rule='b 7:* rmw')
  # allow loop device partitions
  DOCKER_FLAGS+=(--device-cgroup-rule='b 259:* rmw')

  # this is an ugly hack, but it is required to get /dev/loopXpY minor number
  # for mknod inside the container, and container itself still uses private /dev internally
  DOCKER_FLAGS+=(-v /dev:/tmp/dev:ro)
else
  display_alert "Your Docker version does not support device-cgroup-rule" "" "wrn"
  display_alert "and will be able to create only Kernel and u-boot packages (KERNEL_ONLY=yes)" "" "wrn"
fi

# Expose ports for NFS server inside docker container, required for USB FEL
#DOCKER_FLAGS+=(-p 0.0.0.0:2049:2049 -p 0.0.0.0:2049:2049/udp -p 0.0.0.0:111:111 -p 0.0.0.0:111:111/udp -p 0.0.0.0:32765:32765 -p 0.0.0.0:32765:32765/udp -p 0.0.0.0:32767:32767 -p 0.0.0.0:32767:32767/udp)
# Export usb device for FEL, required for USB FEL
#DOCKER_FLAGS+=(-v /dev/bus/usb:/dev/bus/usb:ro)

# map source to Docker Working dir.
DOCKER_FLAGS+=(-v=$SRC/:/root/armbian/)

# mount 2 named volumes - for cacheable data and compiler cache
DOCKER_FLAGS+=(-v=armbian-cache:/root/armbian/cache -v=armbian-ccache:/root/.ccache)

DOCKER_FLAGS+=(-e COLUMNS="`tput cols`" -e LINES="`tput lines`")

# pass other command line arguments like KERNEL_ONLY=yes, KERNEL_CONFIGURE=yes, etc.
# pass "docker-guest" as an additional config name that will be sourced in the container if exists
if [[ $SHELL_ONLY == yes ]]; then
  display_alert "Running the container in shell mode" "" "info"
  cat <<\EOF
Welcome to the docker shell of Armbian.

To build the whole thing using default profile, run:
    ./compile.sh

To build the U-Boot only, run:
    # Optional: prepare the environment first if you had not run `./compile.sh`
    ./compile.sh 'prepare_host && compile_sunxi_tools && install_rkbin_tools'

    # build the U-Boot only
    ./compile.sh compile_uboot

If you prefer to use profile, for example, `userpatches/config-my.conf`,  try:
    ./compile.sh my 'prepare_host && compile_sunxi_tools && install_rkbin_tools'
    ./compile.sh my compile_uboot

EOF
  docker run "${DOCKER_FLAGS[@]}" -it --entrypoint /usr/bin/env armbian:$VERSION "$@" /bin/bash
else
  display_alert "Running the container" "" "info"
  docker run "${DOCKER_FLAGS[@]}" -it armbian:$VERSION "$@"
fi

# Docker error treatment
STATUS=$?
# Adding a newline, so the message won't be shown in the same line as the error
echo
case $STATUS in
  0)
    # No errors from either Docker or build script
    echo
    ;;
  125)
    display_alert "Docker command failed, check syntax or version support. Error code:  " "$STATUS" "err"
    ;;
  126)
    display_alert "Failure when running containerd command. Error code:  " "$STATUS" "err"
    ;;
  127)
    display_alert "containerd command not found. Error code:  " "$STATUS" "err"
    ;;
  137)
    display_alert "Container exit from docker stop. Error code:  " "$STATUS" "info"
    ;;
  *)
    # Build script exited with error, but the error message should have been already printed
    echo
    ;;
esac

# don't need to proceed further on the host
exit 0
