Files
xxxig/script/install.deb.sh
T
wangdefa b04d41d783
Build and Release / build-and-test (amd64) (push) Successful in 1m40s
Build and Release / build-and-test (arm64) (push) Successful in 1m40s
Build and Release / release (push) Failing after 4s
增加对 1GB Huge Pages 的支持,添加相关服务和配置,优化安装脚本
2026-08-05 12:50:18 +08:00

338 lines
10 KiB
Bash
Executable File

#!/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"
HUGEPAGES_MARKER="$CONFIG_DIR/1gb-pages.enabled"
LEGACY_HUGEPAGES_HELPER="/usr/local/libexec/xxxig-enable-1gb-pages"
LEGACY_HUGEPAGES_SERVICE="/etc/systemd/system/xxxig-hugepages.service"
LEGACY_DAEMON_DROPIN="/etc/systemd/system/xxxig-daemon.service.d/installer.conf"
# 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"
DEFAULT_KEEP_NAME="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/${GITEA_OWNER}.list"
systemctl daemon-reload 2>/dev/null || true
}
# 安装软件包,配置完成后再启动服务
install_xxxig() {
log "$BLUE" "安装 XXXig $version..."
if [[ "$version" == "latest" ]]; then
apt-get install -y xxxig
else
apt-get install -y xxxig="${version#v}"
fi
log "$GREEN" "安装完成"
}
configure_hugepages() {
if [[ "$one_gb_pages" == "true" ]]; then
touch "$HUGEPAGES_MARKER"
chmod 644 "$HUGEPAGES_MARKER"
log "$GREEN" "已启用 DEB 包内置的 1GB Huge Pages 服务"
else
rm -f "$HUGEPAGES_MARKER"
fi
}
start_service() {
log "$BLUE" "启动服务..."
systemctl daemon-reload
systemctl enable --now xxxig-daemon.service
}
# 配置 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"
}
# 更新配置文件
append_pool_options() {
[[ "$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'
[[ "$pool_submit_to_origin" == "true" ]] && \
jq_cmd+=" | .pools[0].\"submit-to-origin\" = true | .pools[0].\"self-select\" = \"$pool_self_select\""
return 0
}
append_cc_options() {
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
}
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"
append_pool_options
append_cc_options
jq "$jq_cmd" "$CONFIG_FILE" >"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
configure_cpu_rx
chown xxxig:xxxig "$CONFIG_FILE"
chmod 640 "$CONFIG_FILE"
}
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
--keep-name 保留已有矿池密码和 CC worker-id
-h, --help 显示帮助信息
$0 -o pool.example.com:3333 -w YOUR_WALLET_ADDRESS
EOF
exit 1
}
init_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
keep_name=$DEFAULT_KEEP_NAME
}
read_args() {
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 ;;
--keep-name | --preserve-name) keep_name="true"; shift ;;
-h | --help) show_usage ;;
*) error "无效选项: $1" ;;
esac
done
}
validate_args() {
[[ -z "$pool_address" ]] && error "矿池地址不能为空"
[[ ! "$threads" =~ ^[0-9]+$ ]] && error "无效线程数"
[[ "$pool_submit_to_origin" == "true" && -z "$pool_self_select" ]] && \
error "启用 submit_to_origin 必须设置 self_select"
return 0
}
resolve_defaults() {
local ip random_str
if [[ -z "$pool_password" ]]; then
ip=$(curl -4s --retry 3 --connect-timeout 10 ifconfig.me 2>/dev/null || echo "0.0.0.0")
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
return 0
}
load_preserved_name() {
local old_password old_work_id preserved="false"
[[ "$keep_name" == "true" && -f "$CONFIG_FILE" ]] || return 0
old_password=$(jq -r '.pools[0].pass // empty' "$CONFIG_FILE" 2>/dev/null || true)
old_work_id=$(jq -r '."cc-client"."worker-id" // empty' "$CONFIG_FILE" 2>/dev/null || true)
if [[ -z "$pool_password" && -n "$old_password" ]]; then
pool_password=$old_password
preserved="true"
fi
if [[ -z "$cc_work_id" && -n "$old_work_id" ]]; then
cc_work_id=$old_work_id
preserved="true"
fi
[[ "$preserved" == "true" ]] && log "$GREEN" "已保留原矿工名称"
return 0
}
parse_args() {
init_args
read_args "$@"
validate_args
}
install_dependencies() {
command -v curl &>/dev/null || apt-get install -y curl
command -v jq &>/dev/null || apt-get install -y jq
}
show_config() {
log "$BLUE" "配置信息:"
echo " 版本: $version"
echo " 架构: $(get_arch)"
echo " 线程: $threads"
echo " 算法: $pool_algo"
echo " 矿池: $pool_address"
echo " 钱包: $wallet_address"
}
main() {
parse_args "$@"
check_os
install_dependencies
load_preserved_name
resolve_defaults
show_config
uninstall_xxxig
add_apt_repository
install_xxxig
replace_config
configure_hugepages
start_service
echo "管理命令:"
echo " systemctl status xxxig-daemon"
echo " journalctl -u xxxig-daemon -f"
echo " systemctl restart xxxig-daemon"
}
main "$@"