mirror of
https://github.com/ilyakooo0/nixpkgs.git
synced 2024-09-21 04:28:40 +03:00
Merge pull request #129468 from jwygoda/litestream-service
nixos/litestream: init
This commit is contained in:
commit
404cd360c2
@ -634,6 +634,7 @@
|
|||||||
./services/network-filesystems/glusterfs.nix
|
./services/network-filesystems/glusterfs.nix
|
||||||
./services/network-filesystems/kbfs.nix
|
./services/network-filesystems/kbfs.nix
|
||||||
./services/network-filesystems/ipfs.nix
|
./services/network-filesystems/ipfs.nix
|
||||||
|
./services/network-filesystems/litestream/default.nix
|
||||||
./services/network-filesystems/netatalk.nix
|
./services/network-filesystems/netatalk.nix
|
||||||
./services/network-filesystems/nfsd.nix
|
./services/network-filesystems/nfsd.nix
|
||||||
./services/network-filesystems/openafs/client.nix
|
./services/network-filesystems/openafs/client.nix
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.litestream;
|
||||||
|
settingsFormat = pkgs.formats.yaml {};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.litestream = {
|
||||||
|
enable = mkEnableOption "litestream";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
description = "Package to use.";
|
||||||
|
default = pkgs.litestream;
|
||||||
|
defaultText = "pkgs.litestream";
|
||||||
|
type = types.package;
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
description = ''
|
||||||
|
See the <link xlink:href="https://litestream.io/reference/config/">documentation</link>.
|
||||||
|
'';
|
||||||
|
type = settingsFormat.type;
|
||||||
|
example = {
|
||||||
|
dbs = [
|
||||||
|
{
|
||||||
|
path = "/var/lib/db1";
|
||||||
|
replicas = [
|
||||||
|
{
|
||||||
|
url = "s3://mybkt.litestream.io/db1";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environmentFile = mkOption {
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
example = "/run/secrets/litestream";
|
||||||
|
description = ''
|
||||||
|
Environment file as defined in <citerefentry>
|
||||||
|
<refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum>
|
||||||
|
</citerefentry>.
|
||||||
|
|
||||||
|
Secrets may be passed to the service without adding them to the
|
||||||
|
world-readable Nix store, by specifying placeholder variables as
|
||||||
|
the option value in Nix and setting these variables accordingly in the
|
||||||
|
environment file.
|
||||||
|
|
||||||
|
By default, Litestream will perform environment variable expansion
|
||||||
|
within the config file before reading it. Any references to ''$VAR or
|
||||||
|
''${VAR} formatted variables will be replaced with their environment
|
||||||
|
variable values. If no value is set then it will be replaced with an
|
||||||
|
empty string.
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
# Content of the environment file
|
||||||
|
LITESTREAM_ACCESS_KEY_ID=AKIAxxxxxxxxxxxxxxxx
|
||||||
|
LITESTREAM_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxx
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
Note that this file needs to be available on the host on which
|
||||||
|
this exporter is running.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
environment.etc = {
|
||||||
|
"litestream.yml" = {
|
||||||
|
source = settingsFormat.generate "litestream-config.yaml" cfg.settings;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.litestream = {
|
||||||
|
description = "Litestream";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "networking.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
EnvironmentFile = mkIf (cfg.environmentFile != null) cfg.environmentFile;
|
||||||
|
ExecStart = "${cfg.package}/bin/litestream replicate";
|
||||||
|
Restart = "always";
|
||||||
|
User = "litestream";
|
||||||
|
Group = "litestream";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.litestream = {
|
||||||
|
description = "Litestream user";
|
||||||
|
group = "litestream";
|
||||||
|
isSystemUser = true;
|
||||||
|
};
|
||||||
|
users.groups.litestream = {};
|
||||||
|
};
|
||||||
|
meta.doc = ./litestream.xml;
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
version="5.0"
|
||||||
|
xml:id="module-services-litestream">
|
||||||
|
<title>Litestream</title>
|
||||||
|
<para>
|
||||||
|
<link xlink:href="https://litestream.io/">Litestream</link> is a standalone streaming
|
||||||
|
replication tool for SQLite.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<section xml:id="module-services-litestream-configuration">
|
||||||
|
<title>Configuration</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Litestream service is managed by a dedicated user named <literal>litestream</literal>
|
||||||
|
which needs permission to the database file. Here's an example config which gives
|
||||||
|
required permissions to access <link linkend="opt-services.grafana.database.path">
|
||||||
|
grafana database</link>:
|
||||||
|
<programlisting>
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
users.users.litestream.extraGroups = [ "grafana" ];
|
||||||
|
|
||||||
|
systemd.services.grafana.serviceConfig.ExecStartPost = "+" + pkgs.writeShellScript "grant-grafana-permissions" ''
|
||||||
|
timeout=10
|
||||||
|
|
||||||
|
while [ ! -f /var/lib/grafana/data/grafana.db ];
|
||||||
|
do
|
||||||
|
if [ "$timeout" == 0 ]; then
|
||||||
|
echo "ERROR: Timeout while waiting for /var/lib/grafana/data/grafana.db."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
((timeout--))
|
||||||
|
done
|
||||||
|
|
||||||
|
find /var/lib/grafana -type d -exec chmod -v 775 {} \;
|
||||||
|
find /var/lib/grafana -type f -exec chmod -v 660 {} \;
|
||||||
|
'';
|
||||||
|
|
||||||
|
services.litestream = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
environmentFile = "/run/secrets/litestream";
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
dbs = [
|
||||||
|
{
|
||||||
|
path = "/var/lib/grafana/data/grafana.db";
|
||||||
|
replicas = [{
|
||||||
|
url = "s3://mybkt.litestream.io/grafana";
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</chapter>
|
@ -227,6 +227,7 @@ in
|
|||||||
libreswan = handleTest ./libreswan.nix {};
|
libreswan = handleTest ./libreswan.nix {};
|
||||||
lightdm = handleTest ./lightdm.nix {};
|
lightdm = handleTest ./lightdm.nix {};
|
||||||
limesurvey = handleTest ./limesurvey.nix {};
|
limesurvey = handleTest ./limesurvey.nix {};
|
||||||
|
litestream = handleTest ./litestream.nix {};
|
||||||
locate = handleTest ./locate.nix {};
|
locate = handleTest ./locate.nix {};
|
||||||
login = handleTest ./login.nix {};
|
login = handleTest ./login.nix {};
|
||||||
loki = handleTest ./loki.nix {};
|
loki = handleTest ./loki.nix {};
|
||||||
|
93
nixos/tests/litestream.nix
Normal file
93
nixos/tests/litestream.nix
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import ./make-test-python.nix ({ pkgs, ...} : {
|
||||||
|
name = "litestream";
|
||||||
|
meta = with pkgs.lib.maintainers; {
|
||||||
|
maintainers = [ jwygoda ];
|
||||||
|
};
|
||||||
|
|
||||||
|
machine =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{ services.litestream = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
dbs = [
|
||||||
|
{
|
||||||
|
path = "/var/lib/grafana/data/grafana.db";
|
||||||
|
replicas = [{
|
||||||
|
url = "sftp://foo:bar@127.0.0.1:22/home/foo/grafana";
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.services.grafana.serviceConfig.ExecStartPost = "+" + pkgs.writeShellScript "grant-grafana-permissions" ''
|
||||||
|
timeout=10
|
||||||
|
|
||||||
|
while [ ! -f /var/lib/grafana/data/grafana.db ];
|
||||||
|
do
|
||||||
|
if [ "$timeout" == 0 ]; then
|
||||||
|
echo "ERROR: Timeout while waiting for /var/lib/grafana/data/grafana.db."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
((timeout--))
|
||||||
|
done
|
||||||
|
|
||||||
|
find /var/lib/grafana -type d -exec chmod -v 775 {} \;
|
||||||
|
find /var/lib/grafana -type f -exec chmod -v 660 {} \;
|
||||||
|
'';
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
allowSFTP = true;
|
||||||
|
listenAddresses = [ { addr = "127.0.0.1"; port = 22; } ];
|
||||||
|
};
|
||||||
|
services.grafana = {
|
||||||
|
enable = true;
|
||||||
|
security = {
|
||||||
|
adminUser = "admin";
|
||||||
|
adminPassword = "admin";
|
||||||
|
};
|
||||||
|
addr = "localhost";
|
||||||
|
port = 3000;
|
||||||
|
extraOptions = {
|
||||||
|
DATABASE_URL = "sqlite3:///var/lib/grafana/data/grafana.db?cache=private&mode=rwc&_journal_mode=WAL";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
users.users.foo = {
|
||||||
|
isNormalUser = true;
|
||||||
|
password = "bar";
|
||||||
|
};
|
||||||
|
users.users.litestream.extraGroups = [ "grafana" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
start_all()
|
||||||
|
machine.wait_until_succeeds("test -d /home/foo/grafana")
|
||||||
|
machine.wait_for_open_port(3000)
|
||||||
|
machine.succeed("""
|
||||||
|
curl -sSfN -X PUT -H "Content-Type: application/json" -d '{
|
||||||
|
"oldPassword": "admin",
|
||||||
|
"newPassword": "newpass",
|
||||||
|
"confirmNew": "newpass"
|
||||||
|
}' http://admin:admin@127.0.0.1:3000/api/user/password
|
||||||
|
""")
|
||||||
|
# https://litestream.io/guides/systemd/#simulating-a-disaster
|
||||||
|
machine.systemctl("stop litestream.service")
|
||||||
|
machine.succeed(
|
||||||
|
"rm -f /var/lib/grafana/data/grafana.db "
|
||||||
|
"/var/lib/grafana/data/grafana.db-shm "
|
||||||
|
"/var/lib/grafana/data/grafana.db-wal"
|
||||||
|
)
|
||||||
|
machine.succeed(
|
||||||
|
"litestream restore /var/lib/grafana/data/grafana.db "
|
||||||
|
"&& chown grafana:grafana /var/lib/grafana/data/grafana.db "
|
||||||
|
"&& chmod 660 /var/lib/grafana/data/grafana.db"
|
||||||
|
)
|
||||||
|
machine.systemctl("restart grafana.service")
|
||||||
|
machine.wait_for_open_port(3000)
|
||||||
|
machine.succeed(
|
||||||
|
"curl -sSfN -u admin:newpass http://127.0.0.1:3000/api/org/users | grep admin\@localhost"
|
||||||
|
)
|
||||||
|
'';
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user