[Kimchi-devel] [PATCH] [Wok] Use system's nginx proxy service.

pvital at linux.vnet.ibm.com pvital at linux.vnet.ibm.com
Fri Jul 8 16:26:49 UTC 2016


From: Paulo Vital <pvital at linux.vnet.ibm.com>

This patch removes the code that executes a dedicated nginx proxy, making Wok
to use the system's nginx service. This is a requirement to make Wok acceptable
in community repositories.

It also make sure that a Wok executed from path different than installed (from
a cloned and built source code, for example) will create a symbolic link in
system's nginx config dir to the running configuration file.

This patch solves part of issue #25

Signed-off-by: Paulo Vital <pvital at linux.vnet.ibm.com>
---
 src/nginx/wok.conf.in | 95 +++++++++++++++++++++------------------------------
 src/wok/config.py.in  |  6 +++-
 src/wok/i18n.py       |  2 ++
 src/wok/proxy.py      | 27 +++++++++------
 src/wok/server.py     |  6 +---
 5 files changed, 63 insertions(+), 73 deletions(-)

diff --git a/src/nginx/wok.conf.in b/src/nginx/wok.conf.in
index cb05e4d..823d94d 100644
--- a/src/nginx/wok.conf.in
+++ b/src/nginx/wok.conf.in
@@ -22,71 +22,54 @@
 # This is a template file to be used to generate a nginx
 # proxy config file at wokd script.

-user  ${user};
-worker_processes  1;
+client_max_body_size ${max_body_size}k;

-error_log  /var/log/nginx/error.log;
+# Timeout set to 10 minutes to avoid the 504 Gateway Timeout
+# when Wok is processing a request.
+proxy_connect_timeout       600;
+proxy_send_timeout          600;
+proxy_read_timeout          600;
+send_timeout                600;

-events {
-    worker_connections  1024;
+map $http_upgrade $connection_upgrade {
+    default upgrade;
+    '' close;
 }

-http {
-    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
-                      '$status $body_bytes_sent "$http_referer" '
-                      '"$http_user_agent" "$http_x_forwarded_for"';
-
-    access_log  /var/log/nginx/access.log  main;
-    sendfile    on;
+upstream websocket {
+    server 127.0.0.1:${websockets_port};
+}

-    client_max_body_size ${max_body_size}k;
+server {
+    listen ${host_addr}:${proxy_ssl_port} ssl;

-    # Timeout set to 10 minutes to avoid the 504 Gateway Timeout
-    # when Wok is processing a request.
-    proxy_connect_timeout       600;
-    proxy_send_timeout          600;
-    proxy_read_timeout          600;
-    send_timeout                600;
+    ssl_certificate ${cert_pem};
+    ssl_certificate_key ${cert_key};
+    ssl_protocols TLSv1.1 TLSv1.2;
+    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:@STRENGTH';
+    ssl_prefer_server_ciphers on;
+    ssl_dhparam ${dhparams_pem};
+    ssl_session_timeout ${session_timeout}m;

-    map $http_upgrade $connection_upgrade {
-        default upgrade;
-        '' close;
-    }
+    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
+    add_header X-Frame-Options DENY;
+    add_header X-Content-Type-Options nosniff;
+    add_header X-XSS-Protection "1; mode=block";

-    upstream websocket {
-        server 127.0.0.1:${websockets_port};
+    location / {
+        proxy_pass http://127.0.0.1:${cherrypy_port};
+        proxy_set_header Host $host;
+        proxy_set_header X-Real-IP $remote_addr;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_redirect http://127.0.0.1:${cherrypy_port}/ https://$host:${proxy_ssl_port}/;
     }

-    server {
-        listen ${host_addr}:${proxy_ssl_port} ssl;
-
-        ssl_certificate ${cert_pem};
-        ssl_certificate_key ${cert_key};
-        ssl_protocols TLSv1.1 TLSv1.2;
-        ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:@STRENGTH';
-        ssl_prefer_server_ciphers on;
-        ssl_dhparam ${dhparams_pem};
-        ssl_session_timeout ${session_timeout}m;
-
-        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
-        add_header X-Frame-Options DENY;
-        add_header X-Content-Type-Options nosniff;
-        add_header X-XSS-Protection "1; mode=block";
-
-        location / {
-            proxy_pass http://127.0.0.1:${cherrypy_port};
-            proxy_set_header Host $host;
-            proxy_set_header X-Real-IP $remote_addr;
-            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-            proxy_redirect http://127.0.0.1:${cherrypy_port}/ https://$host:${proxy_ssl_port}/;
-        }
-
-        location /websockify {
-            proxy_pass http://websocket;
-            proxy_http_version 1.1;
-            proxy_set_header Upgrade $http_upgrade;
-            proxy_set_header Connection $connection_upgrade;
-        }
+    location /websockify {
+        proxy_pass http://websocket;
+        proxy_http_version 1.1;
+        proxy_set_header Upgrade $http_upgrade;
+        proxy_set_header Connection $connection_upgrade;
     }
-    ${http_config}
 }
+
+${http_config}
diff --git a/src/wok/config.py.in b/src/wok/config.py.in
index 1ca6f73..d0bca9b 100644
--- a/src/wok/config.py.in
+++ b/src/wok/config.py.in
@@ -76,9 +76,10 @@ class Paths(object):
         self.prefix = self.get_prefix()
         self.installed = (self.prefix == '@pkgdatadir@')
         self.ui_dir = self.add_prefix('ui')
+        self.sys_nginx_conf_dir = '@sysconfdir@/nginx/conf.d'

         if self.installed:
-            self.nginx_conf_dir = '@sysconfdir@/nginx/conf.d'
+            self.nginx_conf_dir = self.sys_nginx_conf_dir
             self.state_dir = '@localstatedir@/lib/wok'
             self.log_dir = '@localstatedir@/log/wok'
             self.conf_dir = '@sysconfdir@/wok'
@@ -119,6 +120,9 @@ class Paths(object):
     def get_template_path(self, resource):
         return os.path.join(self.ui_dir, 'pages/%s.tmpl' % resource)

+    def is_wok_installed(self):
+        return self.installed
+

 paths = Paths()

diff --git a/src/wok/i18n.py b/src/wok/i18n.py
index d6cb17c..33107ee 100644
--- a/src/wok/i18n.py
+++ b/src/wok/i18n.py
@@ -55,6 +55,8 @@ messages = {
     "WOKUTILS0004E": _("Invalid data value '%(value)s'"),
     "WOKUTILS0005E": _("Invalid data unit '%(unit)s'"),

+    "WOKPROXY0001E": _("Unable to (re)start system's nginx.service. Details: '%(error)s'"),
+
     # These messages (ending with L) are for user log purposes
     "WOKCOL0001L": _("Request made on collection"),
     "WOKRES0001L": _("Request made on resource"),
diff --git a/src/wok/proxy.py b/src/wok/proxy.py
index a74e88a..ab959e1 100644
--- a/src/wok/proxy.py
+++ b/src/wok/proxy.py
@@ -31,6 +31,8 @@ from string import Template

 from wok import sslcert
 from wok.config import paths
+from wok.exception import OperationFailed
+from wok.utils import run_command


 HTTP_CONFIG = """
@@ -110,18 +112,21 @@ def _create_proxy_config(options):
     config_file.write(data)
     config_file.close()

+    # If not running from the installed path (from a cloned and builded source
+    # code), create a symbolic link in  system's dir to prevent errors on read
+    # SSL certifications.
+    if not paths.is_wok_installed():
+        dst = os.path.join(paths.sys_nginx_conf_dir, "wok.conf")
+        if os.path.isfile(dst):
+            os.remove(dst)
+        os.symlink(os.path.join(nginx_config_dir, "wok.conf"), dst)
+

 def start_proxy(options):
     """Start nginx reverse proxy."""
     _create_proxy_config(options)
-    nginx_config_dir = paths.nginx_conf_dir
-    config_file = "%s/wok.conf" % nginx_config_dir
-    cmd = ['nginx', '-c', config_file]
-    subprocess.call(cmd)
-
-
-def terminate_proxy():
-    """Stop nginx process."""
-    config_file = "%s/wok.conf" % paths.nginx_conf_dir
-    term_proxy_cmd = ['nginx', '-s', 'stop', '-c', config_file]
-    subprocess.call(term_proxy_cmd)
+    # Restart system's nginx service to reload wok configuration
+    cmd = ['systemctl', 'restart', 'nginx.service']
+    output, error, retcode = run_command(cmd, silent=True)
+    if retcode != 0:
+        raise OperationFailed('WOKPROXY0001E', {'error': error})
diff --git a/src/wok/server.py b/src/wok/server.py
index 8a02596..b1185e3 100644
--- a/src/wok/server.py
+++ b/src/wok/server.py
@@ -33,7 +33,7 @@ from wok.config import config as configParser
 from wok.config import paths, PluginConfig, WokConfig
 from wok.control import sub_nodes
 from wok.model import model
-from wok.proxy import start_proxy, terminate_proxy
+from wok.proxy import start_proxy
 from wok.reqlogger import RequestLogger
 from wok.root import WokRoot
 from wok.safewatchedfilehandler import SafeWatchedFileHandler
@@ -180,10 +180,6 @@ class Server(object):
         self.app = cherrypy.tree.mount(WokRoot(model_instance, dev_env),
                                        config=self.configObj)
         self._load_plugins(options)
-
-        # Terminate proxy when cherrypy server is terminated
-        cherrypy.engine.subscribe('exit', terminate_proxy)
-
         cherrypy.lib.sessions.init()

     def _load_plugins(self, options):
--
2.7.4




More information about the Kimchi-devel mailing list