Merge lp:~johnsca/charms/trusty/cloudfoundry/catchup into lp:~cf-charmers/charms/trusty/cloudfoundry/trunk

Proposed by Cory Johns
Status: Merged
Merged at revision: 164
Proposed branch: lp:~johnsca/charms/trusty/cloudfoundry/catchup
Merge into: lp:~cf-charmers/charms/trusty/cloudfoundry/trunk
Diff against target: 675 lines (+321/-30)
11 files modified
.bzrignore (+4/-0)
charmgen/generator.py (+4/-0)
charmgen/placements.yaml (+1/-1)
cloudfoundry/contexts.py (+58/-5)
cloudfoundry/releases.py (+41/-5)
cloudfoundry/services.py (+172/-0)
cloudfoundry/utils.py (+3/-1)
reconciler/app.py (+2/-0)
reconciler/strategy.py (+11/-2)
tests/02-cats (+1/-1)
tests/cats.py (+24/-15)
To merge this branch: bzr merge lp:~johnsca/charms/trusty/cloudfoundry/catchup
Reviewer Review Type Date Requested Status
Benjamin Saller (community) Approve
Review via email: mp+244226@code.launchpad.net

Description of the change

Changes to support 190. I haven't run CATS on it, but pushing an app and logging works.

To post a comment you must log in.
171. By Cory Johns

Fixes for CATs test to match cfdeploy changes

172. By Cory Johns

Fixes for running CATs

173. By Cory Johns

Test arg needs to be optional

Revision history for this message
Benjamin Saller (bcsaller) wrote :

These changes LGTM. Its nice that you found the dangling reference issue with placement and the clean up on interface types, like http->login.

I'd like to hold off landing this until we've identified the remaining issue with CATs, even if we can't fix that one remaining test run today I'd like some clarity as to why. If it works on a fresh run this morning its most likely a GC issue and we'll need to address that separately.

Thanks

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.bzrignore'
--- .bzrignore 2014-11-13 16:22:27 +0000
+++ .bzrignore 2014-12-10 15:53:53 +0000
@@ -47,3 +47,7 @@
47# Generated test charms47# Generated test charms
48cloudfoundry-r*48cloudfoundry-r*
49output-v*.yaml49output-v*.yaml
50
51# Generated when running CATs
52src/
53pkg/
5054
=== modified file 'charmgen/generator.py'
--- charmgen/generator.py 2014-11-07 21:50:48 +0000
+++ charmgen/generator.py 2014-12-10 15:53:53 +0000
@@ -227,6 +227,10 @@
227 if zone:227 if zone:
228 driver = zone[0]228 driver = zone[0]
229 for follower in zone[1:]:229 for follower in zone[1:]:
230 if follower not in services:
231 # allow dangling references in placement to handle
232 # removed services
233 continue
230 with_references.add(driver)234 with_references.add(driver)
231 if 'to' not in services[follower]:235 if 'to' not in services[follower]:
232 services[follower]['to'] = [driver]236 services[follower]['to'] = [driver]
233237
=== modified file 'charmgen/placements.yaml'
--- charmgen/placements.yaml 2014-11-11 03:52:11 +0000
+++ charmgen/placements.yaml 2014-12-10 15:53:53 +0000
@@ -5,7 +5,7 @@
5 b: [router, nats, nats-sf]5 b: [router, nats, nats-sf]
6 c: [login, uaa, mysql]6 c: [login, uaa, mysql]
7 d: [dea, hm, etcd]7 d: [dea, hm, etcd]
8 e: [loggregator, loggregator-trafficcontrol]8 e: [loggregator-trafficcontrol, loggregator, doppler]
9 f: [haproxy, collector]9 f: [haproxy, collector]
10local:10local:
11 __default__:11 __default__:
1212
=== modified file 'cloudfoundry/contexts.py'
--- cloudfoundry/contexts.py 2014-11-11 04:02:53 +0000
+++ cloudfoundry/contexts.py 2014-12-10 15:53:53 +0000
@@ -226,7 +226,7 @@
226226
227class LoginRelation(RelationContext):227class LoginRelation(RelationContext):
228 name = 'login'228 name = 'login'
229 interface = 'http'229 interface = 'login'
230 required_keys = []230 required_keys = []
231 port = 8080231 port = 8080
232232
@@ -239,6 +239,8 @@
239 data = self[self.name][0]239 data = self[self.name][0]
240 return {240 return {
241 'login.port': data['port'],241 'login.port': data['port'],
242 'login.saml.socket.connectionManagerTimeout': 10000,
243 'login.saml.socket.soTimeout': 10000,
242 }244 }
243245
244246
@@ -250,6 +252,11 @@
250 def erb_mapping(self):252 def erb_mapping(self):
251 return {253 return {
252 'dea_next.directory_server_protocol': 'http',254 'dea_next.directory_server_protocol': 'http',
255 # these are the default values, but since they're used in hm and
256 # cc and those specs don't give the default value (only dea_next),
257 # we have to manually specify them here
258 'dea_next.advertise_interval_in_seconds': 5,
259 'dea_next.heartbeat_interval_in_seconds': 10,
253 }260 }
254261
255262
@@ -296,8 +303,6 @@
296 'traffic_controller.host': data[0]['host'],303 'traffic_controller.host': data[0]['host'],
297 'traffic_controller.incoming_port': data[0]['port'],304 'traffic_controller.incoming_port': data[0]['port'],
298 'traffic_controller.outgoing_port': data[0]['outgoing_port'],305 'traffic_controller.outgoing_port': data[0]['outgoing_port'],
299 'logger_endpoint.use_ssl': False, # TODO: support SSL option
300 'logger_endpoint.port': 80, # default is 443
301 }306 }
302307
303308
@@ -328,6 +333,48 @@
328 }333 }
329334
330335
336class DopplerRelation(RelationContext):
337 name = 'doppler'
338 interface = 'doppler'
339 required_keys = ['address', 'incoming_port', 'outgoing_port',
340 'dropsonde_port', 'doppler_endpoint_secret']
341 incoming_port = 3457
342 outgoing_port = 8083
343 dropsonde_port = 3460
344
345 def get_shared_secrets(self):
346 secret_context = StoredContext('doppler-secrets.yml', {
347 'doppler_endpoint_secret': host.pwgen(20),
348 })
349 return secret_context
350
351 def provide_data(self):
352 secrets = self.get_shared_secrets()
353 return {
354 'address': hookenv.unit_get('private-address').encode('utf-8'),
355 'incoming_port': self.incoming_port,
356 'outgoing_port': self.outgoing_port,
357 'dropsonde_port': self.dropsonde_port,
358 'doppler_endpoint_secret': secrets['doppler_endpoint_secret']
359 }
360
361 def erb_mapping(self):
362 data = self[self.name]
363 return {
364 'doppler.zone': 'z1',
365 'doppler.blacklisted_syslog_ranges': [],
366 'doppler.incoming_port': data[0]['incoming_port'],
367 'doppler.outgoing_port': data[0]['outgoing_port'],
368 'doppler.dropsonde_incoming_port': data[0]['dropsonde_port'],
369 'doppler_endpoint.shared_secret': data[0]['doppler_endpoint_secret'],
370 'loggregator.doppler_port': data[0]['outgoing_port'],
371 'loggregator.incoming_port': data[0]['incoming_port'],
372 'loggregator.dropsonde_incoming_port': data[0]['dropsonde_port'],
373 'loggregator.dropsonde_outgoing_port': data[0]['outgoing_port'],
374 'loggregator_endpoint.shared_secret': data[0]['doppler_endpoint_secret'],
375 }
376
377
331class EtcdRelation(RelationContext):378class EtcdRelation(RelationContext):
332 name = 'etcd'379 name = 'etcd'
333 interface = 'etcd'380 interface = 'etcd'
@@ -343,13 +390,15 @@
343class CloudControllerRelation(RelationContext):390class CloudControllerRelation(RelationContext):
344 name = 'cc'391 name = 'cc'
345 interface = 'controller'392 interface = 'controller'
346 required_keys = ['hostname', 'port', 'user', 'password', 'db_encryption_key']393 required_keys = ['hostname', 'port', 'user', 'password',
394 'internal_api_password', 'db_encryption_key']
347395
348 def get_credentials(self):396 def get_credentials(self):
349 return StoredContext('api_credentials.yml', {397 return StoredContext('api_credentials.yml', {
350 'user': host.pwgen(7),398 'user': host.pwgen(7),
351 'password': host.pwgen(7),399 'password': host.pwgen(7),
352 'db_encryption_key': host.pwgen(7),400 'db_encryption_key': host.pwgen(7),
401 'internal_api_password': host.pwgen(7),
353 })402 })
354403
355 def provide_data(self):404 def provide_data(self):
@@ -357,6 +406,7 @@
357 return {406 return {
358 'user': creds['user'],407 'user': creds['user'],
359 'password': creds['password'],408 'password': creds['password'],
409 'internal_api_password': creds['internal_api_password'],
360 'db_encryption_key': creds['db_encryption_key'],410 'db_encryption_key': creds['db_encryption_key'],
361 'hostname': hookenv.unit_get('private-address').encode('utf-8'),411 'hostname': hookenv.unit_get('private-address').encode('utf-8'),
362 'port': 9022,412 'port': 9022,
@@ -369,6 +419,7 @@
369 'cc.srv_api_uri': 'http://{}:{}'.format(data['hostname'], data['port']),419 'cc.srv_api_uri': 'http://{}:{}'.format(data['hostname'], data['port']),
370 'cc.bulk_api_user': data['user'],420 'cc.bulk_api_user': data['user'],
371 'cc.bulk_api_password': data['password'],421 'cc.bulk_api_password': data['password'],
422 'cc.internal_api_password': data['internal_api_password'],
372 'cc.staging_upload_user': 'ignored', # FIXME: We need a staging cache set up423 'cc.staging_upload_user': 'ignored', # FIXME: We need a staging cache set up
373 'cc.staging_upload_password': 'ignored',424 'cc.staging_upload_password': 'ignored',
374 'cc.db_encryption_key': data['db_encryption_key'],425 'cc.db_encryption_key': data['db_encryption_key'],
@@ -439,7 +490,7 @@
439490
440class RouterRelation(RelationContext):491class RouterRelation(RelationContext):
441 name = 'router'492 name = 'router'
442 interface = 'http'493 interface = 'router'
443 required_keys = ['address']494 required_keys = ['address']
444 port = 8000495 port = 8000
445 varz_port = 8084 # not currently used496 varz_port = 8084 # not currently used
@@ -545,6 +596,8 @@
545 'app_domains': [d['domain'] for d in self[self.name]],596 'app_domains': [d['domain'] for d in self[self.name]],
546 'system_domain': domain, # TODO: These should probably be config options597 'system_domain': domain, # TODO: These should probably be config options
547 'system_domain_organization': 'juju-org',598 'system_domain_organization': 'juju-org',
599 'logger_endpoint.use_ssl': False, # TODO: support SSL option
600 'logger_endpoint.port': 80, # default is 443
548 }601 }
549602
550603
551604
=== modified file 'cloudfoundry/releases.py'
--- cloudfoundry/releases.py 2014-11-05 18:22:07 +0000
+++ cloudfoundry/releases.py 2014-12-10 15:53:53 +0000
@@ -8,8 +8,6 @@
8 ('uaa-v1', 'uaa'),8 ('uaa-v1', 'uaa'),
9 ('login-v1', 'login'),9 ('login-v1', 'login'),
10 ('nats-stream-forwarder-v1', 'nats-sf'),10 ('nats-stream-forwarder-v1', 'nats-sf'),
11 ('loggregator-v1', 'loggregator'),
12 ('hm9000-v1', 'hm'),
13 ('haproxy-v1', 'haproxy'),11 ('haproxy-v1', 'haproxy'),
14 ('collector-v1', 'collector'),12 ('collector-v1', 'collector'),
1513
@@ -25,7 +23,6 @@
25 ('mysql:db', 'cc:db'),23 ('mysql:db', 'cc:db'),
26 ('mysql:db', 'uaa:db'),24 ('mysql:db', 'uaa:db'),
27 ('etcd:client', 'hm:etcd'),25 ('etcd:client', 'hm:etcd'),
28 ('etcd:client', 'loggregator:etcd'),
29 ('etcd:client', 'loggregator-trafficcontrol:etcd'),26 ('etcd:client', 'loggregator-trafficcontrol:etcd'),
30]27]
3128
@@ -34,6 +31,38 @@
3431
35RELEASES = [32RELEASES = [
36 {33 {
34 "releases": (190, 190),
35 "topology": {
36 "services": COMMON_SERVICES + [
37 ('router-v3', 'router'),
38 ('cloud-controller-v3', 'cc'),
39 ('cloud-controller-clock-v3', 'cc-clock'),
40 ('cloud-controller-worker-v3', 'cc-worker'),
41 ('dea-v3', 'dea'),
42 ('loggregator-trafficcontroller-v3', 'loggregator-trafficcontrol'),
43 ('hm9000-v2', 'hm'),
44 ('doppler-v1', 'doppler'),
45 ],
46 "relations": COMMON_RELATIONS + [
47 ('etcd:client', 'cc:etcd'),
48 ('etcd:client', 'cc-worker:etcd'),
49 ('etcd:client', 'cc-clock:etcd'),
50 ('etcd:client', 'router:etcd'),
51 ('etcd:client', 'dea:etcd'),
52 ('etcd:client', 'doppler:etcd'),
53 ],
54 "expose": ['haproxy'],
55 "constraints": {
56 "__default__": "arch=amd64 instance-type=m3.medium",
57 "cc": "arch=amd64 root-disk=12G mem=12G",
58 "cc-worker": "arch=amd64 root-disk=10G",
59 "cc-clock": "arch=amd64 root-disk=10G",
60 "dea": "arch=amd64 mem=5G",
61 },
62 },
63 "upgrades": COMMON_UPGRADES
64 },
65 {
37 "releases": (177, 180),66 "releases": (177, 180),
38 "topology": {67 "topology": {
39 "services": COMMON_SERVICES + [68 "services": COMMON_SERVICES + [
@@ -42,7 +71,9 @@
42 ('cloud-controller-clock-v2', 'cc-clock'),71 ('cloud-controller-clock-v2', 'cc-clock'),
43 ('cloud-controller-worker-v2', 'cc-worker'),72 ('cloud-controller-worker-v2', 'cc-worker'),
44 ('dea-v2', 'dea'),73 ('dea-v2', 'dea'),
74 ('loggregator-v1', 'loggregator'),
45 ('loggregator-trafficcontroller-v2', 'loggregator-trafficcontrol'),75 ('loggregator-trafficcontroller-v2', 'loggregator-trafficcontrol'),
76 ('hm9000-v1', 'hm'),
46 ],77 ],
47 "relations": COMMON_RELATIONS + [78 "relations": COMMON_RELATIONS + [
48 ('etcd:client', 'cc:etcd'),79 ('etcd:client', 'cc:etcd'),
@@ -50,6 +81,7 @@
50 ('etcd:client', 'cc-clock:etcd'),81 ('etcd:client', 'cc-clock:etcd'),
51 ('etcd:client', 'router:etcd'),82 ('etcd:client', 'router:etcd'),
52 ('etcd:client', 'dea:etcd'),83 ('etcd:client', 'dea:etcd'),
84 ('etcd:client', 'loggregator:etcd'),
53 ],85 ],
54 "expose": ['haproxy'],86 "expose": ['haproxy'],
55 "constraints": {87 "constraints": {
@@ -71,9 +103,13 @@
71 ('cloud-controller-clock-v1', 'cc-clock'),103 ('cloud-controller-clock-v1', 'cc-clock'),
72 ('cloud-controller-worker-v1', 'cc-worker'),104 ('cloud-controller-worker-v1', 'cc-worker'),
73 ('dea-v1', 'dea'),105 ('dea-v1', 'dea'),
106 ('loggregator-v1', 'loggregator'),
74 ('loggregator-trafficcontroller-v1', 'loggregator-trafficcontrol'),107 ('loggregator-trafficcontroller-v1', 'loggregator-trafficcontrol'),
75 ],108 ('hm9000-v1', 'hm'),
76 "relations": COMMON_RELATIONS,109 ],
110 "relations": COMMON_RELATIONS + [
111 ('etcd:client', 'loggregator:etcd'),
112 ],
77 "expose": ['haproxy'],113 "expose": ['haproxy'],
78 "constraints": {114 "constraints": {
79 "__default__": "arch=amd64",115 "__default__": "arch=amd64",
80116
=== modified file 'cloudfoundry/services.py'
--- cloudfoundry/services.py 2014-11-07 21:18:42 +0000
+++ cloudfoundry/services.py 2014-12-10 15:53:53 +0000
@@ -49,6 +49,27 @@
4949
50 },50 },
5151
52 'cloud-controller-clock-v3': {
53 'summary': "A shared clock",
54 'description': '',
55 'jobs': [
56 {'job_name': 'cloud_controller_clock',
57 'mapping': {'ccdb': mapper.ccdb},
58 'provided_data': [],
59 'required_data': [contexts.NatsRelation,
60 contexts.CloudControllerRelation,
61 contexts.UAARelation,
62 contexts.CloudControllerDBRelation],
63 },
64 {'job_name': 'metron_agent',
65 'required_data': [contexts.LTCRelation,
66 contexts.NatsRelation,
67 contexts.DopplerRelation,
68 contexts.EtcdRelation]},
69 ],
70
71 },
72
52 'cloud-controller-v1': {73 'cloud-controller-v1': {
53 'summary': 'CF Cloud Controller, the brains of the operation',74 'summary': 'CF Cloud Controller, the brains of the operation',
54 'description': '',75 'description': '',
@@ -89,6 +110,29 @@
89 ]110 ]
90 },111 },
91112
113 'cloud-controller-v3': {
114 'summary': 'CF Cloud Controller, the brains of the operation',
115 'description': '',
116 'jobs': [
117 {'job_name': 'cloud_controller_ng',
118 'mapping': {'db': mapper.ccdb},
119 'provided_data': [contexts.CloudControllerRelation,
120 contexts.CloudControllerDBRelation],
121 'required_data': [contexts.NatsRelation,
122 contexts.MysqlRelation,
123 contexts.UAARelation,
124 contexts.DEARelation,
125 contexts.CloudControllerRelation.remote_view,
126 ],
127 },
128 {'job_name': 'metron_agent',
129 'required_data': [contexts.LTCRelation,
130 contexts.NatsRelation,
131 contexts.DopplerRelation,
132 contexts.EtcdRelation]},
133 ]
134 },
135
92 'cloud-controller-worker-v1': {136 'cloud-controller-worker-v1': {
93 'summary': "Worker for cc",137 'summary': "Worker for cc",
94 'description': '',138 'description': '',
@@ -128,6 +172,27 @@
128 ]172 ]
129 },173 },
130174
175 'cloud-controller-worker-v3': {
176 'summary': "Worker for cc",
177 'description': '',
178 'jobs': [
179 {'job_name': 'cloud_controller_worker',
180 'mapping': {'ccdb': mapper.ccdb},
181 'provided_data': [],
182 'required_data': [contexts.NatsRelation,
183 contexts.UAARelation,
184 contexts.CloudControllerRelation,
185 contexts.CloudControllerDBRelation,
186 ],
187 },
188 {'job_name': 'metron_agent',
189 'required_data': [contexts.LTCRelation,
190 contexts.NatsRelation,
191 contexts.DopplerRelation,
192 contexts.EtcdRelation]},
193 ]
194 },
195
131 'dea-v1': {196 'dea-v1': {
132 'summary': 'DEA runs CF apps in containers',197 'summary': 'DEA runs CF apps in containers',
133 'description': '',198 'description': '',
@@ -199,6 +264,47 @@
199264
200 },265 },
201266
267
268 'dea-v3': {
269 'summary': 'DEA runs CF apps in containers',
270 'description': '',
271 'jobs': [
272 {
273 'job_name': 'dea_next',
274 'mapping': {},
275 'install': [
276 utils.install_linux_image_extra,
277 utils.apt_install(['quota']),
278 utils.modprobe(['quota_v1', 'quota_v2'])
279 ],
280 'provided_data': [contexts.DEARelation],
281 'required_data': [
282 contexts.NatsRelation,
283 contexts.LTCRelation,
284 contexts.DEARelation.remote_view,
285 contexts.RouterRelation,
286 ],
287 'data_ready': [
288 #tasks.enable_swapaccounting
289 tasks.patch_dea
290 ]
291 },
292 {
293 'job_name': 'dea_logging_agent',
294 'mapping': {},
295 'required_data': [contexts.NatsRelation,
296 contexts.LTCRelation,
297 contexts.EtcdRelation]
298 },
299 {'job_name': 'metron_agent',
300 'required_data': [contexts.LTCRelation,
301 contexts.NatsRelation,
302 contexts.DopplerRelation,
303 contexts.EtcdRelation]},
304 ]
305
306 },
307
202 'nats-v1': {308 'nats-v1': {
203 'service': 'nats',309 'service': 'nats',
204 'summary': 'NATS message bus for CF',310 'summary': 'NATS message bus for CF',
@@ -259,6 +365,25 @@
259365
260 },366 },
261367
368 'router-v3': {
369 'service': 'router',
370 'summary': 'CF Router',
371 'jobs': [
372 {'job_name': 'gorouter',
373 'ports': [contexts.RouterRelation.port],
374 'mapping': {},
375 'provided_data': [contexts.RouterRelation],
376 'required_data': [contexts.NatsRelation,
377 contexts.RouterRelation.remote_view]},
378 {'job_name': 'metron_agent',
379 'required_data': [contexts.LTCRelation,
380 contexts.NatsRelation,
381 contexts.DopplerRelation,
382 contexts.EtcdRelation]},
383 ],
384
385 },
386
262 'uaa-v1': {387 'uaa-v1': {
263 'service': 'uaa',388 'service': 'uaa',
264 'summary': 'CF Oauth2 for identity management service',389 'summary': 'CF Oauth2 for identity management service',
@@ -303,6 +428,21 @@
303 }]428 }]
304 },429 },
305430
431 'doppler-v1': {
432 'service': 'doppler',
433 'summary': 'successor of loggregator',
434 'description': 'Successor of loggregator.',
435 'jobs': [{
436 'job_name': 'doppler',
437 'mapping': {},
438 'provided_data': [contexts.DopplerRelation],
439 'required_data': [contexts.NatsRelation,
440 contexts.EtcdRelation,
441 contexts.LTCRelation,
442 contexts.DopplerRelation.remote_view]
443 }]
444 },
445
306 'loggregator-trafficcontroller-v1': {446 'loggregator-trafficcontroller-v1': {
307 'service': 'loggregator-trafficcontroller',447 'service': 'loggregator-trafficcontroller',
308 'summary': 'loggregator-trafficcontroller',448 'summary': 'loggregator-trafficcontroller',
@@ -337,6 +477,23 @@
337 ]477 ]
338 },478 },
339479
480 'loggregator-trafficcontroller-v3': {
481 'service': 'loggregator-trafficcontroller',
482 'summary': 'loggregator-trafficcontroller',
483 'description': '',
484 'jobs': [
485 {'job_name': 'loggregator_trafficcontroller',
486 'ports': [contexts.LTCRelation.outgoing_port],
487 'mapping': {},
488 'provided_data': [contexts.LTCRelation],
489 'required_data': [contexts.DopplerRelation,
490 contexts.LTCRelation.remote_view,
491 contexts.NatsRelation,
492 contexts.CloudControllerRelation,
493 contexts.EtcdRelation]},
494 ]
495 },
496
340 'hm9000-v1': {497 'hm9000-v1': {
341 'service': 'hm9000',498 'service': 'hm9000',
342 'summary': 'health monitor',499 'summary': 'health monitor',
@@ -351,6 +508,21 @@
351 }]508 }]
352 },509 },
353510
511 'hm9000-v2': {
512 'service': 'hm9000',
513 'summary': 'health monitor',
514 'description': '',
515 'jobs': [{
516 'job_name': 'hm9000',
517 'mapping': {},
518 'provided_data': [],
519 'required_data': [contexts.NatsRelation,
520 contexts.CloudControllerRelation,
521 contexts.EtcdRelation,
522 contexts.DEARelation]
523 }]
524 },
525
354 'haproxy-v1': {526 'haproxy-v1': {
355 'service': 'haproxy',527 'service': 'haproxy',
356 'summary': 'loadbalance the routers',528 'summary': 'loadbalance the routers',
357529
=== modified file 'cloudfoundry/utils.py'
--- cloudfoundry/utils.py 2014-12-03 23:14:23 +0000
+++ cloudfoundry/utils.py 2014-12-10 15:53:53 +0000
@@ -23,8 +23,10 @@
2323
2424
25@contextmanager25@contextmanager
26def cd(directory):26def cd(directory, make=False):
27 cwd = os.getcwd()27 cwd = os.getcwd()
28 if not os.path.exists(directory) and make:
29 os.makedirs(directory)
28 os.chdir(directory)30 os.chdir(directory)
29 try:31 try:
30 yield32 yield
3133
=== modified file 'reconciler/app.py'
--- reconciler/app.py 2014-11-20 16:09:27 +0000
+++ reconciler/app.py 2014-12-10 15:53:53 +0000
@@ -135,6 +135,8 @@
135 service['health'] = 'warn'135 service['health'] = 'warn'
136 else:136 else:
137 service['health'] = 'pass'137 service['health'] = 'pass'
138 if service_name == 'cloudfoundry' and db.error: # XXX don't hard-code
139 service['health'] = 'fail'
138140
139141
140def get_current_state():142def get_current_state():
141143
=== modified file 'reconciler/strategy.py'
--- reconciler/strategy.py 2014-11-11 18:22:53 +0000
+++ reconciler/strategy.py 2014-12-10 15:53:53 +0000
@@ -28,6 +28,7 @@
28 self.strategy = Strategy(self.env)28 self.strategy = Strategy(self.env)
29 self.history = []29 self.history = []
30 self.exec_lock = threading.Lock()30 self.exec_lock = threading.Lock()
31 self.error = False
3132
32 def reset(self):33 def reset(self):
33 self.expected = {}34 self.expected = {}
@@ -106,8 +107,12 @@
106 return []107 return []
107108
108 # Service Deltas109 # Service Deltas
109 self.strategy.extend(self.build_services())110 try:
110 self.strategy.extend(self.build_relations())111 self.strategy.extend(self.build_services())
112 self.strategy.extend(self.build_relations())
113 except Exception as e:
114 self.error = True
115 logging.error('Error building strategy: %s', e)
111116
112 def _changed(self):117 def _changed(self):
113 previous = hashlib.md5(json.dumps(self.previous or {}, sort_keys=True))118 previous = hashlib.md5(json.dumps(self.previous or {}, sort_keys=True))
@@ -205,6 +210,10 @@
205 self.execute_strategy)210 self.execute_strategy)
206 else:211 else:
207 self._reset_strategy()212 self._reset_strategy()
213 self.error = False
214 except Exception as e:
215 self.error = True
216 logging.error('Error executing strategy: %s', e)
208 finally:217 finally:
209 self.exec_lock.release()218 self.exec_lock.release()
210219
211220
=== modified file 'tests/02-cats'
--- tests/02-cats 2014-10-01 18:50:57 +0000
+++ tests/02-cats 2014-12-10 15:53:53 +0000
@@ -1,3 +1,3 @@
1#!/bin/bash1#!/bin/bash
22
3python tests/cats.py3python tests/cats.py "$@"
44
=== modified file 'tests/cats.py'
--- tests/cats.py 2014-10-16 15:01:08 +0000
+++ tests/cats.py 2014-12-10 15:53:53 +0000
@@ -6,6 +6,7 @@
6import subprocess6import subprocess
7import sys7import sys
8import tempfile8import tempfile
9from functools import partial
910
10from cloudfoundry.releases import RELEASES11from cloudfoundry.releases import RELEASES
11from cloudfoundry.utils import (api,12from cloudfoundry.utils import (api,
@@ -26,6 +27,7 @@
26 global options27 global options
27 parser = argparse.ArgumentParser()28 parser = argparse.ArgumentParser()
28 parser.add_argument('-v', '--version', default="latest")29 parser.add_argument('-v', '--version', default="latest")
30 parser.add_argument('admin_password', default="password", nargs='?')
29 options = parser.parse_args()31 options = parser.parse_args()
30 if options.version == 'latest':32 if options.version == 'latest':
31 options.version = RELEASES[0]['releases'][1]33 options.version = RELEASES[0]['releases'][1]
@@ -50,10 +52,11 @@
5052
51def get_cats(version):53def get_cats(version):
52 logging.info("Getting CATs from github")54 logging.info("Getting CATs from github")
53 if not os.path.exists('cf-acceptance-tests'):55 if not os.path.exists('src/github.com/cloudfoundry/cf-acceptance-tests'):
54 sh.git('clone',56 with cd('src/github.com/cloudfoundry', make=True):
55 'https://github.com/cloudfoundry/cf-acceptance-tests.git')57 sh.git('clone',
56 with cd('cf-acceptance-tests'):58 'https://github.com/cloudfoundry/cf-acceptance-tests.git')
59 with cd('src/github.com/cloudfoundry/cf-acceptance-tests'):
57 sh.git('fetch')60 sh.git('fetch')
58 sh.check('./bin/compile')61 sh.check('./bin/compile')
59 # Switch to the branch of the revision in question62 # Switch to the branch of the revision in question
@@ -66,12 +69,13 @@
66 sha = acceptance[0]['sha']69 sha = acceptance[0]['sha']
67 print "Switching CATs to {} to test version {}".format(70 print "Switching CATs to {} to test version {}".format(
68 sha[:6], version)71 sha[:6], version)
69 sh.git('reset', '--hard', sha)72 sh.git('checkout', sha)
7073
7174
72def run_cats():75def run_cats(options):
73 ep = endpoint()76 ep = endpoint()
74 with cd('cf-acceptance-tests'):77 gopath = os.getcwd()
78 with cd('src/github.com/cloudfoundry/cf-acceptance-tests'):
75 fd, fn = tempfile.mkstemp(suffix=".json")79 fd, fn = tempfile.mkstemp(suffix=".json")
76 os.close(fd)80 os.close(fd)
77 with open(fn, 'w') as fp:81 with open(fn, 'w') as fp:
@@ -81,8 +85,8 @@
81 "api": api(),85 "api": api(),
82 "syslog_drain_port": 8082,86 "syslog_drain_port": 8082,
83 "syslog_ip_address": ep,87 "syslog_ip_address": ep,
84 "password": "admin",88 "password": options.admin_password,
85 "admin_password": "admin",89 "admin_password": options.admin_password,
86 "user": "admin",90 "user": "admin",
87 "admin_user": "admin",91 "admin_user": "admin",
88 "org": "juju-org",92 "org": "juju-org",
@@ -94,7 +98,10 @@
94 json.dump(defaults, fp, indent=2, sort_keys=True)98 json.dump(defaults, fp, indent=2, sort_keys=True)
95 logging.info("Running CATs %s", defaults)99 logging.info("Running CATs %s", defaults)
96 env = os.environ.copy()100 env = os.environ.copy()
97 env.update({'CONFIG': os.path.abspath(fn)})101 env.update({
102 'CONFIG': os.path.abspath(fn),
103 'GOPATH': gopath,
104 })
98 subprocess.call('./bin/test', shell=True, env=env)105 subprocess.call('./bin/test', shell=True, env=env)
99106
100107
@@ -103,9 +110,11 @@
103 logging.basicConfig(level=logging.INFO)110 logging.basicConfig(level=logging.INFO)
104 get_cats(options.version)111 get_cats(options.version)
105 bootstrap()112 bootstrap()
106 deploy()113 deploy(generate_dependents=True,
107 wait_for(60 * 40, 30, cf_service, endpoint, login)114 admin_password=options.admin_password)
108 run_cats()115 wait_for(60 * 40, 30,
116 cf_service, endpoint, partial(login, options.admin_password))
117 run_cats(options)
109 sys.exit(0)118 sys.exit(0)
110119
111120

Subscribers

People subscribed via source and target branches