Module for gitit
This commit is contained in:
commit
78340b56f7
27
flake.lock
generated
Normal file
27
flake.lock
generated
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1640871638,
|
||||||
|
"narHash": "sha256-ty6sGnJUQEkCd43At5U3DRQZD7rPARz5VginSW6hZ3k=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "5b091d4fbe3b7b7493c3b46fe0842e4b30ea24b3",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
54
flake.nix
Normal file
54
flake.nix
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
outputs = { self, nixpkgs }: rec {
|
||||||
|
overlay = final: prev: {
|
||||||
|
gitit = prev.callPackage ./gitit.nix {};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Provide module for gitit
|
||||||
|
nixosModules = builtins.listToAttrs (map (x: {
|
||||||
|
name = x;
|
||||||
|
value = import (./modules + "/${x}");
|
||||||
|
}) (builtins.attrNames (builtins.readDir ./modules)));
|
||||||
|
|
||||||
|
# Provide the gitit binary. nixpkgs does provide the binary as well, but
|
||||||
|
# it's built from a version that has a critical bug, login doesn't work
|
||||||
|
packages.x86_64-linux.gitit = with nixpkgs.legacyPackages.x86_64-linux;
|
||||||
|
callPackage ./gitit {};
|
||||||
|
defaultPackage.x86_64-linux = packages.x86_64-linux.gitit;
|
||||||
|
|
||||||
|
# Nixos integration tests for basic functionality
|
||||||
|
checks.x86_64-linux.gitit =
|
||||||
|
nixpkgs.legacyPackages.x86_64-linux.nixosTest (
|
||||||
|
import ./test.nix { modules = builtins.attrValues self.nixosModules; }
|
||||||
|
);
|
||||||
|
|
||||||
|
# For playing around in a container
|
||||||
|
# sudo nixos-container create gitit --flake .
|
||||||
|
nixosConfigurations.container = nixpkgs.lib.nixosSystem {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
modules =
|
||||||
|
[ ({ pkgs, ... }: {
|
||||||
|
imports = builtins.attrValues self.nixosModules ++ [];
|
||||||
|
boot.isContainer = true;
|
||||||
|
environment.systemPackages = [
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
# Let 'nixos-version --json' know about the Git revision
|
||||||
|
# of this flake.
|
||||||
|
system.configurationRevision = nixpkgs.lib.mkIf (self ? rev) self.rev;
|
||||||
|
|
||||||
|
# Network configuration.
|
||||||
|
networking.useDHCP = false;
|
||||||
|
networking.firewall.allowedTCPPorts = [ 5001 ];
|
||||||
|
|
||||||
|
services.gitit = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
40
gitit/cabal.nix
Normal file
40
gitit/cabal.nix
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{ mkDerivation, aeson, base, base64-bytestring, blaze-html
|
||||||
|
, bytestring, ConfigFile, containers, directory, doctemplates, feed
|
||||||
|
, fetchgit, filepath, filestore, ghc, ghc-paths, happstack-server
|
||||||
|
, hoauth2, hslogger, HStringTemplate, HTTP, http-client-tls
|
||||||
|
, http-conduit, json, lib, mtl, network, network-bsd, network-uri
|
||||||
|
, old-locale, old-time, pandoc, pandoc-types, parsec, pretty
|
||||||
|
, process, random, recaptcha, safe, SHA, skylighting, split, syb
|
||||||
|
, tagsoup, temporary, text, time, uri-bytestring, url, utf8-string
|
||||||
|
, uuid, xhtml, xml, xml-conduit, xml-types, xss-sanitize, zlib
|
||||||
|
}:
|
||||||
|
mkDerivation {
|
||||||
|
pname = "gitit";
|
||||||
|
version = "0.15.1.0";
|
||||||
|
src = fetchgit {
|
||||||
|
url = "https://github.com/jgm/gitit";
|
||||||
|
sha256 = "0rzjgi6q338n6cv74438q81v322x2wjrpa7zdvp47z6hrilwpqaa";
|
||||||
|
rev = "11a18b034cc49ddaca652ac745fd308405a1fdad";
|
||||||
|
fetchSubmodules = true;
|
||||||
|
};
|
||||||
|
isLibrary = true;
|
||||||
|
isExecutable = true;
|
||||||
|
enableSeparateDataOutput = true;
|
||||||
|
libraryHaskellDepends = [
|
||||||
|
aeson base base64-bytestring blaze-html bytestring ConfigFile
|
||||||
|
containers directory doctemplates feed filepath filestore ghc
|
||||||
|
ghc-paths happstack-server hoauth2 hslogger HStringTemplate HTTP
|
||||||
|
http-client-tls http-conduit json mtl network network-bsd
|
||||||
|
network-uri old-locale old-time pandoc pandoc-types parsec pretty
|
||||||
|
process random recaptcha safe SHA skylighting split syb tagsoup
|
||||||
|
temporary text time uri-bytestring url utf8-string uuid xhtml xml
|
||||||
|
xml-conduit xml-types xss-sanitize zlib
|
||||||
|
];
|
||||||
|
executableHaskellDepends = [
|
||||||
|
base bytestring directory filepath hslogger HTTP mtl network
|
||||||
|
network-uri syb text url utf8-string
|
||||||
|
];
|
||||||
|
description = "Wiki using happstack, git or darcs, and pandoc";
|
||||||
|
license = "GPL";
|
||||||
|
}
|
||||||
|
|
62
gitit/default.nix
Normal file
62
gitit/default.nix
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{ lib, haskellPackages, haskell, removeReferencesTo
|
||||||
|
# “Plugins” are a fancy way of saying gitit will invoke
|
||||||
|
# GHC at *runtime*, which in turn makes it pull GHC
|
||||||
|
# into its runtime closure. Only enable if you really need
|
||||||
|
# that feature. But if you do you’ll want to use gitit
|
||||||
|
# as a library anyway.
|
||||||
|
, pluginSupport ? false
|
||||||
|
}:
|
||||||
|
|
||||||
|
# this is similar to what we do with the pandoc executable
|
||||||
|
|
||||||
|
let
|
||||||
|
plain = haskellPackages.callPackage ./cabal.nix {};
|
||||||
|
plugins =
|
||||||
|
if pluginSupport
|
||||||
|
then plain
|
||||||
|
else haskell.lib.compose.disableCabalFlag "plugins" plain;
|
||||||
|
static = haskell.lib.compose.justStaticExecutables plugins;
|
||||||
|
|
||||||
|
in
|
||||||
|
(haskell.lib.compose.overrideCabal (drv: {
|
||||||
|
buildTools = (drv.buildTools or []) ++ [ removeReferencesTo ];
|
||||||
|
}) static).overrideAttrs (drv: {
|
||||||
|
|
||||||
|
# These libraries are still referenced, because they generate
|
||||||
|
# a `Paths_*` module for figuring out their version.
|
||||||
|
# The `Paths_*` module is generated by Cabal, and contains the
|
||||||
|
# version, but also paths to e.g. the data directories, which
|
||||||
|
# lead to a transitive runtime dependency on the whole GHC distribution.
|
||||||
|
# This should ideally be fixed in haskellPackages (or even Cabal),
|
||||||
|
# but a minimal gitit is important enough to patch it manually.
|
||||||
|
disallowedReferences = [
|
||||||
|
haskellPackages.pandoc-types
|
||||||
|
haskellPackages.HTTP
|
||||||
|
haskellPackages.pandoc
|
||||||
|
haskellPackages.happstack-server
|
||||||
|
haskellPackages.filestore
|
||||||
|
];
|
||||||
|
postInstall = ''
|
||||||
|
remove-references-to \
|
||||||
|
-t ${haskellPackages.pandoc-types} \
|
||||||
|
$out/bin/gitit
|
||||||
|
remove-references-to \
|
||||||
|
-t ${haskellPackages.HTTP} \
|
||||||
|
$out/bin/gitit
|
||||||
|
remove-references-to \
|
||||||
|
-t ${haskellPackages.pandoc} \
|
||||||
|
$out/bin/gitit
|
||||||
|
remove-references-to \
|
||||||
|
-t ${haskellPackages.happstack-server} \
|
||||||
|
$out/bin/gitit
|
||||||
|
remove-references-to \
|
||||||
|
-t ${haskellPackages.filestore} \
|
||||||
|
$out/bin/gitit
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = drv.meta // {
|
||||||
|
maintainers = drv.meta.maintainers or []
|
||||||
|
++ [ lib.maintainers.Profpatsch ];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
159
modules/gitit/default.nix
Normal file
159
modules/gitit/default.nix
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
{ config, lib, pkgs, ...}:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.services.gitit;
|
||||||
|
yesNo = b: if b then "yes" else "no";
|
||||||
|
gititConf = with cfg; pkgs.writeText "gitit.conf" ''
|
||||||
|
address: ${address}
|
||||||
|
port: ${toString port}
|
||||||
|
wiki-title: ${wiki-title}
|
||||||
|
repository-type: Git
|
||||||
|
repository-path: /var/lib/gitit/wikidata
|
||||||
|
require-authentication: ${require-authentication}
|
||||||
|
authentication-method: ${authentication-method}
|
||||||
|
static-dir: ${toString static-dir}
|
||||||
|
templates-dir: ${toString templates-dir}
|
||||||
|
cache-dir: /var/lib/gitit/cache
|
||||||
|
log-file: /var/lib/gitit/gitit.log
|
||||||
|
disable-registration: ${yesNo disable-registration}
|
||||||
|
access-question: ${access-question}
|
||||||
|
access-question-answers: ${access-question-answers}
|
||||||
|
'';
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
options.services.gitit = {
|
||||||
|
enable = mkEnableOption "gitit";
|
||||||
|
address = mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "0.0.0.0";
|
||||||
|
description = "Sets the IP address on which the web server will listen.";
|
||||||
|
};
|
||||||
|
port = mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 5001;
|
||||||
|
description = "Sets the port on which the web server will run.";
|
||||||
|
};
|
||||||
|
disable-registration = mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "If true, disables registering new users on the wiki";
|
||||||
|
};
|
||||||
|
wiki-title = mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "Wiki";
|
||||||
|
description = "The title of the wiki.";
|
||||||
|
};
|
||||||
|
access-question = mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
specifies a question that users must answer when they attempt to create
|
||||||
|
an account, along with a comma-separated list of acceptable answers.
|
||||||
|
This can be used to institute a rudimentary password for signing up as
|
||||||
|
a user on the wiki, or as an alternative to reCAPTCHA.
|
||||||
|
Example:
|
||||||
|
access-question: What is the code given to you by Ms. X?
|
||||||
|
access-question-answers: RED DOG, red dog
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
access-question-answers = mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
specifies the answer that users must answer when they attempt to create
|
||||||
|
an account, along with a comma-separated list of acceptable answers.
|
||||||
|
This can be used to institute a rudimentary password for signing up as
|
||||||
|
a user on the wiki, or as an alternative to reCAPTCHA.
|
||||||
|
Example:
|
||||||
|
access-question: What is the code given to you by Ms. X?
|
||||||
|
access-question-answers: RED DOG, red dog
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
require-authentication = mkOption {
|
||||||
|
type = lib.types.enum ["none" "read" "modify"];
|
||||||
|
default = "modify";
|
||||||
|
description = ''
|
||||||
|
if 'none' login is never required, and pages can be edited anonymously.
|
||||||
|
if 'modify', login is required to modify the wiki (edit, add, delete pages, upload files)
|
||||||
|
if 'read', login is required to see any wiki pages
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
static-dir = mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
default = "/var/lib/gitit/data/static";
|
||||||
|
description = ''
|
||||||
|
specifies the path of the static directory (containing javascript, css,
|
||||||
|
and images). If it does not exist, gitit will create it and populate it
|
||||||
|
with required scripts, stylesheets and images.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
templates-dir = mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
default = "/var/lib/gitit/data/templates";
|
||||||
|
description = ''
|
||||||
|
specifies the path of the directory containing page templates. If it
|
||||||
|
does not exist, gitit will create it with default templates. Users may
|
||||||
|
with to edit the templates to customize the appearance of their wiki.
|
||||||
|
The template files are HStringTemplate templates. Variables to be
|
||||||
|
interpolated appear between $'s. Literal $'s must be backslash-escaped.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
authentication-method = mkOption {
|
||||||
|
type = lib.types.enum ["form" "http" "generic"];
|
||||||
|
default = "form";
|
||||||
|
description = ''
|
||||||
|
'form' means that users will be logged in and registered using forms in
|
||||||
|
the gitit web interface.
|
||||||
|
|
||||||
|
'http' means that gitit will assume that HTTP authentication is in
|
||||||
|
place and take the logged in username from the "Authorization" field of
|
||||||
|
the HTTP request header (in addition, the login/logout and registration
|
||||||
|
links will be suppressed).
|
||||||
|
|
||||||
|
'generic' means that gitit will assume that some form of authentication
|
||||||
|
is in place that directly sets REMOTE_USER to the name of the
|
||||||
|
authenticated user (e.g. mod_auth_cas on apache).
|
||||||
|
|
||||||
|
'rpx' means that gitit will attempt to log in through
|
||||||
|
https://rpxnow.com. This requires that 'rpx-domain', 'rpx-key', and
|
||||||
|
'base-url' be set below, and that 'curl' be in the system path.
|
||||||
|
|
||||||
|
'github' means that you are redirected to github website and need to
|
||||||
|
avail gitit to use your credential from there (github name and email).
|
||||||
|
Your email is used to identify you when you push your wiki data to git
|
||||||
|
to identify you as the author
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
users.users.gitit = {
|
||||||
|
home = "/var/lib/gitit";
|
||||||
|
createHome = true;
|
||||||
|
isSystemUser = true;
|
||||||
|
group = "gitit";
|
||||||
|
};
|
||||||
|
users.groups.gitit = {};
|
||||||
|
systemd.services.gitit = {
|
||||||
|
description = "Git and Pandoc Powered Wiki";
|
||||||
|
after = [ "network.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
path = with pkgs; [ curl git ];
|
||||||
|
preStart = ''
|
||||||
|
chown gitit:gitit -R /var/lib/gitit
|
||||||
|
'';
|
||||||
|
serviceConfig = {
|
||||||
|
User = config.users.users.gitit.name;
|
||||||
|
Group = config.users.groups.gitit.name;
|
||||||
|
ExecStart = "${pkgs.gitit}/bin/gitit -f ${gititConf}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
57
test.nix
Normal file
57
test.nix
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
{ modules }:
|
||||||
|
{
|
||||||
|
machine = { config, pkgs, lib, ... }:
|
||||||
|
{
|
||||||
|
imports = modules;
|
||||||
|
|
||||||
|
environment.systemPackages = [
|
||||||
|
pkgs.curl
|
||||||
|
];
|
||||||
|
|
||||||
|
services.gitit = {
|
||||||
|
enable = true;
|
||||||
|
port = 4001;
|
||||||
|
wiki-title = "Test Wiki";
|
||||||
|
address = "127.0.0.1";
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.extraHosts = ''
|
||||||
|
127.0.0.1 wiki.local
|
||||||
|
'';
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts."wiki.local" = {
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:4001";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
testScript =
|
||||||
|
let username = "foo";
|
||||||
|
password = "foobar123";
|
||||||
|
form = "'username=${username}&email=&full_name_1=&password=${password}&password2=${password}&destination=%2F_index®ister=Register'";
|
||||||
|
in
|
||||||
|
''
|
||||||
|
start_all()
|
||||||
|
|
||||||
|
machine.wait_for_unit("gitit.service")
|
||||||
|
machine.wait_for_open_port(4001)
|
||||||
|
|
||||||
|
if "Test Wiki" not in machine.succeed("curl -sS http://localhost:4001"):
|
||||||
|
raise Exception("Title not set properly")
|
||||||
|
machine.succeed("curl --data-raw ${form} 'http://localhost:4001/_register?destination=%2F_index'")
|
||||||
|
|
||||||
|
machine.wait_for_unit("nginx.service")
|
||||||
|
machine.wait_for_open_port(80)
|
||||||
|
|
||||||
|
if "Test Wiki" not in machine.succeed("curl -sS http://wiki.local:80"):
|
||||||
|
raise Exception("Wiki not available through nginx")
|
||||||
|
'';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user