feat(proxy-client): добавлены профили и системная служба

Добавлены независимые пользовательские профили, их выбор в Bash-командах и явная установка службы systemd. Инструкции размещены в README пакета.

Проверка: 67 тестов на Python 3.8 и 3.14, shell-наборы и интеграция Bash с CLI. Загрузка ОС и восстановление настоящей службы требуют отдельной проверки.
This commit is contained in:
ddadmin committed 2026-11-02 22:16:12 +01:00
1 parent b36ce50e12
commit b34eb6ac4c
9 files changed
+835 -23

No files matched your search

@@ -4,6 +4,9 @@
Статус: реализовано; 2026-09-28 упрощено по принципу ниже
Расширение от 2026-11-02:
[пользовательские профили и системная служба](2026-11-02-proxy-client-profiles-service-design.md).
Точное поведение, форматы, сообщения и команды описаны в коде,
`proxy-client --help` и [`proxy-client/README.md`](../../proxy-client/README.md).
Здесь — то, чего по коду не видно: задача, границы, выбор и его причины, риски.
@@ -0,0 +1,173 @@
# Профили proxy-client и системная служба
Дата: 2026-11-02
Статус: реализовано; запуск после загрузки ОС и восстановление настоящей
службы systemd требуют отдельной проверки на Linux-ВМ.
## Задача и границы
На Linux-ВМ, компьютерах и ноутбуках нужен прокси, доступный после загрузки
без входа пользователя и ручного запуска. Приложения уже знают его адрес.
Одновременно пользователь должен иметь возможность запустить другой прокси
на другом порту в открытом терминале.
Это расширяет [первоначальный дизайн](2026-07-15-proxy-client-design.md):
добавляет системную службу и несколько пользовательских профилей.
Остальные ограничения и принцип личного инструмента сохраняются.
Термины определены в [CONTEXT.md](../../CONTEXT.md).
Не добавляем несколько системных экземпляров, фоновый пользовательский режим,
TUN, системную маршрутизацию, автоматический выбор прокси или поддержку Windows.
Для системного режима требуется systemd; ручной режим сохраняет независимость
от него. Пакет по-прежнему можно использовать отдельно от остальных dotfiles.
## Пользовательские профили
Профиль по умолчанию сохраняет нынешние файлы
`~/.config/proxy-client/config` и `default.url`. Отсутствие выбора профиля
не меняет поведения существующих команд, включая прежний внешний прокси
при отсутствии конфигурации. Учитываются существующие настройки XDG.
Дополнительные профили размещаются в
`~/.config/proxy-client/profiles/<имя>/`, каждый со своими `config` и
`default.url`. Имя `default` обозначает существующий профиль по умолчанию.
Неизвестное имя даёт ошибку, а не переход к другому профилю.
Один общий параметр выбора профиля действует на запуск, остановку, проверку,
вывод окружения и запуск дочерних команд. Существующий выбор файла VLESS-ссылки
через `start -f` остаётся разовым переопределением ссылки выбранного профиля.
Bash-команды без явного выбора продолжают использовать профиль по умолчанию.
Каждый профиль получает собственные сведения о процессе, блокировку и
сгенерированный JSON. Запуск и остановка одного не затрагивают остальные.
Два экземпляра могут работать одновременно, если их локальные порты различны.
Занятый порт даёт ошибку; чужой процесс не останавливается.
Ручной запуск остаётся на переднем плане, с выводом в терминал и остановкой
через Ctrl+C либо команду остановки выбранного профиля. Само обращение к прокси
через `run` или `env` ничего не запускает.
## Bash-команды
`proxy_on` без параметров выбирает профиль по умолчанию, с `--profile` —
именованный. Он меняет только окружение текущего терминала после успешной
проверки. `proxy_off` очищает переменные, но не останавливает процессы.
`myip` использует текущее окружение.
`pclaude` и `pcodex` принимают ведущий `--proxy-profile` для выбора профиля.
Без него остаётся профиль по умолчанию; остальные аргументы и код возврата
дочерней программы сохраняются. Обычный `--profile` относится к дочерней
программе. Bash-модуль передаёт выбор CLI и не дублирует правила профилей.
Выбор через `proxy_on` не меняет профиль по умолчанию: обычная команда
наследует окружение, а обёртка с префиксом `p` явно выбирает свой профиль.
Это различие должно быть показано в README пакета.
## Системная служба
Одна служба `proxy-client.service` читает один комплект настроек из
`/etc/proxy-client/`. Ей не нужны именованные профили или домашний каталог
пользователя. Исполняемые файлы устанавливаются в системное расположение,
без ссылок на пользовательский каталог исходников. Xray работает под отдельной
непривилегированной учётной записью и слушает только loopback.
Временные файлы процесса, блокировка и сгенерированный JSON находятся в
закрытом `/run/proxy-client/`. Секреты доступны только администратору и
служебной учётной записи. Пользовательские команды остановки не управляют
системным экземпляром: за него отвечает systemd.
Установка оформляется подкомандой `service install`, в соответствии с
существующим интерфейсом CLI. Она размещает необходимые файлы и регистрирует
службу. Запуск сейчас и автозапуск после загрузки выбираются явно; установщик
может предоставить явные параметры для совмещения этих действий с установкой.
Точное написание параметров определяется при реализации.
Для первоначального заполнения можно скопировать выбранный пользовательский
профиль. Источник должен быть указан однозначно: повышение прав не должно
подменить его домашним каталогом root. Копия становится самостоятельной:
дальнейшие изменения домашнего профиля не меняют службу. Повторная установка
сохраняет существующие настройки и не перезапускает службу скрыто.
Systemd отвечает за запуск, остановку и перезапуск после аварии. Явная
остановка должна оставлять службу остановленной до следующего запуска.
Если автозапуск включён, после перезагрузки она запускается снова.
Отсутствие внешней сети при загрузке не должно приводить к окончательному
отказу службы. Готовность локального порта и доступность удалённого маршрута
различаются: автозапуск не гарантирует успешность первого запроса любого
приложения. Для приложений, не умеющих повторять запрос, порядок запуска и
ожидание готовности потребуют отдельной настройки.
## Журналы и совместная работа
Вывод службы направляется в journald. Отдельный текстовый журнал и собственная
ротация не нужны. Хранение между загрузками зависит от настройки journald;
установщик проверяет её и сообщает результат, не меняя глобальную политику
журналирования машины. Секреты не должны попадать в журнал.
Если системная служба занимает порт прежнего пользовательского Xray, второй
запуск на этом порту завершается ошибкой. Чтобы использовать системный прокси
через пользовательские команды, подходит профиль типа `external`. Для второго
Xray нужен другой порт. Установка службы не меняет домашний профиль молча.
## Устройство модулей
Применяем `codebase-design`: выбор профиля и все его пути должны определяться
в одном месте, чтобы команды не повторяли правила размещения файлов.
Управление процессом использует уже выбранные настройки и расположение файлов.
Системная установка скрывает размещение, права и взаимодействие с systemd
за небольшим интерфейсом; не копирует разбор VLESS и управление Xray.
Не вводим обобщённую поддержку других менеджеров служб и дополнительные
слои ради возможного будущего использования. Реально различаются
пользовательское и системное размещение, а также способ управления процессом.
## Проверки
Согласованы три интерфейса для новых тестов TDD:
1. CLI пользовательских профилей: прежнее поведение без имени, выбор
именованного профиля, два одновременных процесса, независимая остановка,
отказ при занятом порте и правильное окружение дочерней команды.
2. Установка службы через CLI и управление через systemd: размещение файлов,
сохранение настроек при повторной установке, явное включение автозапуска,
запуск и остановка, восстановление после аварии и доступность журналов.
3. Bash-команды: выбор профиля, передача аргументов и кода возврата,
сохранение окружения при ошибке и отсутствие остановки процессов.
Тесты проверяют наблюдаемое поведение через эти интерфейсы, а не внутренние
функции и последовательности их вызовов. Идём по одному сценарию:
падающий тест, минимальная реализация, следующий сценарий.
Локальные проверки используют временные каталоги, синтетические профили и
подставные внешние программы. Это не доказывает работу настоящего systemd.
Окончательная проверка системного режима нужна в отдельной Linux-среде
с systemd: запуск до входа пользователя после загрузки, восстановление после
аварии, явная остановка и одновременная работа ручного экземпляра.
Изменение текущей машины или её перезагрузка не входят в проверку по умолчанию.
Локальный набор прошёл на Python 3.8 и 3.14: 67 тестов, проверки Bash-команд
и пользовательского установщика. Дополнительно проверены Bash-команды вместе
с настоящим CLI и двумя локальными тестовыми портами. Unit прошёл статическую
проверку в изолированном корне с тестовыми базовыми target-файлами.
Shellcheck в среде отсутствует. Эти результаты не заменяют проверку загрузки ОС.
## Документация и альтернативы
Подробные инструкции размещены в
[`proxy-client/README.md`](../../proxy-client/README.md): профили, системная
установка и обновление, управление, автозапуск, журналы и диагностика.
В корневом README достаточно существующей ссылки на пакет. Этот документ
хранит причины решений; рабочие команды и примеры живут в README пакета.
Пользовательская служба с linger позволила бы запускать прокси до входа,
но выбрано явное разделение системных и домашних настроек. Несколько
именованных системных служб пока не нужны. Запуск в терминале сохраняется
для дополнительных прокси, но сам по себе не решает задачу загрузки машины.
Правила systemd сверены с документацией
[каталогов службы](https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#RuntimeDirectory=),
[перезапуска](https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html#Restart=)
и [хранения журналов](https://www.freedesktop.org/software/systemd/man/latest/journald.conf.html#Storage=).