Files
virtuality/web/templates/update.html
T
Claude c5b576dbe7 Стабильный канал обновлений был добавлен; клон и увеличение диска защищены от спящих машин
- stable (по умолчанию): обновление до последнего тега vX.Y.Z; пока релизов нет — ветка main
- main: ранний доступ, все изменения; канал берётся из web.env (Настройки → Обновления)
- scripts/update_target.sh общий для автообновления и ручного обновления, ZIP-запасной путь для тегов
- страница «Обновления» показывает канал и целевую версию
- клонирование и увеличение диска недоступны, пока машина в спящем режиме

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg
2026-09-25 15:19:19 +00:00

82 строки
5.3 KiB
HTML

{% extends "base.html" %}
{% from "_ui.html" import icon, badge, alert %}
{% set page_title = 'Обновления' %}
{% block page_header %}
<div class="page-header">
<div>
<h1>Обновления</h1>
<p class="lead">Новые возможности и исправления Virtuality. Машины продолжают работать во время обновления.</p>
</div>
</div>
{% endblock %}
{% block content %}
<section class="grid grid-main">
<div class="stack">
<article class="card {{ 'hero-card' if info.has_update else '' }}">
<div class="card-body row-between" style="align-items:center">
<div class="row" style="gap:16px;align-items:center">
<span class="empty-art" style="margin:0;width:56px;height:56px;{{ 'background:rgba(255,255,255,.14);color:#fff' if info.has_update else '' }}">{{ icon('sparkles' if info.has_update else 'shield-check', 'icon-xl') }}</span>
<div>
{% if info.has_update %}
<h2>Доступна версия {{ info.latest_version }}</h2>
<p>У вас установлена {{ info.current_version }}. {% if info.missing_versions %}Пропущено обновлений: {{ info.missing_versions|length }}.{% endif %}</p>
{% else %}
<h2>Установлена последняя версия</h2>
<p class="muted mt-1">Virtuality {{ info.current_version }} · проверено {{ info.checked_at }}</p>
{% endif %}
</div>
</div>
<div class="row">
{% if info.has_update %}
<form method="post" action="/update/apply" data-confirm="Панель перезапустится и будет недоступна около минуты. Виртуальные машины продолжат работать." data-confirm-title="Установить обновление?" data-confirm-button="Обновить" data-confirm-tone="brand" data-toast="Обновление запущено">
<button class="btn btn-lg" style="background:#fff;color:#14112e;border:0">{{ icon('download') }}Обновить</button>
</form>
{% else %}
<form method="post" action="/update/check" data-busy><button class="btn" data-busy="Проверяем…">{{ icon('refresh-cw', 'icon-sm') }}Проверить сейчас</button></form>
{% endif %}
</div>
</div>
</article>
<div class="alert info" data-update-running hidden>{{ icon('refresh-cw') }}<div><strong>Идёт обновление</strong><span data-update-state></span></div></div>
{% if not info.fetch_ok %}{{ alert('warning', 'Не удалось связаться с GitHub: ' ~ (info.fetch_error or 'нет ответа') ~ '. Проверьте доступ сервера в интернет.', 'Проверка не удалась') }}{% endif %}
<article class="card">
<div class="card-header"><div><h2>Что нового</h2><p>{{ 'Изменения, которые вы получите' if info.missing_versions else 'Последние изменения' }}</p></div></div>
{% set releases = info.missing_versions or ([current_release] if current_release else []) %}
{% if releases %}
{% for release in releases|reverse %}
<div class="release">
<div class="row-between"><div class="row"><span class="badge brand">{{ release.version }}</span><h3>{{ release.title }}</h3></div><span class="subtle small">{{ release.date }}</span></div>
<p class="muted mt-1">{{ release.summary }}</p>
<ul>{% for feature in release.features %}<li>{{ feature }}</li>{% endfor %}</ul>
</div>
{% endfor %}
{% else %}
<div class="card-body subtle">Новых изменений нет — всё уже установлено.</div>
{% endif %}
</article>
</div>
<aside class="stack">
<article class="card">
<div class="card-header"><h2>Версия</h2></div>
<div class="card-body" style="padding-top:6px;padding-bottom:6px">
<div class="summary-row"><span>Установлена</span><strong>{{ info.current_version }}</strong></div>
{% if info.has_update %}<div class="summary-row"><span>Доступна</span><strong>{{ info.latest_version }}</strong></div>{% endif %}
<div class="summary-row"><span>Канал</span><strong>{{ info.channel_label or info.branch }}</strong></div>
{% if info.target %}<div class="summary-row"><span>Обновляемся до</span><strong class="mono">{{ info.target }}</strong></div>{% endif %}
<div class="summary-row"><span></span><a class="small" href="/settings#updates">Сменить канал</a></div>
<div class="summary-row"><span>Сборка</span><strong class="mono">{{ info.current_commit[:8] if info.current_commit else '—' }}</strong></div>
</div>
</article>
<details class="advanced" {% if info.commits %}open{% endif %}>
<summary>{{ icon('terminal', 'icon-sm') }}Журнал обновления<span class="chev">{{ icon('chevron-down', 'icon-sm') }}</span></summary>
<div class="advanced-body"><pre class="terminal" style="max-height:320px" data-update-log>{{ info.log_tail or 'Журнал пока пуст.' }}</pre></div>
</details>
</aside>
</section>
{% endblock %}