Commit 8547cd19 authored by Stavros Sachtouris's avatar Stavros Sachtouris
Browse files

Add a timeout argument to cli *_wait methods

Refs: #4352
parent e9c73313
...@@ -332,7 +332,8 @@ class ProgressBarArgument(FlagArgument): ...@@ -332,7 +332,8 @@ class ProgressBarArgument(FlagArgument):
newarg._value = self._value newarg._value = self._value
return newarg return newarg
def get_generator(self, message, message_len=25, timeout=False): def get_generator(
self, message, message_len=25, countdown=False, timeout=100):
"""Get a generator to handle progress of the bar (gen.next())""" """Get a generator to handle progress of the bar (gen.next())"""
if self.value: if self.value:
return None return None
...@@ -341,17 +342,18 @@ class ProgressBarArgument(FlagArgument): ...@@ -341,17 +342,18 @@ class ProgressBarArgument(FlagArgument):
except NameError: except NameError:
self.value = None self.value = None
return self.value return self.value
if timeout: if countdown:
bar_phases = list(self.bar.phases) bar_phases = list(self.bar.phases)
bar_phases[0], bar_phases[-1] = bar_phases[-1], '' self.bar.empty_fill, bar_phases[0] = bar_phases[-1], ''
bar_phases.reverse()
self.bar.phases = bar_phases self.bar.phases = bar_phases
self.bar.empty_fill = bar_phases[0] self.bar.bar_prefix = ' '
self.bar.bar_prefix = ' (Timeout:'
self.bar.bar_suffix = ' ' self.bar.bar_suffix = ' '
self.bar.suffix = '%(eta)ds)' self.bar.max = timeout or 100
self.bar.eta = 120 self.bar.suffix = '%(remaining)ds to timeout'
else: else:
self.bar.suffix = '%(percent)d%% - %(eta)ds' self.bar.suffix = '%(percent)d%% - %(eta)ds'
self.bar.eta = timeout or 100
self.bar.message = message.ljust(message_len) self.bar.message = message.ljust(message_len)
self.bar.start() self.bar.start()
......
...@@ -379,14 +379,13 @@ class ProgressBarArgument(TestCase): ...@@ -379,14 +379,13 @@ class ProgressBarArgument(TestCase):
self.assertEqual(pba.bar.suffix, '%(percent)d%% - %(eta)ds') self.assertEqual(pba.bar.suffix, '%(percent)d%% - %(eta)ds')
start.assert_called_once() start.assert_called_once()
pba.get_generator(msg, msg_len, timeout=True) pba.get_generator(msg, msg_len, countdown=True)
self.assertTrue( self.assertTrue(
isinstance(pba.bar, argument.KamakiProgressBar)) isinstance(pba.bar, argument.KamakiProgressBar))
self.assertNotEqual(pba.bar.message, msg) self.assertNotEqual(pba.bar.message, msg)
self.assertEqual(pba.bar.message, '%s%s' % ( self.assertEqual(pba.bar.message, '%s%s' % (
msg, ' ' * (msg_len - len(msg)))) msg, ' ' * (msg_len - len(msg))))
self.assertEqual(pba.bar.bar_prefix, ' (Timeout:') self.assertEqual(pba.bar.suffix, '%(remaining)ds to timeout')
self.assertEqual(pba.bar.suffix, '%(eta)ds)')
finally: finally:
try: try:
pba.finish() pba.finish()
......
...@@ -177,12 +177,14 @@ class _command_init(object): ...@@ -177,12 +177,14 @@ class _command_init(object):
assert max_threads > 0, 'invalid max_threads config option' assert max_threads > 0, 'invalid max_threads config option'
self.client.MAX_THREADS = max_threads self.client.MAX_THREADS = max_threads
def _safe_progress_bar(self, msg, arg='progress_bar', timeout=False): def _safe_progress_bar(
self, msg, arg='progress_bar', countdown=False, timeout=100):
"""Try to get a progress bar, but do not raise errors""" """Try to get a progress bar, but do not raise errors"""
try: try:
progress_bar = self.arguments[arg] progress_bar = self.arguments[arg]
progress_bar.file = self._err progress_bar.file = self._err
gen = progress_bar.get_generator(msg, timeout=timeout) gen = progress_bar.get_generator(
msg, countdown=countdown, timeout=timeout)
except Exception: except Exception:
return (None, None) return (None, None)
return (progress_bar, gen) return (progress_bar, gen)
......
...@@ -77,20 +77,20 @@ class _service_wait(object): ...@@ -77,20 +77,20 @@ class _service_wait(object):
def _wait( def _wait(
self, service, service_id, status_method, current_status, self, service, service_id, status_method, current_status,
timeout=True): countdown=True, timeout=60):
(progress_bar, wait_cb) = self._safe_progress_bar( (progress_bar, wait_cb) = self._safe_progress_bar(
'%s %s: status is still %s' % ( '%s %s: status is still %s' % (
service, service_id, current_status), service, service_id, current_status),
timeout=timeout) countdown=countdown, timeout=timeout)
try: try:
new_mode = status_method( new_mode = status_method(
service_id, current_status, wait_cb=wait_cb) service_id, current_status, max_wait=timeout, wait_cb=wait_cb)
if new_mode: if new_mode:
self.error('%s %s: status is now %s' % ( self.error('%s %s: status is now %s' % (
service, service_id, new_mode)) service, service_id, new_mode))
else: else:
self.error('%s %s: (timeout) status is still %s' % ( self.error('%s %s: status is still %s' % (
service, service_id, current_status)) service, service_id, current_status))
except KeyboardInterrupt: except KeyboardInterrupt:
self.error('\n- canceled') self.error('\n- canceled')
...@@ -100,17 +100,19 @@ class _service_wait(object): ...@@ -100,17 +100,19 @@ class _service_wait(object):
class _server_wait(_service_wait): class _server_wait(_service_wait):
def _wait(self, server_id, current_status): def _wait(self, server_id, current_status, timeout=60):
super(_server_wait, self)._wait( super(_server_wait, self)._wait(
'Server', server_id, self.client.wait_server, current_status, 'Server', server_id, self.client.wait_server, current_status,
timeout=(current_status not in ('BUILD', ))) countdown=(current_status not in ('BUILD', )),
timeout=timeout if current_status not in ('BUILD', ) else 100)
class _network_wait(_service_wait): class _network_wait(_service_wait):
def _wait(self, net_id, current_status): def _wait(self, net_id, current_status, timeout=60):
super(_network_wait, self)._wait( super(_network_wait, self)._wait(
'Network', net_id, self.client.wait_network, current_status) 'Network', net_id, self.client.wait_network, current_status,
timeout=timeout)
class _init_cyclades(_command_init): class _init_cyclades(_command_init):
...@@ -700,13 +702,18 @@ class server_stats(_init_cyclades, _optional_json): ...@@ -700,13 +702,18 @@ class server_stats(_init_cyclades, _optional_json):
class server_wait(_init_cyclades, _server_wait): class server_wait(_init_cyclades, _server_wait):
"""Wait for server to finish [BUILD, STOPPED, REBOOT, ACTIVE]""" """Wait for server to finish [BUILD, STOPPED, REBOOT, ACTIVE]"""
arguments = dict(
timeout=IntArgument(
'Wait limit in seconds (default: 60)', '--timeout', default=60)
)
@errors.generic.all @errors.generic.all
@errors.cyclades.connection @errors.cyclades.connection
@errors.cyclades.server_id @errors.cyclades.server_id
def _run(self, server_id, current_status): def _run(self, server_id, current_status):
r = self.client.get_server_details(server_id) r = self.client.get_server_details(server_id)
if r['status'].lower() == current_status.lower(): if r['status'].lower() == current_status.lower():
self._wait(server_id, current_status) self._wait(server_id, current_status, timeout=self['timeout'])
else: else:
self.error( self.error(
'Server %s: Cannot wait for status %s, ' 'Server %s: Cannot wait for status %s, '
...@@ -1063,13 +1070,18 @@ class network_disconnect(_init_cyclades): ...@@ -1063,13 +1070,18 @@ class network_disconnect(_init_cyclades):
class network_wait(_init_cyclades, _network_wait): class network_wait(_init_cyclades, _network_wait):
"""Wait for server to finish [PENDING, ACTIVE, DELETED]""" """Wait for server to finish [PENDING, ACTIVE, DELETED]"""
arguments = dict(
timeout=IntArgument(
'Wait limit in seconds (default: 60)', '--timeout', default=60)
)
@errors.generic.all @errors.generic.all
@errors.cyclades.connection @errors.cyclades.connection
@errors.cyclades.network_id @errors.cyclades.network_id
def _run(self, network_id, current_status): def _run(self, network_id, current_status):
net = self.client.get_network_details(network_id) net = self.client.get_network_details(network_id)
if net['status'].lower() == current_status.lower(): if net['status'].lower() == current_status.lower():
self._wait(network_id, current_status) self._wait(network_id, current_status, timeout=self['timeout'])
else: else:
self.error( self.error(
'Network %s: Cannot wait for status %s, ' 'Network %s: Cannot wait for status %s, '
......
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