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>
117 lines
4.1 KiB
Python
Executable File
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()
|