1{ pkgs, ... }:
2{
3 name = "litestream";
4 meta = with pkgs.lib.maintainers; {
5 maintainers = [ jwygoda ];
6 };
7
8 nodes.machine =
9 { pkgs, ... }:
10 {
11 services.litestream = {
12 enable = true;
13 settings = {
14 dbs = [
15 {
16 path = "/var/lib/grafana/data/grafana.db";
17 replicas = [
18 {
19 url = "sftp://foo:bar@127.0.0.1:22/home/foo/grafana";
20 }
21 ];
22 }
23 ];
24 };
25 };
26 systemd.services.grafana.serviceConfig.ExecStartPost =
27 "+"
28 + pkgs.writeShellScript "grant-grafana-permissions" ''
29 timeout=10
30
31 while [ ! -f /var/lib/grafana/data/grafana.db ];
32 do
33 if [ "$timeout" == 0 ]; then
34 echo "ERROR: Timeout while waiting for /var/lib/grafana/data/grafana.db."
35 exit 1
36 fi
37
38 sleep 1
39
40 ((timeout--))
41 done
42
43 find /var/lib/grafana -type d -exec chmod -v 775 {} \;
44 find /var/lib/grafana -type f -exec chmod -v 660 {} \;
45 '';
46 services.openssh = {
47 enable = true;
48 allowSFTP = true;
49 listenAddresses = [
50 {
51 addr = "127.0.0.1";
52 port = 22;
53 }
54 ];
55 };
56 services.grafana = {
57 enable = true;
58 settings = {
59 security = {
60 admin_user = "admin";
61 admin_password = "admin";
62 };
63
64 server = {
65 http_addr = "localhost";
66 http_port = 3000;
67 };
68
69 database = {
70 type = "sqlite3";
71 path = "/var/lib/grafana/data/grafana.db";
72 wal = true;
73 };
74 };
75 };
76 users.users.foo = {
77 isNormalUser = true;
78 password = "bar";
79 };
80 users.users.litestream.extraGroups = [ "grafana" ];
81 };
82
83 testScript = ''
84 start_all()
85 machine.wait_until_succeeds("test -d /home/foo/grafana")
86 machine.wait_for_open_port(3000)
87 machine.succeed("""
88 curl -sSfN -X PUT -H "Content-Type: application/json" -d '{
89 "oldPassword": "admin",
90 "newPassword": "newpass",
91 "confirmNew": "newpass"
92 }' http://admin:admin@127.0.0.1:3000/api/user/password
93 """)
94 # https://litestream.io/guides/systemd/#simulating-a-disaster
95 machine.systemctl("stop litestream.service")
96 machine.succeed(
97 "rm -f /var/lib/grafana/data/grafana.db "
98 "/var/lib/grafana/data/grafana.db-shm "
99 "/var/lib/grafana/data/grafana.db-wal"
100 )
101 machine.succeed(
102 "litestream restore /var/lib/grafana/data/grafana.db "
103 "&& chown grafana:grafana /var/lib/grafana/data/grafana.db "
104 "&& chmod 660 /var/lib/grafana/data/grafana.db"
105 )
106 machine.systemctl("restart grafana.service")
107 machine.wait_for_open_port(3000)
108 machine.succeed(
109 "curl -sSfN -u admin:newpass http://127.0.0.1:3000/api/org/users | grep admin\@localhost"
110 )
111 '';
112}