feat: PXE setup now fully functional for inventory agent

The process will setup DHCP dnsmasq on opnsense to boot the correct ipxe file depending on the architecture
Then ipxe will chainload to either a mac-specific ipxe boot file or the fallback inventory boot file
Then a kickstart pre script will setup the cluster ssh key to allow ssh connections to the machine and also setup and start harmony_inventory_agent to allow being scraped

Note: there is a bug with the inventory agent currently, it cannot find lsmod on centos stream 9, will fix this soon
This commit is contained in:
Jean-Gabriel Gill-Couture 2025-08-22 10:48:43 -04:00
parent 57c3b01e66
commit 361f240762
14 changed files with 132 additions and 59 deletions

View File

@ -1,3 +1,8 @@
Here lies all the data files required for an OKD cluster PXE boot setup. Here lies all the data files required for an OKD cluster PXE boot setup.
This inclues ISO files, binary boot files, ipxe, etc. This inclues ISO files, binary boot files, ipxe, etc.
TODO as of august 2025 :
- `harmony_inventory_agent` should be downloaded from official releases, this embedded version is practical for now though
- The cluster ssh key should be generated and handled by harmony with the private key saved in a secret store

View File

@ -0,0 +1,9 @@
harmony_inventory_agent filter=lfs diff=lfs merge=lfs -text
os filter=lfs diff=lfs merge=lfs -text
os/centos-stream-9 filter=lfs diff=lfs merge=lfs -text
os/centos-stream-9/images filter=lfs diff=lfs merge=lfs -text
os/centos-stream-9/initrd.img filter=lfs diff=lfs merge=lfs -text
os/centos-stream-9/vmlinuz filter=lfs diff=lfs merge=lfs -text
os/centos-stream-9/images/efiboot.img filter=lfs diff=lfs merge=lfs -text
os/centos-stream-9/images/install.img filter=lfs diff=lfs merge=lfs -text
os/centos-stream-9/images/pxeboot filter=lfs diff=lfs merge=lfs -text

View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBx6bDylvC68cVpjKfEFtLQJ/dOFi6PVS2vsIOqPDJIc jeangab@liliane2

BIN
data/pxe/okd/http_files/harmony_inventory_agent (Stored with Git LFS) Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
data/pxe/okd/http_files/os/centos-stream-9/initrd.img (Stored with Git LFS) Normal file

Binary file not shown.

BIN
data/pxe/okd/http_files/os/centos-stream-9/vmlinuz (Stored with Git LFS) Executable file

Binary file not shown.

View File

@ -0,0 +1,7 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACAcemw8pbwuvHFaYynxBbS0Cf3ThYuj1Utr7CDqjwySHAAAAJikacCNpGnA
jQAAAAtzc2gtZWQyNTUxOQAAACAcemw8pbwuvHFaYynxBbS0Cf3ThYuj1Utr7CDqjwySHA
AAAECiiKk4V6Q5cVs6axDM4sjAzZn/QCZLQekmYQXS9XbEYxx6bDylvC68cVpjKfEFtLQJ
/dOFi6PVS2vsIOqPDJIcAAAAEGplYW5nYWJAbGlsaWFuZTIBAgMEBQ==
-----END OPENSSH PRIVATE KEY-----

View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBx6bDylvC68cVpjKfEFtLQJ/dOFi6PVS2vsIOqPDJIc jeangab@liliane2

View File

@ -30,7 +30,7 @@ echo "Configuring kernel boot arguments..."
# - inst.ks: CRITICAL: Points to our Kickstart file for automation. # - inst.ks: CRITICAL: Points to our Kickstart file for automation.
# - ip=dhcp: Ensures the live environment configures its network. # - ip=dhcp: Ensures the live environment configures its network.
# - console=...: Provides boot output on both serial and graphical consoles for debugging. # - console=...: Provides boot output on both serial and graphical consoles for debugging.
imgargs vmlinuz initrd=initrd.img inst.stage2=${os_base_url} inst.ks=${ks_url} ip=dhcp console=ttyS0,115200 console=tty1 imgargs vmlinuz initrd=initrd.img inst.sshd inst.stage2=${os_base_url} inst.ks=${ks_url} ip=dhcp console=ttyS0,115200 console=tty1
echo "Booting into CentOS Stream 9 live environment..." echo "Booting into CentOS Stream 9 live environment..."
boot || goto failed boot || goto failed

View File

@ -1,66 +1,38 @@
# ================================================================= # --- Pre-Boot Scripting (The Main Goal) ---
# Harmony Discovery Agent - Kickstart File (inventory.kickstart)
# =================================================================
#
# This Kickstart file configures the CentOS Stream 9 live environment.
# It does NOT install to disk. It sets up SSH for remote access
# and downloads and runs the harmony-inventory-agent.
#
# --- System Configuration
lang en_US.UTF-8
keyboard --xlayouts='us'
timezone America/New_York --isUtc
# --- Network Configuration
# Ensure the network is activated using DHCP.
network --bootproto=dhcp --device=link --activate
# --- Security Configuration
# Disable the firewall for this isolated provisioning network.
firewall --disabled
# Disable SELinux for simplicity in the live environment.
selinux --disabled
# Disable password-based root login for security.
rootpw --lock
# --- Service Configuration
# Ensure the SSH daemon is enabled.
services --enabled="sshd"
# We are running a live environment, so no disk partitioning.
# The 'liveimg' command would be used here if booting from a squashfs,
# but since we are booting from kernel/initrd, we just use the %post.
# Do not run the graphical initial setup wizard.
firstboot --disable
# --- Post-Boot Scripting
# This section runs after the live environment has booted into RAM. # This section runs after the live environment has booted into RAM.
%post --log=/root/ks-post.log # It sets up SSH and downloads/runs the harmony-inventory-agent.
%pre --log=/root/ks-pre.log
echo "Harmony Kickstart: Post-boot script started." echo "Harmony Kickstart: Pre-boot script started."
# 1. Configure SSH Access # 1. Configure SSH Access for Root
# Create the .ssh directory and set correct permissions. # Create the .ssh directory and set correct permissions.
echo " - Setting up SSH authorized_keys..." echo " - Setting up SSH authorized_keys for root..."
mkdir -p /root/.ssh mkdir -p /root/.ssh
chmod 700 /root/.ssh chmod 700 /root/.ssh
# Download the public key and place it in authorized_keys. # Download the public key from the provisioning server.
curl -sSL "http://{{ gateway_ip }}:8080/{{ cluster_pubkey_filename }}" -o /root/.ssh/authorized_keys # The -sS flags make curl silent but show errors. -L follows redirects.
chmod 600 /root/.ssh/authorized_keys curl -vSL "http://{{ gateway_ip }}:8080/{{ cluster_pubkey_filename }}" -o /root/.ssh/authorized_keys
if [ $? -ne 0 ]; then
# SELinux context is handled by 'selinux --disabled' above, echo " - ERROR: Failed to download SSH public key."
# but if SELinux were enabled, this would be essential: else
# restorecon -R /root/.ssh echo " - SSH key downloaded successfully."
chmod 600 /root/.ssh/authorized_keys
fi
# 2. Download the Harmony Inventory Agent # 2. Download the Harmony Inventory Agent
echo " - Downloading harmony-inventory-agent..." echo " - Downloading harmony-inventory-agent..."
curl -sSL "http://{{ gateway_ip }}:8080/{{ harmony_inventory_agent }}" -o /usr/local/bin/harmony-inventory-agent curl -vSL "http://{{ gateway_ip }}:8080/{{ harmony_inventory_agent }}" -o /usr/bin/harmony-inventory-agent
chmod +x /usr/local/bin/harmony-inventory-agent if [ $? -ne 0 ]; then
echo " - ERROR: Failed to download harmony_inventory_agent."
else
echo " - Agent binary downloaded successfully."
chmod +x /usr/bin/harmony-inventory-agent
fi
# 3. Create a systemd service to run the agent persistently # 3. Create a systemd service to run the agent persistently.
# This is the most robust method to ensure the agent stays running.
echo " - Creating systemd service for the agent..." echo " - Creating systemd service for the agent..."
cat > /etc/systemd/system/harmony-agent.service << EOF cat > /etc/systemd/system/harmony-agent.service << EOF
[Unit] [Unit]
@ -69,8 +41,9 @@ After=network-online.target
Wants=network-online.target Wants=network-online.target
[Service] [Service]
ExecStart=/usr/local/bin/harmony-inventory-agent Type=simple
Restart=always ExecStart=/usr/bin/harmony-inventory-agent
Restart=on-failure
RestartSec=5 RestartSec=5
[Install] [Install]
@ -78,15 +51,77 @@ WantedBy=multi-user.target
EOF EOF
# 4. Enable and start the service # 4. Enable and start the service
# The 'systemctl' commands will work correctly within the chroot environment of the %pre script.
echo " - Enabling and starting harmony-agent.service..." echo " - Enabling and starting harmony-agent.service..."
systemctl daemon-reload systemctl daemon-reload
systemctl enable --now harmony-agent.service systemctl enable --now harmony-agent.service
echo "Harmony Kickstart: Post-boot script finished. The inventory agent is running." # Check if the service started correctly
systemctl is-active --quiet harmony-agent.service
if [ $? -eq 0 ]; then
echo " - Harmony Inventory Agent service is now running."
else
echo " - ERROR: Harmony Inventory Agent service failed to start."
fi
curl localhost:8080/inventory | tee -a /tmp/harmony_inventory.json echo "Harmony Kickstart: Pre-boot script finished. The machine is ready for inventory."
echo "Running cat - to pause system indefinitely"
cat -
%end %end
# Do not automatically reboot or poweroff. # =================================================================
# The machine should remain running for inventory scraping. # Harmony Discovery Agent - Kickstart File (NON-INSTALL, LIVE BOOT)
# =================================================================
#
# This file achieves a fully automated, non-interactive boot into a
# live CentOS environment. It does NOT install to disk.
#
# --- Automation and Interaction Control ---
# Perform the installation in command-line mode. This is critical for
# preventing Anaconda from starting a UI and halting for input.
cmdline
# Accept the End User License Agreement to prevent a prompt.
eula --agreed
# --- Core System Configuration (Required by Anaconda) ---
# Set keyboard and language. These are mandatory.
keyboard --vckeymap=us --xlayouts='us'
lang en_US.UTF-8
# Configure networking. This is essential for the %post script to work.
# The --activate flag ensures this device is brought up in the installer environment.
network --bootproto=dhcp --device=link --activate
# Set a locked root password. This is a mandatory command.
rootpw --lock
# Set the timezone. This is a mandatory command.
timezone UTC
# --- Disable Installation-Specific Features ---
# CRITICAL: Do not install a bootloader. The --disabled flag prevents
# this step and avoids errors about where to install it.
bootloader --disabled
# CRITICAL: Ignore all disks. This prevents Anaconda from stopping at the
# "Installation Destination" screen asking where to install.
# ignoredisk --drives /dev/sda
# Do not run the Initial Setup wizard on first boot.
firstboot --disable
# --- Package Selection ---
# We are not installing, so this section can be minimal.
# An empty %packages section is valid and ensures no time is wasted
# resolving dependencies for an installation that will not happen.
%packages
%end
# IMPORTANT: Do not include a final action command like 'reboot' or 'poweroff'.
# The default action is 'halt', which in cmdline mode will leave the system
# running in the live environment with the agent active, which is the desired state.