summaryrefslogtreecommitdiff
path: root/forge/laminar.scm
blob: 5dbfbc43d14c357b25f55f737c29017de279f57c (plain)
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
;;; guix-forge --- Guix software forge meta-service
;;; Copyright © 2021, 2022 Arun Isaac <arunisaac@systemreboot.net>
;;;
;;; This file is part of guix-forge.
;;;
;;; guix-forge is free software: you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published
;;; by the Free Software Foundation, either version 3 of the License,
;;; or (at your option) any later version.
;;;
;;; guix-forge is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;;; General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with guix-forge.  If not, see
;;; <https://www.gnu.org/licenses/>.

(define-module (forge laminar)
  #:use-module (gnu)
  #:use-module (srfi srfi-1)
  #:use-module (gnu packages ci)
  #:use-module (guix records)
  #:export (forge-laminar-service-type
            forge-laminar-configuration
            forge-laminar-configuration-state-directory
            forge-laminar-configuration-jobs
            forge-laminar-job
            forge-laminar-job?
            forge-laminar-job-name
            forge-laminar-job-run
            forge-laminar-job-after
            forge-laminar-group
            forge-laminar-group?
            forge-laminar-group-name
            forge-laminar-group-regex))

(define-record-type* <forge-laminar-configuration>
  forge-laminar-configuration make-forge-laminar-configuration
  forge-laminar-configuration?
  (state-directory forge-laminar-configuration-state-directory
                   (default "/var/lib/laminar"))
  (jobs forge-laminar-configuration-jobs
        (default '()))
  (groups forge-laminar-configuration-groups
          (default '())))

(define-record-type* <forge-laminar-job>
  forge-laminar-job make-forge-laminar-job
  forge-laminar-job?
  (name forge-laminar-job-name)
  (run forge-laminar-job-run)
  (after forge-laminar-job-after
         (default #f)))

(define-record-type* <forge-laminar-group>
  forge-laminar-group make-forge-laminar-group
  forge-laminar-group?
  (name forge-laminar-group-name)
  (regex forge-laminar-group-regex))

(define (forge-laminar-activation config)
  (let* ((state-directory (forge-laminar-configuration-state-directory config))
         (groups-configuration (string-append state-directory "/cfg/groups.conf"))
         (jobs-directory (string-append state-directory "/cfg/jobs")))
    #~(begin
        (use-modules (srfi srfi-26))

        ;; Configure groups.
        (when (file-exists? #$groups-configuration)
          (delete-file #$groups-configuration))
        (symlink
         #$(plain-file "laminar-groups"
                       (string-join (map (lambda (group)
                                           (string-append (forge-laminar-group-name group)
                                                          "="
                                                          (forge-laminar-group-regex group)))
                                         (forge-laminar-configuration-groups config))
                                    "\n"))
         #$groups-configuration)
        ;; Create jobs directory and populate with job scripts.
        (mkdir-p #$(dirname jobs-directory))
        (when (file-exists? #$jobs-directory)
          (delete-file #$jobs-directory))
        (symlink
         #$(file-union "laminar-jobs"
                       (append-map (lambda (job)
                                     (let ((name (forge-laminar-job-name job))
                                           (run (forge-laminar-job-run job))
                                           (after (forge-laminar-job-after job)))
                                       (cons (list (string-append name ".run")
                                                   (program-file name run))
                                             (if after
                                                 (list (list (string-append name ".after")
                                                             (program-file name after)))
                                                 (list)))))
                                   (forge-laminar-configuration-jobs config)))
         #$jobs-directory)
        ;; Set permissions for laminar directory.
        (for-each (lambda (file)
                    (let ((user (getpw "laminar")))
                      (chown file (passwd:uid user) (passwd:gid user))))
                  (find-files #$state-directory
                              (lambda (file stat)
                                (memq (stat:type stat)
                                      '(regular directory)))
                              #:directories? #t)))))

(define forge-laminar-service-type
  (service-type
   (name 'forge-laminar)
   (description "Run forge-laminar.")
   (extensions (list (service-extension activation-service-type
                                        forge-laminar-activation)))
   (compose concatenate)
   (extend (lambda (config extended-values)
             (forge-laminar-configuration
              (inherit config)
              (jobs (append (forge-laminar-configuration-jobs config)
                            (filter forge-laminar-job? extended-values)))
              (groups (append (forge-laminar-configuration-groups config)
                              (filter forge-laminar-group? extended-values))))))
   (default-value (forge-laminar-configuration))))