Subject: [bug#75595] [PATCH 0/4] 'guix container run' and isolated inferiors

From: Ludovic Courtès <[email-masked]>
Date: Wed, 15 Jan 2025 23:13:38 +0100

Hello!

You might remember that back in 2018, I sent a ‘guix run’ command
that would let you run programs in a container with hopefully
exactly the authority it needs:

  https://lists.gnu.org/archive/html/help-guix/2018-01/msg00108.html

This patch series adds an improved version of that command
as ‘guix container run’.  By default, it figures out what extra
authority to give: for X11 programs, it lets ‘DISPLAY’ through and
bind-mounts /tmp/.X11-unix, for DBus programs it maps /etc/machine-id,
and so on.

Alternatively, you can use ‘--bare’ and you get a bare container in
the style of ‘guix shell -C’.  It supports ‘-N’, ‘--expose’, and other
options found in ‘guix shell -C’ and related commands.

~~~

But really, my initial motivation was to run inferiors in a container.
Christopher implemented that years ago, using (gnu build linux-container):

  https://issues.guix.gnu.org/34638

There were small issues that needed to be addressed, but the main
problem I would have with it today is the fact that we’d call ‘clone’
directly, making it effectively unusuable in a multi-threaded context
(see horror story in <https://issues.guix.gnu.org/55441>, which led
to the implementation of ‘spawn’ in Guile by Josselin.)

So I thought that by having a command-line interface to
‘call-with-container’ (!), which is essentially what ‘guix container run’
is, we would be able to use ‘posix_spawn’ to run that CLI and spawn
inferiors without risk.  Incidentally, it is rather simple to implement
and reason about.

This is what the last patch does.  I didn’t add tests: the ‘guix’ binary
needs to be in the store, which makes it hard to test.  But here’s an
example session:

--8<---------------cut here---------------start------------->8---
$ ./pre-inst-env guile -q
GNU Guile 3.0.9
Copyright (C) 1995-2023 Free Software Foundation, Inc.

Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.

Enter `,help' for help.
scheme@(guile-user)> ,use(guix inferior)
scheme@(guile-user)> (open-inferior "/home/ludo/.config/guix/current" #:isolated? #t)
$1 = #<inferior pipe (0 1 1) 7f0adf5923c0>
scheme@(guile-user)> (inferior-eval '(use-modules (ice-9 ftw)) $1)
$2 = #<inferior-object #<unspecified>>
scheme@(guile-user)> (inferior-eval '(scandir "/home/ludo") $1)
$3 = ("." ".." ".cache")
scheme@(guile-user)> ,use(guix)
scheme@(guile-user)> (define s (open-connection))
scheme@(guile-user)> (inferior-eval-with-store $1 s `(lambda (s) (add-text-to-store s "isolated" "hi from inferior!")))
$4 = "/gnu/store/kvnxfbcwn5sdr02y75v2w4fswns0ql8d-isolated"
--8<---------------cut here---------------end--------------->8---

Thoughts?

Ludo’.

Ludovic Courtès (4):
  DRAFT container: Add ‘run’ sub-command.
  tests: Make ‘inferior-eval-with-store’ test more robust.
  inferior: Store the bridge directory name in <inferior>.
  inferior: Allow running inferiors in a container.

 Makefile.am                    |   3 +-
 guix/inferior.scm              | 184 ++++++++++++++------
 guix/scripts/container.scm     |   4 +-
 guix/scripts/container/run.scm | 301 +++++++++++++++++++++++++++++++++
 tests/inferior.scm             |  19 ++-
 5 files changed, 446 insertions(+), 65 deletions(-)
 create mode 100644 guix/scripts/container/run.scm

base-commit: d804997897d2a531e0e3186e64df798a7e2e0d1a
-- 
2.47.1