# Copyright (C) 2026 Ilker Manap # SPDX-License-Identifier: AGPL-3.0-or-later # maas-samba-ad - Samba Active Directory domain controller image for MAAS # # Hizli baslangic (build host uzerinde, root olarak): # sudo ./scripts/install-deps.sh # sudo make image # make preseed # make upload MAAS_PROFILE=admin # SHELL := /bin/bash .DEFAULT_GOAL := help # ---------------------------------------------------------------- version settings # Samba's AD DC comes straight from Debian - no third-party repository is # involved, so there is nothing to pin beyond the Debian release itself. DEBIAN_SERIES ?= trixie DEBIAN_VERSION ?= 13 # Packages beyond the domain controller itself. AD_EXTRA_PACKAGES ?= acl attr net-tools ldap-utils python3-gpg bind9-dnsutils \ ethtool ipmitool nvme-cli lsscsi sudo # ---------------------------------------------------------------- imaj ayarlari # amd64 | arm64. arm64 is wired up but has never been built or deployed - # see "Verified status" in the README. Building arm64 on an x86_64 host means # TCG emulation with no KVM, which is very slow; prefer a native arm64 builder. ARCH ?= amd64 SUBARCH ?= generic BOOT ?= uefi TIMEOUT ?= 3h PACKER_LOG ?= 0 # Build VM kaynaklari. Upstream sablon 4G/2CPU/2GB ile gelir; Debian cloud image # (~3G) plus Samba and its dependencies does not fit in 4G, so we patch it. # Sonuc tgz yalnizca kullanilan dosyalari icerdiginden buyuk disk imaji sismez. DISK_SIZE ?= 16G BUILD_CPUS ?= 4 BUILD_MEM ?= 4096 # --- derleme hizi ------------------------------------------------------------- # stable | daily # stable: cloud.debian.org/.../trixie/latest (sabit URL -> packer onbellegi # calisir, tekrarlanan derlemelerde ~350MB indirme yok, tekrarlanabilir) # daily : upstream sablonun varsayilani (her gun degisir, onbellek isabet etmez) DEBIAN_IMAGE_CHANNEL ?= stable # Tarball sikistirma seviyesi. Upstream --best (9) kullaniyor; 6 belirgin daha # hizli ve imaj yalnizca ~%2-3 buyuyor. pigz varsa cok cekirdekli calisir. GZIP_LEVEL ?= 6 # Yerel APT onbellegi (or. apt-cacher-ng): http://10.0.2.2:3142 # Packer'in user-mode aginda build VM host'u 10.0.2.2 olarak gorur. # Bos birakilirsa proxy kullanilmaz. Bkz: make deps-cache APT_PROXY ?= IMAGE_NAME ?= samba-ad-dc IMAGE_TITLE ?= Samba AD Domain Controller (Debian $(DEBIAN_VERSION)) # ---------------------------------------------------------------- yollar WORKDIR ?= $(CURDIR)/build PM_REPO ?= https://github.com/canonical/packer-maas.git # Test edilmis upstream commit'e sabitlenmistir. 'main' birakmak, upstream'de # yapilan bir degisikligin derlemeyi haber vermeden bozmasi anlamina gelir. # Ileri tasimak icin: PM_REF=main ile derleyip test edin, sonra yeni SHA'yi buraya yazin. PM_REF ?= c23d5dd985f52b2eaccc893e886213a424a243a5 PM := $(WORKDIR)/packer-maas TPL := $(PM)/debian OVERLAY_TGZ := $(WORKDIR)/adc-maas-overlay.tar.gz CUSTOMIZE := $(WORKDIR)/customize-samba-ad.sh OUTPUT ?= $(WORKDIR)/$(IMAGE_NAME).tar.gz PRESEED := $(WORKDIR)/curtin_userdata_custom_$(ARCH)_$(SUBARCH)_$(IMAGE_NAME) # ---------------------------------------------------------------- MAAS ayarlari MAAS_PROFILE ?= admin MAAS_ARCH ?= $(ARCH)/$(SUBARCH) MAAS_IMAGE_NAME ?= custom/$(IMAGE_NAME) # MAAS snap kurulumu icin: /var/snap/maas/current/preseeds MAAS_PRESEED_DIR ?= /var/snap/maas/current/preseeds # UEFI firmware, keyed on the TARGET architecture - an aarch64 guest needs # AAVMF whatever the build host is. (Upstream packer-maas keys this on the host # architecture instead, which only works when host and target match.) ifeq ($(strip $(ARCH)),arm64) FW_DIR ?= /usr/share/AAVMF FW ?= AAVMF else FW_DIR ?= /usr/share/OVMF FW ?= OVMF endif FW_SFX ?= $(shell test -f $(FW_DIR)/$(FW)_CODE.fd && echo "" || echo "_4M") # KVM is only usable when the host and the guest share an architecture. # Otherwise QEMU falls back to TCG emulation, which is very slow. HOST_IS_ARM := $(shell test "$$(uname -m)" = aarch64 && echo true || echo false) # ---------------------------------------------------------------- hedefler .PHONY: help deps deps-cache check-upstream print-var checkout overlay customize image verify preseed install-preseed upload clean distclean lint help: @echo "maas-samba-ad - Samba AD Domain Controller MAAS image" @echo @echo " make deps Build host bagimliliklarini kur (root gerekir)" @echo " make deps-cache Yerel APT onbellegi kur (derlemeyi hizlandirir)" @echo " make image Imaji derle -> $(OUTPUT) (root gerekir)" @echo " make verify Uretilen imajin icerigini dogrula" @echo " make check-upstream Depodaki surumleri elimizdeki imajla karsilastir" @echo " make preseed MAAS curtin preseed dosyasini uret" @echo " make install-preseed Preseed'i $(MAAS_PRESEED_DIR) altina kopyala (root)" @echo " make upload Imaji MAAS'a yukle (MAAS_PROFILE=$(MAAS_PROFILE))" @echo " make clean Ara dosyalari sil" @echo " make distclean build/ dizinini tamamen sil" @echo @echo "Onemli degiskenler:" @echo " DEBIAN_SERIES=$(DEBIAN_SERIES) IMAGE_NAME=$(IMAGE_NAME)" @echo " ARCH=$(ARCH) BOOT=$(BOOT)" @echo " OUTPUT=$(OUTPUT)" deps: ./scripts/install-deps.sh # --- packer-maas deposunu getir ----------------------------------------------- $(PM)/.git: @mkdir -p $(WORKDIR) git clone $(PM_REPO) $(PM) # PM_REF bir dal, etiket ya da commit SHA olabilir. checkout: $(PM)/.git @cd $(PM) && git fetch -q --all --tags && git checkout -q -f $(PM_REF) \ && (git symbolic-ref -q HEAD >/dev/null && git pull -q --ff-only || true) @echo "packer-maas: $$(cd $(PM) && git rev-parse --short HEAD) ($(PM_REF))" # --- imaja gomulecek overlay --------------------------------------------------- overlay: $(OVERLAY_TGZ) $(OVERLAY_TGZ): $(shell find overlay -type f 2>/dev/null) @mkdir -p $(WORKDIR) COPYFILE_DISABLE=1 tar czf $@ -C overlay --no-xattrs --exclude='.keep' . @echo "overlay: $@ ($$(du -h $@ | cut -f1))" # --- packer'in VM icinde calistiracagi customize script ------------------------- customize: $(CUSTOMIZE) $(CUSTOMIZE): scripts/customize-samba-ad.sh.in $(OVERLAY_TGZ) @mkdir -p $(WORKDIR) @sed -e 's|@@DEBIAN_SERIES@@|$(DEBIAN_SERIES)|g' \ -e 's|@@AD_EXTRA_PACKAGES@@|$(AD_EXTRA_PACKAGES)|g' \ -e 's|@@PM_REF@@|$(PM_REF)|g' \ $< > $@ @echo '__ADC_MAAS_OVERLAY__' >> $@ @base64 < $(OVERLAY_TGZ) >> $@ @chmod +x $@ @echo "customize script: $@" # --- imaj derleme --------------------------------------------------------------- image: checkout $(CUSTOMIZE) @if [ "$$(id -u)" -ne 0 ]; then echo "HATA: 'make image' root gerektirir (sudo make image)"; exit 1; fi @command -v packer >/dev/null || { echo "HATA: packer yok, once 'make deps'"; exit 1; } @echo "==> Sablon yamalaniyor: disk=$(DISK_SIZE) cpus=$(BUILD_CPUS) mem=$(BUILD_MEM)" sed -i -E 's|^([[:space:]]*disk_size[[:space:]]*=[[:space:]]*).*|\1"$(DISK_SIZE)"|' $(TPL)/debian-cloudimg.pkr.hcl sed -i -E 's|^([[:space:]]*cpus[[:space:]]*=[[:space:]]*).*|\1$(BUILD_CPUS)|' $(TPL)/debian-cloudimg.pkr.hcl sed -i -E 's|^([[:space:]]*memory[[:space:]]*=[[:space:]]*).*|\1$(BUILD_MEM)|' $(TPL)/debian-cloudimg.pkr.hcl ifeq ($(strip $(DEBIAN_IMAGE_CHANNEL)),stable) @echo "==> Kararli Debian cloud image kullanilacak (packer onbellegi isabet eder)" sed -i -E 's|/daily/latest/|/latest/|g; s|-daily\.qcow2|.qcow2|g' $(TPL)/debian-cloudimg.pkr.hcl @grep -nE 'iso_url|iso_checksum' $(TPL)/debian-cloudimg.pkr.hcl endif sed -i -E 's|--best --force|-$(GZIP_LEVEL) --force|' $(PM)/scripts/fuse-tar-root @grep -nE 'disk_size|^ cpus|^ memory' $(TPL)/debian-cloudimg.pkr.hcl cp -v $(FW_DIR)/$(FW)_CODE$(FW_SFX).fd $(TPL)/OVMF_CODE.fd cp -v $(FW_DIR)/$(FW)_VARS$(FW_SFX).fd $(TPL)/OVMF_VARS.fd ifeq ($(strip $(ARCH)),arm64) # AAVMF images must be padded to 64 MiB for QEMU's arm64 "virt" machine. truncate -s 64m $(TPL)/OVMF_CODE.fd truncate -s 64m $(TPL)/OVMF_VARS.fd endif rm -rf $(TPL)/output-cloudimg $(TPL)/seeds-cloudimg.iso cd $(TPL) && PACKER_LOG=$(PACKER_LOG) packer init . cd $(TPL) && PACKER_LOG=$(PACKER_LOG) packer build \ -var debian_series=$(DEBIAN_SERIES) \ -var debian_version=$(DEBIAN_VERSION) \ -var architecture=$(ARCH) \ -var boot_mode=$(BOOT) \ -var ovmf_suffix=$(FW_SFX) \ -var host_is_arm=$(HOST_IS_ARM) \ -var timeout=$(TIMEOUT) \ -var customize_script=$(CUSTOMIZE) \ -var filename=$(OUTPUT) \ -var http_proxy=$(APT_PROXY) \ . @ls -lh $(OUTPUT) # --- MAAS preseed --------------------------------------------------------------- preseed: $(PRESEED) $(PRESEED): maas/curtin_userdata_custom.in @mkdir -p $(WORKDIR) @sed -e 's|@@IMAGE_NAME@@|$(IMAGE_NAME)|g' \ -e 's|@@ARCH@@|$(ARCH)|g' \ $< > $@ @echo "preseed: $@" @echo " -> MAAS region controller uzerinde $(MAAS_PRESEED_DIR)/ altina kopyalayin" install-preseed: $(PRESEED) @if [ "$$(id -u)" -ne 0 ]; then echo "HATA: root gerekir"; exit 1; fi install -D -m 0644 $(PRESEED) $(MAAS_PRESEED_DIR)/$(notdir $(PRESEED)) @echo "kuruldu: $(MAAS_PRESEED_DIR)/$(notdir $(PRESEED))" # --- MAAS'a yukleme ------------------------------------------------------------- upload: @test -f $(OUTPUT) || { echo "HATA: $(OUTPUT) yok, once 'make image'"; exit 1; } maas $(MAAS_PROFILE) boot-resources create \ name='$(MAAS_IMAGE_NAME)' \ title='$(IMAGE_TITLE)' \ architecture='$(MAAS_ARCH)' \ filetype='tgz' \ content@=$(OUTPUT) verify: @test -f $(OUTPUT) || { echo "HATA: $(OUTPUT) yok, once 'make image'"; exit 1; } ./scripts/verify-image.sh $(OUTPUT) # Depoda hangi surumler var, elimizdeki imaj hangi surumde? check-upstream: @echo "==> Available in Debian $(DEBIAN_SERIES):" @curl -fsS http://deb.debian.org/debian/dists/$(DEBIAN_SERIES)/main/binary-$(ARCH)/Packages.gz 2>/dev/null \ | gunzip \ | awk '/^Package: (samba|samba-ad-dc|winbind)$$/{p=$$2; next} \ /^Version: /{if(p!=""){print p" "$$2; p=""}}' \ | sort -V | awk '{v[$$1]=$$2} END{for(k in v) printf " %-18s %s\n", k, v[k]}' \ || echo " (could not reach the archive)" @echo "==> In the local image ($(OUTPUT)):" @if [ -f $(OUTPUT) ]; then \ tar xzf $(OUTPUT) -O ./etc/adc-maas/image-info 2>/dev/null | sed 's/^/ /' \ || echo " (image-info unreadable)"; \ else echo " (no image - run 'make image' first)"; fi # Yerel APT onbellegi - tekrarlanan derlemelerde ~700MB indirmeyi ortadan kaldirir. # Kurduktan sonra: sudo make image APT_PROXY=http://10.0.2.2:3142 deps-cache: @if [ "$$(id -u)" -ne 0 ]; then echo "HATA: root gerekir (sudo make deps-cache)"; exit 1; fi DEBIAN_FRONTEND=noninteractive apt-get install -y apt-cacher-ng systemctl enable --now apt-cacher-ng @echo @echo "Hazir. Derlemede kullanmak icin:" @echo " sudo make image APT_PROXY=http://10.0.2.2:3142" @echo "(10.0.2.2 = packer user-mode aginda build host'un adresi)" # Tek bir degiskenin degerini bas - CI script'leri bunu kullanir. # make -s print-var VAR=OUTPUT print-var: @echo "$($(VAR))" lint: @bash -n scripts/customize-samba-ad.sh.in && echo "customize-samba-ad.sh.in: OK" @bash -n overlay/usr/local/sbin/adc-maas-init && echo "adc-maas-init: OK" @bash -n overlay/usr/local/sbin/adc-sysvol-sync && echo "adc-sysvol-sync: OK" @command -v shellcheck >/dev/null && shellcheck -S warning \ overlay/usr/local/sbin/adc-maas-init overlay/usr/local/sbin/adc-sysvol-sync \ scripts/install-deps.sh || true clean: rm -f $(OVERLAY_TGZ) $(CUSTOMIZE) $(PRESEED) rm -rf $(TPL)/output-cloudimg $(TPL)/seeds-cloudimg.iso \ $(TPL)/OVMF_CODE.fd $(TPL)/OVMF_VARS.fd distclean: rm -rf $(WORKDIR)