From 7b29d68aed5b57a64bf277d5c21c4f910fc93f83 Mon Sep 17 00:00:00 2001 From: Wanjohi <71614375+wanjohiryan@users.noreply.github.com> Date: Thu, 10 Oct 2024 14:42:16 +0300 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20Add=20package=20docker-to-r?= =?UTF-8?q?ootfs=20(#121)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This package will handle creating the rootfs needed by CrosVM > More info incoming --- packages/docker-to-rootfs/Dockerfile | 6 ++ packages/docker-to-rootfs/README.md | 15 +++ packages/docker-to-rootfs/create_image.sh | 54 +++++++++++ packages/docker-to-rootfs/make.sh | 112 ++++++++++++++++++++++ packages/docker-to-rootfs/syslinux.cfg | 5 + 5 files changed, 192 insertions(+) create mode 100644 packages/docker-to-rootfs/Dockerfile create mode 100644 packages/docker-to-rootfs/README.md create mode 100644 packages/docker-to-rootfs/create_image.sh create mode 100644 packages/docker-to-rootfs/make.sh create mode 100644 packages/docker-to-rootfs/syslinux.cfg diff --git a/packages/docker-to-rootfs/Dockerfile b/packages/docker-to-rootfs/Dockerfile new file mode 100644 index 00000000..75f8e3e7 --- /dev/null +++ b/packages/docker-to-rootfs/Dockerfile @@ -0,0 +1,6 @@ +# https://github.com/iximiuz/docker-to-linux/blob/master/Dockerfile + +FROM amd64/debian:bullseye +LABEL com.iximiuz-project="docker-to-linux" +RUN apt-get -y update +RUN apt-get -y install extlinux fdisk \ No newline at end of file diff --git a/packages/docker-to-rootfs/README.md b/packages/docker-to-rootfs/README.md new file mode 100644 index 00000000..6e79237f --- /dev/null +++ b/packages/docker-to-rootfs/README.md @@ -0,0 +1,15 @@ +# Docker to RootFS + +We are building the rootfs as a docker image, mainly for consistency and ease of use. +So, to convert the Docker image to a rootfs good enough to run inside CrosVM we use this script + +Run it like so: +```bash +./make your-docker-image +``` + +TODO: +1. Make sure the docker image name passed in exists +2. Reduce the dependencies of this script to 1 (If possible) +3. Extract not only the rootfs, but also kernel and initrd +4. Add a way to pass in the size of the rootfs the user wants diff --git a/packages/docker-to-rootfs/create_image.sh b/packages/docker-to-rootfs/create_image.sh new file mode 100644 index 00000000..ee8e5100 --- /dev/null +++ b/packages/docker-to-rootfs/create_image.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +set -e + +UID_HOST=$1 +GID_HOST=$2 +VM_DISK_SIZE_MB=$3 + +echo_blue() { + local font_blue="\033[94m" + local font_bold="\033[1m" + local font_end="\033[0m" + + echo -e "\n${font_blue}${font_bold}${1}${font_end}" +} + +echo_blue "[Create disk image]" +[ -z "${VM_DISK_SIZE_MB}" ] && VM_DISK_SIZE_MB=1024 +VM_DISK_SIZE_SECTOR=$(expr $VM_DISK_SIZE_MB \* 1024 \* 1024 / 512) +dd if=/dev/zero of=/os/${DISTR}.img bs=${VM_DISK_SIZE_SECTOR} count=512 + +echo_blue "[Make partition]" +echo "type=83,bootable" | sfdisk /os/${DISTR}.img + +echo_blue "\n[Format partition with ext4]" +losetup -D +LOOPDEVICE=$(losetup -f) +echo -e "\n[Using ${LOOPDEVICE} loop device]" +losetup -o $(expr 512 \* 2048) ${LOOPDEVICE} /os/${DISTR}.img +mkfs.ext4 ${LOOPDEVICE} + +echo_blue "[Copy ${DISTR} directory structure to partition]" +mkdir -p /os/mnt +mount -t auto ${LOOPDEVICE} /os/mnt/ +cp -a /os/${DISTR}.dir/. /os/mnt/ + +echo_blue "[Setup extlinux]" +extlinux --install /os/mnt/boot/ +cp /os/syslinux.cfg /os/mnt/boot/syslinux.cfg +rm /os/mnt/.dockerenv + +echo_blue "[Unmount]" +umount /os/mnt +losetup -D + +echo_blue "[Write syslinux MBR]" +dd if=/usr/lib/syslinux/mbr/mbr.bin of=/os/${DISTR}.img bs=440 count=1 conv=notrunc + +#echo_blue "[Convert to qcow2]" +#qemu-img convert -c /os/${DISTR}.img -O qcow2 /os/${DISTR}.qcow2 + +[ "${UID_HOST}" -a "${GID_HOST}" ] && chown ${UID_HOST}:${GID_HOST} /os/${DISTR}.img + +rm -r /os/${DISTR}.dir /os/${DISTR}.tar \ No newline at end of file diff --git a/packages/docker-to-rootfs/make.sh b/packages/docker-to-rootfs/make.sh new file mode 100644 index 00000000..d9c09fa2 --- /dev/null +++ b/packages/docker-to-rootfs/make.sh @@ -0,0 +1,112 @@ +#!/bin/bash + +# Define colors +COL_RED="\033[0;31m" +COL_GRN="\033[0;32m" +COL_END="\033[0m" + +# Get current user and group IDs +USER_ID=$(id -u) +GROUP_ID=$(id -g) + +# Set default disk size +VM_DISK_SIZE_MB=${VM_DISK_SIZE_MB:-4096} + +# Set repository name +REPO="nestri" + +# Function to create a tar archive from a Docker image +create_tar() { + local name=$1 + echo -e "\n${COL_GRN}[Dump $name directory structure to tar archive]${COL_END}" + docker export -o $name.tar $(docker run -d $name /bin/true) +} + +# Function to extract a tar archive +extract_tar() { + local name=$1 + echo -e "\n${COL_GRN}[Extract $name tar archive]${COL_END}" + docker run -it \ + -v $(pwd):/os:rw \ + $REPO/builder bash -c "mkdir -p /os/$name.dir && tar -C /os/$name.dir --numeric-owner -xf /os/$name.tar" +} + +# Function to create a disk image +create_image() { + local name=$1 + echo -e "\n${COL_GRN}[Create $name disk image]${COL_END}" + docker run -it \ + -v $(pwd):/os:rw \ + -e DISTR=$name \ + --privileged \ + --cap-add SYS_ADMIN \ + $REPO/builder bash /os/create_image.sh $USER_ID $GROUP_ID $VM_DISK_SIZE_MB +} + +# Function to ensure builder is ready +ensure_builder() { + echo -e "\n${COL_GRN}[Ensure builder is ready]${COL_END}" + if [ "$(docker images -q $REPO/builder)" = '' ]; then + docker build -f Dockerfile -t $REPO/builder . + fi +} + +# Function to run builder interactively +run_builder_interactive() { + docker run -it \ + -v $(pwd):/os:rw \ + --cap-add SYS_ADMIN \ + $REPO/builder bash +} + +# Function to clean up +clean_up() { + echo -e "\n${COL_GRN}[Remove leftovers]${COL_END}" + rm -rf mnt debian.* alpine.* ubuntu.* + clean_docker_procs + clean_docker_images +} + +# Function to clean Docker processes +clean_docker_procs() { + echo -e "\n${COL_GRN}[Remove Docker Processes]${COL_END}" + if [ "$(docker ps -qa -f=label=com.iximiuz-project=$REPO)" != '' ]; then + docker rm $(docker ps -qa -f=label=com.iximiuz-project=$REPO) + else + echo "" + fi +} + +# Function to clean Docker images +clean_docker_images() { + echo -e "\n${COL_GRN}[Remove Docker Images]${COL_END}" + if [ "$(docker images -q $REPO/*)" != '' ]; then + docker rmi $(docker images -q $REPO/*) + else + echo "" + fi +} + +# Main script +if [ $# -lt 1 ]; then + echo "Usage: $0 [clean|builder-interactive]" + exit 1 +fi + +IMAGE_NAME=$1 + +case $2 in + builder-interactive) + run_builder_interactive + ;; + clean) + clean_up + ;; +esac + +ensure_builder +create_tar $IMAGE_NAME +extract_tar $IMAGE_NAME +create_image $IMAGE_NAME + +# Extract kernel `` virt-builder --get-kernel "${IMAGE_NAME}.img" -o . `` \ No newline at end of file diff --git a/packages/docker-to-rootfs/syslinux.cfg b/packages/docker-to-rootfs/syslinux.cfg new file mode 100644 index 00000000..0e7d6fcd --- /dev/null +++ b/packages/docker-to-rootfs/syslinux.cfg @@ -0,0 +1,5 @@ +DEFAULT linux + SAY Now booting the kernel from SYSLINUX... + LABEL linux + KERNEL /vmlinuz + APPEND rw root=/dev/sda1 initrd=/initrd.img \ No newline at end of file