Parts of this repository are derived from canonical/packer-maas, which Canonical
distributes under the AGPLv3, so its copyleft carries over and a permissive or
plain-GPL licence is not available:
* maas/curtin_userdata_custom.in is adapted from upstream's
debian/curtin_userdata_custom_amd64, with several late_commands copied
verbatim (the PXE-disable call, the target bind mount, the cloud.cfg rewrite
and the zz-update-grub fix)
* overlay/curtin/curtin-hooks follows upstream's debian/scripts/curtin-hooks:
same imports, same load_command_environment -> load_command_config ->
builtin_curthooks -> cleanup structure, near-identical cleanup(). The
kernel-disabling and interface-pinning functions are original.
The upstream template itself is not vendored; it is cloned at build time and
pinned by PM_REF.
Adds the full AGPL-3.0 text as LICENSE and SPDX-License-Identifier headers to
every source file, placed after the shebang or the #cloud-config marker so both
keep working. deploy-cluster.sh's --help filters the new header lines out of the
usage text it extracts from its own comment block.
GitHub Pages serves index.md, which includes README.md, so the site cannot drift
from the repository documentation. Nothing but build/ is excluded, which keeps
the README's relative links to LICENSE, scripts/ and maas/examples/ resolving on
the published site.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
102 lines
4.3 KiB
Bash
Executable File
102 lines
4.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# Copyright (C) 2026 Ilker Manap
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
#
|
|
# verify-image.sh - Uretilen MAAS tgz imajinin beklenen icerige sahip oldugunu dogrular.
|
|
#
|
|
# Kullanim: ./scripts/verify-image.sh build/proxmox-ve-9.tar.gz
|
|
#
|
|
set -uo pipefail
|
|
|
|
IMG="${1:-}"
|
|
[ -n "$IMG" ] && [ -f "$IMG" ] || { echo "Kullanim: $0 <imaj.tar.gz>" >&2; exit 2; }
|
|
|
|
TMP="$(mktemp -d)"
|
|
trap 'rm -rf "$TMP"' EXIT
|
|
|
|
echo "==> Imaj: $IMG ($(du -h "$IMG" | cut -f1))"
|
|
echo "==> Icerik listesi cikariliyor..."
|
|
tar tzf "$IMG" > "$TMP/list" || { echo "HATA: arsiv okunamadi"; exit 1; }
|
|
echo " $(wc -l < "$TMP/list") giris"
|
|
|
|
pass=0; fail=0
|
|
have() { grep -qx "\./$1" "$TMP/list" || grep -q "^\./$1$" "$TMP/list"; }
|
|
present() { grep -q "^\./$1" "$TMP/list"; }
|
|
|
|
check() {
|
|
local desc="$1" cond="$2"
|
|
if eval "$cond"; then
|
|
printf ' [ OK ] %s\n' "$desc"; pass=$((pass+1))
|
|
else
|
|
printf ' [FAIL] %s\n' "$desc"; fail=$((fail+1))
|
|
fi
|
|
}
|
|
|
|
echo
|
|
echo "==> Dosya varligi kontrolleri"
|
|
check "pve-maas-init mevcut" 'present "usr/local/sbin/pve-maas-init"'
|
|
check "pve-maas.conf mevcut" 'present "etc/pve-maas/pve-maas.conf"'
|
|
check "systemd unit mevcut" 'present "etc/systemd/system/pve-maas-init.service"'
|
|
check "unit multi-user.target icin etkin" 'present "etc/systemd/system/multi-user.target.wants/pve-maas-init.service"'
|
|
check "Proxmox APT deposu mevcut" 'present "etc/apt/sources.list.d/proxmox.sources"'
|
|
check "Proxmox anahtarligi mevcut" 'present "usr/share/keyrings/proxmox-archive-keyring.gpg"'
|
|
check "pveproxy ikilisi mevcut" 'present "usr/bin/pveproxy"'
|
|
check "pvecm ikilisi mevcut" 'present "usr/bin/pvecm"'
|
|
check "pvesh ikilisi mevcut" 'present "usr/bin/pvesh"'
|
|
check "ifupdown2 mevcut" 'present "usr/share/ifupdown2"'
|
|
check "cloud-init mevcut" 'present "usr/bin/cloud-init"'
|
|
check "curtin-hooks mevcut" 'present "curtin/curtin-hooks"'
|
|
|
|
echo
|
|
echo "==> Olmamasi gerekenler"
|
|
check "pmxcfs config.db yok (dugum kimligi temiz)" '! present "var/lib/pve-cluster/config.db"'
|
|
check "corosync yapilandirmasi yok" '! present "etc/corosync/corosync.conf"'
|
|
check "iSCSI initiator adi yok (dugumde uretilir)" '! present "etc/iscsi/initiatorname.iscsi"'
|
|
check "SSH host anahtarlari yok" '! grep -qE "^\./etc/ssh/ssh_host_.*_key$" "$TMP/list"'
|
|
check "networking.service etkin DEGIL" '! present "etc/systemd/system/multi-user.target.wants/networking.service"'
|
|
check "interfaces.new yok (pvenetcommit ezmesin)" '! present "etc/network/interfaces.new"'
|
|
check "Debian cekirdegi yok" '! grep -qE "^\./boot/vmlinuz-.*[^e]-(cloud-)?amd64$" "$TMP/list"'
|
|
|
|
echo
|
|
echo "==> Proxmox cekirdegi"
|
|
if grep -qE '^\./boot/vmlinuz-.*-pve$' "$TMP/list"; then
|
|
printf ' [ OK ] PVE cekirdegi: %s\n' "$(grep -oE 'vmlinuz-[^ ]*-pve' "$TMP/list" | head -1)"
|
|
pass=$((pass+1))
|
|
else
|
|
printf ' [FAIL] /boot altinda *-pve cekirdegi bulunamadi\n'; fail=$((fail+1))
|
|
fi
|
|
|
|
echo
|
|
echo "==> Ayiklanan dosya icerikleri"
|
|
tar xzf "$IMG" -C "$TMP" \
|
|
./etc/apt/sources.list.d/proxmox.sources \
|
|
./usr/local/sbin/pve-maas-init \
|
|
./etc/pve-maas/pve-maas.conf 2>/dev/null
|
|
|
|
tar xzf "$IMG" -C "$TMP" ./etc/network/interfaces 2>/dev/null
|
|
if [ -f "$TMP/etc/network/interfaces" ]; then
|
|
echo "--- /etc/network/interfaces ---"
|
|
sed 's/^/ /' "$TMP/etc/network/interfaces"
|
|
if grep -qE '^\s*(auto|iface)\s+(?!lo)' "$TMP/etc/network/interfaces" 2>/dev/null \
|
|
|| grep -qE '^[[:space:]]*iface[[:space:]]+[^l ]' "$TMP/etc/network/interfaces"; then
|
|
printf ' [FAIL] interfaces dosyasinda build VM artigi arayuz var\n'; fail=$((fail+1))
|
|
else
|
|
printf ' [ OK ] interfaces yalnizca loopback iceriyor\n'; pass=$((pass+1))
|
|
fi
|
|
fi
|
|
|
|
if [ -f "$TMP/etc/apt/sources.list.d/proxmox.sources" ]; then
|
|
echo "--- proxmox.sources ---"
|
|
sed 's/^/ /' "$TMP/etc/apt/sources.list.d/proxmox.sources"
|
|
fi
|
|
|
|
if [ -x "$TMP/usr/local/sbin/pve-maas-init" ]; then
|
|
printf ' [ OK ] pve-maas-init calistirilabilir\n'; pass=$((pass+1))
|
|
else
|
|
printf ' [FAIL] pve-maas-init calistirilabilir degil\n'; fail=$((fail+1))
|
|
fi
|
|
|
|
echo
|
|
echo "==> Sonuc: ${pass} basarili, ${fail} basarisiz"
|
|
[ "$fail" -eq 0 ]
|