From 3b640e997dcd66d1f5b4495cfa1a74f147ac4fa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= Date: Sun, 30 Sep 2018 12:47:57 +0200 Subject: [PATCH] GUID for gdisk: have Guix inject the hash of the inputs into the source tree --- .gitignore | 3 +++ Makefile | 2 ++ Makefile.example-os | 42 ++++++++++++++++++++++++++++++++++++------ guix.scm | 15 +++++++++++++++ 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index c65b28e..9fb75a2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ /build/check_makefile /build/check_makefile_targets /build/check_makefile_w_arnings +/build/gpt_disk_guid +/build/gpt_partition_guid +/build/input-hash /build/iso_files/boot/iso_boot.sys /build/iso_files/os.zip /build/makefile_built_directories diff --git a/Makefile b/Makefile index d8a6a06..dc038b4 100644 --- a/Makefile +++ b/Makefile @@ -70,6 +70,8 @@ ${bld}/makefile_w_arnings: | $${@D} ${built_files}: | $${@D} ${bld}/makefile_w_arnings: ${Makefiles} + test -e input-hash || printf "\033[1;31mWARNING: input-hash should be created by guix build.\033[m\n" + @unset MAKEFLAGS MAKELEVEL MAKE_TERMERR MFLAGS; \ make -n --warn-undefined-variables \ OS_FILENAME=${OS_FILENAME} \ diff --git a/Makefile.example-os b/Makefile.example-os index da255b5..da2ae2e 100644 --- a/Makefile.example-os +++ b/Makefile.example-os @@ -51,6 +51,9 @@ built_files += ${os_filename} \ ${bld}/os.hex_with_offsets \ ${bld}/iso_files/os.zip \ ${bld}/iso_files/boot/iso_boot.sys \ + ${bld}/input-hash \ + ${bld}/gpt_disk_guid \ + ${bld}/gpt_partition_guid \ ${more_offset_dec} \ ${more_offset_hex} \ @@ -221,12 +224,39 @@ ${bld}/os.zip.adjusted: ${bld}/os.zip ${dep_bytes_zip_start} ${bld}/check_makefi gdisk_pipe_commands_slowly=while read str; do echo "$$str"; printf "\033[1;33m%s\033[m\n" "$$str" >&2; sleep 0.01; done -commit_hash_as_guid=$$((git log -1 --pretty=format:%H || echo 0000000000000000000000000000000000000000) | sed -e 's/^\(.\{8\}\)\(.\{4\}\)\(.\{4\}\)\(.\{4\}\)\(.\{12\}\).*$$/\1-\2-\3-\4-\5/' | tr '[:lower:]' '[:upper:]') -git_dirty=test -n "$$(git diff --shortstat)" -gpt_disk_guid=${commit_hash_as_guid}$$(if $$git_dirty; then printf '0'; else printf '2'; fi) -gpt_partition_guid=${commit_hash_as_guid}$$(if $$git_dirty; then printf '1'; else printf '3'; fi) +.PHONY: force-input-hash +${bld}/input-hash: force-input-hash ${bld}/check_makefile +# input-hash must be a 33 (or more) character-long hexadecimal hash of the +# inputs. It can be used to generate UUIDs for the generated disk image, for +# example. +# +# We use `git log -1 --pretty=format:%H' to obtain the hash of the current +# commit as a fallback, but we do not have access to that information +# within a Guix build environment. + h=$$( cat input-hash \ + || git log -1 --pretty=format:%H \ + || echo 0000000000000000000000000000000000000000 \ + ); \ + if test "$$h" != "$$(cat $@ || echo '')"; then \ + echo "$$h" > "$@"; \ + fi + +# The last digit is 1, to distinguish the disk GUID from the partition GUID +${bld}/gpt_disk_guid: ${bld}/input-hash ${bld}/check_makefile + cat $< \ + | sed -e 's/^\(.\{8\}\)\(.\{4\}\)\(.\{4\}\)\(.\{4\}\)\(.\{11\}\).*$$/\1-\2-\3-\4-\51/' \ + | tr '[:lower:]' '[:upper:]' \ + > $@ + +# The last digit is 2, to distinguish the disk GUID from the partition GUID +${bld}/gpt_partition_guid: ${bld}/input-hash ${bld}/check_makefile + cat $< \ + | sed -e 's/^\(.\{8\}\)\(.\{4\}\)\(.\{4\}\)\(.\{4\}\)\(.\{11\}\).*$$/\1-\2-\3-\4-\52/' \ + | tr '[:lower:]' '[:upper:]' \ + > $@ ${os_filename}: ${bld}/os.32k ${bld}/os.iso ${bld}/os.fat12 ${bld}/os.zip.adjusted \ + ${bld}/gpt_disk_guid ${bld}/gpt_partition_guid \ ${dep_bytes_header_32k_start} \ ${dep_bytes_header_32k_size} \ ${dep_bytes_fat12_start} \ @@ -266,8 +296,8 @@ ${os_filename}: ${bld}/os.32k ${bld}/os.iso ${bld}/os.fat12 ${bld}/os.zip.adjust printf "1\nN\n"; \ printf "01\nY\nN\n"; \ printf "x\n"; \ - printf "g\n${gpt_disk_guid}\n"; \ - printf "c\n${gpt_partition_guid}\n"; \ + printf "g\n$$(cat ${bld}/gpt_disk_guid)\n"; \ + printf "c\n$$(cat ${bld}/gpt_partition_guid)\n"; \ printf "p\no\nw\nY\n") | ${gdisk_pipe_commands_slowly} | gdisk $@ # Inject MS-DOS newlines (CR+LF) and comments (":: ") in the GUID field of unused partition table entries, # so that the part that is to be skipped by MS-DOS does not form a line longer than the MS-DOS maximum diff --git a/guix.scm b/guix.scm index 898b5de..8decc99 100644 --- a/guix.scm +++ b/guix.scm @@ -25,6 +25,8 @@ (ice-9 popen) (ice-9 rdelim) (gnu packages version-control) + (gnu packages vim) + (gnu packages package-management) (gnu packages assembly) (gnu packages base) (gnu packages mtools) @@ -75,6 +77,17 @@ `(#:phases (modify-phases %standard-phases ;; unpack ;; this phase is enabled + (add-after 'unpack 'compute-input-hash + (lambda* (#:key inputs #:allow-other-keys) + (invoke "sh" "-c" + (string-append + " guix hash -rx . --format=base32" + " | tr '[:lower:]' '[:upper:]'" + " | head -c 48" + " | base32 -d" + " | xxd -ps" + " | head -c 60" + " > input-hash")))) ;; patch-source-shebangs ;; this phase is enabled (add-after 'patch-source-shebangs 'make-clean (lambda* (#:key inputs #:allow-other-keys) @@ -99,6 +112,8 @@ (list "in-guix" ,makefile-commit-timestamp))) (native-inputs `(("git" ,git) + ("xxd" ,xxd) + ("guix" ,guix) ("nasm" ,nasm) ("which" ,which) ("mtools" ,mtools)