Files
gentoo-pill/binhost.sh
2025-12-07 20:28:13 +06:00

146 lines
4.1 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
REPO_URL="git@git.ayau.me:mira/gentoo-pill.git"
WORK_DIR="$(pwd)"
REPO="${WORK_DIR}/repo"
CTX="${WORK_DIR}/ctx"
IMAGE="docker.io/gentoo/stage3:amd64-desktop-openrc"
CONTAINER_NAME="gentoo_builder"
PROFILE="default/linux/amd64/23.0/desktop"
LOG_FILE="/var/log/gentoo_build.log" # inside container
HOST_KEY_PATH="$(pwd)/secrets/signing.key"
if [[ ! -d "$REPO/.git" ]]; then
git clone "$REPO_URL" "$REPO"
else
git -C "$REPO" pull --rebase
fi
echo "Aggregating config..."
rm -rf "$CTX" && mkdir -p "$CTX"/var/lib/portage
# config types to merge
CONFIGS=(package.use package.accept_keywords package.license package.mask package.unmask package.env repos.conf)
for type in "${CONFIGS[@]}"; do
dest="$CTX/etc/portage/$type"
mkdir -p "$dest"
inject() {
local src=$1 prefix=$2
[[ ! -e "$src" ]] && return
if [[ -d "$src" ]]; then
for f in "$src"/*; do
[[ -f "$f" ]] && cp "$f" "$dest/${prefix}-$(basename "$f")"
done
else
cp "$src" "$dest/${prefix}-$(basename "$src")"
fi
}
inject "$REPO/common/$type" "00-common"
for host_dir in "$REPO/hosts"/*; do
[[ -d "$host_dir" ]] || continue
hostname=$(basename "$host_dir")
inject "$host_dir/$type" "50-${hostname}"
done
done
# generate world union
cat "$REPO"/hosts/*/world 2>/dev/null | sort -u | sed '/^#/d;/^$/d' > "$CTX/var/lib/portage/world"
echo "Packages in aggregated world file: $(wc -l < "$CTX/var/lib/portage/world")"
# make.conf
mkdir -p "$CTX/etc/portage"
cp "$REPO/binhost/make.conf" "$CTX/etc/portage/make.conf"
init_container() {
echo "Creating new builder container..."
podman run -d \
--name "$CONTAINER_NAME" \
--cap-add=SYS_PTRACE \
-v portage_db:/var/db/repos/gentoo \
-v distfiles:/var/cache/distfiles \
-v binpkgs:/var/cache/binpkgs \
-v "$HOST_KEY_PATH":/tmp/signing.key:ro \
--tmpfs /var/tmp/portage:rw,size=48G,mode=1777 \
"$IMAGE" \
bin/bash -c "sleep infinity"
echo "Running setup..."
podman exec "$CONTAINER_NAME" bash -c "
mkdir -p /root/.gnupg
chmod 700 /root/.gnupg
gpg --batch --import /tmp/signing.key
emerge-webrsync -q
emerge -1vn --usepkg --buildpkg dev-vcs/git app-eselect/eselect-repository
eselect profile set '$PROFILE'
"
}
if ! podman container exists "$CONTAINER_NAME"; then
init_container
else
if ! podman container inspect -f '{{.State.Running}}' "$CONTAINER_NAME" >/dev/null 2>&1; then
echo "Starting existing container..."
podman start "$CONTAINER_NAME"
fi
fi
echo "Injecting current config..."
podman cp "$CTX/etc/portage/" "$CONTAINER_NAME":/etc/
podman cp "$CTX/var/lib/portage/world" "$CONTAINER_NAME":/var/lib/portage/world
echo "Starting Builder..."
cat <<EOF | podman exec -i "$CONTAINER_NAME" sh -c "cat > /usr/local/bin/run_job.sh"
#!/bin/bash
set -e
source /etc/profile
SYNC_MARKER="/var/db/repos/gentoo/.last_sync_marker"
chown -R portage:portage /etc/portage /var/lib/portage/world
echo "Syncing..."
# if we're missing the tree, sync snapshot
if [[ ! -d /var/db/repos/gentoo/profiles ]]; then
echo "Portage tree missing. Performing initial webrsync..."
emerge-webrsync -q
fi
if [[ -f "\$SYNC_MARKER" ]] && [[ -n "\$(find "\$SYNC_MARKER" -mtime -1 2>/dev/null)" ]]; then
echo "Skipping sync: Repo was synced within the last 24h"
else
echo "Sync timer expired (or marker missing), updating repos..."
emaint -a sync
touch "\$SYNC_MARKER"
fi
echo "Building world.."
emerge --verbose --usepkg --buildpkg \
--update --deep --changed-use \
--with-bdeps=y --binpkg-respect-use=y --binpkg-changed-deps=y \
--keep-going @world
echo "Cleaning up.."
emerge --depclean
emaint binhost --fix
echo "[$(date)] Build Finished successfully."
EOF
echo "Triggering build in background..."
podman exec -d "$CONTAINER_NAME" bash -c "chmod +x /usr/local/bin/run_job.sh && /usr/local/bin/run_job.sh > $LOG_FILE 2>&1"
echo "Build is running in the background."
echo "To view progress, run:"
echo " podman exec -it $CONTAINER_NAME tail -f $LOG_FILE"