Skip to content

Commit

Permalink
Add more tests and fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Ramblurr committed Jun 12, 2024
1 parent 3e3615c commit 4177ca9
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 12 deletions.
82 changes: 81 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,90 @@
# datomic-pro-flake


[![FlakeHub](https://img.shields.io/endpoint?url=https://flakehub.com/f/ramblurr/datomic-pro-flake/badge)](https://flakehub.com/flake/ramblurr/datomic-pro-flake)
[![GitHub License](https://img.shields.io/github/license/ramblurr/datomic-pro-flake)](./LICENSE)
[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/ramblurr/datomic-pro-flake/ci.yml)](https://github.com/Ramblurr/datomic-pro-flake/actions/workflows/ci.yml)

This flake exposes a `datomic-pro` nix package and several NixOS modules for running Datomic Pro on NixOS.

## Usage

### `flake.nix`

```nix
{
inputs.
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
datomic-pro.url = "https://flakehub.com/f/Ramblurr/datomic-pro/*.tar.gz";
datomic-pro.nixpkgs = "nixpkgs";
};
outputs = { nixpkgs, datomic-pro, ... }@attrs: {
nixosConfigurations.machine = nixpksg.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./configuration.nix
datomic-pro.nixosModules.${system}.datomic-pro
];
};
};
}
```

### `/etc/datomic-pro/secrets.properties`

I wouldn't really do this in production I would use a tool like
[agenix](https://github.com/ryantm/agenix) or
[sops-nix](https://github.com/Mic92/sops-nix).

Whatever you do, do not use
[`environment.etc`](https://search.nixos.org/options?channel=24.05&show=environment.etc&from=0&size=50&sort=relevance&type=packages&query=environment.etc)
to create the secret files! That will write the secrets into the globally
readable nix store, and could end up on a nix cache somewhere. Bad news!

``` java-properties
storage-admin-password=changeme
storage-datomic-password=changeme
```

``` shell
chown root:root /etc/datomic-pro/secrets.properties
chmod 0600 /etc/datomic-pro/secrets.properties
```

### `configuration.nix`

A basic dev-mode datomic that stores its state in `/var/lib/datomic-pro`:

``` nix
{
# ... the rest of your config ...
services.datomic-pro = {
secretsFile = "/etc/datomic-pro/secrets.properties";
settings = {
enable = true;
host = "localhost";
port = 4334;
memory-index-max = "256m";
memory-index-threshold = "32m";
object-cache-max = "128m";
protocol = "dev";
storage-access = "remote";
};
}
# optionally add the console
services.datomic-console = {
enable = true;
port = 8080;
dbUriFile = ..path to secret file containing something like datomic:dev://localhost:4334/.....
};
}
```

### Discussion

Feel free to [open an issue](https://github.com/Ramblurr/datomic-pro-flake/issues/new) or reach out to me on the Clojurians slack ([@Ramblurr](https://clojurians.slack.com/team/U70QFSCG2)).

## License

Expand Down
43 changes: 40 additions & 3 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
};
nixosModules = {
datomic-pro = import ./nixos-modules/datomic-pro.nix;
datomic-console = import ./nixos-modules/datomic-console.nix;
};
checks = {
# A VM test of the NixOS module.
Expand All @@ -40,16 +41,52 @@
{
nixpkgs.overlays = [ self.overlays."${system}" ];
virtualisation.memorySize = 2048;
imports = [ self.nixosModules.${system}.datomic-pro ];
services.datomic-pro.enable = true;
imports = [
self.nixosModules.${system}.datomic-pro
self.nixosModules.${system}.datomic-console
];
environment.etc."datomic-pro/do-not-do-this.properties" = {
text = ''
storage-admin-password=do-not-do-it-this-way-in-prod
storage-datomic-password=do-not-do-it-this-way-in-prod
'';
mode = "0600";
};
services.datomic-pro = {
enable = true;
secretsFile = "/etc/datomic-pro/do-not-do-this.properties";
settings = {
enable = true;
host = "localhost";
port = 4334;
memory-index-max = "256m";
memory-index-threshold = "32m";
object-cache-max = "128m";
protocol = "dev";
storage-access = "remote";
};
};

environment.etc."datomic-console/do-not-do-this" = {
text = "datomic:dev://localhost:4334/?password=do-not-do-it-this-way-in-prod";
mode = "0600";
};
services.datomic-console = {
enable = true;
alias = "dev";
port = 8080;
dbUriFile = "/etc/datomic-console/do-not-do-this";
};
};
};

testScript = ''
start_all()
machine.sleep(5)
machine.wait_for_unit("datomic-pro.service")
machine.wait_for_open_port(4334)
machine.wait_for_unit("datomic-console.service")
machine.wait_for_open_port(8080)
machine.succeed("curl --fail http://localhost:8080/browse")
'';
};
};
Expand Down
12 changes: 7 additions & 5 deletions nixos-modules/datomic-console.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ in
javaPackage = lib.mkPackageOption pkgs "temurin-bin" { };
port = lib.mkOption {
type = lib.types.port;
default = 4335;
description = "The port the console will bind to";
};
alias = lib.mkOption {
Expand All @@ -26,7 +25,11 @@ in
};
dbUriFile = lib.mkOption {
type = lib.types.path;
description = "Path to a file containing the datomic: database uri";
description = ''
Path to a file containing the 'datomic:' database uri
Should be owned by root and have 0600 permissions.
'';
};

stateDirectoryName = lib.mkOption {
Expand All @@ -40,9 +43,9 @@ in

assertions = [
{
assertion = lib.strings.contains "/" cfg.stateDirectoryName == false;
assertion = lib.strings.hasInfix "/" cfg.stateDirectoryName == false;
message = ''
<option>services.datomic-pro.stateDirectoryName> must be a single directory name, not a path with /.
<option>services.datomic-console.stateDirectoryName> must be a single directory name, not a path with /.
'';
}
];
Expand All @@ -59,7 +62,6 @@ in
LoadCredential = [ "datomic-console-db-uri:${cfg.dbUriFile}" ];
DynamicUser = true;
StateDirectory = cfg.stateDirectoryName;
WorkingDirectory = cfg.stateDirectoryName;
Restart = "always";
MemoryDenyWriteExecute = false; # required for the jvm
NoNewPrivileges = true;
Expand Down
23 changes: 20 additions & 3 deletions nixos-modules/datomic-pro.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,20 @@
let
cfg = config.services.datomic-pro;
settingsFormat = pkgs.formats.javaProperties { };
propertiesFile = settingsFormat.generate "transactor.properties" cfg.settings;
stateDir = "/var/lib/${cfg.stateDirectoryName}";
runtimePropertiesPath = "${stateDir}/transactor.properties";
# default settings that will be used unless overriden by the user
settingsDefault = {
host = "localhost";
memory-index-max = "256m";
memory-index-threshold = "32m";
object-cache-max = "128m";
port = 4334;
protocol = "dev";
data-dir = "${stateDir}/data";
log-dir = "${stateDir}/log";
};
propertiesFile = settingsFormat.generate "transactor.properties" (settingsDefault // cfg.settings);
in
{
options = {
Expand All @@ -21,7 +32,11 @@ in
secretsFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = "Path to a file containing secret properties that will be concatenated to the generated properties file at runtime.";
description = ''
Secret configuration concatenated to the transactor properties at runtime.
Should be owned by root and have 0600 permissions.
'';
};

stateDirectoryName = lib.mkOption {
Expand Down Expand Up @@ -68,8 +83,9 @@ in
path = [ cfg.javaPackage ];
preStart = ''
cat ${propertiesFile} > ${runtimePropertiesPath}
chmod 0600 ${runtimePropertiesPath}
${lib.optionalString (cfg.secretsFile != null) ''
cat ${cfg.secretsFile} >> ${runtimePropertiesPath}
cat $CREDENTIALS_DIRECTORY/datomic-pro-secrets >> ${runtimePropertiesPath}
''}
mkdir -p ${stateDir}/data ${stateDir}/log
'';
Expand All @@ -80,6 +96,7 @@ in
Type = "simple";
DynamicUser = true;
StateDirectory = cfg.stateDirectoryName;
LoadCredential = lib.mkIf (cfg.secretsFile != null) [ "datomic-pro-secrets:${cfg.secretsFile}" ];
Restart = "always";
MemoryDenyWriteExecute = false; # required for the jvm
NoNewPrivileges = true;
Expand Down

0 comments on commit 4177ca9

Please sign in to comment.