1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8
9 cfg = config.services.manticore;
10 format = pkgs.formats.json { };
11
12 toSphinx =
13 {
14 mkKeyValue ? lib.generators.mkKeyValueDefault { } "=",
15 listsAsDuplicateKeys ? true,
16 }:
17 attrsOfAttrs:
18 let
19 # map function to string for each key val
20 mapAttrsToStringsSep =
21 sep: mapFn: attrs:
22 lib.concatStringsSep sep (lib.mapAttrsToList mapFn attrs);
23 mkSection =
24 sectName: sectValues:
25 ''
26 ${sectName} {
27 ''
28 + lib.generators.toKeyValue { inherit mkKeyValue listsAsDuplicateKeys; } sectValues
29 + ''}'';
30 in
31 # map input to ini sections
32 mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
33
34 configFile = pkgs.writeText "manticore.conf" (
35 toSphinx {
36 mkKeyValue = k: v: " ${k} = ${v}";
37 } cfg.settings
38 );
39
40in
41{
42
43 options = {
44 services.manticore = {
45
46 enable = lib.mkEnableOption "Manticoresearch";
47
48 settings = lib.mkOption {
49 default = {
50 searchd = {
51 listen = [
52 "127.0.0.1:9312"
53 "127.0.0.1:9306:mysql"
54 "127.0.0.1:9308:http"
55 ];
56 log = "/var/log/manticore/searchd.log";
57 query_log = "/var/log/manticore/query.log";
58 pid_file = "/run/manticore/searchd.pid";
59 data_dir = "/var/lib/manticore";
60 };
61 };
62 description = ''
63 Configuration for Manticoresearch. See
64 <https://manual.manticoresearch.com/Server%20settings>
65 for more information.
66 '';
67 type = lib.types.submodule {
68 freeformType = format.type;
69 };
70 example = lib.literalExpression ''
71 {
72 searchd = {
73 listen = [
74 "127.0.0.1:9312"
75 "127.0.0.1:9306:mysql"
76 "127.0.0.1:9308:http"
77 ];
78 log = "/var/log/manticore/searchd.log";
79 query_log = "/var/log/manticore/query.log";
80 pid_file = "/run/manticore/searchd.pid";
81 data_dir = "/var/lib/manticore";
82 };
83 }
84 '';
85 };
86
87 };
88 };
89
90 config = lib.mkIf cfg.enable {
91
92 systemd = {
93 packages = [ pkgs.manticoresearch ];
94 services.manticore = {
95 wantedBy = [ "multi-user.target" ];
96 after = [ "network.target" ];
97 serviceConfig =
98 {
99 ExecStart = [
100 ""
101 "${pkgs.manticoresearch}/bin/searchd --config ${configFile}"
102 ];
103 ExecStop = [
104 ""
105 "${pkgs.manticoresearch}/bin/searchd --config ${configFile} --stopwait"
106 ];
107 ExecStartPre = [ "" ];
108 DynamicUser = true;
109 LogsDirectory = "manticore";
110 RuntimeDirectory = "manticore";
111 StateDirectory = "manticore";
112 ReadWritePaths = "";
113 CapabilityBoundingSet = "";
114 RestrictAddressFamilies = [
115 "AF_UNIX"
116 "AF_INET"
117 "AF_INET6"
118 ];
119 RestrictNamespaces = true;
120 PrivateDevices = true;
121 PrivateUsers = true;
122 ProtectClock = true;
123 ProtectControlGroups = true;
124 ProtectHome = true;
125 ProtectKernelLogs = true;
126 ProtectKernelModules = true;
127 ProtectKernelTunables = true;
128 SystemCallArchitectures = "native";
129 SystemCallFilter = [
130 "@system-service"
131 "~@privileged"
132 ];
133 RestrictRealtime = true;
134 LockPersonality = true;
135 MemoryDenyWriteExecute = true;
136 UMask = "0066";
137 ProtectHostname = true;
138 }
139 // lib.optionalAttrs (cfg.settings.searchd.pid_file != null) {
140 PIDFile = cfg.settings.searchd.pid_file;
141 };
142 };
143 };
144
145 };
146
147 meta.maintainers = with lib.maintainers; [ onny ];
148
149}