mirror of
https://github.com/Platonic-Systems/process-compose-flake.git
synced 2024-10-26 22:38:39 +03:00
Add submodule type for YAML file
This commit is contained in:
parent
f2ec5b572a
commit
230955df9e
@ -19,6 +19,9 @@
|
||||
# This adds a `self.packages.default`
|
||||
process-compose."default" = {
|
||||
settings = {
|
||||
environment = [
|
||||
"DATAFILE=data.sqlite"
|
||||
];
|
||||
processes = {
|
||||
|
||||
# Print a pony every 2 seconds, because why not.
|
||||
@ -30,17 +33,23 @@
|
||||
'';
|
||||
|
||||
# Create .sqlite database from chinook database.
|
||||
sqlite-init.command = ''
|
||||
echo "`date`: Importing Chinook database..."
|
||||
${lib.getExe pkgs.sqlite} data.sqlite < ${inputs.chinookDb}/ChinookDatabase/DataSources/Chinook_Sqlite.sql
|
||||
echo "`date`: Done."
|
||||
'';
|
||||
sqlite-init.command = pkgs.writeShellApplication {
|
||||
name = "sqlite-init";
|
||||
text = ''
|
||||
echo "$(date): Importing Chinook database ($DATAFILE) ..."
|
||||
${lib.getExe pkgs.sqlite} "$DATAFILE" < ${inputs.chinookDb}/ChinookDatabase/DataSources/Chinook_Sqlite.sql
|
||||
echo "$(date): Done."
|
||||
'';
|
||||
};
|
||||
|
||||
# Run sqlite-web on the local chinook database.
|
||||
sqlite-web = {
|
||||
command = ''
|
||||
${pkgs.sqlite-web}/bin/sqlite_web data.sqlite
|
||||
'';
|
||||
command = pkgs.writeShellApplication {
|
||||
name = "sqlite-web";
|
||||
text = ''
|
||||
${pkgs.sqlite-web}/bin/sqlite_web "$DATAFILE"
|
||||
'';
|
||||
};
|
||||
# The 'depends_on' will have this process wait until the above one is completed.
|
||||
depends_on."sqlite-init".condition = "process_completed_successfully";
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
outputs = { self, ... }: {
|
||||
outputs = _: {
|
||||
flakeModule = ./nix/flake-module.nix;
|
||||
|
||||
templates.default = {
|
||||
|
@ -6,7 +6,7 @@ in
|
||||
{
|
||||
imports = [
|
||||
./cli.nix
|
||||
./settings.nix
|
||||
./settings
|
||||
];
|
||||
|
||||
options = {
|
||||
|
@ -1,45 +0,0 @@
|
||||
{ name, config, pkgs, lib, ... }:
|
||||
let
|
||||
inherit (lib) types mkOption literalExpression;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
settings = mkOption {
|
||||
type = (pkgs.formats.yaml { }).type;
|
||||
example =
|
||||
# packages.${system}.watch-server becomes available
|
||||
# execute `nix run .#watch-server` or incude packages.${system}.watch-server
|
||||
# as a nativeBuildInput to your devShell
|
||||
literalExpression ''
|
||||
{
|
||||
watch-server = {
|
||||
processes = {
|
||||
backend = "''${pkgs.simple-http-server}";
|
||||
frontend = "''${pkgs.simple-http-server}";
|
||||
};
|
||||
};
|
||||
};
|
||||
'';
|
||||
description = ''
|
||||
For each attribute `x = process-compose config` a flake app and package `x` is added to the flake.
|
||||
Which runs process-compose with the declared config.
|
||||
'';
|
||||
};
|
||||
|
||||
outputs.settingsYaml = mkOption {
|
||||
type = types.attrsOf types.raw;
|
||||
internal = true;
|
||||
};
|
||||
};
|
||||
|
||||
config.outputs.settingsYaml =
|
||||
let
|
||||
toYAMLFile =
|
||||
attrs:
|
||||
pkgs.runCommand "toYamlFile" { buildInputs = [ pkgs.yq-go ]; } ''
|
||||
yq -P '.' ${pkgs.writeTextFile { name = "process-compose-${name}.json"; text = (builtins.toJSON attrs); }} > $out
|
||||
'';
|
||||
in
|
||||
toYAMLFile config.settings;
|
||||
}
|
||||
|
9
nix/process-compose/settings/command.nix
Normal file
9
nix/process-compose/settings/command.nix
Normal file
@ -0,0 +1,9 @@
|
||||
{ lib, ... }:
|
||||
|
||||
args:
|
||||
lib.mkOption (args // {
|
||||
type = lib.types.either lib.types.package lib.types.str;
|
||||
apply = pkg:
|
||||
if builtins.isString pkg then pkg else
|
||||
lib.getExe pkg;
|
||||
})
|
116
nix/process-compose/settings/default.nix
Normal file
116
nix/process-compose/settings/default.nix
Normal file
@ -0,0 +1,116 @@
|
||||
{ name, config, pkgs, lib, ... }:
|
||||
let
|
||||
inherit (lib) types mkOption literalExpression;
|
||||
submoduleWithPkgs = mod:
|
||||
types.submoduleWith {
|
||||
specialArgs = { inherit pkgs lib; };
|
||||
modules = [ mod ];
|
||||
};
|
||||
in
|
||||
{
|
||||
options = {
|
||||
settings = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
processes = mkOption {
|
||||
type = types.attrsOf (submoduleWithPkgs ./process.nix);
|
||||
default = { };
|
||||
description = ''
|
||||
A map of process names to their configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
environment = import ./environment.nix { inherit lib; };
|
||||
|
||||
log_length = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
default = null;
|
||||
example = 3000;
|
||||
};
|
||||
log_level = mkOption {
|
||||
type = types.nullOr (types.enum [
|
||||
"trace"
|
||||
"debug"
|
||||
"info"
|
||||
"warn"
|
||||
"error"
|
||||
"fatal"
|
||||
"panic"
|
||||
]);
|
||||
default = null;
|
||||
example = "info";
|
||||
};
|
||||
log_location = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "./pc.log";
|
||||
};
|
||||
|
||||
shell = {
|
||||
shell_argument = mkOption {
|
||||
type = types.str;
|
||||
default = "-c";
|
||||
example = "-c";
|
||||
};
|
||||
shell_command = import ./command.nix { inherit lib; } {
|
||||
description = ''
|
||||
The shell to use to run the process `command`s.
|
||||
|
||||
For reproducibility across systems, by default this uses
|
||||
`pkgs.bash`.
|
||||
'';
|
||||
default = pkgs.bash;
|
||||
};
|
||||
};
|
||||
|
||||
version = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "0.5";
|
||||
};
|
||||
};
|
||||
};
|
||||
example =
|
||||
# packages.${system}.watch-server becomes available
|
||||
# execute `nix run .#watch-server` or incude packages.${system}.watch-server
|
||||
# as a nativeBuildInput to your devShell
|
||||
literalExpression ''
|
||||
{
|
||||
watch-server = {
|
||||
processes = {
|
||||
backend = "''${pkgs.simple-http-server}";
|
||||
frontend = "''${pkgs.simple-http-server}";
|
||||
};
|
||||
};
|
||||
};
|
||||
'';
|
||||
description = ''
|
||||
For each attribute `x = process-compose config` a flake app and package `x` is added to the flake.
|
||||
Which runs process-compose with the declared config.
|
||||
'';
|
||||
};
|
||||
|
||||
outputs.settingsYaml = mkOption {
|
||||
type = types.attrsOf types.raw;
|
||||
internal = true;
|
||||
};
|
||||
};
|
||||
|
||||
config.outputs.settingsYaml =
|
||||
let
|
||||
removeNullAndEmptyAttrs = attrs:
|
||||
let
|
||||
f = lib.filterAttrsRecursive (key: value: value != null && value != { });
|
||||
# filterAttrsRecursive doesn't delete the *resulting* empty attrs, so we must
|
||||
# evaluate it again and to get rid of it.
|
||||
in
|
||||
lib.pipe attrs [ f f ];
|
||||
toYAMLFile =
|
||||
attrs:
|
||||
pkgs.runCommand "toYamlFile" { buildInputs = [ pkgs.yq-go ]; } ''
|
||||
yq -P '.' ${pkgs.writeTextFile { name = "process-compose-${name}.json"; text = (builtins.toJSON attrs); }} > $out
|
||||
'';
|
||||
in
|
||||
toYAMLFile (removeNullAndEmptyAttrs config.settings);
|
||||
}
|
||||
|
6
nix/process-compose/settings/environment.nix
Normal file
6
nix/process-compose/settings/environment.nix
Normal file
@ -0,0 +1,6 @@
|
||||
{ lib, ... }:
|
||||
lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.str);
|
||||
default = null;
|
||||
example = [ "ABC=2221" "PRINT_ERR=111" ];
|
||||
}
|
68
nix/process-compose/settings/probe.nix
Normal file
68
nix/process-compose/settings/probe.nix
Normal file
@ -0,0 +1,68 @@
|
||||
{ lib, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) types mkOption;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
failure_threshold = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 3;
|
||||
example = 3;
|
||||
};
|
||||
http_get = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
options = {
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
example = "google.com";
|
||||
};
|
||||
scheme = mkOption {
|
||||
type = types.str;
|
||||
default = "http";
|
||||
example = "http";
|
||||
};
|
||||
path = mkOption {
|
||||
type = types.str;
|
||||
default = "/";
|
||||
example = "/";
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
example = "8080";
|
||||
};
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
};
|
||||
exec = mkOption {
|
||||
type = types.nullOr (types.submodule {
|
||||
command = mkOption {
|
||||
type = types.str;
|
||||
example = "ps -ef | grep -v grep | grep my-proccess";
|
||||
};
|
||||
});
|
||||
default = null;
|
||||
};
|
||||
initial_delay_seconds = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 0;
|
||||
example = 0;
|
||||
};
|
||||
period_seconds = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 10;
|
||||
example = 10;
|
||||
};
|
||||
success_threshold = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 1;
|
||||
example = 1;
|
||||
};
|
||||
timeout_seconds = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
default = 3;
|
||||
example = 3;
|
||||
};
|
||||
};
|
||||
}
|
117
nix/process-compose/settings/process.nix
Normal file
117
nix/process-compose/settings/process.nix
Normal file
@ -0,0 +1,117 @@
|
||||
{ lib, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) types mkOption;
|
||||
probeType = types.submoduleWith {
|
||||
specialArgs = { inherit lib; };
|
||||
modules = [ ./probe.nix ];
|
||||
};
|
||||
in
|
||||
{
|
||||
options = {
|
||||
command = import ./command.nix { inherit lib; } {
|
||||
description = ''
|
||||
The command that runs this process
|
||||
|
||||
If a package is given, its executable is used as the command. This is
|
||||
useful to pass in a `writeShellApplication.`
|
||||
'';
|
||||
};
|
||||
|
||||
depends_on = mkOption {
|
||||
description = "Process dependency relationships";
|
||||
type = types.nullOr (types.attrsOf (types.submodule {
|
||||
options = {
|
||||
condition = mkOption {
|
||||
type = types.enum [
|
||||
"process_completed"
|
||||
"process_completed_successfully"
|
||||
"process_healthy"
|
||||
"process_started"
|
||||
];
|
||||
example = "process_healthy";
|
||||
};
|
||||
};
|
||||
}));
|
||||
default = null;
|
||||
};
|
||||
|
||||
availability = {
|
||||
restart = mkOption {
|
||||
type = types.nullOr (types.enum [
|
||||
"always"
|
||||
"on_failure"
|
||||
"exit_on_failure"
|
||||
"no"
|
||||
]);
|
||||
default = null;
|
||||
example = "on_failure";
|
||||
};
|
||||
backoff_seconds = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
default = null;
|
||||
example = 2;
|
||||
};
|
||||
max_restarts = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
default = null;
|
||||
example = 0;
|
||||
};
|
||||
};
|
||||
|
||||
shutdown = {
|
||||
command = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "sleep 2 && pkill -f 'test_loop.bash my-proccess'";
|
||||
};
|
||||
signal = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
default = null;
|
||||
example = 15;
|
||||
};
|
||||
timeout_seconds = mkOption {
|
||||
type = types.nullOr types.ints.unsigned;
|
||||
default = null;
|
||||
example = 10;
|
||||
};
|
||||
};
|
||||
|
||||
working_dir = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "/tmp";
|
||||
};
|
||||
readiness_probe = mkOption {
|
||||
type = types.nullOr probeType;
|
||||
default = null;
|
||||
};
|
||||
liveness_probe = mkOption {
|
||||
type = types.nullOr probeType;
|
||||
default = null;
|
||||
};
|
||||
|
||||
environment = import ./environment.nix { inherit lib; };
|
||||
log_location = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
example = "./pc.my-proccess.log";
|
||||
};
|
||||
disable_ansi_colors = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
example = true;
|
||||
};
|
||||
is_daemon = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
example = true;
|
||||
};
|
||||
disabled = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
example = true;
|
||||
};
|
||||
|
||||
};
|
||||
}
|
@ -17,8 +17,10 @@
|
||||
process-compose."default" = {
|
||||
tui = false;
|
||||
settings = {
|
||||
environment = [
|
||||
"DATAFILE=data.sqlite"
|
||||
];
|
||||
processes = {
|
||||
|
||||
# Create a simple sqlite db
|
||||
sqlite-init.command =
|
||||
let
|
||||
@ -30,21 +32,28 @@
|
||||
'';
|
||||
};
|
||||
in
|
||||
''
|
||||
echo "`date`: Creating database..."
|
||||
${lib.getExe pkgs.sqlite} data.sqlite < ${sqlFile}
|
||||
echo "`date`: Done."
|
||||
'';
|
||||
pkgs.writeShellApplication {
|
||||
name = "sqlite-init";
|
||||
text = ''
|
||||
echo "$(date): Creating database ($DATAFILE) ..."
|
||||
${lib.getExe pkgs.sqlite} "$DATAFILE" < ${sqlFile}
|
||||
echo "$(date): Done."
|
||||
'';
|
||||
};
|
||||
|
||||
# Query something, write to result.txt
|
||||
sqlite-query = {
|
||||
command = ''
|
||||
${lib.getExe pkgs.sqlite} data.sqlite \
|
||||
'select val from demo where val = "Hello"' \
|
||||
> result.txt
|
||||
'';
|
||||
command = pkgs.writeShellApplication {
|
||||
name = "sqlite-query";
|
||||
text = ''
|
||||
${lib.getExe pkgs.sqlite} "$DATAFILE" \
|
||||
'select val from demo where val = "Hello"' \
|
||||
> result.txt
|
||||
'';
|
||||
};
|
||||
# The 'depends_on' will have this process wait until the above one is completed.
|
||||
depends_on."sqlite-init".condition = "process_completed_successfully";
|
||||
availability.restart = "no";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -6,6 +6,6 @@ cd "$(dirname "$0")"
|
||||
(cd ../example && nix build -L --override-input process-compose-flake ..)
|
||||
|
||||
# Then run the test.
|
||||
rm -f ./data.sqlite
|
||||
rm -f ./data.sqlite ./result.txt
|
||||
nix run -L --override-input process-compose-flake .. .
|
||||
[[ $(cat result.txt) == "Hello" ]] && echo "Test passed" || (echo "Test failed" && exit 1)
|
||||
|
Loading…
Reference in New Issue
Block a user