Compare commits
No commits in common. "3354f5b221d337600e9ba7ef635f7ae3575848ad" and "4d681f5f93e965c871d3e23509bdd74638e3c5e3" have entirely different histories.
3354f5b221
...
4d681f5f93
62 changed files with 970 additions and 737 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,4 +1 @@
|
||||||
result
|
configuration.nix
|
||||||
result-*
|
|
||||||
*.swp
|
|
||||||
/public.tar.gz
|
|
||||||
|
|
59
hive.nix
59
hive.nix
|
@ -1,59 +0,0 @@
|
||||||
let
|
|
||||||
sources = import ./npins;
|
|
||||||
metadata = import ./meta.nix;
|
|
||||||
|
|
||||||
defaultNixpkgs = importNixpkgsPath "x86_64-linux" sources."nixos-unstable";
|
|
||||||
|
|
||||||
inherit (defaultNixpkgs) lib;
|
|
||||||
|
|
||||||
revision = node: (builtins.fromJSON (builtins.readFile ./npins/sources.json)).pins.${pkgsVersion node}.revision;
|
|
||||||
|
|
||||||
mkNode = node: {
|
|
||||||
${node} = {
|
|
||||||
name,
|
|
||||||
nodes,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
imports = [./machines/${node}/_configuration.nix] ++ lib.attrByPath [ "imports" ] [] metadata.nodes.${node};
|
|
||||||
inherit (metadata.nodes.${node}) deployment;
|
|
||||||
nix.nixPath =
|
|
||||||
builtins.map (n: "${n}=${sources.${n}}") (builtins.attrNames sources)
|
|
||||||
++ ["nixpkgs=${mkNixpkgsPath name}"];
|
|
||||||
system.nixos.tags = [
|
|
||||||
(revision node)
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
pkgsVersion = node: lib.attrByPath [ node "nixpkgs" ] "nixos-unstable" metadata.nodes;
|
|
||||||
|
|
||||||
mkNixpkgsPath = node: sources.${pkgsVersion node};
|
|
||||||
|
|
||||||
mkNixpkgs = node: {
|
|
||||||
${node} =
|
|
||||||
importNixpkgsPath
|
|
||||||
(lib.attrByPath [ "arch" ] "x86_64-linux" metadata.nodes.${node})
|
|
||||||
(mkNixpkgsPath node);
|
|
||||||
};
|
|
||||||
|
|
||||||
importNixpkgsPath = arch: p: import p {
|
|
||||||
config.allowUnfree = true;
|
|
||||||
overlays = import ./pkgs/overlays.nix;
|
|
||||||
system = arch;
|
|
||||||
};
|
|
||||||
|
|
||||||
nodes = builtins.attrNames metadata.nodes;
|
|
||||||
|
|
||||||
concatAttrs = builtins.foldl' (x: y: x // y) {};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
meta = {
|
|
||||||
specialArgs = {inherit metadata;};
|
|
||||||
nixpkgs = defaultNixpkgs;
|
|
||||||
nodeNixpkgs = concatAttrs (builtins.map mkNixpkgs nodes);
|
|
||||||
specialArgs = {
|
|
||||||
lib = lib;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// (concatAttrs (builtins.map mkNode nodes))
|
|
|
@ -9,7 +9,7 @@
|
||||||
[
|
[
|
||||||
# Include the results of the hardware scan.
|
# Include the results of the hardware scan.
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
./shared-hackens
|
../../profiles/shared-hackens
|
||||||
];
|
];
|
||||||
|
|
||||||
# Use the GRUB 2 boot loader.
|
# Use the GRUB 2 boot loader.
|
|
@ -7,25 +7,27 @@
|
||||||
{
|
{
|
||||||
imports =
|
imports =
|
||||||
[
|
[
|
||||||
./_bootloader.nix
|
|
||||||
./_networking.nix
|
|
||||||
./_ssh.nix
|
|
||||||
./_users.nix
|
|
||||||
./dokuwiki.nix
|
|
||||||
./hardware-configuration.nix
|
./hardware-configuration.nix
|
||||||
./matterbridge.nix
|
./physical.nix
|
||||||
./nginx.nix
|
./core-hackens
|
||||||
./orga
|
../../secrets
|
||||||
./secrets
|
|
||||||
./static-sites.nix
|
|
||||||
./legacy-redir.nix
|
|
||||||
./webpass.nix
|
./webpass.nix
|
||||||
|
./nginx.nix
|
||||||
|
./dokuwiki.nix
|
||||||
|
./matterbridge.nix
|
||||||
|
./orga
|
||||||
|
./static-sites
|
||||||
];
|
];
|
||||||
|
|
||||||
time.timeZone = "Europe/Paris";
|
|
||||||
|
|
||||||
networking.hostName = "hackens-org"; # Define your hostname.
|
networking.hostName = "hackens-org"; # Define your hostname.
|
||||||
|
|
||||||
|
# dokuwiki overlay
|
||||||
|
nixpkgs.overlays = [
|
||||||
|
(self: super: {
|
||||||
|
dokuwiki = self.pkgs.callPackage ../../shared/dokuwiki.nix { };
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
# This value determines the NixOS release from which the default
|
# This value determines the NixOS release from which the default
|
||||||
# settings for stateful data, like file locations and database versions
|
# settings for stateful data, like file locations and database versions
|
||||||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
# on your system were taken. It‘s perfectly fine and recommended to leave
|
4
hosts/org/core-hackens/default.nix
Normal file
4
hosts/org/core-hackens/default.nix
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ ./personal-users.nix ./ssh-server.nix ./static-dns.nix ./programs.nix ];
|
||||||
|
}
|
|
@ -7,29 +7,27 @@
|
||||||
extraGroups = [ "wheel" ];
|
extraGroups = [ "wheel" ];
|
||||||
hashedPassword =
|
hashedPassword =
|
||||||
"$6$y/I6nKCMYUku7$91vTR5kYz4nHyhbuA/j6kPsD8Vfo/Rg7ri6Ympftra9V6emOt/mPg0AScECtYjSIxretvfQ3sPUF1Ho0IWx381";
|
"$6$y/I6nKCMYUku7$91vTR5kYz4nHyhbuA/j6kPsD8Vfo/Rg7ri6Ympftra9V6emOt/mPg0AScECtYjSIxretvfQ3sPUF1Ho0IWx381";
|
||||||
openssh.authorizedKeys.keyFiles = [ ../../pubkeys/raito.keys ];
|
openssh.authorizedKeys.keyFiles = [ ../../../pubkeys/raito.keys ];
|
||||||
};
|
};
|
||||||
gdoriathdohler = {
|
gdoriathdohler = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = [ "wheel" ];
|
extraGroups = [ "wheel" ];
|
||||||
openssh.authorizedKeys.keyFiles = [ ../../pubkeys/gdd.keys ];
|
openssh.authorizedKeys.keyFiles = [ ../../../pubkeys/gdd.keys ];
|
||||||
};
|
};
|
||||||
mdebray = {
|
mdebray = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = [ "wheel" ];
|
extraGroups = [ "wheel" ];
|
||||||
hashedPassword =
|
hashedPassword =
|
||||||
"$6$ujz06kXa4TgvPAbF$NaXkDuOUpf3.fBRh7JuygtS0V2U/Bz4N3DpbOznO.md44xEdlKwPH/pSbL9CQJBhI5kodaKZeSaoCyhzybBPA/";
|
"$6$ujz06kXa4TgvPAbF$NaXkDuOUpf3.fBRh7JuygtS0V2U/Bz4N3DpbOznO.md44xEdlKwPH/pSbL9CQJBhI5kodaKZeSaoCyhzybBPA/";
|
||||||
openssh.authorizedKeys.keyFiles = [ ../../pubkeys/sinavir.keys ];
|
openssh.authorizedKeys.keyFiles = [ ../../../pubkeys/sinavir.keys ];
|
||||||
};
|
};
|
||||||
hbarral = {
|
hbarral = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
extraGroups = [ "wheel" ];
|
extraGroups = [ "wheel" ];
|
||||||
openssh.authorizedKeys.keyFiles = [ ../../pubkeys/backslash.keys ];
|
openssh.authorizedKeys.keyFiles = [ ../../../pubkeys/backslash.keys ];
|
||||||
};
|
};
|
||||||
root.openssh.authorizedKeys.keyFiles = [
|
root.openssh.authorizedKeys.keyFiles =
|
||||||
../../pubkeys/beigbeder.keys
|
[ ../../../pubkeys/beigbeder.keys ../../../pubkeys/backup.keys ]; # Jacques Beigbeder est tjrs root.
|
||||||
../../pubkeys/sinavir.keys
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
1
hosts/org/core-hackens/programs.nix
Normal file
1
hosts/org/core-hackens/programs.nix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{ pkgs, ... }: { environment.systemPackages = with pkgs; [ vim git ]; }
|
9
hosts/org/core-hackens/ssh-server.nix
Normal file
9
hosts/org/core-hackens/ssh-server.nix
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{ ... }: {
|
||||||
|
# Enable the OpenSSH daemon.
|
||||||
|
services.openssh.enable = true;
|
||||||
|
services.openssh.passwordAuthentication = false;
|
||||||
|
|
||||||
|
# Open ports in the firewall.
|
||||||
|
networking.firewall.allowedTCPPorts = [ 22 ];
|
||||||
|
programs.mosh.enable = true;
|
||||||
|
}
|
1
hosts/org/core-hackens/static-dns.nix
Normal file
1
hosts/org/core-hackens/static-dns.nix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{ ... }: { networking.nameservers = [ "1.1.1.1" "8.8.8.8" ]; }
|
128
hosts/org/dokuwiki.nix
Normal file
128
hosts/org/dokuwiki.nix
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
{ config, pkgs, lib, ... }: {
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."new.hackens.org" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.dokuwiki.sites."new.hackens.org" = {
|
||||||
|
enable = false; # true;
|
||||||
|
settings = {
|
||||||
|
template = "bootstrap3";
|
||||||
|
license = "cc-by-sa";
|
||||||
|
title = "hackENS";
|
||||||
|
lang = "fr";
|
||||||
|
breadcrumbs = 0;
|
||||||
|
yourarehere = true;
|
||||||
|
userewrite = 1;
|
||||||
|
useacl = true;
|
||||||
|
htmlok = 1;
|
||||||
|
target._raw = ''
|
||||||
|
array(
|
||||||
|
'extern' => '_tab'
|
||||||
|
);
|
||||||
|
'';
|
||||||
|
sitemap = 7;
|
||||||
|
disableactions = "register";
|
||||||
|
superuser = "@admin";
|
||||||
|
start = "accueil";
|
||||||
|
htmlmail = 0;
|
||||||
|
authtype = "oauth";
|
||||||
|
tpl.bootstrap3 = {
|
||||||
|
showAddNewPage = "logged";
|
||||||
|
fluidContainer = 0;
|
||||||
|
};
|
||||||
|
plugin = {
|
||||||
|
tokenbucketauth.tba_send_mail = "hackens@clipper.ens.fr";
|
||||||
|
oauth.register-on-auth = true;
|
||||||
|
oauthkeycloak = {
|
||||||
|
key = "wiki";
|
||||||
|
secret._file = config.age.secrets.wikiOpenID.path;
|
||||||
|
openidurl =
|
||||||
|
"https://auth.rz.ens.wtf/auth/realms/hackENS/.well-known/openid-configuration/";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
pluginsConfig = {
|
||||||
|
|
||||||
|
authad = false;
|
||||||
|
authldap = false;
|
||||||
|
authpdo = false;
|
||||||
|
authmysql = false;
|
||||||
|
authpgsql = false;
|
||||||
|
oauthkeycloak = true;
|
||||||
|
popularity = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
plugins = [
|
||||||
|
|
||||||
|
(pkgs.stdenv.mkDerivation {
|
||||||
|
name = "catlist";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "xif-fr";
|
||||||
|
repo = "dokuwiki-plugin-catlist";
|
||||||
|
rev = "89e024cbf3c0e30def6db6651c72eb76de396785";
|
||||||
|
hash = "sha256-2GAUHxK3dnDhXIftd2luxmn1b84ABZvfjHBMQWeDiTs=";
|
||||||
|
};
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
cp -R * $out/
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
(pkgs.stdenv.mkDerivation {
|
||||||
|
name = "commonmark";
|
||||||
|
src = pkgs.fetchzip {
|
||||||
|
url =
|
||||||
|
"https://github.com/clockoon/dokuwiki-plugin-commonmark/releases/download/v1.2.1/release.tar.gz";
|
||||||
|
sha256 = "sha256-3fpN7SSDDQ3QAmzRuG5UMYrtGeL3ogiooPKc6g1gxRg=";
|
||||||
|
};
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
cp -R * $out/
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
(pkgs.stdenv.mkDerivation {
|
||||||
|
name = "oauth";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "cosmocode";
|
||||||
|
repo = "dokuwiki-plugin-oauth";
|
||||||
|
rev = "da4733221ed7b4fb3ac0e2429499b14ece3d5f2d";
|
||||||
|
hash = "sha256-CNRlaieYm/KCjZ9+OP9pMo5SGjJ4CUrNNdL4iVktCcU=";
|
||||||
|
};
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
cp -R * $out/
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
(pkgs.stdenv.mkDerivation {
|
||||||
|
name = "oauthkeycloak";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "YoitoFes";
|
||||||
|
repo = "dokuwiki-plugin-oauthkeycloak";
|
||||||
|
rev = "28892edb0207d128ddb94fa8a0bd216861a5626b";
|
||||||
|
hash = "sha256-nZo61nW9QjJiEo3FpYt1Zt7locuIDQ88AOn/ZnjjYUc=";
|
||||||
|
};
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
cp -R * $out/
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
|
||||||
|
];
|
||||||
|
templates = [
|
||||||
|
(pkgs.stdenv.mkDerivation rec {
|
||||||
|
name = "bootstrap3";
|
||||||
|
version = "2022-07-27";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "giterlizzi";
|
||||||
|
repo = "dokuwiki-template-bootstrap3";
|
||||||
|
rev = "v${version}";
|
||||||
|
hash = "sha256-B3Yd4lxdwqfCnfmZdp+i/Mzwn/aEuZ0ovagDxuR6lxo=";
|
||||||
|
};
|
||||||
|
installPhase = "mkdir -p $out; cp -R * $out/";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -17,7 +17,7 @@ in
|
||||||
];
|
];
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
enable = true;
|
enable = true;
|
||||||
virtualHosts."hackens.org" = {
|
virtualHosts."new.hackens.org" = {
|
||||||
locations = {
|
locations = {
|
||||||
"/orga" = {
|
"/orga" = {
|
||||||
proxyPass = "http://localhost:51666/orga";
|
proxyPass = "http://localhost:51666/orga";
|
||||||
|
@ -34,7 +34,7 @@ in
|
||||||
assets = assets;
|
assets = assets;
|
||||||
settings = {
|
settings = {
|
||||||
HACKENS_ORGA_DEBUG = "0";
|
HACKENS_ORGA_DEBUG = "0";
|
||||||
HACKENS_ORGA_ALLOWED_HOSTS = [ "hackens.org" ];
|
HACKENS_ORGA_ALLOWED_HOSTS = [ "new.hackens.org" ];
|
||||||
HACKENS_ORGA_SECRET_KEY._file = config.age.secrets.django.path;
|
HACKENS_ORGA_SECRET_KEY._file = config.age.secrets.django.path;
|
||||||
HACKENS_ORGA_DB_FILE = "/var/lib/hackens-orga/db.sqlite3";
|
HACKENS_ORGA_DB_FILE = "/var/lib/hackens-orga/db.sqlite3";
|
||||||
};
|
};
|
|
@ -9,7 +9,7 @@ let
|
||||||
isHasAttr = s: lib.isAttrs v && lib.hasAttr s v;
|
isHasAttr = s: lib.isAttrs v && lib.hasAttr s v;
|
||||||
in
|
in
|
||||||
if builtins.isString v then v
|
if builtins.isString v then v
|
||||||
else if builtins.isList v && lib.any lib.strings.isConvertibleWithToString v then (lib.concatMapStringsSep "," toString v)
|
else if builtins.isList v && lib.any lib.strings.isCoercibleToString v then (lib.concatMapStringsSep "," toString v)
|
||||||
else if builtins.isInt v then toString v
|
else if builtins.isInt v then toString v
|
||||||
else if builtins.isBool v then toString (if v then 1 else 0)
|
else if builtins.isBool v then toString (if v then 1 else 0)
|
||||||
else if isHasAttr "_file" then "$(cat ${v._file} | xargs)"
|
else if isHasAttr "_file" then "$(cat ${v._file} | xargs)"
|
15
hosts/org/physical.nix
Normal file
15
hosts/org/physical.nix
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
# Use the GRUB 2 boot loader.
|
||||||
|
boot.loader.grub.enable = true;
|
||||||
|
boot.loader.grub.version = 2;
|
||||||
|
boot.loader.grub.device = "/dev/vdb"; # or "nodev" for efi only
|
||||||
|
|
||||||
|
time.timeZone = "Europe/Paris";
|
||||||
|
|
||||||
|
networking.useDHCP = false;
|
||||||
|
networking.interfaces.eth0 = {
|
||||||
|
ipv4.addresses = [{ address = "129.199.129.76"; prefixLength = 24; }];
|
||||||
|
};
|
||||||
|
networking.defaultGateway = { address = "129.199.129.1"; interface = "eth0"; };
|
||||||
|
}
|
23
hosts/org/static-sites.nix
Normal file
23
hosts/org/static-sites.nix
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{ pkgs, lib, ... }:
|
||||||
|
let
|
||||||
|
sites = [
|
||||||
|
"/NdS"
|
||||||
|
"/2048"
|
||||||
|
"/prez"
|
||||||
|
"/known"
|
||||||
|
"/pub"
|
||||||
|
];
|
||||||
|
in
|
||||||
|
{
|
||||||
|
|
||||||
|
services.nginx.enable = true;
|
||||||
|
services.nginx.virtualHosts."new.hackens.org" = {
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
locations = lib.genAttrs sites (name: {
|
||||||
|
root = "/var/www";
|
||||||
|
extraConfig = "autoindex on;";
|
||||||
|
});
|
||||||
|
};
|
||||||
|
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||||
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
services.vaultwarden = {
|
services.vaultwarden = {
|
||||||
enable = true;
|
enable = true;
|
||||||
config = {
|
config = {
|
||||||
DOMAIN = "https://pass.hackens.org";
|
DOMAIN = "https://pass.new.hackens.org";
|
||||||
WEBSOCKET_ENABLED = true;
|
WEBSOCKET_ENABLED = true;
|
||||||
WEBSOCKET_PORT = 10500;
|
WEBSOCKET_PORT = 10500;
|
||||||
SIGNUPS_DOMAINS_WHITELIST = "ens.fr,ens.psl.eu";
|
SIGNUPS_DOMAINS_WHITELIST = "ens.fr,ens.psl.eu";
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.enable = true;
|
services.nginx.enable = true;
|
||||||
services.nginx.virtualHosts."pass.hackens.org" = {
|
services.nginx.virtualHosts."pass.new.hackens.org" = {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
locations."/" = {
|
locations."/" = {
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
# Use the GRUB 2 boot loader.
|
|
||||||
boot.loader.grub.enable = true;
|
|
||||||
boot.loader.grub.device = "/dev/vda"; # or "nodev" for efi only
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
networking.useDHCP = false;
|
|
||||||
systemd.network = {
|
|
||||||
enable = true;
|
|
||||||
networks = {
|
|
||||||
"10-uplink" = {
|
|
||||||
name = "eth0";
|
|
||||||
DHCP = "no";
|
|
||||||
address = [
|
|
||||||
"129.199.129.76/24"
|
|
||||||
];
|
|
||||||
networkConfig = {
|
|
||||||
Gateway = "129.199.129.1";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
networking.nameservers = [ "1.1.1.1" "8.8.8.8" ];
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
{ ... }: {
|
|
||||||
# Enable the OpenSSH daemon.
|
|
||||||
services.openssh.enable = true;
|
|
||||||
services.openssh.settings.PasswordAuthentication = false;
|
|
||||||
services.openssh.ports = [ 22 2222 ];
|
|
||||||
|
|
||||||
# Open ports in the firewall. (In fact not needed)
|
|
||||||
networking.firewall.allowedTCPPorts = [ 22 2222 ];
|
|
||||||
|
|
||||||
# Mosh <3
|
|
||||||
programs.mosh.enable = true;
|
|
||||||
}
|
|
|
@ -1,91 +0,0 @@
|
||||||
{ config, pkgs, lib, ... }: {
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."hackens.org" = {
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Si tu as des problèmes un jour, vide le cache avant tout
|
|
||||||
services.dokuwiki.sites."hackens.org" = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
template = "bootstrap3";
|
|
||||||
license = "cc-by-sa";
|
|
||||||
title = "hackENS";
|
|
||||||
lang = "fr";
|
|
||||||
breadcrumbs = 0;
|
|
||||||
yourarehere = true;
|
|
||||||
userewrite = 1;
|
|
||||||
useacl = true;
|
|
||||||
htmlok = 1;
|
|
||||||
target._raw = ''
|
|
||||||
array(
|
|
||||||
'extern' => '_tab'
|
|
||||||
);
|
|
||||||
'';
|
|
||||||
sitemap = 7;
|
|
||||||
disableactions = "register";
|
|
||||||
superuser = "@admin";
|
|
||||||
start = "accueil";
|
|
||||||
tpl.bootstrap3 = {
|
|
||||||
showAddNewPage = "logged";
|
|
||||||
fluidContainer = 0;
|
|
||||||
};
|
|
||||||
plugin.htmlok.htmlok=1;
|
|
||||||
};
|
|
||||||
pluginsConfig = {
|
|
||||||
|
|
||||||
authad = false;
|
|
||||||
authldap = false;
|
|
||||||
authpdo = false;
|
|
||||||
authmysql = false;
|
|
||||||
authpgsql = false;
|
|
||||||
popularity = false;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
plugins = [
|
|
||||||
(pkgs.fetchFromGitHub {
|
|
||||||
name = "catlist";
|
|
||||||
owner = "xif-fr";
|
|
||||||
repo = "dokuwiki-plugin-catlist";
|
|
||||||
rev = "147793e2b41e8cb6465df888eecfbc4ee54fb68a";
|
|
||||||
hash = "sha256-kTL0Hm4BeWpmusLnybmBM9JPpx+ss0e/cusDHu6hH2I=";
|
|
||||||
})
|
|
||||||
(pkgs.php.buildComposerProject (finalAttrs: {
|
|
||||||
pname = "commonmark";
|
|
||||||
name = "commonmark";
|
|
||||||
version = "1.3.1";
|
|
||||||
composerStrictValidation = false;
|
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "clockoon";
|
|
||||||
repo = "dokuwiki-plugin-commonmark";
|
|
||||||
rev = "671ab735193ffb1324064ff0ddb92f63408b8580";
|
|
||||||
hash = "sha256-0WFz71O6GLVZ1Mf5eu96cQ3t+H6F6VtlC3hNtlANwBs=";
|
|
||||||
};
|
|
||||||
vendorHash = "sha256-QnFdwc6IfdH98Hbm9jt6E/rO+u6I7kZqb7+hRnPra9I=";
|
|
||||||
postInstall = ''
|
|
||||||
rm -r $out/share
|
|
||||||
cp -r . $out
|
|
||||||
'';
|
|
||||||
}))
|
|
||||||
(pkgs.fetchFromGitHub {
|
|
||||||
name = "htmlok";
|
|
||||||
owner = "saggi-dw";
|
|
||||||
repo = "dokuwiki-plugin-htmlok";
|
|
||||||
rev = "f186dda6240c61079cd9166c1f17aabefa21c7d8";
|
|
||||||
hash = "sha256-3s+WAb1BG2mq8+wxpQ6HgPJZ+dx6v5e+vMXaOiLYceo=";
|
|
||||||
})
|
|
||||||
];
|
|
||||||
templates = [
|
|
||||||
(pkgs.fetchFromGitHub {
|
|
||||||
name = "bootstrap3";
|
|
||||||
owner = "giterlizzi";
|
|
||||||
repo = "dokuwiki-template-bootstrap3";
|
|
||||||
rev = "v2022-07-27";
|
|
||||||
hash = "sha256-B3Yd4lxdwqfCnfmZdp+i/Mzwn/aEuZ0ovagDxuR6lxo=";
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
{
|
|
||||||
services.nginx.virtualHosts = {
|
|
||||||
|
|
||||||
"www.hackens.org" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
extraConfig = ''
|
|
||||||
return 301 $scheme://hackens.org$request_uri;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
"new.hackens.org" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
extraConfig = ''
|
|
||||||
return 301 $scheme://hackens.org$request_uri;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"pass.new.hackens.org" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
extraConfig = ''
|
|
||||||
return 301 $scheme://pass.hackens.org$request_uri;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"known.hackens.org" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
extraConfig = ''
|
|
||||||
return 301 $scheme://hackens.org/known$request_uri;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"prez.hackens.org" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
extraConfig = ''
|
|
||||||
return 301 $scheme://hackens.org/prez$request_uri;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"pub.hackens.org" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
extraConfig = ''
|
|
||||||
return 301 $scheme://hackens.org/pub$request_uri;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"2048.hackens.org" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
extraConfig = ''
|
|
||||||
return 301 $scheme://hackens.org/2048$request_uri;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
{ pkgs, ... }: {
|
|
||||||
environment.systemPackages = [
|
|
||||||
pkgs.vim
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
{ pkgs, lib, ... }:
|
|
||||||
let
|
|
||||||
sites = [
|
|
||||||
"/2048"
|
|
||||||
"/prez"
|
|
||||||
"/known"
|
|
||||||
"/pub"
|
|
||||||
];
|
|
||||||
in
|
|
||||||
{
|
|
||||||
|
|
||||||
services.nginx.enable = true;
|
|
||||||
services.nginx.virtualHosts = {
|
|
||||||
"hackens.org" = {
|
|
||||||
forceSSL = true;
|
|
||||||
enableACME = true;
|
|
||||||
locations = lib.genAttrs sites (name: {
|
|
||||||
root = "/var/www";
|
|
||||||
extraConfig = ''
|
|
||||||
autoindex on;
|
|
||||||
charset utf-8;
|
|
||||||
'';
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
|
||||||
}
|
|
|
@ -1,203 +0,0 @@
|
||||||
# This is an example configuration for a "typical" small office/home
|
|
||||||
# router and wifi access point.
|
|
||||||
|
|
||||||
# You need to copy it to another filename and change the configuration
|
|
||||||
# wherever the text "EDIT" appears - please consult the tutorial
|
|
||||||
# documentation for details.
|
|
||||||
|
|
||||||
{ config, pkgs, lib, ... } :
|
|
||||||
let
|
|
||||||
inherit (pkgs.liminix.services) bundle oneshot longrun;
|
|
||||||
inherit (pkgs) serviceFns;
|
|
||||||
# EDIT: you can pick your preferred RFC1918 address space
|
|
||||||
# for NATted connections, if you don't like this one.
|
|
||||||
ipv4LocalNet = "10.8.0";
|
|
||||||
svc = config.system.service;
|
|
||||||
|
|
||||||
in rec {
|
|
||||||
boot = {
|
|
||||||
tftp = {
|
|
||||||
freeSpaceBytes = 3 * 1024 * 1024;
|
|
||||||
serverip = "10.0.0.1";
|
|
||||||
ipaddr = "10.0.0.8";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
../modules/bridge
|
|
||||||
../modules/dhcp6c
|
|
||||||
../modules/dnsmasq
|
|
||||||
../modules/firewall
|
|
||||||
../modules/hostapd
|
|
||||||
../modules/network
|
|
||||||
../modules/ntp
|
|
||||||
../modules/ppp
|
|
||||||
../modules/ssh
|
|
||||||
../modules/standard.nix
|
|
||||||
../modules/vlan
|
|
||||||
../modules/wlan.nix
|
|
||||||
];
|
|
||||||
rootfsType = "ubifs";
|
|
||||||
hostname = "LeJeu"; # EDIT
|
|
||||||
|
|
||||||
services.hostap = svc.hostapd.build {
|
|
||||||
interface = config.hardware.networkInterfaces.wlan;
|
|
||||||
# EDIT: you will want to change the obvious things
|
|
||||||
# here to values of your choice
|
|
||||||
params = {
|
|
||||||
ssid = "LeJeu";
|
|
||||||
channel = "1";
|
|
||||||
country_code = "FR";
|
|
||||||
wpa_passphrase = "not a real wifi password";
|
|
||||||
|
|
||||||
hw_mode="g";
|
|
||||||
ieee80211n = 1;
|
|
||||||
auth_algs = 1; # 1=wpa2, 2=wep, 3=both
|
|
||||||
wpa = 2; # 1=wpa, 2=wpa2, 3=both
|
|
||||||
wpa_key_mgmt = "WPA-PSK";
|
|
||||||
wpa_pairwise = "TKIP CCMP"; # auth for wpa (may not need this?)
|
|
||||||
rsn_pairwise = "CCMP"; # auth for wpa2
|
|
||||||
wmm_enabled = 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.int = svc.network.address.build {
|
|
||||||
interface = svc.bridge.primary.build { ifname = "int"; };
|
|
||||||
family = "inet"; address = "${ipv4LocalNet}.1"; prefixLength = 16;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.bridge = svc.bridge.members.build {
|
|
||||||
primary = services.int;
|
|
||||||
members = with config.hardware.networkInterfaces;
|
|
||||||
[ wlan lan ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.ntp = svc.ntp.build {
|
|
||||||
pools = { "pool.ntp.org" = ["iburst"]; };
|
|
||||||
makestep = { threshold = 1.0; limit = 3; };
|
|
||||||
};
|
|
||||||
|
|
||||||
services.sshd = svc.ssh.build { };
|
|
||||||
|
|
||||||
users.root = {
|
|
||||||
# EDIT: choose a root password and then use
|
|
||||||
# "mkpasswd -m sha512crypt" to determine the hash.
|
|
||||||
# It should start wirh $6$.
|
|
||||||
passwd = "$6$6HG7WALLQQY1LQDE$428cnouMJ7wVmyK9.dF1uWs7t0z9ztgp3MHvN5bbeo0M4Kqg/u2ThjoSHIjCEJQlnVpDOaEKcOjXAlIClHWN21";
|
|
||||||
openssh.authorizedKeys.keys = [
|
|
||||||
# EDIT: you can add your ssh pubkey here
|
|
||||||
# "ssh-rsa AAAAB3NzaC1....H6hKd user@example.com";
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.dns =
|
|
||||||
let interface = services.int;
|
|
||||||
in svc.dnsmasq.build {
|
|
||||||
resolvconf = services.resolvconf;
|
|
||||||
inherit interface;
|
|
||||||
ranges = [
|
|
||||||
"${ipv4LocalNet}.10,${ipv4LocalNet}.249"
|
|
||||||
# EDIT: ... maybe. In this example we use "ra-stateless",
|
|
||||||
# meaning dnsmasq sends router advertisements with the O and A
|
|
||||||
# bits set, and provides a stateless DHCP service. The client
|
|
||||||
# will use a SLAAC address, and use DHCP for other
|
|
||||||
# configuration information.
|
|
||||||
# If you didn't understand the preceding sentence then
|
|
||||||
# the default is _probably_ fine, but if you need
|
|
||||||
# a DHCP-only IPv6 network or some other different
|
|
||||||
# configuration, this is the place to change it.
|
|
||||||
"::,constructor:$(output ${interface} ifname),ra-stateless"
|
|
||||||
];
|
|
||||||
# EDIT: choose a domain name for the DNS names issued for your
|
|
||||||
# DHCP-issued hosts
|
|
||||||
domain = "lan.example.com";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.wan = svc.pppoe.build {
|
|
||||||
interface = config.hardware.networkInterfaces.wan;
|
|
||||||
ppp-options = [
|
|
||||||
"debug" "+ipv6" "noauth"
|
|
||||||
# EDIT: change the strings "chap-username"
|
|
||||||
# and "chap-secret" to match the username/password
|
|
||||||
# provided by your ISP for PPP logins
|
|
||||||
"name" "chap-username"
|
|
||||||
"password" "chap-secret"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.resolvconf = oneshot rec {
|
|
||||||
dependencies = [ services.wan ];
|
|
||||||
name = "resolvconf";
|
|
||||||
up = ''
|
|
||||||
. ${serviceFns}
|
|
||||||
( in_outputs ${name}
|
|
||||||
echo "nameserver $(output ${services.wan} ns1)" > resolv.conf
|
|
||||||
echo "nameserver $(output ${services.wan} ns2)" >> resolv.conf
|
|
||||||
chmod 0444 resolv.conf
|
|
||||||
)
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
filesystem =
|
|
||||||
let inherit (pkgs.pseudofile) dir symlink;
|
|
||||||
in dir {
|
|
||||||
etc = dir {
|
|
||||||
"resolv.conf" = symlink "${services.resolvconf}/.outputs/resolv.conf";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.defaultroute4 = svc.network.route.build {
|
|
||||||
via = "$(output ${services.wan} address)";
|
|
||||||
target = "default";
|
|
||||||
dependencies = [ services.wan ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.defaultroute6 = svc.network.route.build {
|
|
||||||
via = "$(output ${services.wan} ipv6-peer-address)";
|
|
||||||
target = "default";
|
|
||||||
interface = services.wan;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.firewall = svc.firewall.build {
|
|
||||||
ruleset = import ./demo-firewall.nix;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.packet_forwarding = svc.network.forward.build { };
|
|
||||||
|
|
||||||
# We expect the ISP uses DHCP6 to issue IPv6 addresses. There is a
|
|
||||||
# service to request address information in the form of a DHCP
|
|
||||||
# lease, and two dependent services that listen for updates to the
|
|
||||||
# DHCP address information and update the addresses of the WAN and
|
|
||||||
# LAN interfaces respectively.
|
|
||||||
|
|
||||||
services.dhcp6c =
|
|
||||||
let client = svc.dhcp6c.client.build {
|
|
||||||
interface = services.wan;
|
|
||||||
};
|
|
||||||
in bundle {
|
|
||||||
name = "dhcp6c";
|
|
||||||
contents = [
|
|
||||||
(svc.dhcp6c.prefix.build {
|
|
||||||
# if your ISP provides you a real IPv6 prefix for your local
|
|
||||||
# network (usually a /64 or /48 or something in between the
|
|
||||||
# two), this service subscribes to that "prefix delegation"
|
|
||||||
# information, and uses it to assign an address to the LAN
|
|
||||||
# device. dnsmasq will notice this address and use it to
|
|
||||||
# form the addresses it hands out to devices on the lan
|
|
||||||
inherit client;
|
|
||||||
interface = services.int;
|
|
||||||
})
|
|
||||||
(svc.dhcp6c.address.build {
|
|
||||||
# if your ISP provides you a regular global IPv6 address,
|
|
||||||
# this service subscribes to that information and assigns
|
|
||||||
# the address to the WAN device.
|
|
||||||
inherit client;
|
|
||||||
interface = services.wan;
|
|
||||||
})
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
defaultProfile.packages = with pkgs; [
|
|
||||||
min-collect-garbage
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
{ liminix ? (import ./npins).liminix
|
|
||||||
, nixpkgs ? (import ./npins).nixpkgs
|
|
||||||
, liminix-config ? ./configuration.nix
|
|
||||||
}:
|
|
||||||
import liminix { inherit nixpkgs liminix-config; device = import (liminix + "/devices/belkin-rt3200"); }
|
|
|
@ -1,47 +0,0 @@
|
||||||
# Generated by npins. Do not modify; will be overwritten regularly
|
|
||||||
let
|
|
||||||
data = builtins.fromJSON (builtins.readFile ./sources.json);
|
|
||||||
version = data.version;
|
|
||||||
|
|
||||||
mkSource = spec:
|
|
||||||
assert spec ? type; let
|
|
||||||
path =
|
|
||||||
if spec.type == "Git" then mkGitSource spec
|
|
||||||
else if spec.type == "GitRelease" then mkGitSource spec
|
|
||||||
else if spec.type == "PyPi" then mkPyPiSource spec
|
|
||||||
else if spec.type == "Channel" then mkChannelSource spec
|
|
||||||
else builtins.throw "Unknown source type ${spec.type}";
|
|
||||||
in
|
|
||||||
spec // { outPath = path; };
|
|
||||||
|
|
||||||
mkGitSource = { repository, revision, url ? null, hash, ... }:
|
|
||||||
assert repository ? type;
|
|
||||||
# At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository
|
|
||||||
# In the latter case, there we will always be an url to the tarball
|
|
||||||
if url != null then
|
|
||||||
(builtins.fetchTarball {
|
|
||||||
inherit url;
|
|
||||||
sha256 = hash; # FIXME: check nix version & use SRI hashes
|
|
||||||
})
|
|
||||||
else assert repository.type == "Git"; builtins.fetchGit {
|
|
||||||
url = repository.url;
|
|
||||||
rev = revision;
|
|
||||||
# hash = hash;
|
|
||||||
};
|
|
||||||
|
|
||||||
mkPyPiSource = { url, hash, ... }:
|
|
||||||
builtins.fetchurl {
|
|
||||||
inherit url;
|
|
||||||
sha256 = hash;
|
|
||||||
};
|
|
||||||
|
|
||||||
mkChannelSource = { url, hash, ... }:
|
|
||||||
builtins.fetchTarball {
|
|
||||||
inherit url;
|
|
||||||
sha256 = hash;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
if version == 3 then
|
|
||||||
builtins.mapAttrs (_: mkSource) data.pins
|
|
||||||
else
|
|
||||||
throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`"
|
|
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
"pins": {
|
|
||||||
"liminix": {
|
|
||||||
"type": "Git",
|
|
||||||
"repository": {
|
|
||||||
"type": "Git",
|
|
||||||
"url": "https://gti.telent.net/dan/liminix"
|
|
||||||
},
|
|
||||||
"branch": "main",
|
|
||||||
"revision": "98d333692645263b5866bed254681b59dc39d196",
|
|
||||||
"url": null,
|
|
||||||
"hash": "186nx05vssly3pcdpkmrwfzhxc2dfsfvvqfgxg2gnqscj2m11ldf"
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"type": "Channel",
|
|
||||||
"name": "nixpkgs-unstable",
|
|
||||||
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-24.05pre555839.0c6d8c783336/nixexprs.tar.xz",
|
|
||||||
"hash": "04dykgz00bfnbxlaw00x2s5jzzh0jjqpgkb1z0ibkd1qkfq0cfcr"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"version": 3
|
|
||||||
}
|
|
27
meta.nix
27
meta.nix
|
@ -1,27 +0,0 @@
|
||||||
let
|
|
||||||
sources = import ./npins;
|
|
||||||
|
|
||||||
agenix = sources.agenix + "/modules/age.nix";
|
|
||||||
|
|
||||||
metadata = {
|
|
||||||
nodes = {
|
|
||||||
milieu = {
|
|
||||||
deployment = {
|
|
||||||
targetHost = null; #"milieu.cave.hackens.org";
|
|
||||||
# targetPort = 4243;
|
|
||||||
allowLocalDeployment = true;
|
|
||||||
};
|
|
||||||
imports = [agenix];
|
|
||||||
};
|
|
||||||
org = {
|
|
||||||
deployment = {
|
|
||||||
targetHost = "server1.hackens.org"; # todo make something with ens firewall
|
|
||||||
targetPort = 2222;
|
|
||||||
};
|
|
||||||
imports = [agenix];
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in
|
|
||||||
metadata
|
|
|
@ -1,67 +0,0 @@
|
||||||
# Generated by npins. Do not modify; will be overwritten regularly
|
|
||||||
let
|
|
||||||
data = builtins.fromJSON (builtins.readFile ./sources.json);
|
|
||||||
version = data.version;
|
|
||||||
|
|
||||||
mkSource = spec:
|
|
||||||
assert spec ? type; let
|
|
||||||
path =
|
|
||||||
if spec.type == "Git"
|
|
||||||
then mkGitSource spec
|
|
||||||
else if spec.type == "GitRelease"
|
|
||||||
then mkGitSource spec
|
|
||||||
else if spec.type == "PyPi"
|
|
||||||
then mkPyPiSource spec
|
|
||||||
else if spec.type == "Channel"
|
|
||||||
then mkChannelSource spec
|
|
||||||
else builtins.throw "Unknown source type ${spec.type}";
|
|
||||||
in
|
|
||||||
spec // {outPath = path;};
|
|
||||||
|
|
||||||
mkGitSource = {
|
|
||||||
repository,
|
|
||||||
revision,
|
|
||||||
url ? null,
|
|
||||||
hash,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
assert repository ? type;
|
|
||||||
# At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository
|
|
||||||
# In the latter case, there we will always be an url to the tarball
|
|
||||||
if url != null
|
|
||||||
then
|
|
||||||
(builtins.fetchTarball {
|
|
||||||
inherit url;
|
|
||||||
sha256 = hash; # FIXME: check nix version & use SRI hashes
|
|
||||||
})
|
|
||||||
else
|
|
||||||
assert repository.type == "Git";
|
|
||||||
builtins.fetchGit {
|
|
||||||
url = repository.url;
|
|
||||||
rev = revision;
|
|
||||||
# hash = hash;
|
|
||||||
};
|
|
||||||
|
|
||||||
mkPyPiSource = {
|
|
||||||
url,
|
|
||||||
hash,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
builtins.fetchurl {
|
|
||||||
inherit url;
|
|
||||||
sha256 = hash;
|
|
||||||
};
|
|
||||||
|
|
||||||
mkChannelSource = {
|
|
||||||
url,
|
|
||||||
hash,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
builtins.fetchTarball {
|
|
||||||
inherit url;
|
|
||||||
sha256 = hash;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
if version == 3
|
|
||||||
then builtins.mapAttrs (_: mkSource) data.pins
|
|
||||||
else throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`"
|
|
|
@ -1,55 +0,0 @@
|
||||||
{
|
|
||||||
"pins": {
|
|
||||||
"agenix": {
|
|
||||||
"type": "Git",
|
|
||||||
"repository": {
|
|
||||||
"type": "GitHub",
|
|
||||||
"owner": "ryantm",
|
|
||||||
"repo": "agenix"
|
|
||||||
},
|
|
||||||
"branch": "main",
|
|
||||||
"revision": "564595d0ad4be7277e07fa63b5a991b3c645655d",
|
|
||||||
"url": "https://github.com/ryantm/agenix/archive/564595d0ad4be7277e07fa63b5a991b3c645655d.tar.gz",
|
|
||||||
"hash": "01dhrghwa7zw93cybvx4gnrskqk97b004nfxgsys0736823956la"
|
|
||||||
},
|
|
||||||
"disko": {
|
|
||||||
"type": "Git",
|
|
||||||
"repository": {
|
|
||||||
"type": "GitHub",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "disko"
|
|
||||||
},
|
|
||||||
"branch": "master",
|
|
||||||
"revision": "b4104fcaea42037b04c199a5d6784682a15be254",
|
|
||||||
"url": "https://github.com/nix-community/disko/archive/b4104fcaea42037b04c199a5d6784682a15be254.tar.gz",
|
|
||||||
"hash": "0shixlm3mgjw0f6anha89ixp36gfhcv508cbjj9488pvlrjd22is"
|
|
||||||
},
|
|
||||||
"dns.nix": {
|
|
||||||
"type": "GitRelease",
|
|
||||||
"repository": {
|
|
||||||
"type": "GitHub",
|
|
||||||
"owner": "kirelagin",
|
|
||||||
"repo": "dns.nix"
|
|
||||||
},
|
|
||||||
"pre_releases": false,
|
|
||||||
"version_upper_bound": null,
|
|
||||||
"version": "v1.1.2",
|
|
||||||
"revision": "c7b9645da9c0ddce4f9de4ef27ec01bb8108039a",
|
|
||||||
"url": "https://api.github.com/repos/kirelagin/dns.nix/tarball/v1.1.2",
|
|
||||||
"hash": "1b95dh15zl0qaf9fvvvvqlambm3plndpy24wwlib0sy4d0zq6y0h"
|
|
||||||
},
|
|
||||||
"nixos-unstable": {
|
|
||||||
"type": "Git",
|
|
||||||
"repository": {
|
|
||||||
"type": "GitHub",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs"
|
|
||||||
},
|
|
||||||
"branch": "nixos-unstable",
|
|
||||||
"revision": "54aac082a4d9bb5bbc5c4e899603abfb76a3f6d6",
|
|
||||||
"url": "https://github.com/NixOS/nixpkgs/archive/54aac082a4d9bb5bbc5c4e899603abfb76a3f6d6.tar.gz",
|
|
||||||
"hash": "1lx3v67ymjr8vy49hzm9z52zzg7g5ak1x33qcp4vcp75rg04vlgs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"version": 3
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
[]
|
|
1
profiles/shared-hackens/result
Symbolic link
1
profiles/shared-hackens/result
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/nix/store/q3gp3rnx0y5pxdq7jlhj1x3bqrisv7pp-nixos-system-hackens-milieu-23.05pre442253.befc83905c9
|
|
@ -1,10 +1,10 @@
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
let
|
let
|
||||||
superadmins = [
|
superadmins = [
|
||||||
../../../../pubkeys/raito.keys
|
../../pubkeys/raito.keys
|
||||||
../../../../pubkeys/gdd.keys
|
../../pubkeys/gdd.keys
|
||||||
../../../../pubkeys/BiBi.keys
|
../../pubkeys/BiBi.keys
|
||||||
../../../../pubkeys/sinavir.keys
|
../../pubkeys/sinavir.keys
|
||||||
];
|
];
|
||||||
in
|
in
|
||||||
{
|
{
|
|
@ -1,5 +1,9 @@
|
||||||
{ ... }: {
|
{ ... }: {
|
||||||
imports = [ <agenix/modules/age.nix> ];
|
imports = [ <agenix/modules/age.nix> ];
|
||||||
|
age.secrets."wikiOpenID" = {
|
||||||
|
file = ./wiki-openID.age;
|
||||||
|
owner = "dokuwiki";
|
||||||
|
};
|
||||||
age.secrets."django" = {
|
age.secrets."django" = {
|
||||||
file = ./django.age;
|
file = ./django.age;
|
||||||
owner = "django-hackens_orga";
|
owner = "django-hackens_orga";
|
|
@ -5,6 +5,9 @@ let
|
||||||
(lib.splitString "\n" (builtins.readFile (../pubkeys + "/${user}.keys")));
|
(lib.splitString "\n" (builtins.readFile (../pubkeys + "/${user}.keys")));
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
"wiki-openid.age".publicKeys = (readpubkeys "sinavir")
|
||||||
|
++ (readpubkeys "hackens-host") ++ (readpubkeys "raito")
|
||||||
|
++ (readpubkeys "gdd") ++ (readpubkeys "backslash");
|
||||||
"matterbridge-env.age".publicKeys = (readpubkeys "sinavir")
|
"matterbridge-env.age".publicKeys = (readpubkeys "sinavir")
|
||||||
++ (readpubkeys "hackens-host") ++ (readpubkeys "raito")
|
++ (readpubkeys "hackens-host") ++ (readpubkeys "raito")
|
||||||
++ (readpubkeys "gdd") ++ (readpubkeys "backslash");
|
++ (readpubkeys "gdd") ++ (readpubkeys "backslash");
|
31
secrets/wiki-openID.age
Normal file
31
secrets/wiki-openID.age
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 JGx7Ng krR1IYLPMfF9fR7P6ECgMy2vec2lHss0XcHuHWcZCBo
|
||||||
|
MDFLnB7DgNdlJjOxhu0Qreb17ejcZIBMnXGs0BLUN+E
|
||||||
|
-> ssh-ed25519 IWJ9yA shKTCkZmyjLLIFY+ZetDqJJgx51cVHk/ZsKD/cdJ+i0
|
||||||
|
xSblu5POmIUKVe4l+KqpGqGkk+UowRhitUdvE9BLUfM
|
||||||
|
-> ssh-ed25519 7hZk0g 8WtQ/vt6MH0pIN5G1GB3RoS1fNFgFQIepR1HqyP8vWI
|
||||||
|
oSYU/uRA4lopWC8TCwWYZAGncoPOx8/sIMFt0QErDlg
|
||||||
|
-> ssh-rsa krWCLQ
|
||||||
|
KkRdhsQ//wkDw4mX3RqGLSbR8hX3ehr+ZDkwDbCh9gwl17p2hGOFzwhvA8UxQJnK
|
||||||
|
O1z7Lu+hA3dvIhNlyimHp8Qt/AkoZAPnR+lf08Q4BajCqy2Z6HBjKJ6qi7c+9t2F
|
||||||
|
xy5YrBrTzpRKbmf7Fz+tm1hg392bLHhv3N+PfTSszjBs8XdUF8nWQNsdETBhZOzz
|
||||||
|
ilwDzRDFWfPuFYhjs7cAiXE+qDGgzleX0Yx+OgwBoBPB93JbmuRIPQZIJL9WQZdN
|
||||||
|
WTS5T5NJ/trZuRAx/Gx+O854G4miLE1M76E/hQ5bZuQN3EvY4Me8j9jzFlwPp3wA
|
||||||
|
M2oxFsJRvSkOmFl1WIWM0Q
|
||||||
|
-> ssh-ed25519 nyw/0Q KinHAGi4K6Gls1otwc9WE+jhzujZ4EETm2Br3myWh1o
|
||||||
|
m1gVTxjs+WJeKc6NvBlqWfGmg3ZwxVO6aHqM14QFRaI
|
||||||
|
-> ssh-ed25519 85WiGg P9BBlxJxxLwijrvo/XzfKh2GnkJUvjCLBhkrR27v0SQ
|
||||||
|
8o3HgtiY8DLYgrau2mfmA4QzvoFThCHqDF/7QCNew7A
|
||||||
|
-> ssh-ed25519 cvTB5g HzkPfCXwsikbISCh7zZgtOaI03G2ErTWIXRk9TfSqm4
|
||||||
|
Wqh9WYB4D2hDAe3nWxz19nZDgGMJYFvtHxrYQnuiHC4
|
||||||
|
-> ssh-ed25519 Wu8JLQ 2x1ikJnqyIkQmOwK1vP4S7n/xZZCdN7czBY1o/L8ZzY
|
||||||
|
Poj21vxJ9sUsoikfepaxbktWWIdjh24zzDRzW4Efb8c
|
||||||
|
-> ssh-ed25519 EIt1vA XxwV8nTlhx7Iy77xCnTrcCEevyKnDGFHGi9JvLb4a0s
|
||||||
|
y9M2VFvUGT0GOydGDbyqpuOuIRyKXPGl1Z35nBI3i68
|
||||||
|
-> ssh-ed25519 X51wxg C6GJqoVqTLpR5L0v1c5umu0gwUEWXOEAJC9kKWV2NEs
|
||||||
|
IogBAsuZG9z8TmX0rVav14ek1qhoq38DWullPSufnWQ
|
||||||
|
-> l@z=5S-grease (,5a5 T tV@xrY %e_ig
|
||||||
|
mIzNLkFaEozopcLCOyQacaU
|
||||||
|
--- 2krWnD1hHZOvN/0zuuIIcFjh2udviLZns/nTsVSPLmc
|
||||||
|
û³¦~<7E>³Å=ï¾Ì>ô©YY<59>W€wpEz±);Úàdó1Må'=èš&!Jìá”$²
|
||||||
|
nÊ_l"ï“æÚ‰”Ï
|
11
setup-link-from-hostname
Executable file
11
setup-link-from-hostname
Executable file
|
@ -0,0 +1,11 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
echo "Setting up $(hostname)"
|
||||||
|
|
||||||
|
HOST_FOLDER=hosts
|
||||||
|
HOSTNAME=$(hostname)
|
||||||
|
CONFIG=$HOST_FOLDER/$HOSTNAME/configuration.nix
|
||||||
|
|
||||||
|
if [[ -n $(cmp --silent configuration.nix "$CONFIG" || echo "different") ]]
|
||||||
|
then
|
||||||
|
ln -s "$CONFIG" configuration.nix
|
||||||
|
fi
|
94
shared/dokuwiki.nix
Normal file
94
shared/dokuwiki.nix
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
{ lib
|
||||||
|
, stdenv
|
||||||
|
, fetchFromGitHub
|
||||||
|
, writeText
|
||||||
|
, nixosTests
|
||||||
|
, dokuwiki
|
||||||
|
}:
|
||||||
|
|
||||||
|
stdenv.mkDerivation rec {
|
||||||
|
pname = "dokuwiki";
|
||||||
|
version = "2022-07-31a";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "splitbrain";
|
||||||
|
repo = pname;
|
||||||
|
rev = "release_stable_${version}";
|
||||||
|
sha256 = "sha256-gtWEtc3kbMokKycTx71XXblkDF39i926uN2kU3oOeVw=";
|
||||||
|
};
|
||||||
|
|
||||||
|
preload = writeText "preload.php" ''
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$config_cascade = array(
|
||||||
|
'acl' => array(
|
||||||
|
'default' => getenv('DOKUWIKI_ACL_AUTH_CONFIG'),
|
||||||
|
),
|
||||||
|
'plainauth.users' => array(
|
||||||
|
'default' => getenv('DOKUWIKI_USERS_AUTH_CONFIG'),
|
||||||
|
'protected' => "" // not used by default
|
||||||
|
),
|
||||||
|
);
|
||||||
|
'';
|
||||||
|
|
||||||
|
phpLocalConfig = writeText "local.php" ''
|
||||||
|
<?php
|
||||||
|
return require(getenv('DOKUWIKI_LOCAL_CONFIG'));
|
||||||
|
?>
|
||||||
|
'';
|
||||||
|
|
||||||
|
phpPluginsLocalConfig = writeText "plugins.local.php" ''
|
||||||
|
<?php
|
||||||
|
return require(getenv('DOKUWIKI_PLUGINS_LOCAL_CONFIG'));
|
||||||
|
?>
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
mkdir -p $out/share/dokuwiki
|
||||||
|
cp -r * $out/share/dokuwiki
|
||||||
|
cp ${preload} $out/share/dokuwiki/inc/preload.php
|
||||||
|
cp ${phpLocalConfig} $out/share/dokuwiki/conf/local.php
|
||||||
|
cp ${phpPluginsLocalConfig} $out/share/dokuwiki/conf/plugins.local.php
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
combine =
|
||||||
|
{ basePackage ? dokuwiki
|
||||||
|
, plugins ? [ ]
|
||||||
|
, templates ? [ ]
|
||||||
|
, localConfig ? null
|
||||||
|
, pluginsConfig ? null
|
||||||
|
, aclConfig ? null
|
||||||
|
, pname ? (p: "${p.pname}-combined")
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
isNotEmpty = x: lib.optionalString (! builtins.elem x [ null "" ]);
|
||||||
|
in
|
||||||
|
basePackage.overrideAttrs (prev: {
|
||||||
|
pname = if builtins.isFunction pname then pname prev else pname;
|
||||||
|
|
||||||
|
postInstall = prev.postInstall or "" + ''
|
||||||
|
${lib.concatMapStringsSep "\n" (tpl: "cp -r ${toString tpl} $out/share/dokuwiki/lib/tpl/${tpl.name}") templates}
|
||||||
|
${lib.concatMapStringsSep "\n" (plugin: "cp -r ${toString plugin} $out/share/dokuwiki/lib/plugins/${plugin.name}") plugins}
|
||||||
|
${isNotEmpty localConfig "ln -sf ${localConfig} $out/share/dokuwiki/conf/local.php" }
|
||||||
|
${isNotEmpty pluginsConfig "ln -sf ${pluginsConfig} $out/share/dokuwiki/conf/plugins.local.php" }
|
||||||
|
${isNotEmpty aclConfig "ln -sf ${aclConfig} $out/share/dokuwiki/acl.auth.php" }
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
tests = {
|
||||||
|
inherit (nixosTests) dokuwiki;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Simple to use and highly versatile Open Source wiki software that doesn't require a database";
|
||||||
|
license = licenses.gpl2;
|
||||||
|
homepage = "https://www.dokuwiki.org";
|
||||||
|
platforms = platforms.all;
|
||||||
|
maintainers = with maintainers; [ _1000101 ];
|
||||||
|
};
|
||||||
|
}
|
613
shared/dokuwiki_module.nix
Normal file
613
shared/dokuwiki_module.nix
Normal file
|
@ -0,0 +1,613 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.dokuwiki;
|
||||||
|
eachSite = cfg.sites;
|
||||||
|
user = "dokuwiki";
|
||||||
|
webserver = config.services.${cfg.webserver};
|
||||||
|
|
||||||
|
mkPhpIni = generators.toKeyValue {
|
||||||
|
mkKeyValue = generators.mkKeyValueDefault { } " = ";
|
||||||
|
};
|
||||||
|
mkPhpPackage = cfg: cfg.phpPackage.buildEnv {
|
||||||
|
extraConfig = mkPhpIni cfg.phpOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
dokuwikiAclAuthConfig = hostName: cfg:
|
||||||
|
let
|
||||||
|
inherit (cfg) acl;
|
||||||
|
acl_gen = concatMapStringsSep "\n" (l: "${l.page} \t ${l.actor} \t ${toString l.level}");
|
||||||
|
in
|
||||||
|
pkgs.writeText "acl.auth-${hostName}.php" ''
|
||||||
|
# acl.auth.php
|
||||||
|
# <?php exit()?>
|
||||||
|
#
|
||||||
|
# Access Control Lists
|
||||||
|
#
|
||||||
|
${if isString acl then acl else acl_gen acl}
|
||||||
|
'';
|
||||||
|
|
||||||
|
mergeConfig = cfg: {
|
||||||
|
useacl = false; # Dokuwiki default
|
||||||
|
savedir = cfg.stateDir;
|
||||||
|
} // cfg.settings;
|
||||||
|
|
||||||
|
writePhpFile = name: text: pkgs.writeTextFile {
|
||||||
|
inherit name;
|
||||||
|
text = "<?php\n${text}";
|
||||||
|
checkPhase = "${pkgs.php81}/bin/php --syntax-check $target";
|
||||||
|
};
|
||||||
|
|
||||||
|
mkPhpValue = v:
|
||||||
|
let
|
||||||
|
isHasAttr = s: isAttrs v && hasAttr s v;
|
||||||
|
in
|
||||||
|
if isString v then escapeShellArg v
|
||||||
|
# NOTE: If any value contains a , (comma) this will not get escaped
|
||||||
|
else if isList v && any lib.strings.isCoercibleToString v then escapeShellArg (concatMapStringsSep "," toString v)
|
||||||
|
else if isInt v then toString v
|
||||||
|
else if isBool v then toString (if v then 1 else 0)
|
||||||
|
else if isHasAttr "_file" then "trim(file_get_contents(${lib.escapeShellArg v._file}))"
|
||||||
|
else if isHasAttr "_raw" then v._raw
|
||||||
|
else abort "The dokuwiki localConf value ${lib.generators.toPretty {} v} can not be encoded."
|
||||||
|
;
|
||||||
|
|
||||||
|
mkPhpAttrVals = v: flatten (mapAttrsToList mkPhpKeyVal v);
|
||||||
|
mkPhpKeyVal = k: v:
|
||||||
|
let
|
||||||
|
values =
|
||||||
|
if (isAttrs v && (hasAttr "_file" v || hasAttr "_raw" v)) || !isAttrs v then
|
||||||
|
[ " = ${mkPhpValue v};" ]
|
||||||
|
else
|
||||||
|
mkPhpAttrVals v;
|
||||||
|
in
|
||||||
|
map (e: "[${escapeShellArg k}]${e}") (flatten values);
|
||||||
|
|
||||||
|
dokuwikiLocalConfig = hostName: cfg:
|
||||||
|
let
|
||||||
|
conf_gen = c: map (v: "$conf${v}") (mkPhpAttrVals c);
|
||||||
|
in
|
||||||
|
writePhpFile "local-${hostName}.php" ''
|
||||||
|
${concatStringsSep "\n" (conf_gen cfg.mergedConfig)}
|
||||||
|
${toString cfg.extraConfig}
|
||||||
|
'';
|
||||||
|
|
||||||
|
dokuwikiPluginsLocalConfig = hostName: cfg:
|
||||||
|
let
|
||||||
|
pc = cfg.pluginsConfig;
|
||||||
|
pc_gen = pc: concatStringsSep "\n" (mapAttrsToList (n: v: "$plugins['${n}'] = ${boolToString v};") pc);
|
||||||
|
in
|
||||||
|
writePhpFile "plugins.local-${hostName}.php" ''
|
||||||
|
${if isString pc then pc else pc_gen pc}
|
||||||
|
'';
|
||||||
|
|
||||||
|
|
||||||
|
pkg = hostName: cfg: cfg.package.combine {
|
||||||
|
inherit (cfg) plugins templates;
|
||||||
|
|
||||||
|
pname = p: "${p.pname}-${hostName}";
|
||||||
|
|
||||||
|
basePackage = cfg.package;
|
||||||
|
localConfig = dokuwikiLocalConfig hostName cfg;
|
||||||
|
pluginsConfig = dokuwikiPluginsLocalConfig hostName cfg;
|
||||||
|
aclConfig = let a = if cfg.aclUse && cfg.acl != null then dokuwikiAclAuthConfig hostName cfg else null; in builtins.trace a a;
|
||||||
|
};
|
||||||
|
|
||||||
|
aclOpts = { ... }: {
|
||||||
|
options = {
|
||||||
|
|
||||||
|
page = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "Page or namespace to restrict";
|
||||||
|
example = "start";
|
||||||
|
};
|
||||||
|
|
||||||
|
actor = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "User or group to restrict";
|
||||||
|
example = "@external";
|
||||||
|
};
|
||||||
|
|
||||||
|
level =
|
||||||
|
let
|
||||||
|
available = {
|
||||||
|
"none" = 0;
|
||||||
|
"read" = 1;
|
||||||
|
"edit" = 2;
|
||||||
|
"create" = 4;
|
||||||
|
"upload" = 8;
|
||||||
|
"delete" = 16;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
mkOption {
|
||||||
|
type = types.enum ((attrValues available) ++ (attrNames available));
|
||||||
|
apply = x: if isInt x then x else available.${x};
|
||||||
|
description = ''
|
||||||
|
Permission level to restrict the actor(s) to.
|
||||||
|
See <https://www.dokuwiki.org/acl#background_info> for explanation
|
||||||
|
'';
|
||||||
|
example = "read";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
siteOpts = { config, lib, name, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
# NOTE: These will sadly not print the absolute argument path but only the name. Related to #96006
|
||||||
|
(mkRenamedOptionModule [ "aclUse" ] [ "settings" "useacl" ])
|
||||||
|
(mkRenamedOptionModule [ "superUser" ] [ "settings" "superuser" ])
|
||||||
|
(mkRenamedOptionModule [ "disableActions" ] [ "settings" "disableactions" ])
|
||||||
|
({ config, options, name, ... }: {
|
||||||
|
config.warnings =
|
||||||
|
(optional (isString config.pluginsConfig) ''
|
||||||
|
Passing plain strings to services.dokuwiki.sites.${name}.pluginsConfig has been deprecated and will not be continue to be supported in the future.
|
||||||
|
Please pass structured settings instead.
|
||||||
|
'')
|
||||||
|
++ (optional (isString config.acl) ''
|
||||||
|
Passing a plain string to services.dokuwiki.sites.${name}.acl has been deprecated and will not continue to be supported in the future.
|
||||||
|
Please pass structured settings instead.
|
||||||
|
'')
|
||||||
|
++ (optional (config.extraConfig != null) ''
|
||||||
|
services.dokuwiki.sites.${name}.extraConfig is deprecated and will be removed in the future.
|
||||||
|
Please pass structured settings to services.dokuwiki.sites.${name}.settings instead.
|
||||||
|
'')
|
||||||
|
;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
enable = mkEnableOption (lib.mdDoc "DokuWiki web application.");
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = pkgs.dokuwiki;
|
||||||
|
defaultText = literalExpression "pkgs.dokuwiki";
|
||||||
|
description = lib.mdDoc "Which DokuWiki package to use.";
|
||||||
|
};
|
||||||
|
|
||||||
|
stateDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/dokuwiki/${name}/data";
|
||||||
|
description = lib.mdDoc "Location of the DokuWiki state directory.";
|
||||||
|
};
|
||||||
|
|
||||||
|
acl = mkOption {
|
||||||
|
type = with types; nullOr (oneOf [ lines (listOf (submodule aclOpts)) ]);
|
||||||
|
default = null;
|
||||||
|
example = literalExpression ''
|
||||||
|
[
|
||||||
|
{
|
||||||
|
page = "start";
|
||||||
|
actor = "@external";
|
||||||
|
level = "read";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
page = "*";
|
||||||
|
actor = "@users";
|
||||||
|
level = "upload";
|
||||||
|
}
|
||||||
|
]
|
||||||
|
'';
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Access Control Lists: see <https://www.dokuwiki.org/acl>
|
||||||
|
Mutually exclusive with services.dokuwiki.aclFile
|
||||||
|
Set this to a value other than null to take precedence over aclFile option.
|
||||||
|
|
||||||
|
Warning: Consider using aclFile instead if you do not
|
||||||
|
want to store the ACL in the world-readable Nix store.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
aclFile = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = if (config.mergedConfig.useacl && config.acl == null) then "/var/lib/dokuwiki/${name}/acl.auth.php" else null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Location of the dokuwiki acl rules. Mutually exclusive with services.dokuwiki.acl
|
||||||
|
Mutually exclusive with services.dokuwiki.acl which is preferred.
|
||||||
|
Consult documentation <https://www.dokuwiki.org/acl> for further instructions.
|
||||||
|
Example: <https://github.com/splitbrain/dokuwiki/blob/master/conf/acl.auth.php.dist>
|
||||||
|
'';
|
||||||
|
example = "/var/lib/dokuwiki/${name}/acl.auth.php";
|
||||||
|
};
|
||||||
|
|
||||||
|
pluginsConfig = mkOption {
|
||||||
|
type = with types; oneOf [ lines (attrsOf bool) ];
|
||||||
|
default = {
|
||||||
|
authad = false;
|
||||||
|
authldap = false;
|
||||||
|
authmysql = false;
|
||||||
|
authpgsql = false;
|
||||||
|
};
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
List of the dokuwiki (un)loaded plugins.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
usersFile = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = if config.mergedConfig.useacl then "/var/lib/dokuwiki/${name}/users.auth.php" else null;
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Location of the dokuwiki users file. List of users. Format:
|
||||||
|
|
||||||
|
login:passwordhash:Real Name:email:groups,comma,separated
|
||||||
|
|
||||||
|
Create passwordHash easily by using:
|
||||||
|
|
||||||
|
mkpasswd -5 password `pwgen 8 1`
|
||||||
|
|
||||||
|
Example: <https://github.com/splitbrain/dokuwiki/blob/master/conf/users.auth.php.dist>
|
||||||
|
'';
|
||||||
|
example = "/var/lib/dokuwiki/${name}/users.auth.php";
|
||||||
|
};
|
||||||
|
|
||||||
|
plugins = mkOption {
|
||||||
|
type = types.listOf types.path;
|
||||||
|
default = [ ];
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
List of path(s) to respective plugin(s) which are copied from the 'plugin' directory.
|
||||||
|
|
||||||
|
::: {.note}
|
||||||
|
These plugins need to be packaged before use, see example.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
example = literalExpression ''
|
||||||
|
let
|
||||||
|
plugin-icalevents = pkgs.stdenv.mkDerivation rec {
|
||||||
|
name = "icalevents";
|
||||||
|
version = "2017-06-16";
|
||||||
|
src = pkgs.fetchzip {
|
||||||
|
stripRoot = false;
|
||||||
|
url = "https://github.com/real-or-random/dokuwiki-plugin-icalevents/releases/download/''${version}/dokuwiki-plugin-icalevents-''${version}.zip";
|
||||||
|
hash = "sha256-IPs4+qgEfe8AAWevbcCM9PnyI0uoyamtWeg4rEb+9Wc=";
|
||||||
|
};
|
||||||
|
installPhase = "mkdir -p $out; cp -R * $out/";
|
||||||
|
};
|
||||||
|
# And then pass this theme to the plugin list like this:
|
||||||
|
in [ plugin-icalevents ]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
templates = mkOption {
|
||||||
|
type = types.listOf types.path;
|
||||||
|
default = [ ];
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
List of path(s) to respective template(s) which are copied from the 'tpl' directory.
|
||||||
|
|
||||||
|
::: {.note}
|
||||||
|
These templates need to be packaged before use, see example.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
example = literalExpression ''
|
||||||
|
let
|
||||||
|
template-bootstrap3 = pkgs.stdenv.mkDerivation rec {
|
||||||
|
name = "bootstrap3";
|
||||||
|
version = "2022-07-27";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "giterlizzi";
|
||||||
|
repo = "dokuwiki-template-bootstrap3";
|
||||||
|
rev = "v''${version}";
|
||||||
|
hash = "sha256-B3Yd4lxdwqfCnfmZdp+i/Mzwn/aEuZ0ovagDxuR6lxo=";
|
||||||
|
};
|
||||||
|
installPhase = "mkdir -p $out; cp -R * $out/";
|
||||||
|
};
|
||||||
|
# And then pass this theme to the template list like this:
|
||||||
|
in [ template-bootstrap3 ]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
poolConfig = mkOption {
|
||||||
|
type = with types; attrsOf (oneOf [ str int bool ]);
|
||||||
|
default = {
|
||||||
|
"pm" = "dynamic";
|
||||||
|
"pm.max_children" = 32;
|
||||||
|
"pm.start_servers" = 2;
|
||||||
|
"pm.min_spare_servers" = 2;
|
||||||
|
"pm.max_spare_servers" = 4;
|
||||||
|
"pm.max_requests" = 500;
|
||||||
|
};
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Options for the DokuWiki PHP pool. See the documentation on `php-fpm.conf`
|
||||||
|
for details on configuration directives.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
phpPackage = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
relatedPackages = [ "php80" "php81" ];
|
||||||
|
default = pkgs.php81;
|
||||||
|
defaultText = "pkgs.php81";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
PHP package to use for this dokuwiki site.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
phpOptions = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = { };
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Options for PHP's php.ini file for this dokuwiki site.
|
||||||
|
'';
|
||||||
|
example = literalExpression ''
|
||||||
|
{
|
||||||
|
"opcache.interned_strings_buffer" = "8";
|
||||||
|
"opcache.max_accelerated_files" = "10000";
|
||||||
|
"opcache.memory_consumption" = "128";
|
||||||
|
"opcache.revalidate_freq" = "15";
|
||||||
|
"opcache.fast_shutdown" = "1";
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
type = types.attrsOf types.anything;
|
||||||
|
default = {
|
||||||
|
useacl = true;
|
||||||
|
superuser = "admin";
|
||||||
|
};
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Structural DokuWiki configuration.
|
||||||
|
Refer to <https://www.dokuwiki.org/config>
|
||||||
|
for details and supported values.
|
||||||
|
Settings can either be directly set from nix,
|
||||||
|
loaded from a file using `._file` or obtained from any
|
||||||
|
PHP function calls using `._raw`.
|
||||||
|
'';
|
||||||
|
example = literalExpression ''
|
||||||
|
{
|
||||||
|
title = "My Wiki";
|
||||||
|
userewrite = 1;
|
||||||
|
disableactions = [ "register" ]; # Will be concatenated with commas
|
||||||
|
plugin.smtp = {
|
||||||
|
smtp_pass._file = "/var/run/secrets/dokuwiki/smtp_pass";
|
||||||
|
smtp_user._raw = "getenv('DOKUWIKI_SMTP_USER')";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
mergedConfig = mkOption {
|
||||||
|
readOnly = true;
|
||||||
|
default = mergeConfig config;
|
||||||
|
defaultText = literalExpression ''
|
||||||
|
{
|
||||||
|
useacl = true;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Read only representation of the final configuration.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
# This Option is deprecated and only kept until sometime before 23.05 for compatibility reasons
|
||||||
|
# FIXME (@e1mo): Actually remember removing this before 23.05.
|
||||||
|
visible = false;
|
||||||
|
type = types.nullOr types.lines;
|
||||||
|
default = null;
|
||||||
|
example = ''
|
||||||
|
$conf['title'] = 'My Wiki';
|
||||||
|
$conf['userewrite'] = 1;
|
||||||
|
'';
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
DokuWiki configuration. Refer to
|
||||||
|
<https://www.dokuwiki.org/config>
|
||||||
|
for details on supported values.
|
||||||
|
|
||||||
|
**Note**: Please pass Structured settings via
|
||||||
|
`services.dokuwiki.sites.${name}.settings` instead.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Required for the mkRenamedOptionModule
|
||||||
|
# TODO: Remove me once https://github.com/NixOS/nixpkgs/issues/96006 is fixed
|
||||||
|
# or the aclUse, ... options are removed.
|
||||||
|
warnings = mkOption {
|
||||||
|
type = types.listOf types.unspecified;
|
||||||
|
default = [ ];
|
||||||
|
visible = false;
|
||||||
|
internal = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
services.dokuwiki = {
|
||||||
|
|
||||||
|
sites = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule siteOpts);
|
||||||
|
default = { };
|
||||||
|
description = lib.mdDoc "Specification of one or more DokuWiki sites to serve";
|
||||||
|
};
|
||||||
|
|
||||||
|
webserver = mkOption {
|
||||||
|
type = types.enum [ "nginx" "caddy" ];
|
||||||
|
default = "nginx";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Whether to use nginx or caddy for virtual host management.
|
||||||
|
|
||||||
|
Further nginx configuration can be done by adapting `services.nginx.virtualHosts.<name>`.
|
||||||
|
See [](#opt-services.nginx.virtualHosts) for further information.
|
||||||
|
|
||||||
|
Further caddy configuration can be done by adapting `services.caddy.virtualHosts.<name>`.
|
||||||
|
See [](#opt-services.caddy.virtualHosts) for further information.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# implementation
|
||||||
|
config = mkIf (eachSite != { }) (mkMerge [{
|
||||||
|
|
||||||
|
warnings = flatten (mapAttrsToList (_: cfg: cfg.warnings) eachSite);
|
||||||
|
|
||||||
|
assertions = flatten (mapAttrsToList
|
||||||
|
(hostName: cfg:
|
||||||
|
[{
|
||||||
|
assertion = cfg.mergedConfig.useacl -> (cfg.acl != null || cfg.aclFile != null);
|
||||||
|
message = "Either services.dokuwiki.sites.${hostName}.acl or services.dokuwiki.sites.${hostName}.aclFile is mandatory if settings.useacl is true";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = cfg.usersFile != null -> cfg.mergedConfig.useacl != false;
|
||||||
|
message = "services.dokuwiki.sites.${hostName}.settings.useacl must must be true if usersFile is not null";
|
||||||
|
}])
|
||||||
|
eachSite);
|
||||||
|
|
||||||
|
services.phpfpm.pools = mapAttrs'
|
||||||
|
(hostName: cfg: (
|
||||||
|
nameValuePair "dokuwiki-${hostName}" {
|
||||||
|
inherit user;
|
||||||
|
group = webserver.group;
|
||||||
|
|
||||||
|
phpPackage = mkPhpPackage cfg;
|
||||||
|
phpEnv = optionalAttrs (cfg.usersFile != null)
|
||||||
|
{
|
||||||
|
DOKUWIKI_USERS_AUTH_CONFIG = "${cfg.usersFile}";
|
||||||
|
} // optionalAttrs (cfg.mergedConfig.useacl) {
|
||||||
|
DOKUWIKI_ACL_AUTH_CONFIG = if (cfg.acl != null) then "${dokuwikiAclAuthConfig hostName cfg}" else "${toString cfg.aclFile}";
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
"listen.owner" = webserver.user;
|
||||||
|
"listen.group" = webserver.group;
|
||||||
|
} // cfg.poolConfig;
|
||||||
|
}
|
||||||
|
))
|
||||||
|
eachSite;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
systemd.tmpfiles.rules = flatten (mapAttrsToList
|
||||||
|
(hostName: cfg: [
|
||||||
|
"d ${cfg.stateDir}/attic 0750 ${user} ${webserver.group} - -"
|
||||||
|
"d ${cfg.stateDir}/cache 0750 ${user} ${webserver.group} - -"
|
||||||
|
"d ${cfg.stateDir}/index 0750 ${user} ${webserver.group} - -"
|
||||||
|
"d ${cfg.stateDir}/locks 0750 ${user} ${webserver.group} - -"
|
||||||
|
"d ${cfg.stateDir}/log 0750 ${user} ${webserver.group} - -"
|
||||||
|
"d ${cfg.stateDir}/media 0750 ${user} ${webserver.group} - -"
|
||||||
|
"d ${cfg.stateDir}/media_attic 0750 ${user} ${webserver.group} - -"
|
||||||
|
"d ${cfg.stateDir}/media_meta 0750 ${user} ${webserver.group} - -"
|
||||||
|
"d ${cfg.stateDir}/meta 0750 ${user} ${webserver.group} - -"
|
||||||
|
"d ${cfg.stateDir}/pages 0750 ${user} ${webserver.group} - -"
|
||||||
|
"d ${cfg.stateDir}/tmp 0750 ${user} ${webserver.group} - -"
|
||||||
|
] ++ lib.optional (cfg.aclFile != null) "C ${cfg.aclFile} 0640 ${user} ${webserver.group} - ${pkg hostName cfg}/share/dokuwiki/conf/acl.auth.php.dist"
|
||||||
|
++ lib.optional (cfg.usersFile != null) "C ${cfg.usersFile} 0640 ${user} ${webserver.group} - ${pkg hostName cfg}/share/dokuwiki/conf/users.auth.php.dist"
|
||||||
|
)
|
||||||
|
eachSite);
|
||||||
|
|
||||||
|
users.users.${user} = {
|
||||||
|
group = webserver.group;
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
(mkIf (cfg.webserver == "nginx") {
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = mapAttrs
|
||||||
|
(hostName: cfg: {
|
||||||
|
serverName = mkDefault hostName;
|
||||||
|
root = "${pkg hostName cfg}/share/dokuwiki";
|
||||||
|
|
||||||
|
locations = {
|
||||||
|
"~ /(conf/|bin/|inc/|install.php)" = {
|
||||||
|
extraConfig = "deny all;";
|
||||||
|
};
|
||||||
|
|
||||||
|
"~ ^/data/" = {
|
||||||
|
root = "${cfg.stateDir}";
|
||||||
|
extraConfig = "internal;";
|
||||||
|
};
|
||||||
|
|
||||||
|
"~ ^/lib.*\.(js|css|gif|png|ico|jpg|jpeg)$" = {
|
||||||
|
extraConfig = "expires 365d;";
|
||||||
|
};
|
||||||
|
|
||||||
|
"/" = {
|
||||||
|
priority = 1;
|
||||||
|
index = "doku.php";
|
||||||
|
extraConfig = ''try_files $uri $uri/ @dokuwiki;'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"@dokuwiki" = {
|
||||||
|
extraConfig = ''
|
||||||
|
# rewrites "doku.php/" out of the URLs if you set the userwrite setting to .htaccess in dokuwiki config page
|
||||||
|
rewrite ^/_media/(.*) /lib/exe/fetch.php?media=$1 last;
|
||||||
|
rewrite ^/_detail/(.*) /lib/exe/detail.php?media=$1 last;
|
||||||
|
rewrite ^/_export/([^/]+)/(.*) /doku.php?do=export_$1&id=$2 last;
|
||||||
|
rewrite ^/(.*) /doku.php?id=$1&$args last;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
"~ \\.php$" = {
|
||||||
|
extraConfig = ''
|
||||||
|
try_files $uri $uri/ /doku.php;
|
||||||
|
include ${config.services.nginx.package}/conf/fastcgi_params;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
fastcgi_param REDIRECT_STATUS 200;
|
||||||
|
fastcgi_pass unix:${config.services.phpfpm.pools."dokuwiki-${hostName}".socket};
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
})
|
||||||
|
eachSite;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
|
(mkIf (cfg.webserver == "caddy") {
|
||||||
|
services.caddy = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = mapAttrs'
|
||||||
|
(hostName: cfg: (
|
||||||
|
nameValuePair "http://${hostName}" {
|
||||||
|
extraConfig = ''
|
||||||
|
root * ${pkg hostName cfg}/share/dokuwiki
|
||||||
|
file_server
|
||||||
|
|
||||||
|
encode zstd gzip
|
||||||
|
php_fastcgi unix/${config.services.phpfpm.pools."dokuwiki-${hostName}".socket}
|
||||||
|
|
||||||
|
@restrict_files {
|
||||||
|
path /data/* /conf/* /bin/* /inc/* /vendor/* /install.php
|
||||||
|
}
|
||||||
|
|
||||||
|
respond @restrict_files 404
|
||||||
|
|
||||||
|
@allow_media {
|
||||||
|
path_regexp path ^/_media/(.*)$
|
||||||
|
}
|
||||||
|
rewrite @allow_media /lib/exe/fetch.php?media=/{http.regexp.path.1}
|
||||||
|
|
||||||
|
@allow_detail {
|
||||||
|
path /_detail*
|
||||||
|
}
|
||||||
|
rewrite @allow_detail /lib/exe/detail.php?media={path}
|
||||||
|
|
||||||
|
@allow_export {
|
||||||
|
path /_export*
|
||||||
|
path_regexp export /([^/]+)/(.*)
|
||||||
|
}
|
||||||
|
rewrite @allow_export /doku.php?do=export_{http.regexp.export.1}&id={http.regexp.export.2}
|
||||||
|
|
||||||
|
try_files {path} {path}/ /doku.php?id={path}&{query}
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
))
|
||||||
|
eachSite;
|
||||||
|
};
|
||||||
|
})]);
|
||||||
|
|
||||||
|
meta.maintainers = with maintainers; [
|
||||||
|
_1000101
|
||||||
|
onny
|
||||||
|
dandellion
|
||||||
|
];
|
||||||
|
}
|
Loading…
Reference in a new issue