summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@codethink.co.uk>2014-06-09 15:54:41 +0100
committerRichard Maw <richard.maw@codethink.co.uk>2014-06-09 15:54:41 +0100
commitf3bf7bbef3927dfb2a2eb12131b7b935659425e6 (patch)
treef46cc17d3c074e1e6997adc7d25a7a2a4b8d9912
parentb6f37209fc277883c983b1602d3a98b4045f6dee (diff)
parent5bbf49ceeaeae07cc8bf165a047f0a4800ecb51a (diff)
downloadmorph-f3bf7bbef3927dfb2a2eb12131b7b935659425e6.tar.gz
Merge branch 'baserock/richardmaw/S11226/yarns-v2'
Reviewed-by: Sam Thursfield and Richard Ipsum
-rwxr-xr-xmorphlib/exts/initramfs.write4
-rw-r--r--yarns/deployment.yarn83
-rw-r--r--yarns/implementations.yarn43
3 files changed, 128 insertions, 2 deletions
diff --git a/morphlib/exts/initramfs.write b/morphlib/exts/initramfs.write
index 815772f2..f8af6d84 100755
--- a/morphlib/exts/initramfs.write
+++ b/morphlib/exts/initramfs.write
@@ -23,5 +23,5 @@ INITRAMFS_PATH="$2"
(cd "$ROOTDIR" &&
find . -print0 |
- cpio -0 -H newc -o |
- gzip -c) >"$INITRAMFS_PATH"
+ cpio -0 -H newc -o) |
+ gzip -c | install -D -m644 /dev/stdin "$INITRAMFS_PATH"
diff --git a/yarns/deployment.yarn b/yarns/deployment.yarn
index fc21b826..67aecce2 100644
--- a/yarns/deployment.yarn
+++ b/yarns/deployment.yarn
@@ -102,3 +102,86 @@ deployed system contains the other. Since the baserock directory is in
every system, we can check for that.
AND tarball test.tar contains var/lib/sysroots/test-system/baserock
+
+Initramfs deployments
+=====================
+
+There's a few ways of creating an initramfs. We could:
+1. Build a sysroot and:
+ 1. Have a chunk turn that into a cpio archive, written into /boot.
+ 2. Embed it in the Linux kernel image, having the initramfs as part
+ of the BSP.
+2. Deploy an existing system as a cpio archive
+ 1. As a stand-alone system, without a rootfs
+ 2. Nested inside another system
+
+1.1 and 1.2 require system engineering work, so won't be mentioned here.
+
+ SCENARIO deploying a system with an initramfs
+ ASSUMING there is space for 5 512M disk images
+ GIVEN a workspace
+ AND a git server
+ WHEN the user checks out the system branch called master
+ GIVEN a cluster called C in system branch master
+ AND a system in cluster C in branch master called S
+
+2.2 needs a nested system that is deployed with the initramfs write
+extension.
+
+ GIVEN a subsystem in cluster C in branch master called S.I
+ AND subsystem S.I in cluster C in branch master builds test-system
+ AND subsystem S.I in cluster C in branch master has deployment type: initramfs
+
+The nested system needs to be placed somewhere in the parent. The
+traditional place for an initramfs is `/boot`.
+
+ AND subsystem S.I in cluster C in branch master has deployment location: boot/initramfs.gz
+
+1.1 and 2.2 need the write extension to configure the boot-loader to
+use the produced initramfs. Only write extensions that involve creating a disk image care, so we'll use `rawdisk.write`.
+
+ GIVEN system S in cluster C in branch master builds test-system
+ AND system S in cluster C in branch master has deployment type: rawdisk
+ AND system S in cluster C in branch master has deployment location: test.img
+ AND system S in cluster C in branch master has deployment variable: DISK_SIZE=512M
+
+Initramfs support is triggered by the `INITRAMFS_PATH` variable. It could have been made automatic, triggering the behaviour if `/boot/initramfs.gz` exists, but:
+
+1. There are a bunch of possible names, some of which imply different formats.
+2. If we decide on one specific name, how do we pick.
+3. If we allow multiple possible names, how do we handle multiple being possible.
+4. We may need to pick a non-standard name: e.g. We have a deployment
+ where the system loads a kernel and initramfs from a disk, then boots
+ the target in KVM, so the bootloader we want to use for the guest is
+ `initramfs.gz`, while the host's initramfs is `hyp-initramfs.gz`.
+5. We may have the initramfs come from a chunk the system built, but
+ for speed, we want this particular deployment not to use an initramfs,
+ even though we have a generic image that may support one.
+
+For all these reasons, despite there being redundancy in some cases,
+we're going to set `INITRAMFS_PATH` to the same as the nested deployment's
+location.
+
+ GIVEN system S in cluster C in branch master has deployment variable: INITRAMFS_PATH=boot/initramfs.gz
+
+Fully testing that the system is bootable requires a lot more time,
+infrastructure and dependencies, so we're just going to build it and
+inspect the result of the deployment.
+
+ WHEN the user builds the system test-system in branch master
+ AND the user attempts to deploy the cluster C in branch master
+ THEN morph succeeded
+ AND file workspace/master/test/morphs/test.img exists
+
+If the initramfs write extension works, the rootfs image should contain
+`boot/initramfs.gz`.
+
+ WHEN disk image workspace/master/test/morphs/test.img is mounted at mnt
+ THEN file mnt/systems/default/run/boot/initramfs.gz exists
+
+If the `rawdisk` write extension worked, then the bootloader config file
+will mention the initramfs, and the UUID of the disk.
+
+ AND file mnt/extlinux.conf matches initramfs
+ AND file mnt/extlinux.conf matches root=UUID=
+ FINALLY mnt is unmounted
diff --git a/yarns/implementations.yarn b/yarns/implementations.yarn
index 0635af72..66d47bfd 100644
--- a/yarns/implementations.yarn
+++ b/yarns/implementations.yarn
@@ -724,6 +724,49 @@ Check attributes of a file on the filesystem
IMPLEMENTS THEN file (\S+) is empty
stat -c %s "$DATADIR/$MATCH_1" | grep -Fx 0
+ IMPLEMENTS THEN file (\S+) matches (.*)
+ grep -q "$MATCH_2" "$DATADIR/$MATCH_1"
+
+Disk image manipulation
+-----------------------
+
+We need to test disk images we create. In the absence of tools for
+inspecting disks without mounting them, we need commands to handle this.
+
+ IMPLEMENTS WHEN disk image (\S+) is mounted at (.*)
+ mkdir -p "$DATADIR/$MATCH_2"
+ mount -o loop "$DATADIR/$MATCH_1" "$DATADIR/$MATCH_2"
+
+ IMPLEMENTS FINALLY (\S+) is unmounted
+ umount -d "$DATADIR/$MATCH_1"
+
+We may not have enough space to run some tests that have disk images.
+
+ IMPLEMENTS ASSUMING there is space for (\d+) (\d+)(\S*) disk images?
+ # Count is included as an argument, so that if we change the disk
+ # image sizes then it's more obvious when we need to change the
+ # assumption, since it's the same value.
+ count="$MATCH_1"
+ case "$MATCH_3" in
+ '')
+ size="$MATCH_2"
+ ;;
+ M)
+ size=$(expr "$MATCH_2" '*' 1024 '*' 1024 )
+ ;;
+ G)
+ size=$(expr "$MATCH_2" '*' 1024 '*' 1024 '*' 1024 )
+ ;;
+ *)
+ echo Unrecognized size suffix: "$MATCH_3" >&2
+ exit 1
+ esac
+ total_image_size="$(expr "$size" '*' "$count" )"
+ blocks="$(stat -f -c %a "$DATADIR")"
+ block_size="$(stat -f -c %S "$DATADIR")"
+ disk_free=$(expr "$blocks" '*' "$block_size" )
+ test "$disk_free" -gt "$total_image_size"
+
Check contents of a file
------------------------