Share accounts: an older live Blancco release warns instead of failing

A fresh server gets boot-tools/blancco from the USB, which can be an older
Blancco (7.15.1) than our preferences (7.20). The version guard refused to
patch its config.img and the exception failed the whole share apply, so the
first-boot playbook failed. refresh_live_prefs() now returns a warning for
config.img and still writes the served preferences.xml (UEFI path).
This commit is contained in:
cproudlock
2026-10-17 12:40:00 -04:00
parent 7572692b84
commit c2b0c3d35e
4 changed files with 37 additions and 7 deletions

View File

@@ -991,9 +991,13 @@ def apply_prefs(version):
def refresh_live_prefs():
"""Re-render the served preferences.xml (site settings, share login)
and write the same preferences into the live config.img, which the
BIOS (native) boot path reads instead. Returns True if a file changed.
release.json keeps describing the release when it did before."""
BIOS (native) boot path reads instead. Returns (changed, warning):
warning is set when config.img could not take them (a release older
than our preferences, see check_prefs); the served file, which the
UEFI path uses, is written regardless. release.json keeps describing
the release when it did before."""
from services import blancco_prefs
warning = None
with _lock:
root = blancco_root()
meta_path = os.path.join(root, "release.json")
@@ -1005,13 +1009,18 @@ def refresh_live_prefs():
if cfg is not None:
with open(blancco_prefs.served_prefs_path(), "rb") as f:
ours = f.read()
new = patch_config_img(cfg, ours)
try:
new = patch_config_img(cfg, ours)
except (StageBlocked, ValueError) as e:
warning = (f"the live config.img (BIOS boot) was not updated: {e} "
"Stage a current release on Updates > Blancco releases.")
new = cfg
if new != cfg:
_atomic_write(cfg_path, new)
changed = True
if changed and meta_ok:
_write_live_meta(meta)
return changed
return changed, warning
def save_merged_prefs(version, data):

View File

@@ -177,7 +177,9 @@ def _apply_menu(password):
def _apply_blancco():
from services import blancco_update as bu
return "Blancco preferences: " + ("updated" if bu.refresh_live_prefs() else "unchanged")
changed, warning = bu.refresh_live_prefs()
out = "Blancco preferences: " + ("updated" if changed else "unchanged")
return out + (f" (WARNING: {warning})" if warning else "")
def apply(only=None, values=None):

View File

@@ -179,6 +179,23 @@ class ShareAccounts(Fixture):
with open(BP.repo_prefs_path(), "rb") as f:
self.assertEqual(self.prefs_share_pw(BP.apply(f.read())), PW)
def test_older_live_release_warns_instead_of_failing(self):
# A config.img from an older Blancco than our preferences (the repo
# payload can lag): the version guard refuses it. The served
# preferences (UEFI path) still change; the change is not refused.
old = cpio_file(self.cfg, "preferences.xml").replace(
b"<major>20</major>", b"<major>15</major>", 1)
self.assertIn(b"<major>15</major>", old)
cfg = newc({"report.key": b"KEY", "preferences.xml": old, "config.xml": b"<c/>"})
with open(os.path.join(BU.blancco_root(), "config.img"), "wb") as f:
f.write(cfg)
done = SA.set_password("blancco", PW)
self.assertTrue(any("WARNING" in d and "config.img" in d for d in done), done)
with open(BP.served_prefs_path(), "rb") as f:
self.assertEqual(self.prefs_share_pw(f.read()), PW)
with open(os.path.join(BU.blancco_root(), "config.img"), "rb") as f:
self.assertEqual(f.read(), cfg) # left as it was
def test_apply_is_idempotent(self):
SA.set_password("pxe-upload", PW)
SA.set_password("clonezilla", PW + "x")

View File

@@ -53,8 +53,8 @@ def site_settings():
request.form.get("wifi_ssid", ""),
request.form.get("wifi_password", ""))
# Served preferences.xml and the live config.img (BIOS path).
changed = bu.refresh_live_prefs()
except (OSError, ValueError, bu.StageBlocked) as e:
changed, warning = bu.refresh_live_prefs()
except (OSError, ValueError) as e:
flash(f"Blancco site settings not saved: {e}", "danger")
return _back()
s = blancco_prefs.public()
@@ -62,6 +62,8 @@ def site_settings():
f"password={'set' if s['wifi_password_set'] else 'empty'}")
flash("Blancco site settings saved" + (" and preferences.xml updated." if changed else " (no change)."),
"success")
if warning:
flash(f"Blancco: {warning}", "warning")
return _back()