snapshot: preserve reliability hardening and Workdock identity pass
This commit is contained in:
@@ -14,6 +14,32 @@
|
||||
|
||||
{% include 'workflows/includes/messages.html' %}
|
||||
|
||||
<section class="card">
|
||||
<div class="toolbar">
|
||||
<div>
|
||||
<h2 style="margin:0;">{% trans "Backup-Status" %}</h2>
|
||||
<div class="hint">{{ backup_health.summary }}</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
{% if backup_health.status == 'healthy' %}
|
||||
<span class="badge sent">{{ backup_health.label }}</span>
|
||||
{% elif backup_health.status == 'stale' %}
|
||||
<span class="badge failed">{{ backup_health.label }}</span>
|
||||
{% elif backup_health.status == 'unverified' %}
|
||||
<span class="badge paused">{{ backup_health.label }}</span>
|
||||
{% else %}
|
||||
<span class="badge cancelled">{{ backup_health.label }}</span>
|
||||
{% endif %}
|
||||
{% if backup_health.bundle_name %}
|
||||
<span class="badge scheduled"><code>{{ backup_health.bundle_name }}</code></span>
|
||||
{% endif %}
|
||||
{% if backup_health.verified_at %}
|
||||
<span class="hint">{% trans "Zuletzt verifiziert:" %} {{ backup_health.verified_at|slice:":16"|cut:"T" }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<div class="toolbar">
|
||||
<div>
|
||||
@@ -27,6 +53,12 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<h2>{% trans "Automation" %}</h2>
|
||||
<div class="hint">{% trans "Für einen geplanten Verify-Run außerhalb der UI:" %}</div>
|
||||
<pre><code>docker compose exec -T web python manage.py verify_latest_backup --create-if-missing</code></pre>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<h2>{% trans "Verfügbare Backup-Bundles" %}</h2>
|
||||
{% if rows %}
|
||||
|
||||
@@ -163,7 +163,7 @@
|
||||
</section>
|
||||
</div>
|
||||
<div class="toolbar" style="margin-top:1.25rem;">
|
||||
<div class="hint">{% trans "TUBCO bleibt als Standard erhalten, bis hier Werte geändert oder Dateien hochgeladen werden." %}</div>
|
||||
<div class="hint">{% trans "Die aktuell gesetzte Deployment-Branding bleibt erhalten, bis hier Werte geändert oder Dateien hochgeladen werden." %}</div>
|
||||
<button class="btn btn-primary" type="submit">{% trans "Branding speichern" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -254,6 +254,10 @@ make backup-verify BACKUP_DIR=backups/backup_YYYYmmdd_HHMMSS</code></pre>
|
||||
<li>Remote backup target configuration is managed in <code>Integrationen → Backup-Ziel</code>.</li>
|
||||
<li>Current remote target support: <code>nextcloud</code> implemented, <code>s3</code> and <code>nfs</code> config-ready but not yet implemented.</li>
|
||||
<li>Verification is non-destructive: it restores into a temporary verification database and extracts media into a temporary directory.</li>
|
||||
<li>For scheduled operational hygiene, verify the newest bundle directly from the app container:
|
||||
<pre><code>docker compose exec -T web python manage.py verify_latest_backup --create-if-missing</code></pre>
|
||||
</li>
|
||||
<li>The Backup & Recovery page now shows whether the latest verification is current, stale, missing, or still unverified.</li>
|
||||
<li>Real restore is explicit and destructive by design:
|
||||
<pre><code>./scripts/backup_restore.sh --yes-restore backend/backups/backup_YYYYmmdd_HHMMSS</code></pre>
|
||||
</li>
|
||||
|
||||
73
backend/workflows/templates/workflows/job_monitor.html
Normal file
73
backend/workflows/templates/workflows/job_monitor.html
Normal file
@@ -0,0 +1,73 @@
|
||||
{% extends 'workflows/base_shell.html' %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block title %}{% trans "Job Monitor" %}{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'workflows/css/admin_tools.css' %}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block shell_body %}
|
||||
{% include 'workflows/includes/app_header.html' with header_show_home=1 header_show_lang=1 header_inside_shell=1 %}
|
||||
<h1>{% trans "Job Monitor" %}</h1>
|
||||
<p class="sub">{% trans "Asynchrone Aufgaben, Fehler und letzte Worker-Läufe zentral prüfen." %}</p>
|
||||
|
||||
{% include 'workflows/includes/messages.html' %}
|
||||
|
||||
<section class="card">
|
||||
<form method="get" class="app-registry-filters">
|
||||
<div class="field">
|
||||
<label for="task-filter">{% trans "Task" %}</label>
|
||||
<select id="task-filter" name="task">
|
||||
<option value="">{% trans "Alle" %}</option>
|
||||
{% for task_name in task_names %}
|
||||
<option value="{{ task_name }}" {% if task_filter == task_name %}selected{% endif %}>{{ task_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="status-filter">{% trans "Status" %}</label>
|
||||
<select id="status-filter" name="status">
|
||||
<option value="">{% trans "Alle" %}</option>
|
||||
{% for key, label in status_choices %}
|
||||
<option value="{{ key }}" {% if status_filter == key %}selected{% endif %}>{{ label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="field actions" style="align-items:end;">
|
||||
<button class="btn btn-secondary" type="submit">{% trans "Filtern" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Start" %}</th>
|
||||
<th>{% trans "Task" %}</th>
|
||||
<th>{% trans "Status" %}</th>
|
||||
<th>{% trans "Ziel" %}</th>
|
||||
<th>{% trans "Task ID" %}</th>
|
||||
<th>{% trans "Fehler" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for log in logs %}
|
||||
<tr>
|
||||
<td>{{ log.started_at|date:"d.m.Y H:i:s" }}</td>
|
||||
<td>{{ log.task_name }}</td>
|
||||
<td><span class="badge {% if log.status == 'failed' %}failed{% elif log.status == 'succeeded' %}sent{% else %}scheduled{% endif %}">{{ log.get_status_display }}</span></td>
|
||||
<td>{{ log.target_label|default:log.target_type }}</td>
|
||||
<td><code>{{ log.task_id|default:"-" }}</code></td>
|
||||
<td>{% if log.error_message %}<code>{{ log.error_message|truncatechars:180 }}</code>{% else %}-{% endif %}</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="6">{% trans "Noch keine Task-Läufe vorhanden." %}</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
@@ -207,9 +207,13 @@
|
||||
<li>Backup standard: create DB+media bundles under <code>backups/</code> and verify them with a temporary restore before using a real restore.</li>
|
||||
<li>Staff UI shortcut: Admin Apps → <code>Backup & Recovery</code> for create, verify, and delete actions.</li>
|
||||
<li>Each backup row shows both local bundle availability and remote backup state.</li>
|
||||
<li>The backup page also shows whether the latest verification is current, stale, missing, or still pending.</li>
|
||||
<li>Remote backup target configuration lives under Admin Apps → <code>Integrationen</code> → <code>Backup-Ziel</code>.</li>
|
||||
<li>Nextcloud remote backups must use a separate backup directory, not the normal onboarding/offboarding document directory.</li>
|
||||
<li>Longer-running admin actions such as backup create/verify and integration tests use the same shared progress overlay after confirmation.</li>
|
||||
<li>For scheduled verification outside the browser, run:
|
||||
<pre><code>docker compose exec -T web python manage.py verify_latest_backup --create-if-missing</code></pre>
|
||||
</li>
|
||||
<li>Brand assets such as logo and PDF letterhead are managed separately under Admin Apps → <code>Branding</code>.</li>
|
||||
<li>Trial deployments can force safe integration behavior: Nextcloud is treated as disabled and email remains in test mode while the trial restriction is active.</li>
|
||||
<li>Expired trials should be cleaned with the dedicated command, not from the browser:
|
||||
|
||||
@@ -40,9 +40,15 @@ docker compose up -d --build web worker</code></pre>
|
||||
<li>{% trans "Run tests or a targeted verification command for the changed area." %}</li>
|
||||
<li>{% trans "Compile translations after UI/content changes." %}</li>
|
||||
<li>{% trans "If dependencies changed, verify imports do not emit warnings." %}</li>
|
||||
<li>{% trans "Verify the latest backup bundle before release if operational tooling, storage, or restore behavior changed." %}</li>
|
||||
<li>{% trans "Prefer the single local release gate command so local validation matches CI." %}</li>
|
||||
</ul>
|
||||
<pre><code>docker compose exec -T web python manage.py check
|
||||
<pre><code>make release-validate
|
||||
|
||||
# individual commands if needed:
|
||||
docker compose exec -T web python manage.py check
|
||||
docker compose exec -T web python manage.py test
|
||||
docker compose exec -T web python manage.py verify_latest_backup --create-if-missing
|
||||
make i18n-compile
|
||||
docker compose exec -T web python -c "import requests"</code></pre>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user