Merge lp:~james-page/charms/precise/quantum-gateway/ha-fixes into lp:~openstack-charmers/charms/precise/quantum-gateway/ha-support

Proposed by James Page
Status: Merged
Approved by: Adam Gandelman
Approved revision: 62
Merged at revision: 53
Proposed branch: lp:~james-page/charms/precise/quantum-gateway/ha-fixes
Merge into: lp:~openstack-charmers/charms/precise/quantum-gateway/ha-support
Diff against target: 436 lines (+57/-193)
8 files modified
config.yaml (+1/-0)
hooks/hooks.py (+34/-53)
hooks/quantum_utils.py (+2/-45)
hooks/utils.py (+16/-85)
metadata.yaml (+1/-7)
templates/nova.conf (+1/-1)
templates/ovs_quantum_plugin.ini (+1/-1)
templates/quantum.conf (+1/-1)
To merge this branch: bzr merge lp:~james-page/charms/precise/quantum-gateway/ha-fixes
Reviewer Review Type Date Requested Status
OpenStack Charmers Pending
Review via email: mp+152682@code.launchpad.net

Description of the change

Quantum has undergone some refactoring upstream and now includes a scheduler which spread dhcp and l3 agent services across all gateway nodes.

This invalidates the original HA approach; HA was on the plan for the scheduler - trying to find out if it will make grizzly.

Other than that fixed up a few other minor issues and added support for HTTPS on the quantum API service itself.

To post a comment you must log in.
Revision history for this message
Adam Gandelman (gandelman-a) wrote :

James-

This looks good to me, but I can't seem to actually push the merge back?

$ bzr push :parent
bzr: ERROR: Cannot lock LockDir(chroot-93200144:///~openstack-charmers/charms/precise/quantum-gateway/ha-support/.bzr/branch/lock): Transport operation not possible: readonly transport

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'config.yaml'
--- config.yaml 2013-01-18 10:09:25 +0000
+++ config.yaml 2013-03-11 14:16:22 +0000
@@ -7,6 +7,7 @@
7 Supported values include:7 Supported values include:
8 .8 .
9 ovs - OpenVSwitch9 ovs - OpenVSwitch
10 nvp - Nicira Network Virtualization Platform
10 ext-port:11 ext-port:
11 type: string12 type: string
12 description: |13 description: |
1314
=== removed symlink 'hooks/cluster-relation-changed'
=== target was u'hooks.py'
=== modified file 'hooks/hooks.py'
--- hooks/hooks.py 2013-02-18 17:50:16 +0000
+++ hooks/hooks.py 2013-03-11 14:16:22 +0000
@@ -24,10 +24,11 @@
24def config_changed():24def config_changed():
25 if PLUGIN in qutils.GATEWAY_PKGS.keys():25 if PLUGIN in qutils.GATEWAY_PKGS.keys():
26 render_quantum_conf()26 render_quantum_conf()
27 render_plugin_conf()27 render_dhcp_agent_conf()
28 render_l3_agent_conf()28 render_l3_agent_conf()
29 render_metadata_agent_conf()29 render_metadata_agent_conf()
30 render_metadata_api_conf()30 render_metadata_api_conf()
31 render_plugin_conf()
31 if PLUGIN == qutils.OVS:32 if PLUGIN == qutils.OVS:
32 qutils.add_bridge(qutils.INT_BRIDGE)33 qutils.add_bridge(qutils.INT_BRIDGE)
33 qutils.add_bridge(qutils.EXT_BRIDGE)34 qutils.add_bridge(qutils.EXT_BRIDGE)
@@ -58,6 +59,16 @@
58 )59 )
5960
6061
62def render_dhcp_agent_conf():
63 if (os.path.exists(qutils.DHCP_AGENT_CONF)):
64 with open(qutils.DHCP_AGENT_CONF, "w") as conf:
65 conf.write(utils.render_template(
66 os.path.basename(qutils.DHCP_AGENT_CONF),
67 {}
68 )
69 )
70
71
61def render_metadata_agent_conf():72def render_metadata_agent_conf():
62 context = get_keystone_conf()73 context = get_keystone_conf()
63 if (context and74 if (context and
@@ -136,6 +147,8 @@
136 unit, relid),147 unit, relid),
137 "quantum_port": utils.relation_get('quantum_port',148 "quantum_port": utils.relation_get('quantum_port',
138 unit, relid),149 unit, relid),
150 "quantum_url": utils.relation_get('quantum_url',
151 unit, relid),
139 "region": utils.relation_get('region',152 "region": utils.relation_get('region',
140 unit, relid)153 unit, relid)
141 }154 }
@@ -197,6 +210,7 @@
197210
198211
199def amqp_changed():212def amqp_changed():
213 render_dhcp_agent_conf()
200 render_quantum_conf()214 render_quantum_conf()
201 render_metadata_api_conf()215 render_metadata_api_conf()
202 restart_agents()216 restart_agents()
@@ -222,62 +236,31 @@
222236
223237
224def nm_changed():238def nm_changed():
239 render_dhcp_agent_conf()
225 render_l3_agent_conf()240 render_l3_agent_conf()
226 render_metadata_agent_conf()241 render_metadata_agent_conf()
227 render_metadata_api_conf()242 render_metadata_api_conf()
243 store_ca_cert()
228 restart_agents()244 restart_agents()
229245
230246
247def store_ca_cert():
248 ca_cert = get_ca_cert()
249 if ca_cert:
250 utils.install_ca(ca_cert)
251
252
253def get_ca_cert():
254 for relid in utils.relation_ids('quantum-network-service'):
255 for unit in utils.relation_list(relid):
256 ca_cert = utils.relation_get('ca_cert', unit, relid)
257 if ca_cert:
258 return ca_cert
259 return None
260
261
231def restart_agents():262def restart_agents():
232 if utils.eligible_leader(RESOURCE_GROUP):263 utils.restart(*qutils.GATEWAY_AGENTS[PLUGIN])
233 utils.restart(*qutils.GATEWAY_AGENTS[PLUGIN])
234 else:
235 # Stop any clustered agents and flush local config
236 # from network namespaces, ovs ports and dnsmasq instances
237 utils.stop(*qutils.CLUSTERED_AGENTS[PLUGIN])
238 utils.restart(*qutils.STANDALONE_AGENTS[PLUGIN])
239 qutils.flush_local_configuration()
240
241
242RESOURCE_GROUP = 'grp_quantum_services'
243
244
245def ha_relation_joined():
246 # init services that will be clusterized. Used to disable init scripts
247 # Used when resources have upstart jobs that are needed to be disabled.
248 # resource_name:init_script_name
249 init_services = {'res_quantum_dhcp_agent': 'quantum-dhcp-agent',
250 'res_quantum_l3_agent': 'quantum-l3-agent'}
251
252 # Obtain resources
253 # TODO: Just use upstart for the time being
254 #resources = {'res_quantum_dhcp_agent': 'ocf:openstack:quantum-agent-dhcp',
255 # 'res_quantum_l3_agent': 'ocf:openstack:quantum-agent-l3'}
256 resources = {'res_quantum_dhcp_agent': 'upstart:quantum-dhcp-agent',
257 'res_quantum_l3_agent': 'upstart:quantum-l3-agent'}
258 # TODO: monitors are currently disabled as this creates issues
259 # when forming the cluster.
260 resource_params = {'res_quantum_dhcp_agent':
261 'op monitor interval="5s"',
262 'res_quantum_l3_agent':
263 'op monitor interval="5s"'}
264 groups = {
265 RESOURCE_GROUP:
266 'res_quantum_dhcp_agent res_quantum_l3_agent'
267 }
268 # set relation values
269 utils.relation_set(resources=resources,
270 resource_params=resource_params,
271 init_services=init_services,
272 groups=groups,
273 corosync_bindiface=utils.config_get('ha-bindiface'),
274 corosync_mcastport=utils.config_get('ha-mcastport'))
275
276
277def cluster_changed():
278 if not utils.eligible_leader(RESOURCE_GROUP):
279 utils.stop(*qutils.CLUSTERED_AGENTS[PLUGIN])
280 qutils.flush_local_configuration()
281264
282265
283utils.do_hooks({266utils.do_hooks({
@@ -288,9 +271,7 @@
288 "shared-db-relation-changed": db_changed,271 "shared-db-relation-changed": db_changed,
289 "amqp-relation-joined": amqp_joined,272 "amqp-relation-joined": amqp_joined,
290 "amqp-relation-changed": amqp_changed,273 "amqp-relation-changed": amqp_changed,
291 "quantum-network-service-relation-changed": nm_changed,274 "quantum-network-service-relation-changed": nm_changed
292 "ha-relation-joined": ha_relation_joined,
293 "cluster-relation-changed": cluster_changed
294 })275 })
295276
296sys.exit(0)277sys.exit(0)
297278
=== modified file 'hooks/quantum_utils.py'
--- hooks/quantum_utils.py 2013-02-18 09:14:49 +0000
+++ hooks/quantum_utils.py 2013-03-11 14:16:22 +0000
@@ -6,24 +6,17 @@
66
77
8OVS = "ovs"8OVS = "ovs"
9NVP = "nvp"
109
11OVS_PLUGIN = \10OVS_PLUGIN = \
12 "quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2"11 "quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2"
13NVP_PLUGIN = \
14 "quantum.plugins.nicira.nicira_nvp_plugin.QuantumPlugin.NvpPluginV2"
15CORE_PLUGIN = {12CORE_PLUGIN = {
16 OVS: OVS_PLUGIN,13 OVS: OVS_PLUGIN,
17 NVP: NVP_PLUGIN
18 }14 }
1915
20OVS_PLUGIN_CONF = \16OVS_PLUGIN_CONF = \
21 "/etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini"17 "/etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini"
22NVP_PLUGIN_CONF = \
23 "/etc/quantum/plugins/nicira/nvp.ini"
24PLUGIN_CONF = {18PLUGIN_CONF = {
25 OVS: OVS_PLUGIN_CONF,19 OVS: OVS_PLUGIN_CONF,
26 NVP: NVP_PLUGIN_CONF
27 }20 }
2821
29GATEWAY_PKGS = {22GATEWAY_PKGS = {
@@ -34,19 +27,8 @@
34 'python-mysqldb',27 'python-mysqldb',
35 "nova-api-metadata"28 "nova-api-metadata"
36 ],29 ],
37 NVP: [
38 "quantum-plugin-nicira",
39 "quantum-l3-agent",
40 "quantum-dhcp-agent",
41 'python-mysqldb',
42 "nova-api-metadata"
43 ]
44 }30 }
4531
46# TODO: conditionally add quantum-metadata-agent if
47# running 2013.1 onwards. OR add some overrides
48# start on starting quantum-l3-agent
49# stop on stopping quantum-l3-agent
50GATEWAY_AGENTS = {32GATEWAY_AGENTS = {
51 OVS: [33 OVS: [
52 "quantum-plugin-openvswitch-agent",34 "quantum-plugin-openvswitch-agent",
@@ -54,33 +36,8 @@
54 "quantum-dhcp-agent",36 "quantum-dhcp-agent",
55 "nova-api-metadata"37 "nova-api-metadata"
56 ],38 ],
57 NVP: [39 }
58 "quantum-l3-agent",40
59 "quantum-dhcp-agent",
60 "nova-api-metadata"
61 ]
62 }
63
64CLUSTERED_AGENTS = {
65 OVS: [
66 "quantum-l3-agent",
67 "quantum-dhcp-agent",
68 ],
69 NVP: [
70 "quantum-l3-agent",
71 "quantum-dhcp-agent",
72 ]
73 }
74
75STANDALONE_AGENTS = {
76 OVS: [
77 "quantum-plugin-openvswitch-agent",
78 "nova-api-metadata"
79 ],
80 NVP: [
81 "nova-api-metadata"
82 ]
83 }
8441
85if get_os_version('quantum-common') >= "2013.1":42if get_os_version('quantum-common') >= "2013.1":
86 for plugin in GATEWAY_AGENTS:43 for plugin in GATEWAY_AGENTS:
8744
=== modified file 'hooks/utils.py'
--- hooks/utils.py 2013-02-08 17:51:20 +0000
+++ hooks/utils.py 2013-03-11 14:16:22 +0000
@@ -12,6 +12,7 @@
12import socket12import socket
13import sys13import sys
14import apt_pkg as apt14import apt_pkg as apt
15import base64
1516
1617
17def do_hooks(hooks):18def do_hooks(hooks):
@@ -86,8 +87,8 @@
86 if source.startswith('cloud:'):87 if source.startswith('cloud:'):
87 install('ubuntu-cloud-keyring')88 install('ubuntu-cloud-keyring')
88 pocket = source.split(':')[1]89 pocket = source.split(':')[1]
89 with open('/etc/apt/sources.list.d/cloud-archive.list', 'w') as apt:90 with open('/etc/apt/sources.list.d/cloud-archive.list', 'w') as sfile:
90 apt.write(CLOUD_ARCHIVE.format(CLOUD_ARCHIVE_POCKETS[pocket]))91 sfile.write(CLOUD_ARCHIVE.format(CLOUD_ARCHIVE_POCKETS[pocket]))
91 if source.startswith('deb'):92 if source.startswith('deb'):
92 l = len(source.split('|'))93 l = len(source.split('|'))
93 if l == 2:94 if l == 2:
@@ -101,8 +102,8 @@
101 elif l == 1:102 elif l == 1:
102 apt_line = source103 apt_line = source
103104
104 with open('/etc/apt/sources.list.d/quantum.list', 'w') as apt:105 with open('/etc/apt/sources.list.d/quantum.list', 'w') as sfile:
105 apt.write(apt_line + "\n")106 sfile.write(apt_line + "\n")
106 cmd = [107 cmd = [
107 'apt-get',108 'apt-get',
108 'update'109 'update'
@@ -214,38 +215,15 @@
214 return hostname215 return hostname
215 except socket.error:216 except socket.error:
216 pass217 pass
217 try:218 answers = dns.resolver.query(hostname, 'A')
218 answers = dns.resolver.query(hostname, 'A')219 if answers:
219 if answers:220 return answers[0].address
220 return answers[0].address221 else:
221 except dns.resolver.NXDOMAIN:222 return None
222 pass
223 return None
224
225
226CLUSTER_RESOURCES = {
227 'quantum-dhcp-agent': 'res_quantum_dhcp_agent',
228 'quantum-l3-agent': 'res_quantum_l3_agent'
229 }
230
231HAMARKER = '/var/lib/juju/haconfigured'
232223
233224
234def _service_ctl(service, action):225def _service_ctl(service, action):
235 if (os.path.exists(HAMARKER) and226 subprocess.call(['service', service, action])
236 os.path.exists(os.path.join('/etc/init/',
237 '{}.override'.format(service))) and
238 service in CLUSTER_RESOURCES):
239 hostname = str(subprocess.check_output(['hostname'])).strip()
240 service_status = \
241 subprocess.check_output(['crm', 'resource', 'show',
242 CLUSTER_RESOURCES[service]])
243 # Only restart if we are the node that owns the service
244 if hostname in service_status:
245 subprocess.check_call(['crm', 'resource', action,
246 CLUSTER_RESOURCES[service]])
247 else:
248 subprocess.call(['service', service, action])
249227
250228
251def restart(*services):229def restart(*services):
@@ -273,55 +251,8 @@
273 return None251 return None
274252
275253
276def is_clustered():254def install_ca(ca_cert):
277 for r_id in (relation_ids('ha') or []):255 with open('/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt',
278 for unit in (relation_list(r_id) or []):256 'w') as crt:
279 clustered = relation_get('clustered',257 crt.write(base64.b64decode(ca_cert))
280 unit=unit,258 subprocess.check_call(['update-ca-certificates', '--fresh'])
281 rid=r_id)
282 if clustered:
283 return True
284 return False
285
286
287def is_leader(resource):
288 if os.path.exists('/usr/sbin/crm'):
289 try:
290 status = subprocess.check_output(['crm', 'resource',
291 'show', resource])
292 hostname = get_unit_hostname()
293 if hostname in status:
294 return True
295 except subprocess.CalledProcessError:
296 pass
297 return False
298
299
300def peer_units():
301 peers = []
302 for r_id in (relation_ids('cluster') or []):
303 for unit in (relation_list(r_id) or []):
304 peers.append(unit)
305 return peers
306
307
308def oldest_peer(peers):
309 local_unit_no = int(os.getenv('JUJU_UNIT_NAME').split('/')[1])
310 for peer in peers:
311 remote_unit_no = int(peer.split('/')[1])
312 if remote_unit_no < local_unit_no:
313 return False
314 return True
315
316
317def eligible_leader(resource):
318 if is_clustered():
319 if not is_leader(resource):
320 juju_log('INFO', 'Deferring action to CRM leader.')
321 return False
322 else:
323 peers = peer_units()
324 if peers and not oldest_peer(peers):
325 juju_log('INFO', 'Deferring action to oldest service unit.')
326 return False
327 return True
328259
=== modified file 'metadata.yaml'
--- metadata.yaml 2013-02-08 16:10:48 +0000
+++ metadata.yaml 2013-03-11 14:16:22 +0000
@@ -20,10 +20,4 @@
20 shared-db:20 shared-db:
21 interface: mysql-shared21 interface: mysql-shared
22 amqp:22 amqp:
23 interface: rabbitmq23 interface: rabbitmq
24 ha:
25 interface: hacluster
26 scope: container
27peers:
28 cluster:
29 interface: quantum-gateway-ha
30\ No newline at end of file24\ No newline at end of file
3125
=== modified file 'templates/nova.conf'
--- templates/nova.conf 2013-01-18 12:39:10 +0000
+++ templates/nova.conf 2013-03-11 14:16:22 +0000
@@ -18,7 +18,7 @@
18# Access to quantum API services18# Access to quantum API services
19network_api_class=nova.network.quantumv2.api.API19network_api_class=nova.network.quantumv2.api.API
20quantum_auth_strategy=keystone20quantum_auth_strategy=keystone
21quantum_url=http://{{ quantum_host }}:{{ quantum_port }}21quantum_url={{ quantum_url }}
22quantum_admin_tenant_name={{ service_tenant }}22quantum_admin_tenant_name={{ service_tenant }}
23quantum_admin_username={{ service_username }}23quantum_admin_username={{ service_username }}
24quantum_admin_password={{ service_password }}24quantum_admin_password={{ service_password }}
2525
=== modified file 'templates/ovs_quantum_plugin.ini'
--- templates/ovs_quantum_plugin.ini 2012-11-05 11:59:27 +0000
+++ templates/ovs_quantum_plugin.ini 2013-03-11 14:16:22 +0000
@@ -7,5 +7,5 @@
7enable_tunneling = True7enable_tunneling = True
8tunnel_id_ranges = 1:10008tunnel_id_ranges = 1:1000
9[AGENT]9[AGENT]
10polling_interval = 210polling_interval = 10
11root_helper = sudo /usr/bin/quantum-rootwrap /etc/quantum/rootwrap.conf11root_helper = sudo /usr/bin/quantum-rootwrap /etc/quantum/rootwrap.conf
1212
=== modified file 'templates/quantum.conf'
--- templates/quantum.conf 2013-02-18 09:14:49 +0000
+++ templates/quantum.conf 2013-03-11 14:16:22 +0000
@@ -14,7 +14,7 @@
14list_notifier_drivers = quantum.openstack.common.notifier.rabbit_notifier14list_notifier_drivers = quantum.openstack.common.notifier.rabbit_notifier
15lock_path = /var/lock/quantum15lock_path = /var/lock/quantum
16# Ensure that netns cleanup operations kill processes and remove ports16# Ensure that netns cleanup operations kill processes and remove ports
17force = true17# force = true
18[AGENT]18[AGENT]
19root_helper = sudo /usr/bin/quantum-rootwrap /etc/quantum/rootwrap.conf19root_helper = sudo /usr/bin/quantum-rootwrap /etc/quantum/rootwrap.conf
20[QUOTAS]20[QUOTAS]
21\ No newline at end of file21\ No newline at end of file

Subscribers

People subscribed via source and target branches