Co-Authored-By: edef <edef@edef.eu> Co-Authored-by: Ryan Lahfa <raito@lix.systems> Change-Id: Ica1cda177a236814de900f50a8a61d288f58f519
		
			
				
	
	
		
			66 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			66 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
| # Configure restic backups to S3-compatible storage, in our case
 | |
| # Hetzner Cloud object storage.
 | |
| #
 | |
| # Conventions:
 | |
| # - restic's cache lives in /var/backup/restic/cache
 | |
| # - repository password lives in `config.age.secrets.restic-repository-password.path`
 | |
| # - object storage credentials in `config.age.secrets.restic-bucket-credentials.path`
 | |
| { config, lib, pkgs, ... }:
 | |
| 
 | |
| let
 | |
|   cfg = config.services.depot.restic;
 | |
|   mkStringOption = default: lib.mkOption {
 | |
|     inherit default;
 | |
|     type = lib.types.str;
 | |
|   };
 | |
| in
 | |
| {
 | |
|   options.services.depot.restic = {
 | |
|     enable = lib.mkEnableOption "the restic backups";
 | |
|     bucketEndpoint = mkStringOption "fsn1.your-objectstorage.com";
 | |
|     bucketName = mkStringOption "snix-backups";
 | |
|     bucketCredentials = mkStringOption config.age.secrets.restic-bucket-credentials.path;
 | |
|     repository = mkStringOption config.networking.hostName;
 | |
|     interval = mkStringOption "hourly";
 | |
| 
 | |
|     paths = with lib; mkOption {
 | |
|       description = "Directories that should be backed up";
 | |
|       type = types.listOf types.str;
 | |
|     };
 | |
| 
 | |
|     exclude = with lib; mkOption {
 | |
|       description = "Files that should be excluded from backups";
 | |
|       type = types.listOf types.str;
 | |
|       default = [ ];
 | |
|     };
 | |
|   };
 | |
| 
 | |
|   config = lib.mkIf cfg.enable {
 | |
|     systemd.services.restic = {
 | |
|       description = "Backups to Hetzner Cloud";
 | |
| 
 | |
|       script = "${pkgs.restic}/bin/restic backup ${lib.concatStringsSep " " cfg.paths}";
 | |
| 
 | |
|       serviceConfig.ExecStartPre = pkgs.writeShellScript "init-repo" ''
 | |
|         ${pkgs.restic}/bin/restic init && echo "Initializing the repository." || echo "Already initialized."
 | |
|       '';
 | |
| 
 | |
|       environment = {
 | |
|         RESTIC_REPOSITORY = "s3:${cfg.bucketEndpoint}/${cfg.bucketName}/${cfg.repository}";
 | |
|         AWS_SHARED_CREDENTIALS_FILE = cfg.bucketCredentials;
 | |
|         RESTIC_PASSWORD_FILE = config.age.secrets.restic-repository-password.path;
 | |
|         RESTIC_CACHE_DIR = "/var/backup/restic/cache";
 | |
| 
 | |
|         RESTIC_EXCLUDE_FILE =
 | |
|           builtins.toFile "exclude-files" (lib.concatStringsSep "\n" cfg.exclude);
 | |
|       };
 | |
|     };
 | |
| 
 | |
|     systemd.timers.restic = {
 | |
|       wantedBy = [ "multi-user.target" ];
 | |
|       timerConfig.OnCalendar = cfg.interval;
 | |
|     };
 | |
| 
 | |
|     environment.systemPackages = [ pkgs.restic ];
 | |
|   };
 | |
| }
 |