如何构建第三方 snap core 包并在其它组件中引用?

目标

snapd 有自己的官方 core 包,这个 core 包可以看做是一个基础的 rootfs。现有的业务程序依赖一个特定版本的 rootfs,不能在官方的 snap core 包上运行,需要用现有的 rootfs 制作一个 snap core 包来使用

尝试构建一个第三方的 core 包的过程

初步编写的 snapcraft.yaml 文件内容:

name: test-rootfs
version: '1'
summary: Runtime environment based on vpp container
description: |
  The base snap based on the Ubuntu 22.04 release.
type: base
architectures:
- amd64
assumes:
- snapd2.55.5
confinement: strict
grade: stable
environment:
  LD_LIBRARY_PATH: ${SNAP_LIBRARY_PATH}${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}:$SNAP/lib:$SNAP/usr/lib:$SNAP/lib/x86_64-linux-gnu:$SNAP/usr/lib/x86_64-linux-gnu
  PATH: $SNAP/usr/sbin:$SNAP/usr/bin:$SNAP/sbin:$SNAP/bin:$PATH

parts:
 file-copy:
   plugin: dump
   source: /root/vpp-rootfs
   stage:
      - bin
      - boot
      - dev
      - etc
      - home
      - lib
      - lib32
      - lib64
      - libx32
      - media
      - mnt
      - opt
      - run
      - sbin
      - srv
      - tmp
      - usr
      - var

拷贝 rootfs 文件并执行 snapcraft 构建,尝试上传制作好的包,有如下报错信息:

longyu@longyu-virtual-machine:/tmp$ snapcraft upload --release=stable test-rootfs_1_amd64.snap
Status: processing - (2.0s)                                                                                                                                                        
Status: processing                                                                                                                                                                 

Issues while processing snap:g                                                                                                                                                     
- missing required mountpoints: /proc, /root, /sys, /usr/lib/snapd, /usr/local/share/fonts, /usr/share/fonts, /var/cache/fontconfig, /var/lib/snapd, /var/snap
- (NEEDS REVIEW) type 'base' not allowed
- found errors in file output: unusual mode 'rwxr-sr-x' for entry './usr/bin/chage', unusual mode 'rwsr-xr-x' for entry './usr/bin/chfn', unusual mode 'rwsr-xr-x' for entry './usr/bin/chsh', unusual mode 'rwxr-sr-x' for entry './usr/bin/expiry', unusual mode 'rwsr-xr-x' for entry './usr/bin/gpasswd', unusual mode 'rwsr-xr-x' for entry './usr/bin/mount', unusual mode 'rwsr-xr-x' for entry './usr/bin/newgrp', unusual mode 'rwsr-xr-x' for entry './usr/bin/passwd', unusual mode 'rwsr-xr-x' for entry './usr/bin/su', unusual mode 'rwsr-xr-x' for entry './usr/bin/umount', unusual mode 'rwxr-sr-x' for entry './usr/bin/wall', unusual mode 'rwxr-sr-x' for entry './usr/sbin/pam_extrausers_chkpwd', unusual mode 'rwxr-sr-x' for entry './usr/sbin/unix_chkpwd', unusual mode 'rwxrwsr-x' for entry './var/local', unusual mode 'rwxrwsr-x' for entry './var/mail'                                                                                                                                                                               
Full execution log: '/home/longyu/.local/state/snapcraft/log/snapcraft-20230905-174851.673611.log'

报错信息中有如下三个问题:

  1. 缺少必要的挂载点如 /proc、/root、/sys 等目录
  2. base 类型 snap 包需要 REVIEW
  3. rootfs 中的文件中有特殊权限,如 suid 等

第一个跟第三个问题比较容易解决,第二个问题看上去不太容易整。

本地编译尝试使用本地生成的三方 core 包

修改 yaml 文件,指定使用本地三方 core 包,编译 snap 包时有如下报错信息:

root@ubuntu:/home/longyu/snap/l2fwd/snap#  snapcraft --destructive-mode --debug
Failed to install or refresh snap 'test-rootfs'.                                                                                                                                           
'test-rootfs' does not exist or is not available on channel 'latest/stable'.
Use `snap info test-rootfs` to get a list of channels the snap is available on.

网上搜索到的解决方法:

https://snapcraft.io/docs/releasing-your-app

https://snapcraft.io/docs/public-private-unlisted-snaps

总结一下就是将编译生成的包推送到 snap-store 进行 release,实际尝试发现 base 类型的包并不能直接推送,需要指定 reviewer,在 review 通过后才能 release,同时 base 包的目录结构以及部分目录的权限也有要求,需要整改。

如何解决使用本地编译生成的 core 包的问题?

1. 官方使用方式

严格控制 core 包的 release,需要 REVIEW,流程相对复杂。

2. 修改 snapcraft 源码方式

对 snapcraft 的源码并不熟悉,修改代码的成本过高。

3. 手动修改、安装现有的 core 包,替换内容为自定义的 rootfs 内容

  1. 执行 unsquashfs 解压现有 core 包到指定目录
  2. 删除解压出来的 rootfs 中的旧目录,保留部分必要的空目录,然后复制新的 rootfs 目录(需要去掉所有使用 suid 执行的程序)
  3. 执行 mksquashfs rootfs xxx.snap -comp xz 重新生成 snap 包
  4. 将新生成的 snap 包替换到 /var/lib/snapd/snaps/ 目录中
  5. 重启系统,重新挂载 snap 包,此时新的 core 包生效

使用如下命令手动拷贝 rootfs:

rm -rf ./bin/
cp ../../bin/ ./ -rf 
rm -rf ./bin
cp -rf  ../../bin/ ./
rm -rf ./etc/
cp -rf ../../etc/ ./
rm -rf ./run/
cp -rf ../../run/ ./
rm -rf ./usr
cp -rf ../../usr/ ./
rm -rf ./var
cp -rf ../../var/ ./
mkdir ./usr/lib/snapd
mkdir -p ./usr/local/share/fonts ./usr/share/fonts ./var/cache/fontconfig ./var/lib/snapd ./var/snap
cp ./var-bak/lib/snapd/ ./var/lib/ -rf

备注:cp 执行后,suid 权限自动丢失,没有再额外处理权限问题。

执行上述操作后,测试验证可以正常使用。

总结

snap 是一个跨发行版的包管理框架,当实际业务系统有在多个发行版运行的场景时,使用 snap 这样的框架能够实现一次开发无需修改多发行版运行的效果,减少了业务系统适配多个发行版的工作量。

虽然 snap 有着这样的优点,但是特定的业务系统并不一定能够使用到。一般来说业务系统都有自己的依赖,在这个依赖中最基础的是 rootfs。snap 框架虽然也提供了多种不同的 rootfs core 包供用户使用,对于特定的依赖却并不支持,自定义开发也显得困难重重,毕竟很难绕过闭源的 snap store。

从另外一个方面想,直接使用 snap 自己的生态提供的组件能够上述问题,却需要额外的适配工作量,需要根据实际情况进行取舍。

  • 19
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值