web.scm 78 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2015 David Thompson <davet@gnu.org>
  3. ;;; Copyright © 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
  4. ;;; Copyright © 2016 Nikita <nikita@n0.is>
  5. ;;; Copyright © 2016, 2017, 2018 Julien Lepiller <julien@lepiller.eu>
  6. ;;; Copyright © 2017 Christopher Baines <mail@cbaines.net>
  7. ;;; Copyright © 2017 nee <nee-git@hidamari.blue>
  8. ;;; Copyright © 2017, 2018 Clément Lassieur <clement@lassieur.org>
  9. ;;; Copyright © 2018 Pierre-Antoine Rouby <pierre-antoine.rouby@inria.fr>
  10. ;;; Copyright © 2017, 2018, 2019 Christopher Baines <mail@cbaines.net>
  11. ;;; Copyright © 2018 Marius Bakke <mbakke@fastmail.com>
  12. ;;; Copyright © 2019, 2020 Florian Pelz <pelzflorian@pelzflorian.de>
  13. ;;; Copyright © 2020 Ricardo Wurmus <rekado@elephly.net>
  14. ;;; Copyright © 2020 Tobias Geerinckx-Rice <me@tobias.gr>
  15. ;;; Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net>
  16. ;;; Copyright © 2020 Oleg Pykhalov <go.wigust@gmail.com>
  17. ;;; Copyright © 2020, 2021 Alexandru-Sergiu Marton <brown121407@posteo.ro>
  18. ;;;
  19. ;;; This file is part of GNU Guix.
  20. ;;;
  21. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  22. ;;; under the terms of the GNU General Public License as published by
  23. ;;; the Free Software Foundation; either version 3 of the License, or (at
  24. ;;; your option) any later version.
  25. ;;;
  26. ;;; GNU Guix is distributed in the hope that it will be useful, but
  27. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  28. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  29. ;;; GNU General Public License for more details.
  30. ;;;
  31. ;;; You should have received a copy of the GNU General Public License
  32. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  33. (define-module (gnu services web)
  34. #:use-module (gnu services)
  35. #:use-module (gnu services shepherd)
  36. #:use-module (gnu services admin)
  37. #:use-module (gnu services getmail)
  38. #:use-module (gnu services mail)
  39. #:use-module (gnu system pam)
  40. #:use-module (gnu system shadow)
  41. #:use-module (gnu packages admin)
  42. #:use-module (gnu packages base)
  43. #:use-module (gnu packages databases)
  44. #:use-module (gnu packages web)
  45. #:use-module (gnu packages patchutils)
  46. #:use-module (gnu packages php)
  47. #:use-module (gnu packages python)
  48. #:use-module (gnu packages gnupg)
  49. #:use-module (gnu packages guile)
  50. #:use-module (gnu packages logging)
  51. #:use-module (gnu packages mail)
  52. #:use-module (gnu packages rust-apps)
  53. #:use-module (guix packages)
  54. #:use-module (guix records)
  55. #:use-module (guix modules)
  56. #:use-module (guix utils)
  57. #:use-module (guix gexp)
  58. #:use-module ((guix store) #:select (text-file))
  59. #:use-module ((guix utils) #:select (version-major))
  60. #:use-module ((guix packages) #:select (package-version))
  61. #:use-module (srfi srfi-1)
  62. #:use-module (srfi srfi-9)
  63. #:use-module (ice-9 match)
  64. #:use-module (ice-9 format)
  65. #:export (httpd-configuration
  66. httpd-configuration?
  67. httpd-configuration-package
  68. httpd-configuration-pid-file
  69. httpd-configuration-config
  70. httpd-virtualhost
  71. httpd-virtualhost?
  72. httpd-virtualhost-addresses-and-ports
  73. httpd-virtualhost-contents
  74. httpd-config-file
  75. httpd-config-file?
  76. httpd-config-file-modules
  77. httpd-config-file-server-root
  78. httpd-config-file-server-name
  79. httpd-config-file-listen
  80. httpd-config-file-pid-file
  81. httpd-config-file-error-log
  82. httpd-config-file-user
  83. httpd-config-file-group
  84. httpd-module
  85. httpd-module?
  86. %default-httpd-modules
  87. httpd-service-type
  88. nginx-configuration
  89. nginx-configuration?
  90. nginx-configuration-nginx
  91. nginx-configuration-log-directory
  92. nginx-configuration-run-directory
  93. nginx-configuration-server-blocks
  94. nginx-configuration-upstream-blocks
  95. nginx-configuration-server-names-hash-bucket-size
  96. nginx-configuration-server-names-hash-bucket-max-size
  97. nginx-configuration-modules
  98. nginx-configuration-global-directives
  99. nginx-configuration-extra-content
  100. nginx-configuration-file
  101. nginx-server-configuration
  102. nginx-server-configuration?
  103. nginx-server-configuration-listen
  104. nginx-server-configuration-server-name
  105. nginx-server-configuration-root
  106. nginx-server-configuration-locations
  107. nginx-server-configuration-index
  108. nginx-server-configuration-ssl-certificate
  109. nginx-server-configuration-ssl-certificate-key
  110. nginx-server-configuration-server-tokens?
  111. nginx-server-configuration-raw-content
  112. nginx-upstream-configuration
  113. nginx-upstream-configuration?
  114. nginx-upstream-configuration-name
  115. nginx-upstream-configuration-servers
  116. nginx-location-configuration
  117. nginx-location-configuration?
  118. nginx-location-configuration-uri
  119. nginx-location-configuration-body
  120. nginx-named-location-configuration
  121. nginx-named-location-configuration?
  122. nginx-named-location-configuration-name
  123. nginx-named-location-configuration-body
  124. nginx-service
  125. nginx-service-type
  126. fcgiwrap-configuration
  127. fcgiwrap-configuration?
  128. fcgiwrap-service-type
  129. php-fpm-configuration
  130. make-php-fpm-configuration
  131. php-fpm-configuration?
  132. php-fpm-configuration-php
  133. php-fpm-configuration-socket
  134. php-fpm-configuration-user
  135. php-fpm-configuration-group
  136. php-fpm-configuration-socket-user
  137. php-fpm-configuration-socket-group
  138. php-fpm-configuration-pid-file
  139. php-fpm-configuration-log-file
  140. php-fpm-configuration-process-manager
  141. php-fpm-configuration-display-errors
  142. php-fpm-configuration-timezone
  143. php-fpm-configuration-workers-log-file
  144. php-fpm-configuration-file
  145. php-fpm-configuration-php-ini-file
  146. php-fpm-dynamic-process-manager-configuration
  147. make-php-fpm-dynamic-process-manager-configuration
  148. php-fpm-dynamic-process-manager-configuration?
  149. php-fpm-dynamic-process-manager-configuration-max-children
  150. php-fpm-dynamic-process-manager-configuration-start-servers
  151. php-fpm-dynamic-process-manager-configuration-min-spare-servers
  152. php-fpm-dynamic-process-manager-configuration-max-spare-servers
  153. php-fpm-static-process-manager-configuration
  154. make-php-fpm-static-process-manager-configuration
  155. php-fpm-static-process-manager-configuration?
  156. php-fpm-static-process-manager-configuration-max-children
  157. php-fpm-on-demand-process-manager-configuration
  158. make-php-fpm-on-demand-process-manager-configuration
  159. php-fpm-on-demand-process-manager-configuration?
  160. php-fpm-on-demand-process-manager-configuration-max-children
  161. php-fpm-on-demand-process-manager-configuration-process-idle-timeout
  162. php-fpm-service-type
  163. nginx-php-location
  164. cat-avatar-generator-service
  165. hpcguix-web-configuration
  166. hpcguix-web-configuration?
  167. hpcguix-web-service-type
  168. tailon-configuration-file
  169. tailon-configuration-file?
  170. tailon-configuration-file-files
  171. tailon-configuration-file-bind
  172. tailon-configuration-file-relative-root
  173. tailon-configuration-file-allow-transfers?
  174. tailon-configuration-file-follow-names?
  175. tailon-configuration-file-tail-lines
  176. tailon-configuration-file-allowed-commands
  177. tailon-configuration-file-debug?
  178. tailon-configuration-file-http-auth
  179. tailon-configuration-file-users
  180. tailon-configuration
  181. tailon-configuration?
  182. tailon-configuration-config-file
  183. tailon-configuration-package
  184. tailon-service-type
  185. varnish-configuration
  186. varnish-configuration?
  187. varnish-configuration-package
  188. varnish-configuration-name
  189. varnish-configuration-backend
  190. varnish-configuration-vcl
  191. varnish-configuration-listen
  192. varnish-configuration-storage
  193. varnish-configuration-parameters
  194. varnish-configuration-extra-options
  195. varnish-service-type
  196. patchwork-database-configuration
  197. patchwork-database-configuration?
  198. patchwork-database-configuration-engine
  199. patchwork-database-configuration-name
  200. patchwork-database-configuration-user
  201. patchwork-database-configuration-password
  202. patchwork-database-configuration-host
  203. patchwork-database-configuration-port
  204. patchwork-settings-module
  205. patchwork-settings-module?
  206. patchwork-settings-module-database-configuration
  207. patchwork-settings-module-secret-key
  208. patchwork-settings-module-allowed-hosts
  209. patchwork-settings-module-default-from-email
  210. patchwork-settings-module-static-url
  211. patchwork-settings-module-admins
  212. patchwork-settings-module-debug?
  213. patchwork-settings-module-enable-rest-api?
  214. patchwork-settings-module-enable-xmlrpc?
  215. patchwork-settings-module-force-https-links?
  216. patchwork-settings-module-extra-settings
  217. patchwork-configuration
  218. patchwork-configuration?
  219. patchwork-configuration-patchwork
  220. patchwork-configuration-settings-module
  221. patchwork-configuration-domain
  222. patchwork-virtualhost
  223. patchwork-service-type
  224. mumi-configuration
  225. mumi-configuration?
  226. mumi-configuration-mumi
  227. mumi-configuration-mailer?
  228. mumi-configuration-sender
  229. mumi-configuration-smtp
  230. mumi-service-type
  231. gmnisrv-configuration
  232. gmnisrv-configuration?
  233. gmnisrv-configuration-package
  234. gmnisrv-configuration-config-file
  235. gmnisrv-service-type
  236. agate-configuration
  237. agate-configuration?
  238. agate-configuration-package
  239. agate-configuration-content
  240. agate-configuration-cert
  241. agate-configuration-key
  242. agate-configuration-addr
  243. agate-configuration-hostname
  244. agate-configuration-lang
  245. agate-configuration-silent
  246. agate-configuration-serve-secret
  247. agate-configuration-log-ip
  248. agate-configuration-user
  249. agate-configuration-group
  250. agate-configuration-log-file
  251. agate-service-type))
  252. ;;; Commentary:
  253. ;;;
  254. ;;; Web services.
  255. ;;;
  256. ;;; Code:
  257. (define-record-type* <httpd-module>
  258. httpd-module make-httpd-module
  259. httpd-module?
  260. (name httpd-load-module-name)
  261. (file httpd-load-module-file))
  262. ;; Default modules for the httpd-service-type, taken from etc/httpd/httpd.conf
  263. ;; file in the httpd package.
  264. (define %default-httpd-modules
  265. (map (match-lambda
  266. ((name file)
  267. (httpd-module
  268. (name name)
  269. (file file))))
  270. '(("authn_file_module" "modules/mod_authn_file.so")
  271. ("authn_core_module" "modules/mod_authn_core.so")
  272. ("authz_host_module" "modules/mod_authz_host.so")
  273. ("authz_groupfile_module" "modules/mod_authz_groupfile.so")
  274. ("authz_user_module" "modules/mod_authz_user.so")
  275. ("authz_core_module" "modules/mod_authz_core.so")
  276. ("access_compat_module" "modules/mod_access_compat.so")
  277. ("auth_basic_module" "modules/mod_auth_basic.so")
  278. ("reqtimeout_module" "modules/mod_reqtimeout.so")
  279. ("filter_module" "modules/mod_filter.so")
  280. ("mime_module" "modules/mod_mime.so")
  281. ("log_config_module" "modules/mod_log_config.so")
  282. ("env_module" "modules/mod_env.so")
  283. ("headers_module" "modules/mod_headers.so")
  284. ("setenvif_module" "modules/mod_setenvif.so")
  285. ("version_module" "modules/mod_version.so")
  286. ("unixd_module" "modules/mod_unixd.so")
  287. ("status_module" "modules/mod_status.so")
  288. ("autoindex_module" "modules/mod_autoindex.so")
  289. ("dir_module" "modules/mod_dir.so")
  290. ("alias_module" "modules/mod_alias.so"))))
  291. (define-record-type* <httpd-config-file>
  292. httpd-config-file make-httpd-config-file
  293. httpd-config-file?
  294. (modules httpd-config-file-modules
  295. (default %default-httpd-modules))
  296. (server-root httpd-config-file-server-root
  297. (default httpd))
  298. (server-name httpd-config-file-server-name
  299. (default #f))
  300. (document-root httpd-config-file-document-root
  301. (default "/srv/http"))
  302. (listen httpd-config-file-listen
  303. (default '("80")))
  304. (pid-file httpd-config-file-pid-file
  305. (default "/var/run/httpd"))
  306. (error-log httpd-config-file-error-log
  307. (default "/var/log/httpd/error_log"))
  308. (user httpd-config-file-user
  309. (default "httpd"))
  310. (group httpd-config-file-group
  311. (default "httpd"))
  312. (extra-config httpd-config-file-extra-config
  313. (default
  314. (list "TypesConfig etc/httpd/mime.types"))))
  315. (define-gexp-compiler (httpd-config-file-compiler
  316. (file <httpd-config-file>) system target)
  317. (match file
  318. (($ <httpd-config-file> load-modules server-root server-name
  319. document-root listen pid-file error-log
  320. user group extra-config)
  321. (gexp->derivation
  322. "httpd.conf"
  323. #~(call-with-output-file (ungexp output "out")
  324. (lambda (port)
  325. (display
  326. (string-append
  327. (ungexp-splicing
  328. `(,@(append-map
  329. (match-lambda
  330. (($ <httpd-module> name module)
  331. `("LoadModule " ,name " " ,module "\n")))
  332. load-modules)
  333. ,@`("ServerRoot " ,server-root "\n")
  334. ,@(if server-name
  335. `("ServerName " ,server-name "\n")
  336. '())
  337. ,@`("DocumentRoot " ,document-root "\n")
  338. ,@(append-map
  339. (lambda (listen-value)
  340. `("Listen " ,listen-value "\n"))
  341. listen)
  342. ,@(if pid-file
  343. `("Pidfile " ,pid-file "\n")
  344. '())
  345. ,@(if error-log
  346. `("ErrorLog " ,error-log "\n")
  347. '())
  348. ,@(if user
  349. `("User " ,user "\n")
  350. '())
  351. ,@(if group
  352. `("Group " ,group "\n")
  353. '())
  354. "\n\n"
  355. ,@extra-config)))
  356. port)))
  357. #:local-build? #t))))
  358. (define-record-type <httpd-virtualhost>
  359. (httpd-virtualhost addresses-and-ports contents)
  360. httpd-virtualhost?
  361. (addresses-and-ports httpd-virtualhost-addresses-and-ports)
  362. (contents httpd-virtualhost-contents))
  363. (define-record-type* <httpd-configuration>
  364. httpd-configuration make-httpd-configuration
  365. httpd-configuration?
  366. (package httpd-configuration-package
  367. (default httpd))
  368. (pid-file httpd-configuration-pid-file
  369. (default "/var/run/httpd"))
  370. (config httpd-configuration-config
  371. (default (httpd-config-file))))
  372. (define %httpd-accounts
  373. (list (user-group (name "httpd") (system? #t))
  374. (user-account
  375. (name "httpd")
  376. (group "httpd")
  377. (system? #t)
  378. (comment "Apache HTTPD server user")
  379. (home-directory "/var/empty")
  380. (shell (file-append shadow "/sbin/nologin")))))
  381. (define httpd-shepherd-services
  382. (match-lambda
  383. (($ <httpd-configuration> package pid-file config)
  384. (list (shepherd-service
  385. (provision '(httpd))
  386. (documentation "The Apache HTTP Server")
  387. (requirement '(networking))
  388. (start #~(make-forkexec-constructor
  389. `(#$(file-append package "/bin/httpd")
  390. #$@(if config
  391. (list "-f" config)
  392. '()))
  393. #:pid-file #$pid-file))
  394. (stop #~(make-kill-destructor)))))))
  395. (define httpd-activation
  396. (match-lambda
  397. (($ <httpd-configuration> package pid-file config)
  398. (match-record
  399. config
  400. <httpd-config-file>
  401. (error-log document-root)
  402. #~(begin
  403. (use-modules (guix build utils))
  404. (mkdir-p #$(dirname error-log))
  405. (mkdir-p #$document-root))))))
  406. (define (httpd-process-extensions original-config extension-configs)
  407. (let ((config (httpd-configuration-config
  408. original-config)))
  409. (if (httpd-config-file? config)
  410. (httpd-configuration
  411. (inherit original-config)
  412. (config
  413. (httpd-config-file
  414. (inherit config)
  415. (extra-config
  416. (append (httpd-config-file-extra-config config)
  417. (append-map
  418. (match-lambda
  419. (($ <httpd-virtualhost>
  420. addresses-and-ports
  421. contents)
  422. `(,(string-append
  423. "\n<VirtualHost " addresses-and-ports ">\n")
  424. ,@contents
  425. "\n</VirtualHost>\n"))
  426. ((? string? x)
  427. `("\n" ,x "\n"))
  428. ((? list? x)
  429. `("\n" ,@x "\n")))
  430. extension-configs)))))))))
  431. (define httpd-service-type
  432. (service-type (name 'httpd)
  433. (extensions
  434. (list (service-extension shepherd-root-service-type
  435. httpd-shepherd-services)
  436. (service-extension activation-service-type
  437. httpd-activation)
  438. (service-extension account-service-type
  439. (const %httpd-accounts))))
  440. (compose concatenate)
  441. (extend httpd-process-extensions)
  442. (default-value
  443. (httpd-configuration))))
  444. (define-record-type* <nginx-server-configuration>
  445. nginx-server-configuration make-nginx-server-configuration
  446. nginx-server-configuration?
  447. (listen nginx-server-configuration-listen
  448. (default '("80" "443 ssl")))
  449. (server-name nginx-server-configuration-server-name
  450. (default (list 'default)))
  451. (root nginx-server-configuration-root
  452. (default "/srv/http"))
  453. (locations nginx-server-configuration-locations
  454. (default '()))
  455. (index nginx-server-configuration-index
  456. (default (list "index.html")))
  457. (try-files nginx-server-configuration-try-files
  458. (default '()))
  459. (ssl-certificate nginx-server-configuration-ssl-certificate
  460. (default #f))
  461. (ssl-certificate-key nginx-server-configuration-ssl-certificate-key
  462. (default #f))
  463. (server-tokens? nginx-server-configuration-server-tokens?
  464. (default #f))
  465. (raw-content nginx-server-configuration-raw-content
  466. (default '())))
  467. (define-record-type* <nginx-upstream-configuration>
  468. nginx-upstream-configuration make-nginx-upstream-configuration
  469. nginx-upstream-configuration?
  470. (name nginx-upstream-configuration-name)
  471. (servers nginx-upstream-configuration-servers))
  472. (define-record-type* <nginx-location-configuration>
  473. nginx-location-configuration make-nginx-location-configuration
  474. nginx-location-configuration?
  475. (uri nginx-location-configuration-uri
  476. (default #f))
  477. (body nginx-location-configuration-body))
  478. (define-record-type* <nginx-named-location-configuration>
  479. nginx-named-location-configuration make-nginx-named-location-configuration
  480. nginx-named-location-configuration?
  481. (name nginx-named-location-configuration-name
  482. (default #f))
  483. (body nginx-named-location-configuration-body))
  484. (define-record-type* <nginx-configuration>
  485. nginx-configuration make-nginx-configuration
  486. nginx-configuration?
  487. (nginx nginx-configuration-nginx ;<package>
  488. (default nginx))
  489. (log-directory nginx-configuration-log-directory ;string
  490. (default "/var/log/nginx"))
  491. (run-directory nginx-configuration-run-directory ;string
  492. (default "/var/run/nginx"))
  493. (server-blocks nginx-configuration-server-blocks
  494. (default '())) ;list of <nginx-server-configuration>
  495. (upstream-blocks nginx-configuration-upstream-blocks
  496. (default '())) ;list of <nginx-upstream-configuration>
  497. (server-names-hash-bucket-size nginx-configuration-server-names-hash-bucket-size
  498. (default #f))
  499. (server-names-hash-bucket-max-size nginx-configuration-server-names-hash-bucket-max-size
  500. (default #f))
  501. (modules nginx-configuration-modules (default '()))
  502. (global-directives nginx-configuration-global-directives
  503. (default '((events . ()))))
  504. (lua-package-path nginx-lua-package-path ;list of <package>
  505. (default #f))
  506. (lua-package-cpath nginx-lua-package-cpath ;list of <package>
  507. (default #f))
  508. (extra-content nginx-configuration-extra-content
  509. (default ""))
  510. (file nginx-configuration-file ;#f | string | file-like
  511. (default #f)))
  512. (define (config-domain-strings names)
  513. "Return a string denoting the nginx config representation of NAMES, a list
  514. of domain names."
  515. (map (match-lambda
  516. ('default "_ ")
  517. ((? string? str) (list str " ")))
  518. names))
  519. (define (config-index-strings names)
  520. "Return a string denoting the nginx config representation of NAMES, a list
  521. of index files."
  522. (map (match-lambda
  523. ((? string? str) (list str " ")))
  524. names))
  525. (define (emit-load-module module)
  526. (list "load_module " module ";\n"))
  527. (define emit-global-directive
  528. (match-lambda
  529. ((key . (? list? alist))
  530. (format #f "~a { ~{~a~}}~%" key (map emit-global-directive alist)))
  531. ((key . value)
  532. (format #f "~a ~a;~%" key value))))
  533. (define emit-nginx-location-config
  534. (match-lambda
  535. (($ <nginx-location-configuration> uri body)
  536. (list
  537. " location " uri " {\n"
  538. (map (lambda (x) (list " " x "\n")) body)
  539. " }\n"))
  540. (($ <nginx-named-location-configuration> name body)
  541. (list
  542. " location @" name " {\n"
  543. (map (lambda (x) (list " " x "\n")) body)
  544. " }\n"))))
  545. (define (emit-nginx-server-config server)
  546. (let ((listen (nginx-server-configuration-listen server))
  547. (server-name (nginx-server-configuration-server-name server))
  548. (ssl-certificate (nginx-server-configuration-ssl-certificate server))
  549. (ssl-certificate-key
  550. (nginx-server-configuration-ssl-certificate-key server))
  551. (root (nginx-server-configuration-root server))
  552. (index (nginx-server-configuration-index server))
  553. (try-files (nginx-server-configuration-try-files server))
  554. (server-tokens? (nginx-server-configuration-server-tokens? server))
  555. (locations (nginx-server-configuration-locations server))
  556. (raw-content (nginx-server-configuration-raw-content server)))
  557. (define-syntax-parameter <> (syntax-rules ()))
  558. (define-syntax-rule (and/l x tail ...)
  559. (let ((x* x))
  560. (if x*
  561. (syntax-parameterize ((<> (identifier-syntax x*)))
  562. (list tail ...))
  563. '())))
  564. (list
  565. " server {\n"
  566. (map (lambda (directive) (list " listen " directive ";\n")) listen)
  567. " server_name " (config-domain-strings server-name) ";\n"
  568. (and/l ssl-certificate " ssl_certificate " <> ";\n")
  569. (and/l ssl-certificate-key " ssl_certificate_key " <> ";\n")
  570. " root " root ";\n"
  571. " index " (config-index-strings index) ";\n"
  572. (if (not (nil? try-files))
  573. (and/l (config-index-strings try-files) " try_files " <> ";\n")
  574. "")
  575. " server_tokens " (if server-tokens? "on" "off") ";\n"
  576. "\n"
  577. (map emit-nginx-location-config locations)
  578. "\n"
  579. (map (lambda (x) (list " " x "\n")) raw-content)
  580. " }\n")))
  581. (define (emit-nginx-upstream-config upstream)
  582. (list
  583. " upstream " (nginx-upstream-configuration-name upstream) " {\n"
  584. (map (lambda (server)
  585. (simple-format #f " server ~A;\n" server))
  586. (nginx-upstream-configuration-servers upstream))
  587. " }\n"))
  588. (define (flatten . lst)
  589. "Return a list that recursively concatenates all sub-lists of LST."
  590. (define (flatten1 head out)
  591. (if (list? head)
  592. (fold-right flatten1 out head)
  593. (cons head out)))
  594. (fold-right flatten1 '() lst))
  595. (define (default-nginx-config config)
  596. (match-record config
  597. <nginx-configuration>
  598. (nginx log-directory run-directory
  599. server-blocks upstream-blocks
  600. server-names-hash-bucket-size
  601. server-names-hash-bucket-max-size
  602. modules
  603. global-directives
  604. lua-package-path
  605. lua-package-cpath
  606. extra-content)
  607. (apply mixed-text-file "nginx.conf"
  608. (flatten
  609. "user nginx nginx;\n"
  610. "pid " run-directory "/pid;\n"
  611. "error_log " log-directory "/error.log info;\n"
  612. (map emit-load-module modules)
  613. (map emit-global-directive global-directives)
  614. "http {\n"
  615. " client_body_temp_path " run-directory "/client_body_temp;\n"
  616. " proxy_temp_path " run-directory "/proxy_temp;\n"
  617. " fastcgi_temp_path " run-directory "/fastcgi_temp;\n"
  618. " uwsgi_temp_path " run-directory "/uwsgi_temp;\n"
  619. " scgi_temp_path " run-directory "/scgi_temp;\n"
  620. " access_log " log-directory "/access.log;\n"
  621. " include " nginx "/share/nginx/conf/mime.types;\n"
  622. (if lua-package-path
  623. #~(format #f " lua_package_path ~s;~%"
  624. (string-join (map (lambda (path)
  625. (string-append path "/lib/?.lua"))
  626. '#$lua-package-path)
  627. ";"))
  628. "")
  629. (if lua-package-cpath
  630. #~(format #f " lua_package_cpath ~s;~%"
  631. (string-join (map (lambda (cpath)
  632. (string-append cpath "/lib/lua/?.lua"))
  633. '#$lua-package-cpath)
  634. ";"))
  635. "")
  636. (if server-names-hash-bucket-size
  637. (string-append
  638. " server_names_hash_bucket_size "
  639. (number->string server-names-hash-bucket-size)
  640. ";\n")
  641. "")
  642. (if server-names-hash-bucket-max-size
  643. (string-append
  644. " server_names_hash_bucket_max_size "
  645. (number->string server-names-hash-bucket-max-size)
  646. ";\n")
  647. "")
  648. "\n"
  649. (map emit-nginx-upstream-config upstream-blocks)
  650. (map emit-nginx-server-config server-blocks)
  651. extra-content
  652. "\n}\n"))))
  653. (define %nginx-accounts
  654. (list (user-group (name "nginx") (system? #t))
  655. (user-account
  656. (name "nginx")
  657. (group "nginx")
  658. (system? #t)
  659. (comment "nginx server user")
  660. (home-directory "/var/empty")
  661. (shell (file-append shadow "/sbin/nologin")))))
  662. (define (nginx-activation config)
  663. (match-record config
  664. <nginx-configuration>
  665. (nginx log-directory run-directory file)
  666. #~(begin
  667. (use-modules (guix build utils))
  668. (format #t "creating nginx log directory '~a'~%" #$log-directory)
  669. (mkdir-p #$log-directory)
  670. (format #t "creating nginx run directory '~a'~%" #$run-directory)
  671. (mkdir-p #$run-directory)
  672. (format #t "creating nginx temp directories '~a/{client_body,proxy,fastcgi,uwsgi,scgi}_temp'~%" #$run-directory)
  673. (mkdir-p (string-append #$run-directory "/client_body_temp"))
  674. (mkdir-p (string-append #$run-directory "/proxy_temp"))
  675. (mkdir-p (string-append #$run-directory "/fastcgi_temp"))
  676. (mkdir-p (string-append #$run-directory "/uwsgi_temp"))
  677. (mkdir-p (string-append #$run-directory "/scgi_temp"))
  678. ;; Start-up logs. Once configuration is loaded, nginx switches to
  679. ;; log-directory.
  680. (mkdir-p (string-append #$run-directory "/logs"))
  681. ;; Check configuration file syntax.
  682. (system* (string-append #$nginx "/sbin/nginx")
  683. "-c" #$(or file
  684. (default-nginx-config config))
  685. "-p" #$run-directory
  686. "-t"))))
  687. (define (nginx-shepherd-service config)
  688. (match-record config
  689. <nginx-configuration>
  690. (nginx file run-directory)
  691. (let* ((nginx-binary (file-append nginx "/sbin/nginx"))
  692. (pid-file (in-vicinity run-directory "pid"))
  693. (nginx-action
  694. (lambda args
  695. #~(lambda _
  696. (invoke #$nginx-binary "-c"
  697. #$(or file
  698. (default-nginx-config config))
  699. #$@args)
  700. (match '#$args
  701. (("-s" . _) #f)
  702. (_
  703. ;; When FILE is true, we cannot be sure that PID-FILE will
  704. ;; be created, so assume it won't show up. When FILE is
  705. ;; false, read PID-FILE.
  706. #$(if file
  707. #~#t
  708. #~(read-pid-file #$pid-file))))))))
  709. ;; TODO: Add 'reload' action.
  710. (list (shepherd-service
  711. (provision '(nginx))
  712. (documentation "Run the nginx daemon.")
  713. (requirement '(user-processes loopback))
  714. (modules `((ice-9 match)
  715. ,@%default-modules))
  716. (start (nginx-action "-p" run-directory))
  717. (stop (nginx-action "-s" "stop")))))))
  718. (define nginx-service-type
  719. (service-type (name 'nginx)
  720. (extensions
  721. (list (service-extension shepherd-root-service-type
  722. nginx-shepherd-service)
  723. (service-extension activation-service-type
  724. nginx-activation)
  725. (service-extension account-service-type
  726. (const %nginx-accounts))))
  727. (compose concatenate)
  728. (extend (lambda (config servers)
  729. (nginx-configuration
  730. (inherit config)
  731. (server-blocks
  732. (append (nginx-configuration-server-blocks config)
  733. servers)))))
  734. (default-value (nginx-configuration))
  735. (description "Run the nginx Web server.")))
  736. (define-record-type* <fcgiwrap-configuration> fcgiwrap-configuration
  737. make-fcgiwrap-configuration
  738. fcgiwrap-configuration?
  739. (package fcgiwrap-configuration-package ;<package>
  740. (default fcgiwrap))
  741. (socket fcgiwrap-configuration-socket
  742. (default "tcp:127.0.0.1:9000"))
  743. (user fcgiwrap-configuration-user
  744. (default "fcgiwrap"))
  745. (group fcgiwrap-configuration-group
  746. (default "fcgiwrap")))
  747. (define fcgiwrap-accounts
  748. (match-lambda
  749. (($ <fcgiwrap-configuration> package socket user group)
  750. (filter identity
  751. (list
  752. (and (equal? group "fcgiwrap")
  753. (user-group
  754. (name "fcgiwrap")
  755. (system? #t)))
  756. (and (equal? user "fcgiwrap")
  757. (user-account
  758. (name "fcgiwrap")
  759. (group group)
  760. (system? #t)
  761. (comment "Fcgiwrap Daemon")
  762. (home-directory "/var/empty")
  763. (shell (file-append shadow "/sbin/nologin")))))))))
  764. (define fcgiwrap-shepherd-service
  765. (match-lambda
  766. (($ <fcgiwrap-configuration> package socket user group)
  767. (list (shepherd-service
  768. (provision '(fcgiwrap))
  769. (documentation "Run the fcgiwrap daemon.")
  770. (requirement '(networking))
  771. (start #~(make-forkexec-constructor
  772. '(#$(file-append package "/sbin/fcgiwrap")
  773. "-s" #$socket)
  774. #:user #$user #:group #$group
  775. #:log-file "/var/log/fcgiwrap.log"))
  776. (stop #~(make-kill-destructor)))))))
  777. (define fcgiwrap-activation
  778. (match-lambda
  779. (($ <fcgiwrap-configuration> package socket user group)
  780. #~(begin
  781. ;; When listening on a unix socket, create a parent directory for the
  782. ;; socket with the correct permissions.
  783. (when (string-prefix? "unix:" #$socket)
  784. (let ((run-directory
  785. (dirname (substring #$socket (string-length "unix:")))))
  786. (mkdir-p run-directory)
  787. (chown run-directory
  788. (passwd:uid (getpw #$user))
  789. (group:gid (getgr #$group)))))))))
  790. (define fcgiwrap-service-type
  791. (service-type (name 'fcgiwrap)
  792. (extensions
  793. (list (service-extension shepherd-root-service-type
  794. fcgiwrap-shepherd-service)
  795. (service-extension account-service-type
  796. fcgiwrap-accounts)
  797. (service-extension activation-service-type
  798. fcgiwrap-activation)))
  799. (default-value (fcgiwrap-configuration))))
  800. (define-record-type* <php-fpm-configuration> php-fpm-configuration
  801. make-php-fpm-configuration
  802. php-fpm-configuration?
  803. (php php-fpm-configuration-php ;<package>
  804. (default php))
  805. (socket php-fpm-configuration-socket
  806. (default (string-append "/var/run/php"
  807. (version-major (package-version php))
  808. "-fpm.sock")))
  809. (user php-fpm-configuration-user
  810. (default "php-fpm"))
  811. (group php-fpm-configuration-group
  812. (default "php-fpm"))
  813. (socket-user php-fpm-configuration-socket-user
  814. (default "php-fpm"))
  815. (socket-group php-fpm-configuration-socket-group
  816. (default "nginx"))
  817. (pid-file php-fpm-configuration-pid-file
  818. (default (string-append "/var/run/php"
  819. (version-major (package-version php))
  820. "-fpm.pid")))
  821. (log-file php-fpm-configuration-log-file
  822. (default (string-append "/var/log/php"
  823. (version-major (package-version php))
  824. "-fpm.log")))
  825. (process-manager php-fpm-configuration-process-manager
  826. (default (php-fpm-dynamic-process-manager-configuration)))
  827. (display-errors php-fpm-configuration-display-errors
  828. (default #f))
  829. (timezone php-fpm-configuration-timezone
  830. (default #f))
  831. (workers-log-file php-fpm-configuration-workers-log-file
  832. (default (string-append "/var/log/php"
  833. (version-major (package-version php))
  834. "-fpm.www.log")))
  835. (file php-fpm-configuration-file ;#f | file-like
  836. (default #f))
  837. (php-ini-file php-fpm-configuration-php-ini-file ;#f | file-like
  838. (default #f)))
  839. (define-record-type* <php-fpm-dynamic-process-manager-configuration>
  840. php-fpm-dynamic-process-manager-configuration
  841. make-php-fpm-dynamic-process-manager-configuration
  842. php-fpm-dynamic-process-manager-configuration?
  843. (max-children php-fpm-dynamic-process-manager-configuration-max-children
  844. (default 5))
  845. (start-servers php-fpm-dynamic-process-manager-configuration-start-servers
  846. (default 2))
  847. (min-spare-servers php-fpm-dynamic-process-manager-configuration-min-spare-servers
  848. (default 1))
  849. (max-spare-servers php-fpm-dynamic-process-manager-configuration-max-spare-servers
  850. (default 3)))
  851. (define-record-type* <php-fpm-static-process-manager-configuration>
  852. php-fpm-static-process-manager-configuration
  853. make-php-fpm-static-process-manager-configuration
  854. php-fpm-static-process-manager-configuration?
  855. (max-children php-fpm-static-process-manager-configuration-max-children
  856. (default 5)))
  857. (define-record-type* <php-fpm-on-demand-process-manager-configuration>
  858. php-fpm-on-demand-process-manager-configuration
  859. make-php-fpm-on-demand-process-manager-configuration
  860. php-fpm-on-demand-process-manager-configuration?
  861. (max-children php-fpm-on-demand-process-manager-configuration-max-children
  862. (default 5))
  863. (process-idle-timeout php-fpm-on-demand-process-manager-configuration-process-idle-timeout
  864. (default 10)))
  865. (define php-fpm-accounts
  866. (match-lambda
  867. (($ <php-fpm-configuration> php socket user group socket-user socket-group _ _ _ _ _ _)
  868. `(,@(if (equal? group "php-fpm")
  869. '()
  870. (list (user-group (name "php-fpm") (system? #t))))
  871. ,(user-group
  872. (name group)
  873. (system? #t))
  874. ,(user-account
  875. (name user)
  876. (group group)
  877. (supplementary-groups '("php-fpm"))
  878. (system? #t)
  879. (comment "php-fpm daemon user")
  880. (home-directory "/var/empty")
  881. (shell (file-append shadow "/sbin/nologin")))))))
  882. (define (default-php-fpm-config socket user group socket-user socket-group
  883. pid-file log-file pm display-errors timezone workers-log-file)
  884. (apply mixed-text-file "php-fpm.conf"
  885. (flatten
  886. "[global]\n"
  887. "pid =" pid-file "\n"
  888. "error_log =" log-file "\n"
  889. "[www]\n"
  890. "user =" user "\n"
  891. "group =" group "\n"
  892. "listen =" socket "\n"
  893. "listen.owner =" socket-user "\n"
  894. "listen.group =" socket-group "\n"
  895. (if timezone
  896. (string-append "php_admin_value[date.timezone] = \"" timezone "\"\n")
  897. "")
  898. (match pm
  899. (($ <php-fpm-dynamic-process-manager-configuration>
  900. pm.max-children
  901. pm.start-servers
  902. pm.min-spare-servers
  903. pm.max-spare-servers)
  904. (list
  905. "pm = dynamic\n"
  906. "pm.max_children =" (number->string pm.max-children) "\n"
  907. "pm.start_servers =" (number->string pm.start-servers) "\n"
  908. "pm.min_spare_servers =" (number->string pm.min-spare-servers) "\n"
  909. "pm.max_spare_servers =" (number->string pm.max-spare-servers) "\n"))
  910. (($ <php-fpm-static-process-manager-configuration>
  911. pm.max-children)
  912. (list
  913. "pm = static\n"
  914. "pm.max_children =" (number->string pm.max-children) "\n"))
  915. (($ <php-fpm-on-demand-process-manager-configuration>
  916. pm.max-children
  917. pm.process-idle-timeout)
  918. (list
  919. "pm = ondemand\n"
  920. "pm.max_children =" (number->string pm.max-children) "\n"
  921. "pm.process_idle_timeout =" (number->string pm.process-idle-timeout) "s\n")))
  922. "php_flag[display_errors] = " (if display-errors "on" "off") "\n"
  923. (if workers-log-file
  924. (list "catch_workers_output = yes\n"
  925. "php_admin_value[error_log] =" workers-log-file "\n"
  926. "php_admin_flag[log_errors] = on\n")
  927. (list "catch_workers_output = no\n")))))
  928. (define php-fpm-shepherd-service
  929. (match-lambda
  930. (($ <php-fpm-configuration> php socket user group socket-user socket-group
  931. pid-file log-file pm display-errors
  932. timezone workers-log-file file php-ini-file)
  933. (list (shepherd-service
  934. (provision '(php-fpm))
  935. (documentation "Run the php-fpm daemon.")
  936. (requirement '(networking))
  937. (start #~(make-forkexec-constructor
  938. '(#$(file-append php "/sbin/php-fpm")
  939. "--fpm-config"
  940. #$(or file
  941. (default-php-fpm-config socket user group
  942. socket-user socket-group pid-file log-file
  943. pm display-errors timezone workers-log-file))
  944. #$@(if php-ini-file
  945. `("-c" ,php-ini-file)
  946. '()))
  947. #:pid-file #$pid-file))
  948. (stop #~(make-kill-destructor)))))))
  949. (define (php-fpm-activation config)
  950. #~(begin
  951. (use-modules (guix build utils))
  952. (let* ((user (getpwnam #$(php-fpm-configuration-user config)))
  953. (touch (lambda (file-name)
  954. (call-with-output-file file-name (const #t))))
  955. (workers-log-file
  956. #$(php-fpm-configuration-workers-log-file config))
  957. (init-log-file
  958. (lambda (file-name)
  959. (when workers-log-file
  960. (when (not (file-exists? file-name))
  961. (touch file-name))
  962. (chown file-name (passwd:uid user) (passwd:gid user))
  963. (chmod file-name #o660)))))
  964. (init-log-file #$(php-fpm-configuration-log-file config))
  965. (init-log-file workers-log-file))))
  966. (define php-fpm-service-type
  967. (service-type
  968. (name 'php-fpm)
  969. (description
  970. "Run @command{php-fpm} to provide a fastcgi socket for calling php through
  971. a webserver.")
  972. (extensions
  973. (list (service-extension shepherd-root-service-type
  974. php-fpm-shepherd-service)
  975. (service-extension activation-service-type
  976. php-fpm-activation)
  977. (service-extension account-service-type
  978. php-fpm-accounts)))
  979. (default-value (php-fpm-configuration))))
  980. (define* (nginx-php-location
  981. #:key
  982. (nginx-package nginx)
  983. (socket (string-append "/var/run/php"
  984. (version-major (package-version php))
  985. "-fpm.sock")))
  986. "Return a nginx-location-configuration that makes nginx run .php files."
  987. (nginx-location-configuration
  988. (uri "~ \\.php$")
  989. (body (list
  990. "fastcgi_split_path_info ^(.+\\.php)(/.+)$;"
  991. (string-append "fastcgi_pass unix:" socket ";")
  992. "fastcgi_index index.php;"
  993. (list "include " nginx-package "/share/nginx/conf/fastcgi.conf;")))))
  994. (define* (cat-avatar-generator-service
  995. #:key
  996. (cache-dir "/var/cache/cat-avatar-generator")
  997. (package cat-avatar-generator)
  998. (configuration (nginx-server-configuration)))
  999. (simple-service
  1000. 'cat-http-server nginx-service-type
  1001. (list (nginx-server-configuration
  1002. (inherit configuration)
  1003. (locations
  1004. (cons
  1005. (let ((base (nginx-php-location)))
  1006. (nginx-location-configuration
  1007. (inherit base)
  1008. (body (list (string-append "fastcgi_param CACHE_DIR \""
  1009. cache-dir "\";")
  1010. (nginx-location-configuration-body base)))))
  1011. (nginx-server-configuration-locations configuration)))
  1012. (root #~(string-append #$package
  1013. "/share/web/cat-avatar-generator"))))))
  1014. (define-record-type* <hpcguix-web-configuration>
  1015. hpcguix-web-configuration make-hpcguix-web-configuration
  1016. hpcguix-web-configuration?
  1017. (package hpcguix-web-package (default hpcguix-web)) ;<package>
  1018. ;; Specs is gexp of hpcguix-web configuration file
  1019. (specs hpcguix-web-configuration-specs))
  1020. (define %hpcguix-web-accounts
  1021. (list (user-group
  1022. (name "hpcguix-web")
  1023. (system? #t))
  1024. (user-account
  1025. (name "hpcguix-web")
  1026. (group "hpcguix-web")
  1027. (system? #t)
  1028. (comment "hpcguix-web")
  1029. (home-directory "/var/empty")
  1030. (shell (file-append shadow "/sbin/nologin")))))
  1031. (define %hpcguix-web-activation
  1032. (with-imported-modules '((guix build utils))
  1033. #~(begin
  1034. (use-modules (guix build utils)
  1035. (ice-9 ftw))
  1036. (let ((home-dir "/var/cache/guix/web")
  1037. (user (getpwnam "hpcguix-web")))
  1038. (mkdir-p home-dir)
  1039. (chown home-dir (passwd:uid user) (passwd:gid user))
  1040. (chmod home-dir #o755)
  1041. ;; Remove stale 'packages.json.lock' file (and other lock files, if
  1042. ;; any) since that would prevent 'packages.json' from being updated.
  1043. (for-each (lambda (lock)
  1044. (delete-file (string-append home-dir "/" lock)))
  1045. (scandir home-dir
  1046. (lambda (file)
  1047. (string-suffix? ".lock" file))))))))
  1048. (define %hpcguix-web-log-file
  1049. "/var/log/hpcguix-web.log")
  1050. (define %hpcguix-web-log-rotations
  1051. (list (log-rotation
  1052. (files (list %hpcguix-web-log-file))
  1053. (frequency 'weekly))))
  1054. (define (hpcguix-web-shepherd-service config)
  1055. (let ((specs (hpcguix-web-configuration-specs config))
  1056. (hpcguix-web (hpcguix-web-package config)))
  1057. (with-imported-modules (source-module-closure
  1058. '((gnu build shepherd)))
  1059. (shepherd-service
  1060. (documentation "hpcguix-web daemon")
  1061. (provision '(hpcguix-web))
  1062. (requirement '(networking))
  1063. (start #~(make-forkexec-constructor
  1064. (list #$(file-append hpcguix-web "/bin/hpcguix-web")
  1065. (string-append "--config="
  1066. #$(scheme-file "hpcguix-web.scm" specs)))
  1067. #:user "hpcguix-web"
  1068. #:group "hpcguix-web"
  1069. #:environment-variables
  1070. (list "XDG_CACHE_HOME=/var/cache/guix/web"
  1071. "SSL_CERT_DIR=/etc/ssl/certs")
  1072. #:log-file #$%hpcguix-web-log-file))
  1073. (stop #~(make-kill-destructor))))))
  1074. (define hpcguix-web-service-type
  1075. (service-type
  1076. (name 'hpcguix-web)
  1077. (description "Run the hpcguix-web server.")
  1078. (extensions
  1079. (list (service-extension account-service-type
  1080. (const %hpcguix-web-accounts))
  1081. (service-extension activation-service-type
  1082. (const %hpcguix-web-activation))
  1083. (service-extension rottlog-service-type
  1084. (const %hpcguix-web-log-rotations))
  1085. (service-extension shepherd-root-service-type
  1086. (compose list hpcguix-web-shepherd-service))))))
  1087. ;;;
  1088. ;;; Tailon
  1089. ;;;
  1090. (define-record-type* <tailon-configuration-file>
  1091. tailon-configuration-file make-tailon-configuration-file
  1092. tailon-configuration-file?
  1093. (files tailon-configuration-file-files
  1094. (default '("/var/log")))
  1095. (bind tailon-configuration-file-bind
  1096. (default "localhost:8080"))
  1097. (relative-root tailon-configuration-file-relative-root
  1098. (default #f))
  1099. (allow-transfers? tailon-configuration-file-allow-transfers?
  1100. (default #t))
  1101. (follow-names? tailon-configuration-file-follow-names?
  1102. (default #t))
  1103. (tail-lines tailon-configuration-file-tail-lines
  1104. (default 200))
  1105. (allowed-commands tailon-configuration-file-allowed-commands
  1106. (default '("tail" "grep" "awk")))
  1107. (debug? tailon-configuration-file-debug?
  1108. (default #f))
  1109. (wrap-lines tailon-configuration-file-wrap-lines
  1110. (default #t))
  1111. (http-auth tailon-configuration-file-http-auth
  1112. (default #f))
  1113. (users tailon-configuration-file-users
  1114. (default #f)))
  1115. (define (tailon-configuration-files-string files)
  1116. (string-append
  1117. "\n"
  1118. (string-join
  1119. (map
  1120. (lambda (x)
  1121. (string-append
  1122. " - "
  1123. (cond
  1124. ((string? x)
  1125. (simple-format #f "'~A'" x))
  1126. ((list? x)
  1127. (string-join
  1128. (cons (simple-format #f "'~A':" (car x))
  1129. (map
  1130. (lambda (x) (simple-format #f " - '~A'" x))
  1131. (cdr x)))
  1132. "\n"))
  1133. (else (error x)))))
  1134. files)
  1135. "\n")))
  1136. (define-gexp-compiler (tailon-configuration-file-compiler
  1137. (file <tailon-configuration-file>) system target)
  1138. (match file
  1139. (($ <tailon-configuration-file> files bind relative-root
  1140. allow-transfers? follow-names?
  1141. tail-lines allowed-commands debug?
  1142. wrap-lines http-auth users)
  1143. (text-file
  1144. "tailon-config.yaml"
  1145. (string-concatenate
  1146. (filter-map
  1147. (match-lambda
  1148. ((key . #f) #f)
  1149. ((key . value) (string-append key ": " value "\n")))
  1150. `(("files" . ,(tailon-configuration-files-string files))
  1151. ("bind" . ,bind)
  1152. ("relative-root" . ,relative-root)
  1153. ("allow-transfers" . ,(if allow-transfers? "true" "false"))
  1154. ("follow-names" . ,(if follow-names? "true" "false"))
  1155. ("tail-lines" . ,(number->string tail-lines))
  1156. ("commands" . ,(string-append "["
  1157. (string-join allowed-commands ", ")
  1158. "]"))
  1159. ("debug" . ,(if debug? "true" #f))
  1160. ("wrap-lines" . ,(if wrap-lines "true" "false"))
  1161. ("http-auth" . ,http-auth)
  1162. ("users" . ,(if users
  1163. (string-concatenate
  1164. (cons "\n"
  1165. (map (match-lambda
  1166. ((user . pass)
  1167. (string-append
  1168. " " user ":" pass)))
  1169. users)))
  1170. #f)))))))))
  1171. (define-record-type* <tailon-configuration>
  1172. tailon-configuration make-tailon-configuration
  1173. tailon-configuration?
  1174. (config-file tailon-configuration-config-file
  1175. (default (tailon-configuration-file)))
  1176. (package tailon-configuration-package
  1177. (default tailon)))
  1178. (define tailon-shepherd-service
  1179. (match-lambda
  1180. (($ <tailon-configuration> config-file package)
  1181. (list (shepherd-service
  1182. (provision '(tailon))
  1183. (documentation "Run the tailon daemon.")
  1184. (start #~(make-forkexec-constructor
  1185. `(,(string-append #$package "/bin/tailon")
  1186. "-c" ,#$config-file)
  1187. #:user "tailon"
  1188. #:group "tailon"))
  1189. (stop #~(make-kill-destructor)))))))
  1190. (define %tailon-accounts
  1191. (list (user-group (name "tailon") (system? #t))
  1192. (user-account
  1193. (name "tailon")
  1194. (group "tailon")
  1195. (system? #t)
  1196. (comment "tailon")
  1197. (home-directory "/var/empty")
  1198. (shell (file-append shadow "/sbin/nologin")))))
  1199. (define tailon-service-type
  1200. (service-type
  1201. (name 'tailon)
  1202. (description
  1203. "Run Tailon, a Web application for monitoring, viewing, and searching log
  1204. files.")
  1205. (extensions
  1206. (list (service-extension shepherd-root-service-type
  1207. tailon-shepherd-service)
  1208. (service-extension account-service-type
  1209. (const %tailon-accounts))))
  1210. (compose concatenate)
  1211. (extend (lambda (parameter files)
  1212. (tailon-configuration
  1213. (inherit parameter)
  1214. (config-file
  1215. (let ((old-config-file
  1216. (tailon-configuration-config-file parameter)))
  1217. (tailon-configuration-file
  1218. (inherit old-config-file)
  1219. (files (append (tailon-configuration-file-files old-config-file)
  1220. files))))))))
  1221. (default-value (tailon-configuration))))
  1222. ;;;
  1223. ;;; Varnish
  1224. ;;;
  1225. (define-record-type* <varnish-configuration>
  1226. varnish-configuration make-varnish-configuration
  1227. varnish-configuration?
  1228. (package varnish-configuration-package ;<package>
  1229. (default varnish))
  1230. (name varnish-configuration-name ;string
  1231. (default "default"))
  1232. (backend varnish-configuration-backend ;string
  1233. (default "localhost:8080"))
  1234. (vcl varnish-configuration-vcl ;#f | <file-like>
  1235. (default #f))
  1236. (listen varnish-configuration-listen ;list of strings
  1237. (default '("localhost:80")))
  1238. (storage varnish-configuration-storage ;list of strings
  1239. (default '("malloc,128m")))
  1240. (parameters varnish-configuration-parameters ;list of string pairs
  1241. (default '()))
  1242. (extra-options varnish-configuration-extra-options ;list of strings
  1243. (default '())))
  1244. (define %varnish-accounts
  1245. (list (user-group
  1246. (name "varnish")
  1247. (system? #t))
  1248. (user-account
  1249. (name "varnish")
  1250. (group "varnish")
  1251. (system? #t)
  1252. (comment "Varnish Cache User")
  1253. (home-directory "/var/varnish")
  1254. (shell (file-append shadow "/sbin/nologin")))))
  1255. (define varnish-shepherd-service
  1256. (match-lambda
  1257. (($ <varnish-configuration> package name backend vcl listen storage
  1258. parameters extra-options)
  1259. (list (shepherd-service
  1260. (provision (list (symbol-append 'varnish- (string->symbol name))))
  1261. (documentation (string-append "The Varnish Web Accelerator"
  1262. " (" name ")"))
  1263. (requirement '(networking))
  1264. (start #~(make-forkexec-constructor
  1265. (list #$(file-append package "/sbin/varnishd")
  1266. "-n" #$name
  1267. #$@(if vcl
  1268. #~("-f" #$vcl)
  1269. #~("-b" #$backend))
  1270. #$@(append-map (lambda (a) (list "-a" a)) listen)
  1271. #$@(append-map (lambda (s) (list "-s" s)) storage)
  1272. #$@(append-map (lambda (p)
  1273. (list "-p" (format #f "~a=~a"
  1274. (car p) (cdr p))))
  1275. parameters)
  1276. #$@extra-options)
  1277. ;; Varnish will drop privileges to the "varnish" user when
  1278. ;; it exists. Not passing #:user here allows the service
  1279. ;; to bind to ports < 1024.
  1280. #:pid-file (if (string-prefix? "/" #$name)
  1281. (string-append #$name "/_.pid")
  1282. (string-append "/var/varnish/" #$name "/_.pid"))))
  1283. (stop #~(make-kill-destructor)))))))
  1284. (define varnish-service-type
  1285. (service-type
  1286. (name 'varnish)
  1287. (description "Run the Varnish cache server.")
  1288. (extensions
  1289. (list (service-extension account-service-type
  1290. (const %varnish-accounts))
  1291. (service-extension shepherd-root-service-type
  1292. varnish-shepherd-service)))
  1293. (default-value
  1294. (varnish-configuration))))
  1295. ;;;
  1296. ;;; Patchwork
  1297. ;;;
  1298. (define-record-type* <patchwork-database-configuration>
  1299. patchwork-database-configuration make-patchwork-database-configuration
  1300. patchwork-database-configuration?
  1301. (engine patchwork-database-configuration-engine
  1302. (default "django.db.backends.postgresql_psycopg2"))
  1303. (name patchwork-database-configuration-name
  1304. (default "patchwork"))
  1305. (user patchwork-database-configuration-user
  1306. (default "httpd"))
  1307. (password patchwork-database-configuration-password
  1308. (default ""))
  1309. (host patchwork-database-configuration-host
  1310. (default ""))
  1311. (port patchwork-database-configuration-port
  1312. (default "")))
  1313. (define-record-type* <patchwork-settings-module>
  1314. patchwork-settings-module make-patchwork-settings-module
  1315. patchwork-settings-module?
  1316. (database-configuration patchwork-settings-module-database-configuration
  1317. (default (patchwork-database-configuration)))
  1318. (secret-key-file patchwork-settings-module-secret-key-file
  1319. (default "/etc/patchwork/django-secret-key"))
  1320. (allowed-hosts patchwork-settings-module-allowed-hosts)
  1321. (default-from-email patchwork-settings-module-default-from-email)
  1322. (static-url patchwork-settings-module-static-url
  1323. (default "/static/"))
  1324. (admins patchwork-settings-module-admins
  1325. (default '()))
  1326. (debug? patchwork-settings-module-debug?
  1327. (default #f))
  1328. (enable-rest-api? patchwork-settings-module-enable-rest-api?
  1329. (default #t))
  1330. (enable-xmlrpc? patchwork-settings-module-enable-xmlrpc?
  1331. (default #t))
  1332. (force-https-links? patchwork-settings-module-force-https-links?
  1333. (default #t))
  1334. (extra-settings patchwork-settings-module-extra-settings
  1335. (default "")))
  1336. (define-record-type* <patchwork-configuration>
  1337. patchwork-configuration make-patchwork-configuration
  1338. patchwork-configuration?
  1339. (patchwork patchwork-configuration-patchwork
  1340. (default patchwork))
  1341. (domain patchwork-configuration-domain)
  1342. (settings-module patchwork-configuration-settings-module)
  1343. (static-path patchwork-configuration-static-url
  1344. (default "/static/"))
  1345. (getmail-retriever-config getmail-retriever-config))
  1346. ;; Django uses a Python module for configuration, so this compiler generates a
  1347. ;; Python module from the configuration record.
  1348. (define-gexp-compiler (patchwork-settings-module-compiler
  1349. (file <patchwork-settings-module>) system target)
  1350. (match file
  1351. (($ <patchwork-settings-module> database-configuration secret-key-file
  1352. allowed-hosts default-from-email
  1353. static-url admins debug? enable-rest-api?
  1354. enable-xmlrpc? force-https-links?
  1355. extra-configuration)
  1356. (gexp->derivation
  1357. "patchwork-settings"
  1358. (with-imported-modules '((guix build utils))
  1359. #~(let ((output #$output))
  1360. (define (create-__init__.py filename)
  1361. (call-with-output-file filename
  1362. (lambda (port) (display "" port))))
  1363. (use-modules (guix build utils)
  1364. (srfi srfi-1))
  1365. (mkdir-p (string-append output "/guix/patchwork"))
  1366. (create-__init__.py
  1367. (string-append output "/guix/__init__.py"))
  1368. (create-__init__.py
  1369. (string-append output "/guix/patchwork/__init__.py"))
  1370. (call-with-output-file
  1371. (string-append output "/guix/patchwork/settings.py")
  1372. (lambda (port)
  1373. (display
  1374. (string-append "from patchwork.settings.base import *
  1375. # Configuration from Guix
  1376. with open('" #$secret-key-file "') as f:
  1377. SECRET_KEY = f.read().strip()
  1378. ALLOWED_HOSTS = [
  1379. " #$(string-concatenate
  1380. (map (lambda (allowed-host)
  1381. (string-append " '" allowed-host "'\n"))
  1382. allowed-hosts))
  1383. "]
  1384. DEFAULT_FROM_EMAIL = '" #$default-from-email "'
  1385. SERVER_EMAIL = DEFAULT_FROM_EMAIL
  1386. NOTIFICATION_FROM_EMAIL = DEFAULT_FROM_EMAIL
  1387. ADMINS = [
  1388. " #$(string-concatenate
  1389. (map (match-lambda
  1390. ((name email-address)
  1391. (string-append
  1392. "('" name "','" email-address "'),")))
  1393. admins))
  1394. "]
  1395. DEBUG = " #$(if debug? "True" "False") "
  1396. ENABLE_REST_API = " #$(if enable-rest-api? "True" "False") "
  1397. ENABLE_XMLRPC = " #$(if enable-xmlrpc? "True" "False") "
  1398. FORCE_HTTPS_LINKS = " #$(if force-https-links? "True" "False") "
  1399. DATABASES = {
  1400. 'default': {
  1401. " #$(match database-configuration
  1402. (($ <patchwork-database-configuration>
  1403. engine name user password host port)
  1404. (string-append
  1405. " 'ENGINE': '" engine "',\n"
  1406. " 'NAME': '" name "',\n"
  1407. " 'USER': '" user "',\n"
  1408. " 'PASSWORD': '" password "',\n"
  1409. " 'HOST': '" host "',\n"
  1410. " 'PORT': '" port "',\n"))) "
  1411. },
  1412. }
  1413. " #$(if debug?
  1414. #~(string-append "STATIC_ROOT = '"
  1415. #$(file-append patchwork "/share/patchwork/htdocs")
  1416. "'")
  1417. #~(string-append "STATIC_URL = '" #$static-url "'")) "
  1418. STATICFILES_STORAGE = (
  1419. 'django.contrib.staticfiles.storage.StaticFilesStorage'
  1420. )
  1421. # Guix Extra Configuration
  1422. " #$extra-configuration "
  1423. ") port)))
  1424. #t))
  1425. #:local-build? #t))))
  1426. (define patchwork-virtualhost
  1427. (match-lambda
  1428. (($ <patchwork-configuration> patchwork domain
  1429. settings-module static-path
  1430. getmail-retriever-config)
  1431. (define wsgi.py
  1432. (file-append patchwork
  1433. (string-append
  1434. "/lib/python"
  1435. (version-major+minor
  1436. (package-version python))
  1437. "/site-packages/patchwork/wsgi.py")))
  1438. (httpd-virtualhost
  1439. "*:8080"
  1440. `("ServerAdmin admin@example.com`
  1441. ServerName " ,domain "
  1442. LogFormat \"%v %h %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" customformat
  1443. LogLevel info
  1444. CustomLog \"/var/log/httpd/" ,domain "-access_log\" customformat
  1445. ErrorLog /var/log/httpd/error.log
  1446. WSGIScriptAlias / " ,wsgi.py "
  1447. WSGIDaemonProcess " ,(package-name patchwork) " user=httpd group=httpd processes=1 threads=2 display-name=%{GROUP} lang='en_US.UTF-8' locale='en_US.UTF-8' python-path=" ,settings-module "
  1448. WSGIProcessGroup " ,(package-name patchwork) "
  1449. WSGIPassAuthorization On
  1450. <Files " ,wsgi.py ">
  1451. Require all granted
  1452. </Files>
  1453. " ,@(if static-path
  1454. `("Alias " ,static-path " " ,patchwork "/share/patchwork/htdocs/")
  1455. '())
  1456. "
  1457. <Directory \"/srv/http/" ,domain "/\">
  1458. AllowOverride None
  1459. Options MultiViews Indexes SymlinksIfOwnerMatch IncludesNoExec
  1460. Require method GET POST OPTIONS
  1461. </Directory>")))))
  1462. (define (patchwork-httpd-configuration patchwork-configuration)
  1463. (list "WSGISocketPrefix /var/run/mod_wsgi"
  1464. (list "LoadModule wsgi_module "
  1465. (file-append mod-wsgi "/modules/mod_wsgi.so"))
  1466. (patchwork-virtualhost patchwork-configuration)))
  1467. (define (patchwork-django-admin-gexp patchwork settings-module)
  1468. #~(lambda command
  1469. (let ((pid (primitive-fork))
  1470. (user (getpwnam "httpd")))
  1471. (if (eq? pid 0)
  1472. (dynamic-wind
  1473. (const #t)
  1474. (lambda ()
  1475. (setgid (passwd:gid user))
  1476. (setuid (passwd:uid user))
  1477. (setenv "DJANGO_SETTINGS_MODULE" "guix.patchwork.settings")
  1478. (setenv "PYTHONPATH" #$settings-module)
  1479. (primitive-exit
  1480. (if (zero?
  1481. (apply system*
  1482. #$(file-append patchwork "/bin/patchwork-admin")
  1483. command))
  1484. 0
  1485. 1)))
  1486. (lambda ()
  1487. (primitive-exit 1)))
  1488. (zero? (cdr (waitpid pid)))))))
  1489. (define (patchwork-django-admin-action patchwork settings-module)
  1490. (shepherd-action
  1491. (name 'django-admin)
  1492. (documentation
  1493. "Run a django admin command for patchwork")
  1494. (procedure (patchwork-django-admin-gexp patchwork settings-module))))
  1495. (define patchwork-shepherd-services
  1496. (match-lambda
  1497. (($ <patchwork-configuration> patchwork domain
  1498. settings-module static-path
  1499. getmail-retriever-config)
  1500. (define secret-key-file-creation-gexp
  1501. (if (patchwork-settings-module? settings-module)
  1502. (with-extensions (list guile-gcrypt)
  1503. #~(let ((secret-key-file
  1504. #$(patchwork-settings-module-secret-key-file
  1505. settings-module)))
  1506. (use-modules (guix build utils)
  1507. (gcrypt random))
  1508. (unless (file-exists? secret-key-file)
  1509. (mkdir-p (dirname secret-key-file))
  1510. (call-with-output-file secret-key-file
  1511. (lambda (port)
  1512. (display (random-token 30 'very-strong) port)))
  1513. (let* ((pw (getpwnam "httpd"))
  1514. (uid (passwd:uid pw))
  1515. (gid (passwd:gid pw)))
  1516. (chown secret-key-file uid gid)
  1517. (chmod secret-key-file #o400)))))
  1518. #~()))
  1519. (list (shepherd-service
  1520. (requirement '(postgres))
  1521. (provision (list (string->symbol
  1522. (string-append (package-name patchwork)
  1523. "-setup"))))
  1524. (start
  1525. #~(lambda ()
  1526. (define run-django-admin-command
  1527. #$(patchwork-django-admin-gexp patchwork
  1528. settings-module))
  1529. #$secret-key-file-creation-gexp
  1530. (run-django-admin-command "migrate")))
  1531. (stop #~(const #f))
  1532. (actions
  1533. (list (patchwork-django-admin-action patchwork
  1534. settings-module)))
  1535. (respawn? #f)
  1536. (documentation "Setup Patchwork."))))))
  1537. (define patchwork-getmail-configs
  1538. (match-lambda
  1539. (($ <patchwork-configuration> patchwork domain
  1540. settings-module static-path
  1541. getmail-retriever-config)
  1542. (list
  1543. (getmail-configuration
  1544. (name (string->symbol (package-name patchwork)))
  1545. (user "httpd")
  1546. (directory (string-append
  1547. "/var/lib/getmail/" (package-name patchwork)))
  1548. (rcfile
  1549. (getmail-configuration-file
  1550. (retriever getmail-retriever-config)
  1551. (destination
  1552. (getmail-destination-configuration
  1553. (type "MDA_external")
  1554. (path (file-append patchwork "/bin/patchwork-admin"))
  1555. (extra-parameters
  1556. '((arguments . ("parsemail"))))))
  1557. (options
  1558. (getmail-options-configuration
  1559. (read-all #f)
  1560. (delivered-to #f)
  1561. (received #f)))))
  1562. (idle (assq-ref
  1563. (getmail-retriever-configuration-extra-parameters
  1564. getmail-retriever-config)
  1565. 'mailboxes))
  1566. (environment-variables
  1567. (list "DJANGO_SETTINGS_MODULE=guix.patchwork.settings"
  1568. #~(string-append "PYTHONPATH=" #$settings-module))))))))
  1569. (define patchwork-service-type
  1570. (service-type
  1571. (name 'patchwork-setup)
  1572. (extensions
  1573. (list (service-extension httpd-service-type
  1574. patchwork-httpd-configuration)
  1575. (service-extension shepherd-root-service-type
  1576. patchwork-shepherd-services)
  1577. (service-extension getmail-service-type
  1578. patchwork-getmail-configs)))
  1579. (description
  1580. "Patchwork patch tracking system.")))
  1581. ;;;
  1582. ;;; Mumi.
  1583. ;;;
  1584. (define-record-type* <mumi-configuration>
  1585. mumi-configuration make-mumi-configuration
  1586. mumi-configuration?
  1587. (mumi mumi-configuration-mumi (default mumi))
  1588. (mailer? mumi-configuration-mailer? (default #t))
  1589. (sender mumi-configuration-sender (default #f))
  1590. (smtp mumi-configuration-smtp (default #f)))
  1591. (define %mumi-activation
  1592. (with-imported-modules '((guix build utils))
  1593. #~(begin
  1594. (use-modules (guix build utils))
  1595. (mkdir-p "/var/mumi/db")
  1596. (mkdir-p "/var/mumi/mails")
  1597. (let* ((pw (getpwnam "mumi"))
  1598. (uid (passwd:uid pw))
  1599. (gid (passwd:gid pw)))
  1600. (chown "/var/mumi" uid gid)
  1601. (chown "/var/mumi/mails" uid gid)
  1602. (chown "/var/mumi/db" uid gid)))))
  1603. (define %mumi-accounts
  1604. (list (user-group (name "mumi") (system? #t))
  1605. (user-account
  1606. (name "mumi")
  1607. (group "mumi")
  1608. (system? #t)
  1609. (comment "Mumi web server")
  1610. (home-directory "/var/empty")
  1611. (shell (file-append shadow "/sbin/nologin")))))
  1612. (define (mumi-shepherd-services config)
  1613. (define environment
  1614. #~(list "LC_ALL=en_US.utf8"
  1615. (string-append "GUIX_LOCPATH=" #$glibc-utf8-locales
  1616. "/lib/locale")))
  1617. (match config
  1618. (($ <mumi-configuration> mumi mailer? sender smtp)
  1619. (list (shepherd-service
  1620. (provision '(mumi))
  1621. (documentation "Mumi bug-tracking web interface.")
  1622. (requirement '(networking))
  1623. (start #~(make-forkexec-constructor
  1624. `(#$(file-append mumi "/bin/mumi") "web"
  1625. ,@(if #$mailer? '() '("--disable-mailer")))
  1626. #:environment-variables #$environment
  1627. #:user "mumi" #:group "mumi"
  1628. #:log-file "/var/log/mumi.log"))
  1629. (stop #~(make-kill-destructor)))
  1630. (shepherd-service
  1631. (provision '(mumi-worker))
  1632. (documentation "Mumi bug-tracking web interface database worker.")
  1633. (requirement '(networking))
  1634. (start #~(make-forkexec-constructor
  1635. '(#$(file-append mumi "/bin/mumi") "worker")
  1636. #:environment-variables #$environment
  1637. #:user "mumi" #:group "mumi"
  1638. #:log-file "/var/log/mumi.worker.log"))
  1639. (stop #~(make-kill-destructor)))
  1640. (shepherd-service
  1641. (provision '(mumi-mailer))
  1642. (documentation "Mumi bug-tracking web interface mailer.")
  1643. (requirement '(networking))
  1644. (start #~(make-forkexec-constructor
  1645. `(#$(file-append mumi "/bin/mumi") "mailer"
  1646. ,@(if #$sender
  1647. (list (string-append "--sender=" #$sender))
  1648. '())
  1649. ,@(if #$smtp
  1650. (list (string-append "--smtp=" #$smtp))
  1651. '()))
  1652. #:environment-variables #$environment
  1653. #:user "mumi" #:group "mumi"
  1654. #:log-file "/var/log/mumi.mailer.log"))
  1655. (stop #~(make-kill-destructor)))))))
  1656. (define mumi-service-type
  1657. (service-type
  1658. (name 'mumi)
  1659. (extensions
  1660. (list (service-extension activation-service-type
  1661. (const %mumi-activation))
  1662. (service-extension account-service-type
  1663. (const %mumi-accounts))
  1664. (service-extension shepherd-root-service-type
  1665. mumi-shepherd-services)))
  1666. (description
  1667. "Run Mumi, a Web interface to the Debbugs bug-tracking server.")
  1668. (default-value
  1669. (mumi-configuration))))
  1670. (define %default-gmnisrv-config-file
  1671. (plain-file "gmnisrv.ini" "
  1672. listen=0.0.0.0:1965 [::]:1965
  1673. [:tls]
  1674. store=/var/lib/gemini/certs
  1675. organization=gmnisrv on Guix user
  1676. [localhost]
  1677. root=/srv/gemini
  1678. "))
  1679. (define-record-type* <gmnisrv-configuration>
  1680. gmnisrv-configuration make-gmnisrv-configuration
  1681. gmnisrv-configuration?
  1682. (package gmnisrv-configuration-package
  1683. (default gmnisrv))
  1684. (config-file gmnisrv-configuration-config-file
  1685. (default %default-gmnisrv-config-file)))
  1686. (define gmnisrv-shepherd-service
  1687. (match-lambda
  1688. (($ <gmnisrv-configuration> package config-file)
  1689. (list (shepherd-service
  1690. (provision '(gmnisrv))
  1691. (requirement '(networking))
  1692. (documentation "Run the gmnisrv Gemini server.")
  1693. (start (let ((gmnisrv (file-append package "/bin/gmnisrv")))
  1694. #~(make-forkexec-constructor
  1695. (list #$gmnisrv "-C" #$config-file)
  1696. #:user "gmnisrv" #:group "gmnisrv"
  1697. #:log-file "/var/log/gmnisrv.log")))
  1698. (stop #~(make-kill-destructor)))))))
  1699. (define %gmnisrv-accounts
  1700. (list (user-group (name "gmnisrv") (system? #t))
  1701. (user-account
  1702. (name "gmnisrv")
  1703. (group "gmnisrv")
  1704. (system? #t)
  1705. (comment "gmnisrv Gemini server")
  1706. (home-directory "/var/empty")
  1707. (shell (file-append shadow "/sbin/nologin")))))
  1708. (define %gmnisrv-activation
  1709. (with-imported-modules '((guix build utils))
  1710. #~(begin
  1711. (use-modules (guix build utils))
  1712. (mkdir-p "/var/lib/gemini/certs")
  1713. (let* ((pw (getpwnam "gmnisrv"))
  1714. (uid (passwd:uid pw))
  1715. (gid (passwd:gid pw)))
  1716. (chown "/var/lib/gemini" uid gid)
  1717. (chown "/var/lib/gemini/certs" uid gid)))))
  1718. (define gmnisrv-service-type
  1719. (service-type
  1720. (name 'guix)
  1721. (extensions
  1722. (list (service-extension activation-service-type
  1723. (const %gmnisrv-activation))
  1724. (service-extension account-service-type
  1725. (const %gmnisrv-accounts))
  1726. (service-extension shepherd-root-service-type
  1727. gmnisrv-shepherd-service)))
  1728. (description
  1729. "Run the gmnisrv Gemini server.")
  1730. (default-value
  1731. (gmnisrv-configuration))))
  1732. (define-record-type* <agate-configuration>
  1733. agate-configuration make-agate-configuration
  1734. agate-configuration?
  1735. (package agate-configuration-package
  1736. (default agate))
  1737. (content agate-configuration-content
  1738. (default "/srv/gemini"))
  1739. (cert agate-configuration-cert
  1740. (default #f))
  1741. (key agate-configuration-key
  1742. (default #f))
  1743. (addr agate-configuration-addr
  1744. (default '("0.0.0.0:1965" "[::]:1965")))
  1745. (hostname agate-configuration-hostname
  1746. (default #f))
  1747. (lang agate-configuration-lang
  1748. (default #f))
  1749. (silent? agate-configuration-silent
  1750. (default #f))
  1751. (serve-secret? agate-configuration-serve-secret
  1752. (default #f))
  1753. (log-ip? agate-configuration-log-ip
  1754. (default #t))
  1755. (user agate-configuration-user
  1756. (default "agate"))
  1757. (group agate-configuration-group
  1758. (default "agate"))
  1759. (log-file agate-configuration-log
  1760. (default "/var/log/agate.log")))
  1761. (define agate-shepherd-service
  1762. (match-lambda
  1763. (($ <agate-configuration> package content cert key addr
  1764. hostname lang silent? serve-secret?
  1765. log-ip? user group log-file)
  1766. (list (shepherd-service
  1767. (provision '(agate))
  1768. (requirement '(networking))
  1769. (documentation "Run the agate Gemini server.")
  1770. (start (let ((agate (file-append package "/bin/agate")))
  1771. #~(make-forkexec-constructor
  1772. (list #$agate
  1773. "--content" #$content
  1774. "--cert" #$cert
  1775. "--key" #$key
  1776. "--addr" #$@addr
  1777. #$@(if lang
  1778. (list "--lang" lang)
  1779. '())
  1780. #$@(if hostname
  1781. (list "--hostname" hostname)
  1782. '())
  1783. #$@(if silent? '("--silent") '())
  1784. #$@(if serve-secret? '("--serve-secret") '())
  1785. #$@(if log-ip? '("--log-ip") '()))
  1786. #:user #$user #:group #$group
  1787. #:log-file #$log-file)))
  1788. (stop #~(make-kill-destructor)))))))
  1789. (define agate-accounts
  1790. (match-lambda
  1791. (($ <agate-configuration> _ _ _ _ _
  1792. _ _ _ _
  1793. _ user group _)
  1794. `(,@(if (equal? group "agate")
  1795. '()
  1796. (list (user-group (name "agate") (system? #t))))
  1797. ,(user-group
  1798. (name group)
  1799. (system? #t))
  1800. ,(user-account
  1801. (name user)
  1802. (group group)
  1803. (supplementary-groups '("agate"))
  1804. (system? #t)
  1805. (comment "agate server user")
  1806. (home-directory "/var/empty")
  1807. (shell (file-append shadow "/sbin/nologin")))))))
  1808. (define agate-service-type
  1809. (service-type
  1810. (name 'guix)
  1811. (extensions
  1812. (list (service-extension account-service-type
  1813. agate-accounts)
  1814. (service-extension shepherd-root-service-type
  1815. agate-shepherd-service)))
  1816. (default-value (agate-configuration))))