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
from kamaki.cli.argument import ArgumentParseManager
from kamaki.cli.history import History
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
_help = False
......@@ -146,9 +146,13 @@ def command(cmd_tree, prefix='', descedants_depth=1):
kloger.warning('%s failed max_len test' % cls_name)
return None
try:
(
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)
cmd_tree.add_command(cls_name, cls.description, cls)
......
......@@ -87,7 +87,6 @@ class _server_wait(object):
currect_status,
wait_cb=wait_cb)
except Exception:
self._safe_progress_bar_finish(progress_bar)
raise
finally:
self._safe_progress_bar_finish(progress_bar)
......@@ -97,6 +96,35 @@ class _server_wait(object):
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):
@errors.generic.all
@addLogSettings
......@@ -778,6 +806,21 @@ class network_disconnect(_init_cyclades):
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)
class floatingip_pools(_init_cyclades, _optional_json):
"""List all floating pools of floating ips"""
......
......@@ -257,66 +257,104 @@ class CycladesClient(CycladesRestClient):
req = dict(remove=dict(attachment=nic))
self.networks_post(netid, 'action', json_data=req)
def wait_server(
self,
server_id,
current_status='BUILD',
delay=0.5,
max_wait=128,
wait_cb=None):
"""Wait for server while its status is current_status
def _wait(
self, item_id, current_status, get_status,
delay=1, max_wait=100, wait_cb=None):
"""Wait for item while its status is current_status
: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 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)
if r['status'] != current_status:
return r['status']
status, progress = get_status(self, item_id)
if status != current_status:
return status
old_wait = total_wait = 0
if current_status == 'BUILD':
max_wait = 100
wait_gen = wait_cb(max_wait) if wait_cb else None
elif wait_cb:
if wait_cb:
wait_gen = wait_cb(1 + max_wait // delay)
wait_gen.next()
while r['status'] == current_status and total_wait <= max_wait:
if current_status == 'BUILD':
total_wait = int(r['progress'])
if wait_cb:
for i in range(int(old_wait), int(total_wait)):
wait_gen.next()
old_wait = total_wait
else:
stdout.write('.')
stdout.flush()
else:
while status == current_status and total_wait <= max_wait:
if wait_cb:
try:
for i in range(total_wait - old_wait):
wait_gen.next()
except Exception:
break
else:
stdout.write('.')
stdout.flush()
total_wait += delay
old_wait = total_wait
total_wait = progress or (total_wait + 1)
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:
try:
while True:
for i in range(max_wait):
wait_gen.next()
except:
pass
return r['status']
return False
return status if status != current_status else 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):
"""
......
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