summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Cournoyer <maxim@guixotic.coop>2026-05-11 10:27:26 +0900
committerMaxim Cournoyer <maxim@guixotic.coop>2026-05-19 14:15:27 +0900
commitb5e047ff9b400585cff590b7ee2f1629b24f6148 (patch)
treed3e27e8b3534dd4dcca1ec495c567e87b8863d35
parent115e10921ee145d10fdba2c00daff5f071ad4537 (diff)
machine: hetzner: Introduce the `make-hetzner-os' procedure.
All the performance and general purpose newer x86 Hetzner server types like the 'cpx22' now require an EFI bootloader, while older ones like the 'cx23' still expect a BIOS bootloader. Instead of exposing the user to errors when selecting the correct operating system template to use, provide a procedure that takes returning one based on the server type name. * gnu/machine/hetzner.scm (%hetzner-os-arm): Rename to... (%hetzner-os-arm/efi): ... this. Adjust for variable name change. (%hetzner-os-x86): Rename to... (%hetzner-os-x86/bios): ... this. Adjust for variable name change. (%hetzner-os-x86/efi): New variable. (server-type-name->arch, server-type-name->bootloader) (make-hetzner-os): New procedures. (%hetzner-os-x86, %hetzner-os-x86): Deprecate variables. (hetzner-machine-bootstrap-os-form): Use the server type name to infer whether the EFI or BIOS bootloader should be used, along the EFI partition. * doc/guix.texi (Invoking guix deploy): Updated doc. Fixes: #8523 Change-Id: I331a76e12bb3c19f5664dcbe4437a8d1cfe1d363
-rw-r--r--doc/guix.texi48
-rw-r--r--gnu/machine/hetzner.scm102
2 files changed, 99 insertions, 51 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 67c81ebe836..9df177d13ae 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -49,7 +49,7 @@ Copyright @copyright{} 2017 humanitiesNerd@*
49Copyright @copyright{} 2017, 2021 Christine Lemmer-Webber@* 49Copyright @copyright{} 2017, 2021 Christine Lemmer-Webber@*
50Copyright @copyright{} 2017, 2018, 2019, 2020, 2021, 2022 Marius Bakke@* 50Copyright @copyright{} 2017, 2018, 2019, 2020, 2021, 2022 Marius Bakke@*
51Copyright @copyright{} 2017, 2019, 2020, 2022 Hartmut Goebel@* 51Copyright @copyright{} 2017, 2019, 2020, 2022 Hartmut Goebel@*
52Copyright @copyright{} 2017, 2019--2025 Maxim Cournoyer@* 52Copyright @copyright{} 2017, 2019--2026 Maxim Cournoyer@*
53Copyright @copyright{} 2017–2022 Tobias Geerinckx-Rice@* 53Copyright @copyright{} 2017–2022 Tobias Geerinckx-Rice@*
54Copyright @copyright{} 2017 George Clemmer@* 54Copyright @copyright{} 2017 George Clemmer@*
55Copyright @copyright{} 2017 Andy Wingo@* 55Copyright @copyright{} 2017 Andy Wingo@*
@@ -50528,36 +50528,36 @@ server.
50528Once the server has been provisioned and SSH is available, deployment 50528Once the server has been provisioned and SSH is available, deployment
50529continues by delegating it to the @code{managed-host-environment-type}. 50529continues by delegating it to the @code{managed-host-environment-type}.
50530 50530
50531Servers on the Hetzner Cloud service can be provisioned on the AArch64 50531Depending on their type, x86_64 or AArch64 servers on the Hetzner Cloud
50532architecture using UEFI boot mode, or on the x86_64 architecture using 50532service can be provisioned using BIOS or UEFI boot mode. The @code{(gnu
50533BIOS boot mode. The @code{(gnu machine hetzner)} module exports the 50533machine hetzner)} module exports the @code{make-hetzner-os} procedure,
50534@code{%hetzner-os-arm} and @code{%hetzner-os-x86} operating systems that 50534which takes the server type string as an argument (e.g. @code{"cx23"})
50535are compatible with those two architectures, and can be used as a base 50535and returns a base @code{operating-system} definition compatible with
50536for defining your custom operating system. 50536it.
50537 50537
50538The following example shows the definition of two machines that are 50538The following example shows the definition of two machines that are
50539deployed on the Hetzner Cloud service. The first one uses the 50539deployed on the Hetzner Cloud service. The first one for an ARM server
50540@code{%hetzner-os-arm} operating system to run a server with 16 shared 50540type that has 16 shared vCPUs and 32 GB of RAM, the second for an x86_64
50541vCPUs and 32 GB of RAM on the @code{aarch64} architecture, the second 50541server type that has 16 shared vCPUs and 32 GB of RAM.
50542one uses the @code{%hetzner-os-x86} operating system on a server with 16
50543shared vCPUs and 32 GB of RAM on the @code{x86_64} architecture.
50544 50542
50545@lisp 50543@lisp
50546(use-modules (gnu machine) 50544(use-modules (gnu machine)
50547 (gnu machine hetzner)) 50545 (gnu machine hetzner))
50548 50546
50549(list (machine 50547(list (let ((server-type "cax41"))
50550 (operating-system %hetzner-os-arm) 50548 (machine
50551 (environment hetzner-environment-type) 50549 (operating-system (make-hetzner-os server-type))
50552 (configuration (hetzner-configuration 50550 (environment hetzner-environment-type)
50553 (server-type "cax41") 50551 (configuration (hetzner-configuration
50554 (ssh-key "/home/charlie/.ssh/id_rsa")))) 50552 (server-type server-type)
50555 (machine 50553 (ssh-key "/home/charlie/.ssh/id_rsa")))))
50556 (operating-system %hetzner-os-x86) 50554 (let ((server-type "cpx51"))
50557 (environment hetzner-environment-type) 50555 (machine
50558 (configuration (hetzner-configuration 50556 (operating-system (make-hetzner-os server-type))
50559 (server-type "cpx51") 50557 (environment hetzner-environment-type)
50560 (ssh-public-key "/home/charlie/.ssh/id_rsa.pub"))))) 50558 (configuration (hetzner-configuration
50559 (server-type server-type)
50560 (ssh-public-key "/home/charlie/.ssh/id_rsa.pub"))))))
50561@end lisp 50561@end lisp
50562 50562
50563@vindex GUIX_HETZNER_API_TOKEN 50563@vindex GUIX_HETZNER_API_TOKEN
diff --git a/gnu/machine/hetzner.scm b/gnu/machine/hetzner.scm
index 8795ff8e5ea..07e62d24e33 100644
--- a/gnu/machine/hetzner.scm
+++ b/gnu/machine/hetzner.scm
@@ -36,6 +36,7 @@
36 #:use-module (gnu system) 36 #:use-module (gnu system)
37 #:use-module (guix base32) 37 #:use-module (guix base32)
38 #:use-module (guix colors) 38 #:use-module (guix colors)
39 #:use-module (guix deprecation)
39 #:use-module (guix derivations) 40 #:use-module (guix derivations)
40 #:use-module (guix diagnostics) 41 #:use-module (guix diagnostics)
41 #:use-module (guix gexp) 42 #:use-module (guix gexp)
@@ -66,8 +67,10 @@
66 #:use-module (ssh session) 67 #:use-module (ssh session)
67 #:use-module (ssh sftp) 68 #:use-module (ssh sftp)
68 #:use-module (ssh shell) 69 #:use-module (ssh shell)
69 #:export (%hetzner-os-arm 70 #:export (%hetzner-os-arm ;deprecated
70 %hetzner-os-x86 71 %hetzner-os-x86 ;deprecated
72 make-hetzner-os
73
71 deploy-hetzner 74 deploy-hetzner
72 hetzner-configuration 75 hetzner-configuration
73 hetzner-configuration-allow-downgrades? 76 hetzner-configuration-allow-downgrades?
@@ -98,7 +101,7 @@
98 101
99;; Operating system for arm servers using UEFI boot mode. 102;; Operating system for arm servers using UEFI boot mode.
100 103
101(define %hetzner-os-arm 104(define %hetzner-os-arm/efi
102 (operating-system 105 (operating-system
103 (host-name "guix-arm") 106 (host-name "guix-arm")
104 (bootloader 107 (bootloader
@@ -128,9 +131,9 @@
128 131
129;; Operating system for x86 servers using BIOS boot mode. 132;; Operating system for x86 servers using BIOS boot mode.
130 133
131(define %hetzner-os-x86 134(define %hetzner-os-x86/bios
132 (operating-system 135 (operating-system
133 (inherit %hetzner-os-arm) 136 (inherit %hetzner-os-arm/efi)
134 (host-name "guix-x86") 137 (host-name "guix-x86")
135 (bootloader 138 (bootloader
136 (bootloader-configuration 139 (bootloader-configuration
@@ -146,6 +149,51 @@
146 (type "ext4")) 149 (type "ext4"))
147 %base-file-systems)))) 150 %base-file-systems))))
148 151
152(define %hetzner-os-x86/efi
153 (operating-system
154 (inherit %hetzner-os-arm/efi)
155 (host-name "guix-x86")
156 (initrd-modules
157 (cons "virtio_scsi" %base-initrd-modules))))
158
159(define (server-type-name->arch type-name)
160 "Return a symbol corresponding to the server type architecture, e.g.
161@code{'x86} or @code{'arm}."
162 (cond
163 ((string-prefix-ci? "cax" type-name)
164 'arm)
165 (else
166 'x86)))
167
168(define (server-type-name->bootloader type-name)
169 "Return a symbol corresponding to the bootloader type, e.g.
170@code{'efi} or @code{'bios}."
171 (if (eq? 'arm (server-type-name->arch type-name))
172 'efi
173 (cond
174 ((string-prefix-ci? "cx" type-name)
175 'bios) ;old, cost-optimized x86 servers
176 (else
177 'efi)))) ;newer, regular performance/general purpose servers
178
179(define* (make-hetzner-os server-type-name)
180 "Return an operating server customized for SERVER-TYPE-NAME, a string like
181\"cx23\" or \"cax11\", denoting the Hetzner virtual server type."
182 (match (server-type-name->arch server-type-name)
183 ('arm %hetzner-os-arm/efi)
184 ('x86
185 (match (server-type-name->bootloader server-type-name)
186 ('bios %hetzner-os-x86/bios)
187 ('efi %hetzner-os-x86/efi)))))
188
189(define-deprecated %hetzner-os-x86
190 make-hetzner-os
191 %hetzner-os-x86/bios)
192
193(define-deprecated %hetzner-os-arm
194 make-hetzner-os
195 %hetzner-os-arm/efi)
196
149(define (operating-system-authorize os) 197(define (operating-system-authorize os)
150 "Authorize the OS with the public signing key of the current machine." 198 "Authorize the OS with the public signing key of the current machine."
151 (if (file-exists? %public-key-file) 199 (if (file-exists? %public-key-file)
@@ -363,43 +411,43 @@ Available locations:~%~%~a~%~%For more details, see: ~a")
363 "Return the form to bootstrap an operating system on SERVER." 411 "Return the form to bootstrap an operating system on SERVER."
364 (let* ((os (machine-operating-system machine)) 412 (let* ((os (machine-operating-system machine))
365 (system (hetzner-server-system server)) 413 (system (hetzner-server-system server))
414 (type-name (hetzner-server-type-name (hetzner-server-type server)))
366 (arm? (equal? "arm" (hetzner-server-architecture server))) 415 (arm? (equal? "arm" (hetzner-server-architecture server)))
367 (x86? (equal? "x86" (hetzner-server-architecture server))) 416 (x86? (equal? "x86" (hetzner-server-architecture server)))
417 (efi? (equal? 'efi (server-type-name->bootloader type-name)))
368 (root-fs-type (operating-system-root-file-system-type os))) 418 (root-fs-type (operating-system-root-file-system-type os)))
369 `(operating-system 419 `(operating-system
370 (host-name ,(operating-system-host-name os)) 420 (host-name ,(operating-system-host-name os))
371 (timezone "Etc/UTC") 421 (timezone "Etc/UTC")
372 (bootloader (bootloader-configuration 422 (bootloader (bootloader-configuration
373 (bootloader ,(cond (arm? 'grub-efi-bootloader) 423 (bootloader ,(if efi?
374 (x86? 'grub-bootloader))) 424 'grub-efi-bootloader
375 (targets ,(cond (arm? '(list "/boot/efi")) 425 'grub-bootloader))
376 (x86? '(list "/dev/sda")))) 426 (targets ,(if efi?
377 (terminal-outputs '(console)))) 427 '(list "/boot/efi")
428 '(list "/dev/sda")))
429 (terminal-outputs '(console))))
378 (initrd-modules (append 430 (initrd-modules (append
379 ,(cond (arm? '(list "sd_mod" "virtio_scsi")) 431 ,(cond (arm? '(list "sd_mod" "virtio_scsi"))
380 (x86? '(list "virtio_scsi"))) 432 (x86? '(list "virtio_scsi")))
381 %base-initrd-modules)) 433 %base-initrd-modules))
382 (file-systems ,(cond 434 (file-systems (cons* (file-system
383 (arm? `(cons* (file-system 435 (mount-point "/")
384 (mount-point "/") 436 (device "/dev/sda1")
385 (device "/dev/sda1") 437 (type ,root-fs-type))
386 (type ,root-fs-type)) 438 ,@(if efi?
387 (file-system 439 '((file-system
388 (mount-point "/boot/efi") 440 (mount-point "/boot/efi")
389 (device "/dev/sda15") 441 (device "/dev/sda15")
390 (type "vfat")) 442 (type "vfat")))
391 %base-file-systems)) 443 '())
392 (x86? `(cons* (file-system 444 %base-file-systems))
393 (mount-point "/")
394 (device "/dev/sda1")
395 (type ,root-fs-type))
396 %base-file-systems))))
397 (services 445 (services
398 (cons* (service dhcpcd-service-type) 446 (cons* (service dhcpcd-service-type)
399 (service openssh-service-type 447 (service openssh-service-type
400 (openssh-configuration 448 (openssh-configuration
401 (openssh openssh-sans-x) 449 (openssh openssh-sans-x)
402 (permit-root-login 'prohibit-password))) 450 (permit-root-login 'prohibit-password)))
403 %base-services))))) 451 %base-services)))))
404 452
405(define (rexec-verbose session cmd) 453(define (rexec-verbose session cmd)