Snapcraft执行prime命令时在pull步骤无限挂起的问题求助
问题描述
首次尝试用Snapcraft为包含3个应用的项目构建snap包,单独执行snapcraft stage a --use-lxd可成功完成对应部件的stage步骤,但执行snapcraft prime --use-lxd时,构建卡在2023-01-08 16:22:11.505 check if Part('websocket'):Step.PULL is outdated \ (31013.8s)步骤。已提前单独构建所有部件且无明显错误,但整体构建不会跳过已完成阶段,怀疑检查pull是否过时的逻辑陷入无限目录递归,需要优化snapcraft配置。
当前snapcraft.yaml配置如下:
name: test summary: ... description: ... confinement: strict base: core22 grade: stable version: "1" architectures: - build-on: amd64 apps: a: command: /usr/share/a/app plugs: - network - home b: command: /usr/share/b/app plugs: - network - home c: command: /usr/share/c/app plugs: - network - home parts: source: plugin: nil source: https://github.com/flutter/flutter.git source-type: "git" source-depth: 1 source-branch: "master" build-packages: [clang, cmake, git, ninja-build, pkg-config, libgtk-3-dev, liblzma-dev, curl, unzip] stage-packages: [libgtk-3-0, libblkid1, liblzma5] override-pull: | craftctl default git fetch --unshallow PATH="$CRAFT_PART_SRC/bin:$PATH" flutter doctor PATH="$CRAFT_PART_SRC/bin:$PATH" flutter channel master PATH="$CRAFT_PART_SRC/bin:$PATH" flutter precache override-build: | set -eux mkdir -p $CRAFT_PART_INSTALL/usr/bin mkdir -p $CRAFT_PART_INSTALL/usr/libexec cp -r $CRAFT_PART_SRC $CRAFT_PART_INSTALL/usr/libexec/flutter ln -sf $CRAFT_PART_INSTALL/usr/libexec/flutter/bin/flutter $CRAFT_PART_INSTALL/usr/bin/flutter ln -sf $CRAFT_PART_INSTALL/usr/libexec/flutter/bin/dart $CRAFT_PART_INSTALL/usr/bin/dart export PATH="$CRAFT_PART_INSTALL/usr/bin:$PATH" override-prime: "" packages: source: packages source-type: local plugin: nil build-packages: [rsync] override-pull: | echo "$(pwd)" rsync -r --exclude snap --exclude .git --exclude .vs --exclude .plugin_symlinks --exclude TestResults --exclude releases --exclude .dart_tool --exclude .vscode --exclude node_modules --exclude build $SNAPCRAFT_PROJECT_DIR/packages/* $SNAPCRAFT_PART_SRC/ override-build: | rsync -r $SNAPCRAFT_PART_SRC/* $SNAPCRAFT_PART_INSTALL override-stage: "" override-prime: "" websocket: source: websocket source-type: local plugin: nil build-packages: [rsync] override-pull: | rsync -r --exclude snap --exclude .git --exclude .vs --exclude .plugin_symlinks --exclude TestResults --exclude releases --exclude .dart_tool --exclude .vscode --exclude node_modules --exclude build $SNAPCRAFT_PROJECT_DIR/websocket/* $SNAPCRAFT_PART_SRC/ override-build: | rsync -r $SNAPCRAFT_PART_SRC/* $SNAPCRAFT_PART_INSTALL override-stage: "" override-prime: "" dummy: plugin: nil build-packages: [rsync] build-snaps: [ yq ] stage-packages: [dotnet-sdk-6.0, dotnet-runtime-6.0] after: [source, packages, websocket] override-pull: "" override-build: "" override-prime: "" a: source: a_src source-type: local plugin: nil after: [dummy] override-pull: | mkdir -p packages mkdir -p a_src mkdir -p websocket rsync -r ~/parts/websocket/install/* $SNAPCRAFT_PART_SRC/websocket rsync -r ~/parts/packages/install/* $SNAPCRAFT_PART_SRC/packages rsync -r --exclude snap --exclude .git --exclude .vs --exclude .plugin_symlinks --exclude TestResults --exclude releases --exclude .dart_tool --exclude .vscode --exclude node_modules --exclude build $SNAPCRAFT_PROJECT_DIR/a_src/* $SNAPCRAFT_PART_SRC/a_src #craftctl default cd a_src flutter clean flutter pub get override-build: | craftctl default cd a_src flutter build linux rsync --mkpath -r build/linux/x64/release/bundle/* $SNAPCRAFT_PART_INSTALL/usr/share/a override-stage: | rsync –-ignore-existing -r $SNAPCRAFT_PART_INSTALL/* $SNAPCRAFT_STAGE b: source: b_src source-type: local plugin: nil after: [dummy] override-pull: | mkdir -p packages mkdir -p b_src mkdir -p websocket rsync -r ~/parts/websocket/install/* $SNAPCRAFT_PART_SRC/websocket rsync -r ~/parts/packages/install/* $SNAPCRAFT_PART_SRC/packages rsync -r --exclude snap --exclude .git --exclude .vs --exclude .plugin_symlinks --exclude TestResults --exclude releases --exclude .dart_tool --exclude .vscode --exclude node_modules --exclude build $SNAPCRAFT_PROJECT_DIR/b_src/* $SNAPCRAFT_PART_SRC/b_src #craftctl default cd b_src flutter pub get override-build: | craftctl default cd b_src flutter build linux rsync --mkpath -r build/linux/x64/release/bundle/* $SNAPCRAFT_PART_INSTALL/usr/share/b override-stage: | rsync –-ignore-existing -r $SNAPCRAFT_PART_INSTALL/* $SNAPCRAFT_STAGE c: source: c_src source-type: local plugin: nil after: [dummy] override-pull: | mkdir -p packages mkdir -p c_src mkdir -p websocket rsync -r ~/parts/websocket/install/* $SNAPCRAFT_PART_SRC/websocket rsync -r ~/parts/packages/install/* $SNAPCRAFT_PART_SRC/packages rsync -r --exclude snap --exclude .git --exclude .vs --exclude .plugin_symlinks --exclude TestResults --exclude releases --exclude .dart_tool --exclude .vscode --exclude node_modules --exclude build $SNAPCRAFT_PROJECT_DIR/c_src/* $SNAPCRAFT_PART_SRC/c_src #craftctl default cd c_src flutter clean flutter pub get override-build: | craftctl default cd c_src flutter build linux rsync --mkpath -r build/linux/x64/release/bundle/* $SNAPCRAFT_PART_INSTALL/usr/share/c override-stage: | rsync –-ignore-existing -r $SNAPCRAFT_PART_INSTALL/* $SNAPCRAFT_STAGE test: after: [a, c, b] plugin: nil
优化方案
1. 移除跨部件手动文件复制,依赖Snapcraft原生机制
当前a/b/c部件的override-pull中手动从~/parts/...复制websocket和packages内容,会导致Snapcraft的文件哈希检查陷入递归循环,同时破坏依赖追踪逻辑。
解决方法:
- 删除
a/b/c部件中mkdir -p packages/websocket及对应rsync命令 - 在
a/b/c的override-pull中,通过环境变量让Flutter直接引用stage目录中的依赖:cd $CRAFT_PART_SRC flutter clean # 指向stage中的依赖目录,避免重复复制 flutter pub get --offline --directory=$CRAFT_PART_SRC - 确保
a/b/c部件的after字段包含packages和websocket,让Snapcraft自动处理依赖顺序
2. 修复语法错误
所有override-stage中的rsync –-ignore-existing使用了中文全角破折号,会被rsync识别为无效参数,导致文件同步异常,让Snapcraft误判文件状态变化。需改为英文半角破折号--ignore-existing。
3. 移除无用部件
dummy部件仅用于依赖管理和安装dotnet包,可将其build-packages、build-snaps、stage-packages合并到基础部件中test部件无实际逻辑,直接删除
4. 简化Flutter安装
当前source部件手动克隆并复制整个Flutter仓库,可直接使用官方Flutter snap包作为构建依赖,避免手动配置:
flutter-base: plugin: nil build-snaps: [flutter/latest/stable, yq/latest/stable] build-packages: [clang, cmake, ninja-build, pkg-config, libgtk-3-dev, liblzma-dev, rsync] stage-packages: [libgtk-3-0, libblkid1, liblzma5, dotnet-sdk-6.0, dotnet-runtime-6.0] override-pull: | craftctl default flutter precache --linux
5. 明确文件同步规则,减少冗余
在packages和websocket部件中使用organize字段指定安装路径,避免无差别复制:
packages: source: packages source-type: local plugin: nil after: [flutter-base] organize: "*": usr/share/packages/
修改后的示例配置
name: test summary: ... description: ... confinement: strict base: core22 grade: stable version: "1" architectures: - build-on: amd64 apps: a: command: /usr/share/a/app plugs: - network - home b: command: /usr/share/b/app plugs: - network - home c: command: /usr/share/c/app plugs: - network - home parts: flutter-base: plugin: nil build-snaps: [flutter/latest/stable, yq/latest/stable] build-packages: [clang, cmake, ninja-build, pkg-config, libgtk-3-dev, liblzma-dev, rsync] stage-packages: [libgtk-3-0, libblkid1, liblzma5, dotnet-sdk-6.0, dotnet-runtime-6.0] override-pull: | craftctl default flutter precache --linux packages: source: packages source-type: local plugin: nil after: [flutter-base] organize: "*": usr/share/packages/ override-pull: | rsync -r --exclude='snap' --exclude='.git' --exclude='.vs' --exclude='.plugin_symlinks' --exclude='TestResults' --exclude='releases' --exclude='.dart_tool' --exclude='.vscode' --exclude='node_modules' --exclude='build' $CRAFT_PROJECT_DIR/packages/* $CRAFT_PART_SRC/ websocket: source: websocket source-type: local plugin: nil after: [flutter-base] organize: "*": usr/share/websocket/ override-pull: | rsync -r --exclude='snap' --exclude='.git' --exclude='.vs' --exclude='.plugin_symlinks' --exclude='TestResults' --exclude='releases' --exclude='.dart_tool' --exclude='.vscode' --exclude='node_modules' --exclude='build' $CRAFT_PROJECT_DIR/websocket/* $CRAFT_PART_SRC/ a: source: a_src source-type: local plugin: nil after: [flutter-base, packages, websocket] override-pull: | rsync -r --exclude='snap' --exclude='.git' --exclude='.vs' --exclude='.plugin_symlinks' --exclude='TestResults' --exclude='releases' --exclude='.dart_tool' --exclude='.vscode' --exclude='node_modules' --exclude='build' $CRAFT_PROJECT_DIR/a_src/* $CRAFT_PART_SRC/ cd $CRAFT_PART_SRC flutter clean flutter pub get --offline --directory=$CRAFT_PART_SRC override-build: | cd $CRAFT_PART_SRC flutter build linux --release rsync --mkpath -r build/linux/x64/release/bundle/* $CRAFT_PART_INSTALL/usr/share/a override-stage: | rsync --ignore-existing -r $CRAFT_PART_INSTALL/* $CRAFT_STAGE b: source: b_src source-type: local plugin: nil after: [flutter-base, packages, websocket] override-pull: | rsync -r --exclude='snap' --exclude='.git' --exclude='.vs' --exclude='.plugin_symlinks' --exclude='TestResults' --exclude='releases' --exclude='.dart_tool' --exclude='.vscode' --exclude='node_modules' --exclude='build' $CRAFT_PROJECT_DIR/b_src/* $CRAFT_PART_SRC/ cd $CRAFT_PART_SRC flutter clean flutter pub get --offline --directory=$CRAFT_PART_SRC override-build: | cd $CRAFT_PART_SRC flutter build linux --release rsync --mkpath -r build/linux/x64/release/bundle/* $CRAFT_PART_INSTALL/usr/share/b override-stage: | rsync --ignore-existing -r $CRAFT_PART_INSTALL/* $CRAFT_STAGE c: source: c_src source-type: local plugin: nil after: [flutter-base, packages, websocket] override-pull: | rsync -r --exclude='snap' --exclude='.git' --exclude='.vs' --exclude='.plugin_symlinks' --exclude='TestResults' --exclude='releases' --exclude='.dart_tool' --exclude='.vscode' --exclude='node_modules' --exclude='build' $CRAFT_PROJECT_DIR/c_src/* $CRAFT_PART_SRC/ cd $CRAFT_PART_SRC flutter clean flutter pub get --offline --directory=$CRAFT_PART_SRC override-build: | cd $CRAFT_PART_SRC flutter build linux --release rsync --mkpath -r build/linux/x64/release/bundle/* $CRAFT_PART_INSTALL/usr/share/c override-stage: | rsync --ignore-existing -r $CRAFT_PART_INSTALL/* $CRAFT_STAGE
内容的提问来源于stack exchange,提问作者Lawrence Kok
相关产品推荐
相关产品推荐

