Первая загрузка образа была исправлена: libvirt больше не останавливается на вопросе о конфиге
Найдено полной установкой ISO в QEMU: панель ставится первой, и virtuality-ctl заранее создавал /etc/default/libvirt-guests; при установке libvirt dpkg спрашивал, какую версию оставить, и падал. - virtuality-ctl пишет этот файл только после установки libvirt - apt ставит пакеты с --force-confdef/--force-confold, перед установкой доделывает прерванную (dpkg --configure -a) - спиннер установщика не засоряет журнал первой загрузки - проверка ISO в CI ищет русский пункт меню Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg
Этот коммит содержится в:
@@ -51,7 +51,7 @@ jobs:
|
|||||||
xorriso -indev "$iso" -report_el_torito plain 2>/dev/null | tee /dev/stderr | grep -q "UEFI"
|
xorriso -indev "$iso" -report_el_torito plain 2>/dev/null | tee /dev/stderr | grep -q "UEFI"
|
||||||
xorriso -osirrox on -indev "$iso" -extract /autoinstall.yaml autoinstall.yaml -extract /boot/grub/grub.cfg grub.cfg
|
xorriso -osirrox on -indev "$iso" -extract /autoinstall.yaml autoinstall.yaml -extract /boot/grub/grub.cfg grub.cfg
|
||||||
python3 -c "import yaml; d = yaml.safe_load(open('autoinstall.yaml')); assert d['autoinstall']['version'] == 1"
|
python3 -c "import yaml; d = yaml.safe_load(open('autoinstall.yaml')); assert d['autoinstall']['version'] == 1"
|
||||||
grep -q "Install Virtuality" grub.cfg
|
grep -q "Установить Virtuality" grub.cfg
|
||||||
# Ubuntu server ISOs are larger than the 2 GB GitHub release asset limit,
|
# Ubuntu server ISOs are larger than the 2 GB GitHub release asset limit,
|
||||||
# so images are published as workflow artifacts.
|
# so images are published as workflow artifacts.
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ MIN_RAM_MB="${VIRTUALITY_MIN_RAM_MB:-4096}"
|
|||||||
MIN_CPU_CORES="${VIRTUALITY_MIN_CPU_CORES:-2}"
|
MIN_CPU_CORES="${VIRTUALITY_MIN_CPU_CORES:-2}"
|
||||||
SKIP_REQUIREMENTS="${VIRTUALITY_SKIP_REQUIREMENTS:-0}"
|
SKIP_REQUIREMENTS="${VIRTUALITY_SKIP_REQUIREMENTS:-0}"
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
# Keep existing configuration files without asking: there is nobody to answer on first boot.
|
||||||
|
APT_OPTS=(-o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold)
|
||||||
|
|
||||||
ESC="\033"
|
ESC="\033"
|
||||||
RESET="${ESC}[0m"
|
RESET="${ESC}[0m"
|
||||||
@@ -74,15 +76,18 @@ run_logged() {
|
|||||||
spinner=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏")
|
spinner=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏")
|
||||||
i=0
|
i=0
|
||||||
while kill -0 "$pid" 2>/dev/null; do
|
while kill -0 "$pid" 2>/dev/null; do
|
||||||
|
# The spinner only makes sense on a terminal; first boot writes this output to a log.
|
||||||
|
if [[ -t 1 ]]; then
|
||||||
elapsed=$(( $(date +%s) - start_ts ))
|
elapsed=$(( $(date +%s) - start_ts ))
|
||||||
symbol="${spinner[$((i % ${#spinner[@]}))]}"
|
symbol="${spinner[$((i % ${#spinner[@]}))]}"
|
||||||
printf "\r ${CYAN}%s${RESET} %s... ${GRAY}%ss${RESET} ${GRAY}(лог: %s)${RESET}" "$symbol" "$description" "$elapsed" "$LOG_FILE"
|
printf "\r ${CYAN}%s${RESET} %s... ${GRAY}%ss${RESET} ${GRAY}(лог: %s)${RESET}" "$symbol" "$description" "$elapsed" "$LOG_FILE"
|
||||||
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
i=$((i + 1))
|
i=$((i + 1))
|
||||||
done
|
done
|
||||||
wait "$pid"
|
code=0
|
||||||
code=$?
|
wait "$pid" || code=$?
|
||||||
printf "\r%*s\r" 120 ""
|
[[ -t 1 ]] && printf "\r%*s\r" 120 ""
|
||||||
if [[ "$code" -eq 0 ]]; then
|
if [[ "$code" -eq 0 ]]; then
|
||||||
ok "$description"
|
ok "$description"
|
||||||
else
|
else
|
||||||
@@ -103,7 +108,7 @@ install_available() {
|
|||||||
warn "Пакет ${pkg} недоступен в этом дистрибутиве, пропускаю"
|
warn "Пакет ${pkg} недоступен в этом дистрибутиве, пропускаю"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
run_logged "$description" apt install -y "${available[@]}"
|
run_logged "$description" apt-get install -y "${APT_OPTS[@]}" "${available[@]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
service_state() { systemctl is-active "$1" 2>/dev/null || echo "inactive"; }
|
service_state() { systemctl is-active "$1" 2>/dev/null || echo "inactive"; }
|
||||||
@@ -164,7 +169,9 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
step "Обновляем apt cache"
|
step "Обновляем apt cache"
|
||||||
run_logged "apt update выполнен" apt update
|
run_logged "apt update выполнен" apt-get update
|
||||||
|
# A previous attempt may have stopped half way (power loss, a question from dpkg): finish it first.
|
||||||
|
run_logged "Незавершённые установки пакетов доделаны" dpkg --configure -a --force-confdef --force-confold
|
||||||
|
|
||||||
step "Устанавливаем базовые утилиты и зависимости диагностики"
|
step "Устанавливаем базовые утилиты и зависимости диагностики"
|
||||||
install_available "Базовые пакеты и диагностические утилиты установлены" \
|
install_available "Базовые пакеты и диагностические утилиты установлены" \
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ if [[ "$PANEL_ONLY" == "1" ]]; then
|
|||||||
ok "Пропущено (VIRTUALITY_PANEL_ONLY=1): пакеты поставит установщик ноды"
|
ok "Пропущено (VIRTUALITY_PANEL_ONLY=1): пакеты поставит установщик ноды"
|
||||||
elif command -v apt-get >/dev/null 2>&1; then
|
elif command -v apt-get >/dev/null 2>&1; then
|
||||||
run_logged "apt update выполнен" apt-get update
|
run_logged "apt update выполнен" apt-get update
|
||||||
run_logged "Пакеты панели установлены" apt-get install -y python3 python3-venv rsync openssl curl nftables novnc python3-websockify qemu-utils virtinst libvirt-clients cloud-image-utils
|
run_logged "Пакеты панели установлены" apt-get install -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold python3 python3-venv rsync openssl curl nftables novnc python3-websockify qemu-utils virtinst libvirt-clients cloud-image-utils
|
||||||
else
|
else
|
||||||
warn "apt не найден — пакеты не устанавливались"
|
warn "apt не найден — пакеты не устанавливались"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -253,12 +253,16 @@ ${LOG_DIR}/*.log {
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Guests shut down gracefully with the host instead of being killed (Proxmox behaviour).
|
# Guests shut down gracefully with the host instead of being killed (Proxmox behaviour).
|
||||||
|
# Only once libvirt is installed: the file is a dpkg conffile, and creating it earlier (the panel is
|
||||||
|
# installed first on the image) makes the libvirt package stop at a "keep your version?" question.
|
||||||
|
if [[ -f /usr/lib/libvirt/libvirt-guests.sh ]]; then
|
||||||
cat > /etc/default/libvirt-guests <<EOF
|
cat > /etc/default/libvirt-guests <<EOF
|
||||||
ON_BOOT=ignore
|
ON_BOOT=ignore
|
||||||
ON_SHUTDOWN=shutdown
|
ON_SHUTDOWN=shutdown
|
||||||
SHUTDOWN_TIMEOUT=180
|
SHUTDOWN_TIMEOUT=180
|
||||||
PARALLEL_SHUTDOWN=5
|
PARALLEL_SHUTDOWN=5
|
||||||
EOF
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl enable virtuality-web.service virtuality-network.service virtuality-maintenance.timer >/dev/null 2>&1 || true
|
systemctl enable virtuality-web.service virtuality-network.service virtuality-maintenance.timer >/dev/null 2>&1 || true
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ say "source: ${SOURCE_DIR}, panel user: ${AUTH_USER}, port: ${VIRTUALITY_WEB_POR
|
|||||||
cd "$SOURCE_DIR"
|
cd "$SOURCE_DIR"
|
||||||
|
|
||||||
# unattended-upgrades often holds the dpkg lock right after the first boot.
|
# unattended-upgrades often holds the dpkg lock right after the first boot.
|
||||||
printf 'DPkg::Lock::Timeout "900";\n' > "$APT_LOCK_CONF"
|
printf 'DPkg::Lock::Timeout "900";\nDPkg::Options { "--force-confdef"; "--force-confold"; };\n' > "$APT_LOCK_CONF"
|
||||||
|
|
||||||
cat > "$ISSUE_FILE" <<'EOF'
|
cat > "$ISSUE_FILE" <<'EOF'
|
||||||
Virtuality настраивается. Ход установки: sudo journalctl -fu virtuality-firstboot
|
Virtuality настраивается. Ход установки: sudo journalctl -fu virtuality-firstboot
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user