projects/guix·blob java-team · refs

265 lines · 10.6 KiB

1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2020, 2021 Marius Bakke <[email protected]>
3;;; Copyright © 2020 Brice Waegeneire <[email protected]>
4;;; Copyright © 2023 Bruno Victal <[email protected]>
5;;;
6;;; This file is part of GNU Guix.
7;;;
8;;; GNU Guix is free software; you can redistribute it and/or modify it
9;;; under the terms of the GNU General Public License as published by
10;;; the Free Software Foundation; either version 3 of the License, or (at
11;;; your option) any later version.
12;;;
13;;; GNU Guix is distributed in the hope that it will be useful, but
14;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;;; GNU General Public License for more details.
17;;;
18;;; You should have received a copy of the GNU General Public License
19;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
20
21(define-module (gnu tests ganeti)
22 #:use-module (gnu)
23 #:use-module (gnu tests)
24 #:use-module (gnu system vm)
25 #:use-module (gnu services)
26 #:use-module (gnu services base)
27 #:use-module (gnu services ganeti)
28 #:use-module (gnu services networking)
29 #:use-module (gnu services ssh)
30 #:use-module (gnu packages virtualization)
31 #:use-module (guix gexp)
32 #:use-module (ice-9 format)
33 #:export (%test-ganeti-kvm %test-ganeti-lxc))
34
35(define %ganeti-os
36 (operating-system-with-console-syslog
37 (operating-system
38 (host-name "gnt1")
39 (timezone "Etc/UTC")
40 (locale "en_US.UTF-8")
41
42 (bootloader (bootloader-configuration
43 (bootloader grub-bootloader)
44 (targets '("/dev/vda"))))
45 (file-systems (cons (file-system
46 (device (file-system-label "my-root"))
47 (mount-point "/")
48 (type "ext4"))
49 %base-file-systems))
50 (firmware '())
51
52 (packages (append (list ganeti-instance-debootstrap ganeti-instance-guix)
53 %base-packages))
54
55 ;; The hosts file must contain a nonlocal IP for host-name.
56 (essential-services
57 (modify-services (operating-system-default-essential-services this-operating-system)
58 (hosts-service-type config => (list
59 (host "127.0.0.1" "localhost")
60 (host "::1" "localhost")))))
61 (services
62 (append (list (service static-networking-service-type
63 (list %qemu-static-networking))
64 (service openssh-service-type
65 (openssh-configuration
66 (permit-root-login 'prohibit-password)))
67
68 ;; In addition, the cluster name must resolve to an IP address that
69 ;; is not currently provisioned.
70 (simple-service 'ganeti-host-entries hosts-service-type
71 (list
72 (host "10.0.2.15" "gnt1.example.com" '("gnt1"))
73 (host "192.168.254.254" "ganeti.example.com")))
74
75 (service ganeti-service-type
76 (ganeti-configuration
77 (file-storage-paths '("/srv/ganeti/file-storage"))
78 (rapi-configuration
79 (ganeti-rapi-configuration
80 ;; Disable TLS so we can test the RAPI without
81 ;; pulling in GnuTLS.
82 (ssl? #f)))
83 (os %default-ganeti-os))))
84 %base-services)))))
85
86(define* (run-ganeti-test hypervisor #:key
87 (master-netdev "eth0")
88 (hvparams '())
89 (extra-packages '())
90 (rapi-port 5080))
91 "Run tests in %GANETI-OS."
92 (define os
93 (marionette-operating-system
94 (operating-system
95 (inherit %ganeti-os)
96 (packages (append extra-packages
97 (operating-system-packages %ganeti-os))))
98 #:imported-modules '((gnu services herd)
99 (guix combinators))))
100
101 (define %forwarded-rapi-port 5080)
102
103 (define vm
104 (virtual-machine
105 (operating-system os)
106 ;; Some of the daemons are fairly memory-hungry.
107 (memory-size 512)
108 ;; Forward HTTP ports so we can access them from the "outside".
109 (port-forwardings `((,%forwarded-rapi-port . ,rapi-port)))))
110
111 (define test
112 (with-imported-modules '((gnu build marionette))
113 #~(begin
114 (use-modules (srfi srfi-11) (srfi srfi-64)
115 (web uri) (web client) (web response)
116 (ice-9 iconv)
117 (gnu build marionette))
118
119 (define marionette
120 (make-marionette (list #$vm "-m" "1024")))
121
122 (test-runner-current (system-test-runner #$output))
123 (test-begin "ganeti")
124
125 ;; Ganeti uses the Shepherd to start/stop daemons, so make sure
126 ;; it is ready before we begin. It takes a while because all
127 ;; Ganeti daemons fail to start initially.
128 (test-assert "shepherd is ready"
129 (wait-for-unix-socket "/var/run/shepherd/socket" marionette))
130
131 (test-eq "gnt-cluster init"
132 0
133 (marionette-eval
134 '(begin
135 (setenv
136 "PATH"
137 ;; Init needs to run 'ssh-keygen', 'ip', etc.
138 "/run/current-system/profile/sbin:/run/current-system/profile/bin")
139 (system* #$(file-append ganeti "/sbin/gnt-cluster") "init"
140 (string-append "--master-netdev=" #$master-netdev)
141 ;; TODO: Enable more disk backends.
142 "--enabled-disk-templates=file"
143 (string-append "--enabled-hypervisors="
144 #$hypervisor)
145 (string-append "--hypervisor-parameters="
146 #$hypervisor ":"
147 (string-join '#$hvparams "\n"))
148 ;; Set the default NIC mode to 'routed' to avoid having to
149 ;; configure a full bridge to placate 'gnt-cluster verify'.
150 "--nic-parameters=mode=routed,link=eth0"
151 "ganeti.example.com"))
152 marionette))
153
154 ;; Disable the watcher while doing daemon tests to prevent interference.
155 (test-eq "watcher pause"
156 0
157 (marionette-eval
158 '(system* #$(file-append ganeti "/sbin/gnt-cluster")
159 "watcher" "pause" "1h")
160 marionette))
161
162 (test-assert "force-start wconfd"
163 ;; Check that the 'force-start' Shepherd action works, used in a
164 ;; master-failover scenario.
165 (marionette-eval
166 '(begin
167 (setenv "PATH" "/run/current-system/profile/bin")
168 (and (zero? (system* "herd" "stop" "ganeti-wconfd"))
169 (zero? (system* "herd" "disable" "ganeti-wconfd"))
170 (zero? (system* "herd" "force-start" "ganeti-wconfd"))))
171 marionette))
172
173 ;; Verify that the cluster is healthy.
174 (test-eq "gnt-cluster verify 1"
175 0
176 (marionette-eval
177 '(system* #$(file-append ganeti "/sbin/gnt-cluster") "verify")
178 marionette))
179
180 ;; Try stopping and starting daemons with daemon-util like
181 ;; 'gnt-node add', 'gnt-cluster init', etc.
182 (test-eq "daemon-util stop-all"
183 0
184 (marionette-eval
185 '(system* #$(file-append ganeti "/lib/ganeti/daemon-util")
186 "stop-all")
187 marionette))
188
189 (test-eq "daemon-util start-all"
190 0
191 (marionette-eval
192 '(system* #$(file-append ganeti "/lib/ganeti/daemon-util")
193 "start-all")
194 marionette))
195
196 ;; Check that the cluster is still healthy after the daemon restarts.
197 (test-eq "gnt-cluster verify 2"
198 0
199 (marionette-eval
200 '(system* #$(file-append ganeti "/sbin/gnt-cluster") "verify")
201 marionette))
202
203 (test-eq "watcher continue"
204 0
205 (marionette-eval
206 '(system* #$(file-append ganeti "/sbin/gnt-cluster")
207 "watcher" "continue")
208 marionette))
209
210 ;; Try accessing the RAPI.
211 (test-equal "http-get RAPI version"
212 '(200 "2\n")
213 (let-values
214 (((response text)
215 (http-get #$(simple-format
216 #f "http://localhost:~A/version"
217 %forwarded-rapi-port)
218 #:decode-body? #f)))
219 (list (response-code response)
220 ;; The API response lacks a content-type, so
221 ;; (http-client) won't decode it for us.
222 (bytevector->string text "UTF-8"))))
223
224 (test-equal "gnt-os list"
225 "debootstrap+default\nguix+default\n"
226 (marionette-eval
227 '(begin
228 (use-modules (ice-9 popen)
229 (ice-9 textual-ports))
230 (let* ((port (open-pipe*
231 OPEN_READ
232 #$(file-append ganeti "/sbin/gnt-os")
233 "list" "--no-headers"))
234 (output (get-string-all port)))
235 (close-pipe port)
236 output))
237 marionette))
238
239 (test-eq "gnt-cluster destroy"
240 0
241 (marionette-eval
242 '(system* #$(file-append ganeti "/sbin/gnt-cluster")
243 "destroy" "--yes-do-it")
244 marionette))
245
246 (test-end))))
247
248 (gexp->derivation (string-append "ganeti-" hypervisor "-test") test))
249
250(define %test-ganeti-kvm
251 (system-test
252 (name "ganeti-kvm")
253 (description "Provision a Ganeti cluster using the KVM hypervisor.")
254 (value (run-ganeti-test "kvm"
255 ;; Set kernel_path to an empty string to prevent
256 ;; 'gnt-cluster verify' from testing for its presence.
257 #:hvparams '("kernel_path=")
258 #:extra-packages (list qemu)))))
259
260(define %test-ganeti-lxc
261 (system-test
262 (name "ganeti-lxc")
263 (description "Provision a Ganeti cluster using LXC as the hypervisor.")
264 (value (run-ganeti-test "lxc"
265 #:extra-packages (list lxc)))))