完善安装脚本,增加对 1GB Huge Pages 的支持,优化服务管理与权限设置
Build and Release / build-and-test (arm64) (push) Successful in 23s
Build and Release / build-and-test (amd64) (push) Successful in 34s
Build and Release / release (push) Skipped

This commit is contained in:
2026-08-05 12:33:33 +08:00
parent 3ce5a2a120
commit 99a17f1852
2 changed files with 396 additions and 86 deletions
+158 -38
View File
@@ -16,6 +16,10 @@ declare -r RESET="\033[0m"
CONFIG_DIR="/etc/xxxig" CONFIG_DIR="/etc/xxxig"
LOG_DIR="/var/log/xxxig" LOG_DIR="/var/log/xxxig"
CONFIG_FILE="$CONFIG_DIR/config.json" CONFIG_FILE="$CONFIG_DIR/config.json"
HUGEPAGES_HELPER="/usr/local/libexec/xxxig-enable-1gb-pages"
HUGEPAGES_SERVICE="/etc/systemd/system/xxxig-hugepages.service"
DAEMON_DROPIN_DIR="/etc/systemd/system/xxxig-daemon.service.d"
DAEMON_DROPIN="$DAEMON_DROPIN_DIR/installer.conf"
# Gitea 配置 # Gitea 配置
GITEA_SERVER="gitea.bcde.io" GITEA_SERVER="gitea.bcde.io"
@@ -34,6 +38,7 @@ DEFAULT_ONE_GB_PAGES="false"
DEFAULT_VERBOSE="true" DEFAULT_VERBOSE="true"
DEFAULT_CC_ENABLED="false" DEFAULT_CC_ENABLED="false"
DEFAULT_CC_TLS="false" DEFAULT_CC_TLS="false"
DEFAULT_KEEP_NAME="false"
# 辅助函数 # 辅助函数
log() { echo -e "${1}${2}${RESET}"; } log() { echo -e "${1}${2}${RESET}"; }
@@ -61,15 +66,16 @@ add_apt_repository() {
# 卸载旧版本 # 卸载旧版本
uninstall_xxxig() { uninstall_xxxig() {
systemctl stop xxxig-daemon xxxig-server 2>/dev/null || true systemctl stop xxxig-daemon xxxig-server xxxig-hugepages 2>/dev/null || true
systemctl disable xxxig-daemon xxxig-server 2>/dev/null || true systemctl disable xxxig-daemon xxxig-server xxxig-hugepages 2>/dev/null || true
apt-get remove -y xxxig 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 rm -rf "$CONFIG_DIR" "$LOG_DIR" /etc/apt/sources.list.d/xxxig.list
rm -f "$HUGEPAGES_HELPER" "$HUGEPAGES_SERVICE" "$DAEMON_DROPIN"
systemctl daemon-reload 2>/dev/null || true systemctl daemon-reload 2>/dev/null || true
} }
# 安装并启动服务 # 安装软件包,配置完成后再启动服务
install_and_start() { install_xxxig() {
log "$BLUE" "安装 XXXig $version..." log "$BLUE" "安装 XXXig $version..."
if [[ "$version" == "latest" ]]; then if [[ "$version" == "latest" ]]; then
apt-get install -y xxxig apt-get install -y xxxig
@@ -77,10 +83,79 @@ install_and_start() {
apt-get install -y xxxig="${version#v}" apt-get install -y xxxig="${version#v}"
fi fi
log "$GREEN" "安装完成"
}
write_hugepages_helper() {
mkdir -p "$(dirname "$HUGEPAGES_HELPER")"
cat >"$HUGEPAGES_HELPER" <<'EOF'
#!/bin/sh
set -eu
sysctl -w vm.nr_hugepages="$(nproc)"
found=0
for node in /sys/devices/system/node/node*; do
file="$node/hugepages/hugepages-1048576kB/nr_hugepages"
[ -e "$file" ] || continue
printf '3\n' >"$file"
actual=$(cat "$file")
[ "$actual" -ge 3 ] || exit 1
found=1
done
[ "$found" -eq 1 ]
EOF
chmod 755 "$HUGEPAGES_HELPER"
}
write_hugepages_service() {
cat >"$HUGEPAGES_SERVICE" <<EOF
[Unit]
Description=Reserve Huge Pages for XXXig
Before=xxxig-daemon.service
ConditionPathExists=/sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
[Service]
Type=oneshot
ExecStart=$HUGEPAGES_HELPER
[Install]
WantedBy=multi-user.target
EOF
}
write_daemon_dropin() {
mkdir -p "$DAEMON_DROPIN_DIR"
{
echo "[Unit]"
if [[ "$one_gb_pages" == "true" ]]; then
echo "Requires=xxxig-hugepages.service"
echo "After=xxxig-hugepages.service"
fi
echo
echo "[Service]"
echo "ReadWritePaths=$LOG_DIR $CONFIG_DIR"
} >"$DAEMON_DROPIN"
}
configure_hugepages() {
write_daemon_dropin
[[ "$one_gb_pages" == "true" ]] || return 0
log "$BLUE" "配置 1GB Huge Pages 持久池..."
write_hugepages_helper
write_hugepages_service
log "$GREEN" "1GB Huge Pages 初始化服务配置完成"
}
start_service() {
log "$BLUE" "启动服务..." log "$BLUE" "启动服务..."
systemctl daemon-reload systemctl daemon-reload
if [[ "$one_gb_pages" == "true" ]]; then
systemctl enable xxxig-hugepages.service
fi
systemctl enable --now xxxig-daemon.service systemctl enable --now xxxig-daemon.service
log "$GREEN" "安装完成"
} }
# 配置 CPU 亲和性 # 配置 CPU 亲和性
@@ -102,6 +177,29 @@ configure_cpu_rx() {
} }
# 更新配置文件 # 更新配置文件
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() { replace_config() {
[[ ! -f "$CONFIG_FILE" ]] && error "配置文件缺失" [[ ! -f "$CONFIG_FILE" ]] && error "配置文件缺失"
@@ -116,33 +214,17 @@ replace_config() {
| .pools[0].nicehash = $pool_nicehash | .pools[0].nicehash = $pool_nicehash
| .\"verbose\" = $verbose" | .\"verbose\" = $verbose"
[[ "$one_gb_pages" == "true" ]] && jq_cmd+=" | .randomx.\"1gb-pages\" = true" append_pool_options
[[ "$pool_keepalive" == "true" ]] && jq_cmd+=" | .pools[0].keepalive = true" append_cc_options
[[ -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" jq "$jq_cmd" "$CONFIG_FILE" >"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
configure_cpu_rx configure_cpu_rx
chown xxxig:xxxig "$CONFIG_FILE"
chmod 640 "$CONFIG_FILE"
} }
show_usage() { show_usage() {
cat <<EOF cat <<EOF
用法: $0 [选项] 用法: $0 [选项]
选项: 选项:
-v, --version <版本> XXXig 版本 (默认: $DEFAULT_VERSION) -v, --version <版本> XXXig 版本 (默认: $DEFAULT_VERSION)
-t, --threads <数字> 线程数 (默认: 自动) -t, --threads <数字> 线程数 (默认: 自动)
@@ -163,15 +245,14 @@ show_usage() {
--cc-work-id <ID> CC 工作 ID --cc-work-id <ID> CC 工作 ID
--cc-token <令牌> CC 访问令牌 --cc-token <令牌> CC 访问令牌
--cc-tls 启用 CC TLS --cc-tls 启用 CC TLS
--keep-name 保留已有矿池密码和 CC worker-id
-h, --help 显示帮助信息 -h, --help 显示帮助信息
示例:
$0 -o pool.example.com:3333 -w YOUR_WALLET_ADDRESS $0 -o pool.example.com:3333 -w YOUR_WALLET_ADDRESS
EOF EOF
exit 1 exit 1
} }
parse_args() { init_args() {
version=$DEFAULT_VERSION version=$DEFAULT_VERSION
threads=$DEFAULT_THREADS threads=$DEFAULT_THREADS
pool_algo=$DEFAULT_POOL_ALGO pool_algo=$DEFAULT_POOL_ALGO
@@ -192,7 +273,10 @@ parse_args() {
cc_token="" cc_token=""
cc_tls=$DEFAULT_CC_TLS cc_tls=$DEFAULT_CC_TLS
one_gb_pages=$DEFAULT_ONE_GB_PAGES one_gb_pages=$DEFAULT_ONE_GB_PAGES
keep_name=$DEFAULT_KEEP_NAME
}
read_args() {
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case "$1" in case "$1" in
-v | --version) version="$2"; shift 2 ;; -v | --version) version="$2"; shift 2 ;;
@@ -215,21 +299,26 @@ parse_args() {
--verbose) verbose="true"; shift ;; --verbose) verbose="true"; shift ;;
--cc) cc_enabled="true"; shift ;; --cc) cc_enabled="true"; shift ;;
--cc-tls) cc_tls="true"; shift ;; --cc-tls) cc_tls="true"; shift ;;
--keep-name | --preserve-name) keep_name="true"; shift ;;
-h | --help) show_usage ;; -h | --help) show_usage ;;
*) error "无效选项: $1" ;; *) error "无效选项: $1" ;;
esac esac
done done
}
# 验证必需参数 validate_args() {
[[ -z "$pool_address" ]] && error "矿池地址不能为空" [[ -z "$pool_address" ]] && error "矿池地址不能为空"
[[ ! "$threads" =~ ^[0-9]+$ ]] && error "无效线程数" [[ ! "$threads" =~ ^[0-9]+$ ]] && error "无效线程数"
[[ "$pool_submit_to_origin" == "true" && -z "$pool_self_select" ]] && \ [[ "$pool_submit_to_origin" == "true" && -z "$pool_self_select" ]] && \
error "启用 submit_to_origin 必须设置 self_select" error "启用 submit_to_origin 必须设置 self_select"
return 0
}
# 处理默认值 resolve_defaults() {
local ip random_str
if [[ -z "$pool_password" ]]; then if [[ -z "$pool_password" ]]; then
local ip=$(curl -4s --retry 3 --connect-timeout 10 ifconfig.me 2>/dev/null || echo "0.0.0.0") 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) random_str=$(tr -dc '0-9a-zA-Z' </dev/urandom | head -c 5)
pool_password=$(echo "$ip" | awk -F. '{print $3"_"$4}')"_$random_str" pool_password=$(echo "$ip" | awk -F. '{print $3"_"$4}')"_$random_str"
fi fi
@@ -241,16 +330,38 @@ parse_args() {
elif [[ "$threads" -gt $(nproc) ]]; then elif [[ "$threads" -gt $(nproc) ]]; then
threads=$(nproc) threads=$(nproc)
fi fi
return 0
} }
main() { load_preserved_name() {
parse_args "$@" local old_password old_work_id preserved="false"
check_os [[ "$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 curl &>/dev/null || apt-get install -y curl
command -v jq &>/dev/null || apt-get install -y jq command -v jq &>/dev/null || apt-get install -y jq
}
show_config() {
log "$BLUE" "配置信息:" log "$BLUE" "配置信息:"
echo " 版本: $version" echo " 版本: $version"
echo " 架构: $(get_arch)" echo " 架构: $(get_arch)"
@@ -258,12 +369,21 @@ main() {
echo " 算法: $pool_algo" echo " 算法: $pool_algo"
echo " 矿池: $pool_address" echo " 矿池: $pool_address"
echo " 钱包: $wallet_address" echo " 钱包: $wallet_address"
}
main() {
parse_args "$@"
check_os
install_dependencies
load_preserved_name
resolve_defaults
show_config
uninstall_xxxig uninstall_xxxig
add_apt_repository add_apt_repository
install_and_start install_xxxig
replace_config replace_config
systemctl restart xxxig-daemon.service configure_hugepages
start_service
echo "管理命令:" echo "管理命令:"
echo " systemctl status xxxig-daemon" echo " systemctl status xxxig-daemon"
+233 -43
View File
@@ -16,6 +16,10 @@ declare -r RESET="\033[0m"
INSTALL_DIR="/etc/miner/xxxig" INSTALL_DIR="/etc/miner/xxxig"
CONFIG_FILE="$INSTALL_DIR/config.json" CONFIG_FILE="$INSTALL_DIR/config.json"
LOG_FILE="$INSTALL_DIR/xxxig.log" LOG_FILE="$INSTALL_DIR/xxxig.log"
HUGEPAGES_HELPER="/usr/local/libexec/xxxig-enable-1gb-pages"
HUGEPAGES_SERVICE="/etc/systemd/system/xxxig-hugepages.service"
SYSTEMD_DROPIN_DIR="/etc/systemd/system/xxxig.service.d"
SYSTEMD_DROPIN="$SYSTEMD_DROPIN_DIR/hugepages.conf"
# Gitea 配置 # Gitea 配置
GITEA_SERVER="gitea.bcde.io" GITEA_SERVER="gitea.bcde.io"
@@ -36,6 +40,7 @@ DEFAULT_ONE_GB_PAGES="false"
DEFAULT_VERBOSE="true" DEFAULT_VERBOSE="true"
DEFAULT_CC_ENABLED="false" DEFAULT_CC_ENABLED="false"
DEFAULT_CC_TLS="false" DEFAULT_CC_TLS="false"
DEFAULT_KEEP_NAME="false"
# 辅助函数 # 辅助函数
log() { echo -e "${1}${2}${RESET}"; } log() { echo -e "${1}${2}${RESET}"; }
@@ -67,12 +72,17 @@ get_gitea_latest_version() {
uninstall_xxxig() { uninstall_xxxig() {
if [[ $os_type == "alpine" ]]; then if [[ $os_type == "alpine" ]]; then
rc-service xxxig stop 2>/dev/null || true rc-service xxxig stop 2>/dev/null || true
rc-service xxxig-hugepages stop 2>/dev/null || true
rc-update del xxxig default 2>/dev/null || true rc-update del xxxig default 2>/dev/null || true
rm -rf "$INSTALL_DIR" /etc/init.d/xxxig rc-update del xxxig-hugepages default 2>/dev/null || true
rm -rf "$INSTALL_DIR" /etc/init.d/xxxig /etc/init.d/xxxig-hugepages
rm -f "$HUGEPAGES_HELPER" "$HUGEPAGES_SERVICE"
else else
systemctl stop xxxig 2>/dev/null || true systemctl stop xxxig xxxig-hugepages 2>/dev/null || true
systemctl disable xxxig 2>/dev/null || true systemctl disable xxxig xxxig-hugepages 2>/dev/null || true
rm -rf "$INSTALL_DIR" /etc/systemd/system/xxxig.service rm -rf "$INSTALL_DIR" /etc/systemd/system/xxxig.service
rm -f "$SYSTEMD_DROPIN" "$HUGEPAGES_HELPER" "$HUGEPAGES_SERVICE"
rmdir "$SYSTEMD_DROPIN_DIR" 2>/dev/null || true
systemctl daemon-reload 2>/dev/null || true systemctl daemon-reload 2>/dev/null || true
fi fi
} }
@@ -90,6 +100,98 @@ install_xxxig() {
chmod +x "$INSTALL_DIR/xxxigDaemon" "$INSTALL_DIR/xxxig" chmod +x "$INSTALL_DIR/xxxigDaemon" "$INSTALL_DIR/xxxig"
} }
create_xxxig_user() {
if [[ "$os_type" == "alpine" ]]; then
getent group xxxig >/dev/null || addgroup -S xxxig
getent passwd xxxig >/dev/null || \
adduser -S -D -H -h "$INSTALL_DIR" -s /sbin/nologin -G xxxig xxxig
else
getent group xxxig >/dev/null || addgroup --system xxxig
getent passwd xxxig >/dev/null || \
adduser --system --ingroup xxxig --no-create-home \
--home "$INSTALL_DIR" --shell /usr/sbin/nologin xxxig
fi
}
set_runtime_permissions() {
touch "$LOG_FILE"
chown -R root:root "$INSTALL_DIR"
chown xxxig:xxxig "$CONFIG_FILE" "$LOG_FILE"
chmod 640 "$CONFIG_FILE"
chmod 640 "$LOG_FILE"
chmod 755 "$INSTALL_DIR" "$INSTALL_DIR/xxxigDaemon" "$INSTALL_DIR/xxxig"
}
write_hugepages_helper() {
mkdir -p "$(dirname "$HUGEPAGES_HELPER")"
cat >"$HUGEPAGES_HELPER" <<'EOF'
#!/bin/sh
set -eu
sysctl -w vm.nr_hugepages="$(nproc)"
found=0
for node in /sys/devices/system/node/node*; do
file="$node/hugepages/hugepages-1048576kB/nr_hugepages"
[ -e "$file" ] || continue
printf '3\n' >"$file"
actual=$(cat "$file")
[ "$actual" -ge 3 ] || exit 1
found=1
done
[ "$found" -eq 1 ]
EOF
chmod 755 "$HUGEPAGES_HELPER"
}
write_hugepages_service() {
cat >"$HUGEPAGES_SERVICE" <<EOF
[Unit]
Description=Reserve Huge Pages for XXXig
Before=xxxig.service
ConditionPathExists=/sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
[Service]
Type=oneshot
ExecStart=$HUGEPAGES_HELPER
[Install]
WantedBy=multi-user.target
EOF
}
configure_systemd_hugepages() {
[[ "$one_gb_pages" == "true" ]] || return 0
log "$BLUE" "配置 1GB Huge Pages 持久池..."
write_hugepages_helper
write_hugepages_service
mkdir -p "$SYSTEMD_DROPIN_DIR"
cat >"$SYSTEMD_DROPIN" <<'EOF'
[Unit]
Requires=xxxig-hugepages.service
After=xxxig-hugepages.service
EOF
}
configure_alpine_hugepages() {
[[ "$one_gb_pages" == "true" ]] || return 0
log "$BLUE" "配置 1GB Huge Pages 持久池..."
write_hugepages_helper
cat >/etc/init.d/xxxig-hugepages <<EOF
#!/sbin/openrc-run
description="Reserve Huge Pages for XXXig"
start() {
ebegin "Reserving Huge Pages for XXXig"
$HUGEPAGES_HELPER
eend \$?
}
EOF
chmod 755 /etc/init.d/xxxig-hugepages
rc-update add xxxig-hugepages default
}
# 配置 CPU 亲和性 # 配置 CPU 亲和性
configure_cpu_rx() { configure_cpu_rx() {
local cpu_cores=$(nproc) local cpu_cores=$(nproc)
@@ -109,6 +211,29 @@ configure_cpu_rx() {
} }
# 更新配置文件 # 更新配置文件
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() { replace_config() {
[[ ! -f "$CONFIG_FILE" ]] && error "配置文件缺失" [[ ! -f "$CONFIG_FILE" ]] && error "配置文件缺失"
@@ -123,76 +248,87 @@ replace_config() {
| .pools[0].nicehash = $pool_nicehash | .pools[0].nicehash = $pool_nicehash
| .\"verbose\" = $verbose" | .\"verbose\" = $verbose"
[[ "$one_gb_pages" == "true" ]] && jq_cmd+=" | .randomx.\"1gb-pages\" = true" append_pool_options
[[ "$pool_keepalive" == "true" ]] && jq_cmd+=" | .pools[0].keepalive = true" append_cc_options
[[ -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" jq "$jq_cmd" "$CONFIG_FILE" >"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE"
configure_cpu_rx configure_cpu_rx
} }
# 创建并启动服务 # 创建并启动服务
create_service() { create_alpine_service() {
if [[ "$os_type" == "alpine" ]]; then local hugepages_dependency=""
cat >/etc/init.d/xxxig <<'EOF' [[ "$one_gb_pages" == "true" ]] && hugepages_dependency=" need xxxig-hugepages"
cat >/etc/init.d/xxxig <<EOF
#!/sbin/openrc-run #!/sbin/openrc-run
name="XXXig Miner" name="XXXig Miner"
description="XXXig Miner Service" description="XXXig Miner Service"
command="/etc/miner/xxxig/xxxigDaemon" command="/etc/miner/xxxig/xxxigDaemon"
command_args="-c /etc/miner/xxxig/config.json" command_args="-c /etc/miner/xxxig/config.json"
pidfile="/run/${RC_SVCNAME}.pid" command_user="xxxig:xxxig"
pidfile="/run/\${RC_SVCNAME}.pid"
command_background="yes" command_background="yes"
rc_ulimit="-n 65535" rc_ulimit="-n 65535 -l unlimited"
depend() { depend() {
need net need net
$hugepages_dependency
after network after network
} }
EOF EOF
chmod +x /etc/init.d/xxxig chmod 755 /etc/init.d/xxxig
rc-update add xxxig default rc-update add xxxig default
rc-service xxxig start rc-service xxxig start
else }
write_systemd_service() {
cat >/etc/systemd/system/xxxig.service <<EOF cat >/etc/systemd/system/xxxig.service <<EOF
[Unit] [Unit]
Description=XXXig Miner Description=XXXig Miner
After=network.target After=network.target
[Service] [Service]
User=root Type=simple
User=xxxig
Group=xxxig
WorkingDirectory=$INSTALL_DIR
ExecStart=$INSTALL_DIR/xxxigDaemon -c $CONFIG_FILE ExecStart=$INSTALL_DIR/xxxigDaemon -c $CONFIG_FILE
Restart=always Restart=always
RestartSec=10 RestartSec=10
LimitNOFILE=65535 LimitNOFILE=65535
LimitMEMLOCK=infinity
AmbientCapabilities=CAP_IPC_LOCK
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=$INSTALL_DIR
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
EOF EOF
}
start_systemd_service() {
systemctl daemon-reload systemctl daemon-reload
if [[ "$one_gb_pages" == "true" ]]; then
systemctl enable xxxig-hugepages.service
fi
systemctl enable --now xxxig.service systemctl enable --now xxxig.service
}
create_service() {
if [[ "$os_type" == "alpine" ]]; then
create_alpine_service
else
write_systemd_service
start_systemd_service
fi fi
} }
show_usage() { show_usage() {
cat <<EOF cat <<EOF
用法: $0 [选项] 用法: $0 [选项]
选项: 选项:
-v, --version <版本> XXXig 版本 (默认: $DEFAULT_VERSION) -v, --version <版本> XXXig 版本 (默认: $DEFAULT_VERSION)
-t, --threads <数字> 线程数 (默认: 自动) -t, --threads <数字> 线程数 (默认: 自动)
@@ -213,15 +349,14 @@ show_usage() {
--cc-work-id <ID> CC 工作 ID --cc-work-id <ID> CC 工作 ID
--cc-token <令牌> CC 访问令牌 --cc-token <令牌> CC 访问令牌
--cc-tls 启用 CC TLS --cc-tls 启用 CC TLS
--keep-name 保留已有矿池密码和 CC worker-id
-h, --help 显示帮助信息 -h, --help 显示帮助信息
示例:
$0 -o pool.example.com:3333 -w YOUR_WALLET_ADDRESS $0 -o pool.example.com:3333 -w YOUR_WALLET_ADDRESS
EOF EOF
exit 1 exit 1
} }
parse_args() { init_args() {
version=$DEFAULT_VERSION version=$DEFAULT_VERSION
threads=$DEFAULT_THREADS threads=$DEFAULT_THREADS
pool_algo=$DEFAULT_POOL_ALGO pool_algo=$DEFAULT_POOL_ALGO
@@ -242,7 +377,10 @@ parse_args() {
cc_token="" cc_token=""
cc_tls=$DEFAULT_CC_TLS cc_tls=$DEFAULT_CC_TLS
one_gb_pages=$DEFAULT_ONE_GB_PAGES one_gb_pages=$DEFAULT_ONE_GB_PAGES
keep_name=$DEFAULT_KEEP_NAME
}
read_args() {
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case "$1" in case "$1" in
-v | --version) version="$2"; shift 2 ;; -v | --version) version="$2"; shift 2 ;;
@@ -265,21 +403,26 @@ parse_args() {
--verbose) verbose="true"; shift ;; --verbose) verbose="true"; shift ;;
--cc) cc_enabled="true"; shift ;; --cc) cc_enabled="true"; shift ;;
--cc-tls) cc_tls="true"; shift ;; --cc-tls) cc_tls="true"; shift ;;
--keep-name | --preserve-name) keep_name="true"; shift ;;
-h | --help) show_usage ;; -h | --help) show_usage ;;
*) error "无效选项: $1" ;; *) error "无效选项: $1" ;;
esac esac
done done
}
# 验证必需参数 validate_args() {
[[ -z "$pool_address" ]] && error "矿池地址不能为空" [[ -z "$pool_address" ]] && error "矿池地址不能为空"
[[ ! "$threads" =~ ^[0-9]+$ ]] && error "无效线程数" [[ ! "$threads" =~ ^[0-9]+$ ]] && error "无效线程数"
[[ "$pool_submit_to_origin" == "true" && -z "$pool_self_select" ]] && \ [[ "$pool_submit_to_origin" == "true" && -z "$pool_self_select" ]] && \
error "启用 submit_to_origin 必须设置 self_select" error "启用 submit_to_origin 必须设置 self_select"
return 0
}
# 处理默认值 resolve_defaults() {
local ip random_str
if [[ -z "$pool_password" ]]; then if [[ -z "$pool_password" ]]; then
local ip=$(curl -4s --retry 3 --connect-timeout 10 ifconfig.me 2>/dev/null || echo "0.0.0.0") 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) random_str=$(tr -dc '0-9a-zA-Z' </dev/urandom | head -c 5)
pool_password=$(echo "$ip" | awk -F. '{print $3"_"$4}')"_$random_str" pool_password=$(echo "$ip" | awk -F. '{print $3"_"$4}')"_$random_str"
fi fi
@@ -291,12 +434,33 @@ parse_args() {
elif [[ "$threads" -gt $(nproc) ]]; then elif [[ "$threads" -gt $(nproc) ]]; then
threads=$(nproc) threads=$(nproc)
fi fi
return 0
} }
main() { load_preserved_name() {
parse_args "$@" 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() {
local deps=(curl jq file) local deps=(curl jq file)
if command -v apt-get &>/dev/null; then if command -v apt-get &>/dev/null; then
for pkg in "${deps[@]}"; do for pkg in "${deps[@]}"; do
@@ -307,14 +471,18 @@ main() {
command -v "$pkg" &>/dev/null || apk add "$pkg" command -v "$pkg" &>/dev/null || apk add "$pkg"
done done
fi fi
}
prepare_download() {
local pkg_version
os_type=$(get_os) os_type=$(get_os)
[[ "$version" == "latest" ]] && version=$(get_gitea_latest_version) [[ "$version" == "latest" ]] && version=$(get_gitea_latest_version)
pkg_version="${version#v}"
local pkg_version="${version#v}" # registry 包版本为数字,去掉可能的 v 前缀
# 产物统一为 musl 全静态(linux-static),不再区分 distro;os_type 仅用于下方服务管理(OpenRC/systemd) # 产物统一为 musl 全静态(linux-static),不再区分 distro;os_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" download_url="https://${GITEA_SERVER}/api/packages/${GITEA_OWNER}/generic/${PACKAGE_NAME}/${pkg_version}/${PACKAGE_NAME}-$(get_arch)-linux-static-${pkg_version}.tar.gz"
}
show_config() {
log "$BLUE" "配置信息:" log "$BLUE" "配置信息:"
echo " 版本: $version" echo " 版本: $version"
echo " 架构: $(get_arch)" echo " 架构: $(get_arch)"
@@ -323,12 +491,23 @@ main() {
echo " 算法: $pool_algo" echo " 算法: $pool_algo"
echo " 矿池: $pool_address" echo " 矿池: $pool_address"
echo " 钱包: $wallet_address" echo " 钱包: $wallet_address"
}
install_runtime() {
uninstall_xxxig uninstall_xxxig
install_xxxig install_xxxig
replace_config replace_config
create_xxxig_user
set_runtime_permissions
if [[ "$os_type" == "alpine" ]]; then
configure_alpine_hugepages
else
configure_systemd_hugepages
fi
create_service create_service
}
show_management_commands() {
echo "管理命令:" echo "管理命令:"
if [[ "$os_type" == "alpine" ]]; then if [[ "$os_type" == "alpine" ]]; then
echo " rc-service xxxig status" echo " rc-service xxxig status"
@@ -341,4 +520,15 @@ main() {
fi fi
} }
main() {
parse_args "$@"
install_dependencies
load_preserved_name
resolve_defaults
prepare_download
show_config
install_runtime
show_management_commands
}
main "$@" main "$@"