Add NixOS modules
This commit is contained in:
parent
6825ba8156
commit
3519bdcec4
21
flake.nix
21
flake.nix
@ -100,7 +100,28 @@
|
|||||||
pythonImportsCheck = [ "diffsync" ];
|
pythonImportsCheck = [ "diffsync" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
yate = pkgs.yate.overrideAttrs (old: {
|
||||||
|
configureFlags = [ "--with-libpq=${pkgs.postgresql.withPackages (ps: [ ])}" ];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
nixosModules = {
|
||||||
|
fieldpoc = { ... }: {
|
||||||
|
imports = [
|
||||||
|
./nix/modules/dhcp.nix
|
||||||
|
./nix/modules/fieldpoc.nix
|
||||||
|
./nix/modules/yate.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
nixpkgs.overlays = [
|
||||||
|
(_: _: {
|
||||||
|
inherit (self.packages."x86_64-linux")
|
||||||
|
fieldpoc
|
||||||
|
yate;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
default = self.nixosModules.fieldpoc;
|
||||||
};
|
};
|
||||||
|
|
||||||
hydraJobs = {
|
hydraJobs = {
|
||||||
|
141
nix/modules/dhcp.nix
Normal file
141
nix/modules/dhcp.nix
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.fieldpoc.dhcp;
|
||||||
|
in {
|
||||||
|
options.services.fieldpoc.dhcp = {
|
||||||
|
enable = mkEnableOption "fieldpoc-dhcp";
|
||||||
|
interface = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
subnet = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
pool = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
router = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
dnsServers = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
omm = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
reservations = mkOption {
|
||||||
|
type = with types; listOf (submodule {
|
||||||
|
options = {
|
||||||
|
name = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
macAddress = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
ipAddress = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.kea.dhcp4 = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
interfaces-config = {
|
||||||
|
interfaces = [ cfg.interface ];
|
||||||
|
};
|
||||||
|
option-def = [
|
||||||
|
{
|
||||||
|
space = "dhcp4";
|
||||||
|
name = "vendor-encapsulated-options";
|
||||||
|
code = 43;
|
||||||
|
type = "empty";
|
||||||
|
encapsulate = "sipdect";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
space = "sipdect";
|
||||||
|
name = "ommip1";
|
||||||
|
code = 10;
|
||||||
|
type = "ipv4-address";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
space = "sipdect";
|
||||||
|
name = "ommip2";
|
||||||
|
code = 19;
|
||||||
|
type = "ipv4-address";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
space = "sipdect";
|
||||||
|
name = "syslogip";
|
||||||
|
code = 14;
|
||||||
|
type = "ipv4-address";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
space = "sipdect";
|
||||||
|
name = "syslogport";
|
||||||
|
code = 15;
|
||||||
|
type = "int16";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
space = "dhcp4";
|
||||||
|
name = "magic_str";
|
||||||
|
code = 224;
|
||||||
|
type = "string";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
subnet4 = [
|
||||||
|
{
|
||||||
|
subnet = cfg.subnet;
|
||||||
|
pools = [
|
||||||
|
{
|
||||||
|
pool = cfg.pool;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
option-data = [
|
||||||
|
{
|
||||||
|
name = "routers";
|
||||||
|
data = cfg.router;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "domain-name-servers";
|
||||||
|
data = cfg.dnsServers;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "vendor-encapsulated-options";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
space = "sipdect";
|
||||||
|
name = "ommip1";
|
||||||
|
data = cfg.omm;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "magic_str";
|
||||||
|
data = "OpenMobilitySIP-DECT";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
reservations = map (r: {
|
||||||
|
hostname = r.name;
|
||||||
|
hw-address = r.macAddress;
|
||||||
|
ip-address = r.ipAddress;
|
||||||
|
option-data = [
|
||||||
|
{
|
||||||
|
name = "host-name";
|
||||||
|
data = r.name;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}) cfg.reservations;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
156
nix/modules/fieldpoc.nix
Normal file
156
nix/modules/fieldpoc.nix
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.fieldpoc;
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
services.fieldpoc = {
|
||||||
|
enable = mkEnableOption "fieldpoc";
|
||||||
|
ommIp = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
ommUser = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
ommPasswordPath = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
};
|
||||||
|
sipsecretPath = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
fieldpoc
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.services.fieldpoc = {
|
||||||
|
description = "Fieldpoc daemon";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network-online.target" "yate.service" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
ExecStart = "${pkgs.fieldpoc}/bin/fieldpoc -c /run/fieldpoc/config.json --debug";
|
||||||
|
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||||
|
User = "fieldpoc";
|
||||||
|
Group = "fieldpoc";
|
||||||
|
RuntimeDirectory = "fieldpoc";
|
||||||
|
RuntimeDirectoryMode = "0755";
|
||||||
|
ConfigurationDirectory = "fieldpoc";
|
||||||
|
StateDirectory = "fieldpoc";
|
||||||
|
StateDirectoryMode = "0700";
|
||||||
|
};
|
||||||
|
|
||||||
|
preStart = let
|
||||||
|
cfgFile = pkgs.writeText "config.json" (lib.generators.toJSON { } {
|
||||||
|
extensions = {
|
||||||
|
file = "/var/lib/fieldpoc/extensions.json";
|
||||||
|
};
|
||||||
|
controller = {
|
||||||
|
host = "127.0.0.1";
|
||||||
|
port = 9437;
|
||||||
|
};
|
||||||
|
dect = {
|
||||||
|
host = cfg.ommIp;
|
||||||
|
username = cfg.ommUser;
|
||||||
|
password = "!!OMMPASSWORD!!";
|
||||||
|
sipsecret = "!!SIPSECRET!!";
|
||||||
|
};
|
||||||
|
yate = {
|
||||||
|
host = "127.0.0.1";
|
||||||
|
port = 5039;
|
||||||
|
};
|
||||||
|
database = {
|
||||||
|
hostname = "127.0.0.1";
|
||||||
|
username = "fieldpoc";
|
||||||
|
password = "fieldpoc";
|
||||||
|
database = "fieldpoc";
|
||||||
|
};
|
||||||
|
});
|
||||||
|
in ''
|
||||||
|
${pkgs.gnused}/bin/sed -e "s/!!OMMPASSWORD!!/$(cat ${cfg.ommPasswordPath})/g" -e "s/!!SIPSECRET!!/$(cat ${cfg.sipsecretPath})/g" ${cfgFile} > /run/fieldpoc/config.json
|
||||||
|
if [ ! -f "/var/lib/fieldpoc/extensions.json" ]; then
|
||||||
|
echo '{"extensions": {}}' > /var/lib/fieldpoc/extensions.json
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.fieldpoc = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = "fieldpoc";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.fieldpoc = { };
|
||||||
|
|
||||||
|
services.postgresql = {
|
||||||
|
enable = true;
|
||||||
|
initialScript = pkgs.writeText "backend-initScript" ''
|
||||||
|
CREATE ROLE fieldpoc WITH LOGIN PASSWORD 'fieldpoc' CREATEDB;
|
||||||
|
CREATE DATABASE fieldpoc;
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE fieldpoc TO fieldpoc;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
services.yate = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
extmodule = {
|
||||||
|
"listener ywsd" = {
|
||||||
|
type = "tcp";
|
||||||
|
addr = "127.0.0.1";
|
||||||
|
port = "5039";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
cdrbuild = {
|
||||||
|
parameters = {
|
||||||
|
X-Eventphone-Id = "false";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
pgsqldb = {
|
||||||
|
default = {
|
||||||
|
host = "localhost";
|
||||||
|
port = "5432";
|
||||||
|
database = "fieldpoc";
|
||||||
|
user = "fieldpoc";
|
||||||
|
password = "fieldpoc";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
register = {
|
||||||
|
general = {
|
||||||
|
expires = 30;
|
||||||
|
"user.auth" = "yes";
|
||||||
|
"user.register" = "yes";
|
||||||
|
"user.unregister" = "yes";
|
||||||
|
"engine.timer" = "yes";
|
||||||
|
"call.cdr" = "yes";
|
||||||
|
"linetracker" = "yes";
|
||||||
|
};
|
||||||
|
default = {
|
||||||
|
priority = 30;
|
||||||
|
account = "default";
|
||||||
|
};
|
||||||
|
"user.auth" = {
|
||||||
|
query = "SELECT password FROM users WHERE username='\${username}' AND password IS NOT NULL AND password<>'' AND type='user' LIMIT 1;";
|
||||||
|
result = "password";
|
||||||
|
};
|
||||||
|
"user.register".query = "INSERT INTO registrations (username, location, oconnection_id, expires) VALUES ('\${username}', '\${data}', '\${oconnection_id}', NOW() + INTERVAL '\${expires} s') ON CONFLICT ON CONSTRAINT uniq_registrations DO UPDATE SET expires = NOW() + INTERVAL '\${expires} s'";
|
||||||
|
"user.unregister".query = "DELETE FROM registrations WHERE (username = '\${username}' AND location = '\${data}' AND oconnection_id = '\${connection_id}') OR ('\${username}' = '' AND '\${data}' = '' AND oconnection_id = '\${connection_id}')";
|
||||||
|
"engine.timer".query = "DELETE FROM registrations WHERE expires<=CURRENT_TIMESTAMP;";
|
||||||
|
"call.cdr".critial = "no";
|
||||||
|
"linetracker" = {
|
||||||
|
critical = "yes";
|
||||||
|
initquery = "UPDATE users SET inuse=0 WHERE inuse is not NULL;DELETE from active_calls;";
|
||||||
|
cdr_initialize = "UPDATE users SET inuse=inuse+1 WHERE username='\${external}';INSERT INTO active_calls SELECT username, x_eventphone_id FROM (SELECT '\${external}' as username, '\${X-Eventphone-Id}' as x_eventphone_id, '\${direction}' as direction) as active_call WHERE x_eventphone_id != '' AND x_eventphone_id IS NOT NULL and direction = 'outgoing';";
|
||||||
|
cdr_finalize = "UPDATE users SET inuse=(CASE WHEN inuse>0 THEN inuse-1 ELSE 0 END) WHERE username='\${external}';DELETE FROM active_calls WHERE username = '\${external}' AND x_eventphone_id = '\${X-Eventphone-Id}' AND '\${direction}' = 'outgoing';";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
56
nix/modules/yate.nix
Normal file
56
nix/modules/yate.nix
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.yate;
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
services.yate = {
|
||||||
|
enable = mkEnableOption "yate";
|
||||||
|
config = mkOption {
|
||||||
|
type = with types; attrsOf anything;
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
environment.etc = mapAttrs' (name: config: nameValuePair "yate/${name}.conf" { text = (if (isAttrs config) then generators.toINI {} config else config); }) cfg.config;
|
||||||
|
|
||||||
|
systemd.services.yate = {
|
||||||
|
description = "YATE Telephony Server";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network-online.target" "postgresql.service" ];
|
||||||
|
|
||||||
|
environment = { PWLIB_ASSERT_ACTION = "C"; };
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "forking";
|
||||||
|
ExecStart =
|
||||||
|
"${pkgs.yate}/bin/yate -d -p /run/yate/yate.pid -c /etc/yate -F -s -vvv -DF -r -l /var/lib/yate/yate.log";
|
||||||
|
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||||
|
User = "yate";
|
||||||
|
Group = "yate";
|
||||||
|
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
|
||||||
|
RuntimeDirectory = "yate";
|
||||||
|
RuntimeDirectoryMode = "0755";
|
||||||
|
ConfigurationDirectory = "yate";
|
||||||
|
StateDirectory = "yate";
|
||||||
|
StateDirectoryMode = "0700";
|
||||||
|
PIDFile = "/run/yate/yate.pid";
|
||||||
|
TimeoutSec = 30;
|
||||||
|
};
|
||||||
|
|
||||||
|
reloadTriggers = map (name: config.environment.etc."yate/${name}.conf".source) (attrNames cfg.config);
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.yate = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = "yate";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.yate = { };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user