# Site Customization The PXE server in this repo was built for the GE Aerospace West Jefferson site. To stand it up at another site, several values need to change. This document lists every site-specific value, where it lives today, and the recommended forward state. ## Status The repo has not yet been parameterized. As of 2026-04-14 the site-specific values below are hardcoded in multiple files. The `config/` directory at the repo root is a placeholder for the future state where one YAML file drives substitution at build time. Until that exists, customizing for a new site means editing the source files directly. If you are bringing up the first non-WJ site, expect to do this manually and contribute a `config/sites/.yaml` template back to the repo. ## Values to change ### Network Every server has two NICs: the imaging NIC (isolated imaging LAN, static 172.16.9.1, the only NIC that serves DHCP/TFTP/HTTP boot/SMB) and the GE corporate NIC (DHCP client; SSH and the webapp on 9009 only). Put both MACs in `playbook/site-vars.yml` (copy `playbook/site-vars.example.yml`) before building the USB: `pxe_nic_mac`, `corp_nic_mac`. The installer brings the network up with DHCP only; the first-boot playbook stops before changing anything if either MAC is unset or missing, then pins both NICs by MAC in netplan (names `pxe0` / `corp0`, overridable), dnsmasq, UFW and Samba. | Value | Default | Where it lives | |-------------------|----------------------|--------------------------------------------------------------------------------| | PXE server IP | 172.16.9.1 | `playbook/pxe_server_setup.yml` (dnsmasq config, iPXE script, samba conf, webapp env), `playbook/startnet.cmd` (mount paths), `boot-tools/blancco/grub-blancco.cfg` (TFTP/HTTP URLs) | | PXE subnet | 172.16.9.0/24 | Same as above, plus `playbook/pxe_server_setup.yml` (UFW rules) | | DHCP range | 172.16.9.10-100 | `playbook/site-vars.yml` (`pxe_dhcp_start`, `pxe_dhcp_end`) | | NIC MACs / names | (required) / pxe0, corp0 | `playbook/site-vars.yml` (`pxe_nic_mac`, `corp_nic_mac`, `pxe_nic_name`, `corp_nic_name`) | | Hostname | pxeserver | `autoinstall/user-data` (identity.hostname) | ### Access from the GE corporate network SSH (password auth, the shared `pxe` password) and the webapp on 9009 (no login, runs as root) are reachable on the corp NIC. By default from ALL of GE, as before, so a re-run never locks anyone out; the play prints a loud warning on every run while that is so. Set these in `playbook/site-vars.yml`: | Var | Default | Effect | |--------------------------|---------|--------| | `corp_admin_cidrs` | `[]` | List of admin subnets/hosts, e.g. `["10.134.48.0/24", "3.12.34.56/32"]`. When non-empty, UFW allows 22 and 9009 on `corp_nic_name` from these only and drops the any-source rules. The play refuses (nothing changed) if an entry is invalid or your own SSH session is not inside one of them. The imaging NIC keeps its rules. | | `corp_ssh_password_auth` | `true` | `false` adds `/etc/ssh/sshd_config.d/10-pxe-corp-auth.conf`: `PasswordAuthentication no`, re-allowed by a `Match Address` block for `pxe_subnet` and localhost. Keys only from GE. The play refuses while `pxe` has no `~/.ssh/authorized_keys`, and removes the drop-in again if `sshd -t` rejects it. | | `allow_disruptive` | `false` | Re-runs while imaging is active (SMB sessions on 445, or DHCP leases granted in the last `pxe_busy_window_min` = 30 min) do not bounce the NICs or restart dnsmasq/Apache/Samba; a needed network change stops the play. `-e allow_disruptive=true` overrides. | Recommended for a production box: `corp_admin_cidrs` set to the admin desks' subnet, then (after `ssh-copy-id`) `corp_ssh_password_auth: false`. ### Re-running the playbook over SSH (from the GE side) The network step refuses before changing anything when the NIC that `pxe_nic_mac` names holds the default route, a DHCP lease, or the route to your SSH client (swapped MACs or cables). When it does apply, it arms a 120 s auto-revert timer (`pxe-netplan-revert-*`), checks both names, the imaging address and that the corp NIC gets its IPv4 back within 30 s, and restores the previous netplan config AND NIC names on any failure. Backups: `/var/backups/netplan-/`. ### Identity and credentials | Value | Default | Where it lives | |-----------------------------|---------------------------------------|---------------------------------------------------------| | Linux user | pxe / pxe | `autoinstall/user-data` (identity.username, password hash) | | Samba upload user | pxe-upload / pxe | `playbook/pxe_server_setup.yml` (Samba user creation) | | Samba blancco user | blancco / blancco | `playbook/pxe_server_setup.yml` | | Sudo password | pxe | autoinstall password hash; also referenced in scripts that ssh + sudo | ### WiFi and BMC (Blancco licensing) The Blancco custom `config.img` carries WiFi credentials and BMC cloud credentials in plaintext. These are GE-Aerospace specific. | Value | Default | Where it lives | |---------------|----------------------|-------------------------------------------------------------------------| | WiFi SSID | INTERNETACCESS | `boot-tools/blancco/config.img` (inside the cpio archive: preferences.xml) | | WiFi password | Acc3ssGr@nted22 | Same | | BMC endpoint | classic.eu-west-1.blancco.cloud:443 | Same; encrypted credentials inside config.img | To rebuild `config.img` for a different site, see BLANCCO.md ("Rebuilding config.img"). ### Image types The repo defines seven image types (see `playbook/pxe_server_setup.yml`, `image_types`). Most sites likely only need a subset. The current set: - gea-standard - gea-engineer - gea-shopfloor - ge-standard - ge-engineer - ge-shopfloor-lockdown - ge-shopfloor-mce Trim or extend this list and the matching `shopfloor_types` filter as needed. ### Engineering Layer (gea-engineer) Handled by the repo; nothing to work out per site except the payload. - `playbook/engineering/Install-EngineeringLayer.ps1` is deployed by the playbook to `gea-engineer/Deploy/Applications/extra_engineering/`. - `FlatUnattendW10-engineer.xml` runs it twice: - specialize Order 37 (`-StageOnly`) copies the payload and the script to `C:\PreInstall\engineering` while `C:\Deploy` exists; - first logon Order 11 installs from that copy. The bulk-enrollment `DeleteDeployDir` task removes `C:\Deploy` on the next boot, so a PC that reboots before the employee signs in would otherwise install nothing and show no icon. - After the install it makes sure the "Configure my Engineering Layer" icon is on the Public desktop (until the PC is configured), and registers Active Setup so a later user gets the icon if someone else already used it. The employee clicks it once, on the GE network: it maps V: and runs `install_local_new.cmd` from GE's share, which removes the icon. - Log on the PC: `C:\Logs\Engineering\install-engineering-layer.log`. The site supplies the payload beside the script, in `gea-engineer/Deploy/Applications/extra_engineering/`: `engineering_layer/Engineering_Install_v3.1.exe` and `prereqs/` (.NET 3.5 sxs cabs, VC++ redists), about 650 MB. ### PC types (shopfloor sub-types) `playbook/shopfloor-setup/` contains per-PC-type install logic. The current types reflect WJ shopfloor needs: - CMM (PC-DMIS) - WaxAndTrace - Keyence - Genspect - Display (Lobby and Dashboard variants) - Standard (Timeclock and Machine variants) - Lab A site without CMMs can drop the CMM type and its installers entirely. ### GCCH bulk-enrollment PPKGs PPKG filenames are baked into `playbook/startnet.cmd` and `startnet-template.cmd`. They are tied to the GE Aerospace tenant. Other sites/tenants will have their own PPKGs with different filenames. | PPKG enrollment menu choice | Default filename | |-----------------------------|---------------------------------------------------------------| | 1 NoOffice | GCCH_Prod_SFLD_NoOffice_US_Exp_20260430_v4.10.ppkg | | 2 StdOffice x86 | GCCH_Prod_SFLD_StdOffice-x86_US_Exp_20260430_v4.10.ppkg | | 3 StdOffice x64 | GCCH_Prod_SFLD_StdOffice-x64_US_Exp_20260430_v4.10.ppkg | | 4 ProPlusOffice x86 | GCCH_Prod_SFLD_ProPlusOffice-x86_US_Exp_20260430_v4.10.ppkg | | 5 ProPlusOffice x64 | GCCH_Prod_SFLD_ProPlusOffice-x64_US_Exp_20260430_v4.10.ppkg | When you bump PPKG versions, update the filenames in startnet.cmd, drop the new PPKGs in `enrollment/` on the workstation, and rebuild the USB. ### Site-specific shopfloor config `playbook/shopfloor-setup/site-config.json` has site-specific values like default machine number ranges, share paths for software, and more. Inspect that file for site name strings, share UNC paths, and machine number ranges. ### Branding The Flask webapp uses GE Aerospace branding: - Logo: `webapp/static/ge-aerospace-logo.svg` - Favicon: `webapp/static/favicon.ico` - Page titles and templates reference "GE Aerospace" in `webapp/templates/*.html` - iPXE menu title: "GE Aerospace PXE Boot Menu" in `playbook/pxe_server_setup.yml` ### Drivers (Dell) Driver content is hardware-specific, not strictly site-specific, but the set of driver families to bundle changes by what hardware the site deploys: - `Dell_11/Pro` and `Dell_11/ProMax`: Dell Pro Micro PCs (most common shopfloor) - `Dell_11/Optiplex`: traditional desktops - `Dell_11/Precision`: workstations - `Dell_11/Latitude`: laptops (large, often excluded if site has none) The `scripts/download-drivers.py` and `scripts/Download-Drivers.ps1` scripts populate `drivers-staging/` from upstream sources. Edit these to target the relevant hardware lists. ### BIOS update manifest `playbook/shopfloor-setup/BIOS/models.txt` maps Dell model strings to the BIOS .exe to flash. Update this whenever new hardware arrives or Dell publishes a new firmware release for a model already in the fleet. ### Intune DSC categories The post-enrollment Intune DSC delivery (per `intune-dsc.md` memory) pulls per-category YAML from Azure Blob: - main - cmm - displaypcs - waxtrace Different sites/tenants will need their own categories and their own Azure Blob storage account. ### Image-upload paths on Windows `scripts/Upload-Image.ps1` defaults to: - `\\172.16.9.1\image-upload` as the destination - `C:\ProgramData\GEAerospace\MediaCreator\Cache\` as the source Update both for a different site (`-Server`, `-CachePath`; `-WebPort` if the webapp is not on 9009). The script checks every file on the server through the webapp before the Image Import page will accept the upload. ## Recommended forward state A site config file should drive substitution at build time. Proposed schema: ```yaml # config/sites/.yaml site: name: westjeff pxe_server_ip: 172.16.9.1 pxe_subnet: 172.16.9.0/24 dhcp_range_start: 172.16.9.10 dhcp_range_end: 172.16.9.100 hostname: pxeserver credentials: pxe_user: pxe pxe_password: pxe pxe_upload_password: pxe blancco_password: blancco blancco: wifi_ssid: INTERNETACCESS wifi_password: Acc3ssGr@nted22 bmc_endpoint: classic.eu-west-1.blancco.cloud:443 ppkg_versions: current: v4.10 expiry: 20260430 intune_dsc_categories: [main, cmm, displaypcs, waxtrace] image_types: [gea-standard, gea-engineer, gea-shopfloor] shopfloor_types: [gea-shopfloor] ``` `scripts/build-usb.sh` and the playbook would consume this and substitute into the templated config files. Implementing this is a separate piece of work; until then, edit source files directly. ## Secrets handling Some values above are sensitive (WiFi passwords, BMC credentials, Samba passwords). Today these sit in plain text in the repo. For a multi-site deployment, treat them as per-site secrets: - Keep `config/sites/.secrets.yaml` out of git (gitignore). - Distribute via secure channel (1Password, Vault, etc.) when standing up a new site. - The `eMxInfo.txt` precedent (see `feedback_emxinfo_secret.md`) is a good template: never commit, document where the canonical copy lives.