mirror of
https://github.com/juspay/services-flake.git
synced 2024-09-17 15:28:33 +03:00
add pgAdmin service (#115)
This commit is contained in:
parent
bdd6dde41a
commit
5e48c5a965
18
doc/pgadmin.md
Normal file
18
doc/pgadmin.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# pgAdmin
|
||||||
|
|
||||||
|
[pgAdmin] is a feature rich Open Source administration and development platform for PostgreSQL.
|
||||||
|
|
||||||
|
[pgAdmin]: https://www.pgadmin.org/
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# In `perSystem.process-compose.<name>`
|
||||||
|
{
|
||||||
|
services.pgadmin."pgad1" = {
|
||||||
|
enable = true;
|
||||||
|
initialEmail = "email@gmail.com";
|
||||||
|
initialPassword = "password";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
@ -18,6 +18,7 @@ short-title: Services
|
|||||||
- [ ] Zookeeper
|
- [ ] Zookeeper
|
||||||
- [x] [[grafana]]#
|
- [x] [[grafana]]#
|
||||||
- [X] [[prometheus]]#
|
- [X] [[prometheus]]#
|
||||||
|
- [X] [[pgadmin]]#
|
||||||
- [ ] ...
|
- [ ] ...
|
||||||
|
|
||||||
[gh]: https://github.com/juspay/services-flake
|
[gh]: https://github.com/juspay/services-flake
|
||||||
|
@ -15,5 +15,6 @@ in
|
|||||||
./zookeeper.nix
|
./zookeeper.nix
|
||||||
./grafana.nix
|
./grafana.nix
|
||||||
./prometheus.nix
|
./prometheus.nix
|
||||||
|
./pgadmin.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
171
nix/pgadmin.nix
Normal file
171
nix/pgadmin.nix
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
# Based on https://github.com/NixOS/nixpkgs/blob/d53c2037394da6fe98decca417fc8fda64bf2443/nixos/modules/services/admin/pgadmin.nix
|
||||||
|
{ pkgs, lib, name, config, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib) types;
|
||||||
|
|
||||||
|
_base = with types; [ int bool str ];
|
||||||
|
base = with types; oneOf ([ (listOf (oneOf _base)) (attrsOf (oneOf _base)) ] ++ _base);
|
||||||
|
|
||||||
|
formatAttrset = attr:
|
||||||
|
"{${lib.concatStringsSep "\n" (lib.mapAttrsToList (key: value: "${builtins.toJSON key}: ${formatPyValue value},") attr)}}";
|
||||||
|
|
||||||
|
formatPyValue = value:
|
||||||
|
if builtins.isString value then builtins.toJSON value
|
||||||
|
else if value ? _expr then value._expr
|
||||||
|
else if builtins.isInt value then toString value
|
||||||
|
else if builtins.isBool value then (if value then "True" else "False")
|
||||||
|
else if builtins.isAttrs value then (formatAttrset value)
|
||||||
|
else if builtins.isList value then "[${lib.concatStringsSep "\n" (map (v: "${formatPyValue v},") value)}]"
|
||||||
|
else throw "Unrecognized type";
|
||||||
|
|
||||||
|
formatPy = attrs:
|
||||||
|
lib.concatStringsSep "\n" (lib.mapAttrsToList (key: value: "${key} = ${formatPyValue value}") attrs);
|
||||||
|
|
||||||
|
pyType = with types; attrsOf (oneOf [ (attrsOf base) (listOf base) base ]);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
enable = lib.mkEnableOption name;
|
||||||
|
|
||||||
|
package = lib.mkPackageOption pkgs "pgadmin4" { };
|
||||||
|
|
||||||
|
host = lib.mkOption {
|
||||||
|
description = lib.mdDoc "Host for pgadmin4 to run on";
|
||||||
|
type = types.str;
|
||||||
|
default = "localhost";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = lib.mkOption {
|
||||||
|
description = lib.mdDoc "Port for pgadmin4 to run on";
|
||||||
|
type = types.port;
|
||||||
|
default = 5050;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
initialEmail = lib.mkOption {
|
||||||
|
description = "Initial email for the pgAdmin account";
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
initialPassword = lib.mkOption {
|
||||||
|
description = "Initial password for the pgAdmin account";
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
minimumPasswordLength = lib.mkOption {
|
||||||
|
description = "Minimum length of the password";
|
||||||
|
type = types.int;
|
||||||
|
default = 6;
|
||||||
|
};
|
||||||
|
|
||||||
|
dataDir = lib.mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "./data/${name}";
|
||||||
|
description = "The pgadmin4 data directory";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraDefaultConfig = lib.mkOption {
|
||||||
|
type = pyType;
|
||||||
|
internal = true;
|
||||||
|
readOnly = true;
|
||||||
|
default = {
|
||||||
|
DATA_DIR = {
|
||||||
|
_expr = "os.getenv('PGADMIN_DATADIR')";
|
||||||
|
};
|
||||||
|
DEFAULT_SERVER = config.host;
|
||||||
|
DEFAULT_SERVER_PORT = config.port;
|
||||||
|
PASSWORD_LENGTH_MIN = config.minimumPasswordLength;
|
||||||
|
SERVER_MODE = true;
|
||||||
|
UPGRADE_CHECK_ENABLED = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = lib.mkOption {
|
||||||
|
type = pyType;
|
||||||
|
default = { };
|
||||||
|
description = "Additional config for pgadmin4";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs.settings = lib.mkOption {
|
||||||
|
type = types.deferredModule;
|
||||||
|
internal = true;
|
||||||
|
readOnly = true;
|
||||||
|
default = {
|
||||||
|
processes =
|
||||||
|
let
|
||||||
|
pgadminConfig = pkgs.writeTextDir "config_local.py" (
|
||||||
|
"import os\n" + (formatPy
|
||||||
|
(lib.recursiveUpdate config.extraDefaultConfig config.extraConfig))
|
||||||
|
);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
"${name}-init" =
|
||||||
|
let
|
||||||
|
setupScript = pkgs.writeShellApplication {
|
||||||
|
name = "setup-pgadmin";
|
||||||
|
runtimeInputs = [ config.package ];
|
||||||
|
text = ''
|
||||||
|
export PYTHONPATH="${pgadminConfig}"
|
||||||
|
PGADMIN_DATADIR="$(readlink -m ${config.dataDir})"
|
||||||
|
mkdir -p "$PGADMIN_DATADIR"
|
||||||
|
export PGADMIN_DATADIR
|
||||||
|
PGADMIN_SETUP_EMAIL=${lib.escapeShellArg config.initialEmail}
|
||||||
|
export PGADMIN_SETUP_EMAIL
|
||||||
|
PGADMIN_SETUP_PASSWORD=${lib.escapeShellArg config.initialPassword}
|
||||||
|
export PGADMIN_SETUP_PASSWORD
|
||||||
|
if [ -f ${config.package}/bin/.pgadmin4-setup-wrapped ]; then
|
||||||
|
# pgadmin-7.5 has .pgadmin4-setup-wrapped
|
||||||
|
${config.package}/bin/.pgadmin4-setup-wrapped setup
|
||||||
|
else
|
||||||
|
# pgadmin-8.2 has .pgadmin4-cli-wrapped
|
||||||
|
${config.package}/bin/.pgadmin4-cli-wrapped setup
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
command = setupScript;
|
||||||
|
namespace = name;
|
||||||
|
};
|
||||||
|
|
||||||
|
"${name}" =
|
||||||
|
let
|
||||||
|
startScript = pkgs.writeShellApplication {
|
||||||
|
name = "start-pgadmin";
|
||||||
|
runtimeInputs = [ config.package ];
|
||||||
|
text = ''
|
||||||
|
export PYTHONPATH="${pgadminConfig}"
|
||||||
|
PGADMIN_DATADIR="$(readlink -m ${config.dataDir})"
|
||||||
|
export PGADMIN_DATADIR
|
||||||
|
PGADMIN_SETUP_EMAIL=${lib.escapeShellArg config.initialEmail}
|
||||||
|
export PGADMIN_SETUP_EMAIL
|
||||||
|
PGADMIN_SETUP_PASSWORD=${lib.escapeShellArg config.initialPassword}
|
||||||
|
export PGADMIN_SETUP_PASSWORD
|
||||||
|
${config.package}/bin/.pgadmin4-wrapped
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
command = startScript;
|
||||||
|
readiness_probe = {
|
||||||
|
http_get = {
|
||||||
|
host = config.host;
|
||||||
|
port = config.port;
|
||||||
|
path = "/misc/ping";
|
||||||
|
};
|
||||||
|
initial_delay_seconds = 2;
|
||||||
|
period_seconds = 10;
|
||||||
|
timeout_seconds = 4;
|
||||||
|
success_threshold = 1;
|
||||||
|
failure_threshold = 5;
|
||||||
|
};
|
||||||
|
namespace = name;
|
||||||
|
depends_on."${name}-init".condition = "process_completed_successfully";
|
||||||
|
# https://github.com/F1bonacc1/process-compose#-auto-restart-if-not-healthy
|
||||||
|
availability.restart = "on_failure";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
23
nix/pgadmin_test.nix
Normal file
23
nix/pgadmin_test.nix
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{ pkgs, config, ... }: {
|
||||||
|
|
||||||
|
services.pgadmin."pgad1" = {
|
||||||
|
enable = true;
|
||||||
|
initialEmail = "email@gmail.com";
|
||||||
|
initialPassword = "password";
|
||||||
|
};
|
||||||
|
|
||||||
|
settings.processes.test =
|
||||||
|
let
|
||||||
|
cfg = config.services.pgadmin."pgad1";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
command = pkgs.writeShellApplication {
|
||||||
|
runtimeInputs = [ cfg.package pkgs.curl pkgs.gnugrep ];
|
||||||
|
text = ''
|
||||||
|
curl http://localhost:5050/misc/ping | grep "PING"
|
||||||
|
'';
|
||||||
|
name = "pgadmin-test";
|
||||||
|
};
|
||||||
|
depends_on."pgad1".condition = "process_healthy";
|
||||||
|
};
|
||||||
|
}
|
@ -17,6 +17,12 @@
|
|||||||
inherit system;
|
inherit system;
|
||||||
# Required for elastic search
|
# Required for elastic search
|
||||||
config.allowUnfree = true;
|
config.allowUnfree = true;
|
||||||
|
overlays = [
|
||||||
|
(final: prev: {
|
||||||
|
# Because tests are failing on darwin: https://github.com/juspay/services-flake/pull/115#issuecomment-1970467684
|
||||||
|
pgadmin4 = prev.pgadmin4.overrideAttrs (_: { doInstallCheck = false; });
|
||||||
|
})
|
||||||
|
];
|
||||||
};
|
};
|
||||||
process-compose =
|
process-compose =
|
||||||
let
|
let
|
||||||
@ -48,6 +54,7 @@
|
|||||||
"${inputs.services-flake}/nix/zookeeper_test.nix"
|
"${inputs.services-flake}/nix/zookeeper_test.nix"
|
||||||
"${inputs.services-flake}/nix/grafana_test.nix"
|
"${inputs.services-flake}/nix/grafana_test.nix"
|
||||||
"${inputs.services-flake}/nix/prometheus_test.nix"
|
"${inputs.services-flake}/nix/prometheus_test.nix"
|
||||||
|
"${inputs.services-flake}/nix/pgadmin_test.nix"
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user