{% extends "layout.html" %} {% from "_partials/recent_events.html" import recent_events_card %} {% from "_partials/page_description.html" import page_description %} {% block title %}Overlays - pixie{% endblock %} {# State -> badge. Kept as a macro so the server render + the live- refresh JS below agree on colour + label for every state. #} {% macro state_badge(state) %} {% if state == 'serving' %}Serving {% elif state == 'held' %}Held {% elif state == 'free' %}Free {% elif state == 'orphaned' %}Orphaned {% elif state == 'pending' %}Pending {% else %}File missing{% endif %} {% endmacro %} {% block subnav %} {% endblock %} {% block content %} {{ page_description('layers', 'Persistent named qcow2 overlays for the nbdboot-overlay mode. Each overlay is a globally-unique writable volume over one catalog base image, single-writer: at most one machine holds it at a time. This is where overlays are created: a machine only ever SELECTS an existing overlay, it never creates one. The disk-used + last-modified columns refresh every 5 s while the page is open. Create provisions the overlay at a chosen size (bigger than the small base image, thin until written) so the target has room to install into. Per overlay, Manage grows the disk and takes/reverts/deletes qcow2 snapshots; both act on the qcow2 offline, so unbind the overlay first. Delete removes an overlay entirely; Prune reclaims overlays whose file is gone or whose holder pixie no longer tracks.') }} {# ---- Summary strip ------------------------------------------------- Fleet-wide roll-up. The numbers poll live alongside the table so an operator watching an overlay grow sees the total tick without a reload. Prune sits with the reclaimable tile it acts on. #}
Overlays
{{ totals.count }}
Disk used
{{ totals.used_bytes | humanize_bytes }}
Serving now
{{ totals.running }}
{{ totals.active }} back a current binding
Reclaimable
{{ totals.reclaimable }} ({{ totals.reclaimable_bytes | humanize_bytes }})
{# ---- Create --------------------------------------------------------- The one place an overlay comes into being. Materializes the qcow2 over a fetched base image up front, so the machine bind form only ever selects an existing overlay (never conjures one). #}
Create overlay
{% if base_images %}
The overlay is a writable qcow2 layered over the base image; writes survive reboots. Size provisions a bigger root than the (small) base image so the target has room to install into -- the space is thin until written, and the target claims it via resize2fs on its next nbdboot. Once created it shows as Free below and can be attached to a machine via the nbdboot-overlay boot mode.
{% else %}

No fetched images to layer over. Fetch a disk image on the Catalog first, then create an overlay here.

{% endif %}
Overlays
{% if overlays %}
{% for ov in overlays %} {# ---- Manage panel (grow + snapshots) -------------------- Collapsed by default. Both operate on the qcow2 with qemu-img offline, so they are only offered for an unbound overlay -- a bound one shows how to release it. id keys on loop.index (aliases may contain '.', which would break the collapse target's CSS selector). #} {% endfor %}
State Alias Base image Attached to Used / size Last modified Created Last boot NBD Actions
{{ state_badge(ov.state) }} {{ ov.alias }} {% if ov.image_name %} {{ ov.image_name }} {% else %} {{ ov.image_sha[:12] }} {% endif %} {% if ov.base_bytes %}
over {{ ov.base_bytes | humanize_bytes }} base
{% endif %}
{% if ov.attached_mac %} {{ ov.attached_mac }} {% if not ov.machine_exists %} unregistered {% endif %} {% if ov.machine_labels %}
{% for lbl in ov.machine_labels %} {{ lbl }} {% endfor %}
{% endif %} {% else %} free {% endif %}
{% if ov.file_exists %} {{ ov.used_bytes | humanize_bytes }} {% else %} - {% endif %} {% if ov.size_bytes %}/ {{ ov.size_bytes | humanize_bytes }}{% endif %} {{ ov.mtime | fmt_ts if ov.mtime else '-' }} {{ ov.created_at | fmt_ts }} {{ ov.last_boot_at | fmt_ts if ov.last_boot_at else '-' }} {% if ov.running %} :{{ ov.nbd_port }} {% else %} idle {% endif %}
{% if ov.attached_mac %}
Bound to {{ ov.attached_mac }}. Grow and snapshot operate on the qcow2 offline, so set that machine to another boot mode (unbind) first, then reopen this panel.
{% else %}
{# Grow #}
Grow
Currently {{ ov.size_bytes | humanize_bytes }}. Grow-only; takes effect on the target's next nbdboot.
{# Snapshots #}
Snapshots
{% if ov.snapshots %}
{% for s in ov.snapshots %} {% endfor %}
Name Taken Actions
{{ s.name }} {{ s.when | fmt_ts if s.when else '-' }}
{% else %}

No snapshots yet.

{% endif %}
{% endif %}
{% else %}

No overlays yet. Use the Create overlay form above to make one, then attach it to a machine via the nbdboot-overlay boot mode.

{% endif %}
{{ recent_events_card(overlay_events, 'overlay', empty_message='No overlay events yet.') }}
{% endblock %}