{% extends "ui/_layout.html" %}
{% block title %}Images - bty-web{% endblock %}
{% block subnav %}
{# In-page jump links: List + Activity. The Downloads / Hashes sub-sections
are gone -- their live status lives on /ui/downloads + /ui/hashing. #}
{% endblock %}
{% block intro %}
{% from "ui/_intro_box.html" import render as intro_box %}
{% call intro_box() %}
Pre-built system images bty flashes onto target disks, content-
addressed by sha256. This is the merged catalog (dir scan +
catalog entries): the header carries Fetch latest catalog
(pull the bty release catalog) and Upload catalog
(a catalog.toml). Files dropped into {{ image_root }}
are picked up and hashed automatically; per-row Fetch / Hash
buttons enqueue jobs visible on the
Downloads /
Hashing pages. Add a single image (URL or
upload) from Downloads.
{% endcall %}
{% endblock %}
{% block content %}
{# Catalog list: the operator's "what images do I have" view. Header
carries the two catalog-shape actions (Upload catalog / Fetch latest
catalog). The per-row Action column triggers fetch / hash / cache-
delete / entry-delete; results show on /ui/downloads + /ui/hashing. #}
| Name(s) | Content SHA | Format | Sources | Local copy | Action |
|---|---|---|---|---|---|
{% for n in u.names %}
{{ n }}{% if not loop.last %}, {% endif %}
{% endfor %}
|
{% if u.sha256 %} {% else %} unhashed {% endif %} | {{ u.format or "?" }} |
{% for s in u.sources %}
{% if s.kind == "local" %}
{{ s.location }}
{% elif s.kind == "url" %}
{{ s.location }}
{% else %}
{{ s.location }}
{% endif %}
{% if not loop.last %}{% endif %} {% endfor %} |
{% if u.cached %} yes {% else %} no {% endif %} |
{# All four actions always render so the column
is visually consistent row-to-row; each is
``disabled`` when its applicability gate is
false, with a tooltip explaining why. The
operator scanning the column sees the same
shape every row; what changes is which
buttons are bright vs. greyed out.
Gates by source shape:
- Fetch: has-remote AND not-cached (bytes
need to land locally).
- Update: has-remote AND cached (re-pull
the upstream bytes; rolling oras tags).
- Cache delete: has-remote AND cached (drop
the local copy; entry stays).
- Entry delete: has-remote (remove the
catalog row entirely). Local-only uploads
aren't deletable here -- the operator
manages those via the filesystem.
Hashing has no manual button: every path
that lands bytes in image_root (PUT
/images, lifespan auto-import, DownloadManager
fetch) already auto-enqueues / computes the
sha. The only state a manual Hash would
help is an operator dropping a file via
SSH/scp at runtime; that's a rare-enough
workflow that "restart bty-web" is the
accepted answer. /ui/hashing still shows
background hash progress driven by the
auto-import sweep. #}
{% set has_remote = u.sources|selectattr('kind','in',['manifest','url'])|list|length > 0 %}
{% set entry_src = u.sources|selectattr('kind','in',['manifest','url'])|map(attribute='location')|first %}
{% set fetch_on = has_remote and not u.cached %}
{% set update_on = has_remote and u.cached %}
{% set cache_del_on = has_remote and u.cached %}
{% set entry_del_on = has_remote %}
|
No images yet. Use Fetch latest or
Upload catalog above, drop a
.qcow2 / .img /
.img.zst / .img.xz /
.img.gz / .img.bz2 file into
{{ image_root }}, or add one via the
Add image card below.
| |||||