diff options
| author | Ludovic Courtès <ludo@gnu.org> | 2019-12-11 23:54:35 +0100 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2020-01-05 11:40:02 +0100 |
| commit | 3bccc5edacbef0204ca1d261da9621a044906028 (patch) | |
| tree | e651aa4cf07c353762868a882c6d3465df9dd3c3 /gnu/system | |
| parent | b446a604b491cf66cc818d50fa23461a37dc94a2 (diff) | |
system: bootstrap: Compute and print the result's hash.wip-system-bootstrap
* gnu/packages/commencement.scm (%bootstrap-guile+guild): Make public.
[properties]: New field.
* gnu/system/bootstrap.scm (hash-script): New procedure.
(bootstrapping-os): Wrap OBJ in 'hash-script'.
Diffstat (limited to 'gnu/system')
| -rw-r--r-- | gnu/system/bootstrap.scm | 83 |
1 files changed, 78 insertions, 5 deletions
diff --git a/gnu/system/bootstrap.scm b/gnu/system/bootstrap.scm index c6eb10616e8..19f309d5060 100644 --- a/gnu/system/bootstrap.scm +++ b/gnu/system/bootstrap.scm | |||
| @@ -21,7 +21,13 @@ | |||
| 21 | #:use-module (guix modules) | 21 | #:use-module (guix modules) |
| 22 | #:use-module ((guix packages) #:select (default-guile)) | 22 | #:use-module ((guix packages) #:select (default-guile)) |
| 23 | #:use-module ((guix self) #:select (make-config.scm)) | 23 | #:use-module ((guix self) #:select (make-config.scm)) |
| 24 | #:use-module (gnu packages bootstrap) | 24 | #:use-module ((guix utils) |
| 25 | #:select (version-major+minor substitute-keyword-arguments)) | ||
| 26 | #:use-module (guix packages) | ||
| 27 | #:use-module (guix build-system trivial) | ||
| 28 | #:use-module (gnu packages commencement) | ||
| 29 | #:use-module (gnu packages guile) | ||
| 30 | #:use-module (gnu packages guile-xyz) | ||
| 25 | #:use-module (gnu system) | 31 | #:use-module (gnu system) |
| 26 | #:use-module (gnu system shadow) | 32 | #:use-module (gnu system shadow) |
| 27 | #:use-module (gnu system file-systems) | 33 | #:use-module (gnu system file-systems) |
| @@ -44,6 +50,73 @@ | |||
| 44 | ;;; | 50 | ;;; |
| 45 | ;;; Code: | 51 | ;;; Code: |
| 46 | 52 | ||
| 53 | (define* (hash-script obj #:key (guile (default-guile))) | ||
| 54 | "Return a derivation that computes the SHA256 hash of OBJ, using Guile and | ||
| 55 | only pure Guile code." | ||
| 56 | (define hashing | ||
| 57 | (package | ||
| 58 | (inherit guile-hashing) | ||
| 59 | (arguments | ||
| 60 | `(#:guile ,guile | ||
| 61 | ,@(package-arguments guile-hashing))) | ||
| 62 | (native-inputs `(("guile" ,guile))))) | ||
| 63 | |||
| 64 | (define build | ||
| 65 | ;; Compute and display the SHA256 of OBJ. Do that in pure Scheme: it's | ||
| 66 | ;; slower, but removes the need for a full-blown C compiler and GNU | ||
| 67 | ;; userland to get libgcrypt, etc. | ||
| 68 | (with-extensions (list hashing) | ||
| 69 | (with-imported-modules (source-module-closure | ||
| 70 | '((guix serialization))) | ||
| 71 | #~(begin | ||
| 72 | (use-modules (hashing sha-2) | ||
| 73 | (guix serialization) | ||
| 74 | (rnrs io ports) | ||
| 75 | (rnrs bytevectors) | ||
| 76 | (ice-9 match)) | ||
| 77 | |||
| 78 | (define (port-sha256 port) | ||
| 79 | ;; Return the SHA256 of the data read from PORT. | ||
| 80 | (define bv (make-bytevector 65536)) | ||
| 81 | (define hash (make-sha-256)) | ||
| 82 | |||
| 83 | (let loop () | ||
| 84 | (match (get-bytevector-n! port bv 0 | ||
| 85 | (bytevector-length bv)) | ||
| 86 | ((? eof-object?) | ||
| 87 | (sha-256-finish! hash) | ||
| 88 | hash) | ||
| 89 | (n | ||
| 90 | (sha-256-update! hash bv 0 n) | ||
| 91 | (loop))))) | ||
| 92 | |||
| 93 | (define (file-sha256 file) | ||
| 94 | ;; Return the SHA256 of FILE. | ||
| 95 | (call-with-input-file file port-sha256)) | ||
| 96 | |||
| 97 | ;; Serialize OBJ as a nar. XXX: We should avoid writing to disk | ||
| 98 | ;; as this might be a tmpfs. | ||
| 99 | (call-with-output-file "nar" | ||
| 100 | (lambda (port) | ||
| 101 | (write-file #$obj port))) | ||
| 102 | |||
| 103 | ;; Compute, display, and store the hash of OBJ. | ||
| 104 | (let ((hash (file-sha256 "nar"))) | ||
| 105 | (call-with-output-file #$output | ||
| 106 | (lambda (result) | ||
| 107 | (for-each (lambda (port) | ||
| 108 | (format port "~a\t~a~%" | ||
| 109 | (sha-256->string hash) | ||
| 110 | #$obj)) | ||
| 111 | (list (current-output-port) | ||
| 112 | result))))))))) | ||
| 113 | |||
| 114 | (computed-file "build-result-hashes" build | ||
| 115 | #:guile guile | ||
| 116 | #:options | ||
| 117 | `(#:effective-version | ||
| 118 | ,(version-major+minor (package-version guile))))) | ||
| 119 | |||
| 47 | (define* (build-script obj #:key (guile (default-guile))) | 120 | (define* (build-script obj #:key (guile (default-guile))) |
| 48 | "Return a build script that builds OBJ, an arbitrary lowerable object such | 121 | "Return a build script that builds OBJ, an arbitrary lowerable object such |
| 49 | as a package, and all its dependencies. The script essentially unrolls the | 122 | as a package, and all its dependencies. The script essentially unrolls the |
| @@ -143,7 +216,6 @@ build loop normally performed by 'guix-daemon'." | |||
| 143 | (format #t "~%Congratulations!~%") | 216 | (format #t "~%Congratulations!~%") |
| 144 | (sleep 3600))) | 217 | (sleep 3600))) |
| 145 | port) | 218 | port) |
| 146 | ;; TODO: Print a hash or something at the end? | ||
| 147 | (chmod port #o555)))))) | 219 | (chmod port #o555)))))) |
| 148 | 220 | ||
| 149 | (computed-file "build.scm" emit-script | 221 | (computed-file "build.scm" emit-script |
| @@ -181,9 +253,10 @@ dependencies, from scratch, as it boots." | |||
| 181 | ;; includes all the source code (tarballs) necessary to build them. | 253 | ;; includes all the source code (tarballs) necessary to build them. |
| 182 | (initrd (lambda (fs . rest) | 254 | (initrd (lambda (fs . rest) |
| 183 | (expression->initrd | 255 | (expression->initrd |
| 184 | #~(execl #$(build-script obj #:guile %bootstrap-guile) | 256 | (let ((obj (hash-script obj #:guile %bootstrap-guile+guild))) |
| 185 | "build") | 257 | #~(execl #$(build-script obj #:guile %bootstrap-guile+guild) |
| 186 | #:guile %bootstrap-guile))))) | 258 | "build")) |
| 259 | #:guile %bootstrap-guile+guild))))) | ||
| 187 | 260 | ||
| 188 | ;; This operating system builds MES-BOOT from scratch. That currently | 261 | ;; This operating system builds MES-BOOT from scratch. That currently |
| 189 | ;; requires ~5 GiB of RAM. TODO: Should we mount a root file system on a hard | 262 | ;; requires ~5 GiB of RAM. TODO: Should we mount a root file system on a hard |
