diff --git a/script/install.deb.sh b/script/install.deb.sh index acbcc0f..f25cef1 100755 --- a/script/install.deb.sh +++ b/script/install.deb.sh @@ -16,6 +16,10 @@ declare -r RESET="\033[0m" CONFIG_DIR="/etc/xxxig" LOG_DIR="/var/log/xxxig" 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_SERVER="gitea.bcde.io" @@ -34,6 +38,7 @@ 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}"; } @@ -61,15 +66,16 @@ add_apt_repository() { # 卸载旧版本 uninstall_xxxig() { - systemctl stop xxxig-daemon xxxig-server 2>/dev/null || true - systemctl disable 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 xxxig-hugepages 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 -f "$HUGEPAGES_HELPER" "$HUGEPAGES_SERVICE" "$DAEMON_DROPIN" systemctl daemon-reload 2>/dev/null || true } -# 安装并启动服务 -install_and_start() { +# 安装软件包,配置完成后再启动服务 +install_xxxig() { log "$BLUE" "安装 XXXig $version..." if [[ "$version" == "latest" ]]; then apt-get install -y xxxig @@ -77,10 +83,79 @@ install_and_start() { apt-get install -y xxxig="${version#v}" 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" <"$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" "启动服务..." systemctl daemon-reload + if [[ "$one_gb_pages" == "true" ]]; then + systemctl enable xxxig-hugepages.service + fi systemctl enable --now xxxig-daemon.service - log "$GREEN" "安装完成" } # 配置 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() { [[ ! -f "$CONFIG_FILE" ]] && error "配置文件缺失" @@ -116,33 +214,17 @@ replace_config() { | .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 - + 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 < XXXig 版本 (默认: $DEFAULT_VERSION) -t, --threads <数字> 线程数 (默认: 自动) @@ -163,15 +245,14 @@ show_usage() { --cc-work-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 } -parse_args() { +init_args() { version=$DEFAULT_VERSION threads=$DEFAULT_THREADS pool_algo=$DEFAULT_POOL_ALGO @@ -192,7 +273,10 @@ parse_args() { 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 ;; @@ -215,21 +299,26 @@ parse_args() { --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 - 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 || echo "0.0.0.0") + random_str=$(tr -dc '0-9a-zA-Z' /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)" @@ -258,12 +369,21 @@ main() { 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_and_start + install_xxxig replace_config - systemctl restart xxxig-daemon.service + configure_hugepages + start_service echo "管理命令:" echo " systemctl status xxxig-daemon" diff --git a/script/install.sh b/script/install.sh index a284997..aff55c3 100644 --- a/script/install.sh +++ b/script/install.sh @@ -16,6 +16,10 @@ declare -r RESET="\033[0m" INSTALL_DIR="/etc/miner/xxxig" CONFIG_FILE="$INSTALL_DIR/config.json" 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_SERVER="gitea.bcde.io" @@ -36,6 +40,7 @@ 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}"; } @@ -67,12 +72,17 @@ get_gitea_latest_version() { uninstall_xxxig() { if [[ $os_type == "alpine" ]]; then 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 - 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 - systemctl stop xxxig 2>/dev/null || true - systemctl disable xxxig 2>/dev/null || true + systemctl stop xxxig xxxig-hugepages 2>/dev/null || true + systemctl disable xxxig xxxig-hugepages 2>/dev/null || true 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 fi } @@ -90,6 +100,98 @@ install_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" <"$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 <"$CONFIG_FILE.tmp" && mv "$CONFIG_FILE.tmp" "$CONFIG_FILE" configure_cpu_rx } # 创建并启动服务 -create_service() { - if [[ "$os_type" == "alpine" ]]; then - cat >/etc/init.d/xxxig <<'EOF' +create_alpine_service() { + local hugepages_dependency="" + [[ "$one_gb_pages" == "true" ]] && hugepages_dependency=" need xxxig-hugepages" + cat >/etc/init.d/xxxig </etc/systemd/system/xxxig.service </etc/systemd/system/xxxig.service < XXXig 版本 (默认: $DEFAULT_VERSION) -t, --threads <数字> 线程数 (默认: 自动) @@ -213,15 +349,14 @@ show_usage() { --cc-work-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 } -parse_args() { +init_args() { version=$DEFAULT_VERSION threads=$DEFAULT_THREADS pool_algo=$DEFAULT_POOL_ALGO @@ -242,7 +377,10 @@ parse_args() { 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 ;; @@ -265,21 +403,26 @@ parse_args() { --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 - 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 || echo "0.0.0.0") + random_str=$(tr -dc '0-9a-zA-Z' /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) if command -v apt-get &>/dev/null; then for pkg in "${deps[@]}"; do @@ -307,14 +471,18 @@ main() { command -v "$pkg" &>/dev/null || apk add "$pkg" done fi +} +prepare_download() { + local pkg_version os_type=$(get_os) [[ "$version" == "latest" ]] && version=$(get_gitea_latest_version) - - local pkg_version="${version#v}" # registry 包版本为数字,去掉可能的 v 前缀 + pkg_version="${version#v}" # 产物统一为 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" +} +show_config() { log "$BLUE" "配置信息:" echo " 版本: $version" echo " 架构: $(get_arch)" @@ -323,12 +491,23 @@ main() { echo " 算法: $pool_algo" echo " 矿池: $pool_address" echo " 钱包: $wallet_address" +} +install_runtime() { uninstall_xxxig install_xxxig replace_config + create_xxxig_user + set_runtime_permissions + if [[ "$os_type" == "alpine" ]]; then + configure_alpine_hugepages + else + configure_systemd_hugepages + fi create_service +} +show_management_commands() { echo "管理命令:" if [[ "$os_type" == "alpine" ]]; then echo " rc-service xxxig status" @@ -341,4 +520,15 @@ main() { fi } +main() { + parse_args "$@" + install_dependencies + load_preserved_name + resolve_defaults + prepare_download + show_config + install_runtime + show_management_commands +} + main "$@"