Container build system
This commit is contained in:
parent
df44328c35
commit
cdb06b320c
8 changed files with 306 additions and 0 deletions
4
cobuild/000-setup.sh
Normal file
4
cobuild/000-setup.sh
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
progress "Installing Hrochobot"
|
||||||
|
|
||||||
|
cd /build/src
|
||||||
|
pip install .
|
13
cobuild/010-service.d/hrochobot.service
Normal file
13
cobuild/010-service.d/hrochobot.service
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
[Unit]
|
||||||
|
Description="Hrochobot"
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=exec
|
||||||
|
ExecStartPre=mkdir -p /data/etc
|
||||||
|
ExecStart=/usr/local/bin/hrochobot
|
||||||
|
Environment=HROCHOBOT_DATA=/data/etc
|
||||||
|
Environment=HROCHOBOT_LOG=/data/log
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
4
cobuild/010-service.d/run.sh
Normal file
4
cobuild/010-service.d/run.sh
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
progress "Configuring hrochobot.service"
|
||||||
|
|
||||||
|
install-config hrochobot.service /etc/systemd/system/
|
||||||
|
systemctl enable hrochobot
|
4
cobuild/Dockerfile.top
Normal file
4
cobuild/Dockerfile.top
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
FROM docker://registry.ks.matfyz.cz/gimli/base:bullseye
|
||||||
|
COPY bin /build/src/bin
|
||||||
|
COPY hrochobot /build/src/hrochobot
|
||||||
|
COPY setup.py /build/src
|
6
cobuild/try
Executable file
6
cobuild/try
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
common/build cobuild --tag hrochobot-test
|
||||||
|
podman rm -if hrochobot-test
|
||||||
|
podman create --name hrochobot-test --hostname hrochobot-test hrochobot-test
|
||||||
|
podman start hrochobot-test
|
73
common/build
Executable file
73
common/build
Executable file
|
@ -0,0 +1,73 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
gen-docker-file ()
|
||||||
|
{
|
||||||
|
if [ -f $src/Dockerfile.top ] ; then
|
||||||
|
cat $src/Dockerfile.top
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "COPY common /build/common"
|
||||||
|
|
||||||
|
for stage in $(cd $src && echo [0-9]*.[a-z]*) ; do
|
||||||
|
case $stage in
|
||||||
|
*.docker)
|
||||||
|
cat $src/$stage
|
||||||
|
;;
|
||||||
|
*.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
|
||||||
|
|
||||||
|
echo "RUN rm -rf /build /data"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $# = 0 ] ; then
|
||||||
|
echo >&2 "Usage: $0 <src-directory> [<podman build options>]"
|
||||||
|
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 - \
|
||||||
|
--layers \
|
||||||
|
--http-proxy \
|
||||||
|
--volume=$CACHE_DIR:/root/.cache \
|
||||||
|
"$@" \
|
||||||
|
.
|
||||||
|
|
||||||
|
echo -n "Cache usage: "
|
||||||
|
du -sh $CACHE_DIR | cut -d ' ' -f1
|
152
common/lib.sh
Normal file
152
common/lib.sh
Normal file
|
@ -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 <source> (<target-file> | <target-dir>/)"
|
||||||
|
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 <target> <sed-script>"
|
||||||
|
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: <command> | pipe-config <target>"
|
||||||
|
local TMP=$(mktemp)
|
||||||
|
cat >$TMP
|
||||||
|
install-config $TMP $1
|
||||||
|
rm $TMP
|
||||||
|
}
|
||||||
|
|
||||||
|
rm-config ()
|
||||||
|
{
|
||||||
|
[ $# = 1 ] || die "Usage: rm-config <target>"
|
||||||
|
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 <URL> <hash-type> <hash>"
|
||||||
|
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 $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"
|
||||||
|
}
|
50
common/run
Executable file
50
common/run
Executable file
|
@ -0,0 +1,50 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ $# != 1 ] ; then
|
||||||
|
echo >&2 "Usage: $0 <stage-directory>"
|
||||||
|
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
|
Loading…
Reference in a new issue