up
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
.PHONY: check build prod-build publish dev game stop venue venue-update venue-https
|
.PHONY: check build prod-build publish dev game stop venue venue-update venue-https venue-clean
|
||||||
|
|
||||||
PROD_DIR ?= prod
|
PROD_DIR ?= prod
|
||||||
|
|
||||||
@@ -33,6 +33,9 @@ game: venue
|
|||||||
stop:
|
stop:
|
||||||
docker compose -f venue/docker-compose.yml -f venue/docker-compose.https.yml --env-file venue/.env down
|
docker compose -f venue/docker-compose.yml -f venue/docker-compose.https.yml --env-file venue/.env down
|
||||||
|
|
||||||
|
venue-clean:
|
||||||
|
bash venue/clean.sh
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
@test -n "$(MSG)" || (echo 'Usage: make publish MSG="commit message"' >&2; exit 1)
|
@test -n "$(MSG)" || (echo 'Usage: make publish MSG="commit message"' >&2; exit 1)
|
||||||
@$(MAKE) build
|
@$(MAKE) build
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
make dev # разработка: локальные БД/RustFS, Go-бэкенд и Vite-фронтенд
|
make dev # разработка: локальные БД/RustFS, Go-бэкенд и Vite-фронтенд
|
||||||
make game # локальная игра: запуск venue с HTTPS из готовых артефактов
|
make game # локальная игра: запуск venue с HTTPS из готовых артефактов
|
||||||
make stop # остановка venue, данные сохраняются
|
make stop # остановка venue, данные сохраняются
|
||||||
|
make venue-clean # полное удаление данных venue без подтверждения
|
||||||
```
|
```
|
||||||
|
|
||||||
`make dev` запускает приложения в текущем терминале; `Ctrl+C` останавливает оба
|
`make dev` запускает приложения в текущем терминале; `Ctrl+C` останавливает оба
|
||||||
@@ -123,7 +124,13 @@ DNS по `http://<VENUE_BIND_IP>:<VENUE_PORT>`. Ссылки на материа
|
|||||||
make stop
|
make stop
|
||||||
```
|
```
|
||||||
|
|
||||||
Не используйте `down -v`: это удаляет данные. После изменений кода или миграций
|
Для полного сброса используйте `make venue-clean`. Команда без подтверждения
|
||||||
|
останавливает площадку и необратимо удаляет аккаунты, игры, команды, результаты
|
||||||
|
и материалы. Настройки `venue/.env`, сертификаты, настройки Cudy, сборка и
|
||||||
|
Docker-образы сохраняются; окружение разработки не затрагивается. Повторный
|
||||||
|
вызов допустим. Следующий `make venue` создаст пустую БД и организатора из `.env`.
|
||||||
|
Внешние тома БД и материалов обычный `down -v` не удаляет.
|
||||||
|
После изменений кода или миграций
|
||||||
выполните `make venue`, пока интернет доступен. Секреты, сборка,
|
выполните `make venue`, пока интернет доступен. Секреты, сборка,
|
||||||
сертификаты и пакеты игры игнорируются Git в `venue/`.
|
сертификаты и пакеты игры игнорируются Git в `venue/`.
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,15 @@
|
|||||||
|
|
||||||
Архив задач, переведённых в статус `DONE`.
|
Архив задач, переведённых в статус `DONE`.
|
||||||
|
|
||||||
|
### ED-048 — Очистка локальной площадки
|
||||||
|
|
||||||
|
- Статус: `DONE`
|
||||||
|
- Репозиторий: корневой workspace.
|
||||||
|
- Цель и результат: добавлена `make venue-clean`; без подтверждения останавливает venue, удаляет внутренние и внешние тома данных и оставляет сервер остановленным. Повторная очистка допустима; ошибки Docker не скрываются.
|
||||||
|
- Сохраняются: `.env`, сертификаты, настройки Cudy, сборка, Docker-образы и окружение разработки. Следующий `make venue` создаёт пустую БД и организатора из `.env`.
|
||||||
|
- Проверки: `python3 tests/venue/clean.py`, `bash -n venue/clean.sh`, `make -n venue-clean`, `git diff --check` — успешно. Тест проверяет порядок команд, повторный вызов, ошибки Docker, сохранность файлов и посторонних томов. Ручное ревью diff выполнено; стандарты Go/Vue неприменимы, код дочерних репозиториев не изменён.
|
||||||
|
- Не проверено: удаление реальных Docker-томов; рабочие данные не затронуты. Commit/push не выполнялись.
|
||||||
|
|
||||||
### ED-047 — Сброс локального режима и повторная подготовка пакета
|
### ED-047 — Сброс локального режима и повторная подготовка пакета
|
||||||
|
|
||||||
- Статус: `DONE`
|
- Статус: `DONE`
|
||||||
|
|||||||
+1
-1
Submodule prod updated: d21525efa4...0f3f22b3b7
@@ -217,3 +217,9 @@ Flow также проверяет переход заполненной БД с
|
|||||||
`python3 tests/venue/design_system.py`. Требуется установленный Firefox.
|
`python3 tests/venue/design_system.py`. Требуется установленный Firefox.
|
||||||
Smoke проверяет три ширины, клавиатурные вкладки, повторные карточки и ID,
|
Smoke проверяет три ширины, клавиатурные вкладки, повторные карточки и ID,
|
||||||
локальную форму и окно, состояния, темы и reduced motion.
|
локальную форму и окно, состояния, темы и reduced motion.
|
||||||
|
|
||||||
|
## Проверка очистки
|
||||||
|
|
||||||
|
`python3 tests/venue/clean.py` проверяет очистку venue с подставным Docker:
|
||||||
|
порядок команд, повторный вызов, ошибки и сохранность настроек и посторонних томов.
|
||||||
|
Реальные данные не удаляются.
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
"""Check venue cleanup using a fake Docker; never remove real data."""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
|
||||||
|
workspace = Path(__file__).resolve().parents[2]
|
||||||
|
with tempfile.TemporaryDirectory(prefix="venue-clean-") as directory:
|
||||||
|
root = Path(directory)
|
||||||
|
venue = root / "venue"
|
||||||
|
venue.mkdir()
|
||||||
|
shutil.copy(workspace / "venue/clean.sh", venue / "clean.sh")
|
||||||
|
protected = [".env", "certificates/privkey.pem", "cudy/password", "backend/app",
|
||||||
|
"frontend/dist/index.html"]
|
||||||
|
for name in protected:
|
||||||
|
path = venue / name
|
||||||
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
path.write_text("preserve me")
|
||||||
|
bin_dir = root / "bin"
|
||||||
|
bin_dir.mkdir()
|
||||||
|
docker = bin_dir / "docker"
|
||||||
|
docker.write_text('''#!/usr/bin/env python3
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
args = sys.argv[1:]
|
||||||
|
with open(os.environ["TEST_LOG"], "a") as log:
|
||||||
|
log.write(json.dumps(args) + "\\n")
|
||||||
|
if os.environ.get("TEST_FAIL") == args[0] or os.environ.get("TEST_FAIL") == " ".join(args[:2]):
|
||||||
|
sys.exit(1)
|
||||||
|
state = Path(os.environ["TEST_VOLUMES"])
|
||||||
|
names = state.read_text().splitlines()
|
||||||
|
if args[:2] == ["volume", "ls"]:
|
||||||
|
print("\\n".join(names))
|
||||||
|
elif args[:2] == ["volume", "rm"]:
|
||||||
|
assert args[2] in names
|
||||||
|
names.remove(args[2])
|
||||||
|
state.write_text("\\n".join(names))
|
||||||
|
''')
|
||||||
|
docker.chmod(0o755)
|
||||||
|
log = root / "commands"
|
||||||
|
state = root / "volumes"
|
||||||
|
targets = ["evening-detective-local_postgres_data", "evening-detective-local_rustfs_data"]
|
||||||
|
unrelated = ["dev_postgres_data", "evening-detective-local_postgres_data-backup"]
|
||||||
|
env = {**os.environ, "PATH": str(bin_dir) + os.pathsep + os.environ["PATH"],
|
||||||
|
"TEST_LOG": str(log), "TEST_VOLUMES": str(state)}
|
||||||
|
|
||||||
|
def check(fail=""):
|
||||||
|
log.write_text("")
|
||||||
|
result = subprocess.run(["bash", str(venue / "clean.sh")],
|
||||||
|
env={**env, "TEST_FAIL": fail}, capture_output=True, text=True)
|
||||||
|
assert (result.returncode == 0) == (not fail), result.stderr
|
||||||
|
for name in protected:
|
||||||
|
assert (venue / name).read_text() == "preserve me"
|
||||||
|
return [json.loads(line) for line in log.read_text().splitlines()]
|
||||||
|
|
||||||
|
state.write_text("\n".join(targets + unrelated))
|
||||||
|
commands = check()
|
||||||
|
assert commands == [
|
||||||
|
["compose", "-f", "docker-compose.yml", "-f", "docker-compose.https.yml",
|
||||||
|
"down", "--volumes", "--remove-orphans"],
|
||||||
|
["volume", "ls", "--format", "{{.Name}}"],
|
||||||
|
*[["volume", "rm", name] for name in targets],
|
||||||
|
]
|
||||||
|
assert state.read_text().splitlines() == unrelated
|
||||||
|
assert len(check()) == 2 # Repeated cleanup skips absent volumes.
|
||||||
|
state.write_text("\n".join(targets + unrelated))
|
||||||
|
assert len(check("compose")) == 1
|
||||||
|
assert len(check("volume ls")) == 2
|
||||||
|
assert len(check("volume rm")) == 3
|
||||||
|
assert state.read_text().splitlines() == targets + unrelated
|
||||||
|
|
||||||
|
print("PASS: cleanup order, repeat calls, Docker failures and preserved files/volumes")
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cd -- "$(dirname -- "${BASH_SOURCE[0]}")"
|
||||||
|
if [[ $# -ne 0 ]]; then
|
||||||
|
echo 'Используйте make venue-clean' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 'Удаление всех данных площадки: аккаунтов, игр, команд, результатов и материалов.'
|
||||||
|
docker compose -f docker-compose.yml -f docker-compose.https.yml down --volumes --remove-orphans
|
||||||
|
|
||||||
|
# Compose does not remove the external data volumes.
|
||||||
|
volumes=$(docker volume ls --format '{{.Name}}')
|
||||||
|
for volume in evening-detective-local_postgres_data evening-detective-local_rustfs_data; do
|
||||||
|
if [[ $'\n'"$volumes"$'\n' == *$'\n'"$volume"$'\n'* ]]; then
|
||||||
|
docker volume rm "$volume"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo 'Площадка очищена и остановлена. Для запуска выполните make venue.'
|
||||||
Reference in New Issue
Block a user