From 8bae9cc7f1cc30baaceba5cc4eb6ced5b703f102 Mon Sep 17 00:00:00 2001 From: Yuhang Wei Date: Tue, 20 Jun 2023 07:23:46 +0000 Subject: [PATCH] KubeOS: support legacy boot mode --- cmd/agent/server/server.go | 12 +++++- cmd/agent/server/utils.go | 21 +++++++++- docs/quick-start.md | 2 +- ...66\344\275\234\346\214\207\345\257\274.md" | 1 + files/boot-grub2.mount | 14 +++++++ scripts/bootloader.sh | 20 +++++++--- scripts/create/imageCreate.sh | 38 ++++++++++++++----- scripts/create/rootfsCreate.sh | 31 +++++++++++---- scripts/kbimg.sh | 21 +++++++--- scripts/rpmlist | 2 - scripts/set_in_chroot.sh | 6 ++- 11 files changed, 134 insertions(+), 34 deletions(-) create mode 100644 files/boot-grub2.mount diff --git a/cmd/agent/server/server.go b/cmd/agent/server/server.go index 78eb0855..d5ee26b0 100644 --- a/cmd/agent/server/server.go +++ b/cmd/agent/server/server.go @@ -137,9 +137,19 @@ func (s *Server) rollback() error { if err != nil { return err } - if err = runCommand("grub2-editenv", grubenvPath, "set", "saved_entry="+next); err != nil { + bootMode, err := getBootMode() + if err != nil { return err } + if bootMode == "uefi" { + if err = runCommand("grub2-editenv", grubenvPath, "set", "saved_entry="+next); err != nil { + return err + } + } else { + if err = runCommand("grub2-set-default", next); err != nil { + return err + } + } return s.reboot() } diff --git a/cmd/agent/server/utils.go b/cmd/agent/server/utils.go index d3b1262c..0903451b 100644 --- a/cmd/agent/server/utils.go +++ b/cmd/agent/server/utils.go @@ -80,7 +80,15 @@ func install(imagePath string, side string, next string) error { return err } defer os.Remove(imagePath) - return runCommand("grub2-editenv", grubenvPath, "set", "saved_entry="+next) + bootMode, err := getBootMode() + if err != nil { + return err + } + if bootMode == "uefi" { + return runCommand("grub2-editenv", grubenvPath, "set", "saved_entry="+next) + } else { + return runCommand("grub2-set-default", next) + } } func getNextPart(partA string, partB string) (string, string, error) { @@ -135,6 +143,17 @@ func getRootfsDisks() (string, string, error) { return partA, partB, nil } +func getBootMode() (string, error) { + _, err := os.Stat("/sys/firmware/efi") + if err == nil { + return "uefi", nil + } else if os.IsNotExist(err) { + return "legacy", nil + } else { + return "", err + } +} + func createOSImage(neededPath preparePath) (string, error) { imagePath := neededPath.imagePath updatePath := neededPath.updatePath diff --git a/docs/quick-start.md b/docs/quick-start.md index 36738a18..21ddf593 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -77,7 +77,7 @@ * raw格式的系统镜像system.img,system.img大小默认为20G,支持的根文件系统分区大小<2020MiB,持久化分区<16GB。 * qcow2 格式的系统镜像 system.qcow2。 * 可用于升级的根文件系统分区镜像 update.img 。 - * 制作出来的容器 OS 虚拟机镜像目前只能用于 CPU 架构为 x86 和 AArch64 的虚拟机场景,不支持 x86 架构的虚拟机使用 legacy 启动模式启动 + * 制作出来的容器 OS 虚拟机镜像目前只能用于 CPU 架构为 x86 和 AArch64 的虚拟机场景,x86 架构的虚拟机使用 legacy 启动模式启动需制作镜像时指定-l参数 * 容器OS运行底噪<150M (不包含k8s组件及相关依赖kubernetes-kubeadm,kubernetes-kubelet, containernetworking-plugins,socat,conntrack-tools,ebtables,ethtool) * 本项目不提供容器OS镜像,仅提供裁剪工具,裁剪出来的容器OS内部的安全性由OS发行商保证。 - 声明: os-agent使用本地unix socket进行通信,因此不会新增端口。下载镜像的时候会新增一个客户端的随机端口,1024~65535使用完后关闭。proxy和operator与api-server通信时作为客户端也会有一个随机端口,基于kubernetes的operator框架,必须使用端口。他们部署在容器里。 diff --git "a/docs/user_guide/\345\256\271\345\231\250OS\351\225\234\345\203\217\345\210\266\344\275\234\346\214\207\345\257\274.md" "b/docs/user_guide/\345\256\271\345\231\250OS\351\225\234\345\203\217\345\210\266\344\275\234\346\214\207\345\257\274.md" index c5d5d687..f2823c85 100644 --- "a/docs/user_guide/\345\256\271\345\231\250OS\351\225\234\345\203\217\345\210\266\344\275\234\346\214\207\345\257\274.md" +++ "b/docs/user_guide/\345\256\271\345\231\250OS\351\225\234\345\203\217\345\210\266\344\275\234\346\214\207\345\257\274.md" @@ -31,6 +31,7 @@ kbimg是KubeOS部署和升级所需的镜像制作工具,可以使用kbimg制 | -b | os-agent二进制的路径 | | -e | KubeOS 镜像 root 用户密码,加密后的带盐值的密码,可以用 openssl,kiwi 命令生成 | | -d | 生成或者使用的 docke r镜像 | + | -l | 如果指定参数,则镜像为legacy引导,不指定默认是UEFI引导 | | -h --help | 查看帮助信息 | diff --git a/files/boot-grub2.mount b/files/boot-grub2.mount new file mode 100644 index 00000000..e6c41500 --- /dev/null +++ b/files/boot-grub2.mount @@ -0,0 +1,14 @@ +[Unit] +Description=grub2 Dir +DefaultDependencies=no +Conflicts=umount.target +Before=local-fs.target umount.target + +[Mount] +What=/dev/disk/by-label/GRUB2 +Where=/boot/grub2 +Type=ext4 +Options=defaults + +[Install] +WantedBy=local-fs.target diff --git a/scripts/bootloader.sh b/scripts/bootloader.sh index 16c5713d..75096a38 100644 --- a/scripts/bootloader.sh +++ b/scripts/bootloader.sh @@ -6,12 +6,22 @@ ARCH=`arch` function install_grub2_x86 () { - # make efi file, and save in FAT16 partition, to support UEFI boot mode - cp -r /usr/lib/grub/x86_64-efi boot/efi/EFI/openEuler - eval "grub2-mkimage -d /usr/lib/grub/x86_64-efi -O x86_64-efi --output=/boot/efi/EFI/openEuler/grubx64.efi '--prefix=(,gpt1)/EFI/openEuler' fat part_gpt part_msdos linux" + if [ "$BOOT_MODE" = "legacy" ]; then + # make boot.img/core.img and setup, to support legacy boot mode + GRUBNAME=$(which grub2-install) + echo "Installing GRUB2..." + GRUB_OPTS=${GRUB_OPTS:-"--force"} + GRUB_OPTS="$GRUB_OPTS --target=i386-pc" - mkdir -p /boot/EFI/BOOT/ - cp -f /boot/efi/EFI/openEuler/grubx64.efi /boot/efi/EFI/BOOT/BOOTX64.EFI + $GRUBNAME --modules="biosdisk part_msdos" $GRUB_OPTS $DEVICE + else + # make efi file, and save in FAT16 partition, to support UEFI boot mode + cp -r /usr/lib/grub/x86_64-efi boot/efi/EFI/openEuler + eval "grub2-mkimage -d /usr/lib/grub/x86_64-efi -O x86_64-efi --output=/boot/efi/EFI/openEuler/grubx64.efi '--prefix=(,gpt1)/EFI/openEuler' fat part_gpt part_msdos linux" + + mkdir -p /boot/EFI/BOOT/ + cp -f /boot/efi/EFI/openEuler/grubx64.efi /boot/efi/EFI/BOOT/BOOTX64.EFI + fi } function install_grub2_efi () diff --git a/scripts/create/imageCreate.sh b/scripts/create/imageCreate.sh index 56f106f7..4d02f9d1 100644 --- a/scripts/create/imageCreate.sh +++ b/scripts/create/imageCreate.sh @@ -14,29 +14,46 @@ RPM_ROOT="${PWD}/rootfs" IMG_SIZE=20 PWD="$(pwd)" function create_img() { + local BOOT_MODE=$1 rm -f system.img update.img qemu-img create system.img ${IMG_SIZE}G - parted system.img -s mklabel gpt - parted system.img -s mkpart primary fat32 1MiB 60MiB + if [ "$BOOT_MODE" = "legacy" ]; then + local BOOT_PATH=${TMP_MOUNT_PATH}/boot/grub2 + parted system.img -s mklabel msdos + parted system.img -s mkpart primary ext4 1MiB 60MiB + else + local BOOT_PATH=${TMP_MOUNT_PATH}/boot/efi + parted system.img -s mklabel gpt + parted system.img -s mkpart primary fat32 1MiB 60MiB + fi parted system.img -s mkpart primary ext4 60MiB 2160MiB parted system.img -s mkpart primary ext4 2160MiB 4260MiB parted system.img -s mkpart primary ext4 4260MiB 100% - parted system.img -s set 1 boot on local device=$(losetup -f) losetup "${device}" system.img mkdir -p "${TMP_MOUNT_PATH}" init_part system.img2 ROOT-A "${TMP_MOUNT_PATH}" - local BOOT_PATH=${TMP_MOUNT_PATH}/boot/efi + mkdir -p ${BOOT_PATH} chmod 755 ${BOOT_PATH} - init_part system.img1 BOOT "${BOOT_PATH}" + if [ "$BOOT_MODE" = "legacy" ]; then + init_part system.img1 GRUB2 "${BOOT_PATH}" + else + init_part system.img1 BOOT "${BOOT_PATH}" + fi tar -x -C ${TMP_MOUNT_PATH} -f os.tar + if [ "$BOOT_MODE" = "legacy" ]; then + sed -i "s/insmod part_gpt/insmod part_msdos/g; \ +s/set root='hd0,gpt2'/set root='hd0,msdos2'/g; \ +s/set root='hd0,gpt3'/set root='hd0,msdos3'/g" \ +"${TMP_MOUNT_PATH}"/boot/grub2/grub.cfg + fi sync cp bootloader.sh "${TMP_MOUNT_PATH}" mount_proc_dev_sys "${TMP_MOUNT_PATH}" - DEVICE="${device}" chroot "${TMP_MOUNT_PATH}" bash bootloader.sh + DEVICE="${device}" BOOT_MODE="${BOOT_MODE}" chroot "${TMP_MOUNT_PATH}" bash bootloader.sh rm -rf "${TMP_MOUNT_PATH}/bootloader.sh" sync @@ -52,6 +69,7 @@ function create_img() { umount "${TMP_MOUNT_PATH}" losetup -D + parted system.img -- set 1 boot on qemu-img convert system.img -O qcow2 system.qcow2 } @@ -70,8 +88,9 @@ function create_pxe_img() { tar -xvf os.tar ./initramfs.img mv os.tar kubeos.tar } + function create_docker_image() { - local DOCKER_IMG="$5" + local DOCKER_IMG="$6" create_os_tar_from_repo "$@" docker build -t ${DOCKER_IMG} -f ./Dockerfile . } @@ -79,14 +98,15 @@ function create_docker_image() { function create_vm_img() { local opt=$1 shift + local BOOT_MODE=$5 case $opt in "repo") create_os_tar_from_repo "$@" - create_img + create_img "${BOOT_MODE}" ;; "docker") create_os_tar_from_docker "$@" - create_img + create_img "${BOOT_MODE}" ;; esac diff --git a/scripts/create/rootfsCreate.sh b/scripts/create/rootfsCreate.sh index 29f2762f..377cbf85 100644 --- a/scripts/create/rootfsCreate.sh +++ b/scripts/create/rootfsCreate.sh @@ -21,7 +21,8 @@ function prepare_yum() { } function install_packages() { - local REPO=$1 + local REPO=$1 + local BOOT_MODE=$2 prepare_yum ${REPO} echo "install package.." @@ -35,9 +36,14 @@ function install_packages() { local rpms=$(cat ./rpmlist | tr "\n" " ") if [ "${ARCH}" == "x86_64" ]; then - yum -y --installroot="${RPM_ROOT}" install --nogpgcheck --setopt install_weak_deps=False ${rpms} grub2 grub2-efi-x64-modules grub2-pc-modules + if [ "${BOOT_MODE}" = "legacy" ]; then + rpms+=" grub2" + else + rpms+=" grub2-efi grub2-tools grub2-efi-x64-modules grub2-pc-modules" + fi + yum -y --installroot="${RPM_ROOT}" install --nogpgcheck --setopt install_weak_deps=False ${rpms} elif [ "${ARCH}" == "aarch64" ]; then - yum -y --installroot="${RPM_ROOT}" install --nogpgcheck --setopt install_weak_deps=False ${rpms} grub2-efi-aa64-modules + yum -y --installroot="${RPM_ROOT}" install --nogpgcheck --setopt install_weak_deps=False ${rpms} grub2-efi grub2-tools grub2-efi-aa64-modules fi yum -y --installroot="${RPM_ROOT}" clean all } @@ -46,6 +52,7 @@ function install_misc() { local VERSION=$1 local AGENT_PATH=$2 local PASSWD=$3 + local BOOT_MODE=$4 local DNS_CONF="${PWD}/resolv.conf" cp ../files/*mount ../files/os-agent.service "${RPM_ROOT}/usr/lib/systemd/system/" cp ../files/os-release "${RPM_ROOT}/usr/lib/" @@ -60,11 +67,18 @@ EOF echo "VERSION_ID=${VERSION}" >> "${RPM_ROOT}/usr/lib/os-release" mv "${RPM_ROOT}"/boot/vmlinuz* "${RPM_ROOT}/boot/vmlinuz" mv "${RPM_ROOT}"/boot/initramfs* "${RPM_ROOT}/boot/initramfs.img" - cp grub.cfg "${RPM_ROOT}"/boot/grub2 - cp grub.cfg "${RPM_ROOT}"/boot/efi/EFI/openEuler + if [ "$BOOT_MODE" = "legacy" ]; then + cp grub.cfg "${RPM_ROOT}"/boot/grub2 + sed -i "s/insmod part_gpt/insmod part_msdos/g; \ +s/set root='hd0,gpt2'/set root='hd0,msdos2'/g; \ +s/set root='hd0,gpt3'/set root='hd0,msdos3'/g" \ +"${RPM_ROOT}"/boot/grub2/grub.cfg + else + cp grub.cfg "${RPM_ROOT}"/boot/efi/EFI/openEuler + fi cp -r ./00bootup ${RPM_ROOT}/usr/lib/dracut/modules.d/ cp set_in_chroot.sh "${RPM_ROOT}" - ROOT_PWD="${PASSWD}" chroot "${RPM_ROOT}" bash /set_in_chroot.sh + ROOT_PWD="${PASSWD}" BOOT_MODE="${BOOT_MODE}" chroot "${RPM_ROOT}" bash /set_in_chroot.sh rm "${RPM_ROOT}/set_in_chroot.sh" if [ -e "${DNS_CONF}" ]; then cp "${DNS_CONF}" "${RPM_ROOT}/etc/resolv.conf" @@ -76,8 +90,9 @@ function create_os_tar_from_repo() { local VERSION=$2 local AGENT_PATH=$3 local PASSWD=$4 - install_packages ${REPO} - install_misc ${VERSION} ${AGENT_PATH} ${PASSWD} + local BOOT_MODE=$5 + install_packages ${REPO} ${BOOT_MODE} + install_misc ${VERSION} ${AGENT_PATH} ${PASSWD} ${BOOT_MODE} unmount_dir "${RPM_ROOT}" tar -C "$RPM_ROOT" -cf ./os.tar . } diff --git a/scripts/kbimg.sh b/scripts/kbimg.sh index 2c93084f..0f75f0db 100644 --- a/scripts/kbimg.sh +++ b/scripts/kbimg.sh @@ -20,6 +20,7 @@ DOCKER_IMG="" DOCKERFILE="" LOCK=./test.lock ADMIN_CONTAINER_DIR=./admin-container +BOOT_MODE=efi source common/globalVariables.sh &>/dev/null source common/log.sh &>/dev/null @@ -72,6 +73,7 @@ options: -b directory of os-agent binary -e os encrypted password -d docker image like repository/name:tag + -l boot to legacy BIOS mode, if not specify, then UEFI mode -h,--help show help information EOF } @@ -89,6 +91,7 @@ options: -b directory of os-agent binary -e os encrypted password -d docker image like repository/name:tag + -l boot to legacy BIOS mode, if not specify, then UEFI mode -h,--help show help information EOF } @@ -146,7 +149,7 @@ function verify_upgrade_image_input() { fi done set -eE - while getopts "p:v:e:b:d:" opt + while getopts "p:v:e:b:d:l" opt do case $opt in p) @@ -169,6 +172,9 @@ function verify_upgrade_image_input() { check_param $OPTARG DOCKER_IMG="$OPTARG" ;; + l) + BOOT_MODE=legacy + ;; *) log_error_print "option $opt not found" show_upgrade_image_usage @@ -190,7 +196,7 @@ function verify_repo_input() { fi done set -eE - while getopts "p:v:e:b:" opt + while getopts "p:v:e:b:l" opt do case $opt in p) @@ -209,6 +215,9 @@ function verify_repo_input() { # encrypted password contains special characters.,not verify. PASSWD="$OPTARG" ;; + l) + BOOT_MODE=legacy + ;; *) log_error_print "option $opt not found" show_vm_pxe_image_usage @@ -272,7 +281,7 @@ function verify_create_input() { exit 0 fi fi - if [ $# -ne 10 ]; then + if [[ $# -ne 10 && $# -ne 11 ]]; then log_error_print "the number of parameters is incorrect, please check it." show_upgrade_image_usage exit 3 @@ -281,7 +290,7 @@ function verify_create_input() { verify_upgrade_image_input "$@" check_repo_path "${REPO}" check_binary_exist "${AGENT_PATH}" - create_docker_image "${REPO}" "${VERSION}" "${AGENT_PATH}" "${PASSWD}" "${DOCKER_IMG}" + create_docker_image "${REPO}" "${VERSION}" "${AGENT_PATH}" "${PASSWD}" "${BOOT_MODE}" "${DOCKER_IMG}" ;; "vm-image") shift @@ -292,11 +301,11 @@ function verify_create_input() { fi fi check_disk_space "vm" - if [ $# -eq 8 ]; then + if [[ $# -eq 8 || $# -eq 9 ]]; then verify_repo_input "$@" check_repo_path "${REPO}" check_binary_exist "${AGENT_PATH}" - create_vm_img "repo" "${REPO}" "${VERSION}" "${AGENT_PATH}" "${PASSWD}" + create_vm_img "repo" "${REPO}" "${VERSION}" "${AGENT_PATH}" "${PASSWD}" "${BOOT_MODE}" elif [ $# -eq 2 ]; then verify_docker_input "$@" check_docker_exist "${DOCKER_IMG}" diff --git a/scripts/rpmlist b/scripts/rpmlist index 077a1642..fb6f2381 100644 --- a/scripts/rpmlist +++ b/scripts/rpmlist @@ -1,7 +1,5 @@ kernel passwd -grub2-efi -grub2-tools dhcp NetworkManager openssh-server diff --git a/scripts/set_in_chroot.sh b/scripts/set_in_chroot.sh index 4b061df6..80b5a91b 100644 --- a/scripts/set_in_chroot.sh +++ b/scripts/set_in_chroot.sh @@ -1,7 +1,11 @@ #!/bin/bash ln -s /usr/lib/systemd/system/os-agent.service /usr/lib/systemd/system/multi-user.target.wants/os-agent.service ln -s /usr/lib/systemd/system/kubelet.service /usr/lib/systemd/system/multi-user.target.wants/kubelet.service -ln -s /usr/lib/systemd/system/boot-efi.mount /lib/systemd/system/local-fs.target.wants/boot-efi.mount +if [ "$BOOT_MODE" = "legacy" ]; then + ln -s /usr/lib/systemd/system/boot-grub2.mount /lib/systemd/system/local-fs.target.wants/boot-grub2.mount +else + ln -s /usr/lib/systemd/system/boot-efi.mount /lib/systemd/system/local-fs.target.wants/boot-efi.mount +fi ln -s /usr/lib/systemd/system/etc.mount /lib/systemd/system/local-fs.target.wants/etc.mount str=`sed -n '/^root:/p' /etc/shadow | awk -F "root:" '{print $2}'` -- Gitee