diff --git a/tools-image/Dockerfile b/tools-image/Dockerfile index 224abde..33c5128 100644 --- a/tools-image/Dockerfile +++ b/tools-image/Dockerfile @@ -28,7 +28,11 @@ FROM quay.io/kairos/packages-arm64:grub-efi-static-0.1 AS grub-efi FROM quay.io/kairos/packages-arm64:grub-config-static-0.1 AS grub-config FROM quay.io/kairos/packages-arm64:grub-artifacts-static-0.1 AS grub-artifacts - + ## RAW images +FROM quay.io/kairos/packages:grub-efi-static-0.1 AS grub-raw-efi +FROM quay.io/kairos/packages:grub-config-static-0.1 AS grub-raw-config +FROM quay.io/kairos/packages:grub-artifacts-static-0.1 AS grub-raw-artifacts + FROM opensuse/leap:$LEAP_VERSION COPY --from=elemental /usr/bin/elemental /usr/bin/elemental COPY --from=luet /usr/bin/luet /usr/bin/luet @@ -37,6 +41,11 @@ COPY --from=luet /usr/bin/luet /usr/bin/luet COPY --from=grub2 / /grub2 COPY --from=efi / /efi +# RAW images +COPY --from=grub-raw-efi / /raw/grub +COPY --from=grub-raw-config / /raw/grubconfig +COPY --from=grub-raw-artifacts / /raw/grubartifacts + # RPI64 COPY --from=rpi-u-boot / /rpi/u-boot COPY --from=rpi-firmware / /rpi/rpi-firmware @@ -71,6 +80,11 @@ COPY ./add-cloud-init.sh /add-cloud-init.sh COPY ./build-arm-image.sh /build-arm-image.sh COPY ./arm /arm +# RAW images helpers +COPY ./gce.sh /gce.sh +COPY ./raw-images.sh /raw-images.sh +COPY ./azure.sh /azure.sh + COPY defaults.yaml /defaults.yaml diff --git a/tools-image/azure.sh b/tools-image/azure.sh new file mode 100755 index 0000000..d6cf273 --- /dev/null +++ b/tools-image/azure.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Transform a raw image disk to azure vhd +RAWIMAGE="$1" +VHDDISK="${2:-disk.vhd}" + +MB=$((1024*1024)) +size=$(qemu-img info -f raw --output json "$RAWIMAGE" | gawk 'match($0, /"virtual-size": ([0-9]+),/, val) {print val[1]}') +# shellcheck disable=SC2004 +ROUNDED_SIZE=$(((($size+$MB-1)/$MB)*$MB)) +echo "Resizing raw image to $ROUNDED_SIZE" +qemu-img resize -f raw "$RAWIMAGE" $ROUNDED_SIZE +echo "Converting $RAWIMAGE to $VHDDISK" +qemu-img convert -f raw -o subformat=fixed,force_size -O vpc "$RAWIMAGE" "$VHDDISK" +echo "Done" \ No newline at end of file diff --git a/tools-image/gce.sh b/tools-image/gce.sh new file mode 100755 index 0000000..a3386a9 --- /dev/null +++ b/tools-image/gce.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Transform a raw image disk to gce compatible +RAWIMAGE="$1" + +GB=$((1024*1024*1024)) +size=$(qemu-img info -f raw --output json "$RAWIMAGE" | gawk 'match($0, /"virtual-size": ([0-9]+),/, val) {print val[1]}') +# shellcheck disable=SC2004 +ROUNDED_SIZE=$(echo "$size/$GB+1"|bc) +echo "Resizing raw image from \"$size\"MB to \"$ROUNDED_SIZE\"GB" +qemu-img resize -f raw "$RAWIMAGE" "$ROUNDED_SIZE"G +echo "Compressing raw image $RAWIMAGE to $RAWIMAGE.tar.gz" +tar -c -z --format=oldgnu -f "$RAWIMAGE".tar.gz $RAWIMAGE +echo "Restoring size to original raw image" +qemu-img resize -f raw "$RAWIMAGE" --shrink "$size" +echo "Done" \ No newline at end of file diff --git a/tools-image/raw-images.sh b/tools-image/raw-images.sh new file mode 100755 index 0000000..71617e3 --- /dev/null +++ b/tools-image/raw-images.sh @@ -0,0 +1,71 @@ +#!/bin/bash +# Generates EFI bootable images (statically) +# This is a re-adaptation of https://github.com/rancher/elemental-toolkit/blob/v0.8.10-1/images/img-builder.sh, which was dropped +# How to use: +# First extract the image which you want to create an image from: +### luet util unpack rootfs +# Then convert it to a raw disk (EFI only): +### docker run -v $PWD:/output --entrypoint /raw-images.sh -ti --rm test-image /output/rootfs /output/foo.raw cloud-init.yaml + +: "${OEM_LABEL:=COS_OEM}" +: "${RECOVERY_LABEL:=COS_RECOVERY}" + +DIRECTORY=$1 +OUT=${2:-disk.raw} +CONFIG=$3 + +echo "Output: $OUT" + +set -e + +mkdir -p /build/root/grub2 +mkdir /build/root/cOS +mkdir /build/efi + +cp -rf /raw/grub/* /build/efi +cp -rf /raw/grubconfig/* /build/root +cp -rf /raw/grubartifacts/* /build/root/grub2 + +echo "Generating squashfs from $DIRECTORY" +mksquashfs $DIRECTORY recovery.squashfs -b 1024k -comp xz -Xbcj x86 +mv recovery.squashfs /build/root/cOS/recovery.squashfs + +# Create a 2GB filesystem for RECOVERY including the contents for root (grub config and squasfs container) +truncate -s $((2048*1024*1024)) rootfs.part +mkfs.ext2 -L "${RECOVERY_LABEL}" -d /build/root rootfs.part + +# Create the EFI partition FAT16 and include the EFI image and a basic grub.cfg +truncate -s $((20*1024*1024)) efi.part + +mkfs.fat -F16 -n COS_GRUB efi.part +mcopy -s -i efi.part /build/efi/EFI ::EFI + +# Create the grubenv forcing first boot to be on recovery system +mkdir -p /build/oem +cp /build/root/etc/cos/grubenv_firstboot /build/oem/grubenv +if [ -n "$CONFIG" ]; then + echo "Copying config file ($CONFIG)" + cp $CONFIG /build/oem +fi + +# Create a 64MB filesystem for OEM volume +truncate -s $((64*1024*1024)) oem.part +mkfs.ext2 -L "${OEM_LABEL}" -d /build/oem oem.part + +echo "Generating image $OUT" +# Create disk image, add 3MB of initial free space to disk, 1MB is for proper alignement, 2MB are for the hybrid legacy boot. +truncate -s $((3*1024*1024)) $OUT +{ + cat efi.part + cat oem.part + cat rootfs.part +} >> $OUT + +# Add an extra MB at the end of the disk for the gpt headers, in fact 34 sectors would be enough, but adding some more does not hurt. +truncate -s "+$((1024*1024))" $OUT + +# Create the partition table in $OUT (assumes sectors of 512 bytes) +sgdisk -n 1:2048:+2M -c 1:legacy -t 1:EF02 $OUT +sgdisk -n 2:0:+20M -c 2:UEFI -t 2:EF00 $OUT +sgdisk -n 3:0:+64M -c 3:oem -t 3:8300 $OUT +sgdisk -n 4:0:+2048M -c 4:root -t 4:8300 $OUT