- GET /updates/: one card per updater (Dell, iPXE, Blancco, BPRT) with
its state, a Check now / Open action and details in accordions; the
shared download cap is a small popover.
- Dell applies list: one line per apply titled by its first change
('Latitude 5350 pack A11 to A12', model looked up in the maps) and
'and n more'; the chip says how many written files are unchanged since
the apply. The body lists every change, skipped item, error and file.
- dell_updates.file_status(): per file an apply wrote, unchanged /
changed / missing by content hash, the same test rollback uses.
describe(), history_view() and rollback_preview() build on it.
- GET /updates/dell/rollback/<id>: review a rollback before doing it,
with the files that would be restored and a diff of each. The POST
route is unchanged; both forms can return to the overview.
69 lines
3.7 KiB
HTML
69 lines
3.7 KiB
HTML
{% extends "base.html" %}
|
|
{% import '_ui.html' as ui %}
|
|
{% block title %}Review rollback - PXE Manager{% endblock %}
|
|
|
|
{% block extra_head %}
|
|
<style>
|
|
.rb-files { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
|
|
.rb-files li { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; justify-content: space-between;
|
|
padding: 10px 12px; border: 1px solid var(--line-2); border-radius: 8px; font-size: 13px; }
|
|
.rb-files .mono { overflow-wrap: anywhere; min-width: 0; }
|
|
.rb-diff { border: 1px solid var(--line-2); border-radius: 10px; overflow: hidden; }
|
|
.rb-diff .h { padding: 8px 12px; background: var(--surface-2); border-bottom: 1px solid var(--line-2); font-size: 13px; font-weight: 600; }
|
|
.rb-diff pre { margin: 0; max-height: 50vh; overflow: auto; font-size: 12px; line-height: 1.45; font-family: var(--font-mono); }
|
|
.rb-diff pre span { display: block; padding: 0 12px; white-space: pre-wrap; word-break: break-all; }
|
|
.rb-diff .d-add { background: var(--add-bg); color: var(--add-text); }
|
|
.rb-diff .d-del { background: var(--del-bg); color: var(--del-text); }
|
|
.rb-diff .d-hunk { color: var(--accent); background: var(--surface-2); }
|
|
.rb-diff .d-meta { color: var(--muted); }
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
{{ ui.head('Roll back the Dell apply of ' ~ (rec.at | local_dt), 'Updates', rec.title ~ ' | apply ' ~ rec.id) }}
|
|
|
|
<div class="ui-stack" style="max-width: 980px">
|
|
{% if rec.rolled_back %}
|
|
<div class="notice info">This apply was already rolled back {{ rec.rolled_back | local_dt }}.</div>
|
|
{% endif %}
|
|
|
|
<section class="panel" style="padding: 18px 22px; display: flex; flex-direction: column; gap: 12px" aria-labelledby="f-h">
|
|
<h2 id="f-h" class="sec" style="font-size: 15px">Files this apply wrote</h2>
|
|
<ul class="rb-files">
|
|
{% for f in rec.files %}
|
|
<li><span class="mono">{{ f.path }}</span>
|
|
{% if f.state == 'unchanged' %}{{ ui.chip('Unchanged since apply: will be restored', 'ok') }}
|
|
{% elif f.state == 'changed' %}{{ ui.chip('Changed since: left alone', 'off') }}
|
|
{% else %}{{ ui.chip('Missing: left alone', 'err') }}{% endif %}
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
<p class="sub" style="margin: 0">"Unchanged" means the content still matches what the apply wrote. A file changed since keeps its current content.</p>
|
|
</section>
|
|
|
|
{% for f in rec.files if f.state == 'unchanged' and f.diff %}
|
|
<div class="rb-diff">
|
|
<div class="h">{{ f.label }}: now, then after rollback</div>
|
|
<pre>{% for line in f.diff.split('\n') %}<span class="{{ 'd-meta' if line[:3] in ('---', '+++') else ('d-hunk' if line[:2] == '@@' else ('d-add' if line[:1] == '+' else ('d-del' if line[:1] == '-' else ''))) }}">{{ line or ' ' }}</span>{% endfor %}</pre>
|
|
</div>
|
|
{% endfor %}
|
|
|
|
<ul class="rb-files">
|
|
<li><span>The current files are backed up first, as <span class="mono">.bak-[timestamp]-pre-rollback</span> next to each one.</span></li>
|
|
<li><span>The new driver zips and BIOS files stay on the share, unused.</span></li>
|
|
</ul>
|
|
|
|
<div style="display: flex; flex-wrap: wrap; gap: 10px; justify-content: flex-end">
|
|
<a class="ui-btn" href="{{ url_for('updates_overview') }}">Cancel</a>
|
|
{% if rec.unchanged and not rec.rolled_back %}
|
|
<form method="post" action="{{ url_for('dell_updates.rollback') }}" style="margin: 0">
|
|
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
|
|
<input type="hidden" name="apply_id" value="{{ rec.id }}">
|
|
<input type="hidden" name="next" value="overview">
|
|
<button type="submit" class="ui-btn pri">Roll back {{ rec.unchanged }} file{{ 's' if rec.unchanged != 1 }}</button>
|
|
</form>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|