summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--heatclient/common/event_utils.py7
-rw-r--r--heatclient/osc/v1/event.py33
-rw-r--r--heatclient/tests/unit/osc/v1/test_event.py26
3 files changed, 63 insertions, 3 deletions
diff --git a/heatclient/common/event_utils.py b/heatclient/common/event_utils.py
index 3e6b197..1b8b179 100644
--- a/heatclient/common/event_utils.py
+++ b/heatclient/common/event_utils.py
@@ -75,8 +75,11 @@ def get_events(hc, stack_id, event_args, nested_depth=0,
# Slice the list if marker is specified
if marker:
- marker_index = [e.id for e in events].index(marker)
- events = events[marker_index:]
+ try:
+ marker_index = [e.id for e in events].index(marker)
+ events = events[marker_index:]
+ except ValueError:
+ pass
# Slice the list if limit is specified
if limit:
diff --git a/heatclient/osc/v1/event.py b/heatclient/osc/v1/event.py
index 664b56c..feee81d 100644
--- a/heatclient/osc/v1/event.py
+++ b/heatclient/osc/v1/event.py
@@ -13,6 +13,7 @@
# Copyright 2015 IBM Corp.
import logging
+import time
from cliff import lister
from cliff import show
@@ -134,6 +135,11 @@ class ListEvent(lister.Lister):
'(default: asc). Specify multiple times to sort on '
'multiple keys')
)
+ parser.add_argument(
+ '--follow',
+ action='store_true',
+ help=_('Print events until process is halted')
+ )
return parser
def take_action(self, parsed_args):
@@ -149,6 +155,7 @@ class ListEvent(lister.Lister):
'limit': parsed_args.limit,
'marker': parsed_args.marker,
'filters': heat_utils.format_parameters(parsed_args.filter),
+ 'sort_dir': 'asc'
}
if parsed_args.resource and parsed_args.nested_depth:
@@ -165,6 +172,31 @@ class ListEvent(lister.Lister):
else:
nested_depth = 0
+ if parsed_args.follow:
+ if parsed_args.formatter != 'value':
+ msg = _('--follow can only be specified with --format value')
+ raise exc.CommandError(msg)
+
+ marker = parsed_args.marker
+ try:
+ while True:
+ kwargs['marker'] = marker
+ events = event_utils.get_events(
+ client,
+ stack_id=parsed_args.stack,
+ event_args=kwargs,
+ nested_depth=nested_depth,
+ marker=marker)
+ if events:
+ marker = getattr(events[-1], 'id', None)
+ events_log = heat_utils.event_log_formatter(events)
+ self.app.stdout.write(events_log)
+ self.app.stdout.write('\n')
+ time.sleep(5)
+ # this loop never exits
+ except (KeyboardInterrupt, EOFError): # ctrl-c, ctrl-d
+ return [], []
+
events = event_utils.get_events(
client, stack_id=parsed_args.stack, event_args=kwargs,
nested_depth=nested_depth, marker=parsed_args.marker,
@@ -175,7 +207,6 @@ class ListEvent(lister.Lister):
if parsed_args.formatter == 'value':
events = heat_utils.event_log_formatter(events).split('\n')
- events.reverse()
return [], [e.split(' ') for e in events]
if len(events):
diff --git a/heatclient/tests/unit/osc/v1/test_event.py b/heatclient/tests/unit/osc/v1/test_event.py
index c18457a..668a62e 100644
--- a/heatclient/tests/unit/osc/v1/test_event.py
+++ b/heatclient/tests/unit/osc/v1/test_event.py
@@ -111,6 +111,7 @@ class TestEventList(TestEvent):
'limit': None,
'marker': None,
'filters': {},
+ 'sort_dir': 'asc'
}
fields = ['resource_name', 'id', 'resource_status',
@@ -199,6 +200,31 @@ class TestEventList(TestEvent):
self.event_client.list.assert_called_with(**self.defaults)
self.assertEqual(self.fields, columns)
+ @mock.patch('time.sleep')
+ def test_event_list_follow(self, sleep):
+ sleep.side_effect = [None, KeyboardInterrupt()]
+ arglist = ['--follow', 'my_stack']
+ expected = (
+ '2015-11-13 10:02:17 [resource1]: '
+ 'CREATE_COMPLETE state changed\n'
+ '2015-11-13 10:02:17 [resource1]: '
+ 'CREATE_COMPLETE state changed\n'
+ )
+ parsed_args = self.check_parser(self.cmd, arglist, [])
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ defaults_with_marker = dict(self.defaults)
+ defaults_with_marker['marker'] = '1234'
+
+ self.event_client.list.assert_has_calls([
+ mock.call(**self.defaults),
+ mock.call(**defaults_with_marker)
+ ])
+ self.assertEqual([], columns)
+ self.assertEqual([], data)
+ self.assertEqual(expected, self.fake_stdout.make_string())
+
def test_event_list_value_format(self):
arglist = ['my_stack']
expected = ('2015-11-13 10:02:17 [resource1]: CREATE_COMPLETE '