summaryrefslogtreecommitdiff
path: root/gnu/machine
diff options
context:
space:
mode:
authorMaxim Cournoyer <maxim@guixotic.coop>2026-05-01 23:38:31 +0900
committerMaxim Cournoyer <maxim@guixotic.coop>2026-05-23 13:29:15 +0900
commitf98c00ab749e6b82e56a4a34d0789496451cbc59 (patch)
treedee7cd04af676a3b0a59fe888c498740d43161a7 /gnu/machine
parent5d3305955041992576fd5ccc9852ab5b78d5c284 (diff)
machine: Dynamically retrieve the base server image name.
Query the API to find the latest Debian image to deploy the base system with. * gnu/machine/hetzner/http.scm (null-or): New procedure. (<hetzner-image>): New JSON record type. (<hetzner-image-created-from>): Likewise. (<hetzner-image-protection>): Likewise. (%hetzner-default-server-image): Change simple variable to a memoized procedure. (hetzner-api-server-create): Adjust user accordingly. (hetzner-api-images): New procedure. Change-Id: I9544708c878971a2c776c80b9a4ee06078d5ce61
Diffstat (limited to 'gnu/machine')
-rw-r--r--gnu/machine/hetzner/http.scm79
1 files changed, 77 insertions, 2 deletions
diff --git a/gnu/machine/hetzner/http.scm b/gnu/machine/hetzner/http.scm
index 4f81b27ca92..f8580021a9e 100644
--- a/gnu/machine/hetzner/http.scm
+++ b/gnu/machine/hetzner/http.scm
@@ -1,5 +1,6 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2024 Roman Scherer <roman@burningswell.com> 2;;; Copyright © 2024 Roman Scherer <roman@burningswell.com>
3;;; Copyright © 2026 Maxim Cournoyer <maxim@guixotic.coop>
3;;; 4;;;
4;;; This file is part of GNU Guix. 5;;; This file is part of GNU Guix.
5;;; 6;;;
@@ -19,6 +20,7 @@
19(define-module (gnu machine hetzner http) 20(define-module (gnu machine hetzner http)
20 #:use-module (guix diagnostics) 21 #:use-module (guix diagnostics)
21 #:use-module (guix i18n) 22 #:use-module (guix i18n)
23 #:use-module (guix memoization)
22 #:use-module (guix records) 24 #:use-module (guix records)
23 #:use-module (ice-9 iconv) 25 #:use-module (ice-9 iconv)
24 #:use-module (ice-9 match) 26 #:use-module (ice-9 match)
@@ -51,6 +53,7 @@
51 hetzner-api-action-wait 53 hetzner-api-action-wait
52 hetzner-api-actions 54 hetzner-api-actions
53 hetzner-api-create-ssh-key 55 hetzner-api-create-ssh-key
56 hetzner-api-images
54 hetzner-api-locations 57 hetzner-api-locations
55 hetzner-api-primary-ips 58 hetzner-api-primary-ips
56 hetzner-api-request-body 59 hetzner-api-request-body
@@ -81,6 +84,23 @@
81 hetzner-error-code 84 hetzner-error-code
82 hetzner-error-message 85 hetzner-error-message
83 hetzner-error? 86 hetzner-error?
87 hetzner-image?
88 hetzner-image-id
89 hetzner-image-type
90 hetzner-image-status
91 hetzner-image-name
92 hetzner-image-description
93 hetzner-image-disk-size
94 hetzner-image-created
95 hetzner-image-created-from
96 hetzner-image-bound-to
97 hetzner-image-os-flavor
98 hetzner-image-os-version
99 hetzner-image-rapid-deploy
100 hetzner-image-protection
101 hetzner-image-deprecated
102 hetzner-image-deleted
103 hetzner-image-architecture
84 hetzner-ipv4-blocked? 104 hetzner-ipv4-blocked?
85 hetzner-ipv4-dns-ptr 105 hetzner-ipv4-dns-ptr
86 hetzner-ipv4-id 106 hetzner-ipv4-id
@@ -148,6 +168,7 @@
148 hetzner-ssh-key? 168 hetzner-ssh-key?
149 make-hetzner-action 169 make-hetzner-action
150 make-hetzner-error 170 make-hetzner-error
171 make-hetzner-image
151 make-hetzner-ipv4 172 make-hetzner-ipv4
152 make-hetzner-ipv6 173 make-hetzner-ipv6
153 make-hetzner-location 174 make-hetzner-location
@@ -168,7 +189,19 @@
168 (make-parameter (getenv "GUIX_HETZNER_API_TOKEN"))) 189 (make-parameter (getenv "GUIX_HETZNER_API_TOKEN")))
169 190
170;; Ideally this would be a Guix image. Maybe one day. 191;; Ideally this would be a Guix image. Maybe one day.
171(define %hetzner-default-server-image "debian-11") 192(define %hetzner-default-server-image
193 (mlambda (api)
194 "Return the latest Debian image available. This image gets used for the
195initial system provisioning phase, before Guix System takes over."
196 (let ((debian-images (filter (lambda (image)
197 (string=? "debian"
198 (hetzner-image-os-flavor image)))
199 (hetzner-api-images api))))
200 (hetzner-image-name
201 (last (sort debian-images
202 (lambda (x y)
203 (< (string->number (hetzner-image-os-version x))
204 (string->number (hetzner-image-os-version y))))))))))
172 205
173;; Falkenstein, Germany 206;; Falkenstein, Germany
174(define %hetzner-default-server-location "fsn1") 207(define %hetzner-default-server-location "fsn1")
@@ -290,6 +323,43 @@
290 (server-type hetzner-server-type "server_type" 323 (server-type hetzner-server-type "server_type"
291 json->hetzner-server-type)) ; <hetzner-server-type> 324 json->hetzner-server-type)) ; <hetzner-server-type>
292 325
326(define-json-mapping <hetzner-image>
327 make-hetzner-image hetzner-image? json->hetzner-image
328 (id hetzner-image-id) ;integer
329 (type hetzner-image-type) ;string
330 (status hetzner-image-status) ;string
331 (name hetzner-image-name "name" (null-or identity)) ;string | null
332 (description hetzner-image-description) ;string
333 (image-size hetzner-image-size "image_size" ;number | null (GiB)
334 (null-or identity))
335 (disk-size hetzner-image-disk-size "disk_size") ;number (GiB)
336 (created hetzner-image-created) ;string (date)
337 (created-from hetzner-image-created-from "created_from" ;object | null
338 (null-or json->hetzner-image-created-from))
339 (bound-to hetzner-image-bound-to "bound_to" (null-or identity)) ;integer | null
340 (os-flavor hetzner-image-os-flavor "os_flavor") ;string
341 (os-version hetzner-image-os-version "os_version" ;string | null
342 (null-or identity))
343 (rapid-deploy hetzner-image-rapid-deploy "rapid_deploy") ;boolean
344 (protection hetzner-image-protection "protection" ;object
345 json->hetzner-image-protection)
346 (deprecated hetzner-image-deprecated) ;string
347 (deleted hetzner-image-deleted "deleted" (null-or identity)) ;null | string
348 (architecture hetzner-image-architecture)) ;string
349
350(define (null-or parser)
351 (lambda (value)
352 (if (eq? 'null value)
353 *unspecified*
354 (parser value))))
355
356(define-json-type <hetzner-image-created-from>
357 (id) ;integer
358 (name)) ;string
359
360(define-json-type <hetzner-image-protection>
361 (delete)) ;boolean
362
293(define-json-mapping <hetzner-server-type> 363(define-json-mapping <hetzner-server-type>
294 make-hetzner-server-type hetzner-server-type? json->hetzner-server-type 364 make-hetzner-server-type hetzner-server-type? json->hetzner-server-type
295 (architecture hetzner-server-type-architecture) ; string 365 (architecture hetzner-server-type-architecture) ; string
@@ -602,7 +672,7 @@
602 ssh-keys 672 ssh-keys
603 (ipv4 #f) 673 (ipv4 #f)
604 (ipv6 #f) 674 (ipv6 #f)
605 (image %hetzner-default-server-image) 675 (image (%hetzner-default-server-image api))
606 (labels '()) 676 (labels '())
607 (location %hetzner-default-server-location) 677 (location %hetzner-default-server-location)
608 (server-type %hetzner-default-server-type) 678 (server-type %hetzner-default-server-type)
@@ -694,3 +764,8 @@
694 "Get server types from the Hetzner API." 764 "Get server types from the Hetzner API."
695 (apply hetzner-api-list api "/server_types" "server_types" 765 (apply hetzner-api-list api "/server_types" "server_types"
696 json->hetzner-server-type options)) 766 json->hetzner-server-type options))
767
768(define* (hetzner-api-images api . options)
769 "Get image types from the Hetzner API."
770 (apply hetzner-api-list api "/images" "images"
771 json->hetzner-image options))