gnu: Populate /etc upon startup.

* gnu/packages/patches/dmd-getpw.patch: New file.
* gnu-system.am (dist_patch_DATA): Add it.
* gnu/packages/system.scm (dmd): Use it.
* gnu/system/vm.scm (system-qemu-image): Don't explicitly populate /etc;
  don't add ETC to the GC roots.
* gnu/system/dmd.scm (dmd-configuration-file): Add 'etc' parameter.
  [config]: Populate /etc from there.
master
Ludovic Courtès 2013-12-08 21:22:22 +01:00
parent 677078b48f
commit 9b0ac80258
5 changed files with 51 additions and 16 deletions

View File

@ -227,6 +227,7 @@ dist_patch_DATA = \
gnu/packages/patches/cpio-gets-undeclared.patch \
gnu/packages/patches/dbus-localstatedir.patch \
gnu/packages/patches/diffutils-gets-undeclared.patch \
gnu/packages/patches/dmd-getpw.patch \
gnu/packages/patches/emacs-configure-sh.patch \
gnu/packages/patches/ffmpeg-check.patch \
gnu/packages/patches/findutils-absolute-paths.patch \

View File

@ -0,0 +1,19 @@
When bootstrapping and running as PID 1, /etc/{passwd,shadow} may be unavailable.
Gracefully handle that.
diff --git a/modules/dmd/support.scm b/modules/dmd/support.scm
index 9b592c5..602e409 100644
--- a/modules/dmd/support.scm
+++ b/modules/dmd/support.scm
@@ -151,7 +151,10 @@ There is NO WARRANTY, to the extent permitted by law.")))
;; Home directory of the user.
-(define user-homedir (passwd:dir (getpwuid (getuid))))
+(define user-homedir
+ (or (false-if-exception (passwd:dir (getpwuid (getuid))))
+ (getenv "HOME")
+ "/"))
;; Logfile.
(define default-logfile

View File

@ -45,7 +45,8 @@
version ".tar.gz"))
(sha256
(base32
"07mddw0p62fcphwjzgb6rfa0pjz5sy6jzbha0sm2vc3rqf459jxg"))))
"07mddw0p62fcphwjzgb6rfa0pjz5sy6jzbha0sm2vc3rqf459jxg"))
(patches (list (search-patch "dmd-getpw.patch")))))
(build-system gnu-build-system)
(arguments
'(#:configure-flags '("--localstatedir=/var")))

View File

@ -266,10 +266,13 @@ true, it must be a string specifying the default network gateway."
'())))))))
(define (dmd-configuration-file services)
"Return the dmd configuration file for SERVICES."
(define (dmd-configuration-file services etc)
"Return the dmd configuration file for SERVICES, that initializes /etc from
ETC on startup."
(define config
`(begin
(use-modules (ice-9 ftw))
(register-services
,@(map (match-lambda
(($ <service> documentation provision requirement
@ -282,6 +285,29 @@ true, it must be a string specifying the default network gateway."
#:start ,start
#:stop ,stop)))
services))
;; /etc is a mixture of static and dynamic settings. Here is where we
;; initialize it from the static part.
(format #t "populating /etc from ~a...~%" ,etc)
(let ((rm-f (lambda (f)
(false-if-exception (delete-file f)))))
(rm-f "/etc/static")
(symlink ,etc "/etc/static")
(for-each (lambda (file)
;; TODO: Handle 'shadow' specially so that changed
;; password aren't lost.
(let ((target (string-append "/etc/" file))
(source (string-append "/etc/static/" file)))
(rm-f target)
(symlink source target)))
(scandir ,etc
(lambda (file)
(not (member file '("." ".."))))))
;; Prevent ETC from being GC'd.
(symlink ,etc "/var/nix/gcroots/etc-directory"))
(format #t "starting services...~%")
(for-each start ',(append-map service-provision services))))
(text-file "dmd.conf" (object->string config)))

View File

@ -577,7 +577,6 @@ Happy birthday, GNU! http://www.gnu.org/gnu30
(bash-file (package-file bash "bin/bash"))
(dmd-file (package-file dmd "bin/dmd"))
(dmd-conf (dmd-configuration-file services))
(accounts -> (cons* (user-account
(name "root")
(password "")
@ -632,26 +631,15 @@ Happy birthday, GNU! http://www.gnu.org/gnu30
#:pam-services pam-services
#:profile profile))
(etc -> (derivation->output-path etc-drv))
(dmd-conf (dmd-configuration-file services etc))
(populate -> `((directory "/nix/store" 0 ,build-user-gid)
(directory "/etc")
(directory "/var/log") ; for dmd
(directory "/var/run/nscd")
("/etc/static" -> ,etc)
("/etc/shadow" -> "/etc/static/shadow")
("/etc/passwd" -> "/etc/static/passwd")
("/etc/group" -> "/etc/static/group")
("/etc/login.defs" -> "/etc/static/login.defs")
("/etc/pam.d" -> "/etc/static/pam.d")
("/etc/profile" -> "/etc/static/profile")
("/etc/issue" -> "/etc/static/issue")
("/etc/services" -> "/etc/static/services")
("/etc/protocols" -> "/etc/static/protocols")
("/etc/rpc" -> "/etc/static/rpc")
(directory "/var/nix/gcroots")
("/var/nix/gcroots/default-profile" -> ,profile)
("/var/nix/gcroots/etc-directory" -> ,etc)
(directory "/tmp")
(directory "/var/nix/profiles/per-user/root" 0 0)
(directory "/var/nix/profiles/per-user/guest"