Add NixOS modules
This commit is contained in:
		
							
								
								
									
										21
									
								
								flake.nix
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								flake.nix
									
									
									
									
									
								
							| @@ -100,7 +100,28 @@ | ||||
|         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 = { | ||||
|   | ||||
							
								
								
									
										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 = { }; | ||||
|   }; | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user