[PATCH] [Wok 0/6] Bug fix #175: Do not generate nginx configuration file on the fly

Aline Manera (6): Fix 'make check' issues Remove log size information from Wok config Add nginx.service as wokd.service dependency Generate SSL self signed certificate on package post installation script Bug fix #175: Do not generate nginx configuration file on the fly Remove nginx-specific parameters from wok.conf file .gitignore | 1 - IBM-license-blacklist | 4 +- Makefile.am | 7 +- contrib/DEBIAN/control.in | 1 + contrib/DEBIAN/postinst | 1 + contrib/DEBIAN/postrm | 1 + contrib/Makefile.am | 2 +- contrib/wok.spec.fedora.in | 11 +-- contrib/wok.spec.suse.in | 41 ++++++---- contrib/wokd.service.fedora | 12 --- contrib/wokd.service.systemd | 14 ++++ docs/API/config.md | 4 +- docs/wokd.8.in | 16 ++-- src/nginx/Makefile.am | 7 +- src/nginx/wok.conf | 82 ++++++++++++++++++++ src/nginx/wok.conf.in | 75 ------------------ src/wok.conf.in | 23 +----- src/wok/config.py.in | 11 +-- src/wok/i18n.py | 2 - src/wok/model/config.py | 2 +- src/wok/plugins/sample/po/update-po | 2 +- src/wok/proxy.py | 147 ++++++++++-------------------------- src/wok/server.py | 6 +- src/wok/sslcert.py | 2 +- src/wokd.in | 18 +---- tests/test_api.py | 14 +--- tests/test_exception.py | 52 +++---------- tests/test_plugin.py | 12 +-- tests/test_server.py | 15 +--- tests/test_server_root.py | 17 ++--- tests/utils.py | 83 ++++---------------- 31 files changed, 242 insertions(+), 443 deletions(-) delete mode 100644 contrib/wokd.service.fedora create mode 100644 contrib/wokd.service.systemd create mode 100644 src/nginx/wok.conf delete mode 100644 src/nginx/wok.conf.in -- 2.7.4

Add Sample configuration file to IBM-license-blacklist as it does not need to have a license header and remove whitespaces from sample/po/update-po Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- IBM-license-blacklist | 1 + src/wok/plugins/sample/po/update-po | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/IBM-license-blacklist b/IBM-license-blacklist index 01a6514..b2f8f66 100644 --- a/IBM-license-blacklist +++ b/IBM-license-blacklist @@ -31,6 +31,7 @@ src/firewalld.xml src/wok.logrotate src/wok.conf.in src/wok/API.json +src/wok/plugins/sample/sample.conf src/wok/plugins/sample/API.json src/wok/plugins/sample/po/LINGUAS src/wok/plugins/sample/po/POTFILES.in diff --git a/src/wok/plugins/sample/po/update-po b/src/wok/plugins/sample/po/update-po index b9c464f..fb4403b 100755 --- a/src/wok/plugins/sample/po/update-po +++ b/src/wok/plugins/sample/po/update-po @@ -28,7 +28,7 @@ for src in `cat POTFILES.in`; do done | xgettext --no-location -o sample.pot -L Python - for lingua in `cat LINGUAS`; do - msgmerge --update --no-fuzzy-matching --backup=off $lingua.po sample.pot + msgmerge --update --no-fuzzy-matching --backup=off $lingua.po sample.pot msgfmt -c --statistics --verbose -o $lingua.gmo $lingua.po done -- 2.7.4

Log size information is not part of Wok configuration anymore (since commit 2a7b3c). So remove the reference to it. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- src/wok/config.py.in | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wok/config.py.in b/src/wok/config.py.in index f1167f4..f958e1e 100644 --- a/src/wok/config.py.in +++ b/src/wok/config.py.in @@ -282,7 +282,6 @@ def _get_config(): config.add_section("logging") config.set("logging", "log_dir", paths.log_dir) config.set("logging", "log_level", DEFAULT_LOG_LEVEL) - config.set("logging", "log_size", "10M") config_file = os.path.join(paths.conf_dir, 'wok.conf') if os.path.exists(config_file): -- 2.7.4

To be able to run Wok properly, nginx must be running, so update the systemd configuration file to ensure that automatically. Also rename wokd.service.fedora to wokd.service.systemd as it is not Fedora specific file. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- IBM-license-blacklist | 2 +- Makefile.am | 4 ++-- contrib/Makefile.am | 2 +- contrib/wokd.service.fedora | 12 ------------ contrib/wokd.service.systemd | 14 ++++++++++++++ 5 files changed, 18 insertions(+), 16 deletions(-) delete mode 100644 contrib/wokd.service.fedora create mode 100644 contrib/wokd.service.systemd diff --git a/IBM-license-blacklist b/IBM-license-blacklist index b2f8f66..19318be 100644 --- a/IBM-license-blacklist +++ b/IBM-license-blacklist @@ -17,7 +17,7 @@ contrib/DEBIAN/control.in contrib/wok.spec.fedora.in contrib/wok.spec.suse.in contrib/wokd.logrotate.in -contrib/wokd.service.fedora +contrib/wokd.service.systemd docs/API/.*.md docs/.*.md docs/wokd.8.in diff --git a/Makefile.am b/Makefile.am index 5c8e69d..60b0818 100644 --- a/Makefile.am +++ b/Makefile.am @@ -90,7 +90,7 @@ install-deb: install cp -R $(top_srcdir)/contrib/DEBIAN $(DESTDIR)/ @if test -d "$(systemdsystemunitdir)" ; then \ $(MKDIR_P) $(DESTDIR)/$(systemdsystemunitdir); \ - cp -R contrib/wokd.service.fedora \ + cp -R contrib/wokd.service.systemd \ $(DESTDIR)/$(systemdsystemunitdir)/wokd.service; \ else \ $(MKDIR_P) $(DESTDIR)/etc/init; \ @@ -140,7 +140,7 @@ ChangeLog: install-data-local: @if test -d "$(systemdsystemunitdir)" ; then \ mkdir -p $(DESTDIR)/$(systemdsystemunitdir); \ - $(INSTALL_DATA) contrib/wokd.service.fedora $(DESTDIR)/$(systemdsystemunitdir)/wokd.service; \ + $(INSTALL_DATA) contrib/wokd.service.systemd $(DESTDIR)/$(systemdsystemunitdir)/wokd.service; \ else \ mkdir -p $(DESTDIR)/etc/init.d/; \ $(INSTALL_DATA) contrib/wokd.sysvinit $(DESTDIR)/etc/init.d/wokd; \ diff --git a/contrib/Makefile.am b/contrib/Makefile.am index 32fcfde..77af87c 100644 --- a/contrib/Makefile.am +++ b/contrib/Makefile.am @@ -24,7 +24,7 @@ SUBDIRS = DEBIAN EXTRA_DIST = \ check_i18n.py \ wokd.sysvinit \ - wokd.service.fedora \ + wokd.service.systemd \ wok.spec.fedora.in \ wokd-upstart.conf.debian \ wokd-upstart.conf.fedora \ diff --git a/contrib/wokd.service.fedora b/contrib/wokd.service.fedora deleted file mode 100644 index 33d88d8..0000000 --- a/contrib/wokd.service.fedora +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -Description=Wok - Webserver Originated from Kimchi - -[Service] -Type=simple -ExecStart=/usr/bin/wokd -ExecStop=/bin/kill -TERM $MAINPID -EnvironmentFile=/etc/wok/wok.conf -KillMode=process - -[Install] -WantedBy=multi-user.target diff --git a/contrib/wokd.service.systemd b/contrib/wokd.service.systemd new file mode 100644 index 0000000..d21c845 --- /dev/null +++ b/contrib/wokd.service.systemd @@ -0,0 +1,14 @@ +[Unit] +Description=Wok - Webserver Originated from Kimchi +Wants=nginx.service +After=nginx.service + +[Service] +Type=simple +ExecStart=/usr/bin/wokd +ExecStop=/bin/kill -TERM $MAINPID +EnvironmentFile=/etc/wok/wok.conf +KillMode=process + +[Install] +WantedBy=multi-user.target -- 2.7.4

When Wok is installed from a package, the SSL self signed certificate should be created on package post installation script instead of on server starts up. That will be required to fix issue #175. As the nginx configuration will not be created on the fly, as the SSL cert/key must be there to do not make nginx fails. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- contrib/DEBIAN/control.in | 1 + contrib/DEBIAN/postinst | 1 + contrib/DEBIAN/postrm | 1 + contrib/wok.spec.fedora.in | 10 ++++++---- contrib/wok.spec.suse.in | 40 +++++++++++++++++++++++++--------------- src/wok/sslcert.py | 2 +- 6 files changed, 35 insertions(+), 20 deletions(-) diff --git a/contrib/DEBIAN/control.in b/contrib/DEBIAN/control.in index e585080..16f8afc 100644 --- a/contrib/DEBIAN/control.in +++ b/contrib/DEBIAN/control.in @@ -15,6 +15,7 @@ Depends: python-cherrypy3 (>= 3.2.0), python-psutil (>= 0.6.0), fonts-font-awesome, logrotate, + openssl, texlive-fonts-extra Build-Depends: xsltproc, gettext, diff --git a/contrib/DEBIAN/postinst b/contrib/DEBIAN/postinst index 54ea20d..473e515 100755 --- a/contrib/DEBIAN/postinst +++ b/contrib/DEBIAN/postinst @@ -20,6 +20,7 @@ systemd_exists=$(type /bin/systemctl > /dev/null 2>&1; echo $?) if test $systemd_exists = "0"; then + openssl req -x509 -newkey rsa:4096 -keyout /etc/wok/wok-key.pem -out /etc/wok/wok-cert.pem -days 365 -nodes -subj "/C=US/CN=wok/O=kimchi-project.org" >/dev/null 2>&1 || : /bin/systemctl enable wokd > /dev/null 2>&1 /bin/systemctl daemon-reload > /dev/null 2>&1 /bin/systemctl start wokd > /dev/null 2>&1 diff --git a/contrib/DEBIAN/postrm b/contrib/DEBIAN/postrm index bfb1973..4b8c8ff 100755 --- a/contrib/DEBIAN/postrm +++ b/contrib/DEBIAN/postrm @@ -26,5 +26,6 @@ case "$1" in ;; purge) rm -rf /var/log/wok /var/run/wok.pid /usr/share/wok/ + rm /etc/wok/wok-key.pem /etc/wok/wok-cert.pem ;; esac diff --git a/contrib/wok.spec.fedora.in b/contrib/wok.spec.fedora.in index fdf3484..5df8d37 100644 --- a/contrib/wok.spec.fedora.in +++ b/contrib/wok.spec.fedora.in @@ -20,6 +20,7 @@ Requires: python-psutil >= 0.6.0 Requires: fontawesome-fonts Requires: open-sans-fonts Requires: logrotate +Requires: openssl BuildRequires: gettext-devel BuildRequires: libxslt BuildRequires: openssl @@ -75,27 +76,28 @@ install -Dm 0755 contrib/wokd.sysvinit %{buildroot}%{_initrddir}/wokd %post if [ $1 -eq 1 ] ; then - /bin/systemctl enable wokd.service >/dev/null 2>&1 || : # Initial installation + /bin/systemctl enable wokd.service >/dev/null 2>&1 || : /bin/systemctl daemon-reload >/dev/null 2>&1 || : + openssl req -x509 -newkey rsa:4096 -keyout /etc/wok/wok-key.pem -out /etc/wok/wok-cert.pem -days 365 -nodes -subj "/C=US/CN=wok/O=kimchi-project.org" >/dev/null 2>&1 || : fi - %preun - if [ $1 -eq 0 ] ; then # Package removal, not upgrade /bin/systemctl --no-reload disable wokd.service > /dev/null 2>&1 || : /bin/systemctl stop wokd.service > /dev/null 2>&1 || : fi - exit 0 %postun if [ "$1" -ge 1 ] ; then /bin/systemctl try-restart wokd.service >/dev/null 2>&1 || : +else + rm /etc/wok/wok-key.pem /etc/wok/wok-cert.pem fi + exit 0 %clean diff --git a/contrib/wok.spec.suse.in b/contrib/wok.spec.suse.in index 70c295b..35c316c 100644 --- a/contrib/wok.spec.suse.in +++ b/contrib/wok.spec.suse.in @@ -21,6 +21,7 @@ Requires: python-psutil >= 0.6.0 Requires: fontawesome-fonts Requires: google-opensans-fonts Requires: logrotate +Requires: openssl BuildRequires: gettext-tools BuildRequires: libxslt-tools BuildRequires: openssl @@ -50,29 +51,38 @@ make DESTDIR=%{buildroot} install %post -%if 0%{?with_systemd} - /bin/systemctl enable wokd.service >/dev/null 2>&1 || : - /bin/systemctl daemon-reload >/dev/null 2>&1 || : -%else - chkconfig wokd on -%endif +if [ $1 -eq 1 ] ; then + %if 0%{?with_systemd} + /bin/systemctl enable wokd.service >/dev/null 2>&1 || : + /bin/systemctl daemon-reload >/dev/null 2>&1 || : + %else + chkconfig wokd on + %endif + openssl req -x509 -newkey rsa:4096 -keyout /etc/wok/wok-key.pem -out /etc/wok/wok-cert.pem -days 365 -nodes -subj "/C=US/CN=wok/O=kimchi-project.org" >/dev/null 2>&1 || : +fi exit 0 %preun -%if 0%{?with_systemd} - /bin/systemctl --no-reload disable wokd.service > /dev/null 2>&1 || : - /bin/systemctl stop wokd.service > /dev/null 2>&1 || : -%else - service wokd stop -%endif +if [ $1 -eq 0 ] ; then + %if 0%{?with_systemd} + /bin/systemctl --no-reload disable wokd.service > /dev/null 2>&1 || : + /bin/systemctl stop wokd.service > /dev/null 2>&1 || : + %else + service wokd stop + %endif +fi exit 0 %postun -%if 0%{?with_systemd} - /bin/systemctl try-restart wokd.service >/dev/null 2>&1 || : -%endif +if [ "$1" -ge 1 ] ; then + %if 0%{?with_systemd} + /bin/systemctl try-restart wokd.service >/dev/null 2>&1 || : + %endif +else + rm /etc/wok/wok-key.pem /etc/wok/wok-cert.pem +fi exit 0 %clean diff --git a/src/wok/sslcert.py b/src/wok/sslcert.py index a3dd551..45b1eb7 100644 --- a/src/wok/sslcert.py +++ b/src/wok/sslcert.py @@ -64,7 +64,7 @@ class SSLCert(object): self.cert.set_not_after(nowPlusYear) issuer = X509.X509_Name() - issuer.CN = 'kimchi' + issuer.CN = 'wok' issuer.O = 'kimchi-project.org' self.cert.set_issuer(issuer) -- 2.7.4

Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> Signed-off-by: Ramon Medeiros <ramonn@linux.vnet.ibm.com> --- .gitignore | 1 - IBM-license-blacklist | 1 + Makefile.am | 3 +- contrib/wok.spec.fedora.in | 1 - contrib/wok.spec.suse.in | 1 - src/nginx/Makefile.am | 7 +-- src/nginx/wok.conf | 82 +++++++++++++++++++++++++ src/nginx/wok.conf.in | 75 ----------------------- src/wok/config.py.in | 3 +- src/wok/i18n.py | 2 - src/wok/proxy.py | 147 +++++++++++++-------------------------------- src/wok/server.py | 6 +- 12 files changed, 134 insertions(+), 195 deletions(-) create mode 100644 src/nginx/wok.conf delete mode 100644 src/nginx/wok.conf.in diff --git a/.gitignore b/.gitignore index 8e2e115..60ac707 100644 --- a/.gitignore +++ b/.gitignore @@ -31,7 +31,6 @@ wok-*.tar.gz wok.spec src/wokd src/wok.conf -src/nginx/wok.conf src/wok/config.py tests/run_tests.sh tests/test_config.py diff --git a/IBM-license-blacklist b/IBM-license-blacklist index 19318be..8477b07 100644 --- a/IBM-license-blacklist +++ b/IBM-license-blacklist @@ -31,6 +31,7 @@ src/firewalld.xml src/wok.logrotate src/wok.conf.in src/wok/API.json +src/nginx/wok.conf src/wok/plugins/sample/sample.conf src/wok/plugins/sample/API.json src/wok/plugins/sample/po/LINGUAS diff --git a/Makefile.am b/Makefile.am index 60b0818..bd7a563 100644 --- a/Makefile.am +++ b/Makefile.am @@ -156,9 +156,10 @@ install-data-local: touch $(DESTDIR)/$(localstatedir)/log/wok/wok-error.log mkdir -p $(DESTDIR)/etc/wok/ $(INSTALL_DATA) src/dhparams.pem $(DESTDIR)/etc/wok/dhparams.pem - touch $(DESTDIR)/etc/nginx/conf.d/wok.conf mkdir -p $(DESTDIR)/etc/logrotate.d/ $(INSTALL_DATA) $(top_srcdir)/src/wok.logrotate $(DESTDIR)/etc/logrotate.d/wokd + mkdir -p $(DESTDIR)/etc/nginx/conf.d + $(INSTALL_DATA) $(top_srcdir)/src/nginx/wok.conf $(DESTDIR)/etc/nginx/conf.d/wok.conf uninstall-local: @if test -f $(systemdsystemunitdir)/wokd.service; then \ diff --git a/contrib/wok.spec.fedora.in b/contrib/wok.spec.fedora.in index 5df8d37..48492ea 100644 --- a/contrib/wok.spec.fedora.in +++ b/contrib/wok.spec.fedora.in @@ -116,7 +116,6 @@ rm -rf $RPM_BUILD_ROOT %{_prefix}/share/locale/*/LC_MESSAGES/wok.mo %{_datadir}/wok/ui/ %{_datadir}/wok -%{_sysconfdir}/nginx/conf.d/wok.conf.in %{_sysconfdir}/wok/wok.conf %{_sysconfdir}/wok/ %{_sysconfdir}/logrotate.d/wokd diff --git a/contrib/wok.spec.suse.in b/contrib/wok.spec.suse.in index 35c316c..11c0464 100644 --- a/contrib/wok.spec.suse.in +++ b/contrib/wok.spec.suse.in @@ -103,7 +103,6 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/wok %{_sysconfdir}/wok/wok.conf %{_sysconfdir}/wok/ -%{_sysconfdir}/nginx/conf.d/wok.conf.in %{_sysconfdir}/nginx/conf.d/wok.conf %{_sysconfdir}/logrotate.d/wokd %{_var}/lib/wok/ diff --git a/src/nginx/Makefile.am b/src/nginx/Makefile.am index a376a74..3a47a5f 100644 --- a/src/nginx/Makefile.am +++ b/src/nginx/Makefile.am @@ -1,7 +1,7 @@ # # Project Wok # -# Copyright IBM Corp, 2015 +# Copyright IBM Corp, 2015-2016 # # Code derived from Project Kimchi # @@ -19,9 +19,8 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -EXTRA_DIST = wok.conf.in +EXTRA_DIST = wok.conf confdir = $(sysconfdir)/nginx/conf.d -dist_conf_DATA = wok.conf.in +dist_conf_DATA = wok.conf -CLEANFILES = wok.conf diff --git a/src/nginx/wok.conf b/src/nginx/wok.conf new file mode 100644 index 0000000..a0d4983 --- /dev/null +++ b/src/nginx/wok.conf @@ -0,0 +1,82 @@ +# +# This is the default nginx configuration for wokd service. +# If you need to change it for any reason, please, validate /etc/wok/wok.conf +# + +client_max_body_size 4194304k; + +# Set timeout, based on configuration values, to avoid the 504 Gateway Timeout +# when Wok is processing a request. +# +# Session timeout value must be properly set in /etc/wok/wok.conf as well +proxy_connect_timeout 10m; +proxy_send_timeout 10m; +proxy_read_timeout 10m; +send_timeout 10m; + +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +# To use a different port to websockets connections, change the configuration +# below and DO NOT forget to update /etc/wok/wok.conf accordingly +upstream websocket { + server 127.0.0.1:64667; +} + +server { + # Default HTTPS port is 8001 + # + # DO NOT forget to update proxy_port parameter in /etc/wok/wok.conf when + # changing this value + listen 0.0.0.0:8001 ssl; + + ssl_certificate /etc/wok/wok-cert.pem; + ssl_certificate_key /etc/wok/wok-key.pem; + 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 /etc/wok/dhparams.pem; + + # Session timeout value must be properly set in /etc/wok/wok.conf as well + ssl_session_timeout 10m; + + 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"; + + # Update location path for relative path + # e.g.: localtion /wok + location / { + # Default cherrypy port for Wok is 8010 + # DO NOT forget to update cherrypy_port parameter in /etc/wok/wok.conf + # when changing this value + proxy_pass http://127.0.0.1:8010; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # Update location path for https for relative path + # e.g.: proxy_redirect http://127.0.0.1:8010/ https://$host:8001/wok; + proxy_redirect http://127.0.0.1:8010/ https://$host:8001/; + } + + # Update location path for relative path + # e.g.: localtion /wok/websockify + location /websockify { + proxy_pass http://websocket; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } +} + +# Default HTTP port is 8000 +# +# Every HTTP request will be forwarded to HTTPS by default +# Remove the block below to disable HTTP connections +server { + listen 0.0.0.0:8000; + rewrite ^/(.*)$ https://$host:8001/$1 redirect; +} diff --git a/src/nginx/wok.conf.in b/src/nginx/wok.conf.in deleted file mode 100644 index 5d2bb17..0000000 --- a/src/nginx/wok.conf.in +++ /dev/null @@ -1,75 +0,0 @@ -# Project Wok -# -# Copyright IBM Corp, 2015-2016 -# -# Code derived from Project Kimchi -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301 USA - -# This is a template file to be used to generate a nginx -# proxy config file at wokd script. - -client_max_body_size ${max_body_size}k; - -# Set timeout, based on configuration values, to avoid the 504 Gateway Timeout -# when Wok is processing a request. -proxy_connect_timeout ${session_timeout}m; -proxy_send_timeout ${session_timeout}m; -proxy_read_timeout ${session_timeout}m; -send_timeout ${session_timeout}m; - -map $http_upgrade $connection_upgrade { - default upgrade; - '' close; -} - -upstream websocket { - server 127.0.0.1:${websockets_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 ${server_root}/ { - 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_root}/; - } - - location ${server_root}/websockify { - proxy_pass http://websocket; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - } -} - -${http_config} diff --git a/src/wok/config.py.in b/src/wok/config.py.in index f958e1e..c48c46a 100644 --- a/src/wok/config.py.in +++ b/src/wok/config.py.in @@ -76,13 +76,14 @@ class Paths(object): self.prefix = self.get_prefix() self.installed = (self.prefix == '@pkgdatadir@') self.ui_dir = self.add_prefix('ui') + self.sys_conf_dir = '@sysconfdir@/wok' self.sys_nginx_conf_dir = '@sysconfdir@/nginx/conf.d' if self.installed: + self.conf_dir = self.sys_conf_dir 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' self.src_dir = '@wokdir@' self.plugins_dir = '@wokdir@/plugins' self.mo_dir = '@prefix@/share/locale' diff --git a/src/wok/i18n.py b/src/wok/i18n.py index ab7ef0e..cbc37cf 100644 --- a/src/wok/i18n.py +++ b/src/wok/i18n.py @@ -55,8 +55,6 @@ 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 "WOKASYNC0001L": _("Successfully completed task '%(target_uri)s'"), "WOKASYNC0002L": _("Failed to complete task '%(target_uri)s'"), diff --git a/src/wok/proxy.py b/src/wok/proxy.py index 5f646e4..8ebb869 100644 --- a/src/wok/proxy.py +++ b/src/wok/proxy.py @@ -25,114 +25,49 @@ # and configure the Nginx proxy. import os -import pwd -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 = """ -server { - listen %(host_addr)s:%(proxy_port)s; - rewrite ^/(.*)$ https://$host:%(proxy_ssl_port)s%(rel_path)s/$1 redirect; -} -""" - - -def _create_proxy_config(options): - """Create nginx configuration file based on current ports config - - To allow flexibility in which port wok runs, we need the same - flexibility with the nginx proxy. This method creates the config - file dynamically by using 'nginx.conf.in' as a template, creating - the file 'wok.conf' which will be used to launch the proxy. - - Arguments: - options - OptionParser object with Wok config options - """ - # User that will run the worker process of the proxy. Fedora, - # RHEL and Suse creates an user called 'nginx' when installing - # the proxy. Ubuntu creates an user 'www-data' for it. - user_proxy = None - user_list = ('nginx', 'www-data', 'http') - sys_users = [p.pw_name for p in pwd.getpwall()] - common_users = list(set(user_list) & set(sys_users)) - if len(common_users) == 0: - raise Exception("No common user found") - else: - user_proxy = common_users[0] - config_dir = paths.conf_dir - nginx_config_dir = paths.nginx_conf_dir - cert = options.ssl_cert - key = options.ssl_key - - # No certificates specified by the user - if not cert or not key: - cert = '%s/wok-cert.pem' % config_dir - key = '%s/wok-key.pem' % config_dir - # create cert files if they don't exist - if not os.path.exists(cert) or not os.path.exists(key): - ssl_gen = sslcert.SSLCert() - with open(cert, "w") as f: - f.write(ssl_gen.cert_pem()) - with open(key, "w") as f: - f.write(ssl_gen.key_pem()) - - # Setting up Diffie-Hellman group with 2048-bit file - dhparams_pem = os.path.join(config_dir, "dhparams.pem") - - http_config = '' - if options.https_only == 'false': - http_config = HTTP_CONFIG % {'host_addr': options.host, - 'proxy_port': options.port, - 'proxy_ssl_port': options.ssl_port, - 'rel_path': options.server_root} - - # Read template file and create a new config file - # with the specified parameters. - with open(os.path.join(nginx_config_dir, "wok.conf.in")) as template: - data = template.read() - data = Template(data) - data = data.safe_substitute(user=user_proxy, - host_addr=options.host, - proxy_ssl_port=options.ssl_port, - http_config=http_config, - cherrypy_port=options.cherrypy_port, - websockets_port=options.websockets_port, - cert_pem=cert, cert_key=key, - max_body_size=eval(options.max_body_size), - session_timeout=options.session_timeout, - dhparams_pem=dhparams_pem, - server_root=options.server_root) - - # Write file to be used for nginx. - config_file = open(os.path.join(nginx_config_dir, "wok.conf"), "w") - 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.installed: - dst = os.path.join(paths.sys_nginx_conf_dir, "wok.conf") - - # directoy does not exist: create it - if not os.path.exists(paths.sys_nginx_conf_dir): - os.makedirs(paths.sys_nginx_conf_dir) - - 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) - # 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}) +def check_proxy_config(): + # When running from a installed system, there is nothing to do + if paths.installed: + return + + # Otherwise, ensure essential directories and files are placed on right + # place to avoid problems + # + # If not running from a installed system, nginx and wok conf + # directories may not exist, so create them if needed + dirs = [paths.sys_nginx_conf_dir, paths.sys_conf_dir] + for d in dirs: + if not os.path.exists(d): + os.makedirs(d) + + # Create a symbolic link in system's dir to prevent errors while + # running from source code + symlinks = [{'target': os.path.join(paths.nginx_conf_dir, 'wok.conf'), + 'link': os.path.join(paths.sys_nginx_conf_dir, + 'wok.conf')}, + {'target': os.path.join(paths.conf_dir, 'dhparams.pem'), + 'link': os.path.join(paths.sys_conf_dir, 'dhparams.pem')}] + for item in symlinks: + link = item['link'] + if os.path.isfile(link) or os.path.islink(link): + os.remove(link) + os.symlink(item['target'], link) + + # Create cert files if they don't exist + cert = os.path.join(paths.sys_conf_dir, 'wok-cert.pem') + key = os.path.join(paths.sys_conf_dir, 'wok-key.pem') + + if not os.path.exists(cert) or not os.path.exists(key): + ssl_gen = sslcert.SSLCert() + with open(cert, "w") as f: + f.write(ssl_gen.cert_pem()) + with open(key, "w") as f: + f.write(ssl_gen.key_pem()) + + # Reload nginx configuration. + os.system('nginx -s reload') diff --git a/src/wok/server.py b/src/wok/server.py index 3aa06da..48f455b 100644 --- a/src/wok/server.py +++ b/src/wok/server.py @@ -31,7 +31,7 @@ from wok.config import config as configParser from wok.config import PluginConfig, WokConfig from wok.control import sub_nodes from wok.model import model -from wok.proxy import start_proxy +from wok.proxy import check_proxy_config from wok.reqlogger import RequestLogger from wok.root import WokRoot from wok.safewatchedfilehandler import SafeWatchedFileHandler @@ -61,8 +61,8 @@ def set_no_cache(): class Server(object): def __init__(self, options): - # Launch reverse proxy - start_proxy(options) + # Check proxy configuration + check_proxy_config() make_dirs = [ os.path.abspath(config.get_log_download_path()), -- 2.7.4

The ssl_port was also renamed to proxy_port for a better meaning. And then in future, other proxy than nginx can be supported. This patch also updates tests cases and remove unused functions (or plugin-specific function) from tests/utils.py Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- docs/API/config.md | 4 +-- docs/wokd.8.in | 16 +++------ src/wok.conf.in | 23 +------------ src/wok/config.py.in | 7 +--- src/wok/model/config.py | 2 +- src/wokd.in | 18 ++-------- tests/test_api.py | 14 +++----- tests/test_exception.py | 52 +++++++---------------------- tests/test_plugin.py | 12 ++----- tests/test_server.py | 15 ++------- tests/test_server_root.py | 17 +++------- tests/utils.py | 83 ++++++++--------------------------------------- 12 files changed, 53 insertions(+), 210 deletions(-) diff --git a/docs/API/config.md b/docs/API/config.md index bdf5c16..0c273e2 100644 --- a/docs/API/config.md +++ b/docs/API/config.md @@ -9,7 +9,7 @@ Contains information about the application environment and configuration. **Methods:** * **GET**: Retrieve configuration information - * ssl_port: SSL port to list on + * proxy_port: SSL port to list on * websockets_port: Port for websocket proxy to listen on * auth: Authentication method used to log in to Wok * version: Wok version @@ -22,7 +22,7 @@ Contains information about the application environment and configuration. #### Examples GET /config { - ssl_port: 8001, + proxy_port: 8001, websockets_port: 64667, version: 2.0 } diff --git a/docs/wokd.8.in b/docs/wokd.8.in index c7a6f3f..4dc0730 100644 --- a/docs/wokd.8.in +++ b/docs/wokd.8.in @@ -3,10 +3,10 @@ Kimchi \- HTML5 based management tool for KVM .SH SYNOPSIS .B kimchid -[\fB-h\fP|\fB--help\fP] [\fB--host\fP \fIhost\fP] [\fB--port\fP \fIport\fP] -[\fB--ssl-port\fP \fIssl_port\fP] [\fB--cherrypy_port\fP \fIcherrypy_port\fP] -[\fB--log-level\fP \fIlog_level\fP] [\fB--access-log\fP \fIaccess_log\fP] -[\fB--error-log\fP \fIerror_log\fP] [\fB--environment\fP \fIenvironment\fP] +[\fB-h\fP|\fB--help\fP] [\fB--proxy-port\fP \fIproxy_port\fP] +[\fB--cherrypy_port\fP \fIcherrypy_port\fP] [\fB--log-level\fP \fIlog_level\fP] +[\fB--access-log\fP \fIaccess_log\fP] [\fB--error-log\fP \fIerror_log\fP] +[\fB--environment\fP \fIenvironment\fP] .SH DESCRIPTION \fBKimchi\fP is an HTML5 based management tool for KVM. It is designed to make it as easy as possible to get started with KVM and create your first guest. @@ -19,13 +19,7 @@ The following options are supported: \fB\-h\fP , \fB\-\-help\fP Show this help message and exit. .TP -\fB\-\-host\fP \fIhost\fP -Specify the hostname or IP to listen on. -.TP -\fB\-\-port\fP \fIport\fP -Specify the HTTP port (default \fI8000\fP). -.TP -\fB\-\-ssl-port\fP \fIssl_port\fP +\fB\-\-proxy-port\fP \fIproxy_port\fP Specify the HTTPS port (default \fI8001\fP). .TP \fB\-\-cherrypy_port\fP \fIcherrypy_port\fP diff --git a/src/wok.conf.in b/src/wok.conf.in index 254f786..3806609 100644 --- a/src/wok.conf.in +++ b/src/wok.conf.in @@ -3,18 +3,8 @@ # [server] -# Hostname or IP address to listen on -#host = 0.0.0.0 - -# Port to listen on -#port = 8000 - # Start an SSL-enabled server on the given port -#ssl_port = 8001 - -# Allow user disables HTTP port. In that case, all the connections -# will be done directly through HTTPS port (values: true|false) -#https_only = false +#proxy_port = 8001 # Cherrypy server port #cherrypy_port = 8010 @@ -26,17 +16,6 @@ # terminates it automatically. #session_timeout = 10 -# The full path to an SSL Certificate or chain of certificates in -# PEM format. When a chain is used, the server's certificate must be -# the first certificate in the file with the chain concatenated into -# the end of that certificate. If left unspecified, Wok will generate -# a self-signed certificate automatically. -#ssl_cert = - -# The corresponding private key in PEM format for the SSL Certificate supplied -# above. If left blank, Wok will generate a self-signed certificate. -#ssl_key = - # Running environment of the server #environment = production diff --git a/src/wok/config.py.in b/src/wok/config.py.in index c48c46a..9573e66 100644 --- a/src/wok/config.py.in +++ b/src/wok/config.py.in @@ -262,15 +262,10 @@ class PluginConfig(dict): def _get_config(): config = SafeConfigParser() config.add_section("server") - config.set("server", "host", "0.0.0.0") - config.set("server", "port", "8000") - config.set("server", "ssl_port", "8001") - config.set("server", "https_only", "false") + config.set("server", "proxy_port", "8001") config.set("server", "cherrypy_port", "8010") config.set("server", "websockets_port", "64667") config.set("server", "session_timeout", "10") - config.set("server", "ssl_cert", "") - config.set("server", "ssl_key", "") config.set("server", "environment", "production") config.set('server', 'max_body_size', '4*1024*1024') config.set("server", "server_root", "") diff --git a/src/wok/model/config.py b/src/wok/model/config.py index 3748a6e..7e8ae4f 100644 --- a/src/wok/model/config.py +++ b/src/wok/model/config.py @@ -25,7 +25,7 @@ class ConfigModel(object): pass def lookup(self, name): - return {'ssl_port': config.get('server', 'ssl_port'), + return {'proxy_port': config.get('server', 'proxy_port'), 'websockets_port': config.get('server', 'websockets_port'), 'auth': config.get('authentication', 'method'), 'server_root': config.get('server', 'server_root'), diff --git a/src/wokd.in b/src/wokd.in index c1b302c..339e4e1 100644 --- a/src/wokd.in +++ b/src/wokd.in @@ -43,10 +43,7 @@ def main(options): if not os.geteuid() == 0: sys.exit("\nMust be root to run this script. Exiting ...\n") - host = config.config.get("server", "host") - port = config.config.get("server", "port") - ssl_port = config.config.get("server", "ssl_port") - https_only = config.config.get("server", "https_only") + proxy_port = config.config.get("server", "proxy_port") cherrypy_port = config.config.get("server", "cherrypy_port") websockets_port = config.config.get("server", "websockets_port") session_timeout = config.config.get("server", "session_timeout") @@ -56,15 +53,8 @@ def main(options): logLevel = config.config.get("logging", "log_level") parser = OptionParser() - parser.add_option('--host', type="string", default=host, - help="Hostname to listen on") - parser.add_option('--port', type="int", default=port, - help="Port to listen on (default %s)" % port) - parser.add_option('--ssl-port', type="int", default=ssl_port, - help="Port to enable SSL (default %s)" % ssl_port) - parser.add_option('--https_only', type="choice", default=https_only, - choices=['false', 'true'], - help="Disable HTTP port (default %s)" % ssl_port) + parser.add_option('--proxy-port', type="int", default=proxy_port, + help="Port to enable SSL (default %s)" % proxy_port) parser.add_option('--cherrypy_port', type="int", default=cherrypy_port, help="Cherrypy server port (default %s)" % cherrypy_port) parser.add_option('--websockets_port', type="int", default=websockets_port, @@ -98,8 +88,6 @@ def main(options): config.config.set(sec, item, str(getattr(options, item))) # Add non-option arguments - setattr(options, 'ssl_cert', config.config.get('server', 'ssl_cert')) - setattr(options, 'ssl_key', config.config.get('server', 'ssl_key')) setattr(options, 'max_body_size', config.config.get('server', 'max_body_size')) diff --git a/tests/test_api.py b/tests/test_api.py index c93aff0..23c263d 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -28,19 +28,13 @@ from wok.asynctask import AsyncTask test_server = None model = None -host = None -port = None -ssl_port = None def setUpModule(): - global test_server, model, host, port, ssl_port + global test_server, model utils.patch_auth() - host = '127.0.0.1' - port = utils.get_free_port('http') - ssl_port = utils.get_free_port('https') - test_server = utils.run_server(host, port, ssl_port, test_mode=True) + test_server = utils.run_server(test_mode=True) def tearDownModule(): @@ -50,12 +44,12 @@ def tearDownModule(): class APITests(unittest.TestCase): def setUp(self): - self.request = partial(utils.request, host, ssl_port) + self.request = partial(utils.request) def test_config(self): resp = self.request('/config').read() conf = json.loads(resp) - keys = ["auth", "ssl_port", "websockets_port", "version", + keys = ["auth", "proxy_port", "websockets_port", "version", "server_root"] self.assertEquals(sorted(keys), sorted(conf.keys())) diff --git a/tests/test_exception.py b/tests/test_exception.py index 31eca08..8dd20d8 100644 --- a/tests/test_exception.py +++ b/tests/test_exception.py @@ -22,25 +22,18 @@ import json import unittest -from utils import get_free_port, patch_auth, request, run_server +from utils import patch_auth, request, run_server test_server = None model = None -host = None -port = None -ssl_port = None def setup_server(environment='development'): - global test_server, model, host, port, ssl_port + global test_server, model patch_auth() - host = '127.0.0.1' - port = get_free_port('http') - ssl_port = get_free_port('https') - test_server = run_server(host, port, ssl_port, test_mode=True, - environment=environment) + test_server = run_server(test_mode=True, environment=environment) class ExceptionTests(unittest.TestCase): @@ -54,37 +47,26 @@ class ExceptionTests(unittest.TestCase): setup_server('production') # test 404 - resp = json.loads(request(host, ssl_port, '/tasks/blah').read()) + resp = json.loads(request('/tasks/blah').read()) self.assertEquals('404 Not Found', resp.get('code')) # test 405 wrong method - resp = json.loads(request(host, ssl_port, '/', None, 'DELETE').read()) + resp = json.loads(request('/', None, 'DELETE').read()) msg = u'WOKAPI0002E: Delete is not allowed for wokroot' self.assertEquals('405 Method Not Allowed', resp.get('code')) self.assertEquals(msg, resp.get('reason')) # test 400 parse error - resp = json.loads(request(host, ssl_port, '/tasks', '{', + resp = json.loads(request('/tasks', '{', 'POST').read()) msg = u'WOKAPI0006E: Unable to parse JSON request' self.assertEquals('400 Bad Request', resp.get('code')) self.assertEquals(msg, resp.get('reason')) self.assertNotIn('call_stack', resp) - # test 400 missing required parameter - # TODO: need add this test when some REST API from wok accepts POST -# req = json.dumps({}) -# resp = json.loads(request(host, ssl_port, '/tasks', req, -# 'POST').read()) -# self.assertEquals('400 Bad Request', resp.get('code')) -# m = u"KCHVM0016E: Specify a template to create a virtual machine from" -# self.assertEquals(m, resp.get('reason')) -# self.assertNotIn('call_stack', resp) - # test 405 method not allowed req = json.dumps({}) - resp = json.loads(request(host, ssl_port, '/tasks', req, - 'POST').read()) + resp = json.loads(request('/tasks', req, 'POST').read()) m = u"WOKAPI0005E: Create is not allowed for tasks" self.assertEquals('405 Method Not Allowed', resp.get('code')) self.assertEquals(m, resp.get('reason')) @@ -95,37 +77,25 @@ class ExceptionTests(unittest.TestCase): """ setup_server() # test 404 - resp = json.loads(request(host, ssl_port, '/tasks/blah').read()) + resp = json.loads(request('/tasks/blah').read()) self.assertEquals('404 Not Found', resp.get('code')) # test 405 wrong method - resp = json.loads(request(host, ssl_port, '/', None, 'DELETE').read()) + resp = json.loads(request('/', None, 'DELETE').read()) msg = u'WOKAPI0002E: Delete is not allowed for wokroot' self.assertEquals('405 Method Not Allowed', resp.get('code')) self.assertEquals(msg, resp.get('reason')) # test 400 parse error - resp = json.loads(request(host, ssl_port, '/tasks', '{', - 'POST').read()) + resp = json.loads(request('/tasks', '{', 'POST').read()) msg = u'WOKAPI0006E: Unable to parse JSON request' self.assertEquals('400 Bad Request', resp.get('code')) self.assertEquals(msg, resp.get('reason')) self.assertIn('call_stack', resp) - # test 400 missing required parameter - # TODO: need add this test when some REST API from wok accepts POST -# req = json.dumps({}) -# resp = json.loads(request(host, ssl_port, '/tasks', req, -# 'POST').read()) -# m = u"KCHVM0016E: Specify a template to create a virtual machine from" -# self.assertEquals('400 Bad Request', resp.get('code')) -# self.assertEquals(m, resp.get('reason')) -# self.assertIn('call_stack', resp) - # test 405 method not allowed req = json.dumps({}) - resp = json.loads(request(host, ssl_port, '/tasks', req, - 'POST').read()) + resp = json.loads(request('/tasks', req, 'POST').read()) m = u"WOKAPI0005E: Create is not allowed for tasks" self.assertEquals('405 Method Not Allowed', resp.get('code')) self.assertEquals(m, resp.get('reason')) diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 7c5e8e8..312412c 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -30,19 +30,13 @@ import utils test_server = None model = None -host = None -port = None -ssl_port = None def setUpModule(): - global test_server, model, host, port, ssl_port + global test_server, model utils.patch_auth() - host = '127.0.0.1' - port = utils.get_free_port('http') - ssl_port = utils.get_free_port('https') - test_server = utils.run_server(host, port, ssl_port, test_mode=True) + test_server = utils.run_server(test_mode=True) def tearDownModule(): @@ -55,7 +49,7 @@ def tearDownModule(): class PluginTests(unittest.TestCase): def setUp(self): - self.request = partial(utils.request, host, ssl_port) + self.request = partial(utils.request) def _create_rectangle(self, name, length, width): req = json.dumps({'name': name, 'length': length, 'width': width}) diff --git a/tests/test_server.py b/tests/test_server.py index 1f5a236..f1950e0 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -34,24 +34,15 @@ import utils test_server = None model = None -host = None -port = None -ssl_port = None -cherrypy_port = None tmpfile = None def setUpModule(): - global test_server, model, host, port, ssl_port, cherrypy_port, tmpfile + global test_server, model, tmpfile utils.patch_auth() tmpfile = tempfile.mktemp() - host = '127.0.0.1' - port = utils.get_free_port('http') - ssl_port = utils.get_free_port('https') - cherrypy_port = utils.get_free_port('cherrypy_port') - test_server = utils.run_server(host, port, ssl_port, test_mode=True, - cherrypy_port=cherrypy_port) + test_server = utils.run_server(test_mode=True) def tearDownModule(): @@ -60,7 +51,7 @@ def tearDownModule(): class ServerTests(unittest.TestCase): def setUp(self): - self.request = partial(utils.request, host, ssl_port) + self.request = partial(utils.request) def assertValidJSON(self, txt): try: diff --git a/tests/test_server_root.py b/tests/test_server_root.py index fb5cf6c..e95a13b 100644 --- a/tests/test_server_root.py +++ b/tests/test_server_root.py @@ -20,25 +20,18 @@ import json import unittest -from utils import get_free_port, patch_auth, request, run_server +from utils import patch_auth, request, run_server test_server = None model = None -host = None -port = None -ssl_port = None def setup_server(environment='development', server_root=''): - global test_server, model, host, port, ssl_port + global test_server, model patch_auth() - host = '127.0.0.1' - port = get_free_port('http') - ssl_port = get_free_port('https') - test_server = run_server(host, port, ssl_port, test_mode=True, - environment=environment, + test_server = run_server(test_mode=True, environment=environment, server_root=server_root) @@ -54,7 +47,7 @@ class ServerRootTests(unittest.TestCase): setup_server('production', server_root) # check if server_root in config is the same used to start server - resp = request(host, ssl_port, server_root + '/config').read() + resp = request(server_root + '/config').read() conf = json.loads(resp) self.assertEquals(len(conf), 5) @@ -66,6 +59,6 @@ class ServerRootTests(unittest.TestCase): setup_server(server_root=server_root) # check if server_root in config is the same used to start server - resp = request(host, ssl_port, server_root + '/config').read() + resp = request(server_root + '/config').read() conf = json.loads(resp) self.assertEquals(len(conf), 5) diff --git a/tests/utils.py b/tests/utils.py index d518f13..0c10ccb 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -25,25 +25,23 @@ import cherrypy import grp import httplib import inspect -import json import os -import socket import ssl import sys import threading import time import unittest -from contextlib import closing -from lxml import etree import wok.server -from wok.config import config, PluginPaths + from wok.auth import User, USER_NAME, USER_GROUPS, USER_ROLES, tabs +from wok.config import config from wok.exception import NotFoundError, OperationFailed from wok.utils import wok_log +HOST = '0.0.0.0' +PROXY_PORT = 8001 -_ports = {} fake_user = {'root': 'letmein!'} @@ -90,37 +88,15 @@ if sys.version_info[:2] == (2, 6): unittest.TestCase.assertNotIn = assertNotIn -def get_free_port(name='http'): - global _ports - if _ports.get(name) is not None: - return _ports[name] - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - with closing(sock): - try: - sock.bind(("0.0.0.0", 0)) - except: - raise Exception("Could not find a free port") - _ports[name] = sock.getsockname()[1] - return _ports[name] - - -def run_server(host, port, ssl_port, test_mode, cherrypy_port=None, - model=None, environment='development', server_root=''): - - if cherrypy_port is None: - cherrypy_port = get_free_port('cherrypy_port') - - if ssl_port is None: - ssl_port = get_free_port('https') +def run_server(test_mode, model=None, environment='dev', server_root=''): args = type('_', (object,), - {'host': host, 'port': port, 'ssl_port': ssl_port, - 'https_only': 'false', 'cherrypy_port': cherrypy_port, - 'websockets_port': 64667, 'ssl_cert': '', 'ssl_key': '', - 'max_body_size': '4*1024', 'test': test_mode, - 'access_log': '/dev/null', 'error_log': '/dev/null', - 'environment': environment, 'log_level': 'debug', - 'session_timeout': 10, 'server_root': server_root})() + {'cherrypy_port': 8010, 'max_body_size': '4*1024', + 'test': test_mode, 'access_log': '/dev/null', + 'error_log': '/dev/null', 'environment': environment, + 'log_level': 'debug', 'session_timeout': 10, + 'server_root': server_root})() + if model is not None: setattr(args, 'model', model) @@ -132,13 +108,6 @@ def run_server(host, port, ssl_port, test_mode, cherrypy_port=None, return s -def silence_server(): - """ - Silence server status messages on stdout - """ - cherrypy.config.update({"environment": "embedded"}) - - def running_as_root(): return os.geteuid() == 0 @@ -155,36 +124,17 @@ def _request(conn, path, data, method, headers): return conn.getresponse() -def request(host, port, path, data=None, method='GET', headers=None): +def request(path, data=None, method='GET', headers=None): # verify if HTTPSConnection has context parameter if "context" in inspect.getargspec(httplib.HTTPSConnection.__init__).args: context = ssl._create_unverified_context() - conn = httplib.HTTPSConnection(host, port, context=context) + conn = httplib.HTTPSConnection(HOST, PROXY_PORT, context=context) else: - conn = httplib.HTTPSConnection(host, port) + conn = httplib.HTTPSConnection(HOST, PROXY_PORT) return _request(conn, path, data, method, headers) -def get_remote_iso_path(): - """ - Get a remote iso with the right arch from the distro files shipped - with kimchi. - """ - host_arch = os.uname()[4] - remote_path = '' - with open(os.path.join(PluginPaths('kimchi').conf_dir, 'distros.d', - 'fedora.json')) as fedora_isos: - # Get a list of dicts - json_isos_list = json.load(fedora_isos) - for iso in json_isos_list: - if (iso.get('os_arch')) == host_arch: - remote_path = iso.get('path') - break - - return remote_path - - class FakeUser(User): auth_type = "fake" sudo = True @@ -224,11 +174,6 @@ def patch_auth(sudo=True): FakeUser.sudo = sudo -def normalize_xml(xml_str): - return etree.tostring(etree.fromstring(xml_str, - etree.XMLParser(remove_blank_text=True))) - - def wait_task(task_lookup, taskid, timeout=10): for i in range(0, timeout): task_info = task_lookup(taskid) -- 2.7.4

Reviewed-By: Ramon Medeiros <ramonn@br.ibm.com> On 11/10/2016 12:25 AM, Aline Manera wrote:
Aline Manera (6): Fix 'make check' issues Remove log size information from Wok config Add nginx.service as wokd.service dependency Generate SSL self signed certificate on package post installation script Bug fix #175: Do not generate nginx configuration file on the fly Remove nginx-specific parameters from wok.conf file
.gitignore | 1 - IBM-license-blacklist | 4 +- Makefile.am | 7 +- contrib/DEBIAN/control.in | 1 + contrib/DEBIAN/postinst | 1 + contrib/DEBIAN/postrm | 1 + contrib/Makefile.am | 2 +- contrib/wok.spec.fedora.in | 11 +-- contrib/wok.spec.suse.in | 41 ++++++---- contrib/wokd.service.fedora | 12 --- contrib/wokd.service.systemd | 14 ++++ docs/API/config.md | 4 +- docs/wokd.8.in | 16 ++-- src/nginx/Makefile.am | 7 +- src/nginx/wok.conf | 82 ++++++++++++++++++++ src/nginx/wok.conf.in | 75 ------------------ src/wok.conf.in | 23 +----- src/wok/config.py.in | 11 +-- src/wok/i18n.py | 2 - src/wok/model/config.py | 2 +- src/wok/plugins/sample/po/update-po | 2 +- src/wok/proxy.py | 147 ++++++++++-------------------------- src/wok/server.py | 6 +- src/wok/sslcert.py | 2 +- src/wokd.in | 18 +---- tests/test_api.py | 14 +--- tests/test_exception.py | 52 +++---------- tests/test_plugin.py | 12 +-- tests/test_server.py | 15 +--- tests/test_server_root.py | 17 ++--- tests/utils.py | 83 ++++---------------- 31 files changed, 242 insertions(+), 443 deletions(-) delete mode 100644 contrib/wokd.service.fedora create mode 100644 contrib/wokd.service.systemd create mode 100644 src/nginx/wok.conf delete mode 100644 src/nginx/wok.conf.in
-- Ramon Nunes Medeiros Kimchi Developer Linux Technology Center Brazil IBM Systems & Technology Group Phone : +55 19 2132 7878 ramonn@br.ibm.com

Reviewed-By: Lucio Correia <luciojhc@linux.vnet.ibm.com> On 10/11/2016 00:25, Aline Manera wrote:
Aline Manera (6): Fix 'make check' issues Remove log size information from Wok config Add nginx.service as wokd.service dependency Generate SSL self signed certificate on package post installation script Bug fix #175: Do not generate nginx configuration file on the fly Remove nginx-specific parameters from wok.conf file
.gitignore | 1 - IBM-license-blacklist | 4 +- Makefile.am | 7 +- contrib/DEBIAN/control.in | 1 + contrib/DEBIAN/postinst | 1 + contrib/DEBIAN/postrm | 1 + contrib/Makefile.am | 2 +- contrib/wok.spec.fedora.in | 11 +-- contrib/wok.spec.suse.in | 41 ++++++---- contrib/wokd.service.fedora | 12 --- contrib/wokd.service.systemd | 14 ++++ docs/API/config.md | 4 +- docs/wokd.8.in | 16 ++-- src/nginx/Makefile.am | 7 +- src/nginx/wok.conf | 82 ++++++++++++++++++++ src/nginx/wok.conf.in | 75 ------------------ src/wok.conf.in | 23 +----- src/wok/config.py.in | 11 +-- src/wok/i18n.py | 2 - src/wok/model/config.py | 2 +- src/wok/plugins/sample/po/update-po | 2 +- src/wok/proxy.py | 147 ++++++++++-------------------------- src/wok/server.py | 6 +- src/wok/sslcert.py | 2 +- src/wokd.in | 18 +---- tests/test_api.py | 14 +--- tests/test_exception.py | 52 +++---------- tests/test_plugin.py | 12 +-- tests/test_server.py | 15 +--- tests/test_server_root.py | 17 ++--- tests/utils.py | 83 ++++---------------- 31 files changed, 242 insertions(+), 443 deletions(-) delete mode 100644 contrib/wokd.service.fedora create mode 100644 contrib/wokd.service.systemd create mode 100644 src/nginx/wok.conf delete mode 100644 src/nginx/wok.conf.in
-- Lucio Correia Software Engineer IBM LTC Brazil

Reviewed-By: Lucio Correia <luciojhc@linux.vnet.ibm.com> On 10/11/2016 00:25, Aline Manera wrote:
Aline Manera (6): Fix 'make check' issues Remove log size information from Wok config Add nginx.service as wokd.service dependency Generate SSL self signed certificate on package post installation script Bug fix #175: Do not generate nginx configuration file on the fly Remove nginx-specific parameters from wok.conf file
.gitignore | 1 - IBM-license-blacklist | 4 +- Makefile.am | 7 +- contrib/DEBIAN/control.in | 1 + contrib/DEBIAN/postinst | 1 + contrib/DEBIAN/postrm | 1 + contrib/Makefile.am | 2 +- contrib/wok.spec.fedora.in | 11 +-- contrib/wok.spec.suse.in | 41 ++++++---- contrib/wokd.service.fedora | 12 --- contrib/wokd.service.systemd | 14 ++++ docs/API/config.md | 4 +- docs/wokd.8.in | 16 ++-- src/nginx/Makefile.am | 7 +- src/nginx/wok.conf | 82 ++++++++++++++++++++ src/nginx/wok.conf.in | 75 ------------------ src/wok.conf.in | 23 +----- src/wok/config.py.in | 11 +-- src/wok/i18n.py | 2 - src/wok/model/config.py | 2 +- src/wok/plugins/sample/po/update-po | 2 +- src/wok/proxy.py | 147 ++++++++++-------------------------- src/wok/server.py | 6 +- src/wok/sslcert.py | 2 +- src/wokd.in | 18 +---- tests/test_api.py | 14 +--- tests/test_exception.py | 52 +++---------- tests/test_plugin.py | 12 +-- tests/test_server.py | 15 +--- tests/test_server_root.py | 17 ++--- tests/utils.py | 83 ++++---------------- 31 files changed, 242 insertions(+), 443 deletions(-) delete mode 100644 contrib/wokd.service.fedora create mode 100644 contrib/wokd.service.systemd create mode 100644 src/nginx/wok.conf delete mode 100644 src/nginx/wok.conf.in
-- Lucio Correia Software Engineer IBM LTC Brazil

Reviewed-By: Lucio Correia <luciojhc@linux.vnet.ibm.com> On 10/11/2016 00:25, Aline Manera wrote:
Aline Manera (6): Fix 'make check' issues Remove log size information from Wok config Add nginx.service as wokd.service dependency Generate SSL self signed certificate on package post installation script Bug fix #175: Do not generate nginx configuration file on the fly Remove nginx-specific parameters from wok.conf file
.gitignore | 1 - IBM-license-blacklist | 4 +- Makefile.am | 7 +- contrib/DEBIAN/control.in | 1 + contrib/DEBIAN/postinst | 1 + contrib/DEBIAN/postrm | 1 + contrib/Makefile.am | 2 +- contrib/wok.spec.fedora.in | 11 +-- contrib/wok.spec.suse.in | 41 ++++++---- contrib/wokd.service.fedora | 12 --- contrib/wokd.service.systemd | 14 ++++ docs/API/config.md | 4 +- docs/wokd.8.in | 16 ++-- src/nginx/Makefile.am | 7 +- src/nginx/wok.conf | 82 ++++++++++++++++++++ src/nginx/wok.conf.in | 75 ------------------ src/wok.conf.in | 23 +----- src/wok/config.py.in | 11 +-- src/wok/i18n.py | 2 - src/wok/model/config.py | 2 +- src/wok/plugins/sample/po/update-po | 2 +- src/wok/proxy.py | 147 ++++++++++-------------------------- src/wok/server.py | 6 +- src/wok/sslcert.py | 2 +- src/wokd.in | 18 +---- tests/test_api.py | 14 +--- tests/test_exception.py | 52 +++---------- tests/test_plugin.py | 12 +-- tests/test_server.py | 15 +--- tests/test_server_root.py | 17 ++--- tests/utils.py | 83 ++++---------------- 31 files changed, 242 insertions(+), 443 deletions(-) delete mode 100644 contrib/wokd.service.fedora create mode 100644 contrib/wokd.service.systemd create mode 100644 src/nginx/wok.conf delete mode 100644 src/nginx/wok.conf.in
-- Lucio Correia Software Engineer IBM LTC Brazil

Applied. Thanks. Regards, Aline Manera
participants (3)
-
Aline Manera
-
Lucio Correia
-
Ramon Medeiros