#!/usr/bin/env bash set -Eeuo pipefail ROOT=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) cd "$ROOT" ENV_FILE="$ROOT/.env" GPG_DIR="$ROOT/gpg" DATA_DIR="$ROOT/data" SERVICE="rust-package-builder" log() { printf '[start] %s\n' "$*" } die() { printf '[start] ERROR: %s\n' "$*" >&2 exit 1 } require_cmd() { command -v "$1" >/dev/null 2>&1 || die "brak wymaganego polecenia: $1" } write_env_file() { local source_repo=${SOURCE_REPO:-} local repository_url=${REPOSITORY_URL:-} cat > "$ENV_FILE" </dev/null || true } load_env_file() { # .env is intentionally limited to simple KEY=value entries used by Compose. # shellcheck disable=SC1090 set -a source "$ENV_FILE" set +a } require_cmd docker if ! docker info >/dev/null 2>&1; then die "Docker daemon nie jest dostepny dla aktualnego uzytkownika" fi if docker compose version >/dev/null 2>&1; then COMPOSE=(docker compose) elif command -v docker-compose >/dev/null 2>&1; then COMPOSE=(docker-compose) else die "brak Docker Compose (docker compose lub docker-compose)" fi if [[ ! -f "$ENV_FILE" ]]; then write_env_file fi load_env_file : "${SOURCE_REPO:?Uzupelnij SOURCE_REPO w .env albo ustaw zmienna przed uruchomieniem start.sh}" : "${REPOSITORY_URL:?Uzupelnij REPOSITORY_URL w .env albo ustaw zmienna przed uruchomieniem start.sh}" case "$SOURCE_REPO" in http://*|https://*|ssh://*|git@*|file://*) ;; *) die "SOURCE_REPO ma nieobslugiwany format: $SOURCE_REPO" ;; esac case "$REPOSITORY_URL" in http://*|https://*) ;; *) die "REPOSITORY_URL musi zaczynac sie od http:// albo https://" ;; esac mkdir -p "$DATA_DIR/repository" "$DATA_DIR/state" "$DATA_DIR/cargo" "$DATA_DIR/work" "$GPG_DIR" chmod 0700 "$GPG_DIR" 2>/dev/null || true log "budowanie obrazu buildera" "${COMPOSE[@]}" --env-file "$ENV_FILE" build "$SERVICE" if [[ ! -s "$GPG_DIR/private-key.asc" ]]; then log "brak klucza GPG - generowanie stalego klucza podpisujacego" IMAGE_REF=$("${COMPOSE[@]}" --env-file "$ENV_FILE" config | awk '$1 == "image:" {print $2; exit}') [[ -n "$IMAGE_REF" ]] || die "nie mozna ustalic nazwy zbudowanego obrazu" docker image inspect "$IMAGE_REF" >/dev/null 2>&1 || die "zbudowany obraz nie istnieje: $IMAGE_REF" uid=$(id -u) gid=$(id -g) docker run --rm \ --user "$uid:$gid" \ --entrypoint /bin/bash \ -e HOME=/tmp \ -v "$GPG_DIR:/out" \ "$IMAGE_REF" \ -lc ' set -Eeuo pipefail export GNUPGHOME=/tmp/rpb-keygen mkdir -p "$GNUPGHOME" chmod 0700 "$GNUPGHOME" cat > /tmp/gpg-batch <<"KEY" Key-Type: RSA Key-Length: 3072 Key-Usage: sign Name-Real: Rust Package Builder Repository Name-Email: packages@localhost Expire-Date: 0 %no-protection %commit KEY gpg --batch --generate-key /tmp/gpg-batch fingerprint=$(gpg --batch --with-colons --list-secret-keys | awk -F: '\''/^sec:/ {seen=1; next} seen && /^fpr:/ {print $10; exit}'\'') test -n "$fingerprint" gpg --batch --armor --export-secret-keys "$fingerprint" > /out/private-key.asc gpg --batch --armor --export "$fingerprint" > /out/public-key.asc printf "%s\n" "$fingerprint" > /out/fingerprint chmod 0600 /out/private-key.asc chmod 0644 /out/public-key.asc /out/fingerprint ' [[ -s "$GPG_DIR/private-key.asc" ]] || die "generowanie prywatnego klucza GPG nie powiodlo sie" [[ -s "$GPG_DIR/public-key.asc" ]] || die "generowanie publicznego klucza GPG nie powiodlo sie" else log "uzywanie istniejacego klucza GPG" fi log "uruchamianie buildera przez Docker Compose" "${COMPOSE[@]}" --env-file "$ENV_FILE" up -d "$SERVICE" fingerprint="" if [[ -r "$GPG_DIR/fingerprint" ]]; then fingerprint=$(tr -d '[:space:]' < "$GPG_DIR/fingerprint") fi log "gotowe" printf '\n' printf 'SOURCE_REPO: %s\n' "$SOURCE_REPO" printf 'REPOSITORY_URL: %s\n' "$REPOSITORY_URL" [[ -n "$fingerprint" ]] && printf 'GPG fingerprint: %s\n' "$fingerprint" printf 'Publiczny katalog: %s\n' "$DATA_DIR/repository" printf '\n' printf 'Podglad logow:\n ' printf '%q ' "${COMPOSE[@]}" printf 'logs -f %q\n' "$SERVICE" printf '\n' printf 'Builder natychmiast sprawdzi branch master (lub SOURCE_BRANCH, jezeli ustawiono go opcjonalnie) i po udanym buildzie opublikuje repozytorium.\n'