[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
01/05: services: Add 'special-files-service-type'.
From: |
Ludovic Courtès |
Subject: |
01/05: services: Add 'special-files-service-type'. |
Date: |
Wed, 8 Feb 2017 10:17:42 -0500 (EST) |
civodul pushed a commit to branch master
in repository guix.
commit 387e175492f960d7d86f34f3b2e43938fa72dbf3
Author: Ludovic Courtès <address@hidden>
Date: Wed Feb 8 15:32:28 2017 +0100
services: Add 'special-files-service-type'.
* gnu/build/activation.scm (activate-/bin/sh): Remove.
(activate-special-files): New procedure.
* gnu/services.scm (activation-script): Remove call to
'activate-/bin/sh'.
(special-files-service-type): New variable.
(extra-special-file): New procedure.
* gnu/services/base.scm (%base-services): Add SPECIAL-FILES-SERVICE-TYPE
instance.
* gnu/tests/base.scm (run-basic-test)[special-files]: New variables.
["special files"]: New test.
---
doc/guix.texi | 44 ++++++++++++++++++++++++++++++++++++++++++++
gnu/build/activation.scm | 23 ++++++++++++++++++-----
gnu/services.scm | 25 +++++++++++++++++++++----
gnu/services/base.scm | 7 ++++++-
gnu/tests/base.scm | 17 +++++++++++++++++
5 files changed, 106 insertions(+), 10 deletions(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index 6acde66..21082ae 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -8272,6 +8272,50 @@ this:
@end example
@end defvr
address@hidden {Scheme Variable} special-files-service-type
+This is the service that sets up ``special files'' such as
address@hidden/bin/sh}; an instance of it is part of @code{%base-services}.
+
+The value associated with @code{special-files-service-type} services
+must be a list of tuples where the first element is the ``special file''
+and the second element is its target. By default it is:
+
address@hidden @file{/bin/sh}
address@hidden @file{sh}, in @file{/bin}
address@hidden
+`(("/bin/sh" ,(file-append @var{bash} "/bin/sh")))
address@hidden example
+
address@hidden @file{/usr/bin/env}
address@hidden @file{env}, in @file{/usr/bin}
+If you want to add, say, @code{/usr/bin/env} to your system, you can
+change it to:
+
address@hidden
+`(("/bin/sh" ,(file-append @var{bash} "/bin/sh"))
+ ("/usr/bin/env" ,(file-append @var{coreutils} "/bin/env")))
address@hidden example
+
+Since this is part of @code{%base-services}, you can use
address@hidden to customize the set of special files
+(@pxref{Service Reference, @code{modify-services}}). But the simple way
+to add a special file is @i{via} the @code{extra-special-file} procedure
+(see below.)
address@hidden defvr
+
address@hidden {Scheme Procedure} extra-special-file @var{file} @var{target}
+Use @var{target} as the ``special file'' @var{file}.
+
+For example, adding the following lines to the @code{services} field of
+your operating system declaration leads to a @file{/usr/bin/env}
+symlink:
+
address@hidden
+(extra-special-file "/usr/bin/env"
+ (file-append coreutils "/bin/env"))
address@hidden example
address@hidden deffn
+
@deffn {Scheme Procedure} host-name-service @var{name}
Return a service that sets the host name to @var{name}.
@end deffn
diff --git a/gnu/build/activation.scm b/gnu/build/activation.scm
index e58304e..c4ed40e 100644
--- a/gnu/build/activation.scm
+++ b/gnu/build/activation.scm
@@ -28,7 +28,7 @@
activate-user-home
activate-etc
activate-setuid-programs
- activate-/bin/sh
+ activate-special-files
activate-modprobe
activate-firmware
activate-ptrace-attach
@@ -383,10 +383,23 @@ copy SOURCE to TARGET."
(for-each make-setuid-program programs))
-(define (activate-/bin/sh shell)
- "Change /bin/sh to point to SHELL."
- (symlink shell "/bin/sh.new")
- (rename-file "/bin/sh.new" "/bin/sh"))
+(define (activate-special-files special-files)
+ "Install the files listed in SPECIAL-FILES. Each element of SPECIAL-FILES
+is a pair where the first element is the name of the special file and the
+second element is the name it should appear at, such as:
+
+ ((\"/bin/sh\" \"/gnu/store/…-bash/bin/sh\")
+ (\"/usr/bin/env\" \"/gnu/store/…-coreutils/bin/env\"))
+"
+ (define install-special-file
+ (match-lambda
+ ((target file)
+ (let ((pivot (string-append target ".new")))
+ (mkdir-p (dirname target))
+ (symlink file pivot)
+ (rename-file pivot target)))))
+
+ (for-each install-special-file special-files))
(define (activate-modprobe modprobe)
"Tell the kernel to use MODPROBE to load modules."
diff --git a/gnu/services.scm b/gnu/services.scm
index e645889..6ac4f13 100644
--- a/gnu/services.scm
+++ b/gnu/services.scm
@@ -72,6 +72,8 @@
activation-service-type
activation-service->script
%linux-bare-metal-service
+ special-files-service-type
+ extra-special-file
etc-service-type
etc-directory
setuid-program-service-type
@@ -336,10 +338,6 @@ ACTIVATION-SCRIPT-TYPE."
#~(begin
(use-modules (gnu build activation))
- ;; Make sure /bin/sh is valid and current.
- (activate-/bin/sh
- (string-append #$(canonical-package bash) "/bin/sh"))
-
;; Make sure the user accounting database exists. If it
;; does not exist, 'setutxent' does not create it and
;; thus there is no accounting at all.
@@ -413,6 +411,25 @@ ACTIVATION-SCRIPT-TYPE."
;; necessary or impossible in a container.
(service linux-bare-metal-service-type #f))
+(define special-files-service-type
+ ;; Service to install "special files" such as /bin/sh and /usr/bin/env.
+ (service-type
+ (name 'special-files)
+ (extensions
+ (list (service-extension activation-service-type
+ (lambda (files)
+ #~(activate-special-files '#$files)))))
+ (compose concatenate)
+ (extend append)))
+
+(define (extra-special-file file target)
+ "Use TARGET as the \"special file\" FILE. For example, TARGET might be
+ (file-append coreutils \"/bin/env\")
+and FILE could be \"/usr/bin/env\"."
+ (simple-service (string->symbol (string-append "special-file-" file))
+ special-files-service-type
+ `((,file ,target))))
+
(define (etc-directory service)
"Return the directory for SERVICE, a service of type ETC-SERVICE-TYPE."
(files->etc-directory (service-parameters service)))
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index d9f3a14..57601ea 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -36,6 +36,7 @@
#:select (alsa-utils crda eudev e2fsprogs fuse gpm kbd lvm2
rng-tools))
#:use-module ((gnu packages base)
#:select (canonical-package glibc))
+ #:use-module (gnu packages bash)
#:use-module (gnu packages package-management)
#:use-module (gnu packages lsof)
#:use-module (gnu packages terminals)
@@ -1558,6 +1559,10 @@ This service is not part of @var{%base-services}."
;; The LVM2 rules are needed as soon as LVM2 or the device-mapper is
;; used, so enable them by default. The FUSE and ALSA rules are
;; less critical, but handy.
- (udev-service #:rules (list lvm2 fuse alsa-utils crda))))
+ (udev-service #:rules (list lvm2 fuse alsa-utils crda))
+
+ (service special-files-service-type
+ `(("/bin/sh" ,(file-append (canonical-package bash)
+ "/bin/sh"))))))
;;; base.scm ends here
diff --git a/gnu/tests/base.scm b/gnu/tests/base.scm
index 8a6a7a1..000a4dd 100644
--- a/gnu/tests/base.scm
+++ b/gnu/tests/base.scm
@@ -77,6 +77,11 @@ When INITIALIZATION is true, it must be a one-argument
procedure that is
passed a gexp denoting the marionette, and it must return gexp that is
inserted before the first test. This is used to introduce an extra
initialization step, such as entering a LUKS passphrase."
+ (define special-files
+ (service-parameters
+ (fold-services (operating-system-services os)
+ #:target-type special-files-service-type)))
+
(define test
(with-imported-modules '((gnu build marionette)
(guix build syscalls))
@@ -120,6 +125,18 @@ grep --version
info --version")
marionette)))
+ (test-equal "special files"
+ '#$special-files
+ (marionette-eval
+ '(begin
+ (use-modules (ice-9 match))
+
+ (map (match-lambda
+ ((file target)
+ (list file (readlink file))))
+ '#$special-files))
+ marionette))
+
(test-assert "accounts"
(let ((users (marionette-eval '(begin
(use-modules (ice-9 match))