init
This commit is contained in:
142
Makefile
Normal file
142
Makefile
Normal file
@@ -0,0 +1,142 @@
|
||||
# Alpine VM Image Builder
|
||||
# ------------------------
|
||||
# Builds a bootable Alpine Linux disk image for Cloud Hypervisor direct boot.
|
||||
#
|
||||
# Usage:
|
||||
# make build — generate GPG key + build qcow2 image
|
||||
# make build-raw — build raw image (for Cloud Hypervisor direct boot)
|
||||
# make extract-kernel — extract kernel + initramfs from image
|
||||
# make clean — remove build artifacts
|
||||
#
|
||||
# Configurable variables (override on command line):
|
||||
# IMAGE_SIZE Size of the disk image (default: 4G)
|
||||
# ALPINE_BRANCH Alpine release branch (default: latest-stable)
|
||||
# KERNEL_FLAVOR Kernel variant (default: virt)
|
||||
# ALPINE_MIRROR APK mirror (default: http://dl-cdn.alpinelinux.org/alpine)
|
||||
|
||||
SHELL := /bin/sh
|
||||
|
||||
# --- configurable ----------------------------------------------------
|
||||
IMAGE_NAME ?= alpine-vm
|
||||
IMAGE_SIZE ?= 4G
|
||||
IMAGE_FORMAT ?= qcow2
|
||||
ALPINE_BRANCH ?= latest-stable
|
||||
KERNEL_FLAVOR ?= virt
|
||||
ALPINE_MIRROR ?= http://dl-cdn.alpinelinux.org/alpine
|
||||
INITFS_FEATURES ?= kms scsi virtio
|
||||
|
||||
IMAGE_FILE = $(IMAGE_NAME).$(IMAGE_FORMAT)
|
||||
SCRIPT_DIR = $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
OVERLAY_DIR = $(SCRIPT_DIR)/overlay
|
||||
CONFIGURE_SH = $(SCRIPT_DIR)/configure.sh
|
||||
GEN_GPG_SH = $(SCRIPT_DIR)/gen-gpg-key.sh
|
||||
|
||||
# alpine-make-vm-image — download if not found
|
||||
MAKE_VM_IMAGE = $(SCRIPT_DIR)/alpine-make-vm-image
|
||||
MAKE_VM_IMAGE_URL = https://raw.githubusercontent.com/alpinelinux/alpine-make-vm-image/v0.13.4/alpine-make-vm-image
|
||||
|
||||
# --- helper ----------------------------------------------------------
|
||||
|
||||
$(MAKE_VM_IMAGE):
|
||||
@echo ">>> Downloading alpine-make-vm-image ..."
|
||||
wget -q -O $@ $(MAKE_VM_IMAGE_URL)
|
||||
chmod +x $@
|
||||
|
||||
# --- GPG key ---------------------------------------------------------
|
||||
|
||||
.gpg-done: $(GEN_GPG_SH)
|
||||
@echo ">>> Generating GPG key ..."
|
||||
cd $(SCRIPT_DIR) && $(GEN_GPG_SH)
|
||||
@touch $@
|
||||
|
||||
# --- build -----------------------------------------------------------
|
||||
|
||||
build: .gpg-done $(MAKE_VM_IMAGE)
|
||||
@echo ">>> Building $(IMAGE_FILE) ..."
|
||||
@test -f $(OVERLAY_DIR)/root/gpg-key.asc || { \
|
||||
echo "ERROR: GPG key not found. Run 'make gpg-key' first." >&2; \
|
||||
exit 1; \
|
||||
}
|
||||
$(MAKE_VM_IMAGE) \
|
||||
--branch $(ALPINE_BRANCH) \
|
||||
--image-format $(IMAGE_FORMAT) \
|
||||
--image-size $(IMAGE_SIZE) \
|
||||
--kernel-flavor $(KERNEL_FLAVOR) \
|
||||
--mirror-uri $(ALPINE_MIRROR) \
|
||||
--initfs-features '$(INITFS_FEATURES)' \
|
||||
--serial-console \
|
||||
--fs-skel-dir $(OVERLAY_DIR) \
|
||||
--fs-skel-chown root:root \
|
||||
--script-chroot \
|
||||
--packages "python3 py3-yaml py3-pydantic git curl gnupg docker docker-cli-buildx docker-cli-compose" \
|
||||
$(IMAGE_FILE) \
|
||||
$(CONFIGURE_SH)
|
||||
@echo ">>> Image built: $(IMAGE_FILE)"
|
||||
@ls -lh $(IMAGE_FILE)
|
||||
|
||||
# Raw image (best for Cloud Hypervisor)
|
||||
build-raw:
|
||||
$(MAKE) build IMAGE_FORMAT=raw
|
||||
|
||||
# Build without GPG key (for testing / CI without GPG)
|
||||
build-no-gpg: $(MAKE_VM_IMAGE)
|
||||
@echo ">>> Building $(IMAGE_FILE) without GPG key ..."
|
||||
$(MAKE_VM_IMAGE) \
|
||||
--branch $(ALPINE_BRANCH) \
|
||||
--image-format $(IMAGE_FORMAT) \
|
||||
--image-size $(IMAGE_SIZE) \
|
||||
--kernel-flavor $(KERNEL_FLAVOR) \
|
||||
--mirror-uri $(ALPINE_MIRROR) \
|
||||
--initfs-features '$(INITFS_FEATURES)' \
|
||||
--serial-console \
|
||||
--fs-skel-dir $(OVERLAY_DIR) \
|
||||
--fs-skel-chown root:root \
|
||||
--script-chroot \
|
||||
--packages "python3 py3-yaml py3-pydantic git curl gnupg docker docker-cli-buildx docker-cli-compose" \
|
||||
$(IMAGE_FILE) \
|
||||
$(CONFIGURE_SH)
|
||||
@echo ">>> Image built: $(IMAGE_FILE)"
|
||||
@ls -lh $(IMAGE_FILE)
|
||||
|
||||
# --- kernel extraction -----------------------------------------------
|
||||
|
||||
extract-kernel: $(IMAGE_FILE)
|
||||
@echo ">>> Extracting kernel and initramfs from $(IMAGE_FILE) ..."
|
||||
@which guestmount >/dev/null 2>&1 || { \
|
||||
echo "ERROR: guestmount (libguestfs) required. Install: apk add libguestfs" >&2; \
|
||||
exit 1; \
|
||||
}
|
||||
@mkdir -p $(IMAGE_NAME)-boot
|
||||
guestmount -a $(IMAGE_FILE) -m /dev/sda --ro $(IMAGE_NAME)-boot
|
||||
cp $(IMAGE_NAME)-boot/boot/vmlinuz-$(KERNEL_FLAVOR) $(IMAGE_NAME)-vmlinuz
|
||||
cp $(IMAGE_NAME)-boot/boot/initramfs-$(KERNEL_FLAVOR) $(IMAGE_NAME)-initramfs
|
||||
guestunmount $(IMAGE_NAME)-boot
|
||||
rmdir $(IMAGE_NAME)-boot
|
||||
@echo ">>> Kernel : $(IMAGE_NAME)-vmlinuz"
|
||||
@echo ">>> Initrd : $(IMAGE_NAME)-initramfs"
|
||||
|
||||
# --- utilities -------------------------------------------------------
|
||||
|
||||
gpg-key: .gpg-done
|
||||
@echo ">>> GPG key ready"
|
||||
|
||||
gpg-fingerprint:
|
||||
@gpg --batch --fingerprint "builder@localhost" || echo "GPG key not found in host keyring"
|
||||
|
||||
# --- cleanup ---------------------------------------------------------
|
||||
|
||||
clean:
|
||||
rm -f $(IMAGE_FILE)
|
||||
rm -f $(IMAGE_NAME).raw
|
||||
rm -f $(IMAGE_NAME)-vmlinuz $(IMAGE_NAME)-initramfs
|
||||
rm -f .gpg-done
|
||||
rm -f $(MAKE_VM_IMAGE)
|
||||
rm -rf $(IMAGE_NAME)-boot
|
||||
@echo ">>> Cleaned (GPG key in overlay/ preserved — use 'make clean-all' to remove)"
|
||||
|
||||
clean-all: clean
|
||||
rm -f $(OVERLAY_DIR)/root/gpg-key.asc
|
||||
rm -f $(OVERLAY_DIR)/root/gpg-pubkey.asc
|
||||
@echo ">>> All artifacts cleaned"
|
||||
|
||||
.PHONY: build build-raw build-no-gpg extract-kernel gpg-key gpg-fingerprint clean clean-all
|
||||
Reference in New Issue
Block a user