forked from jan-leila/nix-config
		
	feat: drafted out database configuration and sgblur config
This commit is contained in:
		
							parent
							
								
									dbd5d36913
								
							
						
					
					
						commit
						01325c3068
					
				
					 1 changed files with 181 additions and 48 deletions
				
			
		|  | @ -6,16 +6,14 @@ | |||
|   ... | ||||
| }: | ||||
| with lib; let | ||||
|   cfg = config.services.panoramax; | ||||
| 
 | ||||
|   # Database configuration assertions | ||||
|   dbUrlConfigured = cfg.database.url != null; | ||||
|   dbUrlConfigured = config.services.panoramax.database.url != null; | ||||
|   individualDbConfigured = all (x: x != null) [ | ||||
|     cfg.database.host | ||||
|     cfg.database.port | ||||
|     cfg.database.username | ||||
|     cfg.database.password | ||||
|     cfg.database.name | ||||
|     config.services.panoramax.database.host | ||||
|     config.services.panoramax.database.port | ||||
|     config.services.panoramax.database.username | ||||
|     config.services.panoramax.database.password | ||||
|     config.services.panoramax.database.name | ||||
|   ]; | ||||
| 
 | ||||
|   envContent = '' | ||||
|  | @ -23,23 +21,24 @@ with lib; let | |||
|     FLASK_APP=geovisio | ||||
|     ${ | ||||
|       if dbUrlConfigured | ||||
|       then "DB_URL=${cfg.database.url}" | ||||
|       then "DB_URL=${config.services.panoramax.database.url}" | ||||
|       else '' | ||||
|         DB_HOST=${cfg.database.host} | ||||
|         DB_PORT=${toString cfg.database.port} | ||||
|         DB_USERNAME=${cfg.database.username} | ||||
|         DB_PASSWORD=${cfg.database.password} | ||||
|         DB_NAME=${cfg.database.name} | ||||
|         DB_HOST=${config.services.panoramax.database.host} | ||||
|         DB_PORT=${toString config.services.panoramax.database.port} | ||||
|         DB_USERNAME=${config.services.panoramax.database.username} | ||||
|         DB_PASSWORD=${config.services.panoramax.database.password} | ||||
|         DB_NAME=${config.services.panoramax.database.name} | ||||
|       '' | ||||
|     } | ||||
|     ${optionalString (cfg.storage.fsUrl != null) "FS_URL=${cfg.storage.fsUrl}"} | ||||
|     ${optionalString (cfg.infrastructure.nbProxies != null) "INFRA_NB_PROXIES=${toString cfg.infrastructure.nbProxies}"} | ||||
|     ${optionalString (cfg.flask.secretKey != null) "FLASK_SECRET_KEY=${cfg.flask.secretKey}"} | ||||
|     ${optionalString (cfg.flask.sessionCookieDomain != null) "FLASK_SESSION_COOKIE_DOMAIN=${cfg.flask.sessionCookieDomain}"} | ||||
|     ${optionalString (cfg.api.pictures.licenseSpdxId != null) "API_PICTURES_LICENSE_SPDX_ID=${cfg.api.pictures.licenseSpdxId}"} | ||||
|     ${optionalString (cfg.api.pictures.licenseUrl != null) "API_PICTURES_LICENSE_URL=${cfg.api.pictures.licenseUrl}"} | ||||
|     ${optionalString (cfg.port != null) "PORT=${toString cfg.port}"} | ||||
|     ${concatStringsSep "\n" (mapAttrsToList (name: value: "${name}=${value}") cfg.extraEnvironment)} | ||||
|     ${optionalString (config.services.panoramax.storage.fsUrl != null) "FS_URL=${config.services.panoramax.storage.fsUrl}"} | ||||
|     ${optionalString (config.services.panoramax.infrastructure.nbProxies != null) "INFRA_NB_PROXIES=${toString config.services.panoramax.infrastructure.nbProxies}"} | ||||
|     ${optionalString (config.services.panoramax.flask.secretKey != null) "FLASK_SECRET_KEY=${config.services.panoramax.flask.secretKey}"} | ||||
|     ${optionalString (config.services.panoramax.flask.sessionCookieDomain != null) "FLASK_SESSION_COOKIE_DOMAIN=${config.services.panoramax.flask.sessionCookieDomain}"} | ||||
|     ${optionalString (config.services.panoramax.api.pictures.licenseSpdxId != null) "API_PICTURES_LICENSE_SPDX_ID=${config.services.panoramax.api.pictures.licenseSpdxId}"} | ||||
|     ${optionalString (config.services.panoramax.api.pictures.licenseUrl != null) "API_PICTURES_LICENSE_URL=${config.services.panoramax.api.pictures.licenseUrl}"} | ||||
|     ${optionalString (config.services.panoramax.port != null) "PORT=${toString config.services.panoramax.port}"} | ||||
|     ${optionalString (config.services.panoramax.sgblur.enable) "SGBLUR_API_URL=${config.services.panoramax.sgblur.url}"} | ||||
|     ${concatStringsSep "\n" (mapAttrsToList (name: value: "${name}=${value}") config.services.panoramax.extraEnvironment)} | ||||
|   ''; | ||||
| 
 | ||||
|   envFile = pkgs.writeText "panoramax.env" envContent; | ||||
|  | @ -59,26 +58,13 @@ in { | |||
|       default = "panoramax"; | ||||
|     }; | ||||
| 
 | ||||
|     # TODO: sgblur config | ||||
|     port = mkOption { | ||||
|       type = types.nullOr types.port; | ||||
|       default = 5000; | ||||
|       description = "Port for the Panoramax service"; | ||||
|     }; | ||||
| 
 | ||||
|     host = mkOption { | ||||
|       type = types.str; | ||||
|       default = "127.0.0.1"; | ||||
|       description = "Host to bind the Panoramax service to"; | ||||
|     }; | ||||
| 
 | ||||
|     urlScheme = mkOption { | ||||
|       type = types.enum ["http" "https"]; | ||||
|       default = "https"; | ||||
|       description = "URL scheme for the application"; | ||||
|     }; | ||||
| 
 | ||||
|     database = { | ||||
|       createDB = mkOption { | ||||
|         type = types.bool; | ||||
|         default = true; | ||||
|         description = "Whether to automatically create the database and user"; | ||||
|       }; | ||||
| 
 | ||||
|       url = mkOption { | ||||
|         type = types.nullOr types.str; | ||||
|         default = null; | ||||
|  | @ -113,12 +99,62 @@ in { | |||
|       }; | ||||
| 
 | ||||
|       name = mkOption { | ||||
|         type = types.nullOr types.str; | ||||
|         type = types.str; | ||||
|         default = "panoramax"; | ||||
|         description = "Database name (ignored if database.url is set)"; | ||||
|       }; | ||||
|     }; | ||||
| 
 | ||||
|     sgblur = { | ||||
|       enable = mkOption { | ||||
|         type = types.bool; | ||||
|         default = false; | ||||
|         description = "Whether to enable sgblur integration for face and license plate blurring"; | ||||
|       }; | ||||
| 
 | ||||
|       package = mkOption { | ||||
|         type = types.package; | ||||
|         default = pkgs.sgblur; | ||||
|         description = "The sgblur package to use"; | ||||
|       }; | ||||
| 
 | ||||
|       port = mkOption { | ||||
|         type = types.port; | ||||
|         default = 8080; | ||||
|         description = "Port for the sgblur service"; | ||||
|       }; | ||||
| 
 | ||||
|       host = mkOption { | ||||
|         type = types.str; | ||||
|         default = "127.0.0.1"; | ||||
|         description = "Host to bind the sgblur service to"; | ||||
|       }; | ||||
| 
 | ||||
|       url = mkOption { | ||||
|         type = types.str; | ||||
|         default = "http://127.0.0.1:8080"; | ||||
|         description = "URL where sgblur service is accessible"; | ||||
|       }; | ||||
|     }; | ||||
| 
 | ||||
|     port = mkOption { | ||||
|       type = types.nullOr types.port; | ||||
|       default = 5000; | ||||
|       description = "Port for the Panoramax service"; | ||||
|     }; | ||||
| 
 | ||||
|     host = mkOption { | ||||
|       type = types.str; | ||||
|       default = "127.0.0.1"; | ||||
|       description = "Host to bind the Panoramax service to"; | ||||
|     }; | ||||
| 
 | ||||
|     urlScheme = mkOption { | ||||
|       type = types.enum ["http" "https"]; | ||||
|       default = "https"; | ||||
|       description = "URL scheme for the application"; | ||||
|     }; | ||||
| 
 | ||||
|     storage = { | ||||
|       fsUrl = mkOption { | ||||
|         type = types.nullOr types.str; | ||||
|  | @ -179,10 +215,14 @@ in { | |||
|   config = lib.mkIf config.services.panoramax.enable ( | ||||
|     lib.mkMerge [ | ||||
|       { | ||||
|         environment.systemPackages = with pkgs; [ | ||||
|           config.services.panoramax.package | ||||
|           python3Packages.waitress | ||||
|         ]; | ||||
|         environment.systemPackages = with pkgs; | ||||
|           [ | ||||
|             config.services.panoramax.package | ||||
|             python3Packages.waitress | ||||
|           ] | ||||
|           ++ optionals config.services.panoramax.sgblur.enable [ | ||||
|             config.services.panoramax.sgblur.package | ||||
|           ]; | ||||
| 
 | ||||
|         systemd.services.panoramax = { | ||||
|           description = "Panoramax Service"; | ||||
|  | @ -233,10 +273,103 @@ in { | |||
|               } | ||||
|             ''; | ||||
|           } | ||||
|         ]; | ||||
|           { | ||||
|             assertion = !config.services.panoramax.database.createDB || config.services.panoramax.database.url == null || (lib.hasPrefix "/run/" config.services.panoramax.database.url || lib.hasPrefix "unix:" config.services.panoramax.database.url || lib.hasPrefix "/" config.services.panoramax.database.host); | ||||
|             message = '' | ||||
|               Panoramax createDB option can only be used with socket connections when a database URL is provided. | ||||
|               Socket connections are identified by: | ||||
|               - URLs starting with "unix:" | ||||
|               - URLs starting with "/run/" | ||||
|               - Host paths starting with "/" | ||||
| 
 | ||||
|         # TODO: auto config db | ||||
|               Current configuration: | ||||
|               - createDB: ${lib.boolToString config.services.panoramax.database.createDB} | ||||
|               - database.url: ${ | ||||
|                 if config.services.panoramax.database.url != null | ||||
|                 then config.services.panoramax.database.url | ||||
|                 else "not set" | ||||
|               } | ||||
|               - database.host: ${config.services.panoramax.database.host} | ||||
|             ''; | ||||
|           } | ||||
|         ]; | ||||
|       } | ||||
|       ( | ||||
|         lib.mkIf config.services.panoramax.sgblur.enable { | ||||
|           systemd.services.sgblur = { | ||||
|             description = "SGBlur AI-powered face and license plate blurring service"; | ||||
|             after = ["network.target"]; | ||||
|             wantedBy = ["multi-user.target"]; | ||||
|             serviceConfig = { | ||||
|               ExecStart = "${config.services.panoramax.sgblur.package}/bin/uvicorn sgblur.main:app --host ${config.services.panoramax.sgblur.host} --port ${toString config.services.panoramax.sgblur.port}"; | ||||
|               Restart = "always"; | ||||
|               User = "sgblur"; | ||||
|               Group = "sgblur"; | ||||
|               WorkingDirectory = "/var/lib/sgblur"; | ||||
|               Environment = "PYTHONPATH=${config.services.panoramax.sgblur.package}/lib/python3.11/site-packages"; | ||||
|             }; | ||||
|           }; | ||||
| 
 | ||||
|           users.users.sgblur = { | ||||
|             isSystemUser = true; | ||||
|             group = "sgblur"; | ||||
|             home = "/var/lib/sgblur"; | ||||
|             createHome = true; | ||||
|           }; | ||||
| 
 | ||||
|           users.groups.sgblur = {}; | ||||
| 
 | ||||
|           systemd.tmpfiles.rules = [ | ||||
|             "d /var/lib/sgblur 0755 sgblur sgblur -" | ||||
|           ]; | ||||
| 
 | ||||
|           # Update panoramax service dependencies when sgblur is enabled | ||||
|           systemd.services.panoramax = { | ||||
|             after = ["sgblur.service"]; | ||||
|             wants = ["sgblur.service"]; | ||||
|           }; | ||||
|         } | ||||
|       ) | ||||
|       ( | ||||
|         lib.mkIf config.services.panoramax.database.createDB { | ||||
|           services.postgresql = { | ||||
|             enable = true; | ||||
|             ensureDatabases = [config.services.panoramax.database.name]; | ||||
|             ensureUsers = [ | ||||
|               { | ||||
|                 name = config.services.panoramax.database.username; | ||||
|                 ensureDBOwnership = true; | ||||
|                 ensureClauses.login = true; | ||||
|               } | ||||
|             ]; | ||||
|             extensions = ps: with ps; [postgis]; | ||||
|             settings = { | ||||
|               shared_preload_libraries = ["postgis"]; | ||||
|             }; | ||||
|           }; | ||||
| 
 | ||||
|           systemd.services.postgresql.serviceConfig.ExecStartPost = let | ||||
|             sqlFile = pkgs.writeText "panoramax-postgis-setup.sql" '' | ||||
|               CREATE EXTENSION IF NOT EXISTS postgis; | ||||
|               CREATE EXTENSION IF NOT EXISTS postgis_topology; | ||||
|               CREATE EXTENSION IF NOT EXISTS fuzzystrmatch; | ||||
|               CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder; | ||||
| 
 | ||||
|               ALTER SCHEMA public OWNER TO ${config.services.panoramax.database.username}; | ||||
|               GRANT ALL ON SCHEMA public TO ${config.services.panoramax.database.username}; | ||||
|             ''; | ||||
|           in [ | ||||
|             '' | ||||
|               ${lib.getExe' config.services.postgresql.package "psql"} -d "${config.services.panoramax.database.name}" -f "${sqlFile}" | ||||
|             '' | ||||
|           ]; | ||||
| 
 | ||||
|           systemd.services.panoramax = { | ||||
|             after = ["postgresql.service"]; | ||||
|             requires = ["postgresql.service"]; | ||||
|           }; | ||||
|         } | ||||
|       ) | ||||
|       ( | ||||
|         lib.mkIf config.host.reverse_proxy.enable { | ||||
|           host = { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue