aboutsummaryrefslogtreecommitdiffstats
path: root/roles/pxe_server
diff options
context:
space:
mode:
Diffstat (limited to 'roles/pxe_server')
-rw-r--r--roles/pxe_server/README.txt18
-rw-r--r--roles/pxe_server/defaults/main.yml4
-rw-r--r--roles/pxe_server/tasks/extract_iso.yml16
-rw-r--r--roles/pxe_server/tasks/main.yml39
-rw-r--r--roles/pxe_server/templates/grub/grub.cfg.j222
-rw-r--r--roles/pxe_server/templates/grub/menuentry-redhat.cfg.j218
-rw-r--r--roles/pxe_server/templates/kickstart/rocky8-ks.cfg.j289
-rw-r--r--roles/pxe_server/vars/main.yml23
8 files changed, 229 insertions, 0 deletions
diff --git a/roles/pxe_server/README.txt b/roles/pxe_server/README.txt
new file mode 100644
index 0000000..5775583
--- /dev/null
+++ b/roles/pxe_server/README.txt
@@ -0,0 +1,18 @@
+To generate the grub binaries:
+------------------------------
+
+Install the required packages:
+
+ dnf install grub2 grub2-pc grub2-efi grub2-pc-modules grub2-efi-x64-modules grub2-efi-aa64-modules
+
+Generate the images:
+
+ # location of the grub.cfg files within the tftp root
+ PREFIX=/grub
+ COMMON_MODULES="normal linux echo http tftp reboot configfile"
+
+ # Last arguments are the modules to "statically link" into the grub image.
+ # I'd rather not maintain a bunch of .mod files within the tftp directory.
+ grub2-mkimage --format=x86_64-efi --output=bootx64.efi -p $PREFIX $COMMON_MODULES efinet bsd
+ grub2-mkimage --format=arm64-efi --output=bootaa64.efi -p $PREFIX $COMMON_MODULES efinet
+ grub2-mkimage --format=i386-pc-pxe --output=booti386 -p $PREFIX $COMMON_MODULES pxe bsd
diff --git a/roles/pxe_server/defaults/main.yml b/roles/pxe_server/defaults/main.yml
new file mode 100644
index 0000000..ce5f7dc
--- /dev/null
+++ b/roles/pxe_server/defaults/main.yml
@@ -0,0 +1,4 @@
+pxe_root: /tftpboot
+pxe_http_port: 80
+pxe_grub_prefix: grub
+locale: en_US.UTF-8
diff --git a/roles/pxe_server/tasks/extract_iso.yml b/roles/pxe_server/tasks/extract_iso.yml
new file mode 100644
index 0000000..754f9ec
--- /dev/null
+++ b/roles/pxe_server/tasks/extract_iso.yml
@@ -0,0 +1,16 @@
+- name: create directories
+ file:
+ path: '{{ pxe_root }}/{{ item.name }}/{{ item.version }}/{{ item.arch }}'
+ state: directory
+ recurse: yes
+
+- name: download iso
+ get_url:
+ url: '{{ item.url }}'
+ checksum: sha256:{{ item.sha256 }}
+ dest: '{{ pxe_root }}/{{ item.name }}/{{ item.version }}/{{ item.arch }}/{{ item.name }}-{{ item.version }}-{{ item.arch }}.iso'
+
+- name: extract iso with bsdtar
+ command: >-
+ bsdtar -C '{{ pxe_root }}/{{ item.name }}/{{ item.version }}/{{ item.arch }}'
+ -xf '{{ pxe_root }}/{{ item.name }}/{{ item.version }}/{{ item.arch }}/{{ item.name }}-{{ item.version }}-{{ item.arch }}.iso'
diff --git a/roles/pxe_server/tasks/main.yml b/roles/pxe_server/tasks/main.yml
new file mode 100644
index 0000000..9bd7b30
--- /dev/null
+++ b/roles/pxe_server/tasks/main.yml
@@ -0,0 +1,39 @@
+- name: prepare boot images
+ include_tasks: extract_iso.yml
+ loop: '{{ pxe_images }}'
+
+- name: create grub directories
+ file:
+ path: '{{ pxe_root }}/{{ item }}'
+ state: directory
+ loop:
+ - '{{ pxe_grub_prefix }}'
+ - kickstart
+
+- name: generate menuentries
+ template:
+ src: grub/menuentry-{{ image.os }}.cfg.j2
+ dest: '{{ pxe_root }}/{{ pxe_grub_prefix }}/{{ image.name }}-{{ image.version }}-{{ image.arch }}.cfg'
+ loop: '{{ pxe_images }}'
+ loop_control:
+ loop_var: image
+
+- name: generate kickstart files
+ template:
+ src: kickstart/{{ item }}.j2
+ dest: '{{ pxe_root }}/kickstart/{{ item }}'
+ loop: '{{ pxe_images | selectattr("kickstart", "defined") | map(attribute="kickstart") | flatten | map(attribute="name") | unique }}'
+
+- name: generate kickstart menuentries
+ template:
+ src: grub/menuentry-{{ image.os }}.cfg.j2
+ dest: '{{ pxe_root }}/{{ pxe_grub_prefix }}/{{ image.name }}-{{ image.version }}-{{ image.arch }}-{{ kickstart.name | splitext | first }}.cfg'
+ vars:
+ image: '{{ item.0 }}'
+ kickstart: '{{ item.1 }}'
+ loop: '{{ pxe_images | subelements("kickstart", { "skip_missing": true }) }}'
+
+- name: generate grub config
+ template:
+ src: grub/grub.cfg.j2
+ dest: '{{ pxe_root }}/{{ pxe_grub_prefix }}/grub.cfg'
diff --git a/roles/pxe_server/templates/grub/grub.cfg.j2 b/roles/pxe_server/templates/grub/grub.cfg.j2
new file mode 100644
index 0000000..ae2d7cb
--- /dev/null
+++ b/roles/pxe_server/templates/grub/grub.cfg.j2
@@ -0,0 +1,22 @@
+set timeout=-1
+
+if [ "$grub_cpu" = "x86_64" -a "$grub_platform" = "efi" ]; then
+ set linux=linuxefi
+ set initrd=initrdefi
+ export linux
+ export initrd
+fi
+
+{% for image in pxe_images %}
+if [ "$grub_cpu" = "{{ image.arch }}" ]; then
+ menuentry "{{ image.description }} {{ image.version }}" {
+ configfile "$prefix/{{ image.name }}-{{ image.version }}-{{image.arch }}.cfg"
+ }
+
+ {% for kickstart in image.kickstart | default([]) %}
+ menuentry "{{ image.description }} {{ image.version }}: {{ kickstart.description }}" {
+ configfile "$prefix/{{ image.name }}-{{ image.version }}-{{image.arch }}-{{ kickstart.name | splitext | first }}.cfg"
+ }
+ {% endfor %}
+fi
+{% endfor %}
diff --git a/roles/pxe_server/templates/grub/menuentry-redhat.cfg.j2 b/roles/pxe_server/templates/grub/menuentry-redhat.cfg.j2
new file mode 100644
index 0000000..f7dc2ac
--- /dev/null
+++ b/roles/pxe_server/templates/grub/menuentry-redhat.cfg.j2
@@ -0,0 +1,18 @@
+echo "{{ image.description }} {{ image.version }} ({{ image.arch }})"
+{% if kickstart is defined %}
+echo "kickstart: {{ kickstart.name }}"
+{% endif %}
+
+echo "loading kernel..."
+linux (http,${net_default_server}:{{ pxe_http_port }})/{{ image.name }}/{{ image.version }}/{{ image.arch }}/{{ image.kernel }} \
+ ip=dhcp \
+ inst.repo=http://${net_default_server}:{{ pxe_http_port }}/{{ image.name }}/{{ image.version }}/{{ image.arch }}/ {%- if kickstart is defined %} \
+ inst.ks=http://${net_default_server}:{{ pxe_http_port }}/kickstart/{{ kickstart.name }}
+ {%- endif %}
+
+
+echo "loading initrd..."
+initrd (http,${net_default_server}:{{ pxe_http_port }})/{{ image.name }}/{{ image.version }}/{{ image.arch }}/{{ image.initrd }}
+
+echo "booting linux..."
+boot
diff --git a/roles/pxe_server/templates/kickstart/rocky8-ks.cfg.j2 b/roles/pxe_server/templates/kickstart/rocky8-ks.cfg.j2
new file mode 100644
index 0000000..ddbb0f0
--- /dev/null
+++ b/roles/pxe_server/templates/kickstart/rocky8-ks.cfg.j2
@@ -0,0 +1,89 @@
+%pre --interpreter=/bin/bash
+set -Eeu -o pipefail
+
+# get the primary interface name
+interface=$(ip route list default | cut -d' ' -f5)
+
+# parse DHCP lease info
+declare -A dhcp
+while IFS= read -r line; do
+ dhcp["${line%% =*}"]=${line#*= }
+done <<< $(nmcli --terse --fields dhcp4 device show "$interface" | cut -d: -f2-)
+
+# configure interface for DHCP
+printf 'network --bootproto=dhcp --device=%q --hostname=%q --onboot=yes --noipv6\n' \
+ "$interface" \
+ "${dhcp[host_name]:-rocky-kickstart}" \
+ > /tmp/network.ks
+
+# if ntp-server was specified by DHCP server, use it
+if [ -n "${dhcp[ntp_servers]:-}" ]; then
+ printf 'timezone %q --utc --ntpservers=%q\n' \
+ {{ timezone | quote }} \
+ "${dhcp[ntp_servers]}" \
+ > /tmp/timezone.ks
+else
+ printf 'timezone %q --utc\n' {{ timezone | quote }} > /tmp/timezone.ks
+fi
+%end
+
+
+# installer configuration
+cmdline
+eula --agreed
+reboot
+
+
+# system configuration
+firstboot --disabled
+firewall --disabled
+keyboard --vckeymap=us
+lang {{ locale }}
+rootpw --iscrypted {{ root_password | password_hash("sha512", root_password_salt | default("")) }}
+selinux --disabled
+skipx
+
+{% for pubkey in root_authorized_keys %}
+sshkey --username=root "{{ pubkey }}"
+{% endfor %}
+
+
+# network
+%include /tmp/network.ks
+
+
+# timezone
+%include /tmp/timezone.ks
+
+
+# storage
+autopart --type=lvm --fstype=xfs --nohome
+bootloader --boot-drive=vda --location=mbr --timeout=3
+clearpart --drives=vda --all --initlabel
+zerombr
+
+
+# packages
+%packages
+@^minimal-environment
+-plymouth
+-iwl100-firmware
+-iwl1000-firmware
+-iwl105-firmware
+-iwl135-firmware
+-iwl2000-firmware
+-iwl2030-firmware
+-iwl3160-firmware
+-iwl5000-firmware
+-iwl5150-firmware
+-iwl6000-firmware
+-iwl6000g2a-firmware
+-iwl6050-firmware
+-iwl7260-firmware
+%end
+
+
+# disable kernel crashdumps
+%addon com_redhat_kdump --disable
+
+%end
diff --git a/roles/pxe_server/vars/main.yml b/roles/pxe_server/vars/main.yml
new file mode 100644
index 0000000..8cc20bd
--- /dev/null
+++ b/roles/pxe_server/vars/main.yml
@@ -0,0 +1,23 @@
+pxe_images:
+ - name: rocky
+ description: Rocky Linux
+ version: 8.6
+ arch: x86_64
+ os: redhat
+ kernel: images/pxeboot/vmlinuz
+ initrd: images/pxeboot/initrd.img
+ url: https://download.rockylinux.org/pub/rocky/8/isos/x86_64/Rocky-8.6-x86_64-minimal.iso
+ sha256: a9ece0e810275e881abfd66bb0e59ac05d567a5ec0bc2f108b9a3e90bef5bf94
+ kickstart:
+ - name: rocky8-ks.cfg
+ description: Unattended Install
+
+ - name: rocky
+ description: Rocky Linux
+ version: 9.0
+ arch: x86_64
+ os: redhat
+ kernel: images/pxeboot/vmlinuz
+ initrd: images/pxeboot/initrd.img
+ url: http://download.rockylinux.org/pub/rocky/9/isos/x86_64/Rocky-9.0-20220805.0-x86_64-minimal.iso
+ sha256: b16bc85f4fd14facf3174cd0cf8434ee048d81e5470292f3e1cfff47af2463b7