wsl2.scm 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2022 Alex Griffin <a@ajgrf.com>
  3. ;;; Copyright © 2022 Mathieu Othacehe <othacehe@gnu.org>
  4. ;;;
  5. ;;; This file is part of GNU Guix.
  6. ;;;
  7. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  8. ;;; under the terms of the GNU General Public License as published by
  9. ;;; the Free Software Foundation; either version 3 of the License, or (at
  10. ;;; your option) any later version.
  11. ;;;
  12. ;;; GNU Guix is distributed in the hope that it will be useful, but
  13. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ;;; GNU General Public License for more details.
  16. ;;;
  17. ;;; You should have received a copy of the GNU General Public License
  18. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  19. (define-module (gnu system images wsl2)
  20. #:use-module (gnu bootloader)
  21. #:use-module (gnu image)
  22. #:use-module (gnu packages admin)
  23. #:use-module (gnu packages base)
  24. #:use-module (gnu packages bash)
  25. #:use-module (gnu packages guile)
  26. #:use-module (gnu packages linux)
  27. #:use-module (gnu services)
  28. #:use-module (gnu services base)
  29. #:use-module (gnu system)
  30. #:use-module (gnu system image)
  31. #:use-module (gnu system shadow)
  32. #:use-module (guix build-system trivial)
  33. #:use-module (guix gexp)
  34. #:use-module (guix packages)
  35. #:export (wsl-boot-program
  36. wsl-os
  37. wsl2-image))
  38. (define (wsl-boot-program user)
  39. "Program that runs the system boot script, then starts a login shell as
  40. USER."
  41. (program-file
  42. "wsl-boot-program"
  43. (with-imported-modules '((guix build syscalls))
  44. #~(begin
  45. (use-modules (guix build syscalls))
  46. (unless (file-exists? "/run/current-system")
  47. (let ((shepherd-socket "/var/run/shepherd/socket"))
  48. ;; Clean up this file so we can wait for it later.
  49. (when (file-exists? shepherd-socket)
  50. (delete-file shepherd-socket))
  51. ;; Child process boots the system and is replaced by shepherd.
  52. (when (zero? (primitive-fork))
  53. (let* ((system-generation
  54. (readlink "/var/guix/profiles/system"))
  55. (system (readlink
  56. (string-append
  57. (if (absolute-file-name? system-generation)
  58. ""
  59. "/var/guix/profiles/")
  60. system-generation))))
  61. (setenv "GUIX_NEW_SYSTEM" system)
  62. (execl #$(file-append guile-3.0 "/bin/guile")
  63. "guile"
  64. "--no-auto-compile"
  65. (string-append system "/boot"))))
  66. ;; Parent process waits for shepherd before continuing.
  67. (while (not (file-exists? shepherd-socket))
  68. (sleep 1))))
  69. (let* ((pw (getpw #$user))
  70. (shell (passwd:shell pw))
  71. (sudo #+(file-append sudo "/bin/sudo"))
  72. (args (cdr (command-line))))
  73. ;; Save the value of $PATH set by WSL. Useful for finding
  74. ;; Windows binaries to run with WSL's binfmt interop.
  75. (setenv "WSLPATH" (getenv "PATH"))
  76. ;; /run is mounted with the nosuid flag by WSL. This prevents
  77. ;; running the /run/setuid-programs. Remount it without this flag
  78. ;; as a workaround. See:
  79. ;; https://github.com/microsoft/WSL/issues/8716.
  80. (mount #f "/run" #f
  81. MS_REMOUNT
  82. #:update-mtab? #f)
  83. ;; Start login shell as user.
  84. (apply execl sudo "sudo"
  85. "--preserve-env=WSLPATH"
  86. "-u" #$user
  87. "--"
  88. shell "-l" args))))))
  89. (define dummy-package
  90. (package
  91. (name "dummy")
  92. (version "0")
  93. (source #f)
  94. (build-system trivial-build-system)
  95. (arguments
  96. `(#:modules ((guix build utils))
  97. #:target #f
  98. #:builder (begin
  99. (use-modules (guix build utils))
  100. (let* ((out (assoc-ref %outputs "out"))
  101. (dummy (string-append out "/dummy")))
  102. (mkdir-p out)
  103. (call-with-output-file dummy
  104. (const #t))))))
  105. (home-page #f)
  106. (synopsis #f)
  107. (description #f)
  108. (license #f)))
  109. (define dummy-bootloader
  110. (bootloader
  111. (name 'dummy-bootloader)
  112. (package dummy-package)
  113. (configuration-file "/dev/null")
  114. (configuration-file-generator
  115. (lambda (. _rest)
  116. (plain-file "dummy-bootloader" "")))
  117. (installer #~(const #t))))
  118. (define dummy-kernel dummy-package)
  119. (define (dummy-initrd . _rest)
  120. (plain-file "dummy-initrd" ""))
  121. (define-public wsl-os
  122. (operating-system
  123. (host-name "gnu")
  124. (timezone "Etc/UTC")
  125. (bootloader
  126. (bootloader-configuration
  127. (bootloader dummy-bootloader)))
  128. (kernel dummy-kernel)
  129. (initrd dummy-initrd)
  130. (initrd-modules '())
  131. (firmware '())
  132. (file-systems '())
  133. (users (cons* (user-account
  134. (name "guest")
  135. (group "users")
  136. (supplementary-groups '("wheel")) ; allow use of sudo
  137. (password "")
  138. (comment "Guest of GNU"))
  139. (user-account
  140. (inherit %root-account)
  141. (shell (wsl-boot-program "guest")))
  142. %base-user-accounts))
  143. (services
  144. (list
  145. (service guix-service-type)
  146. (service special-files-service-type
  147. `(("/bin/sh" ,(file-append bash "/bin/bash"))
  148. ("/bin/mount" ,(file-append util-linux "/bin/mount"))
  149. ("/usr/bin/env" ,(file-append coreutils "/bin/env"))))))))
  150. (define wsl2-image
  151. (image
  152. (inherit
  153. (os->image wsl-os
  154. #:type wsl2-image-type))
  155. (name 'wsl2-image)))
  156. wsl2-image