commit 0e73abb284be6a5144e3173c5379debd80e425fe Author: Greenscreener Date: Sun Dec 22 18:15:24 2024 +0100 Add example container build setup diff --git a/cobuild/000-setup.sh b/cobuild/000-setup.sh new file mode 100644 index 0000000..4aa8061 --- /dev/null +++ b/cobuild/000-setup.sh @@ -0,0 +1,5 @@ +progress "Installing matfyz-help discord bot" + +install-pkgs python3-venv + +# Do stuff?? diff --git a/cobuild/Dockerfile.top b/cobuild/Dockerfile.top new file mode 100644 index 0000000..dd54e3b --- /dev/null +++ b/cobuild/Dockerfile.top @@ -0,0 +1 @@ + FROM docker://registry.ks.matfyz.cz/gimli/base:bookworm diff --git a/cobuild/try b/cobuild/try new file mode 100755 index 0000000..1369239 --- /dev/null +++ b/cobuild/try @@ -0,0 +1,6 @@ + #!/bin/bash +set -e +common/build cobuild --tag matfyz-help-bot-test +podman rm -if matfyz-help-bot-test +podman create --name matfyz-help-bot-test --hostname matfyz-help-bot-test matfyz-help-bot-test +podman start matfyz-help-bot-test diff --git a/common/build b/common/build new file mode 100755 index 0000000..fe548b1 --- /dev/null +++ b/common/build @@ -0,0 +1,84 @@ +#!/usr/bin/env bash +set -euo pipefail + +gen-init () +{ + echo "COPY common /build/common" +} + +gen-cleanup () +{ + echo "RUN rm -rf /build /data" +} + +gen-docker-file () +{ + if [ -f $src/Dockerfile.top ] ; then + cat $src/Dockerfile.top + gen-init + fi + + for stage in $(cd $src && echo [0-9]*.[a-z]*) ; do + case $stage in + *.docker) + cat $src/$stage + if grep -wq '^FROM' $src/$stage ; then + gen-init + fi + ;; + *.d|*.sh) + echo "COPY $src/$stage /build/$stage" + echo "RUN /build/common/run $stage" + ;; + *) + echo >&2 "ERROR: Unrecognized build stage name $stage" + exit 1 + ;; + esac + done + + if [ -f $src/Dockerfile.bottom ] ; then + cat $src/Dockerfile.bottom + fi + + gen-cleanup +} + +if [ $# = 0 ] ; then + echo >&2 "Usage: $0 []" + exit 1 +fi + +src=$1 +shift + +if [ ! -v http_proxy ] ; then + PROXY= + eval "$(apt-config shell PROXY Acquire::http::proxy)" + if [ -n "$PROXY" ] ; then + export http_proxy=$PROXY + fi +fi + +if [ -v http_proxy -a ! -v https_proxy ] ; then + export https_proxy=$http_proxy +fi + +CACHE_DIR=${XDG_CACHE_HOME:-$HOME/.cache}/container-build +if [ -d $CACHE_DIR ] ; then + echo "Using cache $CACHE_DIR" +else + echo "Creating cache $CACHE_DIR" + mkdir -p $CACHE_DIR +fi +mkdir -p $CACHE_DIR/download + +gen-docker-file | podman build \ + --file - \ + --http-proxy \ + --volume=$CACHE_DIR:/root/.cache \ + "$@" \ + . + +echo -n "Cache usage: " +du -sh $CACHE_DIR | cut -d ' ' -f1 diff --git a/common/lib.sh b/common/lib.sh new file mode 100644 index 0000000..7749180 --- /dev/null +++ b/common/lib.sh @@ -0,0 +1,152 @@ +C_RED="$(echo -e '\e[31m')" +C_GREEN="$(echo -e '\e[32m')" +C_YELLOW="$(echo -e '\e[33m')" +C_NORMAL="$(echo -e '\e[0m')" + +export DEBIAN_FRONTEND=noninteractive +B_APT_UPDATED= + +progress () +{ + echo "${C_GREEN}$1${C_NORMAL}" >&2 +} + +note () +{ + echo "${C_YELLOW}$1${C_NORMAL}" >&2 +} + +warn () +{ + echo "${C_RED}WARNING: $1${C_NORMAL}" >&2 +} + +die () +{ + echo "${C_RED}ERROR: $1${C_NORMAL}" >&2 + exit 1 +} + +update-pkgs () +{ + if [ -z "$B_APT_UPDATED" ] ; then + apt update + B_APT_UPDATED=1 + fi +} + +install-pkgs () +{ + update-pkgs + apt install -y --no-install-recommends --no-install-suggests "$@" +} + +install-config () +{ + [ $# = 2 ] || die "Usage: install-config ( | /)" + local S=$1 + local T=$2 + if [ ${T%/} != $T ] ; then + T=$T$(basename $S) + fi + local B=$BUILD_CONFIG$T + mkdir -p $(dirname $B) $(dirname $T) + if [ -f $T ] ; then + if [ ! -f $B.orig ] ; then + echo "Backing up $T to $B.orig" + cp $T $B.orig + else + echo "Backup of $T already present in $B.orig" + fi + fi + if [ -f $S ] ; then + # Just a new file: overwrite + echo "Overwriting $T" + cp $S $T + cp $S $B.new + elif [ -f $S.orig -a -f $S.new ] ; then + # Try 3-way merge + if cmp --quiet $S.new $T ; then + warn "Skipping merge of $T: changes already present" + else + echo "Merging $T" + if diff3 -m $S.new $S.orig $T >$B.new ; then + cp $B.new $T + else + die "Merge failed, please review $B.new" + fi + fi + else + die "Do not know how to install config $T" + fi +} + +sed-config () +{ + [ $# = 2 ] || die "Usage: sed-config " + local T=$1 + local SCRIPT=$2 + local B=$BUILD_CONFIG$T + mkdir -p $(dirname $B) + [ -f $T ] || die "Want to sed $T, but it is missing" + if [ ! -f $B.orig ] ; then + echo "Backing up $T to $B.orig" + cp $T $B.orig + else + echo "Backup of $T already present in $B.orig" + fi + sed -ri "$SCRIPT" $T + cp $T $B.new +} + +pipe-config () +{ + [ $# = 1 ] || die "Usage: | pipe-config " + local TMP=$(mktemp) + cat >$TMP + install-config $TMP $1 + rm $TMP +} + +rm-config () +{ + [ $# = 1 ] || die "Usage: rm-config " + local T=$1 + local B=$BUILD_CONFIG$T + if [ -f $T ] ; then + if [ ! -f $B.orig ] ; then + echo "Backing up $T to $B.orig" + cp $T $B.orig + fi + echo "Removing $T" + rm -f $T + else + echo "Wanted to remove $T, but it does not exist" + fi +} + +download () +{ + [ $# = 3 ] || die "Usage: download " + local URL=$1 + local HTYPE=$2 + local HASH=$3 + local DEST=$(basename $URL) + local CACHE=/root/.cache/download + if [ -d $CACHE ] ; then + if [ -f $CACHE/$DEST ] ; then + echo "Using cached $DEST" + else + echo "Downloading $URL with caching" + curl -L $URL >$CACHE/$DEST.tmp + mv $CACHE/$DEST.tmp $CACHE/$DEST + fi + ln -s $CACHE/$DEST . + else + warn "Cache $CACHE not found: downloading directly" + echo "Downloading $URL" + curl $URL >$DEST + fi + local H=$(${HTYPE}sum $DEST | cut -d' ' -f1) + [ $H == $HASH ] || die "Mismatched hash: got $H, want $HASH" +} diff --git a/common/run b/common/run new file mode 100755 index 0000000..7a9b355 --- /dev/null +++ b/common/run @@ -0,0 +1,50 @@ +#!/bin/bash +set -euo pipefail + +if [ $# != 1 ] ; then + echo >&2 "Usage: $0 " + exit 1 +fi + +STAGE=$1 + +STAGE=/build/$STAGE +BUILD_COMMON=/build/common +BUILD_CONFIG=/build/config-tmp +. $BUILD_COMMON/lib.sh + +note "Running $STAGE" + +if [ ! -v http_proxy -o ! -v https_proxy ] ; then + warn "No HTTP(S) proxy is set" +fi + +case "$STAGE" in + *.sh) + . $STAGE + exit 0 + ;; + *.d) + ;; + *) + die "Unrecognized stage name $STAGE" +esac + +cd $STAGE + +if [ -f run.sh ] ; then + . run.sh +else + for a in [0-9]* ; do + case "$a" in + *.sh) + ( . $a ) + ;; + *.d) + ( cd $a && . run.sh ) + ;; + *) + warn "Unrecognized build step file $a" + esac + done +fi