#!/bin/bash DEFAULT_ARCH=$(dpkg --print-architecture) function help() { cat << EOF Usage: ./image_builder [command] [additional args...] The 'base' image is after yunohost install script, but before postinstall. It is fetched by ynh-dev for local development. The 'appci' image is after postinstall, with a first user named 'package_checker' as expected by the CI (package_check) Commands: - rebuild [BRANCH] [DIST] Rebuild the base and appci image for BRANCH on DIST - update_appci [BRANCH] [DIST] Update the appci image for BRANCH on DIST Arguments: - BRANCH stable, testing or unstable - DIST bullseye, or bookworm EOF } function main() { KNOWN_COMMANDS=$(declare -F | awk '{print $3}') if [ -z "$1" ] || [ "$1" == "--help" ] then help elif grep -q -w "$1" <<< "$KNOWN_COMMANDS" then cmd="$1" shift 1 $cmd $@ else echo "Unknown command '$1', check --help to list available commands" exit 1 fi } function _publish_image() { local instance_to_publish=$1 local alias_image=$2 # Save the finger print to delete the old image later local finger_print_to_delete=$(incus image info "$alias_image" | grep Fingerprint | awk '{print $2}') local should_restart=0 # If the container is running, stop it if [ "$(incus info $instance_to_publish | grep Status | awk '{print tolower($2)}')" = "running" ] then should_restart=1 incus stop "$instance_to_publish" fi # Create image before install incus publish "$instance_to_publish" --alias "$alias_image" --reuse --public "${@:3}" # Remove old image incus image delete "$finger_print_to_delete" if [ $should_restart = 1 ] then incus start "$instance_to_publish" sleep 5 fi } function rebuild() { local YNH_BRANCH=${1:-stable} local DIST=${2:-bullseye} local ARCH=${3:-$DEFAULT_ARCH} local img_name=$YNH_BRANCH-$DIST-$ARCH set -x incus info $img_name >/dev/null && incus delete $img_name --force if [ $DEFAULT_ARCH = $ARCH ]; then incus launch images:debian/$DIST/$ARCH $img_name -c security.privileged=true -c security.nesting=true else incus image info $img_name >/dev/null && incus image delete $img_name tmp_dir=$(mktemp -d) pushd $tmp_dir incus image export images:debian/$DIST/$ARCH tar xJf lxd.tar.xz sed -i "0,/architecture: $ARCH/s//architecture: $DEFAULT_ARCH/" metadata.yaml tar cJf lxd.tar.xz metadata.yaml templates incus image import lxd.tar.xz rootfs.squashfs --alias $img_name popd rm -rf "$tmp_dir" incus launch $img_name $img_name -c security.privileged=true -c security.nesting=true fi sleep 5 IN_CONTAINER="incus exec $img_name --" local INSTALL_SCRIPT="https://install.yunohost.org/$DIST" $IN_CONTAINER apt install curl -y $IN_CONTAINER /bin/bash -c "echo exit 101 > /usr/sbin/policy-rc.d" $IN_CONTAINER /bin/bash -c "chmod +x /usr/sbin/policy-rc.d" $IN_CONTAINER /bin/bash -c "curl $INSTALL_SCRIPT | bash -s -- -a -d $YNH_BRANCH" $IN_CONTAINER /bin/bash -c "rm /usr/sbin/policy-rc.d" $IN_CONTAINER systemctl -q disable apt-daily.timer --now $IN_CONTAINER systemctl -q disable apt-daily-upgrade.timer --now $IN_CONTAINER systemctl -q disable apt-daily.service --now $IN_CONTAINER systemctl -q disable apt-daily-upgrade.service --now $IN_CONTAINER rm -f /etc/cron.daily/apt-compat $IN_CONTAINER cp /bin/true /usr/lib/apt/apt.systemd.daily # Disable services that are useless in the vast majority of cases to try to improve perfs $IN_CONTAINER systemctl -q disable rspamd --now $IN_CONTAINER systemctl -q disable dovecot --now $IN_CONTAINER systemctl -q disable postsrsd --now $IN_CONTAINER systemctl -q disable metronome --now $IN_CONTAINER systemctl -q disable yunohost-api --now $IN_CONTAINER systemctl -q disable fake-hwclock.service --now $IN_CONTAINER systemctl -q disable yunoprompt --now $IN_CONTAINER systemctl -q disable haveged.service --now $IN_CONTAINER systemctl -q disable metronome.service --now $IN_CONTAINER systemctl -q disable unattended-upgrades.service --now $IN_CONTAINER systemctl -q disable e2scrub_all.timer $IN_CONTAINER systemctl -q disable logrotate.timer $IN_CONTAINER systemctl -q disable phpsessionclean.timer $IN_CONTAINER systemctl -q disable systemd-tmpfiles-clean.timer $IN_CONTAINER sed -i 's/worker_processes.*;/worker_processes 4;/g' /etc/nginx/nginx.conf $IN_CONTAINER /bin/bash -c "reboot 0" sleep 5 # Publish ynh-dev image local INCUS_BASE="ynh-dev-$DIST-$ARCH-$YNH_BRANCH-base" _publish_image $img_name $INCUS_BASE "os=YunoHost" "ynh-release=$YNH_BRANCH" "stage=ynh-dev" "release=${DIST^}" "architecture=$ARCH" "description=YunoHost $DIST $YNH_BRANCH ynh-dev $ARCH ($(date '+%Y%m%d'))" local YUNO_PWD="SomeSuperStrongPassword" local DOMAIN="domain.tld" local SUBDOMAIN="sub.$DOMAIN" local TEST_USER="package_checker" local TEST_USER_DISPLAY=${TEST_USER//"_"/""} # 240501: fix because the container was not getting an IP $IN_CONTAINER dhclient eth0 # Disable password strength check $IN_CONTAINER yunohost tools postinstall --domain $DOMAIN --password $YUNO_PWD --username $TEST_USER --fullname "$TEST_USER_DISPLAY" $IN_CONTAINER /bin/bash -c "echo 'admin_strength: -1' >> /etc/yunohost/settings.yml" $IN_CONTAINER /bin/bash -c "echo 'user_strength: -1' >> /etc/yunohost/settings.yml" $IN_CONTAINER yunohost domain add $SUBDOMAIN $IN_CONTAINER yunohost --version INCUS_BASE="ynh-appci-$DIST-$ARCH-$YNH_BRANCH-base" incus stop $img_name _publish_image $img_name $INCUS_BASE "os=YunoHost" "ynh-release=$YNH_BRANCH" "stage=ynh-appci" "release=${DIST^}" "architecture=$ARCH" "description=YunoHost $DIST $YNH_BRANCH ynh-appci $ARCH ($(date '+%Y%m%d'))" incus delete $img_name set +x } function update_appci() { local YNH_BRANCH=${1:-stable} local DIST=${2:-bullseye} local ARCH=${3:-$(dpkg --print-architecture)} local img_name=$YNH_BRANCH-$DIST-$ARCH set -x incus launch ynh-dev-$DIST-$ARCH-$YNH_BRANCH-base $img_name -c security.privileged=true -c security.nesting=true IN_CONTAINER="incus exec $img_name --" sleep 3 echo "nameserver 8.8.8.8" | $IN_CONTAINER tee /etc/resolv.conf sleep 3 $IN_CONTAINER ping -c3 deb.debian.org || exit 1 $IN_CONTAINER apt update $IN_CONTAINER apt dist-upgrade -y local YUNO_PWD="SomeSuperStrongPassword" local DOMAIN="domain.tld" local SUBDOMAIN="sub.$DOMAIN" local TEST_USER="package_checker" local TEST_USER_DISPLAY=${TEST_USER//"_"/""} # Disable password strength check $IN_CONTAINER yunohost tools postinstall --domain $DOMAIN --password $YUNO_PWD --username $TEST_USER --fullname "$TEST_USER_DISPLAY" $IN_CONTAINER /bin/bash -c "echo 'admin_strength: -1' >> /etc/yunohost/settings.yml" $IN_CONTAINER /bin/bash -c "echo 'user_strength: -1' >> /etc/yunohost/settings.yml" $IN_CONTAINER yunohost domain add $SUBDOMAIN $IN_CONTAINER yunohost --version INCUS_BASE="ynh-appci-$DIST-$ARCH-$YNH_BRANCH-base" incus stop $img_name _publish_image $img_name $INCUS_BASE "os=YunoHost" "ynh-release=$YNH_BRANCH" "stage=ynh-appci" "release=${DIST^}" "architecture=$ARCH" "description=YunoHost $DIST $YNH_BRANCH ynh-appci $ARCH ($(date '+%Y%m%d'))" incus delete $img_name set +x } #function from_stable_to_another_version() #{ # local YNH_BRANCH=${1:-testing} # local DIST=${2:-bullseye} # local ARCH=${3:-$DEFAULT_ARCH} # local BASE_IMG=${4:-stable} # local OLD_INCUS_BASE="ynh-dev-$DIST-$ARCH-$BASE_IMG-base" # local NEW_INCUS_BASE="ynh-dev-$DIST-$ARCH-$YNH_BRANCH-base" # # local CUSTOMAPT=/etc/apt/sources.list.d/yunohost.list # # if [[ "$YNH_BRANCH" == "testing" ]] ; then # CHANNELS="testing" # elif [[ "$YNH_BRANCH" == "unstable" ]] ; then # CHANNELS="testing unstable" # fi # # local CUSTOMDEB="deb [signed-by=/usr/share/keyrings/yunohost-archive-keyring.gpg] http://forge.yunohost.org/debian/ $DIST stable $CHANNELS" # # #curl --fail --silent https://forge.yunohost.org/yunohost_bullseye.asc | gpg --dearmor > /usr/share/keyrings/yunohost-archive-keyring.gpg # # set -x # IN_CONTAINER="incus exec $NEW_INCUS_BASE --" # # incus launch $OLD_INCUS_BASE $NEW_INCUS_BASE -c security.privileged=true -c security.nesting=true # sleep 5 # # $IN_CONTAINER /bin/bash -c "echo '$CUSTOMDEB' > $CUSTOMAPT" # $IN_CONTAINER /bin/bash -c "apt-get update" # $IN_CONTAINER /bin/bash -c "apt-get dist-upgrade -y" # # incus stop $NEW_INCUS_BASE # _publish_image $NEW_INCUS_BASE $NEW_INCUS_BASE "os=YunoHost" "ynh-release=$YNH_BRANCH" "stage=ynh-dev" "release=${DIST^}" "architecture=$ARCH" "description=YunoHost $DIST $YNH_BRANCH ynh-dev $ARCH ($(date '+%Y%m%d'))" # incus delete $NEW_INCUS_BASE # # OLD_INCUS_BASE="ynh-appci-$DIST-$ARCH-stable-base" # NEW_INCUS_BASE="ynh-appci-$DIST-$ARCH-$YNH_BRANCH-base" # IN_CONTAINER="incus exec $NEW_INCUS_BASE --" # # incus launch $OLD_INCUS_BASE $NEW_INCUS_BASE -c security.privileged=true -c security.nesting=true # sleep 5 # # $IN_CONTAINER /bin/bash -c "echo '$CUSTOMDEB' > $CUSTOMAPT" # $IN_CONTAINER /bin/bash -c "apt-get update" # $IN_CONTAINER /bin/bash -c "apt-get dist-upgrade -y" # # $IN_CONTAINER /bin/bash -c "echo 'admin_strength: -1' >> /etc/yunohost/settings.yml" # $IN_CONTAINER /bin/bash -c "echo 'user_strength: -1' >> /etc/yunohost/settings.yml" # # incus stop $NEW_INCUS_BASE # _publish_image $NEW_INCUS_BASE $NEW_INCUS_BASE "os=YunoHost" "ynh-release=$YNH_BRANCH" "stage=ynh-appci" "release=${DIST^}" "architecture=$ARCH" "description=YunoHost $DIST $YNH_BRANCH ynh-appci $ARCH ($(date '+%Y%m%d'))" # incus delete $NEW_INCUS_BASE # set +x #} main $@