Compare commits

..

5 Commits

19 changed files with 448 additions and 44 deletions
+4 -1
View File
@@ -1,4 +1,4 @@
.PHONY: base vagrant clean .PHONY: default base vagrant clean
HEADLESS ?= true HEADLESS ?= true
@@ -11,5 +11,8 @@ base:
vagrant: vagrant:
PKR_VAR_headless="$(HEADLESS)" packer build x86_64-qemu-vagrant.pkr.hcl PKR_VAR_headless="$(HEADLESS)" packer build x86_64-qemu-vagrant.pkr.hcl
package:
./scripts/package.sh
clean: clean:
rm -rf ./builds rm -rf ./builds
+24 -14
View File
@@ -1,24 +1,34 @@
# Debian Trixie Builds # Debian Trixie Builds
This directory contains Packer configuration for building Debian 13 (Trixie) This directory contains Packer configuration for building Debian 13 (Trixie)
images
## Usage ### Overview
Build the image: These builds use a multi-stage Packer workflow:
``` - The first stage creates a minimal base image from the installer ISO
make - The second stage reuses that base image to produce a Vagrant-ready box
```
Remove build artifacts: ### Usage
``` Build the base qemu image:
make clean
```
Build with a visible VM console for debugging: make base
``` Build vagrant image:
make HEADLESS=false
``` 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/debian13](https://portal.cloud.hashicorp.com/vagrant/discover/krislamo.org/debian13)
on Vagrant Cloud
-3
View File
@@ -1,3 +0,0 @@
#!/usr/bin/env bash
apt-get update
apt-get upgrade -y
Regular → Executable
+6 -10
View File
@@ -1,16 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -eux set -x
export DEBIAN_FRONTEND=noninteractive apt-get clean || exit 1
apt-get clean -y
apt-get autoclean -y
rm -f /var/lib/dhcpcd/*
rm -rf /var/cache/apt/archives/* rm -rf /var/cache/apt/archives/*
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/*
rm -rf /var/tmp/* /var/tmp/.[!.]* rm -rf /var/tmp/* /var/tmp/.[!.]*
[[ -f /var/log/wtmp ]] && truncate -s 0 /var/log/wtmp
truncate -s 0 /var/log/wtmp dd if=/dev/zero of=/EMPTY bs=1M
sync || exit 1
dd if=/dev/zero of=/EMPTY bs=1M || true rm -f /EMPTY || exit 1
sync
rm -rf /EMPTY
+31
View File
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -x
err() {
printf "[ERROR]: %s\n" "$1" >&2
exit 1
}
export DEBIAN_FRONTEND=noninteractive
apt-get update || err "failed to update APT cache"
apt-get install -y systemd-resolved || err "failed to install systemd-resolved"
install -d -m 755 -o root -g root /etc/systemd/network ||
err "failed to create /etc/systemd/network"
cat >/etc/systemd/network/lan0.network <<'EOF' || err "failed to write lan0"
[Match]
Name=e*
Type=ether
[Network]
DHCP=ipv4
EOF
chown root:root /etc/systemd/network/lan0.network || err "failed to chown"
chmod 644 /etc/systemd/network/lan0.network || err "failed to chmod 644"
systemctl enable systemd-networkd || err "failed to enable networkd"
systemctl enable systemd-resolved || err "failed to enable resolved"
systemctl disable networking || err "failed to disable networking service"
apt-get purge -y ifupdown || err "failed to purge ifupdown"
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -x
err() {
printf "[ERROR]: %s\n" "$1" >&2
exit 1
}
IMG_DIR="./builds/qemu/debian-13-64-vagrant"
if [[ ! -f "$IMG_DIR/debian-13-64-vagrant" ]]; then
err "debian-13-64-vagrant doesn't exist"
fi
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/debian-13-64-vagrant" "$IMG_DIR/box.img" ||
err "failed to hardlink 'debian-13-64-vagrant' to 'box.img' file"
fi
if [[ ! -f ./builds/vagrant/debian-13-64-vagrant.box ]]; then
tar -C "$IMG_DIR" -cvzf ./builds/vagrant/debian-13-64-vagrant.box \
box.img metadata.json Vagrantfile || err "failed to create .box file"
exit 0
fi
err "debian-13-64-vagrant.box already exists"
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -x
export DEBIAN_FRONTEND=noninteractive
apt-get update || exit 1
apt-get upgrade -y || exit 1
Regular → Executable
+31 -12
View File
@@ -1,20 +1,39 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -eu set -x
err() {
printf "[ERROR]: %s\n" "$1" >&2
exit 1
}
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
apt-get update apt-get update || err "failed to update APT cache"
apt-get install -y openssl curl sudo apt-get install -y \
qemu-guest-agent \
nfs-common \
openssl \
curl \
sudo \
vim \
python3-apt || err "failed to install packages"
useradd -m -p "$(openssl passwd -1 vagrant)" vagrant 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"
echo "vagrant ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/vagrant
chmod 440 /etc/sudoers.d/vagrant
install -d -m 0700 -o vagrant -g vagrant /home/vagrant/.ssh
BASE_GH_URL="https://raw.githubusercontent.com/hashicorp/vagrant/refs/heads" BASE_GH_URL="https://raw.githubusercontent.com/hashicorp/vagrant/refs/heads"
curl -fsSL "${BASE_GH_URL}/main/keys/vagrant.pub" \ curl -fsSL "${BASE_GH_URL}/main/keys/vagrant.pub" \
-o /home/vagrant/.ssh/authorized_keys -o /home/vagrant/.ssh/authorized_keys ||
chmod 600 /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 sed -i 's/PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config ||
passwd -d root 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"
+4 -3
View File
@@ -8,11 +8,11 @@ packer {
} }
variable "iso_url" { variable "iso_url" {
default = "https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-13.0.0-amd64-netinst.iso" default = "https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-13.4.0-amd64-netinst.iso"
} }
variable "iso_hash" { variable "iso_hash" {
default = "sha256:e363cae0f1f22ed73363d0bde50b4ca582cb2816185cf6eac28e93d9bb9e1504" default = "sha256:0b813535dd76f2ea96eff908c65e8521512c92a0631fd41c95756ffd7d4896dc"
} }
variable "disk_size" { variable "disk_size" {
@@ -69,7 +69,8 @@ build {
provisioner "shell" { provisioner "shell" {
scripts = [ scripts = [
"scripts/aptupdate.sh", "scripts/upgrade.sh",
"scripts/networkd.sh",
"scripts/clean.sh" "scripts/clean.sh"
] ]
} }
+1 -1
View File
@@ -27,7 +27,7 @@ source "qemu" "debian-13-64-vagrant" {
iso_url = "builds/qemu/debian-13-64-base/debian-13-64-base" iso_url = "builds/qemu/debian-13-64-base/debian-13-64-base"
disk_image = true disk_image = true
iso_checksum = "none" iso_checksum = "none"
output_directory = "builds/qemu" output_directory = "builds/qemu/debian-13-64-vagrant"
shutdown_command = "/usr/bin/systemctl poweroff" shutdown_command = "/usr/bin/systemctl poweroff"
disk_interface = "virtio" disk_interface = "virtio"
disk_size = var.disk_size disk_size = var.disk_size
+18
View File
@@ -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
+34
View File
@@ -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
+37
View File
@@ -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
+11
View File
@@ -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
+35
View File
@@ -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"
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -x
dnf upgrade -y || exit 1
+36
View File
@@ -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"
+74
View File
@@ -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<wait2>",
"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",
"<enter><wait>",
"initrd /images/pxeboot/initrd.img<enter><wait15>",
"boot<enter><wait>"
]
}
build {
name = "rocky-base"
sources = ["source.qemu.rocky-10-64-base"]
provisioner "shell" {
scripts = [
"scripts/upgrade.sh",
"scripts/clean.sh"
]
}
}
+58
View File
@@ -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"
]
}
}