Blancco PXE boot via Ubuntu kernel switch_root

Blancco's own kernel freezes on Dell Precision towers during PXE boot.
Workaround: boot Ubuntu kernel via GRUB chainload, download Blancco's
666MB squashfs rootfs + 132MB kernel modules over HTTP, mount overlay
filesystem, and switch_root into Blancco's userspace.

- Add blancco-init.sh: custom initramfs init script for switch_root approach
- Add blancco-preferences.xml: pre-configured with network share for reports
- Update playbook: build initramfs, deploy Ubuntu kernel/modules, config
- Update prepare-boot-tools.sh: add HTTP modules to GRUB EFI build
- Add UEFI HTTP Boot support to dnsmasq config
- iPXE menu chains to grubx64.efi (replaces sanboot of ISO)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-02-18 11:20:00 -05:00
parent 15983854ed
commit dd2fec5a41
4 changed files with 626 additions and 18 deletions

162
playbook/blancco-init.sh Normal file
View File

@@ -0,0 +1,162 @@
#!/bin/sh
# Blancco PXE Loader - init script for custom initramfs
# Boot chain: iPXE -> GRUB EFI -> Ubuntu kernel + this initramfs -> switch_root to Blancco
#
# Blancco's own kernel freezes on Dell Precision towers during PXE boot.
# Workaround: boot Ubuntu kernel, download Blancco rootfs (squashfs), mount
# overlay filesystem, and switch_root into Blancco's userspace.
export PATH=/bin:/sbin
echo ""
echo "============================================"
echo " Blancco PXE loader"
echo "============================================"
echo ""
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev 2>/dev/null
mkdir -p /tmp /run
echo "[1/4] Loading NIC drivers..."
for mod in /lib/modules/*.ko; do
insmod $mod 2>/dev/null
done
sleep 2
echo " Waiting for network interface..."
IFACE=""
COUNT=0
while [ $COUNT -lt 30 ]; do
for i in /sys/class/net/*; do
ifname="${i##*/}"
if [ "$ifname" != "lo" ] && [ -d "$i" ]; then
IFACE=$ifname
break 2
fi
done
COUNT=$((COUNT + 1))
sleep 1
echo -n "."
done
echo ""
if [ -z "$IFACE" ]; then
echo "ERROR: No network interface found!"
exec sh
fi
echo " Interface: $IFACE"
ip link set $IFACE up
sleep 2
SERVER=10.9.100.1
ifconfig $IFACE 10.9.100.250 netmask 255.255.255.0 up
sleep 1
echo " IP: 10.9.100.250"
echo "[2/4] Downloading Blancco rootfs (666MB)..."
wget -O /tmp/airootfs.sfs http://$SERVER/blancco/arch/x86_64/airootfs.sfs 2>&1
if [ ! -s /tmp/airootfs.sfs ]; then
echo "ERROR: Failed to download rootfs!"
exec sh
fi
echo " OK ($(wc -c < /tmp/airootfs.sfs) bytes)"
echo "[3/4] Mounting rootfs..."
mkdir -p /run/lower /run/upper /run/work /run/newroot
losetup /dev/loop0 /tmp/airootfs.sfs
mount -t squashfs -o ro /dev/loop0 /run/lower
if [ $? -ne 0 ]; then
echo "ERROR: squashfs mount failed!"
exec sh
fi
insmod /lib/modules/overlay.ko 2>/dev/null
mount -t tmpfs -o size=50% tmpfs /run/upper
mkdir -p /run/upper/upper /run/upper/work
mount -t overlay overlay -o lowerdir=/run/lower,upperdir=/run/upper/upper,workdir=/run/upper/work /run/newroot
if [ $? -ne 0 ]; then
echo "ERROR: overlay mount failed!"
exec sh
fi
echo "[4/5] Installing kernel modules (132MB)..."
wget -O /tmp/kmod.tar.gz http://$SERVER/blancco/kmod.tar.gz 2>&1
if [ -s /tmp/kmod.tar.gz ]; then
cd /run/newroot
gunzip -c /tmp/kmod.tar.gz | tar xf -
rm -f /tmp/kmod.tar.gz
cd /
echo " OK"
else
echo " WARNING: Failed to download kernel modules"
fi
echo "[5/6] Switching root to Blancco..."
mkdir -p /run/newroot/run /run/newroot/proc /run/newroot/sys /run/newroot/dev /run/newroot/tmp
echo "[6/6] Downloading Blancco config..."
wget -O /run/newroot/albus/config.xml http://$SERVER/blancco/config-clean.xml 2>&1
wget -O /run/newroot/albus/preferences.xml http://$SERVER/blancco/preferences.xml 2>&1
if [ -s /run/newroot/albus/config.xml ]; then
echo " config.xml: $(wc -c < /run/newroot/albus/config.xml) bytes"
else
echo " WARNING: Failed to download config.xml"
fi
if [ -s /run/newroot/albus/preferences.xml ]; then
cp -f /run/newroot/albus/preferences.xml /run/newroot/albus/preferences.save
echo " preferences.xml: $(wc -c < /run/newroot/albus/preferences.xml) bytes"
else
echo " WARNING: Failed to download preferences.xml"
fi
# Pre-configure X.org to use modesetting driver (generic KMS, works with all GPUs)
mkdir -p /run/newroot/etc/X11/xorg.conf.d
echo " X.org: forcing modesetting driver"
cat > /run/newroot/etc/X11/xorg.conf.d/20-failsafeDriver.conf << 'XEOF'
Section "Device"
Identifier "Failsafe Video Device"
Driver "modesetting"
EndSection
XEOF
# Enable SSH for remote debugging
echo " Enabling SSH (root:blancco)..."
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/' /run/newroot/etc/ssh/sshd_config 2>/dev/null
cat > /run/newroot/etc/rc.local << 'RCEOF'
#!/bin/bash
echo 'root:blancco' | chpasswd
ssh-keygen -A 2>/dev/null
IFACE=$(ls /sys/class/net/ | grep -v lo | head -1)
ip addr add 10.9.100.250/24 dev "$IFACE" 2>/dev/null
/usr/bin/sshd
RCEOF
chmod +x /run/newroot/etc/rc.local
ln -sf /usr/lib/systemd/system/rc-local.service /run/newroot/etc/systemd/system/multi-user.target.wants/rc-local.service 2>/dev/null
cat > /run/newroot/etc/systemd/system/pxe-debug.service << 'SVCEOF'
[Unit]
Description=PXE Debug SSH
After=systemd-networkd.service
Wants=systemd-networkd.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/etc/rc.local
[Install]
WantedBy=multi-user.target
SVCEOF
ln -sf /etc/systemd/system/pxe-debug.service /run/newroot/etc/systemd/system/multi-user.target.wants/pxe-debug.service
mount --move /proc /run/newroot/proc
mount --move /sys /run/newroot/sys
mount --move /dev /run/newroot/dev
echo " Starting Blancco..."
exec switch_root /run/newroot /sbin/init

View File

@@ -0,0 +1,378 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- FASDHFOSGHSVASLGHASDLASDFUILEFHLKJDKLFJGKLXCJGHFKLJDGHKLFJ -->
<root>
<blancco type="albus-preferences" version="4.14"/>
<version>
<generation>7</generation>
<major>14</major>
<minor>0</minor>
</version>
<integrity>WrE8qdGzoKMVy403SVha6O6JOdYlerKbbjyLSWo20NI=</integrity>
<configuration dect="3.14.0" imported="false">
<processes type="array" key="process">
<process>workflow</process>
<process>auto</process>
<process>semi</process>
<process selected="true">manual</process>
</processes>
<hardware_tests type="array" key="test" enabled="false">
<test enabled="true" mandatory="false" auto="true" threshold="60">battery</test>
<test enabled="true" mandatory="false" auto="true">cpu</test>
<test enabled="false" mandatory="false" auto="true" passes="0">memory</test>
<test enabled="true" mandatory="false" auto="true">motherboard</test>
<test enabled="true" mandatory="false" auto="false" threshold="50" duration="600">battery_discharge</test>
<test enabled="true" mandatory="false" auto="false">bios_logo</test>
<test enabled="true" mandatory="false" auto="false" threshold="80" duration="180">cpu_stress</test>
<test enabled="true" mandatory="false" auto="false">display</test>
<test enabled="true" mandatory="false" auto="false" formfactor="compact" language="us">keyboard</test>
<test enabled="true" mandatory="false" auto="false">microphone</test>
<test enabled="true" mandatory="false" auto="false" targets="">network</test>
<test enabled="true" mandatory="false" auto="false" tests="R">optical_devices</test>
<test enabled="true" mandatory="false" auto="false">sound</test>
<test enabled="true" mandatory="false" auto="false">pointing_devices</test>
<test enabled="true" mandatory="false" auto="false">sim_presence</test>
<test enabled="true" mandatory="false" auto="false">speaker</test>
<test enabled="true" mandatory="false" auto="false">touchscreen</test>
<test enabled="true" mandatory="false" auto="false" tests="R">usb_ports</test>
<test enabled="true" mandatory="false" auto="false">webcam</test>
<test enabled="true" mandatory="false" auto="false">wifi</test>
</hardware_tests>
<layouts type="array" key="layout">
<layout selected="true">us</layout>
<layout>be</layout>
<layout>br</layout>
<layout>ca</layout>
<layout>ch</layout>
<layout>ch_fr</layout>
<layout>cn</layout>
<layout>de</layout>
<layout>dk</layout>
<layout>es</layout>
<layout>fi</layout>
<layout>fr</layout>
<layout>gb</layout>
<layout>hu</layout>
<layout>it</layout>
<layout>jp</layout>
<layout>kr</layout>
<layout>latam</layout>
<layout>nl</layout>
<layout>no</layout>
<layout>pl</layout>
<layout>pt</layout>
<layout>ru</layout>
<layout>se</layout>
<layout>sk</layout>
</layouts>
<locales type="array" key="locale">
<locale selected="true">en_US</locale>
<locale>de_DE</locale>
<locale>es_ES</locale>
<locale>fr_FR</locale>
<locale>hu_HU</locale>
<locale>it_IT</locale>
<locale>ja_JP</locale>
<locale>ko_KR</locale>
<locale>pl_PL</locale>
<locale>pt_BR</locale>
<locale>ru_RU</locale>
<locale>sk_SK</locale>
<locale>zh_CN</locale>
<locale>zh_TW</locale>
</locales>
<erasure_standards type="array" key="standard">
<standard enabled="true" id="afssi_5020" name="Air Force System Security Instruction 5020"/>
<standard enabled="true" id="aperiodic_random" name="Aperiodic random overwrite"/>
<standard enabled="true" id="bsi_vs" name="BSI-2011-VS"/>
<standard enabled="true" id="bsi_gs" name="BSI-GS"/>
<standard enabled="true" id="bsi_gse" name="BSI-GSE"/>
<standard enabled="true" id="bsi_gsk" name="BSI-GSK"/>
<standard enabled="true" id="bl_ssd" name="Blancco SSD Erasure"/>
<standard enabled="true" id="bruce_schneier" name="Bruce Schneier's Algorithm"/>
<standard enabled="true" id="cesg_higher" name="CESG CPA - Higher Level"/>
<standard enabled="true" id="dod" name="DoD 5220.22-M"/>
<standard enabled="true" id="dod_ece" name="DoD 5220.22-M ECE"/>
<standard enabled="true" id="extended_firmware" name="Extended Firmware Based Erasure"/>
<standard enabled="true" id="firmware" name="Firmware Based Erasure"/>
<standard enabled="true" id="hmg_higher" name="HMG Infosec Standard 5, Higher Standard"/>
<standard enabled="true" id="hmg_lower" name="HMG Infosec Standard 5, Lower Standard"/>
<standard enabled="true" id="ieee_clear" name="IEEE 2883-2022 Clear"/>
<standard enabled="true" id="ieee_purge" name="IEEE 2883-2022 Purge"/>
<standard enabled="false" id="nist_pc" name="NIST 800-88" pattern="0x00" pattern_type="static"/>
<standard enabled="true" id="nist_clear" name="NIST 800-88 Clear" pattern="0x00" pattern_type="static"/>
<standard selected="true" enabled="true" id="nist_purge" name="NIST 800-88 Purge"/>
<standard enabled="true" id="nsa" name="NSA 130-1"/>
<standard enabled="true" id="ncsc" name="National Computer Security Center (NCSC-TG-025)"/>
<standard enabled="true" id="navso" name="Navy Staff Office Publication (NAVSO P-5239-26)"/>
<standard enabled="true" id="opnavinst" name="OPNAVINST 5239.1A"/>
<standard enabled="true" id="peter_gutmann" name="Peter Gutmann's Algorithm"/>
<standard enabled="true" id="rcmp_tssit" name="RCMP TSSIT OPS-II"/>
<standard enabled="true" id="random_byte_3x" name="Random Byte Overwrite (3x)"/>
<standard enabled="true" id="crypto_erase" name="Sanitize Cryptographic Erasure"/>
<standard enabled="true" id="tcg_crypto_erase" name="TCG Cryptographic Erasure"/>
<standard enabled="true" id="us_army" name="U.S. Army AR380-19"/>
</erasure_standards>
<verification_standards type="array" key="standard">
<standard enabled="true" id="all_bytes_same" name="All bytes the same" pattern="0x00"/>
<standard enabled="true" id="all_ones" name="All ones"/>
<standard selected="true" enabled="true" id="all_sectors_same" name="All sectors the same"/>
<standard enabled="true" id="all_zeros" name="All zeros"/>
</verification_standards>
<network>
<enabled>true</enabled>
<dhcp>true</dhcp>
<sshd>false</sshd>
<looping>false</looping>
<address></address>
<mask></mask>
<gateway></gateway>
<dns1></dns1>
<dns2></dns2>
<vlan></vlan>
</network>
<network_security>
<enabled>false</enabled>
<certificate>false</certificate>
<protocols type="array" key="protocol">
<protocol selected="true">peap</protocol>
<protocol>tls</protocol>
</protocols>
<identity encrypted="false"></identity>
<password encrypted="false"></password>
</network_security>
<network_share>
<username encrypted="false">blancco</username>
<password encrypted="false">blancco</password>
<domain></domain>
<hostname>10.9.100.1</hostname>
<path>blancco-reports</path>
<protocols type="array" key="protocol">
<protocol selected="true">smb</protocol>
</protocols>
</network_share>
<proxy>
<proxy_address encrypted="false"></proxy_address>
<proxy_port encrypted="false"></proxy_port>
<proxy_username encrypted="false"></proxy_username>
<proxy_password encrypted="false"></proxy_password>
</proxy>
<mc>
<username encrypted="false"></username>
<password encrypted="false"></password>
<hostname></hostname>
<port></port>
<timeout>20</timeout>
<validate_remote_certificate>true</validate_remote_certificate>
</mc>
<workflow offline="false" default="false"></workflow>
<erasure>
<drive_self_test type="short">false</drive_self_test>
<max_simultaneous_erasures>50</max_simultaneous_erasures>
<remove_hidden_areas>false</remove_hidden_areas>
<preserve_recovery_partition>false</preserve_recovery_partition>
<store_erasure_progress>false</store_erasure_progress>
<remapped mandatory="false" threshold="0">false</remapped>
<action_if_not_possible>interrupt</action_if_not_possible>
<fail_on_remapped_sectors>false</fail_on_remapped_sectors>
<fail_on_erasure_errors threshold="5">true</fail_on_erasure_errors>
<fail_on_read_errors threshold="5">true</fail_on_read_errors>
<verification>10</verification>
<enforced_rules type="array" key="rule">
<rule enabled="false" name="enforced_standard" standard_id="bl_ssd" target="ssd"/>
<rule enabled="true" name="fallback_nist_standard" standard_id="nist_purge" fallback_id="nist_clear"/>
</enforced_rules>
<fail_on_failed_self_test>false</fail_on_failed_self_test>
<fail_on_low_erasure_speed threshold="1">false</fail_on_low_erasure_speed>
<fail_on_timeout threshold="1">false</fail_on_timeout>
<use_write_same>true</use_write_same>
<allow_secure_erase_enhanced>true</allow_secure_erase_enhanced>
<allow_secure_erase_normal>true</allow_secure_erase_normal>
<allow_nvme_format_crypto_erase>true</allow_nvme_format_crypto_erase>
<allow_nvme_format_user_data_erase>true</allow_nvme_format_user_data_erase>
<allow_scsi_format_unit>true</allow_scsi_format_unit>
<allow_sanitize_block_erase>true</allow_sanitize_block_erase>
<allow_sanitize_crypto_erase>true</allow_sanitize_crypto_erase>
<allow_sanitize_overwrite>true</allow_sanitize_overwrite>
<allow_tcg_block_erase>true</allow_tcg_block_erase>
<allow_tcg_crypto_erase>true</allow_tcg_crypto_erase>
<allow_tcg_overwrite>true</allow_tcg_overwrite>
<allow_tcg_reset_write_pointers>true</allow_tcg_reset_write_pointers>
<allow_tcg_unmap>true</allow_tcg_unmap>
</erasure>
<fingerprint>
<enabled>false</enabled>
<location>67000</location>
</fingerprint>
<bootable_report>
<enabled>true</enabled>
</bootable_report>
<format_disk>
<enabled>false</enabled>
<type>ntfs</type>
</format_disk>
<spin_down_idle_disk>
<enabled>false</enabled>
</spin_down_idle_disk>
<raid>
<show_logical_disks>false</show_logical_disks>
<enable_passthrough>true</enable_passthrough>
<kill_logical_disks>true</kill_logical_disks>
</raid>
<hotplug>
<enabled>false</enabled>
<timeout>30</timeout>
</hotplug>
<external_device_service>
<enabled>false</enabled>
<port>80</port>
<https_port>443</https_port>
<hardware_tests type="array" key="test" enabled="false">
<test enabled="true" passes="1">memory</test>
<test enabled="true">cpu</test>
<test enabled="true" threshold="60">battery</test>
<test enabled="true" threshold="50" duration="600">battery_discharge</test>
<test enabled="true">display</test>
<test enabled="true">keyboard</test>
<test enabled="true">pointing_devices</test>
<test enabled="true">webcam</test>
</hardware_tests>
</external_device_service>
<license>
<provider>bios</provider>
<provider_report>bios</provider_report>
<edition>Enterprise Volume Edition</edition>
<offline></offline>
<mode>Drive Eraser</mode>
</license>
<image>
<description></description>
<creation_date>2025-03-10</creation_date>
</image>
<customer_data>
<business_location></business_location>
<customer_license>General Electric Company</customer_license>
<erasure_person></erasure_person>
<erasure_provider></erasure_provider>
<business_name></business_name>
</customer_data>
<settings>
<gui>
<erasure_console>local</erasure_console>
<erasure_view>list</erasure_view>
<show_removable_devices>false</show_removable_devices>
<show_san_devices>true</show_san_devices>
<ssd_erasure_exception>true</ssd_erasure_exception>
<report_view locked="true">standard</report_view>
<erasure_settings locked="false"/>
<show_customer>false</show_customer>
<show_operator>false</show_operator>
<show_partitions>false</show_partitions>
<screensaver locked="false">
<timeout>30</timeout>
<show_exceptions>false</show_exceptions>
</screensaver>
<hexviewer>
<autostart>false</autostart>
</hexviewer>
<mc_monitor>false</mc_monitor>
<drive_selection_percentage>5</drive_selection_percentage>
<reconfigure_controller_mode>
<timeout enabled="false">30</timeout>
<default_focus_on_proceed>true</default_focus_on_proceed>
</reconfigure_controller_mode>
<disable_sid_block_authentication>
<timeout enabled="true">0</timeout>
<default_focus_on_proceed>false</default_focus_on_proceed>
</disable_sid_block_authentication>
<scale_factor>100</scale_factor>
<clear_tpm>
<timeout enabled="true">0</timeout>
<default_focus_on_proceed>false</default_focus_on_proceed>
</clear_tpm>
<accessibility>
<available>false</available>
<enabled>true</enabled>
<key_echo>true</key_echo>
<speaking_rate>80</speaking_rate>
</accessibility>
<sound_level>70</sound_level>
<input_method>
<enabled>false</enabled>
<jp>false</jp>
<kr>false</kr>
</input_method>
</gui>
</settings>
<custom_fields type="array" key="custom_field">
<custom_field type="input" mandatory="true" locked="false" per_drive="false" show_in_editor="false" pattern="" hint="">
<name>custom_field_1</name>
<title>GERITM Number</title>
<value></value>
</custom_field>
<custom_field type="input" mandatory="true" locked="false" per_drive="false" show_in_editor="false" pattern="" hint="">
<name>custom_field_2</name>
<title>Device Name</title>
<value></value>
</custom_field>
<custom_field type="input" mandatory="true" locked="false" per_drive="false" show_in_editor="false" pattern="" hint="">
<name>custom_field_3</name>
<title>Device Serial Number</title>
<value></value>
</custom_field>
<custom_field type="input" mandatory="false" locked="true" per_drive="false" show_in_editor="false" pattern="" hint="">
<name>custom_field_4</name>
<title>Version</title>
<value>EVE_20250310</value>
</custom_field>
</custom_fields>
<exclude_verification_ranges type="array" key="exclude_verification_range"/>
<report>
<per_drive>false</per_drive>
<auto_backup>true</auto_backup>
<extensions type="array" key="extension">
<extension selected="true">xml</extension>
</extensions>
<utc_offset>0</utc_offset>
<network_info>true</network_info>
<custom_signature>
<enabled>false</enabled>
<label></label>
</custom_signature>
<drive_life_estimation>false</drive_life_estimation>
</report>
<wireless>
<enabled>false</enabled>
<ssid encrypted="false"></ssid>
<password encrypted="false"></password>
<key_mgmt>WPA-PSK</key_mgmt>
<scan_ssid>0</scan_ssid>
</wireless>
<cd_eject>
<after_boot>true</after_boot>
<after_erasure>false</after_erasure>
<after_report>false</after_report>
<at_shutdown>false</at_shutdown>
</cd_eject>
<system_shutdown>
<after_erasure>false</after_erasure>
<after_successful_erasure>false</after_successful_erasure>
</system_shutdown>
<system_restart>
<after_erasure>false</after_erasure>
<after_successful_erasure>false</after_successful_erasure>
</system_restart>
<device_enrollment_detection>
<persistent_software>false</persistent_software>
</device_enrollment_detection>
<vnc_remote>
<enabled>false</enabled>
<mode>viewer</mode>
<repeater_hostname></repeater_hostname>
<port>5900</port>
<password encrypted="false"></password>
</vnc_remote>
<nvme_over_fabrics enabled="false" type="array" key="connection"/>
<adapters type="array" key="adapter"/>
</configuration>
</root>
<!-- JFLKHGDJLKFHGJCXLKGJFLKDJKLHFELIUFDSALDSAHGLSAVSHGSOFHDSAF -->

View File

@@ -136,7 +136,13 @@
dhcp-option=6,8.8.8.8 dhcp-option=6,8.8.8.8
enable-tftp enable-tftp
tftp-root={{ tftp_dir }} tftp-root={{ tftp_dir }}
# HTTP Boot clients (UEFI) identify with vendor class "HTTPClient"
dhcp-vendorclass=set:httpboot,HTTPClient
dhcp-option-force=tag:httpboot,60,"HTTPClient"
dhcp-option-force=tag:httpboot,66,""
dhcp-boot=tag:httpboot,http://10.9.100.1/blancco/grubx64.efi
dhcp-boot=ipxe.efi dhcp-boot=ipxe.efi
log-dhcp
- name: "Create TFTP directory" - name: "Create TFTP directory"
file: file:
@@ -445,24 +451,86 @@
- blancco - blancco
- memtest - memtest
- name: "Create TFTP blancco directory for GRUB boot" # --- Blancco PXE boot via Ubuntu kernel + switch_root ---
file: # Blancco's own kernel freezes on Dell Precision towers. Workaround:
path: "{{ tftp_dir }}/blancco" # Boot Ubuntu kernel, download Blancco rootfs, overlay mount, switch_root.
state: directory
mode: '0755'
- name: "Symlink Blancco boot files to TFTP (GRUB loads via TFTP)" - name: "Build Blancco PXE initramfs"
file: shell: |
src: "{{ web_root }}/blancco/{{ item }}" set -e
dest: "{{ tftp_dir }}/blancco/{{ item }}" WORK=$(mktemp -d)
state: link mkdir -p "$WORK"/{bin,lib/modules,lib64,sbin,usr/share/udhcpc}
force: yes
loop: # Busybox (static)
- vmlinuz-bde-linux cp /bin/busybox "$WORK/bin/" 2>/dev/null || apt-get install -y busybox-static >/dev/null && cp /bin/busybox "$WORK/bin/"
- intel-ucode.img for cmd in sh awk cat chmod echo grep gunzip ifconfig ip ln losetup ls mkdir mknod mount reboot route sed sleep switch_root tar udhcpc umount wget cpio; do
- amd-ucode.img ln -sf busybox "$WORK/bin/$cmd"
- config.img done
- initramfs-bde-linux.img
# NIC drivers (common server NICs)
KVER=$(uname -r)
KMOD="/lib/modules/$KVER/kernel/drivers/net/ethernet"
for drv in intel/e1000e/e1000e.ko.zst intel/igb/igb.ko.zst broadcom/tg3.ko.zst broadcom/bnx2.ko.zst broadcom/bnxt/bnxt_en.ko.zst broadcom/b44.ko.zst; do
if [ -f "$KMOD/$drv" ]; then
zstd -d "$KMOD/$drv" -o "$WORK/lib/modules/$(basename ${drv%.zst})" 2>/dev/null
fi
done
# Overlay module
OVMOD="/lib/modules/$KVER/kernel/fs/overlayfs/overlay.ko.zst"
if [ -f "$OVMOD" ]; then
zstd -d "$OVMOD" -o "$WORK/lib/modules/overlay.ko" 2>/dev/null
fi
# Init script
cp "{{ usb_root }}/playbook/blancco-init.sh" "$WORK/init"
chmod +x "$WORK/init"
# Build CPIO
cd "$WORK"
find . | cpio -o -H newc 2>/dev/null | gzip > "{{ web_root }}/blancco/kexec-initrd.img"
rm -rf "$WORK"
echo "Built kexec-initrd.img: $(stat -c %s '{{ web_root }}/blancco/kexec-initrd.img') bytes"
args:
creates: "{{ web_root }}/blancco/kexec-initrd.img"
- name: "Copy Ubuntu kernel for Blancco PXE boot"
copy:
src: "/boot/vmlinuz-{{ ansible_kernel }}"
dest: "{{ web_root }}/blancco/vmlinuz-ubuntu"
remote_src: yes
mode: '0644'
- name: "Build Ubuntu kernel modules tarball for Blancco"
shell: |
set -e
KVER=$(uname -r)
tar czf "{{ web_root }}/blancco/kmod.tar.gz" -C / "lib/modules/$KVER"
echo "Built kmod.tar.gz: $(du -h '{{ web_root }}/blancco/kmod.tar.gz' | cut -f1)"
args:
creates: "{{ web_root }}/blancco/kmod.tar.gz"
- name: "Deploy Blancco config and preferences (null-stripped)"
shell: |
# Strip null bytes from config.img files and deploy
if [ -f "{{ web_root }}/blancco/config.img" ]; then
WORK=$(mktemp -d)
cd "$WORK"
cpio -id < "{{ web_root }}/blancco/config.img" 2>/dev/null
tr -d '\000' < config.xml > "{{ web_root }}/blancco/config-clean.xml"
rm -rf "$WORK"
fi
# Deploy preferences from playbook (pre-configured with network share)
cp "{{ usb_root }}/playbook/blancco-preferences.xml" "{{ web_root }}/blancco/preferences.xml"
args:
creates: "{{ web_root }}/blancco/config-clean.xml"
- name: "Create Samba user for Blancco reports"
shell: |
id blancco 2>/dev/null || useradd -r -s /usr/sbin/nologin blancco
echo -e "blancco\nblancco" | smbpasswd -a -s blancco 2>/dev/null
args:
creates: /etc/samba/smbpasswd
- name: "Check for WinPE deployment content on USB" - name: "Check for WinPE deployment content on USB"
stat: stat:

View File

@@ -248,7 +248,7 @@ PYEOF
grub-mkstandalone \ grub-mkstandalone \
--format=x86_64-efi \ --format=x86_64-efi \
--output="$OUT_DIR/blancco/grubx64.efi" \ --output="$OUT_DIR/blancco/grubx64.efi" \
--modules="linux normal echo net efinet tftp chain sleep" \ --modules="linux normal echo net efinet http tftp chain sleep all_video efi_gop" \
"boot/grub/grub.cfg=$GRUB_CFG" 2>/dev/null "boot/grub/grub.cfg=$GRUB_CFG" 2>/dev/null
echo " Built grubx64.efi ($(du -h "$OUT_DIR/blancco/grubx64.efi" | cut -f1))" echo " Built grubx64.efi ($(du -h "$OUT_DIR/blancco/grubx64.efi" | cut -f1))"
else else