Add README, update docs, fix CRLF, SSH, and playbook network detection
- Add comprehensive README.md with full project documentation - Update SETUP.md to reflect current state (7 image types, webapp, boot tools, Samba shares) - Enable SSH in autoinstall user-data for remote access - Fix ansible_default_ipv4.interface error when no default gateway exists - Fix Windows CRLF line endings on all shell scripts and YAML files - Fix test-vm.sh: use --install kernel extraction instead of --location, don't delete source ISO on --destroy Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,443 +1,445 @@
|
||||
---
|
||||
- name: PXE Server Setup (Ubuntu with dnsmasq)
|
||||
hosts: localhost
|
||||
connection: local
|
||||
become: yes
|
||||
gather_facts: yes
|
||||
|
||||
pre_tasks:
|
||||
- name: "Verify required packages are installed (pre-installed from offline .debs)"
|
||||
command: dpkg -s {{ item }}
|
||||
loop:
|
||||
- dnsmasq
|
||||
- apache2
|
||||
- samba
|
||||
- unzip
|
||||
- ufw
|
||||
- cron
|
||||
- ansible
|
||||
- wimtools
|
||||
register: pkg_check
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- name: "Warn about missing packages"
|
||||
debug:
|
||||
msg: "WARNING: {{ item.item }} is not installed! Install offline .debs first."
|
||||
loop: "{{ pkg_check.results }}"
|
||||
when: item.rc != 0
|
||||
|
||||
vars:
|
||||
tftp_dir: "/srv/tftp"
|
||||
web_root: "/var/www/html"
|
||||
samba_share: "/srv/samba/winpeapps"
|
||||
usb_mount: "/mnt/usb/playbook" # where your USB is mounted
|
||||
image_types:
|
||||
- gea-standard
|
||||
- gea-engineer
|
||||
- gea-shopfloor
|
||||
- ge-standard
|
||||
- ge-engineer
|
||||
- ge-shopfloor-lockdown
|
||||
- ge-shopfloor-mce
|
||||
deploy_subdirs:
|
||||
- Applications
|
||||
- Control
|
||||
- "Operating Systems"
|
||||
- "Out-of-box Drivers"
|
||||
- Packages
|
||||
- Tools
|
||||
|
||||
tasks:
|
||||
- name: "Gather minimal network facts"
|
||||
ansible.builtin.setup:
|
||||
filter:
|
||||
- ansible_interfaces
|
||||
- ansible_default_ipv4
|
||||
|
||||
- name: "Bring up all ethernet-like interfaces"
|
||||
command: ip link set dev {{ item }} up
|
||||
loop: "{{ ansible_interfaces | select('match','^e(th|n)') | list }}"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: "Determine PXE interface"
|
||||
set_fact:
|
||||
pxe_iface: >-
|
||||
{{ (ansible_interfaces
|
||||
| select('match','^e(th|n)')
|
||||
| reject('equalto','lo')
|
||||
| reject('equalto', ansible_default_ipv4.interface)
|
||||
| list
|
||||
)
|
||||
| first
|
||||
| default(ansible_default_ipv4.interface) }}
|
||||
|
||||
- name: "Debug: final pxe_iface choice"
|
||||
debug:
|
||||
msg: "Using {{ pxe_iface }} for DHCP/TFTP"
|
||||
|
||||
- name: "Configure dnsmasq for DHCP and TFTP"
|
||||
copy:
|
||||
dest: /etc/dnsmasq.conf
|
||||
backup: yes
|
||||
content: |
|
||||
port=0
|
||||
interface={{ pxe_iface }}
|
||||
bind-interfaces
|
||||
dhcp-range=10.9.100.10,10.9.100.100,12h
|
||||
dhcp-option=3,10.9.100.1
|
||||
dhcp-option=6,8.8.8.8
|
||||
enable-tftp
|
||||
tftp-root={{ tftp_dir }}
|
||||
dhcp-boot=ipxe.efi
|
||||
|
||||
- name: "Create TFTP directory"
|
||||
file:
|
||||
path: "{{ tftp_dir }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
owner: nobody
|
||||
group: nogroup
|
||||
|
||||
- name: "Create Win11 directory structure"
|
||||
file:
|
||||
path: "{{ web_root }}/win11/{{ item }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
loop:
|
||||
- "EFI/Boot"
|
||||
- "EFI/Microsoft/Boot"
|
||||
- "Boot"
|
||||
- "sources"
|
||||
|
||||
- name: "Create Altiris iPXE directory"
|
||||
file:
|
||||
path: "{{ web_root }}/Altiris/iPXE"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: "Create boot tool directories"
|
||||
file:
|
||||
path: "{{ web_root }}/{{ item }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
loop:
|
||||
- clonezilla
|
||||
- blancco
|
||||
- memtest
|
||||
|
||||
- name: "Create GetPxeScript.aspx (iPXE boot menu)"
|
||||
copy:
|
||||
dest: "{{ web_root }}/Altiris/iPXE/GetPxeScript.aspx"
|
||||
backup: yes
|
||||
content: |
|
||||
#!ipxe
|
||||
|
||||
set server 10.9.100.1
|
||||
|
||||
:menu
|
||||
menu GE Aerospace PXE Boot Menu
|
||||
item --gap -- ---- Windows Deployment ----
|
||||
item winpe Windows PE (Image Deployment)
|
||||
item --gap -- ---- Utilities ----
|
||||
item clonezilla Clonezilla Live (Disk Imaging)
|
||||
item blancco Blancco Drive Eraser
|
||||
item memtest Memtest86+ (Memory Diagnostics)
|
||||
item --gap -- ----
|
||||
item reboot Reboot
|
||||
item exit Exit to BIOS
|
||||
choose --default winpe --timeout 30000 target && goto ${target}
|
||||
|
||||
:winpe
|
||||
kernel http://${server}/win11/wimboot gui
|
||||
initrd http://${server}/win11/EFI/Microsoft/Boot/boot.stl EFI/Microsoft/Boot/Boot.stl
|
||||
initrd http://${server}/win11/EFI/Microsoft/Boot/BCD EFI/Microsoft/Boot/BCD
|
||||
initrd http://${server}/win11/EFI/Boot/bootx64.efi EFI/Boot/bootx64.efi
|
||||
initrd http://${server}/win11/Boot/boot.sdi Boot/boot.sdi
|
||||
initrd http://${server}/win11/sources/boot.wim sources/boot.wim
|
||||
boot
|
||||
|
||||
:clonezilla
|
||||
set base http://${server}/clonezilla
|
||||
kernel ${base}/vmlinuz boot=live username=user union=overlay config components noswap edd=on nomodeset nodmraid locales= keyboard-layouts= ocs_live_run="ocs-live-general" ocs_live_extra_param="" ocs_live_batch=no net.ifnames=0 nosplash noprompt fetch=${base}/filesystem.squashfs
|
||||
initrd ${base}/initrd.img
|
||||
boot
|
||||
|
||||
:blancco
|
||||
set bbase http://${server}/blancco
|
||||
kernel ${bbase}/vmlinuz-bde-linux archisobasedir=arch archiso_http_srv=http://${server}/blancco/ copytoram=y cow_spacesize=50% memtest=00 vmalloc=400M ip=dhcp quiet nomodeset libata.allow_tpm=1
|
||||
initrd ${bbase}/intel-ucode.img ${bbase}/amd-ucode.img ${bbase}/config.img ${bbase}/initramfs-bde-linux.img
|
||||
boot
|
||||
|
||||
:memtest
|
||||
kernel http://${server}/memtest/memtest.efi
|
||||
boot
|
||||
|
||||
:reboot
|
||||
reboot
|
||||
|
||||
:exit
|
||||
exit
|
||||
|
||||
- name: "Ensure Apache listens on port 4433"
|
||||
lineinfile:
|
||||
path: /etc/apache2/ports.conf
|
||||
line: "Listen 4433"
|
||||
backup: yes
|
||||
state: present
|
||||
|
||||
- name: "Create VirtualHost for Altiris iPXE on 4433"
|
||||
copy:
|
||||
dest: /etc/apache2/sites-available/altiris-ipxe.conf
|
||||
backup: yes
|
||||
content: |
|
||||
<VirtualHost *:4433>
|
||||
DocumentRoot {{ web_root }}
|
||||
<Directory "{{ web_root }}/Altiris/iPXE">
|
||||
Options Indexes FollowSymLinks
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
AddType text/plain .aspx
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
|
||||
- name: "Enable Altiris iPXE site"
|
||||
command: a2ensite altiris-ipxe.conf
|
||||
args:
|
||||
creates: /etc/apache2/sites-enabled/altiris-ipxe.conf
|
||||
|
||||
- name: "Reload Apache to apply changes"
|
||||
systemd:
|
||||
name: apache2
|
||||
state: reloaded
|
||||
|
||||
- name: "Create Samba share root"
|
||||
file:
|
||||
path: "{{ samba_share }}"
|
||||
state: directory
|
||||
mode: '0777'
|
||||
|
||||
- name: "Create Clonezilla backup share directory"
|
||||
file:
|
||||
path: /srv/samba/clonezilla
|
||||
state: directory
|
||||
mode: '0777'
|
||||
|
||||
- name: "Create Blancco reports share directory"
|
||||
file:
|
||||
path: /srv/samba/blancco-reports
|
||||
state: directory
|
||||
mode: '0777'
|
||||
|
||||
- name: "Configure Samba shares"
|
||||
blockinfile:
|
||||
path: /etc/samba/smb.conf
|
||||
backup: yes
|
||||
block: |
|
||||
[winpeapps]
|
||||
path = {{ samba_share }}
|
||||
browseable = yes
|
||||
read only = no
|
||||
guest ok = yes
|
||||
|
||||
[clonezilla]
|
||||
path = /srv/samba/clonezilla
|
||||
browseable = yes
|
||||
read only = no
|
||||
guest ok = yes
|
||||
comment = Clonezilla backup images
|
||||
|
||||
[blancco-reports]
|
||||
path = /srv/samba/blancco-reports
|
||||
browseable = yes
|
||||
read only = no
|
||||
guest ok = yes
|
||||
comment = Blancco Drive Eraser reports
|
||||
|
||||
- name: "Create image-type top-level directories"
|
||||
file:
|
||||
path: "{{ samba_share }}/{{ item }}"
|
||||
state: directory
|
||||
mode: '0777'
|
||||
loop: "{{ image_types }}"
|
||||
|
||||
- name: "Create Deploy subdirectories for each image type"
|
||||
file:
|
||||
path: "{{ samba_share }}/{{ item.0 }}/Deploy/{{ item.1 }}"
|
||||
state: directory
|
||||
mode: '0777'
|
||||
with_nested:
|
||||
- "{{ image_types }}"
|
||||
- "{{ deploy_subdirs }}"
|
||||
|
||||
- name: "Copy WinPE & boot files from USB"
|
||||
copy:
|
||||
src: "{{ usb_mount }}/{{ item.src }}"
|
||||
dest: "{{ web_root }}/win11/{{ item.dest }}"
|
||||
mode: '0644'
|
||||
loop:
|
||||
- { src: "wimboot", dest: "wimboot" }
|
||||
- { src: "boot.stl", dest: "EFI/Microsoft/Boot/boot.stl" }
|
||||
- { src: "BCD", dest: "EFI/Microsoft/Boot/BCD" }
|
||||
- { src: "bootx64.efi", dest: "EFI/Boot/bootx64.efi" }
|
||||
- { src: "boot.sdi", dest: "Boot/boot.sdi" }
|
||||
- { src: "boot.wim", dest: "sources/boot.wim" }
|
||||
|
||||
- name: "Copy iPXE binaries from USB"
|
||||
copy:
|
||||
src: "{{ usb_mount }}/{{ item }}"
|
||||
dest: "{{ tftp_dir }}/{{ item }}"
|
||||
mode: '0755'
|
||||
loop:
|
||||
- ipxe.efi
|
||||
|
||||
- name: "Copy boot tool files from USB (Clonezilla, Blancco, Memtest)"
|
||||
shell: >
|
||||
cp -r "{{ usb_mount }}/../boot-tools/{{ item }}/"* "{{ web_root }}/{{ item }}/" 2>/dev/null ||
|
||||
cp -r "{{ usb_mount }}/boot-tools/{{ item }}/"* "{{ web_root }}/{{ item }}/" 2>/dev/null || true
|
||||
loop:
|
||||
- clonezilla
|
||||
- blancco
|
||||
- memtest
|
||||
|
||||
- name: "Check for WinPE deployment content on USB"
|
||||
stat:
|
||||
path: "{{ usb_mount }}/images"
|
||||
register: usb_images_dir
|
||||
|
||||
- name: "Import WinPE deployment content from USB (if present)"
|
||||
shell: >
|
||||
cp -rn "{{ usb_mount }}/images/{{ item }}/"* "{{ samba_share }}/{{ item }}/" 2>/dev/null || true
|
||||
loop: "{{ image_types }}"
|
||||
when: usb_images_dir.stat.exists
|
||||
|
||||
- name: "Restart and enable services"
|
||||
systemd:
|
||||
name: "{{ item }}"
|
||||
state: restarted
|
||||
enabled: yes
|
||||
loop:
|
||||
- dnsmasq
|
||||
- apache2
|
||||
- smbd
|
||||
|
||||
- name: "Allow necessary firewall ports (UFW)"
|
||||
ufw:
|
||||
rule: allow
|
||||
port: "{{ item }}"
|
||||
proto: "{{ 'udp' if item in ['67','69'] else 'tcp' }}"
|
||||
loop:
|
||||
- 67
|
||||
- 69
|
||||
- 80
|
||||
- 4433
|
||||
- 445
|
||||
- 9009
|
||||
|
||||
- name: "Enable UFW firewall"
|
||||
ufw:
|
||||
state: enabled
|
||||
policy: deny
|
||||
|
||||
- name: "Schedule dnsmasq restart 15s after reboot"
|
||||
cron:
|
||||
name: "Restart dnsmasq after reboot"
|
||||
user: root
|
||||
special_time: "reboot"
|
||||
job: "/bin/sleep 15 && /usr/bin/systemctl restart dnsmasq.service"
|
||||
|
||||
# --- Web Management App (Flask) ---
|
||||
- name: "Create webapp directory"
|
||||
file:
|
||||
path: /opt/pxe-webapp
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: "Copy webapp from USB"
|
||||
shell: >
|
||||
cp -r "{{ usb_mount }}/../webapp/"* /opt/pxe-webapp/ 2>/dev/null ||
|
||||
cp -r "{{ usb_mount }}/webapp/"* /opt/pxe-webapp/ 2>/dev/null || true
|
||||
args:
|
||||
creates: /opt/pxe-webapp/app.py
|
||||
|
||||
- name: "Create Python virtual environment for webapp"
|
||||
command: python3 -m venv /opt/pxe-webapp/venv
|
||||
args:
|
||||
creates: /opt/pxe-webapp/venv/bin/python
|
||||
|
||||
- name: "Install webapp Python dependencies (offline wheels)"
|
||||
shell: >
|
||||
/opt/pxe-webapp/venv/bin/pip install --no-index
|
||||
--find-links="{{ usb_mount }}/../pip-wheels/"
|
||||
--find-links="{{ usb_mount }}/pip-wheels/"
|
||||
-r /opt/pxe-webapp/requirements.txt 2>/dev/null ||
|
||||
/opt/pxe-webapp/venv/bin/pip install -r /opt/pxe-webapp/requirements.txt
|
||||
|
||||
- name: "Create systemd service for PXE webapp"
|
||||
copy:
|
||||
dest: /etc/systemd/system/pxe-webapp.service
|
||||
content: |
|
||||
[Unit]
|
||||
Description=PXE Server Web Management
|
||||
After=network.target apache2.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/pxe-webapp
|
||||
Environment=SAMBA_SHARE={{ samba_share }}
|
||||
Environment=CLONEZILLA_SHARE=/srv/samba/clonezilla
|
||||
Environment=WEB_ROOT={{ web_root }}
|
||||
Environment=BLANCCO_REPORTS=/srv/samba/blancco-reports
|
||||
Environment=AUDIT_LOG=/var/log/pxe-webapp-audit.log
|
||||
ExecStart=/opt/pxe-webapp/venv/bin/python app.py
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
- name: "Enable and start PXE webapp service"
|
||||
systemd:
|
||||
name: pxe-webapp
|
||||
state: started
|
||||
enabled: yes
|
||||
daemon_reload: yes
|
||||
|
||||
- name: "Configure Apache reverse proxy for webapp"
|
||||
copy:
|
||||
dest: /etc/apache2/sites-available/pxe-webapp.conf
|
||||
content: |
|
||||
<VirtualHost *:80>
|
||||
ProxyPreserveHost On
|
||||
ProxyPass /manage http://127.0.0.1:9009/
|
||||
ProxyPassReverse /manage http://127.0.0.1:9009/
|
||||
</VirtualHost>
|
||||
|
||||
- name: "Enable Apache proxy modules"
|
||||
command: a2enmod proxy proxy_http
|
||||
args:
|
||||
creates: /etc/apache2/mods-enabled/proxy.load
|
||||
|
||||
- name: "Enable webapp Apache site"
|
||||
command: a2ensite pxe-webapp.conf
|
||||
args:
|
||||
creates: /etc/apache2/sites-enabled/pxe-webapp.conf
|
||||
|
||||
- name: "Configure static IP for PXE interface"
|
||||
copy:
|
||||
dest: /etc/netplan/50-cloud-init.yaml
|
||||
backup: yes
|
||||
content: |
|
||||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
{{ pxe_iface }}:
|
||||
dhcp4: no
|
||||
addresses: [10.9.100.1/24]
|
||||
notify: "Apply netplan"
|
||||
|
||||
handlers:
|
||||
- name: "Apply netplan"
|
||||
command: netplan apply
|
||||
---
|
||||
- name: PXE Server Setup (Ubuntu with dnsmasq)
|
||||
hosts: localhost
|
||||
connection: local
|
||||
become: yes
|
||||
gather_facts: yes
|
||||
|
||||
pre_tasks:
|
||||
- name: "Verify required packages are installed (pre-installed from offline .debs)"
|
||||
command: dpkg -s {{ item }}
|
||||
loop:
|
||||
- dnsmasq
|
||||
- apache2
|
||||
- samba
|
||||
- unzip
|
||||
- ufw
|
||||
- cron
|
||||
- ansible
|
||||
- wimtools
|
||||
register: pkg_check
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- name: "Warn about missing packages"
|
||||
debug:
|
||||
msg: "WARNING: {{ item.item }} is not installed! Install offline .debs first."
|
||||
loop: "{{ pkg_check.results }}"
|
||||
when: item.rc != 0
|
||||
|
||||
vars:
|
||||
tftp_dir: "/srv/tftp"
|
||||
web_root: "/var/www/html"
|
||||
samba_share: "/srv/samba/winpeapps"
|
||||
usb_mount: "/mnt/usb/playbook" # where your USB is mounted
|
||||
image_types:
|
||||
- gea-standard
|
||||
- gea-engineer
|
||||
- gea-shopfloor
|
||||
- ge-standard
|
||||
- ge-engineer
|
||||
- ge-shopfloor-lockdown
|
||||
- ge-shopfloor-mce
|
||||
deploy_subdirs:
|
||||
- Applications
|
||||
- Control
|
||||
- "Operating Systems"
|
||||
- "Out-of-box Drivers"
|
||||
- Packages
|
||||
- Tools
|
||||
|
||||
tasks:
|
||||
- name: "Gather minimal network facts"
|
||||
ansible.builtin.setup:
|
||||
filter:
|
||||
- ansible_interfaces
|
||||
- ansible_default_ipv4
|
||||
|
||||
- name: "Bring up all ethernet-like interfaces"
|
||||
command: ip link set dev {{ item }} up
|
||||
loop: "{{ ansible_interfaces | select('match','^e(th|n)') | list }}"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: "Determine PXE interface"
|
||||
set_fact:
|
||||
pxe_iface: >-
|
||||
{{ (ansible_interfaces
|
||||
| select('match','^e(th|n)')
|
||||
| reject('equalto','lo')
|
||||
| reject('equalto', ansible_default_ipv4.interface | default(''))
|
||||
| list
|
||||
)
|
||||
| first
|
||||
| default(ansible_default_ipv4.interface | default(
|
||||
ansible_interfaces | select('match','^e(th|n)') | first | default('eth0')
|
||||
)) }}
|
||||
|
||||
- name: "Debug: final pxe_iface choice"
|
||||
debug:
|
||||
msg: "Using {{ pxe_iface }} for DHCP/TFTP"
|
||||
|
||||
- name: "Configure dnsmasq for DHCP and TFTP"
|
||||
copy:
|
||||
dest: /etc/dnsmasq.conf
|
||||
backup: yes
|
||||
content: |
|
||||
port=0
|
||||
interface={{ pxe_iface }}
|
||||
bind-interfaces
|
||||
dhcp-range=10.9.100.10,10.9.100.100,12h
|
||||
dhcp-option=3,10.9.100.1
|
||||
dhcp-option=6,8.8.8.8
|
||||
enable-tftp
|
||||
tftp-root={{ tftp_dir }}
|
||||
dhcp-boot=ipxe.efi
|
||||
|
||||
- name: "Create TFTP directory"
|
||||
file:
|
||||
path: "{{ tftp_dir }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
owner: nobody
|
||||
group: nogroup
|
||||
|
||||
- name: "Create Win11 directory structure"
|
||||
file:
|
||||
path: "{{ web_root }}/win11/{{ item }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
loop:
|
||||
- "EFI/Boot"
|
||||
- "EFI/Microsoft/Boot"
|
||||
- "Boot"
|
||||
- "sources"
|
||||
|
||||
- name: "Create Altiris iPXE directory"
|
||||
file:
|
||||
path: "{{ web_root }}/Altiris/iPXE"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: "Create boot tool directories"
|
||||
file:
|
||||
path: "{{ web_root }}/{{ item }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
loop:
|
||||
- clonezilla
|
||||
- blancco
|
||||
- memtest
|
||||
|
||||
- name: "Create GetPxeScript.aspx (iPXE boot menu)"
|
||||
copy:
|
||||
dest: "{{ web_root }}/Altiris/iPXE/GetPxeScript.aspx"
|
||||
backup: yes
|
||||
content: |
|
||||
#!ipxe
|
||||
|
||||
set server 10.9.100.1
|
||||
|
||||
:menu
|
||||
menu GE Aerospace PXE Boot Menu
|
||||
item --gap -- ---- Windows Deployment ----
|
||||
item winpe Windows PE (Image Deployment)
|
||||
item --gap -- ---- Utilities ----
|
||||
item clonezilla Clonezilla Live (Disk Imaging)
|
||||
item blancco Blancco Drive Eraser
|
||||
item memtest Memtest86+ (Memory Diagnostics)
|
||||
item --gap -- ----
|
||||
item reboot Reboot
|
||||
item exit Exit to BIOS
|
||||
choose --default winpe --timeout 30000 target && goto ${target}
|
||||
|
||||
:winpe
|
||||
kernel http://${server}/win11/wimboot gui
|
||||
initrd http://${server}/win11/EFI/Microsoft/Boot/boot.stl EFI/Microsoft/Boot/Boot.stl
|
||||
initrd http://${server}/win11/EFI/Microsoft/Boot/BCD EFI/Microsoft/Boot/BCD
|
||||
initrd http://${server}/win11/EFI/Boot/bootx64.efi EFI/Boot/bootx64.efi
|
||||
initrd http://${server}/win11/Boot/boot.sdi Boot/boot.sdi
|
||||
initrd http://${server}/win11/sources/boot.wim sources/boot.wim
|
||||
boot
|
||||
|
||||
:clonezilla
|
||||
set base http://${server}/clonezilla
|
||||
kernel ${base}/vmlinuz boot=live username=user union=overlay config components noswap edd=on nomodeset nodmraid locales= keyboard-layouts= ocs_live_run="ocs-live-general" ocs_live_extra_param="" ocs_live_batch=no net.ifnames=0 nosplash noprompt fetch=${base}/filesystem.squashfs
|
||||
initrd ${base}/initrd.img
|
||||
boot
|
||||
|
||||
:blancco
|
||||
set bbase http://${server}/blancco
|
||||
kernel ${bbase}/vmlinuz-bde-linux archisobasedir=arch archiso_http_srv=http://${server}/blancco/ copytoram=y cow_spacesize=50% memtest=00 vmalloc=400M ip=dhcp quiet nomodeset libata.allow_tpm=1
|
||||
initrd ${bbase}/intel-ucode.img ${bbase}/amd-ucode.img ${bbase}/config.img ${bbase}/initramfs-bde-linux.img
|
||||
boot
|
||||
|
||||
:memtest
|
||||
kernel http://${server}/memtest/memtest.efi
|
||||
boot
|
||||
|
||||
:reboot
|
||||
reboot
|
||||
|
||||
:exit
|
||||
exit
|
||||
|
||||
- name: "Ensure Apache listens on port 4433"
|
||||
lineinfile:
|
||||
path: /etc/apache2/ports.conf
|
||||
line: "Listen 4433"
|
||||
backup: yes
|
||||
state: present
|
||||
|
||||
- name: "Create VirtualHost for Altiris iPXE on 4433"
|
||||
copy:
|
||||
dest: /etc/apache2/sites-available/altiris-ipxe.conf
|
||||
backup: yes
|
||||
content: |
|
||||
<VirtualHost *:4433>
|
||||
DocumentRoot {{ web_root }}
|
||||
<Directory "{{ web_root }}/Altiris/iPXE">
|
||||
Options Indexes FollowSymLinks
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
AddType text/plain .aspx
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
|
||||
- name: "Enable Altiris iPXE site"
|
||||
command: a2ensite altiris-ipxe.conf
|
||||
args:
|
||||
creates: /etc/apache2/sites-enabled/altiris-ipxe.conf
|
||||
|
||||
- name: "Reload Apache to apply changes"
|
||||
systemd:
|
||||
name: apache2
|
||||
state: reloaded
|
||||
|
||||
- name: "Create Samba share root"
|
||||
file:
|
||||
path: "{{ samba_share }}"
|
||||
state: directory
|
||||
mode: '0777'
|
||||
|
||||
- name: "Create Clonezilla backup share directory"
|
||||
file:
|
||||
path: /srv/samba/clonezilla
|
||||
state: directory
|
||||
mode: '0777'
|
||||
|
||||
- name: "Create Blancco reports share directory"
|
||||
file:
|
||||
path: /srv/samba/blancco-reports
|
||||
state: directory
|
||||
mode: '0777'
|
||||
|
||||
- name: "Configure Samba shares"
|
||||
blockinfile:
|
||||
path: /etc/samba/smb.conf
|
||||
backup: yes
|
||||
block: |
|
||||
[winpeapps]
|
||||
path = {{ samba_share }}
|
||||
browseable = yes
|
||||
read only = no
|
||||
guest ok = yes
|
||||
|
||||
[clonezilla]
|
||||
path = /srv/samba/clonezilla
|
||||
browseable = yes
|
||||
read only = no
|
||||
guest ok = yes
|
||||
comment = Clonezilla backup images
|
||||
|
||||
[blancco-reports]
|
||||
path = /srv/samba/blancco-reports
|
||||
browseable = yes
|
||||
read only = no
|
||||
guest ok = yes
|
||||
comment = Blancco Drive Eraser reports
|
||||
|
||||
- name: "Create image-type top-level directories"
|
||||
file:
|
||||
path: "{{ samba_share }}/{{ item }}"
|
||||
state: directory
|
||||
mode: '0777'
|
||||
loop: "{{ image_types }}"
|
||||
|
||||
- name: "Create Deploy subdirectories for each image type"
|
||||
file:
|
||||
path: "{{ samba_share }}/{{ item.0 }}/Deploy/{{ item.1 }}"
|
||||
state: directory
|
||||
mode: '0777'
|
||||
with_nested:
|
||||
- "{{ image_types }}"
|
||||
- "{{ deploy_subdirs }}"
|
||||
|
||||
- name: "Copy WinPE & boot files from USB"
|
||||
copy:
|
||||
src: "{{ usb_mount }}/{{ item.src }}"
|
||||
dest: "{{ web_root }}/win11/{{ item.dest }}"
|
||||
mode: '0644'
|
||||
loop:
|
||||
- { src: "wimboot", dest: "wimboot" }
|
||||
- { src: "boot.stl", dest: "EFI/Microsoft/Boot/boot.stl" }
|
||||
- { src: "BCD", dest: "EFI/Microsoft/Boot/BCD" }
|
||||
- { src: "bootx64.efi", dest: "EFI/Boot/bootx64.efi" }
|
||||
- { src: "boot.sdi", dest: "Boot/boot.sdi" }
|
||||
- { src: "boot.wim", dest: "sources/boot.wim" }
|
||||
|
||||
- name: "Copy iPXE binaries from USB"
|
||||
copy:
|
||||
src: "{{ usb_mount }}/{{ item }}"
|
||||
dest: "{{ tftp_dir }}/{{ item }}"
|
||||
mode: '0755'
|
||||
loop:
|
||||
- ipxe.efi
|
||||
|
||||
- name: "Copy boot tool files from USB (Clonezilla, Blancco, Memtest)"
|
||||
shell: >
|
||||
cp -r "{{ usb_mount }}/../boot-tools/{{ item }}/"* "{{ web_root }}/{{ item }}/" 2>/dev/null ||
|
||||
cp -r "{{ usb_mount }}/boot-tools/{{ item }}/"* "{{ web_root }}/{{ item }}/" 2>/dev/null || true
|
||||
loop:
|
||||
- clonezilla
|
||||
- blancco
|
||||
- memtest
|
||||
|
||||
- name: "Check for WinPE deployment content on USB"
|
||||
stat:
|
||||
path: "{{ usb_mount }}/images"
|
||||
register: usb_images_dir
|
||||
|
||||
- name: "Import WinPE deployment content from USB (if present)"
|
||||
shell: >
|
||||
cp -rn "{{ usb_mount }}/images/{{ item }}/"* "{{ samba_share }}/{{ item }}/" 2>/dev/null || true
|
||||
loop: "{{ image_types }}"
|
||||
when: usb_images_dir.stat.exists
|
||||
|
||||
- name: "Restart and enable services"
|
||||
systemd:
|
||||
name: "{{ item }}"
|
||||
state: restarted
|
||||
enabled: yes
|
||||
loop:
|
||||
- dnsmasq
|
||||
- apache2
|
||||
- smbd
|
||||
|
||||
- name: "Allow necessary firewall ports (UFW)"
|
||||
ufw:
|
||||
rule: allow
|
||||
port: "{{ item }}"
|
||||
proto: "{{ 'udp' if item in ['67','69'] else 'tcp' }}"
|
||||
loop:
|
||||
- 67
|
||||
- 69
|
||||
- 80
|
||||
- 4433
|
||||
- 445
|
||||
- 9009
|
||||
|
||||
- name: "Enable UFW firewall"
|
||||
ufw:
|
||||
state: enabled
|
||||
policy: deny
|
||||
|
||||
- name: "Schedule dnsmasq restart 15s after reboot"
|
||||
cron:
|
||||
name: "Restart dnsmasq after reboot"
|
||||
user: root
|
||||
special_time: "reboot"
|
||||
job: "/bin/sleep 15 && /usr/bin/systemctl restart dnsmasq.service"
|
||||
|
||||
# --- Web Management App (Flask) ---
|
||||
- name: "Create webapp directory"
|
||||
file:
|
||||
path: /opt/pxe-webapp
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: "Copy webapp from USB"
|
||||
shell: >
|
||||
cp -r "{{ usb_mount }}/../webapp/"* /opt/pxe-webapp/ 2>/dev/null ||
|
||||
cp -r "{{ usb_mount }}/webapp/"* /opt/pxe-webapp/ 2>/dev/null || true
|
||||
args:
|
||||
creates: /opt/pxe-webapp/app.py
|
||||
|
||||
- name: "Create Python virtual environment for webapp"
|
||||
command: python3 -m venv /opt/pxe-webapp/venv
|
||||
args:
|
||||
creates: /opt/pxe-webapp/venv/bin/python
|
||||
|
||||
- name: "Install webapp Python dependencies (offline wheels)"
|
||||
shell: >
|
||||
/opt/pxe-webapp/venv/bin/pip install --no-index
|
||||
--find-links="{{ usb_mount }}/../pip-wheels/"
|
||||
--find-links="{{ usb_mount }}/pip-wheels/"
|
||||
-r /opt/pxe-webapp/requirements.txt 2>/dev/null ||
|
||||
/opt/pxe-webapp/venv/bin/pip install -r /opt/pxe-webapp/requirements.txt
|
||||
|
||||
- name: "Create systemd service for PXE webapp"
|
||||
copy:
|
||||
dest: /etc/systemd/system/pxe-webapp.service
|
||||
content: |
|
||||
[Unit]
|
||||
Description=PXE Server Web Management
|
||||
After=network.target apache2.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/pxe-webapp
|
||||
Environment=SAMBA_SHARE={{ samba_share }}
|
||||
Environment=CLONEZILLA_SHARE=/srv/samba/clonezilla
|
||||
Environment=WEB_ROOT={{ web_root }}
|
||||
Environment=BLANCCO_REPORTS=/srv/samba/blancco-reports
|
||||
Environment=AUDIT_LOG=/var/log/pxe-webapp-audit.log
|
||||
ExecStart=/opt/pxe-webapp/venv/bin/python app.py
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
- name: "Enable and start PXE webapp service"
|
||||
systemd:
|
||||
name: pxe-webapp
|
||||
state: started
|
||||
enabled: yes
|
||||
daemon_reload: yes
|
||||
|
||||
- name: "Configure Apache reverse proxy for webapp"
|
||||
copy:
|
||||
dest: /etc/apache2/sites-available/pxe-webapp.conf
|
||||
content: |
|
||||
<VirtualHost *:80>
|
||||
ProxyPreserveHost On
|
||||
ProxyPass /manage http://127.0.0.1:9009/
|
||||
ProxyPassReverse /manage http://127.0.0.1:9009/
|
||||
</VirtualHost>
|
||||
|
||||
- name: "Enable Apache proxy modules"
|
||||
command: a2enmod proxy proxy_http
|
||||
args:
|
||||
creates: /etc/apache2/mods-enabled/proxy.load
|
||||
|
||||
- name: "Enable webapp Apache site"
|
||||
command: a2ensite pxe-webapp.conf
|
||||
args:
|
||||
creates: /etc/apache2/sites-enabled/pxe-webapp.conf
|
||||
|
||||
- name: "Configure static IP for PXE interface"
|
||||
copy:
|
||||
dest: /etc/netplan/50-cloud-init.yaml
|
||||
backup: yes
|
||||
content: |
|
||||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
{{ pxe_iface }}:
|
||||
dhcp4: no
|
||||
addresses: [10.9.100.1/24]
|
||||
notify: "Apply netplan"
|
||||
|
||||
handlers:
|
||||
- name: "Apply netplan"
|
||||
command: netplan apply
|
||||
|
||||
Reference in New Issue
Block a user