1import ./make-test-python.nix ({ pkgs, ... }:
2
3 let
4 privateKey = ''
5 -----BEGIN OPENSSH PRIVATE KEY-----
6 b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
7 QyNTUxOQAAACBx8UB04Q6Q/fwDFjakHq904PYFzG9pU2TJ9KXpaPMcrwAAAJB+cF5HfnBe
8 RwAAAAtzc2gtZWQyNTUxOQAAACBx8UB04Q6Q/fwDFjakHq904PYFzG9pU2TJ9KXpaPMcrw
9 AAAEBN75NsJZSpt63faCuaD75Unko0JjlSDxMhYHAPJk2/xXHxQHThDpD9/AMWNqQer3Tg
10 9gXMb2lTZMn0pelo8xyvAAAADXJzY2h1ZXR6QGt1cnQ=
11 -----END OPENSSH PRIVATE KEY-----
12 '';
13 publicKey = ''
14 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHHxQHThDpD9/AMWNqQer3Tg9gXMb2lTZMn0pelo8xyv
15 '';
16 in
17 {
18 name = "btrbk-doas";
19 meta = with pkgs.lib; {
20 maintainers = with maintainers; [ symphorien tu-maurice ];
21 };
22
23 nodes = {
24 archive = { ... }: {
25 security.sudo.enable = false;
26 security.doas.enable = true;
27 environment.systemPackages = with pkgs; [ btrfs-progs ];
28 # note: this makes the privateKey world readable.
29 # don't do it with real ssh keys.
30 environment.etc."btrbk_key".text = privateKey;
31 services.btrbk = {
32 extraPackages = [ pkgs.lz4 ];
33 instances = {
34 remote = {
35 onCalendar = "minutely";
36 settings = {
37 ssh_identity = "/etc/btrbk_key";
38 ssh_user = "btrbk";
39 stream_compress = "lz4";
40 volume = {
41 "ssh://main/mnt" = {
42 target = "/mnt";
43 snapshot_dir = "btrbk/remote";
44 subvolume = "to_backup";
45 };
46 };
47 };
48 };
49 };
50 };
51 };
52
53 main = { ... }: {
54 security.sudo.enable = false;
55 security.doas.enable = true;
56 environment.systemPackages = with pkgs; [ btrfs-progs ];
57 services.openssh = {
58 enable = true;
59 passwordAuthentication = false;
60 kbdInteractiveAuthentication = false;
61 };
62 services.btrbk = {
63 extraPackages = [ pkgs.lz4 ];
64 sshAccess = [
65 {
66 key = publicKey;
67 roles = [ "source" "send" "info" "delete" ];
68 }
69 ];
70 instances = {
71 local = {
72 onCalendar = "minutely";
73 settings = {
74 volume = {
75 "/mnt" = {
76 snapshot_dir = "btrbk/local";
77 subvolume = "to_backup";
78 };
79 };
80 };
81 };
82 };
83 };
84 };
85 };
86
87 testScript = ''
88 start_all()
89
90 # create btrfs partition at /mnt
91 for machine in (archive, main):
92 machine.succeed("dd if=/dev/zero of=/data_fs bs=120M count=1")
93 machine.succeed("mkfs.btrfs /data_fs")
94 machine.succeed("mkdir /mnt")
95 machine.succeed("mount /data_fs /mnt")
96
97 # what to backup and where
98 main.succeed("btrfs subvolume create /mnt/to_backup")
99 main.succeed("mkdir -p /mnt/btrbk/{local,remote}")
100
101 # check that local snapshots work
102 with subtest("local"):
103 main.succeed("echo foo > /mnt/to_backup/bar")
104 main.wait_until_succeeds("cat /mnt/btrbk/local/*/bar | grep foo")
105 main.succeed("echo bar > /mnt/to_backup/bar")
106 main.succeed("cat /mnt/btrbk/local/*/bar | grep foo")
107
108 # check that btrfs send/receive works and ssh access works
109 with subtest("remote"):
110 archive.wait_until_succeeds("cat /mnt/*/bar | grep bar")
111 main.succeed("echo baz > /mnt/to_backup/bar")
112 archive.succeed("cat /mnt/*/bar | grep bar")
113 '';
114 })