Format repo

This commit is contained in:
Pim Kunis 2024-10-28 16:05:06 +01:00
parent 3169149045
commit 8160b9da0b
37 changed files with 643 additions and 392 deletions

View file

@ -3,7 +3,7 @@
"blog-pim": {
"inputs": {
"flutils": [
"flutils"
"flake-utils"
],
"nginx": "nginx",
"nixpkgs": [
@ -89,7 +89,7 @@
},
"dns_2": {
"inputs": {
"flake-utils": "flake-utils_4",
"flake-utils": "flake-utils_5",
"nixpkgs": [
"servers",
"nixpkgs"
@ -227,6 +227,24 @@
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1726560853,
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_3": {
"inputs": {
"systems": "systems_3"
},
@ -243,7 +261,7 @@
"type": "indirect"
}
},
"flake-utils_3": {
"flake-utils_4": {
"inputs": {
"systems": "systems_4"
},
@ -261,7 +279,7 @@
"type": "github"
}
},
"flake-utils_4": {
"flake-utils_5": {
"locked": {
"lastModified": 1614513358,
"narHash": "sha256-LakhOx3S1dRjnh0b5Dg3mbZyH0ToC9I8Y2wKSkBaTzU=",
@ -276,7 +294,7 @@
"type": "github"
}
},
"flake-utils_5": {
"flake-utils_6": {
"inputs": {
"systems": "systems_7"
},
@ -294,24 +312,6 @@
"type": "github"
}
},
"flutils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1726560853,
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
@ -480,7 +480,7 @@
},
"nixhelm": {
"inputs": {
"flake-utils": "flake-utils_2",
"flake-utils": "flake-utils_3",
"haumea": "haumea",
"nix-kube-generators": "nix-kube-generators",
"nixpkgs": [
@ -675,7 +675,7 @@
},
"poetry2nix": {
"inputs": {
"flake-utils": "flake-utils_3",
"flake-utils": "flake-utils_4",
"nix-github-actions": "nix-github-actions",
"nixpkgs": [
"nixhelm",
@ -725,7 +725,7 @@
"inputs": {
"blog-pim": "blog-pim",
"dns": "dns",
"flutils": "flutils",
"flake-utils": "flake-utils_2",
"kubenix": "kubenix",
"nixhelm": "nixhelm",
"nixng": "nixng",
@ -740,7 +740,7 @@
"deploy-rs": "deploy-rs",
"disko": "disko",
"dns": "dns_2",
"flake-utils": "flake-utils_5",
"flake-utils": "flake-utils_6",
"kubenix": "kubenix_2",
"nix-snapshotter": "nix-snapshotter",
"nixng": "nixng_2",

View file

@ -3,7 +3,7 @@
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flutils.url = "github:numtide/flake-utils";
flake-utils.url = "github:numtide/flake-utils";
treefmt-nix.url = "github:numtide/treefmt-nix";
pre-commit-hooks = {
@ -21,7 +21,7 @@
url = "git+https://git.kun.is/home/blog-pim?rev=7296f7f5bf5f089a5137036dcbd8058cf3e4a9e5";
inputs = {
nixpkgs.follows = "nixpkgs";
flutils.follows = "flutils";
flutils.follows = "flake-utils";
};
};
@ -46,10 +46,11 @@
};
};
outputs = inputs @ {flutils, ...}:
flutils.lib.meld inputs [
outputs = inputs @ {flake-utils, ...}:
flake-utils.lib.meld inputs [
./kubenix.nix
./scripts
./globals.nix
./formatter.nix
];
}

View file

@ -1,5 +1,4 @@
{ servers, ... }:
let
{servers, ...}: let
globals = {
images = {
jellyfin = "jellyfin/jellyfin:10.10.0";
@ -34,7 +33,6 @@ let
minecraft = "itzg/minecraft-server:latest";
};
};
in
{
in {
globals = globals // servers.globals;
}

View file

@ -1,13 +1,17 @@
{ nixpkgs, nglib, ... }:
{
nixpkgs,
nglib,
...
}:
nglib.makeSystem {
inherit nixpkgs;
system = "x86_64-linux";
name = "nixng-attic";
config = { ... }: {
config = {...}: {
dumb-init = {
enable = true;
type.services = { };
type.services = {};
};
init.services.attic = {
@ -22,7 +26,7 @@ nglib.makeSystem {
# This is done because we quote the template for the toml file.
# See: https://github.com/helmfile/vals?tab=readme-ov-file#expression-syntax
# database.url = "ref+sops://secrets.yml#attic/databaseURL+";
database = { };
database = {};
storage = {
type = "local";

View file

@ -1,13 +1,18 @@
{ globals, nixpkgs, nglib, ... }:
{
globals,
nixpkgs,
nglib,
...
}:
nglib.makeSystem {
inherit nixpkgs;
system = "x86_64-linux";
name = "nixng-dnsmasq";
config = { ... }: {
config = {...}: {
dumb-init = {
enable = true;
type.services = { };
type.services = {};
};
init.services.dnsmasq = {

View file

@ -1,15 +1,23 @@
inputs@{ self, servers, flutils, nixpkgs, kubenix, ... }: flutils.lib.eachDefaultSystem
(system:
let
pkgs = nixpkgs.legacyPackages.${system};
lib = pkgs.lib;
deployScript = (pkgs.writeScriptBin "applyset-deploy.sh" (builtins.readFile ./applyset-deploy.sh)).overrideAttrs (old: {
buildCommand = "${old.buildCommand}\npatchShebangs $out";
});
inputs @ {
self,
servers,
flake-utils,
nixpkgs,
kubenix,
...
}:
flake-utils.lib.eachDefaultSystem
(system: let
pkgs = nixpkgs.legacyPackages.${system};
lib = pkgs.lib;
deployScript = (pkgs.writeScriptBin "applyset-deploy.sh" (builtins.readFile ./applyset-deploy.sh)).overrideAttrs (old: {
buildCommand = "${old.buildCommand}\npatchShebangs $out";
});
machines = servers.machines.${system};
machines = servers.machines.${system};
mkKubernetes = name: module: namespace: (kubenix.evalModules.${system} {
mkKubernetes = name: module: namespace:
(kubenix.evalModules.${system} {
specialArgs = {
inherit namespace system machines self;
inherit (inputs) nixhelm blog-pim dns nixpkgs nixng;
@ -22,67 +30,74 @@ inputs@{ self, servers, flutils, nixpkgs, kubenix, ... }: flutils.lib.eachDefaul
};
};
module = { kubenix, ... }:
{
imports = [
kubenix.modules.k8s
kubenix.modules.helm
./modules
module
];
module = {kubenix, ...}: {
imports = [
kubenix.modules.k8s
kubenix.modules.helm
./modules
module
];
config = {
kubenix.project = name;
kubernetes.namespace = namespace;
};
config = {
kubenix.project = name;
kubernetes.namespace = namespace;
};
}).config.kubernetes;
mkManifest = name: { module, namespace }: {
name = "${name}-manifest";
value = (mkKubernetes name module namespace).result;
};
mkDeployApp = name: { module, namespace }:
let
kubernetes = mkKubernetes name module namespace;
kubeconfig = kubernetes.kubeconfig or "";
result = kubernetes.result or "";
wrappedDeployScript = pkgs.symlinkJoin
{
name = "applyset-deploy.sh";
paths = [ deployScript pkgs.vals pkgs.kubectl ];
buildInputs = [ pkgs.makeWrapper ];
passthru.manifest = result;
meta.mainProgram = "applyset-deploy.sh";
postBuild =
let
# HACK: create normal way of checking if server runs k8s
k8sMachines = lib.filterAttrs (n: m: m.kubernetesNodeLabels != null) machines;
k8sServerNames = builtins.concatStringsSep " " (builtins.attrNames k8sMachines);
in
/* bash */ ''
wrapProgram $out/bin/applyset-deploy.sh \
--suffix PATH : "$out/bin" \
--run 'export KUBECONFIG=''${KUBECONFIG:-${toString kubeconfig}}' \
--set MANIFEST '${result}' \
--set NAME '${name}' \
--set NAMESPACE '${namespace}' \
--set SERVERS '${k8sServerNames}' \
--set DYFF '${lib.getExe pkgs.dyff}' \
--set GCROOTDIR '/nix/var/nix/gcroots/kubernetes-manifests'
'';
};
in
{
name = "${name}-deploy";
value = wrappedDeployScript;
};
})
.config
.kubernetes;
deployments = import ./deployments.nix;
in
{
packages = pkgs.lib.mergeAttrs (pkgs.lib.mapAttrs' mkDeployApp deployments) (pkgs.lib.mapAttrs' mkManifest deployments);
})
mkManifest = name: {
module,
namespace,
}: {
name = "${name}-manifest";
value = (mkKubernetes name module namespace).result;
};
mkDeployApp = name: {
module,
namespace,
}: let
kubernetes = mkKubernetes name module namespace;
kubeconfig = kubernetes.kubeconfig or "";
result = kubernetes.result or "";
wrappedDeployScript =
pkgs.symlinkJoin
{
name = "applyset-deploy.sh";
paths = [deployScript pkgs.vals pkgs.kubectl];
buildInputs = [pkgs.makeWrapper];
passthru.manifest = result;
meta.mainProgram = "applyset-deploy.sh";
postBuild = let
# HACK: create normal way of checking if server runs k8s
k8sMachines = lib.filterAttrs (n: m: m.kubernetesNodeLabels != null) machines;
k8sServerNames = builtins.concatStringsSep " " (builtins.attrNames k8sMachines);
in
/*
bash
*/
''
wrapProgram $out/bin/applyset-deploy.sh \
--suffix PATH : "$out/bin" \
--run 'export KUBECONFIG=''${KUBECONFIG:-${toString kubeconfig}}' \
--set MANIFEST '${result}' \
--set NAME '${name}' \
--set NAMESPACE '${namespace}' \
--set SERVERS '${k8sServerNames}' \
--set DYFF '${lib.getExe pkgs.dyff}' \
--set GCROOTDIR '/nix/var/nix/gcroots/kubernetes-manifests'
'';
};
in {
name = "${name}-deploy";
value = wrappedDeployScript;
};
deployments = import ./deployments.nix;
in {
packages = pkgs.lib.mergeAttrs (pkgs.lib.mapAttrs' mkDeployApp deployments) (pkgs.lib.mapAttrs' mkManifest deployments);
})

View file

@ -1,4 +1,11 @@
{ self, utils, lib, config, globals, ... }: {
{
self,
utils,
lib,
config,
globals,
...
}: {
options.attic.enable = lib.mkEnableOption "attic";
config = lib.mkIf config.attic.enable {
@ -50,10 +57,12 @@
};
};
volumeMounts = [{
name = "data";
mountPath = "/var/lib/atticd/storage";
}];
volumeMounts = [
{
name = "data";
mountPath = "/var/lib/atticd/storage";
}
];
};
volumes = {
@ -98,10 +107,12 @@
};
};
volumeMounts = [{
name = "data";
mountPath = "/pgdata";
}];
volumeMounts = [
{
name = "data";
mountPath = "/pgdata";
}
];
};
volumes.data.persistentVolumeClaim.claimName = "database";

View file

@ -1,4 +1,9 @@
{ config, globals, lib, ... }: {
{
config,
globals,
lib,
...
}: {
options.atuin.enable = lib.mkEnableOption "atuin";
config = lib.mkIf config.atuin.enable {
@ -34,7 +39,7 @@
image = globals.images.atuin;
imagePullPolicy = "IfNotPresent";
ports.web.containerPort = 8888;
args = [ "server" "start" ];
args = ["server" "start"];
env = {
ATUIN_HOST.value = "0.0.0.0";
@ -47,10 +52,12 @@
};
};
volumeMounts = [{
name = "data";
mountPath = "/config";
}];
volumeMounts = [
{
name = "data";
mountPath = "/config";
}
];
};
database = {
@ -67,10 +74,12 @@
};
};
volumeMounts = [{
name = "database";
mountPath = "/var/lib/postgresql/data";
}];
volumeMounts = [
{
name = "database";
mountPath = "/var/lib/postgresql/data";
}
];
};
};
};

View file

@ -1,8 +1,12 @@
{ config, lib, globals, dns, ... }:
let
kunisZone = dns.lib.toString "kun.is" (import ./kun.is.zone.nix globals dns);
in
{
config,
lib,
globals,
dns,
...
}: let
kunisZone = dns.lib.toString "kun.is" (import ./kun.is.zone.nix globals dns);
in {
options.bind9.enable = lib.mkEnableOption "bind9";
config = lib.mkIf config.bind9.enable {
@ -54,7 +58,7 @@ in
containers = {
bind9-udp = {
image = globals.images.bind9;
envFrom = [{ configMapRef.name = "bind9-env"; }];
envFrom = [{configMapRef.name = "bind9-env";}];
ports.dns-udp = {
containerPort = 53;
@ -77,7 +81,7 @@ in
bind9-tcp = {
image = globals.images.bind9;
envFrom = [{ configMapRef.name = "bind9-env"; }];
envFrom = [{configMapRef.name = "bind9-env";}];
ports.dns-tcp = {
containerPort = 53;
@ -99,10 +103,12 @@ in
};
};
volumes = [{
name = "config";
configMap.name = "bind9-config";
}];
volumes = [
{
name = "config";
configMap.name = "bind9-config";
}
];
};
};
};
@ -117,7 +123,7 @@ in
spec = {
type = "LoadBalancer";
selector.app = "bind9";
ipFamilies = [ "IPv4" "IPv6" ];
ipFamilies = ["IPv4" "IPv6"];
ipFamilyPolicy = "RequireDualStack";
ports.dns = {
@ -137,7 +143,7 @@ in
spec = {
type = "LoadBalancer";
selector.app = "bind9";
ipFamilies = [ "IPv4" "IPv6" ];
ipFamilies = ["IPv4" "IPv6"];
ipFamilyPolicy = "RequireDualStack";
ports.dns = {

View file

@ -1,4 +1,5 @@
globals: dns: with dns.lib.combinators; {
globals: dns:
with dns.lib.combinators; {
CAA = letsEncrypt "caa@kun.is";
SOA = {
@ -17,36 +18,36 @@ globals: dns: with dns.lib.combinators; {
];
TXT = [
(with spf; soft [ "include:spf.glasnet.nl" ])
(with spf; soft ["include:spf.glasnet.nl"])
];
subdomains = rec {
"*".A = [ globals.routerPublicIPv4 ];
"*".A = [globals.routerPublicIPv4];
ns = {
A = [ globals.routerPublicIPv4 ];
AAAA = [ ];
A = [globals.routerPublicIPv4];
AAAA = [];
};
ns1 = ns;
ns2 = ns;
wg = {
A = [ globals.routerPublicIPv4 ];
AAAA = [ ];
A = [globals.routerPublicIPv4];
AAAA = [];
};
#for SMTP2GO to be able send emails from kun.is domain
em670271 = {
CNAME = [ "return.smtp2go.net." ];
CNAME = ["return.smtp2go.net."];
};
"s670271._domainkey" = {
CNAME = [ "dkim.smtp2go.net." ];
CNAME = ["dkim.smtp2go.net."];
};
link = {
CNAME = [ "track.smtp2go.net." ];
CNAME = ["track.smtp2go.net."];
};
};
}

View file

@ -1,4 +1,9 @@
{ blog-pim, lib, config, ... }: {
{
blog-pim,
lib,
config,
...
}: {
options.blog.enable = lib.mkEnableOption "blog";
config = lib.mkIf config.blog.enable {

View file

@ -1,4 +1,12 @@
{ config, lib, nixhelm, system, globals, machines, ... }: {
{
config,
lib,
nixhelm,
system,
globals,
machines,
...
}: {
options.bootstrap-default.enable = lib.mkEnableOption "bootstrap-default";
config = lib.mkIf config.bootstrap-default.enable {
@ -36,36 +44,35 @@
services.longhorn-frontend.spec.loadBalancerIP = globals.longhornIPv4;
namespaces = {
static-websites = { };
freshrss = { };
radicale = { };
kms = { };
atuin = { };
nextcloud = { };
hedgedoc = { };
kitchenowl = { };
forgejo = { };
paperless = { };
syncthing = { };
immich = { };
attic = { };
inbucket = { };
dns = { };
media = { };
minecraft = { };
tailscale = { };
ntfy = { };
static-websites = {};
freshrss = {};
radicale = {};
kms = {};
atuin = {};
nextcloud = {};
hedgedoc = {};
kitchenowl = {};
forgejo = {};
paperless = {};
syncthing = {};
immich = {};
attic = {};
inbucket = {};
dns = {};
media = {};
minecraft = {};
tailscale = {};
ntfy = {};
};
nodes =
let
machinesWithKubernetesLabels = lib.filterAttrs (name: machine: machine.kubernetesNodeLabels != null) machines;
in
nodes = let
machinesWithKubernetesLabels = lib.filterAttrs (name: machine: machine.kubernetesNodeLabels != null) machines;
in
builtins.mapAttrs
(name: machine: {
metadata.labels = machine.kubernetesNodeLabels;
})
machinesWithKubernetesLabels;
(name: machine: {
metadata.labels = machine.kubernetesNodeLabels;
})
machinesWithKubernetesLabels;
recurringJobs.backup-nfs.spec = {
cron = "0 1 * * *"; # One o'clock at night
@ -74,13 +81,13 @@
concurrency = 1;
};
ipAddressPools.main.spec.addresses = [ "192.168.30.128-192.168.30.200" "2a0d:6e00:1a77:30::2-2a0d:6e00:1a77:30:ffff:ffff:ffff:fffe" ];
l2Advertisements.main.metadata = { };
ipAddressPools.main.spec.addresses = ["192.168.30.128-192.168.30.200" "2a0d:6e00:1a77:30::2-2a0d:6e00:1a77:30:ffff:ffff:ffff:fffe"];
l2Advertisements.main.metadata = {};
persistentVolumes = {
music-syncthing.spec = {
capacity.storage = "1Gi";
accessModes = [ "ReadWriteMany" ];
accessModes = ["ReadWriteMany"];
nfs = {
server = "lewis.dmz";
@ -90,7 +97,7 @@
media-media.spec = {
capacity.storage = "1Gi";
accessModes = [ "ReadWriteMany" ];
accessModes = ["ReadWriteMany"];
nfs = {
server = "lewis.dmz";

View file

@ -1,4 +1,10 @@
{ config, lib, nixhelm, system, ... }: {
{
config,
lib,
nixhelm,
system,
...
}: {
options.bootstrap-kube-system.enable = lib.mkEnableOption "bootstrap-kube-system";
config = lib.mkIf config.bootstrap-kube-system.enable {
@ -29,10 +35,12 @@
server = "https://acme-v02.api.letsencrypt.org/directory";
email = "pim@kunis.nl";
privateKeySecretRef.name = "letsencrypt-private-key";
solvers = [{
selector = { };
http01.ingress.class = "traefik";
}];
solvers = [
{
selector = {};
http01.ingress.class = "traefik";
}
];
};
};
};

View file

@ -1,4 +1,9 @@
{ config, lib, globals, ... }: {
{
config,
lib,
globals,
...
}: {
options.cyberchef.enable = lib.mkEnableOption "cyberchef";
config = lib.mkIf config.cyberchef.enable {

View file

@ -1,4 +1,11 @@
{ self, utils, globals, config, lib, ... }: {
{
self,
utils,
globals,
config,
lib,
...
}: {
options.dnsmasq.enable = lib.mkEnableOption "dnsmasq";
config = lib.mkIf config.dnsmasq.enable {

View file

@ -1,9 +1,14 @@
{ lib, config, globals, ... }: {
{
lib,
config,
globals,
...
}: {
options.forgejo.enable = lib.mkEnableOption "forgejo";
config = lib.mkIf config.forgejo.enable {
kubernetes.resources = {
secrets.forgejo.stringData.config = lib.generators.toINI { } (import ./config.nix);
secrets.forgejo.stringData.config = lib.generators.toINI {} (import ./config.nix);
deployments.server.spec = {
selector.matchLabels.app = "forgejo";

View file

@ -1,4 +1,9 @@
{ config, lib, globals, ... }: {
{
config,
lib,
globals,
...
}: {
options.freshrss.enable = lib.mkEnableOption "freshrss";
config = lib.mkIf config.freshrss.enable {
@ -43,10 +48,12 @@
};
};
volumeMounts = [{
name = "data";
mountPath = "/var/www/FreshRSS/data";
}];
volumeMounts = [
{
name = "data";
mountPath = "/var/www/FreshRSS/data";
}
];
};
volumes.data.persistentVolumeClaim.claimName = "data";

View file

@ -1,9 +1,14 @@
{ config, lib, globals, ... }: {
{
config,
lib,
globals,
...
}: {
options.hedgedoc.enable = lib.mkEnableOption "hedgedoc";
config = lib.mkIf config.hedgedoc.enable {
kubernetes.resources = {
configMaps.hedgedoc-config.data.config = lib.generators.toJSON { } {
configMaps.hedgedoc-config.data.config = lib.generators.toJSON {} {
useSSL = false;
};
@ -106,10 +111,12 @@
};
};
volumeMounts = [{
name = "database";
mountPath = "/pgdata";
}];
volumeMounts = [
{
name = "database";
mountPath = "/pgdata";
}
];
};
volumes.database.persistentVolumeClaim.claimName = "database";

View file

@ -1,4 +1,9 @@
{ globals, config, lib, ... }: {
{
globals,
config,
lib,
...
}: {
options.immich.enable = lib.mkEnableOption "immich";
config = lib.mkIf config.immich.enable {
@ -51,10 +56,12 @@
};
};
volumeMounts = [{
name = "data";
mountPath = "/usr/src/app/upload";
}];
volumeMounts = [
{
name = "data";
mountPath = "/usr/src/app/upload";
}
];
};
};
};
@ -90,10 +97,12 @@
ports.ml.containerPort = 3003;
env.MACHINE_LEARNING_WORKER_TIMEOUT.value = "600";
volumeMounts = [{
name = "cache";
mountPath = "/cache";
}];
volumeMounts = [
{
name = "cache";
mountPath = "/cache";
}
];
};
};
};
@ -157,8 +166,8 @@
containers.postgres = {
image = globals.images.immich-postgres;
imagePullPolicy = "IfNotPresent";
command = [ "postgres" ];
args = [ "-c" "shared_preload_libraries=vectors.so" "-c" "search_path=\"$$user\", public, vectors" "-c" "logging_collector=on" "-c" "max_wal_size=2GB" "-c" "shared_buffers=512MB" "-c" "wal_compression=on" ];
command = ["postgres"];
args = ["-c" "shared_preload_libraries=vectors.so" "-c" "search_path=\"$$user\", public, vectors" "-c" "logging_collector=on" "-c" "max_wal_size=2GB" "-c" "shared_buffers=512MB" "-c" "wal_compression=on"];
ports.postgres.containerPort = 5432;
securityContext.runAsUser = 999;
securityContext.runAsGroup = 999;
@ -175,10 +184,12 @@
};
};
volumeMounts = [{
name = "data";
mountPath = "/pgdata";
}];
volumeMounts = [
{
name = "data";
mountPath = "/pgdata";
}
];
};
};
};
@ -239,7 +250,7 @@
};
persistentVolumeClaims.cache.spec = {
accessModes = [ "ReadWriteOnce" ];
accessModes = ["ReadWriteOnce"];
resources.requests.storage = "5Gi";
};
};

View file

@ -1,9 +1,14 @@
{ globals, config, lib, ... }: {
{
globals,
config,
lib,
...
}: {
options.inbucket.enable = lib.mkEnableOption "inbucket";
config = lib.mkIf config.inbucket.enable {
kubernetes.resources = {
serviceAccounts.inbucket = { };
serviceAccounts.inbucket = {};
deployments.inbucket.spec = {
selector.matchLabels.app = "inbucket";

View file

@ -1,6 +1,9 @@
{ lib, config, ... }:
let
ingressOpts = { name, ... }: {
{
lib,
config,
...
}: let
ingressOpts = {name, ...}: {
options = {
host = lib.mkOption {
type = lib.types.str;
@ -22,17 +25,17 @@ let
};
};
};
in
{
in {
options = {
lab.ingresses = lib.mkOption {
type = with lib.types; attrsOf (submodule ingressOpts);
default = { };
default = {};
};
};
config = {
kubernetes.resources.ingresses = builtins.mapAttrs
kubernetes.resources.ingresses =
builtins.mapAttrs
(name: ingress: {
metadata.annotations = {
"cert-manager.io/cluster-issuer" = "letsencrypt";
@ -42,24 +45,30 @@ in
spec = {
ingressClassName = "traefik";
rules = [{
host = ingress.host;
rules = [
{
host = ingress.host;
http.paths = [{
path = "/";
pathType = "Prefix";
http.paths = [
{
path = "/";
pathType = "Prefix";
backend.service = {
name = ingress.service.name;
port.name = ingress.service.portName;
};
}];
}];
backend.service = {
name = ingress.service.name;
port.name = ingress.service.portName;
};
}
];
}
];
tls = [{
secretName = "${name}-tls";
hosts = [ ingress.host ];
}];
tls = [
{
secretName = "${name}-tls";
hosts = [ingress.host];
}
];
};
})
config.lab.ingresses;

View file

@ -1,4 +1,9 @@
{ lib, globals, config, ... }: {
{
lib,
globals,
config,
...
}: {
options.kitchenowl.enable = lib.mkEnableOption "kitchenowl";
config = lib.mkIf config.kitchenowl.enable {
@ -33,10 +38,12 @@
key = "jwtSecretKey";
};
volumeMounts = [{
name = "data";
mountPath = "/data";
}];
volumeMounts = [
{
name = "data";
mountPath = "/data";
}
];
};
securityContext = {

View file

@ -1,4 +1,9 @@
{ config, globals, lib, ... }: {
{
config,
globals,
lib,
...
}: {
options.kms.enable = lib.mkEnableOption "kms";
config = lib.mkIf config.kms.enable {

View file

@ -1,6 +1,9 @@
{ lib, config, ... }:
let
longhornVolumeOpts = { name, ... }: {
{
lib,
config,
...
}: let
longhornVolumeOpts = {name, ...}: {
options = {
storage = lib.mkOption {
type = lib.types.str;
@ -13,7 +16,7 @@ let
};
};
longhornPVOpts = { name, ... }: {
longhornPVOpts = {name, ...}: {
options = {
storage = lib.mkOption {
type = lib.types.str;
@ -21,7 +24,7 @@ let
};
};
longhornPVCOpts = { name, ... }: {
longhornPVCOpts = {name, ...}: {
options = {
volumeName = lib.mkOption {
type = lib.types.str;
@ -34,34 +37,34 @@ let
};
};
};
in
{
in {
options = {
lab.longhornVolumes = lib.mkOption {
type = with lib.types; attrsOf (submodule longhornVolumeOpts);
default = { };
default = {};
};
lab.longhorn = {
persistentVolume = lib.mkOption {
type = with lib.types; attrsOf (submodule longhornPVOpts);
default = { };
default = {};
};
persistentVolumeClaim = lib.mkOption {
type = with lib.types; attrsOf (submodule longhornPVCOpts);
default = { };
default = {};
};
};
};
config = {
kubernetes.resources = {
persistentVolumes = lib.mergeAttrs
persistentVolumes =
lib.mergeAttrs
(builtins.mapAttrs
(name: longhornVolume: {
spec = {
accessModes = [ "ReadWriteOnce" ];
accessModes = ["ReadWriteOnce"];
capacity.storage = longhornVolume.storage;
persistentVolumeReclaimPolicy = "Delete";
volumeMode = "Filesystem";
@ -84,10 +87,12 @@ in
staleReplicaTimeout = "30";
unmapMarkSnapChainRemoved = "ignored";
recurringJobSelector = lib.generators.toYAML { } [{
name = "backup-nfs";
isGroup = false;
}];
recurringJobSelector = lib.generators.toYAML {} [
{
name = "backup-nfs";
isGroup = false;
}
];
};
};
};
@ -96,7 +101,7 @@ in
(builtins.mapAttrs
(name: longhornPV: {
spec = {
accessModes = [ "ReadWriteOnce" ];
accessModes = ["ReadWriteOnce"];
capacity.storage = longhornPV.storage;
persistentVolumeReclaimPolicy = "Delete";
volumeMode = "Filesystem";
@ -114,21 +119,24 @@ in
staleReplicaTimeout = "30";
unmapMarkSnapChainRemoved = "ignored";
recurringJobSelector = lib.generators.toYAML { } [{
name = "backup-nfs";
isGroup = false;
}];
recurringJobSelector = lib.generators.toYAML {} [
{
name = "backup-nfs";
isGroup = false;
}
];
};
};
};
})
config.lab.longhorn.persistentVolume);
persistentVolumeClaims = lib.mergeAttrs
persistentVolumeClaims =
lib.mergeAttrs
(builtins.mapAttrs
(name: longhornVolume: {
spec = {
accessModes = [ "ReadWriteOnce" ];
accessModes = ["ReadWriteOnce"];
resources.requests.storage = longhornVolume.storage;
storageClassName = "";
};
@ -137,7 +145,7 @@ in
(builtins.mapAttrs
(name: longhornPVC: {
spec = {
accessModes = [ "ReadWriteOnce" ];
accessModes = ["ReadWriteOnce"];
resources.requests.storage = longhornPVC.storage;
storageClassName = "";
volumeName = longhornPVC.volumeName;

View file

@ -1,4 +1,9 @@
{ globals, config, lib, ... }: {
{
globals,
config,
lib,
...
}: {
options.media.enable = lib.mkEnableOption "media";
config = lib.mkIf config.media.enable {
@ -64,13 +69,17 @@
fsGroupChangePolicy = "OnRootMismatch";
};
affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms = [{
matchExpressions = [{
key = "hasMedia";
operator = "In";
values = [ "true" ];
}];
}];
affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms = [
{
matchExpressions = [
{
key = "hasMedia";
operator = "In";
values = ["true"];
}
];
}
];
};
};
};
@ -167,10 +176,12 @@
TZ.value = "Europe/Amsterdam";
};
volumeMounts = [{
name = "config";
mountPath = "/app/config";
}];
volumeMounts = [
{
name = "config";
mountPath = "/app/config";
}
];
};
securityContext = {
@ -274,10 +285,12 @@
TZ.value = "Europe/Amsterdam";
};
volumeMounts = [{
name = "config";
mountPath = "/config";
}];
volumeMounts = [
{
name = "config";
mountPath = "/config";
}
];
};
securityContext = {
@ -518,12 +531,12 @@
persistentVolumeClaims = {
jellyfin-cache.spec = {
accessModes = [ "ReadWriteOnce" ];
accessModes = ["ReadWriteOnce"];
resources.requests.storage = "20Gi";
};
media.spec = {
accessModes = [ "ReadWriteMany" ];
accessModes = ["ReadWriteMany"];
storageClassName = "";
resources.requests.storage = "1Mi";
volumeName = "media-media";

View file

@ -1,4 +1,9 @@
{ lib, config, globals, ... }: {
{
lib,
config,
globals,
...
}: {
options.minecraft.enable = lib.mkEnableOption "minecraft";
config = lib.mkIf config.minecraft.enable {
@ -18,10 +23,12 @@
env.EULA.value = "TRUE";
volumeMounts = [{
name = "data";
mountPath = "/data";
}];
volumeMounts = [
{
name = "data";
mountPath = "/data";
}
];
};
securityContext = {

View file

@ -1,4 +1,9 @@
{ lib, config, globals, ... }: {
{
lib,
config,
globals,
...
}: {
options.nextcloud.enable = lib.mkEnableOption "nextcloud";
config = lib.mkIf config.nextcloud.enable {
@ -45,10 +50,12 @@
};
};
volumeMounts = [{
name = "data";
mountPath = "/var/www/html";
}];
volumeMounts = [
{
name = "data";
mountPath = "/var/www/html";
}
];
};
securityContext = {
@ -56,14 +63,18 @@
fsGroupChangePolicy = "OnRootMismatch";
};
affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution = [{
weight = 1;
preference.matchExpressions = [{
key = "storageType";
operator = "In";
values = [ "fast" ];
}];
}];
affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution = [
{
weight = 1;
preference.matchExpressions = [
{
key = "storageType";
operator = "In";
values = ["fast"];
}
];
}
];
};
};
};
@ -97,10 +108,12 @@
};
};
volumeMounts = [{
name = "database";
mountPath = "/pgdata";
}];
volumeMounts = [
{
name = "database";
mountPath = "/pgdata";
}
];
};
volumes.database.persistentVolumeClaim.claimName = "database";

View file

@ -1,9 +1,14 @@
{ lib, config, globals, ... }: {
{
lib,
config,
globals,
...
}: {
options.ntfy.enable = lib.mkEnableOption "ntfy";
config = lib.mkIf config.ntfy.enable {
kubernetes.resources = {
configMaps.ntfy.data.config = lib.generators.toYAML { } {
configMaps.ntfy.data.config = lib.generators.toYAML {} {
base-url = "https://ntfy.kun.is";
cache-file = "/var/cache/ntfy/cache.db";
cache-duration = "14d";
@ -35,7 +40,7 @@
image = globals.images.ntfy;
ports.web.containerPort = 80;
env.TZ.value = "Europe/Amsterdam";
args = [ "serve" ];
args = ["serve"];
volumeMounts = [
{
@ -70,12 +75,12 @@
persistentVolumeClaims = {
cache.spec = {
accessModes = [ "ReadWriteOnce" ];
accessModes = ["ReadWriteOnce"];
resources.requests.storage = "300Mi";
};
attachment-cache.spec = {
accessModes = [ "ReadWriteOnce" ];
accessModes = ["ReadWriteOnce"];
resources.requests.storage = "500Mi";
};
};

View file

@ -1,4 +1,9 @@
{ globals, lib, config, ... }: {
{
globals,
lib,
config,
...
}: {
options.paperless.enable = lib.mkEnableOption "paperless";
config = lib.mkIf config.paperless.enable {
@ -64,10 +69,12 @@
};
};
volumeMounts = [{
name = "data";
mountPath = "/data";
}];
volumeMounts = [
{
name = "data";
mountPath = "/data";
}
];
};
securityContext = {
@ -107,10 +114,12 @@
ports.redis.containerPort = 6379;
imagePullPolicy = "IfNotPresent";
volumeMounts = [{
name = "data";
mountPath = "/data";
}];
volumeMounts = [
{
name = "data";
mountPath = "/data";
}
];
};
securityContext = {
@ -159,10 +168,12 @@
};
};
volumeMounts = [{
name = "data";
mountPath = "/pgdata";
}];
volumeMounts = [
{
name = "data";
mountPath = "/pgdata";
}
];
};
volumes.data.persistentVolumeClaim.claimName = "database";

View file

@ -1,4 +1,9 @@
{ globals, config, lib, ... }: {
{
globals,
config,
lib,
...
}: {
options.pihole.enable = lib.mkEnableOption "pihole";
config = lib.mkIf config.pihole.enable {

View file

@ -1,4 +1,9 @@
{ config, lib, globals, ... }: {
{
config,
lib,
globals,
...
}: {
options.radicale.enable = lib.mkEnableOption "radicale";
config = lib.mkIf config.radicale.enable {
@ -6,7 +11,7 @@
configMaps.server.data = {
users = "pim:$apr1$GUiTihkS$dDCkaUxFx/O86m6NCy/yQ.";
config = lib.generators.toINI { } {
config = lib.generators.toINI {} {
server = {
hosts = "0.0.0.0:5232, [::]:5232";
ssl = false;
@ -31,8 +36,8 @@
filesystem_folder = "/data";
};
logging = { };
headers = { };
logging = {};
headers = {};
};
};

View file

@ -1,9 +1,14 @@
{ globals, config, lib, ... }: {
{
globals,
config,
lib,
...
}: {
options.syncthing.enable = lib.mkEnableOption "syncthing";
config = lib.mkIf config.syncthing.enable {
kubernetes.resources = {
serviceAccounts.syncthing = { };
serviceAccounts.syncthing = {};
deployments.syncthing.spec = {
selector.matchLabels.app = "syncthing";
@ -71,7 +76,7 @@
};
persistentVolumeClaims.music.spec = {
accessModes = [ "ReadWriteMany" ];
accessModes = ["ReadWriteMany"];
storageClassName = "";
resources.requests.storage = "1Mi";
volumeName = "music-syncthing";

View file

@ -1,12 +1,16 @@
{ lib, config, ... }: {
{
lib,
config,
...
}: {
options = with lib.types; {
lab.tailscaleIngresses = lib.mkOption {
type = attrsOf (submodule {
options = {
host = lib.mkOption { type = str; };
host = lib.mkOption {type = str;};
service = {
name = lib.mkOption { type = str; };
name = lib.mkOption {type = str;};
portName = lib.mkOption {
type = str;
@ -16,37 +20,44 @@
};
});
default = { };
default = {};
};
};
config =
let
cfg = config.lab.tailscaleIngresses;
config = let
cfg = config.lab.tailscaleIngresses;
mkTailscaleIngress = name: { host, service }: {
spec = {
ingressClassName = "tailscale";
mkTailscaleIngress = name: {
host,
service,
}: {
spec = {
ingressClassName = "tailscale";
rules = [{
http.paths = [{
path = "/";
pathType = "Prefix";
rules = [
{
http.paths = [
{
path = "/";
pathType = "Prefix";
backend.service = {
name = service.name;
port.name = service.portName;
};
}];
}];
backend.service = {
name = service.name;
port.name = service.portName;
};
}
];
}
];
tls = [{
hosts = [ host ];
}];
};
tls = [
{
hosts = [host];
}
];
};
in
{
kubernetes.resources.ingresses = builtins.mapAttrs mkTailscaleIngress cfg;
};
in {
kubernetes.resources.ingresses = builtins.mapAttrs mkTailscaleIngress cfg;
};
}

View file

@ -1,4 +1,10 @@
{ nixhelm, system, config, lib, ... }: {
{
nixhelm,
system,
config,
lib,
...
}: {
options.tailscale.enable = lib.mkEnableOption "tailscale";
config = lib.mkIf config.tailscale.enable {

View file

@ -1,4 +1,9 @@
{ lib, globals, config, ... }: {
{
lib,
globals,
config,
...
}: {
options.traefik.enable = lib.mkEnableOption "traefik";
config = lib.mkIf config.traefik.enable {
@ -8,7 +13,7 @@
# Override Traefik's service with a static load balancer IP.
# Create endpoint for HTTPS on port 444.
# Allow external name services for servers in LAN.
spec.valuesContent = lib.generators.toYAML { } {
spec.valuesContent = lib.generators.toYAML {} {
providers.kubernetesIngress.allowExternalNameServices = true;
service.loadBalancerIP = globals.traefikIPv4;
@ -23,7 +28,7 @@
enabled = true;
options = "";
certResolver = "";
domains = [ ];
domains = [];
};
};

View file

@ -1,23 +1,31 @@
{ nixpkgs, flutils, ... }: flutils.lib.eachDefaultSystem (system:
let
{
nixpkgs,
flake-utils,
...
}:
flake-utils.lib.eachDefaultSystem (system: let
pkgs = nixpkgs.legacyPackages.${system};
createScript = { name, runtimeInputs, scriptPath, extraWrapperFlags ? "", ... }:
let
script = (pkgs.writeScriptBin name (builtins.readFile scriptPath)).overrideAttrs (old: {
buildCommand = "${old.buildCommand}\n patchShebangs $out";
});
in
createScript = {
name,
runtimeInputs,
scriptPath,
extraWrapperFlags ? "",
...
}: let
script = (pkgs.writeScriptBin name (builtins.readFile scriptPath)).overrideAttrs (old: {
buildCommand = "${old.buildCommand}\n patchShebangs $out";
});
in
pkgs.symlinkJoin {
inherit name;
paths = [ script ] ++ runtimeInputs;
buildInputs = [ pkgs.makeWrapper ];
paths = [script] ++ runtimeInputs;
buildInputs = [pkgs.makeWrapper];
postBuild = "wrapProgram $out/bin/${name} --set PATH $out/bin ${extraWrapperFlags}";
};
in
{
in {
packages.gen-k3s-cert = createScript {
name = "create-k3s-cert";
runtimeInputs = with pkgs; [ openssl coreutils openssh yq ];
runtimeInputs = with pkgs; [openssl coreutils openssh yq];
scriptPath = ./gen-k3s-cert.sh;
};
})

View file

@ -1,11 +1,22 @@
{ pkgs, nixpkgs, nixng, globals, ... }: {
mkNixNGImage = name: file:
let
stream = (import file {
{
pkgs,
nixpkgs,
nixng,
globals,
...
}: {
mkNixNGImage = name: file: let
stream =
(import file {
inherit nixpkgs nixng globals;
inherit (nixng) nglib;
}).config.system.build.ociImage.stream;
in
})
.config
.system
.build
.ociImage
.stream;
in
pkgs.stdenv.mkDerivation {
name = "${name}.tar";
src = stream;