environment: Use (gnu build accounts) for /etc/passwd handling.

* guix/scripts/environment.scm (launch-environment/container): Remove
call to 'mock-passwd'; instantiate a <password-entry> instead.  Call
'write-passwd' to write the pasword database instead of using custom
code.
(mock-passwd): Remove.
* tests/guix-environment-container.sh: Test 'getpwuid'.
This commit is contained in:
Ludovic Courtès 2019-03-26 12:12:41 +01:00
parent ec8bc4a34e
commit 8a9922bdee
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
2 changed files with 19 additions and 41 deletions

View file

@ -33,6 +33,7 @@ (define-module (guix scripts environment)
#:use-module (guix scripts)
#:use-module (guix scripts build)
#:use-module (gnu build linux-container)
#:use-module (gnu build accounts)
#:use-module (gnu system linux-container)
#:use-module (gnu system file-systems)
#:use-module (gnu packages)
@ -458,10 +459,17 @@ (define* (launch-environment/container #:key command bash user user-mappings
(return
(let* ((cwd (getcwd))
(home (getenv "HOME"))
(passwd (mock-passwd (getpwuid (getuid))
user
bash))
(home-dir (passwd:dir passwd))
(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)
(directory (if user
(string-append "/home/" user)
(passwd:dir pwd))))))
(home-dir (password-entry-directory passwd))
;; Bind-mount all requisite store items, user-specified mappings,
;; /bin/sh, the current working directory, and possibly networking
;; configuration files within the container.
@ -519,17 +527,7 @@ (define* (launch-environment/container #:key command bash user user-mappings
;; to read it, such as 'git clone' over SSH, a valid use-case when
;; sharing the host's network namespace.
(mkdir-p "/etc")
(call-with-output-file "/etc/passwd"
(lambda (port)
(display (string-join (list (passwd:name passwd)
"x" ; but there is no shadow
"0" "0" ; user is now root
(passwd:gecos passwd)
(passwd:dir passwd)
bash)
":")
port)
(newline port)))
(write-passwd (list passwd))
;; For convenience, start in the user's current working
;; directory rather than the root directory.
@ -543,32 +541,6 @@ (define* (launch-environment/container #:key command bash user user-mappings
(delq 'net %namespaces) ; share host network
%namespaces)))))))
(define (mock-passwd passwd user-override shell)
"Generate mock information for '/etc/passwd'. If USER-OVERRIDE is not '#f',
it is expected to be a string representing the mock username; it will produce
a user of that name, with a home directory of '/home/USER-OVERRIDE', and no
GECOS field. If USER-OVERRIDE is '#f', data will be inherited from PASSWD.
In either case, the shadow password and UID/GID are cleared, since the user
runs as root within the container. SHELL will always be used in place of the
shell in PASSWD.
The resulting vector is suitable for use with Guile's POSIX user procedures.
See passwd(5) for more information each of the fields."
(if user-override
(vector
user-override
"x" "0" "0" ;; no shadow, user is now root
"" ;; no personal information
(user-override-home user-override)
shell)
(vector
(passwd:name passwd)
"x" "0" "0" ;; no shadow, user is now root
(passwd:gecos passwd)
(passwd:dir passwd)
shell)))
(define (user-override-home user)
"Return home directory for override user USER."
(string-append "/home/" user))

View file

@ -44,6 +44,12 @@ else
test $? = 42
fi
if test "x$USER" = "x"; then USER="`id -un`"; fi
# Check whether /etc/passwd is valid.
guix environment -C --ad-hoc --bootstrap guile-bootstrap \
-- guile -c "(exit (string=? \"$USER\" (passwd:name (getpwuid (getuid)))))"
# Make sure file-not-found errors in mounts are reported.
if guix environment --container --ad-hoc --bootstrap guile-bootstrap \
--expose=/does-not-exist -- guile -c 1 2> "$tmpdir/error"