guix-system.sh 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. # GNU Guix --- Functional package management for GNU
  2. # Copyright © 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
  3. # Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>
  4. # Copyright © 2018 Chris Marusich <cmmarusich@gmail.com>
  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. # Test 'guix system', mostly error reporting.
  22. #
  23. set -e
  24. guix system --version
  25. tmpfile="t-guix-system-$$"
  26. errorfile="t-guix-system-error-$$"
  27. # Note: This directory is chosen outside $builddir so that relative file name
  28. # canonicalization doesn't mess up with 'current-source-directory', used by
  29. # 'local-file' ('load' forces 'relative' for
  30. # %FILE-PORT-NAME-CANONICALIZATION.)
  31. tmpdir="${TMPDIR:-/tmp}/t-guix-system-$$"
  32. mkdir "$tmpdir"
  33. trap 'rm -f "$tmpfile" "$errorfile" "$tmpdir"/*; rmdir "$tmpdir"' EXIT
  34. # Reporting of syntax errors.
  35. cat > "$tmpfile"<<EOF
  36. ;; This is line 1, and the next one is line 2.
  37. (operating-system)
  38. ;; The 'T' is at column 3.
  39. EOF
  40. if guix system vm "$tmpfile" 2> "$errorfile"
  41. then
  42. # This must not succeed.
  43. exit 1
  44. else
  45. cat "$errorfile"
  46. grep "$tmpfile:2:3:.*missing.* initializers" "$errorfile"
  47. fi
  48. cat > "$tmpfile"<<EOF
  49. ;; This is line 1, and the next one is line 2.
  50. (operating-system
  51. ;; This is line 3, and there is no closing paren!
  52. EOF
  53. if guix system vm "$tmpfile" 2> "$errorfile"
  54. then
  55. # This must not succeed.
  56. exit 1
  57. else
  58. cat "$errorfile"
  59. # Guile 3.0.6 gets line/column numbers for 'read-error' wrong
  60. # (zero-indexed): <https://bugs.gnu.org/48089>.
  61. grep "$tmpfile:4:1: missing closing paren" "$errorfile" || \
  62. grep "$tmpfile:3:0: missing closing paren" "$errorfile"
  63. fi
  64. # Reporting of module not found errors.
  65. cat > "$tmpfile" <<EOF
  66. ;; Line 1.
  67. (use-modules (gnu))
  68. (use-service-modules openssh)
  69. EOF
  70. if guix system build "$tmpfile" -n 2> "$errorfile"
  71. then false
  72. else
  73. grep "$tmpfile:3:2: .*module .*openssh.*not found" "$errorfile"
  74. grep "Try.*use-service-modules ssh" "$errorfile"
  75. fi
  76. cat > "$tmpfile" <<EOF
  77. ;; Line 1.
  78. (use-modules (gnu))
  79. (use-package-modules qemu)
  80. EOF
  81. if guix system build "$tmpfile" -n 2> "$errorfile"
  82. then false
  83. else
  84. grep "$tmpfile:3:2: .*module .*qemu.*not found" "$errorfile"
  85. grep "Try.*use-package-modules virtualization" "$errorfile"
  86. fi
  87. # Reporting of unbound variables.
  88. cat > "$tmpfile" <<EOF
  89. (use-modules (gnu)) ; 1
  90. (use-service-modules networking) ; 2
  91. (operating-system ; 4
  92. (host-name "antelope") ; 5
  93. (timezone "Europe/Paris") ; 6
  94. (locale "en_US.UTF-8") ; 7
  95. (bootloader (GRUB-config (target "/dev/sdX"))) ; 9
  96. (file-systems (cons (file-system
  97. (device (file-system-label "root"))
  98. (mount-point "/")
  99. (type "ext4"))
  100. %base-file-systems)))
  101. EOF
  102. if guix system build "$tmpfile" -n 2> "$errorfile"
  103. then false
  104. else
  105. if test "`guile -c '(display (effective-version))'`" = 3.0
  106. then
  107. # FIXME: With Guile 3.3.0 the error is reported on line 11.
  108. # See <https://bugs.gnu.org/38388>.
  109. grep "$tmpfile:[0-9]\+:[0-9]\+:.*GRUB-config.*[Uu]nbound variable" "$errorfile"
  110. elif test "`guile -c '(display (effective-version))'`" = 2.2
  111. then
  112. # FIXME: With Guile 2.2.0 the error is reported on line 4.
  113. # See <http://bugs.gnu.org/26107>.
  114. grep "$tmpfile:[49]:[0-9]\+:.*GRUB-config.*[Uu]nbound variable" "$errorfile"
  115. else
  116. grep "$tmpfile:9:[0-9]\+:.*GRUB-config.*[Uu]nbound variable" "$errorfile"
  117. fi
  118. fi
  119. cat > "$tmpfile" <<EOF
  120. (use-modules (gnu)) ; 1
  121. (operating-system ; 3
  122. (file-systems (cons (file-system ; 4
  123. (device (file-system-label "root"))
  124. (mount-point "/") ; 6
  125. (type "ext4")))) ; 7 (!!)
  126. %base-file-systems)
  127. EOF
  128. if guix system build "$tmpfile" -n 2> "$errorfile"
  129. then false
  130. else
  131. # Here '%base-file-systems' appears as if it were a field specified of the
  132. # enclosing 'operating-system' form due to parenthesis mismatch.
  133. grep "$tmpfile:3:[0-9]\+:.*%base-file-system.*invalid field specifier" \
  134. "$errorfile"
  135. fi
  136. OS_BASE='
  137. (host-name "antelope")
  138. (timezone "Europe/Paris")
  139. (locale "en_US.UTF-8")
  140. (bootloader (bootloader-configuration
  141. (bootloader grub-bootloader)
  142. (target "/dev/sdX")))
  143. (file-systems (cons (file-system
  144. (device (file-system-label "root"))
  145. (mount-point "/")
  146. (type "ext4"))
  147. %base-file-systems))
  148. '
  149. # Reporting of duplicate service identifiers.
  150. cat > "$tmpfile" <<EOF
  151. (use-modules (gnu))
  152. (use-service-modules networking)
  153. (operating-system
  154. $OS_BASE
  155. (services (cons* (service dhcp-client-service-type)
  156. (service dhcp-client-service-type) ;twice!
  157. %base-services)))
  158. EOF
  159. if guix system vm "$tmpfile" 2> "$errorfile"
  160. then
  161. # This must not succeed.
  162. exit 1
  163. else
  164. grep "service 'networking'.*more than once" "$errorfile"
  165. fi
  166. # Reporting unmet shepherd requirements.
  167. cat > "$tmpfile" <<EOF
  168. (use-modules (gnu) (gnu services shepherd))
  169. (use-service-modules networking)
  170. (define buggy-service-type
  171. (shepherd-service-type
  172. 'buggy
  173. (lambda _
  174. (shepherd-service
  175. (provision '(buggy!))
  176. (requirement '(does-not-exist))
  177. (start #t)))
  178. (description "Buggy.")))
  179. (operating-system
  180. $OS_BASE
  181. (services (cons (service buggy-service-type #t)
  182. %base-services)))
  183. EOF
  184. if guix system build "$tmpfile" 2> "$errorfile"
  185. then
  186. exit 1
  187. else
  188. grep "service 'buggy!'.*'does-not-exist'.*not provided" "$errorfile"
  189. fi
  190. # Reporting inconsistent user accounts.
  191. make_user_config ()
  192. {
  193. cat > "$tmpfile" <<EOF
  194. (use-modules (gnu))
  195. (use-service-modules networking)
  196. (operating-system
  197. (host-name "antelope")
  198. (timezone "Europe/Paris")
  199. (locale "en_US.UTF-8")
  200. (bootloader (bootloader-configuration
  201. (bootloader grub-bootloader)
  202. (target "/dev/sdX")))
  203. (file-systems (cons (file-system
  204. (device (file-system-label "root"))
  205. (mount-point "/")
  206. (type "ext4"))
  207. %base-file-systems))
  208. (users (list (user-account
  209. (name "dave")
  210. (home-directory "/home/dave")
  211. (group "$1")
  212. (supplementary-groups '("$2"))))))
  213. EOF
  214. }
  215. make_user_config "users" "wheel"
  216. guix system build "$tmpfile" -n # succeeds
  217. guix system build "$tmpfile" -d # succeeds
  218. guix system build "$tmpfile" -d | grep '\.drv$'
  219. guix system vm "$tmpfile" -d # succeeds
  220. guix system vm "$tmpfile" -d | grep '\.drv$'
  221. # Make sure the behavior is deterministic (<https://bugs.gnu.org/32652>).
  222. drv1="`guix system vm "$tmpfile" -d`"
  223. drv2="`guix system vm "$tmpfile" -d`"
  224. test "$drv1" = "$drv2"
  225. drv1="`guix system image -t iso9660 "$tmpfile" -d`"
  226. drv2="`guix system image -t iso9660 "$tmpfile" -d`"
  227. test "$drv1" = "$drv2"
  228. # Check whether the graph commands work as expected.
  229. guix system extension-graph "$tmpfile" | grep 'label = "file-systems"'
  230. guix system shepherd-graph "$tmpfile" | grep 'label = "guix-daemon"'
  231. make_user_config "group-that-does-not-exist" "users"
  232. if guix system build "$tmpfile" -n 2> "$errorfile"
  233. then false
  234. else grep "primary group.*group-that-does-not-exist.*undeclared" "$errorfile"; fi
  235. make_user_config "users" "group-that-does-not-exist"
  236. if guix system build "$tmpfile" -n 2> "$errorfile"
  237. then false
  238. else grep "supplementary group.*group-that-does-not-exist.*undeclared" "$errorfile"; fi
  239. # Try 'local-file' and relative file name resolution.
  240. cat > "$tmpdir/config.scm"<<EOF
  241. (use-modules (gnu))
  242. (use-service-modules networking)
  243. (operating-system
  244. $OS_BASE
  245. (services (cons (service tor-service-type
  246. (tor-configuration
  247. (config-file (local-file "my-torrc"))))
  248. %base-services)))
  249. EOF
  250. cat > "$tmpdir/my-torrc"<<EOF
  251. # This is an example file.
  252. EOF
  253. # In both cases 'my-torrc' should be properly resolved.
  254. guix system build "$tmpdir/config.scm" -n
  255. (cd "$tmpdir"; guix system build "config.scm" -n)
  256. # Check that we get a warning when passing 'local-file' a non-literal relative
  257. # file name.
  258. cat > "$tmpdir/config.scm" <<EOF
  259. (use-modules (guix))
  260. (define (bad-local-file file)
  261. (local-file file))
  262. (bad-local-file "whatever.scm")
  263. EOF
  264. ! guix system build "$tmpdir/config.scm" -n
  265. guix system build "$tmpdir/config.scm" -n 2>&1 | \
  266. grep "config\.scm:4:2: warning:.*whatever.*relative to current directory"
  267. # Searching.
  268. guix system search tor | grep "^name: tor"
  269. guix system search tor | grep "^shepherdnames: tor"
  270. guix system search anonym network | grep "^name: tor"
  271. guix system search . > "$tmpdir/search"
  272. test $(wc -l < "$tmpdir/search") -gt 500
  273. rm "$tmpdir/search"
  274. # Below, use -n (--dry-run) for the tests because if we actually tried to
  275. # build these images, the commands would take hours to run in the worst case.
  276. # Verify that the examples can be built.
  277. for example in gnu/system/examples/*.tmpl; do
  278. if echo "$example" | grep hurd; then
  279. target="--target=i586-pc-gnu"
  280. else
  281. target=
  282. fi
  283. guix system -n disk-image $target "$example"
  284. done
  285. # Verify that the images can be built.
  286. guix system -n vm gnu/system/examples/vm-image.tmpl
  287. guix system -n image gnu/system/images/pinebook-pro.scm
  288. guix system -n image -t qcow2 gnu/system/examples/vm-image.tmpl
  289. guix system -n image -t iso9660 gnu/system/examples/bare-bones.tmpl
  290. guix system -n docker-image gnu/system/examples/docker-image.tmpl
  291. # Verify that at least the raw image type is available.
  292. guix system --list-image-types | grep "raw"