8 Commits
Author SHA1 Message Date
Melorise f3b0732fc1 fix: 修复容器卸载生命周期问题 2026-10-29 09:05:16 +08:00
Melorise 44aa06b3e8 完善 NixOS 的容器初始化和桌面资源集成
将 NixOS 宿主的程序依赖、桌面资源和持久化状态接入 APM 的 Debian
容器运行链路,支持系统更新后的脚本刷新、桌面启动器发现应用,
以及容器应用访问宿主字体、光标主题和 GTK 运行时资源。

- 新增 amber-pm-ace-init 入口,为初始化提供宿主命令依赖。在
  NixOS 上使用容器内的 Bash、PATH 和 locale 工具执行初始化,
  通过错误检测终止失败流程,在全部步骤完成后写入成功标记。
- 系统激活时从当前 Nix 构建刷新 /var/lib/apm 中 APM 自身的脚本
  和容器工具,使解释器路径随系统版本同步。刷新范围限定到
  APM 管理的文件,已安装应用继续使用原有运行环境。
- 在 NixOS 上通过 XDG_DATA_DIRS 注册 APM 的应用入口和图标,
  由桌面环境直接发现并展示容器应用。
- 根据 fonts.packages 生成 fontconfig 配置,通过 /host 将宿主
  字体接入容器,并合并容器字体和用户字体。显式设置的
  FONTCONFIG_FILE 具有最高优先级。
- 解析宿主光标主题的符号链接,将真实路径映射为容器可访问的
  /host 路径。从 XSettings 读取光标主题和尺寸,使桌面图形设置
  在应用启动时生效,显式设置的光标环境变量优先。
- 为 NixOS 应用和调试入口补充容器自身的 XDG 数据目录,使 GTK
  正确加载 MIME 数据库、GSettings schema 和图标,修复文件选择器
  因 PNG 解码失败而崩溃的问题。

宿主平台检测负责选择初始化和资源集成流程:NixOS 使用上述桥接,
其他发行版使用现有桌面集成、Shell 和 locale 初始化流程。通用
初始化代码修正参数引号、账户记录换行和重复执行时的链接创建。

Nix 打包表达式通过显式参数接收 src,支持 source 别名,同时传入
时以 src 为准。固定 Flake 依赖版本,补充 NixOS 使用文档和构建
检查,验证包参数兼容性、图形环境变量优先级及平台分支行为。
2026-10-08 15:35:35 +08:00
shenmo 068d91329f 修复有时错误地跳过覆盖内容的问题 2026-07-13 21:26:32 +08:00
shenmo ccfbdf0bbd !10 fix desktop entry config for nixos
Merge pull request !10 from SunnyPai/master
2026-06-18 03:13:30 +00:00
SunnyPai 6ee9f7ecdb fix desktop entry config for nixos 2026-06-16 13:44:40 +08:00
shenmo 293ce7006c chore(nix/module): 为amber-pm模块添加运行时依赖PATH
将常用工具加入运行时PATH,确保activation脚本可以正常调用依赖命令
2026-06-07 21:27:49 +08:00
shenmo 8fce0cad4a chore(nix): add version tracking and upgrade handling for amber-pm
1. 在包构建时写入版本文件到生成的状态目录
2. 在NixOS模块中添加版本检测逻辑,当版本变更时重新初始化状态
3. 新增首次初始化、版本升级和已有状态的不同处理流程
2026-06-07 21:03:49 +08:00
shenmo 9fe7714b7b 实验性支持 nixos 2026-06-07 20:32:46 +08:00
18 changed files with 920 additions and 50 deletions
+3
View File
@@ -0,0 +1,3 @@
result
result-*
spark-store/
+2 -1
View File
@@ -59,8 +59,9 @@ Commands:
### 完整命令列表
使用 `apm --help-all` 查看完整的命令列表,包括高级命令如 `sandbox-run`、`bwrap-run`、`hold`、`unhold`、`full-upgrade`、`download`、`ssinstall`、`ssaudit`、`debug` 等。
## NixOS 构建与本地测试
NixOS 本地构建、安装、module 使用以及 NUR/nixpkgs 打包复用说明见 [docs/NIXOS.md](docs/NIXOS.md)。
## APM Deb 包全自动转换器使用方法
+1 -1
View File
@@ -1,5 +1,5 @@
Package: apm
Version: 1.1.6-1
Version: 1.1.6-2
Maintainer: shenmo <jifengshenmo@outlook.com>
Priority: optional
Section: utils
+35 -7
View File
@@ -141,16 +141,44 @@ for pkg_dir in "$APM_BASE_DIR"/*/; do
fi
# 检查是否有文件需要更新(比较源文件和目标文件)
NEED_UPDATE=false
while IFS= read -r -d '' file; do
rel_path="${file#$OVERRIDE_SOURCE/}"
target_file="$target_dir/$rel_path"
# 如果目标文件不存在或源文件更新,则需要更新
if [ ! -e "$target_file" ] || [ "$file" -nt "$target_file" ]; then
NEED_UPDATE=false
while IFS= read -r -d '' file; do
rel_path="${file#$OVERRIDE_SOURCE/}"
target_file="$target_dir/$rel_path"
# 1. 目标文件不存在 ⇒ 需要更新
if [ ! -e "$target_file" ]; then
NEED_UPDATE=true
break
fi
# 2. 先比较文件大小(快速排除明显不同)
if [ "$(stat -c%s "$file")" -ne "$(stat -c%s "$target_file")" ]; then
NEED_UPDATE=true
break
fi
# 3. 再比较哈希值(选择系统中可用的哈希工具)
if command -v md5sum >/dev/null 2>&1; then
hash_cmd="md5sum"
elif command -v sha256sum >/dev/null 2>&1; then
hash_cmd="sha256sum"
else
# 若两者都不可用,退化为直接二进制比较(较慢,但确保正确)
if ! cmp -s "$file" "$target_file"; then
NEED_UPDATE=true
break
fi
done < <(find "$OVERRIDE_SOURCE" -type f -print0 2>/dev/null)
continue
fi
source_hash=$($hash_cmd "$file" | awk '{print $1}')
target_hash=$($hash_cmd "$target_file" | awk '{print $1}')
if [ "$source_hash" != "$target_hash" ]; then
NEED_UPDATE=true
break
fi
done < <(find "$OVERRIDE_SOURCE" -type f -print0 2>/dev/null)
# 如果没有需要更新的文件,跳过
if [ "$NEED_UPDATE" = false ]; then
+3
View File
@@ -0,0 +1,3 @@
{ pkgs ? import <nixpkgs> { } }:
pkgs.callPackage ./nix/package.nix { }
+131
View File
@@ -0,0 +1,131 @@
# NixOS 构建与本地测试
本仓库提供了实验性的 Nix 打包文件,可用于在 NixOS 上本地构建和测试 APM。
## 本地构建
在仓库根目录执行:
```bash
nix-build default.nix
```
构建成功后会生成 `result` 符号链接,可先做基础命令测试:
```bash
./result/bin/apm --version
./result/bin/apm --help
./result/bin/amber-pm-init-state --help
```
如果使用 Flake,也可以执行:
```bash
nix build .#amber-pm
nix flake check
```
## 初始化本地状态目录
APM 需要可写的 `/var/lib/apm` 目录保存自身运行环境和已安装应用。Nix 包中的文件位于只读 Nix store,因此首次测试前需要初始化状态目录:
```bash
sudo ./result/bin/amber-pm-init-state
```
如需用新构建结果覆盖 APM 自身文件,可执行:
```bash
sudo ./result/bin/amber-pm-init-state --force
```
`--force` 会原地覆盖 `/var/lib/apm/apm` 中的 APM 自身文件,不会移动、备份或删除整个 `/var/lib/apm/apm` 目录,以免影响已经安装在该目录下的 APM 应用。
随后初始化内置 AmberCE 环境:
```bash
sudo ./result/bin/amber-pm-ace-init
```
完成后可继续测试:
```bash
./result/bin/apm debug
./result/bin/apm update
./result/bin/apm search amber-pm-
```
## 作为 NixOS Module 使用
可在 NixOS 配置中引入本仓库的 module:
```nix
{ pkgs, ... }:
{
imports = [
/path/to/amber-pm/nix/module.nix
];
nixpkgs.overlays = [
(final: prev: {
amber-pm = final.callPackage /path/to/amber-pm/nix/package.nix { };
})
];
programs.amber-pm.enable = true;
}
```
然后执行:
```bash
sudo nixos-rebuild switch
```
该 module 会将 `amber-pm` 加入 `environment.systemPackages`,并在系统激活时初始化 `/var/lib/apm/apm`。APM 使用 bwrap 与 fuse-overlayfs,module 默认会设置 `kernel.apparmor_restrict_unprivileged_userns = 0`,并启用 `nix-ld` 以提高兼容性。
在 NixOS 上,APM 不会向 `/usr/share` 或 `/usr/local/share` 写入应用入口和图标。module 会将 `/var/lib/apm/apm/files/ace-env/amber-ce-tools/data-dir` 加入 `XDG_DATA_DIRS`,由桌面环境直接发现 APM 管理的应用。启用或更新该配置后需要重新登录桌面会话。
仅在 NixOS 宿主上,应用运行入口和调试入口会在容器的 `XDG_DATA_DIRS` 中,将 `/usr/local/share:/usr/share` 放到继承的宿主目录之前,确保 Debian 运行时能找到自己的 MIME 数据库、GSettings schema 和图标,避免 GTK 文件选择器因无法识别 PNG 而崩溃。其他发行版保持原有的数据目录传递逻辑。更新包后,module 在下一次系统激活时会自动刷新持久化的运行脚本。
module 还会根据 NixOS 合并后的 `fonts.packages` 生成 `/etc/amber-pm/fonts.conf`。仅在 NixOS 宿主且未显式指定 `FONTCONFIG_FILE` 时,APM 才启用该配置;已有的用户或应用配置优先。APM 容器通过已挂载的 `/host` 只读访问这些 Nix store 字体,同时保留容器自身字体以及 `~/.local/share/fonts`、`~/.fonts` 中的用户字体。字体包应加入 `fonts.packages`;仅加入 `environment.systemPackages` 不代表该字体已注册到系统 fontconfig。
仅在 NixOS 宿主上,启动应用时 APM 会保留显式的 `XCURSOR_PATH`,在宿主解析主题文件的真实路径,并补充容器可访问的 `/host/nix/store/...`。在 X11/XWayland 会话中,未显式指定的光标主题名和尺寸通过标准 XSettings 动态读取,因此图形设置中的调整无需写入 Nix 或 Home Manager,也无需重新构建系统。其他发行版不启用上述字体或光标桥接,也不强制替换初始化的 Shell、locale 流程或失败处理策略。
## NUR/nixpkgs 打包复用
`nix/package.nix` 支持外部传入 `version` 和 `src`,并保留 `source` 别名,因此 NUR 或 nixpkgs 中可以复用同一个表达式,不必依赖本地源码路径。同时传入时以 `src` 为准。
NUR 仓库中的示例:
```nix
{ pkgs ? import <nixpkgs> { } }:
{
amber-pm = pkgs.callPackage ./pkgs/amber-pm {
version = "1.3.4.0";
src = pkgs.fetchFromGitHub {
owner = "amber-ce";
repo = "amber-pm";
rev = "v1.3.4.0";
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
};
}
```
nixpkgs 中的包通常应放在类似路径:
```text
pkgs/by-name/am/amber-pm/package.nix
```
提交 nixpkgs 前建议先满足以下条件:
- 使用正式 tag 或 release,不使用本地路径作为源码。
- 固定 `src.hash`。
- 本地通过 `nix-build -A amber-pm` 或 `nix build .#amber-pm`。
- 确认 `apm --version`、`apm --help`、`amber-pm-init-state --help` 正常。
- `meta` 中填写 license、homepage、platforms 和 maintainers。
当前 NixOS 适配仍偏测试用途。建议先发布到 NUR 收集测试反馈,再投 nixpkgs。
Generated
+27
View File
@@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1784497964,
"narHash": "sha256-vlHUuqAcbcH2RKmHbPiuQzbv1pnzzavXnI62RD0bqCU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "241313f4e8e508cb9b13278c2b0fa25b9ca27163",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}
+107
View File
@@ -0,0 +1,107 @@
{
description = "Amber Package Manager packaged for NixOS testing";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs =
{ self, nixpkgs }:
let
systems = [
"x86_64-linux"
"aarch64-linux"
"loongarch64-linux"
];
forAllSystems = nixpkgs.lib.genAttrs systems;
in
{
packages = forAllSystems (
system:
let
pkgs = import nixpkgs { inherit system; };
in
{
amber-pm = pkgs.callPackage ./nix/package.nix { };
default = self.packages.${system}.amber-pm;
}
);
checks = forAllSystems (
system:
let
pkgs = import nixpkgs { inherit system; };
amber-pm = self.packages.${system}.amber-pm;
moduleTest = nixpkgs.lib.nixosSystem {
modules = [
self.nixosModules.default
{
nixpkgs.hostPlatform = system;
programs.amber-pm = {
enable = true;
package = amber-pm;
initializeState = false;
};
fonts.packages = [ pkgs.dejavu_fonts ];
system.stateVersion = "24.11";
}
];
};
apmFontconfig = moduleTest.config.environment.etc."amber-pm/fonts.conf".source;
in
{
cli-smoke =
assert (pkgs.callPackage ./nix/package.nix {
src = ./.;
source = ./src;
}).src == ./.;
assert (pkgs.callPackage ./nix/package.nix { source = ./.; }).src == ./.;
pkgs.runCommand "amber-pm-cli-smoke" { } ''
${amber-pm}/bin/apm --version
${amber-pm}/bin/apm --help >/dev/null
${amber-pm}/bin/amber-pm-init-state --help >/dev/null
! grep -Fq 'XCURSOR_PATH=' ${amber-pm}/bin/apm
grep -Fq 'xsettingsd-' ${amber-pm}/bin/apm
grep -Fq 'export FONTCONFIG_FILE="/host''${host_fontconfig_file}"' ${amber-pm}/usr/libexec/apm/apm-main
grep -Fq 'dump_xsettings' ${amber-pm}/usr/libexec/apm/apm-main
grep -Fq 'append_cursor_path "/host''${icon_root}"' ${amber-pm}/usr/libexec/apm/apm-main
grep -Fq '<include ignore_missing="yes">/etc/fonts/fonts.conf</include>' ${apmFontconfig}
grep -Fq '<dir>/host${pkgs.dejavu_fonts}</dir>' ${apmFontconfig}
(
# Load only helpers; never mount containers or initialize state.
source <(sed '/^# 帮助信息函数/,$d' ${amber-pm}/usr/libexec/apm/apm-main)
is_nixos() { [ "$mock_nixos" = 1 ]; }
dump_xsettings() { printf 'Gtk/CursorThemeName "Test Theme"\nGtk/CursorThemeSize 48\n'; }
mock_nixos=0
unset FONTCONFIG_FILE XCURSOR_PATH XCURSOR_THEME XCURSOR_SIZE
configure_host_fontconfig
configure_host_cursor
[ ! -v FONTCONFIG_FILE ]
[ ! -v XCURSOR_PATH ]
[ ! -v XCURSOR_THEME ]
[ ! -v XCURSOR_SIZE ]
for mock_nixos in 0 1; do
export FONTCONFIG_FILE=/custom/fonts.conf XCURSOR_PATH=/custom/cursors
export XCURSOR_THEME=Custom XCURSOR_SIZE=42
configure_host_fontconfig
configure_host_cursor
[ "$FONTCONFIG_FILE" = /custom/fonts.conf ]
[ "''${XCURSOR_PATH%%:*}" = /custom/cursors ]
[ "$XCURSOR_THEME" = Custom ]
[ "$XCURSOR_SIZE" = 42 ]
done
unset XCURSOR_THEME XCURSOR_SIZE
configure_host_cursor
[ "$XCURSOR_THEME" = 'Test Theme' ]
[ "$XCURSOR_SIZE" = 48 ]
)
touch "$out"
'';
}
);
nixosModules.default = import ./nix/module.nix;
overlays.default = final: prev: {
amber-pm = final.callPackage ./nix/package.nix { };
};
};
}
+74
View File
@@ -0,0 +1,74 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.amber-pm;
apmXdgDataDir = "/var/lib/apm/apm/files/ace-env/amber-ce-tools/data-dir";
apmFontconfig = pkgs.writeText "amber-pm-fonts.conf" ''
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
<!-- Keep the container's own fonts and per-user font directories. -->
<include ignore_missing="yes">/etc/fonts/fonts.conf</include>
<!-- The host root is mounted at /host by every APM runner. -->
${lib.concatMapStringsSep "\n" (
font: " <dir>${lib.escapeXML "/host${font}"}</dir>"
) config.fonts.packages}
</fontconfig>
'';
in
{
options.programs.amber-pm = {
enable = lib.mkEnableOption "Amber Package Manager";
package = lib.mkPackageOption pkgs "amber-pm" { };
initializeState = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Create /var/lib/apm/apm on first activation and refresh APM-managed files on later activations.";
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
# Generated from the final, merged NixOS fonts.packages value for this host.
environment.etc."amber-pm/fonts.conf".source = apmFontconfig;
environment.sessionVariables.XDG_DATA_DIRS = lib.mkAfter [ apmXdgDataDir ];
environment.etc."systemd/user-environment-generators/60-apm".source =
pkgs.writeShellScript "60-apm" ''
apm_xdg_data_dir=${lib.escapeShellArg apmXdgDataDir}
xdg_data_dirs="''${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
case ":$xdg_data_dirs:" in
*":$apm_xdg_data_dir:"*) ;;
*) xdg_data_dirs="$xdg_data_dirs:$apm_xdg_data_dir" ;;
esac
printf 'XDG_DATA_DIRS=%s\n' "$xdg_data_dirs"
'';
programs.nix-ld.enable = lib.mkDefault true;
boot.kernel.sysctl."kernel.apparmor_restrict_unprivileged_userns" = lib.mkDefault 0;
system.activationScripts.amber-pm-state = lib.mkIf cfg.initializeState ''
target="/var/lib/apm/apm"
if [ ! -e "$target" ]; then
echo "APM state directory not found, initializing..."
${cfg.package}/bin/amber-pm-init-state
echo "Running ace-init for first-time setup..."
${cfg.package}/bin/amber-pm-ace-init
else
echo "Refreshing APM-managed files from the current Nix generation..."
${cfg.package}/bin/amber-pm-init-state --force
fi
'';
};
}
+228
View File
@@ -0,0 +1,228 @@
{
lib,
stdenvNoCC,
makeWrapper,
bash,
bubblewrap,
coreutils,
curl,
desktop-file-utils,
dpkg,
fakeroot,
file,
findutils,
fuse-overlayfs,
gawk,
glib,
gnugrep,
gnused,
gzip,
libnotify,
procps,
sudo,
systemd,
gnutar,
util-linux,
which,
xdg-user-dirs,
xsettingsd,
xz,
zenity,
version ? "1.3.4.0",
sourceRoot ? ../.,
source ? lib.cleanSourceWith {
src = sourceRoot;
filter =
path: type:
let
base = baseNameOf path;
in
! lib.elem base [
".git"
"result"
];
},
# Accept explicit src overrides without callPackage auto-injecting pkgs.src,
# an unrelated package name in nixpkgs. source remains an alias.
...
}@args:
let
runtimePath = lib.makeBinPath [
bash
bubblewrap
coreutils
curl
desktop-file-utils
dpkg
fakeroot
file
findutils
fuse-overlayfs
gawk
glib
gnugrep
gnused
gzip
libnotify
procps
sudo
systemd
gnutar
util-linux
which
xdg-user-dirs
xsettingsd
xz
zenity
];
in
stdenvNoCC.mkDerivation {
pname = "amber-pm";
inherit version;
src = if args ? src then args.src else source;
nativeBuildInputs = [ makeWrapper ];
dontConfigure = true;
dontBuild = true;
installPhase = ''
runHook preInstall
echo "copying Debian-style install tree"
mkdir -p "$out"
cp -a src/* "$out"/
rm -f "$out/usr/bin/apm" \
"$out/usr/bin/amber-pm-debug" \
"$out/usr/bin/amber-pm-configure-nvidia"
echo "substituting version and store paths"
substituteInPlace "$out/usr/libexec/apm/apm-main" \
--replace-fail '@VERSION@' '${version}' \
--replace-fail '/usr/libexec/apm/apm-eggs' "$out/usr/libexec/apm/apm-eggs"
while IFS= read -r -d "" file; do
if grep -Iq '@VERSION@' "$file" && grep -q '@VERSION@' "$file"; then
sed -i 's|@VERSION@|${version}|g' "$file"
fi
done < <(find "$out/usr" "$out/etc" -type f -print0)
echo "patching host script shebangs"
patchShebangs "$out/usr/bin" "$out/usr/libexec"
patchShebangs \
"$out/var/lib/apm/apm/files/ace-run" \
"$out/var/lib/apm/apm/files/ace-run-pkg" \
"$out/var/lib/apm/apm/files/bin/ace-init" \
"$out/var/lib/apm/apm/files/bin/ace-run" \
"$out/var/lib/apm/apm/files/bin/amber-ce-configure-nvidia" \
"$out/var/lib/apm/apm/files/build-container.sh" \
"$out/var/lib/apm/apm/files/feedback.sh" \
"$out/var/lib/apm/apm/files/amber-ce-tools/ace-upgrader/ace-upgrader" \
"$out/var/lib/apm/apm/files/amber-ce-tools/container-init/init.sh" \
"$out/var/lib/apm/apm/files/amber-ce-tools/bin-override/apm-debug" \
"$out/var/lib/apm/apm/files/amber-ce-tools/bin-override/bwrap" \
"$out/var/lib/apm/apm/files/amber-ce-tools/bin-override/gio" \
"$out/var/lib/apm/apm/files/amber-ce-tools/bin-override/pkexec" \
"$out/var/lib/apm/apm/files/amber-ce-tools/bin-override/sudo" \
"$out/var/lib/apm/apm/files/amber-ce-tools/bin-override/xdg-open"
echo "installing wrappers"
mkdir -p "$out/bin" "$out/share/amber-pm/var-lib-apm"
ln -s /var/lib/apm/apm/files/bin/ace-run "$out/bin/amber-pm-debug"
ln -s /var/lib/apm/apm/files/bin/amber-ce-configure-nvidia "$out/bin/amber-pm-configure-nvidia"
for prog in "$out"/usr/bin/*; do
if [ -f "$prog" ] || [ -L "$prog" ]; then
name="$(basename "$prog")"
if [ "$name" != apm ] \
&& [ "$name" != amber-pm-debug ] \
&& [ "$name" != amber-pm-configure-nvidia ]; then
makeWrapper "$prog" "$out/bin/$name" \
--prefix PATH : "$out/bin:${runtimePath}"
fi
fi
done
cp -a "$out/var/lib/apm/apm" "$out/share/amber-pm/var-lib-apm/apm"
rm -rf "$out/var"
makeWrapper "$out/usr/libexec/apm/apm-main" "$out/bin/apm" \
--prefix PATH : "$out/bin:${runtimePath}"
cat > "$out/bin/amber-pm-ace-init" <<EOF
#!${bash}/bin/bash
set -euo pipefail
export PATH="${runtimePath}:\$PATH"
exec /var/lib/apm/apm/files/bin/ace-init "\$@"
EOF
chmod +x "$out/bin/amber-pm-ace-init"
cat > "$out/bin/amber-pm-init-state" <<'EOF'
#!@bash@/bin/bash
set -euo pipefail
if [ "''${1:-}" = "--help" ]; then
echo "Usage: amber-pm-init-state [--force]"
echo "Initializes /var/lib/apm/apm from the Nix store seed."
exit 0
fi
if [ "$(id -u)" != 0 ]; then
echo "amber-pm-init-state must be run as root because it writes /var/lib/apm" >&2
exit 1
fi
seed="@out@/share/amber-pm/var-lib-apm/apm"
target="/var/lib/apm/apm"
container_tools="$target/files/ace-env/amber-ce-tools"
mkdir -p /var/lib/apm
if [ -e "$target" ] && [ "''${1:-}" != "--force" ]; then
echo "$target already exists; leaving it untouched."
echo "Run 'amber-pm-init-state --force' to refresh APM's own files."
exit 0
fi
mkdir -p "$target"
cp -a "$seed"/. "$target"/
# ace-init copies these tools into the persistent Debian environment. Refresh
# that copy as well so it cannot retain interpreter paths from an old Nix
# generation. Keep the rest of ace-env, including installed packages, intact.
if [ -d "$target/files/ace-env" ]; then
mkdir -p "$container_tools"
cp -a "$seed/files/amber-ce-tools"/. "$container_tools"/
chmod -R u+rwX "$container_tools"
fi
echo '@version@' > "$target/.amber-pm-version"
# Do not traverse the potentially large persistent Debian environment on every
# system activation. Only make the seed-managed files writable here.
find "$target" -path "$target/files/ace-env" -prune -o -exec chmod u+rwX {} +
echo "Initialized $target"
echo "Next step: run '@out@/bin/amber-pm-ace-init' as root, or run 'apm --help' for CLI smoke testing."
EOF
substituteInPlace "$out/bin/amber-pm-init-state" \
--replace-fail '@bash@' '${bash}' \
--replace-fail '@out@' "$out" \
--replace-fail '@version@' '${version}'
chmod +x "$out/bin/amber-pm-init-state"
runHook postInstall
'';
meta = {
description = "bwrap and fuse-overlayfs based package manager for Debian-style application containers";
homepage = "https://gitee.com/amber-ce/amber-pm/";
license = lib.licenses.gpl3Only;
platforms = [
"x86_64-linux"
"aarch64-linux"
"loongarch64-linux"
];
maintainers = [ ];
};
}
+14 -4
View File
@@ -8,6 +8,10 @@ log.debug() { echo -e "[\e[32mDEBUG\e[0m]: \e[1m$*\e[0m"; }
SCRIPT_NAME=$(basename "$0")
is_nixos() {
[ -r /etc/os-release ] && . /etc/os-release && [ "${ID:-}" = "nixos" ]
}
if ! command -v dpkg > /dev/null ; then
log.error "若想使用APM软件包转换器,您需先安装dpkg"
exit 1
@@ -617,6 +621,12 @@ interactive_copy_entries() {
process_desktop_file() {
local desktop_file="$1"
local pkgname="$2"
local apm_exec_prefix="apm run $pkgname"
if is_nixos; then
apm_exec_prefix="/run/current-system/sw/bin/apm run $pkgname"
fi
# 新增:精确路径检查
local apps_path1="/usr/share/applications"
local apps_path2="/opt/apps/${ORIG_PKGNAME}/entries/applications"
@@ -632,16 +642,16 @@ process_desktop_file() {
log.info "处理桌面文件: $desktop_file"
# 检查文件是否已经处理过(避免重复添加 apm run)
if grep -q "^Exec=apm run $pkgname " "$desktop_file"; then
if grep -q "^Exec=${apm_exec_prefix} " "$desktop_file"; then
log.info "桌面文件已经处理过,跳过: $desktop_file"
return 0
fi
# 检查是否有其他包的 apm run 前缀(清理旧的)
if grep -q "^Exec=apm run [^ ]* " "$desktop_file"; then
if grep -Eq "^Exec=(/run/current-system/sw/bin/)?apm run [^ ]* " "$desktop_file"; then
log.info "发现旧的 apm run 前缀,清理后重新添加"
# 移除所有 apm run 前缀
sed -i "s|^Exec=apm run [^ ]* ||" "$desktop_file"
sed -i -E "s|^Exec=(/run/current-system/sw/bin/)?apm run [^ ]* |Exec=|" "$desktop_file"
fi
# 尝试用 busybox dos2unix(若不存在则跳过转换)
@@ -653,7 +663,7 @@ process_desktop_file() {
# 处理 Exec 行:在原有命令前追加 apm run $pkgname
if grep -q '^Exec=' "$desktop_file"; then
sed -i "s|^Exec=\(.*\)$|Exec=apm run $pkgname \1|" "$desktop_file"
sed -i "s|^Exec=\(.*\)$|Exec=${apm_exec_prefix} \1|" "$desktop_file"
fi
# 删除 TryExec 行
+11 -1
View File
@@ -1,5 +1,15 @@
#!/bin/bash
is_nixos() {
[ -r /etc/os-release ] && grep -Eq '^ID="?nixos"?$' /etc/os-release
}
if is_nixos; then
echo "检测到 NixOS,跳过向 /usr/share 和 /usr/local/share 写入桌面入口。"
echo "APM 桌面入口由 XDG_DATA_DIRS 暴露。"
exit 0
fi
# 检测是否安装了 KDE Plasma 桌面环境
# 通过检查系统中是否存在相关的 desktop 文件或关键程序
is_kde_plasma() {
@@ -128,4 +138,4 @@ if ! grep -q "Kylin" /etc/os-release; then
rmdir "$APM_SUBDIR" 2>/dev/null || true
fi
fi
fi
fi
+174 -5
View File
@@ -9,6 +9,96 @@ 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"; }
is_nixos() {
[ -f /etc/os-release ] && grep -Eq '^ID="?nixos"?$' /etc/os-release
}
configure_host_fontconfig() {
local host_fontconfig_file
is_nixos || return 0
# Respect application-specific or user-provided fontconfig overrides.
[ -z "${FONTCONFIG_FILE:-}" ] || return 0
[ -e /etc/amber-pm/fonts.conf ] || return 0
host_fontconfig_file="$(readlink -f /etc/amber-pm/fonts.conf)"
[ -n "$host_fontconfig_file" ] || return 0
# Every application runner mounts the host root at /host.
export FONTCONFIG_FILE="/host${host_fontconfig_file}"
}
append_cursor_path() {
local path="$1"
[ -n "$path" ] || return 0
case ":${APM_CURSOR_PATHS:-}:" in
*":${path}:"*) ;;
*) APM_CURSOR_PATHS="${APM_CURSOR_PATHS:+${APM_CURSOR_PATHS}:}${path}" ;;
esac
}
configure_host_cursor() {
local cursor_search_path root marker resolved theme_dir icon_root
local xsettings cursor_theme cursor_size
is_nixos || return 0
APM_CURSOR_PATHS=""
cursor_search_path="${XCURSOR_PATH:-}"
# Keep explicit paths (including paths already meaningful in the container)
# in their original order; add resolved host paths rather than replacing them.
while IFS= read -r root; do
append_cursor_path "$root"
done < <(printf '%s\n' "$cursor_search_path" | tr ':' '\n')
cursor_search_path="${cursor_search_path}:${HOME}/.icons:${HOME}/.local/share/icons"
cursor_search_path="${cursor_search_path}:${HOME}/.nix-profile/share/icons"
cursor_search_path="${cursor_search_path}:/etc/profiles/per-user/${USER}/share/icons"
cursor_search_path="${cursor_search_path}:/run/current-system/sw/share/icons"
# Resolve host-side symlinks before entering the container. A path such as
# /run/current-system/sw/share/icons is otherwise broken inside bwrap,
# because its absolute symlink targets point at the container's /nix.
while IFS= read -r root; do
[ -d "$root" ] || continue
while IFS= read -r -d '' marker; do
resolved="$(readlink -f -- "$marker")"
[ -n "$resolved" ] || continue
theme_dir="$(dirname -- "$resolved")"
icon_root="$(dirname -- "$theme_dir")"
append_cursor_path "/host${icon_root}"
done < <(
find -L "$root" -mindepth 2 -maxdepth 2 \
\( -type d -name cursors -o -type f -name index.theme \) \
-print0 2>/dev/null
)
done < <(printf '%s' "$cursor_search_path" | tr ':' '\n')
append_cursor_path "/usr/local/share/icons"
append_cursor_path "/usr/share/icons"
append_cursor_path "/usr/share/cursors"
export XCURSOR_PATH="$APM_CURSOR_PATHS"
# XSettings is shared by X11/XWayland sessions and is independent of the
# desktop environment. Explicit environment overrides retain precedence.
xsettings="$(dump_xsettings 2>/dev/null || true)"
if [ -z "${XCURSOR_THEME:-}" ]; then
cursor_theme="$(
printf '%s\n' "$xsettings" \
| awk '$1 == "Gtk/CursorThemeName" { sub(/^[^ ]+[[:space:]]+"/, ""); sub(/"$/, ""); print; exit }'
)"
[ -n "$cursor_theme" ] && export XCURSOR_THEME="$cursor_theme"
fi
if [ -z "${XCURSOR_SIZE:-}" ]; then
cursor_size="$(
printf '%s\n' "$xsettings" \
| awk '$1 == "Gtk/CursorThemeSize" && $2 ~ /^[0-9]+$/ { print $2; exit }'
)"
[ -n "$cursor_size" ] && export XCURSOR_SIZE="$cursor_size"
fi
}
# 帮助信息函数
show_help() {
cat <<EOF
@@ -97,6 +187,65 @@ apm_exec(){
local current_dir="${PATH_PREFIX}/var/lib/apm/${coredir}"
local next_info_file=""
local APM_RUN_EXEC=/var/lib/apm/apm/files/ace-run
local mount_dir="/tmp/apm/${coredir}"
local overlay_mounted=0
local cleanup_done=0
_unmount_mountpoint() {
local path="$1"
local attempt
for attempt in 1 2 3 4 5 6 7 8; do
mountpoint -q "$path" || return 0
if command -v fusermount3 >/dev/null 2>&1; then
fusermount3 -u "$path" 2>/dev/null || true
fi
if mountpoint -q "$path"; then
umount "$path" 2>/dev/null || true
fi
if mountpoint -q "$path"; then
if command -v fusermount3 >/dev/null 2>&1; then
fusermount3 -uz "$path" 2>/dev/null || true
else
umount -l "$path" 2>/dev/null || true
fi
fi
done
! mountpoint -q "$path"
}
_cleanup_mount() {
local status="${1:-$?}"
if [ "$cleanup_done" = 1 ]; then
return "$status"
fi
cleanup_done=1
trap - EXIT HUP INT TERM
if [ "$overlay_mounted" = 1 ] && mountpoint -q "$mount_dir"; then
if ! _unmount_mountpoint "$mount_dir"; then
log.warn "Unable to unmount APM overlay: $mount_dir"
fi
fi
return "$status"
}
_handle_mount_signal() {
local signal="$1"
local status
case "$signal" in
HUP) status=129 ;;
INT) status=130 ;;
TERM) status=143 ;;
esac
_cleanup_mount "$status"
exit "$status"
}
# ===============================
# 辅助函数:解析并添加某个包的 addons
@@ -262,7 +411,14 @@ apm_exec(){
local lowerdir
lowerdir=$(IFS=:; echo "${lowerdirs[*]}")
mkdir -p "/tmp/apm/${coredir}"
if mountpoint -q "$mount_dir"; then
log.warn "Found an existing APM overlay, trying to unmount it: $mount_dir"
if ! _unmount_mountpoint "$mount_dir"; then
log.error "Unable to clear existing APM overlay: $mount_dir"
return 1
fi
fi
mkdir -p "$mount_dir"
# ===============================
# 应用 info_env(从下到上)
@@ -299,19 +455,32 @@ apm_exec(){
log.debug "Mounting overlayfs"
log.debug "lowerdir=$lowerdir"
fuse-overlayfs \
trap '_cleanup_mount "$?"' EXIT
trap '_handle_mount_signal HUP' HUP
trap '_handle_mount_signal INT' INT
trap '_handle_mount_signal TERM' TERM
overlay_mounted=1
if ! 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}"
"$mount_dir"; then
_cleanup_mount 1
log.error "Unable to mount APM overlay: $mount_dir"
return 1
fi
# ===============================
# 执行
# ===============================
chrootEnvPath="/tmp/apm/${coredir}" "${APM_RUN_EXEC}" "$@"
configure_host_fontconfig
configure_host_cursor
local run_status=0
chrootEnvPath="$mount_dir" "${APM_RUN_EXEC}" "$@" || run_status=$?
# ===============================
# 卸载
# ===============================
umount "/tmp/apm/${coredir}"
_cleanup_mount "$run_status"
return "$run_status"
}
# 启动应用:通过 amber-pm-app-launcher 运行
+17 -3
View File
@@ -27,8 +27,22 @@ function ensure_dir() {
return 0
fi
}
chrootEnvPath="${chrootEnvPath:-$(dirname $0)/ace-env}"
is_nixos() {
[ -f /etc/os-release ] && grep -Eq '^ID="?nixos"?$' /etc/os-release
}
APM_CONTAINER_PATH="/amber-ce-tools/bin-override:$PATH"
APM_CONTAINER_XDG_DATA_DIRS="/amber-ce-tools/additional-data-dir-in-container:\$XDG_DATA_DIRS"
if is_nixos; then
APM_CONTAINER_PATH="/amber-ce-tools/bin-override:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Nix host data paths may be unavailable in the Debian container. Include
# its own MIME database and GSettings schemas before inherited host paths.
APM_CONTAINER_XDG_DATA_DIRS="/amber-ce-tools/additional-data-dir-in-container:/usr/local/share:/usr/share:\$XDG_DATA_DIRS"
fi
APM_PKG_NAME="${APM_PKG_NAME:-apm-general}"
non_root_user=$(who | awk '{print $1}' | head -n 1)
@@ -106,10 +120,10 @@ done
ENV_VARS=(
"FAKEROOTDONTTRYCHOWN 1"
"PULSE_SERVER /run/user/\$uid/pulse/native"
"PATH /amber-ce-tools/bin-override:\$PATH"
"PATH $APM_CONTAINER_PATH"
"IS_ACE_ENV 1"
"GTK_USE_PORTAL 1"
"XDG_DATA_DIRS /amber-ce-tools/additional-data-dir-in-container:\$XDG_DATA_DIRS"
"XDG_DATA_DIRS $APM_CONTAINER_XDG_DATA_DIRS"
"XCURSOR_PATH /host/usr/share/icons:/host/usr/share/cursors:/usr/share/icons:/usr/share/cursors:\$XCURSOR_PATH"
)
@@ -201,4 +215,4 @@ add_command "bash -c \"${container_command}\""
# echo "${EXEC_COMMAND}"
# 注意: 实际执行时,请确保所有变量(如 $uid, $chrootEnvPath 等)都已正确定义
eval "${EXEC_COMMAND}"
eval "${EXEC_COMMAND}"
+14 -3
View File
@@ -7,6 +7,18 @@ export -f bash
chrootEnvPath="${chrootEnvPath:-$(pwd)/ace-env}"
is_nixos() {
[ -f /etc/os-release ] && grep -Eq '^ID="?nixos"?$' /etc/os-release
}
APM_CONTAINER_PATH="/amber-ce-tools/bin-override:$PATH"
APM_CONTAINER_XDG_DATA_DIRS="/amber-ce-tools/additional-data-dir-in-container:\$XDG_DATA_DIRS"
if is_nixos; then
APM_CONTAINER_PATH="/amber-ce-tools/bin-override:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Nix host data paths may be unavailable in the Debian container. Include
# its own MIME database and GSettings schemas before inherited host paths.
APM_CONTAINER_XDG_DATA_DIRS="/amber-ce-tools/additional-data-dir-in-container:/usr/local/share:/usr/share:\$XDG_DATA_DIRS"
fi
non_root_user=$(who | awk '{print $1}' | head -n 1)
@@ -80,10 +92,10 @@ done
ENV_VARS=(
"FAKEROOTDONTTRYCHOWN 1"
"PULSE_SERVER /run/user/\$uid/pulse/native"
"PATH /amber-ce-tools/bin-override:\$PATH"
"PATH $APM_CONTAINER_PATH"
"IS_ACE_ENV 1"
"GTK_USE_PORTAL 1"
"XDG_DATA_DIRS /amber-ce-tools/additional-data-dir-in-container:\$XDG_DATA_DIRS"
"XDG_DATA_DIRS $APM_CONTAINER_XDG_DATA_DIRS"
)
BIND_DIRS=(
@@ -139,4 +151,3 @@ add_command "bash -c \"${container_command}\""
# 注意: 实际执行时,请确保所有变量(如 $uid, $chrootEnvPath 等)都已正确定义
eval ${EXEC_COMMAND}
@@ -1,4 +1,9 @@
#!/bin/bash
# Set by the host initializer, not the Debian container's /etc/os-release.
if [ "${APM_HOST_NIXOS:-0}" = 1 ]; then
set -e
fi
if [ "$IS_ACE_ENV" != "1" ];then
echo "ONLY RUN ME IN ACE"
exit
@@ -8,6 +13,7 @@ fi
printf "ACE: Setting up sudo...\n"
mkdir -p /etc/sudoers.d
touch /etc/sudoers.d/sudoers
# Do not check fqdn when doing sudo, it will not work anyways
if ! grep -q 'Defaults !fqdn' /etc/sudoers.d/sudoers; then
printf "Defaults !fqdn\n" >> /etc/sudoers.d/sudoers
@@ -26,7 +32,7 @@ if ! grep -q "^${container_user_name}:" /etc/group; then
if ! groupadd --force --gid "${container_user_gid}" "${container_user_name}"; then
# It may occur that we have users with unsupported user name (eg. on LDAP or AD)
# So let's try and force the group creation this way.
printf "%s:x:%s:" "${container_user_name}" "${container_user_gid}" >> /etc/group
printf "%s:x:%s:\n" "${container_user_name}" "${container_user_gid}" >> /etc/group
fi
fi
@@ -46,6 +52,7 @@ fi
# If we have sudo/wheel groups, let's add the user to them.
additional_groups=""
container_shell="${SHELL:-/bin/bash}"
if grep -q "^sudo" /etc/group; then
additional_groups="sudo"
elif grep -q "^wheel" /etc/group; then
@@ -63,18 +70,18 @@ if ! grep -q "^$(printf '%s' "${container_user_name}" | tr '\\' '.'):" /etc/pass
--home-dir "${container_user_home}" \
--no-create-home \
--groups "${additional_groups}" \
--shell "${SHELL:-"/bin/bash"}" \
--shell "${container_shell}" \
--uid "${container_user_uid}" \
--gid "${container_user_gid}" \
"${container_user_name}"; then
printf "Warning: there was a problem setting up the user\n"
printf "Warning: trying manual addition\n"
printf "%s:x:%s:%s:%s:%s:%s" \
printf "%s:x:%s:%s:%s:%s:%s\n" \
"${container_user_name}" "${container_user_uid}" \
"${container_user_gid}" "${container_user_name}" \
"${container_user_home}" "${SHELL:-"/bin/bash"}" >> /etc/passwd
printf "%s::1::::::" "${container_user_name}" >> /etc/shadow
"${container_user_home}" "${container_shell}" >> /etc/passwd
printf "%s::1::::::\n" "${container_user_name}" >> /etc/shadow
fi
# Ensure we're not using the specified SHELL. Run it only once, so that future
# user's preferences are not overwritten at each start.
@@ -91,7 +98,7 @@ elif [ ! -e /etc/passwd.done ]; then
if ! usermod \
--home "${container_user_home}" \
--shell "${SHELL:-"/bin/bash"}" \
--shell "${container_shell}" \
--groups "${additional_groups}" \
--uid "${container_user_uid}" \
--gid "${container_user_gid}" \
@@ -102,6 +109,9 @@ elif [ ! -e /etc/passwd.done ]; then
fi
touch /etc/passwd.done
fi
if [ "${APM_HOST_NIXOS:-0}" = 1 ] && [ ! -e /etc/passwd.done ]; then
touch /etc/passwd.done
fi
# We generate a random password to initialize the entry for the user and root.
temporary_password="$(cat /proc/sys/kernel/random/uuid)"
@@ -116,7 +126,7 @@ mkdir -p /usr/share/icons
mkdir -p /usr/share/themes
## init host-spawn
unlink /amber-ce-tools/bin-override/host-spawn
rm -f /amber-ce-tools/bin-override/host-spawn
ln -sfv /amber-ce-tools/bin-override/host-spawn-$(uname -m) /amber-ce-tools/bin-override/host-spawn
@@ -124,6 +134,3 @@ ln -sfv /amber-ce-tools/bin-override/host-spawn-$(uname -m) /amber-ce-tools/bin-
exit 0
+47 -11
View File
@@ -15,9 +15,30 @@ else
PKGNAME=$PACKAGE_NAME
fi
chrootEnvPath=/var/lib/apm/$PKGNAME/files/ace-env
is_nixos() {
[ -f /etc/os-release ] && grep -Eq '^ID="?nixos"?$' /etc/os-release
}
APM_CONTAINER_PATH="/amber-ce-tools/bin-override:$PATH"
APM_HOST_NIXOS=0
APM_CONTAINER_INIT_ENV=()
APM_LOCALE_GEN=(locale-gen)
if is_nixos; then
# The Debian container cannot use a Nix host's SHELL or locale tools.
# Keep upstream initialization semantics on other hosts.
APM_HOST_NIXOS=1
set -eo pipefail
APM_CONTAINER_PATH="/amber-ce-tools/bin-override:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
APM_CONTAINER_INIT_ENV=(--setenv SHELL /bin/bash --setenv APM_HOST_NIXOS 1)
APM_LOCALE_GEN=(bash -c 'if command -v locale-gen >/dev/null 2>&1; then locale-gen; fi')
fi
#if [ ! -e $chrootEnvPath ];then
echo "Uncompress the env...."
tar -xvf $chrootEnvPath.tar.xz -C /var/lib/apm/$PKGNAME/files/
if [ "$APM_HOST_NIXOS" = 1 ]; then
rm -f "$chrootEnvPath/finish.flag"
fi
#fi
HERE="$(dirname $(realpath $0))"
@@ -41,7 +62,8 @@ uid=$(id -u $non_root_user)
function bookworm-run(){
bwrap --dev-bind $chrootEnvPath/ / \
--setenv PULSE_SERVER /run/user/$uid/pulse/native \
--setenv PATH /amber-ce-tools/bin-override:$PATH \
--setenv PATH "$APM_CONTAINER_PATH" \
"${APM_CONTAINER_INIT_ENV[@]}" \
--setenv IS_ACE_ENV "1" \
--dev-bind-try /media /media \
--dev-bind-try /tmp /tmp \
@@ -59,7 +81,7 @@ bwrap --dev-bind $chrootEnvPath/ / \
--unshare-uts \
--dev-bind-try /etc/resolv.conf /etc/resolv.conf \
--dev-bind-try /home /home \
$@
"$@"
}
@@ -80,16 +102,24 @@ export container_user_uid="$(sudo -u $non_root_user id -ru)"
bookworm-run bash /amber-ce-tools/container-init/init.sh
rm $chrootEnvPath/etc/localtime
rm -f $chrootEnvPath/etc/localtime
cp $(realpath /etc/localtime) $chrootEnvPath/etc/localtime
chmod 777 $chrootEnvPath/etc/localtime
bookworm-run cp /host/etc/locale.gen /etc/locale.gen && locale-gen
bookworm-run touch /finish.flag
if [ "$APM_HOST_NIXOS" = 1 ]; then
if [ -f /etc/locale.gen ]; then
bookworm-run cp /host/etc/locale.gen /etc/locale.gen
fi
bookworm-run "${APM_LOCALE_GEN[@]}"
else
bookworm-run cp /host/etc/locale.gen /etc/locale.gen && locale-gen
bookworm-run touch /finish.flag
fi
bookworm-run apt clean
bookworm-run chown -R $(get_current_user) /usr/lib/locale/
sudo -u $(get_current_user) bwrap --dev-bind $chrootEnvPath/ / \
--setenv PULSE_SERVER /run/user/$uid/pulse/native \
--setenv PATH /amber-ce-tools/bin-override:$PATH \
--setenv PATH "$APM_CONTAINER_PATH" \
"${APM_CONTAINER_INIT_ENV[@]}" \
--setenv IS_ACE_ENV "1" \
--dev-bind $chrootEnvPath/ / \
--dev-bind-try /media /media \
@@ -106,12 +136,16 @@ sudo -u $(get_current_user) bwrap --dev-bind $chrootEnvPath/ / \
--bind-try /usr/share/fonts /usr/local/share/fonts \
--dev-bind-try /etc/resolv.conf /etc/resolv.conf \
--dev-bind-try /home /home \
locale-gen
bookworm-run update-locale LANG=$LANG
"${APM_LOCALE_GEN[@]}"
if [ "$APM_HOST_NIXOS" = 1 ]; then
bookworm-run bash -c 'if command -v update-locale >/dev/null 2>&1; then update-locale LANG="${LANG:-C.UTF-8}"; else printf "LANG=%s\n" "${LANG:-C.UTF-8}" > /etc/default/locale; fi'
else
bookworm-run update-locale LANG=$LANG
fi
chown -R root $chrootEnvPath
mkdir -p $chrootEnvPath/amber-ce-tools/data-dir
ln -sv ../../usr/share/applications $chrootEnvPath/amber-ce-tools/data-dir/
ln -sv ../../usr/share/icons $chrootEnvPath/amber-ce-tools/data-dir/
ln -sfnv ../../usr/share/applications $chrootEnvPath/amber-ce-tools/data-dir/applications
ln -sfnv ../../usr/share/icons $chrootEnvPath/amber-ce-tools/data-dir/icons
mkdir -p $chrootEnvPath/usr/share/templates
ln -sfv ../../usr/share/templates/ $chrootEnvPath/amber-ce-tools/data-dir/
mkdir -p $chrootEnvPath/usr/share/mime
@@ -121,4 +155,6 @@ ln -sfv ../../usr/share/pixmaps/ $chrootEnvPath/amber-ce-tools/data-dir/
chmod 777 -R $chrootEnvPath/usr/share/icons
rm -vfr $chrootEnvPath/dev/*
true
if [ "$APM_HOST_NIXOS" = 1 ]; then
touch "$chrootEnvPath/finish.flag"
fi
+15 -4
View File
@@ -14,6 +14,19 @@ export ACE_PACKAGE_NAME=$PKGNAME
chrootEnvPath=/var/lib/apm/$PKGNAME/files/ace-env
is_nixos() {
[ -f /etc/os-release ] && grep -Eq '^ID="?nixos"?$' /etc/os-release
}
APM_CONTAINER_PATH="/amber-ce-tools/bin-override:$PATH"
APM_CONTAINER_XDG_DATA_DIRS="/amber-ce-tools/additional-data-dir-in-container:\$XDG_DATA_DIRS"
if is_nixos; then
APM_CONTAINER_PATH="/amber-ce-tools/bin-override:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Nix host data paths may be unavailable in the Debian container. Include
# its own MIME database and GSettings schemas before inherited host paths.
APM_CONTAINER_XDG_DATA_DIRS="/amber-ce-tools/additional-data-dir-in-container:/usr/local/share:/usr/share:\$XDG_DATA_DIRS"
fi
# if [ ! -e $chrootEnvPath/finish.flag ];then
# if [ "$(id -u)" = "0" ]; then
@@ -94,10 +107,10 @@ done
ENV_VARS=(
"FAKEROOTDONTTRYCHOWN 1"
"PULSE_SERVER /run/user/\$uid/pulse/native"
"PATH /amber-ce-tools/bin-override:\$PATH"
"PATH $APM_CONTAINER_PATH"
"IS_ACE_ENV 1"
"IS_APM_ENV 1"
"XDG_DATA_DIRS /amber-ce-tools/additional-data-dir-in-container:\$XDG_DATA_DIRS"
"XDG_DATA_DIRS $APM_CONTAINER_XDG_DATA_DIRS"
)
BIND_DIRS=(
@@ -149,5 +162,3 @@ add_command "bash -c \"${container_command}\""
# 注意: 实际执行时,请确保所有变量(如 $uid, $chrootEnvPath 等)都已正确定义
eval ${EXEC_COMMAND}