Skip to content

Commit

Permalink
Backup contracts for files and databases (#344)
Browse files Browse the repository at this point in the history
This PR continues the work started in
#314

I had to create my own PR since I couldn't add commits on the fork.

---------

Co-authored-by: sivertism <[email protected]>
  • Loading branch information
ibizaman and sivertism authored Nov 12, 2024
1 parent 7f2aa36 commit 431dd05
Show file tree
Hide file tree
Showing 38 changed files with 1,128 additions and 364 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Upcoming Release

## New Features

- Backup:
- Add feature to backup databases with the database backup contract, implemented with `shb.restic.databases`.

## Breaking Changes

- Remove dependency on `sops-nix`.
Expand Down Expand Up @@ -33,6 +38,8 @@
- `shb.forgejo.sso.secretFileForAuthelia` -> `shb.forgejo.ldap.sharedSecretForAuthelia.result.path`.
- `shb.forgejo.adminPasswordFile` -> `shb.forgejo.adminPassword.result.path`.
- `shb.forgejo.databasePasswordFile` -> `shb.forgejo.databasePassword.result.path`.
- Backup:
- `shb.restic.instances` options has been split between `shb.restic.instances.request` and `shb.restic.instances.settings`, matching better with contracts.


## User Facing Backwards Compatible Changes
Expand Down
4 changes: 4 additions & 0 deletions docs/blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ Not all blocks are yet documented. You can find all available blocks [in the rep
modules/blocks/ssl/docs/default.md
```

```{=include=} chapters html:into-file=//blocks-postgresql.html
modules/blocks/postgresql/docs/default.md
```

```{=include=} chapters html:into-file=//blocks-restic.html
modules/blocks/restic/docs/default.md
```
Expand Down
11 changes: 9 additions & 2 deletions docs/contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ as possible, reducing the quite thick layer that it is now.
Provided contracts are:

- [SSL generator contract](contracts-ssl.html) to generate SSL certificates.
Two implementations are provided: self-signed and Let's Encrypt.
Two providers are implemented: self-signed and Let's Encrypt.
- [Backup contract](contracts-backup.html) to backup directories.
This contract allows to backup multiple times the same directories for extra protection.
One provider is implemented: Restic.
- [Database Backup contract](contracts-databasebackup.html) to backup database dumps.
One provider is implemented: Restic.
- [Secret contract](contracts-secret.html) to provide secrets that are deployed outside of the Nix store.
One provider is implemented: SOPS.

```{=include=} chapters html:into-file=//contracts-ssl.html
modules/contracts/ssl/docs/default.md
Expand All @@ -33,6 +36,10 @@ modules/contracts/ssl/docs/default.md
modules/contracts/backup/docs/default.md
```

```{=include=} chapters html:into-file=//contracts-databasebackup.html
modules/contracts/databasebackup/docs/default.md
```

```{=include=} chapters html:into-file=//contracts-secret.html
modules/contracts/secret/docs/default.md
```
Expand Down
10 changes: 10 additions & 0 deletions docs/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ in stdenv.mkDerivation {
'@OPTIONS_JSON@' \
${individualModuleOptionsDocs [ ../modules/blocks/ssl.nix ]}/share/doc/nixos/options.json
substituteInPlace ./modules/blocks/postgresql/docs/default.md \
--replace \
'@OPTIONS_JSON@' \
${individualModuleOptionsDocs [ ../modules/blocks/postgresql.nix ]}/share/doc/nixos/options.json
substituteInPlace ./modules/blocks/restic/docs/default.md \
--replace \
'@OPTIONS_JSON@' \
Expand Down Expand Up @@ -160,6 +165,11 @@ in stdenv.mkDerivation {
'@OPTIONS_JSON@' \
${individualModuleOptionsDocs [ ../modules/contracts/backup/dummyModule.nix ]}/share/doc/nixos/options.json
substituteInPlace ./modules/contracts/databasebackup/docs/default.md \
--replace \
'@OPTIONS_JSON@' \
${individualModuleOptionsDocs [ ../modules/contracts/databasebackup/dummyModule.nix ]}/share/doc/nixos/options.json
substituteInPlace ./modules/contracts/secret/docs/default.md \
--replace \
'@OPTIONS_JSON@' \
Expand Down
2 changes: 2 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@
// (vm_test "restic" ./test/blocks/restic.nix)
// (vm_test "ssl" ./test/blocks/ssl.nix)

// (vm_test "contracts-backup" ./test/contracts/backup.nix)
// (vm_test "contracts-databasebackup" ./test/contracts/databasebackup.nix)
// (vm_test "contracts-secret" ./test/contracts/secret.nix)
));
}
Expand Down
2 changes: 1 addition & 1 deletion lib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ rec {
results = pkgs.lib.runTests tests;
in
if results != [ ] then
builtins.throw (concatStringsSep "\n" (map resultToString (lib.traceValSeqN 3 results)))
builtins.throw (concatStringsSep "\n" (map resultToString (lib.traceValSeq results)))
else
pkgs.runCommand "nix-flake-tests-success" { } "echo > $out";

Expand Down
11 changes: 6 additions & 5 deletions modules/blocks/ldap.nix
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ in
};

backup = lib.mkOption {
type = contracts.backup;
type = contracts.backup.request;
description = ''
Backup configuration. This is an output option.
Expand All @@ -104,10 +104,11 @@ in
```
shb.restic.instances."lldap" = {
enable = true;
# Options specific to Restic.
} // config.shb.lldap.backup;
request = config.shb.lldap.backup;
settings = {
enable = true;
};
};
```
'';
readOnly = true;
Expand Down
35 changes: 35 additions & 0 deletions modules/blocks/postgresql.nix
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{ config, lib, pkgs, ... }:
let
cfg = config.shb.postgresql;
contracts = pkgs.callPackage ../contracts {};

upgrade-script = old: new:
let
Expand Down Expand Up @@ -49,6 +50,40 @@ in
default = false;
};

databasebackup = lib.mkOption {
description = ''
Backup configuration. This is an output option.
Use it to initialize a block implementing the "backup" contract.
For example, with the restic block:
```
shb.restic.instances."postgresql" = {
request = config.shb.postgresl.backup;
settings = {
enable = true;
};
};
```
'';

type = contracts.databasebackup.requestType;

default = {
user = "postgres";

backupFile = "postgres.sql";

backupCmd = ''
${pkgs.postgresql}/bin/pg_dumpall | ${pkgs.gzip}/bin/gzip --rsyncable
'';

restoreCmd = ''
${pkgs.gzip}/bin/gunzip | ${pkgs.postgresql}/bin/psql postgres
'';
};
};

ensures = lib.mkOption {
description = "List of username, database and/or passwords that should be created.";
type = lib.types.listOf (lib.types.submodule {
Expand Down
39 changes: 39 additions & 0 deletions modules/blocks/postgresql/docs/default.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# PostgreSQL Block {#blocks-postgresql}

Defined in [`/modules/blocks/postgresql.nix`](@REPO@/modules/blocks/postgresql.nix).

This block sets up a [PostgreSQL][] database.

[postgresql]: https://www.postgresql.org/

## Tests {#blocks-postgresql-tests}

Specific integration tests are defined in [`/test/blocks/postgresql.nix`](@REPO@/test/blocks/postgresql.nix).

## Database Backup Requester Contracts {#blocks-postgresql-contract-databasebackup}

This block can be backed up using the [database backup](contracts-databasebackup.html) contract.

Contract integration tests are defined in [`/test/contracts/databasebackup.nix`](@REPO@/test/contracts/databasebackup.nix).

### Backing up All Databases {#blocks-postgresql-contract-databasebackup-all}

```nix
{
my.backup.provider."postgresql" = {
request = config.shb.postgresql.databasebackup;
settings = {
// Specific options for the backup provider.
};
};
}
```

## Options Reference {#blocks-postgresql-options}

```{=include=} options
id-prefix: blocks-postgresql-options-
list-id: selfhostblocks-block-postgresql-options
source: @OPTIONS_JSON@
```
Loading

0 comments on commit 431dd05

Please sign in to comment.