From 8c1137db06a9146f588cbd9d417c15b9de869198 Mon Sep 17 00:00:00 2001 From: shenmo Date: Fri, 24 Apr 2026 20:36:46 +0800 Subject: [PATCH] =?UTF-8?q?chore:=E6=8A=8Aapm=E6=9C=AC=E4=BD=93=E6=94=BE?= =?UTF-8?q?=E5=88=B0/usr/libexec=E9=87=8C=EF=BC=8C=E6=8B=86=E5=88=86?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/usr/bin/apm | 554 +---------------------------------- src/usr/libexec/apm/apm-eggs | 62 ++++ src/usr/libexec/apm/apm-main | 497 +++++++++++++++++++++++++++++++ 3 files changed, 560 insertions(+), 553 deletions(-) mode change 100755 => 120000 src/usr/bin/apm create mode 100755 src/usr/libexec/apm/apm-eggs create mode 100755 src/usr/libexec/apm/apm-main diff --git a/src/usr/bin/apm b/src/usr/bin/apm deleted file mode 100755 index d8fa7a8..0000000 --- a/src/usr/bin/apm +++ /dev/null @@ -1,553 +0,0 @@ -#!/bin/bash -VERSION=@VERSION@ -# 获取脚本名称用于帮助信息 -SCRIPT_NAME=$(basename "$0") -PATH_PREFIX=/var/lib/apm/apm/files/ace-env/ - -log.warn() { echo -e "[\e[33mWARN\e[0m]: \e[1m$*\e[0m"; } -log.error() { echo -e "[\e[31mERROR\e[0m]: \e[1m$*\e[0m"; } -log.info() { echo -e "[\e[96mINFO\e[0m]: \e[1m$*\e[0m"; } -log.debug() { echo -e "[\e[32mDEBUG\e[0m]: \e[1m$*\e[0m"; } - -# 帮助信息函数 -show_help() { - cat < [args...] 启动软件包(通过应用启动器) - run [EXEC_PATH] [args...] 运行指定软件包的可执行文件(可指定容器内路径) - update 更新软件包信息 - list 查看可用软件包信息 - search 搜索软件包 - show 展示包信息 - clean 清除缓存软件包 - autoremove 自动移除不需要的包 - - amber 彩蛋功能 - xmp360 彩蛋功能 - bronya 彩蛋功能 - - -h, --help 显示此帮助信息 - --help-all 显示完整帮助信息 - -v, --version 展示APM版本号 - - 本 APM 具有兔兔伯爵,女武神装甲和超级大运之力。 -EOF -} -# 彩蛋函数 -amber_egg() { - cat <<'EOF' - - ____ ____ - / __ )____ __________ ____ / __ )__ ______ ____ __ __ - / __ / __ `/ ___/ __ \/ __ \ / __ / / / / __ \/ __ \/ / / / - / /_/ / /_/ / / / /_/ / / / / / /_/ / /_/ / / / / / / / /_/ / -/_____/\__,_/_/ \____/_/ /_/ /_____/\__,_/_/ /_/_/ /_/\__, / - /____/ - -Amber Package Manager - Sparkling with magic! 安柏包管理器 - blingbling~ -💎 Another target tracked down by Outrider Amber! 侦察骑士,发现目标! -EOF -} - -bronya_egg() { - cat <<'EOF' - _ __ ____ _ ____ __ - | | / /__ _/ / /____ ______(_)__ / __/_ _____ / /____ __ _ - | |/ / _ `/ / '_/ // / __/ / _-) _\ \/ // (_- [args...] 启动软件包(通过应用启动器) - run [EXEC_PATH] [args...] 运行指定软件包的可执行文件(可指定容器内路径) - sandbox-run [EXEC_PATH] [args...] 运行指定软件包的可执行文件(主目录沙箱化) - bwrap-run [EXEC_PATH] [args...] 运行指定软件包的可执行文件(使用 bwrap) - - update 更新软件包信息 - hold 锁定软件包版本 - unhold 解锁软件包版本 - full-upgrade 升级全部软件包 - list 查看可用软件包信息 - search 搜索软件包 - - download 下载包 - show 展示包信息 - clean 清除缓存软件包 - autoremove 自动移除不需要的包 - ssinstall 使用 ssinstall 进行本地软件安装,详情见 spark-store - ssaudit 使用 ssaudit 进行本地软件安装,详情见 spark-store - debug 显示调试系统信息并进入调试环境 - - amber 彩蛋功能 - xmp360 彩蛋功能 - bronya 彩蛋功能 - - -h, --help 显示简要帮助信息 - --help-all 显示此完整帮助信息 - -v, --version 展示APM版本号 - - 本 APM 具有兔兔伯爵,女武神装甲和超级大运之力。 -EOF -} - -apm_exec(){ - # =============================== - # 基础变量 - # =============================== - local lowerdirs=() - local env_layers=() - local current_dir="${PATH_PREFIX}/var/lib/apm/${coredir}" - local next_info_file="" - local APM_RUN_EXEC=/var/lib/apm/apm/files/ace-run - - # =============================== - # 递归读取 info / info_env - # =============================== - while : ; do - next_info_file="${current_dir}/info" - - # 记录 info_env(底层优先) - if [[ -f "${current_dir}/info_env" ]]; then - env_layers+=("${current_dir}/info_env") - fi - - # 没有 info 就停止 - [[ ! -f "$next_info_file" ]] && break - - # 读取依赖层 - while IFS= read -r basedir; do - [[ -z "$basedir" ]] && continue - - if [[ -d "${PATH_PREFIX}/var/lib/apm/${basedir}/files/ace-env" ]]; then - lowerdirs+=("${PATH_PREFIX}/var/lib/apm/${basedir}/files/ace-env") - elif [[ -d "${PATH_PREFIX}/var/lib/apm/${basedir}/files/core" ]]; then - lowerdirs+=("${PATH_PREFIX}/var/lib/apm/${basedir}/files/core") - else - log.warn "Neither ace-env nor core directory found for base: $basedir" - fi - done < "$next_info_file" - - # 递归到下一个 - local next_basedir - next_basedir="$(tail -n 1 "$next_info_file")" - [[ -z "$next_basedir" || ! -d "${PATH_PREFIX}/var/lib/apm/${next_basedir}" ]] && break - current_dir="${PATH_PREFIX}/var/lib/apm/${next_basedir}" - done - - # =============================== - # info_layer_override(最高优先级) - # =============================== - local override_file="${PATH_PREFIX}/var/lib/apm/${coredir}/info_layer_override" - if [[ -f "$override_file" ]]; then - log.debug "Found info_layer_override: $override_file" - - local override_dirs=() - local override_envs=() - - while IFS= read -r basedir; do - [[ -z "$basedir" ]] && continue - local base="${PATH_PREFIX}/var/lib/apm/${basedir}" - - if [[ -d "${base}/files/ace-env" ]]; then - override_dirs+=("${base}/files/ace-env") - elif [[ -d "${base}/files/core" ]]; then - override_dirs+=("${base}/files/core") - else - log.warn "Override layer not found: $basedir" - fi - - if [[ -f "${base}/info_env" ]]; then - override_envs+=("${base}/info_env") - fi - done < "$override_file" - - # override 层放最前(最高) - if [[ ${#override_dirs[@]} -gt 0 ]]; then - lowerdirs=("${override_dirs[@]}" "${lowerdirs[@]}") - fi - - # override env 最后应用(最高) - if [[ ${#override_envs[@]} -gt 0 ]]; then - env_layers+=("${override_envs[@]}") - fi - fi - - # =============================== - # 检查 lowerdir - # =============================== - if [[ ${#lowerdirs[@]} -eq 0 ]]; then - log.error "No valid lower directories found for package: $coredir" - return 1 - fi - - local lowerdir - lowerdir=$(IFS=:; echo "${lowerdirs[*]}") - - mkdir -p "/tmp/apm/${coredir}" - - # =============================== - # 应用 info_env(从下到上) - # =============================== - for env_file in "${env_layers[@]}"; do - log.debug "Applying env: $env_file" - - while IFS= read -r line || [[ -n "$line" ]]; do - [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue - - if [[ "$line" =~ ^[A-Za-z_][A-Za-z0-9_]*= ]]; then - local key="${line%%=*}" - local val="${line#*=}" - - # 去首尾空白 - val="${val#"${val%%[![:space:]]*}"}" - val="${val%"${val##*[![:space:]]}"}" - - # 去外层引号 - if [[ "$val" =~ ^\".*\"$ || "$val" =~ ^\'.*\'$ ]]; then - val="${val:1:-1}" - fi - - export "$key=$val" - else - log.warn "Invalid env line ignored: $line" - fi - done < "$env_file" - done - - # =============================== - # 挂载 overlay - # =============================== - log.debug "Mounting overlayfs" - log.debug "lowerdir=$lowerdir" - - fuse-overlayfs \ - -o lowerdir="$lowerdir",upperdir="${PATH_PREFIX}/var/lib/apm/${coredir}/files/core/",workdir="${PATH_PREFIX}/var/lib/apm/${coredir}/files/work/" \ - "/tmp/apm/${coredir}" - - # =============================== - # 执行 - # =============================== - chrootEnvPath="/tmp/apm/${coredir}" "${APM_RUN_EXEC}" "$@" - - # =============================== - # 卸载 - # =============================== - umount "/tmp/apm/${coredir}" -} - -# 启动应用:通过 amber-pm-app-launcher 运行 -apm_launch() { - local pkg="$1" - shift - if [ -z "$pkg" ]; then - log.error "Package name required for 'launch' command" - return 1 - fi - - # 保存原始 PATH_PREFIX,检查包是否存在(逻辑同 run 分支) - local original_path_prefix="$PATH_PREFIX" - if ! [ -d "${PATH_PREFIX}/var/lib/apm/$pkg" ]; then - if [ -d "/var/lib/apm/$pkg" ]; then - PATH_PREFIX="" - else - log.error "Package not installed: $pkg" - return 1 - fi - fi - - # 调用应用启动器,传递所有参数 - amber-pm-app-launcher "$pkg" "$@" - local exit_code=$? - - # 恢复 PATH_PREFIX(不影响后续命令) - PATH_PREFIX="$original_path_prefix" - return $exit_code -} - -# 调试信息函数 -debug_info() { - log.debug "======= APM Debug Information =======" - log.debug "User: $(whoami)" - log.debug "Hostname: $(hostname)" - log.debug "OS: $(lsb_release -ds 2>/dev/null || uname -om)" - log.debug "Kernel: $(uname -sr)" - log.debug "Bash Version: ${BASH_VERSION}" - log.debug "APT Version: $(apt --version | head -n1)" - log.debug "APM APT Version: $(amber-pm-debug apt --version | head -n1)" - log.debug "=====================================" - -amber-pm-debug "$@" - -} - - -apm-nvidia-toggle(){ - -# APM 基础路径 -APM_BASE="${PATH_PREFIX}/var/lib/apm" - -# 检查基础目录是否存在 -if [[ ! -d "$APM_BASE" ]]; then - echo "错误: 目录 $APM_BASE 不存在" - exit 1 -fi - -# 遍历 /var/lib/apm 下的所有目录 -for dir in "$APM_BASE"/*/; do - # 移除末尾的斜杠得到纯目录名 - dir="${dir%/}" - - # 提取目录名(不包括完整路径) - dirname=$(basename "$dir") - # 检查目标文件是否存在 - target_file="${APM_BASE}/${dirname}/files/ace-env" - if [[ -e "$target_file" ]]; then - - # 将目录传递给 amber-pm-configure-nvidia - amber-pm-configure-nvidia "$target_file" - - - fi -done -} - -# 主命令处理 -case "$1" in - install|full-upgrade|upgrade|reinstall) - command=$1 - shift - amber-pm-debug aptss "$command" "$@" - exit_code=$? - - # 如果第一次执行失败,尝试修复并重试 - if [ $exit_code -ne 0 ]; then - log.warn "Command failed, attempting to fix with dpkg --configure -a..." - amber-pm-debug dpkg --configure -a - log.info "Retrying $command..." - amber-pm-debug aptss "$command" "$@" - exit_code=$? - fi - - if [ $exit_code -eq 0 ]; then - log.info "Operation successful" - else - log.error "Error: Operation failed" - exit $exit_code - fi - amber-pm-debug amber-pm-dstore-patch - apm-nvidia-toggle - amber-pm-desktop-fix - update-mime-database /var/lib/apm/apm/files/ace-env/amber-ce-tools/data-dir/mime > /dev/null 2>&1 & - ;; - download|search|policy|list|update|clean|show|depends|rdepends|changelog|moo) - command=$1 - shift - amber-pm-debug aptss "$command" "$@" - exit_code=$? - if [ $exit_code -eq 0 ]; then - log.info "Operation successful" - else - log.error "Error: Operation failed" - exit $exit_code - fi - ;; - hold|unhold) - command=$1 - shift - amber-pm-debug apt-mark "$command" "$@" - exit_code=$? - if [ $exit_code -eq 0 ]; then - log.info "Operation successful" - else - log.error "Error: Operation failed" - exit $exit_code - fi - ;; - - remove|autoremove|purge|autopurge) - # 特殊APT命令:移除第一个参数后传递其余参数 - command=$1 - shift - amber-pm-debug aptss "$command" "$@" - exit_code=$? - if [ $exit_code -eq 0 ]; then - log.info "Operation successful" - else - log.error "Error: Operation failed" - exit $exit_code - fi - amber-pm-debug amber-pm-dstore-patch - amber-pm-desktop-fix - ;; - launch) - shift - apm_launch "$@" - exit_code=$? - if [ $exit_code -eq 0 ]; then - log.info "Operation successful" - else - log.error "Error: Operation failed" - exit $exit_code - fi - ;; - run) - # 运行包命令:第二个参数必须是包名 - if [ -z "$2" ]; then - log.error "Package name required for 'run' command" - show_help - exit 1 - fi - - # 检查包是否已安装 - pkg="$2" - shift 2 # 移除 'run' 和包名 - - if ! ls "${PATH_PREFIX}/var/lib/apm/$pkg" >/dev/null 2>&1; then - # 如果带前缀的目录不存在,尝试不带前缀的目录 - if ls "/var/lib/apm/$pkg" >/dev/null 2>&1; then - # 如果不带前缀的目录存在,清空 PATH_PREFIX - PATH_PREFIX="" - else - # 如果两个目录都不存在,报错退出 - log.error "Package not installed: $pkg" - exit 1 - fi - fi - - coredir=$pkg - export APM_PKG_NAME=$pkg - - # 检测是否有额外命令参数 - if [ $# -gt 0 ]; then - # 有额外参数:执行用户提供的命令 - log.info "Running user command: $*" - apm_exec "$@" - else - # 没有额外参数:提示用户改用 launch,并自动调用 launch - log.info "未指定可执行文件路径。如果希望在未指定容器路径的情况下启动应用程序,推荐使用 "launch" 命令" - log.info "正在启动:$SCRIPT_NAME launch $pkg" - apm_launch "$pkg" - exit $? - fi - ;; - sandbox-run) - # 运行包命令:第二个参数必须是包名 - export APM_USE_SANDBOX=1 - shift - $0 run "$@" - ;; - bwrap-run) - # 运行包命令:使用特殊的挂载参数以支持bwrap - export APM_USE_BWRAP=1 - shift - $0 run "$@" - ;; - debug) - shift - debug_info $@ - ;; - ssaudit) - amber-pm-debug dpkg --configure -a - amber-pm-debug ssaudit $@ --native - exit_code=$? - if [ $exit_code -eq 0 ]; then - log.info "Operation successful" - else - log.error "Error: Operation failed" - exit $exit_code - fi - amber-pm-debug amber-pm-dstore-patch - amber-pm-desktop-fix - - ;; - ssinstall) - amber-pm-debug dpkg --configure -a - amber-pm-debug ssinstall $@ --native - exit_code=$? - if [ $exit_code -eq 0 ]; then - log.info "Operation successful" - else - log.error "Error: Operation failed" - exit $exit_code - fi - amber-pm-debug amber-pm-dstore-patch - amber-pm-desktop-fix - - ;; - -h|--help) - show_help - ;; - --help-all) - show_help_all - ;; - -v|--version) - echo "$VERSION" - ;; - amber) - amber_egg - ;; - xmp360) - xmp360_egg - ;; - bronya) - bronya_egg - ;; - *) - show_help - ;; -esac \ No newline at end of file diff --git a/src/usr/bin/apm b/src/usr/bin/apm new file mode 120000 index 0000000..f5fa1a1 --- /dev/null +++ b/src/usr/bin/apm @@ -0,0 +1 @@ +/usr/libexec/apm/apm-main \ No newline at end of file diff --git a/src/usr/libexec/apm/apm-eggs b/src/usr/libexec/apm/apm-eggs new file mode 100755 index 0000000..91f36f7 --- /dev/null +++ b/src/usr/libexec/apm/apm-eggs @@ -0,0 +1,62 @@ +#!/bin/bash +# APM 彩蛋功能模块 +# 被 /usr/libexec/apm/apm-main 按需 source + +amber_egg() { + cat <<'EOF' + + ____ ____ + / __ )____ __________ ____ / __ )__ ______ ____ __ __ + / __ / __ `/ ___/ __ \/ __ \ / __ / / / / __ \/ __ \/ / / / + / /_/ / /_/ / / / /_/ / / / / / /_/ / /_/ / / / / / / / /_/ / +/_____/\__,_/_/ \____/_/ /_/ /_____/\__,_/_/ /_/_/ /_/\__, / + /____/ + +Amber Package Manager - Sparkling with magic! 安柏包管理器 - blingbling~ +💎 Another target tracked down by Outrider Amber! 侦察骑士,发现目标! +EOF +} + +bronya_egg() { + cat <<'EOF' + _ __ ____ _ ____ __ + | | / /__ _/ / /____ ______(_)__ / __/_ _____ / /____ __ _ + | |/ / _ `/ / '_/ // / __/ / _-) _\ \/ // (_- [args...] 启动软件包(通过应用启动器) + run [EXEC_PATH] [args...] 运行指定软件包的可执行文件(可指定容器内路径) + update 更新软件包信息 + list 查看可用软件包信息 + search 搜索软件包 + show 展示包信息 + clean 清除缓存软件包 + autoremove 自动移除不需要的包 + + amber 彩蛋功能 + xmp360 彩蛋功能 + bronya 彩蛋功能 + + -h, --help 显示此帮助信息 + --help-all 显示完整帮助信息 + -v, --version 展示APM版本号 + + 本 APM 具有兔兔伯爵,女武神装甲和超级大运之力。 +EOF +} + +# 完整帮助信息函数 +show_help_all() { + cat < [args...] 启动软件包(通过应用启动器) + run [EXEC_PATH] [args...] 运行指定软件包的可执行文件(可指定容器内路径) + sandbox-run [EXEC_PATH] [args...] 运行指定软件包的可执行文件(主目录沙箱化) + bwrap-run [EXEC_PATH] [args...] 运行指定软件包的可执行文件(使用 bwrap) + + update 更新软件包信息 + hold 锁定软件包版本 + unhold 解锁软件包版本 + full-upgrade 升级全部软件包 + list 查看可用软件包信息 + search 搜索软件包 + + download 下载包 + show 展示包信息 + clean 清除缓存软件包 + autoremove 自动移除不需要的包 + ssinstall 使用 ssinstall 进行本地软件安装,详情见 spark-store + ssaudit 使用 ssaudit 进行本地软件安装,详情见 spark-store + debug 显示调试系统信息并进入调试环境 + + amber 彩蛋功能 + xmp360 彩蛋功能 + bronya 彩蛋功能 + + -h, --help 显示简要帮助信息 + --help-all 显示此完整帮助信息 + -v, --version 展示APM版本号 + + 本 APM 具有兔兔伯爵,女武神装甲和超级大运之力。 +EOF +} + +apm_exec(){ + # =============================== + # 基础变量 + # =============================== + local lowerdirs=() + local env_layers=() + local current_dir="${PATH_PREFIX}/var/lib/apm/${coredir}" + local next_info_file="" + local APM_RUN_EXEC=/var/lib/apm/apm/files/ace-run + + # =============================== + # 递归读取 info / info_env + # =============================== + while : ; do + next_info_file="${current_dir}/info" + + # 记录 info_env(底层优先) + if [[ -f "${current_dir}/info_env" ]]; then + env_layers+=("${current_dir}/info_env") + fi + + # 没有 info 就停止 + [[ ! -f "$next_info_file" ]] && break + + # 读取依赖层 + while IFS= read -r basedir; do + [[ -z "$basedir" ]] && continue + + if [[ -d "${PATH_PREFIX}/var/lib/apm/${basedir}/files/ace-env" ]]; then + lowerdirs+=("${PATH_PREFIX}/var/lib/apm/${basedir}/files/ace-env") + elif [[ -d "${PATH_PREFIX}/var/lib/apm/${basedir}/files/core" ]]; then + lowerdirs+=("${PATH_PREFIX}/var/lib/apm/${basedir}/files/core") + else + log.warn "Neither ace-env nor core directory found for base: $basedir" + fi + done < "$next_info_file" + + # 递归到下一个 + local next_basedir + next_basedir="$(tail -n 1 "$next_info_file")" + [[ -z "$next_basedir" || ! -d "${PATH_PREFIX}/var/lib/apm/${next_basedir}" ]] && break + current_dir="${PATH_PREFIX}/var/lib/apm/${next_basedir}" + done + + # =============================== + # info_layer_override(最高优先级) + # =============================== + local override_file="${PATH_PREFIX}/var/lib/apm/${coredir}/info_layer_override" + if [[ -f "$override_file" ]]; then + log.debug "Found info_layer_override: $override_file" + + local override_dirs=() + local override_envs=() + + while IFS= read -r basedir; do + [[ -z "$basedir" ]] && continue + local base="${PATH_PREFIX}/var/lib/apm/${basedir}" + + if [[ -d "${base}/files/ace-env" ]]; then + override_dirs+=("${base}/files/ace-env") + elif [[ -d "${base}/files/core" ]]; then + override_dirs+=("${base}/files/core") + else + log.warn "Override layer not found: $basedir" + fi + + if [[ -f "${base}/info_env" ]]; then + override_envs+=("${base}/info_env") + fi + done < "$override_file" + + # override 层放最前(最高) + if [[ ${#override_dirs[@]} -gt 0 ]]; then + lowerdirs=("${override_dirs[@]}" "${lowerdirs[@]}") + fi + + # override env 最后应用(最高) + if [[ ${#override_envs[@]} -gt 0 ]]; then + env_layers+=("${override_envs[@]}") + fi + fi + + # =============================== + # 检查 lowerdir + # =============================== + if [[ ${#lowerdirs[@]} -eq 0 ]]; then + log.error "No valid lower directories found for package: $coredir" + return 1 + fi + + local lowerdir + lowerdir=$(IFS=:; echo "${lowerdirs[*]}") + + mkdir -p "/tmp/apm/${coredir}" + + # =============================== + # 应用 info_env(从下到上) + # =============================== + for env_file in "${env_layers[@]}"; do + log.debug "Applying env: $env_file" + + while IFS= read -r line || [[ -n "$line" ]]; do + [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue + + if [[ "$line" =~ ^[A-Za-z_][A-Za-z0-9_]*= ]]; then + local key="${line%%=*}" + local val="${line#*=}" + + # 去首尾空白 + val="${val#"${val%%[![:space:]]*}"}" + val="${val%"${val##*[![:space:]]}"}" + + # 去外层引号 + if [[ "$val" =~ ^\".*\"$ || "$val" =~ ^\'.*\'$ ]]; then + val="${val:1:-1}" + fi + + export "$key=$val" + else + log.warn "Invalid env line ignored: $line" + fi + done < "$env_file" + done + + # =============================== + # 挂载 overlay + # =============================== + log.debug "Mounting overlayfs" + log.debug "lowerdir=$lowerdir" + + fuse-overlayfs \ + -o lowerdir="$lowerdir",upperdir="${PATH_PREFIX}/var/lib/apm/${coredir}/files/core/",workdir="${PATH_PREFIX}/var/lib/apm/${coredir}/files/work/" \ + "/tmp/apm/${coredir}" + + # =============================== + # 执行 + # =============================== + chrootEnvPath="/tmp/apm/${coredir}" "${APM_RUN_EXEC}" "$@" + + # =============================== + # 卸载 + # =============================== + umount "/tmp/apm/${coredir}" +} + +# 启动应用:通过 amber-pm-app-launcher 运行 +apm_launch() { + local pkg="$1" + shift + if [ -z "$pkg" ]; then + log.error "Package name required for 'launch' command" + return 1 + fi + + # 保存原始 PATH_PREFIX,检查包是否存在(逻辑同 run 分支) + local original_path_prefix="$PATH_PREFIX" + if ! [ -d "${PATH_PREFIX}/var/lib/apm/$pkg" ]; then + if [ -d "/var/lib/apm/$pkg" ]; then + PATH_PREFIX="" + else + log.error "Package not installed: $pkg" + return 1 + fi + fi + + # 调用应用启动器,传递所有参数 + amber-pm-app-launcher "$pkg" "$@" + local exit_code=$? + + # 恢复 PATH_PREFIX(不影响后续命令) + PATH_PREFIX="$original_path_prefix" + return $exit_code +} + +# 调试信息函数 +debug_info() { + log.debug "======= APM Debug Information =======" + log.debug "User: $(whoami)" + log.debug "Hostname: $(hostname)" + log.debug "OS: $(lsb_release -ds 2>/dev/null || uname -om)" + log.debug "Kernel: $(uname -sr)" + log.debug "Bash Version: ${BASH_VERSION}" + log.debug "APT Version: $(apt --version | head -n1)" + log.debug "APM APT Version: $(amber-pm-debug apt --version | head -n1)" + log.debug "=====================================" + +amber-pm-debug "$@" + +} + + +apm-nvidia-toggle(){ + +# APM 基础路径 +APM_BASE="${PATH_PREFIX}/var/lib/apm" + +# 检查基础目录是否存在 +if [[ ! -d "$APM_BASE" ]]; then + echo "错误: 目录 $APM_BASE 不存在" + exit 1 +fi + +# 遍历 /var/lib/apm 下的所有目录 +for dir in "$APM_BASE"/*/; do + # 移除末尾的斜杠得到纯目录名 + dir="${dir%/}" + + # 提取目录名(不包括完整路径) + dirname=$(basename "$dir") + # 检查目标文件是否存在 + target_file="${APM_BASE}/${dirname}/files/ace-env" + if [[ -e "$target_file" ]]; then + + # 将目录传递给 amber-pm-configure-nvidia + amber-pm-configure-nvidia "$target_file" + + + fi +done +} + +# 主命令处理 +case "$1" in + install|full-upgrade|upgrade|reinstall) + command=$1 + shift + amber-pm-debug aptss "$command" "$@" + exit_code=$? + + # 如果第一次执行失败,尝试修复并重试 + if [ $exit_code -ne 0 ]; then + log.warn "Command failed, attempting to fix with dpkg --configure -a..." + amber-pm-debug dpkg --configure -a + log.info "Retrying $command..." + amber-pm-debug aptss "$command" "$@" + exit_code=$? + fi + + if [ $exit_code -eq 0 ]; then + log.info "Operation successful" + else + log.error "Error: Operation failed" + exit $exit_code + fi + amber-pm-debug amber-pm-dstore-patch + apm-nvidia-toggle + amber-pm-desktop-fix + update-mime-database /var/lib/apm/apm/files/ace-env/amber-ce-tools/data-dir/mime > /dev/null 2>&1 & + ;; + download|search|policy|list|update|clean|show|depends|rdepends|changelog|moo) + command=$1 + shift + amber-pm-debug aptss "$command" "$@" + exit_code=$? + if [ $exit_code -eq 0 ]; then + log.info "Operation successful" + else + log.error "Error: Operation failed" + exit $exit_code + fi + ;; + hold|unhold) + command=$1 + shift + amber-pm-debug apt-mark "$command" "$@" + exit_code=$? + if [ $exit_code -eq 0 ]; then + log.info "Operation successful" + else + log.error "Error: Operation failed" + exit $exit_code + fi + ;; + + remove|autoremove|purge|autopurge) + # 特殊APT命令:移除第一个参数后传递其余参数 + command=$1 + shift + amber-pm-debug aptss "$command" "$@" + exit_code=$? + if [ $exit_code -eq 0 ]; then + log.info "Operation successful" + else + log.error "Error: Operation failed" + exit $exit_code + fi + amber-pm-debug amber-pm-dstore-patch + amber-pm-desktop-fix + ;; + launch) + shift + apm_launch "$@" + exit_code=$? + if [ $exit_code -eq 0 ]; then + log.info "Operation successful" + else + log.error "Error: Operation failed" + exit $exit_code + fi + ;; + run) + # 运行包命令:第二个参数必须是包名 + if [ -z "$2" ]; then + log.error "Package name required for 'run' command" + show_help + exit 1 + fi + + # 检查包是否已安装 + pkg="$2" + shift 2 # 移除 'run' 和包名 + + if ! ls "${PATH_PREFIX}/var/lib/apm/$pkg" >/dev/null 2>&1; then + # 如果带前缀的目录不存在,尝试不带前缀的目录 + if ls "/var/lib/apm/$pkg" >/dev/null 2>&1; then + # 如果不带前缀的目录存在,清空 PATH_PREFIX + PATH_PREFIX="" + else + # 如果两个目录都不存在,报错退出 + log.error "Package not installed: $pkg" + exit 1 + fi + fi + + coredir=$pkg + export APM_PKG_NAME=$pkg + + # 检测是否有额外命令参数 + if [ $# -gt 0 ]; then + # 有额外参数:执行用户提供的命令 + log.info "Running user command: $*" + apm_exec "$@" + else + # 没有额外参数:提示用户改用 launch,并自动调用 launch + log.info "未指定可执行文件路径。如果希望在未指定容器路径的情况下启动应用程序,推荐使用 \"launch\" 命令" + log.info "正在启动:$SCRIPT_NAME launch $pkg" + apm_launch "$pkg" + exit $? + fi + ;; + sandbox-run) + # 运行包命令:第二个参数必须是包名 + export APM_USE_SANDBOX=1 + shift + "$0" run "$@" + ;; + bwrap-run) + # 运行包命令:使用特殊的挂载参数以支持bwrap + export APM_USE_BWRAP=1 + shift + "$0" run "$@" + ;; + debug) + shift + debug_info $@ + ;; + ssaudit) + amber-pm-debug dpkg --configure -a + amber-pm-debug ssaudit $@ --native + exit_code=$? + if [ $exit_code -eq 0 ]; then + log.info "Operation successful" + else + log.error "Error: Operation failed" + exit $exit_code + fi + amber-pm-debug amber-pm-dstore-patch + amber-pm-desktop-fix + + ;; + ssinstall) + amber-pm-debug dpkg --configure -a + amber-pm-debug ssinstall $@ --native + exit_code=$? + if [ $exit_code -eq 0 ]; then + log.info "Operation successful" + else + log.error "Error: Operation failed" + exit $exit_code + fi + amber-pm-debug amber-pm-dstore-patch + amber-pm-desktop-fix + + ;; + -h|--help) + show_help + ;; + --help-all) + show_help_all + ;; + -v|--version) + echo "$VERSION" + ;; + amber) + source /usr/libexec/apm/apm-eggs + amber_egg + ;; + xmp360) + source /usr/libexec/apm/apm-eggs + xmp360_egg + ;; + bronya) + source /usr/libexec/apm/apm-eggs + bronya_egg + ;; + *) + show_help + ;; +esac