Proxmox VE får 'nyeste' fra værtens apt-kandidat, ny sektion med sikkerhedspakker/genstartsbehov, ntfy ved nye sikkerhedsopdateringer. _norm stripper release-præfiks (qBittorrent). Claude-Session: https://claude.ai/code/session_01AUj1LSMmrowcomkn1ciAgj
109 lines
7.0 KiB
HTML
109 lines
7.0 KiB
HTML
{# fragment — injiceres i #opscontent og pollers hvert 10s fra admin_ops.html #}
|
||
{% set updates = versions|selectattr('status','equalto','update')|list %}
|
||
{% set eol_now = versions|selectattr('eol')|selectattr('eol.state','equalto','eol')|list %}
|
||
{% set eol_soon = versions|selectattr('eol')|selectattr('eol.state','equalto','soon')|list %}
|
||
|
||
<div class="opslead" style="margin-top:1.4rem">
|
||
<h2 style="margin:0">Versioner & opdateringer</h2>
|
||
{% if updates %}<span class="vbadge update">{{ updates|length }} opdatering{{ 'er' if updates|length != 1 }} klar</span>
|
||
{% else %}<span class="vbadge ok">alt opdateret</span>{% endif %}
|
||
{% if eol_now %}<span class="vbadge eol">{{ eol_now|length }} EOL</span>{% endif %}
|
||
{% if eol_soon %}<span class="vbadge soon">{{ eol_soon|length }} EOL snart</span>{% endif %}
|
||
</div>
|
||
|
||
<table class="vtable" style="margin-top:.7rem">
|
||
<thead><tr><th>Tjeneste</th><th>Din version</th><th>Nyeste</th><th>Status</th><th>Support (EOL)</th></tr></thead>
|
||
<tbody>
|
||
{% for v in versions %}
|
||
{% set ec = v.eol.state if v.eol else 'none' %}
|
||
{% set near3 = v.eol and v.eol.state == 'soon' and v.eol.days is defined and v.eol.days < 92 %}
|
||
{% set rowclass = 'eolrow' if ec == 'eol' else ('eolsoon' if near3 else ('eolnear' if ec == 'soon' else ('updrow' if v.status == 'update' else ''))) %}
|
||
<tr class="{{ rowclass }}" data-name="{{ (v.name or '')|lower }}" data-status="{{ v.status }}" data-level="{{ v.level or '' }}" data-eol="{{ ec }}">
|
||
<td data-label="Tjeneste"><strong>{{ v.name }}</strong></td>
|
||
<td class="font-mono" data-label="Din version">{{ v.current or '—' }}</td>
|
||
<td class="font-mono muted" data-label="Nyeste">{{ v.latest or '—' }}</td>
|
||
<td data-label="Status">
|
||
{% if v.status == 'ok' %}<span class="vbadge ok">✓ opdateret</span>
|
||
{% elif v.status == 'update' %}<span class="vbadge update lvl-{{ v.level }}" title="{{ v.level or 'opdatering' }}-opdatering">↑ {{ v.level or 'opdatering' }}: {{ v.latest }}</span>
|
||
{% elif v.status == 'latest-only' %}<span class="vbadge muted" title="kender kun nyeste udgivelse">nyeste: {{ v.latest or '—' }}</span>
|
||
{% else %}<span class="vbadge muted" title="ingen kilde til nyeste version">ukendt</span>{% endif %}
|
||
</td>
|
||
<td data-label="Support (EOL)">
|
||
{% if not v.eol %}<span class="muted">—</span>
|
||
{% elif v.eol.state == 'eol' %}<span class="vbadge eol" title="cyklus {{ v.eol.cycle }} er end-of-life">⚠ EOL{% if v.eol.date %} siden {{ v.eol.date }}{% endif %}</span>
|
||
{% elif v.eol.state == 'soon' %}<span class="vbadge soon" title="cyklus {{ v.eol.cycle }} udløber snart">EOL {{ v.eol.date }}{% if v.eol.days is defined %} ({{ v.eol.days }}d){% endif %}</span>
|
||
{% else %}<span class="vbadge muted" title="cyklus {{ v.eol.cycle }} supporteret">{% if v.eol.date %}✓ til {{ v.eol.date }}{% else %}✓ supporteret{% endif %}</span>{% endif %}
|
||
{% if v.eol and v.eol.state in ('eol','soon') and v.eol.next %}<small class="nextmajor" title="anbefalet opgradering: major {{ v.eol.next.cycle }}{% if v.eol.next.eol %} (EOL {{ v.eol.next.eol }}){% endif %}">→ <strong>{{ v.eol.next.cycle }}</strong>{% if v.eol.next.latest %} ({{ v.eol.next.latest }}){% endif %}</small>{% endif %}
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
<p id="opsnomatch" class="muted" style="display:none;margin:.4rem 0">Ingen tjenester matcher filteret.</p>
|
||
|
||
{% if host %}
|
||
<h2 style="display:flex;align-items:baseline;gap:.8rem;flex-wrap:wrap">Proxmox-vært (apt)
|
||
{% if host.security %}<span class="vbadge eol">🔒 {{ host.security }} sikkerhedsopdatering{{ 'er' if host.security != 1 }}</span>
|
||
{% else %}<span class="vbadge ok">ingen sikkerhedsopdateringer</span>{% endif %}
|
||
{% if host.upgradable %}<span class="vbadge update">{{ host.upgradable }} pakker i alt</span>{% endif %}
|
||
{% if host.reboot_required %}<span class="vbadge soon" title="kører {{ host.kernel_running }}">genstart krævet{% if host.new_kernel %} (ny kerne){% endif %}</span>{% endif %}
|
||
</h2>
|
||
<p class="muted" style="margin:.2rem 0 .6rem">Kerne {{ host.kernel_running }}{% if host.new_kernel %} → {{ host.new_kernel }}{% endif %}
|
||
· apt-lister opdateret {{ (host.apt_checked or '?')|replace('T',' ') }}
|
||
· opdatér med <code>apt update && apt dist-upgrade</code> på værten</p>
|
||
{% if host.security_pkgs %}
|
||
<details><summary class="muted" style="cursor:pointer">Vis sikkerhedspakker ({{ host.security }})</summary>
|
||
<table class="vtable" style="margin-top:.5rem">
|
||
<thead><tr><th>Pakke</th><th>Installeret</th><th>Ny</th></tr></thead>
|
||
<tbody>{% for p in host.security_pkgs %}
|
||
<tr><td data-label="Pakke"><strong>{{ p.name }}</strong></td><td class="font-mono" data-label="Installeret">{{ p['from'] or '—' }}</td><td class="font-mono muted" data-label="Ny">{{ p.to }}</td></tr>
|
||
{% endfor %}</tbody>
|
||
</table></details>
|
||
{% endif %}
|
||
{% endif %}
|
||
|
||
<h2>Static-assets</h2>
|
||
<div class="stat" style="max-width:18rem">
|
||
<div class="n">{{ version if version else '—' }}</div>
|
||
<div class="muted">deployet version (assets.weircon.dk)</div>
|
||
</div>
|
||
|
||
<h2 style="display:flex;align-items:baseline;gap:.8rem">Random-proxy egress
|
||
{% if rp and not rp.error %}<span class="muted" style="font-size:.8rem;letter-spacing:0;text-transform:none">
|
||
{{ rp.available }}/{{ rp.proxies_total }} live · {{ rp.inflight_total }} inflight i alt</span>{% endif %}
|
||
</h2>
|
||
{% if rp.error %}
|
||
<div class="err">Kunne ikke nå random-proxy: {{ rp.error }}</div>
|
||
{% else %}
|
||
{% set rot = rp.rotation %}
|
||
{% if rot %}
|
||
<div class="stat" style="margin-bottom:1rem">
|
||
<div class="muted">Næste rollover</div>
|
||
<div style="margin-top:.3rem">
|
||
<strong>slot {{ rot.next_slot }}</strong>
|
||
— <span class="font-mono">{{ rot.next_egress_ip }}</span>
|
||
{% if rot.geo and rot.geo.flag %}<span title="{{ rot.geo.name }}">{{ rot.geo.flag }} {{ rot.geo.iso }}</span>{% endif %}
|
||
ruller af om <strong>{{ '%d:%02d'|format(rot.eta_sec//60, rot.eta_sec%60) }}</strong>
|
||
<span class="muted">(interval {{ rot.interval_sec }}s · sidst: slot {{ rot.last_slot }} for {{ rot.last_rotated_age_sec }}s siden)</span>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
<div class="grid" style="grid-template-columns:repeat(auto-fill,minmax(190px,1fr))">
|
||
{% for p in rp.proxies %}
|
||
<div class="slot{% if rot and p.id == rot.next_slot %} next{% endif %}">
|
||
<div class="slot-top">
|
||
<span class="slot-id">#{{ p.id }}</span>
|
||
<span class="slot-state {{ 'down' if not p.reachable else ('busy' if p.inflight else 'live') }}">
|
||
{{ '⚠ down' if not p.reachable else (p.state or 'live') }}</span>
|
||
</div>
|
||
<div class="font-mono" style="font-size:.92rem;overflow:hidden;text-overflow:ellipsis">{{ p.egress_ip or '–' }}</div>
|
||
<div class="muted" style="font-size:.84rem;margin-top:.2rem">
|
||
{% if p.geo and p.geo.flag %}{{ p.geo.flag }} {{ p.geo.iso }} · {% endif %}{{ p.inflight or 0 }} inflight
|
||
{% if p.latency_ms %}· {{ p.latency_ms }}ms{% endif %}
|
||
</div>
|
||
{% if rot and p.id == rot.next_slot %}<div class="slot-next">↻ ruller af næst</div>{% endif %}
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
{% endif %}
|