From 836f65f19259716a369ca88cc29cc217d531da7d Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Feb 2026 10:21:46 +0000 Subject: [PATCH] Rewrite install.sh to build from source instead of downloading release The install script previously downloaded pre-built binaries from MHSanaei/3x-ui releases, which didn't include TrustTunnel support. Now it clones the fork, installs Go, and builds from source so all custom protocol changes are included in the installed binary. https://claude.ai/code/session_01RQBndg4ZPmYAToK4KKcBzp --- install.sh | 299 ++++++++++++++++++++++++++++------------------------- 1 file changed, 158 insertions(+), 141 deletions(-) diff --git a/install.sh b/install.sh index 46207777..89bcb072 100644 --- a/install.sh +++ b/install.sh @@ -76,33 +76,70 @@ is_port_in_use() { install_base() { case "${release}" in ubuntu | debian | armbian) - apt-get update && apt-get install -y -q curl tar tzdata socat ca-certificates + apt-get update && apt-get install -y -q curl tar tzdata socat ca-certificates git gcc make unzip ;; fedora | amzn | virtuozzo | rhel | almalinux | rocky | ol) - dnf -y update && dnf install -y -q curl tar tzdata socat ca-certificates + dnf -y update && dnf install -y -q curl tar tzdata socat ca-certificates git gcc make unzip ;; centos) if [[ "${VERSION_ID}" =~ ^7 ]]; then - yum -y update && yum install -y curl tar tzdata socat ca-certificates + yum -y update && yum install -y curl tar tzdata socat ca-certificates git gcc make unzip else - dnf -y update && dnf install -y -q curl tar tzdata socat ca-certificates + dnf -y update && dnf install -y -q curl tar tzdata socat ca-certificates git gcc make unzip fi ;; arch | manjaro | parch) - pacman -Syu && pacman -Syu --noconfirm curl tar tzdata socat ca-certificates + pacman -Syu && pacman -Syu --noconfirm curl tar tzdata socat ca-certificates git gcc make unzip ;; opensuse-tumbleweed | opensuse-leap) - zypper refresh && zypper -q install -y curl tar timezone socat ca-certificates + zypper refresh && zypper -q install -y curl tar timezone socat ca-certificates git gcc make unzip ;; alpine) - apk update && apk add curl tar tzdata socat ca-certificates + apk update && apk add curl tar tzdata socat ca-certificates git gcc musl-dev make unzip ;; *) - apt-get update && apt-get install -y -q curl tar tzdata socat ca-certificates + apt-get update && apt-get install -y -q curl tar tzdata socat ca-certificates git gcc make unzip ;; esac } +# Go version required for building +GO_VERSION="1.22.5" + +install_go() { + if command -v go >/dev/null 2>&1; then + local current_go=$(go version 2>/dev/null | grep -oP 'go\K[0-9]+\.[0-9]+') + local required="1.22" + if [[ "$(printf '%s\n' "$required" "$current_go" | sort -V | head -n1)" == "$required" ]]; then + echo -e "${green}Go ${current_go} is already installed${plain}" + return 0 + fi + fi + + echo -e "${green}Installing Go ${GO_VERSION}...${plain}" + local go_arch + case "$(uname -m)" in + x86_64 | x64 | amd64) go_arch="amd64" ;; + i*86 | x86) go_arch="386" ;; + armv8* | armv8 | arm64 | aarch64) go_arch="arm64" ;; + armv7* | armv7 | arm) go_arch="armv6l" ;; + armv6* | armv6) go_arch="armv6l" ;; + s390x) go_arch="s390x" ;; + *) echo -e "${red}Unsupported architecture for Go${plain}"; exit 1 ;; + esac + + curl -4fLo /tmp/go.tar.gz "https://go.dev/dl/go${GO_VERSION}.linux-${go_arch}.tar.gz" + if [[ $? -ne 0 ]]; then + echo -e "${red}Failed to download Go${plain}" + exit 1 + fi + rm -rf /usr/local/go + tar -C /usr/local -xzf /tmp/go.tar.gz + rm -f /tmp/go.tar.gz + export PATH="/usr/local/go/bin:$PATH" + echo -e "${green}Go $(go version) installed successfully${plain}" +} + gen_random_string() { local length="$1" local random_string=$(LC_ALL=C tr -dc 'a-zA-Z0-9' /dev/null else - systemctl stop x-ui + systemctl stop x-ui 2>/dev/null fi rm ${xui_folder}/ -rf fi - - # Extract resources and set permissions - tar zxvf x-ui-linux-$(arch).tar.gz - rm x-ui-linux-$(arch).tar.gz -f - - cd x-ui + + # Install built files + mkdir -p ${xui_folder} + cp build/x-ui ${xui_folder}/ + cp -r build/bin ${xui_folder}/ + cp x-ui.sh ${xui_folder}/ + # Copy service files into install dir for later detection + cp -f x-ui.service.debian ${xui_folder}/ 2>/dev/null + cp -f x-ui.service.arch ${xui_folder}/ 2>/dev/null + cp -f x-ui.service.rhel ${xui_folder}/ 2>/dev/null + # Also copy as generic x-ui.service for fallback + case "${release}" in + ubuntu | debian | armbian) cp -f x-ui.service.debian ${xui_folder}/x-ui.service 2>/dev/null ;; + arch | manjaro | parch) cp -f x-ui.service.arch ${xui_folder}/x-ui.service 2>/dev/null ;; + *) cp -f x-ui.service.rhel ${xui_folder}/x-ui.service 2>/dev/null ;; + esac + + cd ${xui_folder} chmod +x x-ui chmod +x x-ui.sh - + # Check the system's architecture and rename the file accordingly if [[ $(arch) == "armv5" || $(arch) == "armv6" || $(arch) == "armv7" ]]; then mv bin/xray-linux-$(arch) bin/xray-linux-arm chmod +x bin/xray-linux-arm fi - chmod +x x-ui bin/xray-linux-$(arch) - - # Update x-ui cli and se set permission - mv -f /usr/bin/x-ui-temp /usr/bin/x-ui + chmod +x x-ui bin/xray-linux-$(arch) 2>/dev/null + + # Install x-ui CLI wrapper + cp -f "${xui_folder}/x-ui.sh" /usr/bin/x-ui chmod +x /usr/bin/x-ui mkdir -p /var/log/x-ui + + # Cleanup build directory + rm -rf "${BUILD_DIR}" + + tag_version="source-build" config_after_install # Etckeeper compatibility @@ -848,96 +915,46 @@ install_x-ui() { echo -e "${green}Created /etc/.gitignore and added x-ui.db for etckeeper${plain}" fi fi - + if [[ $release == "alpine" ]]; then - curl -4fLRo /etc/init.d/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.rc - if [[ $? -ne 0 ]]; then - echo -e "${red}Failed to download x-ui.rc${plain}" - exit 1 + if [ -f "${xui_folder}/x-ui.service.debian" ]; then + # Use a simple OpenRC init script + cp -f "${xui_folder}/x-ui.service.debian" /etc/init.d/x-ui 2>/dev/null fi + # Create OpenRC init script + cat > /etc/init.d/x-ui <<'INITEOF' +#!/sbin/openrc-run +name="x-ui" +description="3x-ui panel" +command="/usr/local/x-ui/x-ui" +command_background=true +pidfile="/run/x-ui.pid" +directory="/usr/local/x-ui" +output_log="/var/log/x-ui/x-ui.log" +error_log="/var/log/x-ui/x-ui.log" +INITEOF chmod +x /etc/init.d/x-ui rc-update add x-ui rc-service x-ui start else # Install systemd service file - service_installed=false - - if [ -f "x-ui.service" ]; then - echo -e "${green}Found x-ui.service in extracted files, installing...${plain}" - cp -f x-ui.service ${xui_service}/ >/dev/null 2>&1 - if [[ $? -eq 0 ]]; then - service_installed=true - fi - fi - - if [ "$service_installed" = false ]; then - case "${release}" in - ubuntu | debian | armbian) - if [ -f "x-ui.service.debian" ]; then - echo -e "${green}Found x-ui.service.debian in extracted files, installing...${plain}" - cp -f x-ui.service.debian ${xui_service}/x-ui.service >/dev/null 2>&1 - if [[ $? -eq 0 ]]; then - service_installed=true - fi - fi - ;; - arch | manjaro | parch) - if [ -f "x-ui.service.arch" ]; then - echo -e "${green}Found x-ui.service.arch in extracted files, installing...${plain}" - cp -f x-ui.service.arch ${xui_service}/x-ui.service >/dev/null 2>&1 - if [[ $? -eq 0 ]]; then - service_installed=true - fi - fi - ;; - *) - if [ -f "x-ui.service.rhel" ]; then - echo -e "${green}Found x-ui.service.rhel in extracted files, installing...${plain}" - cp -f x-ui.service.rhel ${xui_service}/x-ui.service >/dev/null 2>&1 - if [[ $? -eq 0 ]]; then - service_installed=true - fi - fi - ;; - esac - fi - - # If service file not found in tar.gz, download from GitHub - if [ "$service_installed" = false ]; then - echo -e "${yellow}Service files not found in tar.gz, downloading from GitHub...${plain}" - case "${release}" in - ubuntu | debian | armbian) - curl -4fLRo ${xui_service}/x-ui.service https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.service.debian >/dev/null 2>&1 - ;; - arch | manjaro | parch) - curl -4fLRo ${xui_service}/x-ui.service https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.service.arch >/dev/null 2>&1 - ;; - *) - curl -4fLRo ${xui_service}/x-ui.service https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.service.rhel >/dev/null 2>&1 - ;; - esac - - if [[ $? -ne 0 ]]; then - echo -e "${red}Failed to install x-ui.service from GitHub${plain}" - exit 1 - fi - service_installed=true - fi - - if [ "$service_installed" = true ]; then - echo -e "${green}Setting up systemd unit...${plain}" - chown root:root ${xui_service}/x-ui.service >/dev/null 2>&1 - chmod 644 ${xui_service}/x-ui.service >/dev/null 2>&1 - systemctl daemon-reload - systemctl enable x-ui - systemctl start x-ui + if [ -f "${xui_folder}/x-ui.service" ]; then + echo -e "${green}Installing systemd service file...${plain}" + cp -f "${xui_folder}/x-ui.service" ${xui_service}/x-ui.service else - echo -e "${red}Failed to install x-ui.service file${plain}" + echo -e "${red}Service file not found${plain}" exit 1 fi + + echo -e "${green}Setting up systemd unit...${plain}" + chown root:root ${xui_service}/x-ui.service >/dev/null 2>&1 + chmod 644 ${xui_service}/x-ui.service >/dev/null 2>&1 + systemctl daemon-reload + systemctl enable x-ui + systemctl start x-ui fi - - echo -e "${green}x-ui ${tag_version}${plain} installation finished, it is running now..." + + echo -e "${green}x-ui (built from source)${plain} installation finished, it is running now..." echo -e "" echo -e "┌───────────────────────────────────────────────────────┐ │ ${blue}x-ui control menu usages (subcommands):${plain} │ @@ -961,4 +978,4 @@ install_x-ui() { echo -e "${green}Running...${plain}" install_base -install_x-ui $1 +install_x-ui