Merge lp:~corey.bryant/charm-helpers/wsgi into lp:charm-helpers

Proposed by Corey Bryant
Status: Merged
Merged at revision: 670
Proposed branch: lp:~corey.bryant/charm-helpers/wsgi
Merge into: lp:charm-helpers
Diff against target: 294 lines (+232/-0)
5 files modified
charmhelpers/contrib/openstack/context.py (+40/-0)
charmhelpers/contrib/openstack/templates/wsgi-openstack-api.conf (+100/-0)
charmhelpers/contrib/openstack/utils.py (+29/-0)
tests/contrib/openstack/test_openstack_utils.py (+34/-0)
tests/contrib/openstack/test_os_contexts.py (+29/-0)
To merge this branch: bzr merge lp:~corey.bryant/charm-helpers/wsgi
Reviewer Review Type Date Requested Status
Liam Young (community) Approve
charmers Pending
Review via email: mp+312947@code.launchpad.net

Commit message

Add WSGI context and template for OpenStack APIs

To post a comment you must log in.
lp:~corey.bryant/charm-helpers/wsgi updated
667. By Liam Young

[gnuoy, r=ajkavanagh] Fixes for amulet memcache service checks.
1) Use 'service' not 'status' for checking status of memcached on pre-systemd systems as its not an upstart script.
2) Trusty memcache uses ip6-localhost as its listen address because it does not understand ::1

668. By Stuart Bishop

[hloeung,r=stub] Add timeout to rsync and capture rsync error messages

669. By Liam Young

[gnuoy, r=ajkavanagh] Add option package var to Memcache context to allow contect to lookup Openstack release without using Openstack-origin which may not be present. enable_memcache also had to be extended to take a package option to support this

Revision history for this message
Liam Young (gnuoy) wrote :

It looks good but needs unit tests for the new context and methods

review: Needs Fixing
lp:~corey.bryant/charm-helpers/wsgi updated
670. By Corey Bryant

Add WSGI context and template for OpenStack APIs

671. By Corey Bryant

Add unit test for WSGI context.

672. By Corey Bryant

Add unit test for git_determine_*()

Revision history for this message
Corey Bryant (corey.bryant) wrote :

Thanks for the review Liam. I've added unit tests.

Revision history for this message
Liam Young (gnuoy) wrote :

LGTM, thanks

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'charmhelpers/contrib/openstack/context.py'
--- charmhelpers/contrib/openstack/context.py 2016-12-14 15:10:32 +0000
+++ charmhelpers/contrib/openstack/context.py 2016-12-14 18:51:33 +0000
@@ -14,6 +14,7 @@
1414
15import glob15import glob
16import json16import json
17import math
17import os18import os
18import re19import re
19import time20import time
@@ -90,6 +91,8 @@
90from charmhelpers.contrib.openstack.utils import (91from charmhelpers.contrib.openstack.utils import (
91 config_flags_parser,92 config_flags_parser,
92 get_host_ip,93 get_host_ip,
94 git_determine_usr_bin,
95 git_determine_python_path,
93 enable_memcache,96 enable_memcache,
94)97)
95from charmhelpers.core.unitdata import kv98from charmhelpers.core.unitdata import kv
@@ -1208,6 +1211,43 @@
1208 return ctxt1211 return ctxt
12091212
12101213
1214class WSGIWorkerConfigContext(WorkerConfigContext):
1215
1216 def __init__(self, name=None, script=None, admin_script=None,
1217 public_script=None, process_weight=1.00,
1218 admin_process_weight=0.75, public_process_weight=0.25):
1219 self.service_name = name
1220 self.user = name
1221 self.group = name
1222 self.script = script
1223 self.admin_script = admin_script
1224 self.public_script = public_script
1225 self.process_weight = process_weight
1226 self.admin_process_weight = admin_process_weight
1227 self.public_process_weight = public_process_weight
1228
1229 def __call__(self):
1230 multiplier = config('worker-multiplier') or 1
1231 total_processes = self.num_cpus * multiplier
1232 ctxt = {
1233 "service_name": self.service_name,
1234 "user": self.user,
1235 "group": self.group,
1236 "script": self.script,
1237 "admin_script": self.admin_script,
1238 "public_script": self.public_script,
1239 "processes": int(math.ceil(self.process_weight * total_processes)),
1240 "admin_processes": int(math.ceil(self.admin_process_weight *
1241 total_processes)),
1242 "public_processes": int(math.ceil(self.public_process_weight *
1243 total_processes)),
1244 "threads": 1,
1245 "usr_bin": git_determine_usr_bin(),
1246 "python_path": git_determine_python_path(),
1247 }
1248 return ctxt
1249
1250
1211class ZeroMQContext(OSContextGenerator):1251class ZeroMQContext(OSContextGenerator):
1212 interfaces = ['zeromq-configuration']1252 interfaces = ['zeromq-configuration']
12131253
12141254
=== added file 'charmhelpers/contrib/openstack/templates/wsgi-openstack-api.conf'
--- charmhelpers/contrib/openstack/templates/wsgi-openstack-api.conf 1970-01-01 00:00:00 +0000
+++ charmhelpers/contrib/openstack/templates/wsgi-openstack-api.conf 2016-12-14 18:51:33 +0000
@@ -0,0 +1,100 @@
1# Configuration file maintained by Juju. Local changes may be overwritten.
2
3{% if port -%}
4Listen {{ port }}
5{% endif -%}
6
7{% if admin_port -%}
8Listen {{ admin_port }}
9{% endif -%}
10
11{% if public_port -%}
12Listen {{ public_port }}
13{% endif -%}
14
15{% if port -%}
16<VirtualHost *:{{ port }}>
17 WSGIDaemonProcess {{ service_name }} processes={{ processes }} threads={{ threads }} user={{ service_name }} group={{ service_name }} \
18{% if python_path -%}
19 python-path={{ python_path }} \
20{% endif -%}
21 display-name=%{GROUP}
22 WSGIProcessGroup {{ service_name }}
23 WSGIScriptAlias / {{ script }}
24 WSGIApplicationGroup %{GLOBAL}
25 WSGIPassAuthorization On
26 <IfVersion >= 2.4>
27 ErrorLogFormat "%{cu}t %M"
28 </IfVersion>
29 ErrorLog /var/log/apache2/{{ service_name }}_error.log
30 CustomLog /var/log/apache2/{{ service_name }}_access.log combined
31
32 <Directory {{ usr_bin }}>
33 <IfVersion >= 2.4>
34 Require all granted
35 </IfVersion>
36 <IfVersion < 2.4>
37 Order allow,deny
38 Allow from all
39 </IfVersion>
40 </Directory>
41</VirtualHost>
42{% endif -%}
43
44{% if admin_port -%}
45<VirtualHost *:{{ admin_port }}>
46 WSGIDaemonProcess {{ service_name }}-admin processes={{ admin_processes }} threads={{ threads }} user={{ service_name }} group={{ service_name }} \
47{% if python_path -%}
48 python-path={{ python_path }} \
49{% endif -%}
50 display-name=%{GROUP}
51 WSGIProcessGroup {{ service_name }}-admin
52 WSGIScriptAlias / {{ admin_script }}
53 WSGIApplicationGroup %{GLOBAL}
54 WSGIPassAuthorization On
55 <IfVersion >= 2.4>
56 ErrorLogFormat "%{cu}t %M"
57 </IfVersion>
58 ErrorLog /var/log/apache2/{{ service_name }}_error.log
59 CustomLog /var/log/apache2/{{ service_name }}_access.log combined
60
61 <Directory {{ usr_bin }}>
62 <IfVersion >= 2.4>
63 Require all granted
64 </IfVersion>
65 <IfVersion < 2.4>
66 Order allow,deny
67 Allow from all
68 </IfVersion>
69 </Directory>
70</VirtualHost>
71{% endif -%}
72
73{% if public_port -%}
74<VirtualHost *:{{ public_port }}>
75 WSGIDaemonProcess {{ service_name }}-public processes={{ public_processes }} threads={{ threads }} user={{ service_name }} group={{ service_name }} \
76{% if python_path -%}
77 python-path={{ python_path }} \
78{% endif -%}
79 display-name=%{GROUP}
80 WSGIProcessGroup {{ service_name }}-public
81 WSGIScriptAlias / {{ public_script }}
82 WSGIApplicationGroup %{GLOBAL}
83 WSGIPassAuthorization On
84 <IfVersion >= 2.4>
85 ErrorLogFormat "%{cu}t %M"
86 </IfVersion>
87 ErrorLog /var/log/apache2/{{ service_name }}_error.log
88 CustomLog /var/log/apache2/{{ service_name }}_access.log combined
89
90 <Directory {{ usr_bin }}>
91 <IfVersion >= 2.4>
92 Require all granted
93 </IfVersion>
94 <IfVersion < 2.4>
95 Order allow,deny
96 Allow from all
97 </IfVersion>
98 </Directory>
99</VirtualHost>
100{% endif -%}
0101
=== modified file 'charmhelpers/contrib/openstack/utils.py'
--- charmhelpers/contrib/openstack/utils.py 2016-12-14 15:46:41 +0000
+++ charmhelpers/contrib/openstack/utils.py 2016-12-14 18:51:33 +0000
@@ -1119,6 +1119,35 @@
1119 shutil.copyfile(service_source, service_dest)1119 shutil.copyfile(service_source, service_dest)
11201120
11211121
1122def git_determine_usr_bin():
1123 """Return the /usr/bin path for Apache2 config.
1124
1125 The /usr/bin path will be located in the virtualenv if the charm
1126 is configured to deploy from source.
1127 """
1128 if git_install_requested():
1129 projects_yaml = config('openstack-origin-git')
1130 projects_yaml = git_default_repos(projects_yaml)
1131 return os.path.join(git_pip_venv_dir(projects_yaml), 'bin')
1132 else:
1133 return '/usr/bin'
1134
1135
1136def git_determine_python_path():
1137 """Return the python-path for Apache2 config.
1138
1139 Returns 'None' unless the charm is configured to deploy from source,
1140 in which case the path of the virtualenv's site-packages is returned.
1141 """
1142 if git_install_requested():
1143 projects_yaml = config('openstack-origin-git')
1144 projects_yaml = git_default_repos(projects_yaml)
1145 return os.path.join(git_pip_venv_dir(projects_yaml),
1146 'lib/python2.7/site-packages')
1147 else:
1148 return None
1149
1150
1122def os_workload_status(configs, required_interfaces, charm_func=None):1151def os_workload_status(configs, required_interfaces, charm_func=None):
1123 """1152 """
1124 Decorator to set workload status based on complete contexts1153 Decorator to set workload status based on complete contexts
11251154
=== modified file 'tests/contrib/openstack/test_openstack_utils.py'
--- tests/contrib/openstack/test_openstack_utils.py 2016-09-16 09:50:01 +0000
+++ tests/contrib/openstack/test_openstack_utils.py 2016-12-14 18:51:33 +0000
@@ -933,6 +933,40 @@
933 openstack.git_src_dir(openstack_origin_git, 'keystone')933 openstack.git_src_dir(openstack_origin_git, 'keystone')
934 join.assert_called_with('/mnt/openstack-git', 'keystone')934 join.assert_called_with('/mnt/openstack-git', 'keystone')
935935
936 @patch.object(openstack, 'config')
937 def test_git_determine_usr_bin(self, config):
938 config.return_value = None
939 result = openstack.git_determine_usr_bin()
940 self.assertEquals(result, '/usr/bin')
941
942 @patch('os.path.join')
943 @patch.object(openstack, 'git_default_repos')
944 @patch.object(openstack, 'config')
945 def test_git_determine_usr_bin_git(self, config, git_default, join):
946 venv_bin = '/mnt/openstack/.venv/bin'
947 join.return_value = venv_bin
948 config.return_value = openstack_origin_git
949 git_default.return_value = openstack_origin_git
950 result = openstack.git_determine_usr_bin()
951 self.assertEquals(result, venv_bin)
952
953 @patch.object(openstack, 'config')
954 def test_git_determine_python_path(self, config):
955 config.return_value = None
956 result = openstack.git_determine_python_path()
957 self.assertEquals(result, None)
958
959 @patch('os.path.join')
960 @patch.object(openstack, 'git_default_repos')
961 @patch.object(openstack, 'config')
962 def test_git_determine_python_path_git(self, config, git_default, join):
963 venv_site = '/mnt/openstack/.venv/lib/python2.7/site-packages'
964 join.return_value = venv_site
965 config.return_value = openstack_origin_git
966 git_default.return_value = openstack_origin_git
967 result = openstack.git_determine_python_path()
968 self.assertEquals(result, venv_site)
969
936 def test_incomplete_relation_data(self):970 def test_incomplete_relation_data(self):
937 configs = MagicMock()971 configs = MagicMock()
938 configs.complete_contexts.return_value = ['pgsql-db', 'amqp']972 configs.complete_contexts.return_value = ['pgsql-db', 'amqp']
939973
=== modified file 'tests/contrib/openstack/test_os_contexts.py'
--- tests/contrib/openstack/test_os_contexts.py 2016-12-09 16:48:53 +0000
+++ tests/contrib/openstack/test_os_contexts.py 2016-12-14 18:51:33 +0000
@@ -2371,6 +2371,35 @@
2371 }2371 }
2372 self.assertEquals(result, expected)2372 self.assertEquals(result, expected)
23732373
2374 @patch.object(context, 'psutil')
2375 @patch.object(context, 'git_determine_python_path')
2376 @patch.object(context, 'git_determine_usr_bin')
2377 def test_wsgi_worker_config_context(self, usr_bin, python_path, psutil):
2378 self.config.return_value = 2 # worker-multiplier=2
2379 usr_bin_path = '/usr/bin'
2380 usr_bin.return_value = usr_bin_path
2381 python_path.return_value = None
2382 psutil.cpu_count.return_value = 4
2383 service_name = 'service-name'
2384 script = '/usr/bin/script'
2385 ctxt = context.WSGIWorkerConfigContext(name=service_name,
2386 script=script)
2387 expect = {
2388 "service_name": service_name,
2389 "user": service_name,
2390 "group": service_name,
2391 "script": script,
2392 "admin_script": None,
2393 "public_script": None,
2394 "processes": 8,
2395 "admin_processes": 6,
2396 "public_processes": 2,
2397 "threads": 1,
2398 "usr_bin": usr_bin_path,
2399 "python_path": None,
2400 }
2401 self.assertEqual(expect, ctxt())
2402
2374 def test_zeromq_context_unrelated(self):2403 def test_zeromq_context_unrelated(self):
2375 self.is_relation_made.return_value = False2404 self.is_relation_made.return_value = False
2376 self.assertEquals(context.ZeroMQContext()(), {})2405 self.assertEquals(context.ZeroMQContext()(), {})

Subscribers

People subscribed via source and target branches