diff options
Diffstat (limited to 'gnu/system/shadow.scm')
-rw-r--r-- | gnu/system/shadow.scm | 156 |
1 files changed, 118 insertions, 38 deletions
diff --git a/gnu/system/shadow.scm b/gnu/system/shadow.scm index f033109614..3f49c1fc9f 100644 --- a/gnu/system/shadow.scm +++ b/gnu/system/shadow.scm @@ -20,15 +20,16 @@ #:use-module (guix records) #:use-module (guix gexp) #:use-module (guix store) - #:use-module (guix monads) #:use-module (guix sets) #:use-module (guix ui) + #:use-module (gnu services) #:use-module ((gnu system file-systems) #:select (%tty-gid)) #:use-module ((gnu packages admin) #:select (shadow)) #:use-module (gnu packages bash) #:use-module (gnu packages guile-wm) + #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) @@ -55,7 +56,9 @@ skeleton-directory %base-groups %base-user-accounts - assert-valid-users/groups)) + + account-service-type + account-service)) ;;; Commentary: ;;; @@ -88,31 +91,32 @@ (system? user-group-system? ; Boolean (default #f))) + (define %base-groups ;; Default set of groups. (let-syntax ((system-group (syntax-rules () ((_ args ...) (user-group (system? #t) args ...))))) (list (system-group (name "root") (id 0)) - (system-group (name "wheel")) ; root-like users - (system-group (name "users")) ; normal users - (system-group (name "nogroup")) ; for daemons etc. + (system-group (name "wheel")) ; root-like users + (system-group (name "users")) ; normal users + (system-group (name "nogroup")) ; for daemons etc. ;; The following groups are conventionally used by things like udev to ;; control access to hardware devices. (system-group (name "tty") (id %tty-gid)) (system-group (name "dialout")) (system-group (name "kmem")) - (system-group (name "input")) ; input devices, from udev + (system-group (name "input")) ; input devices, from udev (system-group (name "video")) (system-group (name "audio")) - (system-group (name "netdev")) ; used in avahi-dbus.conf + (system-group (name "netdev")) ; used in avahi-dbus.conf (system-group (name "lp")) (system-group (name "disk")) (system-group (name "floppy")) (system-group (name "cdrom")) (system-group (name "tape")) - (system-group (name "kvm"))))) ; for /dev/kvm + (system-group (name "kvm"))))) ; for /dev/kvm (define %base-user-accounts ;; List of standard user accounts. Note that "root" is a special case, so @@ -133,10 +137,10 @@ (copy-file (car (find-files #$guile-wm "wm-init-sample.scm")) #$output))) - (mlet %store-monad ((profile (text-file "bash_profile" "\ + (let ((profile (plain-file "bash_profile" "\ # Honor per-interactive-shell startup file if [ -f ~/.bashrc ]; then . ~/.bashrc; fi\n")) - (bashrc (text-file "bashrc" "\ + (bashrc (plain-file "bashrc" "\ # Bash initialization for interactive non-login shells and # for remote shells (info \"(bash) Bash Startup Files\"). @@ -162,42 +166,41 @@ else fi alias ls='ls -p --color' alias ll='ls -l'\n")) - (zlogin (text-file "zlogin" "\ + (zlogin (plain-file "zlogin" "\ # Honor system-wide environment variables source /etc/profile\n")) - (guile-wm (gexp->derivation "guile-wm" copy-guile-wm - #:modules - '((guix build utils)))) - (xdefaults (text-file "Xdefaults" "\ + (guile-wm (computed-file "guile-wm" copy-guile-wm + #:modules '((guix build utils)))) + (xdefaults (plain-file "Xdefaults" "\ XTerm*utf8: always XTerm*metaSendsEscape: true\n")) - (gdbinit (text-file "gdbinit" "\ + (gdbinit (plain-file "gdbinit" "\ # Tell GDB where to look for separate debugging files. set debug-file-directory ~/.guix-profile/lib/debug\n"))) - (return `((".bash_profile" ,profile) - (".bashrc" ,bashrc) - (".zlogin" ,zlogin) - (".Xdefaults" ,xdefaults) - (".guile-wm" ,guile-wm) - (".gdbinit" ,gdbinit))))) + `((".bash_profile" ,profile) + (".bashrc" ,bashrc) + (".zlogin" ,zlogin) + (".Xdefaults" ,xdefaults) + (".guile-wm" ,guile-wm) + (".gdbinit" ,gdbinit)))) (define (skeleton-directory skeletons) - "Return a directory containing SKELETONS, a list of name/derivation pairs." - (gexp->derivation "skel" - #~(begin - (use-modules (ice-9 match)) - - (mkdir #$output) - (chdir #$output) - - ;; Note: copy the skeletons instead of symlinking - ;; them like 'file-union' does, because 'useradd' - ;; would just copy the symlinks as is. - (for-each (match-lambda - ((target source) - (copy-file source target))) - '#$skeletons) - #t))) + "Return a directory containing SKELETONS, a list of name/derivation tuples." + (computed-file "skel" + #~(begin + (use-modules (ice-9 match)) + + (mkdir #$output) + (chdir #$output) + + ;; Note: copy the skeletons instead of symlinking + ;; them like 'file-union' does, because 'useradd' + ;; would just copy the symlinks as is. + (for-each (match-lambda + ((target source) + (copy-file source target))) + '#$skeletons) + #t))) (define (assert-valid-users/groups users groups) "Raise an error if USERS refer to groups not listed in GROUPS." @@ -226,4 +229,81 @@ of user '~a' is undeclared") (user-account-supplementary-groups user))) users))) + +;;; +;;; Service. +;;; + +(define (user-group->gexp group) + "Turn GROUP, a <user-group> object, into a list-valued gexp suitable for +'active-groups'." + #~(list #$(user-group-name group) + #$(user-group-password group) + #$(user-group-id group) + #$(user-group-system? group))) + +(define (user-account->gexp account) + "Turn ACCOUNT, a <user-account> object, into a list-valued gexp suitable for +'activate-users'." + #~`(#$(user-account-name account) + #$(user-account-uid account) + #$(user-account-group account) + #$(user-account-supplementary-groups account) + #$(user-account-comment account) + #$(user-account-home-directory account) + ,#$(user-account-shell account) ; this one is a gexp + #$(user-account-password account) + #$(user-account-system? account))) + +(define (account-activation accounts+groups) + "Return a gexp that activates ACCOUNTS+GROUPS, a list of <user-account> and +<user-group> objects. Raise an error if a user account refers to a undefined +group." + (define accounts + (filter user-account? accounts+groups)) + + (define user-specs + (map user-account->gexp accounts)) + + (define groups + (filter user-group? accounts+groups)) + + (define group-specs + (map user-group->gexp groups)) + + (assert-valid-users/groups accounts groups) + + ;; Add users and user groups. + #~(begin + (setenv "PATH" + (string-append #$(@ (gnu packages admin) shadow) "/sbin")) + (activate-users+groups (list #$@user-specs) + (list #$@group-specs)))) + +(define (etc-skel arguments) + "Filter out among ARGUMENTS things corresponding to skeletons, and return +the /etc/skel directory for those." + (let ((skels (filter pair? arguments))) + `(("skel" ,(skeleton-directory skels))))) + +(define account-service-type + (service-type (name 'account) + + ;; Concatenate <user-account>, <user-group>, and skeleton + ;; lists. + (compose concatenate) + (extend append) + + (extensions + (list (service-extension activation-service-type + account-activation) + (service-extension etc-service-type + etc-skel))))) + +(define (account-service accounts+groups skeletons) + "Return a <service> that takes care of user accounts and user groups, with +ACCOUNTS+GROUPS as its initial list of accounts and groups." + (service account-service-type + (append skeletons accounts+groups))) + ;;; shadow.scm ends here |