Скачивание образов по ссылке и из каталога готовых систем было добавлено
- web/features/downloads.py: фоновая операция типа «download» — urllib по 1 МиБ,
таймаут 30 с, User-Agent Virtuality/<версия>, запись в .<имя>.part и переименование
в конце; в сообщении скорость и остаток («245 МБ из 3,1 ГБ · 12 МБ/с · осталось 4 мин»);
отмена между кусками (POST /api/operations/{id}/cancel и /downloads/{id}/cancel);
проверка схемы, имени файла, занятости имени и свободного места (Content-Length + 512 МиБ);
для каталога — проверка контрольной суммы (SHA256SUMS/SHA512SUMS/одиночный хеш),
при несовпадении файл удаляется; после ISO — virsh pool-refresh virtuality-iso,
после .img.xz — распаковка и запуск конвертации в qcow2 как при загрузке с компьютера.
- /iso и /disk-images: карточка «Скачать по ссылке», на /disk-images — «Каталог готовых
систем» для процессора сервера с пометками «Рекомендуем», «Загружен», «Скачивается»;
идущие скачивания вверху страниц с живым прогрессом (опрос раз в 2 с) и «Отменить».
- Тесты: парсер контрольных сумм, проверка ссылок и имён, загрузка с локального
http-сервера, редирект, отмена, несовпадение суммы, нехватка места, .img.xz, маршруты.
- В ветку скопированы web/core.py, web/catalog.py, presenters.format_bytes и tests/fixtures
из общей рабочей копии (без изменений), conftest подменяет run_cmd и каталоги и в core.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LEUXMcdZo7b87mjkUsPgg
Этот коммит содержится в:
@@ -584,3 +584,12 @@ details.advanced > .advanced-body { padding: 4px 16px 16px; }
|
||||
.hide-sm { display: none !important; }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }
|
||||
|
||||
/* ---------------------------------------------------------- downloads */
|
||||
.downloads { margin-bottom: 20px; }
|
||||
.download-item .download-pct { flex: none; font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; }
|
||||
.download-item[data-status="error"] .download-pct { color: var(--danger); }
|
||||
.download-item[data-status="success"] .download-pct { color: var(--success); }
|
||||
.download-error { color: var(--danger); }
|
||||
.catalog-item .meta code { padding: 1px 5px; border-radius: 5px; background: var(--surface-3); font: 12px/1.4 var(--mono); color: var(--text-2); }
|
||||
@media (max-width: 640px) { .download-item, .catalog-item { flex-wrap: wrap; } .download-item .grow, .catalog-item .grow { flex-basis: calc(100% - 50px); } }
|
||||
|
||||
Ссылка в новой задаче
Block a user