Compare commits

..

3 commits

Author SHA1 Message Date
cb02eba0a2 feat: enable liminix-rebuild
All checks were successful
lint / check (push) Successful in 26s
build configuration / build_vault01 (pull_request) Successful in 1m5s
build configuration / build_storage01 (pull_request) Successful in 1m9s
build configuration / build_compute01 (pull_request) Successful in 1m12s
build configuration / build_web02 (pull_request) Successful in 54s
build configuration / build_web01 (pull_request) Successful in 1m32s
build configuration / build_rescue01 (pull_request) Successful in 51s
Signed-off-by: Ryan Lahfa <ryan@dgnum.eu>
2024-03-06 21:50:45 +01:00
3aafc9d272 feat: add liminix-rebuild in the shell
All checks were successful
lint / check (push) Successful in 27s
build configuration / build_vault01 (pull_request) Successful in 1m8s
build configuration / build_storage01 (pull_request) Successful in 1m13s
build configuration / build_compute01 (pull_request) Successful in 1m19s
build configuration / build_web02 (pull_request) Successful in 52s
build configuration / build_web01 (pull_request) Successful in 1m31s
build configuration / build_rescue01 (pull_request) Successful in 51s
Signed-off-by: Ryan Lahfa <ryan@dgnum.eu>
2024-03-06 21:28:27 +01:00
a5616579dd feat: init Liminix evaluation system
All checks were successful
lint / check (push) Successful in 23s
build configuration / build_rescue01 (pull_request) Successful in 1m6s
build configuration / build_vault01 (pull_request) Successful in 1m8s
build configuration / build_web02 (pull_request) Successful in 1m8s
build configuration / build_storage01 (pull_request) Successful in 1m10s
build configuration / build_compute01 (pull_request) Successful in 1m12s
build configuration / build_web01 (pull_request) Successful in 1m33s
Very rudimentary; undocumented, untested in production. This is for testing purposes.

Signed-off-by: Ryan Lahfa <ryan@dgnum.eu>
2024-03-06 19:14:58 +01:00
270 changed files with 4271 additions and 14135 deletions

1
.envrc
View file

@ -1,2 +1 @@
watch_file workflows/*
use nix use nix

View file

@ -1,21 +0,0 @@
jobs:
check_dns:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Check the validity of the DNS configuration
run: nix-build meta/verify.nix -A dns
check_meta:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Check the validity of meta options
run: nix-build meta/verify.nix -A meta
name: Check meta
on:
pull_request:
branches:
- main
push:
paths:
- meta/*

View file

@ -1,16 +0,0 @@
jobs:
check_workflows:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Check that the workflows are up to date
run: nix-shell -A check-workflows --run '[ $(git status --porcelain | wc -l)
-eq 0 ]'
name: Check workflows
on:
pull_request:
branches:
- main
push:
paths:
- workflows/*

View file

@ -0,0 +1,57 @@
name: ds-fr update
on:
schedule:
# Run at 8 o'clock every day
- cron: "26 18 * * *"
jobs:
npins_update:
runs-on: nix
steps:
- uses: actions/checkout@v3
with:
token: ${{ secrets.TEA_DGNUM_CHORES_TOKEN }}
- name: Update DS and open PR if necessary
run: |
# Fetch the latest release tag
VERSION=$(curl -L \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/demarches-simplifiees/demarches-simplifiees.fr/releases/latest \
| jq -r '.tag_name')
# Move to the ds-fr directory
cd machines/compute01/ds-fr/package
# Run the update script
./update.sh -v "$VERSION"
if [ ! -z "$(git diff --name-only)" ]; then
echo "[+] Changes detected, pushing updates."
git switch -C ds-update
git add .
git config user.name "DGNum Chores"
git config user.email "tech@dgnum.eu"
git commit --message "chore(ds-fr): Update"
git push --set-upstream origin ds-update --force
# Connect to the server with the cli
tea login add \
-n dgnum-chores \
-t '${{ secrets.TEA_DGNUM_CHORES_TOKEN }}' \
-u https://git.dgnum.eu
# Create a pull request if needed
# i.e. no PR with the same title exists
if [ -z "$(tea pr ls -f='title,author' -o simple | grep 'chore(ds-fr): Update dgnum-chores')" ]; then
tea pr create \
--description "Automatic ds-fr update" \
--title "chore(ds-fr): Update" \
--head ds-update
fi
fi

View file

@ -1,119 +0,0 @@
jobs:
bridge01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- env:
BUILD_NODE: bridge01
STORE_ENDPOINT: https://tvix-store.dgnum.eu/infra-signing/
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
STORE_USER: admin
name: Build and cache bridge01
run: nix-shell -A eval-nodes --run cache-node
compute01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- env:
BUILD_NODE: compute01
STORE_ENDPOINT: https://tvix-store.dgnum.eu/infra-signing/
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
STORE_USER: admin
name: Build and cache compute01
run: nix-shell -A eval-nodes --run cache-node
geo01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- env:
BUILD_NODE: geo01
STORE_ENDPOINT: https://tvix-store.dgnum.eu/infra-signing/
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
STORE_USER: admin
name: Build and cache geo01
run: nix-shell -A eval-nodes --run cache-node
geo02:
runs-on: nix
steps:
- uses: actions/checkout@v3
- env:
BUILD_NODE: geo02
STORE_ENDPOINT: https://tvix-store.dgnum.eu/infra-signing/
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
STORE_USER: admin
name: Build and cache geo02
run: nix-shell -A eval-nodes --run cache-node
rescue01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- env:
BUILD_NODE: rescue01
STORE_ENDPOINT: https://tvix-store.dgnum.eu/infra-signing/
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
STORE_USER: admin
name: Build and cache rescue01
run: nix-shell -A eval-nodes --run cache-node
storage01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- env:
BUILD_NODE: storage01
STORE_ENDPOINT: https://tvix-store.dgnum.eu/infra-signing/
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
STORE_USER: admin
name: Build and cache storage01
run: nix-shell -A eval-nodes --run cache-node
vault01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- env:
BUILD_NODE: vault01
STORE_ENDPOINT: https://tvix-store.dgnum.eu/infra-signing/
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
STORE_USER: admin
name: Build and cache vault01
run: nix-shell -A eval-nodes --run cache-node
web01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- env:
BUILD_NODE: web01
STORE_ENDPOINT: https://tvix-store.dgnum.eu/infra-signing/
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
STORE_USER: admin
name: Build and cache web01
run: nix-shell -A eval-nodes --run cache-node
web02:
runs-on: nix
steps:
- uses: actions/checkout@v3
- env:
BUILD_NODE: web02
STORE_ENDPOINT: https://tvix-store.dgnum.eu/infra-signing/
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
STORE_USER: admin
name: Build and cache web02
run: nix-shell -A eval-nodes --run cache-node
web03:
runs-on: nix
steps:
- uses: actions/checkout@v3
- env:
BUILD_NODE: web03
STORE_ENDPOINT: https://tvix-store.dgnum.eu/infra-signing/
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
STORE_USER: admin
name: Build and cache web03
run: nix-shell -A eval-nodes --run cache-node
name: Build all the nodes
on:
pull_request:
branches:
- main
push:
branches:
- main

View file

@ -0,0 +1,70 @@
name: build configuration
on:
pull_request:
types: [opened, synchronize, edited, reopened]
branches:
- main
push:
branches:
- main
jobs:
build_compute01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build compute01
run: |
# Enter the shell
nix-shell --run 'colmena build --on compute01'
build_storage01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build storage01
run: |
# Enter the shell
nix-shell --run 'colmena build --on storage01'
build_vault01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build vault01
run: |
# Enter the shell
nix-shell --run 'colmena build --on vault01'
build_web01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build web01
run: |
# Enter the shell
nix-shell --run 'colmena build --on web01'
build_web02:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build web02
run: |
# Enter the shell
nix-shell --run 'colmena build --on web02'
build_rescue01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build rescue01
run: |
# Enter the shell
nix-shell --run 'colmena build --on rescue01'

View file

@ -0,0 +1,11 @@
name: lint
on: push
jobs:
check:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Run pre-commit on all files
run: nix-shell --run 'pre-commit run --all-files --show-diff-on-failure' -A shells.pre-commit ./.

View file

@ -1,25 +0,0 @@
jobs:
npins_update:
runs-on: nix
steps:
- uses: actions/checkout@v3
with:
depth: 0
token: ${{ secrets.TEA_DGNUM_CHORES_TOKEN }}
- name: Update dependencies and open PR if necessary
run: "npins update\n\nif [ ! -z \"$(git diff --name-only)\" ]; then\n echo
\"[+] Changes detected, pushing updates.\"\n\n git switch -C npins-update\n\
\n git add npins\n\n git config user.name \"DGNum Chores\"\n git config
user.email \"tech@dgnum.eu\"\n\n git commit --message \"chore(npins): Update\"\
\n git push --set-upstream origin npins-update --force\n\n # Connect to
the server with the cli\n tea login add \\\n -n dgnum-chores \\\n -t
\"${{ secrets.TEA_DGNUM_CHORES_TOKEN }}\" \\\n -u https://git.dgnum.eu\n\
\n # Create a pull request if needed\n # i.e. no PR with the same title
exists\n if [ -z \"$(tea pr ls -f='title,author' -o simple | grep 'chore(npins):
Update dgnum-chores')\" ]; then\n tea pr create \\\n --description
\"Automatic npins update\" \\\n --title \"chore(npins): Update\" \\\n\
\ --head npins-update\n fi\nfi\n"
name: npins update
on:
schedule:
- cron: 25 15 * * *

View file

@ -1,24 +1,31 @@
{ name: npins update
name = "npins update"; on:
on.schedule = [ schedule:
# Run at 11 o'clock every wednesday # Run at 11 o'clock every wednesday
{ cron = "25 15 * * *"; } - cron: "25 15 * * *"
];
jobs.npins_update = { jobs:
runs-on = "nix"; npins_update:
steps = [ runs-on: nix
{ steps:
uses = "actions/checkout@v3"; # - name: Install applications
"with" = { # run: apt-get update && apt-get install sudo
depth = 0; #
token = "\${{ secrets.TEA_DGNUM_CHORES_TOKEN }}"; - uses: actions/checkout@v3
}; with:
} depth: 0
token: ${{ secrets.TEA_DGNUM_CHORES_TOKEN }}
#
# - uses: https://github.com/cachix/install-nix-action@v22
# with:
# nix_path: nixpkgs=channel:nixos-unstable
{ # - name: Install tea
name = "Update dependencies and open PR if necessary"; # run: |
run = '' # nix-env -f '<nixpkgs>' -i tea
- name: Update dependencies and open PR if necessary
run: |
npins update npins update
if [ ! -z "$(git diff --name-only)" ]; then if [ ! -z "$(git diff --name-only)" ]; then
@ -37,7 +44,7 @@
# Connect to the server with the cli # Connect to the server with the cli
tea login add \ tea login add \
-n dgnum-chores \ -n dgnum-chores \
-t "''${{ secrets.TEA_DGNUM_CHORES_TOKEN }}" \ -t '${{ secrets.TEA_DGNUM_CHORES_TOKEN }}' \
-u https://git.dgnum.eu -u https://git.dgnum.eu
# Create a pull request if needed # Create a pull request if needed
@ -49,8 +56,3 @@
--head npins-update --head npins-update
fi fi
fi fi
'';
}
];
};
}

View file

@ -1,12 +0,0 @@
jobs:
check:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Run pre-commit on all files
run: nix-shell -A pre-commit --run 'pre-commit run --all-files --hook-stage
pre-push --show-diff-on-failure'
name: Run pre-commit on all files
on:
- push
- pull_request

111
README.md
View file

@ -3,115 +3,6 @@
The dgnum infrastructure. The dgnum infrastructure.
# Contributing # Contributing
Some instruction on how to contribute are available (in french) in [/CONTRIBUTING.md](CONTRIBUTING.md). You're expected to read this document before commiting to the repo.
Some instruction on how to contribute are available (in french) in [/CONTRIBUTE.md](CONTRIBUTE.md).
You're expected to read this document before commiting to the repo.
Some documentation for the development tools are provided in the aforementioned file. Some documentation for the development tools are provided in the aforementioned file.
# Using the binary cache
Add the following module to your configuration (and pin this repo using your favorite tool: npins, lon, etc...):
```
{ lib, ... }:
let
dgnum-infra = PINNED_PATH_TO_INFRA;
in {
nix.settings = (import dgnum-infra { }).mkCacheSettings {
caches = [ "infra" ];
};
}
```
# Adding a new machine
The first step is to create a minimal viable NixOS host, using tha means necessary.
The second step is to find a name for this host, it must be unique from the other hosts.
> [!TIP]
> For the rest of this part, we assume that the host is named `host02`
## Download the keys
The public SSH keys of `host02` have to be saved to `keys`, preferably only the `ssh-ed25519` one.
It can be retreived with :
```bash
ssh-keyscan address.of.host02 2>/dev/null | awk '/ssh-ed25519/ {print $2,$3}'
```
## Initialize the machine folder and configuration
- Create a folder `host02` under `machines/`
- Copy the hardware configuration file generated by `nixos-generate-config` to `machines/host02/_hardware-configuration.nix`
- Create a `machines/host02/_configuration.nix` file, it will contain the main configuration options, the basic content of this file should be the following
```nix
{ lib, ... }:
lib.extra.mkConfig {
enabledModules = [
# List of modules to enable
];
enabledServices = [
# List of services to enable
];
extraConfig = {
services.netbird.enable = true;
};
root = ./.;
}
```
## Fill in the metadata
### Network configuration
The network is declared in `meta/network.nix`, the necessary `hostId` value can be generated with :
```bash
head -c4 /dev/urandom | od -A none -t x4 | sed 's/ //'
```
### Other details
The general metadata is declared in `meta/nodes.nix`, the main values to declare are :
- `site`, where the node is physically located
- `stateVersion`
- `nixpkgs`, the nixpkgs version to use
## Initialize secrets
Create the directory `secrets` in the configuration folder, and add a `secrets.nix` file containing :
```nix
(import ../../../keys).mkSecrets [ "host02" ] [
# List of secrets for host02
]
```
This will be used for future secret management.
## Update encrypted files
Both the Arkheon, Netbox and notification modules have secrets that are deployed on all machines. To make those services work correctly, run in `modules/dgn-records`, `modules/dgn-netbox-agent` and `modules/dgn-notify` :
```bash
agenix -r
```
## Commit and create a PR
Once all of this is done, check that the configuration builds correctly :
```bash
colmena build --on host02
```
Apply it, and create a Pull Request.

View file

@ -1,136 +1,101 @@
/* /* Copyright :
Copyright : - Maurice Debray <maurice.debray@dgnum.eu> 2023
- Maurice Debray <maurice.debray@dgnum.eu> 2023 - Tom Hubrecht <tom.hubrecht@dgnum.eu> 2023
- Tom Hubrecht <tom.hubrecht@dgnum.eu> 2023
Ce logiciel est un programme informatique servant à déployer des Ce logiciel est un programme informatique servant à déployer des
configurations de serveurs via NixOS. configurations de serveurs via NixOS.
Ce logiciel est régi par la licence CeCILL soumise au droit français et 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 respectant les principes de diffusion des logiciels libres. Vous pouvez
utiliser, modifier et/ou redistribuer ce programme sous les conditions 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 de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
sur le site "http://www.cecill.info". sur le site "http://www.cecill.info".
En contrepartie de l'accessibilité au code source et des droits de copie, 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 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, 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 seule une responsabilité restreinte pèse sur l'auteur du programme, le
titulaire des droits patrimoniaux et les concédants successifs. titulaire des droits patrimoniaux et les concédants successifs.
A cet égard l'attention de l'utilisateur est attirée sur les risques 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 associés au chargement, à l'utilisation, à la modification et/ou au
développement et à la reproduction du logiciel par l'utilisateur étant développement et à la reproduction du logiciel par l'utilisateur étant
donné sa spécificité de logiciel libre, qui peut le rendre complexe à 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 manipuler et qui le réserve donc à des développeurs et des professionnels
avertis possédant des connaissances informatiques approfondies. Les avertis possédant des connaissances informatiques approfondies. Les
utilisateurs sont donc invités à charger et tester l'adéquation du utilisateurs sont donc invités à charger et tester l'adéquation du
logiciel à leurs besoins dans des conditions permettant d'assurer la 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, 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é. à 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 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 pris connaissance de la licence CeCILL, et que vous en avez accepté les
termes. termes.
*/ */
{
sources ? import ./npins,
pkgs ? import sources.nixpkgs { },
nix-pkgs ? import sources.nix-pkgs { inherit pkgs; },
}:
let let
inherit (pkgs.lib) sources = import ./npins;
isFunction pkgs = import sources.nixpkgs { };
mapAttrs liminixHive = import ./liminix-hive.nix { inherit sources; };
mapAttrs'
nameValuePair
removeSuffix
;
git-checks = (import sources.git-hooks).run { pre-commit-check = (import sources.pre-commit-hooks).run {
src = ./.; src = ./.;
hooks = { hooks = {
statix = { # Nix Hooks
statix.enable = true;
deadnix.enable = true;
rfc101 = {
enable = true; enable = true;
stages = [ "pre-push" ];
settings.ignore = [ name = "RFC-101 formatting";
"**/lon.nix" entry = "${pkgs.lib.getExe pkgs.nixfmt-rfc-style}";
"**/npins" files = "\\.nix$";
];
};
deadnix = {
enable = true;
stages = [ "pre-push" ];
};
nixfmt-rfc-style = {
enable = true;
stages = [ "pre-push" ];
}; };
# Misc Hooks
commitizen.enable = true; commitizen.enable = true;
}; };
}; };
workflows = (import sources.nix-actions { inherit pkgs; }).install {
src = ./.;
workflows = mapAttrs' (
name: _:
nameValuePair (removeSuffix ".nix" name) (
let
w = import ./workflows/${name};
in
if isFunction w then w { inherit (pkgs) lib; } else w
)
) (builtins.readDir ./workflows);
};
scripts = import ./scripts { inherit pkgs; };
in in
{ {
nodes = builtins.mapAttrs ( nodes = builtins.mapAttrs (host: { site, ... }: "${host}.${site}.infra.dgnum.eu") (
host: { site, ... }: "${host}.${site}.infra.dgnum.eu" import ./meta/nodes.nix
) (import ./meta/nodes.nix); );
dns = import ./meta/dns.nix; dns = import ./meta/dns.nix;
mkCacheSettings = import ./machines/storage01/tvix-cache/cache-settings.nix; shells = {
default = pkgs.mkShell {
name = "dgnum-infra";
devShell = pkgs.mkShell { packages =
name = "dgnum-infra"; (
with pkgs;
[
npins
colmena
nixos-generators
liminixHive.liminix.pkgs.pkgsBuildBuild.min-copy-closure
]
++ (builtins.map (p: callPackage p { }) [ (sources.disko + "/package.nix") ])
)
++ (import ./scripts { inherit pkgs; });
packages = [ shellHook = ''
(pkgs.nixos-generators.overrideAttrs (_: { ${pre-commit-check.shellHook}
version = "1.8.0-unstable"; '';
src = sources.nixos-generators;
}))
pkgs.npins
(pkgs.callPackage ./lib/colmena { inherit (nix-pkgs) colmena; }) preferLocalBuild = true;
(pkgs.callPackage "${sources.agenix}/pkgs/agenix.nix" { }) };
(pkgs.callPackage "${sources.lon}/nix/packages/lon.nix" { })
] ++ (builtins.attrValues scripts);
shellHook = '' pre-commit = pkgs.mkShell {
${git-checks.shellHook} name = "pre-commit-shell";
${workflows.shellHook}
'';
preferLocalBuild = true; shellHook = ''
${pre-commit-check.shellHook}
### '';
# Alternative shells
passthru = mapAttrs (name: value: pkgs.mkShell (value // { inherit name; })) {
pre-commit.shellHook = git-checks.shellHook;
check-workflows.shellHook = workflows.shellHook;
eval-nodes.packages = [ scripts.cache-node ];
}; };
}; };
} }

View file

@ -1,102 +1,78 @@
let let
sources' = import ./npins; sources = import ./npins;
# Patch sources directly lib = import (sources.nix-lib + "/src/trivial.nix");
sources = builtins.mapAttrs (patch.base { pkgs = import sources'.nixos-unstable { }; })
.applyPatches' sources';
nix-lib = import ./lib/nix-lib; patch = import sources.nix-patches { patchFile = ./patches; };
patch = import ./lib/nix-patches { patchFile = ./patches; };
nodes' = import ./meta/nodes.nix; nodes' = import ./meta/nodes.nix;
nodes = builtins.attrNames nodes'; nodes = builtins.attrNames nodes';
mkNode = node: { mkNode = node: {
# Import the base configuration for each node # Import the base configuration for each node
imports = [ ./machines/${node}/_configuration.nix ]; imports = builtins.map (lib.mkRel (./machines/${node})) [
"_configuration.nix"
"_hardware-configuration.nix"
];
}; };
nixpkgs' = import ./meta/nixpkgs.nix; mkNixpkgs =
# All supported nixpkgs versions, instanciated node:
nixpkgs = nix-lib.mapSingleFuse mkNixpkgs nixpkgs'.supported;
# Get the configured nixos version for the node,
# defaulting to the one defined in meta/nixpkgs
version = node: nodes'.${node}.nixpkgs or nixpkgs'.default;
# Builds a patched version of nixpkgs, only as the source
mkNixpkgs' =
v:
patch.mkNixpkgsSrc rec { patch.mkNixpkgsSrc rec {
src = sources'.${name}; src = sources.${version};
name = "nixos-${v}"; version = "nixos-${nodes'.${node}.nixpkgs or (import ./meta/nixpkgs.nix)}";
}; };
# Instanciates the required nixpkgs version mkNixpkgs' = node: import (mkNixpkgs node) { };
mkNixpkgs = version: import (mkNixpkgs' version) { };
### ###
# Function to create arguments based on the node # Function to create arguments based on the node
# #
mkArgs = node: rec { mkArgs = node: rec {
lib = nixpkgs.${version node}.lib // { lib = import sources.nix-lib {
extra = nix-lib; inherit (mkNixpkgs' node) lib;
keysRoot = ./keys;
}; };
meta = (import ./meta) lib; meta = (import ./meta) lib;
nodeMeta = meta.nodes.${node};
}; };
in in
# nodes = builtins.attrNames metadata.nodes;
{ {
meta = { meta = {
nodeNixpkgs = nix-lib.mapSingleFuse (n: nixpkgs.${version n}) nodes; nodeNixpkgs = lib.mapSingleFuse mkNixpkgs' nodes;
specialArgs = { specialArgs = {
inherit nixpkgs sources; inherit sources;
dgn-keys = import ./keys;
}; };
nodeSpecialArgs = nix-lib.mapSingleFuse mkArgs nodes; nodeSpecialArgs = lib.mapSingleFuse mkArgs nodes;
}; };
defaults = defaults =
{ name, nodeMeta, ... }: { meta, name, ... }:
{ {
# Import the default modules # Import the default modules
imports = [ imports = [ ./modules ];
./modules
(import "${sources.lix-module}/module.nix" { inherit (sources) lix; })
];
# Include default secrets # Include default secrets
age-secrets.sources = [ ./machines/${name}/secrets ]; age-secrets.sources = [ (./machines + "/${name}/secrets") ];
# Deployment config is specified in meta.nodes.${node}.deployment # Deployment config is specified in meta.nodes.${node}.deployment
inherit (nodeMeta) deployment; inherit (meta.nodes.${name}) deployment;
nix = { # Set NIX_PATH to the patched version of nixpkgs
# Set NIX_PATH to the patched version of nixpkgs nix.nixPath = [ "nixpkgs=${mkNixpkgs name}" ];
nixPath = [ "nixpkgs=${mkNixpkgs' (version name)}" ]; nix.optimise.automatic = true;
optimise.automatic = true;
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 7d";
};
};
# Allow unfree packages # Allow unfree packages
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
# Use the stateVersion declared in the metadata # Use the stateVersion declared in the metadata
system = { system = {
inherit (nodeMeta) stateVersion; inherit (meta.nodes.${name}) stateVersion;
}; };
}; };
} }
// (nix-lib.mapSingleFuse mkNode nodes) // (lib.mapSingleFuse mkNode nodes)

View file

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
NIXPKGS=$(nix-build --no-out-link nixpkgs.nix) NIXPKGS=$(nix-build nixpkgs.nix)
nixos-generate -c configuration.nix -I NIX_PATH="$NIXPKGS" -f install-iso nixos-generate -c configuration.nix -I NIX_PATH="$NIXPKGS" -f install-iso

View file

@ -1,9 +1,9 @@
{ lib, pkgs, ... }: { lib, pkgs, ... }:
let let
dgn-keys = import ../keys; dgn-lib = import ../lib { };
dgn-members = (import ../meta lib).organization.groups.root; dgn-members = (import ../meta).members.groups.iso;
in in
{ {
@ -11,7 +11,7 @@ in
boot = { boot = {
blacklistedKernelModules = [ "snd_pcsp" ]; blacklistedKernelModules = [ "snd_pcsp" ];
kernelPackages = pkgs.linuxPackages_latest; kernelPackages = pkgs.linuxPackages_6_1;
tmp.cleanOnBoot = true; tmp.cleanOnBoot = true;
loader = { loader = {
@ -22,7 +22,6 @@ in
supportedFilesystems = [ supportedFilesystems = [
"exfat" "exfat"
"zfs" "zfs"
"bcachefs"
]; ];
swraid.enable = lib.mkForce false; swraid.enable = lib.mkForce false;
@ -34,5 +33,7 @@ in
openssh.enable = true; openssh.enable = true;
}; };
users.users.root.openssh.authorizedKeys.keys = dgn-keys.getKeys dgn-members; users.users.root.openssh.authorizedKeys.keyFiles =
builtins.map (m: dgn-lib.mkRel ../keys "${m}.keys")
dgn-members;
} }

View file

@ -1,6 +1,5 @@
let let
version = (import ../meta/nixpkgs.nix).default; inherit (import ../npins) nixpkgs;
nixpkgs = (import ../npins)."nixos-${version}";
in in
(import nixpkgs { }).srcOnly { (import nixpkgs { }).srcOnly {

View file

@ -1,88 +0,0 @@
let
_sources = import ../npins;
meta = import ../meta (import _sources.nixpkgs { }).lib;
getAttr = flip builtins.getAttr;
inherit (import ../lib/nix-lib) flip setDefault unique;
in
rec {
# WARNING: When updating this list, make sure that the nodes and members are alphabetically sorted
# If not, you will face an angry maintainer
_keys = {
# SSH keys of the nodes
bridge01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP5bS3iBXz8wycBnTvI5Qi79WLu0h4IVv/EOdKYbP5y7" ];
compute01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE/YluSVS+4h3oV8CIUj0OmquyJXju8aEQy0Jz210vTu" ];
geo01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEl6Pubbau+usQkemymoSKrTBbrX8JU5m5qpZbhNx8p4" ];
geo02 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFNXaCS0/Nsu5npqQk1TP6wMHCVIOaj4pblp2tIg6Ket" ];
rescue01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEJa02Annu8o7ggPjTH/9ttotdNGyghlWfU9E8pnuLUf" ];
storage01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA0s+rPcEcfWCqZ4B2oJiWT/60awOI8ijL1rtDM2glXZ" ];
vault01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJA6VA7LENvTRlKdcrqt8DxDOPvX3bg3Gjy9mNkdFEW" ];
web01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPR+lewuJ/zhCyizJGJOH1UaAB699ItNKEaeuoK57LY5" ];
web02 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID+QDE+GgZs6zONHvzRW15BzGJNW69k2BFZgB/Zh/tLX" ];
web03 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICrWsMEfK86iaO9SubMqE2UvZNtHkLY5VUod/bbqKC0L" ];
# SSH keys of the DGNum members
agroudiev = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDgyt3ntpcoI/I2n97R1hzjBiNL6R98S73fSi7pkSE/8mQbI8r9GzsPUBcxQ+tIg0FgwkLxTwF8DwLf0E+Le/rPznxBS5LUQaAktSQSrxz/IIID1+jN8b03vf5PjfKS8H2Tu3Q8jZXa8HNsj3cpySpGMqGrE3ieUmknd/YfppRRf+wM4CsGKZeS3ZhB9oZi3Jn22A0U/17AOJTnv4seq+mRZWRQt3pvQvpp8/2M7kEqizie/gTr/DnwxUr45wisqYYH4tat9Cw6iDr7LK10VCrK37BfFagMIZ08Hkh3c46jghjYNQWe+mBUWJByWYhTJ0AtYrbaYeUV1HVYbsRJ6bNx25K6794QQPaE/vc2Z/VK/ILgvJ+9myFSAWVylCWdyYpwUu07RH/jDBl2aqH62ESwAG7SDUUcte6h9N+EryAQLWc8OhsGAYLpshhBpiqZwzX90m+nkbhx1SqMbtt6TS+RPDEHKFYn8E6FBrf1FK34482ndq/hHXZ88mqzGb1nOnM="
];
catvayor = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAA16foz+XzwKwyIR4wFgNIAE3Y7AfXyEsUZFVVz8Rie catvayor@katvayor"
];
cst1 = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKrijwPlb7KQkYPLznMPVzPPT69cLzhEsJzZi9tmxzTh cst1@x270"
];
ecoppens = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIGmU7yEOCGuGNt4PlQbzd0Cms1RePpo8yEA7Ij/+TdA" ];
gdd = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICE7TN5NQKGojNGIeTFiHjLHTDQGT8i05JFqX/zLW2zc"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIFbkPWWZzOBaRdx4+7xQUgxDwuncSl2fxAeVuYfVUPZ"
];
jemagius = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOoxmou5OU74GgpIUkhVt6GiB+O9Jy4ge0TwK5MDFJ2F"
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCxQX0JLRah3GfIOkua4ZhEJhp5Ykv55RO0SPrSUwCBs5arnALg8gq12YLr09t4bzW/NA9/jn7flhh4S54l4RwBUhmV4JSQhGu71KGhfOj5ZBkDoSyYqzbu206DfZP5eQonSmjfP6XghcWOr/jlBzw9YAAQkFxsQgXEkr4kdn0ZXfZGz6b0t3YUjYIuDNbptFsGz2V9iQVy1vnxrjnLSfc25j4et8z729Vpy4M7oCaE6a6hgon4V1jhVbg43NAE5gu2eYFAPIzO3E7ZI8WjyLu1wtOBClk1f+HMen3Tr+SX2PXmpPGb+I2fAkbzu/C4X/M3+2bL1dYjxuvQhvvpAjxFwmdoXW4gWJ3J/FRiFrKsiAY0rYC+yi8SfacJWCv4EEcV/yQ4gYwpmU9xImLaro6w5cOHGCqrzYqjZc4Wi6AWFGeBSNzNs9PXLgMRWeUyiIDOFnSep2ebZeVjTB16m+o/YDEhE10uX9kCCx3Dy/41iJ1ps7V4JWGFsr0Fqaz8mu8="
];
luj = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDMBW7rTtfZL9wtrpCVgariKdpN60/VeAzXkh9w3MwbO julien@enigma"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGa+7n7kNzb86pTqaMn554KiPrkHRGeTJ0asY1NjSbpr julien@tower"
];
mboyer = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGYnwZaFYvUxtJeNvpaA20rLfq8fOO4dFp7cIXsD8YNx" ];
mdebray = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEpwF+XD3HgX64kqD42pcEZRNYAWoO4YNiOm5KO4tH6o maurice@polaris"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFdDnSl3cyWil+S5JiyGqOvBR3wVh+lduw58S5WvraoL maurice@fekda"
];
raito = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcEkYM1r8QVNM/G5CxJInEdoBCWjEHHDdHlzDYNSUIdHHsn04QY+XI67AdMCm8w30GZnLUIj5RiJEWXREUApby0GrfxGGcy8otforygfgtmuUKAUEHdU2MMwrQI7RtTZ8oQ0USRGuqvmegxz3l5caVU7qGvBllJ4NUHXrkZSja2/51vq80RF4MKkDGiz7xUTixI2UcBwQBCA/kQedKV9G28EH+1XfvePqmMivZjl+7VyHsgUVj9eRGA1XWFw59UPZG8a7VkxO/Eb3K9NF297HUAcFMcbY6cPFi9AaBgu3VC4eetDnoN/+xT1owiHi7BReQhGAy/6cdf7C/my5ehZwD"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE0xMwWedkKosax9+7D2OlnMxFL/eV4CvFZLsbLptpXr"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKiXXYkhRh+s7ixZ8rvG8ntIqd6FELQ9hh7HoaHQJRPU"
];
thubrecht = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL+EZXYziiaynJX99EW8KesnmRTZMof3BoIs3mdEl8L3"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHL4M4HKjs4cjRAYRk9pmmI8U0R4+T/jQh6Fxp/i1Eoy"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPM1jpXR7BWQa7Sed7ii3SbvIPRRlKb3G91qC0vOwfJn"
];
};
getKeys = ls: builtins.concatLists (builtins.map (getAttr _keys) ls);
mkSecrets =
nodes: setDefault { publicKeys = unique (rootKeys ++ (builtins.concatMap getNodeKeys' nodes)); };
getNodeKeys' =
node:
let
names = builtins.foldl' (names: group: names ++ meta.organization.groups.${group}) (
meta.nodes.${node}.admins ++ [ node ]
) meta.nodes.${node}.adminGroups;
in
unique (getKeys names);
getNodeKeys = node: rootKeys ++ getNodeKeys' node;
# List of keys for the root group
rootKeys = getKeys meta.organization.groups.root;
# List of 'machine' keys
machineKeys = rootKeys ++ (getKeys (builtins.attrNames meta.nodes));
}

2
keys/gdd.keys Normal file
View file

@ -0,0 +1,2 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICE7TN5NQKGojNGIeTFiHjLHTDQGT8i05JFqX/zLW2zc
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIFbkPWWZzOBaRdx4+7xQUgxDwuncSl2fxAeVuYfVUPZ

2
keys/jemagius.keys Normal file
View file

@ -0,0 +1,2 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOoxmou5OU74GgpIUkhVt6GiB+O9Jy4ge0TwK5MDFJ2F
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCxQX0JLRah3GfIOkua4ZhEJhp5Ykv55RO0SPrSUwCBs5arnALg8gq12YLr09t4bzW/NA9/jn7flhh4S54l4RwBUhmV4JSQhGu71KGhfOj5ZBkDoSyYqzbu206DfZP5eQonSmjfP6XghcWOr/jlBzw9YAAQkFxsQgXEkr4kdn0ZXfZGz6b0t3YUjYIuDNbptFsGz2V9iQVy1vnxrjnLSfc25j4et8z729Vpy4M7oCaE6a6hgon4V1jhVbg43NAE5gu2eYFAPIzO3E7ZI8WjyLu1wtOBClk1f+HMen3Tr+SX2PXmpPGb+I2fAkbzu/C4X/M3+2bL1dYjxuvQhvvpAjxFwmdoXW4gWJ3J/FRiFrKsiAY0rYC+yi8SfacJWCv4EEcV/yQ4gYwpmU9xImLaro6w5cOHGCqrzYqjZc4Wi6AWFGeBSNzNs9PXLgMRWeUyiIDOFnSep2ebZeVjTB16m+o/YDEhE10uX9kCCx3Dy/41iJ1ps7V4JWGFsr0Fqaz8mu8=

2
keys/luj.keys Normal file
View file

@ -0,0 +1,2 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDMBW7rTtfZL9wtrpCVgariKdpN60/VeAzXkh9w3MwbO julien@enigma
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGa+7n7kNzb86pTqaMn554KiPrkHRGeTJ0asY1NjSbpr julien@tower

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE/YluSVS+4h3oV8CIUj0OmquyJXju8aEQy0Jz210vTu

1
keys/machines/geo01.keys Normal file
View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEl6Pubbau+usQkemymoSKrTBbrX8JU5m5qpZbhNx8p4

1
keys/machines/geo02.keys Normal file
View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFNXaCS0/Nsu5npqQk1TP6wMHCVIOaj4pblp2tIg6Ket

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA0s+rPcEcfWCqZ4B2oJiWT/60awOI8ijL1rtDM2glXZ

View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJA6VA7LENvTRlKdcrqt8DxDOPvX3bg3Gjy9mNkdFEW

1
keys/machines/web01.keys Normal file
View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPR+lewuJ/zhCyizJGJOH1UaAB699ItNKEaeuoK57LY5

1
keys/mdebray.keys Normal file
View file

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEpwF+XD3HgX64kqD42pcEZRNYAWoO4YNiOm5KO4tH6o maurice@polaris

3
keys/raito.keys Normal file
View file

@ -0,0 +1,3 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcEkYM1r8QVNM/G5CxJInEdoBCWjEHHDdHlzDYNSUIdHHsn04QY+XI67AdMCm8w30GZnLUIj5RiJEWXREUApby0GrfxGGcy8otforygfgtmuUKAUEHdU2MMwrQI7RtTZ8oQ0USRGuqvmegxz3l5caVU7qGvBllJ4NUHXrkZSja2/51vq80RF4MKkDGiz7xUTixI2UcBwQBCA/kQedKV9G28EH+1XfvePqmMivZjl+7VyHsgUVj9eRGA1XWFw59UPZG8a7VkxO/Eb3K9NF297HUAcFMcbY6cPFi9AaBgu3VC4eetDnoN/+xT1owiHi7BReQhGAy/6cdf7C/my5ehZwD
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE0xMwWedkKosax9+7D2OlnMxFL/eV4CvFZLsbLptpXr
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKiXXYkhRh+s7ixZ8rvG8ntIqd6FELQ9hh7HoaHQJRPU

3
keys/thubrecht.keys Normal file
View file

@ -0,0 +1,3 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL+EZXYziiaynJX99EW8KesnmRTZMof3BoIs3mdEl8L3
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHL4M4HKjs4cjRAYRk9pmmI8U0R4+T/jQh6Fxp/i1Eoy
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPM1jpXR7BWQa7Sed7ii3SbvIPRRlKb3G91qC0vOwfJn

View file

@ -1,11 +0,0 @@
# Copyright: Jade Lovelace <lix@jade.fyi> 2024
{ colmena, runCommandNoCC }:
runCommandNoCC "colmena-wrapper" { env.colmena = "${colmena}/bin/colmena"; } ''
mkdir -p $out
ln -s ${colmena}/share $out/share
mkdir $out/bin
substituteAll ${./wrapper.sh.in} $out/bin/colmena
chmod +x $out/bin/colmena
''

View file

@ -1,31 +0,0 @@
#!/usr/bin/env bash
#
# Copyright: Jade Lovelace <lix@jade.fyi> 2024
doChecks() {
# creates refs in the refs/prefetch/remotes/origin namespace
echo "Prefetching repo changes..." >&2
git fetch --quiet --prefetch --no-write-fetch-head origin
diffs=$(git rev-list --left-right --count HEAD...refs/prefetch/remotes/origin/main)
only_in_local=$(echo "$diffs" | cut -f1)
only_in_main=$(echo "$diffs" | cut -f2)
if [[ $only_in_main -gt 0 && ! -v $FORCE_DEPLOY_DGNUM ]]; then
echo >&2
echo "Attempting to deploy when main has $only_in_main commits not in your branch!" >&2
echo "This will probably revert someone's changes. Consider merging them." >&2
echo "If you really mean it, set the environment variable FORCE_DEPLOY_DGNUM" >&2
exit 1
fi
if [[ $only_in_local -gt 0 ]]; then
echo "You have $only_in_local commits not yet pushed to main. Reminder to push them after :)" >&2
fi
}
if [[ $1 == 'apply' ]]; then
doChecks
fi
exec @colmena@ "$@"

29
lib/default.nix Normal file
View file

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

View file

@ -1,200 +0,0 @@
# Copyright Tom Hubrecht, (2023)
#
# Tom Hubrecht <tom@hubrecht.ovh>
#
# This software is governed by the CeCILL license under French law and
# abiding by the rules of distribution of free software. You can use,
# modify and/ or redistribute the software under the terms of the CeCILL
# license as circulated by CEA, CNRS and INRIA at the following URL
# "http://www.cecill.info".
#
# As a counterpart to the access to the source code and rights to copy,
# modify and redistribute granted by the license, users are provided only
# with a limited warranty and the software's author, the holder of the
# economic rights, and the successive licensors have only limited
# liability.
#
# In this respect, the user's attention is drawn to the risks associated
# with loading, using, modifying and/or developing or reproducing the
# software by the user in light of its specific status of free software,
# that may mean that it is complicated to manipulate, and that also
# therefore means that it is reserved for developers and experienced
# professionals having in-depth computer knowledge. Users are therefore
# encouraged to load and test the software's suitability as regards their
# requirements in conditions enabling the security of their systems and/or
# data to be ensured and, more generally, to use and operate it in the
# same conditions as regards security.
#
# The fact that you are presently reading this means that you have had
# knowledge of the CeCILL license and that you accept its terms.
let
# Reimplement optional functions
_optional =
default: b: value:
if b then value else default;
in
rec {
inherit (import ./nixpkgs.nix)
flip
hasPrefix
recursiveUpdate
splitString
unique
;
/*
Fuses a list of attribute sets into a single attribute set.
Type: [attrs] -> attrs
Example:
x = [ { a = 1; } { b = 2; } ]
fuseAttrs x
=> { a = 1; b = 2; }
*/
fuseAttrs = builtins.foldl' (attrs: x: attrs // x) { };
fuseValueAttrs = attrs: fuseAttrs (builtins.attrValues attrs);
/*
Applies a function to `attrsList` before fusing the resulting list
of attribute sets.
Type: ('a -> attrs) -> ['a] -> attrs
Example:
x = [ "to" "ta" "ti" ]
f = s: { ${s} = s + s; }
mapFuse f x
=> { to = "toto"; ta = "tata"; ti = "titi"; }
*/
mapFuse =
# 'a -> attrs
f:
# ['a]
attrsList:
fuseAttrs (builtins.map f attrsList);
/*
Equivalent of lib.singleton but for an attribute set.
Type: str -> 'a -> attrs
Example:
singleAttr "a" 1
=> { a = 1; }
*/
singleAttr = name: value: { ${name} = value; };
# Enables a list of modules.
enableAttrs' =
enable:
mapFuse (m: {
${m}.${enable} = true;
});
enableModules = enableAttrs' "enable";
/*
Create an attribute set from a list of values, mapping those
values through the function `f`.
Example:
mapSingleFuse (x: "val-${x}") [ "a" "b" ]
=> { a = "val-a"; b = "val-b" }
*/
mapSingleFuse = f: mapFuse (x: singleAttr x (f x));
/*
Creates a relative path as a string
Type: path -> str -> path
Example:
mkRel /home/test/ "file.txt"
=> "/home/test/file.txt"
*/
mkRel = path: file: path + "/${file}";
setDefault =
default:
mapFuse (name: {
${name} = default;
});
mkBaseSecrets =
root:
mapFuse (secret: {
${secret}.file = mkRel root secret;
});
getSecrets = dir: builtins.attrNames (import (mkRel dir "secrets.nix"));
subAttr = attrs: name: attrs.${name};
subAttrs = attrs: builtins.map (subAttr attrs);
optionalList = _optional [ ];
optionalAttrs = _optional { };
optionalString = _optional "";
/*
Same as fuseAttrs but using `lib.recursiveUpdate` to merge attribute
sets together.
Type: [attrs] -> attrs
*/
recursiveFuse = builtins.foldl' recursiveUpdate { };
mkImport =
root: file:
let
path = mkRel root file;
in
path + (optionalString (!(builtins.pathExists path)) ".nix");
mkImports = root: builtins.map (mkImport root);
/*
Creates a confugiration by merging enabled modules,
services and extraConfig.
Example:
mkConfig {
enabledModules = [ "ht-defaults" ];
enabledServices = [ "toto" ];
extraConfig = { services.nginx.enable = true; };
root = ./.;
}
=>
{
imports = [ ./toto ];
ht-defaults.enable = true;
services.nginx.enable = true;
}
*/
mkConfig =
{
# List of modules to enable with `enableModules`
enabledModules,
# List of services to import
enabledServices,
# Extra configuration, defaults to `{ }`
extraConfig ? { },
# Path relative to which the enabled services will be imported
root,
}:
recursiveFuse [
(enableModules enabledModules)
{
imports =
(extraConfig.imports or [ ]) ++ (mkImports root ([ "_hardware-configuration" ] ++ enabledServices));
}
(removeAttrs extraConfig [ "imports" ])
];
}

View file

@ -1,416 +0,0 @@
###
# Collection of nixpkgs library functions, those are necessary for defining our own lib
#
# They have been simplified and builtins are used in some places, instead of lib shims.
rec {
/**
Does the same as the update operator '//' except that attributes are
merged until the given predicate is verified. The predicate should
accept 3 arguments which are the path to reach the attribute, a part of
the first attribute set and a part of the second attribute set. When
the predicate is satisfied, the value of the first attribute set is
replaced by the value of the second attribute set.
# Inputs
`pred`
: Predicate, taking the path to the current attribute as a list of strings for attribute names, and the two values at that path from the original arguments.
`lhs`
: Left attribute set of the merge.
`rhs`
: Right attribute set of the merge.
# Type
```
recursiveUpdateUntil :: ( [ String ] -> AttrSet -> AttrSet -> Bool ) -> AttrSet -> AttrSet -> AttrSet
```
# Examples
:::{.example}
## `lib.attrsets.recursiveUpdateUntil` usage example
```nix
recursiveUpdateUntil (path: l: r: path == ["foo"]) {
# first attribute set
foo.bar = 1;
foo.baz = 2;
bar = 3;
} {
#second attribute set
foo.bar = 1;
foo.quz = 2;
baz = 4;
}
=> {
foo.bar = 1; # 'foo.*' from the second set
foo.quz = 2; #
bar = 3; # 'bar' from the first set
baz = 4; # 'baz' from the second set
}
```
:::
*/
recursiveUpdateUntil =
pred: lhs: rhs:
let
f =
attrPath:
builtins.zipAttrsWith (
n: values:
let
here = attrPath ++ [ n ];
in
if builtins.length values == 1 || pred here (builtins.elemAt values 1) (builtins.head values) then
builtins.head values
else
f here values
);
in
f [ ] [
rhs
lhs
];
/**
A recursive variant of the update operator //. The recursion
stops when one of the attribute values is not an attribute set,
in which case the right hand side value takes precedence over the
left hand side value.
# Inputs
`lhs`
: Left attribute set of the merge.
`rhs`
: Right attribute set of the merge.
# Type
```
recursiveUpdate :: AttrSet -> AttrSet -> AttrSet
```
# Examples
:::{.example}
## `lib.attrsets.recursiveUpdate` usage example
```nix
recursiveUpdate {
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/hda";
} {
boot.loader.grub.device = "";
}
returns: {
boot.loader.grub.enable = true;
boot.loader.grub.device = "";
}
```
:::
*/
recursiveUpdate =
lhs: rhs:
recursiveUpdateUntil (
_: lhs: rhs:
!(builtins.isAttrs lhs && builtins.isAttrs rhs)
) lhs rhs;
/**
Determine whether a string has given prefix.
# Inputs
`pref`
: Prefix to check for
`str`
: Input string
# Type
```
hasPrefix :: string -> string -> bool
```
# Examples
:::{.example}
## `lib.strings.hasPrefix` usage example
```nix
hasPrefix "foo" "foobar"
=> true
hasPrefix "foo" "barfoo"
=> false
```
:::
*/
hasPrefix = pref: str: (builtins.substring 0 (builtins.stringLength pref) str == pref);
/**
Escape occurrence of the elements of `list` in `string` by
prefixing it with a backslash.
# Inputs
`list`
: 1\. Function argument
`string`
: 2\. Function argument
# Type
```
escape :: [string] -> string -> string
```
# Examples
:::{.example}
## `lib.strings.escape` usage example
```nix
escape ["(" ")"] "(foo)"
=> "\\(foo\\)"
```
:::
*/
escape = list: builtins.replaceStrings list (builtins.map (c: "\\${c}") list);
/**
Convert a string `s` to a list of characters (i.e. singleton strings).
This allows you to, e.g., map a function over each character. However,
note that this will likely be horribly inefficient; Nix is not a
general purpose programming language. Complex string manipulations
should, if appropriate, be done in a derivation.
Also note that Nix treats strings as a list of bytes and thus doesn't
handle unicode.
# Inputs
`s`
: 1\. Function argument
# Type
```
stringToCharacters :: string -> [string]
```
# Examples
:::{.example}
## `lib.strings.stringToCharacters` usage example
```nix
stringToCharacters ""
=> [ ]
stringToCharacters "abc"
=> [ "a" "b" "c" ]
stringToCharacters "🦄"
=> [ "<EFBFBD>" "<EFBFBD>" "<EFBFBD>" "<EFBFBD>" ]
```
:::
*/
stringToCharacters = s: builtins.genList (p: builtins.substring p 1 s) (builtins.stringLength s);
/**
Turn a string `s` into an exact regular expression
# Inputs
`s`
: 1\. Function argument
# Type
```
escapeRegex :: string -> string
```
# Examples
:::{.example}
## `lib.strings.escapeRegex` usage example
```nix
escapeRegex "[^a-z]*"
=> "\\[\\^a-z]\\*"
```
:::
*/
escapeRegex = escape (stringToCharacters "\\[{()^$?*+|.");
/**
Appends string context from string like object `src` to `target`.
:::{.warning}
This is an implementation
detail of Nix and should be used carefully.
:::
Strings in Nix carry an invisible `context` which is a list of strings
representing store paths. If the string is later used in a derivation
attribute, the derivation will properly populate the inputDrvs and
inputSrcs.
# Inputs
`src`
: The string to take the context from. If the argument is not a string,
it will be implicitly converted to a string.
`target`
: The string to append the context to. If the argument is not a string,
it will be implicitly converted to a string.
# Type
```
addContextFrom :: string -> string -> string
```
# Examples
:::{.example}
## `lib.strings.addContextFrom` usage example
```nix
pkgs = import <nixpkgs> { };
addContextFrom pkgs.coreutils "bar"
=> "bar"
```
The context can be displayed using the `toString` function:
```nix
nix-repl> builtins.getContext (lib.strings.addContextFrom pkgs.coreutils "bar")
{
"/nix/store/m1s1d2dk2dqqlw3j90jl3cjy2cykbdxz-coreutils-9.5.drv" = { ... };
}
```
:::
*/
addContextFrom = src: target: builtins.substring 0 0 src + target;
/**
Cut a string with a separator and produces a list of strings which
were separated by this separator.
# Inputs
`sep`
: 1\. Function argument
`s`
: 2\. Function argument
# Type
```
splitString :: string -> string -> [string]
```
# Examples
:::{.example}
## `lib.strings.splitString` usage example
```nix
splitString "." "foo.bar.baz"
=> [ "foo" "bar" "baz" ]
splitString "/" "/usr/local/bin"
=> [ "" "usr" "local" "bin" ]
```
:::
*/
splitString =
sep: s:
let
splits = builtins.filter builtins.isString (
builtins.split (escapeRegex (builtins.toString sep)) (builtins.toString s)
);
in
builtins.map (addContextFrom s) splits;
/**
Remove duplicate elements from the `list`. O(n^2) complexity.
# Inputs
`list`
: Input list
# Type
```
unique :: [a] -> [a]
```
# Examples
:::{.example}
## `lib.lists.unique` usage example
```nix
unique [ 3 2 3 4 ]
=> [ 3 2 4 ]
```
:::
*/
unique = builtins.foldl' (acc: e: if builtins.elem e acc then acc else acc ++ [ e ]) [ ];
/**
Flip the order of the arguments of a binary function.
# Inputs
`f`
: 1\. Function argument
`a`
: 2\. Function argument
`b`
: 3\. Function argument
# Type
```
flip :: (a -> b -> c) -> (b -> a -> c)
```
# Examples
:::{.example}
## `lib.trivial.flip` usage example
```nix
flip concat [1] [2]
=> [ 2 1 ]
```
:::
*/
flip =
f: a: b:
f b a;
}

View file

@ -1,110 +0,0 @@
# Copyright Tom Hubrecht, (2023-2024)
#
# Tom Hubrecht <tom@hubrecht.ovh>
#
# This software is governed by the CeCILL license under French law and
# abiding by the rules of distribution of free software. You can use,
# modify and/ or redistribute the software under the terms of the CeCILL
# license as circulated by CEA, CNRS and INRIA at the following URL
# "http://www.cecill.info".
#
# As a counterpart to the access to the source code and rights to copy,
# modify and redistribute granted by the license, users are provided only
# with a limited warranty and the software's author, the holder of the
# economic rights, and the successive licensors have only limited
# liability.
#
# In this respect, the user's attention is drawn to the risks associated
# with loading, using, modifying and/or developing or reproducing the
# software by the user in light of its specific status of free software,
# that may mean that it is complicated to manipulate, and that also
# therefore means that it is reserved for developers and experienced
# professionals having in-depth computer knowledge. Users are therefore
# encouraged to load and test the software's suitability as regards their
# requirements in conditions enabling the security of their systems and/or
# data to be ensured and, more generally, to use and operate it in the
# same conditions as regards security.
#
# The fact that you are presently reading this means that you have had
# knowledge of the CeCILL license and that you accept its terms.
{
patchFile,
excludeGitHubManual ? true,
fetchers ? { },
}:
rec {
base =
{ pkgs }:
rec {
mkUrlPatch =
attrs:
pkgs.fetchpatch (
{
hash = pkgs.lib.fakeHash;
}
// attrs
// (pkgs.lib.optionalAttrs (excludeGitHubManual && !(builtins.hasAttr "includes" attrs)) {
excludes = (attrs.excludes or [ ]) ++ [ "nixos/doc/manual/*" ];
})
);
mkGitHubPatch =
{ id, ... }@attrs:
mkUrlPatch (
(builtins.removeAttrs attrs [ "id" ])
// {
url = "https://github.com/NixOS/nixpkgs/pull/${builtins.toString id}.diff";
}
);
mkCommitPatch =
{ sha, ... }@attrs:
mkUrlPatch (
(builtins.removeAttrs attrs [ "sha" ])
// {
url = "https://github.com/NixOS/nixpkgs/commit/${builtins.toString sha}.diff";
}
);
patchFunctions = {
commit = mkCommitPatch;
github = mkGitHubPatch;
remote = pkgs.fetchpatch;
static = attrs: attrs.path;
url = mkUrlPatch;
} // fetchers;
mkPatch =
{
_type ? "github",
...
}@attrs:
if builtins.hasAttr _type patchFunctions then
patchFunctions.${_type} (builtins.removeAttrs attrs [ "_type" ])
else
throw "Unknown patch type: ${builtins.toString _type}.";
mkPatches = v: builtins.map mkPatch ((import patchFile).${v} or [ ]);
applyPatches =
{
src,
name,
patches ? mkPatches name,
}:
if patches == [ ] then
src
else
pkgs.applyPatches {
inherit patches src;
name = "${name}-patched";
};
applyPatches' = name: src: applyPatches { inherit name src; };
};
mkNixpkgsSrc = { src, name }: (base { pkgs = import src { }; }).applyPatches { inherit src name; };
}

38
liminix-hive.nix Normal file
View file

@ -0,0 +1,38 @@
# This is a very rudimentary hive to deploy Liminix images.
{
sources ? import ./npins,
nixpkgs ? sources.nixpkgs,
liminix ? sources.liminix,
}:
let
evalLiminix =
{ config, device }:
{
primary = import liminix {
inherit device nixpkgs;
imageType = "primary";
liminix-config = config;
};
secondary = import liminix {
inherit device nixpkgs;
imageType = "secondary";
liminix-config = config;
};
};
zyxel = {
nwa50ax = import "${liminix}/devices/zyxel-nwa50ax";
};
in
{
liminix.pkgs =
(import liminix {
device = zyxel.nwa50ax;
imageType = "primary";
liminix-config = ./machines/ap/configuration.nix;
}).pkgs;
devices = zyxel;
ap-test = evalLiminix {
config = ./machines/ap/configuration.nix;
device = zyxel.nwa50ax;
};
}

1
liminix-rebuild.nix Normal file
View file

@ -0,0 +1 @@
{ liminix-system }: (import ./liminix-hive.nix { }).${liminix-system}.primary

View file

@ -0,0 +1,140 @@
{
config,
pkgs,
modulesPath,
...
}:
let
# inherit (pkgs.liminix.services)
# oneshot
# longrun
# bundle
# target
# ;
# inherit (pkgs) writeText;
svc = config.system.service;
secrets-1 = {
ssid = "Zyxel 2G (N)";
wpa_passphrase = "diamond dogs";
};
secrets-2 = {
ssid = "Zyxel 5G (AX)";
wpa_passphrase = "diamond dogs";
};
baseParams = {
country_code = "FR";
hw_mode = "g";
channel = 6;
wmm_enabled = 1;
ieee80211n = 1;
ht_capab = "[LDPC][GF][HT40-][HT40+][SHORT-GI-40][MAX-AMSDU-7935][TX-STBC]";
auth_algs = 1;
wpa = 2;
wpa_key_mgmt = "WPA-PSK";
wpa_pairwise = "TKIP CCMP";
rsn_pairwise = "CCMP";
};
modernParams = {
hw_mode = "a";
he_su_beamformer = 1;
he_su_beamformee = 1;
he_mu_beamformer = 1;
preamble = 1;
# Allow radar detection.
ieee80211d = 1;
ieee80211h = 1;
ieee80211ac = 1;
ieee80211ax = 1;
vht_capab = "[MAX-MPDU-7991][SU-BEAMFORMEE][SU-BEAMFORMER][RXLDPC][SHORT-GI-80][MAX-A-MPDU-LEN-EXP3][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN][TX-STBC-2BY1][RX-STBC-1][MU-BEAMFORMER]";
vht_oper_chwidth = 1;
he_oper_chwidth = 1;
channel = 36;
vht_oper_centr_freq_seg0_idx = 42;
he_oper_centr_freq_seg0_idx = 42;
require_vht = 1;
};
mkWifiSta =
params: interface: secrets:
svc.hostapd.build {
inherit interface;
params = params // {
inherit (secrets) ssid wpa_passphrase;
};
};
in
rec {
imports = [
"${modulesPath}/wlan.nix"
"${modulesPath}/network"
"${modulesPath}/hostapd"
"${modulesPath}/ssh"
"${modulesPath}/ntp"
"${modulesPath}/vlan"
"${modulesPath}/bridge"
];
hostname = "zyxel";
users.root = {
# EDIT: choose a root password and then use
# "mkpasswd -m sha512crypt" to determine the hash.
# It should start wirh $6$.
passwd = "$y$j9T$f8GhLiqYmr3lc58eKhgyD0$z7P/7S9u.kq/cANZExxhS98bze/6i7aBxU6tbl7RMi.";
openssh.authorizedKeys.keys = [
# EDIT: you can add your ssh pubkey here
# "ssh-rsa AAAAB3NzaC1....H6hKd user@example.com";
];
};
services.int = svc.bridge.primary.build { ifname = "int"; };
services.bridge = svc.bridge.members.build {
primary = services.int;
members = with config.hardware.networkInterfaces; [
lan
wlan0
wlan1
];
};
services.dhcpv4 =
let
iface = services.int;
in
svc.network.dhcp.client.build { interface = iface; };
services.defaultroute4 = svc.network.route.build {
via = "$(output ${services.dhcpv4} address)";
target = "default";
dependencies = [ services.dhcpv4 ];
};
services.packet_forwarding = svc.network.forward.build { };
services.sshd = svc.ssh.build { allowRoot = true; };
services.ntp = config.system.service.ntp.build {
pools = {
"pool.ntp.org" = [ "iburst" ];
};
};
boot.tftp = {
serverip = "192.0.2.10";
ipaddr = "192.0.2.12";
};
# wlan0 is the 2.4GHz interface.
services.hostap-1 = mkWifiSta baseParams config.hardware.networkInterfaces.wlan0 secrets-1;
# wlan1 is the 5GHz interface, e.g. AX capable.
services.hostap-2 =
mkWifiSta (baseParams // modernParams) config.hardware.networkInterfaces.wlan1
secrets-2;
defaultProfile.packages = with pkgs; [
zyxel-bootconfig
iw
min-collect-garbage
mtdutils
];
}

View file

@ -1,20 +0,0 @@
{ lib, pkgs, ... }:
lib.extra.mkConfig {
enabledModules = [
# List of modules to enable
];
enabledServices = [
# List of services to enable
"network"
];
extraConfig = {
services.netbird.enable = true;
environment.systemPackages = [ pkgs.bcachefs-tools ];
};
root = ./.;
}

View file

@ -1,53 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ modulesPath, pkgs, ... }:
{
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot = {
initrd = {
availableKernelModules = [
"xhci_pci"
"ehci_pci"
"ahci"
"sd_mod"
"sr_mod"
];
};
kernelModules = [ "kvm-intel" ];
kernelPackages = pkgs.linuxPackages_latest;
supportedFilesystems.bcachefs = true;
};
fileSystems = {
"/" = {
device = "UUID=3da58b64-a2fd-428d-bde8-3a185e2f73fd";
fsType = "bcachefs";
options = [ "compression=zstd" ];
};
"/boot" = {
device = "/dev/disk/by-uuid/4D0A-AF11";
fsType = "vfat";
options = [
"fmask=0022"
"dmask=0022"
];
};
};
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
# networking.interfaces.eno1.useDHCP = lib.mkDefault true;
# networking.interfaces.vlan-admin.useDHCP = lib.mkDefault true;
# networking.interfaces.vlan-uplink-oob.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = "x86_64-linux";
hardware.cpu.intel.updateMicrocode = true;
}

View file

@ -1,79 +0,0 @@
_:
{
networking = {
useNetworkd = true;
useDHCP = false;
nftables.enable = true;
firewall.allowedUDPPorts = [ 67 ];
};
systemd.network = {
networks = {
"10-eno1" = {
name = "eno1";
networkConfig = {
VLAN = [
"vlan-admin"
"vlan-uplink-oob"
];
LinkLocalAddressing = false;
LLDP = false;
EmitLLDP = false;
IPv6AcceptRA = false;
IPv6SendRA = false;
};
# address = [ "192.168.222.1/24" ];
};
"10-vlan-admin" = {
name = "vlan-admin";
# DHCP for the BMC
networkConfig.DHCPServer = "yes";
dhcpServerConfig = {
PoolOffset = 128;
EmitDNS = false;
EmitNTP = false;
EmitSIP = false;
EmitPOP3 = false;
EmitSMTP = false;
EmitLPR = false;
UplinkInterface = ":none";
};
address = [
"fd26:baf9:d250:8000::ffff/64"
"192.168.222.1/24"
];
};
"10-vlan-uplink-oob" = {
name = "vlan-uplink-oob";
networkConfig.DHCP = "ipv4";
};
};
netdevs = {
"10-vlan-admin" = {
netdevConfig = {
Name = "vlan-admin";
Kind = "vlan";
};
vlanConfig.Id = 3000;
};
"10-vlan-uplink-oob" = {
netdevConfig = {
Name = "vlan-uplink-oob";
Kind = "vlan";
};
vlanConfig.Id = 500;
};
};
};
}

View file

@ -1,3 +0,0 @@
(import ../../../keys).mkSecrets [ "bridg01" ] [
# List of secrets for bridge01
]

View file

@ -1,42 +1,38 @@
{ lib, ... }: { lib, ... }:
lib.extra.mkConfig { lib.extra.mkConfig {
# List of modules to enable
enabledModules = [ enabledModules = [
# INFO: This list needs to stay sorted alphabetically # List of modules to enable
"dgn-backups" "dgn-backups"
"dgn-chatops" "dgn-fail2ban"
"dgn-web" "dgn-web"
]; ];
# List of services to enable
enabledServices = [ enabledServices = [
# INFO: This list needs to stay sorted alphabetically # List of services to enable
"arkheon"
"dgsi"
"ds-fr" "ds-fr"
"grafana" "grafana"
"hedgedoc" "hedgedoc"
"k-radius"
"kanidm" "kanidm"
"librenms" "librenms"
"mastodon" "mastodon"
"nextcloud" "nextcloud"
"ollama-proxy"
"outline" "outline"
"plausible"
"postgresql"
"rstudio-server" "rstudio-server"
"satosa" "satosa"
"signal-irc-bridge"
"signald"
"stirling-pdf"
"takumi"
"telegraf" "telegraf"
"vaultwarden" "vaultwarden"
"zammad" "zammad"
"signald"
]; ];
extraConfig = { extraConfig = {
dgn-fail2ban.jails = lib.extra.enableAttrs' "enabled" [
"sshd-bruteforce"
"sshd-timeout"
];
dgn-hardware.useZfs = true; dgn-hardware.useZfs = true;
services.netbird.enable = true; services.netbird.enable = true;

View file

@ -1,28 +0,0 @@
{ config, sources, ... }:
{
nixpkgs.overlays = [ (import (sources.arkheon.outPath + "/overlay.nix")) ];
services.arkheon = {
enable = true;
pythonEnv =
(import sources.nixos-unstable {
overlays = [ (import (sources.arkheon.outPath + "/overlay.nix")) ];
}).python3.withPackages
(ps: [
ps.arkheon
ps.daphne
ps.psycopg2
]);
domain = "arkheon.dgnum.eu";
nginx = {
enableACME = true;
forceSSL = true;
};
envFile = config.age.secrets."arkheon-env_file".path;
};
}

View file

@ -1,222 +0,0 @@
{
config,
lib,
pkgs,
utils,
sources,
...
}:
let
inherit (lib) toLower;
python =
let
python3 = pkgs.python312;
nix-pkgs = import sources.nix-pkgs { inherit pkgs python3; };
in
python3.override {
packageOverrides = _: _: {
inherit (nix-pkgs)
django-allauth
django-allauth-cas
django-browser-reload
django-bulma-forms
django-sass-processor
django-sass-processor-dart-sass
django-unfold
pykanidm
python-cas
loadcredential
xlwt
;
};
};
pythonEnv = python.withPackages (
ps:
[
ps.django
ps.gunicorn
ps.psycopg
ps.django-compressor
ps.django-import-export
# Local packages
ps.django-allauth
ps.django-allauth-cas
ps.django-browser-reload
ps.django-bulma-forms
ps.django-sass-processor
ps.django-sass-processor-dart-sass
ps.django-unfold
ps.loadcredential
ps.pykanidm
ps.python-cas
]
++ ps.django-allauth.optional-dependencies.saml
);
staticDrv = pkgs.stdenv.mkDerivation {
name = "dgsi-static";
src = sources.dgsi;
sourceRoot = "source/src";
nativeBuildInputs = [
pkgs.dart-sass
pythonEnv
];
configurePhase = ''
export DGSI_STATIC_ROOT=$out/static
export CREDENTIALS_DIRECTORY=$(pwd)/../.credentials
export DGSI_KANIDM_CLIENT="dgsi_test"
export DGSI_KANIDM_AUTH_TOKEN="fake.token"
export DGSI_X509_KEY=""
export DGSI_X509_CERT=""
'';
doBuild = false;
installPhase = ''
mkdir -p $out/static
python3 manage.py compilescss
python3 manage.py collectstatic
'';
};
in
{
users = {
users.nginx.extraGroups = [ "django-apps" ];
groups.django-apps = { };
};
systemd = {
services = {
dj-dgsi = {
description = "DGSI web app";
requires = [ "dj-dgsi.socket" ];
wantedBy = [ "multi-user.target" ];
after = [
"network.target"
"postgresql.service"
];
serviceConfig = {
DynamicUser = true;
LoadCredential = map (name: "${name}:${config.age.secrets."dgsi-${toLower name}_file".path}") [
"EMAIL_HOST_PASSWORD"
"KANIDM_AUTH_TOKEN"
"KANIDM_SECRET"
"SECRET_KEY"
"X509_CERT"
"X509_KEY"
];
RuntimeDirectory = "django-apps/dgsi";
StateDirectory = "django-apps/dgsi";
UMask = "0027";
User = "dj-dgsi";
Group = "django-apps";
WorkingDirectory = sources.dgsi;
ExecReload = "${lib.getExe' pkgs.coreutils "kill"} -s HUP $MAINPID";
KillMode = "mixed";
Type = "notify";
ExecStart = utils.escapeSystemdExecArgs [
(lib.getExe' pythonEnv "gunicorn")
"--workers"
4
"--bind"
"unix:/run/django-apps/dgsi.sock"
"--pythonpath"
"src"
"app.wsgi"
];
};
environment = {
DGSI_ALLOWED_HOSTS = builtins.toJSON [
"profil.dgnum.eu"
"dgsi.dgnum.eu"
];
DGSI_EMAIL_HOST = "kurisu.lahfa.xyz";
DGSI_EMAIL_HOST_USER = "web-services@infra.dgnum.eu";
DGSI_EMAIL_USE_SSL = builtins.toJSON true;
DGSI_FROM_EMAIL = "La Délégation Générale Numérique <noreply@infra.dgnum.eu>";
DGSI_SERVER_EMAIL = "dgsi@infra.dgnum.eu";
DGSI_KANIDM_CLIENT = "dgsi";
DGSI_KANIDM_URI = "https://sso.dgnum.eu";
DGSI_MEDIA_ROOT = "/var/lib/django-apps/dgsi/media";
DGSI_STATIC_ROOT = "${staticDrv}/static";
DGSI_DATABASES = builtins.toJSON {
default = {
ENGINE = "django.db.backends.postgresql";
NAME = "dj-dgsi";
};
};
DJANGO_SETTINGS_MODULE = "app.settings";
};
path = [ pythonEnv ];
preStart = ''
python3 src/manage.py migrate --no-input
'';
};
};
sockets."dj-dgsi" = {
description = "Socket for the DGSI Django Application";
wantedBy = [ "sockets.target" ];
socketConfig = {
ListenStream = "/run/django-apps/dgsi.sock";
SocketMode = "600";
SocketUser = config.services.nginx.user;
};
};
mounts = [
{
where = "/run/django-apps/dgsi/media";
what = "/var/lib/django-apps/dgsi/media";
options = "bind";
after = [ "dj-dgsi.service" ];
partOf = [ "dj-dgsi.service" ];
upheldBy = [ "dj-dgsi.service" ];
}
];
};
dgn-redirections.permanent."dgsi.dgnum.eu" = "profil.dgnum.eu";
services = {
postgresql = {
ensureDatabases = [ "dj-dgsi" ];
ensureUsers = [
{
name = "dj-dgsi";
ensureDBOwnership = true;
}
];
};
nginx.virtualHosts."profil.dgnum.eu" = {
enableACME = true;
forceSSL = true;
locations = {
"/".proxyPass = "http://unix:/run/django-apps/dgsi.sock";
"/static/".root = staticDrv;
"/media/".root = "/run/django-apps/dgsi";
};
};
};
}

View file

@ -1,35 +1,14 @@
{ { config, ... }:
config,
pkgs,
sources,
...
}:
let let
host = "demarches.dgnum.eu"; host = "demarches.dgnum.eu";
dgn-id = "fca8f72cd60c00e74d7735ec13e4e3a22e8e1244";
in in
{ {
imports = [ ./module.nix ]; imports = [ ./module.nix ];
dgn-web.internalPorts.ds-fr = 3000;
services.demarches-simplifiees = { services.demarches-simplifiees = {
enable = true; enable = true;
package =
((import sources.nix-pkgs { inherit pkgs; }).demarches-simplifiees.override {
initialDeploymentDate = "20230923";
}).overrideAttrs
(old: {
dsModules = old.dsModules.overrideAttrs {
prePatch = ''
${pkgs.lib.getExe pkgs.git} apply -p1 < ${builtins.fetchurl "https://git.dgnum.eu/DGNum/demarches-normaliennes/commit/${dgn-id}.patch"}
'';
};
});
secretFile = config.age.secrets."ds-fr-secret_file".path; secretFile = config.age.secrets."ds-fr-secret_file".path;
initialDeploymentDate = "20230923"; initialDeploymentDate = "20230923";

View file

@ -3,7 +3,9 @@
stdenv, stdenv,
fetchFromGitHub, fetchFromGitHub,
git, git,
bun, fetchYarnDeps,
yarn,
fixup_yarn_lock,
nodejs, nodejs,
ruby_3_2, ruby_3_2,
bundlerEnv, bundlerEnv,
@ -16,7 +18,7 @@ let
inherit (lib) getExe; inherit (lib) getExe;
# Head of the DGNum repo # Head of the DGNum repo
dgn-id = "f270f1cdd09e643a9c666c94df1841234430de49"; dgn-id = "8eecf28eeaf39bade8aed5e191a5bbf794dec4cc";
pname = "ds-fr"; pname = "ds-fr";
meta = import ./meta.nix; meta = import ./meta.nix;
@ -48,46 +50,20 @@ let
}; };
}; };
node_modules = stdenv.mkDerivation {
pname = "${pname}-node_modules";
inherit src version;
impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [
"GIT_PROXY_COMMAND"
"SOCKS_SERVER"
];
nativeBuildInputs = [ bun ];
dontConfigure = true;
buildPhase = ''
bun install --no-progress --frozen-lockfile --ignore-scripts
rm -r node_modules/.cache
# Remove inconsistent file
rm node_modules/.bin/grunt
'';
installPhase = ''
mv node_modules $out
'';
dontFixup = true;
outputHash = meta.deps-hash or lib.fakeHash;
outputHashAlgo = "sha256";
outputHashMode = "recursive";
};
dsModules = stdenv.mkDerivation { dsModules = stdenv.mkDerivation {
pname = "${pname}-modules"; pname = "${pname}-modules";
inherit src version; inherit src version;
offlineCache = fetchYarnDeps {
yarnLock = "${src}/yarn.lock";
hash = meta.deps-hash;
};
buildInputs = [ rubyEnv ]; buildInputs = [ rubyEnv ];
nativeBuildInputs = [ nativeBuildInputs = [
bun fixup_yarn_lock
nodejs nodejs
yarn
rubyEnv.wrappedRuby rubyEnv.wrappedRuby
]; ];
@ -108,13 +84,18 @@ let
APP_HOST = "precompile_placeholder"; APP_HOST = "precompile_placeholder";
buildPhase = '' buildPhase = ''
cp -R ${node_modules} node_modules export HOME=$(mktemp -d)
chmod u+w -R node_modules yarn config --offline set yarn-offline-mirror $offlineCache
fixup_yarn_lock yarn.lock
yarn install --offline --frozen-lockfile --ignore-platform --ignore-scripts --no-progress --non-interactive
patchShebangs node_modules patchShebangs node_modules/
patchShebangs bin/ patchShebangs bin/
bin/rake assets:precompile bin/rake assets:precompile
yarn cache clean --offline
rm -rf node_modules/
''; '';
installPhase = '' installPhase = ''
@ -135,6 +116,7 @@ stdenv.mkDerivation {
./patches/replay_routing_engine_for_a_cloned_procedure.patch ./patches/replay_routing_engine_for_a_cloned_procedure.patch
./patches/smtp_settings.patch ./patches/smtp_settings.patch
./patches/garage.patch ./patches/garage.patch
./patches/secrets-fc.patch
]; ];
postPatch = '' postPatch = ''

View file

@ -1,5 +1,5 @@
{ {
version = "2024-04-24-01"; version = "2024-02-29-01";
src-hash = "sha256-+FjthJZb1KqqFttFmXr/FN5qaFcY9RGTKAqhdLGVFSg="; src-hash = "sha256-YHK86sQMaa0Oa40uNMXDs25lPR9RkDnkzMcMFW+djYQ=";
deps-hash = "sha256-Vj8WCB+LSHJM67qbsZ5CPc+jK1KWO1MXnSFp/LH0Ow8="; deps-hash = "sha256-9HbZtk0sgBSWzzFrjXnSyEVWaQMiyC1v89vXB0UK9Hc=";
} }

View file

@ -0,0 +1,19 @@
diff --git a/config/secrets.yml b/config/secrets.yml
index 866fa6159..6fd49ee59 100644
--- a/config/secrets.yml
+++ b/config/secrets.yml
@@ -23,10 +23,10 @@ defaults: &defaults
identifier: <%= ENV['FC_PARTICULIER_ID'] %>
secret: <%= ENV['FC_PARTICULIER_SECRET'] %>
redirect_uri: https://<%= ENV['APP_HOST'] %>/france_connect/particulier/callback
- authorization_endpoint: <%= ENV['FC_PARTICULIER_BASE_URL'] %>/api/v1/authorize
- token_endpoint: <%= ENV['FC_PARTICULIER_BASE_URL'] %>/api/v1/token
- userinfo_endpoint: <%= ENV['FC_PARTICULIER_BASE_URL'] %>/api/v1/userinfo
- logout_endpoint: <%= ENV['FC_PARTICULIER_BASE_URL'] %>/api/v1/logout
+ authorization_endpoint: <%= ENV['FC_PARTICULIER_BASE_URL'] %>/ui/oauth2
+ token_endpoint: <%= ENV['FC_PARTICULIER_BASE_URL'] %>/oauth2/token
+ userinfo_endpoint: <%= ENV['FC_PARTICULIER_BASE_URL'] %>/oauth2/openid/demarches_dgn/userinfo
+ logout_endpoint: <%= ENV['FC_PARTICULIER_BASE_URL'] %>/oauth2/token/revoke
agent_connect:
identifier: <%= ENV['AGENT_CONNECT_ID'] %>
secret: <%= ENV['AGENT_CONNECT_SECRET'] %>

View file

@ -10,7 +10,6 @@ gem 'active_storage_validations'
gem 'addressable' gem 'addressable'
gem 'administrate' gem 'administrate'
gem 'administrate-field-enum' # Allow using Field::Enum in administrate gem 'administrate-field-enum' # Allow using Field::Enum in administrate
gem 'after_commit_everywhere'
gem 'after_party' gem 'after_party'
gem 'ancestry' gem 'ancestry'
gem 'anchored' gem 'anchored'
@ -23,24 +22,21 @@ gem 'chunky_png'
gem 'clamav-client', require: 'clamav/client' gem 'clamav-client', require: 'clamav/client'
gem 'daemons' gem 'daemons'
gem 'deep_cloneable' # Enable deep clone of active record models gem 'deep_cloneable' # Enable deep clone of active record models
gem 'delayed_cron_job', require: false # Cron jobs gem 'delayed_cron_job' # Cron jobs
gem 'delayed_job_active_record' gem 'delayed_job_active_record'
gem 'delayed_job_web' gem 'delayed_job_web'
gem 'devise' gem 'devise', git: 'https://github.com/heartcombo/devise.git', ref: "edffc79bf05d7f1c58ba50ffeda645e2e4ae0cb1" # Gestion des comptes utilisateurs, drop ref on next release: 4.9.4
gem 'devise-i18n' gem 'devise-i18n'
gem 'devise-two-factor' gem 'devise-two-factor'
gem 'discard' gem 'discard'
gem 'dotenv-rails', require: 'dotenv/rails-now' # dotenv should always be loaded before rails gem 'dotenv-rails', require: 'dotenv/rails-now' # dotenv should always be loaded before rails
gem 'dry-monads' gem 'dry-monads'
gem 'faraday-jwt'
gem 'flipper' gem 'flipper'
gem 'flipper-active_record' gem 'flipper-active_record'
gem 'flipper-active_support_cache_store'
gem 'flipper-ui' gem 'flipper-ui'
gem 'fugit' gem 'fugit'
gem 'geocoder' gem 'geocoder'
gem 'geo_coord', require: "geo/coord" gem 'geo_coord', require: "geo/coord"
gem 'gitlab-sidekiq-fetcher', require: 'sidekiq-reliable-fetch', git: 'https://github.com/demarches-simplifiees/reliable-fetch.git'
gem 'gon' gem 'gon'
gem 'graphql', '2.0.24' gem 'graphql', '2.0.24'
gem 'graphql-batch', '0.5.1' gem 'graphql-batch', '0.5.1'
@ -77,7 +73,6 @@ gem 'puma' # Use Puma as the app server
gem 'pundit' gem 'pundit'
gem 'rack-attack' gem 'rack-attack'
gem 'rails-i18n' # Locales par défaut gem 'rails-i18n' # Locales par défaut
gem 'rails-pg-extras'
gem 'rake-progressbar', require: false gem 'rake-progressbar', require: false
gem 'redcarpet' gem 'redcarpet'
gem 'redis' gem 'redis'
@ -91,23 +86,15 @@ gem 'sentry-ruby'
gem 'sentry-sidekiq' gem 'sentry-sidekiq'
gem 'sib-api-v3-sdk' gem 'sib-api-v3-sdk'
gem 'sidekiq' gem 'sidekiq'
gem 'sidekiq-cron'
gem 'skylight' gem 'skylight'
gem 'spreadsheet_architect' gem 'spreadsheet_architect'
gem 'strong_migrations' # lint database migrations gem 'strong_migrations' # lint database migrations
gem 'sys-proctable'
gem 'turbo-rails' gem 'turbo-rails'
gem 'typhoeus' gem 'typhoeus'
gem 'ulid-ruby', require: 'ulid' gem 'ulid-ruby', require: 'ulid'
gem 'view_component' gem 'view_component'
gem 'vite_rails' gem 'vite_rails'
gem 'warden' gem 'warden'
gem 'webrick', require: false
gem 'yabeda-graphql'
gem 'yabeda-prometheus'
gem 'yabeda-puma-plugin'
gem 'yabeda-rails'
gem 'yabeda-sidekiq'
gem 'zipline' gem 'zipline'
gem 'zxcvbn-ruby', require: 'zxcvbn' gem 'zxcvbn-ruby', require: 'zxcvbn'
@ -125,8 +112,6 @@ group :test do
gem 'selenium-devtools' gem 'selenium-devtools'
gem 'selenium-webdriver' gem 'selenium-webdriver'
gem 'shoulda-matchers', require: false gem 'shoulda-matchers', require: false
gem 'simplecov', require: false
gem 'simplecov-cobertura', require: false
gem 'timecop' gem 'timecop'
gem 'vcr' gem 'vcr'
gem 'webmock' gem 'webmock'

View file

@ -1,10 +1,14 @@
GIT GIT
remote: https://github.com/demarches-simplifiees/reliable-fetch.git remote: https://github.com/heartcombo/devise.git
revision: f547a270c402b0180091516d790434e83287fae7 revision: edffc79bf05d7f1c58ba50ffeda645e2e4ae0cb1
ref: edffc79bf05d7f1c58ba50ffeda645e2e4ae0cb1
specs: specs:
gitlab-sidekiq-fetcher (0.11.0) devise (4.9.3)
json (>= 2.5) bcrypt (~> 3.0)
sidekiq (~> 7.0) orm_adapter (~> 0.1)
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
@ -104,15 +108,10 @@ GEM
administrate-field-enum (0.0.9) administrate-field-enum (0.0.9)
administrate (~> 0.12) administrate (~> 0.12)
aes_key_wrap (1.1.0) aes_key_wrap (1.1.0)
after_commit_everywhere (1.4.0)
activerecord (>= 4.2)
activesupport
after_party (1.11.2) after_party (1.11.2)
ancestry (4.3.3) ancestry (4.3.3)
activerecord (>= 5.2.6) activerecord (>= 5.2.6)
anchored (1.1.0) anchored (1.1.0)
anyway_config (2.6.3)
ruby-next-core (~> 1.0)
ast (2.4.2) ast (2.4.2)
attr_required (1.0.2) attr_required (1.0.2)
axe-core-api (4.8.2) axe-core-api (4.8.2)
@ -136,8 +135,8 @@ GEM
erubi (~> 1.4) erubi (~> 1.4)
parser (>= 2.4) parser (>= 2.4)
smart_properties smart_properties
bigdecimal (3.1.7) bigdecimal (3.1.6)
bindata (2.5.0) bindata (2.4.15)
bindex (0.8.1) bindex (0.8.1)
bootsnap (1.18.3) bootsnap (1.18.3)
msgpack (~> 1.2) msgpack (~> 1.2)
@ -168,7 +167,7 @@ GEM
nokogiri (~> 1.10, >= 1.10.4) nokogiri (~> 1.10, >= 1.10.4)
rubyzip (>= 1.3.0, < 3) rubyzip (>= 1.3.0, < 3)
charlock_holmes (0.7.7) charlock_holmes (0.7.7)
chartkick (5.0.6) chartkick (5.0.5)
choice (0.2.0) choice (0.2.0)
chunky_png (1.4.0) chunky_png (1.4.0)
clamav-client (3.2.0) clamav-client (3.2.0)
@ -201,12 +200,6 @@ GEM
sinatra (>= 1.4.4) sinatra (>= 1.4.4)
descendants_tracker (0.0.4) descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1) thread_safe (~> 0.3, >= 0.3.1)
devise (4.9.4)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
devise-i18n (1.12.0) devise-i18n (1.12.0)
devise (>= 4.9.0) devise (>= 4.9.0)
devise-two-factor (5.0.0) devise-two-factor (5.0.0)
@ -217,7 +210,6 @@ GEM
diff-lcs (1.5.1) diff-lcs (1.5.1)
discard (1.3.0) discard (1.3.0)
activerecord (>= 4.2, < 8) activerecord (>= 4.2, < 8)
docile (1.4.0)
dotenv (2.8.1) dotenv (2.8.1)
dotenv-rails (2.8.1) dotenv-rails (2.8.1)
dotenv (= 2.8.1) dotenv (= 2.8.1)
@ -226,40 +218,25 @@ GEM
dry-core (1.0.1) dry-core (1.0.1)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
zeitwerk (~> 2.6) zeitwerk (~> 2.6)
dry-initializer (3.1.1)
dry-monads (1.6.0) dry-monads (1.6.0)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
dry-core (~> 1.0, < 2) dry-core (~> 1.0, < 2)
zeitwerk (~> 2.6) zeitwerk (~> 2.6)
dumb_delegator (1.0.0) dumb_delegator (1.0.0)
email_validator (2.2.4)
activemodel
erubi (1.12.0) erubi (1.12.0)
et-orbi (1.2.11) et-orbi (1.2.7)
tzinfo tzinfo
ethon (0.16.0) ethon (0.16.0)
ffi (>= 1.15.0) ffi (>= 1.15.0)
excon (0.109.0) excon (0.109.0)
factory_bot (6.4.6) factory_bot (6.4.6)
activesupport (>= 5.0.0) activesupport (>= 5.0.0)
faraday (2.9.0)
faraday-net_http (>= 2.0, < 3.2)
faraday-follow_redirects (0.3.0)
faraday (>= 1, < 3)
faraday-jwt (0.1.0)
faraday (~> 2.0)
json-jwt (~> 1.16)
faraday-net_http (3.1.0)
net-http
ffi (1.16.3) ffi (1.16.3)
flipper (1.2.2) flipper (1.2.2)
concurrent-ruby (< 2) concurrent-ruby (< 2)
flipper-active_record (1.2.2) flipper-active_record (1.2.2)
activerecord (>= 4.2, < 8) activerecord (>= 4.2, < 8)
flipper (~> 1.2.2) flipper (~> 1.2.2)
flipper-active_support_cache_store (1.2.2)
activesupport (>= 4.2, < 8)
flipper (~> 1.2.2)
flipper-ui (1.2.2) flipper-ui (1.2.2)
erubi (>= 1.0.0, < 2.0.0) erubi (>= 1.0.0, < 2.0.0)
flipper (~> 1.2.2) flipper (~> 1.2.2)
@ -278,7 +255,7 @@ GEM
fog-core (~> 2.1) fog-core (~> 2.1)
fog-json (>= 1.0) fog-json (>= 1.0)
formatador (1.1.0) formatador (1.1.0)
fugit (1.10.1) fugit (1.9.0)
et-orbi (~> 1, >= 1.2.7) et-orbi (~> 1, >= 1.2.7)
raabro (~> 1.4) raabro (~> 1.4)
geo_coord (0.2.0) geo_coord (0.2.0)
@ -328,7 +305,8 @@ GEM
highline (3.0.1) highline (3.0.1)
htmlentities (4.3.4) htmlentities (4.3.4)
http_accept_language (2.1.1) http_accept_language (2.1.1)
i18n (1.14.4) httpclient (2.8.3)
i18n (1.14.1)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
i18n-tasks (1.0.13) i18n-tasks (1.0.13)
activesupport (>= 4.0.2) activesupport (>= 4.0.2)
@ -350,7 +328,7 @@ GEM
invisible_captcha (2.2.0) invisible_captcha (2.2.0)
rails (>= 5.2) rails (>= 5.2)
io-console (0.7.2) io-console (0.7.2)
irb (1.12.0) irb (1.11.2)
rdoc rdoc
reline (>= 0.4.2) reline (>= 0.4.2)
job-iteration (1.4.1) job-iteration (1.4.1)
@ -359,23 +337,17 @@ GEM
rails-dom-testing (>= 1, < 3) rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0) railties (>= 4.2.0)
thor (>= 0.14, < 2.0) thor (>= 0.14, < 2.0)
json (2.7.2) json (2.7.1)
json-jwt (1.16.6) json-jwt (1.13.0)
activesupport (>= 4.2) activesupport (>= 4.2)
aes_key_wrap aes_key_wrap
base64
bindata bindata
faraday (~> 2.0) json_schemer (2.1.1)
faraday-follow_redirects
json_schemer (2.2.1)
base64
bigdecimal
hana (~> 1.3) hana (~> 1.3)
regexp_parser (~> 2.0) regexp_parser (~> 2.0)
simpleidn (~> 0.2) simpleidn (~> 0.2)
jsonapi-renderer (0.2.2) jsonapi-renderer (0.2.2)
jwt (2.8.1) jwt (2.7.1)
base64
kaminari (1.2.2) kaminari (1.2.2)
activesupport (>= 4.1.0) activesupport (>= 4.1.0)
kaminari-actionview (= 1.2.2) kaminari-actionview (= 1.2.2)
@ -402,7 +374,7 @@ GEM
letter_opener (~> 1.7) letter_opener (~> 1.7)
railties (>= 5.2) railties (>= 5.2)
rexml rexml
listen (3.9.0) listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3) rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10) rb-inotify (~> 0.9, >= 0.9.10)
lograge (0.14.0) lograge (0.14.0)
@ -419,7 +391,7 @@ GEM
net-imap net-imap
net-pop net-pop
net-smtp net-smtp
maintenance_tasks (2.7.0) maintenance_tasks (2.6.0)
actionpack (>= 6.0) actionpack (>= 6.0)
activejob (>= 6.0) activejob (>= 6.0)
activerecord (>= 6.0) activerecord (>= 6.0)
@ -429,7 +401,7 @@ GEM
marcel (1.0.2) marcel (1.0.2)
matrix (0.4.2) matrix (0.4.2)
memory_profiler (1.0.1) memory_profiler (1.0.1)
method_source (1.1.0) method_source (1.0.0)
mime-types (3.5.2) mime-types (3.5.2)
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2024.0206) mime-types-data (3.2024.0206)
@ -437,14 +409,12 @@ GEM
rake rake
mini_magick (4.12.0) mini_magick (4.12.0)
mini_mime (1.1.5) mini_mime (1.1.5)
mini_portile2 (2.8.6) mini_portile2 (2.8.5)
minitest (5.22.3) minitest (5.22.2)
msgpack (1.7.2) msgpack (1.7.2)
multi_json (1.15.0) multi_json (1.15.0)
mustermann (3.0.0) mustermann (3.0.0)
ruby2_keywords (~> 0.0.1) ruby2_keywords (~> 0.0.1)
net-http (0.4.1)
uri
net-imap (0.4.10) net-imap (0.4.10)
date date
net-protocol net-protocol
@ -454,23 +424,20 @@ GEM
timeout timeout
net-smtp (0.4.0.1) net-smtp (0.4.0.1)
net-protocol net-protocol
nio4r (2.7.1) nio4r (2.7.0)
nokogiri (1.16.4) nokogiri (1.16.2)
mini_portile2 (~> 2.8.2) mini_portile2 (~> 2.8.2)
racc (~> 1.4) racc (~> 1.4)
openid_connect (2.3.0) openid_connect (1.3.0)
activemodel activemodel
attr_required (>= 1.0.0) attr_required (>= 1.0.0)
email_validator json-jwt (>= 1.5.0)
faraday (~> 2.0) rack-oauth2 (>= 1.6.1)
faraday-follow_redirects swd (>= 1.0.0)
json-jwt (>= 1.16)
mail
rack-oauth2 (~> 2.2)
swd (~> 2.0)
tzinfo tzinfo
validate_email
validate_url validate_url
webfinger (~> 2.0) webfinger (>= 1.0.1)
orm_adapter (0.5.0) orm_adapter (0.5.0)
parallel (1.24.0) parallel (1.24.0)
parsby (1.1.1) parsby (1.1.1)
@ -478,8 +445,8 @@ GEM
ast (~> 2.4.1) ast (~> 2.4.1)
racc racc
pdf-core (0.9.0) pdf-core (0.9.0)
pg (1.5.6) pg (1.5.4)
phonelib (0.8.8) phonelib (0.8.7)
prawn (2.4.0) prawn (2.4.0)
pdf-core (~> 0.9.0) pdf-core (~> 0.9.0)
ttfunk (~> 1.7) ttfunk (~> 1.7)
@ -497,27 +464,25 @@ GEM
actionmailer (>= 3) actionmailer (>= 3)
net-smtp net-smtp
premailer (~> 1.7, >= 1.7.9) premailer (~> 1.7, >= 1.7.9)
prometheus-client (4.2.2)
promise.rb (0.7.4) promise.rb (0.7.4)
psych (5.1.2) psych (5.1.2)
stringio stringio
public_suffix (5.0.5) public_suffix (5.0.4)
puma (6.4.2) puma (6.4.2)
nio4r (~> 2.0) nio4r (~> 2.0)
pundit (2.3.1) pundit (2.3.1)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
raabro (1.4.0) raabro (1.4.0)
racc (1.7.3) racc (1.7.3)
rack (2.2.9) rack (2.2.8.1)
rack-attack (6.7.0) rack-attack (6.7.0)
rack (>= 1.0, < 4) rack (>= 1.0, < 4)
rack-mini-profiler (3.3.1) rack-mini-profiler (3.3.1)
rack (>= 1.2.0) rack (>= 1.2.0)
rack-oauth2 (2.2.1) rack-oauth2 (1.19.0)
activesupport activesupport
attr_required attr_required
faraday (~> 2.0) httpclient
faraday-follow_redirects
json-jwt (>= 1.11.0) json-jwt (>= 1.11.0)
rack (>= 2.1.0) rack (>= 2.1.0)
rack-protection (3.2.0) rack-protection (3.2.0)
@ -560,12 +525,9 @@ GEM
rails-html-sanitizer (1.6.0) rails-html-sanitizer (1.6.0)
loofah (~> 2.21) loofah (~> 2.21)
nokogiri (~> 1.14) nokogiri (~> 1.14)
rails-i18n (7.0.9) rails-i18n (7.0.8)
i18n (>= 0.7, < 2) i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8) railties (>= 6.0.0, < 8)
rails-pg-extras (5.3.1)
rails
ruby-pg-extras (= 5.3.1)
railties (7.0.8.1) railties (7.0.8.1)
actionpack (= 7.0.8.1) actionpack (= 7.0.8.1)
activesupport (= 7.0.8.1) activesupport (= 7.0.8.1)
@ -574,20 +536,20 @@ GEM
thor (~> 1.0) thor (~> 1.0)
zeitwerk (~> 2.5) zeitwerk (~> 2.5)
rainbow (3.1.1) rainbow (3.1.1)
rake (13.2.1) rake (13.1.0)
rake-progressbar (0.0.5) rake-progressbar (0.0.5)
rb-fsevent (0.11.2) rb-fsevent (0.11.2)
rb-inotify (0.10.1) rb-inotify (0.10.1)
ffi (~> 1.0) ffi (~> 1.0)
rdoc (6.6.3.1) rdoc (6.6.2)
psych (>= 4.0.0) psych (>= 4.0.0)
redcarpet (3.6.0) redcarpet (3.6.0)
redis (5.2.0) redis (5.1.0)
redis-client (>= 0.22.0) redis-client (>= 0.17.0)
redis-client (0.22.1) redis-client (0.20.0)
connection_pool connection_pool
regexp_parser (2.9.0) regexp_parser (2.9.0)
reline (0.5.3) reline (0.4.2)
io-console (~> 0.5) io-console (~> 0.5)
request_store (1.5.1) request_store (1.5.1)
rack (>= 1.4) rack (>= 1.4)
@ -612,20 +574,20 @@ GEM
rspec-mocks (3.13.0) rspec-mocks (3.13.0)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0) rspec-support (~> 3.13.0)
rspec-rails (6.1.2) rspec-rails (6.1.1)
actionpack (>= 6.1) actionpack (>= 6.1)
activesupport (>= 6.1) activesupport (>= 6.1)
railties (>= 6.1) railties (>= 6.1)
rspec-core (~> 3.13) rspec-core (~> 3.12)
rspec-expectations (~> 3.13) rspec-expectations (~> 3.12)
rspec-mocks (~> 3.13) rspec-mocks (~> 3.12)
rspec-support (~> 3.13) rspec-support (~> 3.12)
rspec-retry (0.6.2) rspec-retry (0.6.2)
rspec-core (> 3.3) rspec-core (> 3.3)
rspec-support (3.13.1) rspec-support (3.13.0)
rspec_junit_formatter (0.6.0) rspec_junit_formatter (0.6.0)
rspec-core (>= 2, < 4, != 2.12.0) rspec-core (>= 2, < 4, != 2.12.0)
rubocop (1.63.3) rubocop (1.60.2)
json (~> 2.3) json (~> 2.3)
language_server-protocol (>= 3.17.0) language_server-protocol (>= 3.17.0)
parallel (~> 1.10) parallel (~> 1.10)
@ -633,36 +595,29 @@ GEM
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0) regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0) rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.31.1, < 2.0) rubocop-ast (>= 1.30.0, < 2.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0) unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.31.2) rubocop-ast (1.30.0)
parser (>= 3.3.0.4) parser (>= 3.2.1.0)
rubocop-capybara (2.20.0) rubocop-capybara (2.20.0)
rubocop (~> 1.41) rubocop (~> 1.41)
rubocop-factory_bot (2.25.1) rubocop-factory_bot (2.25.1)
rubocop (~> 1.41) rubocop (~> 1.41)
rubocop-performance (1.21.0) rubocop-performance (1.20.2)
rubocop (>= 1.48.1, < 2.0) rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0) rubocop-ast (>= 1.30.0, < 2.0)
rubocop-rails (2.24.1) rubocop-rails (2.23.1)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
rack (>= 1.1) rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0) rubocop (>= 1.33.0, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0) rubocop-ast (>= 1.30.0, < 2.0)
rubocop-rspec (2.29.1) rubocop-rspec (2.26.1)
rubocop (~> 1.40) rubocop (~> 1.40)
rubocop-capybara (~> 2.17) rubocop-capybara (~> 2.17)
rubocop-factory_bot (~> 2.22) rubocop-factory_bot (~> 2.22)
rubocop-rspec_rails (~> 2.28)
rubocop-rspec_rails (2.28.3)
rubocop (~> 1.40)
ruby-graphviz (1.2.5) ruby-graphviz (1.2.5)
rexml rexml
ruby-next-core (1.0.2)
ruby-pg-extras (5.3.1)
pg
terminal-table
ruby-progressbar (1.13.0) ruby-progressbar (1.13.0)
ruby-vips (2.2.0) ruby-vips (2.2.0)
ffi (~> 1.12) ffi (~> 1.12)
@ -693,52 +648,38 @@ GEM
scss_lint (0.60.0) scss_lint (0.60.0)
sass (~> 3.5, >= 3.5.5) sass (~> 3.5, >= 3.5.5)
selectize-rails (0.12.6) selectize-rails (0.12.6)
selenium-devtools (0.123.0) selenium-devtools (0.121.0)
selenium-webdriver (~> 4.2) selenium-webdriver (~> 4.2)
selenium-webdriver (4.19.0) selenium-webdriver (4.17.0)
base64 (~> 0.2) base64 (~> 0.2)
rexml (~> 3.2, >= 3.2.5) rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0) rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0) websocket (~> 1.0)
sentry-delayed_job (5.17.3) sentry-delayed_job (5.16.1)
delayed_job (>= 4.0) delayed_job (>= 4.0)
sentry-ruby (~> 5.17.3) sentry-ruby (~> 5.16.1)
sentry-rails (5.17.3) sentry-rails (5.16.1)
railties (>= 5.0) railties (>= 5.0)
sentry-ruby (~> 5.17.3) sentry-ruby (~> 5.16.1)
sentry-ruby (5.17.3) sentry-ruby (5.16.1)
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2) concurrent-ruby (~> 1.0, >= 1.0.2)
sentry-sidekiq (5.17.3) sentry-sidekiq (5.16.1)
sentry-ruby (~> 5.17.3) sentry-ruby (~> 5.16.1)
sidekiq (>= 3.0) sidekiq (>= 3.0)
shoulda-matchers (6.2.0) shoulda-matchers (6.1.0)
activesupport (>= 5.2.0) activesupport (>= 5.2.0)
sib-api-v3-sdk (9.1.0) sib-api-v3-sdk (9.1.0)
addressable (~> 2.3, >= 2.3.0) addressable (~> 2.3, >= 2.3.0)
json (~> 2.1, >= 2.1.0) json (~> 2.1, >= 2.1.0)
typhoeus (~> 1.0, >= 1.0.1) typhoeus (~> 1.0, >= 1.0.1)
sidekiq (7.2.2) sidekiq (7.2.1)
concurrent-ruby (< 2) concurrent-ruby (< 2)
connection_pool (>= 2.3.0) connection_pool (>= 2.3.0)
rack (>= 2.2.4) rack (>= 2.2.4)
redis-client (>= 0.19.0) redis-client (>= 0.19.0)
sidekiq-cron (1.12.0)
fugit (~> 1.8)
globalid (>= 1.0.1)
sidekiq (>= 6)
simple_xlsx_reader (1.0.4) simple_xlsx_reader (1.0.4)
nokogiri nokogiri
rubyzip rubyzip
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-cobertura (2.1.0)
rexml
simplecov (~> 0.19)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4)
simpleidn (0.2.1) simpleidn (0.2.1)
unf (~> 0.1.4) unf (~> 0.1.4)
sinatra (3.2.0) sinatra (3.2.0)
@ -746,13 +687,13 @@ GEM
rack (~> 2.2, >= 2.2.4) rack (~> 2.2, >= 2.2.4)
rack-protection (= 3.2.0) rack-protection (= 3.2.0)
tilt (~> 2.0) tilt (~> 2.0)
skylight (6.0.4) skylight (6.0.3)
activesupport (>= 5.2.0) activesupport (>= 5.2.0)
smart_properties (1.17.0) smart_properties (1.17.0)
spreadsheet_architect (5.0.0) spreadsheet_architect (5.0.0)
caxlsx (>= 3.3.0, < 4) caxlsx (>= 3.3.0, < 4)
rodf (>= 1.0.0, < 2) rodf (>= 1.0.0, < 2)
spring (4.2.1) spring (4.1.3)
spring-commands-rspec (1.0.4) spring-commands-rspec (1.0.4)
spring (>= 0.9.1) spring (>= 0.9.1)
sprockets (4.2.1) sprockets (4.2.1)
@ -764,26 +705,23 @@ GEM
sprockets (>= 3.0.0) sprockets (>= 3.0.0)
stackprof (0.2.26) stackprof (0.2.26)
stringio (3.1.0) stringio (3.1.0)
strong_migrations (1.8.0) strong_migrations (1.7.0)
activerecord (>= 5.2) activerecord (>= 5.2)
swd (2.0.3) swd (1.3.0)
activesupport (>= 3) activesupport (>= 3)
attr_required (>= 0.0.5) attr_required (>= 0.0.5)
faraday (~> 2.0) httpclient (>= 2.4)
faraday-follow_redirects
sys-proctable (1.3.0)
ffi (~> 1.1)
sysexits (1.2.0) sysexits (1.2.0)
temple (0.8.2) temple (0.8.2)
terminal-table (3.0.2) terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3) unicode-display_width (>= 1.1.1, < 3)
thor (1.3.1) thor (1.3.0)
thread_safe (0.3.6) thread_safe (0.3.6)
tilt (2.3.0) tilt (2.3.0)
timecop (0.9.8) timecop (0.9.8)
timeout (0.4.1) timeout (0.4.1)
ttfunk (1.7.0) ttfunk (1.7.0)
turbo-rails (2.0.5) turbo-rails (2.0.2)
actionpack (>= 6.0.0) actionpack (>= 6.0.0)
activejob (>= 6.0.0) activejob (>= 6.0.0)
railties (>= 6.0.0) railties (>= 6.0.0)
@ -796,12 +734,14 @@ GEM
unf_ext unf_ext
unf_ext (0.0.9.1) unf_ext (0.0.9.1)
unicode-display_width (2.5.0) unicode-display_width (2.5.0)
uri (0.13.0) validate_email (0.1.6)
activemodel (>= 3.0)
mail (>= 2.2.5)
validate_url (1.0.15) validate_url (1.0.15)
activemodel (>= 3.0.0) activemodel (>= 3.0.0)
public_suffix public_suffix
vcr (6.2.0) vcr (6.2.0)
view_component (3.12.1) view_component (3.10.0)
activesupport (>= 5.2.0, < 8.0) activesupport (>= 5.2.0, < 8.0)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
method_source (~> 1.0) method_source (~> 1.0)
@ -823,15 +763,13 @@ GEM
activemodel (>= 6.0.0) activemodel (>= 6.0.0)
bindex (>= 0.4.0) bindex (>= 0.4.0)
railties (>= 6.0.0) railties (>= 6.0.0)
webfinger (2.1.3) webfinger (1.2.0)
activesupport activesupport
faraday (~> 2.0) httpclient (>= 2.4)
faraday-follow_redirects webmock (3.20.0)
webmock (3.23.0)
addressable (>= 2.8.0) addressable (>= 2.8.0)
crack (>= 0.3.2) crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0) hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.8.1)
websocket (1.2.10) websocket (1.2.10)
websocket-driver (0.7.6) websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
@ -845,30 +783,6 @@ GEM
nokogiri (~> 1.11) nokogiri (~> 1.11)
xpath (3.2.0) xpath (3.2.0)
nokogiri (~> 1.8) nokogiri (~> 1.8)
yabeda (0.12.0)
anyway_config (>= 1.0, < 3)
concurrent-ruby
dry-initializer
yabeda-graphql (0.2.3)
graphql (>= 1.9, < 3)
yabeda (~> 0.2)
yabeda-prometheus (0.9.1)
prometheus-client (>= 3.0, < 5.0)
rack
yabeda (~> 0.10)
yabeda-puma-plugin (0.7.1)
json
puma
yabeda (~> 0.5)
yabeda-rails (0.9.0)
activesupport
anyway_config (>= 1.3, < 3)
railties
yabeda (~> 0.8)
yabeda-sidekiq (0.12.0)
anyway_config (>= 1.3, < 3)
sidekiq
yabeda (~> 0.6)
zeitwerk (2.6.13) zeitwerk (2.6.13)
zip_tricks (5.6.0) zip_tricks (5.6.0)
zipline (1.5.0) zipline (1.5.0)
@ -889,7 +803,6 @@ DEPENDENCIES
addressable addressable
administrate administrate
administrate-field-enum administrate-field-enum
after_commit_everywhere
after_party after_party
ancestry ancestry
anchored anchored
@ -911,22 +824,19 @@ DEPENDENCIES
delayed_cron_job delayed_cron_job
delayed_job_active_record delayed_job_active_record
delayed_job_web delayed_job_web
devise devise!
devise-i18n devise-i18n
devise-two-factor devise-two-factor
discard discard
dotenv-rails dotenv-rails
dry-monads dry-monads
factory_bot factory_bot
faraday-jwt
flipper flipper
flipper-active_record flipper-active_record
flipper-active_support_cache_store
flipper-ui flipper-ui
fugit fugit
geo_coord geo_coord
geocoder geocoder
gitlab-sidekiq-fetcher!
gon gon
graphql (= 2.0.24) graphql (= 2.0.24)
graphql-batch (= 0.5.1) graphql-batch (= 0.5.1)
@ -975,7 +885,6 @@ DEPENDENCIES
rails-controller-testing rails-controller-testing
rails-erd rails-erd
rails-i18n rails-i18n
rails-pg-extras
rake-progressbar rake-progressbar
redcarpet redcarpet
redis redis
@ -1000,17 +909,13 @@ DEPENDENCIES
shoulda-matchers shoulda-matchers
sib-api-v3-sdk sib-api-v3-sdk
sidekiq sidekiq
sidekiq-cron
simple_xlsx_reader simple_xlsx_reader
simplecov
simplecov-cobertura
skylight skylight
spreadsheet_architect spreadsheet_architect
spring spring
spring-commands-rspec spring-commands-rspec
stackprof stackprof
strong_migrations strong_migrations
sys-proctable
timecop timecop
turbo-rails turbo-rails
typhoeus typhoeus
@ -1021,14 +926,8 @@ DEPENDENCIES
warden warden
web-console web-console
webmock webmock
webrick
yabeda-graphql
yabeda-prometheus
yabeda-puma-plugin
yabeda-rails
yabeda-sidekiq
zipline zipline
zxcvbn-ruby zxcvbn-ruby
BUNDLED WITH BUNDLED WITH
2.5.9 2.5.4

File diff suppressed because it is too large Load diff

View file

@ -26,13 +26,13 @@ done
CWD=$(pwd) CWD=$(pwd)
TMP=$(mktemp -d) TMP=$(mktemp -d)
cd "$TMP" || exit 1 cd "$TMP"
# Fetch the latest source or the required version # Fetch the latest source or the required version
gitUrl="https://github.com/demarches-simplifiees/demarches-simplifiees.fr.git" gitUrl="https://github.com/demarches-simplifiees/demarches-simplifiees.fr.git"
if [ -n "$version" ]; then if [ -n "$version" ]; then
git clone --depth 1 --branch "$version" $gitUrl . git clone --depth 1 --branch $version $gitUrl .
else else
git clone --depth 1 $gitUrl . git clone --depth 1 $gitUrl .
@ -48,10 +48,10 @@ cp gemset.nix Gemfile Gemfile.lock "$CWD/rubyEnv/"
# Print the new source details # Print the new source details
SRC_HASH=$(nix-shell -p nurl --run "nurl --hash $gitUrl $version") SRC_HASH=$(nix-shell -p nurl --run "nurl --hash $gitUrl $version")
# Switch to bun # Print Yarn deps hash
nix-shell -p bun --run "bun install --frozen-lockfile --no-cache --no-progress --ignore-scripts" hash=$(nix-shell -p prefetch-yarn-deps --run "prefetch-yarn-deps yarn.lock")
DEPS_HASH=$(nix-hash --sri --type sha256 node_modules) DEPS_HASH=$(nix-hash --to-sri --type sha256 "$hash")
cat <<EOF >"$CWD/meta.nix" cat <<EOF >"$CWD/meta.nix"
{ {
@ -61,6 +61,6 @@ cat <<EOF >"$CWD/meta.nix"
} }
EOF EOF
nix-shell -p nixfmt-rfc-style --run "nixfmt $CWD" nixfmt "$CWD"
rm -rf "$TMP" rm -rf "$TMP"

View file

@ -69,11 +69,17 @@ in
} }
]; ];
}; };
};
dgn-web.simpleProxies.grafana = { nginx.virtualHosts.${host} = {
inherit host port; enableACME = true;
proxyWebsockets = true; forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${builtins.toString port}";
proxyWebsockets = true;
recommendedProxySettings = true;
};
};
}; };
age-secrets.autoMatch = [ "grafana" ]; age-secrets.autoMatch = [ "grafana" ];

View file

@ -29,6 +29,16 @@ in
}; };
}; };
nginx.virtualHosts.${host} = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${builtins.toString port}";
proxyWebsockets = true;
};
};
postgresql = { postgresql = {
enable = true; enable = true;
@ -43,11 +53,6 @@ in
}; };
}; };
dgn-web.simpleProxies.hedgedoc = {
inherit host port;
proxyWebsockets = true;
};
systemd.services.hedgedoc.serviceConfig.StateDirectory = lib.mkForce [ systemd.services.hedgedoc.serviceConfig.StateDirectory = lib.mkForce [
"hedgedoc" "hedgedoc"
"hedgedoc/uploads" "hedgedoc/uploads"

View file

@ -1,4 +1,4 @@
{ config, ... }: { config, lib, ... }:
{ {
imports = [ ./module.nix ]; imports = [ ./module.nix ];
@ -6,15 +6,6 @@
services.k-radius = { services.k-radius = {
enable = true; enable = true;
domain = "radius.dgnum.eu";
radiusClients = {
ap = {
ipaddr = "0.0.0.0/0";
secret = config.age.secrets."radius-ap-radius-secret_file".path;
};
};
settings = { settings = {
# URL to the Kanidm server # URL to the Kanidm server
uri = "https://sso.dgnum.eu"; uri = "https://sso.dgnum.eu";
@ -49,6 +40,18 @@
}; };
authTokenFile = config.age.secrets."radius-auth_token_file".path; authTokenFile = config.age.secrets."radius-auth_token_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) [
"ca"
"cert"
"dh"
"key"
]
);
radiusClients = { };
}; };
age-secrets.autoMatch = [ "radius" ]; age-secrets.autoMatch = [ "radius" ];

View file

@ -0,0 +1,200 @@
{
config,
lib,
pkgs,
...
}:
let
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; };
rlm_python = pkgs.callPackage ./packages/rlm_python.nix { inherit pykanidm; };
cfg = config.services.k-radius;
in
{
options.services.k-radius = {
enable = mkEnableOption "a freeradius service linked to kanidm.";
settings = mkOption { inherit (settingsFormat) type; };
freeradius = mkOption {
type = types.package;
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.";
};
authTokenFile = mkOption {
type = types.path;
description = "File to the auth token for the service account.";
};
radiusClients = mkOption {
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.";
};
certs = {
ca = mkOption {
type = types.str;
description = "The signing CA of the RADIUS certificate.";
};
dh = mkOption {
type = types.str;
description = "The output of `openssl dhparam -in ca.pem -out dh.pem 2048`.";
};
cert = mkOption {
type = types.str;
description = "The certificate for the RADIUS server.";
};
key = mkOption {
type = types.str;
description = "The signing key for the RADIUS certificate.";
};
};
privateKeyPasswordFile = mkOption { type = types.path; };
};
config = mkIf cfg.enable {
users = {
users.radius = {
group = "radius";
description = "Radius daemon user";
isSystemUser = true;
};
groups.radius = { };
};
services.k-radius.settings = {
ca_path = cfg.certs.ca;
radius_cert_path = cfg.certs.cert;
radius_key_path = cfg.certs.key;
radius_dh_path = cfg.certs.dh;
radius_ca_path = cfg.certs.ca;
};
systemd.services.radius = {
description = "FreeRadius server";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
wants = [ "network.target" ];
preStart = ''
cp -R ${cfg.freeradius}/etc/raddb/* ${cfg.configDir}
cp -R ${rlm_python}/etc/raddb/* ${cfg.configDir}
chmod -R u+w ${cfg.configDir}
# disable auth via methods kanidm doesn't support
rm ${cfg.configDir}/mods-available/sql
rm ${cfg.configDir}/mods-enabled/{passwd,totp}
# enable the python and cache modules
ln -nsf ${cfg.configDir}/mods-available/python3 ${cfg.configDir}/mods-enabled/python3
ln -nsf ${cfg.configDir}/sites-available/check-eap-tls ${cfg.configDir}/sites-enabled/check-eap-tls
# write the clients configuration
rm ${cfg.configDir}/clients.conf && touch ${cfg.configDir}/clients.conf
${builtins.concatStringsSep "\n" (
builtins.attrValues (
builtins.mapAttrs
(
name:
{ secret, ipaddr }:
''
cat <<EOF >> ${cfg.configDir}/clients.conf
client ${name} {
ipaddr = ${ipaddr}
secret = $(cat "${secret}")
proto = *
}
EOF
''
)
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
chmod u+w /var/lib/radius/kanidm.toml
# Copy the certificates to the correct directory
rm -rf ${cfg.configDir}/certs && mkdir -p ${cfg.configDir}/certs
cp ${cfg.certs.ca} ${cfg.configDir}/certs/ca.pem
${pkgs.openssl}/bin/openssl rehash ${cfg.configDir}/certs
cp ${cfg.certs.dh} ${cfg.configDir}/certs/dh.pem
cat ${cfg.certs.cert} ${cfg.certs.key} > ${cfg.configDir}/certs/server.pem
# Write the password of the private_key in the eap module
sed -i ${cfg.configDir}/mods-available/eap \
-e "s/whatever/$(cat "${cfg.privateKeyPasswordFile}")/"
# Check the configuration
# ${pkgs.freeradius}/bin/radiusd -C -d ${cfg.configDir} -l stdout
'';
path = [
pkgs.openssl
pkgs.gnused
];
serviceConfig = {
ExecStart = "${cfg.freeradius}/bin/radiusd -X -f -d ${cfg.configDir} -l stdout";
ExecReload = [
"${cfg.freeradius}/bin/radiusd -C -d ${cfg.configDir} -l stdout"
"${pkgs.coreutils}/bin/kill -HUP $MAINPID"
];
User = "radius";
Group = "radius";
DynamicUser = true;
Restart = "on-failure";
RestartSec = 2;
LogsDirectory = "radius";
StateDirectory = "radius";
RuntimeDirectory = "radius";
Environment = [
"KANIDM_RLM_CONFIG=/var/lib/radius/kanidm.toml"
"PYTHONPATH=${rlm_python.pythonPath}"
];
};
};
};
}

View file

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

View file

@ -0,0 +1,18 @@
diff --git a/pyproject.toml b/pyproject.toml
index 1602e32..507048d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -72,13 +72,6 @@ filterwarnings = [
]
timeout = 30
xfail_strict = true
-# min, max, mean, stddev, median, iqr, outliers, ops, rounds, iterations
-addopts = [
- '--benchmark-columns', 'min,mean,stddev,outliers,rounds,iterations',
- '--benchmark-group-by', 'group',
- '--benchmark-warmup', 'on',
- '--benchmark-disable', # this is enable by `make benchmark` when you actually want to run benchmarks
-]
[tool.coverage.run]
source = ['pydantic_core']

View file

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

View file

@ -0,0 +1,84 @@
{
stdenv,
lib,
buildPythonPackage,
fetchFromGitHub,
cargo,
rustPlatform,
rustc,
libiconv,
typing-extensions,
pytestCheckHook,
hypothesis,
pytest-timeout,
pytest-mock,
dirty-equals,
}:
let
pydantic-core = buildPythonPackage rec {
pname = "pydantic-core";
version = "2.14.5";
format = "pyproject";
src = fetchFromGitHub {
owner = "pydantic";
repo = "pydantic-core";
rev = "refs/tags/v${version}";
hash = "sha256-UguZpA3KEutOgIavjx8Ie//0qJq+4FTZNQTwb/ZIgb8=";
};
patches = [ ./01-remove-benchmark-flags.patch ];
cargoDeps = rustPlatform.fetchCargoTarball {
inherit src;
name = "${pname}-${version}";
hash = "sha256-mMgw922QjHmk0yimXfolLNiYZntTsGydQywe7PTNnwc=";
};
nativeBuildInputs = [
cargo
rustPlatform.cargoSetupHook
rustPlatform.maturinBuildHook
rustc
typing-extensions
];
buildInputs = lib.optionals stdenv.isDarwin [ libiconv ];
propagatedBuildInputs = [ typing-extensions ];
pythonImportsCheck = [ "pydantic_core" ];
# escape infinite recursion with pydantic via dirty-equals
doCheck = false;
passthru.tests.pytest = pydantic-core.overrideAttrs { doCheck = true; };
nativeCheckInputs = [
pytestCheckHook
hypothesis
pytest-timeout
dirty-equals
pytest-mock
];
disabledTests = [
# RecursionError: maximum recursion depth exceeded while calling a Python object
"test_recursive"
];
disabledTestPaths = [
# no point in benchmarking in nixpkgs build farm
"tests/benchmarks"
];
meta = with lib; {
changelog = "https://github.com/pydantic/pydantic-core/releases/tag/v${version}";
description = "Core validation logic for pydantic written in rust";
homepage = "https://github.com/pydantic/pydantic-core";
license = licenses.mit;
maintainers = with maintainers; [ blaggacao ];
};
};
in
pydantic-core

View file

@ -0,0 +1,92 @@
{
lib,
buildPythonPackage,
fetchFromGitHub,
pythonOlder,
# build-system
hatchling,
hatch-fancy-pypi-readme,
# native dependencies
libxcrypt,
# dependencies
annotated-types,
pydantic-core,
typing-extensions,
# tests
cloudpickle,
email-validator,
dirty-equals,
faker,
pytestCheckHook,
pytest-mock,
}:
buildPythonPackage rec {
pname = "pydantic";
version = "2.5.2";
pyproject = true;
disabled = pythonOlder "3.7";
src = fetchFromGitHub {
owner = "pydantic";
repo = "pydantic";
rev = "refs/tags/v${version}";
hash = "sha256-D0gYcyrKVVDhBgV9sCVTkGq/kFmIoT9l0i5bRM1qxzM=";
};
buildInputs = lib.optionals (pythonOlder "3.9") [ libxcrypt ];
nativeBuildInputs = [
hatch-fancy-pypi-readme
hatchling
];
propagatedBuildInputs = [
annotated-types
pydantic-core
typing-extensions
];
passthru.optional-dependencies = {
email = [ email-validator ];
};
nativeCheckInputs = [
cloudpickle
dirty-equals
faker
pytest-mock
pytestCheckHook
] ++ lib.flatten (lib.attrValues passthru.optional-dependencies);
preCheck = ''
export HOME=$(mktemp -d)
substituteInPlace pyproject.toml \
--replace "'--benchmark-columns', 'min,mean,stddev,outliers,rounds,iterations'," "" \
--replace "'--benchmark-group-by', 'group'," "" \
--replace "'--benchmark-warmup', 'on'," "" \
--replace "'--benchmark-disable'," ""
'';
disabledTestPaths = [
"tests/benchmarks"
# avoid cyclic dependency
"tests/test_docs.py"
];
pythonImportsCheck = [ "pydantic" ];
meta = with lib; {
description = "Data validation and settings management using Python type hinting";
homepage = "https://github.com/pydantic/pydantic";
changelog = "https://github.com/pydantic/pydantic/blob/v${version}/HISTORY.md";
license = licenses.mit;
maintainers = with maintainers; [ wd15 ];
};
}

View file

@ -1,13 +1,13 @@
diff --git a/mods-available/python3 b/mods-available/python3 diff --git a/rlm_python/mods-available/python3 b/rlm_python/mods-available/python3
index 978536f8a..90c71fca0 100644 index 978536f8a..90c71fca0 100644
--- a/mods-available/python3 --- a/rlm_python/mods-available/python3
+++ b/mods-available/python3 +++ b/rlm_python/mods-available/python3
@@ -13,7 +13,7 @@ python3 { @@ -13,7 +13,7 @@ python3 {
# item is GLOBAL TO THE SERVER. That is, you cannot have two # item is GLOBAL TO THE SERVER. That is, you cannot have two
# instances of the python module, each with a different path. # instances of the python module, each with a different path.
# #
- python_path="/usr/lib64/python3.8:/usr/lib/python3.8:/usr/lib/python3.8/site-packages:/usr/lib64/python3.8/site-packages:/usr/lib64/python3.8/lib-dynload:/usr/local/lib/python3.8/site-packages:/etc/raddb/mods-config/python3/" - python_path="/usr/lib64/python3.8:/usr/lib/python3.8:/usr/lib/python3.8/site-packages:/usr/lib64/python3.8/site-packages:/usr/lib64/python3.8/lib-dynload:/usr/local/lib/python3.8/site-packages:/etc/raddb/mods-config/python3/"
+ python_path="@pythonPath@:/etc/raddb/mods-config/python3/" + python_path="@kanidm_python@:/etc/raddb/mods-config/python3/"
module = "kanidm.radius" module = "kanidm.radius"
# python_path = ${modconfdir}/${.:name} # python_path = ${modconfdir}/${.:name}

View file

@ -0,0 +1,45 @@
{
stdenv,
fetchFromGitHub,
python3,
pykanidm,
}:
let
pythonPath = with python3.pkgs; makePythonPath [ pykanidm ];
in
stdenv.mkDerivation rec {
pname = "rlm_python";
version = "1.1.0-rc.15";
src = fetchFromGitHub {
owner = "kanidm";
repo = "kanidm";
rev = "v${version}";
hash = "sha256-0y8juXS61Z9zxOdsWAQ6lJurP+n855Nela6egYRecok=";
};
patches = [ ./python_path.patch ];
postPatch = ''
substituteInPlace rlm_python/mods-available/python3 \
--replace "@kanidm_python@" "${pythonPath}"
'';
installPhase = ''
mkdir -p $out/etc/raddb/
cp -R rlm_python/{mods-available,sites-available} $out/etc/raddb/
'';
phases = [
"unpackPhase"
"patchPhase"
"installPhase"
];
passthru = {
inherit pythonPath;
};
preferLocalBuild = true;
}

View file

@ -1,55 +1,31 @@
{ { config, sources, ... }:
config,
lib,
meta,
...
}:
let let
inherit (lib)
attrValues
catAttrs
escapeRegex
concatStringsSep
mapAttrs'
nameValuePair
;
domain = "sso.dgnum.eu"; domain = "sso.dgnum.eu";
port = 8443;
cert = config.security.acme.certs.${domain}; cert = config.security.acme.certs.${domain};
allowedDomains = builtins.map escapeRegex ( allowedSubDomains = [
(builtins.map (s: "${s}.dgnum.eu") [ "cloud"
# DGNum subdomains "git"
"cloud" "videos"
"git" "social"
"videos" "demarches"
"social" "netbird"
"demarches" ];
"netbird"
])
++ [
# Extra domains
"netbird-beta.hubrecht.ovh"
]
);
usernameFor = member: meta.organization.members.${member}.username;
in in
{ {
services.kanidm = { services.kanidm = {
enableServer = true; enableServer = true;
# package = nixpkgs.unstable.kanidm; package = (import sources.nixos-unstable { }).kanidm;
serverSettings = { serverSettings = {
inherit domain; inherit domain;
origin = "https://${domain}"; origin = "https://${domain}";
bindaddress = "127.0.0.1:${builtins.toString port}"; bindaddress = "127.0.0.1:8443";
ldapbindaddress = "0.0.0.0:636"; ldapbindaddress = "0.0.0.0:636";
trust_x_forward_for = true; trust_x_forward_for = true;
@ -57,113 +33,10 @@ in
tls_chain = "${cert.directory}/fullchain.pem"; tls_chain = "${cert.directory}/fullchain.pem";
tls_key = "${cert.directory}/key.pem"; tls_key = "${cert.directory}/key.pem";
}; };
provision = {
enable = true;
persons = mapAttrs' (
_:
{
email,
name,
username,
...
}:
nameValuePair username {
displayName = name;
mailAddresses = [ email ];
}
) meta.organization.members;
groups =
{
grp_active.members = catAttrs "username" (attrValues meta.organization.members);
}
// (mapAttrs' (
name: members: nameValuePair "grp_${name}" { members = builtins.map usernameFor members; }
) meta.organization.groups);
# INFO: The authentication resources declared here can only be for internal services,
# as regular members cannot be statically known.
systems.oauth2 = {
dgn_grafana = {
displayName = "Grafana [Analysis]";
originLanding = "https://grafana.dgnum.eu";
originUrl = "https://grafana.dgnum.eu/";
preferShortUsername = true;
scopeMaps.grp_active = [
"openid"
"profile"
"email"
];
};
dgn_librenms = {
allowInsecureClientDisablePkce = true;
displayName = "LibreNMS [Network]";
enableLegacyCrypto = true;
originLanding = "https://nms.dgnum.eu";
originUrl = "https://nms.dgnum.eu/";
preferShortUsername = true;
scopeMaps.grp_active = [
"openid"
"profile"
"email"
];
};
dgn_netbird = {
displayName = "Netbird [VPN]";
enableLocalhostRedirects = true;
originLanding = "https://netbird.dgnum.eu";
originUrl = "https://netbird.dgnum.eu/";
preferShortUsername = true;
public = true;
scopeMaps.grp_active = [
"openid"
"profile"
"email"
];
};
dgn_netbox = {
allowInsecureClientDisablePkce = true;
displayName = "Netbox [Inventory]";
enableLegacyCrypto = true;
originLanding = "https://netbox.dgnum.eu";
originUrl = "https://netbox.dgnum.eu/";
preferShortUsername = true;
scopeMaps.grp_active = [
"openid"
"profile"
"email"
];
};
dgn_outline = {
displayName = "Outline [Docs]";
originUrl = "https://docs.dgnum.eu/";
originLanding = "https://docs.dgnum.eu";
preferShortUsername = true;
scopeMaps.grp_active = [
"openid"
"profile"
"email"
];
};
};
};
}; };
users.users.kanidm.extraGroups = [ cert.group ]; users.users.kanidm.extraGroups = [ cert.group ];
dgn-web.internalPorts.kanidm = port;
services.nginx = { services.nginx = {
enable = true; enable = true;
@ -171,7 +44,7 @@ in
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
locations."/" = { locations."/" = {
proxyPass = "https://127.0.0.1:${builtins.toString port}"; proxyPass = "https://127.0.0.1:8443";
extraConfig = '' extraConfig = ''
if ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) { if ( $request_method !~ ^(GET|POST|HEAD|OPTIONS|PUT|PATCH|DELETE)$ ) {
@ -180,7 +53,7 @@ in
set $origin $http_origin; set $origin $http_origin;
if ($origin !~ '^https?://(${concatStringsSep "|" allowedDomains})$') { if ($origin !~ '^https?://(${builtins.concatStringsSep "|" allowedSubDomains})\.dgnum\.eu$') {
set $origin 'https://${domain}'; set $origin 'https://${domain}';
} }

View file

@ -1,4 +1,9 @@
(import ../../../../keys).mkSecrets [ "compute01" ] [ let
lib = import ../../../../lib { };
publicKeys = lib.getNodeKeys "compute01";
in
lib.setDefault { inherit publicKeys; } [
"kanidm-password_admin" "kanidm-password_admin"
"kanidm-password_idm_admin" "kanidm-password_idm_admin"
] ]

View file

@ -12,10 +12,12 @@ in
package = package =
(pkgs.librenms.override { inherit (config.services.librenms) dataDir logDir; }).overrideAttrs (pkgs.librenms.override { inherit (config.services.librenms) dataDir logDir; }).overrideAttrs
(old: { (
patches = (old.patches or [ ]) ++ [ ./kanidm.patch ]; old: {
vendorHash = "sha256-2RgtMXQp4fTE+WloO36rtfytO4Sh2q0plt8WkWxEGHI="; patches = (old.patches or [ ]) ++ [ ./kanidm.patch ];
}); vendorHash = "sha256-2RgtMXQp4fTE+WloO36rtfytO4Sh2q0plt8WkWxEGHI=";
}
);
hostname = host; hostname = host;

View file

@ -198,11 +198,13 @@ in
poolConfig = mkOption { poolConfig = mkOption {
type = type =
with types; with types;
attrsOf (oneOf [ attrsOf (
str oneOf [
int str
bool int
]); bool
]
);
default = { default = {
"pm" = "dynamic"; "pm" = "dynamic";
"pm.max_children" = 32; "pm.max_children" = 32;
@ -219,9 +221,9 @@ in
nginx = mkOption { nginx = mkOption {
type = types.submodule ( type = types.submodule (
recursiveUpdate (import "${modulesPath}/services/web-servers/nginx/vhost-options.nix" { recursiveUpdate
inherit config lib; (import "${modulesPath}/services/web-servers/nginx/vhost-options.nix" { inherit config lib; })
}) { } { }
); );
default = { }; default = { };
example = literalExpression '' example = literalExpression ''
@ -390,9 +392,9 @@ in
} }
// (lib.optionalAttrs cfg.distributedPoller.enable { // (lib.optionalAttrs cfg.distributedPoller.enable {
"distributed_poller" = true; "distributed_poller" = true;
"distributed_poller_name" = lib.mkIf ( "distributed_poller_name" =
cfg.distributedPoller.name != null lib.mkIf (cfg.distributedPoller.name != null)
) cfg.distributedPoller.name; cfg.distributedPoller.name;
"distributed_poller_group" = cfg.distributedPoller.group; "distributed_poller_group" = cfg.distributedPoller.group;
"distributed_billing" = cfg.distributedPoller.distributedBilling; "distributed_billing" = cfg.distributedPoller.distributedBilling;
"distributed_poller_memcached_host" = cfg.distributedPoller.memcachedHost; "distributed_poller_memcached_host" = cfg.distributedPoller.memcachedHost;

View file

@ -9,12 +9,8 @@ in
localDomain = host; localDomain = host;
smtp = { smtp = {
fromAddress = "noreply@infra.dgnum.eu"; # TODO: smtp setup
host = "kurisu.lahfa.xyz"; fromAddress = "social@services.dgnum.eu";
port = 465;
user = "web-services@infra.dgnum.eu";
passwordFile = config.age.secrets.mastodon-smtp-password.path;
authenticate = true;
}; };
streamingProcesses = 4; streamingProcesses = 4;
@ -26,8 +22,6 @@ in
# LOCAL_DOMAIN = "dgnum.eu"; # LOCAL_DOMAIN = "dgnum.eu";
WEB_DOMAIN = host; WEB_DOMAIN = host;
SMTP_TLS = "true";
RAILS_LOG_LEVEL = "warn"; RAILS_LOG_LEVEL = "warn";
# ObjectStorage configuration # ObjectStorage configuration

View file

@ -3,24 +3,28 @@
let let
host = "cloud.dgnum.eu"; host = "cloud.dgnum.eu";
nextcloud-occ = "${config.services.nextcloud.occ}/bin/nextcloud-occ"; nextcloud-occ = "${config.services.nextcloud.occ}/bin/nextcloud-occ";
port = 9980;
in in
{ {
services.nextcloud = { services.nextcloud = {
enable = true; enable = true;
hostName = host; hostName = host;
package = pkgs.nextcloud29; package = pkgs.nextcloud28;
https = true; https = true;
config = { config = {
overwriteProtocol = "https";
dbtype = "pgsql"; dbtype = "pgsql";
adminpassFile = config.age.secrets."nextcloud-adminpass_file".path; adminpassFile = config.age.secrets."nextcloud-adminpass_file".path;
adminuser = "thubrecht"; adminuser = "thubrecht";
defaultPhoneRegion = "FR";
trustedProxies = [ "::1" ];
objectstore.s3 = { objectstore.s3 = {
enable = true; enable = true;
@ -57,7 +61,7 @@ in
"opcache.max_accelerated_files" = "10000"; "opcache.max_accelerated_files" = "10000";
"opcache.memory_consumption" = "128"; "opcache.memory_consumption" = "128";
"opcache.revalidate_freq" = "1"; "opcache.revalidate_freq" = "1";
"opcache.fast_shutdown" = "0"; "opcache.fast_shutdown" = "1";
"openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt"; "openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt";
catch_workers_output = "yes"; catch_workers_output = "yes";
}; };
@ -67,17 +71,11 @@ in
autoUpdateApps.enable = true; autoUpdateApps.enable = true;
settings = { extraOptions = {
overwriteprotocol = "https";
overwritehost = host; overwritehost = host;
"overwrite.cli.url" = "https://${host}"; "overwrite.cli.url" = "https://${host}";
updatechecker = false; updatechecker = false;
default_phone_region = "FR";
trusted_proxies = [ "::1" ];
allow_local_remote_servers = true; allow_local_remote_servers = true;
maintenance_window_start = 1; maintenance_window_start = 1;
@ -99,20 +97,22 @@ in
}; };
virtualisation.oci-containers = { virtualisation.oci-containers = {
# # Since 22.05, the default driver is podman but it doesn't work
# # with podman. It would however be nice to switch to podman.
# backend = "docker";
containers.collabora = { containers.collabora = {
image = "collabora/code"; image = "collabora/code";
imageFile = pkgs.dockerTools.pullImage { imageFile = pkgs.dockerTools.pullImage {
imageName = "collabora/code"; imageName = "collabora/code";
imageDigest = "sha256:07da8a191b37058514dfdf921ea8c2270c6634fa659acee774cf8594f86950e4"; imageDigest = "sha256:a8cce07c949aa59cea0a7f1f220266a1a6d886c717c3b5005782baf6f384d645";
sha256 = "sha256-5oaz07NQScHUVN/HznzZGQ2bGrU/V1GhI+9btXHz0GM="; sha256 = "sha256-lN6skv62x+x7G7SNOUyZ8W6S/uScrkqE1nbBwwSEWXQ=";
}; };
ports = [ "${builtins.toString port}:${builtins.toString port}" ]; ports = [ "9980:9980" ];
environment = { environment = {
domain = "cloud.dgnum.eu"; 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"; 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 = [ extraOptions = [
"--network=host"
"--cap-add" "--cap-add"
"MKNOD" "MKNOD"
"--cap-add" "--cap-add"
@ -121,8 +121,6 @@ in
}; };
}; };
dgn-web.internalPorts.collabora = port;
services.nginx.virtualHosts = { services.nginx.virtualHosts = {
${host} = { ${host} = {
enableACME = true; enableACME = true;
@ -140,25 +138,25 @@ in
extraConfig = '' extraConfig = ''
# static files # static files
location ^~ /browser { location ^~ /browser {
proxy_pass http://127.0.0.1:${builtins.toString port}; proxy_pass http://127.0.0.1:9980;
proxy_set_header Host $host; proxy_set_header Host $host;
} }
# WOPI discovery URL # WOPI discovery URL
location ^~ /hosting/discovery { location ^~ /hosting/discovery {
proxy_pass http://127.0.0.1:${builtins.toString port}; proxy_pass http://127.0.0.1:9980;
proxy_set_header Host $host; proxy_set_header Host $host;
} }
# Capabilities # Capabilities
location ^~ /hosting/capabilities { location ^~ /hosting/capabilities {
proxy_pass http://127.0.0.1:${builtins.toString port}; proxy_pass http://127.0.0.1:9980;
proxy_set_header Host $host; proxy_set_header Host $host;
} }
# main websocket # main websocket
location ~ ^/cool/(.*)/ws$ { location ~ ^/cool/(.*)/ws$ {
proxy_pass http://127.0.0.1:${builtins.toString port}; proxy_pass http://127.0.0.1:9980;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade"; proxy_set_header Connection "Upgrade";
proxy_set_header Host $host; proxy_set_header Host $host;
@ -167,13 +165,13 @@ in
# download, presentation and image upload # download, presentation and image upload
location ~ ^/(c|l)ool { location ~ ^/(c|l)ool {
proxy_pass http://127.0.0.1:${builtins.toString port}; proxy_pass http://127.0.0.1:9980;
proxy_set_header Host $host; proxy_set_header Host $host;
} }
# Admin Console websocket # Admin Console websocket
location ^~ /cool/adminws { location ^~ /cool/adminws {
proxy_pass http://127.0.0.1:${builtins.toString port}; proxy_pass http://127.0.0.1:9980;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade"; proxy_set_header Connection "Upgrade";
proxy_set_header Host $host; proxy_set_header Host $host;

View file

@ -1,15 +0,0 @@
{ pkgs, ... }:
{
services.nginx = {
virtualHosts."ollama01.beta.dgnum.eu" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://100.80.103.206:11434";
basicAuthFile = pkgs.writeText "ollama-htpasswd" ''
raito:$y$j9T$UDEHpLtM52hRGK0I4qT6M0$N75AhENLqgtJnTGaPzq51imhjZvuPr.ow81Co1ZTcX2
'';
};
};
};
}

View file

@ -2,7 +2,6 @@
let let
host = "docs.dgnum.eu"; host = "docs.dgnum.eu";
port = 3003;
in in
{ {
services.outline = { services.outline = {
@ -36,12 +35,21 @@ in
defaultLanguage = "fr_FR"; defaultLanguage = "fr_FR";
forceHttps = false; forceHttps = false;
inherit port; port = 3003;
}; };
dgn-web.simpleProxies.outline = { services.nginx.virtualHosts.${host} = {
inherit host port; enableACME = true;
vhostConfig.locations."/robots.txt".return = ''200 "User-agent: *\nDisallow: /s/demarches-normaliennes/\n"''; forceSSL = true;
locations."/" = {
proxyPass = "http://localhost:3003";
proxyWebsockets = true;
};
locations."/robots.txt" = {
return = ''200 "User-agent: *\nDisallow: /s/demarches-normaliennes/\n"'';
};
}; };
age-secrets.autoMatch = [ "outline" ]; age-secrets.autoMatch = [ "outline" ];

View file

@ -1,34 +0,0 @@
{ pkgs, ... }:
{
services.postgresql = {
enable = true;
package = pkgs.postgresql_16;
settings = {
checkpoint_completion_target = 0.90625;
default_statistics_target = 100;
effective_cache_size = "32GB";
effective_io_concurrency = 200;
maintenance_work_mem = "2GB";
max_connections = 500;
max_parallel_maintenance_workers = 4;
max_parallel_workers = 12;
max_parallel_workers_per_gather = 4;
max_wal_size = "4GB";
max_worker_processes = 12;
min_wal_size = "1GB";
random_page_cost = 1.125;
shared_buffers = "16GB";
wal_buffers = "16MB";
work_mem = "83886kB";
};
};
dgn-console = {
# Update the versions below for upgrading
pg-upgrade-to = pkgs.postgresql_16.withPackages (ps: [ ps.postgis ]);
pg-upgrade-from = pkgs.postgresql_16.withPackages (ps: [ ps.postgis ]);
};
}

View file

@ -2,15 +2,16 @@
let let
host = "saml-idp.dgnum.eu"; host = "saml-idp.dgnum.eu";
port = 8090;
in in
{ {
imports = [ ./module.nix ]; imports = [ ./module.nix ];
services.satosa = { services.satosa = {
enable = true; enable = true;
inherit host port; inherit host;
port = 8090;
envFile = config.age.secrets."satosa-env_file".path; envFile = config.age.secrets."satosa-env_file".path;
@ -147,8 +148,9 @@ in
}; };
}; };
dgn-web.simpleProxies.satosa = { services.nginx.virtualHosts.${host} = {
inherit host port; enableACME = true;
forceSSL = true;
}; };
age-secrets.autoMatch = [ "satosa" ]; age-secrets.autoMatch = [ "satosa" ];

View file

@ -23,10 +23,12 @@ let
mkYamlFiles = mkYamlFiles =
files: builtins.attrValues (builtins.mapAttrs (name: yamlFormat.generate "${name}.yaml") files); files: builtins.attrValues (builtins.mapAttrs (name: yamlFormat.generate "${name}.yaml") files);
pyEnv = cfg.package.python.withPackages (ps: [ pyEnv = cfg.package.python.withPackages (
cfg.package ps: [
ps.gunicorn cfg.package
]); ps.gunicorn
]
);
in in
{ {
options.services.satosa = { options.services.satosa = {
@ -190,6 +192,14 @@ in
}; };
}; };
services.nginx = mkIf cfg.configureNginx {
enable = true;
virtualHosts.${cfg.host} = {
locations."/".proxyPass = "http://127.0.0.1:${builtins.toString cfg.port}";
};
};
users.users.satosa = { users.users.satosa = {
isSystemUser = true; isSystemUser = true;
group = "satosa"; group = "satosa";

View file

@ -1,7 +1,7 @@
{ {
lib, lib,
python3, python3,
fetchFromGitHub, fetchPypi,
cookies-samesite-compat, cookies-samesite-compat,
pyop, pyop,
}: }:
@ -11,13 +11,17 @@ python3.pkgs.buildPythonPackage rec {
version = "8.4.0"; version = "8.4.0";
pyproject = true; pyproject = true;
src = fetchFromGitHub { src = fetchPypi {
owner = "IdentityPython"; pname = "SATOSA";
repo = "SATOSA"; inherit version;
rev = "v${version}"; hash = "sha256-KREROjb157RJJVRr9YefzoR/eflR/U7ZmG6yOH5DjcU=";
hash = "sha256-q7XmZ3EnAFO1OXIhXIF4Vd0H8uaayFIHFZpWiZUsAFA=";
}; };
nativeBuildInputs = [
python3.pkgs.setuptools
python3.pkgs.wheel
];
propagatedBuildInputs = with python3.pkgs; [ propagatedBuildInputs = with python3.pkgs; [
chevron chevron
click click
@ -46,7 +50,7 @@ python3.pkgs.buildPythonPackage rec {
description = "Protocol proxy (SAML/OIDC)"; description = "Protocol proxy (SAML/OIDC)";
homepage = "https://pypi.org/project/SATOSA"; homepage = "https://pypi.org/project/SATOSA";
license = licenses.asl20; license = licenses.asl20;
maintainers = with maintainers; [ thubrecht ]; maintainers = with maintainers; [ ];
mainProgram = "satosa"; mainProgram = "satosa";
}; };
} }

View file

@ -1,28 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 jIXfPA CQffZYaxexZ2f+HeNj+SHeSak0kzNPiq6ExW7tUyCBs
oJQhtMFD9KSnXSPGRb3zLwCB2/KEXo8cgxHN5ML83Qw
-> ssh-ed25519 QlRB9Q V1PnEYJvFCdBRzN4z3iDtIzHLxxCimejdkqRS4zMCG8
bVc87bxPmhofmoscGFBgQ+ffRlo216RiRkkV1MNoQyY
-> ssh-ed25519 r+nK/Q YI+1MYnCvSq5/QfA2y01IQlJeMGF0AfNs91QlrVaVGs
HSB8Gai96mjRbM68G3iRmXNkI4kqyJAWTMxWc8UOPr8
-> ssh-rsa krWCLQ
k2mssz4C9p8K+rJ6Jbbm+w7uLTqoUOiOKvlt2btEyw2Lup8PQNfyTNFSBvuBMmfj
re1zuAufH0HIw3B0xWYauBSD4pasc7EFTr/OLoM8BRFMEb11IM5ZKJrO+hnWy0Sk
eIs6cpkoBVi4GZmkRfbvaitk42i9JzjrKU0OeqLCWQbHmHkTb3acsGXCc6A6JSbF
AVb+Eaak6EIdX1dP4PWyCxU2PkcBtYBcLoGH74r1o0i3SzvmuzKvlBntx5IzsAvY
+QNGJLNZl0+NePafAkvVY8UOrlzxj+tCgfunAGXIXlZlVfNcjZX9Wv30sJOtwpbw
DdkJAqSrNkHianC5MEGgpA
-> ssh-ed25519 /vwQcQ yxGAMhwDcoDjw5MJudEE95PakhZvNpYfmfWiM6wbQBg
C1o3mNO2YFnBXamCcpAW0aQVGrNNcUpDtSn8+VLobmE
-> ssh-ed25519 0R97PA XRWbcwt3wXR3AYg0rhzc6OUuAA+blVTf3SHERYy3MkA
iCBd0E1NrV7tv3/0pD0FYWgUfGmB4M+VWfiixvVGv68
-> ssh-ed25519 JGx7Ng R47xTx4IGC/qf/v6WOXvJTd20MbeTdZ/8ovAA6d0iyQ
uBxcQVztpW4QaAR5rKfEVgtmrPk6l51+tY3brNjsTV4
-> ssh-ed25519 5SY7Kg LNtU+/1YlPX6T6gO2lb/wEei7hsy2oud8cTQXFQy0HY
xxPvBAIpFyCUqExjseerz6WlwWQEmw9fltzQBx51KI0
-> ssh-ed25519 p/Mg4Q uWIz5shMnsLXsh160cCW8E6kh9v4LPunOonugjWdSEY
5aRrIB5gxIplVWDGeMQ6g09togku6LxWRxBP7FbRNU0
-> ssh-ed25519 tDqJRg G8rNpeGY29czDVMvvt4LZ7nffZ/JAHDzxuIs7C/0SEM
HowgAvrQQcvUx93ZdK5q2bSsJDqaOxFf+x/lwTRss4I
--- ktcSPCC1TpguyYJ2ua7IuGcEw+Z9YuqjzcmH18abjo4
<EFBFBD><20><>ゥ煩 ネ9<1猤カワ簒<EFBE9C>pWJSWpsV/ム#<23>ウリ9タ{タ゚cHB<><42><EFBFBD>5<EFBFBD>ャ^ァ

View file

@ -1,30 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 jIXfPA zSfj75mxEod8RszD4XGaFIeMvcLnBgUHShIW5yFPdiE
YXaCFZ07BMzehG/PCUFDEzRy+y4c+IESO9kcLx+eG8M
-> ssh-ed25519 QlRB9Q 39DPdLnRMs5YSQOr/rY2nXO/8s/oCnYDkRex51tZayw
W3GbNP7qbgW2b0RoZmcWH0kLtQaIV50APGcntjMfn8o
-> ssh-ed25519 r+nK/Q dnX8kPKvyHS5U1N52QTDwonaHbBh8sv2DPBL1PoBO2E
mxduSFeWB4tJlrHDEthNKGv/vxzeWUtNwq1b2nDP6Z0
-> ssh-rsa krWCLQ
QN1OOmCREY2LljXm0+TAsOSkjIQ0RXyX8w5TVOOus5QAt1WTJan/mm4X1SviWqmn
UFDIeCoG2l5tBSyZr4VpnDeq7koWRA2eC7WnwWW47PQIRFSyjf+sy00rGR9kxVuL
1M9gsAGa5sud/PvmgSPSLsGhhrPsH/ZxN9beyIXIwmssmjN34KygUz9+u4T8IkVz
oxdq75LMzE2o0gcgC1EZ5+rDq0NSPQ9+1KgqwJuKlLKRXGdudgaVEUxX60g2ZnkX
8fNEgxqEkQ5MNnPfwbVumF6SWmMWyZSJ0rwHC94O1RdRNDcD3yKimuBmNSv2X+3L
cS3kE9LfNst2zBKHBGBOHQ
-> ssh-ed25519 /vwQcQ ZD8aiyO6fWEM9zG0iPP1/lftRPNl+mmFLHvGxVpSWzg
ZcTmN8zSHz8iLQmCLTZCdaqX5En/KrciR8KHwoXl8t0
-> ssh-ed25519 0R97PA xLQYBS5ozP1e4NWVa9yahN2OQB0Luw7mm3nBYdoHyRI
SKTRzLfGNFQ9fSX8ZFkKIYPZ4If5QrxcmSoBoGVG2Xk
-> ssh-ed25519 JGx7Ng XPo1QJ8OS/ShEAaXWwzZCS1p5/C6mLNlk4Us63YTVQ8
HGbfr8WBfCDKnIlATAeiE6JcLWCbn64vn1Cg7i9QGbA
-> ssh-ed25519 5SY7Kg CFpRcZmZ7DTspxkmdD8x7dRh1mqOHpTF7GzW5xBtLxw
n1n6/Ciwwo4rb3Cb6Yv/b1dHSvVAbCuDZ52maNpCexg
-> ssh-ed25519 p/Mg4Q km6ZjasKtOlaQL8rdVXkjRP4sooql15PrW0lz6YZaDg
Yrpi65IC3RJS3YSAChKjVyvowGxxmSPFkwa6CXUYVZ4
-> ssh-ed25519 tDqJRg au3x6e4L1os7OH4WXbdST74LhMsHPjP6KYrTWKUc1i8
zxKFk51MteTETWEu8peSH/lninM3zZkQi+Xjx5OQMTU
-> l$R6Y:c1-grease
MY0HS+ErZAtAhg
--- w+3gxmkrZ+xxSAQHbERgvsqur0v6k2/U0KUsfegRGcI
7Ú”gpò7šæ«¹Š\ŠE„àø~Â$±\¹Ä”Q„™H˜Èî¼¼2'k4Ž¥zÿqȦì'ÍNò!{@qxÎ,ƒ+iTû

View file

@ -1,31 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 jIXfPA xQaZW42vwq7pndbRqiATFVgl1QM3LbD5Sqzz61yinUY
7N4GIIAnzwTPA2IgOPWLtE03kCZPihKu8ZAG9e7Bv7k
-> ssh-ed25519 QlRB9Q mfs9SndrSY1meTEYiVxXLbS7Ecf0rjaQ3vX4626+9CI
BDdh3a02EqMeO5jPlz6kjmjuLMldf/s9V7hDkIef+g4
-> ssh-ed25519 r+nK/Q HqduuibujATQyp2TUswgrFyTdcdmPsNsZJ2pOLZ+MTc
WjFm95dxVYKA2ekOgKzMrMmk1nxfuurmDyMXtUIGnIo
-> ssh-rsa krWCLQ
GzznBXY+5RpGFJKli2rOdzO5bun6REyjA78nV8RviQdAN/mGXEZfGFq4HFuQZM0e
fYADtpZxOZ3vyY/9DqCguay3R02DcyTpAhdb6A3kdzApUVR/3ZKJXy0+l5qRqKD7
j/cMfIxk/WpsHKHDWKXkG+FiTnF+V+ZtUom9W1aYFc1506OdDbjBVfTnBFs/+WVf
MWd+Y0ANCFiNH+kjzvALRazkmJgt9SvYWBG6suym6YZ2073GFu85jUJB2juSDmBN
tp0OJvNrjH5F/CcJXLMVrJz4Azin+2iM+re78cSVmZ1aqLf72RIrg/VhuuNy2MVn
gU32t9qy5EvTbzliWpAvxw
-> ssh-ed25519 /vwQcQ rVT/tH4fZ49hwxJTaZMZhzMgkS0MJILZmuL/J1CCPGY
mW3BNdXsylo0Yhg2KYpGNLoDkd7DYX+NEGF8a7j5R5g
-> ssh-ed25519 0R97PA vnXhW5pn1XgOJcMcD1cu7hQLlnIrJyp2Bu3TbThBIik
QFQFocftqwsPS1AbGykbDkIWqaAdZ7I9njS2ZUXz+4w
-> ssh-ed25519 JGx7Ng ljVNZ4AdZ3DLow2m3mf+6bf9zj6+t9RP7w8Bi7aMlAI
E5Q9yEA3d2nPTZO2jFkGnsHyo3W19P/lSG6yl3RL6Vo
-> ssh-ed25519 5SY7Kg 2LcgbYRROFSGfq0L5XBQMl6p62DreGceGqRFzKGi4X8
x4V+gnzdm1HgjYwhBnYAldkchX4YCsUhqoq1iCaOZ6s
-> ssh-ed25519 p/Mg4Q Y+o5nrSvL+xL43OHjEnesKV+9gCl4H4gBmBBjbqDABA
TvGky1wSVanvpq2Xj2FUmRtJ205iq92g6PVDASAfyaE
-> ssh-ed25519 tDqJRg X0Y8YCi5qOy3Du1/DIMMc4W7P6zQNTlwF4+QrisHCwM
SzJPH+h5847WSl9CrJatqIf9CSnKGUQZDK6ROD5LqXU
-> `--grease N]PH
fdR7jONsDC5Fj/FU++dDsFJSa4sLmvnTzPbt3X96zJDHVQypmV+JMhQNudQGrq9K
7oPr3+cA61qtqUv6v519zFLtRXkpY6FMiB2euGJufVZqGh9jDzfi0jNu6dUO7A
--- a0TP8YPal5jgd3BSIm0THbaMHgLOiOgMqdlwQwUGzWk
:È/ Àn ž±Ý§¦p=fu²hãT¶ÅêF—ÙêÂ¥nh¢„¾•œ¹ÀU2#„éµÆ©“ºôâ>Û“<4.<2E>uŸ‰…m3Ü&<26>g¤(ö<>5 Û¶Ã

View file

@ -1,28 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 jIXfPA T6TOJOuejaoxw3zdeLzGm0CrSkDCCIRenL7wMGnDtlU
dubdAXhc32S6BszHddOcMA6aStZLOvc+36s3nZsYFMU
-> ssh-ed25519 QlRB9Q akzRDbZzo0LwoS1cOwE/tYdz7M+6bhgI81d37d1GtBw
KsGqFhkjlcJNquMi2+1TfQDBy9qguwh5ED9KBg4Y2hU
-> ssh-ed25519 r+nK/Q bL6A9O6UnjjyY+iLvbQSvSTjXX38FLsNjaSngoQXHxY
YZ7Y11inKpzA2m6lro9XXX2qkW6FmkeFGZ3Ak6X+U2w
-> ssh-rsa krWCLQ
dZVUqAyqrP3KHZlpu70IBU8U3I9IP71RzjbiF1rp4rOdz4iQ9ik88ai+hXVuadcN
DMl/7pIkVky6EL8JxFXTQhLivJUpO3NcN3iAS+CLKC+0EFVc03sLyCjn8IExO85r
Lec37ICk9n4LUNEA91A2h4C8U9TbDxCt7MLrIKcQtfFcd+4U1o9g3n19xo9PK1Ho
mcqTbUVgW1nOLxsEeCp5zsCQ+/8tFLcnK08yUB0RlWK+PDFZkk8u8Q2SYZjnaeEp
cwOhUnm/1a15IbW2oGCrVaEd/ymnLDJc6S7vXGpFDWHmOzvJ4Av9KZlGFYaWCjbV
7bGIgWkiQ7iJvTxzu0ZEqw
-> ssh-ed25519 /vwQcQ /DR3Kox7XkbdYQH7SyIc9atjwwe7Ah7hH/63RlzDd0g
k/199lCIfxR7l4ETJMEr1Ch1Zx8v3M5zn0b8mg6ip2k
-> ssh-ed25519 0R97PA H1PS+SlW5FNOf15eO6MKJ/nnVJQkfFMub0IzTS4PhDo
77zwCD0tbrLu4J0vS0RxPK3YZucFV1VYkUVoMTHjf2o
-> ssh-ed25519 JGx7Ng 2WIYPKkWXplInR8v1q22ygs7uYNfIzETeiCt5+MKQQQ
9Gsyr30kaNhxn+fUCBicvoA+hHiWpUf0d0pxRZauhMY
-> ssh-ed25519 5SY7Kg QTnBfvkMcnXpGITtaHr+mRZGogI1kTUqO4byfyMZhGE
89A/PPHVPeBQvTxCeXH8ITVDMkcsYUMbwatyw8NQ04E
-> ssh-ed25519 p/Mg4Q n6hQLuUv3QOMADJF0zpcALYqVUVi5tZHmKGmVZA0IVQ
ZXa+3y33kyo4vQxcEa2XTMIwjH2HE+bAKZw993PgROk
-> ssh-ed25519 tDqJRg Hf1KIZjUTTaHo18P1vWxaSehyKTFElBOovrCN0uJFCc
H8qGw8vIqp4bNiyon2uvTkrrd8lIYnMWnIfzS+w4QRQ
--- QOKOfU20JY1Sj+K20UUxgtPZ7JxKuZ1GtK+OKBZ1Zhg
Íúâ?º}àæ2æŽýiÐM}6BÖw#b2Ï´žËŠ¹ÍÊžvu´¿,Ö'.ŒWÔ”øIPýã'ixYÍ€*·šKoÎtXI#Àß6b`„1pʬòÍœˆ×"§lâSf(ˆ`UöëÄê6 kT°Á'µÎÔM@ÈÖå„hŸï®{WYŸØÝÏÂ<SN;UŒœ ݨÿ

View file

@ -1,28 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 jIXfPA CQffZYaxexZ2f+HeNj+SHeSak0kzNPiq6ExW7tUyCBs
oJQhtMFD9KSnXSPGRb3zLwCB2/KEXo8cgxHN5ML83Qw
-> ssh-ed25519 QlRB9Q V1PnEYJvFCdBRzN4z3iDtIzHLxxCimejdkqRS4zMCG8
bVc87bxPmhofmoscGFBgQ+ffRlo216RiRkkV1MNoQyY
-> ssh-ed25519 r+nK/Q YI+1MYnCvSq5/QfA2y01IQlJeMGF0AfNs91QlrVaVGs
HSB8Gai96mjRbM68G3iRmXNkI4kqyJAWTMxWc8UOPr8
-> ssh-rsa krWCLQ
k2mssz4C9p8K+rJ6Jbbm+w7uLTqoUOiOKvlt2btEyw2Lup8PQNfyTNFSBvuBMmfj
re1zuAufH0HIw3B0xWYauBSD4pasc7EFTr/OLoM8BRFMEb11IM5ZKJrO+hnWy0Sk
eIs6cpkoBVi4GZmkRfbvaitk42i9JzjrKU0OeqLCWQbHmHkTb3acsGXCc6A6JSbF
AVb+Eaak6EIdX1dP4PWyCxU2PkcBtYBcLoGH74r1o0i3SzvmuzKvlBntx5IzsAvY
+QNGJLNZl0+NePafAkvVY8UOrlzxj+tCgfunAGXIXlZlVfNcjZX9Wv30sJOtwpbw
DdkJAqSrNkHianC5MEGgpA
-> ssh-ed25519 /vwQcQ yxGAMhwDcoDjw5MJudEE95PakhZvNpYfmfWiM6wbQBg
C1o3mNO2YFnBXamCcpAW0aQVGrNNcUpDtSn8+VLobmE
-> ssh-ed25519 0R97PA XRWbcwt3wXR3AYg0rhzc6OUuAA+blVTf3SHERYy3MkA
iCBd0E1NrV7tv3/0pD0FYWgUfGmB4M+VWfiixvVGv68
-> ssh-ed25519 JGx7Ng R47xTx4IGC/qf/v6WOXvJTd20MbeTdZ/8ovAA6d0iyQ
uBxcQVztpW4QaAR5rKfEVgtmrPk6l51+tY3brNjsTV4
-> ssh-ed25519 5SY7Kg LNtU+/1YlPX6T6gO2lb/wEei7hsy2oud8cTQXFQy0HY
xxPvBAIpFyCUqExjseerz6WlwWQEmw9fltzQBx51KI0
-> ssh-ed25519 p/Mg4Q uWIz5shMnsLXsh160cCW8E6kh9v4LPunOonugjWdSEY
5aRrIB5gxIplVWDGeMQ6g09togku6LxWRxBP7FbRNU0
-> ssh-ed25519 tDqJRg G8rNpeGY29czDVMvvt4LZ7nffZ/JAHDzxuIs7C/0SEM
HowgAvrQQcvUx93ZdK5q2bSsJDqaOxFf+x/lwTRss4I
--- ktcSPCC1TpguyYJ2ua7IuGcEw+Z9YuqjzcmH18abjo4
<EFBFBD><20><>ゥ煩 ネ9<1猤カワ簒<EFBE9C>pWJSWpsV/ム#<23>ウリ9タ{タ゚cHB<><42><EFBFBD>5<EFBFBD>ャ^ァ

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,31 @@
age-encryption.org/v1
-> ssh-ed25519 tDqJRg R3h8Ph1ooMaR/bmz09yRzVRq1mR3L7o87wMhsysC5kU
Go50Us/u8CgZS7Up20RH8NlRS0+ESBw30wa8SZ5dqoo
-> ssh-ed25519 jIXfPA gMaMIQvUIu5bK5mRWP6SSZQArMzhg4bDZDcjwx9dyDY
Vv8H7oTBvogaoW4dhdm81TOe995CSGeBxB8LtFgJqwc
-> ssh-ed25519 QlRB9Q 1CxZ2F8EMykWDzrAzN6NSPtjLmMJ99zf8UWLyV3e+Ag
ak7M8/mCeQOMKFPllTsA79glffS/vu51vHIRT3F8qLE
-> ssh-ed25519 r+nK/Q qcuIACZn+1ofDpWW1IBmY0IIj4WZNQhxtUJlHgh11ws
OJhEfDQHkg3s5CCBcVfba9S4OG4hBjJIYkCoLAIFwOI
-> ssh-rsa krWCLQ
1XseIDq7c94X7Dpp1sC3oBLhZSd4w7UJ7QI03SGmqVTd3VVwP5IV430vrSIFETMI
LopkMvCtF1XpIJQ+nHoxsukG/0kefh5Iodmd6anQNp0iVU/tWkQzWbkHlVlkxJ2M
o3fMRAaVyH5GvQkIT5ndWma34vqwydAinM2mchi0hy0ibP5lkk8K7OtafNP4eYNh
m7necRRI8yCuE1wBRy8sBpo5mEqGj1uINxXiF6yUI05pCBXHG1qDiFkDHfw8va9k
Qitfwv2Clkk/hQG6aEYuruoXwq4SZxSCswMpP5Nz70I+e5YkZw8G50ICaVBXxuAP
ABByGBZ/QKLw66NpE7rbSA
-> ssh-ed25519 /vwQcQ 1P92WFx8+9DaL2dPwmX+Bva+h7Hy9qXszDTyPvd81kc
gLVhBlE4lAMcod32/Y8xzypVCDu4vRca3aem3OHiocU
-> ssh-ed25519 0R97PA rZblJRi2bYJig4HyzOXdtpUEEkGDlHS456aKlqxwGX4
qjIkEyHjDxzmf34bS7qWJ9lexMXu2QMmcD9RP4MpkYQ
-> ssh-ed25519 JGx7Ng IbCSvxAUY1gDTny5KurzONVaQwX/VgvNs1hAQ9iUQRE
5ivoGkzEHAyTl3gUE+9nVYclF8/aqnyOF3a81fZfbW0
-> t|-grease (u /1\q}65 ]@
Dd2SJgnQFUSDlS4eSkKUaGwve8Rsv/4MNEwGRJftdtTvxv80bRuNBEFe+ah4YhiV
LA3n6c+Te9Q
--- wWhpJpx4IHeC1Qo4nH6iuEB3e9l5b8U5xOnsX8BoBgQ
5¥t·Œ °ÒxÚ@<1E>`zÈÔgCà Ѭ:4Œó¾&‡Spi8ñŸuæ"lÕ×)<29>aŒÁÄ,4ÃsÌ*uÿ€ƒ±v#ÿ*ÎàÜÊ^ݶ‚Ø«%´Ñº98¾,yBÙ
"¶%Ç㤄†NÎÓ· íò¬} [Ñ¿Ó(äØ{<11>ý0ô—f²<66>„|Š à-—&qF k Ö¶¹µùÔÎLì,¹À„žD™áΩ­QÍ—½è<C2BD>4N}<7D>ÙÐJ´·ÇÓˆ€]dU Ïø¿<C3B8>I—:ÌôÑÉ öì°¦£sý¨õB #}¹
ÞÃXzð‰N4·>ñ5iSan`‰¹.õÃPcHØÉAéßÈÿµH=¥ËæÂ~ö(Pçô±Š$ ,¡ã‹ù¯ZЬÆwçÚ /×
Á–+rC$†ýê&ØJñ ; ÉvÞjæ‰ÎY¹,š*`ºGå=ã¯M¼ƒƒeäA<51>\D˜ÿ@¥j¾$gö{Q´lhIoÊÏIM)};@ìNü½b‰<62>k5Dgüoþ'ItW(Ïk
ê6)ËŒä0£<30>tM¶É Ó(Ûê¡<C3AA>n²k®Zu%m<17>¡ bzÚõŠ¿ÁìÍÿ

Binary file not shown.

View file

@ -0,0 +1,26 @@
age-encryption.org/v1
-> ssh-ed25519 tDqJRg sTm4u+QVtvUqNgMJhufIljdH63oCmvfbRz6NRa2ZbwI
ZYjAINMp/ds7g+7Wjg26YRpRV+nznQPB1r7NzAHGfW0
-> ssh-ed25519 jIXfPA z4LS/Igwab0moIzxG9b06T5rZiODkdJyjaFepJVcxQ8
qNkDc+prvr1bNTSWJyygJj7yb8MOz2nR+Z8EMHUVVOs
-> ssh-ed25519 QlRB9Q 6TQ0Vp3KB5yDIEt029hIB3aCnDjTDP0JG6LN2J9gtjU
fZXeSxb7GJOJYvCr2nVf6BKf8QjaqOOuoi0I/xXV1qc
-> ssh-ed25519 r+nK/Q eW4wTH9PNd0mzVFsxwS4mEEn5gVUCpYA/g+ifeUB+00
kqED+vZVHn0SXTpgbaiMseI6vPCyTt5Gfu4pHxPvKp0
-> ssh-rsa krWCLQ
axyFJ/zhMoZ1mJLzWAbXbHjlAlLj7HraHyY6ddZBVibgRSEufdXsa8ABmdR6+EuM
ty37+/TZOBv11ew/D1C7vQ7B/1JXgej2TAAmYt4vN3lVZdgJI+tQGiOf1nsqfI64
p4ZbMi9G0wlzb+Z7Z5SLKo6HwharYI+vDEgh3Ua9Q+6bpZeXxxJHmkACikAI4xJV
3lLo1iTeyJy/9u/WoHmEOuqJLeZdhmPZBozxTdDTWz9wMHy+NotfXFaIFTyUpocu
OU19N95fyVyTRwmrGFcWs34O631Ejpo3oVLDvjXrFtV4HISSweB/YbU84EveFbz5
28gTWKdeOQcHJfmaeJV/Rg
-> ssh-ed25519 /vwQcQ cXNRE5eLKNh4lL7S7cMDfp79+TQyiJK3gTzYCuHeRHo
4bz0al2kf/S6VEhObpLxy8tvB1t/tBVdB1Gi/7XinD4
-> ssh-ed25519 0R97PA iGdUtE7KDRBNSXv1w0dJNPQWxAeDpIAePUU8t0qURV8
OUoeLNWl0rLt6+FNf5plNmQIgrULwIgEL/W4HFTYeB8
-> ssh-ed25519 JGx7Ng tPkAPvVDZOcP06+mrD5uK03dUJi4aMAvkoz21y9L6Ak
tcUItLMra+EIYH6MA1ULMpr8bkUql448jnurev8N5wk
-> \<?_-grease (+d_8zF H
--- /CiW5jTjVkXDOdwmb4P80FswPEpgTt2GZnqT7KlOvC0
=þ%©»gæÆQ³-¼ffÄUC.qÅ͘·H<C2B7>µ—ìäÙ=Vý£žØú<C398>ŽRåN

View file

@ -1,31 +1,29 @@
(import ../../../keys).mkSecrets [ "compute01" ] [ let
# List of secrets for compute01 lib = import ../../../lib { };
"arkheon-env_file" publicKeys = lib.getNodeKeys "compute01";
in
lib.setDefault { inherit publicKeys; } [
"bupstash-put_key" "bupstash-put_key"
"dgsi-email_host_password_file"
"dgsi-kanidm_auth_token_file"
"dgsi-kanidm_secret_file"
"dgsi-secret_key_file"
"dgsi-x509_cert_file"
"dgsi-x509_key_file"
"ds-fr-secret_file" "ds-fr-secret_file"
"grafana-oauth_client_secret_file"
"grafana-smtp_password_file" "grafana-smtp_password_file"
"grafana-oauth_client_secret_file"
"hedgedoc-environment_file" "hedgedoc-environment_file"
"librenms-database_password_file" "librenms-database_password_file"
"librenms-environment_file" "librenms-environment_file"
"mastodon-extra_env_file" "mastodon-extra_env_file"
"mastodon-smtp-password"
"nextcloud-adminpass_file" "nextcloud-adminpass_file"
"nextcloud-s3_secret_file" "nextcloud-s3_secret_file"
"outline-oidc_client_secret_file" "outline-oidc_client_secret_file"
"outline-smtp_password_file" "outline-smtp_password_file"
"outline-storage_secret_key_file" "outline-storage_secret_key_file"
"plausible-admin_user_password_file" "radius-auth_token_file"
"plausible-secret_key_base_file" "radius-ca_pem_file"
"plausible-smtp_password_file" "radius-cert_pem_file"
"radius-dh_pem_file"
"radius-key_pem_file"
"radius-private_key_password_file"
"satosa-env_file" "satosa-env_file"
"signal-irc-bridge-config"
"telegraf-environment_file" "telegraf-environment_file"
"vaultwarden-environment_file" "vaultwarden-environment_file"
"zammad-secret_key_base_file" "zammad-secret_key_base_file"

View file

@ -1,29 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 jIXfPA Io/zqmrxU05V3yhgyGySW5f2hlQdBOqzXzv2I5x+nVs
O5szAc5hiv4Kw+Xo90mhst3vGLqhtqSuaKxPTkCQCJw
-> ssh-ed25519 QlRB9Q 9gQ+5aCcW+gi30S20om5+Zign9zXfgKlG9/59a2rdl4
nXyckLZ6zNdG096GAPlK/gyold3XxOqeKB1Kiy/BCmI
-> ssh-ed25519 r+nK/Q nctFMke6IvbEII3/Mq7wq9Cb30GO1yBqePJXdOFjExs
fMEbZoSsvMiFS2wHD0RCcSqbigmFHCnhEagXDTYBIW8
-> ssh-rsa krWCLQ
i7lgxs2DFU6OYdR0wC9NBJAUrYOarTpIBu8JiQKKTymkGauTtpCkOgakEF7N/TLd
1KFX6ww2lhmGwgi/4qYK5R21geqbLaogm5LsSrWgwI+nAqzAasD30i4MYWSfd1PS
kewXfRmMOUc2feMN/FiLDlyxxdg3DQImEwwAUq3k4F7W7/ggi4qPKzqzGhlOG1kB
Ma05hLsOhTVwbyRQzf9MFDUypYJ8KRsV5/rdxnGzTaJLlYbNoQpIG3lQZelggGpS
N6f5kz0fHRkTqCrINJpmLVkvQDbNNDslsDcr86O0LEI7NPrBry5fUSxI+YOzCJCu
3xnkIiYlcua2WGEXNd6vPQ
-> ssh-ed25519 /vwQcQ L9OynFtsmYWQBB/PKHsJ4B2mdUFk8wkuPzaKBmvKERc
LPHLANWrv90EFdF+cXEOFnOf1XaLWeyEDij+DYVrDJM
-> ssh-ed25519 0R97PA 49YuJOzGjfLe8RixCtw8Z/EEngEGyNRQjb6sDXESQyM
ICCw8XFpzJjZpOayDR6uoHqdv0vuEVg1uQyNrNONj8s
-> ssh-ed25519 JGx7Ng fESc17fhVuC9dfNvDZKLq5EheYw+ufw0hpJqeDffxSE
CWRV2wnZYh/bK5xgCDUASUmYMWSLbTXqnD1TFcbEHUU
-> ssh-ed25519 5SY7Kg DgOrBwnV6Uxc5dMcNSR57HSgTW5DsG9Y9kcNYNevMGw
W0HtwhGJ2jiU9jrfvGoEXthZ3ewxAL8ERNOUYSgWI1A
-> ssh-ed25519 p/Mg4Q doo+f6eD3s2uoMwekzHcUFCsls8gNZjiI0Nyyd1sClA
NZnBQy9PJeabIwp6N7D85sI/UbCIcC7FzQALoNOD5h0
-> ssh-ed25519 tDqJRg tVVtvHVf/l4k+vr5A81tKTff49Rn1L1lrONq1DaGxDk
vskCx+/l45iAtB8Mn6S9T7I0rKEGgesDfqBrrT0wewU
--- HQzVXwtwdHyjKCBSbBOTiytzpLVc1eBCZZgW7sIgFEI
9˜†%}/JÞ„U»cMä<38>ç™`®=%¿ÝîN} è9tñœÇ§‰¡¨‰rŒ}ˆ½KÿøžqøëO5GlùÑct#" Ò[Yw½e‰<65>_ûtˆ)f3Çòª´ÕGÊ2¹j„Wý^ìr¹ôYa=ESÓ ýØ,<2C>²Ú“rÐ_„£ ý8E ªª Ž¬1çî•íŇ“sÂ<73>ü–¼<”µŸ‚£ 0QMU"Œ±Ú’Åõ õˆ¬wSúœ4º=ï‰G(ˆ’º<<3C>?iZSW]Œ. pP93±zžl¸OSd·êS¯šçI­8Äeײ·Ú7ÃUMù¯< ªº<C2AA>Ýžóì<>?îOc2Z¬Uº Ä•èc²àԗ×7@ÄýôóŠòZæ™ihCžXß”QŸcɹ[èo=kÏòñËÞL"Z Í/uê´q ÛGäçó Ú[<5B>ú,£«i×Ãäs<C3A4>Jÿ•=GBç~^€Ù'Aý´èÕ±©¹í*giÝ|Ý*ùN·ÿŠË‘a]º˜áäši|áÔŽP'_(½±ÂQLŽØl„O ÈÛ´
P94ϨäÛF½]³¡È{Öºeç4ý[McQuÎÞî« ¥Jwȃ¼Ê“÷•ÁÛX@RÙÑÛŒú‰5M•Ý£V<E280B9>rjÇ—ó<E28094>„—½¢Ÿó7<C3B3>[¨8qÐb

View file

@ -1,22 +0,0 @@
{
config,
sources,
nixpkgs,
...
}:
{
imports = [ (import (sources.signal-irc-bridge.outPath + "/module.nix")) ];
services.signal-irc-bridge = {
enable = true;
package = nixpkgs.unstable.callPackage (sources.signal-irc-bridge.outPath + "/package.nix") { };
configFile = config.age.secrets."signal-irc-bridge-config".path;
};
services.nginx.virtualHosts."bridge.dgnum.eu" = {
forceSSL = true;
enableACME = true;
locations."/files/".alias = "/var/lib/signal-irc/hermes-media/";
};
users.users.nginx.extraGroups = [ "signal-irc" ];
}

View file

@ -1,35 +0,0 @@
diff --git a/build.gradle b/build.gradle
index 78901d8e..3a14ceee 100644
--- a/build.gradle
+++ b/build.gradle
@@ -70,20 +70,6 @@ launch4j {
messagesInstanceAlreadyExists="Stirling-PDF is already running."
}
-spotless {
- java {
- target project.fileTree('src/main/java')
-
- googleJavaFormat('1.19.1').aosp().reorderImports(false)
-
- importOrder('java', 'javax', 'org', 'com', 'net', 'io')
- toggleOffOn()
- trimTrailingWhitespace()
- indentWithSpaces()
- endWithNewline()
- }
-}
-
dependencies {
//security updates
implementation 'ch.qos.logback:logback-classic:1.5.3'
@@ -171,9 +157,6 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok:1.18.32'
}
-tasks.withType(JavaCompile).configureEach {
- dependsOn 'spotlessApply'
-}
compileJava {
options.compilerArgs << '-parameters'
}

View file

@ -1,12 +0,0 @@
diff --git a/build.gradle b/build.gradle
index 78901d8e..2e7ff96b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -166,6 +166,7 @@ task writeVersion {
def props = new Properties()
props.setProperty('version', version)
props.store(propsFile.newWriter(), null)
+ propsFile.text = propsFile.readLines().tail().join('\n')
}
swaggerhubUpload {

View file

@ -1,16 +0,0 @@
diff --git a/build.gradle b/build.gradle
index 2e7ff96b..f3a4a15c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -21,6 +21,11 @@ repositories {
mavenCentral()
}
+tasks.withType(AbstractArchiveTask) {
+ preserveFileTimestamps = false
+ reproducibleFileOrder = true
+}
+
licenseReport {
renderers = [new JsonReportRenderer()]
}

View file

@ -1,25 +0,0 @@
diff --git a/build.gradle b/build.gradle
index f3a4a15c..61fbd74e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -18,7 +18,7 @@ version = '0.26.1'
sourceCompatibility = '17'
repositories {
- mavenCentral()
+ maven { url '@deps@' }
}
tasks.withType(AbstractArchiveTask) {
diff --git a/settings.gradle b/settings.gradle
index f8139930..2c87f3cc 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1,7 @@
+pluginManagement {
+ repositories {
+ maven { url '@deps@' }
+ }
+}
+
rootProject.name = 'Stirling-PDF'

Some files were not shown because too many files have changed in this diff Show more