Files
pxe-server/webapp/config.py
cproudlock 04db6d6605 Generic build for other GE sites: no WJ data, one shopfloor type, Windows USB builder
Everything West Jefferson specific moved out to a separate repo
(pxe-site-wj): NTLARS/UDC/heat-treat backups keyed by WJ machine numbers,
CMM and Wax/Trace bay lists, WJ OpenText profiles, site-config.json, the
WJ preinstall list, and the WJ shopfloor PC types (Collections,
NoCollections, Common, Keyence, CMM, Genspect, HeatTreat, Wax/Trace,
Display, PartMarker) with GE-Enforce, machine numbers and the desktop
layout. The part-marker bench tools moved to their own repo. Dead
scripts removed: build-proxmox-iso, deploy-bios, sync_hardware_models,
mirror-from-gold, pull-bios, startnet-template.cmd.

Shopfloor is one generic type, gea-shopfloor-standard, with today's
timing:
- PPKG at first logon (unattend Order 10, unchanged).
- Install-AppList.ps1 runs C:\PreInstall\preinstall.json during setup.
- A new SYSTEM task, GE Shopfloor Post-PPKG, runs postppkg.json once
  after the post-PPKG reboot. It also clears AutoLogonCount after the
  ShopFloor handover (the Users-level monitor can be denied that HKLM
  write) and removes the Intune Sync task when done.
- Both lists ship empty. A site adds entries and installers.
- WinPE choice 3 goes straight to the PPKG menu. Staging, fetch and heal
  carry only the generic payload. The webapp's shopfloor sub-menu editor
  is gone, and the imaging tiles name the new stages.
- The playbook deploys the empty lists only if missing. It now deploys
  the PowerShell 7 MSI the shopfloor unattend installs, which it never
  did before.

Blancco site settings move into the webapp (Updates > Blancco releases):
business location, licensing Wi-Fi SSID and password. They are rendered
into the served preferences.xml and applied to every staged release, and
are seeded from site-vars (site_name, blancco_wifi_ssid,
blancco_wifi_password) only while none exist. The repo XML carries no
site values; the plaintext Wi-Fi password is gone from it.

New site_name and site_timezone settings: report and evidence-pack site
name, server clock and webapp time zone. No more West Jefferson defaults
in webapp/config.py or the dashboard title. Sync-BPRT.ps1 gets the
server address filled in at download instead of WJ's GE address.

USB on Windows:
- scripts/Build-PxeUsb.ps1 runs the same checks as build-usb.sh. It
  writes one FAT32 CIDATA partition (ISO files plus patched grub.cfg plus
  payload) with diskpart and reads every file back by SHA-256.
- Tested with Windows PowerShell 5.1 in the win11 VM, and the layout
  installs and first-boots in the pxetest VM.
- scripts/stage-usb-share.sh stages the build folder on a share.
- site-content/ is optional for both builders.

KB docs/kb/How_To_Deploy_PXE_Server_New_Site.html: new-site deployment,
Windows only, with a site-vars.yml guide.

Checks: webapp tests pass (5 suites); the unattend lint and playbook
syntax checks pass; every .ps1 parses; there are no WJ hosts, IPs, names
or PC types in playbook/, webapp/, scripts/ or autoinstall/.
2026-10-16 20:37:22 -04:00

101 lines
5.0 KiB
Python

"""Configuration constants for the PXE webapp.
Reads from environment variables with sensible defaults that match the
Ansible playbook's deploy paths. Also defines the canonical image type
list and shared-directory taxonomy used by the import pipeline.
"""
import os
# --- Filesystem paths --------------------------------------------------------
SAMBA_SHARE = os.environ.get("SAMBA_SHARE", "/srv/samba/winpeapps")
CLONEZILLA_SHARE = os.environ.get("CLONEZILLA_SHARE", "/srv/samba/clonezilla")
BLANCCO_REPORTS = os.environ.get("BLANCCO_REPORTS", "/srv/samba/blancco-reports")
ENROLLMENT_SHARE = os.environ.get("ENROLLMENT_SHARE", "/srv/samba/enrollment")
ENROLLMENT_PPKG_DIR = os.environ.get(
"ENROLLMENT_PPKG_DIR", os.path.join(ENROLLMENT_SHARE, "ppkgs")
)
# Our BPRT overlay scripts (repo playbook/shopfloor-setup/BPRT/), which the
# playbook syncs here with the rest of shopfloor-setup.
BPRT_OVERLAY_DIR = os.environ.get(
"BPRT_OVERLAY_DIR", os.path.join(ENROLLMENT_SHARE, "shopfloor-setup", "BPRT")
)
UPLOAD_DIR = os.environ.get("UPLOAD_DIR", "/home/pxe/image-upload")
SHARED_DIR = os.path.join(SAMBA_SHARE, "_shared")
WEB_ROOT = os.environ.get("WEB_ROOT", "/var/www/html")
BOOT_WIM = os.path.join(WEB_ROOT, "win11", "sources", "boot.wim")
AUDIT_LOG = os.environ.get("AUDIT_LOG", "/var/log/pxe-webapp-audit.log")
IMAGING_DIR = os.environ.get("IMAGING_DIR", "/var/log/pxe-imaging")
# Blancco evidence: site name stamped on reports and evidence packs, and a
# small JSON state file (cloud-upload confirmations, ServiceNow ticks) kept
# off the report share so it never shows up as a report.
BLANCCO_SITE = os.environ.get("BLANCCO_SITE", "Unnamed site")
# Every time the webapp shows (and evidence-pack month boundaries) is in
# this zone, DST included. Stored timestamps keep their own UTC offsets.
DISPLAY_TZ = os.environ.get("DISPLAY_TZ", "America/New_York")
# Hardware models seen by WinPE, checked against driver packs and BIOS.
HARDWARE_STATE = os.environ.get("HARDWARE_STATE", "/var/lib/pxe-webapp/hardware-seen.json")
BIOS_DIR = os.environ.get("BIOS_DIR", "/srv/samba/winpeapps/_shared/BIOS")
BLANCCO_STATE = os.environ.get("BLANCCO_STATE", "/var/lib/pxe-webapp/blancco-state.json")
# Clonezilla backups page settings (keep last N per machine, disk warning).
CLONEZILLA_STATE = os.environ.get("CLONEZILLA_STATE", "/var/lib/pxe-webapp/clonezilla-settings.json")
# PXE server address the Blancco preferences must point the report share at
# (blancco-init.sh greps for it too); checked when a release is staged.
BLANCCO_SERVER = os.environ.get("BLANCCO_SERVER", "172.16.9.1")
# Updates pages (Dell drivers/BIOS, iPXE): settings, staged downloads, backups.
UPDATES_DIR = os.environ.get("UPDATES_DIR", "/var/lib/pxe-webapp/updates")
TFTP_ROOT = os.environ.get("TFTP_ROOT", "/srv/tftp")
DNSMASQ_CONF = os.environ.get("DNSMASQ_CONF", "/etc/dnsmasq.conf")
# Network interfaces (Overview): the pxe-nic-check verdict file, its config,
# and dnsmasq's NIC pin (the fallback for which NIC is the imaging one).
NIC_STATUS_FILE = os.environ.get("NIC_STATUS_FILE", "/run/pxe-nic-status.json")
NIC_CONF = os.environ.get("NIC_CONF", "/etc/pxe-server/nic.conf")
DNSMASQ_NIC_CONF = os.environ.get("DNSMASQ_NIC_CONF", "/etc/dnsmasq.d/pxe-nic-only.conf")
# Log sources used by services/imaging_log_tail.py to infer client progress
# when no /imaging/status push has arrived yet. Override per-host if any of
# these live elsewhere on the live PXE server.
DNSMASQ_LEASES = os.environ.get("DNSMASQ_LEASES", "/var/lib/misc/dnsmasq.leases")
APACHE_ACCESS_LOG = os.environ.get("APACHE_ACCESS_LOG", "/var/log/apache2/access.log")
SAMBA_LOG_DIR = os.environ.get("SAMBA_LOG_DIR", "/var/log/samba")
# dnsmasq log-dhcp + TFTP requests land in syslog by default. Used to spot
# very-early boot (TFTP bootloader fetch) before Apache sees anything.
DNSMASQ_SYSLOG = os.environ.get("DNSMASQ_SYSLOG", "/var/log/syslog")
# --- Flask -------------------------------------------------------------------
FLASK_SECRET_KEY = os.environ.get("FLASK_SECRET_KEY", "pxe-manager-dev-key-change-in-prod")
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 * 1024 # 16 GB max upload
# --- Image taxonomy ----------------------------------------------------------
# Subdirs inside Deploy/ shared across ALL image types.
SHARED_DEPLOY_GLOBAL = ["Out-of-box Drivers"]
# Subdirs inside Deploy/ shared within the same image family (by prefix).
SHARED_DEPLOY_SCOPED = {
"gea-": ["Operating Systems", "Packages"],
"ge-": ["Operating Systems", "Packages"],
}
# Sibling dirs at image root shared within the same image family.
SHARED_ROOT_DIRS = {
"gea-": ["Sources"],
"ge-": ["Sources"],
}
IMAGE_TYPES = [
"gea-standard",
"gea-engineer",
"gea-shopfloor",
]
FRIENDLY_NAMES = {
"gea-standard": "GE Aerospace Standard",
"gea-engineer": "GE Aerospace Engineer",
"gea-shopfloor": "GE Aerospace Shop Floor",
}
# --- Unattend XML namespaces -------------------------------------------------
UNATTEND_NS = "urn:schemas-microsoft-com:unattend"
WCM_NS = "http://schemas.microsoft.com/WMIConfig/2002/State"
NSMAP = {None: UNATTEND_NS, "wcm": WCM_NS}