[--execute]`: dry run по умолчанию, local ↔ S3 и S3 ↔ S3 без удаления source. - Последовательное копирование с проверкой размера и полным SHA-256 readback destination; конфликтующий объект не перезаписывается. Временный диск — максимум один переносимый файл дополнительно к постоянному destination. - Durable migration journal позволяет продолжить прерванную операцию с теми же конфигурациями. Незавершённый или повреждённый journal блокирует startup; backend identity меняется только после проверки всех файлов. - Native `uploads`/`upload_stats`, slots и JWT сохраняются; поддерживаются native локальные файлы без Rust completion sidecar. Миграция требует остановки RustXMPP и Prosody, использующих общий `data_path`. - Multipart intent сохраняется до создания удалённого upload. Recovery находит потерянный UploadId через paginated listing и очищает только точный key принадлежащего slot. При сохранных metadata cleanup не зависит от lifecycle; lifecycle остаётся дополнительной защитой, а не гарантией. - Перед completion сохраняется durable marker. Неопределённый результат completion при отсутствии подтверждённого объекта помещает только этот slot в quarantine: PUT 409, retention не удаляет его, maintenance повторяет сверку. Startup продолжается; сохраняется single-use семантика. - Добавлены network regressions миграции и расширены проверки multipart recovery, потерянных ответов, отмены запросов и конфликтов destination. Настройка, команды миграции, recovery и ограничения отката: [docs/HTTP-UPLOAD.md](docs/HTTP-UPLOAD.md). Команды, результаты и границы подтверждения, включая qualification реального object store и 10 GiB: [docs/VALIDATION-0.7.9.md](docs/VALIDATION-0.7.9.md). Итог: 265 тестов, нагрузка 500 TLS клиентов и native reference — успешно. Реальные 10 GiB через MinIO (описанный test adapter), 1280parts и полный SHA-256 пройдены; подробности — [VALIDATION-0.7.9](docs/VALIDATION-0.7.9.md).
14 KiB
Rust XMPP 0.7.9
Сервер на Rust, разрабатываемый для замены Prosody 13.0 nightly 100, cafd74b9c5ea с предоставленными модулями. Читает существующий Lua-конфиг, а также JSON, YAML/YML и TOML. Использует внутреннее файловое хранилище Prosody: конвертация аккаунтов и истории для проверенных сценариев не нужна. Nginx не требуется: HTTPS, WebSocket, BOSH и загрузка файлов обслуживаются самим сервером; coturn остаётся отдельным сервисом.
Это работающая экспериментальная реализация, полная взаимозаменяемость ещё не достигнута. Уже реализованы вход, сообщения, контакты, MAM, MUC, PEP/pubsub, закладки, offline, carbons, SM, push, TLS-федерация и HTTP. Точные ограничения перечислены в docs/COMPATIBILITY.md, проверки — в docs/VALIDATION.md.
Нестандартные HTTP-пути и TLS reverse proxy: docs/HTTP-PROXY.md.
Пример для слияния с действующим конфигом: examples/reverse-proxy.fragment.yaml.
MUC-расширения и условия восстановления участников: docs/MUC-RECOVERY.md.
Встроенный http_altconnect: docs/HTTP-ALTCONNECT.md.
Сборка и изолированный запуск
Нужны Rust 1.99.1 (rustup установит версию из rust-toolchain.toml),
C-компилятор и make. Для тестовых сертификатов и сетевых проверок нужны
OpenSSL CLI, Bash и Python 3; HTTP-тест дополнительно использует Python websockets.
Системные CA-сертификаты нужны для проверки удалённых серверов федерации.
Cargo.lock фиксирует зависимости; первая сборка требует их загрузки.
cd rust-xmpp
cargo build --release --locked
bash scripts/make-demo.sh
./target/release/rust-xmpp serve demo/config.toml --experimental
Demo слушает только 127.0.0.1:55222 и создаёт отдельное хранилище demo/data.
Аккаунты: alice@localhost / alice-test-only и
bob@localhost / bob-test-only. Для ручного клиента используйте STARTTLS
и доверьте сгенерированному demo/cert.pem. make-demo.sh не перезаписывает
существующий demo. Сертификаты и аккаунты в исходный архив не включены.
Существующий конфиг без редактирования
./target/release/rust-xmpp check-config /etc/prosody/prosody.cfg.lua
./target/release/rust-xmpp serve /etc/prosody/prosody.cfg.lua --experimental
check-config проверяет разбор и базовые типы; ограничения runtime проверяются
при serve. Существующий Lua-файл читается непосредственно, преобразовывать
его в другой формат не требуется. Процессу нужны права на сертификат, ключ,
каталог данных и Unix admin socket. Используйте тот же UID/GID, что и Prosody,
чтобы сохранять доступ при возврате к нему.
Первую проверку выполняйте на копии данных с отдельными портами: сервер пишет аккаунты, историю, комнаты и другие данные в обычном режиме. Одновременно запускать Rust и Prosody с одним каталогом данных нельзя. Между экземплярами Rust действует блокировка inode каталога данных, в том числе при разных портах и путях-синонимах. Prosody в этой блокировке не участвует. Команда create-user также отказывается писать в каталог работающего Rust-сервера; для изменения аккаунтов во время работы используйте admin shell. Для переключения остановите один процесс и запустите другой. Резервная копия нужна для проверки отката до переключения рабочего сервера; тестирование формата не доказывает совместимость всех ваших записей.
Ваш Docker Compose
Распакуйте каталог rust-xmpp рядом с исходным docker-compose.yml.
Дополнительный файл заменяет образ только сервиса prosody. Порты, тома,
healthcheck prosodyctl check и сервис coturn наследуются из исходного файла.
docker compose -f docker-compose.yml -f rust-xmpp/compose.override.yml config
docker compose -f docker-compose.yml -f rust-xmpp/compose.override.yml up -d --build prosody
Эта команда запускает сервер на томах из исходного Compose; применяйте её
после проверки на копии. Исходные docker-compose.yml и prosody.cfg.lua
редактировать не требуется. Образ содержит CA-сертификаты и команду
prosodyctl, совместимую с указанным healthcheck. Это проверка ответа
работающего процесса через admin socket, а не полный аналог диагностики
prosodyctl check.
Entrypoint определяет UID/GID владельца /var/lib/prosody и запускает процесс
с этими правами, не меняя рекурсивно владельцев существующих файлов. Если
каталог принадлежит root, а файлы внутри другому UID, задайте XMPP_UID и
XMPP_GID в окружении контейнера через дополнительный Compose-файл.
При другом пути данных задайте также XMPP_DATA_DIR. Выбранный пользователь
должен читать TLS-ключ и писать данные. Docker-образ в среде разработки
не собирался: здесь нет Docker; состав образа и override подготовлены,
но запуск на целевом Docker ещё предстоит проверить.
Форматы конфигурации
Все форматы используют одну структуру: global и hosts; у хоста есть
options и, для компонента, component. Надёжнее получить её из Lua:
./target/release/rust-xmpp convert /etc/prosody/prosody.cfg.lua json config.json
./target/release/rust-xmpp convert /etc/prosody/prosody.cfg.lua yaml config.yml
./target/release/rust-xmpp convert /etc/prosody/prosody.cfg.lua toml config.toml
./target/release/rust-xmpp check-config config.yml
Конвертер сохраняет области настроек и Include, не меняет исходный файл,
не перезаписывает существующий выходной и создаёт его с правами 0600.
Выходной файл содержит секреты конфигурации. Lua выполняется в ограниченной
VM без системных библиотек; произвольные Lua-плагины не исполняются.
Поддержка Lua в проекте также нужна для точного чтения файлов данных Prosody.
Команды и проверки
Полный локальный прогон: bash scripts/verify-local.sh.
XMPP_LOAD_CHECK=1 добавляет нагрузочный сценарий; настройки native Prosody
для дополнительных проверок описаны в scripts/prosody_compat/README.md.
cargo test --locked
cargo clippy --locked --all-targets -- -D warnings
cargo build --release --locked
python3 scripts/smoke.py # после make-demo.sh
python3 scripts/integration_xmpp.py
python3 tests/sasl_network.py --spawn --hash sha1
python3 tests/sasl_network.py --spawn --hash sha256
python3 tests/sasl2_bind.py target/release/rust-xmpp
python3 scripts/integration_http.py # требует websockets
python3 scripts/load_smoke.py --clients 500 --accounts 100 --rounds 10 --message-rounds 10 --archive
Все сетевые тесты создают отдельные тестовые данные; кроме smoke с портом 55222, выбирают свободные loopback-порты. Оригинальная Prosody отдельно проверяет формат данных и пароли: инструкции в scripts/prosody_compat/README.md.
./target/release/rust-xmpp create-user CONFIG USER --password-stdin
./target/release/rust-xmpp check [CONFIG]
./target/release/rust-xmpp shell CONFIG 'server:status()'
Пароль create-user принимает через stdin; существующий аккаунт не заменяет.
Admin shell реализует ограниченный набор команд управления сервером и
аккаунтами. Произвольный Lua-код и горячая перезагрузка модулей не поддержаны.
Дополнительный SASL2 Bind2
Модуль sasl2_bind2 (alias bind2) включает привязку ресурса внутри SASL2,
inline SM/CSI/Carbons и MAM metadata. Добавьте его в modules_enabled вместе
с sasl2 только если эта функция нужна. Исходный конфиг по-прежнему работает
без включения нового модуля. Ресурс генерируется случайно; прежние соединения
того же аккаунта с тем же валидным UUIDv4 user-agent завершаются после успешного
входа. Inline возобновление SM через SASL2 пока не объявляется.
PEP, push и pre-authenticated roster
В 0.5.0 исправлены ответы disco для bare JID аккаунта. При включённых
pep и cloud_notify (они уже есть в предоставленном конфиге) изменение
конфига не требуется. После обновления переподключите аккаунт в клиенте,
чтобы повторить service discovery. Push требует также настройки
клиентского push-сервиса; реальный APNs/FCM шлюз здесь не имитируется.
При включённом roster клиент может обнаружить и вызвать контактную
ad-hoc команду urn:xmpp:invite#invite на серверном JID. Она возвращает
xmpp:…?roster;preauth=… и срок действия. Регистрацию аккаунта такое
приглашение не разрешает. XEP-0379 presence tokens сохраняются даже
для неизвестных серверу приглашений, созданных самим клиентом.
Переподключение в 0.6.0
Повторная привязка одного ресурса по умолчанию заменяет старое соединение,
как в Prosody. conflict_resolve поддерживает kick_old, kick_new,
increment и random. Если явно задан kick_new, занятый ресурс по-прежнему
получит protocol conflict — это выбранная политика.
SM восстанавливается при гонке со старым TCP и внутри SASL2. Исправлено освобождение ресурсов при BOSH/WebSocket close. Подробности: CHANGELOG-0.6.0.md.
Android SASL в 0.6.1
Добавлен tls-server-end-point для TLS1.2/1.3 и исправлена SSDP-проверка
соединений WebSocket без channel binding. Причина воспроизводимого
not-authorized в Conversations, область тестирования и ограничения
описаны в CHANGELOG-0.6.1.md и
docs/ANDROID-SASL.md.
Логирование в 0.7.0
Добавлены журнал TLS/SASL/bind/SM с единым connection ID, точные причины отказов, файлы/console, JSON/plain и SIGHUP rotation reopen. Для диагностики Conversations/monocles используйте docs/LOGGING.md.
Исправления 0.7.5
Cached SASL2 Bind2/SM requests допускают legacy fallback, XEP-0258/0077 объявляются для Gajim; policy/classifications схема может использоваться как каталог labels. Дубликаты одинаковых log destinations устранены. Подробности — CHANGELOG-0.7.5.md.
HTTP Upload в 0.7.9
Несколько upload components с разными HTTP hosts или mounts и S3-compatible gateway с multipart streaming описаны в docs/HTTP-UPLOAD.md. Добавлены offline миграция с SHA-256/resume, точечная очистка multipart и карантин неопределённого completion. Реальные 10 GiB через MinIO проверены с описанной адаптацией тестовой среды. Изменения и границы подтверждения — CHANGELOG-0.7.9.md.