···
1
-
{ config, lib, pkgs, ... }:
7
-
cfg = config.services.gitit;
9
-
homeDir = "/var/lib/gitit";
11
-
toYesNo = b: if b then "yes" else "no";
13
-
gititShared = with cfg.haskellPackages; gitit + "/share/" + ghc.targetPrefix + ghc.haskellCompilerName + "/" + gitit.pname + "-" + gitit.version;
15
-
gititWithPkgs = hsPkgs: extras: hsPkgs.ghcWithPackages (self: with self; [ gitit ] ++ (extras self));
17
-
gititSh = hsPkgs: extras: with pkgs; let
18
-
env = gititWithPkgs hsPkgs extras;
19
-
in writeScript "gitit" ''
22
-
export NIX_GHC="${env}/bin/ghc"
23
-
export NIX_GHCPKG="${env}/bin/ghc-pkg"
24
-
export NIX_GHC_DOCDIR="${env}/share/doc/ghc/html"
25
-
export NIX_GHC_LIBDIR=$( $NIX_GHC --print-libdir )
26
-
${env}/bin/gitit -f ${configFile}
34
-
description = lib.mdDoc "Enable the gitit service.";
37
-
haskellPackages = mkOption {
38
-
default = pkgs.haskellPackages;
39
-
defaultText = literalExpression "pkgs.haskellPackages";
40
-
example = literalExpression "pkgs.haskell.packages.ghc784";
41
-
description = lib.mdDoc "haskellPackages used to build gitit and plugins.";
44
-
extraPackages = mkOption {
45
-
type = types.functionTo (types.listOf types.package);
47
-
example = literalExpression ''
49
-
haskellPackages.wreq
52
-
description = lib.mdDoc ''
53
-
Extra packages available to ghc when running gitit. The
54
-
value must be a function which receives the attrset defined
55
-
in {var}`haskellPackages` as the sole argument.
59
-
address = mkOption {
61
-
default = "0.0.0.0";
62
-
description = lib.mdDoc "IP address on which the web server will listen.";
68
-
description = lib.mdDoc "Port on which the web server will run.";
71
-
wikiTitle = mkOption {
74
-
description = lib.mdDoc "The wiki title.";
77
-
repositoryType = mkOption {
78
-
type = types.enum ["git" "darcs" "mercurial"];
80
-
description = lib.mdDoc "Specifies the type of repository used for wiki content.";
83
-
repositoryPath = mkOption {
85
-
default = homeDir + "/wiki";
86
-
description = lib.mdDoc ''
87
-
Specifies the path of the repository directory. If it does not
88
-
exist, gitit will create it on startup.
92
-
requireAuthentication = mkOption {
93
-
type = types.enum [ "none" "modify" "read" ];
95
-
description = lib.mdDoc ''
96
-
If 'none', login is never required, and pages can be edited
97
-
anonymously. If 'modify', login is required to modify the wiki
98
-
(edit, add, delete pages, upload files). If 'read', login is
99
-
required to see any wiki pages.
103
-
authenticationMethod = mkOption {
104
-
type = types.enum [ "form" "http" "generic" "github" ];
106
-
description = lib.mdDoc ''
107
-
'form' means that users will be logged in and registered using forms
108
-
in the gitit web interface. 'http' means that gitit will assume that
109
-
HTTP authentication is in place and take the logged in username from
110
-
the "Authorization" field of the HTTP request header (in addition,
111
-
the login/logout and registration links will be suppressed).
112
-
'generic' means that gitit will assume that some form of
113
-
authentication is in place that directly sets REMOTE_USER to the name
114
-
of the authenticated user (e.g. mod_auth_cas on apache). 'rpx' means
115
-
that gitit will attempt to log in through https://rpxnow.com. This
116
-
requires that 'rpx-domain', 'rpx-key', and 'base-url' be set below,
117
-
and that 'curl' be in the system path.
121
-
userFile = mkOption {
123
-
default = homeDir + "/gitit-users";
124
-
description = lib.mdDoc ''
125
-
Specifies the path of the file containing user login information. If
126
-
it does not exist, gitit will create it (with an empty user list).
127
-
This file is not used if 'http' is selected for
128
-
authentication-method.
132
-
sessionTimeout = mkOption {
135
-
description = lib.mdDoc ''
136
-
Number of minutes of inactivity before a session expires.
140
-
staticDir = mkOption {
142
-
default = gititShared + "/data/static";
143
-
description = lib.mdDoc ''
144
-
Specifies the path of the static directory (containing javascript,
145
-
css, and images). If it does not exist, gitit will create it and
146
-
populate it with required scripts, stylesheets, and images.
150
-
defaultPageType = mkOption {
151
-
type = types.enum [ "markdown" "rst" "latex" "html" "markdown+lhs" "rst+lhs" "latex+lhs" ];
152
-
default = "markdown";
153
-
description = lib.mdDoc ''
154
-
Specifies the type of markup used to interpret pages in the wiki.
155
-
Possible values are markdown, rst, latex, html, markdown+lhs,
156
-
rst+lhs, and latex+lhs. (the +lhs variants treat the input as
157
-
literate Haskell. See pandoc's documentation for more details.) If
158
-
Markdown is selected, pandoc's syntax extensions (for footnotes,
159
-
delimited code blocks, etc.) will be enabled. Note that pandoc's
160
-
restructuredtext parser is not complete, so some pages may not be
161
-
rendered correctly if rst is selected. The same goes for latex and
167
-
type = types.enum [ "mathml" "raw" "mathjax" "jsmath" "google" ];
168
-
default = "mathml";
169
-
description = lib.mdDoc ''
170
-
Specifies how LaTeX math is to be displayed. Possible values are
171
-
mathml, raw, mathjax, jsmath, and google. If mathml is selected,
172
-
gitit will convert LaTeX math to MathML and link in a script,
173
-
MathMLinHTML.js, that allows the MathML to be seen in Gecko browsers,
174
-
IE + mathplayer, and Opera. In other browsers you may get a jumble of
175
-
characters. If raw is selected, the LaTeX math will be displayed as
176
-
raw LaTeX math. If mathjax is selected, gitit will link to the
177
-
remote mathjax script. If jsMath is selected, gitit will link to the
178
-
script /js/jsMath/easy/load.js, and will assume that jsMath has been
179
-
installed into the js/jsMath directory. This is the most portable
180
-
solution. If google is selected, the google chart API is called to
181
-
render the formula as an image. This requires a connection to google,
182
-
and might raise a technical or a privacy problem.
186
-
mathJaxScript = mkOption {
188
-
default = "https://d3eoax9i5htok0.cloudfront.net/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
189
-
description = lib.mdDoc ''
190
-
Specifies the path to MathJax rendering script. You might want to
191
-
use your own MathJax script to render formulas without Internet
192
-
connection or if you want to use some special LaTeX packages. Note:
193
-
path specified there cannot be an absolute path to a script on your
194
-
hdd, instead you should run your (local if you wish) HTTP server
195
-
which will serve the MathJax.js script. You can easily (in four lines
196
-
of code) serve MathJax.js using
197
-
http://happstack.com/docs/crashcourse/FileServing.html Do not forget
198
-
the "http://" prefix (e.g. http://localhost:1234/MathJax.js).
202
-
showLhsBirdTracks = mkOption {
205
-
description = lib.mdDoc ''
206
-
Specifies whether to show Haskell code blocks in "bird style", with
207
-
"> " at the beginning of each line.
211
-
templatesDir = mkOption {
213
-
default = gititShared + "/data/templates";
214
-
description = lib.mdDoc ''
215
-
Specifies the path of the directory containing page templates. If it
216
-
does not exist, gitit will create it with default templates. Users
217
-
may wish to edit the templates to customize the appearance of their
218
-
wiki. The template files are HStringTemplate templates. Variables to
219
-
be interpolated appear between $\'s. Literal $\'s must be
224
-
logFile = mkOption {
226
-
default = homeDir + "/gitit.log";
227
-
description = lib.mdDoc ''
228
-
Specifies the path of gitit's log file. If it does not exist, gitit
229
-
will create it. The log is in Apache combined log format.
233
-
logLevel = mkOption {
234
-
type = types.enum [ "DEBUG" "INFO" "NOTICE" "WARNING" "ERROR" "CRITICAL" "ALERT" "EMERGENCY" ];
236
-
description = lib.mdDoc ''
237
-
Determines how much information is logged. Possible values (from
238
-
most to least verbose) are DEBUG, INFO, NOTICE, WARNING, ERROR,
239
-
CRITICAL, ALERT, EMERGENCY.
243
-
frontPage = mkOption {
245
-
default = "Front Page";
246
-
description = lib.mdDoc ''
247
-
Specifies which wiki page is to be used as the wiki's front page.
248
-
Gitit creates a default front page on startup, if one does not exist
253
-
noDelete = mkOption {
255
-
default = "Front Page, Help";
256
-
description = lib.mdDoc ''
257
-
Specifies pages that cannot be deleted through the web interface.
258
-
(They can still be deleted directly using git or darcs.) A
259
-
comma-separated list of page names. Leave blank to allow every page
264
-
noEdit = mkOption {
267
-
description = lib.mdDoc ''
268
-
Specifies pages that cannot be edited through the web interface.
269
-
Leave blank to allow every page to be edited.
273
-
defaultSummary = mkOption {
276
-
description = lib.mdDoc ''
277
-
Specifies text to be used in the change description if the author
278
-
leaves the "description" field blank. If default-summary is blank
279
-
(the default), the author will be required to fill in the description
284
-
tableOfContents = mkOption {
287
-
description = lib.mdDoc ''
288
-
Specifies whether to print a tables of contents (with links to
289
-
sections) on each wiki page.
293
-
plugins = mkOption {
294
-
type = with types; listOf str;
295
-
default = [ (gititShared + "/plugins/Dot.hs") ];
296
-
description = lib.mdDoc ''
297
-
Specifies a list of plugins to load. Plugins may be specified either
298
-
by their path or by their module name. If the plugin name starts
299
-
with Gitit.Plugin., gitit will assume that the plugin is an installed
300
-
module and will not try to find a source file.
304
-
useCache = mkOption {
307
-
description = lib.mdDoc ''
308
-
Specifies whether to cache rendered pages. Note that if use-feed is
309
-
selected, feeds will be cached regardless of the value of use-cache.
313
-
cacheDir = mkOption {
315
-
default = homeDir + "/cache";
316
-
description = lib.mdDoc "Path where rendered pages will be cached.";
319
-
maxUploadSize = mkOption {
322
-
description = lib.mdDoc ''
323
-
Specifies an upper limit on the size (in bytes) of files uploaded
324
-
through the wiki's web interface. To disable uploads, set this to
325
-
0K. This will result in the uploads link disappearing and the
326
-
_upload url becoming inactive.
330
-
maxPageSize = mkOption {
333
-
description = lib.mdDoc "Specifies an upper limit on the size (in bytes) of pages.";
336
-
debugMode = mkOption {
339
-
description = lib.mdDoc "Causes debug information to be logged while gitit is running.";
342
-
compressResponses = mkOption {
345
-
description = lib.mdDoc "Specifies whether HTTP responses should be compressed.";
348
-
mimeTypesFile = mkOption {
350
-
default = "/etc/mime/types.info";
351
-
description = lib.mdDoc ''
352
-
Specifies the path of a file containing mime type mappings. Each
353
-
line of the file should contain two fields, separated by whitespace.
354
-
The first field is the mime type, the second is a file extension.
359
-
If the file is not found, some simple defaults will be used.
363
-
useReCaptcha = mkOption {
366
-
description = lib.mdDoc ''
367
-
If true, causes gitit to use the reCAPTCHA service
368
-
(http://recaptcha.net) to prevent bots from creating accounts.
372
-
reCaptchaPrivateKey = mkOption {
373
-
type = with types; nullOr str;
375
-
description = lib.mdDoc ''
376
-
Specifies the private key for the reCAPTCHA service. To get
377
-
these, you need to create an account at http://recaptcha.net.
381
-
reCaptchaPublicKey = mkOption {
382
-
type = with types; nullOr str;
384
-
description = lib.mdDoc ''
385
-
Specifies the public key for the reCAPTCHA service. To get
386
-
these, you need to create an account at http://recaptcha.net.
390
-
accessQuestion = mkOption {
392
-
default = "What is the code given to you by Ms. X?";
393
-
description = lib.mdDoc ''
394
-
Specifies a question that users must answer when they attempt to
399
-
accessQuestionAnswers = mkOption {
401
-
default = "RED DOG, red dog";
402
-
description = lib.mdDoc ''
403
-
Specifies a question that users must answer when they attempt to
404
-
create an account, along with a comma-separated list of acceptable
405
-
answers. This can be used to institute a rudimentary password for
406
-
signing up as a user on the wiki, or as an alternative to reCAPTCHA.
408
-
access-question: What is the code given to you by Ms. X?
409
-
access-question-answers: RED DOG, red dog
413
-
rpxDomain = mkOption {
414
-
type = with types; nullOr str;
416
-
description = lib.mdDoc ''
417
-
Specifies the domain and key of your RPX account. The domain is just
418
-
the prefix of the complete RPX domain, so if your full domain is
419
-
'https://foo.rpxnow.com/', use 'foo' as the value of rpx-domain.
423
-
rpxKey = mkOption {
424
-
type = with types; nullOr str;
426
-
description = lib.mdDoc "RPX account access key.";
429
-
mailCommand = mkOption {
431
-
default = "sendmail %s";
432
-
description = lib.mdDoc ''
433
-
Specifies the command to use to send notification emails. '%s' will
434
-
be replaced by the destination email address. The body of the
435
-
message will be read from stdin. If this field is left blank,
436
-
password reset will not be offered.
440
-
resetPasswordMessage = mkOption {
441
-
type = types.lines;
443
-
> From: gitit@$hostname$
445
-
> Subject: Wiki password reset
447
-
> Hello $username$,
449
-
> To reset your password, please follow the link below:
450
-
> http://$hostname$:$port$$resetlink$
454
-
description = lib.mdDoc ''
455
-
Gives the text of the message that will be sent to the user should
456
-
she want to reset her password, or change other registration info.
457
-
The lines must be indented, and must begin with '>'. The initial
458
-
spaces and '> ' will be stripped off. $username$ will be replaced by
459
-
the user's username, $useremail$ by her email address, $hostname$ by
460
-
the hostname on which the wiki is running (as returned by the
461
-
hostname system call), $port$ by the port on which the wiki is
462
-
running, and $resetlink$ by the relative path of a reset link derived
463
-
from the user's existing hashed password. If your gitit wiki is being
464
-
proxied to a location other than the root path of $port$, you should
465
-
change the link to reflect this: for example, to
466
-
http://$hostname$/path/to/wiki$resetlink$ or
467
-
http://gitit.$hostname$$resetlink$
471
-
useFeed = mkOption {
474
-
description = lib.mdDoc ''
475
-
Specifies whether an ATOM feed should be enabled (for the site and
476
-
for individual pages).
480
-
baseUrl = mkOption {
481
-
type = with types; nullOr str;
483
-
description = lib.mdDoc ''
484
-
The base URL of the wiki, to be used in constructing feed IDs and RPX
485
-
token_urls. Set this if useFeed is false or authentication-method
490
-
absoluteUrls = mkOption {
493
-
description = lib.mdDoc ''
494
-
Make wikilinks absolute with respect to the base-url. So, for
495
-
example, in a wiki served at the base URL '/wiki', on a page
496
-
Sub/Page, the wikilink `[Cactus]()` will produce a link to
497
-
'/wiki/Cactus' if absoluteUrls is true, and a relative link to
498
-
'Cactus' (referring to '/wiki/Sub/Cactus') if absolute-urls is 'no'.
502
-
feedDays = mkOption {
505
-
description = lib.mdDoc "Number of days to be included in feeds.";
508
-
feedRefreshTime = mkOption {
511
-
description = lib.mdDoc "Number of minutes to cache feeds before refreshing.";
514
-
pdfExport = mkOption {
517
-
description = lib.mdDoc ''
518
-
If true, PDF will appear in export options. PDF will be created using
519
-
pdflatex, which must be installed and in the path. Note that PDF
520
-
exports create significant additional server load.
524
-
pandocUserData = mkOption {
525
-
type = with types; nullOr path;
527
-
description = lib.mdDoc ''
528
-
If a directory is specified, this will be searched for pandoc
529
-
customizations. These can include a templates/ directory for custom
530
-
templates for various export formats, an S5 directory for custom S5
531
-
styles, and a reference.odt for ODT exports. If no directory is
532
-
specified, $HOME/.pandoc will be searched. See pandoc's README for
537
-
xssSanitize = mkOption {
540
-
description = lib.mdDoc ''
541
-
If true, all HTML (including that produced by pandoc) is filtered
542
-
through xss-sanitize. Set to no only if you trust all of your users.
546
-
oauthClientId = mkOption {
547
-
type = with types; nullOr str;
549
-
description = lib.mdDoc "OAuth client ID";
552
-
oauthClientSecret = mkOption {
553
-
type = with types; nullOr str;
555
-
description = lib.mdDoc "OAuth client secret";
558
-
oauthCallback = mkOption {
559
-
type = with types; nullOr str;
561
-
description = lib.mdDoc "OAuth callback URL";
564
-
oauthAuthorizeEndpoint = mkOption {
565
-
type = with types; nullOr str;
567
-
description = lib.mdDoc "OAuth authorize endpoint";
570
-
oauthAccessTokenEndpoint = mkOption {
571
-
type = with types; nullOr str;
573
-
description = lib.mdDoc "OAuth access token endpoint";
576
-
githubOrg = mkOption {
577
-
type = with types; nullOr str;
579
-
description = lib.mdDoc "Github organization";
583
-
configFile = pkgs.writeText "gitit.conf" ''
584
-
address: ${cfg.address}
585
-
port: ${toString cfg.port}
586
-
wiki-title: ${cfg.wikiTitle}
587
-
repository-type: ${cfg.repositoryType}
588
-
repository-path: ${cfg.repositoryPath}
589
-
require-authentication: ${cfg.requireAuthentication}
590
-
authentication-method: ${cfg.authenticationMethod}
591
-
user-file: ${cfg.userFile}
592
-
session-timeout: ${toString cfg.sessionTimeout}
593
-
static-dir: ${cfg.staticDir}
594
-
default-page-type: ${cfg.defaultPageType}
596
-
mathjax-script: ${cfg.mathJaxScript}
597
-
show-lhs-bird-tracks: ${toYesNo cfg.showLhsBirdTracks}
598
-
templates-dir: ${cfg.templatesDir}
599
-
log-file: ${cfg.logFile}
600
-
log-level: ${cfg.logLevel}
601
-
front-page: ${cfg.frontPage}
602
-
no-delete: ${cfg.noDelete}
603
-
no-edit: ${cfg.noEdit}
604
-
default-summary: ${cfg.defaultSummary}
605
-
table-of-contents: ${toYesNo cfg.tableOfContents}
606
-
plugins: ${concatStringsSep "," cfg.plugins}
607
-
use-cache: ${toYesNo cfg.useCache}
608
-
cache-dir: ${cfg.cacheDir}
609
-
max-upload-size: ${cfg.maxUploadSize}
610
-
max-page-size: ${cfg.maxPageSize}
611
-
debug-mode: ${toYesNo cfg.debugMode}
612
-
compress-responses: ${toYesNo cfg.compressResponses}
613
-
mime-types-file: ${cfg.mimeTypesFile}
614
-
use-recaptcha: ${toYesNo cfg.useReCaptcha}
615
-
recaptcha-private-key: ${toString cfg.reCaptchaPrivateKey}
616
-
recaptcha-public-key: ${toString cfg.reCaptchaPublicKey}
617
-
access-question: ${cfg.accessQuestion}
618
-
access-question-answers: ${cfg.accessQuestionAnswers}
619
-
rpx-domain: ${toString cfg.rpxDomain}
620
-
rpx-key: ${toString cfg.rpxKey}
621
-
mail-command: ${cfg.mailCommand}
622
-
reset-password-message: ${cfg.resetPasswordMessage}
623
-
use-feed: ${toYesNo cfg.useFeed}
624
-
base-url: ${toString cfg.baseUrl}
625
-
absolute-urls: ${toYesNo cfg.absoluteUrls}
626
-
feed-days: ${toString cfg.feedDays}
627
-
feed-refresh-time: ${toString cfg.feedRefreshTime}
628
-
pdf-export: ${toYesNo cfg.pdfExport}
629
-
pandoc-user-data: ${toString cfg.pandocUserData}
630
-
xss-sanitize: ${toYesNo cfg.xssSanitize}
633
-
oauthclientid: ${toString cfg.oauthClientId}
634
-
oauthclientsecret: ${toString cfg.oauthClientSecret}
635
-
oauthcallback: ${toString cfg.oauthCallback}
636
-
oauthauthorizeendpoint: ${toString cfg.oauthAuthorizeEndpoint}
637
-
oauthaccesstokenendpoint: ${toString cfg.oauthAccessTokenEndpoint}
638
-
github-org: ${toString cfg.githubOrg}
645
-
options.services.gitit = gititOptions;
647
-
config = mkIf cfg.enable {
649
-
users.users.gitit = {
650
-
group = config.users.groups.gitit.name;
651
-
description = "Gitit user";
654
-
uid = config.ids.uids.gitit;
657
-
users.groups.gitit.gid = config.ids.gids.gitit;
659
-
systemd.services.gitit = let
660
-
uid = toString config.ids.uids.gitit;
661
-
gid = toString config.ids.gids.gitit;
663
-
description = "Git and Pandoc Powered Wiki";
664
-
after = [ "network.target" ];
665
-
wantedBy = [ "multi-user.target" ];
666
-
path = with pkgs; [ curl ]
667
-
++ optional cfg.pdfExport texlive.combined.scheme-basic
668
-
++ optional (cfg.repositoryType == "darcs") darcs
669
-
++ optional (cfg.repositoryType == "mercurial") mercurial
670
-
++ optional (cfg.repositoryType == "git") git;
673
-
gm = "gitit@${config.networking.hostName}";
676
-
chown ${uid}:${gid} -R ${homeDir}
677
-
for dir in ${repositoryPath} ${staticDir} ${templatesDir} ${cacheDir}
682
-
find $dir -type d -exec chmod 0750 {} +
683
-
find $dir -type f -exec chmod 0640 {} +
686
-
cd ${repositoryPath}
688
-
if repositoryType == "darcs" then
693
-
echo "${gm}" > _darcs/prefs/email
695
-
else if repositoryType == "mercurial" then
700
-
cat >> .hg/hgrc <<NAMED
702
-
username = gitit ${gm}
710
-
git config user.email "${gm}"
711
-
git config user.name "gitit"
713
-
chown ${uid}:${gid} -R ${repositoryPath}
719
-
User = config.users.users.gitit.name;
720
-
Group = config.users.groups.gitit.name;
721
-
ExecStart = with cfg; gititSh haskellPackages extraPackages;