Hi Guix, these patches add Lua support to NGINX. Oleg Pykhalov (8): gnu: Add lua-resty-core. gnu: Add lua-resty-lrucache. gnu: Add lua-resty-signal. gnu: Add lua-tablepool. gnu: Add lua-resty-shell. gnu: Add nginx-socket-cloexec. gnu: Add nginx-lua-module. services: nginx: Add lua module. doc/guix-cookbook.texi | 58 ++++++ doc/guix.texi | 24 ++- gnu/local.mk | 1 + gnu/packages/lua.scm | 179 +++++++++++++++++ .../patches/nginx-socket-cloexec.patch | 185 ++++++++++++++++++ gnu/packages/web.scm | 73 +++++++ gnu/services/web.scm | 25 ++- 7 files changed, 539 insertions(+), 6 deletions(-) create mode 100644 gnu/packages/patches/nginx-socket-cloexec.patch -- 2.28.0
* gnu/packages/lua.scm (lua-resty-core): New variable. --- gnu/packages/lua.scm | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/gnu/packages/lua.scm b/gnu/packages/lua.scm index 5479b891bd..774df85170 100644 --- a/gnu/packages/lua.scm +++ b/gnu/packages/lua.scm @@ -880,3 +880,40 @@ on numbers.") "Selene is a simple C++11 header-only library enabling seamless interoperability between C++ and Lua programming language.") (license license:zlib))) + +(define-public lua-resty-core + (package + (name "lua-resty-core") + (version "0.1.17") + (source (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/openresty/lua-resty-core") + (commit (string-append "v" version)))) + (file-name (git-file-name name version)) + (sha256 + (base32 + "11fyli6yrg7b91nv9v2sbrc6y7z3h9lgf4lrrhcjk2bb906576a0")))) + (build-system trivial-build-system) + (arguments + `(#:modules ((guix build utils)) + #:builder + (begin + (use-modules (guix build utils)) + (let* ((luajit-major+minor ,(version-major+minor (package-version lua))) + (package-lua-resty (lambda (input output) + (mkdir-p (string-append output "/lib/lua")) + (copy-recursively (string-append input "/lib/resty") + (string-append output "/lib/lua/resty")) + (copy-recursively (string-append input "/lib/ngx") + (string-append output "/lib/ngx")) + (symlink (string-append output "/lib/lua/resty") + (string-append output "/lib/resty"))))) + (package-lua-resty (assoc-ref %build-inputs "source") + (assoc-ref %outputs "out"))) + #t))) + (home-page "https://github.com/openresty/lua-resty-core") + (synopsis "Lua API for NGINX") + (description "This package provides a FFI-based Lua API for +@code{ngx_http_lua_module} or @code{ngx_stream_lua_module}.") + (license license:bsd-2))) -- 2.28.0
* gnu/packages/lua.scm (lua-resty-lrucache): New variable. --- gnu/packages/lua.scm | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/gnu/packages/lua.scm b/gnu/packages/lua.scm index 774df85170..59d449dfe5 100644 --- a/gnu/packages/lua.scm +++ b/gnu/packages/lua.scm @@ -917,3 +917,38 @@ on numbers.") (description "This package provides a FFI-based Lua API for @code{ngx_http_lua_module} or @code{ngx_stream_lua_module}.") (license license:bsd-2))) + +(define-public lua-resty-lrucache + (package + (name "lua-resty-lrucache") + (version "0.09") + (source (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/openresty/lua-resty-lrucache") + (commit (string-append "v" version)))) + (file-name (git-file-name name version)) + (sha256 + (base32 + "1mwiy55qs8bija1kpgizmqgk15ijizzv4sa1giaz9qlqs2kqd7q2")))) + (build-system trivial-build-system) + (arguments + `(#:modules ((guix build utils)) + #:builder + (begin + (use-modules (guix build utils)) + (let* ((luajit-major+minor ,(version-major+minor (package-version lua))) + (package-lua-resty (lambda (input output) + (mkdir-p (string-append output "/lib/lua/" luajit-major+minor)) + (copy-recursively (string-append input "/lib/resty") + (string-append output "/lib/lua/" luajit-major+minor "/resty")) + (symlink (string-append output "/lib/lua/" luajit-major+minor "/resty") + (string-append output "/lib/resty"))))) + (package-lua-resty (assoc-ref %build-inputs "source") + (assoc-ref %outputs "out"))) + #t))) + (home-page "https://github.com/openresty/lua-resty-lrucache") + (synopsis "Lua LRU cache based on the LuaJIT FFI") + (description + "This package provides Lua LRU cache based on the LuaJIT FFI.") + (license license:bsd-2))) -- 2.28.0
* gnu/packages/lua.scm (lua-resty-signal): New variable. --- gnu/packages/lua.scm | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/gnu/packages/lua.scm b/gnu/packages/lua.scm index 59d449dfe5..60f88c1536 100644 --- a/gnu/packages/lua.scm +++ b/gnu/packages/lua.scm @@ -952,3 +952,43 @@ on numbers.") (description "This package provides Lua LRU cache based on the LuaJIT FFI.") (license license:bsd-2))) + +(define-public lua-resty-signal + (package + (name "lua-resty-signal") + (version "0.02") + (source (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/openresty/lua-resty-signal") + (commit (string-append "v" version)))) + (file-name (git-file-name name version)) + (sha256 + (base32 + "13y1pqn45y49mhqwywasfdsid46d0c33yi6mrnracbnmvyxz1cif")))) + (build-system gnu-build-system) + (arguments + `(#:tests? #f ;TODO: Run the test suite. + #:make-flags (list "CC=gcc" + (string-append "PREFIX=" %output)) + #:phases + (modify-phases %standard-phases + (delete 'configure) + (add-after 'install 'install-lua + (lambda* (#:key inputs outputs #:allow-other-keys) + (use-modules (guix build utils)) + (let* ((luajit-major+minor ,(version-major+minor (package-version lua))) + (package-lua-resty (lambda (input output) + (mkdir-p (string-append output "/lib/lua/" luajit-major+minor)) + (copy-recursively (string-append input "/lib/resty") + (string-append output "/lib/lua/" luajit-major+minor "/resty")) + (symlink (string-append output "/lib/lua/" luajit-major+minor "/resty") + (string-append output "/lib/resty"))))) + (package-lua-resty (assoc-ref inputs "source") + (assoc-ref outputs "out"))) + #t))))) + (home-page "https://github.com/openresty/lua-resty-signal") + (synopsis "Lua library for killing or sending signals to Linux processes") + (description "This package provides Lua library for killing or sending +signals to Linux processes.") + (license license:bsd-3))) -- 2.28.0
* gnu/packages/lua.scm (lua-tablepool): New variable. --- gnu/packages/lua.scm | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/gnu/packages/lua.scm b/gnu/packages/lua.scm index 60f88c1536..d30692d2df 100644 --- a/gnu/packages/lua.scm +++ b/gnu/packages/lua.scm @@ -992,3 +992,35 @@ on numbers.") (description "This package provides Lua library for killing or sending signals to Linux processes.") (license license:bsd-3))) + +(define-public lua-tablepool + (package + (name "lua-tablepool") + (version "0.01") + (source (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/openresty/lua-tablepool") + (commit (string-append "v" version)))) + (file-name (git-file-name name version)) + (sha256 + (base32 + "03yjj3w6znvj6843prg84m0lkrn49l901f9hj9bgy3cj9s0awl6y")))) + (build-system trivial-build-system) + (arguments + `(#:modules ((guix build utils)) + #:builder + (begin + (use-modules (guix build utils)) + (let* ((luajit-major+minor ,(version-major+minor (package-version lua))) + (package-lua-resty (lambda (input output) + (mkdir-p (string-append output "/lib/lua/" luajit-major+minor)) + (copy-recursively (string-append input "/lib") + (string-append output "/lib"))))) + (package-lua-resty (assoc-ref %build-inputs "source") + (assoc-ref %outputs "out"))) + #t))) + (home-page "https://github.com/openresty/lua-tablepool") + (synopsis "Lua table recycling pools for LuaJIT") + (description "This package provides Lua table recycling pools for LuaJIT.") + (license license:bsd-2))) -- 2.28.0
* gnu/packages/lua.scm (lua-resty-shell): New variable. --- gnu/packages/lua.scm | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/gnu/packages/lua.scm b/gnu/packages/lua.scm index d30692d2df..2f21d85d0b 100644 --- a/gnu/packages/lua.scm +++ b/gnu/packages/lua.scm @@ -1024,3 +1024,38 @@ signals to Linux processes.") (synopsis "Lua table recycling pools for LuaJIT") (description "This package provides Lua table recycling pools for LuaJIT.") (license license:bsd-2))) + +(define-public lua-resty-shell + (package + (name "lua-resty-shell") + (version "0.03") + (source (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/openresty/lua-resty-shell") + (commit (string-append "v" version)))) + (file-name (git-file-name name version)) + (sha256 + (base32 + "1s6g04ip4hr97r2pd8ry3alq063604s9a3l0hn9nsidh81ps4dp7")))) + (build-system trivial-build-system) + (arguments + `(#:modules ((guix build utils)) + #:builder + (begin + (use-modules (guix build utils)) + (let* ((luajit-major+minor ,(version-major+minor (package-version lua))) + (package-lua-resty (lambda (input output) + (mkdir-p (string-append output "/lib/lua/" luajit-major+minor)) + (copy-recursively (string-append input "/lib/resty") + (string-append output "/lib/lua/" luajit-major+minor "/resty")) + (symlink (string-append output "/lib/lua/" luajit-major+minor "/resty") + (string-append output "/lib/resty"))))) + (package-lua-resty (assoc-ref %build-inputs "source") + (assoc-ref %outputs "out"))) + #t))) + (home-page "https://github.com/openresty/lua-resty-shell") + (synopsis "Lua module for nonblocking system shell command executions") + (description "This package provides Lua module for nonblocking system +shell command executions.") + (license license:bsd-3))) -- 2.28.0
* gnu/packages/patches/nginx-socket-cloexec.patch: New file. * gnu/local.mk (dist_patch_DATA): Add this. * gnu/packages/web.scm (nginx-socket-cloexec): New variable. --- gnu/local.mk | 1 + .../patches/nginx-socket-cloexec.patch | 185 ++++++++++++++++++ gnu/packages/web.scm | 10 + 3 files changed, 196 insertions(+) create mode 100644 gnu/packages/patches/nginx-socket-cloexec.patch diff --git a/gnu/local.mk b/gnu/local.mk index b59b122e86..947b3ef17f 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -1362,6 +1362,7 @@ dist_patch_DATA = \ %D%/packages/patches/nfs4-acl-tools-0.3.7-fixpaths.patch \ %D%/packages/patches/ngircd-handle-zombies.patch \ %D%/packages/patches/network-manager-plugin-path.patch \ + %D%/packages/patches/nginx-socket-cloexec.patch \ %D%/packages/patches/nsis-env-passthru.patch \ %D%/packages/patches/nss-increase-test-timeout.patch \ %D%/packages/patches/nss-pkgconfig.patch \ diff --git a/gnu/packages/patches/nginx-socket-cloexec.patch b/gnu/packages/patches/nginx-socket-cloexec.patch new file mode 100644 index 0000000000..985ce573b5 --- /dev/null +++ b/gnu/packages/patches/nginx-socket-cloexec.patch @@ -0,0 +1,185 @@ +diff --git a/auto/unix b/auto/unix +index 10835f6c..b5b33bb3 100644 +--- a/auto/unix ++++ b/auto/unix +@@ -990,3 +990,27 @@ ngx_feature_test='struct addrinfo *res; + if (getaddrinfo("localhost", NULL, NULL, &res) != 0) return 1; + freeaddrinfo(res)' + . auto/feature ++ ++ngx_feature="SOCK_CLOEXEC support" ++ngx_feature_name="NGX_HAVE_SOCKET_CLOEXEC" ++ngx_feature_run=no ++ngx_feature_incs="#include <sys/types.h> ++ #include <sys/socket.h>" ++ngx_feature_path= ++ngx_feature_libs= ++ngx_feature_test="int fd; ++ fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);" ++. auto/feature ++ ++ngx_feature="FD_CLOEXEC support" ++ngx_feature_name="NGX_HAVE_FD_CLOEXEC" ++ngx_feature_run=no ++ngx_feature_incs="#include <sys/types.h> ++ #include <sys/socket.h> ++ #include <fcntl.h>" ++ngx_feature_path= ++ngx_feature_libs= ++ngx_feature_test="int fd; ++ fd = socket(AF_INET, SOCK_STREAM, 0); ++ fcntl(fd, F_SETFD, FD_CLOEXEC);" ++. auto/feature +diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c +index cd55520c..438e0806 100644 +--- a/src/core/ngx_resolver.c ++++ b/src/core/ngx_resolver.c +@@ -4466,8 +4466,14 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec) + ngx_event_t *rev, *wev; + ngx_connection_t *c; + ++#if (NGX_HAVE_SOCKET_CLOEXEC) ++ s = ngx_socket(rec->sockaddr->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0); ++ ++#else + s = ngx_socket(rec->sockaddr->sa_family, SOCK_STREAM, 0); + ++#endif ++ + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &rec->log, 0, "TCP socket %d", s); + + if (s == (ngx_socket_t) -1) { +@@ -4494,6 +4500,15 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec) + goto failed; + } + ++#if (NGX_HAVE_FD_CLOEXEC) ++ if (ngx_cloexec(s) == -1) { ++ ngx_log_error(NGX_LOG_ALERT, &rec->log, ngx_socket_errno, ++ ngx_cloexec_n " failed"); ++ ++ goto failed; ++ } ++#endif ++ + rev = c->read; + wev = c->write; + +diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h +index 19fec68..8c2f01a 100644 +--- a/src/event/ngx_event.h ++++ b/src/event/ngx_event.h +@@ -73,6 +73,9 @@ struct ngx_event_s { + /* to test on worker exit */ + unsigned channel:1; + unsigned resolver:1; ++#if (HAVE_SOCKET_CLOEXEC_PATCH) ++ unsigned skip_socket_leak_check:1; ++#endif + + unsigned cancelable:1; + +diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c +index 77563709..5827b9d0 100644 +--- a/src/event/ngx_event_accept.c ++++ b/src/event/ngx_event_accept.c +@@ -62,7 +62,9 @@ ngx_event_accept(ngx_event_t *ev) + + #if (NGX_HAVE_ACCEPT4) + if (use_accept4) { +- s = accept4(lc->fd, &sa.sockaddr, &socklen, SOCK_NONBLOCK); ++ s = accept4(lc->fd, &sa.sockaddr, &socklen, ++ SOCK_NONBLOCK | SOCK_CLOEXEC); ++ + } else { + s = accept(lc->fd, &sa.sockaddr, &socklen); + } +@@ -202,6 +204,16 @@ ngx_event_accept(ngx_event_t *ev) + ngx_close_accepted_connection(c); + return; + } ++ ++#if (NGX_HAVE_FD_CLOEXEC) ++ if (ngx_cloexec(s) == -1) { ++ ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, ++ ngx_cloexec_n " failed"); ++ ngx_close_accepted_connection(c); ++ return; ++ } ++#endif ++ + } + } + +diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c +index c5bb8068..cf33b1d2 100644 +--- a/src/event/ngx_event_connect.c ++++ b/src/event/ngx_event_connect.c +@@ -38,8 +38,15 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) + + type = (pc->type ? pc->type : SOCK_STREAM); + ++#if (NGX_HAVE_SOCKET_CLOEXEC) ++ s = ngx_socket(pc->sockaddr->sa_family, type | SOCK_CLOEXEC, 0); ++ ++#else + s = ngx_socket(pc->sockaddr->sa_family, type, 0); + ++#endif ++ ++ + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pc->log, 0, "%s socket %d", + (type == SOCK_STREAM) ? "stream" : "dgram", s); + +@@ -80,6 +87,15 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) + goto failed; + } + ++#if (NGX_HAVE_FD_CLOEXEC) ++ if (ngx_cloexec(s) == -1) { ++ ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, ++ ngx_cloexec_n " failed"); ++ ++ goto failed; ++ } ++#endif ++ + if (pc->local) { + + #if (NGX_HAVE_TRANSPARENT_PROXY) +diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c +index c4376a5..48e8fa8 100644 +--- a/src/os/unix/ngx_process_cycle.c ++++ b/src/os/unix/ngx_process_cycle.c +@@ -1032,6 +1032,9 @@ ngx_worker_process_exit(ngx_cycle_t *cycle) + for (i = 0; i < cycle->connection_n; i++) { + if (c[i].fd != -1 + && c[i].read ++#if (HAVE_SOCKET_CLOEXEC_PATCH) ++ && !c[i].read->skip_socket_leak_check ++#endif + && !c[i].read->accept + && !c[i].read->channel + && !c[i].read->resolver) +diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h +index fcc51533..d1eebf47 100644 +--- a/src/os/unix/ngx_socket.h ++++ b/src/os/unix/ngx_socket.h +@@ -38,6 +38,17 @@ int ngx_blocking(ngx_socket_t s); + + #endif + ++#if (NGX_HAVE_FD_CLOEXEC) ++ ++#define ngx_cloexec(s) fcntl(s, F_SETFD, FD_CLOEXEC) ++#define ngx_cloexec_n "fcntl(FD_CLOEXEC)" ++ ++/* at least FD_CLOEXEC is required to ensure connection fd is closed ++ * after execve */ ++#define HAVE_SOCKET_CLOEXEC_PATCH 1 ++ ++#endif ++ + int ngx_tcp_nopush(ngx_socket_t s); + int ngx_tcp_push(ngx_socket_t s); + diff --git a/gnu/packages/web.scm b/gnu/packages/web.scm index 1699c92366..f7330aa749 100644 --- a/gnu/packages/web.scm +++ b/gnu/packages/web.scm @@ -550,6 +550,16 @@ This is modified version, specifically intended for use with the NGinx documentation.") (license license:bsd-2)))) +(define nginx-socket-cloexec + (package + (inherit nginx) + (name "nginx-socket-cloexec") ;required for lua-resty-shell + (source + (origin + (inherit (package-source nginx)) + (patches (append (search-patches "nginx-socket-cloexec.patch") + (origin-patches (package-source nginx)))))))) + (define-public lighttpd (package (name "lighttpd") -- 2.28.0
* gnu/packages/web.scm (nginx-lua-module): New variable. --- gnu/packages/web.scm | 63 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/gnu/packages/web.scm b/gnu/packages/web.scm index f7330aa749..d2177d2229 100644 --- a/gnu/packages/web.scm +++ b/gnu/packages/web.scm @@ -560,6 +560,69 @@ documentation.") (patches (append (search-patches "nginx-socket-cloexec.patch") (origin-patches (package-source nginx)))))))) +(define-public nginx-lua-module + (package + (inherit nginx) + (name "nginx-lua-module") + (version "0.10.15") + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/openresty/lua-nginx-module") + (commit (string-append "v" version)))) + (file-name (git-file-name "lua-nginx-module" version)) + (sha256 + (base32 + "1j216isp0546hycklbr5wi8mlga5hq170hk7f2sm16sfavlkh5gz")))) + (build-system gnu-build-system) + (inputs + `(("nginx-sources" ,(package-source nginx-socket-cloexec)) + ("luajit" ,luajit) + ,@(package-inputs nginx))) + (arguments + (substitute-keyword-arguments + `(#:configure-flags '("--add-dynamic-module=.") + #:make-flags '("modules") + #:modules ((guix build utils) + (guix build gnu-build-system) + (ice-9 popen) + (ice-9 regex) + (ice-9 textual-ports)) + ,@(package-arguments nginx)) + ((#:phases phases) + `(modify-phases ,phases + (add-after 'unpack 'unpack-nginx-sources + (lambda* (#:key inputs native-inputs #:allow-other-keys) + (begin + ;; The nginx source code is part of the module’s source. + (format #t "decompressing nginx source code~%") + (let ((tar (assoc-ref inputs "tar")) + (nginx-srcs (assoc-ref inputs "nginx-sources"))) + (invoke (string-append tar "/bin/tar") + "xvf" nginx-srcs "--strip-components=1")) + #t))) + (add-before 'configure 'set-luajit-env + (lambda* (#:key inputs #:allow-other-keys) + (let ((luajit (assoc-ref inputs "luajit"))) + (setenv "LUAJIT_LIB" + (string-append luajit "/lib")) + (setenv "LUAJIT_INC" + (string-append luajit "/include/luajit-2.1")) + #t))) + (replace 'install + (lambda* (#:key outputs #:allow-other-keys) + (let ((modules-dir (string-append (assoc-ref outputs "out") "/etc/nginx/modules"))) + (mkdir-p modules-dir) + (copy-file "objs/ngx_http_lua_module.so" + (string-append modules-dir "/ngx_http_lua_module.so")) + #t))) + (delete 'fix-root-dirs) + (delete 'install-man-page))))) + (synopsis "NGINX module for Lua programming language support") + (description "This NGINX module provides a scripting support with Lua +programming language."))) + (define-public lighttpd (package (name "lighttpd") -- 2.28.0
* gnu/services/web.scm (<nginx-configuration>) [lua-package-path, lua-package-cpath]: New record types. * gnu/services/web.scm (default-nginx-config): Use them. * doc/guix.texi (Web Services): Document this. * doc/guix-cookbook.texi (System Configuration): Document this. --- doc/guix-cookbook.texi | 58 ++++++++++++++++++++++++++++++++++++++++++ doc/guix.texi | 24 ++++++++++++++++- gnu/services/web.scm | 25 ++++++++++++++---- 3 files changed, 101 insertions(+), 6 deletions(-) diff --git a/doc/guix-cookbook.texi b/doc/guix-cookbook.texi index a783c0ae4c..6577c340d9 100644 --- a/doc/guix-cookbook.texi +++ b/doc/guix-cookbook.texi @@ -1352,6 +1352,7 @@ reference. * Running Guix on a Linode Server:: Running Guix on a Linode Server * Setting up a bind mount:: Setting up a bind mount in the file-systems definition. * Getting substitutes from Tor:: Configuring Guix daemon to get substitutes through Tor. +* Setting up NGINX with Lua:: Configuring NGINX web-server to load Lua modules. @end menu @node Customizing the Kernel @@ -2113,6 +2114,63 @@ sudo herd set-http-proxy guix-daemon http://localhost:9250 guix build --substitute-urls=https://bp7o7ckwlewr4slm.onion … @end example +@node Setting up NGINX with Lua +@section Setting up NGINX with Lua +@cindex nginx, lua, openresty, resty + +NGINX could be extended with Lua scripts. + +Guix provides NGINX service with ability to load Lua module and specific +Lua packages, and reply to requests by evaluating Lua scripts. + +The following example demonstrates system definition with configuration +to evaluate @file{index.lua} Lua script on HTTP request to +@uref{http://localhost/hello} endpoint: + +@example +local shell = require "resty.shell" + +local stdin = "" +local timeout = 1000 -- ms +local max_size = 4096 -- byte + +local ok, stdout, stderr, reason, status = + shell.run([[/run/current-system/profile/bin/ls /tmp]], stdin, timeout, max_size) + +ngx.say(stdout) +@end example + +@lisp +(use-modules (gnu)) +(use-service-modules #;… web) +(use-package-modules #;… lua) +(operating-system + ;; … + (services + ;; … + (service nginx-service-type + (nginx-configuration + (modules + (list + (file-append nginx-lua-module "/etc/nginx/modules/ngx_http_lua_module.so"))) + (lua-package-path (list lua-resty-core + lua-resty-lrucache + lua-resty-signal + lua-tablepool + lua-resty-shell)) + (lua-package-cpath (list lua-resty-signal)) + (server-blocks + (list (nginx-server-configuration + (server-name '("localhost")) + (listen '("80")) + (root "/etc") + (locations (list + (nginx-location-configuration + (uri "/hello") + (body (list #~(format #f "content_by_lua_file ~s;" + #$(local-file "index.lua")))))))))))))) +@end lisp + @c ********************************************************************* @node Advanced package management @chapter Advanced package management diff --git a/doc/guix.texi b/doc/guix.texi index 8514dfe86f..c8e5928590 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -21903,7 +21903,29 @@ names of loadable modules, as in this example: (modules (list (file-append nginx-accept-language-module "\ -/etc/nginx/modules/ngx_http_accept_language_module.so"))) +/etc/nginx/modules/ngx_http_accept_language_module.so") + (file-append nginx-lua-module "\ +/etc/nginx/modules/ngx_http_lua_module.so"))) +@end lisp + +@item @code{lua-package-path} (default: @code{'()}) +List of nginx lua packages to load. This should be a list of package +names of loadable lua modules, as in this example: + +@lisp +(lua-package-path (list lua-resty-core + lua-resty-lrucache + lua-resty-signal + lua-tablepool + lua-resty-shell)) +@end lisp + +@item @code{lua-package-cpath} (default: @code{'()}) +List of nginx lua C packages to load. This should be a list of package +names of loadable lua C modules, as in this example: + +@lisp +(lua-package-cpath (list lua-resty-signal)) @end lisp @item @code{global-directives} (default: @code{'((events . ()))}) diff --git a/gnu/services/web.scm b/gnu/services/web.scm index c8ffc19d83..d17faa2b59 100644 --- a/gnu/services/web.scm +++ b/gnu/services/web.scm @@ -13,6 +13,7 @@ ;;; Copyright © 2020 Ricardo Wurmus <rekado@elephly.net> ;;; Copyright © 2020 Tobias Geerinckx-Rice <me@tobias.gr> ;;; Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net> +;;; Copyright © 2020 Oleg Pykhalov <go.wigust@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;; @@ -525,6 +526,10 @@ (modules nginx-configuration-modules (default '())) (global-directives nginx-configuration-global-directives (default '((events . ())))) + (lua-package-path nginx-lua-package-path ;list of <package> + (default #f)) + (lua-package-cpath nginx-lua-package-cpath ;list of <package> + (default #f)) (extra-content nginx-configuration-extra-content (default "")) (file nginx-configuration-file ;#f | string | file-like @@ -630,6 +635,8 @@ of index files." server-names-hash-bucket-max-size modules global-directives + lua-package-path + lua-package-cpath extra-content) (apply mixed-text-file "nginx.conf" (flatten @@ -646,11 +653,19 @@ of index files." " scgi_temp_path " run-directory "/scgi_temp;\n" " access_log " log-directory "/access.log;\n" " include " nginx "/share/nginx/conf/mime.types;\n" - (if server-names-hash-bucket-size - (string-append - " server_names_hash_bucket_size " - (number->string server-names-hash-bucket-size) - ";\n") + (if lua-package-path + #~(format #f " lua_package_path ~s;~%" + (string-join (map (lambda (path) + (string-append path "/lib/?.lua")) + '#$lua-package-path) + ";")) + "") + (if lua-package-cpath + #~(format #f " lua_package_cpath ~s;~%" + (string-join (map (lambda (cpath) + (string-append cpath "/lib/lua/?.lua")) + '#$lua-package-cpath) + ";")) "") (if server-names-hash-bucket-max-size (string-append -- 2.28.0