diff --git a/emmc-provisioning/dashboard/app.py b/emmc-provisioning/dashboard/app.py index 21ef57e..7e191c8 100644 --- a/emmc-provisioning/dashboard/app.py +++ b/emmc-provisioning/dashboard/app.py @@ -1636,12 +1636,15 @@ def api_build_cloudinit(): meta_data = body.get("meta_data") or DEFAULT_META_DATA network_config = body.get("network_config") or DEFAULT_NETWORK_CONFIG set_as_golden_after = bool(body.get("set_as_golden_after")) + image_name = (body.get("image_name") or "").strip()[:64] + image_name = re.sub(r"[^\w\-]", "", image_name) # only alphanumeric, underscore, dash try: BUILD_REQUEST_FILE.parent.mkdir(parents=True, exist_ok=True) with open(BUILD_REQUEST_FILE, "w") as f: json.dump({ "url": url, "variant": variant, + "image_name": image_name or None, "user_data": user_data, "meta_data": meta_data, "network_config": network_config, diff --git a/emmc-provisioning/dashboard/templates/cloudinit_build.html b/emmc-provisioning/dashboard/templates/cloudinit_build.html index 1e8b8db..174fa79 100644 --- a/emmc-provisioning/dashboard/templates/cloudinit_build.html +++ b/emmc-provisioning/dashboard/templates/cloudinit_build.html @@ -70,6 +70,11 @@ +
+ + + + date suffix +
@@ -143,7 +148,9 @@ function startBuild() { var btn = document.getElementById('buildCloudInitBtn'); if (btn) btn.disabled = true; + var nameEl = document.getElementById('buildImageName'); var body = { variant: document.getElementById('buildVariant').value, set_as_golden_after: document.getElementById('buildSetGolden').checked }; + if (nameEl && nameEl.value.trim()) body.image_name = nameEl.value.trim(); body.user_data = document.getElementById('buildUserData').value.trim(); body.meta_data = document.getElementById('buildMetaData').value.trim(); body.network_config = document.getElementById('buildNetworkConfig').value.trim(); diff --git a/emmc-provisioning/dashboard/templates/index.html b/emmc-provisioning/dashboard/templates/index.html index 045a331..fafd088 100644 --- a/emmc-provisioning/dashboard/templates/index.html +++ b/emmc-provisioning/dashboard/templates/index.html @@ -437,6 +437,11 @@ +
+ + + + date suffix (e.g. 20251204-143022) +
(use for Deploy without clicking manually) @@ -913,9 +918,11 @@ var md = document.getElementById('buildMetaData'); var nc = document.getElementById('buildNetworkConfig'); var setGolden = document.getElementById('buildSetGolden'); + var nameEl = document.getElementById('buildImageName'); var body = { variant: getBuildVariant(), set_as_golden_after: setGolden && setGolden.checked, + image_name: (nameEl && nameEl.value.trim()) ? nameEl.value.trim() : undefined, user_data: (ud && ud.value.trim()) ? ud.value.trim() : undefined, meta_data: (md && md.value.trim()) ? md.value.trim() : undefined, network_config: (nc && nc.value.trim()) ? nc.value.trim() : undefined diff --git a/emmc-provisioning/host/build-cloudinit-image.sh b/emmc-provisioning/host/build-cloudinit-image.sh index c709a59..b38999a 100644 --- a/emmc-provisioning/host/build-cloudinit-image.sh +++ b/emmc-provisioning/host/build-cloudinit-image.sh @@ -47,14 +47,24 @@ with open(f"{out}/url", "w") as f: f.write(d.get("url", "")) with open(f"{out}/set_golden", "w") as f: f.write("1" if d.get("set_as_golden_after") else "0") +name = (d.get("image_name") or "").strip()[:64] +name = "".join(c for c in name if c.isalnum() or c in "_-") +with open(f"{out}/image_name", "w") as f: + f.write(name) PY URL=$(cat "$TEMP_DIR/url") VARIANT=$(cat "$TEMP_DIR/variant") SET_AS_GOLDEN=$(cat "$TEMP_DIR/set_golden") +IMAGE_NAME="$(cat "$TEMP_DIR/image_name" 2>/dev/null || true)" [[ -n "$URL" ]] || { write_status "error" "" "" "Missing url in request"; exit 1; } -OUT_NAME="raspios-${VARIANT}-cloudinit-$(date +%Y%m%d-%H%M%S).img" +DATE_SUFFIX="$(date +%Y%m%d-%H%M%S)" +if [[ -n "$IMAGE_NAME" ]]; then + OUT_NAME="${IMAGE_NAME}-${DATE_SUFFIX}.img" +else + OUT_NAME="raspios-${VARIANT}-cloudinit-${DATE_SUFFIX}.img" +fi OUT_PATH="$OUTPUT_DIR/$OUT_NAME" BASENAME=$(basename "$URL")