Merge lp:~bcsaller/charms/trusty/cloudfoundry/progressbar into lp:~cf-charmers/charms/trusty/cloudfoundry/trunk
- Trusty Tahr (14.04)
- progressbar
- Merge into trunk
Proposed by
Benjamin Saller
Status: | Merged |
---|---|
Merged at revision: | 160 |
Proposed branch: | lp:~bcsaller/charms/trusty/cloudfoundry/progressbar |
Merge into: | lp:~cf-charmers/charms/trusty/cloudfoundry/trunk |
Diff against target: |
449 lines (+169/-50) 9 files modified
README.rst (+4/-6) cfdeploy (+114/-11) cloudfoundry/utils.py (+41/-23) reconciler/app.py (+2/-3) reconciler/strategy.py (+2/-2) reconciler/tactics.py (+2/-2) tests/test_strategy.py (+1/-1) tests/test_utils.py (+2/-2) tox.ini (+1/-0) |
To merge this branch: | bzr merge lp:~bcsaller/charms/trusty/cloudfoundry/progressbar |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Cory Johns (community) | Needs Fixing | ||
Review via email: mp+241618@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 178. By Benjamin Saller
-
attempt to install deps from the wheelhouse, needs verification
Revision history for this message
Cory Johns (johnsca) wrote : | # |
- 179. By Benjamin Saller
-
change func name
- 180. By Benjamin Saller
-
build out a virtualenv with deps prior to kickoff
Revision history for this message
Benjamin Saller (bcsaller) wrote : | # |
I re-pushed this with a venv.
Revision history for this message
Cory Johns (johnsca) wrote : | # |
Typo in python-virtualenv package, noted inline, below.
review:
Needs Fixing
Revision history for this message
Cory Johns (johnsca) wrote : | # |
Actually, I can just fix this while merging.
Revision history for this message
Cory Johns (johnsca) wrote : | # |
I propose this change to make it less chatty: http://
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'README.rst' | |||
2 | --- README.rst 2014-11-06 23:37:55 +0000 | |||
3 | +++ README.rst 2014-11-13 00:05:21 +0000 | |||
4 | @@ -24,11 +24,6 @@ | |||
5 | 24 | We provide a set of helper scripts (in bash) which can be used to assist in the deployment and | 24 | We provide a set of helper scripts (in bash) which can be used to assist in the deployment and |
6 | 25 | management of CF. | 25 | management of CF. |
7 | 26 | 26 | ||
8 | 27 | You will need the cf command line client. This can easily be installed using the following: | ||
9 | 28 | |||
10 | 29 | wget http://go-cli.s3-website-us-east-1.amazonaws.com/releases/latest/cf-cli_amd64.deb | ||
11 | 30 | dpkg -i cf-cli_amd64.deb | ||
12 | 31 | |||
13 | 32 | 27 | ||
14 | 33 | Deployment | 28 | Deployment |
15 | 34 | ---------- | 29 | ---------- |
16 | @@ -51,7 +46,10 @@ | |||
17 | 51 | will block until the deployment is fully up and running. It also will create a | 46 | will block until the deployment is fully up and running. It also will create a |
18 | 52 | CF "admin" user with the given password, leaving you logged in and ready to push | 47 | CF "admin" user with the given password, leaving you logged in and ready to push |
19 | 53 | a CF app. Note that while this can take quite some time, the whole process is | 48 | a CF app. Note that while this can take quite some time, the whole process is |
21 | 54 | automated. | 49 | automated. |
22 | 50 | |||
23 | 51 | If you don't have the cf command line client the latest one will be installed | ||
24 | 52 | from a .deb package to your local system as part of cfdeploy. | ||
25 | 55 | 53 | ||
26 | 56 | Once the deploy completes, you can push apps. A sample application we recommend | 54 | Once the deploy completes, you can push apps. A sample application we recommend |
27 | 57 | to become familiar with the system is GitHub High Score website. This can be | 55 | to become familiar with the system is GitHub High Score website. This can be |
28 | 58 | 56 | ||
29 | === modified file 'cfdeploy' | |||
30 | --- cfdeploy 2014-11-07 00:06:24 +0000 | |||
31 | +++ cfdeploy 2014-11-13 00:05:21 +0000 | |||
32 | @@ -2,9 +2,48 @@ | |||
33 | 2 | # modeline vim:set syntax=python | 2 | # modeline vim:set syntax=python |
34 | 3 | import argparse | 3 | import argparse |
35 | 4 | import logging | 4 | import logging |
37 | 5 | import webbrowser | 5 | import os |
38 | 6 | import subprocess | ||
39 | 7 | import sys | ||
40 | 8 | from contextlib import contextmanager | ||
41 | 6 | from functools import partial | 9 | from functools import partial |
42 | 7 | 10 | ||
43 | 11 | |||
44 | 12 | def verify_dep(name): | ||
45 | 13 | try: | ||
46 | 14 | __import__(name) | ||
47 | 15 | return True | ||
48 | 16 | except ImportError: | ||
49 | 17 | pass | ||
50 | 18 | return False | ||
51 | 19 | |||
52 | 20 | |||
53 | 21 | def install_python_deps(): | ||
54 | 22 | print "Setting up virutalenv." | ||
55 | 23 | subprocess.check_output(['pip', 'install', 'wheel']) | ||
56 | 24 | for dep in ['progress', 'requests', 'jujuclient']: | ||
57 | 25 | subprocess.check_output(['pip', 'install', | ||
58 | 26 | '--use-wheel', '--find-links', | ||
59 | 27 | os.path.abspath('wheelhouse'), | ||
60 | 28 | dep]) | ||
61 | 29 | |||
62 | 30 | |||
63 | 31 | def prepare_runtime(): | ||
64 | 32 | activate = "bin/activate_this.py" | ||
65 | 33 | if not verify_dep('virtualenv'): | ||
66 | 34 | print "(sudo) installing python-virtualenv package." | ||
67 | 35 | subprocess.check_call( | ||
68 | 36 | ['sudo', 'apt-get', 'install', '-yq', 'python-virutalenv']) | ||
69 | 37 | import virtualenv | ||
70 | 38 | venv = os.path.join(os.getcwd(), '.venv') | ||
71 | 39 | if not os.path.exists(venv): | ||
72 | 40 | virtualenv.create_environment(venv, site_packages=False) | ||
73 | 41 | venv_launcher = os.path.join(venv, activate) | ||
74 | 42 | execfile(venv_launcher, dict(__file__=venv_launcher)) | ||
75 | 43 | install_python_deps() | ||
76 | 44 | |||
77 | 45 | prepare_runtime() | ||
78 | 46 | |||
79 | 8 | from cloudfoundry.releases import RELEASES | 47 | from cloudfoundry.releases import RELEASES |
80 | 9 | from cloudfoundry.utils import (bootstrap, | 48 | from cloudfoundry.utils import (bootstrap, |
81 | 10 | cf_service, | 49 | cf_service, |
82 | @@ -15,9 +54,13 @@ | |||
83 | 15 | login, | 54 | login, |
84 | 16 | reconciler_endpoint, | 55 | reconciler_endpoint, |
85 | 17 | webadmin_endpoint, | 56 | webadmin_endpoint, |
86 | 57 | sh, | ||
87 | 18 | socket_open, | 58 | socket_open, |
88 | 19 | until, | 59 | until, |
90 | 20 | wait_for) | 60 | which |
91 | 61 | ) | ||
92 | 62 | |||
93 | 63 | from progress.bar import Bar | ||
94 | 21 | 64 | ||
95 | 22 | 65 | ||
96 | 23 | def setup(): | 66 | def setup(): |
97 | @@ -35,31 +78,91 @@ | |||
98 | 35 | return options | 78 | return options |
99 | 36 | 79 | ||
100 | 37 | 80 | ||
101 | 81 | # This is done because the default webbrowser invocation will output | ||
102 | 82 | # on stderr and muck with the progress bar. By hiding the output | ||
103 | 83 | # with devnull it proceeds as expected. | ||
104 | 84 | show = sh.check('xdg-open') | ||
105 | 85 | |||
106 | 86 | |||
107 | 87 | @contextmanager | ||
108 | 88 | def devnull(): | ||
109 | 89 | _save = sys.stderr | ||
110 | 90 | fp = open('/dev/null', 'w') | ||
111 | 91 | sys.stderr = fp | ||
112 | 92 | yield | ||
113 | 93 | sys.stderr = _save | ||
114 | 94 | |||
115 | 95 | |||
116 | 38 | def show_reconciler(): | 96 | def show_reconciler(): |
119 | 39 | uri = "http://%s:8888/" % reconciler_endpoint() | 97 | with devnull(): |
120 | 40 | webbrowser.open_new_tab(uri) | 98 | uri = "http://%s:8888/" % reconciler_endpoint() |
121 | 99 | show(uri) | ||
122 | 41 | 100 | ||
123 | 42 | 101 | ||
124 | 43 | def show_webadmin(): | 102 | def show_webadmin(): |
127 | 44 | uri = "http://%s:8070/" % webadmin_endpoint() | 103 | with devnull(): |
128 | 45 | webbrowser.open_new_tab(uri) | 104 | uri = "http://%s:8070/" % webadmin_endpoint() |
129 | 105 | show(uri) | ||
130 | 106 | |||
131 | 107 | |||
132 | 108 | class ProgressBar(Bar): | ||
133 | 109 | message = "Deploying CloudFoundry" | ||
134 | 110 | fill = "." | ||
135 | 111 | suffix = "%(percent).1f%% %(elapsed_td)s" | ||
136 | 112 | |||
137 | 113 | def next(self, i=1, message=None): | ||
138 | 114 | if message: | ||
139 | 115 | self.message = message | ||
140 | 116 | super(ProgressBar, self).next(i) | ||
141 | 117 | |||
142 | 118 | |||
143 | 119 | def install_deps(): | ||
144 | 120 | if not which('cf'): | ||
145 | 121 | from platform import machine | ||
146 | 122 | if machine() != "x86_64": | ||
147 | 123 | print "Unable to install CF CLI for your architecture. " | ||
148 | 124 | "Deploy will not work as expected." | ||
149 | 125 | return | ||
150 | 126 | sh.wget('http://go-cli.s3-website-us-east-1.amazonaws.com/' | ||
151 | 127 | 'releases/latest/cf-cli_amd64.deb') | ||
152 | 128 | print "Installing CF CLI (this requires sudo access)" | ||
153 | 129 | sh.sudo('dpkg', '-i', 'cf-cli_amd64.deb') | ||
154 | 46 | 130 | ||
155 | 47 | 131 | ||
156 | 48 | def main(): | 132 | def main(): |
157 | 49 | options = setup() | 133 | options = setup() |
158 | 50 | logging.basicConfig(level=options.log_level) | 134 | logging.basicConfig(level=options.log_level) |
159 | 135 | install_deps() | ||
160 | 136 | |||
161 | 137 | bar = ProgressBar('Deploying CloudFoundry', max=10) | ||
162 | 138 | bar.start() | ||
163 | 139 | bar.next(message='Bootstrapping') | ||
164 | 51 | bootstrap() | 140 | bootstrap() |
166 | 52 | until(juju_state_server) | 141 | until(juju_state_server, bar=bar, message="Waiting for State Server") |
167 | 142 | bar.next(message='Deploying Orchestrator') | ||
168 | 53 | deploy(constraints=options.constraints, | 143 | deploy(constraints=options.constraints, |
169 | 54 | generate_dependents=options.generate, | 144 | generate_dependents=options.generate, |
170 | 55 | admin_password=options.admin_password) | 145 | admin_password=options.admin_password) |
172 | 56 | until(lambda: socket_open(reconciler_endpoint(), 8888)) | 146 | until(lambda: socket_open(reconciler_endpoint(), 8888), |
173 | 147 | bar=bar, message="Waiting on Reconciler") | ||
174 | 148 | bar.next(message='Showing Reconciler') | ||
175 | 57 | show_reconciler() | 149 | show_reconciler() |
176 | 150 | |||
177 | 58 | # Wait forever, its in the reconciler's hands now. | 151 | # Wait forever, its in the reconciler's hands now. |
180 | 59 | wait_for(0, 30, cf_service, endpoint, partial(login, options.admin_password)) | 152 | until(cf_service, bar=bar, message="Waiting for Orchestrator Charm") |
181 | 60 | until(lambda: socket_open(webadmin_endpoint(), 8070)) | 153 | until(endpoint, bar=bar, message='Waiting for CloudFoundry API endpoint') |
182 | 154 | until(partial(login, options.admin_password), | ||
183 | 155 | bar=bar, message='Waiting to login to CloudFoundry (long)') | ||
184 | 156 | until(lambda: socket_open(webadmin_endpoint(), 8070), | ||
185 | 157 | bar=bar, message="Waiting on webadmin.") | ||
186 | 158 | bar.next(message="Opening Admin Console") | ||
187 | 61 | show_webadmin() | 159 | show_webadmin() |
189 | 62 | print "You should now be logged into a running CF deployment" | 160 | bar.finish() |
190 | 161 | |||
191 | 162 | print "You should now be logged into a running CF deployment." | ||
192 | 163 | if which('cf'): | ||
193 | 164 | print "The 'cf' command line client is installed and available." | ||
194 | 165 | |||
195 | 63 | 166 | ||
196 | 64 | if __name__ == "__main__": | 167 | if __name__ == "__main__": |
197 | 65 | main() | 168 | main() |
198 | 66 | 169 | ||
199 | === modified file 'cloudfoundry/utils.py' | |||
200 | --- cloudfoundry/utils.py 2014-11-07 00:06:24 +0000 | |||
201 | +++ cloudfoundry/utils.py 2014-11-13 00:05:21 +0000 | |||
202 | @@ -168,6 +168,7 @@ | |||
203 | 168 | 168 | ||
204 | 169 | def command(*base_args, **kwargs): | 169 | def command(*base_args, **kwargs): |
205 | 170 | check = kwargs.pop('check', False) | 170 | check = kwargs.pop('check', False) |
206 | 171 | throw = kwargs.pop('throw', True) | ||
207 | 171 | 172 | ||
208 | 172 | def callable_command(*args, **kws): | 173 | def callable_command(*args, **kws): |
209 | 173 | kwargs.update(kws) | 174 | kwargs.update(kws) |
210 | @@ -176,10 +177,20 @@ | |||
211 | 176 | if 'env' not in kwargs: | 177 | if 'env' not in kwargs: |
212 | 177 | kwargs['env'] = os.environ | 178 | kwargs['env'] = os.environ |
213 | 178 | logging.debug("invoke: %s", all_args) | 179 | logging.debug("invoke: %s", all_args) |
214 | 180 | |||
215 | 181 | p = subprocess.Popen(all_args, | ||
216 | 182 | stdout=subprocess.PIPE, | ||
217 | 183 | stderr=subprocess.STDOUT, | ||
218 | 184 | **kwargs) | ||
219 | 185 | output, _ = p.communicate() | ||
220 | 186 | ret_code = p.poll() | ||
221 | 187 | logging.debug('result: %s', output) | ||
222 | 179 | if check is True: | 188 | if check is True: |
224 | 180 | return subprocess.check_call(all_args, **kwargs) | 189 | if ret_code != 0 and throw: |
225 | 190 | raise subprocess.CalledProcessError(ret_code, all_args, output=output) | ||
226 | 191 | return ret_code | ||
227 | 181 | else: | 192 | else: |
229 | 182 | return subprocess.check_output(all_args, **kwargs).strip() | 193 | return output.strip() |
230 | 183 | return callable_command | 194 | return callable_command |
231 | 184 | 195 | ||
232 | 185 | 196 | ||
233 | @@ -196,7 +207,7 @@ | |||
234 | 196 | 207 | ||
235 | 197 | sh = Commander() | 208 | sh = Commander() |
236 | 198 | dig = command('dig', '+short') | 209 | dig = command('dig', '+short') |
238 | 199 | api_endpoints = sh.check('juju', 'api-endpoints') | 210 | api_endpoints = sh.check('juju', 'api-endpoints', throw=False) |
239 | 200 | 211 | ||
240 | 201 | 212 | ||
241 | 202 | def current_env(): | 213 | def current_env(): |
242 | @@ -210,7 +221,7 @@ | |||
243 | 210 | 'environments/%s.jenv' % cenv) | 221 | 'environments/%s.jenv' % cenv) |
244 | 211 | 222 | ||
245 | 212 | 223 | ||
247 | 213 | def wait_for(timeout, interval, *callbacks): | 224 | def wait_for(timeout, interval, *callbacks, **kwargs): |
248 | 214 | """ | 225 | """ |
249 | 215 | Repeatedly try callbacks until all return True | 226 | Repeatedly try callbacks until all return True |
250 | 216 | 227 | ||
251 | @@ -223,25 +234,35 @@ | |||
252 | 223 | hardware fails, or the heat death of the universe. | 234 | hardware fails, or the heat death of the universe. |
253 | 224 | """ | 235 | """ |
254 | 225 | start = time.time() | 236 | start = time.time() |
255 | 237 | if timeout: | ||
256 | 238 | end = start + timeout | ||
257 | 239 | else: | ||
258 | 240 | end = 0 | ||
259 | 241 | |||
260 | 242 | bar = kwargs.get('bar', None) | ||
261 | 243 | message = kwargs.get('message', None) | ||
262 | 244 | once = 1 | ||
263 | 226 | while True: | 245 | while True: |
264 | 227 | passes = True | 246 | passes = True |
276 | 228 | for callback in callbacks: | 247 | if end > 0 and time.time() > end: |
266 | 229 | result = callback() | ||
267 | 230 | passes = passes & bool(result) | ||
268 | 231 | if passes is False: | ||
269 | 232 | break | ||
270 | 233 | if passes is True: | ||
271 | 234 | break | ||
272 | 235 | current = time.time() | ||
273 | 236 | if timeout != 0 and ( | ||
274 | 237 | current - start >= timeout or | ||
275 | 238 | (current - start) + interval > timeout): | ||
277 | 239 | raise OSError("Timeout exceeded in wait_for") | 248 | raise OSError("Timeout exceeded in wait_for") |
283 | 240 | time.sleep(interval) | 249 | if bar: |
284 | 241 | 250 | bar.next(once, message=message) | |
285 | 242 | 251 | if once == 1: | |
286 | 243 | def until(*callbacks): | 252 | once = 0 |
287 | 244 | return wait_for(0, 20, *callbacks) | 253 | if int(time.time()) % interval == 0: |
288 | 254 | for callback in callbacks: | ||
289 | 255 | result = callback() | ||
290 | 256 | passes = passes & bool(result) | ||
291 | 257 | if passes is False: | ||
292 | 258 | break | ||
293 | 259 | if passes is True: | ||
294 | 260 | break | ||
295 | 261 | time.sleep(1) | ||
296 | 262 | |||
297 | 263 | |||
298 | 264 | def until(*callbacks, **kwargs): | ||
299 | 265 | return wait_for(0, 20, *callbacks, **kwargs) | ||
300 | 245 | 266 | ||
301 | 246 | 267 | ||
302 | 247 | def juju_state_server(): | 268 | def juju_state_server(): |
303 | @@ -249,7 +270,6 @@ | |||
304 | 249 | return False | 270 | return False |
305 | 250 | endpoints = json.loads(sh.juju('api-endpoints', '--format=json')) | 271 | endpoints = json.loads(sh.juju('api-endpoints', '--format=json')) |
306 | 251 | for ep in endpoints: | 272 | for ep in endpoints: |
307 | 252 | print "Attempt to connect to juju state server:", ep | ||
308 | 253 | host, port = ep.split(':', 1) | 273 | host, port = ep.split(':', 1) |
309 | 254 | result = socket_open(host, int(port)) | 274 | result = socket_open(host, int(port)) |
310 | 255 | if result is True: | 275 | if result is True: |
311 | @@ -266,7 +286,6 @@ | |||
312 | 266 | # .jenv with the state server | 286 | # .jenv with the state server |
313 | 267 | sh.juju('status') | 287 | sh.juju('status') |
314 | 268 | data = yaml.load(open(get_jenv())) | 288 | data = yaml.load(open(get_jenv())) |
315 | 269 | print "Waiting for state server(s)", data['state-servers'] | ||
316 | 270 | return data.get('state-servers', []) != [] | 289 | return data.get('state-servers', []) != [] |
317 | 271 | current = current_env() | 290 | current = current_env() |
318 | 272 | wait_for(1000, 20, env_connection) | 291 | wait_for(1000, 20, env_connection) |
319 | @@ -387,7 +406,6 @@ | |||
320 | 387 | if constraints: | 406 | if constraints: |
321 | 388 | args.append('--constraints=%s' % constraints) | 407 | args.append('--constraints=%s' % constraints) |
322 | 389 | args.append('local:trusty/cloudfoundry') | 408 | args.append('local:trusty/cloudfoundry') |
323 | 390 | print "Deploying:", ' '.join(args) | ||
324 | 391 | sh.juju(*args) | 409 | sh.juju(*args) |
325 | 392 | time.sleep(5) | 410 | time.sleep(5) |
326 | 393 | sh.juju('expose', 'cloudfoundry') | 411 | sh.juju('expose', 'cloudfoundry') |
327 | 394 | 412 | ||
328 | === modified file 'reconciler/app.py' | |||
329 | --- reconciler/app.py 2014-11-03 16:13:57 +0000 | |||
330 | +++ reconciler/app.py 2014-11-13 00:05:21 +0000 | |||
331 | @@ -49,7 +49,6 @@ | |||
332 | 49 | import tornado.web | 49 | import tornado.web |
333 | 50 | 50 | ||
334 | 51 | from tornado.options import define, options | 51 | from tornado.options import define, options |
335 | 52 | from cloudfoundry import config | ||
336 | 53 | from cloudfoundry import utils | 52 | from cloudfoundry import utils |
337 | 54 | from cloudfoundry.path import path | 53 | from cloudfoundry.path import path |
338 | 55 | from reconciler import strategy | 54 | from reconciler import strategy |
339 | @@ -57,6 +56,8 @@ | |||
340 | 57 | from reconciler.ui.app import DashboardIO | 56 | from reconciler.ui.app import DashboardIO |
341 | 58 | from reconciler.ui.app import static_resources | 57 | from reconciler.ui.app import static_resources |
342 | 59 | 58 | ||
343 | 59 | import config | ||
344 | 60 | |||
345 | 60 | application = None | 61 | application = None |
346 | 61 | env_name = None | 62 | env_name = None |
347 | 62 | server = None | 63 | server = None |
348 | @@ -283,7 +284,6 @@ | |||
349 | 283 | loop = tornado.ioloop.IOLoop.instance() | 284 | loop = tornado.ioloop.IOLoop.instance() |
350 | 284 | # call poll_health ASAP, to populate the initial health data, and | 285 | # call poll_health ASAP, to populate the initial health data, and |
351 | 285 | # also schedule poll_health for every 60s to refresh health data | 286 | # also schedule poll_health for every 60s to refresh health data |
352 | 286 | |||
353 | 287 | loop.add_callback(poll_health) | 287 | loop.add_callback(poll_health) |
354 | 288 | tornado.ioloop.PeriodicCallback(poll_health, 60000, io_loop=loop).start() | 288 | tornado.ioloop.PeriodicCallback(poll_health, 60000, io_loop=loop).start() |
355 | 289 | tornado.ioloop.PeriodicCallback(poll_current_state, 60000, | 289 | tornado.ioloop.PeriodicCallback(poll_current_state, 60000, |
356 | @@ -294,6 +294,5 @@ | |||
357 | 294 | io_loop=loop).start() | 294 | io_loop=loop).start() |
358 | 295 | loop.start() | 295 | loop.start() |
359 | 296 | 296 | ||
360 | 297 | |||
361 | 298 | if __name__ == "__main__": | 297 | if __name__ == "__main__": |
362 | 299 | main() | 298 | main() |
363 | 300 | 299 | ||
364 | === renamed file 'cloudfoundry/config.py' => 'reconciler/config.py' | |||
365 | === modified file 'reconciler/strategy.py' | |||
366 | --- reconciler/strategy.py 2014-11-05 23:40:05 +0000 | |||
367 | +++ reconciler/strategy.py 2014-11-13 00:05:21 +0000 | |||
368 | @@ -7,7 +7,7 @@ | |||
369 | 7 | from tornado import gen | 7 | from tornado import gen |
370 | 8 | 8 | ||
371 | 9 | from reconciler import tactics | 9 | from reconciler import tactics |
373 | 10 | from cloudfoundry.config import (PENDING, COMPLETE, FAILED, RUNNING) | 10 | from reconciler.config import (PENDING, COMPLETE, FAILED, RUNNING) |
374 | 11 | from cloudfoundry import utils | 11 | from cloudfoundry import utils |
375 | 12 | from cloudfoundry import tsort | 12 | from cloudfoundry import tsort |
376 | 13 | 13 | ||
377 | @@ -160,7 +160,7 @@ | |||
378 | 160 | elif expose_intent is False and exposed is True: | 160 | elif expose_intent is False and exposed is True: |
379 | 161 | result.append(tactics.UnexposeTactic(service=service)) | 161 | result.append(tactics.UnexposeTactic(service=service)) |
380 | 162 | 162 | ||
382 | 163 | logging.debug("Build New %s", result) | 163 | logging.debug("Build Strategy %s", result) |
383 | 164 | return result | 164 | return result |
384 | 165 | 165 | ||
385 | 166 | def build_relations(self): | 166 | def build_relations(self): |
386 | 167 | 167 | ||
387 | === modified file 'reconciler/tactics.py' | |||
388 | --- reconciler/tactics.py 2014-11-05 23:40:05 +0000 | |||
389 | +++ reconciler/tactics.py 2014-11-13 00:05:21 +0000 | |||
390 | @@ -3,7 +3,7 @@ | |||
391 | 3 | import os | 3 | import os |
392 | 4 | import shutil | 4 | import shutil |
393 | 5 | 5 | ||
395 | 6 | from cloudfoundry.config import ( | 6 | from reconciler.config import ( |
396 | 7 | PENDING, COMPLETE, RUNNING, FAILED, STATES | 7 | PENDING, COMPLETE, RUNNING, FAILED, STATES |
397 | 8 | ) | 8 | ) |
398 | 9 | 9 | ||
399 | @@ -169,7 +169,7 @@ | |||
400 | 169 | class UnexposeTactic(Tactic): | 169 | class UnexposeTactic(Tactic): |
401 | 170 | name = "Unexpose Service" | 170 | name = "Unexpose Service" |
402 | 171 | 171 | ||
404 | 172 | def run(self, env, **kwargs): | 172 | def _run(self, env, **kwargs): |
405 | 173 | s = kwargs['service'] | 173 | s = kwargs['service'] |
406 | 174 | env.unexpose(s['service_name']) | 174 | env.unexpose(s['service_name']) |
407 | 175 | 175 | ||
408 | 176 | 176 | ||
409 | === modified file 'tests/test_strategy.py' | |||
410 | --- tests/test_strategy.py 2014-10-30 18:34:30 +0000 | |||
411 | +++ tests/test_strategy.py 2014-11-13 00:05:21 +0000 | |||
412 | @@ -2,7 +2,7 @@ | |||
413 | 2 | import unittest | 2 | import unittest |
414 | 3 | import mock | 3 | import mock |
415 | 4 | 4 | ||
417 | 5 | from cloudfoundry import config | 5 | from reconciler import config |
418 | 6 | from reconciler import tactics | 6 | from reconciler import tactics |
419 | 7 | from reconciler import strategy | 7 | from reconciler import strategy |
420 | 8 | 8 | ||
421 | 9 | 9 | ||
422 | === modified file 'tests/test_utils.py' | |||
423 | --- tests/test_utils.py 2014-10-27 19:48:56 +0000 | |||
424 | +++ tests/test_utils.py 2014-11-13 00:05:21 +0000 | |||
425 | @@ -7,10 +7,10 @@ | |||
426 | 7 | 7 | ||
427 | 8 | 8 | ||
428 | 9 | class TestUtils(unittest.TestCase): | 9 | class TestUtils(unittest.TestCase): |
430 | 10 | @mock.patch('subprocess.check_output') | 10 | @mock.patch('cloudfoundry.utils.sh.juju') |
431 | 11 | def test_current_env(self, check_output): | 11 | def test_current_env(self, check_output): |
432 | 12 | utils.current_env() | 12 | utils.current_env() |
434 | 13 | check_output.assert_called_once_with(('juju', 'switch'), env=mock.ANY) | 13 | check_output.assert_called_once_with('switch') |
435 | 14 | 14 | ||
436 | 15 | def test_flatten_relations(self): | 15 | def test_flatten_relations(self): |
437 | 16 | r = utils.flatten_relations([ | 16 | r = utils.flatten_relations([ |
438 | 17 | 17 | ||
439 | === modified file 'tox.ini' | |||
440 | --- tox.ini 2014-09-30 21:15:05 +0000 | |||
441 | +++ tox.ini 2014-11-13 00:05:21 +0000 | |||
442 | @@ -30,3 +30,4 @@ | |||
443 | 30 | clint | 30 | clint |
444 | 31 | path.py | 31 | path.py |
445 | 32 | subparse | 32 | subparse |
446 | 33 | progress | ||
447 | 33 | 34 | ||
448 | === added file 'wheelhouse/progress-1.2-py2-none-any.whl' | |||
449 | 34 | Binary files wheelhouse/progress-1.2-py2-none-any.whl 1970-01-01 00:00:00 +0000 and wheelhouse/progress-1.2-py2-none-any.whl 2014-11-13 00:05:21 +0000 differ | 35 | Binary files wheelhouse/progress-1.2-py2-none-any.whl 1970-01-01 00:00:00 +0000 and wheelhouse/progress-1.2-py2-none-any.whl 2014-11-13 00:05:21 +0000 differ |
See inline comments.