153 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
| { 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;
 | |
|     };
 | |
|   });
 | |
| }
 | |
| 
 | 
