blob: 78eda7b361ae088d1f720b522b42516b1a621855 (
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
|
{ config, lib, pkgs, ... }:
with lib;
let
globalConfig = config;
settingsFormat = {
type = with lib.types; let
value = oneOf [ int str ] // {
description = "INI-like atom (int or string)";
};
values = coercedTo value lib.singleton (listOf value) // {
description = value.description + " or a list of them for duplicate keys";
};
in
attrsOf (values);
generate = name: values:
pkgs.writeText name (lib.generators.toKeyValue { listsAsDuplicateKeys = true; } values);
};
in
{
options.services.nginx.virtualHosts = mkOption {
type = types.attrsOf (types.submodule ({ config, ... }:
let
cfg = config.cgit;
# These are the global options for this submodule, but for nicer UX they
# are inlined into the freeform settings. Hence they MUST NOT INTERSECT
# with any settings from cgitrc!
options = {
enable = mkEnableOption "cgit";
location = mkOption {
default = "/";
type = types.str;
description = ''
Location to serve cgit on.
'';
};
};
# Remove the global options for serialization into cgitrc
settings = removeAttrs cfg (attrNames options);
in
{
options.cgit = mkOption {
type = types.submodule {
freeformType = settingsFormat.type;
inherit options;
config = {
css = mkDefault "/cgit.css";
logo = mkDefault "/cgit.png";
favicon = mkDefault "/favicon.ico";
};
};
default = { };
example = literalExample ''
{
enable = true;
virtual-root = "/";
source-filter = "''${pkgs.cgit}/lib/cgit/filters/syntax-highlighting.py";
about-filter = "''${pkgs.cgit}/lib/cgit/filters/about-formatting.sh";
cache-size = 1000;
scan-path = "/srv/git";
include = [
(builtins.toFile "cgitrc-extra-1" '''
# Anything that has to be in a particular order
''')
(builtins.toFile "cgitrc-extra-2" '''
# Anything that has to be in a particular order
''')
];
}
'';
description = ''
Verbatim contents of the cgit runtime configuration file. Documentation
(with cgitrc example file) is available in "man cgitrc". Or online:
http://git.zx2c4.com/cgit/tree/cgitrc.5.txt
'';
};
config = let
location = removeSuffix "/" cfg.location;
in mkIf cfg.enable {
locations."${location}/" = {
root = "${pkgs.cgit}/cgit/";
tryFiles = "$uri @cgit";
};
locations."~ ^${location}/(cgit.(css|png)|favicon.ico|robots.txt)$" = {
alias = "${pkgs.cgit}/cgit/$1";
};
locations."@cgit" = {
extraConfig = ''
include ${pkgs.nginx}/conf/fastcgi_params;
fastcgi_param CGIT_CONFIG ${settingsFormat.generate "cgitrc" settings};
fastcgi_param SCRIPT_FILENAME ${pkgs.cgit}/cgit/cgit.cgi;
fastcgi_param QUERY_STRING $args;
fastcgi_param HTTP_HOST $server_name;
fastcgi_pass unix:${globalConfig.services.fcgiwrap.socketAddress};
'' + (
if cfg.location == "/"
then
''
fastcgi_param PATH_INFO $uri;
''
else
''
fastcgi_split_path_info ^(${location}/)(/?.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
''
);
};
};
}));
};
config =
let
vhosts = config.services.nginx.virtualHosts;
in
mkIf (any (name: vhosts.${name}.cgit.enable) (attrNames vhosts)) {
# make the cgitrc manpage available
environment.systemPackages = [ pkgs.cgit ];
services.fcgiwrap.enable = true;
};
meta = {
maintainers = with lib.maintainers; [ bsima ]; # afix-space hmenke ];
};
}
|