Commit 7b2e4bf1 authored by Stavros Sachtouris's avatar Stavros Sachtouris
Browse files

Make wait mechanism usble by more cyclades methods

Refs: #3867
parent 60c42f9f
...@@ -39,7 +39,7 @@ from inspect import getargspec ...@@ -39,7 +39,7 @@ from inspect import getargspec
from kamaki.cli.argument import ArgumentParseManager from kamaki.cli.argument import ArgumentParseManager
from kamaki.cli.history import History from kamaki.cli.history import History
from kamaki.cli.utils import print_dict, red, magenta, yellow from kamaki.cli.utils import print_dict, red, magenta, yellow
from kamaki.cli.errors import CLIError from kamaki.cli.errors import CLIError, CLICmdSpecError
from kamaki.cli import logger from kamaki.cli import logger
_help = False _help = False
...@@ -146,9 +146,13 @@ def command(cmd_tree, prefix='', descedants_depth=1): ...@@ -146,9 +146,13 @@ def command(cmd_tree, prefix='', descedants_depth=1):
kloger.warning('%s failed max_len test' % cls_name) kloger.warning('%s failed max_len test' % cls_name)
return None return None
( try:
cls.description, sep, cls.long_description (
) = cls.__doc__.partition('\n') cls.description, sep, cls.long_description
) = cls.__doc__.partition('\n')
except AttributeError:
raise CLICmdSpecError(
'No commend in %s (acts as cmd description)' % cls.__name__)
_construct_command_syntax(cls) _construct_command_syntax(cls)
cmd_tree.add_command(cls_name, cls.description, cls) cmd_tree.add_command(cls_name, cls.description, cls)
......
...@@ -87,7 +87,6 @@ class _server_wait(object): ...@@ -87,7 +87,6 @@ class _server_wait(object):
currect_status, currect_status,
wait_cb=wait_cb) wait_cb=wait_cb)
except Exception: except Exception:
self._safe_progress_bar_finish(progress_bar)
raise raise
finally: finally:
self._safe_progress_bar_finish(progress_bar) self._safe_progress_bar_finish(progress_bar)
...@@ -97,6 +96,35 @@ class _server_wait(object): ...@@ -97,6 +96,35 @@ class _server_wait(object):
raiseCLIError(None, 'Time out') raiseCLIError(None, 'Time out')
class _network_wait(object):
wait_arguments = dict(
progress_bar=ProgressBarArgument(
'do not show progress bar',
('-N', '--no-progress-bar'),
False
)
)
def _wait(self, net_id, currect_status):
(progress_bar, wait_cb) = self._safe_progress_bar(
'Network %s still in %s mode' % (net_id, currect_status))
try:
new_mode = self.client.wait_network(
net_id,
currect_status,
wait_cb=wait_cb)
except Exception:
raise
finally:
self._safe_progress_bar_finish(progress_bar)
if new_mode:
print('Network %s is now in %s mode' % (net_id, new_mode))
else:
raiseCLIError(None, 'Time out')
class _init_cyclades(_command_init): class _init_cyclades(_command_init):
@errors.generic.all @errors.generic.all
@addLogSettings @addLogSettings
...@@ -778,6 +806,21 @@ class network_disconnect(_init_cyclades): ...@@ -778,6 +806,21 @@ class network_disconnect(_init_cyclades):
self._run(nic_id=nic_id, server_id=server_id) self._run(nic_id=nic_id, server_id=server_id)
@command(network_cmds)
class network_wait(_init_cyclades, _network_wait):
"""Wait for server to finish [PENDING, ACTIVE, DELETED]"""
@errors.generic.all
@errors.cyclades.connection
@errors.cyclades.network_id
def _run(self, network_id, currect_status):
self._wait(network_id, currect_status)
def main(self, network_id, currect_status='PENDING'):
super(self.__class__, self)._run()
self._run(network_id=network_id, currect_status=currect_status)
@command(floatingip_cmds) @command(floatingip_cmds)
class floatingip_pools(_init_cyclades, _optional_json): class floatingip_pools(_init_cyclades, _optional_json):
"""List all floating pools of floating ips""" """List all floating pools of floating ips"""
......
...@@ -257,66 +257,104 @@ class CycladesClient(CycladesRestClient): ...@@ -257,66 +257,104 @@ class CycladesClient(CycladesRestClient):
req = dict(remove=dict(attachment=nic)) req = dict(remove=dict(attachment=nic))
self.networks_post(netid, 'action', json_data=req) self.networks_post(netid, 'action', json_data=req)
def wait_server( def _wait(
self, self, item_id, current_status, get_status,
server_id, delay=1, max_wait=100, wait_cb=None):
current_status='BUILD', """Wait for item while its status is current_status
delay=0.5,
max_wait=128,
wait_cb=None):
"""Wait for server while its status is current_status
:param server_id: integer (str or int) :param server_id: integer (str or int)
:param current_status: (str) BUILD|ACTIVE|STOPPED|DELETED|REBOOT :param current_status: (str)
:param get_status: (method(self, item_id)) if called, returns
(status, progress %) If no way to tell progress, return None
:param delay: time interval between retries :param delay: time interval between retries
:param wait_cb: if set a progressbar is used to show progress :param wait_cb: if set a progress bar is used to show progress
:returns: (str) the new mode if succesfull, (bool) False if timed out :returns: (str) the new mode if successful, (bool) False if timed out
""" """
r = self.get_server_details(server_id) status, progress = get_status(self, item_id)
if r['status'] != current_status: if status != current_status:
return r['status'] return status
old_wait = total_wait = 0 old_wait = total_wait = 0
if current_status == 'BUILD': if wait_cb:
max_wait = 100
wait_gen = wait_cb(max_wait) if wait_cb else None
elif wait_cb:
wait_gen = wait_cb(1 + max_wait // delay) wait_gen = wait_cb(1 + max_wait // delay)
wait_gen.next() wait_gen.next()
while r['status'] == current_status and total_wait <= max_wait: while status == current_status and total_wait <= max_wait:
if current_status == 'BUILD': if wait_cb:
total_wait = int(r['progress']) try:
if wait_cb: for i in range(total_wait - old_wait):
for i in range(int(old_wait), int(total_wait)):
wait_gen.next() wait_gen.next()
old_wait = total_wait except Exception:
else: break
stdout.write('.')
stdout.flush()
else: else:
if wait_cb: stdout.write('.')
wait_gen.next() stdout.flush()
else: old_wait = total_wait
stdout.write('.') total_wait = progress or (total_wait + 1)
stdout.flush()
total_wait += delay
sleep(delay) sleep(delay)
r = self.get_server_details(server_id) status, progress = get_status(self, item_id)
if r['status'] != current_status: if total_wait < max_wait:
if wait_cb: if wait_cb:
try: try:
while True: for i in range(max_wait):
wait_gen.next() wait_gen.next()
except: except:
pass pass
return r['status'] return status if status != current_status else False
return False
def wait_server(
self, server_id,
current_status='BUILD',
delay=1, max_wait=100, wait_cb=None):
"""Wait for server while its status is current_status
:param server_id: integer (str or int)
:param current_status: (str) BUILD|ACTIVE|STOPPED|DELETED|REBOOT
:param delay: time interval between retries
:param wait_cb: if set a progressbar is used to show progress
:returns: (str) the new mode if succesfull, (bool) False if timed out
"""
def get_status(self, server_id):
r = self.get_server_details(server_id)
return r['status'], (r.get('progress', None) if (
current_status in ('BUILD', )) else None)
return self._wait(
server_id, current_status, get_status, delay, max_wait, wait_cb)
def wait_network(
self, net_id,
current_status='LALA', delay=1, max_wait=100, wait_cb=None):
"""Wait for network while its status is current_status
:param net_id: integer (str or int)
:param current_status: (str) PENDING | ACTIVE | DELETED
:param delay: time interval between retries
:param wait_cb: if set a progressbar is used to show progress
:returns: (str) the new mode if succesfull, (bool) False if timed out
"""
def get_status(self, net_id):
r = self.get_network_details(net_id)
return r['status'], None
return self._wait(
net_id, current_status, get_status, delay, max_wait, wait_cb)
def get_floating_ip_pools(self): def get_floating_ip_pools(self):
""" """
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment