aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2019-04-02 10:57:24 +0200
committerLudovic Courtès <ludo@gnu.org>2019-04-02 18:15:37 +0200
commit1ccc0f807d3f22fa9ade1c607c112e04df833a72 (patch)
tree4b63fa9c0aa1b658b126ff14858f4be6f21f8503
parentaf76c020bf19de5fe2e92f31d8b85cbd55c481de (diff)
downloadgnu-guix-1ccc0f807d3f22fa9ade1c607c112e04df833a72.tar
gnu-guix-1ccc0f807d3f22fa9ade1c607c112e04df833a72.tar.gz
environment: '-C' creates namespaces where the user is not root.
* guix/scripts/environment.scm (launch-environment/container): Add UID and GID. Use them in PASSWD and GROUPS. Pass them as #:guest-uid and #:guest-gid to 'call-with-container'. * tests/guix-environment-container.sh: Test the inner UID. In '--user' test, replace hard-coded 0 with 1000. * doc/guix.texi (Invoking guix environment): Adjust accordingly.
-rw-r--r--doc/guix.texi13
-rw-r--r--guix/scripts/environment.scm8
-rw-r--r--tests/guix-environment-container.sh15
3 files changed, 28 insertions, 8 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 616970b505..616c2ef305 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -4557,9 +4557,11 @@ Run @var{command} within an isolated container. The current working
directory outside the container is mapped inside the container.
Additionally, unless overridden with @code{--user}, a dummy home
directory is created that matches the current user's home directory, and
-@file{/etc/passwd} is configured accordingly. The spawned process runs
-as the current user outside the container, but has root privileges in
-the context of the container.
+@file{/etc/passwd} is configured accordingly.
+
+The spawned process runs as the current user outside the container. Inside
+the container, it has the same UID and GID as the current user, unless
+@option{--user} is passed (see below.)
@item --network
@itemx -N
@@ -4587,8 +4589,9 @@ the environment.
@itemx -u @var{user}
For containers, use the username @var{user} in place of the current
user. The generated @file{/etc/passwd} entry within the container will
-contain the name @var{user}; the home directory will be
-@file{/home/USER}; and no user GECOS data will be copied. @var{user}
+contain the name @var{user}, the home directory will be
+@file{/home/@var{user}}, and no user GECOS data will be copied. Furthermore,
+the UID and GID inside the container are 1000. @var{user}
need not exist on the system.
Additionally, any shared or exposed path (see @code{--share} and
diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm
index c27edc7982..2d1ba4c938 100644
--- a/guix/scripts/environment.scm
+++ b/guix/scripts/environment.scm
@@ -459,17 +459,19 @@ will be used for the passwd entry. LINK-PROFILE? creates a symbolic link from
(return
(let* ((cwd (getcwd))
(home (getenv "HOME"))
+ (uid (if user 1000 (getuid)))
+ (gid (if user 1000 (getgid)))
(passwd (let ((pwd (getpwuid (getuid))))
(password-entry
(name (or user (passwd:name pwd)))
(real-name (if user
""
(passwd:gecos pwd)))
- (uid 0) (gid 0) (shell bash)
+ (uid uid) (gid gid) (shell bash)
(directory (if user
(string-append "/home/" user)
(passwd:dir pwd))))))
- (groups (list (group-entry (name "users") (gid 0))
+ (groups (list (group-entry (name "users") (gid gid))
(group-entry (gid 65534) ;the overflow GID
(name "overflow"))))
(home-dir (password-entry-directory passwd))
@@ -541,6 +543,8 @@ will be used for the passwd entry. LINK-PROFILE? creates a symbolic link from
;; A container's environment is already purified, so no need to
;; request it be purified again.
(launch-environment command profile manifest #:pure? #f)))
+ #:guest-uid uid
+ #:guest-gid gid
#:namespaces (if network?
(delq 'net %namespaces) ; share host network
%namespaces)))))))
diff --git a/tests/guix-environment-container.sh b/tests/guix-environment-container.sh
index f2221af95b..78507f76c0 100644
--- a/tests/guix-environment-container.sh
+++ b/tests/guix-environment-container.sh
@@ -44,6 +44,19 @@ else
test $? = 42
fi
+# By default, the UID inside the container should be the same as outside.
+uid="`id -u`"
+inner_uid="`guix environment -C --ad-hoc --bootstrap guile-bootstrap \
+ -- guile -c '(display (getuid))'`"
+test $inner_uid = $uid
+
+# When '--user' is passed, the UID should be 1000. (Note: Use a separate HOME
+# so that we don't run into problems when the test directory is under /home.)
+export tmpdir
+inner_uid="`HOME=$tmpdir guix environment -C --ad-hoc --bootstrap guile-bootstrap \
+ --user=gnu-guix -- guile -c '(display (getuid))'`"
+test $inner_uid = 1000
+
if test "x$USER" = "x"; then USER="`id -un`"; fi
# Check whether /etc/passwd and /etc/group are valid.
@@ -123,7 +136,7 @@ rm $tmpdir/mounts
# Test that user can be mocked.
usertest='(exit (and (string=? (getenv "HOME") "/home/foognu")
- (string=? (passwd:name (getpwuid 0)) "foognu")
+ (string=? (passwd:name (getpwuid 1000)) "foognu")
(file-exists? "/home/foognu/umock")))'
touch "$tmpdir/umock"
HOME="$tmpdir" guix environment --bootstrap --container --user=foognu \