monitoring.scm 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2018 Sou Bunnbu <iyzsong@member.fsf.org>
  3. ;;; Copyright © 2018, 2019 Gábor Boskovits <boskovits@gmail.com>
  4. ;;; Copyright © 2018, 2019, 2020 Oleg Pykhalov <go.wigust@gmail.com>
  5. ;;; Copyright © 2022 Marius Bakke <marius@gnu.org>
  6. ;;;
  7. ;;; This file is part of GNU Guix.
  8. ;;;
  9. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  10. ;;; under the terms of the GNU General Public License as published by
  11. ;;; the Free Software Foundation; either version 3 of the License, or (at
  12. ;;; your option) any later version.
  13. ;;;
  14. ;;; GNU Guix is distributed in the hope that it will be useful, but
  15. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. ;;; GNU General Public License for more details.
  18. ;;;
  19. ;;; You should have received a copy of the GNU General Public License
  20. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  21. (define-module (gnu services monitoring)
  22. #:use-module (gnu services)
  23. #:use-module (gnu services configuration)
  24. #:use-module (gnu services shepherd)
  25. #:use-module (gnu services web)
  26. #:use-module (gnu packages admin)
  27. #:use-module (gnu packages monitoring)
  28. #:use-module (gnu system shadow)
  29. #:use-module (guix gexp)
  30. #:use-module (guix packages)
  31. #:use-module (guix records)
  32. #:use-module (guix utils)
  33. #:use-module ((guix ui) #:select (display-hint G_))
  34. #:use-module (ice-9 match)
  35. #:use-module (ice-9 rdelim)
  36. #:use-module (srfi srfi-26)
  37. #:use-module (srfi srfi-35)
  38. #:export (darkstat-configuration
  39. darkstat-service-type
  40. prometheus-node-exporter-configuration
  41. prometheus-node-exporter-configuration?
  42. prometheus-node-exporter-configuration-package
  43. prometheus-node-exporter-web-listen-address
  44. prometheus-node-exporter-service-type
  45. zabbix-server-configuration
  46. zabbix-server-service-type
  47. zabbix-agent-configuration
  48. zabbix-agent-service-type
  49. zabbix-front-end-configuration
  50. zabbix-front-end-service-type
  51. %zabbix-front-end-configuration-nginx))
  52. ;;;
  53. ;;; darkstat
  54. ;;;
  55. (define-record-type* <darkstat-configuration>
  56. darkstat-configuration make-darkstat-configuration darkstat-configuration?
  57. (package darkstat-configuration-package
  58. (default darkstat))
  59. (interface darkstat-configuration-interface)
  60. (port darkstat-configuration-port
  61. (default "667"))
  62. (bind-address darkstat-configuration-bind-address
  63. (default "127.0.0.1"))
  64. (base darkstat-configuration-base
  65. (default "/")))
  66. (define %darkstat-accounts
  67. (list (user-account
  68. (name "darkstat")
  69. (group "darkstat")
  70. (system? #t)
  71. (comment "darkstat daemon user")
  72. (home-directory "/var/lib/darkstat")
  73. (shell (file-append shadow "/sbin/nologin")))
  74. (user-group
  75. (name "darkstat")
  76. (system? #t))))
  77. (define darkstat-shepherd-service
  78. (match-lambda
  79. (($ <darkstat-configuration>
  80. package interface port bind-address base)
  81. (shepherd-service
  82. (documentation "Network statistics gatherer.")
  83. (provision '(darkstat))
  84. (requirement '(networking))
  85. (start #~(make-forkexec-constructor
  86. (list #$(file-append package "/sbin/darkstat")
  87. "-i" #$interface
  88. "-p" #$port
  89. "-b" #$bind-address
  90. "--base" #$base
  91. "--syslog" "--no-daemon"
  92. "--chroot" "/var/lib/darkstat"
  93. "--user" "darkstat"
  94. "--import" "darkstat.db"
  95. "--export" "darkstat.db")))
  96. (stop #~(make-kill-destructor))))))
  97. (define darkstat-service-type
  98. (service-type
  99. (name 'darkstat)
  100. (description
  101. "Run @command{darkstat} to serve network traffic statistics reports over
  102. HTTP.")
  103. (extensions
  104. (list (service-extension account-service-type
  105. (const %darkstat-accounts))
  106. (service-extension shepherd-root-service-type
  107. (compose list darkstat-shepherd-service))))))
  108. ;;;
  109. ;;; Prometheus node exporter
  110. ;;;
  111. (define-record-type* <prometheus-node-exporter-configuration>
  112. prometheus-node-exporter-configuration
  113. make-prometheus-node-exporter-configuration
  114. prometheus-node-exporter-configuration?
  115. (package prometheus-node-exporter-configuration-package
  116. (default go-github-com-prometheus-node-exporter))
  117. (web-listen-address prometheus-node-exporter-web-listen-address
  118. (default ":9100"))
  119. (textfile-directory prometheus-node-exporter-textfile-directory
  120. (default "/var/lib/prometheus/node-exporter"))
  121. (extra-options prometheus-node-exporter-extra-options
  122. (default '())))
  123. (define %prometheus-node-exporter-accounts
  124. (list (user-account
  125. (name "prometheus-node-exporter")
  126. (group "prometheus-node-exporter")
  127. (system? #t)
  128. (comment "Prometheus node exporter daemon user")
  129. (home-directory "/var/empty")
  130. (shell (file-append shadow "/sbin/nologin")))
  131. (user-group
  132. (name "prometheus-node-exporter")
  133. (system? #t))))
  134. (define prometheus-node-exporter-shepherd-service
  135. (match-lambda
  136. (( $ <prometheus-node-exporter-configuration>
  137. package web-listen-address textfile-directory extra-options)
  138. (list
  139. (shepherd-service
  140. (documentation "Prometheus node exporter.")
  141. (provision '(prometheus-node-exporter))
  142. (requirement '(networking))
  143. (start #~(make-forkexec-constructor
  144. (list #$(file-append package "/bin/node_exporter")
  145. "--web.listen-address" #$web-listen-address
  146. #$@(if textfile-directory
  147. (list "--collector.textfile.directory"
  148. textfile-directory)
  149. '())
  150. #$@extra-options)
  151. #:user "prometheus-node-exporter"
  152. #:group "prometheus-node-exporter"
  153. #:log-file "/var/log/prometheus-node-exporter.log"))
  154. (stop #~(make-kill-destructor)))))))
  155. (define (prometheus-node-exporter-activation config)
  156. (with-imported-modules '((guix build utils))
  157. #~(let ((textfile-directory
  158. #$(prometheus-node-exporter-textfile-directory config)))
  159. (use-modules (guix build utils))
  160. (when textfile-directory
  161. (let ((user (getpw "prometheus-node-exporter")))
  162. #t
  163. (mkdir-p textfile-directory)
  164. (chown textfile-directory (passwd:uid user) (passwd:gid user))
  165. (chmod textfile-directory #o775))))))
  166. (define prometheus-node-exporter-service-type
  167. (service-type
  168. (name 'prometheus-node-exporter)
  169. (description
  170. "Run @command{node_exporter} to serve hardware and OS metrics to
  171. Prometheus.")
  172. (extensions
  173. (list
  174. (service-extension account-service-type
  175. (const %prometheus-node-exporter-accounts))
  176. (service-extension activation-service-type
  177. prometheus-node-exporter-activation)
  178. (service-extension shepherd-root-service-type
  179. prometheus-node-exporter-shepherd-service)))
  180. (default-value (prometheus-node-exporter-configuration))))
  181. ;;;
  182. ;;; Zabbix server
  183. ;;;
  184. (define (uglify-field-name field-name)
  185. (apply string-append
  186. (map (lambda (str)
  187. (if (member (string->symbol str) '(ca db ssl))
  188. (string-upcase str)
  189. (string-capitalize str)))
  190. (string-split (string-delete #\?
  191. (symbol->string field-name))
  192. #\-))))
  193. (define (serialize-field field-name val)
  194. #~(format #f "~a=~a~%" #$(uglify-field-name field-name) #$val))
  195. (define (serialize-number field-name val)
  196. (serialize-field field-name (number->string val)))
  197. (define (serialize-list field-name val)
  198. #~(if (null? '#$val)
  199. ""
  200. #$(serialize-field field-name (string-join val ","))))
  201. (define (serialize-string field-name val)
  202. (if (and (string? val) (string=? val ""))
  203. ""
  204. (serialize-field field-name val)))
  205. (define group? string?)
  206. (define serialize-group
  207. (const ""))
  208. (define include-files? list?)
  209. (define (serialize-include-files field-name val)
  210. #~(string-append #$@(map (cut serialize-field 'include <>) val)))
  211. (define extra-options? string?)
  212. (define (serialize-extra-options field-name val)
  213. #~(if (= 0 (string-length #$val)) "" #$(format #f "~a~%" val)))
  214. (define (nginx-server-configuration-list? val)
  215. (and (list? val) (and-map nginx-server-configuration? val)))
  216. (define (serialize-nginx-server-configuration-list field-name val)
  217. "")
  218. (define-configuration zabbix-server-configuration
  219. (zabbix-server
  220. (file-like zabbix-server)
  221. "The zabbix-server package.")
  222. (user
  223. (string "zabbix")
  224. "User who will run the Zabbix server.")
  225. (group ;for zabbix-server-account procedure
  226. (group "zabbix")
  227. "Group who will run the Zabbix server.")
  228. (db-host
  229. (string "127.0.0.1")
  230. "Database host name.")
  231. (db-name
  232. (string "zabbix")
  233. "Database name.")
  234. (db-user
  235. (string "zabbix")
  236. "Database user.")
  237. (db-password
  238. (string "")
  239. "Database password. Please, use @code{include-files} with
  240. @code{DBPassword=SECRET} inside a specified file instead.")
  241. (db-port
  242. (number 5432)
  243. "Database port.")
  244. (log-type
  245. (string "")
  246. "Specifies where log messages are written to:
  247. @itemize
  248. @item @code{system} - syslog.
  249. @item @code{file} - file specified with @code{log-file} parameter.
  250. @item @code{console} - standard output.
  251. @end itemize\n")
  252. (log-file
  253. (string "/var/log/zabbix/server.log")
  254. "Log file name for @code{log-type} @code{file} parameter.")
  255. (pid-file
  256. (string "/var/run/zabbix/zabbix_server.pid")
  257. "Name of PID file.")
  258. (ssl-ca-location
  259. (string "/etc/ssl/certs/ca-certificates.crt")
  260. "The location of certificate authority (CA) files for SSL server
  261. certificate verification.")
  262. (ssl-cert-location
  263. (string "/etc/ssl/certs")
  264. "Location of SSL client certificates.")
  265. (extra-options
  266. (extra-options "")
  267. "Extra options will be appended to Zabbix server configuration file.")
  268. (include-files
  269. (include-files '())
  270. "You may include individual files or all files in a directory in the
  271. configuration file."))
  272. (define (zabbix-server-account config)
  273. "Return the user accounts and user groups for CONFIG."
  274. (let ((zabbix-user (zabbix-server-configuration-user config))
  275. (zabbix-group (zabbix-server-configuration-group config)))
  276. (list (user-group (name zabbix-group) (system? #t))
  277. (user-account
  278. (name zabbix-user)
  279. (system? #t)
  280. (group zabbix-group)
  281. (comment "zabbix privilege separation user")
  282. (home-directory (string-append "/var/run/" zabbix-user))
  283. (shell (file-append shadow "/sbin/nologin"))))))
  284. (define (zabbix-server-config-file config)
  285. "Return the zabbix-server configuration file corresponding to CONFIG."
  286. (computed-file
  287. "zabbix_server.conf"
  288. #~(begin
  289. (call-with-output-file #$output
  290. (lambda (port)
  291. (format port "# Generated by 'zabbix-server-service'.~%")
  292. (format port #$(serialize-configuration
  293. config zabbix-server-configuration-fields)))))))
  294. (define (zabbix-server-activation config)
  295. "Return the activation gexp for CONFIG."
  296. (with-imported-modules '((guix build utils))
  297. #~(begin
  298. (use-modules (guix build utils)
  299. (ice-9 rdelim))
  300. (let ((user (getpw #$(zabbix-server-configuration-user config))))
  301. (for-each (lambda (file)
  302. (let ((directory (dirname file)))
  303. (mkdir-p directory)
  304. (chown directory (passwd:uid user) (passwd:gid user))
  305. (chmod directory #o755)))
  306. (list #$(zabbix-server-configuration-log-file config)
  307. #$(zabbix-server-configuration-pid-file config)
  308. "/etc/zabbix/maintenance.inc.php"))))))
  309. (define (zabbix-server-runtime-control-procedure zabbix-server config command)
  310. ;; XXX: This is duplicated from mcron; factorize.
  311. #~(lambda (_ . args)
  312. ;; Run 'zabbix_server' in a pipe so we can explicitly redirect its output
  313. ;; to 'current-output-port', which at this stage is bound to the client
  314. ;; connection.
  315. (let ((pipe (apply open-pipe* OPEN_READ #$zabbix-server
  316. "--config" #$config
  317. "-R" #$command args)))
  318. (let loop ()
  319. (match (read-line pipe 'concat)
  320. ((? eof-object?)
  321. (catch 'system-error
  322. (lambda ()
  323. (zero? (close-pipe pipe)))
  324. (lambda args
  325. ;; There's a race with the SIGCHLD handler, which could
  326. ;; call 'waitpid' before 'close-pipe' above does. If we
  327. ;; get ECHILD, that means we lost the race; in that case, we
  328. ;; cannot tell what the exit code was (FIXME).
  329. (or (= ECHILD (system-error-errno args))
  330. (apply throw args)))))
  331. (line
  332. (display line)
  333. (loop)))))))
  334. ;; Provide shepherd actions for common "zabbix_server -R" commands
  335. ;; mainly for a convenient way to use the correct configuration file.
  336. (define (zabbix-server-actions zabbix-server config)
  337. (list (shepherd-action
  338. (name 'reload-config-cache)
  339. (documentation "Reload the configuration cache.")
  340. (procedure (zabbix-server-runtime-control-procedure
  341. zabbix-server config "config_cache_reload")))
  342. (shepherd-action
  343. (name 'reload-snmp-cache)
  344. (documentation "Reload SNMP cache.")
  345. (procedure (zabbix-server-runtime-control-procedure
  346. zabbix-server config "snmp_cache_reload")))))
  347. (define (zabbix-server-shepherd-service config)
  348. "Return a <shepherd-service> for Zabbix server with CONFIG."
  349. (let ((zabbix-server
  350. (file-append (zabbix-server-configuration-zabbix-server config)
  351. "/sbin/zabbix_server"))
  352. (config-file (zabbix-server-config-file config)))
  353. (list (shepherd-service
  354. (provision '(zabbix-server))
  355. (requirement '(user-processes))
  356. (documentation "Run the Zabbix server daemon.")
  357. (actions (zabbix-server-actions zabbix-server config-file))
  358. (start #~(make-forkexec-constructor
  359. (list #$zabbix-server
  360. "--config" #$config-file
  361. "--foreground")
  362. #:user #$(zabbix-server-configuration-user config)
  363. #:group #$(zabbix-server-configuration-group config)
  364. #:pid-file #$(zabbix-server-configuration-pid-file config)
  365. #:environment-variables
  366. (list "SSL_CERT_DIR=/run/current-system/profile\
  367. /etc/ssl/certs"
  368. "SSL_CERT_FILE=/run/current-system/profile\
  369. /etc/ssl/certs/ca-certificates.crt")))
  370. (stop #~(make-kill-destructor))))))
  371. (define zabbix-server-service-type
  372. (service-type
  373. (name 'zabbix-server)
  374. (extensions
  375. (list (service-extension shepherd-root-service-type
  376. zabbix-server-shepherd-service)
  377. (service-extension account-service-type
  378. zabbix-server-account)
  379. (service-extension activation-service-type
  380. zabbix-server-activation)))
  381. (default-value (zabbix-server-configuration))))
  382. (define (generate-zabbix-server-documentation)
  383. (generate-documentation
  384. `((zabbix-server-configuration
  385. ,zabbix-server-configuration-fields))
  386. 'zabbix-server-configuration))
  387. (define-configuration zabbix-agent-configuration
  388. (zabbix-agent
  389. (file-like zabbix-agentd)
  390. "The zabbix-agent package.")
  391. (user
  392. (string "zabbix")
  393. "User who will run the Zabbix agent.")
  394. (group
  395. (group "zabbix")
  396. "Group who will run the Zabbix agent.")
  397. (hostname
  398. (string "")
  399. "Unique, case sensitive hostname which is required for active checks and
  400. must match hostname as configured on the server.")
  401. (log-type
  402. (string "")
  403. "Specifies where log messages are written to:
  404. @itemize
  405. @item @code{system} - syslog.
  406. @item @code{file} - file specified with @code{log-file} parameter.
  407. @item @code{console} - standard output.
  408. @end itemize\n")
  409. (log-file
  410. (string "/var/log/zabbix/agent.log")
  411. "Log file name for @code{log-type} @code{file} parameter.")
  412. (pid-file
  413. (string "/var/run/zabbix/zabbix_agent.pid")
  414. "Name of PID file.")
  415. (server
  416. (list '("127.0.0.1"))
  417. "List of IP addresses, optionally in CIDR notation, or hostnames of Zabbix
  418. servers and Zabbix proxies. Incoming connections will be accepted only from
  419. the hosts listed here.")
  420. (server-active
  421. (list '("127.0.0.1"))
  422. "List of IP:port (or hostname:port) pairs of Zabbix servers and Zabbix
  423. proxies for active checks. If port is not specified, default port is used.
  424. If this parameter is not specified, active checks are disabled.")
  425. (extra-options
  426. (extra-options "")
  427. "Extra options will be appended to Zabbix server configuration file.")
  428. (include-files
  429. (include-files '())
  430. "You may include individual files or all files in a directory in the
  431. configuration file."))
  432. (define (zabbix-agent-account config)
  433. "Return the user accounts and user groups for CONFIG."
  434. (let ((zabbix-user (zabbix-agent-configuration-user config))
  435. (zabbix-group (zabbix-agent-configuration-group config)))
  436. (list (user-group (name zabbix-group) (system? #t))
  437. (user-account
  438. (name zabbix-user)
  439. (system? #t)
  440. (group zabbix-group)
  441. (comment "zabbix privilege separation user")
  442. (home-directory (string-append "/var/run/" zabbix-user))
  443. (shell (file-append shadow "/sbin/nologin"))))))
  444. (define (zabbix-agent-activation config)
  445. "Return the activation gexp for CONFIG."
  446. (with-imported-modules '((guix build utils))
  447. #~(begin
  448. (use-modules (guix build utils)
  449. (ice-9 rdelim))
  450. (let ((user
  451. (getpw #$(zabbix-agent-configuration-user config))))
  452. (for-each (lambda (file)
  453. (let ((directory (dirname file)))
  454. (mkdir-p directory)
  455. (chown directory (passwd:uid user) (passwd:gid user))
  456. (chmod directory #o755)))
  457. (list #$(zabbix-agent-configuration-log-file config)
  458. #$(zabbix-agent-configuration-pid-file config)))))))
  459. (define (zabbix-agent-config-file config)
  460. "Return the zabbix-agent configuration file corresponding to CONFIG."
  461. (computed-file
  462. "zabbix_agent.conf"
  463. #~(begin
  464. (call-with-output-file #$output
  465. (lambda (port)
  466. (format port "# Generated by 'zabbix-agent-service'.~%")
  467. (format port #$(serialize-configuration
  468. config zabbix-agent-configuration-fields)))))))
  469. (define (zabbix-agent-shepherd-service config)
  470. "Return a <shepherd-service> for Zabbix agent with CONFIG."
  471. (list (shepherd-service
  472. (provision '(zabbix-agent))
  473. (requirement '(user-processes))
  474. (documentation "Run Zabbix agent daemon.")
  475. (start #~(make-forkexec-constructor
  476. (list #$(file-append (zabbix-agent-configuration-zabbix-agent config)
  477. "/sbin/zabbix_agentd")
  478. "--config" #$(zabbix-agent-config-file config)
  479. "--foreground")
  480. #:user #$(zabbix-agent-configuration-user config)
  481. #:group #$(zabbix-agent-configuration-group config)
  482. #:pid-file #$(zabbix-agent-configuration-pid-file config)
  483. #:environment-variables
  484. (list "SSL_CERT_DIR=/run/current-system/profile\
  485. /etc/ssl/certs"
  486. "SSL_CERT_FILE=/run/current-system/profile\
  487. /etc/ssl/certs/ca-certificates.crt"
  488. "PATH=/run/setuid-programs:\
  489. /run/current-system/profile/bin:/run/current-system/profile/sbin")))
  490. (stop #~(make-kill-destructor)))))
  491. (define zabbix-agent-service-type
  492. (service-type
  493. (name 'zabbix-agent)
  494. (extensions
  495. (list (service-extension shepherd-root-service-type
  496. zabbix-agent-shepherd-service)
  497. (service-extension account-service-type
  498. zabbix-agent-account)
  499. (service-extension activation-service-type
  500. zabbix-agent-activation)))
  501. (default-value (zabbix-agent-configuration))))
  502. (define (generate-zabbix-agent-documentation)
  503. (generate-documentation
  504. `((zabbix-agent-configuration
  505. ,zabbix-agent-configuration-fields))
  506. 'zabbix-agent-configuration))
  507. (define %zabbix-front-end-configuration-nginx
  508. (nginx-server-configuration
  509. (root #~(string-append #$zabbix-server:front-end "/share/zabbix/php"))
  510. (index '("index.php"))
  511. (locations
  512. (let ((php-location (nginx-php-location)))
  513. (list (nginx-location-configuration
  514. (inherit php-location)
  515. (body (append (nginx-location-configuration-body php-location)
  516. (list "
  517. fastcgi_param PHP_VALUE \"post_max_size = 16M
  518. max_execution_time = 300\";
  519. ")))))))
  520. (listen '("80"))))
  521. (define (zabbix-front-end-nginx-extension config)
  522. (match config
  523. (($ <zabbix-front-end-configuration> _ server nginx)
  524. (if (null? nginx)
  525. (list
  526. (nginx-server-configuration
  527. (inherit %zabbix-front-end-configuration-nginx)
  528. (root #~(string-append #$server:front-end "/share/zabbix/php"))))
  529. nginx))))
  530. (define-configuration zabbix-front-end-configuration
  531. (zabbix-server
  532. (file-like zabbix-server)
  533. "The Zabbix server package to use.")
  534. (nginx
  535. (list '())
  536. "List of @ref{nginx-server-configuration,@code{nginx-server-configuration}}
  537. blocks for the Zabbix front-end. When empty, a default that listens on port 80
  538. is used.")
  539. (db-host
  540. (string "localhost")
  541. "Database host name.")
  542. (db-port
  543. (number 5432)
  544. "Database port.")
  545. (db-name
  546. (string "zabbix")
  547. "Database name.")
  548. (db-user
  549. (string "zabbix")
  550. "Database user.")
  551. (db-password
  552. (string "")
  553. "Database password. Please, use @code{db-secret-file} instead.")
  554. (db-secret-file
  555. (string "")
  556. "Secret file which will be appended to @file{zabbix.conf.php} file. This
  557. file contains credentials for use by Zabbix front-end. You are expected to
  558. create it manually.")
  559. (zabbix-host
  560. (string "localhost")
  561. "Zabbix server hostname.")
  562. (zabbix-port
  563. (number 10051)
  564. "Zabbix server port."))
  565. (define (zabbix-front-end-config config)
  566. (match-record config <zabbix-front-end-configuration>
  567. (%location db-host db-port db-name db-user db-password db-secret-file
  568. zabbix-host zabbix-port)
  569. (mixed-text-file "zabbix.conf.php"
  570. "\
  571. <?php
  572. // Zabbix GUI configuration file.
  573. global $DB;
  574. $DB['TYPE'] = 'POSTGRESQL';
  575. $DB['SERVER'] = '" db-host "';
  576. $DB['PORT'] = '" (number->string db-port) "';
  577. $DB['DATABASE'] = '" db-name "';
  578. $DB['USER'] = '" db-user "';
  579. $DB['PASSWORD'] = " (let ((file (location-file %location))
  580. (line (location-line %location))
  581. (column (location-column %location)))
  582. (if (string-null? db-password)
  583. (if (string-null? db-secret-file)
  584. (raise (make-compound-condition
  585. (condition
  586. (&message
  587. (message
  588. (format #f "no '~A' or '~A' field in your '~A' record"
  589. 'db-secret-file 'db-password
  590. 'zabbix-front-end-configuration))))
  591. (condition
  592. (&error-location
  593. (location %location)))))
  594. (string-append "trim(file_get_contents('"
  595. db-secret-file "'));\n"))
  596. (begin
  597. (display-hint (format #f (G_ "~a:~a:~a: ~a:
  598. Consider using @code{db-secret-file} instead of @code{db-password} for better
  599. security.") file line column 'zabbix-front-end-configuration))
  600. (format #f "'~a';~%" db-password))))
  601. "
  602. // Schema name. Used for IBM DB2 and PostgreSQL.
  603. $DB['SCHEMA'] = '';
  604. // Use IEEE754 compatible value range for 64-bit Numeric (float) history values.
  605. $DB['DOUBLE_IEEE754'] = true;
  606. $ZBX_SERVER = '" zabbix-host "';
  607. $ZBX_SERVER_PORT = '" (number->string zabbix-port) "';
  608. $ZBX_SERVER_NAME = '';
  609. $IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_PNG;
  610. ")))
  611. (define %maintenance.inc.php
  612. ;; Empty php file to allow us move zabbix-frontend configs to ‘/etc/zabbix’
  613. ;; directory. See ‘install-front-end’ phase in
  614. ;; (@ (gnu packages monitoring) zabbix-server) package.
  615. "\
  616. <?php
  617. ")
  618. (define (zabbix-front-end-activation config)
  619. "Return the activation gexp for CONFIG."
  620. #~(begin
  621. (use-modules (guix build utils))
  622. (mkdir-p "/etc/zabbix")
  623. (call-with-output-file "/etc/zabbix/maintenance.inc.php"
  624. (lambda (port)
  625. (display #$%maintenance.inc.php port)))
  626. (copy-file #$(zabbix-front-end-config config)
  627. "/etc/zabbix/zabbix.conf.php")))
  628. (define zabbix-front-end-service-type
  629. (service-type
  630. (name 'zabbix-front-end)
  631. (extensions
  632. (list (service-extension activation-service-type
  633. zabbix-front-end-activation)
  634. (service-extension nginx-service-type
  635. zabbix-front-end-nginx-extension)
  636. ;; Make sure php-fpm is instantiated.
  637. (service-extension php-fpm-service-type
  638. (const #t))))
  639. (default-value (zabbix-front-end-configuration))
  640. (description
  641. "Run the zabbix-front-end web interface, which allows users to interact
  642. with Zabbix server.")))
  643. (define (generate-zabbix-front-end-documentation)
  644. (generate-documentation
  645. `((zabbix-front-end-configuration
  646. ,zabbix-front-end-configuration-fields))
  647. 'zabbix-front-end-configuration))