# SPDX-FileCopyrightText: 2025 Gergely Nagy # SPDX-FileContributor: Gergely Nagy # # SPDX-License-Identifier: MIT { self }: { config, lib, pkgs, ... }: let cfg = config.services.iocaine; defaultPackage = self.packages.${pkgs.hostPlatform.system}.iocaine; tomlFormat = pkgs.formats.toml { }; configFile = tomlFormat.generate "iocaine.toml" cfg.config; in { options.services.iocaine = { enable = lib.mkEnableOption "iocaine, the deadliest poison known to AI"; package = lib.mkOption { type = lib.types.package; default = defaultPackage; description = "The iocaine package to use."; }; config = lib.mkOption { inherit (tomlFormat) type; default = { }; description = "THe configuration for iocaine."; }; }; config = lib.mkIf cfg.enable { assertions = [ { assertion = cfg.config.sources.markov or null != null; message = '' You have to define at least one Markov source (`services.iocaine.config.sources.markov`) for iocaine. ''; } { assertion = cfg.config.sources.words or null != null; message = '' You have to define a word list source (`services.iocaine.config.sources.words`) for iocaine. ''; } ]; systemd.services.iocaine = { description = "iocaine, the deadliest poison known to AI"; restartTriggers = [ configFile ]; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; environment = { HOME = "%S/home"; }; serviceConfig = { Type = "simple"; ExecStart = "${pkgs.lib.getExe cfg.package} --config-file ${configFile}"; Restart = "on-failure"; DynamicUser = true; StateDirectory = "iocaine"; WorkingDirectory = "/var/lib/iocaine"; ProtectSystem = "strict"; SystemCallArchitectures = "native"; MemoryDenyWriteExecute = true; NoNewPrivileges = true; PrivateTmp = true; PrivateDevices = true; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; RestrictNamespaces = true; RestrictRealtime = true; DevicePolicy = "closed"; ProtectClock = true; ProtectHostname = true; ProtectProc = "invisible"; ProtectControlGroups = true; ProtectKernelModules = true; ProtectKernelTunables = true; LockPersonality = true; }; }; }; }