Inventory: implement borgbackup

This commit is contained in:
Johannes Kirschbauer
2024-06-19 16:56:26 +02:00
committed by hsjobeki
parent 39ec23bd31
commit d934b67c72
6 changed files with 130 additions and 220 deletions

89
inventory/default.nix Normal file
View File

@@ -0,0 +1,89 @@
{ inputs, self, ... }:
let
clan-core = self;
system = "x86_64-linux";
pkgs = clan-core.inputs.nixpkgs.legacyPackages.${system};
# syncthing_inventory = builtins.fromJSON (builtins.readFile ./src/tests/syncthing.json);
syncthing_inventory = builtins.fromJSON (builtins.readFile ./src/tests/borgbackup.json);
machines = machinesFromInventory {
inherit clan-core;
lib = pkgs.lib;
} syncthing_inventory;
/*
Returns a NixOS configuration for every machine in the inventory.
machinesFromInventory :: Inventory -> { ${machine_name} :: NixOSConfiguration }
*/
machinesFromInventory =
{ lib, clan-core, ... }:
inventory:
# For every machine in the inventory, build a NixOS configuration
# For each machine generate config, forEach service, if the machine is used.
builtins.mapAttrs (
machine_name: _:
builtins.foldl' (
acc: service_name:
let
service_config = inventory.services.${service_name};
isInService = builtins.elem machine_name (builtins.attrNames service_config.machineConfig);
machine_service_config = (service_config.machineConfig.${machine_name} or { }).config or { };
global_config = inventory.services.${service_name}.config;
module_name = inventory.services.${service_name}.module;
in
# Possible roles: "server", "client", "peer"
if
builtins.trace ''
isInService ${builtins.toJSON isInService},
${builtins.toJSON machine_name} ${builtins.toJSON (builtins.attrNames service_config.machineConfig)}
'' isInService
then
acc
++ [
{
imports = [ clan-core.clanModules.${module_name} ];
config.clan.${module_name} = lib.mkMerge [
global_config
machine_service_config
];
}
{
config.clan.${module_name} = {
# TODO: filter, show only the roles that are needed by the machine
roles = builtins.mapAttrs (_m: c: c.roles) service_config.machineConfig;
};
}
]
else
acc
) [ ] (builtins.attrNames inventory.services)
) inventory.machines;
in
{
clan = clan-core.lib.buildClan {
meta.name = "vis clans";
# Should usually point to the directory of flake.nix
directory = self;
machines = {
"vi_machine" = {
imports = machines.vi_machine;
};
"vyr_machine" = {
imports = machines.vyr_machine;
};
"camina_machine" = {
imports = machines.camina_machine;
};
};
};
intern = machines;
# inherit (clan) nixosConfigurations clanInternals;
# add the Clan cli tool to the dev shell
devShells.${system}.default = pkgs.mkShell {
packages = [ clan-core.packages.${system}.clan-cli ];
};
}

View File

@@ -1,137 +0,0 @@
{
description = "<Put your description here>";
inputs.clan-core.url = "https://git.clan.lol/clan/clan-core/archive/main.tar.gz";
outputs =
{ clan-core, ... }:
let
pkgs = clan-core.inputs.nixpkgs.legacyPackages.${system};
system = "x86_64-linux";
in
# Usage see: https://docs.clan.lol
# nice_flake_interface -> buildInventory() -> Inventory -> buildClanFromInventory() -> nixosConfigurations
# buildClanFromInventory = inventory: evalModules {
# extraAttrs = { inherit inventory; };
# # (attrNames inventory.machines)
# };
# clan =
# clan-core.lib.buildClanFromInventory [
# # Inventory 0 (loads the json file managed by the Python API)
# (builtins.fromJSON (builtins.readFile ./inventory.json))
# # ->
# # {
# # services."backups_1".autoIncludeMachines = true;
# # services."backups_1".module = "borgbackup";
# # ... etc.
# # }
# ]
# ++ (buildInventory {
# clanName = "nice_flake_interface";
# description = "A nice flake interface";
# icon = "assets/icon.png";
# machines = {
# jon = {
# # Just regular nixos/clan configuration ?
# # config = {
# # imports = [
# # ./modules/shared.nix
# # ./machines/jon/configuration.nix
# # ];
# # nixpkgs.hostPlatform = system;
# # # Set this for clan commands use ssh i.e. `clan machines update`
# # # If you change the hostname, you need to update this line to root@<new-hostname>
# # # This only works however if you have avahi running on your admin machine else use IP
# # clan.networking.targetHost = pkgs.lib.mkDefault "root@jon";
# # # ssh root@flash-installer.local lsblk --output NAME,ID-LINK,FSTYPE,SIZE,MOUNTPOINT
# # disko.devices.disk.main = {
# # device = "/dev/disk/by-id/__CHANGE_ME__";
# # };
# # # IMPORTANT! Add your SSH key here
# # # e.g. > cat ~/.ssh/id_ed25519.pub
# # users.users.root.openssh.authorizedKeys.keys = throw ''
# # Don't forget to add your SSH key here!
# # users.users.root.openssh.authorizedKeys.keys = [ "<YOUR SSH_KEY>" ]
# # '';
# # # Zerotier needs one controller to accept new nodes. Once accepted
# # # the controller can be offline and routing still works.
# # clan.networking.zerotier.controller.enable = true;
# # };
# };
# };
# })
# ++ [
# # Low level inventory overrides (comes at the end)
# {
# services."backups_2".autoIncludeMachines = true;
# services."backups_2".module = "borgbackup";
# }
# ];
# # buildClan :: [ Partial<Inventory> ] -> Inventory
# # foldl' (acc: v: lib.recursiveUpdate acc v) {} []
# inventory = [
# # import json
# {...}
# # power user flake
# {...}
# ]
# # With Module system
# # Pros: Easy to understand,
# # Cons: Verbose, hard to maintain
# # buildClan :: { modules = [ { config = Partial<Inventory>; options :: InventoryOptions; } } ]; } -> Inventory
# eval = lib.evalModules {
# modules = [
# {
# # Inventory Schema
# # Python validation
# options = {...}
# }
# {
# config = map lib.mkDefault
# (builtins.fromJSON (builtins.readFile ./inventory.json))
# }
# {
# # User provided
# config = {...}
# }
# # Later overrides.
# {
# lib.mkForce ...
# }
# ];
# }
# nixosConfigurations = lib.evalModules inventory;
# eval.config.inventory
# #
# eval.config.machines.jon#nixosConfig
# eval.config.machines.sara#nixosConfig
#
# {inventory, config, ...}:{
# hostname = config.machines.sara # Invalid
# hostname = inventory.machines.sara.hostname # Valid
# }
/*
# Type
buildInventory :: {
clanName :: string
machines :: {
${name} :: {
config :: {
# NixOS configuration
};
};
};
# ... More mapped inventory options
# i.e. shared config for all machines
} -> Inventory
*/
{
# all machines managed by Clan
inherit (clan) nixosConfigurations clanInternals;
# add the Clan cli tool to the dev shell
devShells.${system}.default = pkgs.mkShell {
packages = [ clan-core.packages.${system}.clan-cli ];
};
};
}

View File

@@ -1,5 +1,6 @@
{ ... }:
{ inputs, self, ... }:
{
flake.inventory = import ./default.nix { inherit inputs self; };
perSystem =
{ pkgs, config, ... }:
{
@@ -13,6 +14,7 @@
mkdir -p $out
'';
};
devShells.inventory-schema = pkgs.mkShell { inputsFrom = [ config.packages.inventory-schema ]; };
checks.inventory-schema-checks = pkgs.stdenv.mkDerivation {

View File

@@ -18,21 +18,19 @@
"meta": {
"name": "My backup"
},
"module": "borbackup-static",
"module": "borgbackup-static",
"machineConfig": {
"vyr": {
"vyr_machine": {
"roles": ["server"]
},
"vi": {
"vi_machine": {
"roles": ["client"]
},
"camina_machine": {
"roles": ["client"]
}
},
"config": {
"folders": ["/home", "/root", "/var", "/etc"]
}
"config": {}
}
}
}

View File

@@ -3,10 +3,10 @@
"camina_machine": {
"name": "camina"
},
"vyr": {
"vyr_machine": {
"name": "vyr"
},
"vi": {
"vi_machine": {
"name": "vi"
}
},
@@ -20,23 +20,23 @@
},
"module": "syncthing-static-peers",
"machineConfig": {
"vyr": {},
"vi": {},
"vyr_machine": {},
"vi_machine": {},
"camina_machine": {}
},
"config": {
"folders": {
"test": {
"path": "~/data/docs",
"devices": ["camina", "vyr", "vi"]
"devices": ["camina_machine", "vyr_machine", "vi_machine"]
},
"videos": {
"path": "~/data/videos",
"devices": ["camina", "vyr", "ezra"]
"devices": ["camina_machine", "vyr_machine"]
},
"playlist": {
"path": "~/data/playlist",
"devices": ["camina", "vyr", "ezra"]
"devices": ["camina_machine", "vi_machine"]
}
}
}