mirror of
https://gitee.com/amber-ce/amber-pm
synced 2026-06-22 06:03:55 +08:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ccfbdf0bbd | |||
| 6ee9f7ecdb | |||
| 293ce7006c | |||
| 8fce0cad4a | |||
| 9fe7714b7b | |||
| a66944cfba | |||
| ea1700bb4f | |||
| de59de465b | |||
| fb05f759a1 | |||
| f37b118c67 | |||
| d05df2ea9a | |||
| 56e9d5bbb0 | |||
| e8a95ab13a | |||
| ec93f280f9 | |||
| 68d5e85d0d | |||
| b9bd4552e5 | |||
| 2e524df411 | |||
| 736e11255e | |||
| eba44e8489 | |||
| 682e987816 | |||
| 0a94f1a854 | |||
| fde7fd6051 |
@@ -0,0 +1,3 @@
|
||||
result
|
||||
result-*
|
||||
spark-store/
|
||||
@@ -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,5 +1,5 @@
|
||||
Package: apm
|
||||
Version: 1.1.5
|
||||
Version: 1.1.6-1
|
||||
Maintainer: shenmo <jifengshenmo@outlook.com>
|
||||
Priority: optional
|
||||
Section: utils
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[Desktop Entry]
|
||||
Exec=xdg-open %U
|
||||
MimeType=x-scheme-handler/spk;inode/directory;application/x-mimearchive;x-scheme-handler/http;x-scheme-handler/https;application/msword;application/vnd.openxmlformats-officedocument.wordprocessingml.document;application/vnd.ms-excel;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;application/vnd.ms-powerpoint;application/vnd.openxmlformats-officedocument.presentationml.presentation;application/x-gzip;application/zip;application/rar;application/x-tar;application/pdf;application/rtf;image/gif;image/jpeg;image/jp2;image/png;image/tiff;image/bmp;image/svg+xml;image/webp;image/x-icon;application/kswps;application/kset;application/ksdps;application/x-photoshop;application/x-coreldraw;application/x-shockwave-flash;text/plain;application/x-javascript;text/javascript;text/css;text/html;application/xhtml+xml;text/xml;text/x-vcard;application/x-httpd-php;application/java-archive;application/vnd.android.package-archive;application/octet-stream;application/x-x509-user-cert;audio/mpeg;audio/midi;audio/x-wav;audio/x-mpegurl;audio/x-m4a;audio/ogg;audio/x-realaudio;video/mp4;video/mpeg;video/quicktime;video/x-m4v;video/x-ms-wmv;video/x-msvideo;video/webm;video/x-flv;application/xhtml_xml;
|
||||
MimeType=x-scheme-handler/spk;x-scheme-handler/wemeet;inode/directory;application/x-mimearchive;x-scheme-handler/http;x-scheme-handler/https;application/msword;application/vnd.openxmlformats-officedocument.wordprocessingml.document;application/vnd.ms-excel;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;application/vnd.ms-powerpoint;application/vnd.openxmlformats-officedocument.presentationml.presentation;application/x-gzip;application/zip;application/rar;application/x-tar;application/pdf;application/rtf;image/gif;image/jpeg;image/jp2;image/png;image/tiff;image/bmp;image/svg+xml;image/webp;image/x-icon;application/kswps;application/kset;application/ksdps;application/x-photoshop;application/x-coreldraw;application/x-shockwave-flash;text/plain;application/x-javascript;text/javascript;text/css;text/html;application/xhtml+xml;text/xml;text/x-vcard;application/x-httpd-php;application/java-archive;application/vnd.android.package-archive;application/octet-stream;application/x-x509-user-cert;audio/mpeg;audio/midi;audio/x-wav;audio/x-mpegurl;audio/x-m4a;audio/ogg;audio/x-realaudio;video/mp4;video/mpeg;video/quicktime;video/x-m4v;video/x-ms-wmv;video/x-msvideo;video/webm;video/x-flv;application/xhtml_xml;
|
||||
Name=ace-run-in-host-os
|
||||
NoDisplay=true
|
||||
Terminal=false
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# amber-pm-base-overrider
|
||||
# 功能:检查 /opt/apm-dummy/files-to-override 下的文件,并覆盖到所有包含
|
||||
# /var/lib/apm/文件夹/files 的 /var/lib/apm/文件夹/files/ace-env 下
|
||||
# 同时删除每个 ace-env 目录下的 amber-ce-tools/bin-override/bwrap
|
||||
|
||||
# 日志函数
|
||||
log_warn() { echo -e "[\e[33mWARN\e[0m]: \e[1m$*\e[0m"; }
|
||||
@@ -13,6 +14,7 @@ log_debug() { echo -e "[\e[32mDEBUG\e[0m]: \e[1m$*\e[0m"; }
|
||||
# 配置
|
||||
OVERRIDE_SOURCE="/opt/apm-dummy/files-to-override"
|
||||
APM_BASE_DIR="/var/lib/apm"
|
||||
BWRAP_PATH="amber-ce-tools/bin-override/bwrap"
|
||||
|
||||
# 显示帮助信息
|
||||
show_help() {
|
||||
@@ -30,6 +32,7 @@ amber-pm-base-overrider - APM 基础环境覆盖工具
|
||||
功能:
|
||||
检查 /opt/apm-dummy/files-to-override 下的文件,
|
||||
并覆盖到所有 /var/lib/apm/<包名>/files/ace-env 目录下。
|
||||
同时删除每个 ace-env 目录下的 amber-ce-tools/bin-override/bwrap。
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -67,7 +70,7 @@ fi
|
||||
|
||||
# 检查源目录是否为空
|
||||
if [ -z "$(ls -A "$OVERRIDE_SOURCE" 2>/dev/null)" ]; then
|
||||
exit 0
|
||||
$VERBOSE && log_info "源目录为空,仅执行清理操作"
|
||||
fi
|
||||
|
||||
$VERBOSE && log_info "源目录: $OVERRIDE_SOURCE"
|
||||
@@ -79,8 +82,8 @@ fi
|
||||
|
||||
# 计数器
|
||||
OVERRIDE_COUNT=0
|
||||
DELETE_COUNT=0
|
||||
ERROR_COUNT=0
|
||||
HAS_CHANGES=false
|
||||
|
||||
# 遍历 /var/lib/apm/ 下的所有子目录
|
||||
for pkg_dir in "$APM_BASE_DIR"/*/; do
|
||||
@@ -108,6 +111,35 @@ for pkg_dir in "$APM_BASE_DIR"/*/; do
|
||||
continue
|
||||
fi
|
||||
|
||||
# ---- 删除 amber-ce-tools/bin-override/bwrap ----
|
||||
bwrap_file="$target_dir/$BWRAP_PATH"
|
||||
if [ -e "$bwrap_file" ] || [ -L "$bwrap_file" ]; then
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
if [ -d "$bwrap_file" ]; then
|
||||
echo " [试运行] 将删除目录: $bwrap_file"
|
||||
else
|
||||
echo " [试运行] 将删除文件: $bwrap_file"
|
||||
fi
|
||||
((DELETE_COUNT++))
|
||||
else
|
||||
if rm -rf "$bwrap_file" 2>/dev/null; then
|
||||
$VERBOSE && log_info "已删除: $bwrap_file"
|
||||
((DELETE_COUNT++))
|
||||
else
|
||||
log_error "删除失败: $bwrap_file"
|
||||
((ERROR_COUNT++))
|
||||
fi
|
||||
fi
|
||||
else
|
||||
$VERBOSE && log_debug "$pkg_name: bwrap 文件不存在,无需删除"
|
||||
fi
|
||||
|
||||
# ---- 覆盖文件 ----
|
||||
# 检查源目录是否为空
|
||||
if [ -z "$(ls -A "$OVERRIDE_SOURCE" 2>/dev/null)" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# 检查是否有文件需要更新(比较源文件和目标文件)
|
||||
NEED_UPDATE=false
|
||||
while IFS= read -r -d '' file; do
|
||||
@@ -126,7 +158,6 @@ for pkg_dir in "$APM_BASE_DIR"/*/; do
|
||||
continue
|
||||
fi
|
||||
|
||||
HAS_CHANGES=true
|
||||
$VERBOSE && log_info "处理包: $pkg_name"
|
||||
|
||||
# 使用 rsync 或 cp 进行覆盖
|
||||
@@ -150,17 +181,16 @@ for pkg_dir in "$APM_BASE_DIR"/*/; do
|
||||
fi
|
||||
done
|
||||
|
||||
# 只有在有改动或 verbose 模式时才输出统计信息
|
||||
if [ "$HAS_CHANGES" = true ] || [ "$VERBOSE" = true ]; then
|
||||
$VERBOSE && log_info "===================================="
|
||||
$VERBOSE && log_info "覆盖操作完成"
|
||||
log_info "成功处理: $OVERRIDE_COUNT 个包"
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
log_info "[试运行模式] 未实际执行覆盖"
|
||||
fi
|
||||
if [ $ERROR_COUNT -gt 0 ]; then
|
||||
log_error "失败: $ERROR_COUNT 个包"
|
||||
fi
|
||||
# 输出统计信息
|
||||
$VERBOSE && log_info "===================================="
|
||||
$VERBOSE && log_info "操作完成"
|
||||
log_info "成功覆盖: $OVERRIDE_COUNT 个包"
|
||||
log_info "成功删除 bwrap: $DELETE_COUNT 个包"
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
log_info "[试运行模式] 未实际执行操作"
|
||||
fi
|
||||
if [ $ERROR_COUNT -gt 0 ]; then
|
||||
log_error "失败: $ERROR_COUNT 个操作"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
exit 0
|
||||
+1
-1
@@ -1 +1 @@
|
||||
@VERSION@=1.3.0
|
||||
@VERSION@=1.3.4.0
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{ pkgs ? import <nixpkgs> { } }:
|
||||
|
||||
pkgs.callPackage ./nix/package.nix { }
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
# 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 /var/lib/apm/apm/files/bin/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` 以提高兼容性。
|
||||
|
||||
## NUR/nixpkgs 打包复用
|
||||
|
||||
`nix/package.nix` 支持外部传入 `version` 和 `src`,因此 NUR 或 nixpkgs 中可以复用同一个表达式,不必依赖本地源码路径。
|
||||
|
||||
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。
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
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;
|
||||
in
|
||||
{
|
||||
cli-smoke = 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
|
||||
touch "$out"
|
||||
'';
|
||||
}
|
||||
);
|
||||
|
||||
nixosModules.default = import ./nix/module.nix;
|
||||
|
||||
overlays.default = final: prev: {
|
||||
amber-pm = final.callPackage ./nix/package.nix { };
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.programs.amber-pm;
|
||||
apmXdgDataDir = "/var/lib/apm/apm/files/ace-env/amber-ce-tools/data-dir";
|
||||
|
||||
aceRuntimePath = lib.makeBinPath (with pkgs; [
|
||||
bash
|
||||
bubblewrap
|
||||
coreutils
|
||||
gawk
|
||||
gnugrep
|
||||
gnused
|
||||
gnutar
|
||||
sudo
|
||||
]);
|
||||
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 during system activation when it does not already exist.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
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 ''
|
||||
export PATH="${aceRuntimePath}:$PATH"
|
||||
target="/var/lib/apm/apm"
|
||||
version_file="$target/.amber-pm-version"
|
||||
current_version="${cfg.package.version}"
|
||||
|
||||
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..."
|
||||
/var/lib/apm/apm/files/bin/ace-init
|
||||
elif [ -f "$version_file" ]; then
|
||||
stored_version="$(cat "$version_file")"
|
||||
if [ "$stored_version" != "$current_version" ]; then
|
||||
echo "APM version changed ($stored_version -> $current_version), re-initializing..."
|
||||
${cfg.package}/bin/amber-pm-init-state --force
|
||||
echo "Running ace-init..."
|
||||
/var/lib/apm/apm/files/bin/ace-init
|
||||
else
|
||||
echo "APM version unchanged ($current_version), skipping ace-init."
|
||||
fi
|
||||
else
|
||||
echo "No version file found, refreshing state and running ace-init..."
|
||||
${cfg.package}/bin/amber-pm-init-state --force
|
||||
/var/lib/apm/apm/files/bin/ace-init
|
||||
fi
|
||||
'';
|
||||
};
|
||||
}
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
{
|
||||
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,
|
||||
xz,
|
||||
zenity,
|
||||
version ? "1.3.4.0",
|
||||
sourceRoot ? ../.,
|
||||
src ? lib.cleanSourceWith {
|
||||
src = sourceRoot;
|
||||
filter =
|
||||
path: type:
|
||||
let
|
||||
base = baseNameOf path;
|
||||
in
|
||||
! lib.elem base [
|
||||
".git"
|
||||
"result"
|
||||
];
|
||||
},
|
||||
}:
|
||||
|
||||
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
|
||||
xz
|
||||
zenity
|
||||
];
|
||||
in
|
||||
stdenvNoCC.mkDerivation {
|
||||
pname = "amber-pm";
|
||||
inherit version;
|
||||
|
||||
inherit src;
|
||||
|
||||
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-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"
|
||||
|
||||
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"/
|
||||
echo '@version@' > "$target/.amber-pm-version"
|
||||
chmod -R u+rwX "$target"
|
||||
echo "Initialized $target"
|
||||
echo "Next step: run '/var/lib/apm/apm/files/bin/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 = [ ];
|
||||
};
|
||||
}
|
||||
@@ -9,10 +9,13 @@ systemctl daemon-reload
|
||||
systemctl enable apm-daily-update
|
||||
systemctl start apm-daily-update
|
||||
systemctl restart apparmor.service || true
|
||||
mkdir -p /etc/apparmor.d/disable/
|
||||
ln -sv /etc/apparmor.d/bwrap-userns-restrict /etc/apparmor.d/disable/
|
||||
|
||||
if [ -f /usr/lib/sysctl.d/apm.conf ];then
|
||||
sysctl -p /usr/lib/sysctl.d/apm.conf
|
||||
fi
|
||||
systemctl reload apparmor
|
||||
# Send statistics data
|
||||
/var/lib/apm/apm/files/feedback.sh &
|
||||
ln -sv / /host
|
||||
|
||||
@@ -264,14 +264,15 @@ if [ -n "$DEB_PATH" ]; then
|
||||
exit 1
|
||||
fi
|
||||
log.info "DEB 包安装完成(ssaudit)"
|
||||
|
||||
# 清理 apt 缓存
|
||||
sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg aptss clean || true
|
||||
sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg rm -vfr /var/lib/apt/lists || true
|
||||
sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg rm -vfr /var/lib/aptss/lists || true
|
||||
sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg rm -vfr /var/cache/apt/archives/* || true
|
||||
fi
|
||||
|
||||
# 清理 apt 缓存和包列表(无论是否有 DEB 文件或是否 manual 模式)
|
||||
log.info "清理 apt 缓存..."
|
||||
sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg aptss clean || true
|
||||
sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg rm -vfr /var/lib/apt/lists || true
|
||||
sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg rm -vfr /var/lib/aptss/lists || true
|
||||
sudo -E chrootEnvPath="$chrootEnvPath" /var/lib/apm/apm/files/ace-run-pkg rm -vfr /var/cache/apt/archives/* || true
|
||||
|
||||
# 5. 清理 .dpkg-new 文件
|
||||
log.info "搜索并清理 .dpkg-new 文件..."
|
||||
find "$CRAFT_DIR/core" -name "*.dpkg-new" 2>/dev/null | while read -r file; do
|
||||
@@ -293,8 +294,19 @@ if [ -z "$PKGNAME" ]; then
|
||||
if [ "$MANUAL_MODE" = true ]; then
|
||||
read -r -p "请输入要创建的 addons 包名 (建议格式: ${BASE_NAME}-<描述>-addons): " PKGNAME
|
||||
else
|
||||
log.warn "未指定包名,使用默认格式: ${BASE_NAME}-addons"
|
||||
PKGNAME="${BASE_NAME}-addons"
|
||||
if [ -n "$DEB_PATH" ]; then
|
||||
DEB_PKG_NAME=$(dpkg-deb -f "$DEB_PATH" Package 2>/dev/null || echo "")
|
||||
if [ -n "$DEB_PKG_NAME" ]; then
|
||||
log.info "未指定包名,使用 Deb 包名生成默认格式: ${BASE_NAME}-${DEB_PKG_NAME}-addons"
|
||||
PKGNAME="${BASE_NAME}-${DEB_PKG_NAME}-addons"
|
||||
else
|
||||
log.warn "无法读取 Deb 包名,使用默认格式: ${BASE_NAME}-addons"
|
||||
PKGNAME="${BASE_NAME}-addons"
|
||||
fi
|
||||
else
|
||||
log.warn "未指定包名,使用默认格式: ${BASE_NAME}-addons"
|
||||
PKGNAME="${BASE_NAME}-addons"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -302,8 +314,22 @@ fi
|
||||
if [ -z "$VERSION" ]; then
|
||||
if [ "$MANUAL_MODE" = true ]; then
|
||||
read -r -p "请输入要创建的版本 (Version) [默认 1.0.0-apm]: " VERSION
|
||||
VERSION="${VERSION:-1.0.0-apm}"
|
||||
else
|
||||
if [ -n "$DEB_PATH" ]; then
|
||||
DEB_PKG_VERSION=$(dpkg-deb -f "$DEB_PATH" Version 2>/dev/null || echo "")
|
||||
if [ -n "$DEB_PKG_VERSION" ]; then
|
||||
log.info "未指定版本,使用 Deb 版本号: ${DEB_PKG_VERSION}"
|
||||
VERSION="$DEB_PKG_VERSION"
|
||||
else
|
||||
log.warn "无法读取 Deb 版本号,使用默认版本: 1.0.0-apm"
|
||||
VERSION="1.0.0-apm"
|
||||
fi
|
||||
else
|
||||
log.warn "未指定版本,使用默认版本: 1.0.0-apm"
|
||||
VERSION="1.0.0-apm"
|
||||
fi
|
||||
fi
|
||||
VERSION="${VERSION:-1.0.0-apm}"
|
||||
fi
|
||||
|
||||
NEW_PKGNAME="$PKGNAME"
|
||||
@@ -319,6 +345,10 @@ PKG_BUILD_DIR="$CRAFT_DIR/new-pkg"
|
||||
mkdir -p "$PKG_BUILD_DIR/DEBIAN"
|
||||
mkdir -p "$PKG_BUILD_DIR/var/lib/apm/$NEW_PKGNAME/files" 2>/dev/null || true
|
||||
|
||||
# 写入 addons 自身的基础依赖信息,供 amber-pm-convert 识别并自动补依赖。
|
||||
echo "$BASE_NAME" > "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/info"
|
||||
echo "$BASE_NAME" > "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/info_addon_base"
|
||||
|
||||
# 复制融合环境(core, work)到新的包内 files
|
||||
log.info "复制融合环境文件..."
|
||||
sudo cp -r "$CRAFT_DIR"/core "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/files/" 2>/dev/null || true
|
||||
|
||||
+105
-67
@@ -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
|
||||
@@ -15,12 +19,12 @@ fi
|
||||
|
||||
# 显示用法信息
|
||||
usage() {
|
||||
echo "用法: $SCRIPT_NAME [--manual] --base <basename> [--base <basename> ...] [--addons <addon-name> ...] <deb文件路径>"
|
||||
echo " 或者在手动模式下不传入 DEB 文件: $SCRIPT_NAME --manual --base <basename> [--base <basename> ...]"
|
||||
echo "用法: $SCRIPT_NAME [--manual] --base <basename> [basename ...] [--base <basename> ...] [--addons <addon-name> ...] <deb文件路径>"
|
||||
echo " 或者在手动模式下不传入 DEB 文件: $SCRIPT_NAME --manual --base <basename> [basename ...] [--base <basename> ...]"
|
||||
echo ""
|
||||
echo "参数说明:"
|
||||
echo " --manual 启用手动模式:融合挂载后打开交互 shell,退出 shell 后脚本继续"
|
||||
echo " --basename 必填参数(非手动模式下),指定基础环境名称,可多次使用"
|
||||
echo " --basename 必填参数(非手动模式下),指定基础环境名称,可一次指定多个或多次使用"
|
||||
echo " --addons 可选参数,指定额外挂载的 addons 包名称,可多次使用"
|
||||
echo " deb文件路径 要转换的DEB文件路径(非手动且非空模式下必填)"
|
||||
echo " --pkgname 可选参数,指定新包的包名(默认使用原DEB包名)"
|
||||
@@ -28,6 +32,7 @@ usage() {
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " $SCRIPT_NAME --base amber-pm-trixie /path/to/package.deb"
|
||||
echo " $SCRIPT_NAME --base amber-pm-trixie amber-pm-trixie-gxde-base /path/to/package.deb"
|
||||
echo " $SCRIPT_NAME --base amber-pm-trixie --addons amber-pm-trixie-nvidia-addons /path/to/package.deb"
|
||||
echo " $SCRIPT_NAME --manual --base amber-pm-trixie # 只融合挂载并进入手动 shell"
|
||||
echo " $SCRIPT_NAME --manual --base amber-pm-trixie --pkgname newpkg --version 1.2.3 /path/to/package.deb"
|
||||
@@ -39,6 +44,7 @@ usage() {
|
||||
BASENAMES=() # 存放实际用于构建 overlay 的 base(可能会被递归添加)
|
||||
BASENAMES_ORIG=() # 存放用户原始输入的 base 列表(用于 control 中 Depends 等)
|
||||
ADDONS=() # 存放用户显式指定的 addons 包名
|
||||
SELECTED_ADDONS=() # 存放本次转换要写入应用 info_layer_addons 的 addons
|
||||
DEB_PATH=""
|
||||
PKGNAME=""
|
||||
VERSION=""
|
||||
@@ -48,14 +54,28 @@ MANUAL_MODE=false
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--base)
|
||||
if [ -z "$2" ]; then
|
||||
shift
|
||||
if [ $# -eq 0 ] || [[ "$1" == -* ]]; then
|
||||
log.error "--base 后需要跟名称"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
BASENAMES+=("$2")
|
||||
BASENAMES_ORIG+=("$2")
|
||||
shift 2
|
||||
while [ $# -gt 0 ]; do
|
||||
[[ "$1" == -* ]] && break
|
||||
if [ -n "$DEB_PATH" ]; then
|
||||
log.error "未知参数或多余的参数: $1"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
if [ -f "$1" ]; then
|
||||
DEB_PATH="$1"
|
||||
shift
|
||||
break
|
||||
fi
|
||||
BASENAMES+=("$1")
|
||||
BASENAMES_ORIG+=("$1")
|
||||
shift
|
||||
done
|
||||
;;
|
||||
--addons)
|
||||
if [ -z "$2" ]; then
|
||||
@@ -64,6 +84,7 @@ while [ $# -gt 0 ]; do
|
||||
exit 1
|
||||
fi
|
||||
ADDONS+=("$2")
|
||||
SELECTED_ADDONS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--pkgname)
|
||||
@@ -159,6 +180,34 @@ cleanup() {
|
||||
# 设置退出时清理
|
||||
trap cleanup EXIT
|
||||
|
||||
# 辅助函数:追加数组项并去重
|
||||
_append_unique() {
|
||||
local array_name="$1"
|
||||
local item="$2"
|
||||
[ -z "$item" ] && return
|
||||
|
||||
local existing
|
||||
eval 'for existing in "${'"$array_name"'[@]}"; do
|
||||
[ "$existing" = "$item" ] && return
|
||||
done'
|
||||
eval "$array_name"'+=("$item")'
|
||||
}
|
||||
|
||||
_pkg_dir() {
|
||||
local pkgname="$1"
|
||||
local pkg_dir="/var/lib/apm/${pkgname}"
|
||||
if [ ! -d "$pkg_dir" ]; then
|
||||
pkg_dir="/var/lib/apm/apm/files/ace-env/var/lib/apm/${pkgname}"
|
||||
fi
|
||||
[ -d "$pkg_dir" ] && echo "$pkg_dir"
|
||||
}
|
||||
|
||||
_is_addon_pkg() {
|
||||
local pkg_dir
|
||||
pkg_dir="$(_pkg_dir "$1")"
|
||||
[ -n "$pkg_dir" ] && [ -f "${pkg_dir}/info_addon_base" ]
|
||||
}
|
||||
|
||||
# 递归获取info文件中的依赖 (会把新依赖追加到 BASENAMES 数组中)
|
||||
get_recursive_basenames() {
|
||||
local basename="$1"
|
||||
@@ -188,7 +237,33 @@ get_recursive_basenames() {
|
||||
fi
|
||||
}
|
||||
|
||||
# 递归获取所有基础环境(从用户输入的 base 开始)
|
||||
BASE_INPUTS=("${BASENAMES[@]}")
|
||||
BASENAMES=()
|
||||
|
||||
# 将 --base 中的 addons 转换为显式 addons,并把其 info 依赖的 base 加入 base 列表。
|
||||
for BASE in "${BASE_INPUTS[@]}"; do
|
||||
if _is_addon_pkg "$BASE"; then
|
||||
log.info "检测到 --base 指向 addons: $BASE"
|
||||
_append_unique ADDONS "$BASE"
|
||||
_append_unique SELECTED_ADDONS "$BASE"
|
||||
|
||||
addon_info="$(_pkg_dir "$BASE")/info"
|
||||
if [ -f "$addon_info" ]; then
|
||||
while IFS= read -r addon_base; do
|
||||
[ -z "$addon_base" ] && continue
|
||||
_append_unique BASENAMES "$addon_base"
|
||||
done < "$addon_info"
|
||||
else
|
||||
log.warn "addons 缺少 info,无法自动补 base 依赖: $BASE"
|
||||
fi
|
||||
else
|
||||
_append_unique BASENAMES "$BASE"
|
||||
fi
|
||||
done
|
||||
|
||||
BASENAMES_ORIG=("${BASENAMES[@]}")
|
||||
|
||||
# 递归获取所有基础环境(从规范化后的 base 开始)
|
||||
for BASE in "${BASENAMES[@]}"; do
|
||||
get_recursive_basenames "$BASE"
|
||||
done
|
||||
@@ -217,56 +292,7 @@ log.info "将使用的新包名: ${NEW_PKGNAME:-<未指定>}"
|
||||
log.info "将使用的新版本: ${NEW_VERSION:-<未指定>}"
|
||||
log.info "使用的架构: $ORIG_ARCH"
|
||||
|
||||
# 辅助函数:读取某个 base 的 addons 并追加到 LOWERDIRS
|
||||
_add_base_addons_to_lowerdirs() {
|
||||
local base_name="$1"
|
||||
local base_dir="/var/lib/apm/apm/files/ace-env/var/lib/apm/${base_name}"
|
||||
if [ ! -d "$base_dir" ]; then
|
||||
base_dir="/var/lib/apm/${base_name}"
|
||||
fi
|
||||
[ ! -d "$base_dir" ] && return
|
||||
|
||||
local addon_dirs=()
|
||||
local addon_file
|
||||
local addon_name
|
||||
|
||||
# 读取 info_layer_addons 主文件
|
||||
if [ -f "${base_dir}/info_layer_addons" ]; then
|
||||
while IFS= read -r addon_name; do
|
||||
[ -z "$addon_name" ] && continue
|
||||
addon_dirs+=("$addon_name")
|
||||
done < "${base_dir}/info_layer_addons"
|
||||
fi
|
||||
|
||||
# 读取 info_layer_addons.d 目录
|
||||
if [ -d "${base_dir}/info_layer_addons.d" ]; then
|
||||
for addon_file in $(ls -1 "${base_dir}/info_layer_addons.d" 2>/dev/null | sort); do
|
||||
addon_name="${addon_file#*-}"
|
||||
[ -z "$addon_name" ] && continue
|
||||
addon_dirs+=("$addon_name")
|
||||
done
|
||||
fi
|
||||
|
||||
local addon
|
||||
for addon in "${addon_dirs[@]}"; do
|
||||
local addon_path="/var/lib/apm/${addon}"
|
||||
if [ ! -d "$addon_path" ]; then
|
||||
addon_path="/var/lib/apm/apm/files/ace-env/var/lib/apm/${addon}"
|
||||
fi
|
||||
|
||||
if [ -d "${addon_path}/files/ace-env" ]; then
|
||||
log.info " 自动挂载 addon: $addon (ace-env)"
|
||||
LOWERDIRS+=("${addon_path}/files/ace-env")
|
||||
elif [ -d "${addon_path}/files/core" ]; then
|
||||
log.info " 自动挂载 addon: $addon (core)"
|
||||
LOWERDIRS+=("${addon_path}/files/core")
|
||||
else
|
||||
log.warn "自动 addon 路径不存在,跳过: $addon"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# 2. 构建 lowerdir 路径(多个 base 按顺序叠放,包含自动 addons)
|
||||
# 2. 构建 lowerdir 路径(多个 base 按顺序叠放,只包含本次显式选择的 addons)
|
||||
log.info "构建 overlay lowerdir 路径..."
|
||||
LOWERDIRS=()
|
||||
|
||||
@@ -274,9 +300,6 @@ for BASENAME in "${BASENAMES[@]}"; do
|
||||
ACE_ENV_PATH="/var/lib/apm/apm/files/ace-env/var/lib/apm/${BASENAME}/files/ace-env"
|
||||
CORE_PATH="/var/lib/apm/apm/files/ace-env/var/lib/apm/${BASENAME}/files/core"
|
||||
|
||||
# 先挂载该 base 的 addons(addons 在 base 之上)
|
||||
_add_base_addons_to_lowerdirs "$BASENAME"
|
||||
|
||||
if [ -d "$ACE_ENV_PATH" ]; then
|
||||
log.info "使用 ace-env 路径: $ACE_ENV_PATH"
|
||||
LOWERDIRS+=("$ACE_ENV_PATH")
|
||||
@@ -291,7 +314,7 @@ for BASENAME in "${BASENAMES[@]}"; do
|
||||
fi
|
||||
done
|
||||
|
||||
# 追加用户显式指定的 addons(放在 bases 之上)
|
||||
# 追加本次显式选择的 addons(放在 bases 之上)
|
||||
for addon in "${ADDONS[@]}"; do
|
||||
ADDON_PATH="/var/lib/apm/${addon}"
|
||||
if [ ! -d "$ADDON_PATH" ]; then
|
||||
@@ -598,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"
|
||||
@@ -613,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(若不存在则跳过转换)
|
||||
@@ -634,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 行
|
||||
@@ -772,6 +801,15 @@ for BASENAME in "${BASENAMES[@]}"; do
|
||||
log.info " 写入: $BASENAME"
|
||||
done
|
||||
|
||||
if [ ${#SELECTED_ADDONS[@]} -gt 0 ]; then
|
||||
log.info "创建 info_layer_addons 文件(仅包含本次选择的 addons)..."
|
||||
: > "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/info_layer_addons" 2>/dev/null || true
|
||||
for addon in "${SELECTED_ADDONS[@]}"; do
|
||||
echo "$addon" >> "$PKG_BUILD_DIR/var/lib/apm/${NEW_PKGNAME}/info_layer_addons"
|
||||
log.info " 写入 addon: $addon"
|
||||
done
|
||||
fi
|
||||
|
||||
# 创建 postrm 脚本
|
||||
cat > "$PKG_BUILD_DIR/DEBIAN/postrm" << 'EOF'
|
||||
#!/bin/bash
|
||||
@@ -835,7 +873,7 @@ calculate_directory_size() {
|
||||
fi
|
||||
}
|
||||
|
||||
# 构建依赖字符串 - 包含所有用户原始输入的 base 和显式指定的 addons(用于 control)
|
||||
# 构建依赖字符串 - 包含规范化后的 base 和显式指定的 addons(用于 control)
|
||||
DEPENDS_PARTS=("${BASENAMES_ORIG[@]}")
|
||||
|
||||
# 如果包名是 addons 格式(*-addons),确保 base 已在依赖中
|
||||
|
||||
@@ -1,32 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 检测是否安装了 XFCE、DDE 或 GNOME 桌面环境
|
||||
# 检测是否安装了 KDE Plasma 桌面环境
|
||||
# 通过检查系统中是否存在相关的 desktop 文件或关键程序
|
||||
is_xfce_or_dde_or_gnome() {
|
||||
# 检查 XFCE
|
||||
if [ -f /usr/share/xsessions/xfce.desktop ] || \
|
||||
[ -f /usr/local/share/xsessions/xfce.desktop ] || \
|
||||
command -v xfce4-session >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
# 检查 DDE/Deepin
|
||||
if [ -f /usr/share/xsessions/deepin.desktop ] || \
|
||||
[ -f /usr/share/xsessions/dde.desktop ] || \
|
||||
[ -f /usr/local/share/xsessions/deepin.desktop ] || \
|
||||
[ -f /usr/local/share/xsessions/dde.desktop ] || \
|
||||
command -v dde-session >/dev/null 2>&1 || \
|
||||
command -v startdde >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
# 检查 GNOME
|
||||
if [ -f /usr/share/xsessions/gnome.desktop ] || \
|
||||
[ -f /usr/share/xsessions/gnome-xorg.desktop ] || \
|
||||
[ -f /usr/share/xsessions/gnome-wayland.desktop ] || \
|
||||
[ -f /usr/local/share/xsessions/gnome.desktop ] || \
|
||||
[ -f /usr/local/share/xsessions/gnome-xorg.desktop ] || \
|
||||
[ -f /usr/local/share/xsessions/gnome-wayland.desktop ] || \
|
||||
command -v gnome-session >/dev/null 2>&1 || \
|
||||
command -v gnome-shell >/dev/null 2>&1; then
|
||||
is_kde_plasma() {
|
||||
# 检查 KDE Plasma
|
||||
if [ -f /usr/share/xsessions/plasma.desktop ] || \
|
||||
[ -f /usr/share/xsessions/plasma-xorg.desktop ] || \
|
||||
[ -f /usr/share/xsessions/plasma-wayland.desktop ] || \
|
||||
[ -f /usr/local/share/xsessions/plasma.desktop ] || \
|
||||
[ -f /usr/local/share/xsessions/plasma-xorg.desktop ] || \
|
||||
[ -f /usr/local/share/xsessions/plasma-wayland.desktop ] || \
|
||||
command -v startplasma-x11 >/dev/null 2>&1 || \
|
||||
command -v startplasma-wayland >/dev/null 2>&1 || \
|
||||
command -v plasmashell >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
@@ -39,13 +25,13 @@ if grep -q "Kylin" /etc/os-release; then
|
||||
echo "检测到麒麟系统,使用目标目录: $TARGET_BASE"
|
||||
else
|
||||
TARGET_BASE="/usr/local/share"
|
||||
# 检测是否为 XFCE、DDE 或 GNOME 桌面环境
|
||||
if is_xfce_or_dde_or_gnome; then
|
||||
APP_TARGET_DIR="$TARGET_BASE/applications"
|
||||
echo "检测到 XFCE/DDE/GNOME 桌面环境,使用目标目录: $APP_TARGET_DIR"
|
||||
else
|
||||
# 检测是否为 KDE Plasma 桌面环境
|
||||
if is_kde_plasma; then
|
||||
APP_TARGET_DIR="$TARGET_BASE/applications/apm"
|
||||
echo "使用目标目录: $APP_TARGET_DIR"
|
||||
echo "检测到 KDE Plasma 桌面环境,使用目标目录: $APP_TARGET_DIR"
|
||||
else
|
||||
APP_TARGET_DIR="$TARGET_BASE/applications"
|
||||
echo "使用标准目标目录: $APP_TARGET_DIR"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -142,12 +128,4 @@ if ! grep -q "Kylin" /etc/os-release; then
|
||||
rmdir "$APM_SUBDIR" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# 更新桌面数据库
|
||||
if command -v update-desktop-database >/dev/null 2>&1; then
|
||||
echo "正在更新桌面数据库..."
|
||||
update-desktop-database "$TARGET_BASE/applications/"
|
||||
else
|
||||
echo "警告: update-desktop-database 命令未找到"
|
||||
fi
|
||||
@@ -81,6 +81,8 @@ while ! network-check; do
|
||||
done
|
||||
|
||||
# 每日更新星火源文件
|
||||
apm autoremove -y
|
||||
apm clean
|
||||
|
||||
exit
|
||||
###########################################################################
|
||||
|
||||
Binary file not shown.
@@ -27,8 +27,18 @@ 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"
|
||||
if is_nixos; then
|
||||
APM_CONTAINER_PATH="/amber-ce-tools/bin-override:/usr/local/bin:/usr/bin/"
|
||||
fi
|
||||
|
||||
APM_PKG_NAME="${APM_PKG_NAME:-apm-general}"
|
||||
|
||||
non_root_user=$(who | awk '{print $1}' | head -n 1)
|
||||
@@ -61,7 +71,7 @@ fi
|
||||
#########################################################################################
|
||||
##########合成bwrap 1. 基础函数配置段
|
||||
# 初始化 EXEC_COMMAND 为 bwrap 基础指令
|
||||
EXEC_COMMAND="bwrap --dev-bind / / bwrap"
|
||||
EXEC_COMMAND="bwrap --dev-bind / / "
|
||||
|
||||
# add_command 函数定义
|
||||
function add_command() {
|
||||
@@ -106,7 +116,7 @@ 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"
|
||||
@@ -201,4 +211,4 @@ add_command "bash -c \"${container_command}\""
|
||||
# echo "${EXEC_COMMAND}"
|
||||
|
||||
# 注意: 实际执行时,请确保所有变量(如 $uid, $chrootEnvPath 等)都已正确定义
|
||||
eval "${EXEC_COMMAND}"
|
||||
eval "${EXEC_COMMAND}"
|
||||
|
||||
@@ -7,6 +7,14 @@ 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"
|
||||
if is_nixos; then
|
||||
APM_CONTAINER_PATH="/amber-ce-tools/bin-override:/usr/local/bin:/usr/bin/"
|
||||
fi
|
||||
|
||||
|
||||
non_root_user=$(who | awk '{print $1}' | head -n 1)
|
||||
@@ -28,7 +36,7 @@ fi
|
||||
#########################################################################################
|
||||
##########合成bwrap 1. 基础函数配置段
|
||||
# 初始化 EXEC_COMMAND 为 bwrap 基础指令
|
||||
EXEC_COMMAND="bwrap --dev-bind / / bwrap"
|
||||
EXEC_COMMAND="bwrap --dev-bind / / "
|
||||
|
||||
# add_command 函数定义
|
||||
function add_command() {
|
||||
@@ -80,7 +88,7 @@ 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"
|
||||
@@ -139,4 +147,3 @@ add_command "bash -c \"${container_command}\""
|
||||
|
||||
# 注意: 实际执行时,请确保所有变量(如 $uid, $chrootEnvPath 等)都已正确定义
|
||||
eval ${EXEC_COMMAND}
|
||||
|
||||
|
||||
@@ -15,6 +15,15 @@ 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"
|
||||
if is_nixos; then
|
||||
APM_CONTAINER_PATH="/amber-ce-tools/bin-override:/usr/local/bin:/usr/bin/"
|
||||
fi
|
||||
|
||||
#if [ ! -e $chrootEnvPath ];then
|
||||
echo "Uncompress the env...."
|
||||
tar -xvf $chrootEnvPath.tar.xz -C /var/lib/apm/$PKGNAME/files/
|
||||
@@ -41,7 +50,7 @@ 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" \
|
||||
--setenv IS_ACE_ENV "1" \
|
||||
--dev-bind-try /media /media \
|
||||
--dev-bind-try /tmp /tmp \
|
||||
@@ -89,7 +98,7 @@ 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" \
|
||||
--setenv IS_ACE_ENV "1" \
|
||||
--dev-bind $chrootEnvPath/ / \
|
||||
--dev-bind-try /media /media \
|
||||
@@ -121,4 +130,4 @@ ln -sfv ../../usr/share/pixmaps/ $chrootEnvPath/amber-ce-tools/data-dir/
|
||||
|
||||
chmod 777 -R $chrootEnvPath/usr/share/icons
|
||||
rm -vfr $chrootEnvPath/dev/*
|
||||
true
|
||||
true
|
||||
|
||||
@@ -14,16 +14,24 @@ export ACE_PACKAGE_NAME=$PKGNAME
|
||||
|
||||
chrootEnvPath=/var/lib/apm/$PKGNAME/files/ace-env
|
||||
|
||||
if [ ! -e $chrootEnvPath/finish.flag ];then
|
||||
is_nixos() {
|
||||
[ -f /etc/os-release ] && grep -Eq '^ID="?nixos"?$' /etc/os-release
|
||||
}
|
||||
|
||||
if [ "$(id -u)" = "0" ]; then
|
||||
`dirname $chrootEnvPath`/bin/ace-init
|
||||
else
|
||||
pkexec `dirname $chrootEnvPath`/bin/ace-init
|
||||
APM_CONTAINER_PATH="/amber-ce-tools/bin-override:$PATH"
|
||||
if is_nixos; then
|
||||
APM_CONTAINER_PATH="/amber-ce-tools/bin-override:/usr/local/bin:/usr/bin/"
|
||||
fi
|
||||
|
||||
# if [ ! -e $chrootEnvPath/finish.flag ];then
|
||||
|
||||
fi
|
||||
# if [ "$(id -u)" = "0" ]; then
|
||||
# `dirname $chrootEnvPath`/bin/ace-init
|
||||
# else
|
||||
# pkexec `dirname $chrootEnvPath`/bin/ace-init
|
||||
# fi
|
||||
# Ubuntu 26.04 中断了我们配置容器
|
||||
#fi
|
||||
non_root_user=$(who | awk '{print $1}' | head -n 1)
|
||||
uid=$(id -u $non_root_user)
|
||||
|
||||
@@ -43,7 +51,7 @@ fi
|
||||
#########################################################################################
|
||||
##########合成bwrap 1. 基础函数配置段
|
||||
# 初始化 EXEC_COMMAND 为 bwrap 基础指令
|
||||
EXEC_COMMAND="bwrap --dev-bind / / bwrap"
|
||||
EXEC_COMMAND="bwrap --dev-bind / /"
|
||||
|
||||
# add_command 函数定义
|
||||
function add_command() {
|
||||
@@ -95,7 +103,7 @@ 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"
|
||||
@@ -150,5 +158,3 @@ add_command "bash -c \"${container_command}\""
|
||||
|
||||
# 注意: 实际执行时,请确保所有变量(如 $uid, $chrootEnvPath 等)都已正确定义
|
||||
eval ${EXEC_COMMAND}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user