Super User 3 months ago
parent
commit
0241796e12
  1. 2
      pxe-boot/.gitignore
  2. 0
      pxe-boot/README.md
  3. 21
      pxe-boot/config/dnsmasq/dnsmasq.conf
  4. 34
      pxe-boot/config/nginx/nginx.conf
  5. 100
      pxe-boot/install.sh
  6. 7
      pxe-boot/tftpboot/boot.cfg
  7. 30
      pxe-boot/tftpboot/boot.ipxe
  8. 59
      pxe-boot/tftpboot/menu.ipxe
  9. 85
      pxe-boot/www/ks/mac-00190f440391.ks
  10. 85
      pxe-boot/www/ks/mac-00be43ec5619.ks

2
pxe-boot/.gitignore

@ -0,0 +1,2 @@
config.yaml
auth.json

0
pxe-boot/README.md

21
pxe-boot/config/dnsmasq/dnsmasq.conf

@ -0,0 +1,21 @@
# Bind on enp1s0
bind-dynamic
interface=enp1s0
# Disable DHCP
no-dhcpv4-interface=enp1s0
no-dhcpv6-interface=enp1s0
dhcp-alternate-port
# Disable DNS
port=0
# Enable TFTP
enable-tftp=enp1s0
tftp-root=/var/lib/tftpboot
tftp-secure
tftp-lowercase
# Just to be safe...
log-dhcp
log-queries

34
pxe-boot/config/nginx/nginx.conf

@ -0,0 +1,34 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 127.0.0.1:8080;
server_name _;
root /var/www;
access_log /var/log/nginx/access.log;
}
}

100
pxe-boot/install.sh

@ -0,0 +1,100 @@
#!/bin/bash
set -Eeuo pipefail
if [[ "$UID" -ne 0 ]]; then
echo "This command must be run as root!"
exit 1
fi
# Get the directory of this script
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
# This function iterates over all files contained in the directory passed as the first argument
# and install them to the directory passed as the second argument, using the install command.
# It preserves the directory structure of the source directory.
# The remaining arguments are passed to the install command.
function install_files() {
local src_dir="$1"
local dest_dir="$2"
shift 2
find "$src_dir" -type f | while read -r file; do
local relative_path="${file#$src_dir/}"
local dest_path="$dest_dir/$relative_path"
install "$@" "$file" "$dest_path"
done
}
# Same but for directories
function install_directories() {
local src_dir="$1"
local dest_dir="$2"
shift 2
find "$src_dir" -type d | while read -r dir; do
local relative_path="${dir#$src_dir}"
relative_path="${relative_path#/}" # Remove leading slash if present
local dest_path="$dest_dir/$relative_path"
install "$@" -d "$dest_path"
done
}
# This function templates a kickstart file by replacing placeholders with actual values.
# The templates are located in the www/ks directory.
# The output files are written to /var/www/ks.
# The placeholders are in the format expected by envsubst.
# For each template file, seven versions are created: base + scenario{1,2,3,4,5,6}.
# The output files are named as /var/www/ks/<template>/<scenario>.ks.
function template_kickstart_files() {
local templates_dir="${SCRIPT_DIR}/www/ks"
local output_dir="/var/www/ks"
local scenarios=("base" "scenario1" "scenario2" "scenario3" "scenario4" "scenario5" "scenario6")
for template in "$templates_dir"/*.ks; do
local template_name="$(basename "$template" .ks)"
for scenario in "${scenarios[@]}"; do
install -d -m 0755 -o root -g root -Z "$output_dir/${template_name}"
local output_file="$output_dir/${template_name}/${scenario}.ks"
echo "Templating $template_name to $output_file"
(
export SCENARIO_NAME="$scenario"
if [ -f "auth.json" ]; then
export AUTH_JSON_CONTENT="$(cat auth.json)"
fi
if [ -f "config.yaml" ]; then
export FLIGHTCTL_CONFIG_CONTENT="$(cat config.yaml)"
fi
envsubst < "$template" > "/tmp/tmp.$$.ks"
)
install -m 0644 -o root -g root "/tmp/tmp.$$.ks" "$output_file"
done
done
}
echo "Installing PXE boot files..."
rm -rf "/var/lib/tftpboot"
install_directories "${SCRIPT_DIR}/tftpboot" "/var/lib/tftpboot" -m 755 -o dnsmasq -g dnsmasq -Z
install_files "${SCRIPT_DIR}/tftpboot" "/var/lib/tftpboot" -m 644 -o dnsmasq -g dnsmasq -Z
install -m 0644 -o dnsmasq -g dnsmasq /usr/share/ipxe/{undionly.kpxe,ipxe-snponly-x86_64.efi} /var/lib/tftpboot/
install -m 0644 -o dnsmasq -g dnsmasq /usr/share/ipxe/arm64-efi/snponly.efi /var/lib/tftpboot/ipxe-snponly-arm64.efi
restorecon -RF "/var/lib/tftpboot"
echo "Installing nginx files..."
rm -rf "/var/www/ks"
install -d -m 0755 -o root -g root /var/www/repo/rhel{9,10}/{x86_64,arm64}/ /var/www/ks/
template_kickstart_files
restorecon -RF "/var/www"
echo "Configuring dnsmasq..."
install -m 0644 -o root -g root -Z "${SCRIPT_DIR}/config/dnsmasq/dnsmasq.conf" /etc/dnsmasq.d/tftp.conf
systemctl enable dnsmasq.service
systemctl restart dnsmasq.service
echo "Configuring nginx..."
install -m 0644 -o root -g root -Z "${SCRIPT_DIR}/config/nginx/nginx.conf" /etc/nginx/nginx.conf
systemctl enable nginx.service
systemctl restart nginx.service

7
pxe-boot/tftpboot/boot.cfg

@ -0,0 +1,7 @@
#!ipxe
set base_url http://192.168.2.41
set rhel9_url http://192.168.2.41/repo/rhel9/${buildarch}
set rhel10_url http://192.168.2.41/repo/rhel10/${buildarch}
set rhde_options inst.text
set kickstart_url ${base_url}/ks/mac-${mac:hexraw}

30
pxe-boot/tftpboot/boot.ipxe

@ -0,0 +1,30 @@
#!ipxe
# Load global variables
chain --autofree boot.cfg ||
# Boot config/buildarch-<arch>.ipxe
# if buildarch DHCP variable is set and script is present
isset ${buildarch} && chain --autofree config/buildarch-${buildarch}.ipxe ||
# Boot config/hostname-<hostname>.ipxe
# if hostname DHCP variable is set and script is present
isset ${hostname} && chain --autofree config/hostname-${hostname}.ipxe ||
# Boot config/uuid-<UUID>.ipxe
# if SMBIOS UUID variable is set and script is present
isset ${uuid} && chain --autofree config/uuid-${uuid}.ipxe ||
# Boot config/mac-010203040506.ipxe if script is present
chain --autofree config/mac-${mac:hexraw}.ipxe ||
# Boot config/pci-8086100e.ipxe if one type of
# PCI Intel adapter is present and script is present
chain --autofree config/pci-${pci/${busloc}.0.2}${pci/${busloc}.2.2}.ipxe ||
# Boot config/chip-82541pi.ipxe if one type of
# PCI Intel adapter is present and script is present
chain --autofree config/chip-${chip}.ipxe ||
# Boot menu.ipxe script if all other options have been exhausted
chain --replace --autofree menu.ipxe ||

59
pxe-boot/tftpboot/menu.ipxe

@ -0,0 +1,59 @@
#!ipxe
isset ${menu_default} || set menu_default rhde
isset ${menu_timeout} || set menu_timeout 30000
menu iPXE Menu
item --key 0 rhde [0] Install Red Hat Device Edge - Base
item --key 1 rhde-scenario1 [1] Install Red Hat Device Edge - Scenario 1
item --key 2 rhde-scenario2 [2] Install Red Hat Device Edge - Scenario 2
item --key 3 rhde-scenario3 [3] Install Red Hat Device Edge - Scenario 3
item --key 4 rhde-scenario4 [4] Install Red Hat Device Edge - Scenario 4
item --key 5 rhde-scenario5 [5] Install Red Hat Device Edge - Scenario 5
item --key 6 rhde-scenario6 [6] Install Red Hat Device Edge - Scenario 6
item
item --key r reboot [R] Reboot computer
item --key x exit [X] Exit iPXE and continue BIOS boot
choose --timeout ${menu_timeout} --default ${menu_default} selected
goto ${selected}
:reboot
reboot
:exit
exit
:rhde
initrd ${rhel9_url}/images/pxeboot/initrd.img
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/base.ks ${rhde_options}
boot
:rhde-scenario1
initrd ${rhel9_url}/images/pxeboot/initrd.img
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/scenario1.ks ${rhde_options}
boot
:rhde-scenario2
initrd ${rhel9_url}/images/pxeboot/initrd.img
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/scenario2.ks ${rhde_options}
boot
:rhde-scenario3
initrd ${rhel9_url}/images/pxeboot/initrd.img
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/scenario3.ks ${rhde_options}
boot
:rhde-scenario4
initrd ${rhel9_url}/images/pxeboot/initrd.img
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/scenario4.ks ${rhde_options}
boot
:rhde-scenario5
initrd ${rhel9_url}/images/pxeboot/initrd.img
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/scenario5.ks ${rhde_options}
boot
:rhde-scenario6
initrd ${rhel9_url}/images/pxeboot/initrd.img
kernel ${rhel9_url}/images/pxeboot/vmlinuz initrd=initrd.img ip=dhcp inst.repo=${rhel9_url} inst.ks=${kickstart_url}/scenario6.ks ${rhde_options}
boot

85
pxe-boot/www/ks/mac-00190f440391.ks

@ -0,0 +1,85 @@
##
## Environment setup
##
# Install mode: text (interactive installs) or cmdline (unattended installs)
text
# French keyboard layout
keyboard --vckeymap=fr --xlayouts='fr'
# English i18n
lang en_US.UTF-8 --addsupport fr_FR.UTF-8
# Accept the EULA
eula --agreed
# Which action to perform after install: poweroff or reboot
reboot
# Timezone is GMT
timezone Etc/GMT --utc
##
## network configuration
##
# No network configuration here since Anaconda does it automatically.
##
## partitioning
##
# Install on /dev/sda
ignoredisk --only-use=sda
# Clear the target disk
zerombr
# Remove existing partitions
clearpart --all --initlabel
# Automatically create partitions required by hardware platform
reqpart --add-boot
# Create a root and a /var partition
part / --fstype xfs --size=1 --grow --asprimary --label=root
##
## Pre-installation
##
%pre --log=/tmp/pre-install.log --erroronfail
cat > /etc/ostree/auth.json << 'EOF'
${AUTH_JSON_CONTENT}
EOF
chmod 0600 /etc/ostree/auth.json
%end
##
## Installation
##
rootpw --lock
ostreecontainer --url="edge-registry.itix.fr/demo-edge-retail/${SCENARIO_NAME}:latest" --transport=registry --no-signature-verification
##
## Post-installation
##
%post --log=/var/log/anaconda/post-install.log --erroronfail
set -Eeuo pipefail
# Inject flightctl initial configuration
cat > /etc/flightctl/config.yaml << 'EOF'
${FLIGHTCTL_CONFIG_CONTENT}
EOF
chmod 600 /etc/flightctl/config.yaml
cat > /etc/ostree/auth.json << 'EOF'
${AUTH_JSON_CONTENT}
EOF
chmod 0600 /etc/ostree/auth.json
%end

85
pxe-boot/www/ks/mac-00be43ec5619.ks

@ -0,0 +1,85 @@
##
## Environment setup
##
# Install mode: text (interactive installs) or cmdline (unattended installs)
text
# French keyboard layout
keyboard --vckeymap=fr --xlayouts='fr'
# English i18n
lang en_US.UTF-8 --addsupport fr_FR.UTF-8
# Accept the EULA
eula --agreed
# Which action to perform after install: poweroff or reboot
reboot
# Timezone is GMT
timezone Etc/GMT --utc
##
## network configuration
##
# No network configuration here since Anaconda does it automatically.
##
## partitioning
##
# Install on /dev/nvme0n1
ignoredisk --only-use=nvme0n1
# Clear the target disk
zerombr
# Remove existing partitions
clearpart --all --initlabel
# Automatically create partitions required by hardware platform
reqpart --add-boot
# Create a root and a /var partition
part / --fstype xfs --size=1 --grow --asprimary --label=root
##
## Pre-installation
##
%pre --log=/tmp/pre-install.log --erroronfail
cat > /etc/ostree/auth.json << 'EOF'
${AUTH_JSON_CONTENT}
EOF
chmod 0600 /etc/ostree/auth.json
%end
##
## Installation
##
rootpw --lock
ostreecontainer --url="edge-registry.itix.fr/demo-edge-retail/${SCENARIO_NAME}:latest" --transport=registry --no-signature-verification
##
## Post-installation
##
%post --log=/var/log/anaconda/post-install.log --erroronfail
set -Eeuo pipefail
# Inject flightctl initial configuration
cat > /etc/flightctl/config.yaml << 'EOF'
${FLIGHTCTL_CONFIG_CONTENT}
EOF
chmod 600 /etc/flightctl/config.yaml
cat > /etc/ostree/auth.json << 'EOF'
${AUTH_JSON_CONTENT}
EOF
chmod 0600 /etc/ostree/auth.json
%end
Loading…
Cancel
Save