unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: David Thompson <dthompson2@worcester.edu>
To: guix-devel@gnu.org
Subject: [PATCH] services: nginx: Allow for server extensions.
Date: Tue, 01 Dec 2015 09:07:35 -0500	[thread overview]
Message-ID: <874mg2tg7s.fsf@izanagi.i-did-not-set--mail-host-address--so-tickle-me> (raw)

[-- Attachment #1: Type: text/plain, Size: 1020 bytes --]

Hey folks,

Looking for some feedback on my first stab at making the nginx service
extensible.  With this extension mechanism, future web applications
(such as GNU MediaGoblin) that use nginx as a front-end web server will
be able to extend nginx with the server configuration that they need in
order to work.

Here's a useless service that adds nginx configuration to serve the
contents of /tmp:

    (define server
      (plain-file "foo.conf"
                  "
    server {
      listen 80;
      root /tmp;
      index index.html;
      server_name dthompson.us;
    }
    "))

    (define foo-service-type
      (service-type (name 'foo)
                    (extensions
                     (list (service-extension nginx-service-type
                                              (const (list server)))))))

    (define foo-service
      (service foo-service-type #f))

One big question I have is whether I should enforce that configuration
be in file-like objects or if I should allow strings, too.  Thoughts?


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-services-nginx-Allow-for-server-extensions.patch --]
[-- Type: text/x-patch, Size: 7190 bytes --]

From 108db2d183526c42b53060e55f7fb292b53663cb Mon Sep 17 00:00:00 2001
From: David Thompson <dthompson2@worcester.edu>
Date: Mon, 30 Nov 2015 08:49:08 -0500
Subject: [PATCH] services: nginx: Allow for server extensions.

* gnu/services/web.scm (<nginx-configuration>)[servers]: New field.
  (nginx-configuration-servers): New accessor.
  (default-nginx-config): Delete.
  (nginx-configuration-file*): New procedure.
  (nginx-activation): Perform the syntax check on the full computed
  configuration file.
  (nginx-dmd-service): Use the full computed configuration file when
  starting the service.
  (extend-nginx): New procedure.
  (nginx-service-type): Specify extension procedures.
  (nginx-service): Add #:servers argument.
---
 gnu/services/web.scm | 97 ++++++++++++++++++++++++++++++++--------------------
 1 file changed, 60 insertions(+), 37 deletions(-)

diff --git a/gnu/services/web.scm b/gnu/services/web.scm
index 84bb30d..a5bc364 100644
--- a/gnu/services/web.scm
+++ b/gnu/services/web.scm
@@ -26,7 +26,16 @@
   #:use-module (guix records)
   #:use-module (guix gexp)
   #:use-module (ice-9 match)
-  #:export (nginx-service))
+  #:use-module (srfi srfi-1)
+  #:export (nginx-configuration
+            nginx-configuration?
+            nginx-configuration-log-directory
+            nginx-configuration-run-directory
+            nginx-configuration-file
+            nginx-configuration-servers
+
+            nginx-service-type
+            nginx-service))
 
 ;;; Commentary:
 ;;;
@@ -37,23 +46,26 @@
 (define-record-type* <nginx-configuration>
   nginx-configuration make-nginx-configuration
   nginx-configuration?
-  (nginx         nginx-configuration-nginx)         ;<package>
-  (log-directory nginx-configuration-log-directory) ;string
-  (run-directory nginx-configuration-run-directory) ;string
-  (file          nginx-configuration-file))         ;string | file-like
+  (nginx         nginx-configuration-nginx)         ; <package>
+  (log-directory nginx-configuration-log-directory) ; string
+  (run-directory nginx-configuration-run-directory) ; string
+  (file          nginx-configuration-file)          ; file-like
+  (servers       nginx-configuration-servers))      ; list of file-like
 
-(define (default-nginx-config log-directory run-directory)
-  (plain-file "nginx.conf"
-              (string-append
-               "user nginx nginx;\n"
-               "pid " run-directory "/pid;\n"
-               "error_log " log-directory "/error.log info;\n"
-               "http {\n"
-               "    access_log " log-directory "/access.log;\n"
-               "    root /var/www;\n"
-               "    server {}\n"
-               "}\n"
-               "events {}\n")))
+(define (nginx-configuration-file* config)
+  (match config
+    (($ <nginx-configuration> _ log run file servers)
+     (apply mixed-text-file "nginx.conf"
+            `("user nginx nginx;\n"
+              "pid " ,run "/pid;\n"
+              "error_log " ,log "/error.log info;\n"
+              "include " ,file ";\n"
+              "http {\n"
+              "  access_log " ,log "/access.log;\n"
+              ,@(append-map (lambda (server-config)
+                              (list "include " server-config ";\n"))
+                            servers)
+              "}\n")))))
 
 (define %nginx-accounts
   (list (user-group (name "nginx") (system? #t))
@@ -66,37 +78,43 @@
          (shell #~(string-append #$shadow "/sbin/nologin")))))
 
 (define nginx-activation
-  (match-lambda
-    (($ <nginx-configuration> nginx log-directory run-directory config-file)
-     #~(begin
-         (use-modules (guix build utils))
+  (lambda (config)
+    (match config
+      (($ <nginx-configuration> nginx log-directory run-directory _)
+       #~(begin
+           (use-modules (guix build utils))
 
-         (format #t "creating nginx log directory '~a'~%" #$log-directory)
-         (mkdir-p #$log-directory)
-         (format #t "creating nginx run directory '~a'~%" #$run-directory)
-         (mkdir-p #$run-directory)
-         ;; Check configuration file syntax.
-         (system* (string-append #$nginx "/bin/nginx")
-                  "-c" #$config-file "-t")))))
+           (format #t "creating nginx log directory '~a'~%" #$log-directory)
+           (mkdir-p #$log-directory)
+           (format #t "creating nginx run directory '~a'~%" #$run-directory)
+           (mkdir-p #$run-directory)
+           ;; Check configuration file syntax.
+           (system* (string-append #$nginx "/sbin/nginx")
+                    "-c" #$(nginx-configuration-file* config) "-t"))))))
 
-(define nginx-dmd-service
-  (match-lambda
-    (($ <nginx-configuration> nginx log-directory run-directory config-file)
+(define (nginx-dmd-service config)
+  (match config
+    (($ <nginx-configuration> nginx log run file servers)
      (let* ((nginx-binary #~(string-append #$nginx "/sbin/nginx"))
+            (config-file (nginx-configuration-file* config))
             (nginx-action
              (lambda args
                #~(lambda _
                    (zero?
                     (system* #$nginx-binary "-c" #$config-file #$@args))))))
 
-       ;; TODO: Add 'reload' action.
        (list (dmd-service
               (provision '(nginx))
               (documentation "Run the nginx daemon.")
               (requirement '(user-processes loopback))
-              (start (nginx-action "-p" run-directory))
+              (start (nginx-action "-p" run))
               (stop (nginx-action "-s" "stop"))))))))
 
+(define (extend-nginx config servers)
+  (nginx-configuration
+   (inherit config)
+   (servers (append (nginx-configuration-servers config) servers))))
+
 (define nginx-service-type
   (service-type (name 'nginx)
                 (extensions
@@ -105,13 +123,17 @@
                        (service-extension activation-service-type
                                           nginx-activation)
                        (service-extension account-service-type
-                                          (const %nginx-accounts))))))
+                                          (const %nginx-accounts))))
+                (compose concatenate)
+                (extend extend-nginx)))
 
 (define* (nginx-service #:key (nginx nginx)
                         (log-directory "/var/log/nginx")
                         (run-directory "/var/run/nginx")
-                        (config-file
-                         (default-nginx-config log-directory run-directory)))
+                        ;; Nginx requires an 'events' block.
+                        (config-file (plain-file "nginx-main.conf"
+                                                 "events {}"))
+                        (servers '()))
   "Return a service that runs NGINX, the nginx web server.
 
 The nginx daemon loads its runtime configuration from CONFIG-FIGLE, stores log
@@ -121,4 +143,5 @@ files in LOG-DIRECTORY, and stores temporary runtime files in RUN-DIRECTORY."
             (nginx nginx)
             (log-directory log-directory)
             (run-directory run-directory)
-            (file config-file))))
+            (file config-file)
+            (servers servers))))
-- 
2.5.0


[-- Attachment #3: Type: text/plain, Size: 37 bytes --]


--
David Thompson
GPG Key: 0FF1D807

             reply	other threads:[~2015-12-01 14:07 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-01 14:07 David Thompson [this message]
2015-12-02  8:07 ` [PATCH] services: nginx: Allow for server extensions Ludovic Courtès
2015-12-07 19:57   ` Leo Famulari
2015-12-07 23:06     ` Ludovic Courtès
2016-02-28 16:31   ` Ludovic Courtès

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=874mg2tg7s.fsf@izanagi.i-did-not-set--mail-host-address--so-tickle-me \
    --to=dthompson2@worcester.edu \
    --cc=guix-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).