diff --git a/playbook/startnet.cmd b/playbook/startnet.cmd index abbf6ca..807ae5a 100644 --- a/playbook/startnet.cmd +++ b/playbook/startnet.cmd @@ -176,10 +176,23 @@ set /p enroll=Enter your choice (1-6): REM --- PPKG configuration (constructed at menu time, see docs) --- REM Vendor ships one source PPKG; we construct the BPRT-tagged filename REM by filling in Office, Region, Expiry, Version on the target copy. -REM Update SOURCE_PPKG + PPKG_VER when a new PPKG is released. -set SOURCE_PPKG=GCCH_Prod_SFLD_v4.16.ppkg -set PPKG_VER=v4.16 -set PPKG_EXP=20260831 +REM The ACTIVE ppkg is read from \\172.16.9.1\enrollment\ppkg.conf, which the +REM PXE webapp writes on upload - so a new ppkg goes live with no startnet edit. +REM The baked-in values below are only a fallback if ppkg.conf is missing. +net use Y: \\172.16.9.1\enrollment /user:pxe-upload pxe /persistent:no >nul 2>&1 +set SOURCE_PPKG= +set PPKG_VER= +set PPKG_EXP= +if exist "Y:\ppkg.conf" ( + for /f "usebackq tokens=1,* delims==" %%A in ("Y:\ppkg.conf") do ( + if /i "%%A"=="SOURCE_PPKG" set "SOURCE_PPKG=%%B" + if /i "%%A"=="PPKG_VER" set "PPKG_VER=%%B" + if /i "%%A"=="PPKG_EXP" set "PPKG_EXP=%%B" + ) +) +if "%SOURCE_PPKG%"=="" set SOURCE_PPKG=GCCH_Prod_SFLD_v4.16.ppkg +if "%PPKG_VER%"=="" set PPKG_VER=v4.16 +if "%PPKG_EXP%"=="" set PPKG_EXP=20260831 set REGION=US set OFFICE= diff --git a/webapp/app.py b/webapp/app.py index dbf5477..b12f13b 100644 --- a/webapp/app.py +++ b/webapp/app.py @@ -15,6 +15,7 @@ This file is the route surface; most logic lives in ``services/``: import hashlib import json import os +import re import shutil import tempfile import time @@ -814,6 +815,37 @@ def imaging_set_laps(serial): # Routes - Enrollment Packages # --------------------------------------------------------------------------- +PPKG_CONF = os.path.join(config.ENROLLMENT_SHARE, "ppkg.conf") + + +def read_ppkg_conf(): + """Read the active-PPKG config (SOURCE_PPKG/PPKG_VER/PPKG_EXP) that + startnet.cmd sources at boot. Returns a dict (empty if unset).""" + data = {} + if os.path.isfile(PPKG_CONF): + try: + with open(PPKG_CONF, "r", errors="replace") as fh: + for line in fh: + if "=" in line: + k, _, v = line.strip().partition("=") + data[k.strip()] = v.strip() + except OSError: + pass + return data + + +def write_ppkg_conf(source_ppkg, ppkg_ver, ppkg_exp): + """Write ppkg.conf (CRLF) so startnet.cmd picks up the active ppkg at + boot with no boot.wim edit.""" + lines = [ + f"SOURCE_PPKG={source_ppkg}", + f"PPKG_VER={ppkg_ver}", + f"PPKG_EXP={ppkg_exp}", + ] + with open(PPKG_CONF, "w", newline="\r\n") as fh: + fh.write("\n".join(lines) + "\n") + + @app.route("/enrollment") def enrollment(): packages = [] @@ -830,6 +862,7 @@ def enrollment(): return render_template( "enrollment.html", packages=packages, + active_ppkg=read_ppkg_conf(), image_types=config.IMAGE_TYPES, friendly_names=config.FRIENDLY_NAMES, ) @@ -856,6 +889,21 @@ def enrollment_upload(): f.save(dest) audit("ENROLLMENT_UPLOAD", filename) flash(f"Uploaded {filename} successfully.", "success") + + # 2b: set this ppkg active for startnet.cmd by writing ppkg.conf on the + # share (no boot.wim edit). Only for the standard GCCH_..._v.ppkg name. + m = re.search(r"_(v\d+(?:\.\d+)*)\.ppkg$", filename, re.IGNORECASE) + if m: + ver = m.group(1) + expiry = (request.form.get("expiry") or "").strip() + if not expiry: + expiry = read_ppkg_conf().get("PPKG_EXP", "") + try: + write_ppkg_conf(filename, ver, expiry) + audit("PPKG_ACTIVATE", f"{filename} ver={ver} exp={expiry}") + flash(f"Set {filename} as the active PPKG - startnet.cmd will use it.", "success") + except OSError as exc: + flash(f"Uploaded, but could not update ppkg.conf: {exc}", "warning") return redirect(url_for("enrollment")) diff --git a/webapp/templates/enrollment.html b/webapp/templates/enrollment.html index 3c66ba1..2e4f7c4 100644 --- a/webapp/templates/enrollment.html +++ b/webapp/templates/enrollment.html @@ -11,6 +11,15 @@ +{% if active_ppkg and active_ppkg.SOURCE_PPKG %} +
+ Active PPKG: {{ active_ppkg.SOURCE_PPKG }} +  {{ active_ppkg.PPKG_VER }} + {% if active_ppkg.PPKG_EXP %}exp {{ active_ppkg.PPKG_EXP }}{% endif %} + - startnet.cmd boots with this (from ppkg.conf). +
+{% endif %} +
GCCH Provisioning Packages @@ -89,9 +98,16 @@
- Use with-office.ppkg or without-office.ppkg to match the WinPE boot menu. + A standard GCCH_Prod_SFLD_v<ver>.ppkg upload is set as the active PPKG automatically + (written to ppkg.conf on the share; startnet.cmd reads it at boot - no boot.wim edit).
+
+ + +
Blank keeps the current expiry.
+