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

Paulo Ricardo Paz Vital pvital at linux.vnet.ibm.com
Thu Jul 21 15:39:16 UTC 2016


On Jul 21 11:11AM, Aline Manera wrote:
> 
> 
> On 07/18/2016 06:59 PM, pvital at linux.vnet.ibm.com wrote:
> > 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 builded 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      | 28 ++++++++-------
> >   src/wok/server.py     |  6 +---
> >   5 files changed, 63 insertions(+), 74 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.
> 
> The session timeout is configurable in the wok config file so you should not
> assume 10 minutes.
> You will need to get the timeout value and do the right count to set the
> nginx config file.
> 

Interesting!!! The current code has this values hardcoded.
I'll change this.

> > +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
> > +
> 
> In other part of the code, we are accessing self.installed directly! Any
> special reason to create this new function?
> Seems like too Java huh

Really? I'm going to check better, but I guess the only code I saw was
inside the same class or method.

> 
> >   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..cf978ad 100644
> > --- a/src/wok/proxy.py
> > +++ b/src/wok/proxy.py
> > @@ -26,11 +26,12 @@
> > 
> >   import os
> >   import pwd
> > -import subprocess
> >   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 +111,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) or os.path.islink(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):
> 

-- 
Paulo Ricardo Paz Vital
Linux Technology Center, IBM Systems
http://www.ibm.com/linux/ltc/




More information about the Kimchi-devel mailing list