Files
Bridge-and-Join-s/deploy/iso/build-iso.sh

99 lines
6.4 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/sh
# Сборка образа ISO Bridge&Join на основе официального Debian 13 netinst.
#
# deploy/iso/build-iso.sh <debian-13.x-amd64-netinst.iso> <bj-installer> <версия> [канал] [выходной.iso] [каталог релиза]
# Каталог релиза (dist с manifest.json) — ядро bj кладётся в образ: установка без ключа продукта, ключ вводится в браузере.
#
# В образ добавляются: файл ответов установщику (preseed.cfg), bj-installer и служба первой загрузки.
# Загрузочное меню BIOS (isolinux) и UEFI (grub) по умолчанию запускает установку с этими ответами.
# Загрузочные записи исходного образа сохраняются (xorriso -boot_image any replay).
# Нужен xorriso. Проверка исходного образа — по SHA256SUMS с cdimage.debian.org.
set -eu
SRC=${1:?исходный debian-13.x-amd64-netinst.iso}
INSTALLER=${2:?файл bj-installer}
VERSION=${3:?версия образа, например 2026.10.1}
CHANNEL=${4:-stable}
OUT=${5:-bj-debian13-$VERSION.iso}
BUNDLE=${6:-}
HERE=$(cd "$(dirname "$0")" && pwd)
command -v xorriso >/dev/null || { echo "нужен xorriso: apt-get install xorriso"; exit 1; }
WORK=$(mktemp -d)
trap 'rm -rf "$WORK"' EXIT
mkdir -p "$WORK/bj" "$WORK/preseed" "$WORK/isolinux" "$WORK/grub"
cp "$HERE/preseed.cfg" "$WORK/preseed/bj.cfg"
install -m 0755 "$INSTALLER" "$WORK/bj/bj-installer"
install -m 0755 "$HERE/bj-firstboot" "$WORK/bj/bj-firstboot"
install -m 0755 "$HERE/bj-firstboot-screen" "$WORK/bj/bj-firstboot-screen" # экран установки bj при первой загрузке
cp "$HERE/bj-firstboot.service" "$WORK/bj/bj-firstboot.service"
echo "$CHANNEL" > "$WORK/bj/channel"
echo "$VERSION" > "$WORK/bj/version"
# приветственный экран консоли (адрес веб-входа) — ставится ещё до установки bj
install -m 0755 "$HERE/../linux/sbin/bj-welcome" "$WORK/bj/bj-welcome"
cp "$HERE/../systemd/bj-welcome.service" "$HERE/../systemd/bj-welcome.timer" "$WORK/bj/"
# ядро bj с образа: подписанный манифест и файлы компонентов ядра (bj-server, bj-component-install)
if [ -n "$BUNDLE" ]; then
[ -s "$BUNDLE/manifest.json" ] || { echo "в $BUNDLE нет manifest.json"; exit 1; }
mkdir -p "$WORK/bj/bundle"; cp "$BUNDLE/manifest.json" "$WORK/bj/bundle/"
# манифест подписан: тело — base64 в поле payload
FILES=$(python3 -c 'import json,sys,base64;s=json.load(open(sys.argv[1]));m=json.loads(base64.b64decode(s["payload"]));print(" ".join(a["file"] for a in m["artifacts"] if a["name"] in ("bj-server","bj-component-install")))' "$BUNDLE/manifest.json") || { echo "не удалось прочитать манифест релиза"; exit 1; }
[ -n "$FILES" ] || { echo "в релизе нет компонентов ядра (bj-server, bj-component-install)"; exit 1; }
for f in $FILES; do
cp "$BUNDLE/$f" "$WORK/bj/bundle/" || exit 1
done
echo "в образ добавлено ядро bj: $(ls "$WORK/bj/bundle" | tr '\n' ' ')"
fi
BOOT="auto=true priority=high preseed/file=/cdrom/preseed/bj.cfg language=ru country=RU locale=ru_RU.UTF-8 keyboard-configuration/xkb-keymap=ru"
# BIOS: пункт по умолчанию в isolinux
xorriso -osirrox on -indev "$SRC" -extract /isolinux/txt.cfg "$WORK/isolinux/txt.orig" >/dev/null 2>&1
KERNEL=$(awk '/^\s*kernel/{print $2; exit}' "$WORK/isolinux/txt.orig")
INITRD=$(grep -o 'initrd=[^ ]*' "$WORK/isolinux/txt.orig" | head -1 | cut -d= -f2)
{
echo "default bj"
# Подпись — латиницей: vesamenu (BIOS) кириллицу не отображает (кракозябры).
echo "label bj"
echo " menu label ^Install Bridge&Join $VERSION"
echo " menu default"
echo " kernel $KERNEL"
echo " append vga=788 initrd=$INITRD $BOOT --- quiet"
sed '/menu default/d;/^default /d' "$WORK/isolinux/txt.orig"
} > "$WORK/isolinux/txt.cfg"
xorriso -osirrox on -indev "$SRC" -extract /isolinux/isolinux.cfg "$WORK/isolinux/isolinux.cfg" >/dev/null 2>&1
sed -i 's/^timeout .*/timeout 100/; s/^prompt .*/prompt 0/' "$WORK/isolinux/isolinux.cfg"
grep -q '^timeout' "$WORK/isolinux/isolinux.cfg" || echo "timeout 100" >> "$WORK/isolinux/isolinux.cfg"
# Подсказка обратного отсчёта — в конец isolinux.cfg, ПОСЛЕ include menu.cfg: внутри
# menu.cfg подменю «Advanced» повторно включает stdmenu.cfg и перебивает autoboot из txt.cfg.
# (файл, извлечённый xorriso, имеет права 0444: sed -i пересоздаёт его, а >> без chmod не запишет)
chmod u+w "$WORK/isolinux/isolinux.cfg"
echo "menu autoboot Bridge&Join install starts in # seconds, press a key to choose" >> "$WORK/isolinux/isolinux.cfg"
# UEFI: первый пункт в grub
xorriso -osirrox on -indev "$SRC" -extract /boot/grub/grub.cfg "$WORK/grub/grub.orig" >/dev/null 2>&1
# текстовый установщик (без gtk), как в BIOS: установка идёт без графической среды
LINUX=$(awk '/^\s*linux\s/ && $2 !~ /gtk/ {print $2; exit}' "$WORK/grub/grub.orig")
INITRDG=$(awk '/^\s*initrd\s/ && $2 !~ /gtk/ {print $2; exit}' "$WORK/grub/grub.orig")
{
echo "set default=0"
echo "set timeout=10"
# латиницей (шрифт grub-темы без кириллицы), горячая клавиша b — у родного «Install» занята i
echo "menuentry --hotkey=b 'Install Bridge&Join $VERSION' {"
echo " set background_color=black"
echo " linux $LINUX vga=788 $BOOT --- quiet"
echo " initrd $INITRDG"
echo "}"
sed '/^set default/d;/^set timeout/d' "$WORK/grub/grub.orig"
} > "$WORK/grub/grub.cfg"
rm -f "$OUT"
xorriso -indev "$SRC" -outdev "$OUT" -boot_image any replay \
-volid "BJ_DEBIAN13" \
-map "$WORK/preseed" /preseed \
-map "$WORK/bj" /bj \
-map "$WORK/isolinux/txt.cfg" /isolinux/txt.cfg \
-map "$WORK/isolinux/isolinux.cfg" /isolinux/isolinux.cfg \
-map "$WORK/grub/grub.cfg" /boot/grub/grub.cfg \
-end >/dev/null 2>"$WORK/xorriso.log" || { cat "$WORK/xorriso.log"; exit 1; }
echo "Образ собран: $OUT ($(du -h "$OUT" | cut -f1)), канал обновлений $CHANNEL"