From 8fbe982752bbc276e99008b581f8e3b7d06c60d9 Mon Sep 17 00:00:00 2001
From: jehad <jehad@leastauthority.com>
Date: Thu, 18 Aug 2022 12:38:20 +0200
Subject: [PATCH] working update without configurable token count

Co-authored-by: Benoit Donneaux <benoit@leastauthority.com>
Signed-off-by: Benoit Donneaux <benoit@leastauthority.com>
---
 morph/grid/hro-cloud/config.json              |  18 +++
 morph/grid/hro-cloud/grid.nix                 | 130 ++++++++++++++++++
 .../grid/hro-cloud/public-keys/deploy_key.pub |   1 +
 .../public-keys/monitoringvpn/172.23.23.1.pub |   1 +
 .../monitoringvpn/172.23.23.11.pub            |   1 +
 .../monitoringvpn/172.23.23.21.pub            |   1 +
 .../monitoringvpn/172.23.23.22.pub            |   1 +
 .../monitoringvpn/172.23.23.23.pub            |   1 +
 .../monitoringvpn/172.23.23.24.pub            |   1 +
 .../monitoringvpn/172.23.23.25.pub            |   1 +
 .../public-keys/monitoringvpn/server.pub      |   1 +
 morph/grid/hro-cloud/public-keys/users.nix    |   6 +
 morph/grid/hro-cloud/storage001-config.nix    |  14 ++
 morph/grid/hro-cloud/storage001-hardware.nix  |  37 +++++
 morph/grid/hro-cloud/storage002-config.nix    |  14 ++
 morph/grid/hro-cloud/storage002-hardware.nix  |  40 ++++++
 morph/grid/hro-cloud/storage003-config.nix    |  11 ++
 morph/grid/hro-cloud/storage003-hardware.nix  |  41 ++++++
 morph/lib/default.nix                         |   2 +
 morph/lib/issuer-monitoring-ovh.nix           |  40 ++++++
 morph/lib/issuer-payments-ovh.nix             |  36 +++++
 morph/lib/storage.nix                         |   2 +-
 nixos/modules/100tb.nix                       |  30 +++-
 23 files changed, 427 insertions(+), 3 deletions(-)
 create mode 100644 morph/grid/hro-cloud/config.json
 create mode 100644 morph/grid/hro-cloud/grid.nix
 create mode 100644 morph/grid/hro-cloud/public-keys/deploy_key.pub
 create mode 100644 morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.1.pub
 create mode 100644 morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.11.pub
 create mode 100644 morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.21.pub
 create mode 100644 morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.22.pub
 create mode 100644 morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.23.pub
 create mode 100644 morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.24.pub
 create mode 100644 morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.25.pub
 create mode 100644 morph/grid/hro-cloud/public-keys/monitoringvpn/server.pub
 create mode 100644 morph/grid/hro-cloud/public-keys/users.nix
 create mode 100644 morph/grid/hro-cloud/storage001-config.nix
 create mode 100644 morph/grid/hro-cloud/storage001-hardware.nix
 create mode 100644 morph/grid/hro-cloud/storage002-config.nix
 create mode 100644 morph/grid/hro-cloud/storage002-hardware.nix
 create mode 100644 morph/grid/hro-cloud/storage003-config.nix
 create mode 100644 morph/grid/hro-cloud/storage003-hardware.nix
 create mode 100644 morph/lib/issuer-monitoring-ovh.nix
 create mode 100644 morph/lib/issuer-payments-ovh.nix

diff --git a/morph/grid/hro-cloud/config.json b/morph/grid/hro-cloud/config.json
new file mode 100644
index 00000000..dca2b2ec
--- /dev/null
+++ b/morph/grid/hro-cloud/config.json
@@ -0,0 +1,18 @@
+{ "domain": "deerfield.leastauthority.com"
+, "publicStoragePort": 8898
+, "privateKeyPath": "./private-keys"
+, "publicKeyPath": "./public-keys"
+, "monitoringvpnEndpoint": "monitoring.deerfield.leastauthority.com:51820"
+, "passValue": 1000000
+, "issuerDomains": [
+    "payments.deerfield.leastauthority.com"
+  ]
+, "monitoringDomains": [
+    "monitoring.deerfield.leastauthority.com"
+]
+, "letsEncryptAdminEmail": "infrastructure@leastauthority.com"
+, "allowedChargeOrigins": [
+    "https://leastauthority.com"
+  ]
+, "monitoringGoogleOAuthClientID": ""
+}
diff --git a/morph/grid/hro-cloud/grid.nix b/morph/grid/hro-cloud/grid.nix
new file mode 100644
index 00000000..bd7ee0f6
--- /dev/null
+++ b/morph/grid/hro-cloud/grid.nix
@@ -0,0 +1,130 @@
+# See morph/grid/local/grid.nix for additional commentary.
+let
+  gridlib = import ../../lib;
+  grid-config = builtins.fromJSON (builtins.readFile ./config.json);
+
+  # Module with per-grid configuration
+  grid-module = {config, ...}: {
+    imports = [
+      gridlib.base
+      # Allow us to remotely trigger updates to this system.
+      ../../../nixos/modules/deployment.nix
+      # Give it a good SSH configuration.
+      ../../../nixos/modules/ssh.nix
+    ];
+    services.private-storage.sshUsers = import ./public-keys/users.nix;
+    networking.domain = grid-config.domain;
+    # Convert relative paths to absolute so library code can resolve names
+    # correctly.
+    grid = {
+      publicKeyPath = toString ./. + "/${grid-config.publicKeyPath}";
+      privateKeyPath = toString ./. + "/${grid-config.privateKeyPath}";
+      inherit (grid-config) monitoringvpnEndpoint letsEncryptAdminEmail;
+    };
+    # Configure deployment management authorization for all systems in the grid.
+    services.private-storage.deployment = {
+      authorizedKey = builtins.readFile "${config.grid.publicKeyPath}/deploy_key.pub";
+      gridName = "production";
+    };
+  };
+  payments = {
+    imports = [
+      gridlib.issuer
+      gridlib.hardware-payments-ovh
+      grid-module
+    ];
+    config = {
+      grid.monitoringvpnIPv4 = "172.23.23.11";
+      grid.issuer = {
+        inherit (grid-config) issuerDomains allowedChargeOrigins;
+      };
+    };
+  };
+
+  monitoring = {
+    imports = [
+      gridlib.monitoring
+      gridlib.hardware-monitoring-ovh
+      grid-module
+    ];
+    config = {
+      grid.monitoringvpnIPv4 = "172.23.23.1";
+      grid.monitoring = {
+        inherit paymentExporterTargets blackboxExporterHttpsTargets;
+        inherit (grid-config) monitoringDomains;
+        googleOAuthClientID = grid-config.monitoringGoogleOAuthClientID;
+        enableSlackAlert = false;
+      };
+      system.stateVersion = "19.09";
+    };
+  };
+
+  defineStorageNode = name: { vpnIP, stateVersion }:
+  let
+    nodecfg = import "${./.}/${name}-config.nix";
+    hardware ="${./.}/${name}-hardware.nix";
+  in {
+    imports = [
+      # Get some of the very lowest-level system configuration for this
+      # node.  This isn't all *completely* hardware related.  Maybe some
+      # more factoring is in order, someday.
+      hardware
+
+      # Slightly awkwardly, enable some of our hardware / network / bootloader options.
+      ../../../nixos/modules/100tb.nix
+
+      # At least some of our storage nodes utilize MegaRAID storage controllers.
+      # Monitor their array status.
+      ../../../nixos/modules/monitoring/exporters/megacli2prom.nix
+
+      # Get all of the configuration that is common across all storage nodes.
+      gridlib.storage
+      # Also configure deployment management authorization
+      grid-module
+    ];
+
+    config = {
+      grid.monitoringvpnIPv4 = vpnIP;
+      grid.storage = {
+        inherit (grid-config) passValue publicStoragePort;
+      };
+      system.stateVersion = stateVersion;
+
+      # And supply configuration for those hardware / network / bootloader
+      # options.  See the 100tb module for handling of this value.  The module
+      # name is quoted because `1` makes `100tb` look an awful lot like a
+      # number.
+      "100tb".config = nodecfg;
+
+      # Enable statistics gathering for MegaRAID cards.
+      # TODO would be nice to enable only on machines that have such a device.
+      services.private-storage.monitoring.exporters.megacli2prom.enable = true;
+
+      # Disable Borg Backup for this grid!
+      services.private-storage.borgbackup.enable = false;
+    };
+  };
+
+  # Define all of the storage nodes for this grid.
+  storageNodes = builtins.mapAttrs defineStorageNode {
+    storage001 = { vpnIP = "172.23.23.21"; stateVersion = "19.09"; };
+    storage002 = { vpnIP = "172.23.23.22"; stateVersion = "19.09"; };
+    storage003 = { vpnIP = "172.23.23.23"; stateVersion = "19.09"; };
+  };
+
+  paymentExporterTargets = [ "payments.monitoringvpn" ];
+  blackboxExporterHttpsTargets = [
+    "https://deerfield.leastauthority.com/"
+    "https://www.deerfield.leastauthority.com/"
+    "https://payments.deerfield.leastauthority.com/"
+    "https://monitoring.deerfield.leastauthority.com/"
+  ];
+
+in {
+  network = {
+    description = "HRO Grid";
+    inherit (gridlib) pkgs;
+  };
+  inherit payments;
+  inherit monitoring;
+} // storageNodes
diff --git a/morph/grid/hro-cloud/public-keys/deploy_key.pub b/morph/grid/hro-cloud/public-keys/deploy_key.pub
new file mode 100644
index 00000000..9338b184
--- /dev/null
+++ b/morph/grid/hro-cloud/public-keys/deploy_key.pub
@@ -0,0 +1 @@
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC2ME4kxDgS5KtwdITfq4hKuB6mQDv2zYsPcUlhXhZkS jehad@nixos
\ No newline at end of file
diff --git a/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.1.pub b/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.1.pub
new file mode 100644
index 00000000..5e1f8829
--- /dev/null
+++ b/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.1.pub
@@ -0,0 +1 @@
+An7g9oexXQizNu6PTNWuLHDprwd5GydHHd2fuImvhGs=
diff --git a/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.11.pub b/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.11.pub
new file mode 100644
index 00000000..ca6afb60
--- /dev/null
+++ b/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.11.pub
@@ -0,0 +1 @@
+mVXVGBpS/rHp5qQG8izNdP/Tpj5TXO9CA4CGJ5c0cXk=
diff --git a/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.21.pub b/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.21.pub
new file mode 100644
index 00000000..ebd2e8f7
--- /dev/null
+++ b/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.21.pub
@@ -0,0 +1 @@
+aKsdXaE+1YINE71pX2BLiaIrxeSXbr/F/lHo/gDSxG4=
diff --git a/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.22.pub b/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.22.pub
new file mode 100644
index 00000000..2f5ca047
--- /dev/null
+++ b/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.22.pub
@@ -0,0 +1 @@
+GCnw0k/Y4HDkRCSpZ/hrpMIGQt6LViS7ub25cpbHm3Q=
diff --git a/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.23.pub b/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.23.pub
new file mode 100644
index 00000000..07cf3a9a
--- /dev/null
+++ b/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.23.pub
@@ -0,0 +1 @@
+8xMB69/yQDyjfXbPWn3VWqXKqRT/yCZ/RGjy1hLBE2Y=
diff --git a/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.24.pub b/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.24.pub
new file mode 100644
index 00000000..c54c728a
--- /dev/null
+++ b/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.24.pub
@@ -0,0 +1 @@
+fPUnFOzBZRJDBdSR6iS5AaC40KKy/2REiM16hx+woxk=
diff --git a/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.25.pub b/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.25.pub
new file mode 100644
index 00000000..0ae6bb2a
--- /dev/null
+++ b/morph/grid/hro-cloud/public-keys/monitoringvpn/172.23.23.25.pub
@@ -0,0 +1 @@
+qS4rT+zjWrbXDhtEF4oyGv8/5oCIE1ZU9FF+O6AL8V4=
diff --git a/morph/grid/hro-cloud/public-keys/monitoringvpn/server.pub b/morph/grid/hro-cloud/public-keys/monitoringvpn/server.pub
new file mode 100644
index 00000000..5e1f8829
--- /dev/null
+++ b/morph/grid/hro-cloud/public-keys/monitoringvpn/server.pub
@@ -0,0 +1 @@
+An7g9oexXQizNu6PTNWuLHDprwd5GydHHd2fuImvhGs=
diff --git a/morph/grid/hro-cloud/public-keys/users.nix b/morph/grid/hro-cloud/public-keys/users.nix
new file mode 100644
index 00000000..953c20d1
--- /dev/null
+++ b/morph/grid/hro-cloud/public-keys/users.nix
@@ -0,0 +1,6 @@
+let
+  jbaeth = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC2ME4kxDgS5KtwdITfq4hKuB6mQDv2zYsPcUlhXhZkS jehad@nixos"];
+in {
+  "root" = jbaeth;
+  "jbaeth" = jbaeth;
+}
diff --git a/morph/grid/hro-cloud/storage001-config.nix b/morph/grid/hro-cloud/storage001-config.nix
new file mode 100644
index 00000000..d4f4082c
--- /dev/null
+++ b/morph/grid/hro-cloud/storage001-config.nix
@@ -0,0 +1,14 @@
+#100tb
+{ "hostId" = "00000001";
+  "interface" = "eno1";
+  "publicIPv4" = "185.225.209.174";
+  "prefixLength" = 24;
+  "gateway" = "185.225.209.173";
+  "gatewayInterface" = "eno1";
+  "grubDeviceID" = "nodev"; #might be wrong
+  "efiSupport" = true;
+  #"efiInstallAsRemovable" = true;
+  "fsIdentifier" = "label";
+  #"canTouchEfiVariables" = false;
+  "systemd-boot" = false;
+}
diff --git a/morph/grid/hro-cloud/storage001-hardware.nix b/morph/grid/hro-cloud/storage001-hardware.nix
new file mode 100644
index 00000000..80608f1a
--- /dev/null
+++ b/morph/grid/hro-cloud/storage001-hardware.nix
@@ -0,0 +1,37 @@
+# Do not modify this file!  It was generated by ‘nixos-generate-config’
+# and may be overwritten by future invocations.  Please make changes
+# to /etc/nixos/configuration.nix instead.
+{ config, lib, pkgs, ... }:
+
+{
+  imports =
+    [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
+    ];
+
+  boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "sr_mod" ];
+  boot.initrd.kernelModules = [ ];
+  boot.kernelModules = [ "kvm-intel" ];
+  boot.extraModulePackages = [ ];
+
+  fileSystems."/" =
+    { device = "/dev/disk/by-uuid/d0837e6f-72cb-4ffa-85ba-fd57bbbd9a97";
+      fsType = "ext4";
+    };
+
+  fileSystems."/boot" =
+    { device = "/dev/disk/by-uuid/915E-08F9";
+      fsType = "vfat";
+    };
+
+    fileSystems."/storage" =
+    { device = "root";
+      fsType = "zfs";
+    };
+
+  swapDevices =
+    [ { device = "/dev/disk/by-uuid/45eb994e-0d1b-4903-9412-920f0ba017c9"; }
+    ];
+
+  nix.maxJobs = lib.mkDefault 24;
+  powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
+}
diff --git a/morph/grid/hro-cloud/storage002-config.nix b/morph/grid/hro-cloud/storage002-config.nix
new file mode 100644
index 00000000..270160fd
--- /dev/null
+++ b/morph/grid/hro-cloud/storage002-config.nix
@@ -0,0 +1,14 @@
+#Servermania
+{ "hostId" = "00000002";
+  "interface" = "eno1";
+  "publicIPv4" = "104.144.74.50";
+  "prefixLength" = 29;
+  "gateway" = "104.144.74.49";
+  "gatewayInterface" = "eno1";
+  "grubDeviceID" = "nodev"; #nodev if we want to use efi (double check)
+  #"canTouchEfiVariables" = false;
+  "efiSupport" = true;
+  #"efiInstallAsRemovable" = true;
+  "fsIdentifier" = "label";
+  "systemd-boot" = false;
+}
diff --git a/morph/grid/hro-cloud/storage002-hardware.nix b/morph/grid/hro-cloud/storage002-hardware.nix
new file mode 100644
index 00000000..c011e02f
--- /dev/null
+++ b/morph/grid/hro-cloud/storage002-hardware.nix
@@ -0,0 +1,40 @@
+# Do not modify this file!  It was generated by ‘nixos-generate-config’
+# and may be overwritten by future invocations.  Please make changes
+# to /etc/nixos/configuration.nix instead.
+{ config, lib, pkgs, ... }:
+
+{
+  imports =
+    [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
+    ];
+
+  boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "ehci_pci" "megaraid_sas" "usbhid" "usb_storage" "sd_mod" "sr_mod" ];
+  boot.initrd.kernelModules = [ ];
+  boot.kernelModules = [ "kvm-intel" ];
+  boot.extraModulePackages = [ ];
+  boot.kernel.sysctl = { "vm.swappiness" = 0; };
+
+  fileSystems."/" =
+    { device = "/dev/disk/by-uuid/c8d29070-c5d3-4cfb-9bb2-c14d3727c45b";
+      fsType = "ext4";
+    };
+
+  # Manually created using:
+  #   zpool create -m legacy -o ashift=12 root raidz /dev/disk/by-id/{wwn-0x5000cca25dcc966d,wwn-0x5000cca24cec02e3,wwn-0x5000cca25dcc7711,wwn-0x5000cca25dccca63,wwn-0x5000cca25dcc74b6,wwn-0x5000cca25dcc4591,wwn-0x5000cca25dcc4461}
+  fileSystems."/storage" = {
+    device = "root";
+    fsType = "zfs";
+  };
+
+  fileSystems."/boot" =
+    { device = "/dev/disk/by-uuid/3648-C8F5";
+      fsType = "vfat";
+    };
+
+  swapDevices =
+    [ { device = "/dev/disk/by-uuid/51e0652f-46c9-4150-95a1-223f37154d4f"; }
+    ];
+
+  nix.maxJobs = lib.mkDefault 24;
+  powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
+}
diff --git a/morph/grid/hro-cloud/storage003-config.nix b/morph/grid/hro-cloud/storage003-config.nix
new file mode 100644
index 00000000..6abce610
--- /dev/null
+++ b/morph/grid/hro-cloud/storage003-config.nix
@@ -0,0 +1,11 @@
+#OVH
+{ "hostId" = "00000001";
+  "interface" = "eno3";
+  "publicIPv4" = "151.80.28.108";
+  "prefixLength" = 24;
+  "gateway" = "151.80.28.254";
+  "gatewayInterface" = "eno3";
+  "grubDeviceID" = "nodev";
+  #"grubDeviceID" = "nvme-eui.e8238fa6bf530001001b448b463b77bf";
+  "systemd-boot" = true;
+}
diff --git a/morph/grid/hro-cloud/storage003-hardware.nix b/morph/grid/hro-cloud/storage003-hardware.nix
new file mode 100644
index 00000000..3ff55090
--- /dev/null
+++ b/morph/grid/hro-cloud/storage003-hardware.nix
@@ -0,0 +1,41 @@
+# Do not modify this file!  It was generated by ‘nixos-generate-config’
+# and may be overwritten by future invocations.  Please make changes
+# to /etc/nixos/configuration.nix instead.
+{ config, lib, pkgs, modulesPath, ... }:
+
+{
+  imports =
+    [ (modulesPath + "/installer/scan/not-detected.nix")
+    ];
+
+  boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "ehci_pci" "megaraid_sas" "usbhid" ];
+  boot.initrd.kernelModules = [ ];
+  boot.kernelModules = [ "kvm-intel" ];
+  boot.extraModulePackages = [ ];
+  boot.supportedFilesystems = [ "zfs" ];
+  boot.kernel.sysctl = { "vm.swappiness" = 0; };
+
+  fileSystems."/" =
+    { device = "/dev/disk/by-uuid/56a050e2-daee-40e2-becb-17d1f7908ceb";
+      fsType = "ext4";
+    };
+
+  fileSystems."/boot" =
+    { device = "/dev/disk/by-uuid/B89B-F110";    
+      fsType = "vfat";
+    };
+
+  # Manually created using:
+  #   zpool create -f -m legacy -o ashift=12 root raidz /dev/disk/by-id/{wwn-0x5000cca249d43969,wwn-0x5000039a8bc0075e,wwn-0x5000cca249d44a67,wwn-0x5000cca249d46730,wwn-0x5000cca25dcc719c,wwn-0x5000cca25dcc0241,wwn-0x5000039a8bc00765}
+  fileSystems."/storage" =
+    { device = "root";
+      fsType = "zfs";
+    };
+
+  swapDevices =     
+    [ { device = "/dev/disk/by-uuid/e47cfddc-485c-46fb-9004-c9b8619b81ff"; }
+    ];
+
+  nix.maxJobs = lib.mkDefault 24;
+  powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
+}
diff --git a/morph/lib/default.nix b/morph/lib/default.nix
index c99c19a5..6b91aab9 100644
--- a/morph/lib/default.nix
+++ b/morph/lib/default.nix
@@ -6,6 +6,8 @@
 
   hardware-aws = import ./issuer-aws.nix;
   hardware-vagrant = import ./hardware-vagrant.nix;
+  hardware-monitoring-ovh = import ./issuer-monitoring-ovh.nix;
+  hardware-payments-ovh = import ./issuer-payments-ovh.nix;
 
   issuer = import ./issuer.nix;
   storage = import ./storage.nix;
diff --git a/morph/lib/issuer-monitoring-ovh.nix b/morph/lib/issuer-monitoring-ovh.nix
new file mode 100644
index 00000000..51a51afd
--- /dev/null
+++ b/morph/lib/issuer-monitoring-ovh.nix
@@ -0,0 +1,40 @@
+{ modulesPath, name, lib, ... }: {
+
+  imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
+  boot.loader.grub.device = "/dev/sda";
+  boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" ];
+  boot.initrd.kernelModules = [ "nvme" ];
+  fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; };
+  
+
+
+  swapDevices = [ {
+    device = "/var/swapfile";
+    size = 4096; # megabytes
+    randomEncryption = true;
+  } ];
+
+  # Break the tie between AWS and morph for the hostname by forcing the
+  # morph-supplied name.  See also
+  # <https://github.com/DBCDK/morph/issues/146>.
+  networking.hostName = name;
+
+  # Mount a dedicated filesystem (ideally on a dedicated volume, but that's
+  # beyond control of this particular part of the system) for the
+  # PaymentServer voucher database.  This makes it easier to manage for
+  # tasks like backup/recovery and encryption.
+  services.private-storage-issuer.databaseFileSystem = {
+    label = "zkapissuer-data";
+  };
+
+  # Clean up packages after a while
+  nix.gc = {
+    automatic = true;
+    dates = "weekly";
+    options = "--delete-older-than 30d";
+  };
+
+  # Turn on automatic optimization of nix store
+  # https://nixos.wiki/wiki/Storage_optimization
+  nix.autoOptimiseStore = true;
+}
diff --git a/morph/lib/issuer-payments-ovh.nix b/morph/lib/issuer-payments-ovh.nix
new file mode 100644
index 00000000..73c606f6
--- /dev/null
+++ b/morph/lib/issuer-payments-ovh.nix
@@ -0,0 +1,36 @@
+{ modulesPath, name, lib, ... }: {
+
+  imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
+  boot.loader.grub.device = "/dev/sda";
+  fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; };
+  
+  swapDevices = [ {
+    device = "/var/swapfile";
+    size = 4096; # megabytes
+    randomEncryption = true;
+  } ];
+
+  # Break the tie between AWS and morph for the hostname by forcing the
+  # morph-supplied name.  See also
+  # <https://github.com/DBCDK/morph/issues/146>.
+  networking.hostName = name;
+
+  # Mount a dedicated filesystem (ideally on a dedicated volume, but that's
+  # beyond control of this particular part of the system) for the
+  # PaymentServer voucher database.  This makes it easier to manage for
+  # tasks like backup/recovery and encryption.
+  services.private-storage-issuer.databaseFileSystem = {
+    label = "zkapissuer-data";
+  };
+
+  # Clean up packages after a while
+  nix.gc = {
+    automatic = true;
+    dates = "weekly";
+    options = "--delete-older-than 30d";
+  };
+
+  # Turn on automatic optimization of nix store
+  # https://nixos.wiki/wiki/Storage_optimization
+  nix.autoOptimiseStore = true;
+}
diff --git a/morph/lib/storage.nix b/morph/lib/storage.nix
index 1fd8c26c..37efb8df 100644
--- a/morph/lib/storage.nix
+++ b/morph/lib/storage.nix
@@ -47,7 +47,7 @@ in {
     services.private-storage.monitoring.exporters.node.enable = true;
     services.private-storage.monitoring.exporters.tahoe.enable = true;
 
-    services.private-storage.borgbackup.enable = true;
+    services.private-storage.borgbackup.enable = lib.mkDefault true;
 
     # Turn on the Private Storage (Tahoe-LAFS) service.
     services.private-storage = {
diff --git a/nixos/modules/100tb.nix b/nixos/modules/100tb.nix
index 87554ef3..ef57324c 100644
--- a/nixos/modules/100tb.nix
+++ b/nixos/modules/100tb.nix
@@ -69,6 +69,32 @@ let
       example = "wwn-0x5000c500936410b9";
       description = "The ID of the disk on which to install grub.";
     };
+    fsIdentifier = lib.mkOption
+    { type = lib.types.str;
+      example = "nixos";
+      description = "Determines how GRUB will identify devices when generating the configuration file";
+    };
+    efiInstallAsRemovable = lib.mkOption
+    { type = lib.types.bool;
+      example = false;
+      description = "Whether to invoke grub-install with --removable";
+    };
+    efiSupport = lib.mkOption
+    { type = lib.types.bool;
+      example = false;
+      description = "Whether GRUB should be built with EFI support. EFI support is only available for GRUB v2.";
+    };
+    canTouchEfiVariables = lib.mkOption
+    { type = lib.types.bool;
+      example = false;
+      description = "Fill later";
+    };
+    systemd-boot = lib.mkOption
+    { type = lib.types.bool;
+      example = false;
+      description = "Fill later";
+    };
+
   };
 in {
   # Here we actually define the module's options.  They're what we said they
@@ -103,8 +129,8 @@ in {
   config =
   { boot.loader.grub.enable = true;
     boot.loader.grub.version = 2;
-    boot.loader.grub.device = "/dev/disk/by-id/${cfg.grubDeviceID}";
-
+    boot.loader.grub.device = if cfg.grubDeviceID == "nodev"  then "nodev" else "/dev/disk/by-id/${cfg.grubDeviceID}";
+    boot.loader.systemd-boot.enable = if cfg.systemd-boot == ""  then false else cfg.systemd-boot; 
     boot.loader.timeout = 10;
     networking.firewall.enable = false;
 
-- 
GitLab