| 
									
										
										
										
											2018-03-12 20:20:24 +01:00
										 |  |  | import ./make-test.nix ({ pkgs, ... }: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let | 
					
						
							|  |  |  |   passphrase = "supersecret"; | 
					
						
							|  |  |  |   dataDir = "/ran:dom/data"; | 
					
						
							|  |  |  |   excludeFile = "not_this_file"; | 
					
						
							|  |  |  |   keepFile = "important_file"; | 
					
						
							|  |  |  |   keepFileData = "important_data"; | 
					
						
							|  |  |  |   localRepo = "/root/back:up"; | 
					
						
							|  |  |  |   archiveName = "my_archive"; | 
					
						
							|  |  |  |   remoteRepo = "borg@server:."; # No need to specify path | 
					
						
							|  |  |  |   privateKey = pkgs.writeText "id_ed25519" ''
 | 
					
						
							|  |  |  |     -----BEGIN OPENSSH PRIVATE KEY----- | 
					
						
							|  |  |  |     b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW | 
					
						
							|  |  |  |     QyNTUxOQAAACBx8UB04Q6Q/fwDFjakHq904PYFzG9pU2TJ9KXpaPMcrwAAAJB+cF5HfnBe | 
					
						
							|  |  |  |     RwAAAAtzc2gtZWQyNTUxOQAAACBx8UB04Q6Q/fwDFjakHq904PYFzG9pU2TJ9KXpaPMcrw | 
					
						
							|  |  |  |     AAAEBN75NsJZSpt63faCuaD75Unko0JjlSDxMhYHAPJk2/xXHxQHThDpD9/AMWNqQer3Tg | 
					
						
							|  |  |  |     9gXMb2lTZMn0pelo8xyvAAAADXJzY2h1ZXR6QGt1cnQ= | 
					
						
							|  |  |  |     -----END OPENSSH PRIVATE KEY----- | 
					
						
							|  |  |  |   '';
 | 
					
						
							|  |  |  |   publicKey = ''
 | 
					
						
							|  |  |  |     ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHHxQHThDpD9/AMWNqQer3Tg9gXMb2lTZMn0pelo8xyv root@client | 
					
						
							|  |  |  |   '';
 | 
					
						
							|  |  |  |   privateKeyAppendOnly = pkgs.writeText "id_ed25519" ''
 | 
					
						
							|  |  |  |     -----BEGIN OPENSSH PRIVATE KEY----- | 
					
						
							|  |  |  |     b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW | 
					
						
							|  |  |  |     QyNTUxOQAAACBacZuz1ELGQdhI7PF6dGFafCDlvh8pSEc4cHjkW0QjLwAAAJC9YTxxvWE8 | 
					
						
							|  |  |  |     cQAAAAtzc2gtZWQyNTUxOQAAACBacZuz1ELGQdhI7PF6dGFafCDlvh8pSEc4cHjkW0QjLw | 
					
						
							|  |  |  |     AAAEAAhV7wTl5dL/lz+PF/d4PnZXuG1Id6L/mFEiGT1tZsuFpxm7PUQsZB2Ejs8Xp0YVp8 | 
					
						
							|  |  |  |     IOW+HylIRzhweORbRCMvAAAADXJzY2h1ZXR6QGt1cnQ= | 
					
						
							|  |  |  |     -----END OPENSSH PRIVATE KEY----- | 
					
						
							|  |  |  |   '';
 | 
					
						
							|  |  |  |   publicKeyAppendOnly = ''
 | 
					
						
							|  |  |  |     ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFpxm7PUQsZB2Ejs8Xp0YVp8IOW+HylIRzhweORbRCMv root@client | 
					
						
							|  |  |  |   '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | in { | 
					
						
							| 
									
										
										
										
											2018-01-02 09:08:38 +01:00
										 |  |  |   name = "borgbackup"; | 
					
						
							| 
									
										
										
										
											2018-03-12 20:20:24 +01:00
										 |  |  |   meta = with pkgs.stdenv.lib; { | 
					
						
							|  |  |  |     maintainers = with maintainers; [ dotlambda ]; | 
					
						
							| 
									
										
										
										
											2018-01-02 09:08:38 +01:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   nodes = { | 
					
						
							| 
									
										
										
										
											2018-03-12 20:20:24 +01:00
										 |  |  |     client = { config, pkgs, ... }: { | 
					
						
							|  |  |  |       services.borgbackup.jobs = { | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         local = rec { | 
					
						
							|  |  |  |           paths = dataDir; | 
					
						
							|  |  |  |           repo = localRepo; | 
					
						
							|  |  |  |           preHook = ''
 | 
					
						
							|  |  |  |             # Don't append a timestamp | 
					
						
							|  |  |  |             archiveName="${archiveName}" | 
					
						
							|  |  |  |           '';
 | 
					
						
							|  |  |  |           encryption = { | 
					
						
							|  |  |  |             mode = "repokey"; | 
					
						
							|  |  |  |             inherit passphrase; | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |           compression = "auto,zlib,9"; | 
					
						
							|  |  |  |           prune.keep = { | 
					
						
							|  |  |  |             within = "1y"; | 
					
						
							|  |  |  |             yearly = 5; | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |           exclude = [ "*/${excludeFile}" ]; | 
					
						
							|  |  |  |           postHook = "echo post"; | 
					
						
							|  |  |  |           startAt = [ ]; # Do not run automatically | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         remote = { | 
					
						
							|  |  |  |           paths = dataDir; | 
					
						
							|  |  |  |           repo = remoteRepo; | 
					
						
							|  |  |  |           encryption.mode = "none"; | 
					
						
							|  |  |  |           startAt = [ ]; | 
					
						
							|  |  |  |           environment.BORG_RSH = "ssh -oStrictHostKeyChecking=no -i /root/id_ed25519"; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         remoteAppendOnly = { | 
					
						
							|  |  |  |           paths = dataDir; | 
					
						
							|  |  |  |           repo = remoteRepo; | 
					
						
							|  |  |  |           encryption.mode = "none"; | 
					
						
							|  |  |  |           startAt = [ ]; | 
					
						
							|  |  |  |           environment.BORG_RSH = "ssh -oStrictHostKeyChecking=no -i /root/id_ed25519.appendOnly"; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     server = { config, pkgs, ... }: { | 
					
						
							|  |  |  |       services.openssh = { | 
					
						
							|  |  |  |         enable = true; | 
					
						
							|  |  |  |         passwordAuthentication = false; | 
					
						
							|  |  |  |         challengeResponseAuthentication = false; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       services.borgbackup.repos.repo1 = { | 
					
						
							|  |  |  |         authorizedKeys = [ publicKey ]; | 
					
						
							|  |  |  |         path = "/data/borgbackup"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # Second repo to make sure the authorizedKeys options are merged correctly | 
					
						
							|  |  |  |       services.borgbackup.repos.repo2 = { | 
					
						
							|  |  |  |         authorizedKeysAppendOnly = [ publicKeyAppendOnly ]; | 
					
						
							|  |  |  |         path = "/data/borgbackup"; | 
					
						
							|  |  |  |         quota = ".5G"; | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2018-01-02 09:08:38 +01:00
										 |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   testScript = ''
 | 
					
						
							| 
									
										
										
										
											2018-03-12 20:20:24 +01:00
										 |  |  |     startAll; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $client->fail('test -d "${remoteRepo}"'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $client->succeed("cp ${privateKey} /root/id_ed25519"); | 
					
						
							|  |  |  |     $client->succeed("chmod 0600 /root/id_ed25519"); | 
					
						
							|  |  |  |     $client->succeed("cp ${privateKeyAppendOnly} /root/id_ed25519.appendOnly"); | 
					
						
							|  |  |  |     $client->succeed("chmod 0600 /root/id_ed25519.appendOnly"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $client->succeed("mkdir -p ${dataDir}"); | 
					
						
							|  |  |  |     $client->succeed("touch ${dataDir}/${excludeFile}"); | 
					
						
							|  |  |  |     $client->succeed("echo '${keepFileData}' > ${dataDir}/${keepFile}"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     subtest "local", sub { | 
					
						
							|  |  |  |       my $borg = "BORG_PASSPHRASE='${passphrase}' borg"; | 
					
						
							|  |  |  |       $client->systemctl("start --wait borgbackup-job-local"); | 
					
						
							|  |  |  |       $client->fail("systemctl is-failed borgbackup-job-local"); | 
					
						
							|  |  |  |       # Make sure exactly one archive has been created | 
					
						
							|  |  |  |       $client->succeed("c=\$($borg list '${localRepo}' | wc -l) && [[ \$c == '1' ]]"); | 
					
						
							|  |  |  |       # Make sure excludeFile has been excluded | 
					
						
							|  |  |  |       $client->fail("$borg list '${localRepo}::${archiveName}' | grep -qF '${excludeFile}'"); | 
					
						
							|  |  |  |       # Make sure keepFile has the correct content | 
					
						
							|  |  |  |       $client->succeed("$borg extract '${localRepo}::${archiveName}'"); | 
					
						
							|  |  |  |       $client->succeed('c=$(cat ${dataDir}/${keepFile}) && [[ "$c" == "${keepFileData}" ]]'); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     subtest "remote", sub { | 
					
						
							|  |  |  |       my $borg = "BORG_RSH='ssh -oStrictHostKeyChecking=no -i /root/id_ed25519' borg"; | 
					
						
							|  |  |  |       $server->waitForUnit("sshd.service"); | 
					
						
							|  |  |  |       $client->waitForUnit("network.target"); | 
					
						
							|  |  |  |       $client->systemctl("start --wait borgbackup-job-remote"); | 
					
						
							|  |  |  |       $client->fail("systemctl is-failed borgbackup-job-remote"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # Make sure we can't access repos other than the specified one | 
					
						
							|  |  |  |       $client->fail("$borg list borg\@server:wrong"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       #TODO: Make sure that data is actually deleted | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     subtest "remoteAppendOnly", sub { | 
					
						
							|  |  |  |       my $borg = "BORG_RSH='ssh -oStrictHostKeyChecking=no -i /root/id_ed25519.appendOnly' borg"; | 
					
						
							|  |  |  |       $server->waitForUnit("sshd.service"); | 
					
						
							|  |  |  |       $client->waitForUnit("network.target"); | 
					
						
							|  |  |  |       $client->systemctl("start --wait borgbackup-job-remoteAppendOnly"); | 
					
						
							|  |  |  |       $client->fail("systemctl is-failed borgbackup-job-remoteAppendOnly"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # Make sure we can't access repos other than the specified one | 
					
						
							|  |  |  |       $client->fail("$borg list borg\@server:wrong"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       #TODO: Make sure that data is not actually deleted | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-02 09:08:38 +01:00
										 |  |  |   '';
 | 
					
						
							|  |  |  | }) |