scripts: environment: Add --no-cwd.

* doc/guix.texi (Invoking guix environment): Add --no-cwd.
* guix/scripts/environment.scm (show-help, %options): Add --no-cwd.
(launch-environment/container): Add 'map-cwd?' param; only add mapping
for cwd if #t.  Only change to cwd within container if #t, otherwise
home.
(guix-environment): Error if --no-cwd without --container.  Provide
'(not no-cwd?)' to launch-environment/container as 'map-cwd?'.
* tests/guix-environment.sh: Add test for no-cwd.

Co-authored-by: Mike Gerwitz <mtg@gnu.org>
This commit is contained in:
Carl Dong 2019-06-29 17:15:11 -04:00 committed by Carl Dong
parent a655d504aa
commit b6dc08393e
No known key found for this signature in database
GPG key ID: 0CC52153197991A5
3 changed files with 43 additions and 9 deletions

View file

@ -4657,6 +4657,14 @@ While this will limit the leaking of user identity through home paths
and each of the user fields, this is only one useful component of a and each of the user fields, this is only one useful component of a
broader privacy/anonymity solution---not one in and of itself. broader privacy/anonymity solution---not one in and of itself.
@item --no-cwd
For containers, the default behavior is to share the current working
directory with the isolated container and immediately change to that
directory within the container. If this is undesirable, @code{--no-cwd}
will cause the current working directory to @emph{not} be automatically
shared and will change to the user's home directory within the container
instead. See also @code{--user}.
@item --expose=@var{source}[=@var{target}] @item --expose=@var{source}[=@var{target}]
For containers, expose the file system @var{source} from the host system For containers, expose the file system @var{source} from the host system
as the read-only file system @var{target} within the container. If as the read-only file system @var{target} within the container. If

View file

@ -161,6 +161,10 @@ (define (show-help)
-u, --user=USER instead of copying the name and home of the current -u, --user=USER instead of copying the name and home of the current
user into an isolated container, use the name USER user into an isolated container, use the name USER
with home directory /home/USER")) with home directory /home/USER"))
(display (G_ "
--no-cwd do not share current working directory with an
isolated container"))
(display (G_ " (display (G_ "
--share=SPEC for containers, share writable host file system --share=SPEC for containers, share writable host file system
according to SPEC")) according to SPEC"))
@ -269,6 +273,9 @@ (define %options
(lambda (opt name arg result) (lambda (opt name arg result)
(alist-cons 'user arg (alist-cons 'user arg
(alist-delete 'user result eq?)))) (alist-delete 'user result eq?))))
(option '("no-cwd") #f #f
(lambda (opt name arg result)
(alist-cons 'no-cwd? #t result)))
(option '("share") #t #f (option '("share") #t #f
(lambda (opt name arg result) (lambda (opt name arg result)
(alist-cons 'file-system-mapping (alist-cons 'file-system-mapping
@ -444,7 +451,8 @@ (define* (launch-environment/fork command profile manifest
((_ . status) status))))) ((_ . status) status)))))
(define* (launch-environment/container #:key command bash user user-mappings (define* (launch-environment/container #:key command bash user user-mappings
profile manifest link-profile? network?) profile manifest link-profile? network?
map-cwd?)
"Run COMMAND within a container that features the software in PROFILE. "Run COMMAND within a container that features the software in PROFILE.
Environment variables are set according to the search paths of MANIFEST. Environment variables are set according to the search paths of MANIFEST.
The global shell is BASH, a file name for a GNU Bash binary in the The global shell is BASH, a file name for a GNU Bash binary in the
@ -483,11 +491,13 @@ (define* (launch-environment/container #:key command bash user user-mappings
(override-user-mappings (override-user-mappings
user home user home
(append user-mappings (append user-mappings
;; Current working directory. ;; Share current working directory, unless asked not to.
(list (file-system-mapping (if map-cwd?
(source cwd) (list (file-system-mapping
(target cwd) (source cwd)
(writable? #t))))) (target cwd)
(writable? #t)))
'())))
;; When in Rome, do as Nix build.cc does: Automagically ;; When in Rome, do as Nix build.cc does: Automagically
;; map common network configuration files. ;; map common network configuration files.
(if network? (if network?
@ -537,8 +547,10 @@ (define* (launch-environment/container #:key command bash user user-mappings
(write-group groups) (write-group groups)
;; 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 or, if unmapped, the home directory.
(chdir (override-user-dir user home cwd)) (chdir (if map-cwd?
(override-user-dir user home cwd)
home-dir))
(primitive-exit/status (primitive-exit/status
;; A container's environment is already purified, so no need to ;; A container's environment is already purified, so no need to
@ -665,6 +677,7 @@ (define (guix-environment . args)
(container? (assoc-ref opts 'container?)) (container? (assoc-ref opts 'container?))
(link-prof? (assoc-ref opts 'link-profile?)) (link-prof? (assoc-ref opts 'link-profile?))
(network? (assoc-ref opts 'network?)) (network? (assoc-ref opts 'network?))
(no-cwd? (assoc-ref opts 'no-cwd?))
(user (assoc-ref opts 'user)) (user (assoc-ref opts 'user))
(bootstrap? (assoc-ref opts 'bootstrap?)) (bootstrap? (assoc-ref opts 'bootstrap?))
(system (assoc-ref opts 'system)) (system (assoc-ref opts 'system))
@ -685,6 +698,9 @@ (define (guix-environment . args)
(leave (G_ "'--link-profile' cannot be used without '--container'~%"))) (leave (G_ "'--link-profile' cannot be used without '--container'~%")))
(when (and (not container?) user) (when (and (not container?) user)
(leave (G_ "'--user' cannot be used without '--container'~%"))) (leave (G_ "'--user' cannot be used without '--container'~%")))
(when (and (not container?) no-cwd?)
(leave (G_ "--no-cwd cannot be used without --container~%")))
(with-store store (with-store store
(with-status-verbosity (assoc-ref opts 'verbosity) (with-status-verbosity (assoc-ref opts 'verbosity)
@ -741,7 +757,9 @@ (define manifest
#:profile profile #:profile profile
#:manifest manifest #:manifest manifest
#:link-profile? link-prof? #:link-profile? link-prof?
#:network? network?))) #:network? network?
#:map-cwd? (not no-cwd?))))
(else (else
(return (return
(exit/status (exit/status

View file

@ -84,6 +84,14 @@ echo "(use-modules (guix profiles) (gnu packages bootstrap))
guix environment --bootstrap --manifest=$tmpdir/manifest.scm --pure \ guix environment --bootstrap --manifest=$tmpdir/manifest.scm --pure \
-- "$SHELL" -c 'test -f "$GUIX_ENVIRONMENT/bin/guile"' -- "$SHELL" -c 'test -f "$GUIX_ENVIRONMENT/bin/guile"'
# if not sharing CWD, chdir home
(
cd "$tmpdir" \
&& guix environment --bootstrap --container --no-cwd --user=foo \
--ad-hoc guile-bootstrap --pure \
-- /bin/sh -c 'test $(pwd) == "/home/foo" -a ! -d '"$tmpdir"
)
# Make sure '-r' works as expected. # Make sure '-r' works as expected.
rm -f "$gcroot" rm -f "$gcroot"
expected="`guix environment --bootstrap --ad-hoc guile-bootstrap \ expected="`guix environment --bootstrap --ad-hoc guile-bootstrap \