feat(shell): Add pre-commit hooks and reformat the repo

This commit is contained in:
Tom Hubrecht 2024-02-02 10:51:31 +01:00
parent 988c44d461
commit 5e3819c9b2
91 changed files with 3772 additions and 2282 deletions

1
.pre-commit-config.yaml Symbolic link
View file

@ -0,0 +1 @@
/nix/store/sbc33iwjwgwj0cklac3qjffvi93i723k-pre-commit-config.json

93
default.nix Normal file
View file

@ -0,0 +1,93 @@
/* Copyright :
- Maurice Debray <maurice.debray@dgnum.eu> 2023
- Tom Hubrecht <tom.hubrecht@dgnum.eu> 2023
Ce logiciel est un programme informatique servant à déployer des
configurations de serveurs via NixOS.
Ce logiciel est régi par la licence CeCILL soumise au droit français et
respectant les principes de diffusion des logiciels libres. Vous pouvez
utiliser, modifier et/ou redistribuer ce programme sous les conditions
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
sur le site "http://www.cecill.info".
En contrepartie de l'accessibilité au code source et des droits de copie,
de modification et de redistribution accordés par cette licence, il n'est
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
seule une responsabilité restreinte pèse sur l'auteur du programme, le
titulaire des droits patrimoniaux et les concédants successifs.
A cet égard l'attention de l'utilisateur est attirée sur les risques
associés au chargement, à l'utilisation, à la modification et/ou au
développement et à la reproduction du logiciel par l'utilisateur étant
donné sa spécificité de logiciel libre, qui peut le rendre complexe à
manipuler et qui le réserve donc à des développeurs et des professionnels
avertis possédant des connaissances informatiques approfondies. Les
utilisateurs sont donc invités à charger et tester l'adéquation du
logiciel à leurs besoins dans des conditions permettant d'assurer la
sécurité de leurs systèmes et ou de leurs données et, plus généralement,
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
pris connaissance de la licence CeCILL, et que vous en avez accepté les
termes.
*/
let
sources = import ./npins;
pkgs = import sources.nixpkgs { };
pre-commit-check = (import sources.pre-commit-hooks).run {
src = ./.;
hooks = {
# Nix Hooks
statix.enable = true;
deadnix.enable = true;
rfc101 = {
enable = true;
name = "RFC-101 formatting";
entry = "${pkgs.lib.getExe pkgs.nixfmt-rfc-style}";
files = "\\.nix$";
};
# Misc Hooks
commitizen.enable = true;
};
};
in
{
shells = {
default = pkgs.mkShell {
name = "dgnum-infra";
packages =
(
with pkgs;
[
npins
colmena
nixos-generators
]
++ (builtins.map (p: callPackage p { }) [ (sources.disko + "/package.nix") ])
)
++ (import ./scripts { inherit pkgs; });
shellHook = ''
${pre-commit-check.shellHook}
'';
preferLocalBuild = true;
};
pre-commit = pkgs.mkShell {
name = "pre-commit-shell";
shellHook = ''
${pre-commit-check.shellHook}
'';
};
};
}

View file

@ -1,4 +1,5 @@
{ config, pkgs, ... }: {
{ config, pkgs, ... }:
{
imports = [ ./secrets ];
services = {
@ -8,8 +9,7 @@
listenAddress = "127.0.0.1";
settings = {
ALLOWED_HOSTS = [ "netbox.dgnum.sinavir.fr" ];
REMOTE_AUTH_BACKEND =
"social_core.backends.open_id_connect.OpenIdConnectAuth";
REMOTE_AUTH_BACKEND = "social_core.backends.open_id_connect.OpenIdConnectAuth";
};
extraConfig = ''
@ -27,12 +27,8 @@
enableACME = true;
forceSSL = true;
locations."/".proxyPass =
"http://${config.services.netbox.listenAddress}:${
builtins.toString config.services.netbox.port
}";
locations."/static/".alias =
"${config.services.netbox.dataDir}/static/";
locations."/".proxyPass = "http://${config.services.netbox.listenAddress}:${builtins.toString config.services.netbox.port}";
locations."/static/".alias = "${config.services.netbox.dataDir}/static/";
};
};
@ -50,5 +46,8 @@
};
users.users.nginx.extraGroups = [ "netbox" ];
networking.firewall.allowedTCPPorts = [ 443 80 ];
networking.firewall.allowedTCPPorts = [
443
80
];
}

View file

@ -6,10 +6,15 @@ let
inherit ((import ../../../meta).members) groups;
publicKeys = lib.splitString "\n"
(builtins.readFile (./maurice.keys)) # maurice servers' keys
publicKeys =
lib.splitString "\n" (builtins.readFile (./maurice.keys)) # maurice servers' keys
++ nix-lib.getAllKeys (groups.netbox ++ groups.root);
in {
"netbox.age" = { inherit publicKeys; };
"netbox_env.age" = { inherit publicKeys; };
in
{
"netbox.age" = {
inherit publicKeys;
};
"netbox_env.age" = {
inherit publicKeys;
};
}

View file

@ -6,8 +6,7 @@ let
patch = import sources.nix-patches { patchFile = ./patches; };
mkNode = node:
{ name, nodes, pkgs, ... }: {
mkNode = node: _: {
# Import the base configuration for each node
imports = builtins.map (lib.mkRel ./machines/${node}) [
"_configuration.nix"
@ -28,10 +27,13 @@ let
nixpkgs.config.allowUnfree = true;
# Use the stateVersion declared in the metadata
system = { inherit (metadata.nodes.${node}) stateVersion; };
system = {
inherit (metadata.nodes.${node}) stateVersion;
};
};
mkNixpkgs = node:
mkNixpkgs =
node:
patch.mkNixpkgsSrc rec {
src = sources.${version};
version = "nixos-${metadata.nodes.${node}.nixpkgs}";
@ -42,9 +44,12 @@ let
###
# Function to create arguments based on the node
#
mkArgs = node:
let lib' = (mkNixpkgs' node).lib;
in {
mkArgs =
node:
let
lib' = (mkNixpkgs' node).lib;
in
{
lib = import sources.nix-lib {
lib = lib';
keysRoot = ./keys;
@ -52,8 +57,8 @@ let
};
nodes = builtins.attrNames metadata.nodes;
in {
in
{
meta = {
nodeNixpkgs = lib.mapSingleFuse mkNixpkgs' nodes;
@ -65,8 +70,9 @@ in {
nodeSpecialArgs = lib.mapSingleFuse mkArgs nodes;
};
defaults = { pkgs, ... }: {
defaults = _: {
# Import the default modules
imports = [ ./modules ];
};
} // (lib.mapSingleFuse mkNode nodes)
}
// (lib.mapSingleFuse mkNode nodes)

View file

@ -34,5 +34,6 @@ in
};
users.users.root.openssh.authorizedKeys.keyFiles =
builtins.map (m: dgn-lib.mkRel ../keys "${m}.keys") dgn-members;
builtins.map (m: dgn-lib.mkRel ../keys "${m}.keys")
dgn-members;
}

View file

@ -2,4 +2,7 @@ let
inherit (import ../npins) nixpkgs;
in
(import nixpkgs { }).srcOnly { name = "nixpkgs-for-iso"; src = nixpkgs; }
(import nixpkgs { }).srcOnly {
name = "nixpkgs-for-iso";
src = nixpkgs;
}

View file

@ -3,20 +3,24 @@ _:
let
sources = import ../npins;
nix-lib = (import sources.nix-lib {
nix-lib =
(import sources.nix-lib {
inherit ((import sources.nixpkgs { })) lib;
keysRoot = ../keys;
}).extra;
in nix-lib // (with nix-lib; {
in
nix-lib
// (with nix-lib; {
# Get publickeys associated to a node
getNodeKeys = node:
getNodeKeys =
node:
let
meta = import ../meta;
names =
builtins.foldl' (names: group: names ++ meta.members.groups.${group})
(meta.nodes.${node}.admins ++ [ "/machines/${node}" ])
(meta.nodes.${node}.adminGroups ++ [ "root" ]);
in getAllKeys names;
in
getAllKeys names;
})

View file

@ -29,6 +29,5 @@
fsType = "vfat";
};
swapDevices =
[{ device = "/dev/disk/by-uuid/30547280-00e9-4ee1-8a07-d116590d9fbf"; }];
swapDevices = [ { device = "/dev/disk/by-uuid/30547280-00e9-4ee1-8a07-d116590d9fbf"; } ];
}

View file

@ -1,7 +1,9 @@
{ config, ... }:
let host = "demarches.dgnum.eu";
in {
let
host = "demarches.dgnum.eu";
in
{
imports = [ ./module.nix ];
services.demarches-simplifiees = {
@ -62,5 +64,7 @@ in {
};
};
age-secrets.matches."^ds_fr-.*$" = { owner = "ds-fr"; };
age-secrets.matches."^ds_fr-.*$" = {
owner = "ds-fr";
};
}

View file

@ -31,15 +31,26 @@
# The fact that you are presently reading this means that you have had
# knowledge of the CeCILL license and that you accept its terms.
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
mdDoc mkDefault mkEnableOption mkIf mkOption
mdDoc
mkDefault
mkEnableOption
mkIf
mkOption
optional optionalString
optional
optionalString
types;
types
;
cfg = config.services.demarches-simplifiees;
@ -64,16 +75,14 @@ let
$SUDO ${cfg.package}/bin/$BIN "$@"
'';
in {
in
{
options.services.demarches-simplifiees = {
enable = mkEnableOption "demarches-simplifiees.";
package = mkOption {
type = types.package;
default = pkgs.callPackage ./package {
inherit (cfg) initialDeploymentDate dataDir logDir;
};
default = pkgs.callPackage ./package { inherit (cfg) initialDeploymentDate dataDir logDir; };
};
user = mkOption {
@ -127,15 +136,17 @@ in {
description = "Demarches Simplifiees setup";
wantedBy = [ "multi-user.target" ];
path = [ pkgs.bash ds-fr ];
path = [
pkgs.bash
ds-fr
];
after = [ "postgresql.service" ];
serviceConfig = {
Type = "oneshot";
User = cfg.user;
Group = cfg.group;
EnvironmentFile = [ env ]
++ (optional (cfg.secretFile != null) cfg.secretFile);
EnvironmentFile = [ env ] ++ (optional (cfg.secretFile != null) cfg.secretFile);
StateDirectory = mkIf (cfg.dataDir == "/var/lib/ds-fr") "ds-fr";
LogsDirectory = mkIf (cfg.logDir == "/var/log/ds-fr") "ds-fr";
};
@ -155,14 +166,19 @@ in {
ds-fr-work = {
description = "Demarches Simplifiees work service";
wantedBy = [ "multi-user.target" "ds-fr.service" ];
after = [ "network.target" "ds-fr-setup.service" ];
wantedBy = [
"multi-user.target"
"ds-fr.service"
];
after = [
"network.target"
"ds-fr-setup.service"
];
requires = [ "ds-fr-setup.service" ];
serviceConfig = {
ExecStart = "${ds-fr}/bin/ds-fr rails jobs:work";
EnvironmentFile = [ env ]
++ (optional (cfg.secretFile != null) cfg.secretFile);
EnvironmentFile = [ env ] ++ (optional (cfg.secretFile != null) cfg.secretFile);
User = cfg.user;
Group = cfg.group;
StateDirectory = mkIf (cfg.dataDir == "/var/lib/ds-fr") "ds-fr";
@ -174,15 +190,17 @@ in {
description = "Demarches Simplifiees web service";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" "ds-fr-setup.service" ];
after = [
"network.target"
"ds-fr-setup.service"
];
requires = [ "ds-fr-setup.service" ];
path = [ pkgs.imagemagick ];
serviceConfig = {
ExecStart = "${ds-fr}/bin/ds-fr rails server";
Environment = [ "RAILS_QUEUE_ADAPTER=delayed_job" ];
EnvironmentFile = [ env ]
++ (optional (cfg.secretFile != null) cfg.secretFile);
EnvironmentFile = [ env ] ++ (optional (cfg.secretFile != null) cfg.secretFile);
User = cfg.user;
Group = cfg.group;
StateDirectory = mkIf (cfg.dataDir == "/var/lib/ds-fr") "ds-fr";
@ -192,7 +210,8 @@ in {
};
services = {
demarches-simplifiees.settings = (builtins.mapAttrs (_: mkDefault) {
demarches-simplifiees.settings =
(builtins.mapAttrs (_: mkDefault) {
RAILS_ENV = "production";
RAILS_ROOT = builtins.toString cfg.package;
@ -346,7 +365,8 @@ in {
# Siret number used for API Entreprise, by default we use SIRET from dinum
API_ENTREPRISE_DEFAULT_SIRET = "put_your_own_siret";
}) // {
})
// {
# Database credentials
DB_DATABASE = "ds-fr";
DB_USERNAME = cfg.user;
@ -368,8 +388,7 @@ in {
ensureDBOwnership = true;
};
extraPlugins = with config.services.postgresql.package.pkgs;
[ postgis ];
extraPlugins = with config.services.postgresql.package.pkgs; [ postgis ];
};
nginx = {
@ -381,7 +400,9 @@ in {
root = "${cfg.package}/public/";
locations."/".tryFiles = "$uri @proxy";
locations."@proxy" = { proxyPass = "http://127.0.0.1:3000"; };
locations."@proxy" = {
proxyPass = "http://127.0.0.1:3000";
};
};
};
};

View file

@ -1,6 +1,18 @@
{ lib, stdenv, fetchFromGitHub, git, fetchYarnDeps, yarn, fixup_yarn_lock, imagemagick
, nodejs, ruby_3_2, bundlerEnv, logDir ? "/var/log/ds-fr"
, dataDir ? "/var/lib/ds-fr", initialDeploymentDate ? "17941030" }:
{
lib,
stdenv,
fetchFromGitHub,
git,
fetchYarnDeps,
yarn,
fixup_yarn_lock,
nodejs,
ruby_3_2,
bundlerEnv,
logDir ? "/var/log/ds-fr",
dataDir ? "/var/lib/ds-fr",
initialDeploymentDate ? "17941030",
}:
let
pname = "ds-fr";
@ -43,7 +55,12 @@ let
};
buildInputs = [ rubyEnv ];
nativeBuildInputs = [ fixup_yarn_lock nodejs yarn rubyEnv.wrappedRuby ];
nativeBuildInputs = [
fixup_yarn_lock
nodejs
yarn
rubyEnv.wrappedRuby
];
RAILS_ENV = "production";
NODE_ENV = "dev";
@ -53,8 +70,9 @@ let
./patches/build.patch
];
postPatch = builtins.concatStringsSep "\n"
(builtins.map (p: "${git}/bin/git apply -p1 < ${p}") dgn-patches);
postPatch = builtins.concatStringsSep "\n" (
builtins.map (p: "${git}/bin/git apply -p1 < ${p}") dgn-patches
);
OTP_SECRET_KEY = "precompile_placeholder";
SECRET_KEY_BASE = "precompile_placeholder";
@ -82,8 +100,8 @@ let
};
dgn-patches = import ./dgnum.nix { };
in stdenv.mkDerivation {
in
stdenv.mkDerivation {
name = "demarches-simplifiees.fr-${version}";
inherit src;
@ -98,8 +116,9 @@ in stdenv.mkDerivation {
./patches/secrets-fc.patch
];
postPatch = builtins.concatStringsSep "\n"
(builtins.map (p: "${git}/bin/git apply -p1 < ${p}") dgn-patches);
postPatch = builtins.concatStringsSep "\n" (
builtins.map (p: "${git}/bin/git apply -p1 < ${p}") dgn-patches
);
buildPhase = ''
rm -rf public
@ -132,8 +151,7 @@ in stdenv.mkDerivation {
meta = with lib; {
description = "Dématérialiser et simplifier les démarches administratives";
homepage =
"https://github.com/demarches-simplifiees/demarches-simplifiees.fr";
homepage = "https://github.com/demarches-simplifiees/demarches-simplifiees.fr";
license = licenses.agpl3Only;
maintainers = with maintainers; [ thubrecht ];
};

View file

@ -1,6 +1,5 @@
_:
builtins.map (id:
builtins.fetchurl
"https://git.dgnum.eu/DGNum/demarches-normaliennes/commit/${id}.patch")
[ "0b9b32483a700ad3060b3d4ef723d5f40c290c62" ]
builtins.map
(id: builtins.fetchurl "https://git.dgnum.eu/DGNum/demarches-normaliennes/commit/${id}.patch")
[ "0b9b32483a700ad3060b3d4ef723d5f40c290c62" ]

File diff suppressed because it is too large Load diff

View file

@ -3,7 +3,8 @@
let
host = "pads.dgnum.eu";
port = 3007;
in {
in
{
services = {
hedgedoc = {
enable = true;
@ -43,13 +44,17 @@ in {
ensureDatabases = [ "hedgedoc" ];
ensureUsers = [{
ensureUsers = [
{
name = "hedgedoc";
ensureDBOwnership = true;
}];
}
];
};
};
systemd.services.hedgedoc.serviceConfig.StateDirectory =
lib.mkForce [ "hedgedoc" "hedgedoc/uploads" ];
systemd.services.hedgedoc.serviceConfig.StateDirectory = lib.mkForce [
"hedgedoc"
"hedgedoc/uploads"
];
}

View file

@ -40,22 +40,23 @@
};
authTokenFile = config.age.secrets."radius-auth_token_file".path;
privateKeyPasswordFile =
config.age.secrets."radius-private_key_password_file".path;
privateKeyPasswordFile = config.age.secrets."radius-private_key_password_file".path;
certs = builtins.listToAttrs (builtins.map (name:
lib.nameValuePair name
config.age.secrets."radius-${name}_pem_file".path) [
certs = builtins.listToAttrs (
builtins.map (name: lib.nameValuePair name config.age.secrets."radius-${name}_pem_file".path) [
"ca"
"cert"
"dh"
"key"
]);
]
);
radiusClients = { };
};
age-secrets.matches."^radius-.*$" = { owner = "radius"; };
age-secrets.matches."^radius-.*$" = {
owner = "radius";
};
networking.firewall.allowedTCPPorts = [ 1812 ];
networking.firewall.allowedUDPPorts = [ 1812 ];

View file

@ -1,17 +1,27 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
inherit (lib) mkEnableOption mkIf mkOption types;
inherit (lib)
mkEnableOption
mkIf
mkOption
types
;
settingsFormat = pkgs.formats.toml { };
py-pkgs = import ./packages/python { inherit pkgs; };
pykanidm =
pkgs.callPackage ./packages/pykanidm.nix { inherit (py-pkgs) pydantic; };
pykanidm = pkgs.callPackage ./packages/pykanidm.nix { inherit (py-pkgs) pydantic; };
rlm_python = pkgs.callPackage ./packages/rlm_python.nix { inherit pykanidm; };
cfg = config.services.k-radius;
in {
in
{
options.services.k-radius = {
enable = mkEnableOption "a freeradius service linked to kanidm.";
@ -19,17 +29,17 @@ in {
freeradius = mkOption {
type = types.package;
default = pkgs.freeradius.overrideAttrs (old: {
buildInputs = (old.buildInputs or [ ])
++ [ (pkgs.python3.withPackages (ps: [ ps.kanidm ])) ];
});
default = pkgs.freeradius.overrideAttrs (
old: {
buildInputs = (old.buildInputs or [ ]) ++ [ (pkgs.python3.withPackages (ps: [ ps.kanidm ])) ];
}
);
};
configDir = mkOption {
type = types.path;
default = "/var/lib/radius/raddb";
description =
"The path of the freeradius server configuration directory.";
description = "The path of the freeradius server configuration directory.";
};
authTokenFile = mkOption {
@ -38,12 +48,14 @@ in {
};
radiusClients = mkOption {
type = types.attrsOf (types.submodule {
type = types.attrsOf (
types.submodule {
options = {
secret = mkOption { type = types.path; };
ipaddr = mkOption { type = types.str; };
};
});
}
);
default = { };
description = "A mapping of clients and their authentication tokens.";
};
@ -55,8 +67,7 @@ in {
};
dh = mkOption {
type = types.str;
description =
"The output of `openssl dhparam -in ca.pem -out dh.pem 2048`.";
description = "The output of `openssl dhparam -in ca.pem -out dh.pem 2048`.";
};
cert = mkOption {
type = types.str;
@ -113,9 +124,13 @@ in {
# write the clients configuration
rm ${cfg.configDir}/clients.conf && touch ${cfg.configDir}/clients.conf
${builtins.concatStringsSep "\n" (builtins.attrValues (builtins.mapAttrs
(name:
{ secret, ipaddr }: ''
${builtins.concatStringsSep "\n" (
builtins.attrValues (
builtins.mapAttrs
(
name:
{ secret, ipaddr }:
''
cat <<EOF >> ${cfg.configDir}/client.conf
client ${name} {
ipaddr = ${ipaddr}
@ -123,16 +138,18 @@ in {
proto = *
}
EOF
'') cfg.radiusClients))}
''
)
cfg.radiusClients
)
)}
# Copy the kanidm configuration
cat <<EOF > /var/lib/radius/kanidm.toml
auth_token = "$(cat "${cfg.authTokenFile}")"
EOF
cat ${
settingsFormat.generate "kanidm.toml" cfg.settings
} >> /var/lib/radius/kanidm.toml
cat ${settingsFormat.generate "kanidm.toml" cfg.settings} >> /var/lib/radius/kanidm.toml
chmod u+w /var/lib/radius/kanidm.toml
# Copy the certificates to the correct directory
@ -154,11 +171,13 @@ in {
# ${pkgs.freeradius}/bin/radiusd -C -d ${cfg.configDir} -l stdout
'';
path = [ pkgs.openssl pkgs.gnused ];
path = [
pkgs.openssl
pkgs.gnused
];
serviceConfig = {
ExecStart =
"${cfg.freeradius}/bin/radiusd -f -d ${cfg.configDir} -l stdout";
ExecStart = "${cfg.freeradius}/bin/radiusd -f -d ${cfg.configDir} -l stdout";
ExecReload = [
"${cfg.freeradius}/bin/radiusd -C -d ${cfg.configDir} -l stdout"
"${pkgs.coreutils}/bin/kill -HUP $MAINPID"

View file

@ -1,25 +1,38 @@
{ lib, fetchFromGitHub, python3, pydantic }:
{
lib,
fetchFromGitHub,
python3,
pydantic,
}:
let
pname = "kanidm";
version = "0.0.3";
in python3.pkgs.buildPythonPackage {
in
python3.pkgs.buildPythonPackage {
inherit pname version;
format = "pyproject";
disabled = python3.pythonOlder "3.8";
src = (fetchFromGitHub {
src =
(fetchFromGitHub {
owner = pname;
repo = pname;
# Latest 1.1.0-rc.15 tip
rev = "a5ca8018e3a636dbb0a79b3fd869db059d92979d";
hash = "sha256-PFGoeGn7a/lVR6rOmOKA3ydAoo3/+9RlkwBAKS22Psg=";
}) + "/pykanidm";
})
+ "/pykanidm";
nativeBuildInputs = with python3.pkgs; [ poetry-core ];
propagatedBuildInputs = with python3.pkgs; [ aiohttp pydantic toml (authlib.overridePythonAttrs (_: { doCheck = false; })) ];
propagatedBuildInputs = with python3.pkgs; [
aiohttp
pydantic
toml
(authlib.overridePythonAttrs (_: { doCheck = false; }))
];
doCheck = false;
@ -29,6 +42,9 @@ in python3.pkgs.buildPythonPackage {
description = "Kanidm client library";
homepage = "https://github.com/kanidm/kanidm/tree/master/pykanidm";
license = licenses.mpl20;
maintainers = with maintainers; [ arianvp hexa ];
maintainers = with maintainers; [
arianvp
hexa
];
};
}

View file

@ -5,8 +5,16 @@ let
callPackage = lib.callPackageWith (pkgs // pkgs.python3.pkgs // self);
self = builtins.listToAttrs (builtins.map (name: {
self = builtins.listToAttrs (
builtins.map
(name: {
inherit name;
value = callPackage (./. + "/${name}.nix") { };
}) [ "pydantic" "pydantic-core" ]);
in self
})
[
"pydantic"
"pydantic-core"
]
);
in
self

View file

@ -1,17 +1,18 @@
{ stdenv
, lib
, buildPythonPackage
, fetchFromGitHub
, cargo
, rustPlatform
, rustc
, libiconv
, typing-extensions
, pytestCheckHook
, hypothesis
, pytest-timeout
, pytest-mock
, dirty-equals
{
stdenv,
lib,
buildPythonPackage,
fetchFromGitHub,
cargo,
rustPlatform,
rustc,
libiconv,
typing-extensions,
pytestCheckHook,
hypothesis,
pytest-timeout,
pytest-mock,
dirty-equals,
}:
let
@ -27,9 +28,7 @@ let
hash = "sha256-UguZpA3KEutOgIavjx8Ie//0qJq+4FTZNQTwb/ZIgb8=";
};
patches = [
./01-remove-benchmark-flags.patch
];
patches = [ ./01-remove-benchmark-flags.patch ];
cargoDeps = rustPlatform.fetchCargoTarball {
inherit src;
@ -45,13 +44,9 @@ let
typing-extensions
];
buildInputs = lib.optionals stdenv.isDarwin [
libiconv
];
buildInputs = lib.optionals stdenv.isDarwin [ libiconv ];
propagatedBuildInputs = [
typing-extensions
];
propagatedBuildInputs = [ typing-extensions ];
pythonImportsCheck = [ "pydantic_core" ];
@ -85,4 +80,5 @@ let
maintainers = with maintainers; [ blaggacao ];
};
};
in pydantic-core
in
pydantic-core

View file

@ -1,27 +1,28 @@
{ lib
, buildPythonPackage
, fetchFromGitHub
, pythonOlder
{
lib,
buildPythonPackage,
fetchFromGitHub,
pythonOlder,
# build-system
, hatchling
, hatch-fancy-pypi-readme
# build-system
hatchling,
hatch-fancy-pypi-readme,
# native dependencies
, libxcrypt
# native dependencies
libxcrypt,
# dependencies
, annotated-types
, pydantic-core
, typing-extensions
# dependencies
annotated-types,
pydantic-core,
typing-extensions,
# tests
, cloudpickle
, email-validator
, dirty-equals
, faker
, pytestCheckHook
, pytest-mock
# tests
cloudpickle,
email-validator,
dirty-equals,
faker,
pytestCheckHook,
pytest-mock,
}:
buildPythonPackage rec {
@ -38,9 +39,7 @@ buildPythonPackage rec {
hash = "sha256-D0gYcyrKVVDhBgV9sCVTkGq/kFmIoT9l0i5bRM1qxzM=";
};
buildInputs = lib.optionals (pythonOlder "3.9") [
libxcrypt
];
buildInputs = lib.optionals (pythonOlder "3.9") [ libxcrypt ];
nativeBuildInputs = [
hatch-fancy-pypi-readme
@ -54,9 +53,7 @@ buildPythonPackage rec {
];
passthru.optional-dependencies = {
email = [
email-validator
];
email = [ email-validator ];
};
nativeCheckInputs = [
@ -93,4 +90,3 @@ buildPythonPackage rec {
maintainers = with maintainers; [ wd15 ];
};
}

View file

@ -1,8 +1,14 @@
{ stdenv, fetchFromGitHub, python3, pykanidm }:
{
stdenv,
fetchFromGitHub,
python3,
pykanidm,
}:
let pythonPath = with python3.pkgs; makePythonPath [ pykanidm ];
in stdenv.mkDerivation rec {
let
pythonPath = with python3.pkgs; makePythonPath [ pykanidm ];
in
stdenv.mkDerivation rec {
pname = "rlm_python";
version = "1.1.0-rc.15";
@ -25,9 +31,15 @@ in stdenv.mkDerivation rec {
cp -R rlm_python/{mods-available,sites-available} $out/etc/raddb/
'';
phases = [ "unpackPhase" "patchPhase" "installPhase" ];
phases = [
"unpackPhase"
"patchPhase"
"installPhase"
];
passthru = { inherit pythonPath; };
passthru = {
inherit pythonPath;
};
preferLocalBuild = true;
}

View file

@ -5,8 +5,16 @@ let
cert = config.security.acme.certs.${domain};
allowedSubDomains = [ "cloud" "git" "videos" "social" "demarches" "netbird" ];
in {
allowedSubDomains = [
"cloud"
"git"
"videos"
"social"
"demarches"
"netbird"
];
in
{
services.kanidm = {
enableServer = true;

View file

@ -7,4 +7,3 @@ lib.setDefault { inherit publicKeys; } [
"kanidm-password_admin"
"kanidm-password_idm_admin"
]

View file

@ -1,7 +1,9 @@
{ config, ... }:
let host = "social.dgnum.eu";
in {
let
host = "social.dgnum.eu";
in
{
services.mastodon = {
enable = true;
@ -9,7 +11,6 @@ in {
smtp = {
# TODO: smtp setup
fromAddress = "social@services.dgnum.eu";
};
streamingProcesses = 4;
@ -38,5 +39,7 @@ in {
extraEnvFiles = [ config.age.secrets."mastodon-extra_env_file".path ];
};
age-secrets.matches."^mastodon-.*$" = { owner = "mastodon"; };
age-secrets.matches."^mastodon-.*$" = {
owner = "mastodon";
};
}

View file

@ -3,7 +3,8 @@
let
host = "cloud.dgnum.eu";
nextcloud-occ = "${config.services.nextcloud.occ}/bin/nextcloud-occ";
in {
in
{
services.nextcloud = {
enable = true;
hostName = host;
@ -102,8 +103,7 @@ in {
image = "collabora/code";
imageFile = pkgs.dockerTools.pullImage {
imageName = "collabora/code";
imageDigest =
"sha256:a8cce07c949aa59cea0a7f1f220266a1a6d886c717c3b5005782baf6f384d645";
imageDigest = "sha256:a8cce07c949aa59cea0a7f1f220266a1a6d886c717c3b5005782baf6f384d645";
sha256 = "sha256-lN6skv62x+x7G7SNOUyZ8W6S/uScrkqE1nbBwwSEWXQ=";
};
ports = [ "9980:9980" ];
@ -111,7 +111,12 @@ in {
domain = "cloud.dgnum.eu";
extra_params = "--o:ssl.enable=false --o:ssl.termination=true --o:remote_font_config.url=https://cloud.dgnum.eu/apps/richdocuments/settings/fonts.json";
};
extraOptions = [ "--cap-add" "MKNOD" "--cap-add" "SYS_ADMIN" ];
extraOptions = [
"--cap-add"
"MKNOD"
"--cap-add"
"SYS_ADMIN"
];
};
};
@ -180,7 +185,9 @@ in {
description = "Generate preview for nextcloud media.";
script = "${nextcloud-occ} preview:pre-generate -vvv";
startAt = "*-*-* 01:00:00 UTC";
serviceConfig = { Restart = "on-failure"; };
serviceConfig = {
Restart = "on-failure";
};
};
nextcloud-cron.path = [ pkgs.perl ];
@ -188,9 +195,13 @@ in {
environment.systemPackages = [ pkgs.ffmpeg_6-headless ];
networking.hosts = { "129.199.146.148" = [ "s3.dgnum.eu" ]; };
networking.hosts = {
"129.199.146.148" = [ "s3.dgnum.eu" ];
};
age-secrets.matches."^nextcloud-.*$" = { owner = "nextcloud"; };
age-secrets.matches."^nextcloud-.*$" = {
owner = "nextcloud";
};
system.activationScripts = {
restart-nextcloud.text = ''

View file

@ -1,7 +1,9 @@
{ config, ... }:
let host = "docs.dgnum.eu";
in {
let
host = "docs.dgnum.eu";
in
{
services.outline = {
enable = true;
@ -27,8 +29,7 @@ in {
userinfoUrl = "https://sso.dgnum.eu/oauth2/openid/outline_dgn/userinfo";
displayName = "DGNum SSO";
clientSecretFile =
config.age.secrets."outline-oidc_client_secret_file".path;
clientSecretFile = config.age.secrets."outline-oidc_client_secret_file".path;
};
defaultLanguage = "fr_FR";
@ -51,5 +52,7 @@ in {
};
};
age-secrets.matches."^outline-.*$" = { owner = "outline"; };
age-secrets.matches."^outline-.*$" = {
owner = "outline";
};
}

View file

@ -1,9 +1,10 @@
{ pkgs, ... }:
let
host = "rstudio.dgnum.eu";
# host = "rstudio.dgnum.eu";
port = 19000;
in {
in
{
services.rstudio-server = {
enable = true;
rserverExtraConfig = ''
@ -11,14 +12,17 @@ in {
'';
package = pkgs.rstudioServerWrapper.override {
packages = with pkgs.rPackages; [ ggplot2 rmarkdown dplyr ];
packages = with pkgs.rPackages; [
ggplot2
rmarkdown
dplyr
];
};
};
users.users.ruser = {
isNormalUser = true;
hashedPassword =
"$6$pTXXVh8NfE.M8VPc$q0fFh3Y7Y0DauLCcZLgJzFciq1wkjoHmO61XpOrZLH3a1M32ZzOMbjx2XMm2QxrUncbx6hGerY/lD8rQ8InS4.";
hashedPassword = "$6$pTXXVh8NfE.M8VPc$q0fFh3Y7Y0DauLCcZLgJzFciq1wkjoHmO61XpOrZLH3a1M32ZzOMbjx2XMm2QxrUncbx6hGerY/lD8rQ8InS4.";
};
dgn-access-control.users.ruser = [ "jemagius" ];

View file

@ -1,7 +1,9 @@
{ config, ... }:
let host = "saml-idp.dgnum.eu";
in {
let
host = "saml-idp.dgnum.eu";
in
{
imports = [ ./module.nix ];
@ -20,8 +22,7 @@ in {
config = {
endpoints.single_sign_on_service = {
"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" = "sso/post";
"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" =
"sso/redirect";
"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" = "sso/redirect";
};
entityid_endpoint = true;
enable_metadata_reload = false;
@ -32,11 +33,13 @@ in {
url = "https://dgnum.eu";
};
contact_person = [{
contact_person = [
{
contact_type = "technical";
email_address = "mailto:tom.hubrecht@dgnum.eu";
given_name = "Tom Hubrecht";
}];
}
];
key_file = "/var/lib/satosa/ssl/key.pem";
cert_file = "/var/lib/satosa/ssl/cert.pem";
@ -50,10 +53,12 @@ in {
endpoints.single_sign_on_service = [ ];
name = "DGNum proxy IdP";
ui_info = {
display_name = [{
display_name = [
{
lang = "fr";
text = "Service de connexion DGNum";
}];
}
];
};
name_id_format = [
"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
@ -63,9 +68,10 @@ in {
default = {
attribute_restrictions = null;
fail_on_missing_requested = false;
lifetime = { minutes = 15; };
name_form =
"urn:oasis:names:tc:SAML:2.0:attrname-format:uri";
lifetime = {
minutes = 15;
};
name_form = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri";
encrypt_assertion = false;
encrypted_advice_attributes = false;
};
@ -121,12 +127,15 @@ in {
module = "satosa.backends.openid_connect.OpenIDConnectBackend";
name = "kanidm";
config = {
provider_metadata.issuer =
"https://sso.dgnum.eu/oauth2/openid/satosa_dgn/";
provider_metadata.issuer = "https://sso.dgnum.eu/oauth2/openid/satosa_dgn/";
client = {
auth_req_params = {
response_type = "code";
scope = [ "openid" "profile" "email" ];
scope = [
"openid"
"profile"
"email"
];
};
client_metadata = {
client_id = "satosa_dgn";
@ -144,5 +153,7 @@ in {
forceSSL = true;
};
age-secrets.matches."^satosa-.*$" = { owner = "satosa"; };
age-secrets.matches."^satosa-.*$" = {
owner = "satosa";
};
}

View file

@ -1,7 +1,18 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
inherit (lib) mkDefault mkEnableOption mkIf mkOption types;
inherit (lib)
mkDefault
mkEnableOption
mkIf
mkOption
types
;
yamlFormat = pkgs.formats.yaml { };
@ -9,12 +20,17 @@ let
cfg = config.services.satosa;
mkYamlFiles = files:
builtins.attrValues
(builtins.mapAttrs (name: yamlFormat.generate "${name}.yaml") files);
mkYamlFiles =
files: builtins.attrValues (builtins.mapAttrs (name: yamlFormat.generate "${name}.yaml") files);
pyEnv = cfg.package.python.withPackages (ps: [ cfg.package ps.gunicorn ]);
in {
pyEnv = cfg.package.python.withPackages (
ps: [
cfg.package
ps.gunicorn
]
);
in
{
options.services.satosa = {
enable = mkEnableOption "SATOSA, a SAML and OIDC proxy.";
@ -88,8 +104,7 @@ in {
MICRO_SERVICES = mkYamlFiles cfg.microServices;
LOGGING = {
version = 1;
formatters.simple.format =
"[%(asctime)s] [%(levelname)s] [%(name)s.%(funcName)s] %(message)s";
formatters.simple.format = "[%(asctime)s] [%(levelname)s] [%(name)s.%(funcName)s] %(message)s";
handlers.stdout = {
class = "logging.StreamHandler";
stream = "ext://sys.stdout";
@ -171,7 +186,9 @@ in {
TimeoutStopSec = "5";
EnvironmentFile = lib.optional (cfg.envFile != null) cfg.envFile;
};
environment = { SATOSA_CONFIG = configFile; };
environment = {
SATOSA_CONFIG = configFile;
};
};
};
@ -179,8 +196,7 @@ in {
enable = true;
virtualHosts.${cfg.host} = {
locations."/".proxyPass =
"http://127.0.0.1:${builtins.toString cfg.port}";
locations."/".proxyPass = "http://127.0.0.1:${builtins.toString cfg.port}";
};
};

View file

@ -1,6 +1,7 @@
{ lib
, python3
, fetchPypi
{
lib,
python3,
fetchPypi,
}:
python3.pkgs.buildPythonPackage rec {

View file

@ -13,5 +13,5 @@ let
pydantic = callPackage ./pydantic.nix { };
pydantic-core = callPackage ./pydantic-core.nix { };
};
in self.satosa
in
self.satosa

View file

@ -1,7 +1,8 @@
{ lib
, python3
, fetchPypi
, pydantic-settings
{
lib,
python3,
fetchPypi,
pydantic-settings,
}:
python3.pkgs.buildPythonPackage rec {

View file

@ -1,9 +1,10 @@
{ lib
, python3
, fetchPypi
, cargo
, rustPlatform
, rustc
{
lib,
python3,
fetchPypi,
cargo,
rustPlatform,
rustc,
}:
python3.pkgs.buildPythonPackage rec {
@ -31,9 +32,7 @@ python3.pkgs.buildPythonPackage rec {
rustc
];
propagatedBuildInputs = with python3.pkgs; [
typing-extensions
];
propagatedBuildInputs = with python3.pkgs; [ typing-extensions ];
pythonImportsCheck = [ "pydantic_core" ];

View file

@ -1,7 +1,8 @@
{ lib
, python3
, fetchPypi
, pydantic
{
lib,
python3,
fetchPypi,
pydantic,
}:
python3.pkgs.buildPythonPackage rec {
@ -15,9 +16,7 @@ python3.pkgs.buildPythonPackage rec {
hash = "sha256-li3DZySVqtaulqQ5D6x+WTWR4URiXlES01n49n+3WUU=";
};
nativeBuildInputs = [
python3.pkgs.hatchling
];
nativeBuildInputs = [ python3.pkgs.hatchling ];
propagatedBuildInputs = with python3.pkgs; [
pydantic

View file

@ -1,7 +1,8 @@
{ lib
, python3
, fetchPypi
, pydantic-core
{
lib,
python3,
fetchPypi,
pydantic-core,
}:
python3.pkgs.buildPythonPackage rec {
@ -26,9 +27,7 @@ python3.pkgs.buildPythonPackage rec {
];
passthru.optional-dependencies = with python3.pkgs; {
email = [
email-validator
];
email = [ email-validator ];
};
pythonImportsCheck = [ "pydantic" ];

View file

@ -1,7 +1,8 @@
{ lib
, python3
, fetchPypi
, oic
{
lib,
python3,
fetchPypi,
oic,
}:
python3.pkgs.buildPythonPackage rec {

View file

@ -1,8 +1,9 @@
{ lib
, python3
, fetchPypi
, cookies-samesite-compat
, pyop
{
lib,
python3,
fetchPypi,
cookies-samesite-compat,
pyop,
}:
python3.pkgs.buildPythonPackage rec {
@ -36,15 +37,9 @@ python3.pkgs.buildPythonPackage rec {
];
passthru.optional-dependencies = with python3.pkgs; {
ldap = [
ldap3
];
pyop_mongo = [
pyop
];
pyop_redis = [
pyop
];
ldap = [ ldap3 ];
pyop_mongo = [ pyop ];
pyop_redis = [ pyop ];
};
passthru.python = python3;

View file

@ -1,8 +1,9 @@
{ config, ... }:
let host = "pass.dgnum.eu";
in {
let
host = "pass.dgnum.eu";
in
{
services.vaultwarden = {
enable = true;
@ -62,10 +63,12 @@ in {
ensureDatabases = [ "vaultwarden" ];
ensureUsers = [{
ensureUsers = [
{
name = "vaultwarden";
ensureDBOwnership = true;
}];
}
];
};
};
}

View file

@ -5,7 +5,8 @@ let
port = 3005;
websocketPort = 6902;
in {
in
{
services.zammad = {
enable = true;
@ -38,8 +39,7 @@ in {
proxyWebsockets = true;
};
"~ ^/(assets/|robots.txt|humans.txt|favicon.ico|apple-touch-icon.png)".extraConfig =
''
"~ ^/(assets/|robots.txt|humans.txt|favicon.ico|apple-touch-icon.png)".extraConfig = ''
expires max;
'';
};
@ -51,5 +51,7 @@ in {
};
};
age-secrets.matches."^zammad-.*$" = { owner = "zammad"; };
age-secrets.matches."^zammad-.*$" = {
owner = "zammad";
};
}

View file

@ -29,6 +29,5 @@
fsType = "vfat";
};
swapDevices =
[{ device = "/dev/disk/by-uuid/65a6f6e4-e996-4718-a4d0-cd0c78dcb15b"; }];
swapDevices = [ { device = "/dev/disk/by-uuid/65a6f6e4-e996-4718-a4d0-cd0c78dcb15b"; } ];
}

View file

@ -1,8 +1,14 @@
{ config, pkgs, sources, ... }:
{
config,
pkgs,
sources,
...
}:
let host = "cachix.dgnum.eu";
in {
let
host = "cachix.dgnum.eu";
in
{
services = {
atticd = {
enable = true;
@ -68,10 +74,12 @@ in {
ensureDatabases = [ "atticd" ];
ensureUsers = [{
ensureUsers = [
{
name = "atticd";
ensureDBOwnership = true;
}];
}
];
};
};
}

View file

@ -3,18 +3,29 @@
let
url = "https://git.dgnum.eu";
mkRunner = { labels, name, token }: {
mkRunner =
{
labels,
name,
token,
}:
{
enable = true;
inherit name labels token url;
inherit
name
labels
token
url
;
settings.container = {
network = "host";
options = "--cpus=4";
};
};
in {
in
{
services.forgejo-nix-runners = {
enable = true;
@ -23,7 +34,11 @@ in {
storePath = "/data/slow/nix";
tokenFile = config.age.secrets."forgejo_runners-token_file".path;
dependencies = [ pkgs.colmena pkgs.npins pkgs.tea ];
dependencies = [
pkgs.colmena
pkgs.npins
pkgs.tea
];
containerOptions = [ "--cpus=4" ];

View file

@ -3,7 +3,8 @@
let
port = 3000;
host = "git.dgnum.eu";
in {
in
{
services = {
forgejo = {
enable = true;
@ -19,7 +20,9 @@ in {
};
settings = {
DEFAULT = { APP_NAME = "Forge git de la DGNum"; };
DEFAULT = {
APP_NAME = "Forge git de la DGNum";
};
server = {
ROOT_URL = "https://${host}/";
@ -62,7 +65,9 @@ in {
virtualHosts.${host} = {
enableACME = true;
forceSSL = true;
locations."/" = { proxyPass = "http://127.0.0.1:${toString port}"; };
locations."/" = {
proxyPass = "http://127.0.0.1:${toString port}";
};
};
};
};
@ -77,5 +82,7 @@ in {
users.groups.git = { };
age-secrets.matches."^forgejo-.*$" = { owner = "git"; };
age-secrets.matches."^forgejo-.*$" = {
owner = "git";
};
}

View file

@ -8,12 +8,13 @@ let
metadata_dir = "/data/fast/garage/meta";
buckets = [ "peertube-videos-dgnum" ];
in {
in
{
services.garage = {
enable = true;
package = pkgs.garage_0_9.overrideAttrs (old: {
package = pkgs.garage_0_9.overrideAttrs (
old: {
patches = (old.patches or [ ]) ++ [
# Allow 0 as a part number marker
(pkgs.fetchpatch {
@ -21,7 +22,8 @@ in {
hash = "sha256-28ctLl1qscMRj2JEVnmhuLyK1Avub8QeyfQFxAK0y08=";
})
];
});
}
);
settings = {
inherit data_dir metadata_dir;
@ -56,7 +58,10 @@ in {
systemd.services.garage.serviceConfig = {
User = "garage";
ReadWriteDirectories = [ data_dir metadata_dir ];
ReadWriteDirectories = [
data_dir
metadata_dir
];
};
users.users.garage = {

View file

@ -1,8 +1,24 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
filterAttrs literalExpression maintainers mkDefault mkEnableOption mkIf
mkMerge mkOption optionalAttrs optionalString optionals types;
filterAttrs
literalExpression
maintainers
mkDefault
mkEnableOption
mkIf
mkMerge
mkOption
optionalAttrs
optionalString
optionals
types
;
inherit ((import ./package { inherit pkgs; })) dashboard;
@ -13,37 +29,33 @@ let
settingsFormat = pkgs.formats.keyValue { };
managementFormat = pkgs.formats.json { };
settingsFile = settingsFormat.generate "setup.env" (builtins.mapAttrs (_: val:
if builtins.isList val then
''"${builtins.concatStringsSep " " val}"''
else
val) settings);
settingsFile = settingsFormat.generate "setup.env" (
builtins.mapAttrs
(_: val: if builtins.isList val then ''"${builtins.concatStringsSep " " val}"'' else val)
settings
);
managementFile = managementFormat.generate "config.json" cfg.managementConfig;
settings = rec {
settings =
rec {
TURN_DOMAIN = cfg.settings.NETBIRD_DOMAIN;
TURN_PORT = 3478;
TURN_USER = "netbird";
TURN_MIN_PORT = 49152;
TURN_MAX_PORT = 65535;
TURN_PASSWORD =
if cfg.secretFiles.TURN_PASSWORD != null then "$TURN_PASSWORD" else null;
TURN_SECRET =
if cfg.secretFiles.TURN_SECRET != null then "$TURN_SECRET" else "secret";
TURN_PASSWORD = if cfg.secretFiles.TURN_PASSWORD != null then "$TURN_PASSWORD" else null;
TURN_SECRET = if cfg.secretFiles.TURN_SECRET != null then "$TURN_SECRET" else "secret";
STUN_USERNAME = "";
STUN_PASSWORD =
if cfg.secretFiles.STUN_PASSWORD != null then "$STUN_PASSWORD" else null;
STUN_PASSWORD = if cfg.secretFiles.STUN_PASSWORD != null then "$STUN_PASSWORD" else null;
NETBIRD_DASHBOARD_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:443";
NETBIRD_MGMT_API_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:${
builtins.toString
cfg.settings.NETBIRD_MGMT_API_PORT or NETBIRD_MGMT_API_PORT
builtins.toString cfg.settings.NETBIRD_MGMT_API_PORT or NETBIRD_MGMT_API_PORT
}";
NETBIRD_SIGNAL_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:${
builtins.toString
cfg.settings.NETBIRD_SIGNAL_PORT or NETBIRD_SIGNAL_PORT
builtins.toString cfg.settings.NETBIRD_SIGNAL_PORT or NETBIRD_SIGNAL_PORT
}";
NETBIRD_SIGNAL_PROTOCOL = "https";
@ -51,12 +63,14 @@ let
NETBIRD_AUTH_USER_ID_CLAIM = "sub";
NETBIRD_AUTH_CLIENT_SECRET =
if cfg.secretFiles.AUTH_CLIENT_SECRET != null then
"$AUTH_CLIENT_SECRET"
else
"";
NETBIRD_AUTH_SUPPORTED_SCOPES =
[ "openid" "profile" "email" "offline_access" "api" ];
if cfg.secretFiles.AUTH_CLIENT_SECRET != null then "$AUTH_CLIENT_SECRET" else "";
NETBIRD_AUTH_SUPPORTED_SCOPES = [
"openid"
"profile"
"email"
"offline_access"
"api"
];
NETBIRD_AUTH_REDIRECT_URI = "";
NETBIRD_AUTH_SILENT_REDIRECT_URI = "";
@ -64,8 +78,13 @@ let
NETBIRD_AUTH_DEVICE_AUTH_PROVIDER = "none";
NETBIRD_AUTH_DEVICE_AUTH_CLIENT_ID = cfg.settings.NETBIRD_AUTH_CLIENT_ID;
NETBIRD_AUTH_DEVICE_AUTH_AUDIENCE = cfg.settings.NETBIRD_AUTH_AUDIENCE;
NETBIRD_AUTH_DEVICE_AUTH_SCOPE =
[ "openid" "profile" "email" "offline_access" "api" ];
NETBIRD_AUTH_DEVICE_AUTH_SCOPE = [
"openid"
"profile"
"email"
"offline_access"
"api"
];
NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN = false;
NETBIRD_MGMT_API_PORT = 443;
@ -87,18 +106,23 @@ let
NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT = "";
NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS = [ "53000" ];
NETBIRD_AUTH_PKCE_REDIRECT_URLS = builtins.map (p: "http://localhost:${p}")
NETBIRD_AUTH_PKCE_REDIRECT_URLS =
builtins.map (p: "http://localhost:${p}")
cfg.settings.NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS or NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS;
} // (optionalAttrs cfg.setupAutoOidc {
NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT =
"$NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT";
}
// (optionalAttrs cfg.setupAutoOidc {
NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT = "$NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT";
NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT = "$NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT";
NETBIRD_AUTH_TOKEN_ENDPOINT = "$NETBIRD_AUTH_TOKEN_ENDPOINT";
NETBIRD_AUTH_JWT_CERTS = "$NETBIRD_AUTH_JWT_CERTS";
NETBIRD_AUTH_AUTHORITY = "$NETBIRD_AUTH_AUTHORITY";
}) // cfg.settings;
in {
meta = { maintainers = with maintainers; [ thubrecht ]; };
})
// cfg.settings;
in
{
meta = {
maintainers = with maintainers; [ thubrecht ];
};
options.services.netbird-server = {
enable = mkEnableOption (lib.mdDoc "netbird management service.");
@ -111,8 +135,19 @@ in {
};
settings = mkOption {
type = with types;
attrsOf (nullOr (oneOf [ (listOf str) bool int float str ]));
type =
with types;
attrsOf (
nullOr (
oneOf [
(listOf str)
bool
int
float
str
]
)
);
defaultText = lib.literalExpression ''
{
TURN_DOMAIN = cfg.settings.NETBIRD_DOMAIN;
@ -195,13 +230,17 @@ in {
};
logLevel = mkOption {
type = types.enum [ "ERROR" "WARN" "INFO" "DEBUG" ];
type = types.enum [
"ERROR"
"WARN"
"INFO"
"DEBUG"
];
default = "INFO";
description = lib.mdDoc "Log level of the netbird services.";
};
enableDeviceAuthorizationFlow =
mkEnableOption "device authorization flow for netbird." // {
enableDeviceAuthorizationFlow = mkEnableOption "device authorization flow for netbird." // {
default = true;
};
@ -232,8 +271,7 @@ in {
disableAnonymousMetrics = mkOption {
type = types.bool;
default = true;
description =
lib.mdDoc "Disables push of anonymous usage metrics to NetBird.";
description = lib.mdDoc "Disables push of anonymous usage metrics to NetBird.";
};
disableSingleAccountMode = mkOption {
@ -250,38 +288,32 @@ in {
TURN_PASSWORD = mkOption {
type = with types; nullOr path;
default = null;
description =
lib.mdDoc "Path to a file containing the secret TURN_PASSWORD.";
description = lib.mdDoc "Path to a file containing the secret TURN_PASSWORD.";
};
TURN_SECRET = mkOption {
type = with types; nullOr path;
default = null;
description =
lib.mdDoc "Path to a file containing the secret TURN_SECRET.";
description = lib.mdDoc "Path to a file containing the secret TURN_SECRET.";
};
STUN_PASSWORD = mkOption {
type = with types; nullOr path;
default = null;
description =
lib.mdDoc "Path to a file containing the secret STUN_PASSWORD.";
description = lib.mdDoc "Path to a file containing the secret STUN_PASSWORD.";
};
AUTH_CLIENT_SECRET = mkOption {
type = with types; nullOr path;
default = null;
description = lib.mdDoc
"Path to a file containing the secret NETBIRD_AUTH_CLIENT_SECRET.";
description = lib.mdDoc "Path to a file containing the secret NETBIRD_AUTH_CLIENT_SECRET.";
};
IDP_MGMT_CLIENT_SECRET = mkOption {
type = with types; nullOr path;
default = cfg.secretFiles.AUTH_CLIENT_SECRET;
defaultText =
lib.literalExpression "cfg.secretFiles.AUTH_CLIENT_SECRET;";
description = lib.mdDoc
"Path to a file containing the secret NETBIRD_IDP_MGMT_CLIENT_SECRET.";
defaultText = lib.literalExpression "cfg.secretFiles.AUTH_CLIENT_SECRET;";
description = lib.mdDoc "Path to a file containing the secret NETBIRD_IDP_MGMT_CLIENT_SECRET.";
};
};
};
@ -289,19 +321,23 @@ in {
config = mkMerge [
(mkIf cfg.enable {
services.netbird-server.managementConfig = with settings; {
Stuns = mkDefault [{
Stuns = mkDefault [
{
Proto = "udp";
URI = "stun:${TURN_DOMAIN}:${builtins.toString TURN_PORT}";
Username = STUN_USERNAME;
Password = STUN_PASSWORD;
}];
}
];
TURNConfig = {
Turns = [{
Turns = [
{
Proto = "udp";
URI = "turn:${TURN_DOMAIN}:${builtins.toString TURN_PORT}";
Username = TURN_USER;
Password = TURN_PASSWORD;
}];
}
];
CredentialsTTL = "12h";
Secret = TURN_SECRET;
TimeBasedCredentials = false;
@ -340,8 +376,7 @@ in {
ClientID = NETBIRD_AUTH_DEVICE_AUTH_CLIENT_ID;
TokenEndpoint = NETBIRD_AUTH_TOKEN_ENDPOINT;
DeviceAuthEndpoint = NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT;
Scope =
builtins.concatStringsSep " " NETBIRD_AUTH_DEVICE_AUTH_SCOPE;
Scope = builtins.concatStringsSep " " NETBIRD_AUTH_DEVICE_AUTH_SCOPE;
UseIDToken = NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN;
};
};
@ -377,13 +412,10 @@ in {
grpc_socket_keepalive on;
'';
"/api".proxyPass =
"http://localhost:${builtins.toString cfg.ports.management}";
"/api".proxyPass = "http://localhost:${builtins.toString cfg.ports.management}";
"/management.ManagementService/".extraConfig = ''
grpc_pass grpc://localhost:${
builtins.toString cfg.ports.management
};
grpc_pass grpc://localhost:${builtins.toString cfg.ports.management};
grpc_read_timeout 1d;
grpc_send_timeout 1d;
grpc_socket_keepalive on;
@ -411,12 +443,26 @@ in {
StartLimitBurst = 10;
};
path = (with pkgs; [ coreutils findutils gettext gnused ])
++ (optionals cfg.setupAutoOidc (with pkgs; [ curl jq ]));
path =
(with pkgs; [
coreutils
findutils
gettext
gnused
])
++ (optionals cfg.setupAutoOidc (
with pkgs;
[
curl
jq
]
));
script = ''
script =
''
cp ${managementFile} ${stateDir}/management.json.copy
'' + (optionalString cfg.setupAutoOidc ''
''
+ (optionalString cfg.setupAutoOidc ''
mv ${stateDir}/management.json.copy ${stateDir}/management.json
echo "loading OpenID configuration from $NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT to the openid-configuration.json file"
curl "$NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT" -q -o ${stateDir}/openid-configuration.json
@ -428,11 +474,16 @@ in {
export NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT=$(jq -r '.authorization_endpoint' ${stateDir}/openid-configuration.json)
envsubst '$NETBIRD_AUTH_AUTHORITY $NETBIRD_AUTH_JWT_CERTS $NETBIRD_AUTH_TOKEN_ENDPOINT $NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT $NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT' < ${stateDir}/management.json > ${stateDir}/management.json.copy
'') + ''
'')
+ ''
# Update secrets in management.json
${builtins.concatStringsSep "\n" (builtins.attrValues
(builtins.mapAttrs (name: path: "export ${name}=$(cat ${path})")
(filterAttrs (_: p: p != null) cfg.secretFiles)))}
${builtins.concatStringsSep "\n" (
builtins.attrValues (
builtins.mapAttrs (name: path: "export ${name}=$(cat ${path})") (
filterAttrs (_: p: p != null) cfg.secretFiles
)
)
)}
envsubst '$TURN_PASSWORD $TURN_SECRET $STUN_PASSWORD $AUTH_CLIENT_SECRET $IDP_MGMT_CLIENT_SECRET' < ${stateDir}/management.json.copy > ${stateDir}/management.json
@ -463,7 +514,10 @@ in {
netbird-signal = {
after = [ "network.target" ];
wantedBy = [ "netbird-management.service" ];
restartTriggers = [ settingsFile managementFile ];
restartTriggers = [
settingsFile
managementFile
];
serviceConfig = {
ExecStart = ''
@ -487,24 +541,27 @@ in {
netbird-management = {
description = "The management server for Netbird, a wireguard VPN";
documentation = [ "https://netbird.io/docs/" ];
after = [ "network.target" "netbird-setup.service" ];
after = [
"network.target"
"netbird-setup.service"
];
wantedBy = [ "multi-user.target" ];
wants = [ "netbird-signal.service" "netbird-setup.service" ];
restartTriggers = [ settingsFile managementFile ];
wants = [
"netbird-signal.service"
"netbird-setup.service"
];
restartTriggers = [
settingsFile
managementFile
];
serviceConfig = {
ExecStart = ''
${cfg.package}/bin/netbird-mgmt management \
--config ${stateDir}/management.json \
--datadir ${stateDir}/data \
${
optionalString cfg.management.disableAnonymousMetrics
"--disable-anonymous-metrics"
} \
${
optionalString cfg.management.disableSingleAccountMode
"--disable-single-account-mode"
} \
${optionalString cfg.management.disableAnonymousMetrics "--disable-anonymous-metrics"} \
${optionalString cfg.management.disableSingleAccountMode "--disable-single-account-mode"} \
--dns-domain ${cfg.management.dnsDomain} \
--single-account-mode-domain ${cfg.management.singleAccountModeDomain} \
--idp-sign-key-refresh-enabled \
@ -514,7 +571,10 @@ in {
'';
Restart = "always";
RuntimeDirectory = "netbird-mgmt";
StateDirectory = [ "netbird-mgmt" "netbird-mgmt/data" ];
StateDirectory = [
"netbird-mgmt"
"netbird-mgmt/data"
];
WorkingDirectory = stateDir;
};
unitConfig = {
@ -549,18 +609,25 @@ in {
5349
5350
];
allowedTCPPorts = with settings; [ TURN_PORT (TURN_PORT + 1) ];
allowedUDPPortRanges = [{
allowedTCPPorts = with settings; [
TURN_PORT
(TURN_PORT + 1)
];
allowedUDPPortRanges = [
{
from = settings.TURN_MIN_PORT;
to = settings.TURN_MAX_PORT;
}];
}
];
};
})
(mkIf (cfg.enableNginx && cfg.enableCoturn) {
services.coturn =
let cert = config.security.acme.certs.${settings.TURN_DOMAIN};
in {
let
cert = config.security.acme.certs.${settings.TURN_DOMAIN};
in
{
cert = "${cert.directory}/fullchain.pem";
pkey = "${cert.directory}/key.pem";
};
@ -570,8 +637,7 @@ in {
# share certs with coturn and restart on renewal
security.acme.certs.${settings.TURN_DOMAIN} = {
group = "turnserver";
postRun =
"systemctl reload nginx.service; systemctl restart coturn.service";
postRun = "systemctl reload nginx.service; systemctl restart coturn.service";
};
})
];

View file

@ -1,4 +1,8 @@
{ lib, buildNpmPackage, fetchFromGitHub }:
{
lib,
buildNpmPackage,
fetchFromGitHub,
}:
buildNpmPackage rec {
pname = "netbird-dashboard";

View file

@ -1,4 +1,6 @@
{ pkgs ? import <nixpkgs> {} }:
{
pkgs ? import <nixpkgs> { },
}:
{
dashboard = pkgs.callPackage ./dashboard.nix { };

View file

@ -1,7 +1,9 @@
{ config, ... }:
let host = "videos.dgnum.eu";
in {
let
host = "videos.dgnum.eu";
in
{
services.peertube = {
enable = true;
@ -53,8 +55,7 @@ in {
database.createLocally = true;
smtp.passwordFile = config.age.secrets."peertube-smtp_password_file".path;
serviceEnvironmentFile =
config.age.secrets."peertube-service_environment_file".path;
serviceEnvironmentFile = config.age.secrets."peertube-service_environment_file".path;
secrets.secretsFile = config.age.secrets."peertube-secrets_file".path;
};
@ -63,5 +64,7 @@ in {
forceSSL = true;
};
age-secrets.matches."^peertube-.*$" = { owner = "peertube"; };
age-secrets.matches."^peertube-.*$" = {
owner = "peertube";
};
}

View file

@ -1,8 +1,8 @@
let
lib = import ../../../lib { };
publicKeys = lib.getNodeKeys "storage01";
in lib.setDefault { inherit publicKeys; } [
in
lib.setDefault { inherit publicKeys; } [
"atticd-credentials_file"
"forgejo-database_password_file"
"forgejo_runners-token_file"

View file

@ -11,8 +11,10 @@ lib.extra.mkConfig {
];
extraConfig = {
dgn-fail2ban.jails =
lib.extra.enableAttrs' "enabled" [ "sshd-bruteforce" "sshd-timeout" ];
dgn-fail2ban.jails = lib.extra.enableAttrs' "enabled" [
"sshd-bruteforce"
"sshd-timeout"
];
services.netbird.enable = true;

View file

@ -8,8 +8,14 @@
boot = {
initrd = {
availableKernelModules =
[ "xhci_pci" "megaraid_sas" "ehci_pci" "ahci" "usb_storage" "sd_mod" ];
availableKernelModules = [
"xhci_pci"
"megaraid_sas"
"ehci_pci"
"ahci"
"usb_storage"
"sd_mod"
];
kernelModules = [ ];
};
@ -30,6 +36,5 @@
};
};
swapDevices =
[{ device = "/dev/disk/by-uuid/954ecb9c-ccd1-4e98-9eb6-3514bd3c01d1"; }];
swapDevices = [ { device = "/dev/disk/by-uuid/954ecb9c-ccd1-4e98-9eb6-3514bd3c01d1"; } ];
}

View file

@ -1,6 +1,5 @@
let
lib = import ../../../lib { };
publicKeys = lib.getNodeKeys "vault01";
in lib.setDefault { inherit publicKeys; } [
]
in
lib.setDefault { inherit publicKeys; } [ ]

View file

@ -6,7 +6,12 @@
{
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
(let sources = import ../../npins; in sources.disko + "/module.nix")
(
let
sources = import ../../npins;
in
sources.disko + "/module.nix"
)
./disko.nix
];
}

View file

@ -3,7 +3,7 @@ let
cfg = config.services.castopod;
fpm = config.services.phpfpm.pools.castopod;
in
{
{
services.nginx = {
resolver.addresses = [ "127.0.0.53" ];
virtualHosts."${cfg.localDomain}" = {
@ -16,7 +16,7 @@ in
'';
};
locations."~ \.php$" = {
locations."~ .php$" = {
extraConfig = lib.mkForce ''
error_page 550 = @force_get;
if ($request_method = HEAD) { return 550; }
@ -30,4 +30,4 @@ in
};
};
};
}
}

View file

@ -1,38 +1,41 @@
{ config, pkgs, ...}:
{ config, pkgs, ... }:
let
host = "podcasts.dgnum.eu";
in
{
imports = [
./castopod-head-proxy.nix
];
services.castopod = {
imports = [ ./castopod-head-proxy.nix ];
services = {
castopod = {
enable = true;
localDomain = host;
environmentFile = config.age.secrets.castopod-environment_file.path;
maxUploadSize = 512;
settings = {
"email.fromEmail"="noreply@infra.dgnum.eu";
"email.SMTPHost"="kurisu.lahfa.xyz";
"email.SMTPUser"="web-services@infra.dgnum.eu";
"email.SMTPPort"="587";
"email.fromEmail" = "noreply@infra.dgnum.eu";
"email.SMTPHost" = "kurisu.lahfa.xyz";
"email.SMTPUser" = "web-services@infra.dgnum.eu";
"email.SMTPPort" = "587";
"media.fileManager"="s3";
"media.s3.endpoint"="https://s3.dgnum.eu/";
"media.s3.region"="garage";
"media.s3.bucket"="castopod-dgnum";
"media.s3.pathStyleEndpoint"=true;
"media.fileManager" = "s3";
"media.s3.endpoint" = "https://s3.dgnum.eu/";
"media.s3.region" = "garage";
"media.s3.bucket" = "castopod-dgnum";
"media.s3.pathStyleEndpoint" = true;
"restapi.enabled"=true;
"restapi.basicAuthUsername"="castopod";
"restapi.basicAuth"=true;
"restapi.enabled" = true;
"restapi.basicAuthUsername" = "castopod";
"restapi.basicAuth" = true;
};
database.createLocally = true;
configureNginx = true;
};
services.mysql.package = pkgs.mariadb;
services.nginx.virtualHosts.${host} = {
mysql.package = pkgs.mariadb;
nginx.virtualHosts.${host} = {
forceSSL = true;
enableACME = true;
};
};
}

View file

@ -56,7 +56,10 @@ in
mountpoint = "/var/log";
};
"/nix" = {
mountOptions = [ "noatime" "compress=zstd" ];
mountOptions = [
"noatime"
"compress=zstd"
];
mountpoint = "/nix";
};
};

View file

@ -1,5 +1,4 @@
{ ... }:
{
_: {
services.dolibarr = {
enable = true;
domain = "erp.dgnum.eu";

View file

@ -1,4 +1,9 @@
{ sources, pkgs, lib, ... }:
{
sources,
pkgs,
lib,
...
}:
let
host = "cal.dgnum.eu";
@ -26,7 +31,8 @@ let
calendars = metis2linkal sources.metis;
};
};
in {
in
{
imports = [ ./module.nix ];
dgn-linkal = {

View file

@ -7,18 +7,10 @@ let
inherit (import source { inherit pkgs; }) providers;
# helper function to map 2-level deep attribute-sets
mapDeepAttrs = mapFct:
lib.concatMapAttrs (name: value:
lib.mapAttrs' (name': value':
mapFct name name' value'
) value
);
toLinkal = upstream: identifier:
lib.nameValuePair
"${providers.${upstream}}${identifier}"
;
mapDeepAttrs =
mapFct:
lib.concatMapAttrs (name: value: lib.mapAttrs' (name': value': mapFct name name' value') value);
toLinkal = upstream: identifier: lib.nameValuePair "${providers.${upstream}}${identifier}";
in
mapDeepAttrs toLinkal calendars
mapDeepAttrs toLinkal calendars

View file

@ -1,14 +1,28 @@
{ config, lib, pkgs, sources, ... }:
{
config,
lib,
pkgs,
sources,
...
}:
let
inherit (lib) mapAttrs' mkEnableOption mkIf mkOption nameValuePair types;
inherit (lib)
mapAttrs'
mkEnableOption
mkIf
mkOption
nameValuePair
types
;
package = import sources.linkal { inherit pkgs; };
cfg = config.dgn-linkal;
jsonFormat = pkgs.formats.json { };
in {
in
{
options.dgn-linkal = {
enable = mkEnableOption "the linkal server.";
@ -20,32 +34,40 @@ in {
domain = mkOption { type = types.str; };
calendarGroups = mkOption {
type = let inherit (types) attrsOf port submodule;
in attrsOf (submodule {
type =
let
inherit (types) attrsOf port submodule;
in
attrsOf (
submodule {
options = {
port = mkOption { type = port; };
calendars = mkOption { inherit (jsonFormat) type; };
};
});
}
);
default = { };
};
};
config = mkIf cfg.enable {
systemd.services = mapAttrs' (name:
systemd.services =
mapAttrs'
(
name:
{ port, calendars }:
nameValuePair "linkal-${name}" {
description = "Linkal - ${name}";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "simple";
ExecStart = "${cfg.package}/bin/linkal --port ${
builtins.toString port
} --calendar-file ${
ExecStart = "${cfg.package}/bin/linkal --port ${builtins.toString port} --calendar-file ${
jsonFormat.generate "linkal-${name}.json" { inherit calendars; }
}";
};
}) cfg.calendarGroups;
}
)
cfg.calendarGroups;
# Configure bind for DNS certificate validation on *.cal.dgnum.eu.
# services.bind = {
@ -85,16 +107,20 @@ in {
services.nginx = {
enable = true;
virtualHosts = mapAttrs' (name:
virtualHosts =
mapAttrs'
(
name:
{ port, ... }:
nameValuePair "${name}.${cfg.domain}" {
enableACME = true;
# acmeRoot = null; # Use DNS-01 validation
forceSSL = true;
locations."/".proxyPass =
"http://127.0.0.1:${builtins.toString port}/";
}) cfg.calendarGroups;
locations."/".proxyPass = "http://127.0.0.1:${builtins.toString port}/";
}
)
cfg.calendarGroups;
};
};
}

View file

@ -6,5 +6,7 @@
configPath = config.age.secrets."matterbridge-config_file".path;
};
age-secrets.matches."^matterbridge-.*$" = { owner = "matterbridge"; };
age-secrets.matches."^matterbridge-.*$" = {
owner = "matterbridge";
};
}

View file

@ -1,16 +1,25 @@
{ lib, pkgs, sources, ... }:
{
lib,
pkgs,
sources,
...
}:
let
metis = import sources.metis { inherit pkgs; };
inherit (metis) providers;
in {
in
{
services.nginx.virtualHosts."calendrier.dgnum.eu" = {
enableACME = true;
forceSSL = true;
root = metis.production;
locations = lib.mapAttrs' (name: value:
locations =
lib.mapAttrs'
(
name: value:
lib.nameValuePair "/cal/${name}/" {
extraConfig = ''
proxy_set_header X-Forwarded-Host $host;
@ -18,7 +27,9 @@ in {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass ${value};
'';
}) providers;
}
)
providers;
extraConfig = ''
rewrite ^/calendrier(.*)$ $1 permanent;

View file

@ -1,8 +1,9 @@
{ config, ... }:
let host = "push.dgnum.eu";
in {
let
host = "push.dgnum.eu";
in
{
services.ntfy-sh = {
enable = true;
@ -26,6 +27,7 @@ in {
};
};
systemd.services.ntfy-sh.serviceConfig.EnvironmentFile =
[ config.age.secrets."ntfy_sh-environment_file".path ];
systemd.services.ntfy-sh.serviceConfig.EnvironmentFile = [
config.age.secrets."ntfy_sh-environment_file".path
];
}

View file

@ -3,15 +3,19 @@ _:
let
retired_host = "retired.dgnum.eu";
mkRetired = hosts:
builtins.listToAttrs (builtins.map (name: {
mkRetired =
hosts:
builtins.listToAttrs (
builtins.map
(name: {
inherit name;
value.to = retired_host;
}) hosts);
})
hosts
);
mkSub = domain: builtins.map (s: "${s}.${domain}");
mkSubs = attrs:
builtins.concatLists (builtins.attrValues (builtins.mapAttrs mkSub attrs));
mkSubs = attrs: builtins.concatLists (builtins.attrValues (builtins.mapAttrs mkSub attrs));
redirections = {
"calendrier.eleves.ens.fr".to = "calendrier.dgnum.eu";
@ -23,9 +27,15 @@ let
} // (mkRetired retired);
retired = mkSubs {
"ens.fr" = [ "alevins" "www.climatenavigator" ];
"ens.fr" = [
"alevins"
"www.climatenavigator"
];
"ens.wtf" = [ "photos" ];
"rz.ens.wtf" = [ "s3" "cdn" ];
"rz.ens.wtf" = [
"s3"
"cdn"
];
"beta.rz.ens.wtf" = [
"todo"
"minecraft"
@ -39,14 +49,25 @@ let
"rstudio"
];
};
in {
services.nginx.virtualHosts = {
in
{
services.nginx.virtualHosts =
{
${retired_host}.default = true;
} // (builtins.mapAttrs (host:
{ to, ssl ? true }: {
}
// (builtins.mapAttrs
(
_:
{
to,
ssl ? true,
}:
{
globalRedirect = to;
enableACME = ssl;
forceSSL = ssl;
}) redirections);
}
)
redirections
);
}

View file

@ -1,7 +1,8 @@
let
lib = import ../../../lib { };
publicKeys = lib.getNodeKeys "web01";
in lib.setDefault { inherit publicKeys; } [
in
lib.setDefault { inherit publicKeys; } [
"acme-certs_secret"
"matterbridge-config_file"
"named-bind_dnskeys_conf"

View file

@ -1,20 +1,34 @@
# Generated by npins. Do not modify; will be overwritten regularly
let
data = builtins.fromJSON (builtins.readFile ./sources.json);
version = data.version;
inherit (data) version;
mkSource = spec:
assert spec ? type; let
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}";
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, ... }:
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
@ -23,19 +37,23 @@ let
inherit url;
sha256 = hash; # FIXME: check nix version & use SRI hashes
})
else assert repository.type == "Git"; builtins.fetchGit {
url = repository.url;
else
assert repository.type == "Git";
builtins.fetchGit {
inherit (repository) url;
rev = revision;
# hash = hash;
};
mkPyPiSource = { url, hash, ... }:
mkPyPiSource =
{ url, hash, ... }:
builtins.fetchurl {
inherit url;
sha256 = hash;
};
mkChannelSource = { url, hash, ... }:
mkChannelSource =
{ url, hash, ... }:
builtins.fetchTarball {
inherit url;
sha256 = hash;

View file

@ -1,7 +1,9 @@
{ pkgs, sources, ... }:
let wp4nix = pkgs.callPackage sources.wp4nix { };
in {
let
wp4nix = pkgs.callPackage sources.wp4nix { };
in
{
imports = [ ./module.nix ];
services.wp-containers = {
@ -9,26 +11,38 @@ in {
sites = {
"lavoixduntexte.normalesup.eu" = {
themes = { inherit (wp4nix.themes) avant; };
themes = {
inherit (wp4nix.themes) avant;
};
plugins = { inherit (wp4nix.plugins) wordpress-importer; };
plugins = {
inherit (wp4nix.plugins) wordpress-importer;
};
languages = [ pkgs.wordpressPackages.languages.fr_FR ];
};
"bds.wp.dgnum.eu" = {
plugins = { inherit (wp4nix.plugins) user-role-editor; };
plugins = {
inherit (wp4nix.plugins) user-role-editor;
};
languages = [ pkgs.wordpressPackages.languages.fr_FR ];
themes = { inherit (wp4nix.themes) gateway twentytwentythree; };
themes = {
inherit (wp4nix.themes) gateway twentytwentythree;
};
};
"bda.wp.dgnum.eu" = {
plugins = { inherit (wp4nix.plugins) user-role-editor; };
plugins = {
inherit (wp4nix.plugins) user-role-editor;
};
languages = [ pkgs.wordpressPackages.languages.fr_FR ];
};
"cineclub.wp.dgnum.eu" = {
plugins = { inherit (wp4nix.plugins) user-role-editor; };
plugins = {
inherit (wp4nix.plugins) user-role-editor;
};
languages = [ pkgs.wordpressPackages.languages.fr_FR ];
};
};

View file

@ -1,4 +1,9 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
inherit (lib) mkEnableOption mkIf mkOption;
@ -13,7 +18,13 @@ let
mkHost = mkIp "10.31.41";
mkLocal = mkIp "10.0.0";
mkConfig = { name, value, i }: {
mkConfig =
{
name,
value,
i,
}:
{
services.wordpress = {
webserver = "nginx";
sites.${name} = value;
@ -33,7 +44,10 @@ let
firewall.allowedTCPPorts = [ 443 ];
};
environment.systemPackages = [ pkgs.wp-cli pkgs.neovim ];
environment.systemPackages = [
pkgs.wp-cli
pkgs.neovim
];
system.stateVersion = "23.11";
};
@ -44,10 +58,12 @@ let
value = {
privateNetwork = true;
forwardPorts = [{
forwardPorts = [
{
containerPort = 443;
hostPort = cfg.basePort + i;
}];
}
];
bindMounts.certs = {
hostPath = certs.${site.name}.directory;
@ -69,13 +85,13 @@ let
enableACME = true;
forceSSL = true;
locations."/".proxyPass =
"https://${mkHost i}:${builtins.toString (cfg.basePort + i)}";
locations."/".proxyPass = "https://${mkHost i}:${builtins.toString (cfg.basePort + i)}";
};
};
siteList = lib.attrsToList cfg.sites;
in {
in
{
options.services.wp-containers = {
enable = mkEnableOption "wordpress sites in containers";
@ -93,7 +109,6 @@ in {
config = mkIf cfg.enable {
containers = builtins.listToAttrs (lib.imap1 mkContainer siteList);
services.nginx.virtualHosts =
builtins.listToAttrs (lib.imap1 mkVhost siteList);
services.nginx.virtualHosts = builtins.listToAttrs (lib.imap1 mkVhost siteList);
};
}

View file

@ -11,8 +11,10 @@ lib.extra.mkConfig {
];
extraConfig = {
dgn-fail2ban.jails =
lib.extra.enableAttrs' "enabled" [ "sshd-bruteforce" "sshd-timeout" ];
dgn-fail2ban.jails = lib.extra.enableAttrs' "enabled" [
"sshd-bruteforce"
"sshd-timeout"
];
services.netbird.enable = true;
};

View file

@ -8,8 +8,14 @@
boot = {
initrd = {
availableKernelModules =
[ "ata_piix" "uhci_hcd" "ehci_pci" "virtio_pci" "sr_mod" "virtio_blk" ];
availableKernelModules = [
"ata_piix"
"uhci_hcd"
"ehci_pci"
"virtio_pci"
"sr_mod"
"virtio_blk"
];
kernelModules = [ ];
};
@ -30,6 +36,5 @@
};
};
swapDevices =
[{ device = "/dev/disk/by-uuid/d64ae21e-693c-4c77-b62c-97d5e2a960cb"; }];
swapDevices = [ { device = "/dev/disk/by-uuid/d64ae21e-693c-4c77-b62c-97d5e2a960cb"; } ];
}

View file

@ -1,6 +1,5 @@
let
lib = import ../../../lib { };
publicKeys = lib.getNodeKeys "web02";
in lib.setDefault { inherit publicKeys; } [
]
in
lib.setDefault { inherit publicKeys; } [ ]

View file

@ -8,9 +8,7 @@
];
# Jourdan
par02 = [
"vault01"
];
par02 = [ "vault01" ];
# VMs du SPI/NPS/Whatever
dmi01 = [

View file

@ -26,15 +26,25 @@ let
groups = {
# members of this group are root on all nodes
root = [ "thubrecht" "raito" "mdebray" ];
root = [
"thubrecht"
"raito"
"mdebray"
];
# members of this group will have root access on the installation isos
iso = [ "thubrecht" "mdebray" "raito" ];
iso = [
"thubrecht"
"mdebray"
"raito"
];
# members of this group can access netbox's secret
netbox = [];
netbox = [ ];
bureau = [ "gdd" ];
};
in { inherit groups members; }
in
{
inherit groups members;
}

View file

@ -1,27 +1,47 @@
let
mkDefaultInterface = _: attrs: { ipv4 = [ ]; ipv6 = [ ]; gateways = [ ]; } // attrs;
mkDefaultInterface =
_: attrs:
{
ipv4 = [ ];
ipv6 = [ ];
gateways = [ ];
}
// attrs;
mkBase = config: config // { interfaces = builtins.mapAttrs mkDefaultInterface (config.interfaces or { }); };
mkBase =
config: config // { interfaces = builtins.mapAttrs mkDefaultInterface (config.interfaces or { }); };
getAddresses = version: interface: builtins.map (builtins.getAttr "address") interface.${version};
filterIPv4 = ip: builtins.substring 0 7 ip != "192.168";
filterIPv6 = _: true;
mkNet = _: value:
let base = mkBase value; in
base // {
mkNet =
_: value:
let
base = mkBase value;
in
base
// {
addresses =
let
_addresses = builtins.foldl'
({ ipv4, ipv6 }: net: {
_addresses =
builtins.foldl'
(
{ ipv4, ipv6 }:
net: {
ipv4 = ipv4 ++ getAddresses "ipv4" net;
ipv6 = ipv6 ++ getAddresses "ipv6" net;
})
{ ipv4 = [ ]; ipv6 = [ ]; }
}
)
{
ipv4 = [ ];
ipv6 = [ ];
}
(builtins.attrValues base.interfaces);
in
_addresses // rec {
_addresses
// rec {
publicV4 = builtins.filter filterIPv4 _addresses.ipv4;
publicV6 = builtins.filter filterIPv6 _addresses.ipv6;
public = publicV4 ++ publicV6;
@ -34,8 +54,14 @@ builtins.mapAttrs mkNet {
interfaces = {
eno1 = {
ipv4 = [
{ address = "129.199.146.147"; prefixLength = 24; }
{ address = "192.168.1.147"; prefixLength = 24; }
{
address = "129.199.146.147";
prefixLength = 24;
}
{
address = "192.168.1.147";
prefixLength = 24;
}
];
gateways = [ "129.199.146.254" ];
@ -49,8 +75,14 @@ builtins.mapAttrs mkNet {
interfaces = {
eno1 = {
ipv4 = [
{ address = "129.199.146.148"; prefixLength = 24; }
{ address = "192.168.1.148"; prefixLength = 24; }
{
address = "129.199.146.148";
prefixLength = 24;
}
{
address = "192.168.1.148";
prefixLength = 24;
}
];
gateways = [ "129.199.146.254" ];
@ -64,7 +96,10 @@ builtins.mapAttrs mkNet {
interfaces = {
enp130s0f0 = {
ipv4 = [
{ address = "129.199.210.85"; prefixLength = 24; }
{
address = "129.199.210.85";
prefixLength = 24;
}
];
gateways = [ "129.199.210.254" ];
@ -77,7 +112,12 @@ builtins.mapAttrs mkNet {
web01 = {
interfaces = {
ens3 = {
ipv4 = [{ address = "129.199.129.53"; prefixLength = 24; }];
ipv4 = [
{
address = "129.199.129.53";
prefixLength = 24;
}
];
gateways = [ "129.199.129.1" ];
};
@ -89,7 +129,12 @@ builtins.mapAttrs mkNet {
web02 = {
interfaces = {
ens3 = {
ipv4 = [{ address = "129.199.129.235"; prefixLength = 24; }];
ipv4 = [
{
address = "129.199.129.235";
prefixLength = 24;
}
];
gateways = [ "129.199.129.1" ];
};

View file

@ -11,14 +11,17 @@
# }
let
mkNode = _: attrs: {
mkNode =
_: attrs:
{
adminGroups = [ ];
admins = [ ];
deployment = { };
nixpkgs = "23.11";
} // attrs;
}
// attrs;
in
builtins.mapAttrs mkNode {

View file

@ -35,7 +35,8 @@
{ lib, sources, ... }:
{
imports = (lib.extra.mkImports ./. [
imports =
(lib.extra.mkImports ./. [
"dgn-access-control"
"dgn-acme"
"dgn-console"
@ -45,10 +46,12 @@
"dgn-ssh"
"dgn-web"
"dgn-vm-variant"
]) ++ [
])
++ [
"${sources.agenix}/modules/age.nix"
"${sources.attic}/nixos/atticd.nix"
] ++ ((import sources.nix-modules { inherit lib; }).importModules [
]
++ ((import sources.nix-modules { inherit lib; }).importModules [
"age-secrets"
"services/crabfit"
"services/forgejo-nix-runners"

View file

@ -31,7 +31,13 @@
# pris connaissance de la licence CeCILL, et que vous en avez accepté les
# termes.
{ config, lib, meta, name, ... }:
{
config,
lib,
meta,
name,
...
}:
let
inherit (lib)
@ -40,10 +46,13 @@ let
mkIf
mkOption
types;
types
;
nodeMeta = meta.nodes.${name};
admins = meta.members.groups.root ++ nodeMeta.admins
admins =
meta.members.groups.root
++ nodeMeta.admins
++ (builtins.concatMap (g: meta.members.groups.${g}) nodeMeta.adminGroups);
cfg = config.dgn-access-control;
@ -51,7 +60,9 @@ in
{
options.dgn-access-control = {
enable = mkEnableOption "DGNum access control." // { default = true; };
enable = mkEnableOption "DGNum access control." // {
default = true;
};
users = mkOption {
type = with types; attrsOf (listOf str);
@ -72,8 +83,8 @@ in
# Admins have root access to the node
dgn-access-control.users.root = mkDefault admins;
users.users = builtins.mapAttrs
(u: members: { openssh.authorizedKeys.keys = lib.extra.getAllKeys members; })
users.users =
builtins.mapAttrs (_: members: { openssh.authorizedKeys.keys = lib.extra.getAllKeys members; })
cfg.users;
};
}

View file

@ -34,15 +34,15 @@
{ config, lib, ... }:
let
inherit (lib)
mkEnableOption
mkIf;
inherit (lib) mkEnableOption mkIf;
cfg = config.dgn-acme;
in
{
options.dgn-acme.enable = mkEnableOption "ACME settings." // { default = true; };
options.dgn-acme.enable = mkEnableOption "ACME settings." // {
default = true;
};
config = mkIf cfg.enable {
security.acme = {

View file

@ -1,13 +1,20 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
inherit (lib) mkEnableOption mkOption mkIf;
cfg = config.dgn-console;
in {
in
{
options.dgn-console = {
enable = mkEnableOption "DGNum console setup." // { default = true; };
enable = mkEnableOption "DGNum console setup." // {
default = true;
};
pg-upgrade-to = mkOption {
type = lib.types.package;
@ -18,7 +25,9 @@ in {
config = mkIf cfg.enable {
time.timeZone = "Europe/Paris";
console = { keyMap = "fr"; };
console = {
keyMap = "fr";
};
environment.variables.EDITOR = "nvim";
@ -26,7 +35,7 @@ in {
# services.nscd.enableNsncd = false;
nixpkgs.overlays = [
(final: prev: {
(_: _: {
nsncd = pkgs.rustPlatform.buildRustPackage {
pname = "nsncd";
version = "unstable-2023-10-26";
@ -70,10 +79,16 @@ in {
hardware.enableRedistributableFirmware = true;
environment.systemPackages = (with pkgs; [ neovim wget kitty.terminfo ])
++ lib.optional (config.services.postgresql.enable
&& config.services.postgresql.package != cfg.pg-upgrade-to)
(pkgs.writeScriptBin "upgrade-pg-cluster" ''
environment.systemPackages =
(with pkgs; [
neovim
wget
kitty.terminfo
])
++ lib.optional
(config.services.postgresql.enable && config.services.postgresql.package != cfg.pg-upgrade-to)
(
pkgs.writeScriptBin "upgrade-pg-cluster" ''
set -eux
# XXX it's perhaps advisable to stop all services that depend on postgresql
systemctl stop postgresql
@ -93,6 +108,7 @@ in {
--old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \
--old-bindir $OLDBIN --new-bindir $NEWBIN \
"$@"
'');
''
);
};
}

View file

@ -1,10 +1,19 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
mkDefault mkEnableOption mkIf mkOption
mkDefault
mkEnableOption
mkIf
mkOption
types;
types
;
cfg = config.dgn-fail2ban;
@ -22,8 +31,7 @@ let
};
filter = mkOption {
type =
types.nullOr (types.submodule { freeformType = configFormat.type; });
type = types.nullOr (types.submodule { freeformType = configFormat.type; });
description = "Content of the filter used for this jail.";
};
@ -36,8 +44,8 @@ let
};
};
};
in {
in
{
options.dgn-fail2ban = {
enable = mkEnableOption "fail2ban service.";
@ -50,9 +58,9 @@ in {
};
config = mkIf cfg.enable {
dgn-fail2ban.jails =
builtins.mapAttrs (_: j: j // { enabled = mkDefault false; })
(import ./jails.nix { });
dgn-fail2ban.jails = builtins.mapAttrs (_: j: j // { enabled = mkDefault false; }) (
import ./jails.nix { }
);
services.fail2ban = {
enable = true;

View file

@ -33,8 +33,7 @@
_: {
nginx-spam = {
filter.Definition.failregex = ''
^<HOST>.*GET.*(matrix/server|\.php|admin|wp\-).* HTTP/\d.\d\" 404.*$'';
filter.Definition.failregex = ''^<HOST>.*GET.*(matrix/server|\.php|admin|wp\-).* HTTP/\d.\d\" 404.*$'';
settings = {
logpath = "/var/log/nginx/access.log";

View file

@ -1,11 +1,16 @@
{ config, lib, pkgs, ... }:
{
config,
lib,
pkgs,
...
}:
let
inherit (lib) mkEnableOption mkIf mkMerge;
cfg = config.dgn-hardware;
in {
in
{
options.dgn-hardware = {
enable = mkEnableOption "default hardware configuration." // {
default = true;
@ -19,7 +24,8 @@ in {
useBcachefs = mkEnableOption "bcachefs configuration";
};
config = mkIf cfg.enable (mkMerge [
config = mkIf cfg.enable (
mkMerge [
{
hardware.enableRedistributableFirmware = true;
hardware.cpu.intel.updateMicrocode = true;
@ -27,8 +33,14 @@ in {
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
boot = {
initrd.availableKernelModules =
[ "ata_piix" "uhci_hcd" "ehci_pci" "virtio_pci" "ahci" "virtio_blk" ];
initrd.availableKernelModules = [
"ata_piix"
"uhci_hcd"
"ehci_pci"
"virtio_pci"
"ahci"
"virtio_blk"
];
kernelModules = [ "kvm-intel" ];
kernelParams = [
"cgroup_enable=cpu"
@ -54,10 +66,14 @@ in {
zfs = {
forceImportRoot = false;
extraPools = [ "fast01" "work01" ];
extraPools = [
"fast01"
"work01"
];
package = pkgs.zfs_2_1;
};
};
})
]);
]
);
}

View file

@ -1,12 +1,22 @@
{ config, lib, meta, name, ... }:
{
config,
lib,
meta,
name,
...
}:
let
inherit (lib) mapAttrs' mkEnableOption mkIf optionalAttrs;
inherit (lib)
mapAttrs'
mkEnableOption
mkIf
optionalAttrs
;
net = meta.network.${name};
mkAddress = { address, prefixLength, ... }:
"${address}/${builtins.toString prefixLength}";
mkAddress = { address, prefixLength, ... }: "${address}/${builtins.toString prefixLength}";
mkRoute = gateway: {
routeConfig = {
Gateway = gateway;
@ -38,10 +48,9 @@ let
};
cfg = config.dgn-network;
in {
options.dgn-network.enable =
mkEnableOption "automatic network configuration based on metadata" // {
in
{
options.dgn-network.enable = mkEnableOption "automatic network configuration based on metadata" // {
default = true;
};

View file

@ -1,14 +1,14 @@
{ config, lib, ... }:
let
inherit (lib)
mkEnableOption
mkIf;
inherit (lib) mkEnableOption mkIf;
cfg = config.dgn-vmVariant;
in
{
options.dgn-vmVariant.enable = mkEnableOption "ACME settings." // { default = true; };
options.dgn-vmVariant.enable = mkEnableOption "ACME settings." // {
default = true;
};
config = mkIf cfg.enable {
virtualisation.vmVariant = {
@ -16,4 +16,3 @@ in
};
};
}

View file

@ -4,7 +4,8 @@ let
inherit (lib) mkEnableOption mkIf;
cfg = config.dgn-web;
in {
in
{
options.dgn-web = {
enable = mkEnableOption "sane defaults for web services.";
};
@ -21,6 +22,9 @@ in {
recommendedZstdSettings = true;
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
networking.firewall.allowedTCPPorts = [
80
443
];
};
}

View file

@ -1,20 +1,34 @@
# Generated by npins. Do not modify; will be overwritten regularly
let
data = builtins.fromJSON (builtins.readFile ./sources.json);
version = data.version;
inherit (data) version;
mkSource = spec:
assert spec ? type; let
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}";
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, ... }:
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
@ -23,19 +37,23 @@ let
inherit url;
sha256 = hash; # FIXME: check nix version & use SRI hashes
})
else assert repository.type == "Git"; builtins.fetchGit {
url = repository.url;
else
assert repository.type == "Git";
builtins.fetchGit {
inherit (repository) url;
rev = revision;
# hash = hash;
};
mkPyPiSource = { url, hash, ... }:
mkPyPiSource =
{ url, hash, ... }:
builtins.fetchurl {
inherit url;
sha256 = hash;
};
mkChannelSource = { url, hash, ... }:
mkChannelSource =
{ url, hash, ... }:
builtins.fetchTarball {
inherit url;
sha256 = hash;

View file

@ -118,6 +118,18 @@
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-24.05pre578430.5ad9903c1612/nixexprs.tar.xz",
"hash": "1zg01pxmaf56gqxdf59mj1aanlvkpw5b3gmsx4mawxi6m1f2l6c6"
},
"pre-commit-hooks": {
"type": "Git",
"repository": {
"type": "GitHub",
"owner": "cachix",
"repo": "pre-commit-hooks.nix"
},
"branch": "master",
"revision": "7c54e08a689b53c8a1e5d70169f2ec9e2a68ffaf",
"url": "https://github.com/cachix/pre-commit-hooks.nix/archive/7c54e08a689b53c8a1e5d70169f2ec9e2a68ffaf.tar.gz",
"hash": "0gj03fzsqcybzr4shj7x62l0xc34w20zhphd2jg7sd2rxaw42x23"
},
"wp4nix": {
"type": "Git",
"repository": {

View file

@ -8,10 +8,14 @@ let
coreutils
nvd
git
jq;
jq
;
};
mkShellScript = name: (pkgs.substituteAll ({
mkShellScript =
name:
(pkgs.substituteAll (
{
inherit name;
src = ./. + "/${name}.sh";
dir = "/bin/";
@ -20,7 +24,9 @@ let
checkPhase = ''
${pkgs.stdenv.shellDryRun} "$target"
'';
} // substitutions));
}
// substitutions
));
scripts = [
"check-deployment"

View file

@ -1,52 +1 @@
/*
Copyright :
- Maurice Debray <maurice.debray@dgnum.eu> 2023
- Tom Hubrecht <tom.hubrecht@dgnum.eu> 2023
Ce logiciel est un programme informatique servant à déployer des
configurations de serveurs via NixOS.
Ce logiciel est régi par la licence CeCILL soumise au droit français et
respectant les principes de diffusion des logiciels libres. Vous pouvez
utiliser, modifier et/ou redistribuer ce programme sous les conditions
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
sur le site "http://www.cecill.info".
En contrepartie de l'accessibilité au code source et des droits de copie,
de modification et de redistribution accordés par cette licence, il n'est
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
seule une responsabilité restreinte pèse sur l'auteur du programme, le
titulaire des droits patrimoniaux et les concédants successifs.
A cet égard l'attention de l'utilisateur est attirée sur les risques
associés au chargement, à l'utilisation, à la modification et/ou au
développement et à la reproduction du logiciel par l'utilisateur étant
donné sa spécificité de logiciel libre, qui peut le rendre complexe à
manipuler et qui le réserve donc à des développeurs et des professionnels
avertis possédant des connaissances informatiques approfondies. Les
utilisateurs sont donc invités à charger et tester l'adéquation du
logiciel à leurs besoins dans des conditions permettant d'assurer la
sécurité de leurs systèmes et ou de leurs données et, plus généralement,
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
pris connaissance de la licence CeCILL, et que vous en avez accepté les
termes.
*/
let
sources = import ./npins;
pkgs = import sources.nixpkgs { };
in
pkgs.mkShell {
packages = (with pkgs; [
npins
colmena
nixos-generators
] ++ (builtins.map (p: callPackage p { }) [
(sources.disko + "/package.nix")
])) ++ (import ./scripts { inherit pkgs; });
preferLocalBuild = true;
}
(import ./.).shells.default