Replace the hand-maintained Docsify site (parallel docs/en + docs/ru trees that had already drifted) with a MkDocs Material build where English is the single source of truth and Russian is generated at build time. Engine & structure - mkdocs.yml: Material theme, site_url for the /XC_VM/ Pages subpath, and a two-tab information architecture — User Guide (administration, API/Swagger, UI translations, diagnostics, info/FAQ) vs Developer Guide (architecture, workflow, security, integrations, build). Files are NOT moved — the split is nav-only, so URLs and cross-links stay stable. - mkdocs-static-i18n (folder mode): English at root, Russian under /ru/, with a language switcher. `mkdocs build --strict` validates every link/anchor. Translation pipeline (tools/docs/translate.py) - Engine-agnostic via DOCS_TRANSLATE_PROVIDER: translators (free, no API key — default), anthropic, deepl, or noop. Per-file sha256 cache so only changed English files are re-translated. Markdown-safe: code, URLs, HTML tags and glossary terms (XC_VM, FFmpeg, HLS, ...) are masked and never translated. A file whose translation fails falls back to English so the build never breaks. - docs/ru is generated and gitignored — never committed. It is produced locally (`make docs-serve` / `docs-build`) and in CI. CI & tooling - pages.yml: build-then-upload (setup-python -> install -> restore .docs-cache with restore-keys -> translate -> mkdocs build --strict -> deploy), replacing the verbatim docs/ upload. - Makefile: docs-venv / docs-translate / docs-build / docs-serve. - docs/requirements.txt; .gitignore for docs/ru, site/, .docs-cache. Migration details - Removed Docsify control files (index.html, _navbar.md, _sidebar.md, .nojekyll) and de-Docsify-ed body links in 6 English files (en-us/ aliases -> relative, swagger _media paths, stripped ':ignore' link syntax). - Preserved the two Russian-only planning docs (no English source) by moving them into docs/adr/ as *.ru.md (repo-internal, excluded from the site).
4.3 KiB
Update Mechanism in XC_VM
The XC_VM update system is implemented as a multi-layered process, from the web interface to system-level scripts. This approach ensures reliability, automation, and data integrity during panel updates.
📋 For a step-by-step guide with screenshots, see Updating a Server.
1. Update Initiation
The process begins when the administrator clicks the "Update" button in the web interface.
- A signal named
updateis inserted into thesignalstable in the database. - This signal acts as a trigger for the entire update procedure.
2. CRON Trigger
Every minute, the following CRON job runs:
/home/xc_vm/console.php cron:root_signals
The root_signals cron job checks for new signals.
When it detects an update signal, it launches:
/home/xc_vm/console.php update update
3. Update Management (PHP Layer)
Core logic resides in the UpdateCommand class:
src/Cli/Commands/UpdateCommand.php
At this stage the following actions are performed:
- Detect the current panel type (
MAINorLB). - Fetch update metadata from GitHub:
- Direct link to the update archive.
- SHA checksum for integrity verification.
- Download the archive to a temporary directory.
- Verify the downloaded file matches the expected hash.
- Hand over control to the system-level updater (Python):
sudo /usr/bin/python3 /home/xc_vm/update "/home/xc_vm/tmp/.update.tar.gz" "HASH" > /dev/null 2>&1 &
💡 After the Python updater finishes, it calls
console.php update post-updatewhich triggers database migrations and post-update cleanup.
4. System-Level Update (Python Layer)
Control is transferred to the Python script:
/home/xc_vm/update
It performs privileged system operations:
-
Re-verify the archive checksum.
-
Stop the panel to prevent conflicts during update.
-
Extract the archive into a temporary directory:
/tmp/xc_vm_update_*/ -
Remove excluded directories from the temp copy — binaries, configs, and user data that must not be overwritten:
bin/ffmpeg_bin,bin/nginx,bin/nginx_rtmp,bin/php,bin/redis,bin/install,bin/maxmind,bin/certbot,content,backups,tmp,config,signals -
Copy remaining files over the live installation:
cp -a /tmp/xc_vm_update_*/. /home/xc_vm/ -
Fix ownership:
chown -R xc_vm:xc_vm /home/xc_vm/ -
Run post-update tasks:
/home/xc_vm/console.php update post-update -
Restart the panel in normal operating mode.
-
Cleanup the temporary directory and delete the archive.
ℹ️ The same archive is used for both installation and update. Filtering happens on the server at update time — the exclude list is defined directly in
src/update.
5. Update Completion
Final steps are executed in the post-update phase of UpdateCommand:
-
If LB auto-update is enabled and the main node (
MAIN) was updated → createupdatesignals for all Load Balancers. -
Update the panel version in the database.
-
Remove obsolete files.
-
Re-apply correct permissions:
chown -R xc_vm:xc_vm /home/xc_vm/ -
Reload systemd daemons:
sudo systemctl daemon-reload -
Verify panel status:
sudo /home/xc_vm/console.php status -
Mark the update process as complete.
6. Full Workflow Diagram
[ Web Interface ]
│
▼
[ DB: "update" signal ]
│
▼
[ CRON → console.php cron:root_signals ]
│
▼
[ UpdateCommand (PHP): download + verify hash ]
│
▼
[ update (Python): extract to /tmp → remove excluded → copy over ]
│
▼
[ post-update → UpdateCommand ]
│
▼
[ Finalize, restart daemons, update version in DB ]
Key Features
- Double integrity check (both PHP and Python layers verify the hash).
- Automatic propagation of updates from MAIN to all Load Balancers.
- Cleanup of deprecated files and permission normalization.
- Safe panel restart after installation.
- Flexibility & autonomy thanks to CRON + signal-based triggering.