Files
maas-proxmox/overlay/curtin/curtin-hooks
ilkermanap 40b5d50ec9 License under AGPL-3.0-or-later and publish documentation via GitHub Pages
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>
2026-09-04 21:57:03 +02:00

117 lines
4.1 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright (C) 2026 Ilker Manap
# SPDX-License-Identifier: AGPL-3.0-or-later
#
# curtin-hooks - MAAS/curtin kurulum kancasi (Proxmox VE imaji icin)
#
# Curtin, hedef sistemde /curtin/curtin-hooks varsa dahili curthooks yerine
# bu script'i calistirir (curtin.util.run_hook_if_exists).
#
# Amac: curtin'in APT uzerinden cekirdek kurmaya calismasini engellemek.
# Proxmox cekirdegi (proxmox-default-kernel) imajin icinde hazir gelir;
# curtin'in onu yeniden kurmasi gereksizdir ve dugumun deploy sirasinda
# download.proxmox.com'a erisebilmesini zorunlu kilar (izole aglarda calismaz).
#
# Not: Bunu preseed'de "kernel: null" ile yapmak mumkun degil - MAAS ile
# gelen curtin surumlerinin bir kismi bu degeri desteklemiyor ve
# install_kernel icinde AttributeError ile patliyor. Kancayi kullanmak
# curtin surumunden bagimsiz olarak calisir.
#
import shutil
import os
from curtin.commands import curthooks
from curtin.config import load_command_config
from curtin.util import load_command_environment
def disable_kernel_install():
"""curtin'in cekirdek kurulum adimini etkisiz hale getir.
Fonksiyon adi curtin surumune gore degisiyor (install_kernel ->
curthook_install_kernel), ikisini de yakaliyoruz.
"""
disabled = []
for name in ("install_kernel", "curthook_install_kernel"):
if hasattr(curthooks, name):
setattr(curthooks, name, lambda *args, **kwargs: None)
disabled.append(name)
print("curtin-hooks: cekirdek kurulumu devre disi: %s" % (disabled or "hicbiri bulunamadi"))
def pin_interface_names(config, target):
"""MAAS'in bildigi arayuz adlarini hedef sistemde MAC uzerinden sabitle.
MAAS commissioning'i Ubuntu ephemeral ortaminda yapiyor ve arayuzu orada
gordugu adla (or. enp6s18) kaydediyor. Deploy edilen Debian 13 / Proxmox
ise udev'in farkli isimlendirme semasi yuzunden ayni karti ens18 diye
adlandirabiliyor. Bu durumda cloud-init acilista arayuzu yeniden
adlandirmaya calisiyor, su hatayi aliyor:
Failed to rename devices: [busy] Error renaming
mac=... from ens18 to enp6s18
...ve arayuzu KAPALI birakiyor; dugum agini tamamen kaybediyor.
Cozum: MAC -> ad eslemesini systemd .link dosyasi olarak yaziyoruz, boylece
udev karti en bastan MAAS'in bekledigi adla olusturuyor ve yeniden
adlandirmaya hic gerek kalmiyor.
"""
net = config.get("network") or {}
pairs = []
# netplan / v2 bicimi
for name, cfg in (net.get("ethernets") or {}).items():
cfg = cfg or {}
mac = (cfg.get("match") or {}).get("macaddress")
if mac:
pairs.append((cfg.get("set-name") or name, mac))
# curtin v1 bicimi
for entry in net.get("config") or []:
if not isinstance(entry, dict) or entry.get("type") != "physical":
continue
if entry.get("name") and entry.get("mac_address"):
pairs.append((entry["name"], entry["mac_address"]))
if not pairs:
print("curtin-hooks: arayuz adi sabitlenmedi (ag yapilandirmasi bos)")
return
link_dir = os.path.join(target, "etc/systemd/network")
os.makedirs(link_dir, exist_ok=True)
for name, mac in pairs:
path = os.path.join(link_dir, "10-maas-%s.link" % name)
with open(path, "w") as fh:
fh.write(
"# MAAS tarafindan beklenen arayuz adi - pve-maas imaji\n"
"# curtin-hooks tarafindan olusturuldu.\n"
"[Match]\n"
"MACAddress=%s\n"
"\n"
"[Link]\n"
"Name=%s\n" % (mac.lower(), name)
)
print("curtin-hooks: arayuz adi sabitlendi %s -> %s" % (mac, name))
def cleanup():
"""Kancayi hedef sistemden kaldir - iz birakma."""
curtin_dir = os.path.dirname(os.path.abspath(__file__))
shutil.rmtree(curtin_dir, ignore_errors=True)
def main():
state = load_command_environment()
config = load_command_config(None, state)
target = state["target"]
disable_kernel_install()
curthooks.builtin_curthooks(config, target, state)
pin_interface_names(config, target)
cleanup()
if __name__ == "__main__":
main()