Revision e9c73313

b/kamaki/cli/argument/__init__.py
332 332
        newarg._value = self._value
333 333
        return newarg
334 334

  
335
    def get_generator(self, message, message_len=25):
335
    def get_generator(self, message, message_len=25, timeout=False):
336 336
        """Get a generator to handle progress of the bar (gen.next())"""
337 337
        if self.value:
338 338
            return None
......
341 341
        except NameError:
342 342
            self.value = None
343 343
            return self.value
344
        if timeout:
345
            bar_phases = list(self.bar.phases)
346
            bar_phases[0], bar_phases[-1] = bar_phases[-1], ''
347
            self.bar.phases = bar_phases
348
            self.bar.empty_fill = bar_phases[0]
349
            self.bar.bar_prefix = ' (Timeout:'
350
            self.bar.bar_suffix = ' '
351
            self.bar.suffix = '%(eta)ds)'
352
            self.bar.eta = 120
353
        else:
354
            self.bar.suffix = '%(percent)d%% - %(eta)ds'
344 355
        self.bar.message = message.ljust(message_len)
345
        self.bar.suffix = '%(percent)d%% - %(eta)ds'
346 356
        self.bar.start()
347 357

  
348 358
        def progress_gen(n):
b/kamaki/cli/argument/test.py
369 369
        pba.value = None
370 370
        msg, msg_len = 'message', 40
371 371
        with patch('%s.KamakiProgressBar.start' % arg_path) as start:
372
            pba.get_generator(msg, msg_len)
373
            self.assertTrue(isinstance(pba.bar, argument.KamakiProgressBar))
374
            self.assertNotEqual(pba.bar.message, msg)
375
            self.assertEqual(
376
                pba.bar.message, '%s%s' % (msg, ' ' * (msg_len - len(msg))))
377
            self.assertEqual(pba.bar.suffix, '%(percent)d%% - %(eta)ds')
378
            start.assert_called_once()
372
            try:
373
                pba.get_generator(msg, msg_len)
374
                self.assertTrue(
375
                    isinstance(pba.bar, argument.KamakiProgressBar))
376
                self.assertNotEqual(pba.bar.message, msg)
377
                self.assertEqual(pba.bar.message, '%s%s' % (
378
                    msg, ' ' * (msg_len - len(msg))))
379
                self.assertEqual(pba.bar.suffix, '%(percent)d%% - %(eta)ds')
380
                start.assert_called_once()
381

  
382
                pba.get_generator(msg, msg_len, timeout=True)
383
                self.assertTrue(
384
                    isinstance(pba.bar, argument.KamakiProgressBar))
385
                self.assertNotEqual(pba.bar.message, msg)
386
                self.assertEqual(pba.bar.message, '%s%s' % (
387
                    msg, ' ' * (msg_len - len(msg))))
388
                self.assertEqual(pba.bar.bar_prefix, ' (Timeout:')
389
                self.assertEqual(pba.bar.suffix, '%(eta)ds)')
390
            finally:
391
                try:
392
                    pba.finish()
393
                except Exception:
394
                    pass
379 395

  
380 396
    def test_finish(self):
381 397
        pba = argument.ProgressBarArgument(parsed_name='--progress')
b/kamaki/cli/commands/__init__.py
177 177
            assert max_threads > 0, 'invalid max_threads config option'
178 178
            self.client.MAX_THREADS = max_threads
179 179

  
180
    def _safe_progress_bar(self, msg, arg='progress_bar'):
180
    def _safe_progress_bar(self, msg, arg='progress_bar', timeout=False):
181 181
        """Try to get a progress bar, but do not raise errors"""
182 182
        try:
183 183
            progress_bar = self.arguments[arg]
184 184
            progress_bar.file = self._err
185
            gen = progress_bar.get_generator(msg)
185
            gen = progress_bar.get_generator(msg, timeout=timeout)
186 186
        except Exception:
187 187
            return (None, None)
188 188
        return (progress_bar, gen)
b/kamaki/cli/commands/cyclades.py
75 75
            'do not show progress bar', ('-N', '--no-progress-bar'), False)
76 76
    )
77 77

  
78
    def _wait(self, service, service_id, status_method, currect_status):
78
    def _wait(
79
            self, service, service_id, status_method, current_status,
80
            timeout=True):
79 81
        (progress_bar, wait_cb) = self._safe_progress_bar(
80
            '%s %s: periodically check if status is %s' % (
81
                service, service_id, currect_status))
82
            '%s %s: status is still %s' % (
83
                service, service_id, current_status),
84
            timeout=timeout)
82 85

  
83 86
        try:
84 87
            new_mode = status_method(
85
                service_id, currect_status, wait_cb=wait_cb)
88
                service_id, current_status, wait_cb=wait_cb)
86 89
            if new_mode:
87
                self.error('\n%s %s: status is %s' % (
90
                self.error('%s %s: status is now %s' % (
88 91
                    service, service_id, new_mode))
89 92
            else:
90
                self.error('\nTime out: %s %s still in %s' % (
91
                    service, service_id, currect_status))
93
                self.error('%s %s: (timeout) status is still %s' % (
94
                    service, service_id, current_status))
92 95
        except KeyboardInterrupt:
93 96
            self.error('\n- canceled')
94 97
        finally:
......
97 100

  
98 101
class _server_wait(_service_wait):
99 102

  
100
    def _wait(self, server_id, currect_status):
103
    def _wait(self, server_id, current_status):
101 104
        super(_server_wait, self)._wait(
102
            'Server', server_id, self.client.wait_server, currect_status)
105
            'Server', server_id, self.client.wait_server, current_status,
106
            timeout=(current_status not in ('BUILD', )))
103 107

  
104 108

  
105 109
class _network_wait(_service_wait):
106 110

  
107
    def _wait(self, net_id, currect_status):
111
    def _wait(self, net_id, current_status):
108 112
        super(_network_wait, self)._wait(
109
            'Network', net_id, self.client.wait_network, currect_status)
113
            'Network', net_id, self.client.wait_network, current_status)
110 114

  
111 115

  
112 116
class _init_cyclades(_command_init):
......
699 703
    @errors.generic.all
700 704
    @errors.cyclades.connection
701 705
    @errors.cyclades.server_id
702
    def _run(self, server_id, currect_status):
703
        self._wait(server_id, currect_status)
706
    def _run(self, server_id, current_status):
707
        r = self.client.get_server_details(server_id)
708
        if r['status'].lower() == current_status.lower():
709
            self._wait(server_id, current_status)
710
        else:
711
            self.error(
712
                'Server %s: Cannot wait for status %s, '
713
                'status is already %s' % (
714
                    server_id, current_status, r['status']))
704 715

  
705
    def main(self, server_id, currect_status='BUILD'):
716
    def main(self, server_id, current_status='BUILD'):
706 717
        super(self.__class__, self)._run()
707
        self._run(server_id=server_id, currect_status=currect_status)
718
        self._run(server_id=server_id, current_status=current_status)
708 719

  
709 720

  
710 721
@command(flavor_cmds)
......
946 957
            type=self['type'])
947 958
        _add_name(self, r)
948 959
        self._print(r, self.print_dict)
949
        if self['wait']:
960
        if self['wait'] and r['status'] in ('PENDING', ):
950 961
            self._wait(r['id'], 'PENDING')
951 962

  
952 963
    def main(self, name):
......
1055 1066
    @errors.generic.all
1056 1067
    @errors.cyclades.connection
1057 1068
    @errors.cyclades.network_id
1058
    def _run(self, network_id, currect_status):
1059
        self._wait(network_id, currect_status)
1069
    def _run(self, network_id, current_status):
1070
        net = self.client.get_network_details(network_id)
1071
        if net['status'].lower() == current_status.lower():
1072
            self._wait(network_id, current_status)
1073
        else:
1074
            self.error(
1075
                'Network %s: Cannot wait for status %s, '
1076
                'status is already %s' % (
1077
                    network_id, current_status, net['status']))
1060 1078

  
1061
    def main(self, network_id, currect_status='PENDING'):
1079
    def main(self, network_id, current_status='PENDING'):
1062 1080
        super(self.__class__, self)._run()
1063
        self._run(network_id=network_id, currect_status=currect_status)
1081
        self._run(network_id=network_id, current_status=current_status)
1064 1082

  
1065 1083

  
1066 1084
@command(server_cmds)
b/kamaki/clients/cyclades/__init__.py
295 295
        :returns: (str) the new mode if successful, (bool) False if timed out
296 296
        """
297 297
        status, progress = get_status(self, item_id)
298
        if status != current_status:
299
            return status
300
        old_wait = total_wait = 0
301 298

  
302 299
        if wait_cb:
303
            wait_gen = wait_cb(1 + max_wait // delay)
300
            wait_gen = wait_cb(max_wait // delay)
304 301
            wait_gen.next()
305 302

  
303
        if status != current_status:
304
            if wait_cb:
305
                try:
306
                    wait_gen.next()
307
                except Exception:
308
                    pass
309
            return status
310
        old_wait = total_wait = 0
311

  
306 312
        while status == current_status and total_wait <= max_wait:
307 313
            if wait_cb:
308 314
                try:
......
310 316
                        wait_gen.next()
311 317
                except Exception:
312 318
                    break
313
            else:
314
                stdout.write('.')
315
                stdout.flush()
316 319
            old_wait = total_wait
317
            total_wait = progress or (total_wait + 1)
320
            total_wait = progress or total_wait + 1
318 321
            sleep(delay)
319 322
            status, progress = get_status(self, item_id)
320 323

  

Also available in: Unified diff