{% extends "base.html" %} {% import '_ui.html' as ui %} {% block title %}Blancco releases - PXE Manager{% endblock %} {% macro mb(n) -%}{{ "%.1f"|format((n or 0) / 1048576) }} MB{%- endmacro %} {% macro prefs(r) -%}{{ r.prefs_version or '-' }}{% if r.vendor_prefs_version and r.vendor_prefs_version != r.prefs_version %} (vendor {{ r.vendor_prefs_version }}){% endif %}{%- endmacro %} {% block extra_head %} {% endblock %} {% block content %}
Updates

Blancco releases

{{ ui.chip('Live: ' ~ current.version ~ (' (installed by hand)' if current.inferred else ''), 'fail' if current.missing else 'ok') }} {% if test %}{{ ui.chip('Test entry: ' ~ (test.version or '?'), 'warn') }}{% endif %} {% set n_ready = staged | selectattr('status', 'equalto', 'ready') | list | length %} {% if staged %}{{ staged | length }} staged, {{ n_ready }} ready{% endif %}
Upload release
{# ---- Job ----------------------------------------------------------------- #} {% if job.state %}
{% if job_running %}
Staging {{ job.source or '' }}: {{ job.step or 'Starting' }} {{ job.message or '' }}
{% elif job.state == 'done' %}
Staging {{ job.source or '' }}: {{ job.message }} ({{ job.finished | local_dt }})
{% elif job.state == 'blocked' %}
Staging {{ job.source or '' }} stopped: preferences need merging. {{ job.message }} See the staged release below.
{% elif job.state == 'cancelled' %}
Staging {{ job.source or '' }} was cancelled.
{% else %}
Staging {{ job.source or '' }}: {{ job.message or 'Staging failed.' }}
{% endif %} {% if job.log %}
Job log
{{ job.log | join('\n') }}
{% endif %}
{% endif %} {# ---- Live release -------------------------------------------------------- #}

Live release

{{ current.version }}
{% if current.missing %}{{ ui.chip('Files missing', 'fail') }}{% elif current.changed_by_hand %}{{ ui.chip('Changed by hand', 'warn') }}{% else %}{{ ui.chip('Serving', 'ok') }}{% endif %}
{% if current.missing %}
Missing from the live folder: {{ current.missing | join(', ') }}
{% endif %} {% if current.changed_by_hand %}
Files changed outside this page since the last activate or roll back.
{% endif %}
Blancco kernel
{{ current.kernel or '-' }}
Preferences
{{ prefs(current) }}
Size
{{ mb(current.size) }}
Rootfs date
{{ current.rootfs_mtime | timestamp_fmt if current.rootfs_mtime else '-' }}
Installed
{% if current.activated %}{{ current.activated | local_dt }} {% if current.restored_from %}
rolled back to {{ current.restored_from }}
{% elif current.source %}
from {{ current.source }}
{% endif %} {% else %}by hand (before this page){% endif %} {% if current.inferred %}
version read from the preferences in config.img
{% endif %}
Served from {{ current.path }}.
{# ---- Staged -------------------------------------------------------------- #}

Staged releases

Next step for each: add a test entry, test-boot it from the PXE menu, then activate.
{% for s in staged %} {% set q_test = ('Add a test entry for ' ~ s.name ~ ' to the PXE boot menu' ~ (' (replacing the one for ' ~ (test.version or '?') ~ ')' if test else '') ~ '? The menu is backed up first.') %} {% set q_act = ('Make Blancco ' ~ s.name ~ ' the live release? Every Blancco boot from now on gets it. The current files (' ~ current.version ~ ') are backed up first and can be rolled back.') %}
{{ s.name }}{% if s.in_menu %}{{ ui.chip('in boot menu', 'warn') }}{% endif %} Staged {{ s.staged | local_dt }}{% if s.source %} from {{ s.source }}{% endif %} {% if s.status == 'ready' and s.in_menu %}{{ ui.chip('Ready: testing', 'ok') }} {% elif s.status == 'ready' %}{{ ui.chip('Ready to test', 'ok') }} {% elif s.status == 'blocked' %}{{ ui.chip('Needs preferences merge', 'act') }} {% elif s.status == 'failed' %}{{ ui.chip('Failed', 'err') }} {% else %}{{ ui.chip(s.status, 'neutral') }}{% endif %}
{% if s.status == 'failed' and s.error %}
{{ s.error }}
{% endif %}
Blancco kernel
{{ s.kernel or '-' }}
Preferences
{{ prefs(s) }}{% if s.merged_prefs %} (merged preferences){% endif %}
Size
{{ mb(s.size) }}
Staged
{{ s.staged | local_dt }}{% if s.source %} from {{ s.source }}{% endif %}
{% if s.status == 'ready' %}
{% if s.in_menu %}The test entry boots this release. When a test boot works, activate it.{% else %}Add a test entry, test-boot it, then activate.{% endif %}
{% endif %} {% if s.status == 'blocked' %}
{{ s.blocked }}
  1. Download the vendor preferences.xml of {{ s.name }}.
  2. Carry our settings across from playbook/blancco-preferences.xml (report share {{ server }}/blancco-reports, auto_backup, WiFi, screensaver, business location and the rest), keeping the new file's <version> block and any new settings.
  3. Upload the merged file here; staging then finishes. Commit it to the repo as playbook/blancco-preferences.xml.
{% endif %}
{% if s.status == 'ready' and not s.in_menu %}
{% elif s.status == 'ready' %}
{% endif %} {% call ui.more('staged release ' ~ s.name) %} {% if s.status == 'ready' and not s.in_menu %}
{% endif %}
{% endcall %}
{% else %}
Nothing staged. Upload a release file below, then Stage it.
{% endfor %}
{# ---- Test entry ---------------------------------------------------------- #}

Test entry in the PXE boot menu

{% if test %}
The menu has {{ test.item or 'a blancco_staged entry' }}, booting the staged {{ test.version or '?' }} from /blancco/staged/{{ test.version }}/.
{% else %}
No test entry. Add test entry on a staged release puts one under the normal Blancco entry.
{% endif %}
{% if test %}
{% endif %}
{% if test and test.efi is false %}
The entry's UEFI branch is off: when it was added, the UEFI initrd did not read blancco.base=, so a UEFI test boot would have run the LIVE release. A UEFI boot of the entry says so and returns to the menu. After rebuilding the initrd, add the test entry again.
{% endif %} {% if initrd.state == 'no' %}
The UEFI initrd {{ initrd.file or 'kexec-initrd' }} predates blancco.base=: booted, it would run the LIVE release, so a test entry added now has its UEFI branch off (legacy BIOS still works). Rebuild the initrd with the current playbook/blancco-init.sh, then add the entry again (the boot screen shows "release under test" when it works).
{% endif %}
How the test entry boots {% if initrd.state == 'yes' %}{{ ui.chip('UEFI supported', 'ok') }}{% elif initrd.state == 'no' %}{{ ui.chip('UEFI not supported', 'err') }}{% else %}{{ ui.chip('UEFI unknown', 'off') }}{% endif %}
  • Legacy BIOS: the entry boots Blancco's own kernel from the staged folder (archiso_http_srv pointed at it). Works with any initrd.
  • UEFI: the entry copies the live :blancco_efi kernel line (Ubuntu kernel, Secure Boot as the normal entry) and adds blancco.base=/blancco/staged/<version>, which the init in {{ initrd.file or 'kexec-initrd' }} must understand: {% if initrd.state == 'yes' %}supported.{% elif initrd.state == 'no' %}not supported (see above).{% else %}unknown, {{ initrd.detail }}.{% endif %}
  • Add, replace and remove edit only the test entry's lines; each edit saves GetPxeScript.aspx.bak-<time>-pre-blancco-staged* next to the menu first. Activating the version under test removes its entry.
{# ---- Release files and upload -------------------------------------------- #}

Release files

Upload the vendor ISO or USB image (about 1 GB), then Stage it.
Streamed to {{ upload_dir }}.
{% for s in sources %}
{{ s.name }} {{ s.key }} {{ mb(s.size) }} {{ s.modified | timestamp_fmt }}
{% if s.deletable %} {% call ui.more(s.name) %}
{% endcall %} {% endif %}
{% else %}
No release files yet. Upload the vendor ISO or USB image above.
{% endfor %}
Files copied in by hand are listed too, from {% for key, folder in source_dirs %}{{ folder }}{{ ', ' if not loop.last }}{% endfor %} (.iso, .img, .img.gz, .iso.gz).
{# ---- Backups (folded) ----------------------------------------------------- #}

Backups

Activating a release saves the one it replaces here. A rollback first saves what is live.
{{ ui.chip(backups | length ~ ' backup' ~ ('s' if backups | length != 1), 'neutral') }}
{% for b in backups %}
{{ b.name }} {{ b.version }} {{ b.created | local_dt if b.created is string else b.created | timestamp_fmt }}
{% if b.reason %}
{{ b.reason }}
{% endif %} {% if not b.complete %}
Incomplete, cannot be rolled back to: missing {{ b.missing | join(', ') }}
{% endif %}
Blancco kernel
{{ b.kernel or '-' }}
Preferences
{{ prefs(b) }}
Size
{{ mb(b.size) }}
{% if b.complete %}
{% else %}{{ ui.chip('Incomplete', 'off') }}{% endif %} {% call ui.more(b.name) %}
{% endcall %}
{% else %}
No backups yet. Activating a release saves the one it replaces here.
{% endfor %}
Folders {{ current.path }}/backup-*, about 1 GB each. Taking one is instant (hard links of the live files before they are replaced); the restored backup's folder is released after a rollback, because its files are the live files.
{# ---- How it works -------------------------------------------------------- #}
What a release changes

Installs a new Blancco Drive Eraser release from the vendor ISO (or the vendor's USB image, .img or .img.gz). Staging extracts the release next to the live one, applies the same changes as scripts/prepare-boot-tools.sh (our preferences written into config.img, the initramfs network patch), and a test entry in the PXE boot menu boots the staged copy. Only Activate changes what the normal Blancco entry boots, and the files it replaces are kept as a backup you can roll back to.

Replaced in {{ current.path }}: arch/x86_64/airootfs.sfs, vmlinuz-bde-linux, initramfs-bde-linux.img (copytoram network patch), intel-ucode.img, amd-ucode.img, config.img (vendor cpio with our preferences written in at the same size), preferences.xml, config-clean.xml (the licence container from config.img) and, when the ISO has one, blancco-shim.efi. Never touched: vmlinuz-ubuntu*, kexec-initrd*, kmod*.tar.gz, grubx64.efi, shimx64.efi, blancco-progress.py.

Our preferences come from the live preferences.xml (the playbook deploys playbook/blancco-preferences.xml there). They are a merge onto one vendor release's file, so when a release's <version> differs, staging stops until a merged file is uploaded. After activating such a release, commit the merged file to the repo, or the next playbook run puts the old one back.

A playbook run also copies boot-tools/blancco/* from the USB over the live files. After activating a release here, refresh that copy (scripts/prepare-boot-tools.sh with the new ISO), or a playbook run puts the old release back.

{% endblock %} {% block extra_scripts %} {% endblock %}