最早 v0.0
yocto部分提供了3个接口:
- PRE_CMD :前置操作。
- EXTRA_INSTALL:额外安装的包。
- POST_CMD :收尾操作。
当时考虑的比较简单,实际上经常性的无法满足实际需要。
改进版 v0.1
在v0.0基础上,稍加改动 —— 使用PRE_CMD POST_CMD
。例子如下:
16 PRE_CMD = "sudo mount --bind /dev ${IMAGE_ROOTFS}/dev; \
17 sudo mount --bind /run ${IMAGE_ROOTFS}/run; \
18 sudo mount -t devpts devpts ${IMAGE_ROOTFS}/dev/pts; \
19 sudo mount -t proc proc ${IMAGE_ROOTFS}/proc; \
20 sudo mount -t sysfs sysfs ${IMAGE_ROOTFS}/sys; \
21 sudo cp ${WORKDIR}/config.sh ${IMAGE_ROOTFS}; \
22 sudo chroot ${IMAGE_ROOTFS} bash /config.sh; \
23 "
24
25 POST_CMD = "sudo umount ${IMAGE_ROOTFS}/proc; \
26 sudo umount ${IMAGE_ROOTFS}/sys; \
27 sudo umount ${IMAGE_ROOTFS}/dev/pts; \
28 sudo umount ${IMAGE_ROOTFS}/dev; \
29 sudo umount ${IMAGE_ROOTFS}/run; \
30 sudo rm ${IMAGE_ROOTFS}/config.sh; \
31 "
这一部分在每个项目中都是一样的,并且EXTRA_INSTALL
已经无用。所有的扩展通过config.sh
脚本去实现,像这样:
1 set -e
2
3 export HOME=/root
4 export LC_ALL=C
5
6 apt update
7 apt install -y systemd-sysv
8 apt install -y dialog locales
9
10 # 扩展根分区大小
11 apt install -y resize-assistant
12 # set background
13 apt install -y simple-wallpaper
14
15 # libopen62541-1 -> libmbedcrypto3 libmbedx509-0 libmbedtls12
16 apt install -y libopen62541-1
17
18 # 制作过程中使用的源
19 cat >/etc/apt/sources.list <<EOF
20 # 第三方其他包
21 deb http://172.29.157.20/my_mirror/extra v101-0721 main
22 # kvisor, 协议包
23 deb http://172.29.157.20/my_mirror/kvisor v101-0621 main
24 # 麒麟V10 SP1源
25 deb http://172.29.157.20/kylin/KYLIN-ALL 10.1 main restricted universe multiverse
26 EOF
......
132 cat >/etc/lightdm/lightdm.conf <<EOF
133 [SeatDefaults]
134 autologin-guest=false
135 autologin-user=root
136 autologin-user-timeout=0
137 EOF
138
139 # 最终系统使用的源
140 cat >/etc/apt/sources.list <<EOF
141 deb http://archive.kylinos.cn/kylin/KYLIN-ALL 10.1 main universe multiverse restricted
142 EOF
143
144 # 设置 hostname
145 echo kylinos >/etc/hostname
146
147 # 设置 root密码
148 echo root:qwer1234 | chpasswd
149
150 # 添加 kylin 用户
151 if ! awk -F: '{print $1}' /etc/passwd | grep -q ekylin; then
152 USERNAME="ekylin"
153 PASSWORD="qwer1234"
154 useradd -m -s /bin/bash -u 2000 "${USERNAME}"
155 usermod -c "${USERNAME}" "${USERNAME}"
156 echo "${USERNAME}:${PASSWORD}" | chpasswd
157 adduser ${USERNAME} sudo
158 adduser ${USERNAME} adm
159 fi
此时每个项目的config.sh
看起来都差不多,基本上就是apt install
加上一些配置啥的;存在大量的重复,并且这些重复分布在各个项目中。
当前状态存在的问题:
- 扩展一个新项目比较麻烦,往往通过
复制粘贴
的形式。 - 没有抽象,不宜维护。
v0.2
将各个项目中的config.sh
文件中的一些共性的内容抽象成函数,例如:
23 # 扩充根分区
24 function ins_resize() {
25 apt install -y resize-assistant
26 }
27
28 # 开机执行resize
29 function set_resize() {
30 if dpkg -l | grep ^ii | awk '{print $2}' | grep -q "^resize-assistant$"; then
31 ¦ systemctl enable resize-assistant
32 fi
33 }
63 # 网络工具
64 ## 基础网络工具
65 function ins_base_network() {
66 apt install -y iputils-ping iproute2 net-tools
67 }
68
69 function ins_network() {
70 ins_base_network
71 # Network Manager
72 apt install -y network-manager
73 if [ -d /etc/NetworkManager/conf.d ]; then
74 ¦ touch /etc/NetworkManager/conf.d/10-globally-managed-devices.conf
75 fi
76 apt install -y netplan.io
77 }
309 # 创建用户
310 function create_user() {
311 USERNAME="$1"
312 PASSWORD="$2"
313 if ! awk -F: '{print $1}' /etc/passwd | grep -q ${USERNAME}; then
314 ¦ useradd -m -s /bin/bash -u 2000 "${USERNAME}"
315 ¦ usermod -c "${USERNAME}" "${USERNAME}"
316 ¦ echo "${USERNAME}:${PASSWORD}" | chpasswd
317 ¦ adduser ${USERNAME} sudo
318 ¦ adduser ${USERNAME} adm
319 else
320 ¦ echo "user ${USERNAME} already exists"
321 fi
322 }
323
324 function set_hostname() {
325 HOSTNAME="$1"
326 echo ${HOSTNAME} >/etc/hostname
327
328 if ! grep -q "127.0.0.1 localhost" /etc/hosts; then
329 ¦ cat >>/etc/hosts <<EOF
330 127.0.0.1 localhost
331 127.0.1.1 ${HOSTNAME}
332 EOF
333 fi
334 }
然后,每个项目都会有一个对应的函数,例如:
438 function ubuntu() {
439 cat >/etc/apt/sources.list <<EOF
440 # deb http://172.29.157.20/ubuntu jammy main universe multiverse restricted
441 deb http://172.29.157.20/ubuntu-ports focal main universe multiverse restricted
442 EOF
443 apt update
444 ins_sysv
445 ins_kernel
446
447 (
448 ¦ # 解决不生成initrd问题
449 ¦ apt install -y initramfs-tools
450 ¦ version=$(basename $(readlink -f /boot/vmlinuz) | sed 's,vmlinuz-,,')
451 ¦ update-initramfs -u -k ${version}
452 )
453
454 ins_tools
455 ins_network
456 ins_ssh
457 finish
458 }
553 function chuangxin() {
554 cat >/etc/apt/sources.list <<EOF
555 # 第三方其他包
556 deb http://172.29.157.20/my_mirror/extra-0721 10.1 main
557
558 # kvisor, 协议包
559 deb http://172.29.157.20/my_mirror/kvisor-0811 10.1 main
560 deb http://172.29.157.20/my_mirror/kvisor-0621 10.1 main
561
562 deb http://archive.launchpad.dev/archive.kylinos.cn/kylin/KYLIN-ALL 10.1 main restricted universe multiverse
563 EOF
564 set_kylin_hosts
565 apt update
566
567 ins_sysv
568 ins_resize
569 ins_ssh
570 ins_network
571 ins_tools
572
573 ins_kvisor_chuangxin
574 ins_protocol
575
576 # 登录提示
577 sed -i "s#Kylin V10 SP1#Kylin Secure RT Operating System(IoT)V10#g" /etc/issue
578 sed -i "s#Kylin V10 SP1#Kylin Secure RT Operating System(IoT)V10#g" /etc/issue.net
579
580 remove_some_pkg
581 clean_kylin_hosts
582
583 # 最终系统使用的源
584 apt_KYLIN_ALL_public_2107
585
586 finish
587 }
此时,所有项目共用一个config.sh
脚本,通过传给该脚本不同的参数生成不同的版本,像这样:
public.inc
18 PRE_CMD = "sudo mount --bind /dev ${IMAGE_ROOTFS}/dev; \
19 sudo mount --bind /run ${IMAGE_ROOTFS}/run; \
20 sudo mount -t devpts devpts ${IMAGE_ROOTFS}/dev/pts; \
21 sudo mount -t proc proc ${IMAGE_ROOTFS}/proc; \
22 sudo mount -t sysfs sysfs ${IMAGE_ROOTFS}/sys; \
23 sudo cp ${WORKDIR}/config.sh ${IMAGE_ROOTFS}; \
24 sudo chroot ${IMAGE_ROOTFS} bash /config.sh ${KYCODENAME}; \
25 "
vkylin-2209.bb
7 KYCODENAME = "v2209"
比以前强一些,但是需要不断的扩展config.sh
;而且至此完全跟yocto/bitbake
没有关系;最终还是希望能跟yocto/bitbake
结合起来,使用include、inherit
等语法更好的构建版本。
v0.3 (讨论中)
主要修改yocto这块的流程:
- 缓存
debootstrap
的结果:以前每次运行都要重新执行debootstrap
,很耗时不方便;目前除非执行do_clean
,否则不在执行debootstrap
。
103 python do_copy_from_origin() {
104 src = d.getVar('ROOTFS_ORIGIN')
105 dst = d.getVar('IMAGE_ROOTFS')
106 cmd = "sudo rm -rf {};sudo cp -av {} {}".format(dst, src, dst)
107 exec_cmd(cmd)
108 }
- 将原来的
PRE_CMD POST_CMD
修改(但是依然兼容)为下面的形式:
114 python do_prepare_rootfs_first_stage() {
115 pre_cmd = d.getVar("PRE_CMD")
116 bb.note("fucking life : pre_cmd [%s]" % (pre_cmd))
117
118 if pre_cmd:
119 ¦ exec_cmd(pre_cmd)
120 }
121 python do_prepare_rootfs_middle_stage() {
122 bb.note("fucking life : here is middle stage !")
123 }
124 python do_prepare_rootfs_last_stage() {
125 post_cmd = d.getVar("POST_CMD")
126 bb.note("fucking life : post_cmd [%s]" % (post_cmd))
127
128 if post_cmd:
129 ¦ exec_cmd(post_cmd)
130 }
- 对
debootstrap
生成的origin_rootfs
进一步的操作都放在middle_stage
这里扩展。
设想
first_stage 、middle_stage、last_stage
都可以通过bitbake
的append语法进行扩展,结合v0.2
抽象出来的函数使用,会非常的灵活。
append语法设想:
8 do_first_stage:append() {
9 sudo mount --bind /dev ${IMAGE_ROOTFS}/dev;
10 sudo mount --bind /run ${IMAGE_ROOTFS}/run;
11 sudo mount -t devpts devpts ${IMAGE_ROOTFS}/dev/pts;
12 sudo mount -t proc proc ${IMAGE_ROOTFS}/proc;
13 sudo mount -t sysfs sysfs ${IMAGE_ROOTFS}/sys;
14 }
15
16 do_middle_stage:append() {
17 echo "xxx" > /etc/apt/sources.list
18 apt update
19 apt install xxx
20 }
21
22 do_last_stage:append() {
23 sudo umount ${IMAGE_ROOTFS}/proc;
24 sudo umount ${IMAGE_ROOTFS}/sys;
25 sudo umount ${IMAGE_ROOTFS}/dev/pts;
26 sudo umount ${IMAGE_ROOTFS}/dev;
27 sudo umount ${IMAGE_ROOTFS}/run;
28 sudo rm ${IMAGE_ROOTFS}/config.sh;
29 }
30
31
32 do_middle_stage:append() {
567 ins_sysv
568 ins_resize
569 ins_ssh
570 ins_network
571 ins_tools
572
573 ins_kvisor_chuangxin
574 ins_protocol
34 }
还可以考虑结合bitbake
的layer —— 使用.append文件,更加灵活的控制版本生成流程。
v0.4 版本规划(设想)
- 根据实际需求,规划若干基线——类似需求分类,针对项目出的版本依附在某个基线上。
- 基线是成长的——随着需求的增加,将共性的需求提到基线中即基线成长。
- 基线分级——底层基线负责
大
功能,比如系统基础包、安全特性等;中层基线相对大
的功能,比如可视化等。
补充:
- 基线可以不随着项目走;基线可以提前测试,为项目提供一个稳定的基础,提高发版速度。