M gnu-system.am => gnu-system.am +1 -0
@@ 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 \
A gnu/packages/patches/dmd-getpw.patch => gnu/packages/patches/dmd-getpw.patch +19 -0
@@ 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
M gnu/packages/system.scm => gnu/packages/system.scm +2 -1
@@ 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")))
M gnu/system/dmd.scm => gnu/system/dmd.scm +28 -2
@@ 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)))
M gnu/system/vm.scm => gnu/system/vm.scm +1 -13
@@ 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"