diff options
Diffstat (limited to 'lass')
-rw-r--r-- | lass/3modules/default.nix | 1 | ||||
-rw-r--r-- | lass/3modules/drbd.nix | 118 |
2 files changed, 119 insertions, 0 deletions
diff --git a/lass/3modules/default.nix b/lass/3modules/default.nix index 570bb45be..3a0b1306c 100644 --- a/lass/3modules/default.nix +++ b/lass/3modules/default.nix @@ -2,6 +2,7 @@ _: { imports = [ ./dnsmasq.nix + ./drbd.nix ./folderPerms.nix ./hosts.nix ./klem.nix diff --git a/lass/3modules/drbd.nix b/lass/3modules/drbd.nix new file mode 100644 index 000000000..816e58f0a --- /dev/null +++ b/lass/3modules/drbd.nix @@ -0,0 +1,118 @@ +{ config, lib, pkgs, ... }: let + cfg = config.lass.drbd; + slib = import <stockholm/lib>; +in { + options = { + lass.drbd = lib.mkOption { + default = {}; + type = lib.types.attrsOf (lib.types.submodule ({ config, ... }: { + options = { + name = lib.mkOption { + type = lib.types.str; + default = config._module.args.name; + }; + blockMinor = lib.mkOption { + type = lib.types.int; + default = lib.mod (slib.genid config.name) 16000; # TODO get max_id fron drbd + }; + port = lib.mkOption { + type = lib.types.int; + default = 20000 + config.blockMinor; + }; + peers = lib.mkOption { + type = lib.types.listOf slib.types.host; + }; + disk = lib.mkOption { + type = lib.types.str; + default = "/dev/loop${toString config.blockMinor}"; + }; + drbdConfig = lib.mkOption { + type = lib.types.path; + internal = true; + default = pkgs.writeText "drbd-${config.name}.conf" '' + resource ${config.name} { + net { + protocol a; + ping-int 10; + } + device minor ${toString config.blockMinor}; + disk ${config.disk}; + meta-disk internal; + ${slib.indent (lib.concatStrings (lib.imap1 (i: peer: /* shell */ '' + on ${peer.name} { + address ${peer.nets.retiolum.ip4.addr}:${toString config.port}; + node-id ${toString i}; + } + '') config.peers))} + connection-mesh { + hosts ${lib.concatMapStringsSep " " (peer: peer.name) config.peers}; + } + } + ''; + }; + }; + })); + }; + }; + config = lib.mkIf (cfg != {}) { + boot.extraModulePackages = [ + (pkgs.linuxPackages.callPackage ../5pkgs/drbd9/default.nix {}) + ]; + boot.extraModprobeConfig = '' + options drbd usermode_helper=/run/current-system/sw/bin/drbdadm + ''; + services.udev.packages = [ pkgs.drbd ]; + boot.kernelModules = [ "drbd" ]; + + environment.systemPackages = [ pkgs.drbd ]; + + + networking.firewall.allowedTCPPorts = map (device: device.port) (lib.attrValues cfg); + systemd.services = lib.mapAttrs' (_: device: + lib.nameValuePair "drbd-${device.name}" { + after = [ "systemd-udev.settle.service" "network.target" ]; + wants = [ "systemd-udev.settle.service" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + RemainAfterExit = true; + ExecStart = pkgs.writers.writeDash "start-drbd-${device.name}" '' + set -efux + mkdir -p /var/lib/sync-containers2 + ${lib.optionalString (device.disk == "/dev/loop${toString device.blockMinor}") '' + if ! test -e /var/lib/sync-containers2/${device.name}.disk; then + truncate -s 10G /var/lib/sync-containers2/${device.name}.disk + fi + if ! ${pkgs.util-linux}/bin/losetup /dev/loop${toString device.blockMinor}; then + ${pkgs.util-linux}/bin/losetup /dev/loop${toString device.blockMinor} /var/lib/sync-containers2/${device.name}.disk + fi + ''} + if ! ${pkgs.drbd}/bin/drbdadm adjust ${device.name}; then + ${pkgs.drbd}/bin/drbdadm down ${device.name} + ${pkgs.drbd}/bin/drbdadm create-md ${device.name} + ${pkgs.drbd}/bin/drbdadm up ${device.name} + fi + ''; + ExecStop = pkgs.writers.writeDash "stop-drbd-${device.name}" '' + set -efux + ${pkgs.drbd}/bin/drbdadm -c ${device.drbdConfig} down ${device.name} + ${lib.optionalString (device.disk == "/dev/loop${toString device.blockMinor}") '' + ${pkgs.util-linux}/bin/losetup -d /dev/loop${toString device.blockMinor} + ''} + ''; + }; + } + ) cfg; + + + environment.etc."drbd.conf".text = '' + global { + usage-count yes; + } + + ${lib.concatMapStrings (device: /* shell */ '' + include ${device.drbdConfig}; + '') (lib.attrValues cfg)} + ''; + }; +} + |