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 | with lib; let | ||||||
|   cfg = config.services.panoramax; |  | ||||||
| 
 |  | ||||||
|   # Database configuration assertions |   # Database configuration assertions | ||||||
|   dbUrlConfigured = cfg.database.url != null; |   dbUrlConfigured = config.services.panoramax.database.url != null; | ||||||
|   individualDbConfigured = all (x: x != null) [ |   individualDbConfigured = all (x: x != null) [ | ||||||
|     cfg.database.host |     config.services.panoramax.database.host | ||||||
|     cfg.database.port |     config.services.panoramax.database.port | ||||||
|     cfg.database.username |     config.services.panoramax.database.username | ||||||
|     cfg.database.password |     config.services.panoramax.database.password | ||||||
|     cfg.database.name |     config.services.panoramax.database.name | ||||||
|   ]; |   ]; | ||||||
| 
 | 
 | ||||||
|   envContent = '' |   envContent = '' | ||||||
|  | @ -23,23 +21,24 @@ with lib; let | ||||||
|     FLASK_APP=geovisio |     FLASK_APP=geovisio | ||||||
|     ${ |     ${ | ||||||
|       if dbUrlConfigured |       if dbUrlConfigured | ||||||
|       then "DB_URL=${cfg.database.url}" |       then "DB_URL=${config.services.panoramax.database.url}" | ||||||
|       else '' |       else '' | ||||||
|         DB_HOST=${cfg.database.host} |         DB_HOST=${config.services.panoramax.database.host} | ||||||
|         DB_PORT=${toString cfg.database.port} |         DB_PORT=${toString config.services.panoramax.database.port} | ||||||
|         DB_USERNAME=${cfg.database.username} |         DB_USERNAME=${config.services.panoramax.database.username} | ||||||
|         DB_PASSWORD=${cfg.database.password} |         DB_PASSWORD=${config.services.panoramax.database.password} | ||||||
|         DB_NAME=${cfg.database.name} |         DB_NAME=${config.services.panoramax.database.name} | ||||||
|       '' |       '' | ||||||
|     } |     } | ||||||
|     ${optionalString (cfg.storage.fsUrl != null) "FS_URL=${cfg.storage.fsUrl}"} |     ${optionalString (config.services.panoramax.storage.fsUrl != null) "FS_URL=${config.services.panoramax.storage.fsUrl}"} | ||||||
|     ${optionalString (cfg.infrastructure.nbProxies != null) "INFRA_NB_PROXIES=${toString cfg.infrastructure.nbProxies}"} |     ${optionalString (config.services.panoramax.infrastructure.nbProxies != null) "INFRA_NB_PROXIES=${toString config.services.panoramax.infrastructure.nbProxies}"} | ||||||
|     ${optionalString (cfg.flask.secretKey != null) "FLASK_SECRET_KEY=${cfg.flask.secretKey}"} |     ${optionalString (config.services.panoramax.flask.secretKey != null) "FLASK_SECRET_KEY=${config.services.panoramax.flask.secretKey}"} | ||||||
|     ${optionalString (cfg.flask.sessionCookieDomain != null) "FLASK_SESSION_COOKIE_DOMAIN=${cfg.flask.sessionCookieDomain}"} |     ${optionalString (config.services.panoramax.flask.sessionCookieDomain != null) "FLASK_SESSION_COOKIE_DOMAIN=${config.services.panoramax.flask.sessionCookieDomain}"} | ||||||
|     ${optionalString (cfg.api.pictures.licenseSpdxId != null) "API_PICTURES_LICENSE_SPDX_ID=${cfg.api.pictures.licenseSpdxId}"} |     ${optionalString (config.services.panoramax.api.pictures.licenseSpdxId != null) "API_PICTURES_LICENSE_SPDX_ID=${config.services.panoramax.api.pictures.licenseSpdxId}"} | ||||||
|     ${optionalString (cfg.api.pictures.licenseUrl != null) "API_PICTURES_LICENSE_URL=${cfg.api.pictures.licenseUrl}"} |     ${optionalString (config.services.panoramax.api.pictures.licenseUrl != null) "API_PICTURES_LICENSE_URL=${config.services.panoramax.api.pictures.licenseUrl}"} | ||||||
|     ${optionalString (cfg.port != null) "PORT=${toString cfg.port}"} |     ${optionalString (config.services.panoramax.port != null) "PORT=${toString config.services.panoramax.port}"} | ||||||
|     ${concatStringsSep "\n" (mapAttrsToList (name: value: "${name}=${value}") cfg.extraEnvironment)} |     ${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; |   envFile = pkgs.writeText "panoramax.env" envContent; | ||||||
|  | @ -59,26 +58,13 @@ in { | ||||||
|       default = "panoramax"; |       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 = { |     database = { | ||||||
|  |       createDB = mkOption { | ||||||
|  |         type = types.bool; | ||||||
|  |         default = true; | ||||||
|  |         description = "Whether to automatically create the database and user"; | ||||||
|  |       }; | ||||||
|  | 
 | ||||||
|       url = mkOption { |       url = mkOption { | ||||||
|         type = types.nullOr types.str; |         type = types.nullOr types.str; | ||||||
|         default = null; |         default = null; | ||||||
|  | @ -113,12 +99,62 @@ in { | ||||||
|       }; |       }; | ||||||
| 
 | 
 | ||||||
|       name = mkOption { |       name = mkOption { | ||||||
|         type = types.nullOr types.str; |         type = types.str; | ||||||
|         default = "panoramax"; |         default = "panoramax"; | ||||||
|         description = "Database name (ignored if database.url is set)"; |         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 = { |     storage = { | ||||||
|       fsUrl = mkOption { |       fsUrl = mkOption { | ||||||
|         type = types.nullOr types.str; |         type = types.nullOr types.str; | ||||||
|  | @ -179,10 +215,14 @@ in { | ||||||
|   config = lib.mkIf config.services.panoramax.enable ( |   config = lib.mkIf config.services.panoramax.enable ( | ||||||
|     lib.mkMerge [ |     lib.mkMerge [ | ||||||
|       { |       { | ||||||
|         environment.systemPackages = with pkgs; [ |         environment.systemPackages = with pkgs; | ||||||
|           config.services.panoramax.package |           [ | ||||||
|           python3Packages.waitress |             config.services.panoramax.package | ||||||
|         ]; |             python3Packages.waitress | ||||||
|  |           ] | ||||||
|  |           ++ optionals config.services.panoramax.sgblur.enable [ | ||||||
|  |             config.services.panoramax.sgblur.package | ||||||
|  |           ]; | ||||||
| 
 | 
 | ||||||
|         systemd.services.panoramax = { |         systemd.services.panoramax = { | ||||||
|           description = "Panoramax Service"; |           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 { |         lib.mkIf config.host.reverse_proxy.enable { | ||||||
|           host = { |           host = { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue