diff --git a/.drone.yml b/.drone.yml index 23465945..d59620e5 100644 --- a/.drone.yml +++ b/.drone.yml @@ -7,7 +7,7 @@ platform: steps: - name: build - image: balenalib/armv7hf-golang + image: johndockenson/runner-armhf volumes: - name: dockersock path: /var/run/docker.sock @@ -19,21 +19,12 @@ steps: - git fetch --tags - df -h - losetup -a - - apt-get update - - apt-get dist-upgrade -y - - apt-get install kpartx parted wget curl jq aria2 unzip python3 python3-pip qemu-user-static dmsetup g++-arm-linux-gnueabihf nodejs npm git apt-transport-https ca-certificates gnupg-agent software-properties-common -y - - curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - - - apt-key fingerprint 0EBFCD88 - - add-apt-repository "deb [arch=armhf] https://download.docker.com/linux/debian $(lsb_release -cs) stable" - - apt-get update - - apt-get install docker-ce -y - - python3 -m pip install requests - dmsetup remove_all - losetup -D - bash -c 'export GITHUB_KEY="$GITHUB_KEY";mkdir images && PATH=./node_modules/.bin:$PATH ./builder --noninteractive --armhf' # --arm64 or --armhf, need to implement in builder -- name: deploy-experiment - image: balenalib/armv7hf-golang +- name: deploy + image: johndockenson/runner-armhf volumes: - name: dockersock path: /var/run/docker.sock @@ -43,24 +34,19 @@ steps: privileged: true commands: - pwd - - apt-get update - - apt-get install rsync git ssh -y #- git fetch --tags - echo "$ssh_deploy_key" | base64 --decode --ignore-garbage > .drone/id_deploy - .drone/environment.sh - echo "$experiment" - echo "$image_path" - - .drone/compress.sh + - .drone/compress.sh #split these steps! - .drone/upload.sh when: - branch: - exclude: - - master event: include: - tag -- name: s3-experiment +- name: s3-master image: plugins/s3 settings: bucket: treehouses @@ -68,36 +54,9 @@ steps: from_secret: aws_id secret_key: from_secret: aws_secret - source: /**/build/* # build/* - target: / #strip_prefix: build/ - when: - branch: - exclude: - - master - event: - include: - - tag - -- name: deploy-master - image: balenalib/armv7hf-golang - volumes: - - name: dockersock - path: /var/run/docker.sock - environment: - ssh_deploy_key: - from_secret: ssh_secret - privileged: true - commands: - - pwd - - apt-get update - - apt-get install rsync git ssh -y - #- git fetch --tags - - echo "$ssh_deploy_key" | base64 --decode --ignore-garbage > .drone/id_deploy - - .drone/environment.sh - - echo "$experiment" - - echo "$image_path" - - .drone/compress.sh - - .drone/upload.sh + source: build/* + strip_prefix: build/ + target: / when: branch: - master @@ -105,7 +64,7 @@ steps: include: - tag -- name: s3-master +- name: s3-experiment image: plugins/s3 settings: bucket: treehouses @@ -113,11 +72,13 @@ steps: from_secret: aws_id secret_key: from_secret: aws_secret - source: /**/build/* # build/* - target: / #strip_prefix: build/ + source: build/* + strip_prefix: build/ + target: experiment when: branch: - - master + exclude: + - master event: include: - tag @@ -137,7 +98,7 @@ platform: steps: - name: build - image: balenalib/aarch64-golang + image: johndockenson/runner-arm64 volumes: - name: dockersock path: /var/run/docker.sock @@ -149,21 +110,12 @@ steps: - git fetch --tags - df -h - losetup -a - - apt-get update - - apt-get dist-upgrade -y - - apt-get install kpartx parted wget curl jq aria2 unzip python3 python3-pip qemu-user-static dmsetup g++-aarch64-linux-gnu nodejs npm git apt-transport-https ca-certificates gnupg-agent software-properties-common -y - - curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - - - apt-key fingerprint 0EBFCD88 - - add-apt-repository "deb [arch=arm64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" - - apt-get update - - apt-get install docker-ce -y - - python3 -m pip install requests - dmsetup remove_all - losetup -D - bash -c 'export GITHUB_KEY="$GITHUB_KEY";mkdir images && PATH=./node_modules/.bin:$PATH ./builder --noninteractive --arm64' -- name: deploy-experiment - image: balenalib/aarch64-golang +- name: deploy + image: johndockenson/runner-arm64 volumes: - name: dockersock path: /var/run/docker.sock @@ -173,24 +125,19 @@ steps: privileged: true commands: - pwd - - apt-get update - - apt-get install rsync git ssh -y #- git fetch --tags - echo "$ssh_deploy_key" | base64 --decode --ignore-garbage > .drone/id_deploy - .drone/environment.sh - echo "$experiment" - echo "$image_path" - - .drone/compress.sh + - .drone/compress.sh #split these steps! - .drone/upload.sh when: - branch: - exclude: - - master event: include: - tag -- name: s3-experiment +- name: s3-master image: plugins/s3 settings: bucket: treehouses @@ -198,36 +145,9 @@ steps: from_secret: aws_id secret_key: from_secret: aws_secret - source: /**/build/* # build/* - target: / #strip_prefix: build/ - when: - branch: - exclude: - - master - event: - include: - - tag - -- name: deploy-master - image: balenalib/aarch64-golang - volumes: - - name: dockersock - path: /var/run/docker.sock - environment: - ssh_deploy_key: - from_secret: ssh_secret - privileged: true - commands: - - pwd - - apt-get update - - apt-get install rsync git ssh -y - #- git fetch --tags - - echo "$ssh_deploy_key" | base64 --decode --ignore-garbage > .drone/id_deploy - - .drone/environment.sh - - echo "$experiment" - - echo "$image_path" - - .drone/compress.sh - - .drone/upload.sh + source: build/* + strip_prefix: build/ + target: / when: branch: - master @@ -235,7 +155,7 @@ steps: include: - tag -- name: s3-master +- name: s3-experiment image: plugins/s3 settings: bucket: treehouses @@ -243,11 +163,13 @@ steps: from_secret: aws_id secret_key: from_secret: aws_secret - source: /**/build/* # build/* - target: / #strip_prefix: build/ + source: build/* + strip_prefix: build/ + target: experiment when: branch: - - master + exclude: + - master event: include: - tag @@ -256,19 +178,6 @@ volumes: - name: dockersock host: path: /var/run/docker.sock - -#AWS STUFF HERE -# steps: -# - name: upload -# image: plugins/s3 -# settings: -# bucket: my-bucket-name -# access_key: -# from_secret: aws_access_key_id -# secret_key: -# from_secret: aws_secret_access_key -# source: public/**/* -# target: /target/location --- kind: secret diff --git a/install/etc/install/etc/rc.local b/install/etc/install/etc/rc.local new file mode 100644 index 00000000..f62409de --- /dev/null +++ b/install/etc/install/etc/rc.local @@ -0,0 +1,25 @@ +#!/bin/sh -e +# +# rc.local +# +# This script is executed at the end of each multiuser runlevel. +# Make sure that the script will "exit 0" on success or any other +# value on error. +# +# In order to enable or disable this script just change the execution +# bits. +# +# By default this script does nothing. + +# Print the IP address +_IP=$(hostname -I) || true +if [ "$_IP" ]; then + printf "My IP address is %s\n" "$_IP" +fi + +if [ -f "/etc/tunnel" ]; +then + /etc/tunnel +fi + +exit 0 diff --git a/install/etc/install/etc/systemd/system/autorun.service b/install/etc/install/etc/systemd/system/autorun.service new file mode 100644 index 00000000..5f30070a --- /dev/null +++ b/install/etc/install/etc/systemd/system/autorun.service @@ -0,0 +1,12 @@ +[Unit] +Description=run autorun(once)(.sh) scripts from USB stick or in /boot +After=local_fs.target remote_fs.target network-online.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/local/bin/do_autorun start +Restart=no + +[Install] +WantedBy=multi-user.target diff --git a/install/etc/install/etc/systemd/system/balena.service b/install/etc/install/etc/systemd/system/balena.service new file mode 100644 index 00000000..4003289e --- /dev/null +++ b/install/etc/install/etc/systemd/system/balena.service @@ -0,0 +1,34 @@ +[Unit] +Description=Balena Application Container Engine +Documentation=https://www.balena.io/engine/ +After=network-online.target balena.socket firewalld.service +Wants=network-online.target +Requires=balena.socket + +[Service] +Type=notify +# the default is not to use systemd for cgroups because the delegate issues still +# exists and systemd currently does not support the cgroup feature set required +# for containers run by balena +ExecStart=/usr/bin/balena-engine-daemon -H tcp://0.0.0.0:2375 -H unix:///var/run/balena-engine.sock +ExecReload=/bin/kill -s HUP $MAINPID +LimitNOFILE=1048576 +# Having non-zero Limit*s causes performance problems due to accounting overhead +# in the kernel. We recommend using cgroups to do container-local accounting. +LimitNPROC=infinity +LimitCORE=infinity +# Uncomment TasksMax if your systemd version supports it. +# Only systemd 226 and above support this version. +#TasksMax=infinity +TimeoutStartSec=0 +# set delegate yes so that systemd does not reset the cgroups of balena containers +Delegate=yes +# kill only the balena process, not all processes in the cgroup +KillMode=process +# restart the balena process if it exits prematurely +Restart=on-failure +StartLimitBurst=3 +StartLimitInterval=60s + +[Install] +WantedBy=multi-user.target diff --git a/install/etc/install/etc/systemd/system/balena.socket b/install/etc/install/etc/systemd/system/balena.socket new file mode 100644 index 00000000..8583cad2 --- /dev/null +++ b/install/etc/install/etc/systemd/system/balena.socket @@ -0,0 +1,12 @@ +[Unit] +Description=Balena Socket for the API +PartOf=balena.service + +[Socket] +ListenStream=/var/run/balena.sock +SocketMode=0660 +SocketUser=root +SocketGroup=balena + +[Install] +WantedBy=sockets.target \ No newline at end of file diff --git a/scripts.d/16_pkg_install.sh b/scripts.d/16_pkg_install.sh index a2f5f80c..8dc594f8 100755 --- a/scripts.d/16_pkg_install.sh +++ b/scripts.d/16_pkg_install.sh @@ -39,6 +39,7 @@ INSTALL_PACKAGES=( libhdf5-dev libatlas-base-dev libqt4-test # opencv libjasper1 imagemagick # tiv python3-bcrypt python3-nacl # fix slow pip + netcat-openbsd # ssh ) ARMHF_PACKAGES=( #packages which do not work on arm64 diff --git a/scripts.d/20_balena.sh b/scripts.d/20_balena.sh index 817cd06e..9f9cb787 100755 --- a/scripts.d/20_balena.sh +++ b/scripts.d/20_balena.sh @@ -8,6 +8,14 @@ echo "Balena installation" releases=$(curl -s https://api.github.com/repos/balena-os/balena-engine/releases/latest -H "Authorization: token $GITHUB_KEY" | jq -r ".assets[].browser_download_url") armv6link=$(echo "$releases" | tr " " "\\n" | grep armv6) armv7link=$(echo "$releases" | tr " " "\\n" | grep armv7) +arm64link=$(echo "$releases" | tr " " "\\n" | grep aarch64) + +# arm64 +wget -c "$arm64link" +tar xvzf "$(basename "$arm64link")" ./balena-engine/balena-engine +mv balena-engine/balena-engine mnt/img_root/usr/bin/balena-engine-aarch64 +_op _chroot chown root:root /usr/bin/balena-engine-aarch64 +rm -rf balena-engine/ # armv7 wget -c "$armv7link" @@ -40,3 +48,57 @@ _op _chroot usermod -aG balena root _op _chroot rm -rf /var/lib/balena-engine _op _chroot ln -sr /var/lib/docker /var/lib/balena-engine + +#install balena service scripts + +cat << EOF > mnt/img_root/etc/systemd/system/balena.socket +[Unit] +Description=Balena Socket for the API +PartOf=balena.service + +[Socket] +ListenStream=/var/run/balena.sock +SocketMode=0660 +SocketUser=root +SocketGroup=balena + +[Install] +WantedBy=sockets.target +EOF + +cat << EOF > mnt/img_root/etc/systemd/system/balena.service +[Unit] +Description=Balena Application Container Engine +Documentation=https://www.balena.io/engine/ +After=network-online.target balena.socket firewalld.service +Wants=network-online.target +Requires=balena.socket + +[Service] +Type=notify +# the default is not to use systemd for cgroups because the delegate issues still +# exists and systemd currently does not support the cgroup feature set required +# for containers run by balena +ExecStart=/usr/bin/balena-engine-daemon -H tcp://0.0.0.0:2375 -H unix:///var/run/balena-engine.sock +ExecReload=/bin/kill -s HUP $MAINPID +LimitNOFILE=1048576 +# Having non-zero Limit*s causes performance problems due to accounting overhead +# in the kernel. We recommend using cgroups to do container-local accounting. +LimitNPROC=infinity +LimitCORE=infinity +# Uncomment TasksMax if your systemd version supports it. +# Only systemd 226 and above support this version. +#TasksMax=infinity +TimeoutStartSec=0 +# set delegate yes so that systemd does not reset the cgroups of balena containers +Delegate=yes +# kill only the balena process, not all processes in the cgroup +KillMode=process +# restart the balena process if it exits prematurely +Restart=on-failure +StartLimitBurst=3 +StartLimitInterval=60s + +[Install] +WantedBy=multi-user.target +EOF \ No newline at end of file diff --git a/scripts.d/20_install_files.sh b/scripts.d/20_install_files.sh index ee1fde27..b2316eb8 100755 --- a/scripts.d/20_install_files.sh +++ b/scripts.d/20_install_files.sh @@ -2,326 +2,4 @@ source lib.sh echo "Installing files" -#(cd install || die "ERROR: install folder doesn't exist, exiting"; tar c .) | _op _chroot tar vx --owner=root --group=root - -cat << EOF > /etc/rc.local -#!/bin/sh -e -# -# rc.local -# -# This script is executed at the end of each multiuser runlevel. -# Make sure that the script will "exit 0" on success or any other -# value on error. -# -# In order to enable or disable this script just change the execution -# bits. -# -# By default this script does nothing. - -# Print the IP address -_IP=$(hostname -I) || true -if [ "$_IP" ]; then - printf "My IP address is %s\n" "$_IP" -fi - -if [ -f "/etc/tunnel" ]; -then - /etc/tunnel -fi - -exit 0 -EOF - -cat << EOF > /usr/local/bin/do_autorun -#!/bin/bash - -rebootrequired=0 - -led_mode() { - mode="$1" - trigger=/sys/class/leds/led0/trigger - [ -e $trigger ] && echo "$mode" > $trigger -} - -log() { - echo "do_autorun:" "$@" -} - -find_script() { - base_name="$1" - - for ext in "" .sh .txt; do - script="$base_name$ext" - - if [ -e "$script" ]; then - echo "$script" - return - fi - done -} - -wifiunblock(){ - if [[ $(rfkill list wifi -o soft -n) == "blocked" ]]; then - rfkill unblock wifi - log "wifi unblocked" - fi -} - -autorunonce(){ - log "searching for autorunonce script" - script=$(find_script "$1/autorunonce") - - if [ -z "$script" ]; then - log "no autorunonce found" - return 1 - fi - - newname="$(basename "$script" | sed -e 's/run/ran/')" - newscript="$(dirname "$script")/$newname" - log "moving autorunonce script: $script -> $newscript" - mv -v "$script" "$newscript" - log "converting dos newlines to unix" - dos2unix "$newscript" - sync - log "running autorunonce script $script" - led_mode timer - bash "$newscript" - log "autorunonce script is done" -} - -autorun(){ - log "searching for autorun script" - script=$(find_script "$1/autorun") - - if [ -z "$script" ]; then - log "no autorun script found" - return 1 - fi - - log "converting dos newlines to unix" - dos2unix "$script" - - log "running autorun script $script" - led_mode heartbeat - sudo screen -dmS treehouses bash -c 'sudo '"$script" - log "autorun script started in screen" -} - -onenodeforall() { - arch=$(uname -m) - log "onenodeforall" - if [ "$arch" == "armv6l" ] - then - log "$arch - rpi0/1" - if [ "$(readlink -- /usr/bin/node)" != "node-armv6l" ] - then - unlink /usr/bin/node - ln -sr /usr/bin/node-armv6l /usr/bin/node - fi - elif [ "$arch" == "armv7l" ] - then - log "$arch - rpi2/3" - if [ "$(readlink -- /usr/bin/node)" != "node-armv7l" ] - then - unlink /usr/bin/node - ln -sr /usr/bin/node-armv7l /usr/bin/node - fi - else - log "$arch - something went wrong" - fi -} - -onebalenaforall() { - arch=$(uname -m) - log "onebalenaforall" - if [ "$arch" == "armv6l" ] - then - log "$arch - rpi0/1" - if [ "$(readlink -- /usr/bin/balena)" != "balena-engine-armv6l" ] - then - unlink /usr/bin/balena-engine - ln -sr /usr/bin/balena-engine-armv6l /usr/bin/balena-engine - fi - elif [ "$arch" == "armv7l" ] - then - log "$arch - rpi2/3" - if [ "$(readlink -- /usr/bin/balena-engine)" != "balena-engine-armv7l" ] - then - unlink /usr/bin/balena-engine - ln -sr /usr/bin/balena-engine-armv7l /usr/bin/balena-engine - fi - else - log "$arch - something went wrong" - fi -} - -usbgadget() { - case "$(treehouses detectrpi)" in - RPIZ|RPIZW) - if grep -q -w "^#dtoverlay=dwc2" /boot/config.txt - then - sed -i -e 's/#dtoverlay=dwc2/dtoverlay=dwc2/g' /boot/config.txt - rebootrequired=1 - fi - - if grep -q "#modules-load=dwc2,g_ether" /boot/cmdline.txt - then - sed -i -e 's/#modules-load=dwc2,g_ether/modules-load=dwc2,g_ether/g' /boot/cmdline.txt - rebootrequired=1 - fi - ;; - *) - if grep -q -w "^dtoverlay=dwc2" /boot/config.txt - then - sed -i -e 's/dtoverlay=dwc2/#dtoverlay=dwc2/g' /boot/config.txt - rebootrequired=1 - fi - - if grep -q " modules-load=dwc2,g_ether" /boot/cmdline.txt - then - sed -i -e 's/ modules-load=dwc2,g_ether/ #modules-load=dwc2,g_ether/g' /boot/cmdline.txt - rebootrequired=1 - fi - esac -} - -start() { - led_mode default-on - log "starting" - wifiunblock - usbgadget - onenodeforall - onebalenaforall - if [[ rebootrequired -eq 1 ]] - then - reboot - fi - mkdir -p /data - if [ -b /dev/sda1 ] - then - log "usb stick" - mountpoint -q /data || mount /dev/sda1 /data - cd /data || exit 1 - autorunonce /data || autorun /data - else - log "no usb stick" - cd /boot || exit 1 - autorunonce /boot || autorun /boot - fi -} - -stop() { - log "stopping" - sudo screen -X -S "treehouses" quit -} - - -# Some things that run always -touch /var/lock/autorun - -# Carry out specific functions when asked to by the system -case "$1" in - start) - start - ;; - stop) - stop - ;; - *) - echo "Usage: $0 {start|stop}" - exit 1 - ;; -esac - -exit 0 -EOF - -cat << EOF > /etc/systemd/system/autorun.service -[Unit] -Description=run autorun(once)(.sh) scripts from USB stick or in /boot -After=local_fs.target remote_fs.target network-online.target - -[Service] -Type=oneshot -RemainAfterExit=yes -ExecStart=/usr/local/bin/do_autorun start -Restart=no - -[Install] -WantedBy=multi-user.target - -EOF - -cat << EOF > /etc/systemd/system/balena.service -[Unit] -Description=Balena Application Container Engine -Documentation=https://www.balena.io/engine/ -After=network-online.target balena.socket firewalld.service -Wants=network-online.target -Requires=balena.socket - -[Service] -Type=notify -# the default is not to use systemd for cgroups because the delegate issues still -# exists and systemd currently does not support the cgroup feature set required -# for containers run by balena -ExecStart=/usr/bin/balena-engine-daemon -H tcp://0.0.0.0:2375 -H unix:///var/run/balena-engine.sock -ExecReload=/bin/kill -s HUP $MAINPID -LimitNOFILE=1048576 -# Having non-zero Limit*s causes performance problems due to accounting overhead -# in the kernel. We recommend using cgroups to do container-local accounting. -LimitNPROC=infinity -LimitCORE=infinity -# Uncomment TasksMax if your systemd version supports it. -# Only systemd 226 and above support this version. -#TasksMax=infinity -TimeoutStartSec=0 -# set delegate yes so that systemd does not reset the cgroups of balena containers -Delegate=yes -# kill only the balena process, not all processes in the cgroup -KillMode=process -# restart the balena process if it exits prematurely -Restart=on-failure -StartLimitBurst=3 -StartLimitInterval=60s - -[Install] -WantedBy=multi-user.target -EOF - -cat << EOF > /etc/systemd/system/balena.socket -[Unit] -Description=Balena Socket for the API -PartOf=balena.service - -[Socket] -ListenStream=/var/run/balena.sock -SocketMode=0660 -SocketUser=root -SocketGroup=balena - -[Install] -WantedBy=sockets.target -EOF - -cat << EOF > /etc/systemd/system/rpibluetooth.service -[Unit] -Description=Bluetooth server -After=rpibluetooth.service -Requires=rpibluetooth.service bluetooth.service - -StartLimitIntervalSec=500 -StartLimitBurst=5 - -[Service] -Restart=always -RestartSec=5s - -ExecStart=/usr/bin/python3 /usr/local/bin/bluetooth-server.py & - -[Install] -WantedBy=multi-user.target -EOF - -mkdir -p mnt/img_root/etc/systemd/system/multi-user.target -_op _chroot ln -s /etc/systemd/system/autorun.service /etc/systemd/system/multi-user.target/autorun.service \ No newline at end of file +(cd install || die "ERROR: install folder doesn't exist, exiting"; tar c .) | _op _chroot tar vx --owner=root --group=root \ No newline at end of file diff --git a/scripts.d/40_mirrors_default.sh b/scripts.d/40_mirrors_default.sh new file mode 100755 index 00000000..d8cdc2c8 --- /dev/null +++ b/scripts.d/40_mirrors_default.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +source lib.sh + +if uname -m | grep -q "aarch64" ; then + exit 0 +fi + +cat << EOF > mnt/img_root/etc/apt/sources.list +deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi +#deb http://mirrors.ocf.berkeley.edu/raspbian/raspbian buster main contrib non-free rpi +# Uncomment line below then 'apt-get update' to enable 'apt-get source' +#deb-src http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi +EOF + +_apt update || die "Could not update package sources" \ No newline at end of file