# Infrastructure - Systemd Service Unit Schema # Defines type-safe systemd service configuration # Validates resource limits, dependencies, and restart policies { # Unit section configuration UnitSection = { description | String, after | Array String | doc "Order dependencies" | default = [], before | Array String | doc "Reverse order dependencies" | default = [], requires | Array String | doc "Hard dependencies" | default = [], wants | Array String | doc "Soft dependencies" | default = [], }, # Service resource limits ResourceLimits = { cpu_quota | String | optional, cpu_shares | Number | optional, memory_limit | String | optional, memory_high | String | optional, }, # Service restart policy RestartPolicy = { restart | [| 'no, 'always, 'on_failure, 'on_abnormal, 'on_watchdog, 'on_abort, 'always |] | default = 'on_failure', restart_sec | String | doc "Restart delay" | default = "100ms", max_restarts | Number | optional, }, # Service execution configuration ExecConfig = { exec_start | String, exec_stop | String | optional, exec_reload | String | optional, type | [| 'simple, 'exec, 'forking, 'oneshot, 'dbus, 'notify, 'idle |] | default = 'simple', }, # Service section configuration ServiceSection = { exec_config | ExecConfig, resource_limits | ResourceLimits | default = {}, restart_policy | RestartPolicy | default = { restart = 'on_failure', restart_sec = "100ms", }, working_directory | String | optional, user | String | optional, group | String | optional, environment | Array String | doc "Environment variables" | default = [], environment_files | Array String | doc "Environment files to load" | default = [], timeout_start_sec | String | default = "90s", timeout_stop_sec | String | default = "90s", standard_output | [| 'journal, 'syslog, 'kmsg, 'null |] | default = 'journal', standard_error | [| 'journal, 'syslog, 'kmsg, 'null |] | default = 'journal', }, # Install section configuration InstallSection = { wanted_by | Array String | doc "Install target" | default = ["multi-user.target"], required_by | Array String | doc "Required by target" | default = [], also | Array String | doc "Also install units" | default = [], }, # Complete systemd service unit ServiceUnit = { unit | UnitSection, service | ServiceSection, install | InstallSection, }, # Service unit builder function createService = fun name description exec_start => { unit = { description = description, after = ["docker.service", "network-online.target"], before = [], requires = ["docker.service"], wants = [], }, service = { exec_config = { exec_start = exec_start, type = 'forking', }, resource_limits = {}, restart_policy = { restart = 'unless_stopped', restart_sec = "5s", }, timeout_start_sec = "90s", timeout_stop_sec = "90s", standard_output = 'journal', standard_error = 'journal', }, install = { wanted_by = ["multi-user.target"], }, }, # Orchestrator service preset orchestratorServicePreset = { unit = { description = "Provisioning Platform Orchestrator", after = ["docker.service", "network-online.target"], requires = ["docker.service"], wants = ["kms.service"], }, service = { exec_config = { exec_start = "/usr/bin/docker run --rm --name provisioning-orchestrator --net provisioning-net -p 8080:8080 -e PROVISIONING_MODE=solo -e ORCHESTRATOR_KMS_URL=http://kms:9998 provisioning/orchestrator:latest", exec_stop = "/usr/bin/docker stop provisioning-orchestrator", type = 'simple', }, resource_limits = { cpu_quota = "200%", memory_limit = "1G", }, restart_policy = { restart = 'unless_stopped', restart_sec = "5s", }, user = "provisioning", group = "provisioning", }, install = { wanted_by = ["multi-user.target"], }, }, # Control Center service preset controlCenterServicePreset = { unit = { description = "Provisioning Platform Control Center", after = ["docker.service", "orchestrator.service"], requires = ["docker.service"], wants = [], }, service = { exec_config = { exec_start = "/usr/bin/docker run --rm --name provisioning-control-center --net provisioning-net -p 8081:8081 -e PROVISIONING_MODE=solo -e CONTROL_CENTER_ORCHESTRATOR_URL=http://orchestrator:8080 provisioning/control-center:latest", exec_stop = "/usr/bin/docker stop provisioning-control-center", type = 'simple', }, resource_limits = { cpu_quota = "100%", memory_limit = "512M", }, restart_policy = { restart = 'unless_stopped', restart_sec = "5s", }, user = "provisioning", group = "provisioning", }, install = { wanted_by = ["multi-user.target"], }, }, # KMS service preset (required for all modes) kmsServicePreset = { unit = { description = "Cosmian KMS - Key Management System", after = ["docker.service"], requires = ["docker.service"], }, service = { exec_config = { exec_start = "/usr/bin/docker run --rm --name provisioning-kms --net provisioning-net -p 9998:9998 -v kms-data:/data -e KMS_DATABASE_PATH=/data/kms.db -e KMS_AUTH_METHOD=none ghcr.io/cosmian/kms:latest", exec_stop = "/usr/bin/docker stop provisioning-kms", type = 'simple', }, resource_limits = { cpu_quota = "100%", memory_limit = "512M", }, restart_policy = { restart = 'unless_stopped', restart_sec = "5s", }, user = "provisioning", group = "provisioning", timeout_start_sec = "120s", }, install = { wanted_by = ["multi-user.target"], }, }, # Solo mode all services soloModeServices = { orchestrator = orchestratorServicePreset, control_center = controlCenterServicePreset, kms = kmsServicePreset, }, # Enterprise mode services (with replicas) enterpriseModeServices = { orchestrator_1 = orchestratorServicePreset & { unit.description = "Provisioning Platform Orchestrator (Replica 1)", service.resource_limits.cpu_quota = "400%", service.resource_limits.memory_limit = "2G", }, orchestrator_2 = orchestratorServicePreset & { unit.description = "Provisioning Platform Orchestrator (Replica 2)", unit.after = ["orchestrator_1.service"], service.resource_limits.cpu_quota = "400%", service.resource_limits.memory_limit = "2G", }, orchestrator_3 = orchestratorServicePreset & { unit.description = "Provisioning Platform Orchestrator (Replica 3)", unit.after = ["orchestrator_2.service"], service.resource_limits.cpu_quota = "400%", service.resource_limits.memory_limit = "2G", }, control_center_1 = controlCenterServicePreset & { unit.description = "Provisioning Platform Control Center (Replica 1)", service.resource_limits.cpu_quota = "200%", service.resource_limits.memory_limit = "1G", }, control_center_2 = controlCenterServicePreset & { unit.description = "Provisioning Platform Control Center (Replica 2)", unit.after = ["control_center_1.service"], service.resource_limits.cpu_quota = "200%", service.resource_limits.memory_limit = "1G", }, kms = kmsServicePreset & { service.resource_limits.cpu_quota = "200%", service.resource_limits.memory_limit = "1G", }, }, }