diff options
| author | Rutherther <rutherther@ditigal.xyz> | 2025-12-16 12:26:57 +0100 |
|---|---|---|
| committer | Rutherther <rutherther@ditigal.xyz> | 2025-12-23 09:16:05 +0100 |
| commit | 2d4ed08662714ea46cfe0b41ca195d1ef845fd1b (patch) | |
| tree | 3b352c59a9dc01a178db365783f891a63eb71892 /etc/teams/release/artifacts-manifest.scm | |
| parent | ab63e29e90aba4f10d477e76587d687a7bb6a27d (diff) | |
etc: release: Switch to Guile declaration of artifacts.v1.5.0rc1
This is a rewrite of the bash commands for generation of guix binary
tarballs and system images to Guile. I am expecting this will help us
significantly with getting the same derivations locally and from Cuirass,
instead of relying on images/tarball job specifications and trying to tweak
it locally to have the same ones.
Implements: #4347, #4348.
* etc/teams/release/artifacts-manifest.scm: Make a manifest with
release artifacts for all supported systems.
* etc/teams/release/artifacts.scm: Collect artifacts for
all supported systems into a union with proper names for
the release artifacts.
* Makefile.am (release): Use time-machine instead of pre-inst-env; Switch to
building new artifacts.scm
Change-Id: I71a6a27e6f315dd31b91c49e71dff2d09695c0dc
Signed-off-by: Rutherther <rutherther@ditigal.xyz>
Diffstat (limited to 'etc/teams/release/artifacts-manifest.scm')
| -rw-r--r-- | etc/teams/release/artifacts-manifest.scm | 412 |
1 files changed, 412 insertions, 0 deletions
diff --git a/etc/teams/release/artifacts-manifest.scm b/etc/teams/release/artifacts-manifest.scm new file mode 100644 index 00000000000..7b8c942c795 --- /dev/null +++ b/etc/teams/release/artifacts-manifest.scm | |||
| @@ -0,0 +1,412 @@ | |||
| 1 | ;;; GNU Guix --- Functional package management for GNU | ||
| 2 | ;;; | ||
| 3 | ;;; This file is part of GNU Guix. | ||
| 4 | ;;; | ||
| 5 | ;;; GNU Guix is free software; you can redistribute it and/or modify it | ||
| 6 | ;;; under the terms of the GNU General Public License as published by | ||
| 7 | ;;; the Free Software Foundation; either version 3 of the License, or (at | ||
| 8 | ;;; your option) any later version. | ||
| 9 | ;;; | ||
| 10 | ;;; GNU Guix is distributed in the hope that it will be useful, but | ||
| 11 | ;;; WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | ;;; GNU General Public License for more details. | ||
| 14 | ;;; | ||
| 15 | ;;; You should have received a copy of the GNU General Public License | ||
| 16 | ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | |||
| 18 | ;;; This manifest returns build artfacts for all supported systems. This can be | ||
| 19 | ;;; controlled by SUPPORTED_SYSTEMS environment variable. For the list of | ||
| 20 | ;;; artifacts produced, see artifacts-for-system and the `<thing>-for-system?` | ||
| 21 | ;;; procedures. NOTE: the --system argument does not change the system for which | ||
| 22 | ;;; the resulting package is built. They return different definitions of the | ||
| 23 | ;;; images. To change the system, pass different SUPPORTED_SYSTEMS. | ||
| 24 | |||
| 25 | (use-modules (gnu compression) | ||
| 26 | (gnu image) | ||
| 27 | (gnu packages graphviz) | ||
| 28 | (gnu packages imagemagick) | ||
| 29 | (gnu packages package-management) | ||
| 30 | (gnu packages perl) | ||
| 31 | (gnu services) | ||
| 32 | (gnu system image) | ||
| 33 | (gnu system install) | ||
| 34 | (gnu system) | ||
| 35 | (guix build-system gnu) | ||
| 36 | (guix build-system trivial) | ||
| 37 | (guix channels) | ||
| 38 | (guix gexp) | ||
| 39 | (guix git) | ||
| 40 | (guix grafts) | ||
| 41 | (guix memoization) | ||
| 42 | (guix monads) | ||
| 43 | (guix packages) | ||
| 44 | (guix profiles) | ||
| 45 | (guix records) | ||
| 46 | (guix scripts pack) | ||
| 47 | (guix store) | ||
| 48 | (guix ui) | ||
| 49 | (guix utils) | ||
| 50 | (ice-9 format) | ||
| 51 | (ice-9 match) | ||
| 52 | (srfi srfi-9) | ||
| 53 | (srfi srfi-26) | ||
| 54 | (srfi srfi-35)) | ||
| 55 | |||
| 56 | ;; For easier testing, use (snapshot) guix package from (gnu packages | ||
| 57 | ;; package-management). Otherwise, the package is updated to current commit and | ||
| 58 | ;; might not be substitutable, leading to longer build times. | ||
| 59 | (define %use-snapshot-package? | ||
| 60 | (string=? (or (getenv "GUIX_USE_SNAPSHOT_PACKAGE") "no") "yes")) | ||
| 61 | |||
| 62 | (define (%guix-version) | ||
| 63 | ;; NOTE: while package-version guix is not correct in general, | ||
| 64 | ;; it is correct for the release itself. At that time, the | ||
| 65 | ;; guix package is updated to vX.Y.Z and it's the version | ||
| 66 | ;; we want to use. | ||
| 67 | (package-version guix)) | ||
| 68 | |||
| 69 | (define (%vm-image-path) | ||
| 70 | (search-path %load-path "gnu/system/examples/vm-image.tmpl")) | ||
| 71 | |||
| 72 | (define (%vm-image-efi-path) | ||
| 73 | (search-path %load-path "gnu/system/examples/vm-image-efi.tmpl")) | ||
| 74 | |||
| 75 | ;; monadic record and gexp-compiler | ||
| 76 | ;; taken from Inria | ||
| 77 | ;; https://gitlab.inria.fr/numpex-pc5/wp3/guix-images/-/blob/17bf4585abc2d637faa5d339436e778b7c9fb1ce/modules/guix-hpc/packs.scm | ||
| 78 | |||
| 79 | ;; XXX: The <monadic> hack below will hopefully become unnecessary once the | ||
| 80 | ;; (guix scripts pack) interface switches to declarative style--i.e., | ||
| 81 | ;; file-like objects. | ||
| 82 | |||
| 83 | (define-record-type <monadic> | ||
| 84 | (monadic->declarative mvalue) | ||
| 85 | monadic? | ||
| 86 | (mvalue monadic-value)) | ||
| 87 | |||
| 88 | (define-gexp-compiler (monadic-compiler (monadic <monadic>) system target) | ||
| 89 | (monadic-value monadic)) | ||
| 90 | |||
| 91 | ;; The tarball should be the same for every system. | ||
| 92 | ;; Still, we need to decide what system to build it | ||
| 93 | ;; for, so use the one that CI has most resources for. | ||
| 94 | (define (source-tarball-for-system? system) | ||
| 95 | (member system | ||
| 96 | '("x86_64-linux"))) | ||
| 97 | |||
| 98 | (define (iso-for-system? system) | ||
| 99 | (member system | ||
| 100 | '("x86_64-linux" "i686-linux" "aarch64-linux"))) | ||
| 101 | |||
| 102 | (define (qcow2-for-system? system) | ||
| 103 | (member system | ||
| 104 | '("x86_64-linux" "aarch64-linux"))) | ||
| 105 | |||
| 106 | (define* (qcow2-gpt-for-system? system) | ||
| 107 | (string=? system "aarch64-linux")) | ||
| 108 | |||
| 109 | (define (copy-/etc/config.scm config) | ||
| 110 | "Copy the configuration.scm of the operating system to /etc/config.scm, for | ||
| 111 | user's convenience. The file has to be writable, not a link to the store, so | ||
| 112 | etc-service-type can't be used here. CONFIG is a pair of strings, (FROM . TO). | ||
| 113 | The config will be copied from FROM to TO." | ||
| 114 | (match config | ||
| 115 | ((from . to) | ||
| 116 | (with-imported-modules '((guix build utils)) | ||
| 117 | #~(begin | ||
| 118 | (use-modules (guix build utils)) | ||
| 119 | (when (not (file-exists? #$to)) | ||
| 120 | (copy-file #$from #$to) | ||
| 121 | (make-file-writable #$to))))) | ||
| 122 | (_ (raise | ||
| 123 | (formatted-message-string | ||
| 124 | (G_ "unexpected config parameter, should be pair of strings: ~a" | ||
| 125 | config)))))) | ||
| 126 | |||
| 127 | (define copy-/etc/config.scm-service-type | ||
| 128 | (service-type (name 'copy-/etc/config.scm) | ||
| 129 | (description | ||
| 130 | "Copy the system configuration file to /etc/config.scm.") | ||
| 131 | (extensions (list (service-extension activation-service-type | ||
| 132 | copy-/etc/config.scm))) | ||
| 133 | (default-value (cons "/run/current-system/configuration.scm" | ||
| 134 | "/etc/config.scm")))) | ||
| 135 | |||
| 136 | (define (operating-system-with-/etc/config.scm os) | ||
| 137 | "Copy the system configuration file to writable /etc/config.scm on first boot." | ||
| 138 | (operating-system | ||
| 139 | (inherit os) | ||
| 140 | (services (cons (service copy-/etc/config.scm-service-type) | ||
| 141 | (operating-system-user-services os))))) | ||
| 142 | |||
| 143 | (define (simple-provenance-entry config-file) | ||
| 144 | "Return system entries describing the operating system config, provided | ||
| 145 | through CONFIG-FILE." | ||
| 146 | (mbegin %store-monad | ||
| 147 | (return `(("configuration.scm" | ||
| 148 | ,(local-file (assume-valid-file-name config-file) | ||
| 149 | "configuration.scm")))))) | ||
| 150 | |||
| 151 | ;; This is mostly taken from provenance-service-type from (gnu services), | ||
| 152 | ;; but it provides only configuration.scm, not channels.scm. This is | ||
| 153 | ;; to get the same derivations for both Cuirass and local builds. | ||
| 154 | ;; In the future, provenance-service-type could be adapted to support | ||
| 155 | ;; this use case as well. | ||
| 156 | (define simple-provenance-service-type | ||
| 157 | (service-type (name 'provenance) | ||
| 158 | (extensions | ||
| 159 | (list (service-extension system-service-type | ||
| 160 | simple-provenance-entry))) | ||
| 161 | (default-value #f) ;the OS config file | ||
| 162 | (description | ||
| 163 | "Store configuration.scm of the system in the system | ||
| 164 | itself."))) | ||
| 165 | |||
| 166 | (define* (operating-system-with-simple-provenance | ||
| 167 | os | ||
| 168 | #:optional | ||
| 169 | (config-file | ||
| 170 | (operating-system-configuration-file | ||
| 171 | os))) | ||
| 172 | "Return a variant of OS that stores its CONFIG-FILE. This is similar to | ||
| 173 | `operating-system-with-provenance`, but it does copy only the | ||
| 174 | configuration.scm." | ||
| 175 | (operating-system | ||
| 176 | (inherit os) | ||
| 177 | (services (cons (service simple-provenance-service-type config-file) | ||
| 178 | (operating-system-user-services os))))) | ||
| 179 | |||
| 180 | (define (guix-package-commit guix) | ||
| 181 | ;; Extract the commit of the GUIX package. | ||
| 182 | (match (package-source guix) | ||
| 183 | ((? channel? source) | ||
| 184 | (channel-commit source)) | ||
| 185 | (_ | ||
| 186 | (apply (lambda* (#:key commit #:allow-other-keys) commit) | ||
| 187 | (package-arguments guix))))) | ||
| 188 | |||
| 189 | ;; NOTE: Normally, we would use (current-guix), along with url | ||
| 190 | ;; overriden to the upstream repository to not leak our local checkout. | ||
| 191 | ;; But currently, the (current-guix) derivation has to be computed through | ||
| 192 | ;; QEMU for systems other than your host system. This takes a lot of time, | ||
| 193 | ;; it takes at least half an hour to get the derivations. | ||
| 194 | (define (guix-package/with-commit guix commit) | ||
| 195 | "Use the guix from (gnu packages package-management), | ||
| 196 | but override its commit to the specified version. Make sure | ||
| 197 | to also override the channel commit to have the correct | ||
| 198 | provenance." | ||
| 199 | (let ((scm-version (car (string-split (package-version guix) #\-)))) | ||
| 200 | (package | ||
| 201 | (inherit guix) | ||
| 202 | (version (string-append scm-version "." (string-take commit 7))) | ||
| 203 | (source (git-checkout | ||
| 204 | (url (channel-url %default-guix-channel)) | ||
| 205 | (commit commit))) | ||
| 206 | (arguments | ||
| 207 | (substitute-keyword-arguments (package-arguments guix) | ||
| 208 | ((#:configure-flags flags '()) | ||
| 209 | #~(cons* | ||
| 210 | (string-append "--with-channel-commit=" #$commit) | ||
| 211 | (filter (lambda (flag) | ||
| 212 | (not (string-prefix? "--with-channel-commit=" flag))) | ||
| 213 | #$flags)))))))) | ||
| 214 | |||
| 215 | (define guix-for-images | ||
| 216 | (mlambda (system) | ||
| 217 | (cond | ||
| 218 | ;; For testing purposes, use the guix package directly. | ||
| 219 | (%use-snapshot-package? guix) | ||
| 220 | ;; Normally, update the guix package to current commit. | ||
| 221 | (else | ||
| 222 | (guix-package/with-commit guix (guix-package-commit (current-guix))))))) | ||
| 223 | |||
| 224 | (define %binary-tarball-compression "xz") | ||
| 225 | |||
| 226 | ;; Like guix pack -C xz -s --localstatedir --profile-name=current-guix guix | ||
| 227 | (define* (binary-tarball-for-system system #:key (extra-packages '())) | ||
| 228 | (let* ((base-name (string-append "guix-binary-" (%guix-version) "." system)) | ||
| 229 | (manifest (packages->manifest (cons* guix extra-packages))) | ||
| 230 | (profile (profile (content manifest))) | ||
| 231 | (inputs `(("profile" ,profile))) | ||
| 232 | (compression %binary-tarball-compression)) | ||
| 233 | (manifest-entry | ||
| 234 | (name (string-append base-name ".tar." compression)) | ||
| 235 | (version (%guix-version)) | ||
| 236 | (item (monadic->declarative | ||
| 237 | (self-contained-tarball | ||
| 238 | base-name profile | ||
| 239 | #:profile-name "current-guix" | ||
| 240 | #:compressor (lookup-compressor compression) | ||
| 241 | #:localstatedir? #t)))))) | ||
| 242 | |||
| 243 | ;; Like guix system image -t iso9660 \ | ||
| 244 | ;; --label="GUIX_$${system}_$(VERSION)" gnu/system/install.scm | ||
| 245 | (define* (iso-for-system system) | ||
| 246 | (let* ((name (string-append | ||
| 247 | "guix-system-install-" (%guix-version) "." system ".iso")) | ||
| 248 | (base-os (make-installation-os | ||
| 249 | #:grub-displayed-version (%guix-version) | ||
| 250 | #:efi-only? (string=? system "aarch64-linux"))) | ||
| 251 | (base-image (os->image base-os #:type iso-image-type)) | ||
| 252 | (label (string-append "GUIX_" system "_" | ||
| 253 | (if (> (string-length (%guix-version)) 7) | ||
| 254 | (string-take (%guix-version) 7) | ||
| 255 | (%guix-version))))) | ||
| 256 | (manifest-entry | ||
| 257 | (name name) | ||
| 258 | (version (%guix-version)) | ||
| 259 | (item (system-image | ||
| 260 | (image-with-label | ||
| 261 | (image | ||
| 262 | (inherit base-image) | ||
| 263 | (name (string->symbol name))) | ||
| 264 | label)))))) | ||
| 265 | |||
| 266 | ;; Like guix system image -t qcow2 gnu/system/examples/vm-image.tmpl | ||
| 267 | (define* (qcow2-for-system system) | ||
| 268 | (let* ((name (string-append | ||
| 269 | "guix-system-vm-image-" (%guix-version) "." system ".qcow2")) | ||
| 270 | (base-os-path | ||
| 271 | (if (qcow2-gpt-for-system? system) | ||
| 272 | (%vm-image-efi-path) | ||
| 273 | (%vm-image-path))) | ||
| 274 | (target-image-type | ||
| 275 | (if (qcow2-gpt-for-system? system) | ||
| 276 | qcow2-gpt-image-type | ||
| 277 | qcow2-image-type)) | ||
| 278 | (base-os | ||
| 279 | (operating-system-with-/etc/config.scm | ||
| 280 | (operating-system-with-simple-provenance | ||
| 281 | (load base-os-path) base-os-path))) | ||
| 282 | (base-image (os->image base-os #:type target-image-type))) | ||
| 283 | (manifest-entry | ||
| 284 | (name name) | ||
| 285 | (version (%guix-version)) | ||
| 286 | (item (system-image | ||
| 287 | (image | ||
| 288 | (inherit base-image) | ||
| 289 | (volatile-root? #f) | ||
| 290 | (name (string->symbol name)))))))) | ||
| 291 | |||
| 292 | (define* (guix-source-tarball) | ||
| 293 | (let ((guix (package | ||
| 294 | (inherit guix) | ||
| 295 | (native-inputs | ||
| 296 | (modify-inputs (package-native-inputs guix) | ||
| 297 | ;; graphviz-minimal -> graphviz | ||
| 298 | (replace "graphviz" graphviz) | ||
| 299 | (append imagemagick) | ||
| 300 | (append perl)))))) | ||
| 301 | (manifest-entry | ||
| 302 | (name (string-append "guix-" (%guix-version) ".tar.gz")) | ||
| 303 | (version (package-version guix)) | ||
| 304 | (item (dist-package | ||
| 305 | guix | ||
| 306 | ;; Guix is built from git source, not from tarball. | ||
| 307 | ;; So it's fine to use its source directly. | ||
| 308 | (package-source guix)))))) | ||
| 309 | |||
| 310 | (define* (manifest-entry-with-parameters system entry | ||
| 311 | #:key | ||
| 312 | (guix-for-images-proc guix-for-images)) | ||
| 313 | (manifest-entry | ||
| 314 | (inherit entry) | ||
| 315 | (item | ||
| 316 | (with-parameters | ||
| 317 | ((%current-system system) | ||
| 318 | (%current-target-system #f) | ||
| 319 | (current-guix-package (guix-for-images-proc system))) | ||
| 320 | (manifest-entry-item entry))))) | ||
| 321 | |||
| 322 | (define* (manifest-with-parameters system manifest | ||
| 323 | #:key | ||
| 324 | (guix-for-images-proc guix-for-images)) | ||
| 325 | "Returns entries in the manifest accompanied with %current-system, | ||
| 326 | %current-target-sytem and current-guix-package parameters." | ||
| 327 | (make-manifest | ||
| 328 | (map (cut manifest-entry-with-parameters system <> | ||
| 329 | #:guix-for-images-proc guix-for-images-proc) | ||
| 330 | (manifest-entries manifest)))) | ||
| 331 | |||
| 332 | (define (artifacts-for-system/nonparameterized system) | ||
| 333 | "Get all artifacts for given system. This will always include the | ||
| 334 | guix-binary tarball and optionally iso and/or qcow2 images." | ||
| 335 | (manifest | ||
| 336 | (append | ||
| 337 | (list | ||
| 338 | (binary-tarball-for-system system)) | ||
| 339 | ;; TODO: After source tarball generation is ready, uncomment. | ||
| 340 | ;; (if (source-tarball-for-system? system) | ||
| 341 | ;; (list (guix-source-tarball)) | ||
| 342 | ;; '()) | ||
| 343 | (if (iso-for-system? system) | ||
| 344 | (list (iso-for-system system)) | ||
| 345 | '()) | ||
| 346 | (if (qcow2-for-system? system) | ||
| 347 | (list (qcow2-for-system system)) | ||
| 348 | '())))) | ||
| 349 | |||
| 350 | (define* (artifacts-for-system system | ||
| 351 | #:key | ||
| 352 | (guix-for-images-proc guix-for-images)) | ||
| 353 | "Collects all artifacts for a system. Gives them the proper %current-system | ||
| 354 | and %current-target-system parameters, so the --system passed on CLI is | ||
| 355 | irrelevant." | ||
| 356 | ;; NOTE: parameterizing current system, because the tarball seems to somehow | ||
| 357 | ;; depend on it early on. I haven't investigated it, but seems like a bug. Could | ||
| 358 | ;; it be the gexp->derivation + monadic->declarative, not passing down the | ||
| 359 | ;; system? Symptom: guix build --system=x86_64 -m artifacts-manifest.scm and | ||
| 360 | ;; guix build --system=i686-linux -m artifacts-manifest.scm gives out different | ||
| 361 | ;; results without the parameterization. | ||
| 362 | (parameterize | ||
| 363 | ((%current-system system) | ||
| 364 | (%current-target-system #f) | ||
| 365 | (current-guix-package (guix-for-images-proc system))) | ||
| 366 | (manifest-with-parameters | ||
| 367 | system | ||
| 368 | (artifacts-for-system/nonparameterized system) | ||
| 369 | #:guix-for-images-proc guix-for-images-proc))) | ||
| 370 | |||
| 371 | (define (manifest->union manifest) | ||
| 372 | "Makes a union that will be a folder with all the entries symlinked. This | ||
| 373 | is different from a profile as it expects the entries are just simple files | ||
| 374 | and symlinks them by their manifest-entry-name." | ||
| 375 | (let ((entries (manifest-entries manifest))) | ||
| 376 | (computed-file | ||
| 377 | "artifacts-union" | ||
| 378 | (with-imported-modules '((guix build union) | ||
| 379 | (guix build utils)) | ||
| 380 | #~(begin | ||
| 381 | (use-modules (guix build utils)) | ||
| 382 | |||
| 383 | (mkdir-p #$output) | ||
| 384 | |||
| 385 | (for-each | ||
| 386 | (lambda* (entry) | ||
| 387 | (symlink (cdr entry) | ||
| 388 | (string-append #$output "/" (car entry)))) | ||
| 389 | (list #$@(map (lambda (entry) | ||
| 390 | #~(cons | ||
| 391 | #$(manifest-entry-name entry) | ||
| 392 | #$(manifest-entry-item entry))) | ||
| 393 | entries)))))))) | ||
| 394 | |||
| 395 | (define %supported-systems | ||
| 396 | (or (and | ||
| 397 | (getenv "SUPPORTED_SYSTEMS") | ||
| 398 | (string-split (getenv "SUPPORTED_SYSTEMS") #\ )) | ||
| 399 | '("x86_64-linux" "i686-linux" | ||
| 400 | "armhf-linux" "aarch64-linux" | ||
| 401 | "powerpc64le-linux" "riscv64-linux"))) | ||
| 402 | |||
| 403 | (define supported-systems-union-manifest | ||
| 404 | (concatenate-manifests | ||
| 405 | (map artifacts-for-system | ||
| 406 | %supported-systems))) | ||
| 407 | |||
| 408 | (when %use-snapshot-package? | ||
| 409 | (warning (G_ "building images using the 'guix' package (snapshot)~%"))) | ||
| 410 | (info (G_ "producing artifacts for the following systems: ~a~%") | ||
| 411 | %supported-systems) | ||
| 412 | supported-systems-union-manifest | ||
