chore: some cleaning + logging implementation

This commit is contained in:
Xavier Morel
2025-10-23 20:44:12 +02:00
parent c542509c2f
commit 0d343b12a3
10 changed files with 149 additions and 48 deletions

View File

@@ -13,13 +13,13 @@ My main objective was to have a "light" definition for the containers and to be
# Usage # Usage
## Prepare the infra constants ## Prepare the infra constants
- `cp infra/constants.nix.template infra/constants.nix` - `cp lib/constants.nix.template lib/constants.nix`
- adapt `infra/constants.nix` to match your needs - adapt `lib/constants.nix` to match your needs
- touch `infra/ips.nix` - touch `lib/ips.nix`
- remove both these files from `.gitignore` and `git add` them. - remove both these files from `.gitignore` and `git add` them.
## Build NixOS template ## Build NixOS template
- modify `infra/lxc-template.nix` as needed - modify `lib/lxc-template.nix` as needed
- run `build-template` - run `build-template`
- template available in `nixos-template/tarball/` - template available in `nixos-template/tarball/`
(.tar.xz to be uploaded to Proxmox) (.tar.xz to be uploaded to Proxmox)
@@ -34,19 +34,19 @@ TODO Script the Proxmox Template upload if possible.
- run `tofu init` - run `tofu init`
## Adapt NixOS / Terraform modules building ## Adapt NixOS / Terraform modules building
- edit `lib/containers.nix` to change how a container definition is translated to TF / NixOS config (in particular check the template name) - edit `lib/container_build.nix` to change how a container definition is translated to TF / NixOS config (in particular check the template name)
## Create containers definitions ## Create containers definitions
- `cp containers/lxc-cont.nix.template containers/lxc-#NAME#.nix` - run `add-lxc [name] [id]`
- edit `containers/lxc-#NAME#.nix` as needed - edit `lxc/#NAME#.nix` as needed
- run `build-terraform-json` - run `build-terraform-json`
- run `tofu plan` and review the plan - run `tofu plan` and review the plan
- run `tofu apply`, hopefully without errors - run `tofu apply`, hopefully without errors
- run `deploy #NAME#` - run `deploy-lxc #NAME#`
## Update container ## Update container
- edit `containers/lxc-#NAME#.nix` as needed - edit `lxc/#NAME#.nix` as needed
- if the container specs have changed, do all as above - if the container specs have changed, do all as above
- otherwise you can just run `deploy #NAME#` - otherwise you can just run `deploy-lxc #NAME#`

View File

@@ -1,13 +1,13 @@
{ def, ... }: { def, lib, ... }:
let let
infra = import ../infra/constants.nix; infra = import ./constants.nix;
hostname = def.hostname; hostname = def.hostname;
memory = def.memory or 512; memory = def.memory or 512;
cores = def.cores or 1; cores = def.cores or 1;
container_id = def.container_id; container_id = def.container_id;
disk = def.disk or "4G"; disk = def.disk or "4G";
swap = def.swap or null; # TODO: Implement swap = def.swap or 512;
services = def.services or { }; services = def.services or { };
open_ports = def.open_ports or [ ]; open_ports = def.open_ports or [ ];
other_packages = def.other_packages or [ ]; other_packages = def.other_packages or [ ];
@@ -18,6 +18,7 @@ let
template = def.template or infra.nixos_template_name; template = def.template or infra.nixos_template_name;
unprivileged = def.unprivileged or true; unprivileged = def.unprivileged or true;
tags = def.tags or ""; tags = def.tags or "";
additional_tf_modules = def.additional_tf_modules or [ ];
in in
{ {
terraformResource = { terraformResource = {
@@ -40,30 +41,41 @@ in
storage = "local-lvm"; storage = "local-lvm";
size = disk; size = disk;
}; };
swap = swap;
vmid = container_id; vmid = container_id;
tags = "terraform;${tags}"; tags = "terraform;${tags}";
}; }; # // each additional_tf_modules ?
nixosModule = nixosModule =
{ config, pkgs, ... }: { config, pkgs, ... }:
{ {
imports = [ imports = [
../infra/lxc-template.nix ./lxc-template.nix
] ]
++ extraModules; ++ extraModules;
networking.hostName = hostname; networking.hostName = hostname;
networking.firewall.allowedTCPPorts = open_ports; networking.firewall.allowedTCPPorts = open_ports;
services = services; services =
environment.etc = etc; services
// lib.optionalAttrs (logging_enabled) {
alloy = {
enable = true;
extraFlags = [
"--server.http.listen-addr=0.0.0.0:12345"
"--disable-reporting"
];
};
};
environment.etc =
etc
// lib.optionalAttrs (logging_enabled) {
"alloy/config.alloy".text = (import ./config/alloy/config.alloy.nix).out;
"alloy/metrics.alloy".text =
if (logging_metrics_enabled) then
(import ./config/alloy/metrics.alloy.nix { inherit container_id; }).out
else
"";
};
environment.systemPackages = other_packages; environment.systemPackages = other_packages;
# logging things...
# # logs configuration ...
# # environment.etc."alloy/config.alloy" = '' loki blabla '';
# # environment.etc."alloy/metrics.alloy" = '' prometheus blabla '';
# #
# # -> services.alloy.extraFlags = [
# # "--server.http.listen-addr=127.0.0.1:12346"
# # "--disable-reporting"
# # ]
}; };
} }

View File

@@ -29,13 +29,13 @@
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
lib = pkgs.lib; lib = pkgs.lib;
containersMapping = import ./infra/ips.nix; containersMapping = import ./lib/ips.nix;
containers = import ./lxc { inherit pkgs containersMapping; }; containers = import ./lxc { inherit pkgs containersMapping; };
lxc-def = import ./infra/lxc-template.nix; lxc-def = import ./lib/lxc-template.nix;
infra = import ./infra/constants.nix; infra = import ./lib/constants.nix;
nixosConfigurations = lib.mapAttrs ( nixosConfigurations = lib.mapAttrs (
_: def: _: def:
@@ -45,7 +45,7 @@
} }
) containers; ) containers;
terraformCfg = import ./infra; terraformCfg = import ./lib/infra.nix;
terraformResources = { terraformResources = {
resource.proxmox_lxc = lib.mapAttrs (_: def: def.terraformResource) containers; resource.proxmox_lxc = lib.mapAttrs (_: def: def.terraformResource) containers;
@@ -93,19 +93,19 @@
if ! [[ "$2" =~ ^[0-9]+$ ]]; then if ! [[ "$2" =~ ^[0-9]+$ ]]; then
echo "Error: invalid container ID '$2', should be a number" && exit echo "Error: invalid container ID '$2', should be a number" && exit
fi fi
if ! [ -f infra/ips.nix ]; then if ! [ -f lib/ips.nix ]; then
echo "{" > infra/ips.nix echo "{" > lib/ips.nix
echo "}" >> infra/ips.nix echo "}" >> lib/ips.nix
fi fi
if ! [[ -z "`grep "[^0-9]$2[^0-9]" infra/ips.nix`" ]]; then if ! [[ -z "`grep "[^0-9]$2[^0-9]" lib/ips.nix`" ]]; then
echo "Error: container ID '$2' already used" && exit echo "Error: container ID '$2' already used" && exit
fi fi
if [ -f lxc/$1.nix ]; then if [ -f lxc/$1.nix ]; then
echo "Error: container definition '$1' already exists" && exit echo "Error: container definition '$1' already exists" && exit
fi fi
sed -i "s#}# $1 = $2;#" infra/ips.nix sed -i "s#}# $1 = $2;#" lib/ips.nix
echo "}" >> infra/ips.nix echo "}" >> lib/ips.nix
cp lxc/container.nix.template lxc/$1.nix cp lib/container.nix.template lxc/$1.nix
git add lxc/$1.nix git add lxc/$1.nix
echo "Entry added to infra/ips.nix" echo "Entry added to infra/ips.nix"
echo "Container template copied to lxc/$1.nix, please edit it" echo "Container template copied to lxc/$1.nix, please edit it"
@@ -113,7 +113,8 @@
scripts.deploy-lxc.exec = '' scripts.deploy-lxc.exec = ''
if [ -f lxc/$1.nix ]; then if [ -f lxc/$1.nix ]; then
CONTID=`grep -E "$1 ?=" infra/ips.nix | cut -d '=' -f 2 | grep -o '\<[0-9]*\>' ` CONTID=`grep -E "$1 ?=" lib/ips.nix | cut -d '=' -f 2 | grep -o '\<[0-9]*\>' `
# TODO Verify mapping exists...
echo "Redeploying LXC on container '$1' ('$CONTID')" echo "Redeploying LXC on container '$1' ('$CONTID')"
nixos-rebuild switch --flake .#$1 --target-host root@${infra.ip_prefix}$CONTID nixos-rebuild switch --flake .#$1 --target-host root@${infra.ip_prefix}$CONTID
echo "Done." echo "Done."

View File

@@ -0,0 +1,15 @@
let
infra = import ../../constants.nix;
in
{
out = ''
logging {
level = "warning"
}
loki.write "grafana_loki" {
endpoint {
url = "http://${infra.loki_addr}/loki/api/v1/push"
}
}
'';
}

View File

@@ -0,0 +1,47 @@
{ container_id, ... }:
let
infra = import ../../constants.nix;
in
{
out = ''
prometheus.exporter.unix "default" {
include_exporter_metrics = true
disable_collectors = ["mdadm"]
}
prometheus.scrape "default" {
targets = array.concat(
prometheus.exporter.unix.default.targets,
[{
// Self-collect metrics
job = "alloy",
__address__ = "127.0.0.1:12345",
}],
)
forward_to = [prometheus.relabel.filter_metrics.receiver]
scrape_interval = "60s"
}
prometheus.relabel "filter_metrics" {
rule {
action = "drop"
source_labels = [ "env" ]
regex = "dev"
}
rule {
action = "replace"
regex = "127\\.0\\.0\\.1"
target_label = "instance"
replacement = "${infra.build_ip container_id}"
}
forward_to = [prometheus.remote_write.metrics_service.receiver]
}
prometheus.remote_write "metrics_service" {
endpoint {
url = "http://${infra.prometheus_addr}/api/v1/write"
}
}
'';
}

View File

@@ -1,14 +1,28 @@
let
ip_prefix = "10.0.0.";
in
{ {
# Centralizes the IP to the gateway for the containers. # Centralizes the IP to the gateway for the containers.
gateway_ip = "10.0.0.1"; gateway_ip = "10.0.0.1";
# Builders for IP addresses, given a container id. # Builders for IP addresses, given a container id.
ip_prefix = "10.0.0."; ip_prefix = ip_prefix;
cidr = "24"; cidr = "24";
build_ip = id: "${ip_prefix}${toString id}"; build_ip = id: "${ip_prefix}${toString id}";
build_ip_cidr = id: "${ip_prefix}${toString id}/${cidr}"; build_ip_cidr = id: "${ip_prefix}${toString id}/${cidr}";
loki_addr = "10.0.0.42:3100";
prometheus_addr = "10.0.0.42:9090";
reverse_proxy_addr = "10.0.0.50";
domains = {
exposed = ".mydomain.tld";
internal = ".local";
};
# Your deployer's host # Your deployer's host
master_login = "admin";
master_htpasswd = "$2$10$pouet.pouet";
master_public_ssh_key = "ssh-ed25519 [...] me@here"; master_public_ssh_key = "ssh-ed25519 [...] me@here";
# Default timezone for the containers # Default timezone for the containers

View File

@@ -1,6 +1,6 @@
{ pkgs, containersMapping, ... }: { pkgs, containersMapping, ... }:
let let
infra = import ../infra/constants.nix; infra = import ../lib/constants.nix;
in in
{ {
# OPTIONAL int cores: number of CPU (default = 1) # OPTIONAL int cores: number of CPU (default = 1)
@@ -38,4 +38,20 @@ in
# OPTIONAL bool logging.metrics.enable: whether to enable the Alloy metrics configuration (=> Prometheus) # OPTIONAL bool logging.metrics.enable: whether to enable the Alloy metrics configuration (=> Prometheus)
logging.metrics.enable = true; logging.metrics.enable = true;
# OPTIONAL string template: template file to use (default defined in infra/constants.nix)
template = null;
# OPTIONAL bool unprivileged: whether the container should be unprivileged (default true)
unprivileged = true;
# OPTIONAL string tags: ';'-separated tags, appended to "terraform" (default empty)
tags = "";
# OPTIONAL list of paths additional_tf_modules: list of modules to merge into the tf ressource module (default [])
# Not implemented
additional_tf_modules = [];
# OPTIONAL bool exposed: whether this host should be exposed by the reverse proxy.
exposed = false;
} }

View File

@@ -25,11 +25,6 @@ in
coreutils coreutils
]; ];
services.openssh.enable = true; services.openssh.enable = true;
services.chrony = {
enable = true;
enableNTS = true;
servers = [ "time.cloudflare.com" ];
};
nix.settings = { nix.settings = {
experimental-features = [ experimental-features = [
"nix-command" "nix-command"
@@ -49,6 +44,7 @@ in
openssh.authorizedKeys.keys = [ openssh.authorizedKeys.keys = [
infra.master_public_ssh_key infra.master_public_ssh_key
]; ];
initialPassword = "nixos";
}; };
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";

View File

@@ -2,7 +2,7 @@
let let
lib = pkgs.lib; lib = pkgs.lib;
containerBuild = import ../lib/containers.nix; containerBuild = import ../lib/container_build.nix;
containersFiles = builtins.readDir ./.; containersFiles = builtins.readDir ./.;
@@ -10,7 +10,7 @@ let
lib.mapAttrs ( lib.mapAttrs (
name: type: name: type:
if type == "regular" && name != "default.nix" && lib.hasSuffix ".nix" name then if type == "regular" && name != "default.nix" && lib.hasSuffix ".nix" name then
import ./${name} { inherit containersMapping pkgs; } import ./${name} { inherit name containersMapping pkgs; }
else else
null null
) containersFiles ) containersFiles
@@ -26,7 +26,7 @@ let
hostname = hostname; hostname = hostname;
container_id = containersMapping.${hostname}; container_id = containersMapping.${hostname};
}; };
result = containerBuild { inherit def; }; result = containerBuild { inherit def lib; };
in in
{ {
name = hostname; name = hostname;