Files
xxxig/script/install.sh
T
wangdefaandClaude Opus 4.8 491c9e0bc3
Build and Release / release (push) Successful in 12s
Build and Release / build-and-test (amd64) (push) Successful in 1m27s
Build and Release / build-and-test (arm64) (push) Successful in 4m5s
统一 musl 全静态构建,规范 Dockerfile 与产物命名
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 10:12:08 +08:00

356 lines
11 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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 <<EOF
[Unit]
Description=XXXig Miner
After=network.target
[Service]
User=root
ExecStart=$INSTALL_DIR/xxxigDaemon -c $CONFIG_FILE
Restart=always
RestartSec=10
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now xxxig.service
fi
}
show_usage() {
cat <<EOF
用法: $0 [选项]
选项:
-v, --version <版本> 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 <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/urandom | head -c 5)
pool_password=$(echo "$ip" | awk -F. '{print $3"_"$4}')"_$random_str"
fi
[[ -z "$cc_work_id" ]] && cc_work_id="$(get_arch)_$pool_password"
[[ -z "$wallet_address" ]] && wallet_address="empty_wallet_$(date +%s)"
if [[ "$threads" -le 0 ]]; then
threads=$(nproc)
elif [[ "$threads" -gt $(nproc) ]]; then
threads=$(nproc)
fi
}
main() {
parse_args "$@"
# 检查并安装依赖
local deps=(curl jq file)
if command -v apt-get &>/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 前缀
# 产物统一为 musl 全静态(linux-static),不再区分 distroos_type 仅用于下方服务管理(OpenRC/systemd)
download_url="https://${GITEA_SERVER}/api/packages/${GITEA_OWNER}/generic/${PACKAGE_NAME}/${pkg_version}/${PACKAGE_NAME}-$(get_arch)-linux-static-${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 "$@"