RENAMING.md: exact mapping, LUI_ inventory, sing-box orphan-scan re-verification, Tianyi badge mechanism, intentionally-kept items (module path, upstream mentions, frozen Windows, ps1, log filenames, Postgres creds, generated schemas, stale test binaries), and pending items (repo spelling BLOCKER, version bump, ps1 URL after repo rename, schema regeneration). docs/migration-l-ui.md: operator-only mv table, DB file rename, unit-env translation, backup-then-delete, old-core stop rule, rollback before acceptance only, per-machine acceptance checklist, pilot order (probe node, master, rest one by one, TYYUN untouched). docs/release.md: placeholder-repo warning.
11 KiB
Migration: x-ui → l-ui (operator runbook, no code runs this)
This document is the only migration mechanism. The renamed code
does not auto-migrate old paths at startup (except the
Windows-only DB copy safety net noted in RENAMING.md) and does
not read old XUI_* variables. Every old path below must be
moved by the operator, on each machine, in the order given.
Applies to: panel hosts (systemd), agent nodes (systemd / OpenRC / procd), and the master host that also runs a local agent. It does not apply to the frozen Windows agent (TYYUN): that machine is untouched — its panel-side update badge is suppressed by the panel, its agent stays A2.2.1, no file on it moves.
0. Before anything
- Confirm the Gitea repo spelling first (see RENAMING.md pending
item 1). The renamed binaries' update check points at the
placeholder
rogue/l-ui; do not roll the renamed build out while that placeholder is still in place, or the first update check after migration will 404. - Confirm the release version for this migration (panel line, and agent line only if agent code changed). The rename diff itself keeps V2.6.0 / A2.5.0; the migration runs against the release that actually ships the rename, whatever its number is.
- One machine at a time. Never migrate the whole fleet at once: a panel/agent restart interrupts that machine's inbounds for seconds, and a bad step must be caught on the pilot before it can repeat everywhere.
1. Per-machine move table (mv, never cp)
Stop the old service first, then move, then install the new
binary + unit, then start. mv keeps the data in one place;
cp leaves two copies and is how stale-DB incidents happen.
| old | new | notes |
|---|---|---|
/usr/local/x-ui/ |
/usr/local/l-ui/ |
panel binary, bin/ (sing-box, geo, config-singbox.json) |
/etc/x-ui/ |
/etc/l-ui/ |
l-ui.db is the renamed file: move x-ui.db → l-ui.db inside the move (see §2) |
/etc/x-ui/x-ui.db |
/etc/l-ui/l-ui.db |
the panel DB; see §2 for the file rename |
/etc/x-ui/probe.db |
/etc/l-ui/probe.db |
name unchanged, directory moved |
/etc/x-ui/cert/ |
/etc/l-ui/cert/ |
panel + subscription certs move with the dir |
/etc/x-ui/agent.json |
/etc/l-ui/agent.json |
agent nodes |
/etc/x-ui/node_token_key.json |
/etc/l-ui/node_token_key.json |
panel hosts |
/var/log/x-ui/ |
/var/log/l-ui/ |
log filenames inside (3xui.log, 3xipl.log) do NOT change |
/usr/local/x-ui/bin/config-singbox.json |
/usr/local/l-ui/bin/config-singbox.json |
the live config the orphan scan matches on (see §5) |
/etc/systemd/system/x-ui.service |
/etc/systemd/system/l-ui.service |
delete the old unit file, install the new one from the repo — do not edit the old file in place |
/etc/systemd/system/x-ui-agent.service |
/etc/systemd/system/lui-agent.service |
same: delete old, install new |
/etc/init.d/x-ui-agent (OpenRC) |
/etc/init.d/lui-agent |
same: delete old, install new |
/etc/init.d/x-ui (OpenRC panel, if present) |
/etc/init.d/l-ui |
from l-ui.rc |
/etc/default/x-ui |
/etc/default/l-ui |
env file, with translation in §3 |
/etc/conf.d/x-ui |
/etc/conf.d/l-ui |
Arch/Alpine env file, with translation in §3 |
/etc/sysconfig/x-ui |
/etc/sysconfig/l-ui |
RHEL env file, with translation in §3 |
/usr/bin/x-ui (Docker management CLI) |
/usr/bin/l-ui |
Docker images only; from l-ui.sh |
/tmp/xui.log (install-master scratch) |
/tmp/lui.log |
scratch only; delete, don't migrate |
Pure-probe nodes (56HL-NAT, AX6600, WW39, TYYUN excepted as
frozen): same table, minus inbounds — they have no core config to
worry about, which is why they go first (§6). AX6600 and 56HL-NAT
carry a probeOnly preset in agent.json; it moves with the file.
2. Database file rename
The panel DB file itself is renamed, not just its directory:
mv /etc/x-ui/x-ui.db /etc/l-ui/l-ui.db
(probe.db keeps its name.) If the move is done as a whole-dir
mv /etc/x-ui /etc/l-ui followed by mv /etc/l-ui/x-ui.db /etc/l-ui/l-ui.db, the result is identical. Do not leave a copy
of x-ui.db behind "just in case" — the backup in §4 is the
just-in-case copy, and it is deleted after acceptance.
Postgres deployments: the DB name/user (xui) is intentionally
unchanged (RENAMING.md), so no database rename is needed there;
only the env prefix in the unit changes (LUI_DB_TYPE,
LUI_DB_DSN).
3. Unit environment translation (XUI_ → LUI_)
Old units must be replaced with the new units from the repo. If a host has a local env-file override, translate every line:
XUI_... → LUI_...
i.e. XUI_DB_FOLDER → LUI_DB_FOLDER,
XUI_MAIN_FOLDER → LUI_MAIN_FOLDER,
XUI_LOG_FOLDER → LUI_LOG_FOLDER,
XUI_BIN_FOLDER → LUI_BIN_FOLDER, and so on for the full
inventory in RENAMING.md. There is no fallback: a leftover
XUI_DB_FOLDER pointing at /etc/x-ui will simply be ignored
by the new binary, which will then open the default
/etc/l-ui/l-ui.db — that looks like "the panel lost its data"
when it is really "the env file was never translated". After
installing the new unit, run systemctl daemon-reload (systemd)
or the OpenRC equivalent, and verify with
systemctl cat l-ui / systemctl cat lui-agent that no XUI_
line remains.
4. Backup, and deleting it
Before the move, on each machine:
cp -a /etc/x-ui /root/l-ui-migration-bak-$(date +%F)
cp -a /usr/local/x-ui /root/l-ui-migration-bin-bak-$(date +%F) # panel hosts only if bin/ holds local files worth keeping
(Adjust the backup root if /root is small; the panel DB is the
critical part.) The backup exists only until that machine passes
§7. After acceptance, delete it. A backup left in /root
indefinitely is residual garbage by definition, and a later
operator can mistake it for the live directory. Do not keep
x-ui.db copies, .bak binaries, or old units "for safety"
past acceptance — acceptance is the safety check.
5. Old cores: stop them, do not re-adopt them
The renamed agent's orphan scan matches only cores started with
/usr/local/l-ui/bin/config-singbox.json (exact argv triple
run -c <path>). A core still running the old
/usr/local/x-ui/bin/config-singbox.json will not be matched
and will keep holding the inbound ports, so the new core will fail
to bind and the agent will roll back every 30 s. Before starting
the new agent, confirm no old core survives:
ps -ef | grep -F "config-singbox.json" | grep -v grep
# any line with /usr/local/x-ui/bin/config-singbox.json must be
# stopped (kill it; SIGTERM, then SIGKILL if it survives 5 s)
# before the new agent starts. Do NOT kill a core whose config
# path belongs to another panel/agent/router (e.g. amo, momo).
The same rule applies to the panel's own old process: stop
x-ui / xui-agent processes before starting l-ui /
lui-agent. install-agent.sh's legacy kill covers the
dual-mode x-ui agent form as a one-time cleanup, but the
migration step above is the authoritative check — do not rely on
the installer to notice a stray core.
6. Rollback (before acceptance only)
If a machine fails §7, roll it back before moving on:
systemctl stop l-ui lui-agent 2>/dev/null
mv /etc/l-ui /etc/x-ui
mv /etc/x-ui/l-ui.db /etc/x-ui/x-ui.db # if the DB file was renamed
mv /usr/local/l-ui /usr/local/x-ui
mv /var/log/l-ui /var/log/x-ui
# reinstall the OLD unit files and the OLD binary, then:
systemctl daemon-reload
systemctl start x-ui x-ui-agent # only the units that existed before
Rollback after acceptance is not a plan — it is a new migration in reverse, and it needs the backup from §4, which acceptance deletes. That is intentional: acceptance must mean "this machine is good on the new names".
7. Per-machine acceptance checklist (all must pass)
psshowsl-ui/lui-agent, and nox-ui/xui-agentprocess remains (except unrelated amo/momo cores, identified by their own config paths).- No old directory remains:
ls /usr/local/x-ui /etc/x-ui /var/log/x-uiall fail with "No such file or directory". - No old unit remains:
systemctl list-unit-files | grep x-uiempty;/etc/init.d/has nox-ui*file. - No
XUI_line remains in the active unit / env file (systemctl cat l-ui,systemctl cat lui-agent). - Panel answers on its usual port; login works; node list shows the machine with its agent version (A-line) and probe data (CPU/mem/uptime) updating.
- Inbounds on the machine accept a real client connection (not just "port listening" — the Oracle 27084 lesson: a bound port is not a working inbound).
- Probe reporting is normal on the panel (history continues, no gap longer than the machine's normal heartbeat interval).
- Subscription endpoint serves (panel hosts: the usual subscription URL returns a non-empty list for a test client).
- Update check no longer points at the old repo: panel
update info resolves against the confirmed repo spelling
(placeholder
rogue/l-uimust be gone before rollout). - Backup from §4 deleted.
Only after every box is ticked is the machine done. Do not tick "probe normal" from a single heartbeat — watch at least two intervals.
8. Pilot order (suggested)
- One pure-probe node first (e.g. 56HL-NAT or WW39): no inbounds, so a failure costs nothing but probe history, and it proves the agent rename + telemetry + probe path end to end.
- The master (HW-SG) second, including its local agent: the master is the only machine whose failure blocks every other machine's verification, so it goes early but never first — the pilot must have proven the agent binary first.
- Remaining nodes one by one, core nodes before probe-only leftovers, each fully through §7 before the next starts. Never two at once: if a step is wrong, exactly one machine is in the broken state, and its §6 rollback is still available.
- TYYUN (Windows) last and untouched: verify only that its panel row shows A2.2.1 with no orange update badge, and that probe data still updates. No file moves, no exe swap, no service change on that machine.
9. What this migration deliberately does not do
- It does not rename the Gitea repo (see RENAMING.md pending item 1) — the repo rename, if confirmed, is a separate step with its own verification (new clone, new release read-back).
- It does not touch the frozen Windows agent or its service.
- It does not rename Docker Postgres credentials, log filenames, or the fail2ban jail (RENAMING.md, intentionally kept).
- It does not "fix" unrelated stale items found on a machine
(e.g. the old
install-master.shxray download, the legacy GitHub Actions workflow). Note them, don't bundle them.