aboutsummaryrefslogtreecommitdiff
path: root/modules/scripts/zquota/default.nix
diff options
context:
space:
mode:
authortdback <tyler@tdback.net>2024-12-24 20:08:50 -0500
committertdback <tyler@tdback.net>2024-12-24 20:08:50 -0500
commit2f335a6c47b363189b976d18a8c7633bff4d7a33 (patch)
treeade55bb4f55a91ab34a1c859d8a849af8532ca77 /modules/scripts/zquota/default.nix
parent7643ff0660c93239d53406d331b3e026a20a8af4 (diff)
add zquota to easily monitor disk usage of zfs datasets
Diffstat (limited to 'modules/scripts/zquota/default.nix')
-rw-r--r--modules/scripts/zquota/default.nix77
1 files changed, 77 insertions, 0 deletions
diff --git a/modules/scripts/zquota/default.nix b/modules/scripts/zquota/default.nix
new file mode 100644
index 0000000..1dc1fbd
--- /dev/null
+++ b/modules/scripts/zquota/default.nix
@@ -0,0 +1,77 @@
+{ config, lib, pkgs, ... }:
+with lib;
+let
+ cfg = config.services.zquota;
+
+ zquota = let hostname = config.networking.hostName; in
+ pkgs.writeShellScriptBin "zquota" ''
+ #!/usr/bin/env bash
+
+ if [ "$#" -ne 2 ]; then
+ echo "failed to provide both a dataset and quota" >&2
+ exit 1
+ fi
+
+ DATASET="$1"
+ QUOTA="$2"
+
+ if [ -n "$(echo "$QUOTA" | tr -d 0-9.)" ]; then
+ echo "failed to provide a valid quota" >&2
+ exit 1
+ fi
+
+ USED=$(${getExe pkgs.zfs} list -Hpo used "$DATASET" 2>/dev/null) || {
+ echo "failed to provide a valid dataset" >&2
+ exit 1
+ }
+
+ USAGE=$(${getExe pkgs.bc} <<< "scale=2; $NUM / 1024^3")
+
+ DIFF=$(${getExe pkgs.bc} <<< "scale=2; $NUM - $QUOTA")
+
+ (( $(awk '{ print ($1 > $2) }' <<< "$USAGE $QUOTA") )) &&
+ /run/current-system/sw/bin/pushover -t "${hostname} quota exceeded" \
+ "dataset $DATASET on ${hostname} has exceeded quota by ''${DIFF}GB"
+ '';
+in
+{
+ options = {
+ services.zquota = {
+ enable = mkEnableOption "zquota";
+ quotas = mkOption {
+ default = { };
+ type = types.attrsOf types.int;
+ description = "Attribute set of ZFS dataset and disk quota (in GB).";
+ };
+ dates = mkOption {
+ default = "daily";
+ type = types.str;
+ description = ''
+ How often quota checks are performed.
+
+ This value must be a calendar event specified by
+ {manpage}`systemd.time(7)`.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ environment.systemPackages = [ zquota ];
+
+ systemd.services."zquota" = {
+ description = "Perform and report routine quota checks on ZFS datasets";
+ serviceConfig.Type = "oneshot";
+ script = strings.concatStringsSep "\n" <| mapAttrsToList (
+ dataset: quota: "/run/current-system/sw/bin/zquota ${dataset} ${builtins.toString quota}"
+ ) cfg.quotas;
+ };
+ systemd.timers."zquota" = {
+ wantedBy = [ "timers.target" ];
+ timerConfig = {
+ OnCalendar = cfg.dates;
+ Persistent = true;
+ };
+ };
+ };
+}