blob: 1e5ae4eb5d59c4686ad3544453bf6b65fb5eb3e1 (
plain) (
blame)
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
(define-module (services)
#:use-module ((ice-9 popen) #:prefix popen:)
#:use-module ((ice-9 textual-ports) #:prefix textual-ports:)
#:use-module ((gnu build linux-container) #:prefix container:)
#:use-module ((srfi srfi-1) #:prefix srfi-1:)
#:use-module ((xyz euandreh heredoc) #:prefix heredoc:)
#:use-module (gnu)
#:use-module (guix build utils)
#:use-module (guix least-authority)
#:use-module (guix records))
(use-package-modules
admin)
(use-service-modules
admin
mcron
shepherd)
(heredoc:enable-syntax)
(define +working-dir+
(if (directory-exists? "/opt/deploy/current")
"/opt/deploy/current"
(canonicalize-path ".")))
(add-to-load-path
(string-append +working-dir+ "/src/infrastructure/guix"))
(use-modules
((packages) #:prefix packages:))
(define-record-type* <papo-configuration>
papo-configuration
make-papo-configuration
papo-configuration?
(package papo-configuration-package (default packages:papo))
(user papo-configuration-user (default "papo"))
(group papo-configuration-group (default "papo"))
(config-dirname papo-configuration-config (default "papo"))
(port papo-configuration-port (default 6666))
(log-file papo-configuration-log-file (default "/var/log/papo.log"))
(data-directory papo-configuration-data-directory (default "/var/lib/papo"))
(run-directory papo-configuration-run-directory (default "/var/run/papo"))
(run-in-container? papo-configuration-run-in-container? (default #t))
(container-name papo-configuration-container-name (default "papo-container"))
(container-namespaces papo-configuration-container-namespaces (default container:%namespaces))
(extra-mappings papo-configuration-extra-mappings (default '())))
(define (papo-etc-files config)
(match-record config <papo-configuration>
()
`(("papo.json" ,(plain-file "papo.json" "")))))
(define (papo-log-rotations config)
(match-record config <papo-configuration>
(log-file)
(list
(log-rotation
(frequency 'weekly)
(files (list log-file))
(options '("rotate 5200"))))))
(define (papo-activation config)
(match-record config <papo-configuration>
(user log-file data-directory run-directory)
#~(begin
(use-modules (guix build utils))
(format (current-error-port)
"Creating papo log directory for '~a'.~%" #$log-file)
(mkdir-p (dirname #$log-file))
(when (not (file-exists? #$log-file))
(call-with-output-file #$log-file (const #t)))
(chmod #$log-file #o644)
(let ((user (getpwnam #$user)))
(format (current-error-port)
"Creating papo data directory '~a'.~%" #$data-directory)
(mkdir-p #$data-directory)
(chown #$data-directory (passwd:uid user) (passwd:gid user))
(chmod #$data-directory #o750)
(format (current-error-port)
"Creating papo run directory '~a'.~%" #$run-directory)
(mkdir-p #$run-directory)
(chown #$run-directory (passwd:uid user) (passwd:gid user))
(chmod #$run-directory #o755)))))
(define (papo-cronjobs _config)
(list))
(define (papo-accounts config)
(match-record config <papo-configuration>
(user group)
(list
(user-group
(name group)
(system? #t))
(user-account
(name user)
(group group)
(system? #t)
(comment "The user for runtime execution of papo code")
(home-directory "/var/empty")
(shell
(file-append shadow "/sbin/nologin"))))))
(define (wrapped-command config)
(match-record config <papo-configuration>
(package data-directory
run-in-container? container-name container-namespaces extra-mappings)
(let ((bin (file-append package "/bin/papo")))
(if (not run-in-container?)
bin
(least-authority-wrapper
bin
#:name container-name
#:namespaces container-namespaces
#:directory data-directory
#:preserved-environment-variables
'()
#:mappings
(append
(list
(file-system-mapping
(source data-directory)
(target source)
(writable? #t))
(file-system-mapping
(source (file-append glibc-locales "/lib/locale"))
(target "/run/current-system/locale")))
extra-mappings))))))
(define (exec-action config . static-args)
(match-record config <papo-configuration>
(user group log-file data-directory)
#~(lambda dynamic-args
(fork+exec-command
(append '(#$@static-args) dynamic-args)
#:user #$user
#:group #$group
#:directory #$data-directory
#:log-file #$log-file))))
(define (papo-shepherd-services config)
(let ((cmd (wrapped-command config)))
(list
(shepherd-service
(provision '(papo))
(requirement '())
(start (exec-action config cmd "ircd"))
(stop #~(make-kill-destructor SIGKILL))
(documentation
#"-
The Shepherd service that runs the server via "papo-ircd"."#)))))
(define-public papo-service-type
(service-type
(name 'papo)
(extensions
(list
(service-extension shepherd-root-service-type
papo-shepherd-services)
(service-extension etc-service-type
papo-etc-files)
(service-extension profile-service-type
(compose list papo-configuration-package))
(service-extension activation-service-type
papo-activation)
(service-extension account-service-type
papo-accounts)
(service-extension mcron-service-type
papo-cronjobs)
(service-extension rottlog-service-type
papo-log-rotations)))
(default-value (papo-configuration))
(description
#"-
The top-level system service for papo code.
It includes:
- the Shepherd service for starting, stopping and reloading the
service ("papo");
- a list of cronjobs to be added to the system for sending documents
proactively;
- activation script for setting up the initial directories and permissions;
- the "papo" group and "papo" account for running the production service;
- log management (storage and rotation) for logs produced by the running services.
The defaults of <papo-configuration> provide sane values for all of these."#)))
|