summaryrefslogtreecommitdiff
path: root/gnu/services/virtualization.scm
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2024-01-20 14:55:46 +0100
committerLudovic Courtès <ludo@gnu.org>2024-02-10 23:21:07 +0100
commit9edbb2d7a40c9da7583a1046e39b87633459f656 (patch)
treee056280c955c0ab5e09fa3e3e0d1f6a1000458e3 /gnu/services/virtualization.scm
parent5f34796dc4a615c8fe496bbb9cc18a489bc5d107 (diff)
services: Add ‘virtual-build-machine’ service.
* gnu/services/virtualization.scm (<virtual-build-machine>): New record type. (%build-vm-ssh-port, %build-vm-secrets-port, %x86-64-intel-cpu-models): New variables. (qemu-cpu-model-for-date, virtual-build-machine-ssh-port) (virtual-build-machine-secrets-port): New procedures. (%minimal-vm-syslog-config, %virtual-build-machine-operating-system): New variables. (virtual-build-machine-default-image): (virtual-build-machine-account-name) (virtual-build-machine-accounts) (build-vm-shepherd-services) (initialize-build-vm-substitutes) (build-vm-activation) (virtual-build-machine-offloading-ssh-key) (virtual-build-machine-activation) (virtual-build-machine-secret-root) (check-vm-availability) (build-vm-guix-extension): New procedures. (initialize-hurd-vm-substitutes): Remove. (hurd-vm-activation): Rewrite in terms of ‘build-vm-activation’. * gnu/system/vm.scm (linux-image-startup-command): New procedure. (operating-system-for-image): Export. * gnu/tests/virtualization.scm (run-command-over-ssh): New procedure, extracted from… (run-childhurd-test): … here. [test]: Adjust accordingly. (%build-vm-os): New variable. (run-build-vm-test): New procedure. (%test-build-vm): New variable. * doc/guix.texi (Virtualization Services)[Virtual Build Machines]: New section. (Build Environment Setup): Add cross-reference. Change-Id: I0a47652a583062314020325aedb654f11cb2499c
Diffstat (limited to 'gnu/services/virtualization.scm')
-rw-r--r--gnu/services/virtualization.scm602
1 files changed, 472 insertions, 130 deletions
diff --git a/gnu/services/virtualization.scm b/gnu/services/virtualization.scm
index 5b8566f6009..cc95dfdf223 100644
--- a/gnu/services/virtualization.scm
+++ b/gnu/services/virtualization.scm
@@ -1,6 +1,6 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2017 Ryan Moe <ryan.moe@gmail.com> 2;;; Copyright © 2017 Ryan Moe <ryan.moe@gmail.com>
3;;; Copyright © 2018, 2020-2023 Ludovic Courtès <ludo@gnu.org> 3;;; Copyright © 2018, 2020-2024 Ludovic Courtès <ludo@gnu.org>
4;;; Copyright © 2020, 2021, 2023 Janneke Nieuwenhuizen <janneke@gnu.org> 4;;; Copyright © 2020, 2021, 2023 Janneke Nieuwenhuizen <janneke@gnu.org>
5;;; Copyright © 2021 Timotej Lazar <timotej.lazar@araneo.si> 5;;; Copyright © 2021 Timotej Lazar <timotej.lazar@araneo.si>
6;;; Copyright © 2022 Oleg Pykhalov <go.wigust@gmail.com> 6;;; Copyright © 2022 Oleg Pykhalov <go.wigust@gmail.com>
@@ -43,6 +43,8 @@
43 #:use-module (gnu system hurd) 43 #:use-module (gnu system hurd)
44 #:use-module (gnu system image) 44 #:use-module (gnu system image)
45 #:use-module (gnu system shadow) 45 #:use-module (gnu system shadow)
46 #:autoload (gnu system vm) (linux-image-startup-command
47 virtualized-operating-system)
46 #:use-module (gnu system) 48 #:use-module (gnu system)
47 #:use-module (guix derivations) 49 #:use-module (guix derivations)
48 #:use-module (guix gexp) 50 #:use-module (guix gexp)
@@ -55,12 +57,20 @@
55 #:autoload (guix self) (make-config.scm) 57 #:autoload (guix self) (make-config.scm)
56 #:autoload (guix platform) (platform-system) 58 #:autoload (guix platform) (platform-system)
57 59
60 #:use-module (srfi srfi-1)
58 #:use-module (srfi srfi-9) 61 #:use-module (srfi srfi-9)
62 #:use-module (srfi srfi-19)
59 #:use-module (srfi srfi-26) 63 #:use-module (srfi srfi-26)
60 #:use-module (rnrs bytevectors) 64 #:use-module (rnrs bytevectors)
61 #:use-module (ice-9 match) 65 #:use-module (ice-9 match)
62 66
63 #:export (%hurd-vm-operating-system 67 #:export (virtual-build-machine
68 virtual-build-machine-service-type
69
70 %virtual-build-machine-operating-system
71 %virtual-build-machine-default-vm
72
73 %hurd-vm-operating-system
64 hurd-vm-configuration 74 hurd-vm-configuration
65 hurd-vm-configuration? 75 hurd-vm-configuration?
66 hurd-vm-configuration-os 76 hurd-vm-configuration-os
@@ -1066,6 +1076,461 @@ that will be listening to receive secret keys on ADDRESS."
1066 1076
1067 1077
1068;;; 1078;;;
1079;;; Offloading-as-a-service.
1080;;;
1081
1082(define-record-type* <virtual-build-machine>
1083 virtual-build-machine make-virtual-build-machine
1084 virtual-build-machine?
1085 this-virtual-build-machine
1086 (name virtual-build-machine-name
1087 (default 'build-vm))
1088 (image virtual-build-machine-image
1089 (thunked)
1090 (default
1091 (virtual-build-machine-default-image
1092 this-virtual-build-machine)))
1093 (qemu virtual-build-machine-qemu
1094 (default qemu-minimal))
1095 (cpu virtual-build-machine-cpu
1096 (thunked)
1097 (default
1098 (qemu-cpu-model-for-date
1099 (virtual-build-machine-systems this-virtual-build-machine)
1100 (virtual-build-machine-date this-virtual-build-machine))))
1101 (cpu-count virtual-build-machine-cpu-count
1102 (default 4))
1103 (memory-size virtual-build-machine-memory-size ;integer (MiB)
1104 (default 2048))
1105 (date virtual-build-machine-date
1106 ;; Default to a date "in the past" assuming a common use case
1107 ;; is to rebuild old packages.
1108 (default (make-date 0 0 00 00 01 01 2020 0)))
1109 (port-forwardings virtual-build-machine-port-forwardings
1110 (default
1111 `((,%build-vm-ssh-port . 22)
1112 (,%build-vm-secrets-port . 1004))))
1113 (systems virtual-build-machine-systems
1114 (default (list (%current-system))))
1115 (auto-start? virtual-build-machine-auto-start?
1116 (default #f)))
1117
1118(define %build-vm-ssh-port
1119 ;; Default host port where the guest's SSH port is forwarded.
1120 11022)
1121
1122(define %build-vm-secrets-port
1123 ;; Host port to communicate secrets to the build VM.
1124 ;; FIXME: Anyone on the host can talk to it; use virtio ports or AF_VSOCK
1125 ;; instead.
1126 11044)
1127
1128(define %x86-64-intel-cpu-models
1129 ;; List of release date/CPU model pairs representing Intel's x86_64 models.
1130 ;; The list is taken from
1131 ;; <https://en.wikipedia.org/wiki/List_of_Intel_CPU_microarchitectures>.
1132 ;; CPU model strings are those found in 'qemu-system-x86_64 -cpu help'.
1133 (letrec-syntax ((cpu-models (syntax-rules ()
1134 ((_ (date model) rest ...)
1135 (alist-cons (date->time-utc
1136 (string->date date "~Y-~m-~d"))
1137 model
1138 (cpu-models rest ...)))
1139 ((_)
1140 '()))))
1141 (reverse
1142 (cpu-models ("2006-01-01" "core2duo")
1143 ("2010-01-01" "Westmere")
1144 ("2008-01-01" "Nehalem")
1145 ("2011-01-01" "SandyBridge")
1146 ("2012-01-01" "IvyBridge")
1147 ("2013-01-01" "Haswell")
1148 ("2014-01-01" "Broadwell")
1149 ("2015-01-01" "Skylake-Client")))))
1150
1151(define (qemu-cpu-model-for-date systems date)
1152 "Return the QEMU name of a CPU model for SYSTEMS that was current at DATE."
1153 (if (any (cut string-prefix? "x86_64-" <>) systems)
1154 (let ((time (date->time-utc date)))
1155 (any (match-lambda
1156 ((release-date . model)
1157 (and (time<? release-date time)
1158 model)))
1159 %x86-64-intel-cpu-models))
1160 ;; TODO: Add models for other architectures.
1161 "host"))
1162
1163(define (virtual-build-machine-ssh-port config)
1164 "Return the host port where CONFIG has its VM's SSH port forwarded."
1165 (any (match-lambda
1166 ((host-port . 22) host-port)
1167 (_ #f))
1168 (virtual-build-machine-port-forwardings config)))
1169
1170(define (virtual-build-machine-secrets-port config)
1171 "Return the host port where CONFIG has its VM's secrets port forwarded."
1172 (any (match-lambda
1173 ((host-port . 1004) host-port)
1174 (_ #f))
1175 (virtual-build-machine-port-forwardings config)))
1176
1177(define %minimal-vm-syslog-config
1178 ;; Minimal syslog configuration for a VM.
1179 (plain-file "vm-syslog.conf" "\
1180# Log most messages to the console, which goes to the serial
1181# output, allowing the host to log it.
1182*.info;auth.notice;authpriv.none -/dev/console
1183
1184# The rest.
1185*.=debug -/var/log/debug
1186authpriv.*;auth.info /var/log/secure
1187"))
1188
1189(define %virtual-build-machine-operating-system
1190 (operating-system
1191 (host-name "build-machine")
1192 (bootloader (bootloader-configuration ;unused
1193 (bootloader grub-minimal-bootloader)
1194 (targets '("/dev/null"))))
1195 (file-systems (list (file-system ;unused
1196 (mount-point "/")
1197 (device "none")
1198 (type "tmpfs"))))
1199 (users (cons (user-account
1200 (name "offload")
1201 (group "users")
1202 (supplementary-groups '("kvm"))
1203 (comment "Account used for offloading"))
1204 %base-user-accounts))
1205 (services (cons* (service static-networking-service-type
1206 (list %qemu-static-networking))
1207 (service openssh-service-type
1208 (openssh-configuration
1209 (openssh openssh-sans-x)))
1210
1211 (modify-services %base-services
1212 ;; By default, the secret service introduces a
1213 ;; pre-initialized /etc/guix/acl file in the VM. Thus,
1214 ;; clear 'authorize-key?' so that it's not overridden
1215 ;; at activation time.
1216 (guix-service-type config =>
1217 (guix-configuration
1218 (inherit config)
1219 (authorize-key? #f)))
1220 (syslog-service-type config =>
1221 (syslog-configuration
1222 (config-file
1223 %minimal-vm-syslog-config)))
1224 (delete mingetty-service-type)
1225 (delete console-font-service-type))))))
1226
1227(define (virtual-build-machine-default-image config)
1228 (let* ((type (lookup-image-type-by-name 'mbr-raw))
1229 (base (os->image %virtual-build-machine-operating-system
1230 #:type type)))
1231 (image (inherit base)
1232 (name (symbol-append 'build-vm-
1233 (virtual-build-machine-name config)))
1234 (format 'compressed-qcow2)
1235 (partition-table-type 'mbr)
1236 (shared-store? #f)
1237 (size (* 10 (expt 2 30))))))
1238
1239(define (virtual-build-machine-account-name config)
1240 (string-append "build-vm-"
1241 (symbol->string
1242 (virtual-build-machine-name config))))
1243
1244(define (virtual-build-machine-accounts config)
1245 (let ((name (virtual-build-machine-account-name config)))
1246 (list (user-group (name name) (system? #t))
1247 (user-account
1248 (name name)
1249 (group name)
1250 (supplementary-groups '("kvm"))
1251 (comment "Privilege separation user for the virtual build machine")
1252 (home-directory "/var/empty")
1253 (shell (file-append shadow "/sbin/nologin"))
1254 (system? #t)))))
1255
1256(define (build-vm-shepherd-services config)
1257 (define transform
1258 (compose secret-service-operating-system
1259 operating-system-with-locked-root-account
1260 operating-system-with-offloading-account
1261 (lambda (os)
1262 (virtualized-operating-system os #:full-boot? #t))))
1263
1264 (define transformed-image
1265 (let ((base (virtual-build-machine-image config)))
1266 (image
1267 (inherit base)
1268 (operating-system
1269 (transform (image-operating-system base))))))
1270
1271 (define command
1272 (linux-image-startup-command transformed-image
1273 #:qemu
1274 (virtual-build-machine-qemu config)
1275 #:cpu
1276 (virtual-build-machine-cpu config)
1277 #:cpu-count
1278 (virtual-build-machine-cpu-count config)
1279 #:memory-size
1280 (virtual-build-machine-memory-size config)
1281 #:port-forwardings
1282 (virtual-build-machine-port-forwardings
1283 config)
1284 #:date
1285 (virtual-build-machine-date config)))
1286
1287 (define user
1288 (virtual-build-machine-account-name config))
1289
1290 (list (shepherd-service
1291 (documentation "Run the build virtual machine service.")
1292 (provision (list (virtual-build-machine-name config)))
1293 (requirement '(user-processes))
1294 (modules `((gnu build secret-service)
1295 (guix build utils)
1296 ,@%default-modules))
1297 (start
1298 (with-imported-modules (source-module-closure
1299 '((gnu build secret-service)
1300 (guix build utils)))
1301 #~(lambda arguments
1302 (let* ((pid (fork+exec-command (append #$command arguments)
1303 #:user #$user
1304 #:group "kvm"
1305 #:environment-variables
1306 ;; QEMU tries to write to /var/tmp
1307 ;; by default.
1308 '("TMPDIR=/tmp")))
1309 (port #$(virtual-build-machine-secrets-port config))
1310 (root #$(virtual-build-machine-secret-root config))
1311 (address (make-socket-address AF_INET INADDR_LOOPBACK
1312 port)))
1313 (catch #t
1314 (lambda _
1315 (if (secret-service-send-secrets address root)
1316 pid
1317 (begin
1318 (kill (- pid) SIGTERM)
1319 #f)))
1320 (lambda (key . args)
1321 (kill (- pid) SIGTERM)
1322 (apply throw key args)))))))
1323 (stop #~(make-kill-destructor))
1324 (auto-start? (virtual-build-machine-auto-start? config)))))
1325
1326(define (authorize-guest-substitutes-on-host)
1327 "Return a program that authorizes the guest's archive signing key (passed as
1328an argument) on the host."
1329 (define not-config?
1330 (match-lambda
1331 ('(guix config) #f)
1332 (('guix _ ...) #t)
1333 (('gnu _ ...) #t)
1334 (_ #f)))
1335
1336 (define run
1337 (with-extensions (list guile-gcrypt)
1338 (with-imported-modules `(((guix config) => ,(make-config.scm))
1339 ,@(source-module-closure
1340 '((guix pki)
1341 (guix build utils))
1342 #:select? not-config?))
1343 #~(begin
1344 (use-modules (ice-9 match)
1345 (ice-9 textual-ports)
1346 (gcrypt pk-crypto)
1347 (guix pki)
1348 (guix build utils))
1349
1350 (match (command-line)
1351 ((_ guest-config-directory)
1352 (let ((guest-key (string-append guest-config-directory
1353 "/signing-key.pub")))
1354 (if (file-exists? guest-key)
1355 ;; Add guest key to the host's ACL.
1356 (let* ((key (string->canonical-sexp
1357 (call-with-input-file guest-key
1358 get-string-all)))
1359 (acl (public-keys->acl
1360 (cons key (acl->public-keys (current-acl))))))
1361 (with-atomic-file-replacement %acl-file
1362 (lambda (_ port)
1363 (write-acl acl port))))
1364 (format (current-error-port)
1365 "warning: guest key missing from '~a'~%"
1366 guest-key)))))))))
1367
1368 (program-file "authorize-guest-substitutes-on-host" run))
1369
1370(define (initialize-build-vm-substitutes)
1371 "Initialize the Hurd VM's key pair and ACL and store it on the host."
1372 (define run
1373 (with-imported-modules '((guix build utils))
1374 #~(begin
1375 (use-modules (guix build utils)
1376 (ice-9 match))
1377
1378 (define host-key
1379 "/etc/guix/signing-key.pub")
1380
1381 (define host-acl
1382 "/etc/guix/acl")
1383
1384 (match (command-line)
1385 ((_ guest-config-directory)
1386 (setenv "GUIX_CONFIGURATION_DIRECTORY"
1387 guest-config-directory)
1388 (invoke #+(file-append guix "/bin/guix") "archive"
1389 "--generate-key")
1390
1391 (when (file-exists? host-acl)
1392 ;; Copy the host ACL.
1393 (copy-file host-acl
1394 (string-append guest-config-directory
1395 "/acl")))
1396
1397 (when (file-exists? host-key)
1398 ;; Add the host key to the childhurd's ACL.
1399 (let ((key (open-fdes host-key O_RDONLY)))
1400 (close-fdes 0)
1401 (dup2 key 0)
1402 (execl #+(file-append guix "/bin/guix")
1403 "guix" "archive" "--authorize"))))))))
1404
1405 (program-file "initialize-build-vm-substitutes" run))
1406
1407(define* (build-vm-activation secret-directory
1408 #:key
1409 offloading-ssh-key
1410 (offloading? #t))
1411 (with-imported-modules '((guix build utils))
1412 #~(begin
1413 (use-modules (guix build utils))
1414
1415 (define secret-directory
1416 #$secret-directory)
1417
1418 (define ssh-directory
1419 (string-append secret-directory "/etc/ssh"))
1420
1421 (define guix-directory
1422 (string-append secret-directory "/etc/guix"))
1423
1424 (define offloading-ssh-key
1425 #$offloading-ssh-key)
1426
1427 (unless (file-exists? ssh-directory)
1428 ;; Generate SSH host keys under SSH-DIRECTORY.
1429 (mkdir-p ssh-directory)
1430 (invoke #$(file-append openssh "/bin/ssh-keygen")
1431 "-A" "-f" secret-directory))
1432
1433 (unless (or (not #$offloading?)
1434 (file-exists? offloading-ssh-key))
1435 ;; Generate a user SSH key pair for the host to use when offloading
1436 ;; to the guest.
1437 (mkdir-p (dirname offloading-ssh-key))
1438 (invoke #$(file-append openssh "/bin/ssh-keygen")
1439 "-t" "ed25519" "-N" ""
1440 "-f" offloading-ssh-key)
1441
1442 ;; Authorize it in the guest for user 'offloading'.
1443 (let ((authorizations
1444 (string-append ssh-directory
1445 "/authorized_keys.d/offloading")))
1446 (mkdir-p (dirname authorizations))
1447 (copy-file (string-append offloading-ssh-key ".pub")
1448 authorizations)
1449 (chmod (dirname authorizations) #o555)))
1450
1451 (unless (file-exists? guix-directory)
1452 (invoke #$(initialize-build-vm-substitutes)
1453 guix-directory))
1454
1455 (when #$offloading?
1456 ;; Authorize the archive signing key from GUIX-DIRECTORY in the host.
1457 (invoke #$(authorize-guest-substitutes-on-host) guix-directory)))))
1458
1459(define (virtual-build-machine-offloading-ssh-key config)
1460 "Return the name of the file containing the SSH key of user 'offloading'."
1461 (string-append "/etc/guix/offload/ssh/virtual-build-machine/"
1462 (symbol->string
1463 (virtual-build-machine-name config))))
1464
1465(define (virtual-build-machine-activation config)
1466 "Return a gexp to activate the build VM according to CONFIG."
1467 (build-vm-activation (virtual-build-machine-secret-root config)
1468 #:offloading? #t
1469 #:offloading-ssh-key
1470 (virtual-build-machine-offloading-ssh-key config)))
1471
1472(define (virtual-build-machine-secret-root config)
1473 (string-append "/etc/guix/virtual-build-machines/"
1474 (symbol->string
1475 (virtual-build-machine-name config))))
1476
1477(define (check-vm-availability config)
1478 "Return a Scheme file that evaluates to true if the service corresponding to
1479CONFIG, a <virtual-build-machine>, is up and running."
1480 (define service-name
1481 (virtual-build-machine-name config))
1482
1483 (scheme-file "check-build-vm-availability.scm"
1484 #~(begin
1485 (use-modules (gnu services herd)
1486 (srfi srfi-34))
1487
1488 (guard (c ((service-not-found-error? c) #f))
1489 (->bool (current-service '#$service-name))))))
1490
1491(define (build-vm-guix-extension config)
1492 (define vm-ssh-key
1493 (string-append
1494 (virtual-build-machine-secret-root config)
1495 "/etc/ssh/ssh_host_ed25519_key.pub"))
1496
1497 (define host-ssh-key
1498 (virtual-build-machine-offloading-ssh-key config))
1499
1500 (guix-extension
1501 (build-machines
1502 (list #~(if (primitive-load #$(check-vm-availability config))
1503 (list (build-machine
1504 (name "localhost")
1505 (port #$(virtual-build-machine-ssh-port config))
1506 (systems
1507 '#$(virtual-build-machine-systems config))
1508 (user "offloading")
1509 (host-key (call-with-input-file #$vm-ssh-key
1510 (@ (ice-9 textual-ports)
1511 get-string-all)))
1512 (private-key #$host-ssh-key)))
1513 '())))))
1514
1515(define virtual-build-machine-service-type
1516 (service-type
1517 (name 'build-vm)
1518 (extensions (list (service-extension shepherd-root-service-type
1519 build-vm-shepherd-services)
1520 (service-extension guix-service-type
1521 build-vm-guix-extension)
1522 (service-extension account-service-type
1523 virtual-build-machine-accounts)
1524 (service-extension activation-service-type
1525 virtual-build-machine-activation)))
1526 (description
1527 "Create a @dfn{virtual build machine}: a virtual machine (VM) that builds
1528can be offloaded to. By default, the virtual machine starts with a clock
1529running at some point in the past.")
1530 (default-value (virtual-build-machine))))
1531
1532
1533;;;
1069;;; The Hurd in VM service: a Childhurd. 1534;;; The Hurd in VM service: a Childhurd.
1070;;; 1535;;;
1071 1536
@@ -1290,136 +1755,13 @@ is added to the OS specified in CONFIG."
1290 (shell (file-append shadow "/sbin/nologin")) 1755 (shell (file-append shadow "/sbin/nologin"))
1291 (system? #t)))) 1756 (system? #t))))
1292 1757
1293(define (initialize-hurd-vm-substitutes)
1294 "Initialize the Hurd VM's key pair and ACL and store it on the host."
1295 (define run
1296 (with-imported-modules '((guix build utils))
1297 #~(begin
1298 (use-modules (guix build utils)
1299 (ice-9 match))
1300
1301 (define host-key
1302 "/etc/guix/signing-key.pub")
1303
1304 (define host-acl
1305 "/etc/guix/acl")
1306
1307 (match (command-line)
1308 ((_ guest-config-directory)
1309 (setenv "GUIX_CONFIGURATION_DIRECTORY"
1310 guest-config-directory)
1311 (invoke #+(file-append guix "/bin/guix") "archive"
1312 "--generate-key")
1313
1314 (when (file-exists? host-acl)
1315 ;; Copy the host ACL.
1316 (copy-file host-acl
1317 (string-append guest-config-directory
1318 "/acl")))
1319
1320 (when (file-exists? host-key)
1321 ;; Add the host key to the childhurd's ACL.
1322 (let ((key (open-fdes host-key O_RDONLY)))
1323 (close-fdes 0)
1324 (dup2 key 0)
1325 (execl #+(file-append guix "/bin/guix")
1326 "guix" "archive" "--authorize"))))))))
1327
1328 (program-file "initialize-hurd-vm-substitutes" run))
1329
1330(define (authorize-guest-substitutes-on-host)
1331 "Return a program that authorizes the guest's archive signing key (passed as
1332an argument) on the host."
1333 (define not-config?
1334 (match-lambda
1335 ('(guix config) #f)
1336 (('guix _ ...) #t)
1337 (('gnu _ ...) #t)
1338 (_ #f)))
1339
1340 (define run
1341 (with-extensions (list guile-gcrypt)
1342 (with-imported-modules `(((guix config) => ,(make-config.scm))
1343 ,@(source-module-closure
1344 '((guix pki)
1345 (guix build utils))
1346 #:select? not-config?))
1347 #~(begin
1348 (use-modules (ice-9 match)
1349 (ice-9 textual-ports)
1350 (gcrypt pk-crypto)
1351 (guix pki)
1352 (guix build utils))
1353
1354 (match (command-line)
1355 ((_ guest-config-directory)
1356 (let ((guest-key (string-append guest-config-directory
1357 "/signing-key.pub")))
1358 (if (file-exists? guest-key)
1359 ;; Add guest key to the host's ACL.
1360 (let* ((key (string->canonical-sexp
1361 (call-with-input-file guest-key
1362 get-string-all)))
1363 (acl (public-keys->acl
1364 (cons key (acl->public-keys (current-acl))))))
1365 (with-atomic-file-replacement %acl-file
1366 (lambda (_ port)
1367 (write-acl acl port))))
1368 (format (current-error-port)
1369 "warning: guest key missing from '~a'~%"
1370 guest-key)))))))))
1371
1372 (program-file "authorize-guest-substitutes-on-host" run))
1373
1374(define (hurd-vm-activation config) 1758(define (hurd-vm-activation config)
1375 "Return a gexp to activate the Hurd VM according to CONFIG." 1759 "Return a gexp to activate the Hurd VM according to CONFIG."
1376 (with-imported-modules '((guix build utils)) 1760 (build-vm-activation (hurd-vm-configuration-secret-root config)
1377 #~(begin 1761 #:offloading?
1378 (use-modules (guix build utils)) 1762 (hurd-vm-configuration-offloading? config)
1379 1763 #:offloading-ssh-key
1380 (define secret-directory 1764 (hurd-vm-configuration-offloading-ssh-key config)))
1381 #$(hurd-vm-configuration-secret-root config))
1382
1383 (define ssh-directory
1384 (string-append secret-directory "/etc/ssh"))
1385
1386 (define guix-directory
1387 (string-append secret-directory "/etc/guix"))
1388
1389 (define offloading-ssh-key
1390 #$(hurd-vm-configuration-offloading-ssh-key config))
1391
1392 (unless (file-exists? ssh-directory)
1393 ;; Generate SSH host keys under SSH-DIRECTORY.
1394 (mkdir-p ssh-directory)
1395 (invoke #$(file-append openssh "/bin/ssh-keygen")
1396 "-A" "-f" secret-directory))
1397
1398 (unless (or (not #$(hurd-vm-configuration-offloading? config))
1399 (file-exists? offloading-ssh-key))
1400 ;; Generate a user SSH key pair for the host to use when offloading
1401 ;; to the guest.
1402 (mkdir-p (dirname offloading-ssh-key))
1403 (invoke #$(file-append openssh "/bin/ssh-keygen")
1404 "-t" "ed25519" "-N" ""
1405 "-f" offloading-ssh-key)
1406
1407 ;; Authorize it in the guest for user 'offloading'.
1408 (let ((authorizations
1409 (string-append ssh-directory
1410 "/authorized_keys.d/offloading")))
1411 (mkdir-p (dirname authorizations))
1412 (copy-file (string-append offloading-ssh-key ".pub")
1413 authorizations)
1414 (chmod (dirname authorizations) #o555)))
1415
1416 (unless (file-exists? guix-directory)
1417 (invoke #$(initialize-hurd-vm-substitutes)
1418 guix-directory))
1419
1420 (when #$(hurd-vm-configuration-offloading? config)
1421 ;; Authorize the archive signing key from GUIX-DIRECTORY in the host.
1422 (invoke #$(authorize-guest-substitutes-on-host) guix-directory)))))
1423 1765
1424(define (hurd-vm-configuration-offloading-ssh-key config) 1766(define (hurd-vm-configuration-offloading-ssh-key config)
1425 "Return the name of the file containing the SSH key of user 'offloading'." 1767 "Return the name of the file containing the SSH key of user 'offloading'."