system: images: Add wsl2 module.

* gnu/system/images/wsl2.scm: New file.
* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
* doc/guix.texi ("System Images"): Document it.

Signed-off-by: Mathieu Othacehe <othacehe@gnu.org>
This commit is contained in:
Alex Griffin 2022-09-10 10:03:10 +02:00 committed by Mathieu Othacehe
parent 233cf9f036
commit c8112f3bd9
No known key found for this signature in database
GPG Key ID: 8354763531769CA6
3 changed files with 185 additions and 0 deletions

View File

@ -41476,6 +41476,8 @@ one or multiple partitions.
@item @code{tarball}, a tar.gz image archive.
@item @code{wsl2}, a WSL2 image.
@end itemize
@item @code{platform} (default: @code{#false})
@ -41842,6 +41844,17 @@ Build an image similar to the one built by the @code{hurd-image-type}
but with the @code{format} set to @code{'compressed-qcow2}.
@end defvr
@defvr {Scheme Variable} wsl2-image-type
Build an image for the @acronym{WSL2, Windows Subsystem for Linux 2}.
It can be imported by running:
@example
wsl --import Guix ./guix ./wsl2-image.tar.gz
wsl -d Guix
@end example
@end defvr
So, if we get back to the @code{guix system image} command taking an
@code{operating-system} declaration as argument. By default, the
@code{efi-raw-image-type} is used to turn the provided

View File

@ -53,6 +53,7 @@
# Copyright © 2022 John Kehayias <john.kehayias@protonmail.com>
# Copyright © 2022 muradm <mail@muradm.net>
# Copyright © 2022 Hilton Chain <hako@ultrarare.space>
# Copyright © 2022 Alex Griffin <a@ajgrf.com>
#
# This file is part of GNU Guix.
#
@ -718,6 +719,7 @@ GNU_SYSTEM_MODULES = \
%D%/system/images/pine64.scm \
%D%/system/images/pinebook-pro.scm \
%D%/system/images/rock64.scm \
%D%/system/images/wsl2.scm \
\
%D%/machine.scm \
\

170
gnu/system/images/wsl2.scm Normal file
View File

@ -0,0 +1,170 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2022 Alex Griffin <a@ajgrf.com>
;;; Copyright © 2022 Mathieu Othacehe <othacehe@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (gnu system images wsl2)
#:use-module (gnu bootloader)
#:use-module (gnu image)
#:use-module (gnu packages admin)
#:use-module (gnu packages base)
#:use-module (gnu packages bash)
#:use-module (gnu packages guile)
#:use-module (gnu packages linux)
#:use-module (gnu services)
#:use-module (gnu services base)
#:use-module (gnu system)
#:use-module (gnu system image)
#:use-module (gnu system shadow)
#:use-module (guix build-system trivial)
#:use-module (guix gexp)
#:use-module (guix packages)
#:export (wsl-boot-program
wsl-os
wsl2-image))
(define (wsl-boot-program user)
"Program that runs the system boot script, then starts a login shell as
USER."
(program-file
"wsl-boot-program"
(with-imported-modules '((guix build syscalls))
#~(begin
(use-modules (guix build syscalls))
(unless (file-exists? "/run/current-system")
(let ((shepherd-socket "/var/run/shepherd/socket"))
;; Clean up this file so we can wait for it later.
(when (file-exists? shepherd-socket)
(delete-file shepherd-socket))
;; Child process boots the system and is replaced by shepherd.
(when (zero? (primitive-fork))
(let* ((system-generation
(readlink "/var/guix/profiles/system"))
(system (readlink
(string-append
(if (absolute-file-name? system-generation)
""
"/var/guix/profiles/")
system-generation))))
(setenv "GUIX_NEW_SYSTEM" system)
(execl #$(file-append guile-3.0 "/bin/guile")
"guile"
"--no-auto-compile"
(string-append system "/boot"))))
;; Parent process waits for shepherd before continuing.
(while (not (file-exists? shepherd-socket))
(sleep 1))))
(let* ((pw (getpw #$user))
(shell (passwd:shell pw))
(sudo #+(file-append sudo "/bin/sudo"))
(args (cdr (command-line))))
;; Save the value of $PATH set by WSL. Useful for finding
;; Windows binaries to run with WSL's binfmt interop.
(setenv "WSLPATH" (getenv "PATH"))
;; /run is mounted with the nosuid flag by WSL. This prevents
;; running the /run/setuid-programs. Remount it without this flag
;; as a workaround. See:
;; https://github.com/microsoft/WSL/issues/8716.
(mount #f "/run" #f
MS_REMOUNT
#:update-mtab? #f)
;; Start login shell as user.
(apply execl sudo "sudo"
"--preserve-env=WSLPATH"
"-u" #$user
"--"
shell "-l" args))))))
(define dummy-package
(package
(name "dummy")
(version "0")
(source #f)
(build-system trivial-build-system)
(arguments
`(#:modules ((guix build utils))
#:target #f
#:builder (begin
(use-modules (guix build utils))
(let* ((out (assoc-ref %outputs "out"))
(dummy (string-append out "/dummy")))
(mkdir-p out)
(call-with-output-file dummy
(const #t))))))
(home-page #f)
(synopsis #f)
(description #f)
(license #f)))
(define dummy-bootloader
(bootloader
(name 'dummy-bootloader)
(package dummy-package)
(configuration-file "/dev/null")
(configuration-file-generator
(lambda (. _rest)
(plain-file "dummy-bootloader" "")))
(installer #~(const #t))))
(define dummy-kernel dummy-package)
(define (dummy-initrd . _rest)
(plain-file "dummy-initrd" ""))
(define-public wsl-os
(operating-system
(host-name "gnu")
(timezone "Etc/UTC")
(bootloader
(bootloader-configuration
(bootloader dummy-bootloader)))
(kernel dummy-kernel)
(initrd dummy-initrd)
(initrd-modules '())
(firmware '())
(file-systems '())
(users (cons* (user-account
(name "guest")
(group "users")
(supplementary-groups '("wheel")) ; allow use of sudo
(password "")
(comment "Guest of GNU"))
(user-account
(inherit %root-account)
(shell (wsl-boot-program "guest")))
%base-user-accounts))
(services
(list
(service guix-service-type)
(service special-files-service-type
`(("/bin/sh" ,(file-append bash "/bin/bash"))
("/bin/mount" ,(file-append util-linux "/bin/mount"))
("/usr/bin/env" ,(file-append coreutils "/bin/env"))))))))
(define wsl2-image
(image
(inherit
(os->image wsl-os
#:type wsl2-image-type))
(name 'wsl2-image)))
wsl2-image