about summary refs log tree commit diff
path: root/guix/forge/klaus.scm
blob: dffd61dbda4cc7a91e7f9514320669322ef27f05 (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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
;;; guix-forge --- Guix software forge meta-service
;;; Copyright © 2023–2025 Arun Isaac <arunisaac@systemreboot.net>
;;; Copyright © 2024 jgart <jgart@dismail.de>
;;;
;;; 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 klaus)
  #:use-module (forge environment)
  #:use-module ((forge git) #:select (git-without-safe-directory-check))
  #:use-module (forge gunicorn)
  #:use-module (forge nginx)
  #:use-module (forge socket)
  #:use-module ((gnu packages version-control)
                #:select (python-klaus)
                #:prefix guix:)
  #:use-module (gnu services)
  #:use-module ((gnu services web) #:select (nginx-server-configuration
                                             nginx-location-configuration))
  #:use-module (gnu system file-systems)
  #:use-module (guix deprecation)
  #:use-module (guix packages)
  #:use-module (guix records)
  #:export (<klaus-configuration>
            klaus-configuration
            klaus-configuration?
            klaus-configuration-python-klaus
            klaus-configuration-server-name
            klaus-configuration-socket
            klaus-configuration-repository-directory
            klaus-configuration-site-name
            klaus-service-type
            klaus-gunicorn-app))

(define-public python-klaus
  (package
    (inherit guix:python-klaus)
    (inputs
     ;; We use klaus to serve shared repositories. But, git's safe directory
     ;; check does not permit us to use shared repositories. Disable it. The
     ;; more long term solution is to rewrite klaus to not use the git CLI at
     ;; all. See https://github.com/jonashaag/klaus/issues/322
     (modify-inputs (package-inputs guix:python-klaus)
       (replace "git-minimal" git-without-safe-directory-check)))))

(define-record-type* <klaus-configuration>
  klaus-configuration make-klaus-configuration
  klaus-configuration?
  (python-klaus klaus-configuration-python-klaus
                (default python-klaus))
  (server-name klaus-configuration-server-name)
  (socket klaus-configuration-socket
          (default (forge-unix-socket
                    (path "/var/run/gunicorn/klaus/socket"))))
  (repository-directory klaus-configuration-repository-directory
                        (default "/srv/git"))
  (site-name klaus-configuration-site-name
             (default #f)))

(define klaus-gunicorn-apps
  (match-record-lambda <klaus-configuration>
    (python-klaus socket repository-directory site-name)
    (list (gunicorn-app
           (name "klaus")
           (package python-klaus)
           (wsgi-app-module "klaus.contrib.wsgi_autoreload")
           (sockets (list socket))
           (environment-variables (cons (environment-variable
                                         (name "KLAUS_REPOS_ROOT")
                                         (value repository-directory))
                                        (if site-name
                                            (list (environment-variable
                                                   (name "KLAUS_SITE_NAME")
                                                   (value site-name)))
                                            (list))))
           (mappings (list (file-system-mapping
                            (source repository-directory)
                            (target source))))))))

(define klaus-nginx-server-blocks
  (match-record-lambda <klaus-configuration>
    (server-name socket)
    (list (nginx-server-configuration
           (server-name (list server-name))
           (locations
            (list (nginx-location-configuration
                   (uri "/")
                   (body (list (socket->nginx-proxy-pass socket))))))))))

(define klaus-service-type
  (service-type
   (name 'klaus)
   (description "Run klaus.")
   (extensions (list (service-extension gunicorn-service-type
                                        klaus-gunicorn-apps)
                     (service-extension forge-nginx-service-type
                                        klaus-nginx-server-blocks)))))

(define-deprecated (klaus-gunicorn-app repository-directory
                                       #:key
                                       (klaus python-klaus)
                                       (sockets (list (forge-unix-socket
                                                       (path "/var/run/gunicorn/klaus/socket"))))
                                       site-name)
  klaus-service-type
  "Return a @code{<gunicorn-app>} object to deploy klaus.

@var{repository-directory} is the path to the directory containing git
repositories to serve.

@var{klaus} is the klaus package to use.

@var{sockets} is a list of @code{<forge-ip-socket>} or
@code{<forge-unix-socket>} objects describing sockets to listen on.

@var{site-name} is the name of the klaus site to be displayed in the
banner."
  (gunicorn-app
   (name "klaus")
   (package klaus)
   (wsgi-app-module "klaus.contrib.wsgi_autoreload")
   (sockets sockets)
   (environment-variables (cons (environment-variable
                                 (name "KLAUS_REPOS_ROOT")
                                 (value repository-directory))
                                (if site-name
                                    (list (environment-variable
                                           (name "KLAUS_SITE_NAME")
                                           (value site-name)))
                                    (list))))
   (mappings (list (file-system-mapping
                    (source repository-directory)
                    (target source))))))