diff --git a/rocky-10/Makefile b/rocky-10/Makefile new file mode 100644 index 0000000..45b5ce9 --- /dev/null +++ b/rocky-10/Makefile @@ -0,0 +1,18 @@ +.PHONY: default base vagrant clean + +HEADLESS ?= true + +default: + @echo "Please run 'make base' or 'make vagrant'" + +base: + PKR_VAR_headless="$(HEADLESS)" packer build x86_64-qemu-base.pkr.hcl + +vagrant: + PKR_VAR_headless="$(HEADLESS)" packer build x86_64-qemu-vagrant.pkr.hcl + +package: + ./scripts/package.sh + +clean: + rm -rf ./builds diff --git a/rocky-10/README.md b/rocky-10/README.md new file mode 100644 index 0000000..f4ae8fe --- /dev/null +++ b/rocky-10/README.md @@ -0,0 +1,34 @@ +# Rocky Red Quartz Builds + +This directory contains Packer configuration for building Rocky 10 (Red Quartz) + +### Overview + +These builds use a multi-stage Packer workflow: + +- The first stage creates a minimal base image from the installer ISO +- The second stage reuses that base image to produce a Vagrant-ready box + +### Usage + +Build the base qemu image: + + make base + +Build vagrant image: + + make vagrant + +Package vagrant box: + + make package + +Build with visible console: + + make base HEADLESS=false + +### Publishing + +Built boxes from this configuration are published at +[krislamo.org/rocky10](https://portal.cloud.hashicorp.com/vagrant/discover/krislamo.org/rocky10) +on Vagrant Cloud diff --git a/rocky-10/http/ks.cfg b/rocky-10/http/ks.cfg new file mode 100644 index 0000000..c1c7c68 --- /dev/null +++ b/rocky-10/http/ks.cfg @@ -0,0 +1,37 @@ +# Source +url --url='https://download.rockylinux.org/pub/rocky/10/BaseOS/x86_64/os/' + +# Localization +lang en_US.UTF-8 +keyboard --xlayouts='us' +timezone America/New_York --utc + +# Initial security settings +rootpw rocky --allow-ssh +selinux --enforcing +firewall --enabled --ssh + +# Network +network --bootproto=dhcp --device=link --activate --onboot=on +network --hostname=redquartz.localdomain + +# Disk +zerombr +ignoredisk --only-use=vda +clearpart --all --initlabel --disklabel=gpt +bootloader --location=mbr --append="net.ifnames=0 biosdevname=0" +part biosboot --fstype=biosboot --size=1 +part /boot --fstype=xfs --size=1024 +part swap --fstype=swap --size=1024 +part / --fstype=xfs --size=1 --grow + +# Packages +%packages +@core +%end + +# Install +text +reboot +skipx +firstboot --disable diff --git a/rocky-10/scripts/clean.sh b/rocky-10/scripts/clean.sh new file mode 100755 index 0000000..c238f69 --- /dev/null +++ b/rocky-10/scripts/clean.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -x + +dnf clean all || exit 1 +rm -rf /var/cache/libdnf5/* +rm -rf /var/tmp/* /var/tmp/.[!.]* +[[ -f /var/log/wtmp ]] && truncate -s 0 /var/log/wtmp + +dd if=/dev/zero of=/EMPTY bs=1M +sync || exit 1 +rm -f /EMPTY || exit 1 diff --git a/rocky-10/scripts/package.sh b/rocky-10/scripts/package.sh new file mode 100755 index 0000000..20fcd5d --- /dev/null +++ b/rocky-10/scripts/package.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +set -x + +err() { + printf "[ERROR]: %s\n" "$1" >&2 + exit 1 +} + +IMG_NAME="rocky-10-64-vagrant" +IMG_DIR="./builds/qemu/$IMG_NAME" +[[ ! -f "$IMG_DIR/$IMG_NAME" ]] && err "$IMG_NAME doesn't exist" + +cat >"$IMG_DIR/metadata.json" <<'EOF' || err "failed to write metadata.json" +{"provider":"libvirt","format":"qcow2","virtual_size":100} +EOF + +cat >"$IMG_DIR/Vagrantfile" <<'EOF' || err "failed to write Vagrantfile" +Vagrant.configure("2") do |config| + config.vm.synced_folder ".", "/vagrant", type: "nfs", nfs_version: 4 +end +EOF + +mkdir -p ./builds/vagrant || err "failed to mkdir ./builds/vagrant" +if [[ ! -f "$IMG_DIR/box.img" ]]; then + cp -l "$IMG_DIR/$IMG_NAME" "$IMG_DIR/box.img" || + err "failed to hardlink '$IMG_NAME' to 'box.img' file" +fi + +if [[ ! -f "./builds/vagrant/$IMG_NAME.box" ]]; then + tar -C "$IMG_DIR" -cvzf "./builds/vagrant/$IMG_NAME.box" \ + box.img metadata.json Vagrantfile || err "failed to create .box file" + exit 0 +fi + +err "$IMG_NAME.box already exists" diff --git a/rocky-10/scripts/upgrade.sh b/rocky-10/scripts/upgrade.sh new file mode 100755 index 0000000..1b982ff --- /dev/null +++ b/rocky-10/scripts/upgrade.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +set -x +dnf upgrade -y || exit 1 diff --git a/rocky-10/scripts/vagrant.sh b/rocky-10/scripts/vagrant.sh new file mode 100755 index 0000000..2c3e675 --- /dev/null +++ b/rocky-10/scripts/vagrant.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +set -x + +err() { + printf "[ERROR]: %s\n" "$1" >&2 + exit 1 +} + +dnf install -y \ + qemu-guest-agent \ + nfs-utils \ + openssl \ + curl \ + sudo \ + vim-enhanced || err "failed to install packages" + +useradd -m -s /bin/bash -p "$(openssl passwd -1 vagrant)" vagrant || + err "failed to add vagrant user" +printf '%s\n' "vagrant ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/vagrant || + err "failed to write sudoers file" +chmod 440 /etc/sudoers.d/vagrant || err "failed to chmod sudoers file" +install -d -m 0700 -o vagrant -g vagrant /home/vagrant/.ssh || + err "failed to create vagrant .ssh dir" + +BASE_GH_URL="https://raw.githubusercontent.com/hashicorp/vagrant/refs/heads" +curl -fsSL "${BASE_GH_URL}/main/keys/vagrant.pub" \ + -o /home/vagrant/.ssh/authorized_keys || + err "failed to download initial authorized_keys" +chmod 600 /home/vagrant/.ssh/authorized_keys || err "failed to chmod 600 authorized_keys" +chown vagrant:vagrant /home/vagrant/.ssh/authorized_keys || + err "failed to chown initial authorized_keys" + +sed -i 's/PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config || + err "failed to disable root login via SSH" +passwd -d root || err "failed to delete root password" +passwd -l root || err "failed to lock root password" diff --git a/rocky-10/x86_64-qemu-base.pkr.hcl b/rocky-10/x86_64-qemu-base.pkr.hcl new file mode 100644 index 0000000..cdc8621 --- /dev/null +++ b/rocky-10/x86_64-qemu-base.pkr.hcl @@ -0,0 +1,74 @@ +packer { + required_plugins { + qemu = { + version = ">= 1.1.3" + source = "github.com/hashicorp/qemu" + } + } +} + +variable "iso_url" { + default = "https://download.rockylinux.org/pub/rocky/10/isos/x86_64/Rocky-10.1-x86_64-boot.iso" +} + +variable "iso_hash" { + default = "sha256:18543988d9a1a5632d142c3dc288136dcc48ab71628f92ebcd40ada7f4ecd110" +} + +variable "disk_size" { + default = 102400 +} + +variable "memory" { + default = 4096 +} + +variable "ssh_password" { + default = "rocky" +} + +variable "headless" { + default = true +} + +source "qemu" "rocky-10-64-base" { + iso_url = var.iso_url + iso_checksum = "${var.iso_hash}" + output_directory = "builds/qemu/rocky-10-64-base" + shutdown_command = "/usr/bin/systemctl poweroff" + disk_interface = "virtio" + cpu_model = "host" + disk_size = var.disk_size + memory = var.memory + headless = var.headless + format = "qcow2" + accelerator = "kvm" + http_directory = "http" + ssh_username = "root" + ssh_password = var.ssh_password + ssh_timeout = "60m" + vm_name = "rocky-10-64-base" + net_device = "virtio-net" + boot_wait = "5s" + boot_command = [ + "c", + "linux /images/pxeboot/vmlinuz", + " inst.stage2=https://download.rockylinux.org/pub/rocky/10/BaseOS/x86_64/os/", + " inst.text inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg ip=dhcp", + "", + "initrd /images/pxeboot/initrd.img", + "boot" + ] +} + +build { + name = "rocky-base" + sources = ["source.qemu.rocky-10-64-base"] + + provisioner "shell" { + scripts = [ + "scripts/upgrade.sh", + "scripts/clean.sh" + ] + } +} diff --git a/rocky-10/x86_64-qemu-vagrant.pkr.hcl b/rocky-10/x86_64-qemu-vagrant.pkr.hcl new file mode 100644 index 0000000..789ca47 --- /dev/null +++ b/rocky-10/x86_64-qemu-vagrant.pkr.hcl @@ -0,0 +1,58 @@ +packer { + required_plugins { + qemu = { + version = ">= 1.1.3" + source = "github.com/hashicorp/qemu" + } + } +} + +variable "memory" { + default = 4096 +} + +variable "ssh_password" { + default = "rocky" +} + +variable "headless" { + default = true +} + +variable "disk_size" { + default = 102400 +} + +source "qemu" "rocky-10-64-vagrant" { + iso_url = "builds/qemu/rocky-10-64-base/rocky-10-64-base" + disk_image = true + iso_checksum = "none" + output_directory = "builds/qemu/rocky-10-64-vagrant" + shutdown_command = "/usr/bin/systemctl poweroff" + disk_interface = "virtio" + cpu_model = "host" + disk_size = var.disk_size + memory = var.memory + headless = var.headless + format = "qcow2" + accelerator = "kvm" + http_directory = "http" + ssh_username = "root" + ssh_password = var.ssh_password + ssh_timeout = "60m" + vm_name = "rocky-10-64-vagrant" + net_device = "virtio-net" + boot_wait = "5s" +} + +build { + name = "rocky-base" + sources = ["source.qemu.rocky-10-64-vagrant"] + + provisioner "shell" { + scripts = [ + "scripts/vagrant.sh", + "scripts/clean.sh" + ] + } +}