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 @@
#:use-module (guix scripts) #:use-module (guix scripts)
#:use-module (guix scripts build) #:use-module (guix scripts build)
#:use-module (gnu build linux-container) #:use-module (gnu build linux-container)
#:use-module (gnu build accounts)
#:use-module (gnu system linux-container) #:use-module (gnu system linux-container)
#:use-module (gnu system file-systems) #:use-module (gnu system file-systems)
#:use-module (gnu packages) #:use-module (gnu packages)
@ -458,10 +459,17 @@ will be used for the passwd entry. LINK-PROFILE? creates a symbolic link from
(return (return
(let* ((cwd (getcwd)) (let* ((cwd (getcwd))
(home (getenv "HOME")) (home (getenv "HOME"))
(passwd (mock-passwd (getpwuid (getuid)) (passwd (let ((pwd (getpwuid (getuid))))
user (password-entry
bash)) (name (or user (passwd:name pwd)))
(home-dir (passwd:dir passwd)) (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, ;; Bind-mount all requisite store items, user-specified mappings,
;; /bin/sh, the current working directory, and possibly networking ;; /bin/sh, the current working directory, and possibly networking
;; configuration files within the container. ;; configuration files within the container.
@ -519,17 +527,7 @@ will be used for the passwd entry. LINK-PROFILE? creates a symbolic link from
;; to read it, such as 'git clone' over SSH, a valid use-case when ;; to read it, such as 'git clone' over SSH, a valid use-case when
;; sharing the host's network namespace. ;; sharing the host's network namespace.
(mkdir-p "/etc") (mkdir-p "/etc")
(call-with-output-file "/etc/passwd" (write-passwd (list 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)))
;; For convenience, start in the user's current working ;; For convenience, start in the user's current working
;; directory rather than the root directory. ;; directory rather than the root directory.
@ -543,32 +541,6 @@ will be used for the passwd entry. LINK-PROFILE? creates a symbolic link from
(delq 'net %namespaces) ; share host network (delq 'net %namespaces) ; share host network
%namespaces))))))) %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) (define (user-override-home user)
"Return home directory for override user USER." "Return home directory for override user USER."
(string-append "/home/" user)) (string-append "/home/" user))

View File

@ -44,6 +44,12 @@ else
test $? = 42 test $? = 42
fi 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. # Make sure file-not-found errors in mounts are reported.
if guix environment --container --ad-hoc --bootstrap guile-bootstrap \ if guix environment --container --ad-hoc --bootstrap guile-bootstrap \
--expose=/does-not-exist -- guile -c 1 2> "$tmpdir/error" --expose=/does-not-exist -- guile -c 1 2> "$tmpdir/error"