Add 2nd box (libvirt with UEFI)
This commit is contained in:
parent
e2f3d03b1d
commit
26cba165dc
|
@ -0,0 +1,22 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
tab_width = 8
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
# HCL2
|
||||
[{*.pkr.hcl,*.tf,*.tfvars}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[{Makefile,*.sh}]
|
||||
indent_style = tab
|
||||
tab_width = 2
|
||||
|
||||
[*.md]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = false
|
18
Makefile
18
Makefile
|
@ -2,12 +2,22 @@ VM_STATE_RUNNING ?= true
|
|||
|
||||
all: build_all alpine-qemu
|
||||
|
||||
build_all: iso_checksum alpine-qemu.pkr.hcl
|
||||
build_all: checksum alpine-qemu.pkr.hcl alpine-libvirt.pkr.hcl
|
||||
|
||||
alpine-qemu.pkr.hcl:
|
||||
alpine-qemu.pkr.hcl: clean
|
||||
@packer validate $@
|
||||
@packer build -on-error=abort $@
|
||||
|
||||
# By default Packer will build all sources at the same time
|
||||
# We explicitly make it build in order here
|
||||
alpine-libvirt.pkr.hcl: clean
|
||||
@packer init -upgrade $@
|
||||
@packer validate $@
|
||||
@echo "==> Building QEMU box ..."
|
||||
@packer build -on-error=abort -only="*.alpine-qemu-uefi" $@
|
||||
@echo "==> Importing QEMU box as libvirt domain ..."
|
||||
@packer build -on-error=abort -only="*.alpine-libvirt" $@
|
||||
|
||||
alpine-qemu:
|
||||
@terraform -chdir=./terraform/alpine-qemu init -upgrade -migrate-state
|
||||
@terraform -chdir=./terraform/alpine-qemu validate
|
||||
|
@ -25,7 +35,7 @@ clean:
|
|||
destroy:
|
||||
@find ./terraform/* -prune -exec terraform -chdir={} apply -destroy \;
|
||||
|
||||
iso_checksum:
|
||||
checksum:
|
||||
@find . -name *.pkr.hcl -type f -exec sh update_iso_checksum.sh {} \;
|
||||
|
||||
.PHONY: all build_all alpine-qemu.pkr.hcl alpine-qemu format-packer format-terraform clean destroy iso_checksum
|
||||
.PHONY: all build_all alpine-qemu.pkr.hcl alpine-libvirt.pkr.hcl alpine-qemu format-packer format-terraform clean destroy checksum
|
||||
|
|
39
README.md
39
README.md
|
@ -1,19 +1,44 @@
|
|||
# packer-templates
|
||||
# Packer templates
|
||||
|
||||
This repository holds Packer's VM templates I use. Most (if not all) of them run [AlpineLinux](https://alpinelinux.org).
|
||||
|
||||
## Dependencies
|
||||
|
||||
For [update_iso_checksum.sh](./update_iso_checksum.sh) script:
|
||||
- [hcl2json](https://github.com/tmccombs/hcl2json)
|
||||
- [jq](https://github.com/stedolan/jq) ([gojq](https://github.com/itchyny/gojq) and [jaq](https://github.com/01mf02/jaq) also work)
|
||||
|
||||
Other:
|
||||
- [packer](https://www.packer.io/) (of course)
|
||||
- [terraform](https://www.terraform.io/)
|
||||
- [make](https://www.gnu.org/software/make/) (for convenience’ sake)
|
||||
- [qemu](http://www.qemu.org/) + [libvirt](https://libvirt.org/)
|
||||
|
||||
Note that libvirt plugins (for both Packer and Terraform) do not support modular daemons so running `libvirtd` service is required. Issue filled at <https://github.com/digitalocean/go-libvirt/issues/171>.
|
||||
|
||||
## VM boxes
|
||||
|
||||
- [alpine-qemu.pkr.hcl](./alpine-qemu.pkr.hcl): libvirt-compatible VM on local machine running Alpine edge.
|
||||
- [alpine-qemu.pkr.hcl](./alpine-qemu.pkr.hcl): libvirt-compatible VM on local machine running Alpine edge
|
||||
|
||||
```bash
|
||||
# Build the VM box
|
||||
make alpine-qemu.pkr.hcl
|
||||
|
||||
# Import the built box to libvirt volume and launch it
|
||||
VM_STATE_RUNNING=true terraform -chdir=terraform/alpine-qemu apply
|
||||
# Build the VM box and launch it as a libvirt domain
|
||||
VM_STATE_RUNNING=true make alpine-qemu.pkr.hcl alpine-qemu
|
||||
```
|
||||
|
||||
- [alpine-libvirt.pkr.hcl](./alpine-libvirt.pkr.hcl): a variation of `alpine-qemu` box with UEFI, using [packer-plugin-libvirt](https://github.com/thomasklein94/packer-plugin-libvirt) instead of [terraform-provider-libvirt](https://github.com/dmacvicar/terraform-provider-libvirt)
|
||||
|
||||
```bash
|
||||
# Build the box and import it into `default` libvirt pool
|
||||
make alpine-libvirt.pkr.hcl
|
||||
|
||||
# You'll have to start the VM manually
|
||||
virsh -c qemu:///system start packer-alpine-edge-uefi-libvirt-x86_64
|
||||
```
|
||||
|
||||
## Acknowledge
|
||||
|
||||
- [rgl/alpine-vagrant](https://github.com/rgl/alpine-vagrant)
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
packer {
|
||||
required_plugins {
|
||||
libvirt = {
|
||||
version = ">= 0.3.3"
|
||||
source = "github.com/thomasklein94/libvirt"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "headless" {
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "iso_url" {
|
||||
type = string
|
||||
default = "https://dl-cdn.alpinelinux.org/alpine/v3.16/releases/x86_64/alpine-standard-3.16.2-x86_64.iso"
|
||||
}
|
||||
|
||||
variable "iso_checksum" {
|
||||
type = string
|
||||
default = "sha512:b4dcc47b28390c20348d14643863ce41fb9ad55755a1ec00af0117c3dd09c9d03c2c722b005534abece67baa2a017bd78a65c18d2dccd525491d679fe13cd615"
|
||||
}
|
||||
|
||||
variable "disk_size" {
|
||||
type = string
|
||||
default = "20G"
|
||||
}
|
||||
|
||||
variable "ram" {
|
||||
type = number
|
||||
default = 2048
|
||||
}
|
||||
|
||||
variable "cpus" {
|
||||
type = number
|
||||
default = 2
|
||||
}
|
||||
|
||||
variable "rootfstype" {
|
||||
type = string
|
||||
default = "ext4"
|
||||
}
|
||||
|
||||
variable "ssh_username" {
|
||||
type = string
|
||||
default = "kawaii"
|
||||
}
|
||||
|
||||
variable "ssh_password" {
|
||||
type = string
|
||||
default = "kawaii"
|
||||
}
|
||||
|
||||
variable "vm_name" {
|
||||
type = string
|
||||
default = "packer-alpine-edge-uefi-libvirt-x86_64"
|
||||
}
|
||||
|
||||
source "qemu" "alpine-qemu-uefi" {
|
||||
accelerator = "kvm"
|
||||
boot_command = [
|
||||
"root<enter>",
|
||||
"ifconfig eth0 up && udhcpc -i eth0<enter><wait10s>",
|
||||
"wget -qO answers http://{{.HTTPIP}}:{{.HTTPPort}}/answers/alpine-libvirt<enter><wait5s>",
|
||||
"echo 'USEROPTS=\"-a -u ${var.ssh_username}\"' >> answers<enter>",
|
||||
"ERASE_DISKS=/dev/vda ROOTFS=${var.rootfstype} setup-alpine -ef answers<enter><wait10m>",
|
||||
"wget -qO- http://{{.HTTPIP}}:{{.HTTPPort}}/scripts/reset-uefi-bootloaders.sh | sh -s /dev/vda<enter><wait30s>",
|
||||
"reboot<enter><wait40s>",
|
||||
"root<enter>",
|
||||
"echo '${var.ssh_username}:${var.ssh_password}' | chpasswd<enter>",
|
||||
"sed -i 's/^permit persist/permit nopass/' /etc/doas.d/doas.conf<enter>",
|
||||
"apk add dropbear-scp<enter>",
|
||||
"passwd -l root<enter>",
|
||||
"reboot<enter>"
|
||||
]
|
||||
boot_wait = "30s"
|
||||
disk_cache = "none"
|
||||
disk_compression = true
|
||||
disk_discard = "unmap"
|
||||
disk_interface = "virtio"
|
||||
disk_size = var.disk_size
|
||||
format = "qcow2"
|
||||
headless = var.headless
|
||||
http_directory = "."
|
||||
iso_checksum = var.iso_checksum
|
||||
iso_url = var.iso_url
|
||||
net_device = "virtio-net"
|
||||
output_directory = "artifacts/libvirt"
|
||||
qemu_binary = "/usr/bin/qemu-system-x86_64"
|
||||
qemuargs = [
|
||||
["-bios", "/usr/share/OVMF/OVMF.fd"],
|
||||
["-m", "${var.ram}"],
|
||||
["-display", "none"],
|
||||
["-smp", "${var.cpus}"]
|
||||
]
|
||||
shutdown_command = "doas /sbin/poweroff"
|
||||
ssh_password = var.ssh_password
|
||||
ssh_username = var.ssh_username
|
||||
ssh_wait_timeout = "30m"
|
||||
vm_name = "${var.vm_name}.qcow2"
|
||||
}
|
||||
|
||||
source "libvirt" "alpine-libvirt" {
|
||||
libvirt_uri = "qemu:///system"
|
||||
domain_name = var.vm_name
|
||||
domain_type = "kvm"
|
||||
vcpu = var.cpus
|
||||
memory = var.ram
|
||||
network_address_source = "agent"
|
||||
shutdown_mode = "guest"
|
||||
|
||||
network_interface {
|
||||
type = "bridge"
|
||||
bridge = "virbr0"
|
||||
model = "virtio"
|
||||
}
|
||||
|
||||
communicator {
|
||||
communicator = "none"
|
||||
}
|
||||
|
||||
volume {
|
||||
alias = "artifact"
|
||||
target_dev = "vda"
|
||||
bus = "virtio"
|
||||
format = "qcow2"
|
||||
pool = "default"
|
||||
name = "${var.vm_name}.qcow2"
|
||||
capacity = var.disk_size
|
||||
|
||||
source {
|
||||
type = "external"
|
||||
urls = ["./artifacts/libvirt/${var.vm_name}.qcow2"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
build {
|
||||
sources = ["source.qemu.alpine-qemu-uefi"]
|
||||
|
||||
provisioner "shell" {
|
||||
execute_command = "{{.Vars}} doas sh {{.Path}}"
|
||||
scripts = ["scripts/provision-generic.sh"]
|
||||
}
|
||||
}
|
||||
|
||||
build {
|
||||
sources = ["source.libvirt.alpine-libvirt"]
|
||||
}
|
|
@ -19,13 +19,13 @@ variable "disk_size" {
|
|||
}
|
||||
|
||||
variable "ram" {
|
||||
type = string
|
||||
default = "2048M"
|
||||
type = number
|
||||
default = 2048
|
||||
}
|
||||
|
||||
variable "cpus" {
|
||||
type = string
|
||||
default = "2"
|
||||
type = number
|
||||
default = 2
|
||||
}
|
||||
|
||||
variable "rootfstype" {
|
||||
|
@ -89,11 +89,7 @@ build {
|
|||
sources = ["source.qemu.alpine-qemu"]
|
||||
|
||||
provisioner "shell" {
|
||||
execute_command = "doas sh {{.Path}}"
|
||||
inline_shebang = "/bin/sh -e"
|
||||
inline = [
|
||||
"apk add qemu-guest-agent",
|
||||
"rc-update add qemu-guest-agent"
|
||||
]
|
||||
execute_command = "{{.Vars}} doas sh {{.Path}}"
|
||||
script = "scripts/provision-generic.sh"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# Answer file for alpine-libvirt.pkr.hcl template
|
||||
|
||||
KEYMAPOPTS="us us"
|
||||
|
||||
HOSTNAMEOPTS="alpine-libvirt"
|
||||
|
||||
DEVDOPTS="mdev"
|
||||
|
||||
INTERFACESOPTS="auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
auto eth0
|
||||
iface eth0 inet dhcp
|
||||
hostname alpine-libvirt
|
||||
"
|
||||
|
||||
DNSOPTS=""
|
||||
|
||||
TIMEZONEOPTS="UTC"
|
||||
|
||||
PROXYOPTS="none"
|
||||
|
||||
APKREPOSOPTS="https://download.nus.edu.sg/mirror/alpine/edge/main
|
||||
https://download.nus.edu.sg/mirror/alpine/edge/community
|
||||
https://download.nus.edu.sg/mirror/alpine/edge/testing
|
||||
"
|
||||
|
||||
SSHDOPTS="dropbear"
|
||||
|
||||
NTPOPTS="busybox"
|
||||
|
||||
DISKOPTS="-s 0 -m sys /dev/vda"
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -eux
|
||||
|
||||
# Install qemu-guest-agent for graceful libvirt shutdown
|
||||
apk add qemu-guest-agent
|
||||
rc-update add qemu-guest-agent
|
||||
|
||||
# Configure GA_PATH for qemu-guest-agent
|
||||
sed -i -E 's,#?(GA_PATH=).+,\1"/dev/vport0p1",' /etc/conf.d/qemu-guest-agent
|
||||
|
||||
# Zero out empty space (slower build), make the result image a little bit smaller
|
||||
dd if=/dev/zero of=/zero.fill bs=1M || true && sync && sleep 1 && sync && rm -f /zero.fill
|
||||
|
||||
# Discard unused blocks
|
||||
fstrim -v /
|
|
@ -0,0 +1,37 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -eux
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Required 1 argument."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
device="$1"
|
||||
|
||||
if [ -d /sys/firmware/efi/efivars ]; then
|
||||
# install the efi boot manager.
|
||||
apk add efibootmgr
|
||||
# show the boot options.
|
||||
efibootmgr -v
|
||||
# remove all the boot options.
|
||||
efibootmgr \
|
||||
| sed -nE 's,^Boot([0-9A-F]{4}).*,\1,gp' \
|
||||
| xargs -I% efibootmgr --quiet --delete-bootnum --bootnum %
|
||||
# create the boot option.
|
||||
# NB if we do not set any boot option, the firmware will recover/discover them
|
||||
# at the next boot. the firmware will find the shimx64.efi. when the shim
|
||||
# runs for the first time in a system with an enabled TPM, it will do an
|
||||
# extra reboot. when we are connected to the machine using AMT Remote
|
||||
# Desktop, that extra reboot messes with the ethernet speed by switching it
|
||||
# to a crawling 10 Mbps. to prevent all this we have to create this boot
|
||||
# option.
|
||||
# see https://github.com/coreos/fedora-coreos-tracker/issues/563
|
||||
# see https://github.com/rhboot/shim
|
||||
efibootmgr \
|
||||
-c \
|
||||
-d "$device" \
|
||||
-p 1 \
|
||||
-L Alpine \
|
||||
-l '\EFI\alpine\grubx64.efi'
|
||||
fi
|
Loading…
Reference in New Issue