virtualization.scm 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2017 Christopher Baines <mail@cbaines.net>
  3. ;;; Copyright © 2020 Ludovic Courtès <ludo@gnu.org>
  4. ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
  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. (define-module (gnu tests virtualization)
  21. #:use-module (gnu tests)
  22. #:use-module (gnu image)
  23. #:use-module (gnu system)
  24. #:use-module (gnu system file-systems)
  25. #:use-module (gnu system image)
  26. #:use-module (gnu system images hurd)
  27. #:use-module (gnu system vm)
  28. #:use-module (gnu services)
  29. #:use-module (gnu services dbus)
  30. #:use-module (gnu services networking)
  31. #:use-module (gnu services virtualization)
  32. #:use-module (gnu packages virtualization)
  33. #:use-module (gnu packages ssh)
  34. #:use-module (guix gexp)
  35. #:use-module (guix records)
  36. #:use-module (guix store)
  37. #:export (%test-libvirt
  38. %test-childhurd))
  39. ;;;
  40. ;;; Libvirt.
  41. ;;;
  42. (define %libvirt-os
  43. (simple-operating-system
  44. (service dhcp-client-service-type)
  45. (dbus-service)
  46. (polkit-service)
  47. (service libvirt-service-type)))
  48. (define (run-libvirt-test)
  49. "Run tests in %LIBVIRT-OS."
  50. (define os
  51. (marionette-operating-system
  52. %libvirt-os
  53. #:imported-modules '((gnu services herd)
  54. (guix combinators))))
  55. (define vm
  56. (virtual-machine
  57. (operating-system os)
  58. (port-forwardings '())))
  59. (define test
  60. (with-imported-modules '((gnu build marionette))
  61. #~(begin
  62. (use-modules (srfi srfi-11) (srfi srfi-64)
  63. (gnu build marionette))
  64. (define marionette
  65. (make-marionette (list #$vm)))
  66. (mkdir #$output)
  67. (chdir #$output)
  68. (test-begin "libvirt")
  69. (test-assert "service running"
  70. (marionette-eval
  71. '(begin
  72. (use-modules (gnu services herd))
  73. (match (start-service 'libvirtd)
  74. (#f #f)
  75. (('service response-parts ...)
  76. (match (assq-ref response-parts 'running)
  77. ((pid) (number? pid))))))
  78. marionette))
  79. (test-eq "fetch version"
  80. 0
  81. (marionette-eval
  82. `(begin
  83. (system* ,(string-append #$libvirt "/bin/virsh")
  84. "-c" "qemu:///system" "version"))
  85. marionette))
  86. (test-end)
  87. (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
  88. (gexp->derivation "libvirt-test" test))
  89. (define %test-libvirt
  90. (system-test
  91. (name "libvirt")
  92. (description "Connect to the running LIBVIRT service.")
  93. (value (run-libvirt-test))))
  94. ;;;
  95. ;;; GNU/Hurd virtual machines, aka. childhurds.
  96. ;;;
  97. ;; Copy of `hurd-vm-disk-image', using plain disk-image for test
  98. (define (hurd-vm-disk-image-raw config)
  99. (let ((os ((@@ (gnu services virtualization) secret-service-operating-system)
  100. (hurd-vm-configuration-os config)))
  101. (disk-size (hurd-vm-configuration-disk-size config)))
  102. (system-image
  103. (image
  104. (inherit hurd-disk-image)
  105. (format 'disk-image)
  106. (size disk-size)
  107. (operating-system os)))))
  108. (define %childhurd-os
  109. (simple-operating-system
  110. (service dhcp-client-service-type)
  111. (service hurd-vm-service-type
  112. (hurd-vm-configuration
  113. (image (hurd-vm-disk-image-raw this-record))))))
  114. (define (run-childhurd-test)
  115. (define os
  116. (marionette-operating-system
  117. %childhurd-os
  118. #:imported-modules '((gnu services herd)
  119. (guix combinators))))
  120. (define vm
  121. (virtual-machine
  122. (operating-system os)
  123. (memory-size (* 1024 3))))
  124. (define run-uname-over-ssh
  125. ;; Program that runs 'uname' over SSH and prints the result on standard
  126. ;; output.
  127. (let ()
  128. (define run
  129. (with-extensions (list guile-ssh)
  130. #~(begin
  131. (use-modules (ssh session)
  132. (ssh auth)
  133. (ssh popen)
  134. (ice-9 match)
  135. (ice-9 textual-ports))
  136. (let ((session (make-session #:user "root"
  137. #:port 10022
  138. #:host "localhost"
  139. #:log-verbosity 'rare)))
  140. (match (connect! session)
  141. ('ok
  142. (userauth-password! session "")
  143. (display
  144. (get-string-all
  145. (open-remote-input-pipe* session "uname" "-on"))))
  146. (status
  147. (error "could not connect to childhurd over SSH"
  148. session status)))))))
  149. (program-file "run-uname-over-ssh" run)))
  150. (define test
  151. (with-imported-modules '((gnu build marionette))
  152. #~(begin
  153. (use-modules (gnu build marionette)
  154. (srfi srfi-64)
  155. (ice-9 match))
  156. (define marionette
  157. (make-marionette (list #$vm)))
  158. (mkdir #$output)
  159. (chdir #$output)
  160. (test-begin "childhurd")
  161. (test-assert "service running"
  162. (marionette-eval
  163. '(begin
  164. (use-modules (gnu services herd))
  165. (match (start-service 'childhurd)
  166. (#f #f)
  167. (('service response-parts ...)
  168. (match (assq-ref response-parts 'running)
  169. ((pid) (number? pid))))))
  170. marionette))
  171. (test-equal "childhurd SSH server replies"
  172. "SSH"
  173. ;; Check from within the guest whether its childhurd's SSH
  174. ;; server is reachable. Do that from the guest: port forwarding
  175. ;; to the host won't work because QEMU listens on 127.0.0.1.
  176. (marionette-eval
  177. '(begin
  178. (use-modules (ice-9 match))
  179. (let loop ((n 60))
  180. (if (zero? n)
  181. 'all-attempts-failed
  182. (let ((s (socket PF_INET SOCK_STREAM 0))
  183. (a (make-socket-address AF_INET
  184. INADDR_LOOPBACK
  185. 10022)))
  186. (format #t "connecting to childhurd SSH server...~%")
  187. (connect s a)
  188. (match (get-string-n s 3)
  189. ((? eof-object?)
  190. (close-port s)
  191. (sleep 1)
  192. (loop (- n 1)))
  193. (str
  194. (close-port s)
  195. str))))))
  196. marionette))
  197. (test-equal "SSH up and running"
  198. "childhurd GNU\n"
  199. ;; Connect from the guest to the chidhurd over SSH and run the
  200. ;; 'uname' command.
  201. (marionette-eval
  202. '(begin
  203. (use-modules (ice-9 popen))
  204. (get-string-all
  205. (open-input-pipe #$run-uname-over-ssh)))
  206. marionette))
  207. (test-end)
  208. (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
  209. (gexp->derivation "childhurd-test" test))
  210. (define %test-childhurd
  211. (system-test
  212. (name "childhurd")
  213. (description
  214. "Connect to the GNU/Hurd virtual machine service, aka. a childhurd, making
  215. sure that the childhurd boots and runs its SSH server.")
  216. (value (run-childhurd-test))))