1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
+;; Usage:
+
+;; By default account-service will extend user-space-shepherd-service and
+;; force it instantiation, but nothing will happen because extend function
+;; will return '()
+
+;; (service user-space-shepherd-service-type
+;; '(accept-extensions "non-user1" "non-user2"))
+;; In that case shepherds will be started for all user-accounts from
+;; account-service and additionally for "non-user1" and "non-user2"
+
+;; (service user-space-shepherd-service-type
+;; '(reject-extensions "user1" "user2"))
+;; user-space-shepherds will launched only for "user1" "user2"
+
+(define (add-user-space-shepherds users)
+ (map
+ (lambda (user)
+ (shepherd-service
+ (start
+ #~(lambda ()
+ (start-user-shepherd user)
+ #t))
+ (documentation (format #f "Starts a shepherd for user ~a" user))))))
+
+(define user-space-shepherd-service-type
+ (service-type
+ (name 'user-space-shepherd)
+ (compose concatenate)
+ (extend (lambda (initial-users additional-users)
+ (match
+ ('(auto-defined) '())
+ ('(accept-extensions tails ...) (append tails additional-users))
+ ('(reject-extensions tails ...) tails)
+ )))
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ add-user-space-shepherds)))
+ (default-value '(auto-defined))
+ (description
+ "Running a separate shepherd for each user.")))
+
+(define (let-user-space-shepherd-know-about-users accounts+groups)
+ (filter user-account? accounts+groups))
+
(define account-service-type
(service-type (name 'account)
@@ -372,6 +417,8 @@ the /etc/skel directory for those."
account-activation)
(service-extension shepherd-root-service-type
account-shepherd-service)
+ (service-extension user-space-shepherd-service-type
+ let-user-space-shepherd-know-about-users)
;; Have 'user-processes' depend on 'user-homes' so that
;; daemons start after their home directory has been
;; created.