From 144a890c715537c48735a89d22e895d3f84b2f08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 14 Apr 2025 22:21:11 +0800 Subject: [PATCH] release: Add openwrt packages --- .fpm_openwrt | 30 ++++++++ .fpm => .fpm_systemd | 3 +- .github/deb2ipk.sh | 28 +++++++ .github/workflows/build.yml | 89 ++++++++++++++++------- docs/installation/package-manager.md | 78 +++++++++++--------- docs/installation/package-manager.zh.md | 39 ++++++---- docs/installation/tools/install.sh | 97 +++++++++++++++++++++++++ release/config/openwrt.init | 13 ++-- release/config/openwrt.keep | 1 + release/config/openwrt.prerm | 4 + 10 files changed, 301 insertions(+), 81 deletions(-) create mode 100644 .fpm_openwrt rename .fpm => .fpm_systemd (93%) create mode 100755 .github/deb2ipk.sh create mode 100755 docs/installation/tools/install.sh mode change 100644 => 100755 release/config/openwrt.init create mode 100644 release/config/openwrt.keep create mode 100755 release/config/openwrt.prerm diff --git a/.fpm_openwrt b/.fpm_openwrt new file mode 100644 index 00000000..ab8b6db6 --- /dev/null +++ b/.fpm_openwrt @@ -0,0 +1,30 @@ +-s dir +--name sing-box +--category net +--license GPL-3.0-or-later +--description "The universal proxy platform." +--url "https://sing-box.sagernet.org/" +--maintainer "nekohasekai " +--no-deb-generate-changes + +--config-files /etc/config/sing-box +--config-files /etc/sing-box/config.json + +--depends ca-bundle +--depends kmod-inet-diag +--depends kmod-tun +--depends firewall4 + +--before-remove release/config/openwrt.prerm + +release/config/config.json=/etc/sing-box/config.json + +release/config/openwrt.conf=/etc/config/sing-box +release/config/openwrt.init=/etc/init.d/sing-box +release/config/openwrt.keep=/lib/upgrade/keep.d/sing-box + +release/completions/sing-box.bash=/usr/share/bash-completion/completions/sing-box.bash +release/completions/sing-box.fish=/usr/share/fish/vendor_completions.d/sing-box.fish +release/completions/sing-box.zsh=/usr/share/zsh/site-functions/_sing-box + +LICENSE=/usr/share/licenses/sing-box/LICENSE diff --git a/.fpm b/.fpm_systemd similarity index 93% rename from .fpm rename to .fpm_systemd index 82e786bc..62d42588 100644 --- a/.fpm +++ b/.fpm_systemd @@ -1,11 +1,12 @@ -s dir --name sing-box --category net ---license GPLv3-or-later +--license GPL-3.0-or-later --description "The universal proxy platform." --url "https://sing-box.sagernet.org/" --maintainer "nekohasekai " --deb-field "Bug: https://github.com/SagerNet/sing-box/issues" +--no-deb-generate-changes --config-files /etc/sing-box/config.json release/config/config.json=/etc/sing-box/config.json diff --git a/.github/deb2ipk.sh b/.github/deb2ipk.sh new file mode 100755 index 00000000..0b820533 --- /dev/null +++ b/.github/deb2ipk.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# mod from https://gist.github.com/pldubouilh/c5703052986bfdd404005951dee54683 + +set -e -o pipefail + +PROJECT=$(dirname "$0")/../.. +TMP_PATH=`mktemp -d` +cp $2 $TMP_PATH +pushd $TMP_PATH + +DEB_NAME=`ls *.deb` +ar x $DEB_NAME + +mkdir control +pushd control +tar xf ../control.tar.gz +rm md5sums +sed "s/Architecture:\\ \w*/Architecture:\\ $1/g" ./control -i +cat control +tar czf ../control.tar.gz ./* +popd + +DEB_NAME=${DEB_NAME%.deb} +tar czf $DEB_NAME.ipk control.tar.gz data.tar.gz debian-binary +popd + +cp $TMP_PATH/$DEB_NAME.ipk $3 +rm -r $TMP_PATH diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 211743fa..4d8232bb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -68,32 +68,39 @@ jobs: - calculate_version strategy: matrix: - os: [ linux, windows, darwin, android ] - arch: [ "386", amd64, arm64 ] - legacy_go: [ false ] include: - - { os: linux, arch: amd64, debian: amd64, rpm: x86_64, pacman: x86_64 } - - { os: linux, arch: "386", debian: i386, rpm: i386 } - - { os: linux, arch: arm, goarm: "6", debian: armel, rpm: armv6hl } - - { os: linux, arch: arm, goarm: "7", debian: armhf, rpm: armv7hl, pacman: armv7hl } - - { os: linux, arch: arm64, debian: arm64, rpm: aarch64, pacman: aarch64 } - - { os: linux, arch: mips64le, debian: mips64el, rpm: mips64el } - - { os: linux, arch: mipsle, debian: mipsel, rpm: mipsel } + - { os: linux, arch: amd64, debian: amd64, rpm: x86_64, pacman: x86_64, openwrt: "x86_64" } + - { os: linux, arch: "386", go386: sse2, debian: i386, rpm: i386, openwrt: "i386_pentium4" } + - { os: linux, arch: "386", go386: softfloat, openwrt: "i386_pentium-mmx" } + - { os: linux, arch: arm64, debian: arm64, rpm: aarch64, pacman: aarch64, openwrt: "aarch64_cortex-a53 aarch64_cortex-a72 aarch64_cortex-a76 aarch64_generic" } + - { os: linux, arch: arm, goarm: "5", openwrt: "arm_arm926ej-s arm_cortex-a7 arm_cortex-a9 arm_fa526 arm_xscale" } + - { os: linux, arch: arm, goarm: "6", debian: armel, rpm: armv6hl, openwrt: "arm_arm1176jzf-s_vfp" } + - { os: linux, arch: arm, goarm: "7", debian: armhf, rpm: armv7hl, pacman: armv7hl, openwrt: "arm_cortex-a5_vfpv4 arm_cortex-a7_neon-vfpv4 arm_cortex-a7_vfpv4 arm_cortex-a8_vfpv3 arm_cortex-a9_neon arm_cortex-a9_vfpv3-d16 arm_cortex-a15_neon-vfpv4" } + - { os: linux, arch: mips, gomips: softfloat, openwrt: "mips_24kc mips_4kec mips_mips32" } + - { os: linux, arch: mipsle, gomips: hardfloat, debian: mipsel, rpm: mipsel, openwrt: "mipsel_24kc_24kf" } + - { os: linux, arch: mipsle, gomips: softfloat, openwrt: "mipsel_24kc mipsel_74kc mipsel_mips32" } + - { os: linux, arch: mips64, gomips: softfloat, openwrt: "mips64_mips64r2 mips64_octeonplus" } + - { os: linux, arch: mips64le, gomips: hardfloat, debian: mips64el, rpm: mips64el } + - { os: linux, arch: mips64le, gomips: softfloat, openwrt: "mips64el_mips64r2" } - { os: linux, arch: s390x, debian: s390x, rpm: s390x } - { os: linux, arch: ppc64le, debian: ppc64el, rpm: ppc64le } - - { os: linux, arch: riscv64, debian: riscv64, rpm: riscv64 } - - { os: linux, arch: loong64, debian: loongarch64, rpm: loongarch64 } + - { os: linux, arch: riscv64, debian: riscv64, rpm: riscv64, openwrt: "riscv64_generic" } + - { os: linux, arch: loong64, debian: loongarch64, rpm: loongarch64, openwrt: "loongarch64_generic" } - - { os: windows, arch: "386", legacy_go: true } + - { os: windows, arch: amd64 } - { os: windows, arch: amd64, legacy_go: true } - - { os: darwin, arch: amd64, legacy_go: true } + - { os: windows, arch: "386" } + - { os: windows, arch: "386", legacy_go: true } + - { os: windows, arch: arm64 } + + - { os: darwin, arch: amd64 } + - { os: darwin, arch: amd64, legacy_go: true } + - { os: darwin, arch: arm64 } - - { os: android, arch: "386", ndk: "i686-linux-android21" } - - { os: android, arch: amd64, ndk: "x86_64-linux-android21" } - { os: android, arch: arm64, ndk: "aarch64-linux-android21" } - { os: android, arch: arm, ndk: "armv7a-linux-androideabi21" } - exclude: - - { os: darwin, arch: "386" } + - { os: android, arch: amd64, ndk: "x86_64-linux-android21" } + - { os: android, arch: "386", ndk: "i686-linux-android21" } steps: - name: Checkout uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4 @@ -139,7 +146,10 @@ jobs: CGO_ENABLED: "0" GOOS: ${{ matrix.os }} GOARCH: ${{ matrix.arch }} + GO386: ${{ matrix.go386 }} GOARM: ${{ matrix.goarm }} + GOMIPS: ${{ matrix.gomips }} + GOMIPS64: ${{ matrix.gomips }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Build Android if: matrix.os == 'android' @@ -159,14 +169,19 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Set name run: |- - ARM_VERSION=$([ -n '${{ matrix.goarm}}' ] && echo 'v${{ matrix.goarm}}' || true) - LEGACY=$([ '${{ matrix.legacy_go }}' = 'true' ] && echo "-legacy" || true) - DIR_NAME="sing-box-${{ needs.calculate_version.outputs.version }}-${{ matrix.os }}-${{ matrix.arch }}${ARM_VERSION}${LEGACY}" - PKG_NAME="sing-box_${{ needs.calculate_version.outputs.version }}_${{ matrix.os }}_${{ matrix.arch }}${ARM_VERSION}" + DIR_NAME="sing-box-${{ needs.calculate_version.outputs.version }}-${{ matrix.os }}-${{ matrix.arch }}" + if [[ -n "${{ matrix.goarm }}" ]]; then + DIR_NAME="${DIR_NAME}v${{ matrix.goarm }}" + elif [[ -n "${{ matrix.go386 }}" && "${{ matrix.go386 }}" != 'sse2' ]]; then + DIR_NAME="${DIR_NAME}-${{ matrix.go386 }}" + elif [[ -n "${{ matrix.gomips }}" && "${{ matrix.gomips }}" != 'hardfloat' ]]; then + DIR_NAME="${DIR_NAME}-${{ matrix.gomips }}" + elif [[ "${{ matrix.legacy_go }}" == 'true' ]]; then + DIR_NAME="${DIR_NAME}-legacy" + fi echo "DIR_NAME=${DIR_NAME}" >> "${GITHUB_ENV}" - echo "PKG_NAME=${PKG_NAME}" >> "${GITHUB_ENV}" PKG_VERSION="${{ needs.calculate_version.outputs.version }}" - PKG_VERSION="${PKG_VERSION//-/\~}" + PKG_VERSION="${PKG_VERSION//-/\~}-1" echo "PKG_VERSION=${PKG_VERSION}" >> "${GITHUB_ENV}" - name: Package DEB if: matrix.debian != '' @@ -174,9 +189,10 @@ jobs: set -xeuo pipefail sudo gem install fpm sudo apt-get install -y debsigs + cp .fpm_systemd .fpm fpm -t deb \ -v "$PKG_VERSION" \ - -p "dist/${PKG_NAME}.deb" \ + -p "dist/sing-box_${{ needs.calculate_version.outputs.version }}_${{ matrix.os }}_${{ matrix.debian }}.deb" \ --architecture ${{ matrix.debian }} \ dist/sing-box=/usr/bin/sing-box curl -Lo '/tmp/debsigs.diff' 'https://gitlab.com/debsigs/debsigs/-/commit/160138f5de1ec110376d3c807b60a37388bc7c90.diff' @@ -191,9 +207,10 @@ jobs: run: |- set -xeuo pipefail sudo gem install fpm + cp .fpm_systemd .fpm fpm -t rpm \ -v "$PKG_VERSION" \ - -p "dist/${PKG_NAME}.rpm" \ + -p "dist/sing-box_${{ needs.calculate_version.outputs.version }}_${{ matrix.os }}_${{ matrix.rpm }}.rpm" \ --architecture ${{ matrix.rpm }} \ dist/sing-box=/usr/bin/sing-box cat > $HOME/.rpmmacros < /dev/null - sudo apt-get update - sudo apt-get install sing-box # or sing-box-beta - ``` + ```bash + sudo mkdir -p /etc/apt/keyrings && + sudo curl -fsSL https://sing-box.app/gpg.key -o /etc/apt/keyrings/sagernet.asc && + sudo chmod a+r /etc/apt/keyrings/sagernet.asc && + echo ' + Types: deb + URIs: https://deb.sagernet.org/ + Suites: * + Components: * + Enabled: yes + Signed-By: /etc/apt/keyrings/sagernet.asc + ' | sudo tee /etc/apt/sources.list.d/sagernet.sources && + sudo apt-get update && + sudo apt-get install sing-box # or sing-box-beta + ``` -=== ":material-redhat: Redhat / DNF" +=== ":material-redhat: Redhat / DNF 5" - ```bash - sudo dnf -y install dnf-plugins-core - sudo dnf config-manager --add-repo https://sing-box.app/sing-box.repo - sudo dnf install sing-box # or sing-box-beta - ``` - (This applies to any distribution that uses `dnf` as the package manager: Fedora, CentOS, even OpenSUSE with DNF installed.) + ```bash + sudo dnf config-manager addrepo --from-repofile=https://sing-box.app/sing-box.repo && + sudo dnf install sing-box # or sing-box-beta + ``` + +=== ":material-redhat: Redhat / DNF 4" + + ```bash + sudo dnf config-manager --add-repo https://sing-box.app/sing-box.repo && + sudo dnf -y install dnf-plugins-core && + sudo dnf install sing-box # or sing-box-beta + ``` ## :material-download-box: Manual Installation -=== ":material-debian: Debian / DEB" - - ```bash - bash <(curl -fsSL https://sing-box.app/deb-install.sh) - ``` - -=== ":material-redhat: Redhat / RPM" - - ```bash - bash <(curl -fsSL https://sing-box.app/rpm-install.sh) - ``` - (This applies to any distribution that uses `rpm` and `systemd`. Because of how `rpm` defines dependencies, if it installs, it probably works.) - -=== ":simple-archlinux: Archlinux / PKG" - - ```bash - bash <(curl -fsSL https://sing-box.app/arch-install.sh) - ``` + The script download and install the latest package from GitHub releases for deb or rpm based Linux distributions, ArchLinux and OpenWrt. + + ```shell + curl -fsSL https://sing-box.app/install.sh | sh + ``` + + or latest beta: + + ```shell + curl -fsSL https://sing-box.app/install.sh | sh -s -- --beta + ``` + + or specific version: + + ```shell + curl -fsSL https://sing-box.app/install.sh | sh -s -- --version + ``` ## :material-book-lock-open: Managed Installation diff --git a/docs/installation/package-manager.zh.md b/docs/installation/package-manager.zh.md index e4ff9da3..b59e95cb 100644 --- a/docs/installation/package-manager.zh.md +++ b/docs/installation/package-manager.zh.md @@ -9,22 +9,35 @@ icon: material/package === ":material-debian: Debian / APT" ```bash - sudo curl -fsSL https://sing-box.app/gpg.key -o /etc/apt/keyrings/sagernet.asc - sudo chmod a+r /etc/apt/keyrings/sagernet.asc - echo "deb [arch=`dpkg --print-architecture` signed-by=/etc/apt/keyrings/sagernet.asc] https://deb.sagernet.org/ * *" | \ - sudo tee /etc/apt/sources.list.d/sagernet.list > /dev/null - sudo apt-get update - sudo apt-get install sing-box # or sing-box-beta + sudo mkdir -p /etc/apt/keyrings && + sudo curl -fsSL https://sing-box.app/gpg.key -o /etc/apt/keyrings/sagernet.asc && + sudo chmod a+r /etc/apt/keyrings/sagernet.asc && + echo ' + Types: deb + URIs: https://deb.sagernet.org/ + Suites: * + Components: * + Enabled: yes + Signed-By: /etc/apt/keyrings/sagernet.asc + ' | sudo tee /etc/apt/sources.list.d/sagernet.sources && + sudo apt-get update && + sudo apt-get install sing-box # or sing-box-beta ``` -=== ":material-redhat: Redhat / DNF" +=== ":material-redhat: Redhat / DNF 5" - ```bash - sudo dnf -y install dnf-plugins-core - sudo dnf config-manager --add-repo https://sing-box.app/sing-box.repo - sudo dnf install sing-box # or sing-box-beta - ``` - (这适用于任何使用 `dnf` 作为包管理器的发行版:Fedora、CentOS,甚至安装了 DNF 的 OpenSUSE。) + ```bash + sudo dnf config-manager addrepo --from-repofile=https://sing-box.app/sing-box.repo && + sudo dnf install sing-box # or sing-box-beta + ``` + +=== ":material-redhat: Redhat / DNF 4" + + ```bash + sudo dnf config-manager --add-repo https://sing-box.app/sing-box.repo && + sudo dnf -y install dnf-plugins-core && + sudo dnf install sing-box # or sing-box-beta + ``` ## :material-download-box: 手动安装 diff --git a/docs/installation/tools/install.sh b/docs/installation/tools/install.sh new file mode 100755 index 00000000..e042dde8 --- /dev/null +++ b/docs/installation/tools/install.sh @@ -0,0 +1,97 @@ +#!/bin/sh + +download_beta=false +download_version="" + +for arg in "$@"; do + if [[ "$arg" == "--beta" ]]; then + download_beta=true + elif [[ "$arg" == "--version" ]]; then + download_version=true + elif [[ "$download_version" == 'true' ]]; then + download_version="$arg" + else + echo "Unknown argument: $arg" + echo "Usage: $0 [--beta] [--version ]" + exit 1 + fi +done + +if [[ $(command -v dpkg) ]]; then + os="linux" + arch=$(dpkg --print-architecture) + package_suffix=".deb" + package_install="dpkg -i" +elif [[ $(command -v dnf) ]]; then + os="linux" + arch=$(uname -m) + package_suffix=".rpm" + package_install="dnf install -y" +elif [[ $(command -v rpm) ]]; then + os="linux" + arch=$(uname -m) + package_suffix=".rpm" + package_install="rpm -i" +elif [[ $(command -v pacman) ]]; then + os="linux" + arch=$(uname -m) + package_suffix=".pkg.tar.zst" + package_install="pacman -U --noconfirm" +elif [[ $(command -v opkg) ]]; then + os="openwrt" + source /etc/os-release + arch="$OPENWRT_ARCH" + package_suffix=".ipk" + package_install="opkg update && opkg install -y" +else + echo "Missing supported package manager." + exit 1 +fi + +if [[ -z "$download_version" ]]; then + if [[ "$download_beta" != 'true' ]]; then + if [[ -n "$GITHUB_TOKEN" ]]; then + latest_release=$(curl -s --fail-with-body -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/repos/SagerNet/sing-box/releases/latest) + else + latest_release=$(curl -s --fail-with-body https://api.github.com/repos/SagerNet/sing-box/releases/latest) + fi + curl_exit_status=$? + if [[ $curl_exit_status -ne 0 ]]; then + echo "$latest_release" + exit $? + fi + download_version=$(echo "$latest_release" | grep tag_name | cut -d ":" -f2 | sed 's/\"//g;s/\,//g;s/\ //g;s/v//') + else + if [[ -n "$GITHUB_TOKEN" ]]; then + latest_release=$(curl -s --fail-with-body -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/repos/SagerNet/sing-box/releases) + else + latest_release=$(curl -s --fail-with-body https://api.github.com/repos/SagerNet/sing-box/releases) + fi + curl_exit_status=$? + if [[ $? -ne 0 ]]; then + echo "$latest_release" + exit $? + fi + download_version=$(echo "$latest_release" | grep tag_name | head -n 1 | cut -d ":" -f2 | sed 's/\"//g;s/\,//g;s/\ //g;s/v//') + fi +fi + +package_name="sing-box_${download_version}_${os}_${arch}${package_suffix}" +package_url="https://github.com/SagerNet/sing-box/releases/download/v${download_version}/${package_name}" + +echo "Downloading $package_url" +if [[ -n "$GITHUB_TOKEN" ]]; then + curl --fail-with-body -Lo "$package_name" -H "Authorization: token ${GITHUB_TOKEN}" "$package_url" +else + curl --fail-with-body -Lo "$package_name" "$package_url" +fi + +if [[ $? -ne 0 ]]; then + exit $? +fi + +if [[ $(command -v sudo) ]]; then + package_install="sudo $package_install" +fi + +echo "$package_install $package_name" && $package_install "$package_name" && rm "$package_name" diff --git a/release/config/openwrt.init b/release/config/openwrt.init old mode 100644 new mode 100755 index bae70e4b..9979fc1a --- a/release/config/openwrt.init +++ b/release/config/openwrt.init @@ -1,26 +1,27 @@ #!/bin/sh /etc/rc.common +USE_PROCD=1 +START=99 PROG="/usr/bin/sing-box" start_service() { config_load "sing-box" local enabled config_file working_directory - local log_stdout log_stderr + local log_stderr config_get_bool enabled "main" "enabled" "0" [ "$enabled" -eq "1" ] || return 0 config_get config_file "main" "conffile" "/etc/sing-box/config.json" config_get working_directory "main" "workdir" "/usr/share/sing-box" - config_get_bool log_stdout "main" "log_stdout" "1" config_get_bool log_stderr "main" "log_stderr" "1" procd_open_instance - procd_swet_param command "$PROG" run -c "$conffile" -D "$workdir" - procd_set_param file "$conffile" + procd_set_param command "$PROG" run -c "$config_file" -D "$working_directory" + procd_set_param file "$config_file" procd_set_param stderr "$log_stderr" procd_set_param limits core="unlimited" - sprocd_set_param limits nofile="1000000 1000000" + procd_set_param limits nofile="1000000 1000000" procd_set_param respawn procd_close_instance @@ -28,4 +29,4 @@ start_service() { service_triggers() { procd_add_reload_trigger "sing-box" -} \ No newline at end of file +} diff --git a/release/config/openwrt.keep b/release/config/openwrt.keep new file mode 100644 index 00000000..b26dd531 --- /dev/null +++ b/release/config/openwrt.keep @@ -0,0 +1 @@ +/etc/sing-box/ diff --git a/release/config/openwrt.prerm b/release/config/openwrt.prerm new file mode 100755 index 00000000..12d06ec7 --- /dev/null +++ b/release/config/openwrt.prerm @@ -0,0 +1,4 @@ +#!/bin/sh +[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0 +. ${IPKG_INSTROOT}/lib/functions.sh +default_prerm $0 $@