forked from pub-solar/os
nixos/invoiceplane: merge upstream module fixes
This commit is contained in:
parent
555dd5d133
commit
2196ed1427
|
@ -4,9 +4,16 @@ let
|
||||||
inherit (lib)
|
inherit (lib)
|
||||||
any
|
any
|
||||||
attrValues
|
attrValues
|
||||||
|
boolToString
|
||||||
concatMapStringsSep
|
concatMapStringsSep
|
||||||
concatStrings
|
concatStrings
|
||||||
|
concatStringsSep
|
||||||
|
escapeShellArg
|
||||||
flatten
|
flatten
|
||||||
|
isBool
|
||||||
|
isInt
|
||||||
|
isList
|
||||||
|
isString
|
||||||
literalExpression
|
literalExpression
|
||||||
mapAttrs'
|
mapAttrs'
|
||||||
mapAttrsToList
|
mapAttrsToList
|
||||||
|
@ -16,6 +23,7 @@ let
|
||||||
mkMerge
|
mkMerge
|
||||||
mkOption
|
mkOption
|
||||||
nameValuePair
|
nameValuePair
|
||||||
|
optionalString
|
||||||
types;
|
types;
|
||||||
|
|
||||||
cfg = config.services.invoiceplane;
|
cfg = config.services.invoiceplane;
|
||||||
|
@ -31,7 +39,7 @@ let
|
||||||
DB_HOSTNAME=${cfg.database.host}
|
DB_HOSTNAME=${cfg.database.host}
|
||||||
DB_USERNAME=${cfg.database.user}
|
DB_USERNAME=${cfg.database.user}
|
||||||
# NOTE: file_get_contents adds newline at the end of returned string
|
# NOTE: file_get_contents adds newline at the end of returned string
|
||||||
DB_PASSWORD=${if cfg.database.passwordFile == null then "" else "trim(file_get_contents('${cfg.database.passwordFile}'),\"\\r\\n\")"}
|
DB_PASSWORD=${optionalString (cfg.database.passwordFile != null) "trim(file_get_contents('${cfg.database.passwordFile}'), \"\\r\\n\")"}
|
||||||
DB_DATABASE=${cfg.database.name}
|
DB_DATABASE=${cfg.database.name}
|
||||||
DB_PORT=${toString cfg.database.port}
|
DB_PORT=${toString cfg.database.port}
|
||||||
SESS_EXPIRATION=864000
|
SESS_EXPIRATION=864000
|
||||||
|
@ -43,19 +51,28 @@ let
|
||||||
REMOVE_INDEXPHP=true
|
REMOVE_INDEXPHP=true
|
||||||
'';
|
'';
|
||||||
|
|
||||||
extraConfig = hostName: cfg: pkgs.writeText "extraConfig.php" ''
|
mkPhpValue = v:
|
||||||
${toString cfg.extraConfig}
|
if isString v then escapeShellArg v
|
||||||
'';
|
# NOTE: If any value contains a , (comma) this will not get escaped
|
||||||
|
else if isList v && any lib.strings.isCoercibleToString v then escapeShellArg (concatMapStringsSep "," toString v)
|
||||||
|
else if isInt v then toString v
|
||||||
|
else if isBool v then boolToString v
|
||||||
|
else abort "The Invoiceplane config value ${lib.generators.toPretty {} v} can not be encoded."
|
||||||
|
;
|
||||||
|
|
||||||
|
extraConfig = hostName: cfg: let
|
||||||
|
settings = mapAttrsToList (k: v: "${k}=${mkPhpValue v}") cfg.settings;
|
||||||
|
in pkgs.writeText "extraConfig.php" (concatStringsSep "\n" settings);
|
||||||
|
|
||||||
pkg = hostName: cfg: pkgs.stdenv.mkDerivation rec {
|
pkg = hostName: cfg: pkgs.stdenv.mkDerivation rec {
|
||||||
pname = "invoiceplane-${hostName}";
|
pname = "invoiceplane-${hostName}";
|
||||||
version = src.version;
|
version = src.version;
|
||||||
src = pkgs.invoiceplane;
|
src = pkgs.invoiceplane;
|
||||||
|
|
||||||
postPhase = ''
|
postPatch = ''
|
||||||
# Patch index.php file to load additional config file
|
# Patch index.php file to load additional config file
|
||||||
substituteInPlace index.php \
|
substituteInPlace index.php \
|
||||||
--replace "require('vendor/autoload.php');" "require('vendor/autoload.php'); \$dotenv = Dotenv\Dotenv::createImmutable(__DIR__, 'extraConfig.php'); \$dotenv->load();";
|
--replace-fail "require('vendor/autoload.php');" "require('vendor/autoload.php'); \$dotenv = Dotenv\Dotenv::createImmutable(__DIR__, 'extraConfig.php'); \$dotenv->load();";
|
||||||
'';
|
'';
|
||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
|
@ -79,16 +96,16 @@ let
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
siteOpts = { lib, name, ... }:
|
siteOpts = { name, ... }:
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
enable = mkEnableOption (lib.mdDoc "InvoicePlane web application");
|
enable = mkEnableOption "InvoicePlane web application";
|
||||||
|
|
||||||
stateDir = mkOption {
|
stateDir = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
default = "/var/lib/invoiceplane/${name}";
|
default = "/var/lib/invoiceplane/${name}";
|
||||||
description = lib.mdDoc ''
|
description = ''
|
||||||
This directory is used for uploads of attachments and cache.
|
This directory is used for uploads of attachments and cache.
|
||||||
The directory passed here is automatically created and permissions
|
The directory passed here is automatically created and permissions
|
||||||
adjusted as required.
|
adjusted as required.
|
||||||
|
@ -99,32 +116,32 @@ let
|
||||||
host = mkOption {
|
host = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "localhost";
|
default = "localhost";
|
||||||
description = lib.mdDoc "Database host address.";
|
description = "Database host address.";
|
||||||
};
|
};
|
||||||
|
|
||||||
port = mkOption {
|
port = mkOption {
|
||||||
type = types.port;
|
type = types.port;
|
||||||
default = 3306;
|
default = 3306;
|
||||||
description = lib.mdDoc "Database host port.";
|
description = "Database host port.";
|
||||||
};
|
};
|
||||||
|
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "invoiceplane";
|
default = "invoiceplane";
|
||||||
description = lib.mdDoc "Database name.";
|
description = "Database name.";
|
||||||
};
|
};
|
||||||
|
|
||||||
user = mkOption {
|
user = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "invoiceplane";
|
default = "invoiceplane";
|
||||||
description = lib.mdDoc "Database user.";
|
description = "Database user.";
|
||||||
};
|
};
|
||||||
|
|
||||||
passwordFile = mkOption {
|
passwordFile = mkOption {
|
||||||
type = types.nullOr types.path;
|
type = types.nullOr types.path;
|
||||||
default = null;
|
default = null;
|
||||||
example = "/run/keys/invoiceplane-dbpassword";
|
example = "/run/keys/invoiceplane-dbpassword";
|
||||||
description = lib.mdDoc ''
|
description = ''
|
||||||
A file containing the password corresponding to
|
A file containing the password corresponding to
|
||||||
{option}`database.user`.
|
{option}`database.user`.
|
||||||
'';
|
'';
|
||||||
|
@ -133,14 +150,14 @@ let
|
||||||
createLocally = mkOption {
|
createLocally = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
description = lib.mdDoc "Create the database and database user locally.";
|
description = "Create the database and database user locally.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
invoiceTemplates = mkOption {
|
invoiceTemplates = mkOption {
|
||||||
type = types.listOf types.path;
|
type = types.listOf types.path;
|
||||||
default = [];
|
default = [];
|
||||||
description = lib.mdDoc ''
|
description = ''
|
||||||
List of path(s) to respective template(s) which are copied from the 'invoice_templates/pdf' directory.
|
List of path(s) to respective template(s) which are copied from the 'invoice_templates/pdf' directory.
|
||||||
|
|
||||||
::: {.note}
|
::: {.note}
|
||||||
|
@ -179,45 +196,44 @@ let
|
||||||
"pm.max_spare_servers" = 4;
|
"pm.max_spare_servers" = 4;
|
||||||
"pm.max_requests" = 500;
|
"pm.max_requests" = 500;
|
||||||
};
|
};
|
||||||
description = lib.mdDoc ''
|
description = ''
|
||||||
Options for the InvoicePlane PHP pool. See the documentation on `php-fpm.conf`
|
Options for the InvoicePlane PHP pool. See the documentation on `php-fpm.conf`
|
||||||
for details on configuration directives.
|
for details on configuration directives.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
extraConfig = mkOption {
|
settings = mkOption {
|
||||||
type = types.nullOr types.lines;
|
type = types.attrsOf types.anything;
|
||||||
default = null;
|
default = {};
|
||||||
example = ''
|
description = ''
|
||||||
SETUP_COMPLETED=true
|
Structural InvoicePlane configuration. Refer to
|
||||||
DISABLE_SETUP=true
|
|
||||||
IP_URL=https://invoice.example.com
|
|
||||||
'';
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
InvoicePlane configuration. Refer to
|
|
||||||
<https://github.com/InvoicePlane/InvoicePlane/blob/master/ipconfig.php.example>
|
<https://github.com/InvoicePlane/InvoicePlane/blob/master/ipconfig.php.example>
|
||||||
for details on supported values.
|
for details and supported values.
|
||||||
|
'';
|
||||||
|
example = literalExpression ''
|
||||||
|
{
|
||||||
|
SETUP_COMPLETED = true;
|
||||||
|
DISABLE_SETUP = true;
|
||||||
|
IP_URL = "https://invoice.example.com";
|
||||||
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
cron = {
|
cron = {
|
||||||
|
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
description = lib.mdDoc ''
|
description = ''
|
||||||
Enable cron service which periodically runs Invoiceplane tasks.
|
Enable cron service which periodically runs Invoiceplane tasks.
|
||||||
Requires key taken from the administration page. Refer to
|
Requires key taken from the administration page. Refer to
|
||||||
<https://wiki.invoiceplane.com/en/1.0/modules/recurring-invoices>
|
<https://wiki.invoiceplane.com/en/1.0/modules/recurring-invoices>
|
||||||
on how to configure it.
|
on how to configure it.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
key = mkOption {
|
key = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = lib.mdDoc "Cron key taken from the administration page.";
|
description = "Cron key taken from the administration page.";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -237,20 +253,20 @@ in
|
||||||
options.sites = mkOption {
|
options.sites = mkOption {
|
||||||
type = types.attrsOf (types.submodule siteOpts);
|
type = types.attrsOf (types.submodule siteOpts);
|
||||||
default = {};
|
default = {};
|
||||||
description = lib.mdDoc "Specification of one or more WordPress sites to serve";
|
description = "Specification of one or more WordPress sites to serve";
|
||||||
};
|
};
|
||||||
|
|
||||||
options.webserver = mkOption {
|
options.webserver = mkOption {
|
||||||
type = types.enum [ "caddy" "nginx" ];
|
type = types.enum [ "caddy" "nginx" ];
|
||||||
default = "caddy";
|
default = "caddy";
|
||||||
description = lib.mdDoc ''
|
example = "nginx";
|
||||||
Which webserver to use for virtual host management. Currently only
|
description = ''
|
||||||
caddy is supported.
|
Which webserver to use for virtual host management.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
default = {};
|
default = {};
|
||||||
description = lib.mdDoc "InvoicePlane configuration.";
|
description = "InvoicePlane configuration.";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -258,8 +274,8 @@ in
|
||||||
# implementation
|
# implementation
|
||||||
config = mkIf (eachSite != {}) (mkMerge [{
|
config = mkIf (eachSite != {}) (mkMerge [{
|
||||||
|
|
||||||
assertions = flatten (mapAttrsToList (hostName: cfg:
|
assertions = flatten (mapAttrsToList (hostName: cfg: [
|
||||||
[{ assertion = cfg.database.createLocally -> cfg.database.user == user;
|
{ assertion = cfg.database.createLocally -> cfg.database.user == user;
|
||||||
message = ''services.invoiceplane.sites."${hostName}".database.user must be ${user} if the database is to be automatically provisioned'';
|
message = ''services.invoiceplane.sites."${hostName}".database.user must be ${user} if the database is to be automatically provisioned'';
|
||||||
}
|
}
|
||||||
{ assertion = cfg.database.createLocally -> cfg.database.passwordFile == null;
|
{ assertion = cfg.database.createLocally -> cfg.database.passwordFile == null;
|
||||||
|
@ -377,8 +393,8 @@ in
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
enable = true;
|
enable = true;
|
||||||
virtualHosts = mapAttrs' (hostName: cfg: (
|
virtualHosts = mapAttrs' (hostName: cfg: (
|
||||||
nameValuePair "${hostName}" {
|
nameValuePair hostName {
|
||||||
root = "${pkg hostName cfg}";
|
root = pkg hostName cfg;
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
index index.php index.html index.htm;
|
index index.php index.html index.htm;
|
||||||
|
|
||||||
|
@ -397,8 +413,8 @@ in
|
||||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
fastcgi_pass unix:${config.services.phpfpm.pools."invoiceplane-${hostName}".socket};
|
fastcgi_pass unix:${config.services.phpfpm.pools."invoiceplane-${hostName}".socket};
|
||||||
include ${pkgs.nginx}/conf/fastcgi_params;
|
include ${config.services.nginx.package}/conf/fastcgi_params;
|
||||||
include ${pkgs.nginx}/conf/fastcgi.conf;
|
include ${config.services.nginx.package}/conf/fastcgi.conf;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue