refactor: separate framework from production environment
- Create nixos-infra-framework repo with reusable modules, lib, pkgs, overlays, scripts, and a sample environment - Restructure private repo: move hosts/, network/, secrets/, users/ into environments/production/ - Update all host configs to import from framework repo via fetchGit - Update deploy.sh with --environment flag (default: production) - Create hypervisor inventory records (Proxmox, non-NixOS) - Add environment entry point: environments/production/configuration.nix - Remove duplicated technical components (now in framework repo)
This commit is contained in:
+40
-4
@@ -1,5 +1,41 @@
|
|||||||
# nixos-infra
|
# nixos-infra — Private environments
|
||||||
|
|
||||||
Central infrastructure-as-code repository for the NixOS fleet (servers and
|
This repository contains **environment-specific declarations** (hosts, network
|
||||||
workstations). Reproductible deployments via NixOS, agenix for secrets,
|
layout, secrets, users) for the NixOS fleet. Reusable technical components
|
||||||
Proxmox for hypervision. See `../README.md` for an overview.
|
(modules, lib, pkgs, scripts) live in the **public framework repository**:
|
||||||
|
|
||||||
|
→ `nixos-infra-framework` (ssh://git@gitea.prod.lagraula.fr:2222/xavier/nixos-infra-framework.git)
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
nixos-infra/
|
||||||
|
├── environments/
|
||||||
|
│ └── production/ # Production infrastructure
|
||||||
|
│ ├── configuration.nix # Environment entry point
|
||||||
|
│ ├── hosts/
|
||||||
|
│ │ ├── servers/ # Server configurations (LXC, hypervisors)
|
||||||
|
│ │ └── workstations/ # Workstation configurations
|
||||||
|
│ ├── network/ # VLANs, subnets, host IPs
|
||||||
|
│ ├── secrets/ # agenix-encrypted secrets
|
||||||
|
│ └── users/ # User configurations
|
||||||
|
├── scripts/ # Environment-specific script wrappers
|
||||||
|
└── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adding a New Environment
|
||||||
|
|
||||||
|
1. Create `environments/<name>/` with the same sub-structure as `production/`.
|
||||||
|
2. Set up its own `network/`, `secrets/`, and `users/`.
|
||||||
|
3. Deploy with:
|
||||||
|
```
|
||||||
|
deploy.sh --environment <name>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
```
|
||||||
|
deploy.sh --environment production
|
||||||
|
```
|
||||||
|
|
||||||
|
See the framework repo for the deploy script and reusable modules.
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
frameworkRev = "c53d997d075236f6d8c2a8e9db0238e46391735a";
|
||||||
|
framework = builtins.fetchGit {
|
||||||
|
url = "ssh://git@gitea.prod.lagraula.fr:2222/xavier/nixos-infra-framework.git";
|
||||||
|
rev = frameworkRev;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
# Import the framework utilities
|
||||||
|
(framework + "/lib")
|
||||||
|
(framework + "/overlays/custom-pkgs.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
# Production environment-wide settings
|
||||||
|
system.stateVersion = "25.11";
|
||||||
|
}
|
||||||
+13
-4
@@ -1,11 +1,19 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
{
|
let
|
||||||
|
# Pin to a specific commit of the framework repo for reproducibility.
|
||||||
|
# Update this hash when you want to pull in new framework changes.
|
||||||
|
frameworkRev = "c53d997d075236f6d8c2a8e9db0238e46391735a";
|
||||||
|
framework = builtins.fetchGit {
|
||||||
|
url = "ssh://git@gitea.prod.lagraula.fr:2222/xavier/nixos-infra-framework.git";
|
||||||
|
rev = frameworkRev;
|
||||||
|
};
|
||||||
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
# Module for LXC containers
|
# Module for LXC containers
|
||||||
../../../modules/machine-types/lxc
|
(framework + "/modules/machine-types/lxc")
|
||||||
# Technitium DNS Server service module
|
# Technitium DNS Server service module
|
||||||
../../../modules/services/dns/default.nix
|
(framework + "/modules/services/dns/default.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
# Explicitly enable LXC machine type
|
# Explicitly enable LXC machine type
|
||||||
@@ -13,6 +21,7 @@
|
|||||||
|
|
||||||
# Host identity (IP address 10.40.128.10/16 assigned via DHCP reservation)
|
# Host identity (IP address 10.40.128.10/16 assigned via DHCP reservation)
|
||||||
networking.hostName = "dns01";
|
networking.hostName = "dns01";
|
||||||
|
networking.domain = "prod.lagraula.fr";
|
||||||
networking.useDHCP = true;
|
networking.useDHCP = true;
|
||||||
|
|
||||||
# Technitium DNS Server — primary DNS server
|
# Technitium DNS Server — primary DNS server
|
||||||
@@ -25,4 +34,4 @@
|
|||||||
allowZoneTransfer = [ "10.40.128.11" ]; # Allow secondary to dns02
|
allowZoneTransfer = [ "10.40.128.11" ]; # Allow secondary to dns02
|
||||||
listenAddresses = [ "10.40.128.10" "127.0.0.1" "::1" ];
|
listenAddresses = [ "10.40.128.10" "127.0.0.1" "::1" ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
+11
-4
@@ -1,11 +1,17 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
{
|
let
|
||||||
|
frameworkRev = "c53d997d075236f6d8c2a8e9db0238e46391735a";
|
||||||
|
framework = builtins.fetchGit {
|
||||||
|
url = "ssh://git@gitea.prod.lagraula.fr:2222/xavier/nixos-infra-framework.git";
|
||||||
|
rev = frameworkRev;
|
||||||
|
};
|
||||||
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
# Module for LXC containers
|
# Module for LXC containers
|
||||||
../../../modules/machine-types/lxc
|
(framework + "/modules/machine-types/lxc")
|
||||||
# Technitium DNS Server service module
|
# Technitium DNS Server service module
|
||||||
../../../modules/services/dns/default.nix
|
(framework + "/modules/services/dns/default.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
# Explicitly enable LXC machine type
|
# Explicitly enable LXC machine type
|
||||||
@@ -13,6 +19,7 @@
|
|||||||
|
|
||||||
# Host identity (IP address 10.40.128.11/16 assigned via DHCP reservation)
|
# Host identity (IP address 10.40.128.11/16 assigned via DHCP reservation)
|
||||||
networking.hostName = "dns02";
|
networking.hostName = "dns02";
|
||||||
|
networking.domain = "prod.lagraula.fr";
|
||||||
networking.useDHCP = true;
|
networking.useDHCP = true;
|
||||||
|
|
||||||
# Technitium DNS Server — secondary (replica) DNS server
|
# Technitium DNS Server — secondary (replica) DNS server
|
||||||
@@ -24,4 +31,4 @@
|
|||||||
# adminPasswordFile = config.age.secrets.dns-admin-password.path;
|
# adminPasswordFile = config.age.secrets.dns-admin-password.path;
|
||||||
listenAddresses = [ "10.40.128.11" "127.0.0.1" "::1" ];
|
listenAddresses = [ "10.40.128.11" "127.0.0.1" "::1" ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
+11
-4
@@ -1,11 +1,17 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
{
|
let
|
||||||
|
frameworkRev = "c53d997d075236f6d8c2a8e9db0238e46391735a";
|
||||||
|
framework = builtins.fetchGit {
|
||||||
|
url = "ssh://git@gitea.prod.lagraula.fr:2222/xavier/nixos-infra-framework.git";
|
||||||
|
rev = frameworkRev;
|
||||||
|
};
|
||||||
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
# Module for LXC containers
|
# Module for LXC containers
|
||||||
../../../modules/machine-types/lxc
|
(framework + "/modules/machine-types/lxc")
|
||||||
# Module for the git forge service (Forgejo)
|
# Module for the git forge service (Forgejo)
|
||||||
../../../modules/services/git-forge/default.nix
|
(framework + "/modules/services/git-forge/default.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
# Explicitly enable LXC machine type
|
# Explicitly enable LXC machine type
|
||||||
@@ -13,6 +19,7 @@
|
|||||||
|
|
||||||
# Host identity (IP address 10.40.128.20/16 assigned via DHCP reservation)
|
# Host identity (IP address 10.40.128.20/16 assigned via DHCP reservation)
|
||||||
networking.hostName = "git01";
|
networking.hostName = "git01";
|
||||||
|
networking.domain = "prod.lagraula.fr";
|
||||||
networking.useDHCP = true;
|
networking.useDHCP = true;
|
||||||
|
|
||||||
# Forgejo — self-hosted git forge
|
# Forgejo — self-hosted git forge
|
||||||
@@ -23,4 +30,4 @@
|
|||||||
httpPort = 3000;
|
httpPort = 3000;
|
||||||
databaseType = "sqlite3";
|
databaseType = "sqlite3";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# ╔══════════════════════════════════════════════════════════╗
|
||||||
|
# ║ This machine runs Proxmox VE (not NixOS). ║
|
||||||
|
# ║ This configuration serves as an inventory record ║
|
||||||
|
# ║ documenting the machine's role and network settings. ║
|
||||||
|
# ╚══════════════════════════════════════════════════════════╝
|
||||||
|
|
||||||
|
networking.hostName = "hyper01";
|
||||||
|
networking.hostId = "deadbeef01"; # Unique 8-char hex identifier
|
||||||
|
|
||||||
|
# Hypervisor management network
|
||||||
|
# Proxmox management interface: 10.10.128.10/16
|
||||||
|
# SSH: root@10.10.128.10:22
|
||||||
|
# Proxmox web UI: https://10.10.128.10:8006
|
||||||
|
|
||||||
|
system.stateVersion = "25.11";
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# ╔══════════════════════════════════════════════════════════╗
|
||||||
|
# ║ This machine runs Proxmox VE (not NixOS). ║
|
||||||
|
# ║ This configuration serves as an inventory record ║
|
||||||
|
# ║ documenting the machine's role and network settings. ║
|
||||||
|
# ╚══════════════════════════════════════════════════════════╝
|
||||||
|
|
||||||
|
networking.hostName = "hyper02";
|
||||||
|
networking.hostId = "deadbeef02"; # Unique 8-char hex identifier
|
||||||
|
|
||||||
|
# Hypervisor management network
|
||||||
|
# Proxmox management interface: 10.10.128.11/16
|
||||||
|
# SSH: root@10.10.128.11:22
|
||||||
|
# Proxmox web UI: https://10.10.128.11:8006
|
||||||
|
|
||||||
|
system.stateVersion = "25.11";
|
||||||
|
}
|
||||||
+11
-4
@@ -1,11 +1,17 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
{
|
let
|
||||||
|
frameworkRev = "c53d997d075236f6d8c2a8e9db0238e46391735a";
|
||||||
|
framework = builtins.fetchGit {
|
||||||
|
url = "ssh://git@gitea.prod.lagraula.fr:2222/xavier/nixos-infra-framework.git";
|
||||||
|
rev = frameworkRev;
|
||||||
|
};
|
||||||
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
# Module for LXC containers
|
# Module for LXC containers
|
||||||
../../../modules/machine-types/lxc
|
(framework + "/modules/machine-types/lxc")
|
||||||
# Module for password manager service (Vaultwarden)
|
# Module for password manager service (Vaultwarden)
|
||||||
../../../modules/services/password-manager/default.nix
|
(framework + "/modules/services/password-manager/default.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
# Explicitly enable LXC machine type
|
# Explicitly enable LXC machine type
|
||||||
@@ -13,6 +19,7 @@
|
|||||||
|
|
||||||
# Host identity (IP address 10.40.128.30/16 assigned via DHCP reservation)
|
# Host identity (IP address 10.40.128.30/16 assigned via DHCP reservation)
|
||||||
networking.hostName = "pass01";
|
networking.hostName = "pass01";
|
||||||
|
networking.domain = "prod.lagraula.fr";
|
||||||
networking.useDHCP = true;
|
networking.useDHCP = true;
|
||||||
|
|
||||||
# Vaultwarden — Bitwarden-compatible password manager
|
# Vaultwarden — Bitwarden-compatible password manager
|
||||||
@@ -25,4 +32,4 @@
|
|||||||
# Uncomment and configure with agenix secret:
|
# Uncomment and configure with agenix secret:
|
||||||
# adminTokenFile = config.age.secrets.vaultwarden-admin-token.path;
|
# adminTokenFile = config.age.secrets.vaultwarden-admin-token.path;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
+10
-3
@@ -1,15 +1,22 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
{
|
let
|
||||||
|
frameworkRev = "c53d997d075236f6d8c2a8e9db0238e46391735a";
|
||||||
|
framework = builtins.fetchGit {
|
||||||
|
url = "ssh://git@gitea.prod.lagraula.fr:2222/xavier/nixos-infra-framework.git";
|
||||||
|
rev = frameworkRev;
|
||||||
|
};
|
||||||
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
# Module for LXC containers
|
# Module for LXC containers
|
||||||
../../../modules/machine-types/lxc
|
(framework + "/modules/machine-types/lxc")
|
||||||
# Module for the reverse proxy
|
# Module for the reverse proxy
|
||||||
../../../modules/services/reverse-proxy/default.nix
|
(framework + "/modules/services/reverse-proxy/default.nix")
|
||||||
];
|
];
|
||||||
|
|
||||||
# Host identity (IP address assigned via DHCP reservation)
|
# Host identity (IP address assigned via DHCP reservation)
|
||||||
networking.hostName = "rp01";
|
networking.hostName = "rp01";
|
||||||
|
networking.domain = "prod.lagraula.fr";
|
||||||
networking.useDHCP = true;
|
networking.useDHCP = true;
|
||||||
|
|
||||||
# Services to expose via the reverse proxy
|
# Services to expose via the reverse proxy
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Workstation configuration for PC-FRIDA
|
||||||
|
# TODO: Fill in workstation-specific settings
|
||||||
|
networking.hostName = "PC-FRIDA";
|
||||||
|
networking.domain = "prod.lagraula.fr";
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Workstation configuration for gaia
|
||||||
|
# TODO: Fill in workstation-specific settings
|
||||||
|
networking.hostName = "gaia";
|
||||||
|
networking.domain = "prod.lagraula.fr";
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# Workstation configuration for sting
|
||||||
|
# TODO: Fill in workstation-specific settings
|
||||||
|
networking.hostName = "sting";
|
||||||
|
networking.domain = "prod.lagraula.fr";
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# User configuration for frida
|
||||||
|
# TODO: Fill in user-specific settings
|
||||||
|
users.users.frida = {
|
||||||
|
isNormalUser = true;
|
||||||
|
description = "Frida";
|
||||||
|
extraGroups = [ "wheel" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# User configuration for guest
|
||||||
|
# TODO: Fill in user-specific settings
|
||||||
|
users.users.guest = {
|
||||||
|
isNormalUser = true;
|
||||||
|
description = "Guest";
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# User configuration for root
|
||||||
|
# TODO: Fill in root-specific settings
|
||||||
|
users.root = {
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
# Add SSH public keys for root access
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# User configuration for xavier
|
||||||
|
# TODO: Fill in user-specific settings
|
||||||
|
users.users.xavier = {
|
||||||
|
isNormalUser = true;
|
||||||
|
description = "Xavier";
|
||||||
|
extraGroups = [ "wheel" ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Do not modify!!
|
|
||||||
# Proxmox hypervisor on NixOS is not mature enough.
|
|
||||||
# Hypervisor are here for future reference only.
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Do not modify!!
|
|
||||||
# Proxmox hypervisor on NixOS is not mature enough.
|
|
||||||
# Hypervisor are here for future reference only.
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# Lib
|
|
||||||
Custom Nix utility functions and helpers.
|
|
||||||
Used across the configuration to factorize code.
|
|
||||||
Simplifies data and string manipulation.
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
# Modules
|
|
||||||
Reusable NixOS modules for the infrastructure.
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
{
|
|
||||||
# TODO: Add hypervisor-specific configuration
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
{ config, modulesPath, pkgs, lib, ... }:
|
|
||||||
{
|
|
||||||
imports = [ (modulesPath + "/virtualisation/proxmox-lxc.nix") ];
|
|
||||||
nix.settings = { sandbox = false; };
|
|
||||||
proxmoxLXC = {
|
|
||||||
manageNetwork = false;
|
|
||||||
privileged = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Enable LXC specific options
|
|
||||||
options.lxc = {
|
|
||||||
enable = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "Enable LXC machine type";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.fstrim.enable = false; # Let Proxmox host handle fstrim
|
|
||||||
|
|
||||||
# Cache DNS lookups to improve performance
|
|
||||||
services.resolved = {
|
|
||||||
extraConfig = ''
|
|
||||||
Cache=true
|
|
||||||
CacheFromLocalhost=true
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# Default configuration for a LXC container
|
|
||||||
config = lib.mkIf config.lxc.enable {
|
|
||||||
# Disabling useless services
|
|
||||||
services.avahi.daemon.enable = false; # TODO : review the need for avahi in a container
|
|
||||||
services.bluetooth.enable = false;
|
|
||||||
services.printing.enable = false;
|
|
||||||
|
|
||||||
# Optimzing for conainters
|
|
||||||
boot.kernelModules = [ ]; # TODO : review the disabling of all kernelModules in a container
|
|
||||||
powerManagement.enable = false;
|
|
||||||
|
|
||||||
# Limiter les ressources si nécessaire
|
|
||||||
# TODO : review the need to limit ZFS pools in the LXC container configuration, in my ZFSless context
|
|
||||||
boot.zfs.extraPools = [ ];
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
system.stateVersion = "25.11";
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
{
|
|
||||||
# TODO: Add VM-specific configuration
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
{
|
|
||||||
# TODO: Add workstation-specific configuration
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
options.secrets = {
|
|
||||||
enable = lib.mkEnableOption "agenix secret management";
|
|
||||||
|
|
||||||
identity = lib.mkOption {
|
|
||||||
type = lib.types.path;
|
|
||||||
default = "/etc/ssh/ssh_host_ed25519_key";
|
|
||||||
description = "Path to the SSH host private key used for age decryption.";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = lib.mkIf config.secrets.enable {
|
|
||||||
age = {
|
|
||||||
identityPaths = [ config.secrets.identity ];
|
|
||||||
secrets = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [ agenix ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.dns;
|
|
||||||
dnsPkg = if cfg.package != null then cfg.package else pkgs.technitium-dns-server;
|
|
||||||
|
|
||||||
# Build the config.json for Technitium DNS Server.
|
|
||||||
# The server reads this file on startup from its config directory.
|
|
||||||
configJson = {
|
|
||||||
WebServicePort = cfg.webPort;
|
|
||||||
DNSListenerPort = cfg.dnsPort;
|
|
||||||
Recursion = cfg.recursion;
|
|
||||||
Forwarders = cfg.forwarders;
|
|
||||||
Log = false;
|
|
||||||
CachePrefetch = false;
|
|
||||||
AllowTtlOverride = true;
|
|
||||||
} // lib.optionalAttrs (cfg.adminPasswordFile != null) {
|
|
||||||
# Password hash will be set by the activation script on first run
|
|
||||||
# using the value from adminPasswordFile.
|
|
||||||
} // lib.optionalAttrs (cfg.listenAddresses != [ ]) {
|
|
||||||
ListenAddresses = cfg.listenAddresses;
|
|
||||||
} // lib.optionalAttrs (cfg.allowZoneTransfer != [ ]) {
|
|
||||||
AllowZoneTransfer = cfg.allowZoneTransfer;
|
|
||||||
} // cfg.extraConfig;
|
|
||||||
|
|
||||||
configFile = pkgs.writeText "technitium-dns-config.json"
|
|
||||||
(builtins.toJSON configJson);
|
|
||||||
in
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./options.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
|
|
||||||
environment.systemPackages = [ dnsPkg ];
|
|
||||||
|
|
||||||
# Create the config directory and deploy initial config.json
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d ${cfg.configDir} 0750 dns dns - -"
|
|
||||||
];
|
|
||||||
|
|
||||||
systemd.services.technitium-dns-server = {
|
|
||||||
description = "Technitium DNS Server";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
after = [ "network.target" ];
|
|
||||||
wants = [ "network-online.target" ];
|
|
||||||
|
|
||||||
# Generate a password hash if adminPasswordFile is provided.
|
|
||||||
# The server is stopped on first run if no password hash exists,
|
|
||||||
# so we pre-seed the config with the hashed password.
|
|
||||||
preStart = ''
|
|
||||||
if [ -f "${cfg.configDir}/config.json" ]; then
|
|
||||||
# Config already exists, do not overwrite
|
|
||||||
true
|
|
||||||
else
|
|
||||||
install -m 0640 ${configFile} ${cfg.configDir}/config.json
|
|
||||||
${lib.optionalString (cfg.adminPasswordFile != null) ''
|
|
||||||
if [ -f "${cfg.adminPasswordFile}" ]; then
|
|
||||||
# .NET-compatible SHA256 hash of the password
|
|
||||||
PASSWORD=$(cat "${cfg.adminPasswordFile}" | tr -d '\n')
|
|
||||||
HASH=$(echo -n "$PASSWORD" | ${pkgs.openssl}/bin/openssl dgst -sha256 -hex | cut -d' ' -f2)
|
|
||||||
${pkgs.jq}/bin/jq \
|
|
||||||
".AdminPassword = \"$HASH\" | .Pbkdf2Iterations = 600000" \
|
|
||||||
${cfg.configDir}/config.json > ${cfg.configDir}/config.json.tmp
|
|
||||||
mv ${cfg.configDir}/config.json.tmp ${cfg.configDir}/config.json
|
|
||||||
fi
|
|
||||||
''}
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "simple";
|
|
||||||
ExecStart = "${dnsPkg}/bin/technitium-dns-server ${cfg.configDir}";
|
|
||||||
User = "dns";
|
|
||||||
Group = "dns";
|
|
||||||
Restart = "on-failure";
|
|
||||||
RestartSec = "5s";
|
|
||||||
LimitNOFILE = 1048576;
|
|
||||||
# Protect the system
|
|
||||||
ProtectSystem = "full";
|
|
||||||
ProtectHome = true;
|
|
||||||
PrivateTmp = true;
|
|
||||||
NoNewPrivileges = true;
|
|
||||||
ReadWritePaths = [ cfg.configDir ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Create the dns system user and group
|
|
||||||
users.users.dns = {
|
|
||||||
description = "Technitium DNS Server daemon user";
|
|
||||||
group = "dns";
|
|
||||||
isSystemUser = true;
|
|
||||||
home = cfg.configDir;
|
|
||||||
createHome = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
users.groups.dns = { };
|
|
||||||
|
|
||||||
# Open firewall ports for DNS (UDP/TCP 53) and optionally the web interface
|
|
||||||
networking.firewall = lib.mkMerge [
|
|
||||||
{
|
|
||||||
allowedTCPPorts = [ cfg.dnsPort ];
|
|
||||||
allowedUDPPorts = [ cfg.dnsPort ];
|
|
||||||
}
|
|
||||||
# Allow web admin access only if listenAddresses restricts it to localhost
|
|
||||||
(lib.mkIf (cfg.listenAddresses == [ ] || builtins.elem "127.0.0.1" cfg.listenAddresses) {
|
|
||||||
allowedTCPPorts = [ cfg.webPort ];
|
|
||||||
})
|
|
||||||
];
|
|
||||||
|
|
||||||
# Ensure DNS resolution is available locally before starting
|
|
||||||
networking.nameservers = lib.mkAfter [ "127.0.0.1" ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
{ config, lib, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
inherit (lib) types mkOption;
|
|
||||||
in
|
|
||||||
|
|
||||||
{
|
|
||||||
options.services.dns = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Enable the Technitium DNS Server";
|
|
||||||
};
|
|
||||||
|
|
||||||
package = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
default = null;
|
|
||||||
description = "Technitium DNS Server package to use. Defaults to pkgs.technitium-dns-server.";
|
|
||||||
};
|
|
||||||
|
|
||||||
webPort = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
default = 5380;
|
|
||||||
description = "HTTP port for the Technitium web administration interface";
|
|
||||||
};
|
|
||||||
|
|
||||||
dnsPort = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
default = 53;
|
|
||||||
description = "DNS server port (both TCP and UDP)";
|
|
||||||
};
|
|
||||||
|
|
||||||
recursion = mkOption {
|
|
||||||
type = types.enum [ "AllowOnlyForPrivateNetworks" "AllowAll" "DenyAll" ];
|
|
||||||
default = "AllowOnlyForPrivateNetworks";
|
|
||||||
description = "Recursion policy for DNS queries";
|
|
||||||
};
|
|
||||||
|
|
||||||
forwarders = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = "Upstream DNS forwarders (e.g. [ \"1.1.1.1\" \"8.8.8.8\" ]). Empty means use root hints";
|
|
||||||
};
|
|
||||||
|
|
||||||
configDir = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "/etc/dns";
|
|
||||||
description = "Directory for persistent Technitium DNS configuration and zone data";
|
|
||||||
};
|
|
||||||
|
|
||||||
adminPasswordFile = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Path to a file containing the admin password for the web interface.
|
|
||||||
If not set, the default credentials (admin/admin) are used.
|
|
||||||
Use agenix or sops-nix to provide this file securely.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
listenAddresses = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = "IP addresses to listen on. Empty means listen on all interfaces";
|
|
||||||
};
|
|
||||||
|
|
||||||
allowZoneTransfer = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = "IP addresses or subnets allowed to request zone transfers (AXFR/IXFR)";
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig = mkOption {
|
|
||||||
type = types.attrsOf types.anything;
|
|
||||||
default = { };
|
|
||||||
description = "Additional Technitium DNS configuration options as an attribute set";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.git-forge;
|
|
||||||
inherit (lib) mkIf mkOption types;
|
|
||||||
in
|
|
||||||
|
|
||||||
{
|
|
||||||
options.services.git-forge = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Enable the git forge service (Forgejo)";
|
|
||||||
};
|
|
||||||
|
|
||||||
domain = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "git.lagraula.fr";
|
|
||||||
description = "Domain name for the Forgejo instance";
|
|
||||||
};
|
|
||||||
|
|
||||||
sshPort = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
default = 2222;
|
|
||||||
description = "SSH port for Git operations (avoid conflict with host SSH on 22)";
|
|
||||||
};
|
|
||||||
|
|
||||||
httpPort = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
default = 3000;
|
|
||||||
description = "HTTP port for the Forgejo web interface";
|
|
||||||
};
|
|
||||||
|
|
||||||
dataDir = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "/var/lib/forgejo";
|
|
||||||
description = "Data directory for Forgejo repositories and database";
|
|
||||||
};
|
|
||||||
|
|
||||||
databaseType = mkOption {
|
|
||||||
type = types.enum [ "sqlite3" "postgres" "mysql" ];
|
|
||||||
default = "sqlite3";
|
|
||||||
description = "Database backend type";
|
|
||||||
};
|
|
||||||
|
|
||||||
settings = mkOption {
|
|
||||||
type = types.attrsOf types.anything;
|
|
||||||
default = { };
|
|
||||||
description = "Additional Forgejo settings (merged into services.forgejo.settings)";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
# Use the built-in NixOS forgejo module
|
|
||||||
services.forgejo = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.forgejo;
|
|
||||||
settings = lib.recursiveUpdate {
|
|
||||||
server = {
|
|
||||||
DOMAIN = cfg.domain;
|
|
||||||
HTTP_PORT = cfg.httpPort;
|
|
||||||
HTTP_ADDR = "0.0.0.0";
|
|
||||||
ROOT_URL = "https://${cfg.domain}";
|
|
||||||
SSH_PORT = cfg.sshPort;
|
|
||||||
SSH_LISTEN_PORT = cfg.sshPort;
|
|
||||||
};
|
|
||||||
service = {
|
|
||||||
DISABLE_REGISTRATION = false;
|
|
||||||
};
|
|
||||||
"repository".ROOT = "${cfg.dataDir}/repos";
|
|
||||||
} (lib.mapAttrs (section: values: lib.mapAttrs (key: value: lib.mkDefault value) values) cfg.settings);
|
|
||||||
|
|
||||||
database = {
|
|
||||||
type = cfg.databaseType;
|
|
||||||
};
|
|
||||||
|
|
||||||
dump = {
|
|
||||||
type = "tar.zst";
|
|
||||||
};
|
|
||||||
|
|
||||||
# LXC container specifics - use the existing forgejo user
|
|
||||||
stateDir = cfg.dataDir;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Open firewall ports for HTTP and SSH (git protocol)
|
|
||||||
networking.firewall = lib.mkIf config.services.forgejo.enable {
|
|
||||||
allowedTCPPorts = [ cfg.httpPort cfg.sshPort ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.password-manager;
|
|
||||||
inherit (lib) mkIf mkOption types;
|
|
||||||
in
|
|
||||||
|
|
||||||
{
|
|
||||||
options.services.password-manager = {
|
|
||||||
enable = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Enable the password manager service (Vaultwarden)";
|
|
||||||
};
|
|
||||||
|
|
||||||
domain = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "pass.lagraula.fr";
|
|
||||||
description = "Domain name for the Vaultwarden instance";
|
|
||||||
};
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
default = 8080;
|
|
||||||
description = "HTTP port for the Vaultwarden web interface";
|
|
||||||
};
|
|
||||||
|
|
||||||
dataDir = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "/var/lib/vaultwarden";
|
|
||||||
description = "Data directory for Vaultwarden persistent state";
|
|
||||||
};
|
|
||||||
|
|
||||||
dbBackend = mkOption {
|
|
||||||
type = types.enum [ "sqlite" "mysql" "postgresql" ];
|
|
||||||
default = "sqlite";
|
|
||||||
description = "Database backend type";
|
|
||||||
};
|
|
||||||
|
|
||||||
adminTokenFile = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Path to a file containing the admin token for the /admin panel.
|
|
||||||
Use agenix or sops-nix to provide this file securely.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
signupsAllowed = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = "Allow new user registration";
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig = mkOption {
|
|
||||||
type = types.attrsOf (types.nullOr (types.oneOf [ types.bool types.str types.int types.port ]));
|
|
||||||
default = { };
|
|
||||||
description = "Additional Vaultwarden config options as attribute set (mapped to env vars)";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
# Use the built-in NixOS vaultwarden module
|
|
||||||
services.vaultwarden = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.vaultwarden;
|
|
||||||
webVaultPackage = pkgs.vaultwarden-webvault;
|
|
||||||
inherit (cfg) dbBackend;
|
|
||||||
config = {
|
|
||||||
DOMAIN = "https://${cfg.domain}";
|
|
||||||
PORT = cfg.port;
|
|
||||||
SIGNUPS_ALLOWED = cfg.signupsAllowed;
|
|
||||||
} // (lib.mapAttrs (name: value:
|
|
||||||
if value == true then "true"
|
|
||||||
else if value == false then "false"
|
|
||||||
else toString value
|
|
||||||
) cfg.extraConfig);
|
|
||||||
} // lib.optionalAttrs (cfg.adminTokenFile != null) {
|
|
||||||
environmentFile = cfg.adminTokenFile;
|
|
||||||
config = {
|
|
||||||
ADMIN_TOKEN = null; # Will be read from environmentFile
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Open firewall port
|
|
||||||
networking.firewall = mkIf config.services.vaultwarden.enable {
|
|
||||||
allowedTCPPorts = [ cfg.port ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
# Récupère la liste des services depuis la configuration
|
|
||||||
publicServices = config.services.reverse-proxy.publicServices or [];
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# Options pour le module reverse-proxy
|
|
||||||
options.services.reverse-proxy = {
|
|
||||||
publicServices = lib.mkOption {
|
|
||||||
type = lib.types.listOf (lib.types.submodule {
|
|
||||||
options = {
|
|
||||||
host = lib.mkOption { type = lib.types.str; };
|
|
||||||
internalHost = lib.mkOption { type = lib.types.str; };
|
|
||||||
port = lib.mkOption { type = lib.types.int; default = 80; };
|
|
||||||
};
|
|
||||||
});
|
|
||||||
default = [];
|
|
||||||
description = "Liste des services à exposer via le reverse proxy";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Configuration de Caddy
|
|
||||||
config = lib.mkIf (config.services.reverse-proxy.publicServices or []) != [] {
|
|
||||||
services.caddy = {
|
|
||||||
enable = true;
|
|
||||||
virtualHosts = map (service: {
|
|
||||||
host = "${service.host}.lagraula.fr";
|
|
||||||
reverseProxy = "http://${service.internalHost}.lagraula.fr:${toString service.port}";
|
|
||||||
tls = {
|
|
||||||
email = config.services.caddy.email or "xavier@lagraula.fr";
|
|
||||||
};
|
|
||||||
}) (config.services.reverse-proxy.publicServices or []);
|
|
||||||
|
|
||||||
# Configuration globale pour Caddy
|
|
||||||
extraConfig = ''
|
|
||||||
{
|
|
||||||
# Rate limiting global (optionnel)
|
|
||||||
rate_limit {
|
|
||||||
requests 100
|
|
||||||
burst 200
|
|
||||||
interval 1m
|
|
||||||
}
|
|
||||||
# Logging
|
|
||||||
log {
|
|
||||||
output file /var/log/caddy/access.log
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# Ouvrir les ports firewall pour HTTP/HTTPS
|
|
||||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
|
||||||
networking.firewall.allowedUDPPorts = [];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# Overlays
|
|
||||||
Custom modifications and extensions to Nixpkgs.
|
|
||||||
Applies patches or version overrides to existing packages.
|
|
||||||
Applied globally across the infrastructure.
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
self: super: {
|
|
||||||
# Custom packages and overrides for nixos-infra
|
|
||||||
# agenix is already available in nixpkgs — no custom overlay needed.
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# Packages
|
|
||||||
Custom software packages not found in upstream Nixpkgs.
|
|
||||||
Contains project-specific derivations (default.nix).
|
|
||||||
Can be referenced via overlays or directly by hosts.
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
let
|
|
||||||
spec = builtins.fromJSON (builtins.readFile ./nixpkgs.json);
|
|
||||||
in
|
|
||||||
import (builtins.fetchTarball {
|
|
||||||
url = "https://github.com/NixOS/nixpkgs/archive/${spec.rev}.tar.gz";
|
|
||||||
sha256 = spec.sha256;
|
|
||||||
}) {}
|
|
||||||
# TODO: add a nixos-infra module
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"url": "https://github.com/NixOS/nixpkgs/archive/755f5aa91337890c432639c60b6064bb7fe67769.tar.gz",
|
|
||||||
"rev": "755f5aa91337890c432639c60b6064bb7fe67769",
|
|
||||||
"sha256": "1lmn8dicfwmsfdaiw18xjjys78bal6yjy3a41j02my7kw0wlb76a"
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
bridge=
|
|
||||||
cmode=
|
|
||||||
cores=
|
|
||||||
domain=
|
|
||||||
dry_run=false
|
|
||||||
help=false
|
|
||||||
ip=
|
|
||||||
memory=
|
|
||||||
password=
|
|
||||||
pve_host=
|
|
||||||
pve_password=
|
|
||||||
pve_port=
|
|
||||||
pve_ssh_key=
|
|
||||||
pve_user=
|
|
||||||
rootfs_size=
|
|
||||||
ssh_public_keys=
|
|
||||||
swap=
|
|
||||||
tags=
|
|
||||||
template=
|
|
||||||
unprivileged=
|
|
||||||
vlan=
|
|
||||||
short_name='2'
|
|
||||||
@@ -2,9 +2,10 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# --- Default values (can be overridden by environment variables) ---
|
# --- Default values (can be overridden by environment variables) ---
|
||||||
REPO_URL="${REPO_URL:-https://gitea.lagraula.fr/xavier/nixos-infra.git}"
|
REPO_URL="${REPO_URL:-ssh://git@gitea.prod.lagraula.fr:2222/xavier/nixos-infra.git}"
|
||||||
REPO_DIR="${REPO_DIR:-/etc/nixos-infra}"
|
REPO_DIR="${REPO_DIR:-/etc/nixos-infra}"
|
||||||
BRANCH="${BRANCH:-main}"
|
BRANCH="${BRANCH:-main}"
|
||||||
|
ENVIRONMENT="${ENVIRONMENT:-production}"
|
||||||
DRY_RUN="${DRY_RUN:-false}"
|
DRY_RUN="${DRY_RUN:-false}"
|
||||||
|
|
||||||
# --- Usage ---
|
# --- Usage ---
|
||||||
@@ -22,11 +23,13 @@ Options:
|
|||||||
[default: ${REPO_DIR}]
|
[default: ${REPO_DIR}]
|
||||||
-b, --branch BRANCH Git branch to deploy
|
-b, --branch BRANCH Git branch to deploy
|
||||||
[default: ${BRANCH}]
|
[default: ${BRANCH}]
|
||||||
|
-e, --environment ENV Environment name (production, dev, staging, etc.)
|
||||||
|
[default: ${ENVIRONMENT}]
|
||||||
-n, --dry-run Simulate deployment without making changes.
|
-n, --dry-run Simulate deployment without making changes.
|
||||||
-h, --help Show this help message.
|
-h, --help Show this help message.
|
||||||
|
|
||||||
Environment variables:
|
Environment variables:
|
||||||
REPO_URL, REPO_DIR, BRANCH, DRY_RUN (same as options above).
|
REPO_URL, REPO_DIR, BRANCH, ENVIRONMENT, DRY_RUN (same as options above).
|
||||||
EOF
|
EOF
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
@@ -34,11 +37,12 @@ EOF
|
|||||||
# --- Parse arguments ---
|
# --- Parse arguments ---
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-u|--repo-url) REPO_URL="$2"; shift 2 ;;
|
-u|--repo-url) REPO_URL="$2"; shift 2 ;;
|
||||||
-d|--repo-dir) REPO_DIR="$2"; shift 2 ;;
|
-d|--repo-dir) REPO_DIR="$2"; shift 2 ;;
|
||||||
-b|--branch) BRANCH="$2"; shift 2 ;;
|
-b|--branch) BRANCH="$2"; shift 2 ;;
|
||||||
-n|--dry-run) DRY_RUN="true"; shift ;;
|
-e|--environment) ENVIRONMENT="$2"; shift 2 ;;
|
||||||
-h|--help) usage ;;
|
-n|--dry-run) DRY_RUN="true"; shift ;;
|
||||||
|
-h|--help) usage ;;
|
||||||
*) echo "❌ Unknown option: $1" >&2; usage ;;
|
*) echo "❌ Unknown option: $1" >&2; usage ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
@@ -56,8 +60,9 @@ if [ "$DRY_RUN" = "true" ]; then
|
|||||||
echo " - Repository URL: $REPO_URL"
|
echo " - Repository URL: $REPO_URL"
|
||||||
echo " - Repository dir: $REPO_DIR"
|
echo " - Repository dir: $REPO_DIR"
|
||||||
echo " - Branch: $BRANCH"
|
echo " - Branch: $BRANCH"
|
||||||
|
echo " - Environment: $ENVIRONMENT"
|
||||||
echo " - Hostname: $HOSTNAME"
|
echo " - Hostname: $HOSTNAME"
|
||||||
echo " - Expected config: $REPO_DIR/hosts/servers/$HOSTNAME/configuration.nix"
|
echo " - Expected config: $REPO_DIR/environments/$ENVIRONMENT/hosts/servers/$HOSTNAME/configuration.nix"
|
||||||
echo ""
|
echo ""
|
||||||
echo " Would execute:"
|
echo " Would execute:"
|
||||||
echo " git clone --branch $BRANCH $REPO_URL $REPO_DIR"
|
echo " git clone --branch $BRANCH $REPO_URL $REPO_DIR"
|
||||||
@@ -79,21 +84,21 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Find the configuration for this machine ---
|
# --- Find the configuration for this machine ---
|
||||||
CONFIG_PATH="$REPO_DIR/hosts/servers/$HOSTNAME/configuration.nix"
|
CONFIG_PATH="$REPO_DIR/environments/$ENVIRONMENT/hosts/servers/$HOSTNAME/configuration.nix"
|
||||||
if [ ! -f "$CONFIG_PATH" ]; then
|
if [ ! -f "$CONFIG_PATH" ]; then
|
||||||
CONFIG_PATH="$REPO_DIR/hosts/workstations/$HOSTNAME/configuration.nix"
|
CONFIG_PATH="$REPO_DIR/environments/$ENVIRONMENT/hosts/workstations/$HOSTNAME/configuration.nix"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f "$CONFIG_PATH" ]; then
|
if [ ! -f "$CONFIG_PATH" ]; then
|
||||||
echo "❌ Error : No configuration found for $HOSTNAME in $REPO_DIR" >&2
|
echo "❌ Error : No configuration found for $HOSTNAME in environment '$ENVIRONMENT'" >&2
|
||||||
echo " Checked paths :" >&2
|
echo " Checked paths :" >&2
|
||||||
echo " - $REPO_DIR/hosts/servers/$HOSTNAME/configuration.nix" >&2
|
echo " - $REPO_DIR/environments/$ENVIRONMENT/hosts/servers/$HOSTNAME/configuration.nix" >&2
|
||||||
echo " - $REPO_DIR/hosts/workstations/$HOSTNAME/configuration.nix" >&2
|
echo " - $REPO_DIR/environments/$ENVIRONMENT/hosts/workstations/$HOSTNAME/configuration.nix" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Apply the configuration ---
|
# --- Apply the configuration ---
|
||||||
echo "🚀 Deploying the configuration for $HOSTNAME..."
|
echo "🚀 Deploying the configuration for $HOSTNAME (environment: $ENVIRONMENT)..."
|
||||||
nixos-rebuild switch -I nixos-config="$CONFIG_PATH"
|
nixos-rebuild switch -I nixos-config="$CONFIG_PATH"
|
||||||
|
|
||||||
echo "✅ Deployment was successful !"
|
echo "✅ Deployment was successful !"
|
||||||
Reference in New Issue
Block a user