monitoring.scm 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  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. (description "Run the Zabbix server, a high-performance monitoring system
  383. that can collect data about machines from a variety of sources and provide the
  384. results in a Web interface.")))
  385. (define (generate-zabbix-server-documentation)
  386. (generate-documentation
  387. `((zabbix-server-configuration
  388. ,zabbix-server-configuration-fields))
  389. 'zabbix-server-configuration))
  390. (define-configuration zabbix-agent-configuration
  391. (zabbix-agent
  392. (file-like zabbix-agentd)
  393. "The zabbix-agent package.")
  394. (user
  395. (string "zabbix")
  396. "User who will run the Zabbix agent.")
  397. (group
  398. (group "zabbix")
  399. "Group who will run the Zabbix agent.")
  400. (hostname
  401. (string "")
  402. "Unique, case sensitive hostname which is required for active checks and
  403. must match hostname as configured on the server.")
  404. (log-type
  405. (string "")
  406. "Specifies where log messages are written to:
  407. @itemize
  408. @item @code{system} - syslog.
  409. @item @code{file} - file specified with @code{log-file} parameter.
  410. @item @code{console} - standard output.
  411. @end itemize\n")
  412. (log-file
  413. (string "/var/log/zabbix/agent.log")
  414. "Log file name for @code{log-type} @code{file} parameter.")
  415. (pid-file
  416. (string "/var/run/zabbix/zabbix_agent.pid")
  417. "Name of PID file.")
  418. (server
  419. (list '("127.0.0.1"))
  420. "List of IP addresses, optionally in CIDR notation, or hostnames of Zabbix
  421. servers and Zabbix proxies. Incoming connections will be accepted only from
  422. the hosts listed here.")
  423. (server-active
  424. (list '("127.0.0.1"))
  425. "List of IP:port (or hostname:port) pairs of Zabbix servers and Zabbix
  426. proxies for active checks. If port is not specified, default port is used.
  427. If this parameter is not specified, active checks are disabled.")
  428. (extra-options
  429. (extra-options "")
  430. "Extra options will be appended to Zabbix server configuration file.")
  431. (include-files
  432. (include-files '())
  433. "You may include individual files or all files in a directory in the
  434. configuration file."))
  435. (define (zabbix-agent-account config)
  436. "Return the user accounts and user groups for CONFIG."
  437. (let ((zabbix-user (zabbix-agent-configuration-user config))
  438. (zabbix-group (zabbix-agent-configuration-group config)))
  439. (list (user-group (name zabbix-group) (system? #t))
  440. (user-account
  441. (name zabbix-user)
  442. (system? #t)
  443. (group zabbix-group)
  444. (comment "zabbix privilege separation user")
  445. (home-directory (string-append "/var/run/" zabbix-user))
  446. (shell (file-append shadow "/sbin/nologin"))))))
  447. (define (zabbix-agent-activation config)
  448. "Return the activation gexp for CONFIG."
  449. (with-imported-modules '((guix build utils))
  450. #~(begin
  451. (use-modules (guix build utils)
  452. (ice-9 rdelim))
  453. (let ((user
  454. (getpw #$(zabbix-agent-configuration-user config))))
  455. (for-each (lambda (file)
  456. (let ((directory (dirname file)))
  457. (mkdir-p directory)
  458. (chown directory (passwd:uid user) (passwd:gid user))
  459. (chmod directory #o755)))
  460. (list #$(zabbix-agent-configuration-log-file config)
  461. #$(zabbix-agent-configuration-pid-file config)))))))
  462. (define (zabbix-agent-config-file config)
  463. "Return the zabbix-agent configuration file corresponding to CONFIG."
  464. (computed-file
  465. "zabbix_agent.conf"
  466. #~(begin
  467. (call-with-output-file #$output
  468. (lambda (port)
  469. (format port "# Generated by 'zabbix-agent-service'.~%")
  470. (format port #$(serialize-configuration
  471. config zabbix-agent-configuration-fields)))))))
  472. (define (zabbix-agent-shepherd-service config)
  473. "Return a <shepherd-service> for Zabbix agent with CONFIG."
  474. (list (shepherd-service
  475. (provision '(zabbix-agent))
  476. (requirement '(user-processes))
  477. (documentation "Run Zabbix agent daemon.")
  478. (start #~(make-forkexec-constructor
  479. (list #$(file-append (zabbix-agent-configuration-zabbix-agent config)
  480. "/sbin/zabbix_agentd")
  481. "--config" #$(zabbix-agent-config-file config)
  482. "--foreground")
  483. #:user #$(zabbix-agent-configuration-user config)
  484. #:group #$(zabbix-agent-configuration-group config)
  485. #:pid-file #$(zabbix-agent-configuration-pid-file config)
  486. #:environment-variables
  487. (list "SSL_CERT_DIR=/run/current-system/profile\
  488. /etc/ssl/certs"
  489. "SSL_CERT_FILE=/run/current-system/profile\
  490. /etc/ssl/certs/ca-certificates.crt"
  491. "PATH=/run/setuid-programs:\
  492. /run/current-system/profile/bin:/run/current-system/profile/sbin")))
  493. (stop #~(make-kill-destructor)))))
  494. (define zabbix-agent-service-type
  495. (service-type
  496. (name 'zabbix-agent)
  497. (extensions
  498. (list (service-extension shepherd-root-service-type
  499. zabbix-agent-shepherd-service)
  500. (service-extension account-service-type
  501. zabbix-agent-account)
  502. (service-extension activation-service-type
  503. zabbix-agent-activation)))
  504. (default-value (zabbix-agent-configuration))
  505. (description "Run the Zabbix agent, @command{zabbix_agentd}, which gathers
  506. information about the running system for the Zabbix monitoring server.")))
  507. (define (generate-zabbix-agent-documentation)
  508. (generate-documentation
  509. `((zabbix-agent-configuration
  510. ,zabbix-agent-configuration-fields))
  511. 'zabbix-agent-configuration))
  512. (define %zabbix-front-end-configuration-nginx
  513. (nginx-server-configuration
  514. (root #~(string-append #$zabbix-server:front-end "/share/zabbix/php"))
  515. (index '("index.php"))
  516. (locations
  517. (let ((php-location (nginx-php-location)))
  518. (list (nginx-location-configuration
  519. (inherit php-location)
  520. (body (append (nginx-location-configuration-body php-location)
  521. (list "
  522. fastcgi_param PHP_VALUE \"post_max_size = 16M
  523. max_execution_time = 300\";
  524. ")))))))
  525. (listen '("80"))))
  526. (define (zabbix-front-end-nginx-extension config)
  527. (match config
  528. (($ <zabbix-front-end-configuration> _ server nginx)
  529. (if (null? nginx)
  530. (list
  531. (nginx-server-configuration
  532. (inherit %zabbix-front-end-configuration-nginx)
  533. (root #~(string-append #$server:front-end "/share/zabbix/php"))))
  534. nginx))))
  535. (define-configuration zabbix-front-end-configuration
  536. (zabbix-server
  537. (file-like zabbix-server)
  538. "The Zabbix server package to use.")
  539. (nginx
  540. (list '())
  541. "List of @ref{nginx-server-configuration,@code{nginx-server-configuration}}
  542. blocks for the Zabbix front-end. When empty, a default that listens on port 80
  543. is used.")
  544. (db-host
  545. (string "localhost")
  546. "Database host name.")
  547. (db-port
  548. (number 5432)
  549. "Database port.")
  550. (db-name
  551. (string "zabbix")
  552. "Database name.")
  553. (db-user
  554. (string "zabbix")
  555. "Database user.")
  556. (db-password
  557. (string "")
  558. "Database password. Please, use @code{db-secret-file} instead.")
  559. (db-secret-file
  560. (string "")
  561. "Secret file which will be appended to @file{zabbix.conf.php} file. This
  562. file contains credentials for use by Zabbix front-end. You are expected to
  563. create it manually.")
  564. (zabbix-host
  565. (string "localhost")
  566. "Zabbix server hostname.")
  567. (zabbix-port
  568. (number 10051)
  569. "Zabbix server port."))
  570. (define (zabbix-front-end-config config)
  571. (match-record config <zabbix-front-end-configuration>
  572. (%location db-host db-port db-name db-user db-password db-secret-file
  573. zabbix-host zabbix-port)
  574. (mixed-text-file "zabbix.conf.php"
  575. "\
  576. <?php
  577. // Zabbix GUI configuration file.
  578. global $DB;
  579. $DB['TYPE'] = 'POSTGRESQL';
  580. $DB['SERVER'] = '" db-host "';
  581. $DB['PORT'] = '" (number->string db-port) "';
  582. $DB['DATABASE'] = '" db-name "';
  583. $DB['USER'] = '" db-user "';
  584. $DB['PASSWORD'] = " (let ((file (location-file %location))
  585. (line (location-line %location))
  586. (column (location-column %location)))
  587. (if (string-null? db-password)
  588. (if (string-null? db-secret-file)
  589. (raise (make-compound-condition
  590. (condition
  591. (&message
  592. (message
  593. (format #f "no '~A' or '~A' field in your '~A' record"
  594. 'db-secret-file 'db-password
  595. 'zabbix-front-end-configuration))))
  596. (condition
  597. (&error-location
  598. (location %location)))))
  599. (string-append "trim(file_get_contents('"
  600. db-secret-file "'));\n"))
  601. (begin
  602. (display-hint (format #f (G_ "~a:~a:~a: ~a:
  603. Consider using @code{db-secret-file} instead of @code{db-password} for better
  604. security.") file line column 'zabbix-front-end-configuration))
  605. (format #f "'~a';~%" db-password))))
  606. "
  607. // Schema name. Used for IBM DB2 and PostgreSQL.
  608. $DB['SCHEMA'] = '';
  609. // Use IEEE754 compatible value range for 64-bit Numeric (float) history values.
  610. $DB['DOUBLE_IEEE754'] = true;
  611. $ZBX_SERVER = '" zabbix-host "';
  612. $ZBX_SERVER_PORT = '" (number->string zabbix-port) "';
  613. $ZBX_SERVER_NAME = '';
  614. $IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_PNG;
  615. ")))
  616. (define %maintenance.inc.php
  617. ;; Empty php file to allow us move zabbix-frontend configs to ‘/etc/zabbix’
  618. ;; directory. See ‘install-front-end’ phase in
  619. ;; (@ (gnu packages monitoring) zabbix-server) package.
  620. "\
  621. <?php
  622. ")
  623. (define (zabbix-front-end-activation config)
  624. "Return the activation gexp for CONFIG."
  625. #~(begin
  626. (use-modules (guix build utils))
  627. (mkdir-p "/etc/zabbix")
  628. (call-with-output-file "/etc/zabbix/maintenance.inc.php"
  629. (lambda (port)
  630. (display #$%maintenance.inc.php port)))
  631. (copy-file #$(zabbix-front-end-config config)
  632. "/etc/zabbix/zabbix.conf.php")))
  633. (define zabbix-front-end-service-type
  634. (service-type
  635. (name 'zabbix-front-end)
  636. (extensions
  637. (list (service-extension activation-service-type
  638. zabbix-front-end-activation)
  639. (service-extension nginx-service-type
  640. zabbix-front-end-nginx-extension)
  641. ;; Make sure php-fpm is instantiated.
  642. (service-extension php-fpm-service-type
  643. (const #t))))
  644. (default-value (zabbix-front-end-configuration))
  645. (description
  646. "Run the zabbix-front-end web interface, which allows users to interact
  647. with Zabbix server.")))
  648. (define (generate-zabbix-front-end-documentation)
  649. (generate-documentation
  650. `((zabbix-front-end-configuration
  651. ,zabbix-front-end-configuration-fields))
  652. 'zabbix-front-end-configuration))