Inventory: implement borgbackup
Some checks failed
buildbot/nix-build .#checks.x86_64-linux.inventory-schema-checks Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-test-backup Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-test-backup Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-archlinux Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-deb Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-rpm Build done.
buildbot/nix-build .#checks.x86_64-linux.package-inventory-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-installer-apk Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.x86_64-linux.renderClanOptions Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-iso-installer Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-test-backup Build done.
buildbot/nix-build .#checks.aarch64-darwin.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.check-for-breakpoints Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-app-no-breakpoints Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-app-pytest Build done.
buildbot/nix-build .#checks.x86_64-linux.treefmt Build done.
buildbot/nix-build .#checks.aarch64-darwin.package-deploy-docs Build done.
buildbot/nix-build .#checks.aarch64-darwin.devShell-docs Build done.
buildbot/nix-build .#checks.aarch64-linux.devShell-docs Build done.
buildbot/nix-build .#checks.aarch64-darwin.package-module-docs Build done.
buildbot/nix-build .#checks.aarch64-darwin.package-function-schema Build done.
buildbot/nix-build .#checks.aarch64-linux.module-schema Build done.
buildbot/nix-build .#checks.aarch64-linux.package-docs Build done.
buildbot/nix-build .#checks.aarch64-linux.package-deploy-docs Build done.
buildbot/nix-build .#checks.aarch64-darwin.package-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-bash Build done.
buildbot/nix-build .#checks.aarch64-linux.package-function-schema Build done.
buildbot/nix-build .#checks.aarch64-darwin.package-module-schema Build done.
buildbot/nix-build .#checks.aarch64-darwin.module-schema Build done.
buildbot/nix-build .#checks.aarch64-linux.package-module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-e2fsprogs Build done.
buildbot/nix-build .#checks.aarch64-linux.package-module-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-fakeroot Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-git Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-nix Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-openssh Build done.
buildbot/nix-build .#checks.x86_64-linux."clan-dep-python3.11-mypy" Build done.
buildbot/nix-build .#checks.x86_64-linux."clan-dep-python3.11-qemu" Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-rsync Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-sops Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-sshpass Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-tor Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-zbar Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-pytest-without-core Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-app Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-dep-age Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-webview-ui Build done.
buildbot/nix-build .#checks.aarch64-linux.nixos-iso-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-jsonschema-example-valid Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.container Build done.
buildbot/nix-build .#checks.x86_64-linux.borgbackup Build done.
buildbot/nix-build .#checks.x86_64-linux.module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-default Build done.
buildbot/nix-build .#checks.x86_64-linux.devShell-inventory-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-app Build done.
buildbot/nix-build .#checks.x86_64-linux.matrix-synapse Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-cli-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-clan-ts-api Build done.
buildbot/nix-build .#checks.x86_64-linux.package-default Build done.
buildbot/nix-build .#checks.x86_64-linux.package-deploy-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-function-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-test_install_machine Build done.
buildbot/nix-build .#checks.x86_64-linux.package-impure-checks Build done.
buildbot/nix-build .#checks.x86_64-linux.deltachat Build done.
buildbot/nix-build .#checks.x86_64-linux.package-merge-after-ci Build done.
buildbot/nix-build .#checks.x86_64-linux.lib-jsonschema-nix-unit-tests Build done.
buildbot/nix-build .#checks.x86_64-linux.package-pending-reviews Build done.
buildbot/nix-build .#checks.x86_64-linux.package-tea-create-pr Build done.
buildbot/nix-build .#checks.x86_64-linux.package-webview-ui Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zerotier-members Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-docs Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zt-tcp-relay Build done.
buildbot/nix-build .#checks.x86_64-linux.package-module-schema Build done.
buildbot/nix-build .#checks.x86_64-linux.package-zerotierone Build done.
buildbot/nix-build .#checks.x86_64-linux.package-editor Build done.
buildbot/nix-build .#checks.x86_64-linux.package-moonlight-sunshine-accept Build done.
buildbot/nix-build .#checks.x86_64-linux.postgresql Build done.
buildbot/nix-build .#checks.x86_64-linux.secrets Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-iso-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.template-minimal Build done.
buildbot/nix-build .#checks.x86_64-linux.zt-tcp-relay Build done.
buildbot/nix-build .#checks.x86_64-linux.wayland-proxy-virtwl Build done.
buildbot/nix-build .#checks.x86_64-linux.nixos-flash-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.package-iso-installer Build done.
buildbot/nix-build .#checks.x86_64-linux.syncthing Build done.
buildbot/nix-build .#checks.x86_64-linux.package-gui-install-test-ubuntu-22-04 Build done.
buildbot/nix-build .#checks.x86_64-linux.clan-pytest-with-core Build done.
buildbot/nix-build .#checks.x86_64-linux.test-backups Build done.
buildbot/nix-build .#checks.x86_64-linux.flash Build done.
checks / checks-impure (pull_request) Successful in 2m8s
buildbot/nix-build .#checks.x86_64-linux.test-installation Build done.
buildbot/nix-eval Build done.

This commit is contained in:
Johannes Kirschbauer 2024-06-19 16:56:26 +02:00
parent afdfa6181b
commit a60b1bfafc
Signed by: hsjobeki
SSH Key Fingerprint: SHA256:vX3utDqig7Ph5L0JPv87ZTPb/w7cMzREKVZzzLFg9qU
6 changed files with 130 additions and 220 deletions

View File

@ -2,57 +2,36 @@
let
clanDir = config.clan.core.clanDir;
machineDir = clanDir + "/machines/";
cfg = config.clan.borgbackup-static;
machine_name = config.clan.core.machineName;
in
{
imports = [ ../borgbackup ];
options.clan.borgbackup-static = {
excludeMachines = lib.mkOption {
type = lib.types.listOf lib.types.str;
example = [ config.clan.core.machineName ];
default = [ ];
description = ''
Machines that should not be backuped.
Mutually exclusive with includeMachines.
If this is not empty, every other machine except the targets in the clan will be backuped by this module.
If includeMachines is set, only the included machines will be backuped.
'';
};
includeMachines = lib.mkOption {
type = lib.types.listOf lib.types.str;
example = [ config.clan.core.machineName ];
default = [ ];
description = ''
Machines that should be backuped.
Mutually exclusive with excludeMachines.
'';
};
targets = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = ''
Machines that should act as target machines for backups.
'';
};
# Inventory / Interface.nix
# options.clan.inventory.borgbackup-static.description.
options.clan.borgbackup-static.roles = lib.mkOption {
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
};
config.services.borgbackup.repos =
let
machines = builtins.readDir machineDir;
filteredMachines = builtins.attrNames (lib.filterAttrs (_: v: builtins.elem "client" v) cfg.roles);
borgbackupIpMachinePath = machines: machineDir + machines + "/facts/borgbackup.ssh.pub";
filteredMachines =
if ((builtins.length config.clan.borgbackup-static.includeMachines) != 0) then
lib.filterAttrs (name: _: (lib.elem name config.clan.borgbackup-static.includeMachines)) machines
else
lib.filterAttrs (name: _: !(lib.elem name config.clan.borgbackup-static.excludeMachines)) machines;
machinesMaybeKey = lib.mapAttrsToList (
machine: _:
machinesMaybeKey = builtins.map (
machine:
let
fullPath = borgbackupIpMachinePath machine;
in
if builtins.pathExists fullPath then machine else null
) filteredMachines;
machinesWithKey = lib.filter (x: x != null) machinesMaybeKey;
hosts = builtins.map (machine: {
name = machine;
value = {
@ -61,41 +40,20 @@ in
};
}) machinesWithKey;
in
lib.mkIf
(builtins.any (
target: target == config.clan.core.machineName
) config.clan.borgbackup-static.targets)
(if (builtins.listToAttrs hosts) != null then builtins.listToAttrs hosts else { });
lib.mkIf (builtins.elem "server" cfg.roles.${machine_name}) (
if (builtins.listToAttrs hosts) != null then builtins.listToAttrs hosts else { }
);
config.clan.borgbackup.destinations =
let
destinations = builtins.map (d: {
name = d;
value = {
repo = "borg@${d}:/var/lib/borgbackup/${config.clan.core.machineName}";
};
}) config.clan.borgbackup-static.targets;
in
lib.mkIf (builtins.any (
target: target == config.clan.core.machineName
) config.clan.borgbackup-static.includeMachines) (builtins.listToAttrs destinations);
servers = builtins.attrNames (lib.filterAttrs (_n: v: (builtins.elem "server" v)) cfg.roles);
config.assertions = [
{
assertion =
!(
((builtins.length config.clan.borgbackup-static.excludeMachines) != 0)
&& ((builtins.length config.clan.borgbackup-static.includeMachines) != 0)
);
message = ''
The options:
config.clan.borgbackup-static.excludeMachines = [${builtins.toString config.clan.borgbackup-static.excludeMachines}]
and
config.clan.borgbackup-static.includeMachines = [${builtins.toString config.clan.borgbackup-static.includeMachines}]
are mutually exclusive.
Use excludeMachines to exclude certain machines and backup the other clan machines.
Use include machines to only backup certain machines.
'';
}
];
destinations = builtins.map (server_name: {
name = server_name;
value = {
repo = "borg@${server_name}:/var/lib/borgbackup/${machine_name}";
};
}) servers;
in
lib.mkIf (builtins.elem "client" cfg.roles.${machine_name}) (builtins.listToAttrs destinations);
}

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"]
}
}
}