guix-system.sh 10 KB

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