Compare commits

..

No commits in common. "main" and "add_cst1_ssh" have entirely different histories.

112 changed files with 2615 additions and 2186 deletions

1
.envrc
View file

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

View file

@ -1,16 +1,3 @@
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 name: Check meta
on: on:
pull_request: pull_request:
@ -18,4 +5,21 @@ on:
- main - main
push: push:
paths: paths:
- meta/* - 'meta/*'
jobs:
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
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 --no-out-link

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,56 @@
name: ds-fr update
on:
schedule:
- cron: "26 18 * * wed"
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,200 @@
name: build configuration
on:
pull_request:
types: [opened, synchronize, edited, reopened]
branches:
- main
push:
branches:
- main
jobs:
build_and_cache_krz01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build and cache the node
run: nix-shell --run cache-node
env:
STORE_ENDPOINT: "https://tvix-store.dgnum.eu/infra-signing/"
STORE_USER: "admin"
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
BUILD_NODE: "krz01"
- uses: actions/upload-artifact@v3
if: always()
with:
name: outputs_krz01
path: paths.txt
build_and_cache_compute01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build and cache the node
run: nix-shell --run cache-node
env:
STORE_ENDPOINT: "https://tvix-store.dgnum.eu/infra-signing/"
STORE_USER: "admin"
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
BUILD_NODE: "compute01"
- uses: actions/upload-artifact@v3
if: always()
with:
name: outputs_compute01
path: paths.txt
build_and_cache_storage01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build and cache the node
run: nix-shell --run cache-node
env:
STORE_ENDPOINT: "https://tvix-store.dgnum.eu/infra-signing/"
STORE_USER: "admin"
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
BUILD_NODE: "storage01"
- uses: actions/upload-artifact@v3
if: always()
with:
name: outputs_storage01
path: paths.txt
build_and_cache_rescue01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build and cache the node
run: nix-shell --run cache-node
env:
STORE_ENDPOINT: "https://tvix-store.dgnum.eu/infra-signing/"
STORE_USER: "admin"
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
BUILD_NODE: "rescue01"
- uses: actions/upload-artifact@v3
if: always()
with:
name: outputs_rescue01
path: paths.txt
build_and_cache_geo01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build and cache the node
run: nix-shell --run cache-node
env:
STORE_ENDPOINT: "https://tvix-store.dgnum.eu/infra-signing/"
STORE_USER: "admin"
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
BUILD_NODE: "geo01"
- uses: actions/upload-artifact@v3
if: always()
with:
name: outputs_geo01
path: paths.txt
build_and_cache_geo02:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build and cache the node
run: nix-shell --run cache-node
env:
STORE_ENDPOINT: "https://tvix-store.dgnum.eu/infra-signing/"
STORE_USER: "admin"
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
BUILD_NODE: "geo02"
- uses: actions/upload-artifact@v3
if: always()
with:
name: outputs_geo02
path: paths.txt
build_and_cache_vault01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build and cache the node
run: nix-shell --run cache-node
env:
STORE_ENDPOINT: "https://tvix-store.dgnum.eu/infra-signing/"
STORE_USER: "admin"
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
BUILD_NODE: "vault01"
- uses: actions/upload-artifact@v3
if: always()
with:
name: outputs_vault01
path: paths.txt
build_and_cache_web01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build and cache the node
run: nix-shell --run cache-node
env:
STORE_ENDPOINT: "https://tvix-store.dgnum.eu/infra-signing/"
STORE_USER: "admin"
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
BUILD_NODE: "web01"
- uses: actions/upload-artifact@v3
if: always()
with:
name: outputs_web01
path: paths.txt
build_and_cache_web02:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build and cache the node
run: nix-shell --run cache-node
env:
STORE_ENDPOINT: "https://tvix-store.dgnum.eu/infra-signing/"
STORE_USER: "admin"
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
BUILD_NODE: "web02"
- uses: actions/upload-artifact@v3
if: always()
with:
name: outputs_web02
path: paths.txt
build_and_cache_bridge01:
runs-on: nix
steps:
- uses: actions/checkout@v3
- name: Build and cache the node
run: nix-shell --run cache-node
env:
STORE_ENDPOINT: "https://tvix-store.dgnum.eu/infra-signing/"
STORE_USER: "admin"
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
BUILD_NODE: "bridge01"
- uses: actions/upload-artifact@v3
if: always()
with:
name: outputs_web02
path: paths.txt

View file

@ -0,0 +1,11 @@
name: lint
on: [push, pull_request]
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 --hook-stage pre-push --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

View file

@ -41,15 +41,7 @@
}: }:
let let
inherit (pkgs.lib) git-checks = (import (builtins.storePath sources.git-hooks)).run {
isFunction
mapAttrs
mapAttrs'
nameValuePair
removeSuffix
;
git-checks = (import sources.git-hooks).run {
src = ./.; src = ./.;
hooks = { hooks = {
@ -75,22 +67,6 @@ let
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
{ {
@ -102,35 +78,36 @@ in
mkCacheSettings = import ./machines/storage01/tvix-cache/cache-settings.nix; mkCacheSettings = import ./machines/storage01/tvix-cache/cache-settings.nix;
devShell = pkgs.mkShell { shells = {
default = pkgs.mkShell {
name = "dgnum-infra"; name = "dgnum-infra";
packages = [ packages = [
(pkgs.nixos-generators.overrideAttrs (_: { (pkgs.nixos-generators.overrideAttrs (_: {
version = "1.8.0-unstable"; version = "1.8.0-unstable";
src = sources.nixos-generators; src = builtins.storePath sources.nixos-generators;
})) }))
pkgs.npins pkgs.npins
(pkgs.callPackage ./lib/colmena { inherit (nix-pkgs) colmena; }) (pkgs.callPackage ./lib/colmena { inherit (nix-pkgs) colmena; })
(pkgs.callPackage "${sources.agenix}/pkgs/agenix.nix" { }) (pkgs.callPackage "${sources.agenix}/pkgs/agenix.nix" { })
(pkgs.callPackage "${sources.lon}/nix/packages/lon.nix" { }) (pkgs.callPackage "${sources.lon}/nix/packages/lon.nix" { })
] ++ (builtins.attrValues scripts);
] ++ (import ./scripts { inherit pkgs; });
shellHook = '' shellHook = ''
${git-checks.shellHook} ${git-checks.shellHook}
${workflows.shellHook}
''; '';
preferLocalBuild = true; preferLocalBuild = true;
};
### pre-commit = pkgs.mkShell {
# Alternative shells name = "pre-commit-shell";
passthru = mapAttrs (name: value: pkgs.mkShell (value // { inherit name; })) { shellHook = ''
pre-commit.shellHook = git-checks.shellHook; ${git-checks.shellHook}
check-workflows.shellHook = workflows.shellHook; '';
eval-nodes.packages = [ scripts.cache-node ];
}; };
}; };
} }

View file

@ -64,12 +64,23 @@ in
}; };
defaults = defaults =
{ name, nodeMeta, ... }: {
pkgs,
name,
nodeMeta,
...
}:
{ {
# Import the default modules # Import the default modules
imports = [ imports = [
./modules ./modules
(import "${sources.lix-module}/module.nix" { inherit (sources) lix; }) (import "${sources.lix-module}/module.nix" {
lix = pkgs.applyPatches {
name = "lix-2.90.patched";
src = sources.lix;
patches = [ ./patches/00-disable-installChecks-lix.patch ];
};
})
]; ];
# Include default secrets # Include default secrets

View file

@ -17,17 +17,14 @@ rec {
compute01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE/YluSVS+4h3oV8CIUj0OmquyJXju8aEQy0Jz210vTu" ]; compute01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE/YluSVS+4h3oV8CIUj0OmquyJXju8aEQy0Jz210vTu" ];
geo01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEl6Pubbau+usQkemymoSKrTBbrX8JU5m5qpZbhNx8p4" ]; geo01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEl6Pubbau+usQkemymoSKrTBbrX8JU5m5qpZbhNx8p4" ];
geo02 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFNXaCS0/Nsu5npqQk1TP6wMHCVIOaj4pblp2tIg6Ket" ]; geo02 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFNXaCS0/Nsu5npqQk1TP6wMHCVIOaj4pblp2tIg6Ket" ];
krz01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP4o65gWOgNrxbSd3kiQIGZUM+YD6kuZOQtblvzUGsfB" ];
rescue01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEJa02Annu8o7ggPjTH/9ttotdNGyghlWfU9E8pnuLUf" ]; rescue01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEJa02Annu8o7ggPjTH/9ttotdNGyghlWfU9E8pnuLUf" ];
storage01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA0s+rPcEcfWCqZ4B2oJiWT/60awOI8ijL1rtDM2glXZ" ]; storage01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA0s+rPcEcfWCqZ4B2oJiWT/60awOI8ijL1rtDM2glXZ" ];
vault01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJA6VA7LENvTRlKdcrqt8DxDOPvX3bg3Gjy9mNkdFEW" ]; vault01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJA6VA7LENvTRlKdcrqt8DxDOPvX3bg3Gjy9mNkdFEW" ];
web01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPR+lewuJ/zhCyizJGJOH1UaAB699ItNKEaeuoK57LY5" ]; web01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPR+lewuJ/zhCyizJGJOH1UaAB699ItNKEaeuoK57LY5" ];
web02 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID+QDE+GgZs6zONHvzRW15BzGJNW69k2BFZgB/Zh/tLX" ]; web02 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID+QDE+GgZs6zONHvzRW15BzGJNW69k2BFZgB/Zh/tLX" ];
web03 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICrWsMEfK86iaO9SubMqE2UvZNtHkLY5VUod/bbqKC0L" ];
# SSH keys of the DGNum members # 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 = [ catvayor = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAA16foz+XzwKwyIR4wFgNIAE3Y7AfXyEsUZFVVz8Rie catvayor@katvayor" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAA16foz+XzwKwyIR4wFgNIAE3Y7AfXyEsUZFVVz8Rie catvayor@katvayor"
]; ];
@ -47,10 +44,8 @@ rec {
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDMBW7rTtfZL9wtrpCVgariKdpN60/VeAzXkh9w3MwbO julien@enigma" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDMBW7rTtfZL9wtrpCVgariKdpN60/VeAzXkh9w3MwbO julien@enigma"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGa+7n7kNzb86pTqaMn554KiPrkHRGeTJ0asY1NjSbpr julien@tower" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGa+7n7kNzb86pTqaMn554KiPrkHRGeTJ0asY1NjSbpr julien@tower"
]; ];
mboyer = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGYnwZaFYvUxtJeNvpaA20rLfq8fOO4dFp7cIXsD8YNx" ];
mdebray = [ mdebray = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEpwF+XD3HgX64kqD42pcEZRNYAWoO4YNiOm5KO4tH6o maurice@polaris" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEpwF+XD3HgX64kqD42pcEZRNYAWoO4YNiOm5KO4tH6o maurice@polaris"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFdDnSl3cyWil+S5JiyGqOvBR3wVh+lduw58S5WvraoL maurice@fekda"
]; ];
raito = [ raito = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcEkYM1r8QVNM/G5CxJInEdoBCWjEHHDdHlzDYNSUIdHHsn04QY+XI67AdMCm8w30GZnLUIj5RiJEWXREUApby0GrfxGGcy8otforygfgtmuUKAUEHdU2MMwrQI7RtTZ8oQ0USRGuqvmegxz3l5caVU7qGvBllJ4NUHXrkZSja2/51vq80RF4MKkDGiz7xUTixI2UcBwQBCA/kQedKV9G28EH+1XfvePqmMivZjl+7VyHsgUVj9eRGA1XWFw59UPZG8a7VkxO/Eb3K9NF297HUAcFMcbY6cPFi9AaBgu3VC4eetDnoN/+xT1owiHi7BReQhGAy/6cdf7C/my5ehZwD" "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcEkYM1r8QVNM/G5CxJInEdoBCWjEHHDdHlzDYNSUIdHHsn04QY+XI67AdMCm8w30GZnLUIj5RiJEWXREUApby0GrfxGGcy8otforygfgtmuUKAUEHdU2MMwrQI7RtTZ8oQ0USRGuqvmegxz3l5caVU7qGvBllJ4NUHXrkZSja2/51vq80RF4MKkDGiz7xUTixI2UcBwQBCA/kQedKV9G28EH+1XfvePqmMivZjl+7VyHsgUVj9eRGA1XWFw59UPZG8a7VkxO/Eb3K9NF297HUAcFMcbY6cPFi9AaBgu3VC4eetDnoN/+xT1owiHi7BReQhGAy/6cdf7C/my5ehZwD"

View file

@ -190,11 +190,8 @@ rec {
recursiveFuse [ recursiveFuse [
(enableModules enabledModules) (enableModules enabledModules)
{ { imports = mkImports root ([ "_hardware-configuration" ] ++ enabledServices); }
imports =
(extraConfig.imports or [ ]) ++ (mkImports root ([ "_hardware-configuration" ] ++ enabledServices));
}
(removeAttrs extraConfig [ "imports" ]) extraConfig
]; ];
} }

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

@ -69,11 +69,17 @@ in
} }
]; ];
}; };
};
dgn-web.simpleProxies.grafana = { nginx.virtualHosts.${host} = {
inherit host port; enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${builtins.toString port}";
proxyWebsockets = true; 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,23 +1,14 @@
{ {
config, config,
lib, lib,
meta,
nixpkgs, nixpkgs,
... ...
}: }:
let let
inherit (lib) inherit (lib) escapeRegex concatStringsSep;
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};
@ -36,8 +27,6 @@ let
"netbird-beta.hubrecht.ovh" "netbird-beta.hubrecht.ovh"
] ]
); );
usernameFor = member: meta.organization.members.${member}.username;
in in
{ {
services.kanidm = { services.kanidm = {
@ -50,7 +39,7 @@ in
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;
@ -58,113 +47,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;
@ -172,7 +58,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)$ ) {

View file

@ -3,8 +3,6 @@
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 = {
@ -106,7 +104,7 @@ in
imageDigest = "sha256:07da8a191b37058514dfdf921ea8c2270c6634fa659acee774cf8594f86950e4"; imageDigest = "sha256:07da8a191b37058514dfdf921ea8c2270c6634fa659acee774cf8594f86950e4";
sha256 = "sha256-5oaz07NQScHUVN/HznzZGQ2bGrU/V1GhI+9btXHz0GM="; sha256 = "sha256-5oaz07NQScHUVN/HznzZGQ2bGrU/V1GhI+9btXHz0GM=";
}; };
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";
@ -121,8 +119,6 @@ in
}; };
}; };
dgn-web.internalPorts.collabora = port;
services.nginx.virtualHosts = { services.nginx.virtualHosts = {
${host} = { ${host} = {
enableACME = true; enableACME = true;
@ -140,25 +136,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 +163,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 +1,27 @@
{ pkgs, ... }: {
pkgs,
nodes,
meta,
...
}:
{ {
services.nginx = { services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts."ollama01.beta.dgnum.eu" = { virtualHosts."ollama01.beta.dgnum.eu" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
locations."/" = { locations."/" = {
proxyPass = "http://100.80.103.206:11434"; proxyPass = "http://${meta.network.krz01.netbirdIp}:${toString nodes.krz01.config.services.ollama.port}";
basicAuthFile = pkgs.writeText "ollama-htpasswd" '' basicAuthFile = pkgs.writeText "ollama-htpasswd" ''
raito:$y$j9T$UDEHpLtM52hRGK0I4qT6M0$N75AhENLqgtJnTGaPzq51imhjZvuPr.ow81Co1ZTcX2 raito:$y$j9T$UDEHpLtM52hRGK0I4qT6M0$N75AhENLqgtJnTGaPzq51imhjZvuPr.ow81Co1ZTcX2
''; '';
}; };
}; };
}; };
networking.firewall.allowedTCPPorts = [
80
443
];
} }

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

@ -38,7 +38,16 @@ in
}; };
}; };
dgn-web.simpleProxies.plausible = { services.nginx = {
inherit host port; enable = true;
virtualHosts.${host} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${builtins.toString port}";
};
};
}; };
} }

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

@ -190,6 +190,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

@ -10,13 +10,10 @@ let
# - push to a new branch dgn-v0.A.B where A.B is the new version # - push to a new branch dgn-v0.A.B where A.B is the new version
# - finally, update the commit hash of the customization patch # - finally, update the commit hash of the customization patch
dgn-id = "d73e347b1cefe23092bfcb2d3f8a23903410203e"; dgn-id = "8f19cb1c9623f8da71f6512c1528d83acc35db57";
port = 8084;
in in
{ {
dgn-web.internalPorts.stirling-pdf = port;
services.stirling-pdf = { services.stirling-pdf = {
enable = true; enable = true;
@ -27,7 +24,7 @@ in
}); });
domain = "pdf.dgnum.eu"; domain = "pdf.dgnum.eu";
inherit port; port = 8084;
nginx = { nginx = {
enableACME = true; enableACME = true;

View file

@ -2,8 +2,6 @@
let let
host = "pass.dgnum.eu"; host = "pass.dgnum.eu";
port = 10501;
wsPort = 10500;
in in
{ {
services.vaultwarden = { services.vaultwarden = {
@ -12,9 +10,9 @@ in
config = { config = {
DOMAIN = "https://${host}"; DOMAIN = "https://${host}";
WEBSOCKET_ENABLED = true; WEBSOCKET_ENABLED = true;
WEBSOCKET_PORT = wsPort; WEBSOCKET_PORT = 10500;
SIGNUPS_DOMAINS_WHITELIST = "dgnum.eu,ens.fr,ens.psl.eu"; SIGNUPS_DOMAINS_WHITELIST = "dgnum.eu,ens.fr,ens.psl.eu";
ROCKET_PORT = port; ROCKET_PORT = 10501;
ROCKET_ADDRESS = "127.0.0.1"; ROCKET_ADDRESS = "127.0.0.1";
SIGNUPS_VERIFY = true; SIGNUPS_VERIFY = true;
USE_SYSLOG = true; USE_SYSLOG = true;
@ -33,28 +31,34 @@ in
environmentFile = config.age.secrets."vaultwarden-environment_file".path; environmentFile = config.age.secrets."vaultwarden-environment_file".path;
}; };
dgn-web = { services = {
internalPorts.vaultwarden-websockets = wsPort; nginx = {
enable = true;
simpleProxies.vaultwarden = { virtualHosts.${host} = {
inherit host port; forceSSL = true;
enableACME = true;
locations = {
"/" = {
proxyPass = "http://127.0.0.1:10501";
proxyWebsockets = true; proxyWebsockets = true;
};
vhostConfig.locations = {
"/notifications/hub" = { "/notifications/hub" = {
proxyPass = "http://127.0.0.1:${builtins.toString port}"; proxyPass = "http://127.0.0.1:10500";
proxyWebsockets = true; proxyWebsockets = true;
}; };
"/notifications/hub/negotiate" = { "/notifications/hub/negotiate" = {
proxyPass = "http://127.0.0.1:${builtins.toString wsPort}"; proxyPass = "http://127.0.0.1:10501";
proxyWebsockets = true; proxyWebsockets = true;
}; };
}; };
}; };
}; };
services.postgresql = { postgresql = {
enable = true; enable = true;
ensureDatabases = [ "vaultwarden" ]; ensureDatabases = [ "vaultwarden" ];
@ -66,6 +70,7 @@ in
} }
]; ];
}; };
};
dgn-backups.jobs.vaultwarden.settings.paths = [ "/var/lib/bitwarden_rs" ]; dgn-backups.jobs.vaultwarden.settings.paths = [ "/var/lib/bitwarden_rs" ];
dgn-backups.postgresDatabases = [ "vaultwarden" ]; dgn-backups.postgresDatabases = [ "vaultwarden" ];

View file

@ -0,0 +1,179 @@
From 2abd226ff3093c5a9e18a618fba466853e7ebaf7 Mon Sep 17 00:00:00 2001
From: Raito Bezarius <masterancpp@gmail.com>
Date: Tue, 8 Oct 2024 18:27:41 +0200
Subject: [PATCH] K80 support
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
---
docs/development.md | 6 +++-
docs/gpu.md | 1 +
gpu/amd_linux.go | 6 +++-
gpu/gpu.go | 63 ++++++++++++++++++++++++++++++++++++-----
scripts/build_docker.sh | 2 +-
scripts/build_linux.sh | 2 +-
6 files changed, 69 insertions(+), 11 deletions(-)
diff --git a/docs/development.md b/docs/development.md
index 2f7b9ecf..9da35931 100644
--- a/docs/development.md
+++ b/docs/development.md
@@ -51,7 +51,11 @@ Typically the build scripts will auto-detect CUDA, however, if your Linux distro
or installation approach uses unusual paths, you can specify the location by
specifying an environment variable `CUDA_LIB_DIR` to the location of the shared
libraries, and `CUDACXX` to the location of the nvcc compiler. You can customize
-a set of target CUDA architectures by setting `CMAKE_CUDA_ARCHITECTURES` (e.g. "50;60;70")
+a set of target CUDA architectures by setting `CMAKE_CUDA_ARCHITECTURES` (e.g. "35;37;50;60;70")
+
+To support GPUs older than Compute Capability 5.0, you will need to use an older version of
+the Driver from [Unix Driver Archive](https://www.nvidia.com/en-us/drivers/unix/) (tested with 470) and [CUDA Toolkit Archive](https://developer.nvidia.com/cuda-toolkit-archive) (tested with cuda V11). When you build Ollama, you will need to set two environment variable to adjust the minimum compute capability Ollama supports via `export GOFLAGS="'-ldflags=-w -s \"-X=github.com/ollama/ollama/gpu.CudaComputeMajorMin=3\" \"-X=github.com/ollama/ollama/gpu.CudaComputeMinorMin=5\"'"` and the `CMAKE_CUDA_ARCHITECTURES`. To find the Compute Capability of your older GPU, refer to [GPU Compute Capability](https://developer.nvidia.com/cuda-gpus).
+
Then generate dependencies:
diff --git a/docs/gpu.md b/docs/gpu.md
index a6b559f0..66627611 100644
--- a/docs/gpu.md
+++ b/docs/gpu.md
@@ -28,6 +28,7 @@ Check your compute compatibility to see if your card is supported:
| 5.0 | GeForce GTX | `GTX 750 Ti` `GTX 750` `NVS 810` |
| | Quadro | `K2200` `K1200` `K620` `M1200` `M520` `M5000M` `M4000M` `M3000M` `M2000M` `M1000M` `K620M` `M600M` `M500M` |
+For building locally to support older GPUs, see [developer.md](./development.md#linux-cuda-nvidia)
### GPU Selection
diff --git a/gpu/amd_linux.go b/gpu/amd_linux.go
index 6b08ac2e..768fb97a 100644
--- a/gpu/amd_linux.go
+++ b/gpu/amd_linux.go
@@ -159,7 +159,11 @@ func AMDGetGPUInfo() []GpuInfo {
return []GpuInfo{}
}
- if int(major) < RocmComputeMin {
+ minVer, err := strconv.Atoi(RocmComputeMajorMin)
+ if err != nil {
+ slog.Error("invalid RocmComputeMajorMin setting", "value", RocmComputeMajorMin, "error", err)
+ }
+ if int(major) < minVer {
slog.Warn(fmt.Sprintf("amdgpu too old gfx%d%x%x", major, minor, patch), "gpu", gpuID)
continue
}
diff --git a/gpu/gpu.go b/gpu/gpu.go
index 781e23df..60d68c33 100644
--- a/gpu/gpu.go
+++ b/gpu/gpu.go
@@ -16,6 +16,7 @@ import (
"os"
"path/filepath"
"runtime"
+ "strconv"
"strings"
"sync"
"unsafe"
@@ -38,9 +39,11 @@ const (
var gpuMutex sync.Mutex
// With our current CUDA compile flags, older than 5.0 will not work properly
-var CudaComputeMin = [2]C.int{5, 0}
+// (string values used to allow ldflags overrides at build time)
+var CudaComputeMajorMin = "5"
+var CudaComputeMinorMin = "0"
-var RocmComputeMin = 9
+var RocmComputeMajorMin = "9"
// TODO find a better way to detect iGPU instead of minimum memory
const IGPUMemLimit = 1 * format.GibiByte // 512G is what they typically report, so anything less than 1G must be iGPU
@@ -175,11 +178,57 @@ func GetGPUInfo() GpuInfoList {
var memInfo C.mem_info_t
resp := []GpuInfo{}
- // NVIDIA first
- for i := 0; i < gpuHandles.deviceCount; i++ {
- // TODO once we support CPU compilation variants of GPU libraries refine this...
- if cpuVariant == "" && runtime.GOARCH == "amd64" {
- continue
+ // Load ALL libraries
+ cHandles = initCudaHandles()
+ minMajorVer, err := strconv.Atoi(CudaComputeMajorMin)
+ if err != nil {
+ slog.Error("invalid CudaComputeMajorMin setting", "value", CudaComputeMajorMin, "error", err)
+ }
+ minMinorVer, err := strconv.Atoi(CudaComputeMinorMin)
+ if err != nil {
+ slog.Error("invalid CudaComputeMinorMin setting", "value", CudaComputeMinorMin, "error", err)
+ }
+
+ // NVIDIA
+ for i := range cHandles.deviceCount {
+ if cHandles.cudart != nil || cHandles.nvcuda != nil {
+ gpuInfo := CudaGPUInfo{
+ GpuInfo: GpuInfo{
+ Library: "cuda",
+ },
+ index: i,
+ }
+ var driverMajor int
+ var driverMinor int
+ if cHandles.cudart != nil {
+ C.cudart_bootstrap(*cHandles.cudart, C.int(i), &memInfo)
+ } else {
+ C.nvcuda_bootstrap(*cHandles.nvcuda, C.int(i), &memInfo)
+ driverMajor = int(cHandles.nvcuda.driver_major)
+ driverMinor = int(cHandles.nvcuda.driver_minor)
+ }
+ if memInfo.err != nil {
+ slog.Info("error looking up nvidia GPU memory", "error", C.GoString(memInfo.err))
+ C.free(unsafe.Pointer(memInfo.err))
+ continue
+ }
+
+ if int(memInfo.major) < minMajorVer || (int(memInfo.major) == minMajorVer && int(memInfo.minor) < minMinorVer) {
+ slog.Info(fmt.Sprintf("[%d] CUDA GPU is too old. Compute Capability detected: %d.%d", i, memInfo.major, memInfo.minor))
+ continue
+ }
+ gpuInfo.TotalMemory = uint64(memInfo.total)
+ gpuInfo.FreeMemory = uint64(memInfo.free)
+ gpuInfo.ID = C.GoString(&memInfo.gpu_id[0])
+ gpuInfo.Compute = fmt.Sprintf("%d.%d", memInfo.major, memInfo.minor)
+ gpuInfo.MinimumMemory = cudaMinimumMemory
+ gpuInfo.DependencyPath = depPath
+ gpuInfo.Name = C.GoString(&memInfo.gpu_name[0])
+ gpuInfo.DriverMajor = driverMajor
+ gpuInfo.DriverMinor = driverMinor
+
+ // TODO potentially sort on our own algorithm instead of what the underlying GPU library does...
+ cudaGPUs = append(cudaGPUs, gpuInfo)
}
gpuInfo := GpuInfo{
Library: "cuda",
diff --git a/scripts/build_docker.sh b/scripts/build_docker.sh
index e91c56ed..c03bc25f 100755
--- a/scripts/build_docker.sh
+++ b/scripts/build_docker.sh
@@ -3,7 +3,7 @@
set -eu
export VERSION=${VERSION:-$(git describe --tags --first-parent --abbrev=7 --long --dirty --always | sed -e "s/^v//g")}
-export GOFLAGS="'-ldflags=-w -s \"-X=github.com/ollama/ollama/version.Version=$VERSION\" \"-X=github.com/ollama/ollama/server.mode=release\"'"
+export GOFLAGS=${GOFLAGS:-"'-ldflags=-w -s \"-X=github.com/ollama/ollama/version.Version=$VERSION\" \"-X=github.com/ollama/ollama/server.mode=release\"'"}
# We use 2 different image repositories to handle combining architecture images into multiarch manifest
# (The ROCm image is x86 only and is not a multiarch manifest)
diff --git a/scripts/build_linux.sh b/scripts/build_linux.sh
index 27c4ff1f..e7e6d0dd 100755
--- a/scripts/build_linux.sh
+++ b/scripts/build_linux.sh
@@ -3,7 +3,7 @@
set -eu
export VERSION=${VERSION:-$(git describe --tags --first-parent --abbrev=7 --long --dirty --always | sed -e "s/^v//g")}
-export GOFLAGS="'-ldflags=-w -s \"-X=github.com/ollama/ollama/version.Version=$VERSION\" \"-X=github.com/ollama/ollama/server.mode=release\"'"
+export GOFLAGS=${GOFLAGS:-"'-ldflags=-w -s \"-X=github.com/ollama/ollama/version.Version=$VERSION\" \"-X=github.com/ollama/ollama/server.mode=release\"'"}
BUILD_ARCH=${BUILD_ARCH:-"amd64 arm64"}
export AMDGPU_TARGETS=${AMDGPU_TARGETS:=""}
--
2.46.0

View file

@ -0,0 +1,79 @@
{
config,
lib,
pkgs,
meta,
name,
...
}:
lib.extra.mkConfig {
enabledModules = [
# INFO: This list needs to stay sorted alphabetically
];
enabledServices = [
# INFO: This list needs to stay sorted alphabetically
# Machine learning API machine
"microvm-ml01"
"microvm-router01"
"nvidia-tesla-k80"
"proxmox"
];
extraConfig = {
microvm = {
host.enable = true;
};
dgn-hardware = {
useZfs = true;
zfsPools = [
"dpool"
"ppool0"
];
};
services.netbird.enable = true;
# We are going to use CUDA here.
nixpkgs.config.cudaSupport = true;
hardware.graphics.enable = true;
environment.systemPackages = [
((pkgs.openai-whisper-cpp.override { cudaPackages = pkgs.cudaPackages_11; }).overrideAttrs (old: {
src = pkgs.fetchFromGitHub {
owner = "ggerganov";
repo = "whisper.cpp";
rev = "v1.7.1";
hash = "sha256-EDFUVjud79ZRCzGbOh9L9NcXfN3ikvsqkVSOME9F9oo=";
};
env = {
WHISPER_CUBLAS = "";
GGML_CUDA = "1";
};
# We only need Compute Capability 3.7.
CUDA_ARCH_FLAGS = [ "sm_37" ];
# We are GPU-only anyway.
patches = (old.patches or [ ]) ++ [
./no-weird-microarch.patch
./all-nvcc-arch.patch
];
}))
];
services = {
ollama = {
enable = true;
host = meta.network.${name}.netbirdIp;
package = pkgs.callPackage ./ollama.nix {
cudaPackages = pkgs.cudaPackages_11;
# We need to thread our nvidia x11 driver for CUDA.
extraLibraries = [ config.hardware.nvidia.package ];
};
};
};
networking.firewall.interfaces.wt0.allowedTCPPorts = [ config.services.ollama.port ];
};
root = ./.;
}

View file

@ -0,0 +1,50 @@
{
config,
lib,
modulesPath,
...
}:
{
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot = {
initrd = {
availableKernelModules = [
"ehci_pci"
"ahci"
"mpt3sas"
"usbhid"
"sd_mod"
];
kernelModules = [ ];
};
kernelModules = [ "kvm-intel" ];
extraModulePackages = [ ];
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/92bf4d66-2693-4eca-9b26-f86ae09d468d";
fsType = "ext4";
};
boot.initrd.luks.devices."mainfs" = {
device = "/dev/disk/by-uuid/26f9737b-28aa-4c3f-bd3b-b028283cef88";
keyFileSize = 1;
keyFile = "/dev/zero";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/280C-8844";
fsType = "vfat";
options = [
"fmask=0022"
"dmask=0022"
];
};
swapDevices = [ ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -0,0 +1,26 @@
From 2278389ef9ac9231349440aa68f9544ddc69cdc7 Mon Sep 17 00:00:00 2001
From: Raito Bezarius <masterancpp@gmail.com>
Date: Wed, 9 Oct 2024 13:37:08 +0200
Subject: [PATCH] fix: sm_37 for nvcc
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 2ccb750..70dfd9b 100644
--- a/Makefile
+++ b/Makefile
@@ -537,7 +537,7 @@ endif #GGML_CUDA_NVCC
ifdef CUDA_DOCKER_ARCH
MK_NVCCFLAGS += -Wno-deprecated-gpu-targets -arch=$(CUDA_DOCKER_ARCH)
else ifndef CUDA_POWER_ARCH
- MK_NVCCFLAGS += -arch=native
+ MK_NVCCFLAGS += -arch=sm_37
endif # CUDA_DOCKER_ARCH
ifdef GGML_CUDA_FORCE_DMMV
--
2.46.0

View file

@ -0,0 +1,20 @@
diff --git c/llm/generate/gen_common.sh i/llm/generate/gen_common.sh
index 3825c155..238a74a7 100644
--- c/llm/generate/gen_common.sh
+++ i/llm/generate/gen_common.sh
@@ -69,6 +69,7 @@ git_module_setup() {
}
apply_patches() {
+ return
# apply temporary patches until fix is upstream
for patch in ../patches/*.patch; do
git -c 'user.name=nobody' -c 'user.email=<>' -C ${LLAMACPP_DIR} am ${patch}
@@ -133,6 +134,7 @@ install() {
# Keep the local tree clean after we're done with the build
cleanup() {
+ return
(cd ${LLAMACPP_DIR}/ && git checkout CMakeLists.txt)
if [ -n "$(ls -A ../patches/*.diff)" ]; then

View file

@ -0,0 +1,22 @@
_: {
microvm.autostart = [ "ml01" ];
microvm.vms.ml01 = {
config = {
networking.hostName = "ml01";
microvm = {
hypervisor = "cloud-hypervisor";
vcpu = 4;
mem = 4096;
balloonMem = 2048;
shares = [
{
source = "/nix/store";
mountPoint = "/nix/.ro-store";
tag = "ro-store";
proto = "virtiofs";
}
];
};
};
};
}

View file

@ -0,0 +1,16 @@
_: {
microvm.autostart = [ "router01" ];
microvm.vms.router01 = {
config = {
networking.hostName = "router01";
microvm.shares = [
{
source = "/nix/store";
mountPoint = "/nix/.ro-store";
tag = "ro-store";
proto = "virtiofs";
}
];
};
};
}

View file

@ -0,0 +1,34 @@
From 51568b61ef63ecd97867562571411082c32751d3 Mon Sep 17 00:00:00 2001
From: Raito Bezarius <masterancpp@gmail.com>
Date: Wed, 9 Oct 2024 13:36:51 +0200
Subject: [PATCH] fix: avx & f16c in Makefile
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
---
Makefile | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Makefile b/Makefile
index 32b7cbb..2ccb750 100644
--- a/Makefile
+++ b/Makefile
@@ -361,12 +361,12 @@ ifndef RISCV
ifeq ($(UNAME_M),$(filter $(UNAME_M),x86_64 i686 amd64))
# Use all CPU extensions that are available:
- MK_CFLAGS += -march=native -mtune=native
- HOST_CXXFLAGS += -march=native -mtune=native
+ # MK_CFLAGS += -march=native -mtune=native
+ # HOST_CXXFLAGS += -march=native -mtune=native
# Usage AVX-only
- #MK_CFLAGS += -mfma -mf16c -mavx
- #MK_CXXFLAGS += -mfma -mf16c -mavx
+ MK_CFLAGS += -mf16c -mavx
+ MK_CXXFLAGS += -mf16c -mavx
# Usage SSSE3-only (Not is SSE3!)
#MK_CFLAGS += -mssse3
--
2.46.0

View file

@ -0,0 +1,8 @@
{ config, ... }:
{
nixpkgs.config.nvidia.acceptLicense = true;
# Tesla K80 is not supported by the latest driver.
hardware.nvidia.package = config.boot.kernelPackages.nvidia_x11_legacy470;
# Don't ask.
services.xserver.videoDrivers = [ "nvidia" ];
}

243
machines/krz01/ollama.nix Normal file
View file

@ -0,0 +1,243 @@
{
lib,
buildGoModule,
fetchFromGitHub,
buildEnv,
linkFarm,
overrideCC,
makeWrapper,
stdenv,
addDriverRunpath,
nix-update-script,
cmake,
gcc11,
clblast,
libdrm,
rocmPackages,
cudaPackages,
darwin,
autoAddDriverRunpath,
extraLibraries ? [ ],
nixosTests,
testers,
ollama,
ollama-rocm,
ollama-cuda,
config,
# one of `[ null false "rocm" "cuda" ]`
acceleration ? null,
}:
assert builtins.elem acceleration [
null
false
"rocm"
"cuda"
];
let
pname = "ollama";
version = "2024-09-10-cc35";
src = fetchFromGitHub {
owner = "aliotard";
repo = "ollama";
rev = "34827c01f7723c7f5f9f5e392fe85f5a4a5d5fc0";
hash = "sha256-xFNuqcW7YWeyCyw5QLBnCHHTSMITR6LJkJT0CXZC+Y8=";
fetchSubmodules = true;
};
vendorHash = "sha256-hSxcREAujhvzHVNwnRTfhi0MKI3s8HNavER2VLz6SYk=";
validateFallback = lib.warnIf (config.rocmSupport && config.cudaSupport) (lib.concatStrings [
"both `nixpkgs.config.rocmSupport` and `nixpkgs.config.cudaSupport` are enabled, "
"but they are mutually exclusive; falling back to cpu"
]) (!(config.rocmSupport && config.cudaSupport));
shouldEnable =
mode: fallback: (acceleration == mode) || (fallback && acceleration == null && validateFallback);
rocmRequested = shouldEnable "rocm" config.rocmSupport;
cudaRequested = shouldEnable "cuda" config.cudaSupport;
enableRocm = rocmRequested && stdenv.isLinux;
enableCuda = cudaRequested && stdenv.isLinux;
rocmLibs = [
rocmPackages.clr
rocmPackages.hipblas
rocmPackages.rocblas
rocmPackages.rocsolver
rocmPackages.rocsparse
rocmPackages.rocm-device-libs
rocmPackages.rocm-smi
];
rocmClang = linkFarm "rocm-clang" { llvm = rocmPackages.llvm.clang; };
rocmPath = buildEnv {
name = "rocm-path";
paths = rocmLibs ++ [ rocmClang ];
};
cudaLibs = [
cudaPackages.cuda_cudart
cudaPackages.libcublas
cudaPackages.cuda_cccl
];
cudaToolkit = buildEnv {
name = "cuda-merged";
paths = map lib.getLib cudaLibs ++ [
(lib.getOutput "static" cudaPackages.cuda_cudart)
(lib.getBin (cudaPackages.cuda_nvcc.__spliced.buildHost or cudaPackages.cuda_nvcc))
];
};
metalFrameworks = with darwin.apple_sdk_11_0.frameworks; [
Accelerate
Metal
MetalKit
MetalPerformanceShaders
];
wrapperOptions =
[
# ollama embeds llama-cpp binaries which actually run the ai models
# these llama-cpp binaries are unaffected by the ollama binary's DT_RUNPATH
# LD_LIBRARY_PATH is temporarily required to use the gpu
# until these llama-cpp binaries can have their runpath patched
"--suffix LD_LIBRARY_PATH : '${addDriverRunpath.driverLink}/lib'"
"--suffix LD_LIBRARY_PATH : '${lib.makeLibraryPath (map lib.getLib extraLibraries)}'"
]
++ lib.optionals enableRocm [
"--suffix LD_LIBRARY_PATH : '${rocmPath}/lib'"
"--set-default HIP_PATH '${rocmPath}'"
]
++ lib.optionals enableCuda [
"--suffix LD_LIBRARY_PATH : '${lib.makeLibraryPath (map lib.getLib cudaLibs)}'"
];
wrapperArgs = builtins.concatStringsSep " " wrapperOptions;
goBuild =
if enableCuda then buildGoModule.override { stdenv = overrideCC stdenv gcc11; } else buildGoModule;
inherit (lib) licenses platforms maintainers;
in
goBuild {
inherit
pname
version
src
vendorHash
;
env =
lib.optionalAttrs enableRocm {
ROCM_PATH = rocmPath;
CLBlast_DIR = "${clblast}/lib/cmake/CLBlast";
}
// lib.optionalAttrs enableCuda { CUDA_LIB_DIR = "${cudaToolkit}/lib"; }
// {
CMAKE_CUDA_ARCHITECTURES = "35;37";
};
nativeBuildInputs =
[ cmake ]
++ lib.optionals enableRocm [ rocmPackages.llvm.bintools ]
++ lib.optionals enableCuda [ cudaPackages.cuda_nvcc ]
++ lib.optionals (enableRocm || enableCuda) [
makeWrapper
autoAddDriverRunpath
]
++ lib.optionals stdenv.isDarwin metalFrameworks;
buildInputs =
lib.optionals enableRocm (rocmLibs ++ [ libdrm ])
++ lib.optionals enableCuda cudaLibs
++ lib.optionals stdenv.isDarwin metalFrameworks;
patches = [
# disable uses of `git` in the `go generate` script
# ollama's build script assumes the source is a git repo, but nix removes the git directory
# this also disables necessary patches contained in `ollama/llm/patches/`
# those patches are applied in `postPatch`
./disable-git.patch
];
postPatch = ''
# replace inaccurate version number with actual release version
substituteInPlace version/version.go --replace-fail 0.0.0 '${version}'
# apply ollama's patches to `llama.cpp` submodule
for diff in llm/patches/*; do
patch -p1 -d llm/llama.cpp < $diff
done
'';
overrideModAttrs = _: _: {
# don't run llama.cpp build in the module fetch phase
preBuild = "";
};
preBuild = ''
# disable uses of `git`, since nix removes the git directory
export OLLAMA_SKIP_PATCHING=true
# build llama.cpp libraries for ollama
go generate ./...
'';
postFixup =
''
# the app doesn't appear functional at the moment, so hide it
mv "$out/bin/app" "$out/bin/.ollama-app"
''
+ lib.optionalString (enableRocm || enableCuda) ''
# expose runtime libraries necessary to use the gpu
wrapProgram "$out/bin/ollama" ${wrapperArgs}
'';
ldflags = [
"-s"
"-w"
"-X=github.com/ollama/ollama/version.Version=${version}"
"-X=github.com/ollama/ollama/server.mode=release"
"-X=github.com/ollama/ollama/gpu.CudaComputeMajorMin=3"
"-X=github.com/ollama/ollama/gpu.CudaComputeMinorMin=5"
];
passthru = {
tests =
{
inherit ollama;
version = testers.testVersion {
inherit version;
package = ollama;
};
}
// lib.optionalAttrs stdenv.isLinux {
inherit ollama-rocm ollama-cuda;
service = nixosTests.ollama;
service-cuda = nixosTests.ollama-cuda;
service-rocm = nixosTests.ollama-rocm;
};
updateScript = nix-update-script { };
};
meta = {
description =
"Get up and running with large language models locally"
+ lib.optionalString rocmRequested ", using ROCm for AMD GPU acceleration"
+ lib.optionalString cudaRequested ", using CUDA for NVIDIA GPU acceleration";
homepage = "https://github.com/ollama/ollama";
changelog = "https://github.com/ollama/ollama/releases/tag/v${version}";
license = licenses.mit;
platforms = if (rocmRequested || cudaRequested) then platforms.linux else platforms.unix;
mainProgram = "ollama";
maintainers = with maintainers; [
abysssol
dit7ya
elohmeier
roydubnium
];
};
}

View file

@ -0,0 +1,14 @@
{ sources, lib, ... }:
let
proxmox-nixos = import sources.proxmox-nixos;
in
{
imports = [ proxmox-nixos.nixosModules.proxmox-ve ];
services.proxmox-ve.enable = true;
nixpkgs.overlays = [ proxmox-nixos.overlays.x86_64-linux ];
networking.firewall = {
trustedInterfaces = [ "wt0" ];
allowedTCPPorts = lib.mkForce [ 22 ];
};
}

View file

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

View file

@ -3,7 +3,6 @@
lib.extra.mkConfig { lib.extra.mkConfig {
enabledModules = [ enabledModules = [
# List of modules to enable # List of modules to enable
"dgn-web"
]; ];
enabledServices = [ enabledServices = [

View file

@ -46,16 +46,6 @@ let
accepted_statuscodes = [ "401" ]; accepted_statuscodes = [ "401" ];
}; };
"ollama01.beta.dgnum.eu" = {
type = mkForce "http";
accepted_statuscodes = [ "401" ];
};
"s3-admin.dgnum.eu" = {
type = mkForce "http";
accepted_statuscodes = [ "400" ];
};
"api.meet.dgnum.eu" = { "api.meet.dgnum.eu" = {
keyword = "Crab Fit API"; keyword = "Crab Fit API";
}; };
@ -132,10 +122,23 @@ in
services.uptime-kuma.enable = true; services.uptime-kuma.enable = true;
dgn-web.simpleProxies.uptime-kuma = { services.nginx = {
inherit host port; enable = true;
virtualHosts.${host} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${builtins.toString port}";
proxyWebsockets = true; proxyWebsockets = true;
}; };
};
};
networking.firewall.allowedTCPPorts = [
80
443
];
statelessUptimeKuma = { statelessUptimeKuma = {
probesConfig = mkMerge [ probesConfig = mkMerge [

View file

@ -18,7 +18,6 @@ lib.extra.mkConfig {
"peertube" "peertube"
"prometheus" "prometheus"
"redirections" "redirections"
"victoria-metrics"
]; ];
extraConfig = { extraConfig = {

View file

@ -1,4 +1,10 @@
{ config, pkgs, ... }: {
config,
pkgs,
nixpkgs,
sources,
...
}:
let let
url = "https://git.dgnum.eu"; url = "https://git.dgnum.eu";
@ -24,6 +30,8 @@ let
options = "--cpus=4"; options = "--cpus=4";
}; };
}; };
nix-pkgs = import sources.nix-pkgs { inherit pkgs; };
in in
{ {
services.forgejo-nix-runners = { services.forgejo-nix-runners = {
@ -31,12 +39,14 @@ in
inherit url; inherit url;
storePath = "/data/slow"; storePath = "/data/slow/nix";
tokenFile = config.age.secrets."forgejo_runners-token_file".path; tokenFile = config.age.secrets."forgejo_runners-token_file".path;
dependencies = [ dependencies = [
nix-pkgs.colmena
pkgs.npins pkgs.npins
pkgs.tea pkgs.tea
nixpkgs.unstable.nixfmt-rfc-style
]; ];
containerOptions = [ "--cpus=4" ]; containerOptions = [ "--cpus=4" ];

View file

@ -31,7 +31,6 @@ in
admin = { admin = {
DEFAULT_EMAIL_NOTIFICATIONS = "enabled"; DEFAULT_EMAIL_NOTIFICATIONS = "enabled";
SEND_NOTIFICATION_EMAIL_ON_NEW_USER = true;
}; };
log.LEVEL = "Warn"; log.LEVEL = "Warn";
@ -45,11 +44,6 @@ in
USER = "web-services@infra.dgnum.eu"; USER = "web-services@infra.dgnum.eu";
}; };
session = {
SESSION_LIFE_TIME = 24 * 3600 * 7;
GC_INTERVAL_TIME = 24 * 3600 * 7;
};
server = { server = {
ROOT_URL = "https://${host}/"; ROOT_URL = "https://${host}/";
DOMAIN = host; DOMAIN = host;
@ -61,7 +55,6 @@ in
service = { service = {
EMAIL_DOMAIN_ALLOWLIST = "dgnum.eu,*"; EMAIL_DOMAIN_ALLOWLIST = "dgnum.eu,*";
EMAIL_DOMAIN_BLOCKLIST = "*.shop,*.online,*.store";
ENABLE_NOTIFY_MAIL = true; ENABLE_NOTIFY_MAIL = true;
DISABLE_REGISTRATION = false; DISABLE_REGISTRATION = false;
@ -78,10 +71,18 @@ in
mailerPasswordFile = config.age.secrets."forgejo-mailer_password_file".path; mailerPasswordFile = config.age.secrets."forgejo-mailer_password_file".path;
}; };
};
dgn-web.simpleProxies.forgejo = { nginx = {
inherit host port; enable = true;
virtualHosts.${host} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString port}";
};
};
};
}; };
users.users.git = { users.users.git = {

View file

@ -1,13 +1,6 @@
{ { config, pkgs, ... }:
config,
lib,
pkgs,
...
}:
let let
inherit (lib) mapAttrs' nameValuePair;
host = "s3.dgnum.eu"; host = "s3.dgnum.eu";
webHost = "cdn.dgnum.eu"; webHost = "cdn.dgnum.eu";
@ -32,18 +25,8 @@ let
] ++ domains; ] ++ domains;
mkHosted = host: builtins.map (b: "${b}.${host}"); mkHosted = host: builtins.map (b: "${b}.${host}");
ports = {
admin_api = 3903;
k2v_api = 3904;
rpc = 3901;
s3_api = 3900;
s3_web = 3902;
};
in in
{ {
dgn-web.internalPorts = mapAttrs' (name: nameValuePair "garage-${name}") ports;
services.garage = { services.garage = {
enable = true; enable = true;
@ -57,24 +40,24 @@ in
replication_mode = "none"; # TODO: deprecated replication_mode = "none"; # TODO: deprecated
compression_level = 7; compression_level = 7;
rpc_bind_addr = "[::]:${toString ports.rpc}"; rpc_bind_addr = "[::]:3901";
rpc_public_addr = "127.0.0.1:${toString ports.rpc}"; rpc_public_addr = "127.0.0.1:3901";
s3_api = { s3_api = {
s3_region = "garage"; s3_region = "garage";
api_bind_addr = "127.0.0.1:${toString ports.s3_api}"; api_bind_addr = "127.0.0.1:3900";
root_domain = ".${host}"; root_domain = ".${host}";
}; };
s3_web = { s3_web = {
bind_addr = "127.0.0.1:${toString ports.s3_web}"; bind_addr = "127.0.0.1:3902";
root_domain = ".${webHost}"; root_domain = ".${webHost}";
index = "index.html"; index = "index.html";
}; };
k2v_api.api_bind_addr = "[::]:${toString ports.k2v_api}"; k2v_api.api_bind_addr = "[::]:3904";
admin.api_bind_addr = "127.0.0.1:${toString ports.admin_api}"; admin.api_bind_addr = "127.0.0.1:3903";
}; };
environmentFile = config.age.secrets."garage-environment_file".path; environmentFile = config.age.secrets."garage-environment_file".path;
@ -101,7 +84,7 @@ in
forceSSL = true; forceSSL = true;
locations."/".extraConfig = '' locations."/".extraConfig = ''
proxy_pass http://127.0.0.1:${toString ports.admin_api}; proxy_pass http://127.0.0.1:3903;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host; proxy_set_header Host $host;
''; '';
@ -114,7 +97,7 @@ in
serverAliases = mkHosted host buckets; serverAliases = mkHosted host buckets;
locations."/".extraConfig = '' locations."/".extraConfig = ''
proxy_pass http://127.0.0.1:${toString ports.s3_api}; proxy_pass http://127.0.0.1:3900;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host; proxy_set_header Host $host;
# Disable buffering to a temporary file. # Disable buffering to a temporary file.
@ -130,7 +113,7 @@ in
serverAliases = domains ++ (mkHosted webHost buckets); serverAliases = domains ++ (mkHosted webHost buckets);
locations."/".extraConfig = '' locations."/".extraConfig = ''
proxy_pass http://127.0.0.1:${toString ports.s3_web}; proxy_pass http://127.0.0.1:3902;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host; proxy_set_header Host $host;
''; '';

View file

@ -5,7 +5,6 @@ let
token = user: secret "${user}_token_file"; token = user: secret "${user}_token_file";
host = "influx.dgnum.eu"; host = "influx.dgnum.eu";
port = 8086;
in in
{ {
@ -42,8 +41,13 @@ in
}; };
}; };
dgn-web.simpleProxies.influxdb = { services.nginx.virtualHosts.${host} = {
inherit host port; enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:8086";
};
}; };
age-secrets.autoMatch = [ "influxdb2" ]; age-secrets.autoMatch = [ "influxdb2" ];

View file

@ -1,82 +0,0 @@
{
config,
lib,
nixpkgs,
...
}:
let
domain = "netbird.dgnum.eu";
s = name: config.age.secrets.${name}.path;
in
{
services = {
netbird.server = {
enable = true;
package = nixpkgs.unstable.netbird;
inherit domain;
enableNginx = true;
coturn.enable = lib.mkForce false;
relay = {
environmentFile = s "netbird-relay_environment_file";
metricsPort = 9094;
};
dashboard = {
settings = {
AUTH_AUTHORITY = "https://sso.dgnum.eu/oauth2/openid/dgn_netbird";
AUTH_AUDIENCE = "dgn_netbird";
AUTH_CLIENT_ID = "dgn_netbird";
};
};
management = {
oidcConfigEndpoint = "https://sso.dgnum.eu/oauth2/openid/dgn_netbird/.well-known/openid-configuration";
dnsDomain = "dgnum";
metricsPort = 9092;
settings = {
DataStoreEncryptionKey._secret = s "netbird-data_store_encryption_key_file";
PKCEAuthorizationFlow.ProviderConfig = {
Audience = "dgn_netbird";
ClientID = "dgn_netbird";
AuthorizationEndpoint = "https://sso.dgnum.eu/ui/oauth2";
TokenEndpoint = "https://sso.dgnum.eu/oauth2/token";
};
IdpManagerConfig.ClientConfig.ClientID = "dgn_netbird";
DeviceAuthorizationFlow = {
Provider = "none";
ProviderConfig = {
Audience = "dgn_netbird";
ClientID = "dgn_netbird";
};
};
Relay = {
Addresses = [ "rels://${domain}:443" ];
CredentialsTTL = "24h";
Secret._secret = s "netbird-relay_secret_file";
};
};
};
};
nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
};
};
dgn-backups.jobs.netbird.settings.paths = [ "/var/lib/netbird-mgmt" ];
}

View file

@ -0,0 +1,47 @@
{ config, ... }:
let
domain = "netbird.dgnum.eu";
in
{
imports = [ ./module.nix ];
services.netbird-server = {
enable = true;
logLevel = "DEBUG";
enableDeviceAuthorizationFlow = false;
enableNginx = true;
enableCoturn = true;
setupAutoOidc = true;
management.dnsDomain = "dgnum";
secretFiles.AUTH_CLIENT_SECRET = config.age.secrets."netbird-auth_client_secret_file".path;
settings = {
NETBIRD_DOMAIN = domain;
TURN_PASSWORD = "tototest1234";
NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT = "https://sso.dgnum.eu/oauth2/openid/netbird_dgn/.well-known/openid-configuration";
NETBIRD_AUTH_PKCE_USE_ID_TOKEN = true;
NETBIRD_AUTH_AUDIENCE = "netbird_dgn";
NETBIRD_AUTH_CLIENT_ID = "netbird_dgn";
NETBIRD_AUTH_USER_ID_CLAIM = "sub";
# Updates the preference to use id tokens instead of access token on dashboard
# Okta and Gitlab IDPs can benefit from this
NETBIRD_TOKEN_SOURCE = "idToken";
# NETBIRD_AUTH_PKCE_REDIRECT_URLS = builtins.map (p: "http://localhost:${p}") [
# "53000"
# "54000"
# ];
NETBIRD_STORE_CONFIG_ENGINE = "sqlite";
};
};
dgn-backups.jobs.netbird.settings.paths = [ "/var/lib/netbird-mgmt" ];
}

View file

@ -0,0 +1,643 @@
{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
filterAttrs
literalExpression
maintainers
mkDefault
mkEnableOption
mkIf
mkMerge
mkOption
optionalAttrs
optionalString
optionals
types
;
inherit ((import ./package { inherit pkgs; })) dashboard;
cfg = config.services.netbird-server;
stateDir = "/var/lib/netbird-mgmt";
settingsFormat = pkgs.formats.keyValue { };
managementFormat = pkgs.formats.json { };
settingsFile = settingsFormat.generate "setup.env" (
builtins.mapAttrs (
_: val: if builtins.isList val then ''"${builtins.concatStringsSep " " val}"'' else val
) settings
);
managementFile = managementFormat.generate "config.json" cfg.managementConfig;
settings =
rec {
TURN_DOMAIN = cfg.settings.NETBIRD_DOMAIN;
TURN_PORT = 3478;
TURN_USER = "netbird";
TURN_MIN_PORT = 49152;
TURN_MAX_PORT = 65535;
TURN_PASSWORD = if cfg.secretFiles.TURN_PASSWORD != null then "$TURN_PASSWORD" else null;
TURN_SECRET = if cfg.secretFiles.TURN_SECRET != null then "$TURN_SECRET" else "secret";
STUN_USERNAME = "";
STUN_PASSWORD = if cfg.secretFiles.STUN_PASSWORD != null then "$STUN_PASSWORD" else null;
NETBIRD_DASHBOARD_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:443";
NETBIRD_MGMT_API_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:${
builtins.toString cfg.settings.NETBIRD_MGMT_API_PORT or NETBIRD_MGMT_API_PORT
}";
NETBIRD_SIGNAL_ENDPOINT = "https://${cfg.settings.NETBIRD_DOMAIN}:${
builtins.toString cfg.settings.NETBIRD_SIGNAL_PORT or NETBIRD_SIGNAL_PORT
}";
NETBIRD_SIGNAL_PROTOCOL = "https";
NETBIRD_SIGNAL_PORT = 443;
NETBIRD_AUTH_USER_ID_CLAIM = "sub";
NETBIRD_AUTH_CLIENT_SECRET =
if cfg.secretFiles.AUTH_CLIENT_SECRET != null then "$AUTH_CLIENT_SECRET" else "";
NETBIRD_AUTH_SUPPORTED_SCOPES = [
"openid"
"profile"
"email"
"offline_access"
"api"
];
NETBIRD_AUTH_REDIRECT_URI = "";
NETBIRD_AUTH_SILENT_REDIRECT_URI = "";
NETBIRD_AUTH_DEVICE_AUTH_PROVIDER = "none";
NETBIRD_AUTH_DEVICE_AUTH_CLIENT_ID = cfg.settings.NETBIRD_AUTH_CLIENT_ID;
NETBIRD_AUTH_DEVICE_AUTH_AUDIENCE = cfg.settings.NETBIRD_AUTH_AUDIENCE;
NETBIRD_AUTH_DEVICE_AUTH_SCOPE = [
"openid"
"profile"
"email"
"offline_access"
"api"
];
NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN = false;
NETBIRD_MGMT_API_PORT = 443;
NETBIRD_MGMT_IDP = "none";
NETBIRD_IDP_MGMT_CLIENT_ID = cfg.settings.NETBIRD_AUTH_CLIENT_ID;
NETBIRD_IDP_MGMT_CLIENT_SECRET =
if cfg.secretFiles.IDP_MGMT_CLIENT_SECRET != null then
"$IDP_MGMT_CLIENT_SECRET"
else
cfg.settings.NETBIRD_AUTH_CLIENT_SECRET;
NETBIRD_IDP_MGMT_GRANT_TYPE = "client_credentials";
NETBIRD_TOKEN_SOURCE = "accessToken";
NETBIRD_DRAG_QUERY_PARAMS = false;
NETBIRD_USE_AUTH0 = false;
NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT = "";
NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS = [ "53000" ];
NETBIRD_AUTH_PKCE_REDIRECT_URLS = builtins.map (
p: "http://localhost:${p}"
) cfg.settings.NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS or NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS;
}
// (optionalAttrs cfg.setupAutoOidc {
NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT = "$NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT";
NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT = "$NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT";
NETBIRD_AUTH_TOKEN_ENDPOINT = "$NETBIRD_AUTH_TOKEN_ENDPOINT";
NETBIRD_AUTH_JWT_CERTS = "$NETBIRD_AUTH_JWT_CERTS";
NETBIRD_AUTH_AUTHORITY = "$NETBIRD_AUTH_AUTHORITY";
})
// cfg.settings;
in
{
meta = {
maintainers = with maintainers; [ thubrecht ];
};
options.services.netbird-server = {
enable = mkEnableOption (lib.mdDoc "netbird management service.");
package = mkOption {
type = types.package;
default = pkgs.netbird;
defaultText = literalExpression "pkgs.netbird";
description = lib.mdDoc "The package to use for netbird";
};
settings = mkOption {
type =
with types;
attrsOf (
nullOr (oneOf [
(listOf str)
bool
int
float
str
])
);
defaultText = lib.literalExpression ''
{
TURN_DOMAIN = cfg.settings.NETBIRD_DOMAIN;
TURN_PORT = 3478;
TURN_USER = "netbird";
TURN_MIN_PORT = 49152;
TURN_MAX_PORT = 65535;
TURN_PASSWORD = if cfg.secretFiles.TURN_PASSWORD != null then "$TURN_PASSWORD" else null;
TURN_SECRET = if cfg.secretFiles.TURN_SECRET != null then "$TURN_SECRET" else "secret";
STUN_USERNAME = "";
STUN_PASSWORD = if cfg.secretFiles.STUN_PASSWORD != null then "$STUN_PASSWORD" else null;
NETBIRD_DASHBOARD_ENDPOINT = "https://''${cfg.settings.NETBIRD_DOMAIN}:443";
NETBIRD_MGMT_API_ENDPOINT = "https://''${cfg.settings.NETBIRD_DOMAIN}:''${builtins.toString cfg.settings.NETBIRD_MGMT_API_PORT or NETBIRD_MGMT_API_PORT}";
NETBIRD_SIGNAL_ENDPOINT = "https://''${cfg.settings.NETBIRD_DOMAIN}:''${builtins.toString cfg.settings.NETBIRD_SIGNAL_PORT or NETBIRD_SIGNAL_PORT}";
NETBIRD_SIGNAL_PROTOCOL = "https";
NETBIRD_SIGNAL_PORT = 443;
NETBIRD_AUTH_USER_ID_CLAIM = "sub";
NETBIRD_AUTH_CLIENT_SECRET = if cfg.secretFiles.AUTH_CLIENT_SECRET != null then "$AUTH_CLIENT_SECRET" else "";
NETBIRD_AUTH_SUPPORTED_SCOPES = [ "openid" "profile" "email" "offline_access" "api" ];
NETBIRD_AUTH_REDIRECT_URI = "";
NETBIRD_AUTH_SILENT_REDIRECT_URI = "";
NETBIRD_AUTH_DEVICE_AUTH_PROVIDER = "none";
NETBIRD_AUTH_DEVICE_AUTH_CLIENT_ID = cfg.settings.NETBIRD_AUTH_CLIENT_ID;
NETBIRD_AUTH_DEVICE_AUTH_AUDIENCE = cfg.settings.NETBIRD_AUTH_AUDIENCE;
NETBIRD_AUTH_DEVICE_AUTH_SCOPE = [ "openid" "profile" "email" "offline_access" "api" ];
NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN = false;
NETBIRD_MGMT_API_PORT = 443;
NETBIRD_MGMT_IDP = "none";
NETBIRD_IDP_MGMT_CLIENT_ID = cfg.settings.NETBIRD_AUTH_CLIENT_ID;
NETBIRD_IDP_MGMT_CLIENT_SECRET = if cfg.secretFiles.IDP_MGMT_CLIENT_SECRET != null then "$IDP_MGMT_CLIENT_SECRET" else cfg.settings.NETBIRD_AUTH_CLIENT_SECRET;
NETBIRD_IDP_MGMT_GRANT_TYPE = "client_credentials";
NETBIRD_TOKEN_SOURCE = "accessToken";
NETBIRD_DRAG_QUERY_PARAMS = false;
NETBIRD_USE_AUTH0 = false;
NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT = "";
NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS = [ "53000" ];
NETBIRD_AUTH_PKCE_REDIRECT_URLS = builtins.map (p: "http://localhost:''${p}") cfg.settings.NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS or NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS;
}
'';
description = lib.mdDoc ''
Configuration settings for netbird.
Example config values can be found in [setup.env.example](https://github.com/netbirdio/netbird/blob/main/infrastructure_files/setup.env.example)
List of strings [ a b ] will be concatenated as "a b", useful for setting the supported scopes.
'';
};
managementConfig = mkOption {
inherit (managementFormat) type;
description = lib.mdDoc "Configuration of the netbird management server.";
};
idpManagerExtraConfig = mkOption {
type = types.attrsOf types.str;
default = { };
description = lib.mdDoc "Extra options passed to the IdpManagerConfig.";
};
ports.management = mkOption {
type = types.port;
default = 8011;
description = lib.mdDoc "Internal port of the management server.";
};
ports.signal = mkOption {
type = types.port;
default = 8012;
description = lib.mdDoc "Internal port of the signal server.";
};
logLevel = mkOption {
type = types.enum [
"ERROR"
"WARN"
"INFO"
"DEBUG"
];
default = "INFO";
description = lib.mdDoc "Log level of the netbird services.";
};
enableDeviceAuthorizationFlow = mkEnableOption "device authorization flow for netbird." // {
default = true;
};
enableNginx = mkEnableOption "NGINX reverse-proxy for the netbird server.";
enableCoturn = mkEnableOption "a Coturn server used for Netbird.";
setupAutoOidc = mkEnableOption "the automatic setup of the OIDC.";
management = {
dnsDomain = mkOption {
type = types.str;
default = "netbird.selfhosted";
description = lib.mdDoc "Domain used for peer resolution.";
};
singleAccountModeDomain = mkOption {
type = types.str;
default = "netbird.selfhosted";
description = lib.mdDoc ''
Enables single account mode.
This means that all the users will be under the same account grouped by the specified domain.
If the installation has more than one account, the property is ineffective.
'';
};
disableAnonymousMetrics = mkOption {
type = types.bool;
default = true;
description = lib.mdDoc "Disables push of anonymous usage metrics to NetBird.";
};
disableSingleAccountMode = mkOption {
type = types.bool;
default = false;
description = lib.mdDoc ''
If set to true, disables single account mode.
The `singleAccountModeDomain` property will be ignored and every new user will have a separate NetBird account.
'';
};
};
secretFiles = {
TURN_PASSWORD = mkOption {
type = with types; nullOr path;
default = null;
description = lib.mdDoc "Path to a file containing the secret TURN_PASSWORD.";
};
TURN_SECRET = mkOption {
type = with types; nullOr path;
default = null;
description = lib.mdDoc "Path to a file containing the secret TURN_SECRET.";
};
STUN_PASSWORD = mkOption {
type = with types; nullOr path;
default = null;
description = lib.mdDoc "Path to a file containing the secret STUN_PASSWORD.";
};
AUTH_CLIENT_SECRET = mkOption {
type = with types; nullOr path;
default = null;
description = lib.mdDoc "Path to a file containing the secret NETBIRD_AUTH_CLIENT_SECRET.";
};
IDP_MGMT_CLIENT_SECRET = mkOption {
type = with types; nullOr path;
default = cfg.secretFiles.AUTH_CLIENT_SECRET;
defaultText = lib.literalExpression "cfg.secretFiles.AUTH_CLIENT_SECRET;";
description = lib.mdDoc "Path to a file containing the secret NETBIRD_IDP_MGMT_CLIENT_SECRET.";
};
};
};
config = mkMerge [
(mkIf cfg.enable {
services.netbird-server.managementConfig = with settings; {
Stuns = mkDefault [
{
Proto = "udp";
URI = "stun:${TURN_DOMAIN}:${builtins.toString TURN_PORT}";
Username = STUN_USERNAME;
Password = STUN_PASSWORD;
}
];
TURNConfig = {
Turns = [
{
Proto = "udp";
URI = "turn:${TURN_DOMAIN}:${builtins.toString TURN_PORT}";
Username = TURN_USER;
Password = TURN_PASSWORD;
}
];
CredentialsTTL = "12h";
Secret = TURN_SECRET;
TimeBasedCredentials = false;
};
Signal = {
Proto = NETBIRD_SIGNAL_PROTOCOL;
URI = "${NETBIRD_DOMAIN}:${builtins.toString NETBIRD_SIGNAL_PORT}";
Username = "";
Password = null;
};
Datadir = "${stateDir}/data";
HttpConfig = {
Address = "127.0.0.1:${builtins.toString cfg.ports.management}";
AuthIssuer = NETBIRD_AUTH_AUTHORITY;
AuthAudience = NETBIRD_AUTH_AUDIENCE;
AuthKeysLocation = NETBIRD_AUTH_JWT_CERTS;
AuthUserIDClaim = NETBIRD_AUTH_USER_ID_CLAIM;
OIDCConfigEndpoint = NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT;
};
IdpManagerConfig = {
ManagerType = NETBIRD_MGMT_IDP;
ClientConfig = {
Issuer = NETBIRD_AUTH_AUTHORITY;
TokenEndpoint = NETBIRD_AUTH_TOKEN_ENDPOINT;
ClientID = NETBIRD_IDP_MGMT_CLIENT_ID;
ClientSecret = NETBIRD_IDP_MGMT_CLIENT_SECRET;
GrantType = NETBIRD_IDP_MGMT_GRANT_TYPE;
};
ExtraConfig = cfg.idpManagerExtraConfig;
};
DeviceAuthorizationFlow = mkIf cfg.enableDeviceAuthorizationFlow {
Provider = NETBIRD_AUTH_DEVICE_AUTH_PROVIDER;
ProviderConfig = {
Audience = NETBIRD_AUTH_DEVICE_AUTH_AUDIENCE;
Domain = NETBIRD_AUTH_AUTHORITY;
ClientID = NETBIRD_AUTH_DEVICE_AUTH_CLIENT_ID;
TokenEndpoint = NETBIRD_AUTH_TOKEN_ENDPOINT;
DeviceAuthEndpoint = NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT;
Scope = builtins.concatStringsSep " " NETBIRD_AUTH_DEVICE_AUTH_SCOPE;
UseIDToken = NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN;
};
};
PKCEAuthorizationFlow = {
ProviderConfig = {
Audience = NETBIRD_AUTH_AUDIENCE;
ClientID = NETBIRD_AUTH_CLIENT_ID;
ClientSecret = NETBIRD_AUTH_CLIENT_SECRET;
AuthorizationEndpoint = NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT;
TokenEndpoint = NETBIRD_AUTH_TOKEN_ENDPOINT;
Scope = builtins.concatStringsSep " " NETBIRD_AUTH_SUPPORTED_SCOPES;
RedirectURLs = NETBIRD_AUTH_PKCE_REDIRECT_URLS;
UseIDToken = NETBIRD_AUTH_PKCE_USE_ID_TOKEN;
};
};
};
services.nginx.virtualHosts = mkIf cfg.enableNginx {
${cfg.settings.NETBIRD_DOMAIN} = {
forceSSL = true;
enableACME = true;
locations = {
"/" = {
root = "${stateDir}/web-ui/";
tryFiles = "$uri /index.html";
};
"/signalexchange.SignalExchange/".extraConfig = ''
grpc_pass grpc://localhost:${builtins.toString cfg.ports.signal};
grpc_read_timeout 1d;
grpc_send_timeout 1d;
grpc_socket_keepalive on;
'';
"/api".proxyPass = "http://localhost:${builtins.toString cfg.ports.management}";
"/management.ManagementService/".extraConfig = ''
grpc_pass grpc://localhost:${builtins.toString cfg.ports.management};
grpc_read_timeout 1d;
grpc_send_timeout 1d;
grpc_socket_keepalive on;
'';
};
};
};
systemd.services = {
netbird-setup = {
wantedBy = [
"netbird-management.service"
"netbird-signal.service"
"multi-user.target"
];
serviceConfig = {
Type = "oneshot";
RuntimeDirectory = "netbird-mgmt";
StateDirectory = "netbird-mgmt";
WorkingDirectory = stateDir;
EnvironmentFile = [ settingsFile ];
};
unitConfig = {
StartLimitInterval = 5;
StartLimitBurst = 10;
};
path =
(with pkgs; [
coreutils
findutils
gettext
gnused
])
++ (optionals cfg.setupAutoOidc (
with pkgs;
[
curl
jq
]
));
script =
''
cp ${managementFile} ${stateDir}/management.json.copy
''
+ (optionalString cfg.setupAutoOidc ''
mv ${stateDir}/management.json.copy ${stateDir}/management.json
echo "loading OpenID configuration from $NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT to the openid-configuration.json file"
curl "$NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT" -q -o ${stateDir}/openid-configuration.json
export NETBIRD_AUTH_AUTHORITY=$(jq -r '.issuer' ${stateDir}/openid-configuration.json)
export NETBIRD_AUTH_JWT_CERTS=$(jq -r '.jwks_uri' ${stateDir}/openid-configuration.json)
export NETBIRD_AUTH_TOKEN_ENDPOINT=$(jq -r '.token_endpoint' ${stateDir}/openid-configuration.json)
export NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT=$(jq -r '.device_authorization_endpoint' ${stateDir}/openid-configuration.json)
export NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT=$(jq -r '.authorization_endpoint' ${stateDir}/openid-configuration.json)
envsubst '$NETBIRD_AUTH_AUTHORITY $NETBIRD_AUTH_JWT_CERTS $NETBIRD_AUTH_TOKEN_ENDPOINT $NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT $NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT' < ${stateDir}/management.json > ${stateDir}/management.json.copy
'')
+ ''
# Update secrets in management.json
${builtins.concatStringsSep "\n" (
builtins.attrValues (
builtins.mapAttrs (name: path: "export ${name}=$(cat ${path})") (
filterAttrs (_: p: p != null) cfg.secretFiles
)
)
)}
envsubst '$TURN_PASSWORD $TURN_SECRET $STUN_PASSWORD $AUTH_CLIENT_SECRET $IDP_MGMT_CLIENT_SECRET' < ${stateDir}/management.json.copy > ${stateDir}/management.json
rm -rf ${stateDir}/web-ui
mkdir -p ${stateDir}/web-ui
cp -R ${dashboard}/* ${stateDir}/web-ui
export AUTH_AUTHORITY="$NETBIRD_AUTH_AUTHORITY"
export AUTH_CLIENT_ID="$NETBIRD_AUTH_CLIENT_ID"
${optionalString (
cfg.secretFiles.AUTH_CLIENT_SECRET == null
) ''export AUTH_CLIENT_SECRET="$NETBIRD_AUTH_CLIENT_SECRET"''}
export AUTH_AUDIENCE="$NETBIRD_AUTH_AUDIENCE"
export AUTH_REDIRECT_URI="$NETBIRD_AUTH_REDIRECT_URI"
export AUTH_SILENT_REDIRECT_URI="$NETBIRD_AUTH_SILENT_REDIRECT_URI"
export USE_AUTH0="$NETBIRD_USE_AUTH0"
export AUTH_SUPPORTED_SCOPES=$(echo $NETBIRD_AUTH_SUPPORTED_SCOPES | sed -E 's/"//g')
export NETBIRD_MGMT_API_ENDPOINT=$(echo $NETBIRD_MGMT_API_ENDPOINT | sed -E 's/(:80|:443)$//')
MAIN_JS=$(find ${stateDir}/web-ui/static/js/main.*js)
OIDC_TRUSTED_DOMAINS=${stateDir}/web-ui/OidcTrustedDomains.js
mv "$MAIN_JS" "$MAIN_JS".copy
envsubst '$USE_AUTH0 $AUTH_AUTHORITY $AUTH_CLIENT_ID $AUTH_CLIENT_SECRET $AUTH_SUPPORTED_SCOPES $AUTH_AUDIENCE $NETBIRD_MGMT_API_ENDPOINT $NETBIRD_MGMT_GRPC_API_ENDPOINT $NETBIRD_HOTJAR_TRACK_ID $AUTH_REDIRECT_URI $AUTH_SILENT_REDIRECT_URI $NETBIRD_TOKEN_SOURCE $NETBIRD_DRAG_QUERY_PARAMS' < "$MAIN_JS".copy > "$MAIN_JS"
envsubst '$NETBIRD_MGMT_API_ENDPOINT' < "$OIDC_TRUSTED_DOMAINS".tmpl > "$OIDC_TRUSTED_DOMAINS"
'';
};
netbird-signal = {
after = [ "network.target" ];
wantedBy = [ "netbird-management.service" ];
restartTriggers = [
settingsFile
managementFile
];
serviceConfig = {
ExecStart = ''
${cfg.package}/bin/netbird-signal run \
--port ${builtins.toString cfg.ports.signal} \
--log-file console \
--log-level ${cfg.logLevel}
'';
Restart = "always";
RuntimeDirectory = "netbird-mgmt";
StateDirectory = "netbird-mgmt";
WorkingDirectory = stateDir;
};
unitConfig = {
StartLimitInterval = 5;
StartLimitBurst = 10;
};
stopIfChanged = false;
};
netbird-management = {
description = "The management server for Netbird, a wireguard VPN";
documentation = [ "https://netbird.io/docs/" ];
after = [
"network.target"
"netbird-setup.service"
];
wantedBy = [ "multi-user.target" ];
wants = [
"netbird-signal.service"
"netbird-setup.service"
];
restartTriggers = [
settingsFile
managementFile
];
serviceConfig = {
ExecStart = ''
${cfg.package}/bin/netbird-mgmt management \
--config ${stateDir}/management.json \
--datadir ${stateDir}/data \
${optionalString cfg.management.disableAnonymousMetrics "--disable-anonymous-metrics"} \
${optionalString cfg.management.disableSingleAccountMode "--disable-single-account-mode"} \
--dns-domain ${cfg.management.dnsDomain} \
--single-account-mode-domain ${cfg.management.singleAccountModeDomain} \
--idp-sign-key-refresh-enabled \
--port ${builtins.toString cfg.ports.management} \
--log-file console \
--log-level ${cfg.logLevel}
'';
Restart = "always";
RuntimeDirectory = "netbird-mgmt";
StateDirectory = [
"netbird-mgmt"
"netbird-mgmt/data"
];
WorkingDirectory = stateDir;
};
unitConfig = {
StartLimitInterval = 5;
StartLimitBurst = 10;
};
stopIfChanged = false;
};
};
})
(mkIf cfg.enableCoturn {
services.coturn = {
enable = true;
realm = settings.NETBIRD_DOMAIN;
lt-cred-mech = true;
no-cli = true;
extraConfig = ''
fingerprint
user=${settings.TURN_USER}:${builtins.toString settings.TURN_PASSWORD}
no-software-attribute
'';
};
networking.firewall = {
allowedUDPPorts = with settings; [
TURN_PORT
(TURN_PORT + 1)
5349
5350
];
allowedTCPPorts = with settings; [
TURN_PORT
(TURN_PORT + 1)
];
allowedUDPPortRanges = [
{
from = settings.TURN_MIN_PORT;
to = settings.TURN_MAX_PORT;
}
];
};
})
(mkIf (cfg.enableNginx && cfg.enableCoturn) {
services.coturn =
let
cert = config.security.acme.certs.${settings.TURN_DOMAIN};
in
{
cert = "${cert.directory}/fullchain.pem";
pkey = "${cert.directory}/key.pem";
};
users.users.nginx.extraGroups = [ "turnserver" ];
# share certs with coturn and restart on renewal
security.acme.certs.${settings.TURN_DOMAIN} = {
group = "turnserver";
postRun = "systemctl reload nginx.service; systemctl restart coturn.service";
};
})
];
}

View file

@ -0,0 +1,31 @@
{
lib,
buildNpmPackage,
fetchFromGitHub,
}:
buildNpmPackage rec {
pname = "netbird-dashboard";
version = "1.17.6";
src = fetchFromGitHub {
owner = "netbirdio";
repo = "dashboard";
rev = "v${version}";
hash = "sha256-MDxN/58dv6OqPYnNgDVZ+YRzfw2dER7x8mEWe14rQ40=";
};
npmDepsHash = "sha256-x7YyzBPAiXyxaIcAvUrXBexYaw0TaYnKgQKT3KadW8w=";
npmFlags = [ "--legacy-peer-deps" ];
installPhase = ''
cp -R build $out
'';
meta = with lib; {
description = "NetBird Management Service Web UI Panel";
homepage = "https://github.com/netbirdio/dashboard";
license = licenses.bsd3;
maintainers = with maintainers; [ thubrecht ];
};
}

View file

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

View file

@ -4,8 +4,6 @@ let
host = "videos.dgnum.eu"; host = "videos.dgnum.eu";
in in
{ {
dgn-web.internalPorts.peertube = config.services.peertube.listenHttp;
services.peertube = { services.peertube = {
enable = true; enable = true;

View file

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

View file

@ -1,30 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 jIXfPA xId0d57S+YmTeZzTTNOs7Pt3RPQ7MLNiKg6Mox2MEFo
hFUYZMNoxZQBEKz4SYDC4nLDDXRftXtUtCLCX2kvwZ8
-> ssh-ed25519 QlRB9Q kmsgaV+FRbqcKkhttlbmY22M6pO6kMCqLUYsq1yGSyA
VmprdWLh380qm6aarum1q17pDrMF0KLyXV/PN1OmEO8
-> ssh-ed25519 r+nK/Q XVeZFVNLv0FlL/lPhXrvVJcHAubE1tTfSxl5iiixtF0
Udm/qZMOzNcg2LMffkns+jUlrtXAC8Mk8ofCSD6zf/0
-> ssh-rsa krWCLQ
OJlswMZEz2ONsqvFH8aMo4cRXzNiSkqtOmNQuWbRcAI4sXKCNuNtNcv6WPcpBMPZ
8eTvoIOf8triUwGBWLZ9oRvYOeoucyWCqx0zf11VwOclRBeziRPOQ5Uon+5gpsg2
H1FO7Sk0sVjME/2INUjd1Q4TlPF9tlUOcEDBgyc81cLI0JrR7S2D6Hl/rAN9Gees
D9c+q5PJkvbw7KQPEu7WOxPNCi1gRyHSlKv5ef5gToNOl/c8GAJR5FutO/bTgTTl
P+yLysKXK+r2IwNNMHGFBDVbsp09IjQ+H623Sfr6H0pR7FYShohfzcM6JA3ydztN
Gy5MiJasx3nWCUYJZUL1Fw
-> ssh-ed25519 /vwQcQ OelREEMNnpUXuJ8BA1VPVM8yqEd8PS9m81sw5gaq8U8
wPUQOWxzsj55/hii7Cd4+P1eFWVDQANwIcImOliOqog
-> ssh-ed25519 0R97PA 9NzXGY3sZb8srqaVWWbZhbNJdDfCfeZIhJHPWy9U4FU
+LvE5cI8heO8XhsejCWaJrwaRGYGCziymPZLrYTOXtg
-> ssh-ed25519 JGx7Ng 1jWoS1sqmY9MxZT7fAMsg5QbokAMNlTg9jmpxzr1ekQ
7MndRQ0ruZP2/cOKaid60rQg8Q3ljy2oknf0czOLGSo
-> ssh-ed25519 5SY7Kg Bm19KVQA8DkrDxiYsVRdKVubML7J9L/apLoUs+otehk
kQMv/7uijZlyGDbDt2aNF85vp4nYM9o3fIetvnykX6I
-> ssh-ed25519 p/Mg4Q /vhTds9k+5uwSDjLyKp18ge+bu/Aeg72nHx2joWUTw0
zeim4NPL7floIvZ296vYuyk5XAVFCCaWRc0iRQQxbyg
-> ssh-ed25519 rHotTw YbKb6NyxsknA125fdWj5/RJjmaY22yDwNx+bLKV6ZW4
jJw+YJqQC/B+UMLYAtTAIZuON2hiZAY171ovJ0ceKjg
-> @K'k$-grease x>ie }CH4sS h|s
bVzOpc2vPj8ldZskVlQSmOE7wHR2q/dXcdC6vrPXSvYWCKK8Rg
--- uDaSBMjg5lvDnZyTKHqveb5B+y71HjrDzOqtsJycuBs
1Ò¨Rq¢<>nýµ{”ý5?HXH1¢ Ê%)Í01RGr׿fÖNT4å2B(í);ìíÿ‰íÁœ

View file

@ -1,31 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 jIXfPA lI9DxAFp/gbF+77Sofv9KIrs3kMTYTLEm8C6AsZBPyI
8RFGt1aJnZbd7Lpr4iy1VlMr3yzpPf6sI79cik5X77c
-> ssh-ed25519 QlRB9Q eMENLAMY+eNXJhduTnJoyPimbThM7VA+4m6BrnZa8RE
NpwcJhh0U8pMU1hnXFz2bfwSmCQra1CI5Tr2cbXGMT0
-> ssh-ed25519 r+nK/Q eyuD/hYyYmG96AcPEZVNsohXgK9WD+g+ZyMpIyaiYjY
Ef+R/eXkqvOmYJvjz4muTjGamkXzgHzD31vXDXsgo3M
-> ssh-rsa krWCLQ
BuBMUp5uijNV71OYvMGS9NhBBplfFugJy14EOHclJ2TKjQ19RVKHPj0wX0AxuPCT
iV6j6Po/oKSsGuoKy6JMTLKjYtROPF70Ld8PlC4tFI5i0xQagEFhKONfk1Rd/mF0
2qGriQhSUMvkMirbkhE3CxrAzSqcjuoGji+ZWwpz2LYUVsF89nnoLsTRri+Sg5ZW
4qhoo23UTU+IlrVtqjB7W1rNAwHKhWPZnjc08x1x/qnLATemmDMsFmTEGljJNGMR
kEg+oUdwdvLjDsnGBWkE+Ck/mrEGwjcsDTmZmCYcH/Q11EMdj5hnCfG68PRhLF9K
b28fHveM3i5/jHrrTxWbrA
-> ssh-ed25519 /vwQcQ 1xQWlLW6xCrheirHSKcGEu+KM644y8NP1KYvwOganQc
IFVYj83X1uLvgIRlnDvnLiaoZNM9viLT7X11vIHdLxY
-> ssh-ed25519 0R97PA I8K03IKgC59zmHqVr8h8TaxuuTSbmYsyap830JyhIhw
AGxW9sq7PQNgs9WFcbINI2CnE3lJJ0rDmseN83YSeT0
-> ssh-ed25519 JGx7Ng syz/pzdj3Lg1VwulZhT8UQncgXjOH1nlbtqHgASLAws
IKaU32zbjFc319PctmGPtHt4RXjgzun0K+9HeuGS3FU
-> ssh-ed25519 5SY7Kg 06EjOyKw1zIWcdZGC7EfNt9mFix+fVcy1iS+SBhPgCQ
ZxcNbC1QmTPJkWlwBnD9YjuzekGZtSDeI7RYxq0uwgw
-> ssh-ed25519 p/Mg4Q uCbjjN5S0ZoZtsj5jva9mTrlZ2UE02A3DysxV1PZ/lM
7jWWiWp4ei5VjftKZz29osbaFxfpId+X3GLzgWZ9Wgo
-> ssh-ed25519 rHotTw Q1/zZpGbUCbXiEELad5710uNkllrFuQlhonSLfIoQVo
h6iW26rADPn1MRqNoD33ZVVDRDr2DBoNK+BjrDxwZik
-> ss-grease
A3WDPMHgipAaXF0MStKGx8CAbFTqks74CRTKButwwJYvgnMFp2Yglx3D2NOWTdJm
yde7gp5XInweYf2TjvQK88l0MD0VYlG9Lu7+wbWGFElCpQ
--- 0d/8UVX6ubUZpKG3LzJsFKbsZNRKUwQq7LuWMiyezKo
P?j@¦Hˆ´ßš¥¼ówgêìÚ©L¥_ã+ì|ζãÙ¦Ö#“fu#c涯„IæS†|¨À²å 

View file

@ -8,9 +8,7 @@
"influxdb2-initial_password_file" "influxdb2-initial_password_file"
"influxdb2-initial_token_file" "influxdb2-initial_token_file"
"influxdb2-telegraf_token_file" "influxdb2-telegraf_token_file"
"netbird-data_store_encryption_key_file" "netbird-auth_client_secret_file"
"netbird-relay_environment_file"
"netbird-relay_secret_file"
"nginx-tvix-store-password" "nginx-tvix-store-password"
"nginx-tvix-store-password-ci" "nginx-tvix-store-password-ci"
"peertube-secrets_file" "peertube-secrets_file"

View file

@ -135,11 +135,10 @@ in
systemd.services."tvix-store" = { systemd.services."tvix-store" = {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
environment = { environment = {
RUST_LOG = "info"; RUST_LOG = "debug";
}; };
serviceConfig = { serviceConfig = {
UMask = "007"; UMask = "007";
LimitNOFILE = 1048576;
ExecStart = "${package}/bin/multitier-tvix-cache --endpoints-config ${toml.endpoints} --store-composition ${toml.composition}"; ExecStart = "${package}/bin/multitier-tvix-cache --endpoints-config ${toml.endpoints} --store-composition ${toml.composition}";
StateDirectory = "tvix-store"; StateDirectory = "tvix-store";
RuntimeDirectory = "tvix-store"; RuntimeDirectory = "tvix-store";

View file

@ -1,16 +0,0 @@
let
host = "victoria-metrics.dgnum.eu";
port = 9099;
in
{
services.victoriametrics = {
enable = true;
listenAddress = "127.0.0.1:${builtins.toString port}";
};
dgn-web.simpleProxies.victoria-metrics = {
inherit host port;
};
}

View file

@ -239,7 +239,7 @@ in
chain postrouting { chain postrouting {
type nat hook postrouting priority 100; type nat hook postrouting priority 100;
ip saddr 10.0.0.0/16 ip saddr != 10.0.255.0/24 snat ip to 129.199.195.130-129.199.195.158 ip saddr 10.0.0.0/16 ip saddr != 10.0.255.0/24 snat ip to 129.199.195.130-129.199.195.158
ether saddr { e0:2e:0b:bd:97:73, e8:d5:2b:0d:fe:4a } snat to 129.199.195.130 comment "Elias" ether saddr e0:2b:e9:b5:b4:cc snat to 129.199.195.130 comment "Elias"
ether saddr { 1c:1b:b5:14:9c:e5, e6:ce:e2:b6:e3:82 } snat to 129.199.195.131 comment "Lubin" ether saddr { 1c:1b:b5:14:9c:e5, e6:ce:e2:b6:e3:82 } snat to 129.199.195.131 comment "Lubin"
ether saddr d0:49:7c:46:f6:39 snat to 129.199.195.132 comment "Jean-Marc" ether saddr d0:49:7c:46:f6:39 snat to 129.199.195.132 comment "Jean-Marc"
ether saddr { 5c:64:8e:f4:09:06 } snat to 129.199.195.158 comment "APs" ether saddr { 5c:64:8e:f4:09:06 } snat to 129.199.195.158 comment "APs"

View file

@ -12,12 +12,25 @@
dgn-backups.postgresDatabases = [ "crabfit" ]; dgn-backups.postgresDatabases = [ "crabfit" ];
dgn-web.simpleProxies = { services.nginx =
crabfit-api = { let
inherit (config.services.crabfit.api) host port; cfg = config.services.crabfit;
in
{
enable = true;
virtualHosts.${cfg.frontend.host} = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://127.0.0.1:${builtins.toString cfg.frontend.port}";
}; };
crabfit-frontend = {
inherit (config.services.crabfit.frontend) host port; virtualHosts.${cfg.api.host} = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://127.0.0.1:${builtins.toString cfg.api.port}";
}; };
}; };
} }

View file

@ -101,13 +101,20 @@ in
# }; # };
# }; # };
dgn-web.simpleProxies = mapAttrs' ( services.nginx = {
enable = true;
virtualHosts = mapAttrs' (
name: name:
{ port, ... }: { port, ... }:
nameValuePair "linkal-${name}" { nameValuePair "${name}.${cfg.domain}" {
inherit port; enableACME = true;
host = "${name}.${cfg.domain}"; # acmeRoot = null; # Use DNS-01 validation
forceSSL = true;
locations."/".proxyPass = "http://127.0.0.1:${builtins.toString port}/";
} }
) cfg.calendarGroups; ) cfg.calendarGroups;
}; };
};
} }

View file

@ -6,35 +6,30 @@
}: }:
let let
inherit (lib) mapAttrsToList match;
metis = import sources.metis { inherit pkgs; }; metis = import sources.metis { inherit pkgs; };
inherit (metis) providers;
in in
{ {
services.nginx.virtualHosts."calendrier.dgnum.eu" = { services.nginx.virtualHosts."calendrier.dgnum.eu" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
root = metis.package; root = metis.production;
locations = lib.mapAttrs' ( locations = lib.mapAttrs' (
name: domain: name: value:
lib.nameValuePair "/cal/${name}/" { lib.nameValuePair "/cal/${name}/" {
extraConfig = '' extraConfig = ''
proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://${domain}/remote.php/dav/public-calendars/; proxy_pass ${value};
''; '';
} }
) metis.providers; ) providers;
extraConfig = '' extraConfig = ''
rewrite ^/calendrier(.*)$ $1 permanent; rewrite ^/calendrier(.*)$ $1 permanent;
''; '';
}; };
assertions = mapAttrsToList (name: domain: {
assertion = (match "[a-z-]+" name == [ ]) && (match "[a-z.-]+" domain == [ ]);
message = "The provider `${name}` associated to the domain `${domain}` seems to have an incorrect definition.";
}) metis.providers;
} }

View file

@ -13,7 +13,7 @@ in
services = { services = {
netbox = { netbox = {
enable = true; enable = true;
package = nixpkgs.unstable.netbox_4_1; package = nixpkgs.unstable.netbox_3_7;
secretKeyFile = "/dev/null"; secretKeyFile = "/dev/null";
listenAddress = "127.0.0.1"; listenAddress = "127.0.0.1";
plugins = p: [ p.netbox-qrcode ]; plugins = p: [ p.netbox-qrcode ];
@ -39,6 +39,17 @@ in
SOCIAL_AUTH_OIDC_SECRET = env["NETBOX_OIDC_SECRET"] SOCIAL_AUTH_OIDC_SECRET = env["NETBOX_OIDC_SECRET"]
''; '';
}; };
nginx = {
enable = true;
virtualHosts."netbox.dgnum.eu" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://${config.services.netbox.listenAddress}:${builtins.toString config.services.netbox.port}";
locations."/static/".alias = "${config.services.netbox.dataDir}/static/";
};
};
}; };
systemd.services = { systemd.services = {
@ -58,12 +69,10 @@ in
}; };
users.users.nginx.extraGroups = [ "netbox" ]; users.users.nginx.extraGroups = [ "netbox" ];
networking.firewall.allowedTCPPorts = [
dgn-web.simpleProxies.netbox = { 443
inherit (config.services.netbox) port; 80
host = "netbox.dgnum.eu"; ];
vhostConfig.locations."/static/".alias = "${config.services.netbox.dataDir}/static/";
};
dgn-backups.jobs.netbox.settings.paths = [ "/var/lib/netbox" ]; dgn-backups.jobs.netbox.settings.paths = [ "/var/lib/netbox" ];
dgn-backups.postgresDatabases = [ "netbox" ]; dgn-backups.postgresDatabases = [ "netbox" ];

View file

@ -2,7 +2,6 @@
let let
host = "push.dgnum.eu"; host = "push.dgnum.eu";
port = 2586;
in in
{ {
services.ntfy-sh = { services.ntfy-sh = {
@ -18,10 +17,15 @@ in
}; };
}; };
dgn-web.simpleProxies.ntfy-sh = { services.nginx.virtualHosts.${host} = {
inherit host port; enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:2586";
proxyWebsockets = true; proxyWebsockets = true;
}; };
};
systemd.services.ntfy-sh.serviceConfig.EnvironmentFile = [ systemd.services.ntfy-sh.serviceConfig.EnvironmentFile = [
config.age.secrets."ntfy_sh-environment_file".path config.age.secrets."ntfy_sh-environment_file".path

View file

@ -29,6 +29,7 @@ in
"bds.wp.dgnum.eu" = "bds.ens.fr"; "bds.wp.dgnum.eu" = "bds.ens.fr";
"www.tuteurs.ens.fr" = "tuteurs.ens.fr"; "www.tuteurs.ens.fr" = "tuteurs.ens.fr";
"www.interq.ens.fr" = "interq.ens.fr"; "www.interq.ens.fr" = "interq.ens.fr";
"www.lanuit.ens.fr" = "lanuit.ens.fr";
}; };
temporary = { temporary = {

View file

@ -9,7 +9,6 @@
let let
inherit (lib) mapAttrsToList; inherit (lib) mapAttrsToList;
host = "cas.eleves.ens.fr";
port = 9889; port = 9889;
python3 = python3 =
@ -129,18 +128,8 @@ in
dgn-redirections.permanent."cas-eleves.dgnum.eu" = "cas.eleves.ens.fr"; dgn-redirections.permanent."cas-eleves.dgnum.eu" = "cas.eleves.ens.fr";
dgn-web.simpleProxies.cas-eleves = { services = {
inherit host port; postgresql = {
vhostConfig = {
serverAliases = [ "cas-eleves.dgnum.eu" ];
locations = {
"/static/".root = staticDrv;
"= /robots.txt".root = "${staticDrv}/static";
};
};
};
services.postgresql = {
ensureDatabases = [ "cas_server" ]; ensureDatabases = [ "cas_server" ];
ensureUsers = [ ensureUsers = [
{ {
@ -149,4 +138,18 @@ in
} }
]; ];
}; };
nginx.virtualHosts."cas.eleves.ens.fr" = {
enableACME = true;
forceSSL = true;
serverAliases = [ "cas-eleves.dgnum.eu" ];
locations = {
"/".proxyPass = "http://127.0.0.1:${builtins.toString port}";
"/static/".root = staticDrv;
"= /robots.txt".root = "${staticDrv}/static";
};
};
};
} }

View file

@ -9,7 +9,6 @@
let let
inherit (lib) mapAttrsToList optionals; inherit (lib) mapAttrsToList optionals;
host = "vote.dgnum.eu";
port = 9888; port = 9888;
python3 = python3 =
@ -169,12 +168,8 @@ in
}; };
}; };
dgn-web.simpleProxies.kadenios = { services = {
inherit host port; postgresql = {
vhostConfig.locations."/static/".root = staticDrv;
};
services.postgresql = {
ensureDatabases = [ "kadenios" ]; ensureDatabases = [ "kadenios" ];
ensureUsers = [ ensureUsers = [
{ {
@ -183,4 +178,15 @@ in
} }
]; ];
}; };
nginx.virtualHosts."vote.dgnum.eu" = {
enableACME = true;
forceSSL = true;
locations = {
"/".proxyPass = "http://127.0.0.1:${builtins.toString port}";
"/static/".root = staticDrv;
};
};
};
} }

View file

@ -1,19 +0,0 @@
{ lib, ... }:
lib.extra.mkConfig {
enabledModules = [
# List of modules to enable
"dgn-web"
];
enabledServices = [
# List of services to enable
"django-apps"
];
extraConfig = {
services.netbird.enable = true;
};
root = ./.;
}

View file

@ -1,45 +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, ... }:
{
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
boot = {
initrd = {
availableKernelModules = [
"ahci"
"xhci_pci"
"virtio_pci"
"sr_mod"
"virtio_blk"
];
kernelModules = [ ];
luks.devices."main" = {
device = "/dev/disk/by-uuid/21a5fa9b-35d2-49c9-80f8-5161c652bdc8";
tryEmptyPassphrase = true;
};
};
kernelModules = [ "kvm-intel" ];
extraModulePackages = [ ];
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/9069a0a6-2f9f-4219-a2c4-248de932da6f";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/9826-E466";
fsType = "vfat";
options = [
"fmask=0022"
"dmask=0022"
];
};
swapDevices = [ { device = "/dev/disk/by-uuid/a91c29b4-9b1b-477e-820f-3cf610158e2a"; } ];
}

View file

@ -1,52 +0,0 @@
{ pkgs, sources, ... }:
let
nix-pkgs = import sources.nix-pkgs { inherit pkgs; };
in
{
services.django-apps.sites.annuaire = {
source = "https://git.dgnum.eu/DGNum/annuaire-eleves";
branch = "main";
domain = "annuaire-ens.webapps.dgnum.eu";
nginx = {
enableACME = true;
forceSSL = true;
};
webHookSecret = builtins.toFile "insecure-secret" "T5hNeDraMivRZLUkrekv&QeM";
python = pkgs.python3.override {
packageOverrides = _: _: { inherit (nix-pkgs) authens loadcredential; };
};
dependencies = ps: [
ps.django
ps.pillow
ps.loadcredential
ps.authens
ps.python-dateutil
];
credentials = {
SECRET_KEY = builtins.toFile "insecure-key" "insecure-key";
};
environment = {
ANNUAIRE_ALLOWED_HOSTS = [ "annuaire-ens.webapps.dgnum.eu" ];
ANNUAIRE_LDAP = {
SPI = {
PROTOCOL = "ldaps";
URL = "ldap.spi.ens.fr";
PORT = 636;
};
CRI = {
PROTOCOL = "ldaps";
URL = "annuaire.ens.fr";
PORT = 636;
};
};
};
};
}

View file

@ -1,44 +0,0 @@
{ pkgs, sources, ... }:
let
nix-pkgs = import sources.nix-pkgs { inherit pkgs; };
in
{
services.django-apps.sites.bocal = {
source = "https://git.dgnum.eu/DGNum/www-bocal";
branch = "main";
domain = "bocal.webapps.dgnum.eu";
nginx = {
enableACME = true;
forceSSL = true;
};
webHookSecret = builtins.toFile "insecure-secret" "T5hNeDraMivRZLUkrekv&QeM";
python = pkgs.python3.override {
packageOverrides = _: _: { inherit (nix-pkgs) django-cas-ng django-solo loadcredential; };
};
dependencies = ps: [
ps.django
ps.django-cas-ng
ps.django-markdownx
ps.django-solo
ps.markdown
ps.pillow
ps.loadcredential
];
credentials = {
SECRET_KEY = builtins.toFile "insecure-key" "insecure-key";
};
environment = {
DJANGO_SETTINGS_MODULE = "app.settings";
BOCAL_ALLOWED_HOSTS = [ "bocal.webapps.dgnum.eu" ];
BOCAL_RHOSTS_PATH = "/var/lib/django-apps/bocal/.rhosts";
};
};
}

View file

@ -1,22 +0,0 @@
{
imports = [
./annuaire.nix
./bocal.nix
./gestiojeux.nix
./interludes.nix
./wikiens.nix
];
services.django-apps = {
enable = true;
webhook = {
domain = "apps-webhook.dgnum.eu";
nginx = {
enableACME = true;
forceSSL = true;
};
};
};
}

View file

@ -1,69 +0,0 @@
{ pkgs, sources, ... }:
let
nix-pkgs = import sources.nix-pkgs { inherit pkgs; };
in
{
services.django-apps.sites.gestiojeux = {
source = "https://git.dgnum.eu/DGNum/gestiojeux";
branch = "production";
domain = "gestiojeux.webapps.dgnum.eu";
nginx = {
enableACME = true;
forceSSL = true;
};
webHookSecret = builtins.toFile "insecure-secret" "T5hNeDraMivRZLUkrekv&QeM";
application = {
type = "wsgi";
module = "gestiojeux";
};
python = pkgs.python3.override {
packageOverrides = _: _: {
inherit (nix-pkgs)
django-autoslug
django-cas-ng
loadcredential
markdown-icons
;
};
};
django = ps: ps.django_4;
dependencies = ps: [
ps.django-autoslug
ps.loadcredential
ps.django-cas-ng
ps.django-cleanup
ps.django-haystack
ps.django-markdownx
ps.django-tables2
ps.pillow
ps.psycopg2
ps.whoosh
# Django haystack is drunk
ps.setuptools
];
staticDirectory = "source/public/static";
mediaDirectory = "source/public/media";
credentials = {
SECRET_KEY = builtins.toFile "insecure-key" "insecure-key";
};
environment = {
GESTIOJEUX_ALLOWED_HOSTS = [ "gestiojeux.webapps.dgnum.eu" ];
GESTIOJEUX_EMAIL_HOST_USER = "web-services@infra.dgnum.eu";
GESTIOJEUX_DEFAULT_FROM_EMAIL = "Kadenios <web-services@infra.dgnum.eu>";
GESTIOJEUX_SERVER_EMAIL = "webapps@infra.dgnum.eu";
GESTIOJEUX_DB_NAME = "dj-gestiojeux";
GESTIOJEUX_DB_USER = "dj-gestiojeux";
};
};
}

View file

@ -1,66 +0,0 @@
{
config,
pkgs,
sources,
...
}:
let
nix-pkgs = import sources.nix-pkgs { inherit pkgs; };
in
{
services.webhook.extraArgs = [ "-debug" ];
services.django-apps.sites.interludes = {
source = "https://git.eleves.ens.fr/dlesbre/site-interludes";
branch = "master";
domain = "interludes.ens.fr";
nginx = {
enableACME = true;
forceSSL = true;
serverAliases = [ "interludes.webapps.dgnum.eu" ];
};
webHookSecret = config.age.secrets."webhook-interludes_token".path;
application = {
type = "wsgi";
module = "interludes";
};
dbType = "sqlite";
python = pkgs.python3.override {
packageOverrides = _: _: { inherit (nix-pkgs) python-cas loadcredential; };
};
django = ps: ps.django_4;
dependencies = ps: [
ps.loadcredential
ps.python-ldap
ps.python-cas
];
credentials = {
SECRET_KEY = config.age.secrets."dj_interludes-secret_key_file".path;
EMAIL_HOST_PASSWORD = config.age.secrets."dj_interludes-email_host_password_file".path;
};
environment = {
INTERLUDES_ALLOWED_HOSTS = [
"interludes.ens.fr"
"interludes.webapps.dgnum.eu"
];
# E-mail configuration
INTERLUDES_SERVER_EMAIL = "noreply-interludes-admin@ens.fr";
INTERLUDES_DEFAULT_FROM_EMAIL = "noreply-interludes@ens.fr";
INTERLUDES_EMAIL_HOST = "clipper.ens.fr";
INTERLUDES_EMAIL_PORT = 465;
INTERLUDES_EMAIL_HOST_USER = "interludes";
INTERLUDES_DEBUG = false;
};
};
}

View file

@ -1,40 +0,0 @@
{ pkgs, sources, ... }:
let
nix-pkgs = import sources.nix-pkgs { inherit pkgs; };
in
{
services.django-apps.sites.wikiens = {
source = "https://git.dgnum.eu/DGNum/wiki-eleves";
branch = "main";
domain = "wiki.webapps.dgnum.eu";
nginx = {
enableACME = true;
forceSSL = true;
};
webHookSecret = builtins.toFile "insecure-secret" "T5hNeDraMivRZLUkrekv&QeM";
python = pkgs.python3.override {
packageOverrides = _: _: { inherit (nix-pkgs) django-allauth-ens django-wiki loadcredential; };
};
dependencies = ps: [
ps.django
ps.django-allauth-ens
ps.django-wiki
ps.loadcredential
ps.tinycss2
];
credentials = {
SECRET_KEY = builtins.toFile "insecure-key" "insecure-key";
};
environment = {
WIKIENS_ALLOWED_HOSTS = [ "wiki.webapps.dgnum.eu" ];
};
};
}

View file

@ -1,29 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 jIXfPA iJSzsbA8RiEhUIyhlKWCASQKoSQstjK4drMYl+PsChw
8THrknrBu0WGFEb4xTZiJxEY26q7sW83rwViDjyTE24
-> ssh-ed25519 QlRB9Q e7PRE212Ggt8nO6Bb+BabO85FOARsJGs9cPJmZNI9kg
ubKIBxI1ZBXttA7TWj401siKNT1HyB+N2MsZ+ldkgb8
-> ssh-ed25519 r+nK/Q EWV24Emm9hENa+yUAuQpkuJ0uJ0zIv+vRIbWpM4Wtg4
J59wnHRytgNqpX4+5HaJ9KZ5GvhckgtRK6TzfX7Ci8Y
-> ssh-rsa krWCLQ
AvmrzShR+XTpUpKaScoqvgFQ40PTSqh8p383p98xjG5LIz5kqJoWBnxJK7JabBpq
JkqVeq5XdH5RX4weobieG4KYUV8EDheLfOMXH5BrPgeJO4yhJ1rzH+oHBw4TwvFM
UvEZEAVgi3G1/suPfJAkO7QRkZjE7fRppEo5RAI0gMlM43YyJavrfqVIqB40Uugk
h0b0ybChUbKpXlZjqhYAAMN45jTAvW1emO0DMeIk6dbmnbZNdibul8f+NNdWKbI1
9NN5iH2IzuqTdc6gkE4912hdDeUJ4NZ6x/Fxp1/u3d1z/Yg7daUQUXUIoDX0Hyvb
+01dH0D/7kzRhEdNLO2NXA
-> ssh-ed25519 /vwQcQ GAsAj2i65KDQeFhe69YR2ycdGskop1wu3Lzrxp59sTg
wCSUqEtWv0i6sNg1RVtHI/jZh3VeNX3qtnbagXoNGT4
-> ssh-ed25519 0R97PA mFZ3q/3jd1guXl8bhRWyYjgsgE4JErJEels6vdmpfCs
7oIAT0MTsaKxbf26PSDBk7KqfyFgcBq09FGJ9v/rXqE
-> ssh-ed25519 JGx7Ng tpslfMWMJMUH46EGycbLiXotVdXlP4xmK0slb7XKYS8
wLLfX4jX4mIxzI8zr2GBlpBcPztTrHqKngi/ON0TExg
-> ssh-ed25519 bUjjig zLoniLfwKGH9Ctu34103WHBvjIyImtPyKx8O+5UMLUU
sYsterVGvCg6JWA0z3AO5sSlj9DBfj8u5o5jH9K2xeA
-> ssh-ed25519 VQSaNw oHzU9Lc/7p+MZAjVylzC63h586vOcffXkkpAi4XB8Q0
7T8CREpaCxM58KMYW28FY2i+ELjrx3eC3K7xaBy7O6A
-> (_o61>U-grease .P>ZRrj~ -=7S;N
6vnQVKKZwp4JowIwVb4klrhaR6NZjwlZYnngVQ0wqVenMZPj9oyhIXthLRqE1Q6/
k+sGxA
--- +yT0o8oZJS+32MeUAl8T9zREh31rq77pSVsSoFjHO5A
è ™ñΗ´ä!î^ûØÖ8ÔzøÑaÒÓ ÐàÔ@Ö¡s\ ˜_ÃÃúoÖö<C396>wõÖ¥Cr)¾€fû¿AÃ'•3D€â

View file

@ -1,29 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 jIXfPA 7v2qJ+2ZSp0tf4m6gcK2ShFF9ulNm/g3aHu3Wqe4Sxo
ZyVqTqBCK51/U5yxtp23nywprQv46yL90zwx6+DqKRg
-> ssh-ed25519 QlRB9Q IePmluoRImtaDplOoVqNiwfTQMKF1CuF4M6AzurXGRY
JjtOeyvARlc9t5Q+LS2+TZwAUgV4Qn2L8SFkw9YLnaU
-> ssh-ed25519 r+nK/Q LGPI7PmVPnZDQe6Su5MZQauxRHZkBKehyNbMq+BKlGQ
3RvcfLAFKaScusYKf47zFNAtnot7wySvytuD81s6TwM
-> ssh-rsa krWCLQ
xGH7rl+r8L5HEp6JUlAm04ktn9rQsWfBBlSRp7UsOi6ojwCfjjIA91yUrYw8TYRs
Ci60uoLS7cuMtSE/jQVU/FuVtR5kwjhOkWmQDHrC7rUWb6CufusxPIVJ0xanp3wo
cc2t+EfSdpVyGIx5N8BEMhQ6sR2EfERHGfUrnKCpcL5hM5L8ZHnVh6CkRBtvZaq0
Zy44Ob4pqH6fDz7EziM1hBkfg9myN+/Iqfvg5OUnfSrqooLZ8l0gDvGafS5fok91
uqb0PGDiv6lwzpaj87jKUCaXAF3ag2KAa6j8sbZ4+fSsQeB/jhH7hTlWcAR/oEFW
fuPQDFKxMucAsPjv1H1iaQ
-> ssh-ed25519 /vwQcQ +5+xDNQyRwBWXT6c593S01OG9IemNul/81G4ie1hTVg
Tzkq0toOCqdHOZNPiy/rUrO2eQXTDHi7g+jKbrWU/hU
-> ssh-ed25519 0R97PA WEMs0phnuvw1kQaqeSkovwFUL6w7J6wh+V7D82NxfDs
V5npmkeTPVcnaNwDtoy7PqBRllPTuQjvF9Qu14V59os
-> ssh-ed25519 JGx7Ng 3bty0WCf+ElvPEFt7fSpgYf5MeFUPaZ4vVGWPUAjn0I
ggl5CgXaUx4T6qbA9EG1oaF9NbfFYye4davm7lKqUvI
-> ssh-ed25519 bUjjig zFlaOVzFEkPG+J3Yz7alPgSiCVbC/7u/hCTVIP8X/Ho
3PBIRu9ZKfb9lkzijw6kKjX0ztXBkiwVaQUx8rxuYJc
-> ssh-ed25519 VQSaNw btusrepFF5Jhl3x2YWs6wVrHwzb6qBXfDXESclQJAXo
HwfOU3tyP9OsNjTkaMMmJnd4b+0ZfxJLkP6xe5jsAZE
-> Tp-grease s03Py `u6"4 E|5 _
3CvcQ6NEZKLY1F6y0cTMQPwV9mJvHB0T7dauvWJAYKkfb95TymqfDYGWwW1veND2
n1XD/arAJHVwva95K7TaQdsNLPGo8/VePQGUnYqi
--- qe75UTWqdDd0gGg0nm054SFZ2AgqVBw/bbycvcZSfQY
ãñêÕ]¹¦zÂg©;Ê¡îñ˜öÓ´0éÅYëÀHãŒ!@ìp­ö¸T«?£iÞ‰áèÚ>I^ül·o5”¯ë:{¬gJk£vø>€W8ði

View file

@ -1,6 +0,0 @@
(import ../../../keys).mkSecrets [ "web03" ] [
# List of secrets for web03
"dj_interludes-email_host_password_file"
"dj_interludes-secret_key_file"
"webhook-interludes_token"
]

View file

@ -1,7 +1,7 @@
{ lib, dns, ... }: { lib, dns, ... }:
let let
inherit (lib) mapAttrs' nameValuePair optional; inherit (lib) mapAttrs' nameValuePair;
inherit (lib.extra) fuseAttrs mapSingleFuse; inherit (lib.extra) fuseAttrs mapSingleFuse;
inherit (dns.lib.combinators) mx spf ttl; inherit (dns.lib.combinators) mx spf ttl;
@ -85,7 +85,6 @@ let
"influx" # InfluxDB "influx" # InfluxDB
"netbird" # Netbird "netbird" # Netbird
"prometheus" # Prometheus "prometheus" # Prometheus
"victoria-metrics" # Victoria Metrics
"videos" # Peertube "videos" # Peertube
# Garage S3 # Garage S3
@ -132,15 +131,8 @@ let
]; ];
web02.dual = [ web02.dual = [
"cas-eleves" # CAS server "cas-eleves"
"chat" # Mattermost "vote"
"vote" # Kadenios
];
web03.dual = [
# Django Apps
"*.webapps"
"apps-webhook"
]; ];
} }
) )
@ -217,19 +209,17 @@ in
subdomains = mapAttrs' ( subdomains = mapAttrs' (
host: host:
{ site, ... }: { site, ... }:
let nameValuePair "${host}.${site}" (
net = meta.network.${host}; with meta.network.${host}.addresses;
inherit (net.addresses) ipv4 ipv6; {
in
nameValuePair "${host}.${site}" {
A = ipv4; A = ipv4;
AAAA = ipv6; AAAA = ipv6;
subdomains = { subdomains = {
v4.A = ipv4; v4.A = ipv4;
v6.AAAA = ipv6; v6.AAAA = ipv6;
private.A = optional (net.netbirdIp != null) net.netbirdIp;
}; };
} }
)
) meta.nodes; ) meta.nodes;
}; };
}; };

View file

@ -29,6 +29,29 @@
netbirdIp = "100.80.75.197"; netbirdIp = "100.80.75.197";
}; };
krz01 = {
interfaces = {
eno1 = {
ipv4 = [
{
address = "129.199.146.21";
prefixLength = 24;
}
{
address = "192.168.1.145";
prefixLength = 24;
}
];
gateways = [ "129.199.146.254" ];
enableDefaultDNS = true;
};
};
hostId = "bd11e8fc";
netbirdIp = "100.80.103.206";
};
geo01 = { geo01 = {
interfaces = { interfaces = {
eno1 = { eno1 = {
@ -155,25 +178,6 @@
netbirdIp = null; # web02 is not to be connected on the VPN netbirdIp = null; # web02 is not to be connected on the VPN
}; };
web03 = {
interfaces = {
enp1s0 = {
ipv4 = [
{
address = "129.199.129.223";
prefixLength = 24;
}
];
gateways = [ "129.199.129.1" ];
enableDefaultDNS = true;
};
};
hostId = "8afc7749";
netbirdIp = "100.80.157.46";
};
rescue01 = { rescue01 = {
interfaces = { interfaces = {
ens18 = { ens18 = {

View file

@ -37,6 +37,19 @@
}; };
}; };
web01 = {
site = "rat01";
deployment.tags = [ "web" ];
hashedPassword = "$y$j9T$9YqXO93VJE/GP3z8Sh4h51$hrBsEPL2O1eP/wBZTrNT8XV906V4JKbQ0g04IWBcyd2";
stateVersion = "23.05";
vm-cluster = "Hyperviseur NPS";
nixpkgs = "24.05";
};
compute01 = { compute01 = {
site = "pav01"; site = "pav01";
@ -67,15 +80,15 @@
nixpkgs = "24.05"; nixpkgs = "24.05";
}; };
rescue01 = { krz01 = {
site = "luj01"; site = "pav01";
deployment.targetHost = "v6.rescue01.luj01.infra.dgnum.eu"; hashedPassword = "$y$j9T$eNZQgDN.J5y7KTG2hXgat1$J1i5tjx5dnSZu.C9B7swXi5zMFIkUnmRrnmyLHFAt8/";
hashedPassword = "$y$j9T$nqoMMu/axrD0m8AlUFdbs.$UFVmIdPAOHBe2jJv5HJJTcDgINC7LTnSGRQNs9zS1mC"; stateVersion = "24.05";
nixpkgs = "unstable";
stateVersion = "23.11"; adminGroups = [ "lab" ];
vm-cluster = "Hyperviseur Luj";
}; };
storage01 = { storage01 = {
@ -86,10 +99,7 @@
stateVersion = "23.11"; stateVersion = "23.11";
nixpkgs = "24.05"; nixpkgs = "24.05";
nix-modules = [ nix-modules = [ "services/forgejo-nix-runners" ];
"services/forgejo-nix-runners"
"services/netbird/server.nix"
];
}; };
vault01 = { vault01 = {
@ -104,19 +114,6 @@
adminGroups = [ "fai" ]; adminGroups = [ "fai" ];
}; };
web01 = {
site = "rat01";
deployment.tags = [ "web" ];
hashedPassword = "$y$j9T$9YqXO93VJE/GP3z8Sh4h51$hrBsEPL2O1eP/wBZTrNT8XV906V4JKbQ0g04IWBcyd2";
stateVersion = "23.05";
vm-cluster = "Hyperviseur NPS";
nixpkgs = "24.05";
};
web02 = { web02 = {
site = "rat01"; site = "rat01";
@ -127,15 +124,14 @@
vm-cluster = "Hyperviseur NPS"; vm-cluster = "Hyperviseur NPS";
}; };
web03 = { rescue01 = {
site = "rat01"; site = "luj01";
hashedPassword = "$y$j9T$Un/tcX5SPKNXG.sy/BcTa.$kyNHELjb1GAOWnauJfcjyVi5tacWcuEBKflZDCUC6x4"; deployment.targetHost = "v6.rescue01.luj01.infra.dgnum.eu";
nix-modules = [ "services/django-apps" ]; hashedPassword = "$y$j9T$nqoMMu/axrD0m8AlUFdbs.$UFVmIdPAOHBe2jJv5HJJTcDgINC7LTnSGRQNs9zS1mC";
stateVersion = "24.05"; stateVersion = "23.11";
nixpkgs = "unstable"; vm-cluster = "Hyperviseur Luj";
vm-cluster = "Hyperviseur NPS";
}; };
} }

View file

@ -41,10 +41,7 @@ in
options = { options = {
organization = { organization = {
members = mkOption { members = mkOption {
type = attrsOf ( type = attrsOf (submodule {
submodule (
{ name, ... }:
{
options = { options = {
name = mkOption { name = mkOption {
type = str; type = str;
@ -59,19 +56,8 @@ in
Main e-mail address of the member. Main e-mail address of the member.
''; '';
}; };
username = mkOption {
type = str;
default = name;
description = ''
The username used for authentication.
WARNING: Must be the same as the ens login!
'';
}; };
}; });
}
)
);
description = '' description = ''
Members of the DGNum organization. Members of the DGNum organization.

View file

@ -5,21 +5,14 @@
{ {
members = { members = {
agroudiev = {
name = "Antoine Groudiev";
email = "antoine.groudiev@dgnum.eu";
};
catvayor = { catvayor = {
name = "Lubin Bailly"; name = "Lubin Bailly";
email = "catvayor@dgnum.eu"; email = "catvayor@dgnum.eu";
username = "lbailly";
}; };
cst1 = { cst1 = {
name = "Constantin Gierczak--Galle"; name = "Constantin Gierczak--Galle";
email = "cst1@dgnum.eu"; email = "cst1@dgnum.eu";
username = "cgierczakgalle";
}; };
ecoppens = { ecoppens = {
@ -30,19 +23,11 @@
jemagius = { jemagius = {
name = "Jean-Marc Gailis"; name = "Jean-Marc Gailis";
email = "jm@dgnum.eu"; email = "jm@dgnum.eu";
username = "jgailis";
}; };
luj = { luj = {
name = "Julien Malka"; name = "Julien Malka";
email = "luj@dgnum.eu"; email = "luj@dgnum.eu";
username = "jmalka";
};
mboyer = {
name = "Matthieu Boyer";
email = "matthieu.boyer@dgnum.eu";
username = "mboyer02";
}; };
mdebray = { mdebray = {
@ -53,7 +38,6 @@
raito = { raito = {
name = "Ryan Lahfa"; name = "Ryan Lahfa";
email = "ryan@dgnum.eu"; email = "ryan@dgnum.eu";
username = "rlahfa";
}; };
thubrecht = { thubrecht = {
@ -68,6 +52,7 @@
"thubrecht" "thubrecht"
"raito" "raito"
"mdebray" "mdebray"
"luj"
]; ];
# members of this group are root on the fai infrastructure # members of this group are root on the fai infrastructure

View file

@ -0,0 +1,35 @@
diff --git a/netbox_agent/network.py b/netbox_agent/network.py
index 673dfc1..8ef60aa 100644
--- a/netbox_agent/network.py
+++ b/netbox_agent/network.py
@@ -1,7 +1,7 @@
import logging
import os
import re
-from itertools import chain
+from itertools import chain, islice
import netifaces
from netaddr import IPAddress
@@ -413,11 +413,17 @@ class Network(object):
# delete IP on netbox that are not known on this server
if len(nb_nics):
- netbox_ips = nb.ipam.ip_addresses.filter(
- **{self.intf_type: [x.id for x in nb_nics]}
- )
+
+ def batched(it, n):
+ while batch := tuple(islice(it, n)):
+ yield batch
+
+ netbox_ips = []
+ for ids in batched((x.id for x in nb_nics), 25):
+ netbox_ips += list(
+ nb.ipam.ip_addresses.filter(**{self.intf_type: ids})
+ )
- netbox_ips = list(netbox_ips)
all_local_ips = list(chain.from_iterable([
x['ip'] for x in self.nics if x['ip'] is not None
]))

View file

@ -7,9 +7,7 @@
let let
inherit (config.networking) hostName domain; inherit (config.networking) hostName domain;
in in
{ {
imports = [ ./module.nix ];
options.dgn-netbox-agent = { options.dgn-netbox-agent = {
enable = lib.mkEnableOption "DGNum netbox agent setup." // { enable = lib.mkEnableOption "DGNum netbox agent setup." // {
@ -18,6 +16,14 @@ in
}; };
config = lib.mkIf config.dgn-netbox-agent.enable { config = lib.mkIf config.dgn-netbox-agent.enable {
nixpkgs.overlays = [
(_: super: {
netbox-agent = super.netbox-agent.overrideAttrs (old: {
patches = (old.patches or [ ]) ++ [ ./01-batch-filter.patch ];
});
})
];
services.netbox-agent = { services.netbox-agent = {
enable = true; enable = true;
@ -45,7 +51,6 @@ in
randomizedDelaySec = "3h"; randomizedDelaySec = "3h";
environmentFile = config.age.secrets."netbox-agent".path; environmentFile = config.age.secrets."netbox-agent".path;
}; };
age-secrets.sources = [ ./. ];
age-secrets.sources = [ ./secrets ];
}; };
} }

View file

@ -1,115 +0,0 @@
{
config,
pkgs,
lib,
utils,
...
}:
let
inherit (lib)
getExe
mkEnableOption
mkIf
mkOption
mkPackageOption
;
inherit (lib.types)
either
listOf
nullOr
path
str
;
settingsFormat = pkgs.formats.yaml { };
cfg = config.services.netbox-agent;
in
{
options.services.netbox-agent = {
enable = mkEnableOption "Netbox-agent";
package = (mkPackageOption pkgs "netbox-agent" { }) // {
default = pkgs.callPackage ./package.nix { };
};
startAt = mkOption {
type = either str (listOf str);
default = "*-*-* 00:00:00";
description = ''
Automatically start this unit at the given date/time, which
must be in the format described in
{manpage}`systemd.time(7)`.
'';
};
randomizedDelaySec = mkOption {
type = str;
default = "0";
example = "45min";
description = ''
Add a randomized delay before each netbox-agent runs.
The delay will be chosen between zero and this value.
This value must be a time span in the format specified by
{manpage}`systemd.time(7)`
'';
};
settings = mkOption {
inherit (settingsFormat) type;
description = ''
Settings to be passed to the netbox agent. Will be converted to a YAML
config file
'';
default = { };
};
environmentFile = mkOption {
type = nullOr path;
default = null;
description = ''
Environment file to pass to netbox-agent. See `netbox-agent --help` for
possible environment variables
'';
};
};
config = mkIf cfg.enable {
systemd.services.netbox-agent = {
description = "Netbox-agent service. It generates an existing infrastructure on Netbox and have the ability to update it regularly through this service.";
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
serviceConfig = {
Type = "oneshot";
# We could link directly into pkgs.tzdata, but at least timedatectl seems
# to expect the symlink to point directly to a file in etc.
# Setting the "debian timezone file" to point at /dev/null stops it doing anything.
ExecStart = utils.escapeSystemdExecArgs [
(getExe cfg.package)
"-c"
(settingsFormat.generate "config.yaml" cfg.settings)
];
EnvironmentFile = cfg.environmentFile;
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateTmp = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectSystem = "strict";
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_NETLINK";
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
};
inherit (cfg) startAt;
};
systemd.timers.netbox-agent.timerConfig.RandomizedDelaySec = cfg.randomizedDelaySec;
};
}

View file

@ -0,0 +1,46 @@
age-encryption.org/v1
-> ssh-ed25519 jIXfPA NUkF7lh+zUlEhOD+NEPL5g4VZiljYtL9dmRYXwIXuDU
DLAlaC41tFIyuWa0Jj48PhVR+Z3FRv+/XVdxQsZwDSI
-> ssh-ed25519 QlRB9Q OZZomAuABy7/HE+mnxzKX2JKAtPfASCLeovOD8WPiSM
9SzTBIziqCI3geAi5e8GwW5w+my6bTga3exjBFyg9Ek
-> ssh-ed25519 r+nK/Q QPepIFvtYrJmLiCZCB0UkQPeegGwl1YJt4+5KXxhr0c
z1oacvWwv9zY1SoTEXQkCiglRp43Pod0qwId+1gk3ho
-> ssh-rsa krWCLQ
GJRazPf0i2LBvHGMzGxtWcCOAU+ftg893i869ZbunOdOeFHZHip5u0WHdsSYB8cU
pRISjEONpGKbcZHEWNK9BDdEs/a7ysN4Jpl/2jRvqaNH21son2921d7KOLnpxRCx
11UrPn6H6KedDhThGxPUFfZRuW9qePlyLLQo/W6N/y9wLQ1YXvmrvzDKeYsH5uZE
NWdwcTCvkCDIvrc899wTUjDHeMEZ7HXM5sUTF0uCzuURDzXiDU0Fb0DpNckyHp+9
mHV7JnE9hMb3cFKX0ICYWLdxQZ3gBb3GHiY7JWmk2CaYMEGnrFrGVTfXOeYyTRhp
2iTIOvkJ0F7vhSseiJOPdw
-> ssh-ed25519 /vwQcQ 6RGiLik5D+yo5BYVZ6zsTOjAXVU4s+In06SSUwLO20Q
9liiNqGLNu7yMoPN5UOWigj9svMdY6pFZPwyD6ykzxY
-> ssh-ed25519 0R97PA VTD/SyvWPXHXDqe6PztyOyngDeCjC/EvuGk0mdG27y0
+B6MiMt5949O1rsVCU7PETDJ2xrX02cQwaCm65Jvp7w
-> ssh-ed25519 JGx7Ng kAbPiA0jJIr1cx861DHMJDM3dEWH/JErsVT3UheqNHQ
eYTTBPu/h8SrpvDkbuvv4VkNDIuFlMnv46xupUgWKrE
-> ssh-ed25519 5SY7Kg f5D29L5Br9NxZBYeNYuIoLPWeKgdtqEJKgqy/ynKTw0
7ym1s9hyo+Pd9O7kGcseafExd38uER+lOi8t8sP5o5c
-> ssh-ed25519 p/Mg4Q mMMcON4YC9xaNesoNnuhC8AmO8OYOXgXXalJbcbf/iI
ls4IThQ7bZ7hmdZFwNvid+9sBWTQS+pHUkNa1NslmMc
-> ssh-ed25519 DqHxWQ RvGN0POhPDMrr6u9JeOCHp2MN7RUmKsPY9cpZ+k82yI
LozUXuuVtQStR4duamN4HY7Kdiq2IoqRV1LWqU0cyfI
-> ssh-ed25519 tDqJRg LwZ+eTu8EIgV77YnrtXGPSY0aVZJbeJe4ejobtadAUM
vITC+8MrHkmzJ0zMsk9AU+hcc+bwJ/ZPv6JXTuqUltw
-> ssh-ed25519 9pVK7Q oOySxJ2tO7ECQZEJC2UlUErVO4v7mPwIi2zn2FkPHB0
oSw4tQY8492A/XZFsq+lfNowbiiZz2kgKAfJfVJ//jQ
-> ssh-ed25519 /BRpBQ XBfnufkT0rdvt3588w6xuVL5XK7VnLTNG0d+SBZ82mM
jgtG4VDZaq5AI8/RoBp3XjMFsNNT7x7eQbdaLp9ycwU
-> ssh-ed25519 /x+F2Q aUwvBNo9iOYP4RhoH6SYSmSTZ8adGYZQdM+qC3UYnVM
Kv0R/MIrEEamJzs9TLSI6PfbbaOqqKOT0lsZBcNmrXs
-> ssh-ed25519 +MNHsw 1aektirbIrnR6rq0UndczpXzS588bHcYINTJnvdNLyU
he0QY7CWeQ+eGdJ/gqAI1m+pN7GlLeGEivAONt2BLak
-> ssh-ed25519 rHotTw OX9NgiDaBLqRC/DgLceOmZFrljgNfRywPeSAhZNlKG0
0spiVg3+KYwoWONJf8ZaPDN59LImHxlzhypI8awovIw
-> ssh-ed25519 +mFdtQ Qya0JWuy8YhkkWYcJjwedHtVG8OTcplwaFwUfT3gGzM
kaqko1aL2UE9rQbT5JfCJ+QtdBwCVvzNcL49Lk2UJ94
-> ssh-ed25519 0IVRbA Yajfo3uixZ9oJL/BGWzjkaF89moLHCqtgGhAAWc6d3Y
qUz3pemzPRVOp7CNN/S09+56Fj/6bu1NZR0JTNwuIWk
-> ssh-ed25519 IY5FSQ KZGVezKb0D7M7N7ry2BpOb4Vh/RaNQR94JO8imFTvGM
Et8UN82Ortb0nvP749hYrpwHR7CCcJ/cfw4MgchwUBM
--- h/4Bn/fiFPmNZYIDIRv2fQmZdOn6iDouzUf+ejfIdl4
“ÙxŒ û»6ïž—â?Jt°ý†èfü܆{Äf];•a-ì6p+Œi;ìjªÖ…œ<E280A6>®ÏtÊ-¤3¯·Cezrì¼¹î h¾—:œn>j˜¡í»Û <15>ø]eç¿—%þš¬í´Ý‚

View file

@ -1,46 +0,0 @@
{
lib,
buildPythonPackage,
fetchFromGitHub,
cargo,
rustPlatform,
rustc,
typing-extensions,
}:
buildPythonPackage rec {
pname = "netifaces-2";
version = "0.0.22";
pyproject = true;
src = fetchFromGitHub {
owner = "SamuelYvon";
repo = "netifaces-2";
rev = "V${version}";
hash = "sha256-XO3HWq8FOVzvpbK8mIBOup6hFMnhDpqOK/5bPziPZQ8=";
};
cargoDeps = rustPlatform.fetchCargoTarball {
inherit src;
name = "${pname}-${version}";
hash = "sha256-uoUa6DSBuIV3RrE7svT1TVLxPHdx8BFu/C6mbpRmor0=";
};
build-system = [
cargo
rustPlatform.cargoSetupHook
rustPlatform.maturinBuildHook
rustc
];
dependencies = [ typing-extensions ];
pythonImportsCheck = [ "netifaces" ];
meta = {
description = "Netifaces reborn";
homepage = "https://github.com/SamuelYvon/netifaces-2.git";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [ ];
};
}

View file

@ -1,64 +0,0 @@
{
lib,
python3,
fetchgit,
ethtool,
dmidecode,
ipmitool,
lldpd,
lshw,
}:
python3.pkgs.buildPythonApplication {
pname = "netbox-agent";
version = "unstable-2023-03-19";
pyproject = true;
src = fetchgit {
url = "https://git.dgnum.eu/DGNum/netbox-agent";
rev = "424283239658516feb34c0f68496775350b1bf22";
hash = "sha256-sp1QVy8AIezR2LRDDYS9G0g0GQRwGKGmEE7ykITPxtY=";
};
nativeBuildInputs = with python3.pkgs; [
setuptools
wheel
pythonRelaxDepsHook
];
pythonRelaxDeps = true;
propagatedBuildInputs = with python3.pkgs; [
distro
jsonargparse
netaddr
(callPackage ./netifaces2.nix { })
packaging
pynetbox
python-slugify
pyyaml
];
postInstall = ''
wrapProgram $out/bin/netbox_agent \
--prefix PATH ":" ${
lib.makeBinPath [
ethtool
dmidecode
ipmitool
lldpd
lshw
]
}
'';
pythonImportsCheck = [ "netbox_agent" ];
meta = with lib; {
description = "Netbox agent to run on your infrastructure's servers";
homepage = "https://git.dgnum.eu/DGNum/netbox-agent";
license = licenses.asl20;
maintainers = [ ];
mainProgram = "netbox_agent";
};
}

View file

@ -1,53 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 jIXfPA zyp8jIQ/BGlaOe2hCYdO2/jpiCJO/yASFn2v4yxF3XE
tnajUOFI/LeiRRK2+XEmgAhU8PfyerYDPZ3CASAx6uE
-> ssh-ed25519 QlRB9Q GTRAu+AUZ2MJs3ZaZR8GcS8U2xyGR0mx1FB78TmVhik
PmenwNgQQUd6JWgUU1zmJWF+Lek4QwCKc0MzD/iLGUE
-> ssh-ed25519 r+nK/Q 2cOo2pK5KN0keAbW62MaC0/wDysciEZPgY8+3vhx30s
ZmjX2vi9qYOVWtctWcEt95l2kBlZH1uNLFUdUxSHyus
-> ssh-rsa krWCLQ
xNCMgSxO8SA2rQqU14RD2TU5PQyssMlWomoA9VjoT6FsYZleRd7nPeABYqlnzUNj
wWk3obSp3AO+NNscnmFrAijYQl0C+hBBplsgEyQ87j60s0ReAZGaURbrxRJr0dr/
2JBrPtQ7tiSQYRZG9DH6ASUYrlVCB3Vq18OOa+os8PpqyL6Q6pglx0ePY1wx9irG
6qj54LAR34C+uOi620LZuJ3YhZYIp0blmxqrXGeVTY1c7mmELKCdslFpiBvKE5jf
71Lj6ihc5Z5kJxi0vPXMXkuGXtmlIr57dre2XWhynuXq9sLj0KEE0GVQa/vMV3Hd
4/ATD4bbpkzwkfZIlL1LRQ
-> ssh-ed25519 /vwQcQ 63EfH8Eu6Rdyz01sN7yfpaQpxJ2w4VqzQRWMw3AMSAk
bj1CFYkCOcoMtuq/mC+vn9YM8aM9rLClcGo1rpytN7k
-> ssh-ed25519 0R97PA gOIroiigdZxulsng29mz0o3gLYnMb5YjmBOmTd9UvHw
mgvgYedm7U1y5BlRcvPEZhHpPEnczungDuBAEGcJwMw
-> ssh-ed25519 JGx7Ng FeQyBpbGZ2WGztFXBpJ5uYXIPIEJqnf2FedleYRQJUc
SzbinTIdwa1pvc9AZSWj2GRR86hD+SHY63QzBSv4D3I
-> ssh-ed25519 5SY7Kg BgCKJrxjRS8QNCndIfySdq2u+hv3Q7Dg/hToWOE8e3g
/rKzCb9fdZTEwTP1/QW4vn1ewQDn5TtV4Ui3MwChdB8
-> ssh-ed25519 p/Mg4Q ftfpqvy3TuWoq+Hcmt+oYiJ1GhwYvR+GDh3MzVsfv3s
I2dj0FSRGfoBqwSetdKz9NX11zUeHxIizmjctYrmjD8
-> ssh-ed25519 DqHxWQ Zs+uNTp/4plSisoBzUpnvlZXLrbYphYvaeogHCyg4As
hvXMQNPnJK7ZQrkYIyHW07rWd06QkNpiNuL3oUXxoQo
-> ssh-ed25519 tDqJRg hMw/doebsExNtZ9oC1OFrnWOsiPOKh3D76RPfw0If00
p5dxioeIt558deMFrRiTMxYocmP6p8kTk/nzSb5yuPA
-> ssh-ed25519 9pVK7Q mctwqK3IkQdbeajO9mbvejtG85rFXTmFdptrzIzP9Cc
sVG1NKMmTR0Sf60hvPJ4QRypmBT4a6yUZ+gyp/Xf+EQ
-> ssh-ed25519 /BRpBQ C6CjF9H+x1fd2s4sjHw0IzKpNvbnr3H0tnxJdwzrzlQ
gcrSM7NoHqeFdsTAWpO23cfAISile0uVEHu4fBvqwME
-> ssh-ed25519 /x+F2Q t6mrvde1VJP7ARlwQAFOQxg6Uu2+GDDzN8GG/F/C5zA
z3jOcIvHjH4TgiMHqABBU5t9bilBtv5rBKHJLMp9CaA
-> ssh-ed25519 +MNHsw 5FBjw08c8F2wqrJe8KfWdn5bjzYmXXqLpVIozq8c8WE
47oEgYMsl6/JtL1JqOOajHdB22gIdIGhhtcchUK7ZX4
-> ssh-ed25519 rHotTw 4/W5DKJCc18KOcJQ1s4DveOVEjf5oy3HeQF5AThpvFM
vG9LsTXTFk6TLHNDDS3qtirjm7iyZnhN+FM++xU0qGI
-> ssh-ed25519 +mFdtQ bh0b+b2J2dg9hpBVYM3hDUwJOO/xi+dcH41abtVjt2E
NPU1M+fXjOSROEWY73hftAniWUpr0ymbfo8mqZTPC/M
-> ssh-ed25519 0IVRbA ioMW4UYJ+kKlZBdf430FHnbqdw3BcwWSr2RmOHCv+hA
qw0VDAu93LSEZqhs9nRTCMGWsXKjxK65VfkKJbUU5fY
-> ssh-ed25519 IY5FSQ 1aD4KWKITo+88CEwuTKq1QH+Pf5qoOXlI+EY2FX9IG4
KzOGMeIxLypf7S6WeUM4Zr/S/g9HWXHBGcKkgHMLRJc
-> ssh-ed25519 VQSaNw fCt2YDODTAtamSSYH+RNIpWAQ53WPwOeR92rHa89QBE
2KAY4EgfxnNxvQGV4lgoGT+sb4nJV1eE50GHRljngEo
-> x!p-grease Qza ,IU!}' (fMHX0~ m
DGgaSNyr7o+hl8p9viIHBbTdiTdY79TgFsTdM2oBJAqT5P/LkFzg8TYNsH04eReH
dmTu9wjN2OM
--- +/E2Y1+KnzcreXm8DtJE39wR4dVL6vneloVFzK33c8Y
T|ïá+¡ÆTÔŒÄ
vΧ“8»,OÔ¸lžÇ±z)/0­<30>>hkJMèl öÝ®GØßûGÜ>lU¯1Ÿ}€Š¤£T<C2A3>ÞhèÅý,åÎ8Åç%ßÓ¤lQ‰
ëb©,@

View file

@ -1,50 +1,46 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 jIXfPA zVe/xwQCEtVnX8qWShePzBmhfQbENRMn8XgPzEqb1gY -> ssh-ed25519 jIXfPA yR3cPS4s9FfwKAkXOoX1z9noWB76Dtp1GRHwltjHJGI
CFa4qXtY8lBlSIxnWVbejVta8BFYmsCtp9TdXXexZYE Xm9BU7AhD4gQtHHhp/10Qf2q9hgk8mus2loreeycxd0
-> ssh-ed25519 QlRB9Q 3EJeDSBkwJU2LaKHygG/a0tfFRXcp8SNJBxyhIOwBDU -> ssh-ed25519 QlRB9Q t+0hmPXKCm+lNnHzQtBWkenKqnPIxnf3qR05zFdtZww
PI63A4YJFC1XTNPbl73SBlUMV25o0ZeojAr8tr5mtlY djP+WapwpCStUdL1pvpTR4aI6oj6SgookP7fluDLG44
-> ssh-ed25519 r+nK/Q /4HQCHPBBk7lD2mwJOMEmTeRpPGnPgTcL+htNRvkxkk -> ssh-ed25519 r+nK/Q BUsgW8EA2lk5i63114kH5G9bQ5uSJrsWBpktXIPIYTo
oXLQoX+AK8zn82wsnLHK4BOpK3gn5lThWiFXh8+rxUU DuxpBQqYFXq/bdtsezmGLPza+Y9GUMRhIsdF63IY9jc
-> ssh-rsa krWCLQ -> ssh-rsa krWCLQ
ox5TBB9buXII2U32S/XpQVdr3r87p9lt/7WwELq//ik7vf4B6mZPbYvIV05JZ5bO cyG9NELJZ6kHuXixzqrQgxi9Mi0I7322DsNS+jhAi7igHfc2ta6tNL0qNngmYaHI
4f5khDdw+q1bbniDCBH2aPKM0ni3wBdLkT3jwdQBL5imSQuly/cFMdvVwSTuwN9k +eAO3+IPH4g8pd1tuP+YpRjvBAz0guPCOKMoDdHBDDkC3qTDr91D1zsZ7I/EgGa8
8smSavsUYK5q5xgE49oMYJBAhNVGFI7NKlx7/a3VaVybsLAnzp3AeWy1o5BB1fKT 0YXbHziCqlwo3W49rz+0lKBsz1gOH2UMrsEh6ZmFysvxiHdVxSwOkfqwmNpRMmiv
7Emt88ht4lymL/gyxSMLT5Dreb5Sm+AcE+gYAK92OnX4Z1k8FqETppTKZDuoZUmv zLjDmTSosP1DUEvd8ljHy/KFVgvoxGx6DB39vqg4+IaL62pkblbO+b0dj1rhxq9u
hJPpylXw7/YJU7Q0CluwtcGWFaTuE6AT0IrlCdY3NuMGA9IfpVsZr1kocdq2qB02 iyOSc4G9laEB+umrvIhzbs+9r6tVwFqTIeauaNuKykhkWwq+3e3HYsUEzomMoxwE
90/yy51Ulwhfhiy1/3mlfw EhGpDVfVw/Tf9zUkfuBNdA
-> ssh-ed25519 /vwQcQ SGCKP+4m5p9SiYnU3vL0QaKp/3+yztZ0snZ6os+mUAo -> ssh-ed25519 /vwQcQ 71hXw3fsK7gvQNzNzHgJYXWVlQTkx7xvSKkZldoyNy4
ZEVgV6jo7tRdM1KxQJ2UJRDEYaiQy9PYzaeSAstHYFQ +HgmrnLrK+k/j/Fkn/e/pXfAMpuQz72hSmx8p8dN7ts
-> ssh-ed25519 0R97PA Bblz2DxUIBovbFqHhwGSRrs3Hbc1vNMtn8SK976YYAU -> ssh-ed25519 0R97PA hm9JuJDRq7J3unX6vHPuM15FKV+C4ClETXkUIJcs9iI
FtEsqOUChH+uzFuTsATraNyyJXXdkesmbe8T+LeK9nU 8zSV49d5JBojuvB4ob1/5l9oAnmIEF7qI+fum1Ypbic
-> ssh-ed25519 JGx7Ng 3umTe7hK60ghA4fXbapBRjjJ9K6hXLfV5kQrBzwsmS8 -> ssh-ed25519 JGx7Ng jFGivHErkaUGpxIdgOmzbZDihBKDLjgy6pd9QxdpEUk
oRBFSJsVStw2ul6JxdJuan18GriwYF+d8asKXnWDpZA U/GQwv6YZCqpVmBy05NPOn3Iy3S07hKz4+5uCfUzhM8
-> ssh-ed25519 5SY7Kg Ft714PG5dVVJWHu0aJh+wdT04vSb/vlDVsWmUhdjUXw -> ssh-ed25519 5SY7Kg 5wLPRuunyDGAeh/cF46X24rQwlqoDbSkEowNE0Rz8BI
qY7OJduSibFheBQOrGnSFUOhou/WyyY/M5tAYGvaTJI qoriKBAeOA98oQEyaCICP1VyrOMxwsiWJRQ8oMFlFaM
-> ssh-ed25519 p/Mg4Q u6ES8PpiDb1OY97sMQ/kL6sTIjBhDk1aqoIEd0I5BgA -> ssh-ed25519 p/Mg4Q /lA5xli1c/nsYVsiGzbZg5QNpuTF/wVG0ByyWcoZQWM
pbX1Wk+5aTbf5rU2JM0rf4SR/fJGLKcDcqLF1yDXbiE ikGP4kX1kxFyn/gui2H2YUgA7ph4N+j1ZZLIZp8RGe8
-> ssh-ed25519 DqHxWQ n8qHGzdwY1RfajPN+oZV0Ps44rqbW5tcUFSSPbyZmAw -> ssh-ed25519 DqHxWQ sPPbe/HX+ZMvTzP+IGYZlqUzGWdrw+5Fq+JenoxnMUI
EAK0hA/94/ZxBz0iNaTl2RlpswiO+2eIWugozHrZZfw tel2fWk2B4To5KtdvS6vlQIAVvN+MeOHlBLMZpmaABQ
-> ssh-ed25519 tDqJRg RAEIORbyHLRNkm+mFsq07E1uzbEEIBQ3eG+kpyXLLG0 -> ssh-ed25519 tDqJRg /kVkNfR+SNGS6iOs185A5XwApB9DjjD4kIPnfka3IzA
1S7gL5WgXiFZxgH6kSp1zANafDTEKsC4Wo4kT8oB7b8 0h/svIu2/MCs1/i/X0qhGad59r8lJA+k16Luh/qN67M
-> ssh-ed25519 9pVK7Q p7tGHwbC3CWap6feMXq2twGHkyszLP0EKwhW4McAoj4 -> ssh-ed25519 9pVK7Q wRzALhF6YWQBaxqtZoaPNtLAWXUcGhdeEorWXXWDRiY
7F0zZEON8H2H+v0XRCOiYeUuhJBRUVkFoEP+Cz4vHZo 4ivHOIPeXs7YQoiKn0nEK2Q82PxDoulCrfVZhguOayc
-> ssh-ed25519 /BRpBQ stXNcOvGwPBPz8TtLhQUVgpcvu4BtfUACAZtrEI0eGY -> ssh-ed25519 /BRpBQ dUJdnbTI/Rq2CkAlHnPDfSajTW93rLL4X6vJDgrGO08
FN2yFmvc3GhMGNTUCT+XMr1qsfLvmjHIkYoi5B3MDsE 6itr9WBj0EiuKdyRuRM+4i+c+6DiFyBYI+COkvvPDSA
-> ssh-ed25519 /x+F2Q fmGbMAGFJbjR0zVdJqsigKQ28nbDq8Zx1FsgviLWqHc -> ssh-ed25519 /x+F2Q biQXbA1oZ3ujAw6Pwh5P4iUGNiFYI+R3r7KJrsikuQ4
+v09rkeHZTvFQLaXfOnFaZMBc2G2BD5dXWYg/Nlx2Og QZcrNLEbpki6KDW33TwVt84TwT58g6qcSlluZ5J0i1I
-> ssh-ed25519 +MNHsw KqIxZ4L1aoqLevCwx6Zp0jBHfTOU7WdrE0UN56/xARE -> ssh-ed25519 +MNHsw vOgZMXC+tHWRVRpGwYxrR5C1Nrh0fCkRoNOjgTJHgHc
OwQ2/WUEfl/oXxfbv5rlLu4OOdrACzPfSS6HfcLpi60 dj0m2fbl4V2MUR8Uri4evfWolPoBKf5Rfg/0FjGmntc
-> ssh-ed25519 rHotTw hwCwUHi/xbAQaWt26kOn3/QSP0m0ZKRdIYs55TDMLSM -> ssh-ed25519 rHotTw wgphy9glZhVqnF+idQDFJ8crMbhuXnGcCU9iVT0dEgc
DCvnBearzyPQ6ErYuawsyobpMsD9SSEhkVmFKyp5jUI sFoc7VjZHDMCBTJJ/fBvcVVxl72EcHeur8SSjeH26E0
-> ssh-ed25519 +mFdtQ ZlEsxLPDfy29aIQ9eNsRkZCHSeRmX8+GsuGtikQF4ms -> ssh-ed25519 +mFdtQ pehvyrKd9oYpA5VWwN6DOJckooAMkpm7wSEAuVMjkRg
n1N2xQb4oRWaJgLtrXMFasc8u516e1M4Q/qLNLA0e0A oPWQRFBSLKU0Ic6+qudFzxnM3wggL4Y86zqWxc2p7kY
-> ssh-ed25519 0IVRbA keVcQ4Vx3Avd97N89nUklRnGMABBenHIi+aufVoTABU -> ssh-ed25519 0IVRbA iSgsYBbpWlAgUAGM9JNRqoZTOuEP3NMdmrKDReCXfSs
yrsC1OitS6sqbUsaIaWeU8vYGOQm9afFfc6DprB8Whc Z+zHgn96/09FqhyJZmpCZBB4BHDE6P6/j8avd39I68k
-> ssh-ed25519 IY5FSQ npdYCAEfVSpuDNMZnWS469BgvivTKHRKtEAtxmxDZl8 -> ssh-ed25519 IY5FSQ qQOXJr6TkdwfGFgVe58QqpNjV1uzUPzuV6Vbc5jhnlg
gOB1vpBO8ZqtLVwxCj8V/KrWgnYmZGn5QQJzMhiHH4A fdfonQACyNyJb4q5CgtTArqD4Ht6Cz/W+FWG+nNevvs
-> ssh-ed25519 VQSaNw S3dSnOPVQdMcz1dJYai0DvZATuMBDsG/+a0sJBDc/iE --- F7Ci+t2UpR0PkulLA9cJOjoTXO2GxjmPNX+Go2L9qB8
Q1gl1nIpDESMvTBX03i4lStAtdWqlTkVABHZ3cqocDE Ä<š×]´­D ìÕ¡²À÷HÇ©ßA°&EàÙ¡°V 0ýxRŠÜEÚáб¦R¾eA#üÌ/{`Ø5.
-> t-grease bvZAq
NTQBWWf5UW4zsTEEt7rgmTv+B2rFIk/8WwQPrC/s59Ik
--- 46n57xU0XlDQgUM0vIYveqDifz57FrTcRwCEpoh62+4
[07Æ~Þ3dïálÃÅô!fãš4ÐHßA‡íœ÷<C593>9 ×ò@d»BÌ&½L‰{aãþm…X2ãD‰Å ´

View file

@ -1,50 +1,46 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 jIXfPA YaucboAId6lgc1Y/jV6hLyovkJQnMBnKhJ2QWAci53U -> ssh-ed25519 jIXfPA sHMGZvBA3KQ+vgyPRvthm7RrZv+cpA8rVaLMG11tWzc
Q8RUPu4GUC5QbzTROgL9xaG3BUWO1QU/q1p0/yimBQ0 wb74jb8YFbu4hTaKECNpaCV5besptdBoXXstKd+eLTI
-> ssh-ed25519 QlRB9Q y1tbd/81NoECRtKwOw41Tlls5y+WSu2jGmeOlC939VM -> ssh-ed25519 QlRB9Q RILFFiLngUvfSPOmw6ZLmFLVyIIQqzib7LTV8hZP/w4
DT1zZgWJkkIWRWxzfu4VgiGpV8CioaDKnVemowH59N4 na6S3iWEs3cxff30X59wD0SUNEP0/9LcuCyCUi7wgxg
-> ssh-ed25519 r+nK/Q dDmGkZ3Y7xAzZGKvGIyIdhD+P0tkV6SMPx3UxphoTXo -> ssh-ed25519 r+nK/Q Mtrr3NKJG1MBw150IZK1ZTKCglktIK8mV2M7FiLz9EQ
tkanRbPfu3/cuMPoTrcWBlNcu6RmK+txif+9aIRLy+s zEEJwKeucMsZePFTZF/Cxfcuqn7KiSoBmBnNVKX1jAY
-> ssh-rsa krWCLQ -> ssh-rsa krWCLQ
IZGpFoWjQuQzqkS2KbpVr+fP7NLPhyaxS4yQroVEkPEZnXx2c6eH3ul218zytZld r3OX+AaSGO0zLoEAvAo3UrtWwU/Vjyfdp+qy4haB3tpl305I6Y6O6n2iHnc1PFgw
YRBCxiCtV6VfOB2N2QGuiK7YCGl6oUfN1DePy0jPrGKsnvWBitTuqzADiGQB7aSI qQ7Sa0GekbxNcwD7MzAmKbsm9wmnrF2hX03gFDI5isEPxaLC6ha207Ykauc2q1JC
ie7GgblPpi4q3ovJPgf7Bs+Mi2dKW5hiD8Jnped7rEW7SEnESkQa3Cx22Ww/UYcW /SOZ/OUiizBUuO5OjywYz2AJUfEabmd+X1fw5QxAPSfp57KBZDJCGSpEDeJigU7M
9Uj7ZaDVVbP0ZWyc41HdoJwEnV6MYMRnXUJ/qrLMCIvRaYk8UdiCDgco+XxqAnbs 1n1XsT6eCyNDIIozRzIIyxLZU+tDDswjvjCaDJ/t2BE76LienwMRZK4P4tSn8DQP
iyUqCvz8iVNsWbJxK+7jJHXp0dQJRciHzSGStIVRSGx4gvuXOGjsuBMjfwoq1XoR Jbm7bb5T2P1VAK4qIMP04DXQ861Kr2DvpLA/aPtHd9yMcZn5wQWMCVDgsL3ko0fU
5PE3BnP/atHZg3CkQcC2eA VThQwBW4qe59CCxA68TUcQ
-> ssh-ed25519 /vwQcQ WL0PdIIsSWzw+ar2QNXCp7Xs1NH9gUk2fSPskGC9o2I -> ssh-ed25519 /vwQcQ KYM+4CPxNwxwh3liBBJYIqlWzpDO3h/dl54rEKQXGHU
+kHedFsYHgpsGfILtywJaIrTRj8HtHZvVyhtbRhKYC0 uteNJEqwLKUC3Gjm0BiRmb3uLb3bzRfpf3c1Da3vGjY
-> ssh-ed25519 0R97PA +G7wUHF6NJimsAxe6M9RVVTa3GLPoW1bhsgMsWXKNC8 -> ssh-ed25519 0R97PA Sc9QAI4UNY6x0fZAoQOpUjzFzwev196x+7fjeIry3AU
i++lKoe8hFFb1rilkO9lcwBJujRqFsLGDOPvbaiz6Nw puUi8W0jCbMW3cN7PjoDM+vXnHjdQ2RLfX0kdpsaWhI
-> ssh-ed25519 JGx7Ng o66YGXN0uMC2qZo1tVcEMOa4SwxNZaf4HvnGsgzlqjo -> ssh-ed25519 JGx7Ng LzO5qvnVWhF3+cR4J3nJv9IB55/FYKillkJ2jKadfQA
Tc4KMMrnJbybrNIkhEJz42PVHc3fVMFFSs96lKsEKCA r3F+FKdpoKTB0/e5Vz5JFh9u8BKBOjn9XXE4dJEriuw
-> ssh-ed25519 5SY7Kg P8Xp9wVJDcPdj3uSiq0yLnLMDInMeFs6XX30VwlXWlg -> ssh-ed25519 5SY7Kg Uz/EgMgi0ACJStIvz06efUQpeU6VAuXVj+Veki0LkXA
uJfxXOZl8EX8fjRsHZ61JMKFpYksZJucZwVaRJs7qW8 ukCkNIQMYbZBCBfd5R5dKWJwOcIKHzS9HN9CNk5iSF4
-> ssh-ed25519 p/Mg4Q yUyxue7Oda0b+CjdF9VfUCliWyzXNOsVPH7OFoHzWCw -> ssh-ed25519 p/Mg4Q 9+IsF8fUNcQhRxRddI6WQyKP8Ky0HV4jAUvS0ySDDwM
+zi+TSojvSc+VDXZG8XXSsTezxKRNC2XHc/hGGv4baM 7WamT/OA2Os6uE/hKzWkfjlwOKQpZ6j+fcgkvsk6wCY
-> ssh-ed25519 DqHxWQ 7Vnq/xidbguw/PkZPUOTHUBTe8/x4PvTjCusUe10jio -> ssh-ed25519 DqHxWQ WndaDm+ApRfFj+KL5cJgJqwaZXUYrXHpQ6AxDtGb5FY
7Sl1MptpElvEA9VUj7JiVGuEWC0F3aA2rgYvfIchOB0 u5RHgWaY28QfA3jsD54PLR50Jl5KQyVpPv4CFhLPiYI
-> ssh-ed25519 tDqJRg udOCDV4/vszObNxcQhJ6iGiDkxgZlrBDyKt3MbibMx4 -> ssh-ed25519 tDqJRg Wgx7QpoPeendwBsWB+jAN5K+1uhxPsEHMugOPeC+Ono
CDDd0LNCCdYvEww/h8q2z4f5QtjnL+kJsnPFtlbiD28 CRWVWTQB2eCVSKAwIzNNaWefAmniVtF5hu8xYeTGF0Q
-> ssh-ed25519 9pVK7Q DXqkIewHGpUUDtL2ivAoFwY/HCjoQXjxoHGPGkuFfH0 -> ssh-ed25519 9pVK7Q kB5gWwwNNcCnjN5+1j7alWzqEgYMDQ3IvA8/0ltfLwo
JZ7xC2kdtnRNq8WADL2SNw/Ukezu1s4TuUbQnbP8L4o Tp7n6v/s4swKjOqEDKEKhM8agghKEvaz+zymG+b72f8
-> ssh-ed25519 /BRpBQ 9j1+wzO733ej03ra8LQOkpOyvY63UCbO9sfT6bV6+zs -> ssh-ed25519 /BRpBQ 6B5ODsRsRx8EIOrzBnAAw1bYsAQMvssSC1xxbAh+bGE
2F0UjpAqgCK5JS0y0kkHX30EV8JCcjhnJ1NkW06ww4w Xmhe74XTMwfcGvk620XixhR/6GtOt2fynSMdJ7riZxs
-> ssh-ed25519 /x+F2Q wYchtMn7MCGllfiFwTrycdLEY3dl297ns26PHs7l320 -> ssh-ed25519 /x+F2Q /idVQW3v18G3e++zLmmcpZTvSW6YTfYKYX0xalx3DTU
feRd57Z5k6iJ71JRHud0wyYWo3O56q4rrYZt5y3aoqA ybNKGMgW5ChQU2HXHfM0Od6GWC+HRKDemibhzi+NCA4
-> ssh-ed25519 +MNHsw FHfvx1FQWcsRlKrFF0SRcVZ+XG6LXBwIMcPCVeu/ZCg -> ssh-ed25519 +MNHsw +5EkjYR0CD0tF3jazvyz6WtzIG+84czuEsGzPmucOVI
w9fZGhZpEJHlf8JPcbWcNoAO9S06hi15LZxkv1dJUWk AqBXlugxP84nJ9jK1dPWWRJAAAzZjKl0RKd1+aXeIJg
-> ssh-ed25519 rHotTw QDcThfb0AJMQBfQDbbtqm6z7BGxC4/sBioprElUTXFA -> ssh-ed25519 rHotTw IzGcfj5jNooeVt7+iJwnxUfka95NVEtE9dStQUt+gCE
2JOFoMLcVhMoGzZDDNOTL3PBWsqVnrFx8o/W/cWuzl0 +lrjFHAgNOxI4JS6tGXcDSnbdn6/qwt2tI2WdVX2tO4
-> ssh-ed25519 +mFdtQ tWg17VH1Q4gQj/1IK9yrxjw4kRPzsp4dDHFwDKYxvDE -> ssh-ed25519 +mFdtQ AieFjWmv27LvUbZXCBEqmvfTQM7SLXL12qIOzZLxdi8
9H4ohD3XN4Xtk15SsZQf5k0db+yIVcWp4EV5jKsZgHI s0qzhUO2FDqr/w8B4cbnX8NuXfZM+nv4gj6SF0DreCY
-> ssh-ed25519 0IVRbA rkMPsBgVEaiYtaBN5JzHNCPFYFKr/7dqoY+RX19+03o -> ssh-ed25519 0IVRbA +S10pCaLByp+UrfbZXIIhMvUW79NPSSr5qHbm8Q8nxY
baQK5t5sG8WabaCuMTZ2ZIfMTRH0jQU4l7JEyJ6H+LU fLU4Shu/luX9gLrJDM8rY+HRpHuuLKJAz0BSiLfXkj8
-> ssh-ed25519 IY5FSQ c1+2+CMJFMw/iF2XNx5ma28KhwdKKQ9dNC1nBvFz/B0 -> ssh-ed25519 IY5FSQ FJGXPcN7XjZTl3zc8iLSmc2IfhHx/xqIqnNz7j0dXGg
3AE1FQq+//dNIQfuW9BHcpfNbGn724Ydq7aJc95KmmY D99jvNKh7yzafKB9qzOX6xNjhf3WS4bYBcc91dVX6Ow
-> ssh-ed25519 VQSaNw t9yLak0T7FO8hgGrPWFeR3Jw0D6cPxjR5LOIcMnAmgo --- USWnD/9XEj6tW0aHMZiVK1Guf43b/8wWcsafnVT0+h4
869SBp0nM5v/9+Xjib6rkmmelhTBfXcyuHiAXh08AWo RqÏHª,XHs8ÌÛÔtAbAGI<47>áΤÂ,åÖÝ¥¿è:<G=bFb†ÀTGSGäÊÙ _ ˜
-> r32t]I\-grease ka<*
nkxH0w1aQ64
--- LlTR5EcQzCLJ5trkQcomW0+soQoec/IZZNW+g5dyOo0
M"ÏLm“õh]ñÖa£uq±ýÏ4ßÏ+ö“9;ФˆÇ-Z±L»¯H0o1»Eâ<>

View file

@ -1,17 +1,6 @@
{ config, lib, ... }: { config, ... }:
let
inherit (lib) mkEnableOption mkIf;
cfg = config.dgn-records;
in
{ {
options.dgn-records.enable = mkEnableOption "Arkheon deployment recording." // {
default = true;
};
config = mkIf cfg.enable {
services.arkheon.record = { services.arkheon.record = {
enable = true; enable = true;
@ -21,5 +10,4 @@ in
}; };
age-secrets.sources = [ ./. ]; age-secrets.sources = [ ./. ];
};
} }

View file

@ -1,139 +1,19 @@
{ config, lib, ... }: { config, lib, ... }:
let let
inherit (lib) inherit (lib) mkEnableOption mkIf;
attrsToList
concatStringsSep
filterAttrs
getAttr
mapAttrs
mapAttrs'
mkEnableOption
mkIf
mkOption
nameValuePair
recursiveUpdate
;
inherit (lib.types)
attrs
attrsOf
bool
port
str
submodule
;
cfg = config.dgn-web; cfg = config.dgn-web;
in in
{ {
options.dgn-web = { options.dgn-web = {
enable = mkEnableOption "sane defaults for web services."; enable = mkEnableOption "sane defaults for web services.";
internalPorts = mkOption {
type = attrsOf port;
default = { };
description = ''
Map from the web services to their internal ports, it should avoid port clashes.
'';
};
simpleProxies = mkOption {
type = attrsOf (submodule {
options = {
port = mkOption {
type = port;
description = ''
Port where the service will listen.
'';
};
host = mkOption {
type = str;
description = ''
Hostname of the service.
'';
};
proxyWebsockets = mkOption {
type = bool;
default = false;
description = ''
Whether to support proxying websocket connections with HTTP/1.1.
'';
};
vhostConfig = mkOption {
type = attrs;
default = { };
description = ''
Additional virtualHost settings.
'';
};
};
});
default = { };
description = ''
A set of simple localhost redirections.
'';
};
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
assertions = [
(
let
duplicates = builtins.attrValues (
builtins.mapAttrs (p: serv: "${p}: ${concatStringsSep ", " serv}") (
filterAttrs (_: ls: builtins.length ls != 1) (
builtins.foldl' (
rev:
{ name, value }:
let
str = builtins.toString value;
in
rev // { ${str} = (rev.${str} or [ ]) ++ [ name ]; }
) { } (attrsToList cfg.internalPorts)
)
)
);
in
{
assertion = duplicates == [ ];
message = ''
Internal ports cannot be used for multiple services, the clashes are:
${concatStringsSep "\n " duplicates}
'';
}
)
];
dgn-web.internalPorts = mapAttrs (_: getAttr "port") cfg.simpleProxies;
services.nginx = { services.nginx = {
enable = true; enable = true;
virtualHosts = mapAttrs' (
_:
{
host,
port,
proxyWebsockets,
vhostConfig,
}:
nameValuePair host (
recursiveUpdate {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${builtins.toString port}";
inherit proxyWebsockets;
};
} vhostConfig
)
) cfg.simpleProxies;
recommendedBrotliSettings = true; recommendedBrotliSettings = true;
recommendedGzipSettings = true; recommendedGzipSettings = true;
recommendedOptimisation = true; recommendedOptimisation = true;

View file

@ -45,9 +45,9 @@
"url": "https://git.dgnum.eu/DGNum/dgsi.git" "url": "https://git.dgnum.eu/DGNum/dgsi.git"
}, },
"branch": "main", "branch": "main",
"revision": "24f825c1dd34a3948cce7d39c19623ecf948ffa7", "revision": "f6fcd90622151e116adedb41f53da0445f1ee387",
"url": null, "url": null,
"hash": "0b1pmfzckdbha9j7bvnkvqccf62dqyll8ip6mrdm90m0y8kdkzvg" "hash": "1rrm4j142h2dkphya34hg341xhklrdvqim35jy6g0152a7y1nkk4"
}, },
"disko": { "disko": {
"type": "GitRelease", "type": "GitRelease",
@ -59,10 +59,10 @@
"pre_releases": false, "pre_releases": false,
"version_upper_bound": null, "version_upper_bound": null,
"release_prefix": null, "release_prefix": null,
"version": "v1.9.0", "version": "v1.8.0",
"revision": "49a4936cee640e27d74baee6fd1278285d29b100", "revision": "624fd86460e482017ed9c3c3c55a3758c06a4e7f",
"url": "https://api.github.com/repos/nix-community/disko/tarball/v1.9.0", "url": "https://api.github.com/repos/nix-community/disko/tarball/v1.8.0",
"hash": "0j76ar4qz320fakdii4659w5lww8wiz6yb7g47npywqvf2lbp388" "hash": "06ifryv6rw25cz8zda4isczajdgrvcl3aqr145p8njxx5jya2d77"
}, },
"dns.nix": { "dns.nix": {
"type": "GitRelease", "type": "GitRelease",
@ -87,9 +87,9 @@
"repo": "git-hooks.nix" "repo": "git-hooks.nix"
}, },
"branch": "master", "branch": "master",
"revision": "3308484d1a443fc5bc92012435d79e80458fe43c", "revision": "1211305a5b237771e13fcca0c51e60ad47326a9a",
"url": "https://github.com/cachix/git-hooks.nix/archive/3308484d1a443fc5bc92012435d79e80458fe43c.tar.gz", "url": "https://github.com/cachix/git-hooks.nix/archive/1211305a5b237771e13fcca0c51e60ad47326a9a.tar.gz",
"hash": "0qdhcqisil8zhnf600y0vpa1mayrca8z2bja79p4j5vajy7dnx4s" "hash": "1qz8d9g7rhwjk4p2x0rx59alsf0dpjrb6kpzs681gi3rjr685ivq"
}, },
"kadenios": { "kadenios": {
"type": "Git", "type": "Git",
@ -144,9 +144,9 @@
"url": "https://git.lix.systems/lix-project/lix.git" "url": "https://git.lix.systems/lix-project/lix.git"
}, },
"branch": "main", "branch": "main",
"revision": "66f6dbda32959dd5cf3a9aaba15af72d037ab7ff", "revision": "ed9b7f4f84fd60ad8618645cc1bae2d686ff0db6",
"url": null, "url": null,
"hash": "10mfry8k0jab4ngnhvx9d7ia8m7qf4va4395ylwg3qlsxziqvc8z" "hash": "05kxga8fs9h4qm0yvp5l7jvsda7hzqs7rvxcn8r52dqg3c80hva9"
}, },
"lix-module": { "lix-module": {
"type": "Git", "type": "Git",
@ -155,9 +155,9 @@
"url": "https://git.lix.systems/lix-project/nixos-module.git" "url": "https://git.lix.systems/lix-project/nixos-module.git"
}, },
"branch": "main", "branch": "main",
"revision": "aa2846680fa9a2032939d720487942567fd9eb63", "revision": "fd186f535a4ac7ae35d98c1dd5d79f0a81b7976d",
"url": null, "url": null,
"hash": "0gb174800sgh6y6sir23nxsx85xrk478hbwqbzyd46ac34clz9wz" "hash": "0jxpqaz12lqibg03iv36sa0shfvamn2yhg937llv3kl4csijd34f"
}, },
"lon": { "lon": {
"type": "Git", "type": "Git",
@ -178,9 +178,9 @@
"url": "https://git.dgnum.eu/DGNum/metis" "url": "https://git.dgnum.eu/DGNum/metis"
}, },
"branch": "master", "branch": "master",
"revision": "ed6fafda45d638b1bafd5deaee098b80156b41e8", "revision": "9eaa1f289751b6b62f700e8e0e0ddbfbaa98c021",
"url": null, "url": null,
"hash": "086spyhn2x1x2h31b0y4an501fdhph1nk64riybqnh6mqjkzlq4m" "hash": "0m9il1lllw59a6l9vwfi1bika7g4pxs20clc48kklpflnk0scb1f"
}, },
"microvm.nix": { "microvm.nix": {
"type": "Git", "type": "Git",
@ -194,20 +194,6 @@
"url": "https://github.com/RaitoBezarius/microvm.nix/archive/49899c9a4fdf75320785e79709bf1608c34caeb8.tar.gz", "url": "https://github.com/RaitoBezarius/microvm.nix/archive/49899c9a4fdf75320785e79709bf1608c34caeb8.tar.gz",
"hash": "0sz6azdpiz4bd36x23bcdhx6mwyqj8zl5cczjgv48xqfmysy8zwy" "hash": "0sz6azdpiz4bd36x23bcdhx6mwyqj8zl5cczjgv48xqfmysy8zwy"
}, },
"nix-actions": {
"type": "GitRelease",
"repository": {
"type": "Git",
"url": "https://git.dgnum.eu/DGNum/nix-actions.git"
},
"pre_releases": false,
"version_upper_bound": null,
"release_prefix": null,
"version": "v0.2.2",
"revision": "b9cb5d6f945d1e3fd7b70d63848c70335e9912e8",
"url": null,
"hash": "0m6bw5qlrchsigx7x4nz3xkcn3dnr14k5j0ws9lbggnldnz9qg2w"
},
"nix-modules": { "nix-modules": {
"type": "Git", "type": "Git",
"repository": { "repository": {
@ -215,9 +201,9 @@
"url": "https://git.hubrecht.ovh/hubrecht/nix-modules.git" "url": "https://git.hubrecht.ovh/hubrecht/nix-modules.git"
}, },
"branch": "main", "branch": "main",
"revision": "75e8d70a051dd19d126b5248b62f61d6f8ce4361", "revision": "2fd7c7810b2a901020ddd2d0cc82810b83a313fc",
"url": null, "url": null,
"hash": "0yx5by3v2cshiidyh27n75lcqy9d1kk5zz5mchmfv63s9p0cjzqn" "hash": "0rag870ll745r5isnk6hlxv0b0sbgriba5k6nihahcwsal2f4830"
}, },
"nix-patches": { "nix-patches": {
"type": "GitRelease", "type": "GitRelease",
@ -240,15 +226,21 @@
"url": "https://git.hubrecht.ovh/hubrecht/nix-pkgs" "url": "https://git.hubrecht.ovh/hubrecht/nix-pkgs"
}, },
"branch": "main", "branch": "main",
"revision": "fe54340f49449f01c2ee489abf7016d97706eb59", "revision": "3e731378f3984313ef902c5e5a49e002e6e2c27e",
"url": null, "url": null,
"hash": "1sv9nqhzcqn8anqfgf63i2j5qcqzyy4vl0a45rvllv7rhbhw9adq" "hash": "1vy2dj9fyy653w6idvi1r73s0nd2a332a1xkppddjip6rk0i030p"
},
"nixos-23.11": {
"type": "Channel",
"name": "nixos-23.11",
"url": "https://releases.nixos.org/nixos/23.11/nixos-23.11.7870.205fd4226592/nixexprs.tar.xz",
"hash": "1mbp7jydzxqgv9w3a8fqggq1x8h3cd0vh9wafri5pls52ngyww47"
}, },
"nixos-24.05": { "nixos-24.05": {
"type": "Channel", "type": "Channel",
"name": "nixos-24.05", "name": "nixos-24.05",
"url": "https://releases.nixos.org/nixos/24.05/nixos-24.05.6668.e8c38b73aeb2/nixexprs.tar.xz", "url": "https://releases.nixos.org/nixos/24.05/nixos-24.05.5518.ecbc1ca8ffd6/nixexprs.tar.xz",
"hash": "0lhh36z3fvd3b64dz7an08y3c3shb67aj17ny9z28bs21i3dc5yh" "hash": "1yr2v17d8jg9567rvadv62bpr6i47fp73by2454yjxh1m9ric2cm"
}, },
"nixos-generators": { "nixos-generators": {
"type": "Git", "type": "Git",
@ -258,21 +250,21 @@
"repo": "nixos-generators" "repo": "nixos-generators"
}, },
"branch": "master", "branch": "master",
"revision": "3280fdde8c8f0276c9f5286ad5c0f433dfa5d56c", "revision": "9ae128172f823956e54947fe471bc6dfa670ecb4",
"url": "https://github.com/nix-community/nixos-generators/archive/3280fdde8c8f0276c9f5286ad5c0f433dfa5d56c.tar.gz", "url": "https://github.com/nix-community/nixos-generators/archive/9ae128172f823956e54947fe471bc6dfa670ecb4.tar.gz",
"hash": "12v6lxls3bfkj20rwxy62l8g6zlkhsp29m6wd7764j1wwfwjk274" "hash": "1zn3lykymimzh21q4fixw6ql42n8j82dqwm5axifhcnl8dsdgrvr"
}, },
"nixos-unstable": { "nixos-unstable": {
"type": "Channel", "type": "Channel",
"name": "nixos-unstable", "name": "nixos-unstable",
"url": "https://releases.nixos.org/nixos/unstable/nixos-25.05beta710087.23e89b7da85c/nixexprs.tar.xz", "url": "https://releases.nixos.org/nixos/unstable/nixos-24.11pre688563.bc947f541ae5/nixexprs.tar.xz",
"hash": "0b695yx17sarr7d3ypb9z6njd0qhiga1682wjxidl053lvx6g33b" "hash": "1jsaxwi128fiach3dj8rdj5agqivsr4sidb8lmdnl7g07fl9x0kj"
}, },
"nixpkgs": { "nixpkgs": {
"type": "Channel", "type": "Channel",
"name": "nixpkgs-unstable", "name": "nixpkgs-unstable",
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-25.05pre709559.5083ec887760/nixexprs.tar.xz", "url": "https://releases.nixos.org/nixpkgs/nixpkgs-24.11pre689466.7d49afd36b55/nixexprs.tar.xz",
"hash": "1z912j1lmrg8zp2hpmmi69dls9zlpvqfvdkvh5xc3x6iqkqwn0cd" "hash": "0r4zb6j8in4dk7gxciapfm49dqbdd0c7ajjzj9iy2xrrj5aj32qp"
}, },
"proxmox-nixos": { "proxmox-nixos": {
"type": "Git", "type": "Git",
@ -282,9 +274,9 @@
"repo": "proxmox-nixos" "repo": "proxmox-nixos"
}, },
"branch": "main", "branch": "main",
"revision": "c6a126238e8f8efc3660b523d314a0074e61fe44", "revision": "7869ffc2e0db36f314fb60f1ab0087b760700b00",
"url": "https://github.com/SaumonNet/proxmox-nixos/archive/c6a126238e8f8efc3660b523d314a0074e61fe44.tar.gz", "url": "https://github.com/SaumonNet/proxmox-nixos/archive/7869ffc2e0db36f314fb60f1ab0087b760700b00.tar.gz",
"hash": "0apinc8iiqsjazlj3nh75m4w5f93fd53xs4nj1s06qay4nq1h49w" "hash": "0cam36s3ar366y41rvihjqghkdjl9a1n1wzym8p2mkar1r9x7haj"
}, },
"signal-irc-bridge": { "signal-irc-bridge": {
"type": "Git", "type": "Git",
@ -304,9 +296,9 @@
"url": "https://git.dgnum.eu/mdebray/stateless-uptime-kuma" "url": "https://git.dgnum.eu/mdebray/stateless-uptime-kuma"
}, },
"branch": "master", "branch": "master",
"revision": "880f444ff7862d6127b051cf1a993ad1585b1652", "revision": "390363e6a977d71a96c53d7f8b252038dfee2e2e",
"url": null, "url": null,
"hash": "166057469hhxnyqbpd7jjlccdmigzch51616n1d5r617xg0y1mwp" "hash": "11vvfxw2sznc155x0xlgl00g6n9sr90xa0b1hr14vchg7gkz46r5"
}, },
"wp4nix": { "wp4nix": {
"type": "Git", "type": "Git",
@ -316,9 +308,9 @@
"server": "https://git.helsinki.tools/" "server": "https://git.helsinki.tools/"
}, },
"branch": "master", "branch": "master",
"revision": "cce6f7961eb99fd56a039623c4d9e561d9a98928", "revision": "4c47608f349dd45e4895e1f61f19ad9e8dfcc0bf",
"url": "https://git.helsinki.tools/api/v4/projects/helsinki-systems%2Fwp4nix/repository/archive.tar.gz?sha=cce6f7961eb99fd56a039623c4d9e561d9a98928", "url": "https://git.helsinki.tools/api/v4/projects/helsinki-systems%2Fwp4nix/repository/archive.tar.gz?sha=4c47608f349dd45e4895e1f61f19ad9e8dfcc0bf",
"hash": "0ggqc92mh4xbsrrdv8j0jl6f3cagwizd93sdl8p8mqpxv9445xrf" "hash": "1pnjhbljihf2ras9lbp1f6izzxghccfygkkf2ikkahjr1vbicdbq"
} }
}, },
"version": 3 "version": 3

View file

@ -1,21 +0,0 @@
diff --git a/pkgs/tools/networking/netbird/default.nix b/pkgs/tools/networking/netbird/default.nix
index 07a1e906dad3..d5799446628b 100644
--- a/pkgs/tools/networking/netbird/default.nix
+++ b/pkgs/tools/networking/netbird/default.nix
@@ -26,6 +26,7 @@ let
} else {
client = "netbird";
management = "netbird-mgmt";
+ relay = "netbird-relay";
signal = "netbird-signal";
};
in
@@ -82,7 +83,7 @@ buildGoModule rec {
(lib.mapAttrsToList
(module: binary: ''
mv $out/bin/${lib.last (lib.splitString "/" module)} $out/bin/${binary}
- '' + lib.optionalString (!ui) ''
+ '' + lib.optionalString (!ui && module != "relay") ''
installShellCompletion --cmd ${binary} \
--bash <($out/bin/${binary} completion bash) \
--fish <($out/bin/${binary} completion fish) \

View file

@ -0,0 +1,54 @@
From 4d6e57d2d577cc105c9e0cd397408e9e3ce85cd0 Mon Sep 17 00:00:00 2001
From: Raito Bezarius <masterancpp@gmail.com>
Date: Tue, 8 Oct 2024 16:33:14 +0200
Subject: [PATCH] fix(packaging): correctness of the build top directory
It was using /build which is an implementation detail and not
guaranteed.
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
---
pkgs/pve-container/default.nix | 6 +++---
pkgs/pve-rs/default.nix | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/pkgs/pve-container/default.nix b/pkgs/pve-container/default.nix
index 445c271..5633c0f 100644
--- a/pkgs/pve-container/default.nix
+++ b/pkgs/pve-container/default.nix
@@ -30,7 +30,7 @@ perl536.pkgs.toPerlModule (
postPatch = ''
sed -i Makefile \
-e "s/pct.1 pct.conf.5 pct.bash-completion pct.zsh-completion //" \
- -e "s,/usr/share/lxc,/build/lxc," \
+ -e "s,/usr/share/lxc,$NIX_BUILD_TOP/lxc," \
-e "/pve-doc-generator/d" \
-e "/PVE_GENERATING_DOCS/d" \
-e "/SERVICEDIR/d" \
@@ -45,8 +45,8 @@ perl536.pkgs.toPerlModule (
dontPatchShebangs = true;
postConfigure = ''
- cp -r ${lxc}/share/lxc /build
- chmod -R +w /build/lxc
+ cp -r ${lxc}/share/lxc $NIX_BUILD_TOP/
+ chmod -R +w $NIX_BUILD_TOP/lxc
'';
makeFlags = [
diff --git a/pkgs/pve-rs/default.nix b/pkgs/pve-rs/default.nix
index c024287..881beab 100644
--- a/pkgs/pve-rs/default.nix
+++ b/pkgs/pve-rs/default.nix
@@ -57,7 +57,7 @@ perl536.pkgs.toPerlModule (
];
makeFlags = [
- "BUILDIR=/build"
+ "BUILDIR=$NIX_BUILD_TOP"
"BUILD_MODE=release"
"DESTDIR=$(out)"
"GITVERSION:=${src.rev}"
--
2.46.0

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