Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ body:
attributes:
label: Версии
description: Panel, Node Agent, HAProxy и ОС ноды.
placeholder: "Panel 2.1.0, Agent 2.1.0, HAProxy 3.4, Ubuntu 24.04"
placeholder: "Panel 2.2.0, Agent 2.2.0, HAProxy 3.4, Ubuntu 24.04"
validations:
required: true
- type: textarea
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## 2.2.0 — Закрепление в пулах с резервными серверами, копирование и шаблоны маршрутов

Panel и Node Agent — 2.2.0 (код Agent не менялся), HAProxy renderer v21, миграции 000056 (`route_templates`) и 000057 (прежнее распределение старых failover-маршрутов). Заметки к релизу: [docs/releases/2.2.0.md](docs/releases/2.2.0.md). Спасибо @fesevu (#19, #20).

- **Закрепление клиентов и `leastconn` в DNS-пулах с резервным сервером** (#19). Ограничения: `leastping`/`leastconn` с tolerance > 0 в режиме с резервным сервером отклоняются; клиент, закреплённый за резервным сервером, остаётся на нём до истечения записи. Новый failover по умолчанию без закрепления; `leastping` с `source` отклоняется.
- **Копирование маршрутов между нодами** — копия создаётся выключенным черновиком (#20).
- **Библиотека шаблонов маршрутов** с `schema_version` (#20, миграция 000056).
- **Исправлено:** миграция 000057 сохраняет рендер старых failover-маршрутов — маршруты с устаревшим `source_table` один раз публикуются заново с идентичным конфигом; повторное сохранение в UI сохраняет распределение.
- Аудит `route.copy` и `route_template.*`; ошибки и имена копий/шаблонов; диалоги в стиле панели.

## 2.1.0 — Настройки HAProxy ноды и редактор конфига

Panel и Node Agent — 2.1.0, HAProxy renderer v21, миграция 000055 (`node_config_state.last_error_detail`). Заметки к релизу: [docs/releases/2.1.0.md](docs/releases/2.1.0.md). Идея и первая версия — @fesevu (#15).
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<a href="#быстрая-установка">Установка</a> ·
<a href="#обновление-с-10x">Обновление</a> ·
<a href="#скриншоты">Скриншоты</a> ·
<a href="docs/releases/2.1.0.md">Что нового в 2.1.0</a> ·
<a href="docs/releases/2.2.0.md">Что нового в 2.2.0</a> ·
<a href="../../issues">Issues</a> ·
<a href="#поддержать-проект">Поддержка</a>
</p>
Expand Down Expand Up @@ -60,10 +60,10 @@ curl -fsSL https://raw.githubusercontent.com/NodeFlow-dev/nodeflow/main/install.
2. предложит режим доступа: Caddy cookie-gate (ссылка активации ставит защищённую cookie) или без него — токен администратора Panel нужен в любом случае;
3. установит Docker и **Caddy** — Caddy сам получит сертификат Let's Encrypt и будет проксировать HTTPS на Panel, которая слушает только `127.0.0.1:8080`;
4. скачает install kit последнего релиза, проверит его по SHA-256, который GitHub публикует для каждого asset релиза, возьмёт из него `compose.release.yaml`, сгенерирует `.env`, CA, сертификат mTLS и ключ подписи обновлений в `/opt/nodeflow`;
5. выполнит `docker compose pull && docker compose up -d` с образом `ghcr.io/nodeflow-dev/nodeflow-panel:2.1.0` — на сервере ничего не собирается, миграции БД применяет сам образ;
5. выполнит `docker compose pull && docker compose up -d` с образом `ghcr.io/nodeflow-dev/nodeflow-panel:2.2.0` — на сервере ничего не собирается, миграции БД применяет сам образ;
6. опубликует подписанные релизы Node Agent (amd64 и arm64) и сохранит реквизиты входа в `~/nodeflow-credentials.txt` (права `0600`).

Файрвол установщик не меняет. Для автоматизации без вопросов передайте переменные `NODEFLOW_DOMAIN`, `NODEFLOW_AUTH_MODE=cookie|none` и при необходимости `NODEFLOW_VERSION=2.1.0` (по умолчанию — последний релиз):
Файрвол установщик не меняет. Для автоматизации без вопросов передайте переменные `NODEFLOW_DOMAIN`, `NODEFLOW_AUTH_MODE=cookie|none` и при необходимости `NODEFLOW_VERSION=2.2.0` (по умолчанию — последний релиз):

```bash
curl -fsSL https://raw.githubusercontent.com/NodeFlow-dev/nodeflow/main/install.sh \
Expand Down Expand Up @@ -92,7 +92,7 @@ sudo NODE_AGENT_TOKEN=<токен> bash install-node.sh
Команды выполняются от root (`sudo -i`): каталог `/opt/nodeflow` закрыт для остальных пользователей.

```bash
v=2.1.0
v=2.2.0
kit=NodeFlow-Panel-$v-Agent-$v-install-kit
curl -fsSLO "https://github.com/NodeFlow-dev/nodeflow/releases/download/v$v/$kit.tar.gz"
# сверьте с digest asset'а на странице релиза или в API:
Expand Down Expand Up @@ -121,7 +121,7 @@ curl -fsSL https://raw.githubusercontent.com/NodeFlow-dev/nodeflow/main/install.

Найдя `/opt/nodeflow/.env`, он работает как апгрейдер: делает `pg_dump` и архив конфигурации в `/var/backups/nodeflow/`, сохраняет `.env`, `tls/`, `pki/` и Caddy-сниппет `/etc/caddy/conf.d/nodeflow-panel.caddy`, переводит установку со сборки из исходников на образ ghcr.io, запускает миграции и проверяет, что Panel отвечает новой версией. При ошибке возвращаются прежние `compose.yaml` и `.env`; дамп БД остаётся (миграции автоматически не откатываются).

Затем в **Настройки → Node Agent** обновите ноды до 2.1.0 — updater заменит Agent атомарно и откатит его при неудачном запуске. Самообновление не меняет systemd-юнит, поэтому на нодах, установленных версиями 1.0.x, один раз добавьте права на настройку pipe-буферов ядра (без этого splice остаётся на 256 КиБ) — или переустановите Agent из меню ноды:
Затем в **Настройки → Node Agent** обновите ноды до 2.2.0 — updater заменит Agent атомарно и откатит его при неудачном запуске. Самообновление не меняет systemd-юнит, поэтому на нодах, установленных версиями 1.0.x, один раз добавьте права на настройку pipe-буферов ядра (без этого splice остаётся на 256 КиБ) — или переустановите Agent из меню ноды:

```bash
sudo install -d /etc/systemd/system/nodeflow-node-agent.service.d
Expand Down Expand Up @@ -175,7 +175,7 @@ go test ./...

## Документация

- Заметки к релизам [2.1.0](docs/releases/2.1.0.md), [2.0.1](docs/releases/2.0.1.md) и [2.0.0](docs/releases/2.0.0.md), [CHANGELOG](CHANGELOG.md)
- Заметки к релизам [2.2.0](docs/releases/2.2.0.md), [2.1.0](docs/releases/2.1.0.md), [2.0.1](docs/releases/2.0.1.md) и [2.0.0](docs/releases/2.0.0.md), [CHANGELOG](CHANGELOG.md)
- [API Panel](docs/api-contract.md)
- [Настройки HAProxy ноды и редактор конфига](docs/features/haproxy-configuration.md)
- [Архитектура](docs/architecture.md)
Expand Down
2 changes: 1 addition & 1 deletion cmd/node-agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/nodeflow/nodeflow/internal/agent"
)

var version = "2.1.0"
var version = "2.2.0"

func main() {
showVersion := flag.Bool("version", false, "print Node Agent version and exit")
Expand Down
2 changes: 1 addition & 1 deletion cmd/panel-api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (

// panelVersion is the published Panel release version. Release builds may
// replace it with -ldflags "-X main.panelVersion=...".
var panelVersion = "2.1.0"
var panelVersion = "2.2.0"

func main() {
if len(os.Args) > 1 {
Expand Down
4 changes: 2 additions & 2 deletions compose.release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ services:
<<: *hardening

migrate:
image: ghcr.io/nodeflow-dev/nodeflow-panel:${NODEFLOW_VERSION:-2.1.0}
image: ghcr.io/nodeflow-dev/nodeflow-panel:${NODEFLOW_VERSION:-2.2.0}
restart: "no"
command: ["migrate"]
depends_on:
Expand Down Expand Up @@ -79,7 +79,7 @@ services:
<<: *hardening

panel-api:
image: ghcr.io/nodeflow-dev/nodeflow-panel:${NODEFLOW_VERSION:-2.1.0}
image: ghcr.io/nodeflow-dev/nodeflow-panel:${NODEFLOW_VERSION:-2.2.0}
restart: unless-stopped
depends_on:
migrate:
Expand Down
32 changes: 28 additions & 4 deletions docs/api-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,12 +280,14 @@ keeps working.
- `pool`: all servers are active; `backup` flags are cleared. Client
distribution is selected by `balance_algorithm` and `sticky_mode` (below).
- `failover`: position order is priority. The first server is active, every
later server gets `backup`. `balance_algorithm`, `sticky_mode` and their
settings are accepted, validated and stored empty; `sticky_enabled` is
forced false. No balance directives are emitted.
later server gets `backup`. Явные `sticky_mode` (`none`, `source`,
`source_table`) и `balance_algorithm` теперь сохраняются независимо от ролей.
Без явных настроек сохраняется прежнее поведение без закрепления.
Для резерва доступны алгоритмы самого HAProxy; `leastping` и `leastconn`
с ненулевой толерантностью не поддерживаются агентом для такой топологии.
At least one server must be active.

### Client distribution (pool mode, migration 000052)
### Client distribution (pool and failover)

Two orthogonal settings. `balance_algorithm` picks the server for a **new**
client; `sticky_mode` decides whether a returning client keeps its server.
Expand Down Expand Up @@ -1064,3 +1066,25 @@ groups:
annotations:
summary: "Node {{ $labels.node }} config not in sync for 10+ min"
```

### Шаблоны и копирование маршрутов

Административные endpoints:

- `GET /api/v1/route-templates` — общая библиотека.
- `POST /api/v1/route-templates` — создать шаблон: `name`, `description` и
`config` (тело обычного POST маршрута) либо `source_node_id` + `source_route_id`.
- `GET /api/v1/route-templates/{id}` — настройки и версия шаблона.
- `PUT /api/v1/route-templates/{id}` — заменить шаблон; `name`, `description`,
`config` и обязательный `expected_version`.
- `DELETE /api/v1/route-templates/{id}` — тело с `expected_version`.
- `POST /api/v1/route-templates/{id}/apply` — `node_ids` (1–100 уникальных UUID),
`expected_version`, необязательное `name` новых маршрутов.
- `POST /api/v1/nodes/{node}/routes/{route}/copy` — `node_ids` и необязательное
`name` новых маршрутов.

Применение и копирование возвращают массив `{node_id, route}` либо
`{node_id, error}` для каждой ноды. Каждая копия создаётся самостоятельной
транзакцией и всегда выключена; публикация — отдельная операция. Повтор
запроса создаёт новые копии. Параметры и ограничения валидируются тем же
кодом, что и обычный маршрут. Runtime-состояние в шаблоне отсутствует.
2 changes: 1 addition & 1 deletion docs/brand/nodeflow-hero.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading