Changeset - c8d4251a6ea5
[Not reviewed]
0 11 0
Branko Majic (branko) - 6 years ago 2018-07-30 12:54:28
branko@majic.rs
MAR-131: Added support for specifying Python version in wsgi_website role:

- Introduced additional role parameter for specifying the Python
version.
- Updated tests to verify new functionality.
- Fixed existing tests to account for differences between Python 2 and
Python 3 - including changes to WSGI test applications.
- Updated documentation, documenting new parameter and fixing one
minor typo.
- Updated release notes.
- Bumped default version of Gunicorn/futures used.
11 files changed with 57 insertions and 12 deletions:
0 comments (0 inline, 0 general)
docs/releasenotes.rst
Show inline comments
 
@@ -39,6 +39,11 @@ New features/improvements:
 
    check. E.g. mails are sent out only in case some of the configured
 
    certificates will expire within next 30 days.
 

	
 
* ``wsgi_website`` role
 

	
 
  * Support for specifying Python version for Python virtual
 
    environment.
 

	
 

	
 
2.0.0
 
-----
docs/rolereference.rst
Show inline comments
 
@@ -1645,9 +1645,10 @@ The role implements the following:
 
* Adds website administrator to website's group, so administrator could manage
 
  the code and data.
 
* Installs additional packages required for running the role (as configured).
 
* Sets-up a dedicated Python virtual environment for website.
 
* Sets-up a dedicated Python virtual environment for website. Python
 
  version can be specified (default is Python 2).
 
* Install ``futures`` package in Python virtual environment (required for
 
  Gunicorn in combination withg Python 2.7).
 
  Gunicorn in combination with Python 2.7).
 
* Install Gunicorn in Python virtual environment.
 
* Installs additional packages required for running the role in Python virtual
 
  environment (as configured).
 
@@ -1758,11 +1759,11 @@ Parameters
 
  for calculating the user/group name for dedicated website user, as well as
 
  home directory of the website user (where data/code should be stored at).
 

	
 
**futures_version** (string, optional, ``3.1.1``)
 
**futures_version** (string, optional, ``3.2.0``)
 
  Version of ``futures`` package to deploy in virtual environment. Required by
 
  Gunicorn when using Python 2.7. Default version is tested with the test site.
 

	
 
**gunicorn_version** (string, optional, ``19.7.1``)
 
**gunicorn_version** (string, optional, ``19.9.0``)
 
  Version of Gunicorn to deploy in virtual environment for running the WSGI
 
  application. Default version is tested with the test site.
 

	
 
@@ -1786,6 +1787,9 @@ Parameters
 
  forget to surround them by another set of quotes for YAML syntax, for example
 
  ``"\"\""`` or ``'""'``).
 

	
 
**python_version** (string, optional, ``2``)
 
  Python version to use when setting-up the Python virtual environment.
 

	
 
**rewrites** (list, optional, ``[]``)
 
  A list of rewrite rules that are applied to incoming requests. Each element of
 
  the list should be a string value compatible with the format of ``nginx``
roles/wsgi_website/defaults/main.yml
Show inline comments
 
@@ -10,14 +10,16 @@ virtualenv_packages: []
 
environment_variables: {}
 
https_tls_certificate: "{{ lookup('file', tls_certificate_dir + '/' + fqdn + '_https.pem') }}"
 
https_tls_key: "{{ lookup('file', tls_private_key_dir + '/' + fqdn + '_https.key') }}"
 
gunicorn_version: "19.7.1"
 
futures_version: "3.1.1"
 
gunicorn_version: "19.9.0"
 
futures_version: "3.2.0"
 
website_mail_recipients: "root"
 
environment_indicator: null
 
proxy_headers: {}
 
python_version: 2
 
wsgi_requirements: []
 

	
 
# Internal parameters.
 
admin: "admin-{{ fqdn | replace('.', '_') }}"
 
user: "web-{{ fqdn | replace('.', '_') }}"
 
home: "/var/www/{{ fqdn }}"
 
python_interpreter: "/usr/bin/python{{ python_version }}"
roles/wsgi_website/molecule/default/playbook.yml
Show inline comments
 
@@ -57,6 +57,7 @@
 
      website_mail_recipients: user
 
      wsgi_application: testapp:application
 
      wsgi_requirements: []
 
      python_version: 3
 

	
 
    - role: wsgi_website
 
      fqdn: parameters-paste-req
roles/wsgi_website/molecule/default/tests/data/python/paste/testapp.py
Show inline comments
 
import os
 
import sys
 

	
 
import flask
 

	
 
from flask import Flask
 
@@ -20,6 +22,7 @@ def index(path):
 
    <p>Requested URL was: {scheme}://{host}{script}{path}
 
    <p>MY_ENV_VAR: {my_env_var}</p>
 
    <p>Accept-Encoding: {accept_encoding}</p>
 
    <p>Python version: {python_version}</p>
 
  </body>
 
</html>
 
"""
 
@@ -33,6 +36,7 @@ def index(path):
 
    parameters['path'] = environ['PATH_INFO']
 
    parameters['my_env_var'] = os.environ.get('MY_ENV_VAR', None)
 
    parameters['accept_encoding'] = environ.get('HTTP_ACCEPT_ENCODING')
 
    parameters['python_version'] = "%s.%s.%s" % (sys.version_info.major, sys.version_info.minor, sys.version_info.micro)
 

	
 
    output = template.format(**parameters)
 

	
roles/wsgi_website/molecule/default/tests/data/python/wsgi/testapp.py
Show inline comments
 
#!/usr/bin/env python
 

	
 
import os
 
import sys
 

	
 

	
 
def application(environ, start_response):
 
@@ -17,6 +18,7 @@ def application(environ, start_response):
 
    <p>Requested URL was: {scheme}://{host}{script}{path}
 
    <p>MY_ENV_VAR: {my_env_var}</p>
 
    <p>Accept-Encoding: {accept_encoding}</p>
 
    <p>Python version: {python_version}</p>
 
  </body>
 
</html>
 
"""
 
@@ -28,6 +30,7 @@ def application(environ, start_response):
 
    parameters['path'] = environ['PATH_INFO']
 
    parameters['my_env_var'] = os.environ.get('MY_ENV_VAR', None)
 
    parameters['accept_encoding'] = environ.get('HTTP_ACCEPT_ENCODING')
 
    parameters['python_version'] = "%s.%s.%s" % (sys.version_info.major, sys.version_info.minor, sys.version_info.micro)
 

	
 
    output = template.format(**parameters)
 

	
 
@@ -35,4 +38,4 @@ def application(environ, start_response):
 
                        ('Content-Length', str(len(output)))]
 
    start_response(status, response_headers)
 

	
 
    return [output]
 
    return [output.encode('utf-8')]
roles/wsgi_website/molecule/default/tests/test_default.py
Show inline comments
 
@@ -298,13 +298,12 @@ def test_python_virtualenv_wrapper_script(host, wrapper_script, expected_owner,
 
@pytest.mark.parametrize("admin_user, pip_path, expected_packages",  [
 
    ('admin-parameters-mandatory', '/var/www/parameters-mandatory/virtualenv/bin/pip', [
 
        "argparse==1.2.1",
 
        "futures==3.1.1",
 
        "gunicorn==19.7.1",
 
        "futures==3.2.0",
 
        "gunicorn==19.9.0",
 
        "wsgiref==0.1.2"
 
    ]),
 
    ('admin-parameters-optional_local', '/var/www/parameters-optional.local/virtualenv/bin/pip', [
 
        "Pygments==2.2.0",
 
        "argparse==1.2.1",
 
        "dnspython==1.15.0",
 
        "docopt==0.6.2",
 
        "futures==3.1.0",
 
@@ -315,7 +314,6 @@ def test_python_virtualenv_wrapper_script(host, wrapper_script, expected_owner,
 
        "ptpython==0.41",
 
        "six==1.11.0",
 
        "wcwidth==0.1.7",
 
        "wsgiref==0.1.2"
 
    ]),
 
    ('admin-parameters-paste-req', '/var/www/parameters-paste-req/virtualenv/bin/pip', [
 
        "Flask==0.12.2",
 
@@ -538,3 +536,28 @@ def test_website_enabled(host, config_file, expected_content):
 

	
 
    assert config.is_symlink
 
    assert config.linked_to == expected_content
 

	
 

	
 
@pytest.mark.parametrize("python_path, expected_version_startswith", [
 
    ("/var/www/parameters-mandatory/virtualenv/bin/python", "Python 2"),
 
    ("/var/www/parameters-optional.local/virtualenv/bin/python", "Python 3"),
 
    ("/var/www/parameters-paste-req/virtualenv/bin/python", "Python 2"),
 
])
 
def test_python_version_in_virtualenv(host, python_path, expected_version_startswith):
 
    """
 
    Tests if correct Python version is used inside of virtual
 
    environment.
 
    """
 

	
 
    with host.sudo():
 

	
 
        python_version = host.run(python_path + " --version")
 

	
 
        # Python 2 outputs version to stderr, Python 3 outputs it to
 
        # stdout. Go figure.
 
        python_version_output = python_version.stdout + python_version.stderr
 

	
 
        assert python_version.rc == 0
 

	
 
        # Python binary prints out version to stderr.
 
        assert python_version_output.startswith(expected_version_startswith)
roles/wsgi_website/molecule/default/tests/test_parameters_mandatory.py
Show inline comments
 
@@ -42,6 +42,7 @@ def test_index_page(host):
 
    assert "Requested URL was: https://parameters-mandatory/" in page.stdout
 
    assert "MY_ENV_VAR: None" in page.stdout
 
    assert "Accept-Encoding: plain" in page.stdout
 
    assert "Python version: 2." in page.stdout
 

	
 

	
 
def test_static_file_serving(host):
roles/wsgi_website/molecule/default/tests/test_parameters_optional.py
Show inline comments
 
@@ -63,6 +63,7 @@ def test_index_page(host):
 
    assert "Requested URL was: https://parameters-optional.local/" in page.stdout
 
    assert "MY_ENV_VAR: My environment variable" in page.stdout
 
    assert "Accept-Encoding: None" in page.stdout
 
    assert "Python version: 3." in page.stdout
 

	
 

	
 
def test_static_file_serving(host):
roles/wsgi_website/molecule/default/tests/test_parameters_paste_req.py
Show inline comments
 
@@ -68,6 +68,7 @@ def test_index_page(host):
 
    assert "Requested URL was: https://parameters-paste-req/" in page.stdout
 
    assert "MY_ENV_VAR: None" in page.stdout
 
    assert "Accept-Encoding: plain" in page.stdout
 
    assert "Python version: 2." in page.stdout
 

	
 

	
 
def test_static_file_serving(host):
roles/wsgi_website/tasks/main.yml
Show inline comments
 
@@ -94,7 +94,7 @@
 
    mode: 02750
 

	
 
- name: Create Python virtual environment
 
  command: '/usr/bin/virtualenv --prompt "({{ fqdn }})" "{{ home }}/virtualenv"'
 
  command: '/usr/bin/virtualenv --python "{{ python_interpreter }}" --prompt "({{ fqdn }})" "{{ home }}/virtualenv"'
 
  args:
 
    creates: "{{ home }}/virtualenv/bin/activate"
 
  become: true
0 comments (0 inline, 0 general)