commit 28bc2116fd608b71390692d6a983f9a8e74bb1e4 Author: Wang Defa <1+wangdefa@noreply.gitea.bcde.io> Date: Tue Jun 9 11:28:03 2026 +0800 初始化 XXXig 打包部署脚本与 CI 流水线 Co-Authored-By: Claude Opus 4.8 diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml new file mode 100644 index 0000000..b4e2b98 --- /dev/null +++ b/.gitea/workflows/ci.yaml @@ -0,0 +1,232 @@ +# .gitea/workflows/ci.yaml +name: Build and Release + +on: + push: + branches: [main, develop] + tags: ['*'] + +env: + DOCKER_BUILDKIT: "1" + PRODUCT_NAME: "xxxig" + PACKAGE_VERSION: "6.26.0" + BUILDX_NO_DEFAULT_ATTESTATIONS: "1" + +jobs: + build-and-test: + runs-on: ${{ matrix.arch == 'amd64' && 'ubuntu-latest-amd64' || 'ubuntu-latest-arm64' }} + strategy: + matrix: + arch: [amd64, arm64] + distro: [ubuntu, alpine] + steps: + - uses: actions/checkout@v4 + + - name: Setup Docker Buildx + run: | + # 创建 buildx builder(原生构建不需要 QEMU) + docker buildx create --use --name native-builder \ + --driver docker-container \ + --driver-opt network=host \ + --driver-opt env.BUILDKIT_STEP_LOG_MAX_SIZE=50000000 \ + --driver-opt env.BUILDKIT_STEP_LOG_MAX_SPEED=10000000 \ + || true + docker buildx inspect --bootstrap + + - name: Build binaries + run: | + XXXIG_VERSION=v${PACKAGE_VERSION} # 上游源码 git tag 带 v 前缀,需补回 + PLATFORM="linux/${{ matrix.arch }}" + + echo "🏗️ Building ${PLATFORM} on native ${{ matrix.arch }} runner" + echo "📦 Distribution: ${{ matrix.distro }}" + + # 设置 BuildKit 优化参数 + export BUILDKIT_PROGRESS=plain + + docker buildx build --pull \ + --platform ${PLATFORM} \ + --build-arg XXXIG_VERSION=${XXXIG_VERSION} \ + --output type=local,dest=./output \ + -f docker/Dockerfile.${{ matrix.distro }} . + + - name: Package and test + run: | + DIR="./output/linux_${{ matrix.arch }}" + + if [ ! -d "$DIR" ]; then + echo "❌ 构建输出目录不存在: $DIR" + exit 1 + fi + + TARGZ="${PRODUCT_NAME}-${{ matrix.arch }}-${{ matrix.distro }}-${PACKAGE_VERSION}.tar.gz" + tar -czf "${TARGZ}" -C "$DIR" . + + echo "📦 Created package: ${TARGZ}" + ls -lh "${TARGZ}" + + # 快速验证 + mkdir -p test && tar -xzf "${TARGZ}" -C test + test/xxxigDaemon --version 2>/dev/null || echo "⚠️ 跳过版本检查" + rm -rf test + + - name: Build Debian package + if: matrix.distro == 'ubuntu' + run: | + # 安装 dpkg-deb(如果需要) + sudo apt-get update && sudo apt-get install -y dpkg-dev + + TARGZ="${PRODUCT_NAME}-${{ matrix.arch }}-${{ matrix.distro }}-${PACKAGE_VERSION}.tar.gz" + + echo "📦 Building Debian package for ${{ matrix.arch }}..." + chmod +x debian/build-deb.sh + ./debian/build-deb.sh ${{ matrix.arch }} ${PACKAGE_VERSION} "${TARGZ}" + + ls -lh *.deb + + - uses: https://github.com/ChristopherHX/gitea-upload-artifact@v4 + with: + name: binaries-${{ matrix.arch }}-${{ matrix.distro }} + path: | + *.tar.gz + *.deb + retention-days: 1 + + release: + runs-on: ubuntu-latest-amd64 + needs: build-and-test + if: startsWith(github.ref, 'refs/tags/') + steps: + - uses: https://github.com/ChristopherHX/gitea-download-artifact@v4 + with: + pattern: binaries-* + path: ./packages + merge-multiple: true + + - name: Upload packages and create release + env: + TOKEN: ${{ secrets.BUILD_TOKEN }} + TAG: ${{ github.ref_name }} + run: | + cd packages + + # 提取仓库信息(移除 https:// 前缀和仓库路径) + REGISTRY=$(echo "${{ gitea.server_url }}" | sed 's|https\?://||') + OWNER="${{ gitea.repository_owner }}" + REPO_NAME=$(echo "${{ gitea.repository }}" | cut -d'/' -f2) + VERSION="${TAG#v}" # 包版本:去掉 git tag 的 v 前缀(registry 路径/下载名/Release 标题用) + + echo "📦 上传包到 Generic Package Registry..." + echo " Registry: ${REGISTRY}" + echo " Owner: ${OWNER}" + echo " Package: ${PRODUCT_NAME}" + echo " Version: ${VERSION}" + + # 上传所有 tar.gz 包到 Generic Package Registry + for file in *.tar.gz; do + [ ! -f "$file" ] && continue + echo " ⬆️ $file" + curl -fsSL -X PUT \ + -H "Authorization: token ${TOKEN}" \ + --upload-file "$file" \ + "https://${REGISTRY}/api/packages/${OWNER}/generic/${PRODUCT_NAME}/${VERSION}/$file" || { + echo "❌ 上传失败: $file" + exit 1 + } + done + + # 上传 Debian 包到 Debian Package Registry (通用稳定版) + echo "" + echo "📦 上传 Debian 包到 Debian Package Registry..." + for file in *.deb; do + [ ! -f "$file" ] && continue + + # 上传到 stable (通用稳定版) + echo " ⬆️ $file → stable" + curl -fsSL -X PUT \ + -H "Authorization: token ${TOKEN}" \ + --upload-file "$file" \ + "https://${REGISTRY}/api/packages/${OWNER}/debian/pool/stable/main/upload" || { + echo "❌ Debian 包上传失败: $file (stable)" + exit 1 + } + done + + # 生成 Release 描述 + echo "" + echo "📝 生成 Release..." + + # 拼接 tar.gz 下载链接 + ASSETS=$(for f in *.tar.gz; do + [ -f "$f" ] || continue + echo "- [\`$f\`](https://${REGISTRY}/api/packages/${OWNER}/generic/${PRODUCT_NAME}/${VERSION}/$f)" + done) + + BODY=$(cat < " + echo "Example: $0 amd64 6.26.0 xxxig-amd64-ubuntu-6.26.0.tar.gz" + exit 1 +fi + +ARCH=$1 +VERSION=$2 +TARGZ_FILE=$3 +PKG_NAME="xxxig" +DEB_VERSION="${VERSION#v}" # Debian 版本号必须以数字开头,去掉可能的 v 前缀 + +# 转换架构名称(Docker 使用的架构名到 Debian 架构名) +case "$ARCH" in + amd64) + DEB_ARCH="amd64" + ;; + arm64) + DEB_ARCH="arm64" + ;; + *) + echo "Unsupported architecture: $ARCH" + exit 1 + ;; +esac + +DEB_FILE="${PKG_NAME}_${DEB_VERSION}_${DEB_ARCH}.deb" + +echo "📦 Building Debian package: ${DEB_FILE}" +echo " Architecture: ${DEB_ARCH}" +echo " Version: ${DEB_VERSION}" +echo " Source: ${TARGZ_FILE}" + +# 创建临时目录 +BUILD_DIR=$(mktemp -d) +trap "rm -rf $BUILD_DIR" EXIT + +# 创建包目录结构 +PKG_DIR="${BUILD_DIR}/${PKG_NAME}_${DEB_VERSION}_${DEB_ARCH}" +mkdir -p "${PKG_DIR}/DEBIAN" +mkdir -p "${PKG_DIR}/opt/xxxig" +mkdir -p "${PKG_DIR}/lib/systemd/system" + +# 解压二进制文件 +echo "📂 Extracting binaries..." +tar -xzf "${TARGZ_FILE}" -C "${PKG_DIR}/opt/xxxig" + +# 生成 control 文件 +echo "📝 Generating control file..." +sed -e "s/{{VERSION}}/${DEB_VERSION}/" \ + -e "s/{{ARCH}}/${DEB_ARCH}/" \ + debian/control.template > "${PKG_DIR}/DEBIAN/control" + +# 复制维护脚本 +echo "📋 Copying maintainer scripts..." +cp debian/postinst "${PKG_DIR}/DEBIAN/postinst" +cp debian/prerm "${PKG_DIR}/DEBIAN/prerm" +cp debian/postrm "${PKG_DIR}/DEBIAN/postrm" +chmod 755 "${PKG_DIR}/DEBIAN/postinst" +chmod 755 "${PKG_DIR}/DEBIAN/prerm" +chmod 755 "${PKG_DIR}/DEBIAN/postrm" + +# 复制 systemd service 文件 +echo "🔧 Installing systemd services..." +cp debian/xxxig-server.service "${PKG_DIR}/lib/systemd/system/" +cp debian/xxxig-daemon.service "${PKG_DIR}/lib/systemd/system/" + +# 设置权限 +chmod 755 "${PKG_DIR}/opt/xxxig/xxxigServer" +chmod 755 "${PKG_DIR}/opt/xxxig/xxxigDaemon" +chmod 755 "${PKG_DIR}/opt/xxxig/xxxig" +chmod 644 "${PKG_DIR}/opt/xxxig/config.json" +chmod 644 "${PKG_DIR}/opt/xxxig/config_cc.json" +chmod 644 "${PKG_DIR}/opt/xxxig/index.html" +chmod 644 "${PKG_DIR}/lib/systemd/system/xxxig-server.service" +chmod 644 "${PKG_DIR}/lib/systemd/system/xxxig-daemon.service" + +# 构建 deb 包 +echo "🔨 Building package..." +dpkg-deb --build --root-owner-group "${PKG_DIR}" "${DEB_FILE}" + +# 检查包 +echo "✅ Package built successfully!" +echo "📦 Package: $(pwd)/${DEB_FILE}" +echo "📊 Package info:" +dpkg-deb --info "${DEB_FILE}" + +echo "" +echo "🎉 Done!" diff --git a/debian/control.template b/debian/control.template new file mode 100644 index 0000000..8697fb8 --- /dev/null +++ b/debian/control.template @@ -0,0 +1,18 @@ +Package: xxxig +Version: {{VERSION}} +Section: net +Priority: optional +Architecture: {{ARCH}} +Depends: libc6, libuv1, libssl3 | libssl1.1, libhwloc15 | libhwloc5 +Maintainer: XXXig Team +Homepage: https://github.com/wangdefaa/xxxig +Description: Cryptocurrency mining software suite + XXXig is a customized build of XMRig, + a cryptocurrency mining software with centralized management. + . + This package includes: + - xxxigServer: Central control server with web UI + - xxxigDaemon: Client daemon that connects to the server + - xxxig: Mining executable controlled by the daemon + - Systemd service configurations + - Default configuration files diff --git a/debian/postinst b/debian/postinst new file mode 100755 index 0000000..773aeac --- /dev/null +++ b/debian/postinst @@ -0,0 +1,73 @@ +#!/bin/sh +set -e + +# Create user and group if they don't exist +if ! getent group xxxig >/dev/null; then + addgroup --system xxxig +fi + +if ! getent passwd xxxig >/dev/null; then + adduser --system --ingroup xxxig --no-create-home \ + --home /opt/xxxig --shell /usr/sbin/nologin \ + --gecos "XXXig Service" xxxig +fi + +# Create log directory +mkdir -p /var/log/xxxig +chown xxxig:xxxig /var/log/xxxig +chmod 750 /var/log/xxxig + +# Create config directory +mkdir -p /etc/xxxig + +# Copy default configs if they don't exist +if [ ! -f /etc/xxxig/config.json ]; then + cp /opt/xxxig/config.json /etc/xxxig/config.json + chown xxxig:xxxig /etc/xxxig/config.json + chmod 640 /etc/xxxig/config.json +fi + +if [ ! -f /etc/xxxig/config_cc.json ]; then + cp /opt/xxxig/config_cc.json /etc/xxxig/config_cc.json + chown xxxig:xxxig /etc/xxxig/config_cc.json + chmod 640 /etc/xxxig/config_cc.json +fi + +# Set permissions +chown -R root:root /opt/xxxig +chmod -R 755 /opt/xxxig + +# Reload systemd +if [ -d /run/systemd/system ]; then + systemctl daemon-reload + + # 升级时重启正在运行的服务以加载新二进制;try-restart 不会启动未运行的服务, + # 故首次安装仍保持"不自动启动"语义 + systemctl try-restart xxxig-daemon.service xxxig-server.service 2>/dev/null || true + + # Note: Services are NOT auto-enabled or auto-started + # Users should manually enable the services they need: + # systemctl enable xxxig-server.service + # systemctl start xxxig-server.service + # or + # systemctl enable xxxig-daemon.service + # systemctl start xxxig-daemon.service +fi + +echo "" +echo "✅ XXXig installed successfully!" +echo "" +echo "📁 Important paths:" +echo " Config files: /etc/xxxig/config.json (daemon)" +echo " /etc/xxxig/config_cc.json (server)" +echo " Log directory: /var/log/xxxig" +echo " Binaries: /opt/xxxig/xxxigServer (control server)" +echo " /opt/xxxig/xxxigDaemon (mining daemon)" +echo " /opt/xxxig/xxxig (miner executable)" +echo " Systemd services: xxxig-server.service (control server)" +echo " xxxig-daemon.service (mining daemon)" +echo "" +echo "💡 Tip: Your config files will NOT be overwritten during package upgrades." +echo "" + +exit 0 diff --git a/debian/postrm b/debian/postrm new file mode 100755 index 0000000..4a33c79 --- /dev/null +++ b/debian/postrm @@ -0,0 +1,35 @@ +#!/bin/sh +set -e + +case "$1" in + purge) + # Remove user and group + if getent passwd xxxig >/dev/null; then + deluser --quiet xxxig || true + fi + + if getent group xxxig >/dev/null; then + delgroup --quiet xxxig || true + fi + + # Remove data directories (only on purge) + rm -rf /var/log/xxxig + rm -rf /etc/xxxig + ;; + + remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + # Do nothing + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# Reload systemd +if [ -d /run/systemd/system ]; then + systemctl daemon-reload +fi + +exit 0 \ No newline at end of file diff --git a/debian/prerm b/debian/prerm new file mode 100755 index 0000000..5332521 --- /dev/null +++ b/debian/prerm @@ -0,0 +1,19 @@ +#!/bin/sh +set -e + +# 仅在卸载(remove)时停用服务;升级(upgrade)时保持运行与开机自启状态 +if [ "$1" = "remove" ] && [ -d /run/systemd/system ]; then + for service in xxxig-server.service xxxig-daemon.service; do + if systemctl is-active --quiet "$service"; then + echo "Stopping $service..." + systemctl stop "$service" + fi + + if systemctl is-enabled --quiet "$service"; then + echo "Disabling $service..." + systemctl disable "$service" + fi + done +fi + +exit 0 diff --git a/debian/xxxig-daemon.service b/debian/xxxig-daemon.service new file mode 100644 index 0000000..93cf9f2 --- /dev/null +++ b/debian/xxxig-daemon.service @@ -0,0 +1,40 @@ +[Unit] +Description=XXXig Daemon (Miner Client) +After=network.target + +[Service] +Type=simple + +# 工作目录 +WorkingDirectory=/opt/xxxig + +# 执行命令 +ExecStart=/opt/xxxig/xxxigDaemon --config /etc/xxxig/config.json --log-file=/var/log/xxxig/daemon.log + +# 重启策略 +Restart=always +RestartSec=10 + +# 用户和组 +User=xxxig +Group=xxxig + +# 安全设置 +NoNewPrivileges=true +PrivateTmp=true +ProtectSystem=strict +ProtectHome=true +ReadWritePaths=/var/log/xxxig + +# 日志设置 +StandardOutput=journal +StandardError=journal +SyslogIdentifier=xxxig-daemon + +# 资源限制 +LimitNOFILE=65535 +LimitMEMLOCK=infinity +AmbientCapabilities=CAP_IPC_LOCK + +[Install] +WantedBy=multi-user.target diff --git a/debian/xxxig-server.service b/debian/xxxig-server.service new file mode 100644 index 0000000..0882843 --- /dev/null +++ b/debian/xxxig-server.service @@ -0,0 +1,38 @@ +[Unit] +Description=XXXig Server (Control Center) +After=network.target + +[Service] +Type=simple + +# 工作目录 +WorkingDirectory=/opt/xxxig + +# 执行命令 +ExecStart=/opt/xxxig/xxxigServer --config /etc/xxxig/config_cc.json --log-file=/var/log/xxxig/server.log + +# 重启策略 +Restart=always +RestartSec=10 + +# 用户和组 +User=xxxig +Group=xxxig + +# 安全设置 +NoNewPrivileges=true +PrivateTmp=true +ProtectSystem=strict +ProtectHome=true +ReadWritePaths=/var/log/xxxig + +# 日志设置 +StandardOutput=journal +StandardError=journal +SyslogIdentifier=xxxig-server + +# 资源限制 +LimitNOFILE=65535 + +[Install] +WantedBy=multi-user.target diff --git a/docker/Dockerfile.alpine b/docker/Dockerfile.alpine new file mode 100644 index 0000000..3389df4 --- /dev/null +++ b/docker/Dockerfile.alpine @@ -0,0 +1,86 @@ +FROM alpine:latest AS base + +# 根据目标架构设置构建参数 +ARG TARGETARCH + +RUN apk update && apk add --no-cache \ + git \ + make \ + cmake \ + libstdc++ \ + gcc \ + g++ \ + automake \ + libtool \ + autoconf \ + linux-headers \ + libuv-dev \ + openssl-dev \ + hwloc-dev + +FROM base AS build + +ARG TARGZ_FILE +ARG XXXIG_VERSION +ARG TARGETARCH +ARG BUILDPLATFORM +ARG TARGETPLATFORM + +RUN git clone --recursive https://github.com/wangdefaa/xxxig.git && \ + cd xxxig && \ + git checkout ${XXXIG_VERSION} + +WORKDIR /xxxig + + +# 根据目标架构优化编译 +RUN mkdir build && cd scripts && chmod +x ./*.sh && \ + if [ "$BUILDPLATFORM" != "$TARGETPLATFORM" ]; then \ + MAKE_JOBS="-j2"; \ + else \ + MAKE_JOBS="-j$(nproc)"; \ + fi && \ + echo "Building with parallel jobs: $MAKE_JOBS (cross-compile: $([ "$BUILDPLATFORM" != "$TARGETPLATFORM" ] && echo yes || echo no))" && \ + ./build_deps.sh $MAKE_JOBS && cd ../build && \ + if [ "$TARGETARCH" = "arm64" ]; then \ + cmake .. -DWITH_CC_CLIENT=ON \ + -DWITH_CC_SERVER=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DXMRIG_DEPS=scripts/deps \ + -DBUILD_STATIC=ON \ + -DWITH_ZLIB=ON \ + -DWITH_OPENCL=OFF \ + -DWITH_CUDA=OFF \ + -DARM_TARGET=8; \ + elif [ "$TARGETARCH" = "arm" ]; then \ + cmake .. -DWITH_CC_CLIENT=ON \ + -DWITH_CC_SERVER=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DXMRIG_DEPS=scripts/deps \ + -DBUILD_STATIC=ON \ + -DWITH_ZLIB=ON \ + -DWITH_OPENCL=OFF \ + -DWITH_CUDA=OFF \ + -DARM_TARGET=7; \ + else \ + cmake .. -DWITH_CC_CLIENT=ON \ + -DWITH_CC_SERVER=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DXMRIG_DEPS=scripts/deps \ + -DBUILD_STATIC=ON \ + -DWITH_ZLIB=ON \ + -DWITH_OPENCL=OFF \ + -DWITH_CUDA=OFF; \ + fi && \ + make $MAKE_JOBS + +FROM scratch + +ARG TARGETARCH + +COPY --from=build /xxxig/build/xxxigDaemon /linux_${TARGETARCH}/xxxigDaemon +COPY --from=build /xxxig/build/xxxig /linux_${TARGETARCH}/xxxig +COPY --from=build /xxxig/build/xxxigServer /linux_${TARGETARCH}/xxxigServer +COPY --from=build /xxxig/src/config_cc.json /linux_${TARGETARCH}/config_cc.json +COPY --from=build /xxxig/src/config.json /linux_${TARGETARCH}/config.json +COPY --from=build /xxxig/index.html /linux_${TARGETARCH}/index.html diff --git a/docker/Dockerfile.ubuntu b/docker/Dockerfile.ubuntu new file mode 100644 index 0000000..2f67dd2 --- /dev/null +++ b/docker/Dockerfile.ubuntu @@ -0,0 +1,86 @@ +FROM ubuntu:20.04 AS base + +ARG TARGETARCH +ARG BUILDPLATFORM + +ENV DEBIAN_FRONTEND=noninteractive + +# 根据目标架构安装相应的交叉编译工具链 +RUN apt-get update && apt-get install -y \ + git \ + wget \ + build-essential \ + cmake \ + libuv1-dev \ + libssl-dev \ + libhwloc-dev \ + && if [ "$TARGETARCH" = "arm64" ] && [ "$BUILDPLATFORM" != "linux/arm64" ]; then \ + apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu; \ + elif [ "$TARGETARCH" = "arm" ] && [ "$BUILDPLATFORM" != "linux/arm/v7" ]; then \ + apt-get install -y gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf; \ + fi \ + && rm -rf /var/lib/apt/lists/* + +FROM base AS build + +ARG TARGZ_FILE +ARG TARGET_ARCH +ARG XXXIG_VERSION +ARG TARGETARCH +ARG BUILDPLATFORM +ARG TARGETPLATFORM + +RUN git clone --recursive https://github.com/wangdefaa/xxxig.git && \ + cd xxxig && \ + git checkout ${XXXIG_VERSION} + +WORKDIR /xxxig + +# 根据目标架构设置编译环境和参数 +RUN mkdir build && cd scripts && chmod +x ./*.sh && \ + if [ "$BUILDPLATFORM" != "$TARGETPLATFORM" ]; then \ + MAKE_JOBS="-j2"; \ + else \ + MAKE_JOBS="-j$(nproc)"; \ + fi && \ + echo "Building with parallel jobs: $MAKE_JOBS (cross-compile: $([ "$BUILDPLATFORM" != "$TARGETPLATFORM" ] && echo yes || echo no))" && \ + ./build_deps.sh $MAKE_JOBS && cd ../build && \ + if [ "$TARGETARCH" = "arm64" ] && [ "$BUILDPLATFORM" != "linux/arm64" ]; then \ + export CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++; \ + cmake .. -DWITH_CC_CLIENT=ON \ + -DWITH_CC_SERVER=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc \ + -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ \ + -DARM_TARGET=8 \ + -DXMRIG_DEPS=scripts/deps \ + -DWITH_ZLIB=ON; \ + elif [ "$TARGETARCH" = "arm" ] && [ "$BUILDPLATFORM" != "linux/arm/v7" ]; then \ + export CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++; \ + cmake .. -DWITH_CC_CLIENT=ON \ + -DWITH_CC_SERVER=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc \ + -DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ \ + -DARM_TARGET=7 \ + -DXMRIG_DEPS=scripts/deps \ + -DWITH_ZLIB=ON; \ + else \ + cmake .. -DWITH_CC_CLIENT=ON \ + -DWITH_CC_SERVER=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DXMRIG_DEPS=scripts/deps \ + -DWITH_ZLIB=ON; \ + fi && \ + make $MAKE_JOBS + +FROM scratch + +ARG TARGETARCH + +COPY --from=build /xxxig/build/xxxigDaemon /linux_${TARGETARCH}/xxxigDaemon +COPY --from=build /xxxig/build/xxxig /linux_${TARGETARCH}/xxxig +COPY --from=build /xxxig/build/xxxigServer /linux_${TARGETARCH}/xxxigServer +COPY --from=build /xxxig/src/config_cc.json /linux_${TARGETARCH}/config_cc.json +COPY --from=build /xxxig/src/config.json /linux_${TARGETARCH}/config.json +COPY --from=build /xxxig/index.html /linux_${TARGETARCH}/index.html diff --git a/script/README.md b/script/README.md new file mode 100644 index 0000000..7026b47 --- /dev/null +++ b/script/README.md @@ -0,0 +1,255 @@ +# XXXig 安装脚本 + +本目录包含 XXXig 的安装和卸载脚本。 + +## 脚本列表 + +### 1. install.sh - 通用安装脚本 +从 Gitea Generic Package Registry 下载 tar.gz 包并安装。 + +**支持系统:** +- Alpine Linux (OpenRC) +- Ubuntu/Debian (systemd) + +**使用方法:** +```bash +# 基本安装 +sudo ./install.sh -o pool.example.com:3333 -w YOUR_WALLET_ADDRESS + +# 指定版本和线程数 +sudo ./install.sh -v 6.26.0 -t 4 -o pool.example.com:3333 -w YOUR_WALLET + +# 启用高级功能 +sudo ./install.sh -o pool.example.com:3333 -w YOUR_WALLET \ + --1gb-pages --tls --keepalive \ + --cc --cc-url http://server:3344 --cc-token YOUR_TOKEN +``` + +### 2. install.deb.sh - DEB 包安装脚本 +通过 APT 仓库直接安装。 + +**支持系统:** +- Ubuntu/Debian (systemd) + +**使用方法:** +```bash +# 基本安装 +sudo ./install.deb.sh -o pool.example.com:3333 -w YOUR_WALLET_ADDRESS + +# 指定版本 +sudo ./install.deb.sh -v 6.26.0 -o pool.example.com:3333 -w YOUR_WALLET + +# 查看可用版本 +apt-cache policy xxxig +``` + +### 3. uninstall.sh - 卸载脚本 +通用卸载脚本,自动检测安装方式。 + +**使用方法:** +```bash +# 交互式卸载(推荐) +sudo ./uninstall.sh + +# 直接卸载,不确认 +sudo ./uninstall.sh -y + +# 完全清除(包括配置文件和日志) +sudo ./uninstall.sh --purge -y +``` + +## 命令行参数 + +### 通用参数(两种安装脚本都支持) + +| 参数 | 说明 | 默认值 | +|------|------|--------| +| `-v, --version` | 版本号 | latest | +| `-t, --threads` | 线程数 | 自动 (CPU 核心数) | +| `-a, --algo` | 算法 | rx/0 | +| `-o, --pool` | 矿池地址 | **必需** | +| `-w, --wallet` | 钱包地址 | 自动生成 | +| `-p, --password` | 矿池密码 | 自动生成 | +| `--1gb-pages` | 启用 1GB 大页 | false | +| `--tls` | 启用 TLS | false | +| `--keepalive` | 启用 KeepAlive | false | +| `--daemon` | 启用 SOLO 挖矿 | false | +| `--nicehash` | 启用 NiceHash 模式 | **true** | +| `--verbose` | 启用详细输出 | **true** | +| `--submit-to-origin` | 提交到原始矿池 | false | +| `--self-select` | 自选矿池地址 | - | +| `--cc` | 启用 CC | false | +| `--cc-url` | CC 服务器地址 | - | +| `--cc-work-id` | CC 工作 ID | 自动生成 | +| `--cc-token` | CC 访问令牌 | - | +| `--cc-tls` | 启用 CC TLS | false | + +## 安装路径 + +### tar.gz 安装 +``` +/etc/miner/xxxig/ +├── config.json # 配置文件 +├── xxxigDaemon # 守护进程 +├── xxxig # 挖矿程序 +└── xxxig.log # 日志文件 +``` + +**服务文件:** +- Alpine: `/etc/init.d/xxxig` +- Ubuntu/Debian: `/etc/systemd/system/xxxig.service` + +### DEB 包安装 +``` +/etc/xxxig/ +└── config.json # 配置文件 + +/var/log/xxxig/ # 日志目录 + +/opt/xxxig/ +├── xxxigDaemon # 守护进程 +├── xxxig # 挖矿程序 +└── xxxigServer # 控制服务器 +``` + +**服务文件:** +- `/etc/systemd/system/xxxig-daemon.service` +- `/etc/systemd/system/xxxig-server.service` + +## 服务管理 + +### Alpine Linux +```bash +# 查看状态 +rc-service xxxig status + +# 启动/停止/重启 +rc-service xxxig start +rc-service xxxig stop +rc-service xxxig restart + +# 查看日志 +tail -f /etc/miner/xxxig/xxxig.log +``` + +### Ubuntu/Debian + +#### tar.gz 安装 +```bash +# 查看状态 +systemctl status xxxig + +# 启动/停止/重启 +systemctl start xxxig +systemctl stop xxxig +systemctl restart xxxig + +# 查看日志 +journalctl -u xxxig -f +``` + +#### DEB 包安装 +```bash +# 查看状态 +systemctl status xxxig-daemon + +# 启动/停止/重启 +systemctl start xxxig-daemon +systemctl stop xxxig-daemon +systemctl restart xxxig-daemon + +# 查看日志 +journalctl -u xxxig-daemon -f +``` + +## 配置文件 + +配置文件为 JSON 格式,位于: +- tar.gz: `/etc/miner/xxxig/config.json` +- DEB: `/etc/xxxig/config.json` + +修改配置后需要重启服务: +```bash +# Alpine +rc-service xxxig restart + +# Ubuntu/Debian (tar.gz) +systemctl restart xxxig + +# Ubuntu/Debian (DEB) +systemctl restart xxxig-daemon +``` + +## 升级版本 + +### tar.gz 安装 +重新运行安装脚本,指定新版本: +```bash +sudo ./install.sh -v 6.26.0 -o pool.example.com:3333 -w YOUR_WALLET +``` + +### DEB 包安装 +使用 APT 升级: +```bash +sudo apt-get update +sudo apt-get install xxxig +``` + +## 故障排查 + +### 检查服务状态 +```bash +# Alpine +rc-service xxxig status + +# Ubuntu/Debian +systemctl status xxxig # 或 xxxig-daemon +``` + +### 查看日志 +```bash +# Alpine / tar.gz +tail -f /etc/miner/xxxig/xxxig.log + +# Ubuntu/Debian (tar.gz) +journalctl -u xxxig -f + +# Ubuntu/Debian (DEB) +journalctl -u xxxig-daemon -f +``` + +### 手动测试 +```bash +# tar.gz 安装 +/etc/miner/xxxig/xxxigDaemon -c /etc/miner/xxxig/config.json + +# DEB 包安装 +xxxigDaemon -c /etc/xxxig/config.json +``` + +### 常见问题 + +**问题: 下载失败** +```bash +# 检查网络连接 +curl -I https://gitea.bcde.io + +# 手动下载测试 +curl -O https://gitea.bcde.io/api/packages/wangdefa/generic/xxxig/6.26.0/xxxig-amd64-ubuntu-6.26.0.tar.gz +``` + +**问题: 服务无法启动** +```bash +# 检查配置文件 +cat /etc/miner/xxxig/config.json | jq . + +# 检查权限 +ls -la /etc/miner/xxxig/ +``` + +**问题: APT 更新失败 (DEB)** +```bash +# 清理并重新添加源 +sudo rm /etc/apt/sources.list.d/xxxig.list +sudo ./install_deb.sh -o pool.example.com:3333 -w YOUR_WALLET +``` diff --git a/script/install.deb.sh b/script/install.deb.sh new file mode 100755 index 0000000..72d5671 --- /dev/null +++ b/script/install.deb.sh @@ -0,0 +1,285 @@ +#!/bin/bash +# +# XXXigCC 安装脚本 - DEB 版本 +# 通过 APT 从 Gitea Generic Package Registry 安装 XXXigCC +# + +set -e + +declare -r BLUE="\033[0;34m" +declare -r RED="\033[0;31m" +declare -r GREEN="\033[0;32m" +declare -r YELLOW="\033[0;33m" +declare -r RESET="\033[0m" + +# 基本配置 +CONFIG_DIR="/etc/xxxig" +LOG_DIR="/var/log/xxxig" +CONFIG_FILE="$CONFIG_DIR/config.json" + +# Gitea 配置 +GITEA_SERVER="gitea.bcde.io" +GITEA_OWNER="wangdefa" + +# 默认参数 +DEFAULT_VERSION="latest" +DEFAULT_THREADS=0 +DEFAULT_POOL_ALGO="rx/0" +DEFAULT_POOL_TLS="false" +DEFAULT_POOL_KEEPALIVE="false" +DEFAULT_POOL_DAEMON="false" +DEFAULT_POOL_SUBMIT_TO_ORIGIN="false" +DEFAULT_POOL_NICEHASH="true" +DEFAULT_ONE_GB_PAGES="false" +DEFAULT_VERBOSE="true" +DEFAULT_CC_ENABLED="false" +DEFAULT_CC_TLS="false" + +# 辅助函数 +log() { echo -e "${1}${2}${RESET}"; } +error() { log "$RED" "错误: $1"; exit 1; } + +check_os() { + grep -qiE 'debian|ubuntu' /etc/os-release || error "仅支持 Debian/Ubuntu 系统" +} + +get_arch() { + case $(uname -m) in + x86_64) echo "amd64" ;; + aarch64) echo "arm64" ;; + *) error "不支持的架构: $(uname -m)" ;; + esac +} + +# 添加 APT 源并更新 +add_apt_repository() { + curl https://${GITEA_SERVER}/api/packages/${GITEA_OWNER}/debian/repository.key -o /etc/apt/keyrings/gitea-${GITEA_OWNER}.asc + echo "deb [signed-by=/etc/apt/keyrings/gitea-${GITEA_OWNER}.asc] https://${GITEA_SERVER}/api/packages/${GITEA_OWNER}/debian stable main" \ + >/etc/apt/sources.list.d/${GITEA_OWNER}.list + apt-get update -qq +} + +# 卸载旧版本 +uninstall_xxxig() { + systemctl stop xxxig-daemon xxxig-server 2>/dev/null || true + systemctl disable xxxig-daemon xxxig-server 2>/dev/null || true + apt-get remove -y xxxig 2>/dev/null || true + rm -rf "$CONFIG_DIR" "$LOG_DIR" /etc/apt/sources.list.d/xxxig.list + systemctl daemon-reload 2>/dev/null || true +} + +# 安装并启动服务 +install_and_start() { + log "$BLUE" "安装 XXXig $version..." + if [[ "$version" == "latest" ]]; then + apt-get install -y xxxig + else + apt-get install -y xxxig="${version#v}" + fi + + log "$BLUE" "启动服务..." + systemctl daemon-reload + systemctl enable --now xxxig-daemon.service + log "$GREEN" "安装完成" +} + +# 配置 CPU 亲和性 +configure_cpu_rx() { + local cpu_cores=$(nproc) + local rx_array="" step=1 + + [[ "$threads" -le $((cpu_cores / 2)) ]] && step=2 + + for ((i = 0; i < threads; i++)); do + [[ $i -gt 0 ]] && rx_array+=", " + rx_array+="$((i * step))" + done + + local field="rx" + [[ "$pool_algo" == "panthera" ]] && field="panthera" + + jq ".cpu.$field = [ $rx_array ]" "$CONFIG_FILE" >"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE" +} + +# 配置大页内存 +configure_hugepages() { + if [[ "$one_gb_pages" == "true" ]]; then + log "$BLUE" "配置 大页内存..." + sysctl -w vm.nr_hugepages=3072 + echo "vm.nr_hugepages=3072" >>/etc/sysctl.conf + log "$GREEN" "大页内存配置完成" + fi +} + +# 更新配置文件 +replace_config() { + [[ ! -f "$CONFIG_FILE" ]] && error "配置文件缺失" + + local jq_cmd=".\"log-file\" = \"\" + | .\"donate-level\" = 0 + | .\"donate-over-proxy\" = 0 + | .pools[0].algo = \"$pool_algo\" + | .pools[0].url = \"$pool_address\" + | .pools[0].user = \"$wallet_address\" + | .pools[0].pass = \"$pool_password\" + | .pools[0].tls = $pool_tls + | .pools[0].nicehash = $pool_nicehash + | .\"verbose\" = $verbose" + + [[ "$one_gb_pages" == "true" ]] && jq_cmd+=" | .randomx.\"1gb-pages\" = true" + [[ "$pool_keepalive" == "true" ]] && jq_cmd+=" | .pools[0].keepalive = true" + [[ -n "$pool_tls_fingerprint" ]] && jq_cmd+=" | .pools[0].\"tls-fingerprint\" = \"$pool_tls_fingerprint\"" + [[ "$pool_daemon" == "true" ]] && jq_cmd+=" | .pools[0].daemon = true" + + if [[ "$pool_submit_to_origin" == "true" ]]; then + jq_cmd+=" | .pools[0].\"submit-to-origin\" = true | .pools[0].\"self-select\" = \"$pool_self_select\"" + fi + + if [[ "$cc_enabled" == "true" ]]; then + jq_cmd+=" | .\"cc-client\".enabled = true + | .\"cc-client\".servers[0].url = \"$cc_url\" + | .\"cc-client\".servers[0].\"access-token\" = \"$cc_token\" + | .\"cc-client\".servers[0].\"use-tls\" = $cc_tls + | .\"cc-client\".\"worker-id\" = \"$cc_work_id\"" + else + jq_cmd+=" | .\"cc-client\".enabled = false" + fi + + jq "$jq_cmd" "$CONFIG_FILE" >"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE" + configure_cpu_rx + configure_hugepages +} + +show_usage() { + cat < XXXig 版本 (默认: $DEFAULT_VERSION) + -t, --threads <数字> 线程数 (默认: 自动) + -a, --algo <算法> 矿池算法 (默认: $DEFAULT_POOL_ALGO) + -o, --pool <地址> 矿池地址 (必需) + -w, --wallet <地址> 钱包地址 + -p, --password <密码> 矿池密码 (默认自动生成) + --1gb-pages 启用 1GB 大页 + --tls 启用 TLS + --keepalive 启用 KeepAlive + --daemon 启用 SOLO 挖矿 + --nicehash 启用 NiceHash 模式 (默认: 启用) + --submit-to-origin 提交到原始矿池 + --self-select <地址> 自选矿池地址 + --verbose 启用详细输出 (默认: 启用) + --cc 启用 CC + --cc-url <地址> CC 服务器地址 + --cc-work-id CC 工作 ID + --cc-token <令牌> CC 访问令牌 + --cc-tls 启用 CC TLS + -h, --help 显示帮助信息 + +示例: + $0 -o pool.example.com:3333 -w YOUR_WALLET_ADDRESS +EOF + exit 1 +} + +parse_args() { + version=$DEFAULT_VERSION + threads=$DEFAULT_THREADS + pool_algo=$DEFAULT_POOL_ALGO + pool_tls=$DEFAULT_POOL_TLS + pool_keepalive=$DEFAULT_POOL_KEEPALIVE + pool_submit_to_origin=$DEFAULT_POOL_SUBMIT_TO_ORIGIN + pool_daemon=$DEFAULT_POOL_DAEMON + pool_nicehash=$DEFAULT_POOL_NICEHASH + pool_self_select="" + pool_address="" + wallet_address="" + pool_password="" + pool_tls_fingerprint="" + verbose=$DEFAULT_VERBOSE + cc_enabled=$DEFAULT_CC_ENABLED + cc_url="" + cc_work_id="" + cc_token="" + cc_tls=$DEFAULT_CC_TLS + one_gb_pages=$DEFAULT_ONE_GB_PAGES + + while [[ $# -gt 0 ]]; do + case "$1" in + -v | --version) version="$2"; shift 2 ;; + -t | --threads) threads="$2"; shift 2 ;; + -a | --algo) pool_algo="$2"; shift 2 ;; + -o | --pool) pool_address="$2"; shift 2 ;; + -w | --wallet) wallet_address="$2"; shift 2 ;; + -p | --password) pool_password="$2"; shift 2 ;; + --1gb-pages) one_gb_pages="true"; shift ;; + --cc-url) cc_url="$2"; shift 2 ;; + --cc-work-id) cc_work_id="$2"; shift 2 ;; + --cc-token) cc_token="$2"; shift 2 ;; + --tls-fingerprint) pool_tls_fingerprint="$2"; shift 2 ;; + --tls) pool_tls="true"; shift ;; + --keepalive) pool_keepalive="true"; shift ;; + --daemon) pool_daemon="true"; shift ;; + --nicehash) pool_nicehash="true"; shift ;; + --submit-to-origin) pool_submit_to_origin="true"; shift ;; + --self-select) pool_self_select="$2"; shift 2 ;; + --verbose) verbose="true"; shift ;; + --cc) cc_enabled="true"; shift ;; + --cc-tls) cc_tls="true"; shift ;; + -h | --help) show_usage ;; + *) error "无效选项: $1" ;; + esac + done + + # 验证必需参数 + [[ -z "$pool_address" ]] && error "矿池地址不能为空" + [[ ! "$threads" =~ ^[0-9]+$ ]] && error "无效线程数" + [[ "$pool_submit_to_origin" == "true" && -z "$pool_self_select" ]] && \ + error "启用 submit_to_origin 必须设置 self_select" + + # 处理默认值 + if [[ -z "$pool_password" ]]; then + local ip=$(curl -4s --retry 3 --connect-timeout 10 ifconfig.me 2>/dev/null || echo "0.0.0.0") + local random_str=$(tr -dc '0-9a-zA-Z' /dev/null || apt-get install -y curl + command -v jq &>/dev/null || apt-get install -y jq + + log "$BLUE" "配置信息:" + echo " 版本: $version" + echo " 架构: $(get_arch)" + echo " 线程: $threads" + echo " 算法: $pool_algo" + echo " 矿池: $pool_address" + echo " 钱包: $wallet_address" + + uninstall_xxxig + add_apt_repository + install_and_start + replace_config + systemctl restart xxxig-daemon.service + + echo "管理命令:" + echo " systemctl status xxxig-daemon" + echo " journalctl -u xxxig-daemon -f" + echo " systemctl restart xxxig-daemon" +} + +main "$@" diff --git a/script/install.sh b/script/install.sh new file mode 100644 index 0000000..5747a75 --- /dev/null +++ b/script/install.sh @@ -0,0 +1,354 @@ +#!/bin/bash +# +# XXXig 安装脚本 - Gitea 版本 +# 从 Gitea Generic Package Registry 下载并安装 XXXig +# + +set -e + +declare -r BLUE="\033[0;34m" +declare -r RED="\033[0;31m" +declare -r GREEN="\033[0;32m" +declare -r YELLOW="\033[0;33m" +declare -r RESET="\033[0m" + +# 基本配置 +INSTALL_DIR="/etc/miner/xxxig" +CONFIG_FILE="$INSTALL_DIR/config.json" +LOG_FILE="$INSTALL_DIR/xxxig.log" + +# Gitea 配置 +GITEA_SERVER="gitea.bcde.io" +GITEA_OWNER="wangdefa" +GITEA_REPO="xxxig" +PACKAGE_NAME="xxxig" + +# 默认参数 +DEFAULT_VERSION="latest" +DEFAULT_THREADS=0 +DEFAULT_POOL_ALGO="rx/0" +DEFAULT_POOL_TLS="false" +DEFAULT_POOL_KEEPALIVE="false" +DEFAULT_POOL_DAEMON="false" +DEFAULT_POOL_SUBMIT_TO_ORIGIN="false" +DEFAULT_POOL_NICEHASH="true" +DEFAULT_ONE_GB_PAGES="false" +DEFAULT_VERBOSE="true" +DEFAULT_CC_ENABLED="false" +DEFAULT_CC_TLS="false" + +# 辅助函数 +log() { echo -e "${1}${2}${RESET}"; } +error() { log "$RED" "错误: $1"; exit 1; } + + +get_arch() { + case $(uname -m) in + x86_64) echo "amd64" ;; + aarch64) echo "arm64" ;; + *) error "不支持的架构: $(uname -m)" ;; + esac +} + +get_os() { + grep -qi alpine /etc/os-release && echo "alpine" && return + grep -qiE 'debian|ubuntu' /etc/os-release && echo "ubuntu" && return + error "不支持的操作系统" +} + +get_gitea_latest_version() { + local version + version=$(curl -s "https://${GITEA_SERVER}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}/releases" | jq -r '.[0].tag_name') + [[ -z "$version" || "$version" == "null" ]] && error "获取版本失败" + echo "$version" +} + +# 卸载旧版本 +uninstall_xxxig() { + if [[ $os_type == "alpine" ]]; then + rc-service xxxig stop 2>/dev/null || true + rc-update del xxxig default 2>/dev/null || true + rm -rf "$INSTALL_DIR" /etc/init.d/xxxig + else + systemctl stop xxxig 2>/dev/null || true + systemctl disable xxxig 2>/dev/null || true + rm -rf "$INSTALL_DIR" /etc/systemd/system/xxxig.service + systemctl daemon-reload 2>/dev/null || true + fi +} + +# 安装软件包 +install_xxxig() { + local temp_dir=$(mktemp -d) + trap "rm -rf '$temp_dir'" EXIT + + log "$BLUE" "下载 XXXig $version..." + curl -fsSL -o "$temp_dir/xxxig.tar.gz" "$download_url" || error "下载失败" + + mkdir -p "$INSTALL_DIR" + tar -xzf "$temp_dir/xxxig.tar.gz" -C "$INSTALL_DIR" --strip-components=1 || error "解压失败" + chmod +x "$INSTALL_DIR/xxxigDaemon" "$INSTALL_DIR/xxxig" +} + +# 配置 CPU 亲和性 +configure_cpu_rx() { + local cpu_cores=$(nproc) + local rx_array="" step=1 + + [[ "$threads" -le $((cpu_cores / 2)) ]] && step=2 + + for ((i = 0; i < threads; i++)); do + [[ $i -gt 0 ]] && rx_array+=", " + rx_array+="$((i * step))" + done + + local field="rx" + [[ "$pool_algo" == "panthera" ]] && field="panthera" + + jq ".cpu.$field = [ $rx_array ]" "$CONFIG_FILE" >"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE" +} + +# 配置大页内存 +configure_hugepages() { + if [[ "$one_gb_pages" == "true" ]]; then + log "$BLUE" "配置 大页内存..." + sysctl -w vm.nr_hugepages=3072 + echo "vm.nr_hugepages=3072" >>/etc/sysctl.conf + log "$GREEN" "大页内存配置完成" + fi +} + +# 更新配置文件 +replace_config() { + [[ ! -f "$CONFIG_FILE" ]] && error "配置文件缺失" + + local jq_cmd=".\"log-file\" = \"$LOG_FILE\" + | .\"donate-level\" = 0 + | .\"donate-over-proxy\" = 0 + | .pools[0].algo = \"$pool_algo\" + | .pools[0].url = \"$pool_address\" + | .pools[0].user = \"$wallet_address\" + | .pools[0].pass = \"$pool_password\" + | .pools[0].tls = $pool_tls + | .pools[0].nicehash = $pool_nicehash + | .\"verbose\" = $verbose" + + [[ "$one_gb_pages" == "true" ]] && jq_cmd+=" | .randomx.\"1gb-pages\" = true" + [[ "$pool_keepalive" == "true" ]] && jq_cmd+=" | .pools[0].keepalive = true" + [[ -n "$pool_tls_fingerprint" ]] && jq_cmd+=" | .pools[0].\"tls-fingerprint\" = \"$pool_tls_fingerprint\"" + [[ "$pool_daemon" == "true" ]] && jq_cmd+=" | .pools[0].daemon = true" + + if [[ "$pool_submit_to_origin" == "true" ]]; then + jq_cmd+=" | .pools[0].\"submit-to-origin\" = true | .pools[0].\"self-select\" = \"$pool_self_select\"" + fi + + if [[ "$cc_enabled" == "true" ]]; then + jq_cmd+=" | .\"cc-client\".enabled = true + | .\"cc-client\".servers[0].url = \"$cc_url\" + | .\"cc-client\".servers[0].\"access-token\" = \"$cc_token\" + | .\"cc-client\".servers[0].\"use-tls\" = $cc_tls + | .\"cc-client\".\"worker-id\" = \"$cc_work_id\"" + else + jq_cmd+=" | .\"cc-client\".enabled = false" + fi + + jq "$jq_cmd" "$CONFIG_FILE" >"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE" + configure_cpu_rx + configure_hugepages +} + +# 创建并启动服务 +create_service() { + if [[ "$os_type" == "alpine" ]]; then + cat >/etc/init.d/xxxig <<'EOF' +#!/sbin/openrc-run + +name="XXXig Miner" +description="XXXig Miner Service" +command="/etc/miner/xxxig/xxxigDaemon" +command_args="-c /etc/miner/xxxig/config.json" +pidfile="/run/${RC_SVCNAME}.pid" +command_background="yes" +rc_ulimit="-n 65535" + +depend() { + need net + after network +} +EOF + chmod +x /etc/init.d/xxxig + rc-update add xxxig default + rc-service xxxig start + else + cat >/etc/systemd/system/xxxig.service < XXXig 版本 (默认: $DEFAULT_VERSION) + -t, --threads <数字> 线程数 (默认: 自动) + -a, --algo <算法> 矿池算法 (默认: $DEFAULT_POOL_ALGO) + -o, --pool <地址> 矿池地址 (必需) + -w, --wallet <地址> 钱包地址 + -p, --password <密码> 矿池密码 (默认自动生成) + --1gb-pages 启用 1GB 大页 + --tls 启用 TLS + --keepalive 启用 KeepAlive + --daemon 启用 SOLO 挖矿 + --nicehash 启用 NiceHash 模式 (默认: 启用) + --submit-to-origin 提交到原始矿池 + --self-select <地址> 自选矿池地址 + --verbose 启用详细输出 (默认: 启用) + --cc 启用 CC + --cc-url <地址> CC 服务器地址 + --cc-work-id CC 工作 ID + --cc-token <令牌> CC 访问令牌 + --cc-tls 启用 CC TLS + -h, --help 显示帮助信息 + +示例: + $0 -o pool.example.com:3333 -w YOUR_WALLET_ADDRESS +EOF + exit 1 +} + +parse_args() { + version=$DEFAULT_VERSION + threads=$DEFAULT_THREADS + pool_algo=$DEFAULT_POOL_ALGO + pool_tls=$DEFAULT_POOL_TLS + pool_keepalive=$DEFAULT_POOL_KEEPALIVE + pool_submit_to_origin=$DEFAULT_POOL_SUBMIT_TO_ORIGIN + pool_daemon=$DEFAULT_POOL_DAEMON + pool_nicehash=$DEFAULT_POOL_NICEHASH + pool_self_select="" + pool_address="" + wallet_address="" + pool_password="" + pool_tls_fingerprint="" + verbose=$DEFAULT_VERBOSE + cc_enabled=$DEFAULT_CC_ENABLED + cc_url="" + cc_work_id="" + cc_token="" + cc_tls=$DEFAULT_CC_TLS + one_gb_pages=$DEFAULT_ONE_GB_PAGES + + while [[ $# -gt 0 ]]; do + case "$1" in + -v | --version) version="$2"; shift 2 ;; + -t | --threads) threads="$2"; shift 2 ;; + -a | --algo) pool_algo="$2"; shift 2 ;; + -o | --pool) pool_address="$2"; shift 2 ;; + -w | --wallet) wallet_address="$2"; shift 2 ;; + -p | --password) pool_password="$2"; shift 2 ;; + --1gb-pages) one_gb_pages="true"; shift ;; + --cc-url) cc_url="$2"; shift 2 ;; + --cc-work-id) cc_work_id="$2"; shift 2 ;; + --cc-token) cc_token="$2"; shift 2 ;; + --tls-fingerprint) pool_tls_fingerprint="$2"; shift 2 ;; + --tls) pool_tls="true"; shift ;; + --keepalive) pool_keepalive="true"; shift ;; + --daemon) pool_daemon="true"; shift ;; + --nicehash) pool_nicehash="true"; shift ;; + --submit-to-origin) pool_submit_to_origin="true"; shift ;; + --self-select) pool_self_select="$2"; shift 2 ;; + --verbose) verbose="true"; shift ;; + --cc) cc_enabled="true"; shift ;; + --cc-tls) cc_tls="true"; shift ;; + -h | --help) show_usage ;; + *) error "无效选项: $1" ;; + esac + done + + # 验证必需参数 + [[ -z "$pool_address" ]] && error "矿池地址不能为空" + [[ ! "$threads" =~ ^[0-9]+$ ]] && error "无效线程数" + [[ "$pool_submit_to_origin" == "true" && -z "$pool_self_select" ]] && \ + error "启用 submit_to_origin 必须设置 self_select" + + # 处理默认值 + if [[ -z "$pool_password" ]]; then + local ip=$(curl -4s --retry 3 --connect-timeout 10 ifconfig.me 2>/dev/null || echo "0.0.0.0") + local random_str=$(tr -dc '0-9a-zA-Z' /dev/null; then + for pkg in "${deps[@]}"; do + command -v "$pkg" &>/dev/null || apt-get install -y "$pkg" + done + elif command -v apk &>/dev/null; then + for pkg in "${deps[@]}"; do + command -v "$pkg" &>/dev/null || apk add "$pkg" + done + fi + + os_type=$(get_os) + [[ "$version" == "latest" ]] && version=$(get_gitea_latest_version) + + local pkg_version="${version#v}" # registry 包版本为数字,去掉可能的 v 前缀 + download_url="https://${GITEA_SERVER}/api/packages/${GITEA_OWNER}/generic/${PACKAGE_NAME}/${pkg_version}/${PACKAGE_NAME}-$(get_arch)-$os_type-${pkg_version}.tar.gz" + + log "$BLUE" "配置信息:" + echo " 版本: $version" + echo " 架构: $(get_arch)" + echo " 系统: $os_type" + echo " 线程: $threads" + echo " 算法: $pool_algo" + echo " 矿池: $pool_address" + echo " 钱包: $wallet_address" + + uninstall_xxxig + install_xxxig + replace_config + create_service + + echo "管理命令:" + if [[ "$os_type" == "alpine" ]]; then + echo " rc-service xxxig status" + echo " tail -f $LOG_FILE" + echo " rc-service xxxig restart" + else + echo " systemctl status xxxig" + echo " journalctl -u xxxig -f" + echo " systemctl restart xxxig" + fi +} + +main "$@" diff --git a/script/uninstall.sh b/script/uninstall.sh new file mode 100755 index 0000000..45d67ef --- /dev/null +++ b/script/uninstall.sh @@ -0,0 +1,165 @@ +#!/bin/bash +# +# XXXig 卸载脚本 +# 支持 tar.gz 和 DEB 包安装方式 +# + +set -e + +declare -r RED="\033[0;31m" +declare -r GREEN="\033[0;32m" +declare -r YELLOW="\033[0;33m" +declare -r RESET="\033[0m" + +# 安装路径配置 +INSTALL_DIR_TARBALL="/etc/miner/xxxig" +INSTALL_DIR_DEB="/etc/xxxig" +LOG_DIR_DEB="/var/log/xxxig" + +log() { echo -e "${1}${2}${RESET}"; } +error() { log "$RED" "错误: $1"; exit 1; } + + +get_os() { + grep -qi alpine /etc/os-release && echo "alpine" && return + grep -qiE 'debian|ubuntu' /etc/os-release && echo "ubuntu" && return + error "不支持的操作系统" +} + +detect_installation() { + local install_type="" + + # 检测 DEB 包安装 + if command -v dpkg &>/dev/null && dpkg -l | grep -q "^ii.*xxxig"; then + install_type="deb" + # 检测 tar.gz 安装 + elif [[ -d "$INSTALL_DIR_TARBALL" ]]; then + install_type="tarball" + # 检测 DEB 配置目录 + elif [[ -d "$INSTALL_DIR_DEB" ]]; then + install_type="deb" + fi + + echo "$install_type" +} + +uninstall_alpine_tarball() { + log "$YELLOW" "卸载 Alpine tar.gz 安装..." + + rc-service xxxig stop 2>/dev/null || true + rc-update del xxxig default 2>/dev/null || true + rm -rf "$INSTALL_DIR_TARBALL" /etc/init.d/xxxig + + log "$GREEN" "Alpine tar.gz 安装已卸载" +} + +uninstall_ubuntu_tarball() { + log "$YELLOW" "卸载 Ubuntu/Debian tar.gz 安装..." + + systemctl stop xxxig 2>/dev/null || true + systemctl disable xxxig 2>/dev/null || true + rm -rf "$INSTALL_DIR_TARBALL" /etc/systemd/system/xxxig.service + systemctl daemon-reload 2>/dev/null || true + + log "$GREEN" "Ubuntu/Debian tar.gz 安装已卸载" +} + +uninstall_deb_package() { + log "$YELLOW" "卸载 DEB 包..." + + # 停止并禁用服务 + systemctl stop xxxig-daemon xxxig-server 2>/dev/null || true + systemctl disable xxxig-daemon xxxig-server 2>/dev/null || true + + # 卸载包 + apt-get remove -y xxxig 2>/dev/null || true + + # 清理配置(可选) + if [[ "$PURGE_CONFIG" == "true" ]]; then + apt-get purge -y xxxig 2>/dev/null || true + rm -rf "$INSTALL_DIR_DEB" "$LOG_DIR_DEB" + fi + + # 清理 APT 源 + rm -f /etc/apt/sources.list.d/xxxig.list + apt-get update -qq 2>/dev/null || true + + systemctl daemon-reload 2>/dev/null || true + + log "$GREEN" "DEB 包已卸载" +} + +show_usage() { + cat <