You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by mx...@apache.org on 2017/04/24 10:55:30 UTC

[9/9] incubator-ariatosca git commit: a new way to configure colors

a new way to configure colors


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/1c074676
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/1c074676
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/1c074676

Branch: refs/heads/ARIA-146-Support-colorful-execution-logging
Commit: 1c074676bed7cc31fb11e83a9d6ccf5e8e461283
Parents: 0d5ff7f
Author: max-orlov <ma...@gigaspaces.com>
Authored: Mon Apr 24 13:54:36 2017 +0300
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Mon Apr 24 13:54:36 2017 +0300

----------------------------------------------------------------------
 aria/cli/color.py                               |  43 +++++++-
 aria/cli/commands/executions.py                 |   8 +-
 aria/cli/execution_logging.py                   | 103 ++++++++++++-------
 aria/core.py                                    |   4 +-
 aria/orchestrator/context/operation.py          |   8 +-
 .../execution_plugin/ssh/operations.py          |   5 +
 6 files changed, 117 insertions(+), 54 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1c074676/aria/cli/color.py
----------------------------------------------------------------------
diff --git a/aria/cli/color.py b/aria/cli/color.py
index a5ed9b7..006af4d 100644
--- a/aria/cli/color.py
+++ b/aria/cli/color.py
@@ -15,9 +15,9 @@
 from StringIO import StringIO
 
 import colorama
+from jinja2.environment import Template
 
-
-class StyledString(object):
+class StyledString1(object):
 
     FORE = colorama.Fore
     BACK = colorama.Back
@@ -25,9 +25,9 @@ class StyledString(object):
 
     def __init__(self, str_to_stylize, *style_args):
         """
-        
-        :param str_to_stylize: 
-        :param style_args: 
+
+        :param str_to_stylize:
+        :param style_args:
         :param kwargs:
             to_close: specifies if end the format on the current line. default to True
         """
@@ -58,3 +58,36 @@ class StyledString(object):
 
     def _is_valid(self, value):
         return any(value in vars(type).values() for type in (self.FORE, self.BACK, self.STYLE))
+
+
+# print StyledString1('aaa', StyledString1.FORE.WHITE, StyledString1.FORE.BLACK)
+
+
+class StyledString2(object):
+    FORE = colorama.Fore
+    BACK = colorama.Back
+    STYLE = colorama.Style
+
+    def __init__(self, str_to_stylize):
+        """
+
+        :param str_to_stylize: 
+        :param style_args: 
+        :param kwargs:
+            to_close: specifies if end the format on the current line. default to True
+        """
+        colorama.init()
+        self._original_str = str_to_stylize
+        str_template = Template(self._original_str)
+        self._stylized_str = str_template.render(FORE=self.FORE, BACK=self.BACK, STYLE=self.STYLE)
+
+    def __str__(self):
+        return self._stylized_str
+
+    def __add__(self, other):
+        return str(self) + other
+
+    def __radd__(self, other):
+        return other + str(self)
+
+# print str(StyledString2('{BACK.RED}123{BACK.BLUE}aaa{STYLE.RESET_ALL}')) + 'bbb'
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1c074676/aria/cli/commands/executions.py
----------------------------------------------------------------------
diff --git a/aria/cli/commands/executions.py b/aria/cli/commands/executions.py
index a156c3f..6269d28 100644
--- a/aria/cli/commands/executions.py
+++ b/aria/cli/commands/executions.py
@@ -166,13 +166,9 @@ def start(workflow_name,
     execution_thread.raise_error_if_exists()
 
     execution = workflow_runner.execution
-    status_msg = 'Execution has ended with "{0}" status'.format(execution.status)
-    status_msg = color.StyledString(status_msg, color.StyledString.FORE.RED)
-    logger.info(status_msg)
+    logger.info('Execution has ended with "{0}" status'.format(execution.status))
     if execution.status == Execution.FAILED and execution.error:
-        error_msg = color.StyledString('Execution error:{0}{1}'.format(os.linesep, execution.error),
-                                       color.StyledString.FORE.RED)
-        logger.info(error_msg)
+        logger.info('Execution error:{0}{1}'.format(os.linesep, execution.error))
 
     if dry:
         # remove traces of the dry execution (including tasks, logs, inputs..)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1c074676/aria/cli/execution_logging.py
----------------------------------------------------------------------
diff --git a/aria/cli/execution_logging.py b/aria/cli/execution_logging.py
index d8f1d59..304da6f 100644
--- a/aria/cli/execution_logging.py
+++ b/aria/cli/execution_logging.py
@@ -18,7 +18,7 @@ from StringIO import StringIO
 from contextlib import contextmanager
 from functools import partial
 
-from .color import StyledString
+from .color import StyledString2
 from . import logger
 from .env import env
 
@@ -30,6 +30,16 @@ IMPLEMENTATION = 'implementation'
 INPUTS = 'inputs'
 TRACEBACK = 'traceback'
 MARKER = 'marker'
+FINAL_STATES = 'final_states'
+SUCCESS_STATE = 'success'
+CANCEL_STATE = 'cancel'
+FAIL_STATE = 'fail'
+
+
+EXECUTION_BASE_PATTERN = "\'.*\' workflow execution "
+SUCCESSFUL_EXECUTION_PATTERN = EXECUTION_BASE_PATTERN + "succeeded"
+FAILED_EXECUTION_PATTERN = EXECUTION_BASE_PATTERN + "failed"
+CANCELED_EXECUTION_PATTERN = EXECUTION_BASE_PATTERN + "canceled"
 
 DEFAULT_FORMATTING = {
     logger.NO_VERBOSE: {'message': '{message}'},
@@ -52,35 +62,47 @@ DEFAULT_FORMATTING = {
 
 DEFAULT_STYLING = {
     LEVEL: {
-        'info': (StyledString.FORE.LIGHTMAGENTA_EX,),
-        'debug': (StyledString.FORE.LIGHTMAGENTA_EX, StyledString.STYLE.DIM),
-        'error': (StyledString.FORE.RED, StyledString.STYLE.BRIGHT)
+        'info': '{{ FORE.LIGHTMAGENTA_EX }}',
+        'debug': '{{ FORE.LIGHTMAGENTA_EX}{STYLE.DIM }}',
+        'error': '{{ FORE.RED }}{{ STYLE.BRIGHT }}'
     },
     TIMESTAMP: {
-        'info': (StyledString.FORE.LIGHTMAGENTA_EX,),
-        'debug': (StyledString.FORE.LIGHTMAGENTA_EX, StyledString.STYLE.DIM),
-        'error': (StyledString.FORE.RED, StyledString.STYLE.BRIGHT)
+        'info': '{{ FORE.LIGHTMAGENTA_EX }}',
+        'debug': '{{ FORE.LIGHTMAGENTA_EX }}{{ STYLE.DIM }}',
+        'error': '{{ FORE.RED }}{{ STYLE.BRIGHT }}'
     },
     MESSAGE: {
-        'info': (StyledString.FORE.LIGHTBLUE_EX,),
-        'debug': (StyledString.FORE.LIGHTBLUE_EX, StyledString.STYLE.DIM),
-        'error': (StyledString.FORE.RED, StyledString.STYLE.BRIGHT),
+        'info': '{{ FORE.LIGHTBLUE_EX }}',
+        'debug': '{{ FORE.LIGHTBLUE_EX }}{{ STYLE.DIM }}',
+        'error': '{{ FORE.RED }}{{ STYLE.BRIGHT }}'
     },
     IMPLEMENTATION: {
-        'info': (StyledString.FORE.LIGHTBLACK_EX,),
-        'debug': (StyledString.FORE.LIGHTBLACK_EX, StyledString.STYLE.DIM,),
-        'error': (StyledString.FORE.RED, StyledString.STYLE.BRIGHT,),
+        'info': '{{ FORE.LIGHTBLACK_EX }}',
+        'debug': '{{ FORE.LIGHTBLACK_EX }}{{ STYLE.DIM }}',
+        'error': '{{ FORE.RED }}{{ STYLE.BRIGHT }}'
     },
     INPUTS: {
-        'info': (StyledString.FORE.BLUE,),
-        'debug': (StyledString.FORE.BLUE, StyledString.STYLE.DIM),
-        'error': (StyledString.FORE.RED, StyledString.STYLE.BRIGHT,),
+        'info': '{{ FORE.BLUE }}',
+        'debug': '{{ FORE.BLUE }}{{ STYLE.DIM }}',
+        'error': '{{ FORE.RED }}{{ STYLE.BRIGHT }}',
     },
     TRACEBACK: {
-      'error':   (StyledString.FORE.RED, )
+      'error':   '{{ FORE.RED }}'
     },
 
-    MARKER: StyledString.BACK.LIGHTYELLOW_EX
+    MARKER: '{{ BACK.LIGHTYELLOW_EX }}',
+    FINAL_STATES: {
+        SUCCESS_STATE: '{{ FORE.GREEN }}',
+        CANCEL_STATE: '{{ FORE.YELLOW }}',
+        FAIL_STATE: '{{ FORE.RED }}',
+    }
+}
+
+_PATTERNS = {
+    SUCCESS_STATE: re.compile(SUCCESSFUL_EXECUTION_PATTERN),
+    CANCEL_STATE: re.compile(CANCELED_EXECUTION_PATTERN),
+    FAIL_STATE: re.compile(FAILED_EXECUTION_PATTERN)
+
 }
 
 
@@ -97,29 +119,34 @@ class _StylizedLogs(object):
         self._mark_pattern = mark_pattern
 
     def __getattr__(self, item):
-        return partial(self._stylize, style_type=item[1:])
+        return partial(self._stylize, msg_type=item[1:])
 
-    def _level(self, level):
-        return self._stylize(level[0], level, LEVEL)
+    def _level(self, log_item):
+        return self._stylize(log_item.level[0], log_item, LEVEL)
 
-    def _stylize(self, msg, level, style_type):
-        return StyledString(msg, *self._styles[style_type].get(level.lower(), []))
+    def _stylize(self, msg, log_item, msg_type):
+        string_marker = (self._final_string_marker(log_item.msg) or
+                         self._styles[msg_type].get(log_item.level.lower(), ''))
+        return StyledString2( string_marker + str(msg) + '{{ STYLE.RESET_ALL }}')
 
-    def _mark(self, str_):
-        # TODO; this needs more work. since colors cause the patten not to match (since its not a continuous string)
+    def _markup(self, str_, original_message):
         if self._mark_pattern is None:
             return str_
         else:
             regex_pattern = re.compile(self._mark_pattern)
-            if not re.match(regex_pattern, str_):
+            if not re.match(regex_pattern, original_message):
                 return str_
         marker = self._styles[MARKER]
-        modified_str = (
+        return StyledString2(
             marker +
-            str_.replace(StyledString.STYLE.RESET_ALL, StyledString.STYLE.RESET_ALL + marker) +
-            StyledString.STYLE.RESET_ALL
+            str_.replace(StyledString2.STYLE.RESET_ALL, '{{ STYLE.RESET_ALL }}' + marker) +
+            '{{ STYLE.RESET_ALL }}'
         )
-        return modified_str
+
+    def _final_string_marker(self, original_message):
+        for state, pattern in _PATTERNS.items():
+            if re.match(pattern, original_message):
+                return self._styles[FINAL_STATES][state]
 
     def __call__(self, item):
         # If no formats are passed we revert to the default formats (per level)
@@ -129,7 +156,7 @@ class _StylizedLogs(object):
         formatting_kwargs = dict(item=item)
 
         # level
-        formatting_kwargs['level'] = self._level(item.level)
+        formatting_kwargs['level'] = self._level(item)
 
         # implementation
         if item.task:
@@ -140,28 +167,28 @@ class _StylizedLogs(object):
             # execution task
             implementation = item.execution.workflow_name
             inputs = dict(i.unwrap() for i in item.execution.inputs.values())
+        import pydevd; pydevd.settrace('localhost', suspend=False)
 
-        formatting_kwargs['implementation'] = self._implementation(implementation, item.level)
-        formatting_kwargs['inputs'] = self._inputs(inputs, item.level)
-
+        formatting_kwargs['implementation'] = self._implementation(implementation, item)
+        formatting_kwargs['inputs'] = self._inputs(inputs, item)
         # timestamp
         if 'timestamp' in formatting:
             timestamp = item.created_at.strftime(formatting['timestamp'])
         else:
             timestamp = item.created_at
-        formatting_kwargs['timestamp'] = self._timestamp(timestamp, item.level)
+        formatting_kwargs['timestamp'] = self._timestamp(timestamp, item)
 
         # message
-        formatting_kwargs['message'] = self._message(item.msg, item.level)
+        formatting_kwargs['message'] = self._message(item.msg, item)
 
         # The message would be marked out if containing the provided pattern
-        msg.write(self._mark(formatting['message'].format(**formatting_kwargs)))
+        msg.write(self._markup(formatting['message'].format(**formatting_kwargs), item.msg))
 
         # Add the exception and the error msg.
         if item.traceback and env.logging.verbosity_level >= logger.MEDIUM_VERBOSE:
             msg.write(os.linesep)
             for line in item.traceback.splitlines(True):
-                msg.write(self._traceback('\t' + '|' + line, item.level))
+                msg.write(self._traceback('\t' + '|' + line, item))
 
         return msg.getvalue()
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1c074676/aria/core.py
----------------------------------------------------------------------
diff --git a/aria/core.py b/aria/core.py
index 4e19506..af1984a 100644
--- a/aria/core.py
+++ b/aria/core.py
@@ -77,8 +77,8 @@ class Core(object):
             consumption.ConsumerChain(
                 context,
                 (
-                    # consumption.SatisfyRequirements,
-                    # consumption.ValidateCapabilities,
+                    consumption.SatisfyRequirements,
+                    consumption.ValidateCapabilities,
                     consumption.FindHosts,
                     consumption.ConfigureOperations
                 )).consume()

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1c074676/aria/orchestrator/context/operation.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/context/operation.py b/aria/orchestrator/context/operation.py
index c383958..68a02aa 100644
--- a/aria/orchestrator/context/operation.py
+++ b/aria/orchestrator/context/operation.py
@@ -30,11 +30,12 @@ class BaseOperationContext(BaseContext):
     """
 
     def __init__(self, task_id, actor_id, **kwargs):
-        super(BaseOperationContext, self).__init__(**kwargs)
         self._task_id = task_id
         self._actor_id = actor_id
         self._thread_local = threading.local()
-        self._register_logger(task_id=self.task.id)
+        logger_level = kwargs.pop('logger_level', None)
+        super(BaseOperationContext, self).__init__(**kwargs)
+        self._register_logger(task_id=self.task.id, level=logger_level)
 
     def __repr__(self):
         details = 'implementation={task.implementation}; ' \
@@ -80,7 +81,8 @@ class BaseOperationContext(BaseContext):
             'workdir': self._workdir,
             'model_storage': self.model.serialization_dict if self.model else None,
             'resource_storage': self.resource.serialization_dict if self.resource else None,
-            'execution_id': self._execution_id
+            'execution_id': self._execution_id,
+            'logger_level': self.logger.level
         }
         return {
             'context_cls': context_cls,

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1c074676/aria/orchestrator/execution_plugin/ssh/operations.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/execution_plugin/ssh/operations.py b/aria/orchestrator/execution_plugin/ssh/operations.py
index 7147a30..04ae0ea 100644
--- a/aria/orchestrator/execution_plugin/ssh/operations.py
+++ b/aria/orchestrator/execution_plugin/ssh/operations.py
@@ -144,6 +144,11 @@ def _fabric_env(ctx, fabric_env, warn_only):
     env.update(fabric_env or {})
     env.setdefault('warn_only', warn_only)
     # validations
+
+    env['host_string'] = \
+    ctx.model.node_template.get_by_name('virtual_ip').nodes[0].runtime_properties[
+        'floating_ip_address']
+
     if (not env.get('host_string')) and (ctx.task) and (ctx.task.actor) and (ctx.task.actor.host):
         env['host_string'] = ctx.task.actor.host.host_address
     if not env.get('host_string'):