fix(install): fetch x-ui.sh and unit files from the installed release tag (#6391)

* fix(install): fetch x-ui.sh and unit files from the installed release tag

install.sh and update.sh pin the panel archive to a release tag but always
took x-ui.sh, x-ui.rc and the service units from main, so the management
script and the binary of one installation came from different commits:
the fail2ban templates and setting flags the script writes drift silently
against an older binary, two installs of the same tag differ, and a
reviewed or digest-pinned installer still runs unreviewed code from main.

Use the same ref as the archive, keeping main only for the rolling
dev-latest build. The menu's "update menu" and update_shell paths now
fetch the script matching the installed version and fall back to main
with a visible notice when no script is published for it.

Assisted-by: Claude Code:claude-fable-5-1

* fix(install): fall back to main for files a pinned tag does not publish

Review follow-ups. install.sh accepts tags down to v2.3.5, but x-ui.rc
only exists from v2.8.4 and the split x-ui.service.* files are newer
still, so pinning those to the tag made an Alpine install of an old tag
404 after the previous install was already removed. Probe the tag for
each file and fall back to main with a notice when it is missing, as
the menu already does for x-ui.sh.

The fail2ban auto-setup probe also trusted the exit status of
'x-ui setup-fail2ban', but scripts before v3.4.0 have no such
subcommand and exit 0 from the usage banner, so the installer reported
a setup that never ran. Skip with a notice when the installed script
does not know the subcommand.

Assisted-by: Claude Code:claude-fable-5-1

* fix(install): refuse a tag that does not publish a needed script

Falling back to main reintroduced the binary/script mismatch the tag
pinning exists to remove, and it fired at points where install.sh and
update.sh have already stopped and removed the previous installation --
so the quiet path was also the one that could not be undone.

Probe the tag instead, before anything is touched, for every file that is
always fetched from GitHub (x-ui.sh, plus x-ui.rc on Alpine), and abort
with the HTTP status when one is missing. The unit files stay unprobed:
they are only fetched when the release tarball omits them, so an old tag
that ships x-ui.service inside its tarball still installs. Their existing
failure message now names the ref it tried.

Also tighten the setup-fail2ban probe to the dispatcher's case arm rather
than any mention of the string, which also matches a comment.

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
ilyusha
2026-09-03 17:50:53 +03:00
committed by GitHub
parent 23511108bf
commit 195988bdc1
3 changed files with 95 additions and 14 deletions
+15 -2
View File
@@ -208,6 +208,19 @@ replace_xui_script() {
return 0
}
# The menu must match the installed panel, so update it from that release's
# tag; fall back to main only when no script is published for the version.
installed_script_url() {
local ver
ver=$("${xui_folder}/x-ui" -v 2> /dev/null | tr -d '[:space:]')
if [[ "$ver" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] && curl -fsIL -o /dev/null "https://raw.githubusercontent.com/MHSanaei/3x-ui/v${ver}/x-ui.sh"; then
echo "https://raw.githubusercontent.com/MHSanaei/3x-ui/v${ver}/x-ui.sh"
else
echo -e "${yellow}No x-ui.sh published for the installed version (${ver:-unknown}), using main${plain}" >&2
echo "https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.sh"
fi
}
update_menu() {
echo -e "${yellow}Updating Menu${plain}"
confirm "This function will update the menu to the latest changes." "y"
@@ -219,7 +232,7 @@ update_menu() {
return 0
fi
if replace_xui_script "https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.sh" "false"; then
if replace_xui_script "$(installed_script_url)" "false"; then
chmod +x ${xui_folder}/x-ui.sh
echo -e "${green}Update successful. The panel has automatically restarted.${plain}"
exit 0
@@ -836,7 +849,7 @@ enable_bbr() {
}
update_shell() {
if replace_xui_script "https://github.com/MHSanaei/3x-ui/raw/main/x-ui.sh" "true"; then
if replace_xui_script "$(installed_script_url)" "true"; then
LOGI "Upgrade script succeeded, Please rerun the script"
before_show_menu
else