aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/nixos/modules/services/misc/snapper.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/services/misc/snapper.nix')
-rw-r--r--nixpkgs/nixos/modules/services/misc/snapper.nix152
1 files changed, 152 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/services/misc/snapper.nix b/nixpkgs/nixos/modules/services/misc/snapper.nix
new file mode 100644
index 00000000000..6f3aaa973a0
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/misc/snapper.nix
@@ -0,0 +1,152 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+ cfg = config.services.snapper;
+in
+
+{
+ options.services.snapper = {
+
+ snapshotInterval = mkOption {
+ type = types.str;
+ default = "hourly";
+ description = ''
+ Snapshot interval.
+
+ The format is described in
+ <citerefentry><refentrytitle>systemd.time</refentrytitle>
+ <manvolnum>7</manvolnum></citerefentry>.
+ '';
+ };
+
+ cleanupInterval = mkOption {
+ type = types.str;
+ default = "1d";
+ description = ''
+ Cleanup interval.
+
+ The format is described in
+ <citerefentry><refentrytitle>systemd.time</refentrytitle>
+ <manvolnum>7</manvolnum></citerefentry>.
+ '';
+ };
+
+ filters = mkOption {
+ type = types.nullOr types.lines;
+ default = null;
+ description = ''
+ Global display difference filter. See man:snapper(8) for more details.
+ '';
+ };
+
+ configs = mkOption {
+ default = { };
+ example = literalExample {
+ home = {
+ subvolume = "/home";
+ extraConfig = ''
+ ALLOW_USERS="alice"
+ '';
+ };
+ };
+
+ description = ''
+ Subvolume configuration
+ '';
+
+ type = types.attrsOf (types.submodule {
+ options = {
+ subvolume = mkOption {
+ type = types.path;
+ description = ''
+ Path of the subvolume or mount point.
+ This path is a subvolume and has to contain a subvolume named
+ .snapshots.
+ See also man:snapper(8) section PERMISSIONS.
+ '';
+ };
+
+ fstype = mkOption {
+ type = types.enum [ "btrfs" ];
+ default = "btrfs";
+ description = ''
+ Filesystem type. Only btrfs is stable and tested.
+ '';
+ };
+
+ extraConfig = mkOption {
+ type = types.lines;
+ default = "";
+ description = ''
+ Additional configuration next to SUBVOLUME and FSTYPE.
+ See man:snapper-configs(5).
+ '';
+ };
+ };
+ });
+ };
+ };
+
+ config = mkIf (cfg.configs != {}) (let
+ documentation = [ "man:snapper(8)" "man:snapper-configs(5)" ];
+ in {
+
+ environment = {
+
+ systemPackages = [ pkgs.snapper ];
+
+ # Note: snapper/config-templates/default is only needed for create-config
+ # which is not the NixOS way to configure.
+ etc = {
+
+ "sysconfig/snapper".text = ''
+ SNAPPER_CONFIGS="${lib.concatStringsSep " " (builtins.attrNames cfg.configs)}"
+ '';
+
+ }
+ // (mapAttrs' (name: subvolume: nameValuePair "snapper/configs/${name}" ({
+ text = ''
+ ${subvolume.extraConfig}
+ FSTYPE="${subvolume.fstype}"
+ SUBVOLUME="${subvolume.subvolume}"
+ '';
+ })) cfg.configs)
+ // (lib.optionalAttrs (cfg.filters != null) {
+ "snapper/filters/default.txt".text = cfg.filters;
+ });
+
+ };
+
+ services.dbus.packages = [ pkgs.snapper ];
+
+ systemd.services.snapper-timeline = {
+ description = "Timeline of Snapper Snapshots";
+ inherit documentation;
+ serviceConfig.ExecStart = "${pkgs.snapper}/lib/snapper/systemd-helper --timeline";
+ };
+
+ systemd.timers.snapper-timeline = {
+ description = "Timeline of Snapper Snapshots";
+ inherit documentation;
+ wantedBy = [ "basic.target" ];
+ timerConfig.OnCalendar = cfg.snapshotInterval;
+ };
+
+ systemd.services.snapper-cleanup = {
+ description = "Cleanup of Snapper Snapshots";
+ inherit documentation;
+ serviceConfig.ExecStart = "${pkgs.snapper}/lib/snapper/systemd-helper --cleanup";
+ };
+
+ systemd.timers.snapper-cleanup = {
+ description = "Cleanup of Snapper Snapshots";
+ inherit documentation;
+ wantedBy = [ "basic.target" ];
+ timerConfig.OnBootSec = "10m";
+ timerConfig.OnUnitActiveSec = cfg.cleanupInterval;
+ };
+ });
+}
+