背景简述
- 目标内核分支:4.4、4.18、4.19、5.10
- 根文件系统:最后一版非 Stream 的 CentOS 8
- 架构概述:
- 制作一份统一的原始 rootfs 镜像;
- 为每个内核版本各自设立一个 Job,各自拷贝一份原始 rootfs 运行 VM,随后在 VM 内执行编译内核、安装内核、运行测试套以及其他特定内核版本所需的动作。
Jenkins 配置手册
使用清华开源镜像站 。
Jenkins 有普通版(每周一更)和 LTS 版(每 12 周一更),安装包(以 Ubuntu 为例)在清华源上分别保存在 debian/
和 debian-stable/
上。下载下来直接安装即可,不用配 apt 啥的,主要是网络代理太麻烦。
安装后参考手册的指导 进行后续操作,如安装一些依赖,启动 Jenkins 服务并检查其状态等。
更新插件要用到的 update-center.json
在清华源的 updates/
目录中。
Jenkins 是以 jenkins
用户的身份执行各种命令的,由于启动虚拟机涉及 root 权限,因此要将该用户加入 (与后者冲突)在 sudo
群组,并/etc/sudoers
文件中指明其不需要密码:NOPASSWD
。参考这篇博客
。(暂时未掌握非根用户启动虚拟机的方法,若有求告知)
参考链接:
虚拟机设置避坑
-
虚拟机初始屏幕太小导致内核报错信息不完整的解决方法:
vga=
(链接 ) -
用一套 RSA 秘钥对实现两个用途:
-
主机登录虚拟机:SSH 免手动输密码登录:
cat id_rsa.pub >> ~/.ssh/authorized_keys
-
虚拟机
git clone
下载代码:设置.ssh/config
使 SSH 根据域名使用对应的私钥1Host WWW XXX 2 User YYY 3 Port ZZZ 4 IdentityFile ~/.ssh/generic_ci_key 5 IdentitiesOnly yes
-
参考资料:
man ssh_config(5)
-
-
CentOS 中网络设备自启动:
/etc/sysconfig/network-scripts/ifcfg-XXX
- 注意:不同内核启动时,网络设备的名称可能变化
QEMU 网络相关
总的来说,QEMU 的网络设置包含两部分:
-
虚拟机中的虚拟网络设备(virtual network device),也称虚拟网卡(emulated NIC)。
着重在虚拟机中模拟真实的网络设备,可由参数
-device
配置。 -
在主机侧与前者交互的网络后端(network backend)。
负责在主机网络与虚拟机网卡之间作网络报文的转接和交换,由参数
-netdev
配置。
此外,如果并不关心有关虚拟网卡和网络后端的过多细节,还可以使用 -nic
参数进行极简配置。关于这部分的参考材料(优先级从高到低排序):
- 关于 QEMU 网络配置的介绍 (必先读)
- 关于
-nic
参数的介绍 man qemu-system(1)
,搜“Network options”- user 网络端口映射
- Ubuntu 的
/etc/qemu/bridge.conf
在/usr/local/etc/qemu/bridge.conf
一开始的想法是【tap 网络后端 + 子网 IP 直连】,但最终采用了【user 网络后端 + SSH 端口映射】的方案。后者在同样满足功能要求的前提下,配置起来更简单,可拓展性也更好。
SSH 远程执行命令
执行命令本身很简单(链接 ):
1# Single command
2ssh user1@server1 command1
3
4# Multiple commands with heredoc.
5# The limit string should be quoted for expanding remote variables
6ssh -T user1@server1 <<'EOL'
7 command1
8 command2
9EOL
但有很多坑要躲:
-
远程关机并且返回值正常的方法(链接 ):
1# 直接运行 poweroff 返回值会异常,导致 Jenkins 判定 Job 失败 2shutdown --poweroff +1
-
不询问“是否加入 known_host”直接建立 SSH 连接的方法(链接 ):
1# ~/.ssh/config 2Host localhost 127.0.0.1 3 StrictHostKeyChecking no
或者在建立 SSH 链接时加
-o
参数:1ssh -o StrictHostKeyChecking no user@host
脚本代码
仅贴出相对重要的脚本,不完整,仅供参考。
-
install-rootfs.sh
:利用发行版安装光盘来安装根文件系统。1#!/bin/bash 2 3INSTALL_ISO=CentOS-8.5.2111-x86_64-dvd1.iso # CentOS-7-x86_64-Everything-2009.iso 4ROOTFS_IMG=new.qcow2 5 6sudo qemu-system-x86_64 \ 7 -m 4096 \ 8 -boot d \ 9 -enable-kvm \ 10 -cdrom $INSTALL_ISO \ 11 -hda $ROOTFS_IMG \ 12 -vnc :12 \ 13 -daemonize
-
vm-update-kernel-reboot.sh
:在主机侧启动虚拟机,在其上构建并安装新内核后重启。1#!/bin/bash 2 3source ./util-common.sh # take input $1 and $2 4 5DRIVE=rootfs-$KERNEL_VER.qcow2 6if [ ! -e $DRIVE ]; then 7 cp $PUBLIC_DIR/rootfs.qcow2 $DRIVE 8fi 9 10sudo qemu-system-x86_64 \ 11 -name $VM_NAME \ 12 -m 4096 \ 13 -smp 16 \ 14 -hda $DRIVE \ 15 -enable-kvm \ 16 -k en-us \ 17 -nic user,hostfwd=tcp::$SSH_PORT-:22 \ 18 -daemonize 19# For debugging 20# VNC_DISPLAY=":$((10+$SERIAL))" 21 # -vnc $VNC_DISPLAY \ 22 # -append "root=/dev/sda1 vga=ask" \ 23 # -initrd rootfs-images/x86.cpio.gz \ 24 25source ./util-check-connection.sh 26 27ssh -i $PUBLIC_DIR/generic_ci_key root@localhost -p$SSH_PORT<<EOL 28bash -ex ~/build_kernel.sh $KERNEL_VER 29shutdown --reboot +1 30EOL