diff --git a/pkg/mkimage/Dockerfile b/pkg/mkimage/Dockerfile new file mode 100644 index 000000000..229fed31b --- /dev/null +++ b/pkg/mkimage/Dockerfile @@ -0,0 +1,23 @@ +FROM linuxkit/alpine:6336329f15b4166514782eaa555cf0ffd35c519c@sha256:f6c2ce92910b1d6e4e5557850a554f4a3ae9f66c1e89ad86a24d6c6e550f165e AS mirror + +RUN mkdir -p /out/etc/apk && cp -r /etc/apk/* /out/etc/apk/ +RUN apk add --no-cache --initdb -p /out \ + alpine-baselayout \ + busybox \ + e2fsprogs \ + e2fsprogs-extra \ + musl \ + sfdisk \ + syslinux \ + xfsprogs \ + && true +RUN rm -rf /out/etc/apk /out/lib/apk /out/var/cache + +FROM scratch +ENTRYPOINT [] +CMD [] +WORKDIR / +COPY --from=mirror /out/ / +COPY mkimage.sh /usr/bin/ +CMD ["mkimage.sh"] +LABEL org.mobyproject.config='{"readonly": true, "capabilities": ["CAP_SYS_ADMIN", "CAP_MKNOD"], "binds": ["/dev:/dev", "/data:/data"]}' diff --git a/pkg/mkimage/Makefile b/pkg/mkimage/Makefile new file mode 100644 index 000000000..26931a984 --- /dev/null +++ b/pkg/mkimage/Makefile @@ -0,0 +1,15 @@ +.PHONY: tag push +default: push + +ORG?=linuxkit +IMAGE=mkimage +DEPS=Dockerfile mkimage.sh + +HASH?=$(shell git ls-tree HEAD -- ../$(notdir $(CURDIR)) | awk '{print $$3}') + +tag: $(DEPS) + docker build --no-cache --network=none -t $(ORG)/$(IMAGE):$(HASH) . + +push: tag + docker pull $(ORG)/$(IMAGE):$(HASH) || \ + docker push $(ORG)/$(IMAGE):$(HASH) diff --git a/pkg/mkimage/mkimage.sh b/pkg/mkimage/mkimage.sh new file mode 100755 index 000000000..16d2ed813 --- /dev/null +++ b/pkg/mkimage/mkimage.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +# currently only supports ext4 disks; will extend for other filesystems, ISO, ... + +do_mkfs() +{ + diskdev="$1" + + # new disks does not have an DOS signature in sector 0 + # this makes sfdisk complain. We can workaround this by letting + # fdisk create that DOS signature, by just do a "w", a write. + # http://bugs.alpinelinux.org/issues/145 + echo "w" | fdisk $diskdev >/dev/null + + # format one large partition + echo ";" | sfdisk --quiet $diskdev + + # update status + blockdev --rereadpt $diskdev 2> /dev/null + + # wait for device + for i in $(seq 1 50); do test -b "$DATA" && break || sleep .1; mdev -s; done + + FSOPTS="-O resize_inode,has_journal,extent,huge_file,flex_bg,uninit_bg,64bit,dir_nlink,extra_isize" + + mkfs.ext4 -q -F $FSOPTS ${diskdev}1 +} + +DEV="$(find /dev -maxdepth 1 -type b ! -name 'loop*' | grep -v '[0-9]$' | sed 's@.*/dev/@@' | sort | head -1 )" + +[ -z "${DEV}" ] && exit 1 + +DRIVE="/dev/${DEV}" + +# format +do_mkfs "$DRIVE" + +PARTITION="${DRIVE}1" + +# mount +mount "$PARTITION" /mnt + +# copy kernel, initrd +cp -a /data/kernel /data/initrd.img /mnt/ + +# create syslinux.cfg +CMDLINE="$(cat /data/cmdline)" + +CFG="DEFAULT linux +LABEL linux + KERNEL /kernel + INITRD /initrd.img + APPEND ${CMDLINE} +" + +printf "$CFG" > /mnt/syslinux.cfg + +# install syslinux +extlinux --install /mnt + +# unmount +umount /mnt + +# install mbr +dd if=usr/share/syslinux/mbr.bin of="$DRIVE" bs=440 count=1 + +# make bootable +sfdisk -A "$DRIVE" 1 diff --git a/test/cases/040_packages/001_mkimage/mkimage.yml b/test/cases/040_packages/001_mkimage/mkimage.yml new file mode 100644 index 000000000..7ff26285a --- /dev/null +++ b/test/cases/040_packages/001_mkimage/mkimage.yml @@ -0,0 +1,26 @@ +kernel: + image: "linuxkit/kernel:4.9.x" + cmdline: "console=ttyS0" +init: + - linuxkit/init:cbd7ae748f0a082516501a3e914fa0c924ee941e + - linuxkit/runc:24dfe632ed3ff53a026ee3fac046fd544434e2d6 + - linuxkit/containerd:f1130450206d4f64f0ddc13d15bb68435aa1ff61 +onboot: + - name: mkimage + image: "linuxkit/mkimage:8bb18fe306afaca9ba50fe3148ec12570586c2a6" + - name: poweroff + image: "linuxkit/poweroff:a8f1e4ad8d459f1fdaad9e4b007512cb3b504ae8" +files: + - path: data/kernel + source: run-kernel + - path: data/initrd.img + source: run-initrd.img + - path: data/cmdline + source: run-cmdline +trust: + image: + - linuxkit/kernel + - linuxkit/binfmt + - linuxkit/rngd +outputs: + - format: kernel+initrd diff --git a/test/cases/040_packages/001_mkimage/run.yml b/test/cases/040_packages/001_mkimage/run.yml new file mode 100644 index 000000000..69ba7fe6d --- /dev/null +++ b/test/cases/040_packages/001_mkimage/run.yml @@ -0,0 +1,18 @@ +kernel: + image: "linuxkit/kernel:4.9.x" + cmdline: "console=ttyS0" +init: + - linuxkit/init:cbd7ae748f0a082516501a3e914fa0c924ee941e + - linuxkit/runc:24dfe632ed3ff53a026ee3fac046fd544434e2d6 + - linuxkit/containerd:1c71f95fa36040ea7e987deb98a7a2a363853f01 + - linuxkit/ca-certificates:4e9a83e890e6477dcd25029fc4f1ced61d0642f4 +onboot: + - name: poweroff + image: "linuxkit/poweroff:a8f1e4ad8d459f1fdaad9e4b007512cb3b504ae8" +trust: + image: + - linuxkit/kernel + - linuxkit/binfmt + - linuxkit/rngd +outputs: + - format: kernel+initrd diff --git a/test/cases/040_packages/001_mkimage/test.sh b/test/cases/040_packages/001_mkimage/test.sh new file mode 100644 index 000000000..6afa72a93 --- /dev/null +++ b/test/cases/040_packages/001_mkimage/test.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# SUMMARY: Test the mkimage container by using it to build a bootable qcow2 +# LABELS: +# REPEAT: + +set -e + +# Source libraries. Uncomment if needed/defined +#. "${RT_LIB}" +. "${RT_PROJECT_ROOT}/_lib/lib.sh" + +clean_up() { + find . -iname "run*" -not -iname "*.yml" -exec rm -rf {} \; + find . -iname "mkimage*" -not -iname "*.yml" -exec rm -rf {} \; + rm -f disk.qcow2 +} +trap clean_up EXIT + +# Test code goes here +moby build run.yml +moby build mkimage.yml +linuxkit run qemu -disk-size 200 -disk-format qcow2 -disk disk.qcow2 -kernel mkimage +linuxkit run qemu disk.qcow2 + +exit 0