Repository: incubator-ariatosca Updated Branches: refs/heads/ARIA-36-plugin-workdir 08f678fca -> 9ffcd9c2a (forced update)
ARIA-36 plugin workdir Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/9ffcd9c2 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/9ffcd9c2 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/9ffcd9c2 Branch: refs/heads/ARIA-36-plugin-workdir Commit: 9ffcd9c2a5f8ef14f2d5782788c027f8a10195cb Parents: e3056d4 Author: Dan Kilman <d...@gigaspaces.com> Authored: Wed Jan 25 16:22:41 2017 +0200 Committer: Dan Kilman <d...@gigaspaces.com> Committed: Wed Jan 25 17:20:56 2017 +0200 ---------------------------------------------------------------------- aria/orchestrator/context/common.py | 2 ++ aria/orchestrator/context/operation.py | 22 ++++++++++++++ aria/orchestrator/context/serialization.py | 1 + aria/orchestrator/workflows/core/task.py | 3 +- tests/orchestrator/context/test_operation.py | 36 ++++++++++++++++++++++- tests/orchestrator/context/test_serialize.py | 13 ++++++-- 6 files changed, 72 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9ffcd9c2/aria/orchestrator/context/common.py ---------------------------------------------------------------------- diff --git a/aria/orchestrator/context/common.py b/aria/orchestrator/context/common.py index 691c17d..6ab27ef 100644 --- a/aria/orchestrator/context/common.py +++ b/aria/orchestrator/context/common.py @@ -34,6 +34,7 @@ class BaseContext(logger.LoggerMixin): deployment_id, model_storage, resource_storage, + workdir=None, **kwargs): super(BaseContext, self).__init__(**kwargs) self._name = name @@ -41,6 +42,7 @@ class BaseContext(logger.LoggerMixin): self._model = model_storage self._resource = resource_storage self._deployment_id = deployment_id + self._workdir = workdir def __repr__(self): return ( http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9ffcd9c2/aria/orchestrator/context/operation.py ---------------------------------------------------------------------- diff --git a/aria/orchestrator/context/operation.py b/aria/orchestrator/context/operation.py index b33d107..3948750 100644 --- a/aria/orchestrator/context/operation.py +++ b/aria/orchestrator/context/operation.py @@ -17,6 +17,8 @@ Workflow and operation contexts """ +import errno +import os from .common import BaseContext @@ -60,6 +62,26 @@ class BaseOperationContext(BaseContext): self._task = self.model.task.get(self._task_id) return self._task + @property + def plugin_workdir(self): + """ + A work directory that is unique to the plugin and the deployment id + """ + if not self._workdir: + return None + plugin_name = self.task.plugin_name + if not plugin_name: + return None + plugin_workdir = '{0}/plugins/{1}-{2}'.format( + self._workdir, self.deployment.id, plugin_name) + if not os.path.exists(plugin_workdir): + try: + os.makedirs(plugin_workdir) + except IOError as e: + if e.errno != errno.EEXIST: + raise + return plugin_workdir + class NodeOperationContext(BaseOperationContext): """ http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9ffcd9c2/aria/orchestrator/context/serialization.py ---------------------------------------------------------------------- diff --git a/aria/orchestrator/context/serialization.py b/aria/orchestrator/context/serialization.py index 93cb38a..760818f 100644 --- a/aria/orchestrator/context/serialization.py +++ b/aria/orchestrator/context/serialization.py @@ -26,6 +26,7 @@ def operation_context_to_dict(context): 'deployment_id': context._deployment_id, 'task_id': context._task_id, 'actor_id': context._actor_id, + 'workdir': context._workdir } if context.model: model = context.model http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9ffcd9c2/aria/orchestrator/workflows/core/task.py ---------------------------------------------------------------------- diff --git a/aria/orchestrator/workflows/core/task.py b/aria/orchestrator/workflows/core/task.py index 4017ed0..9625c97 100644 --- a/aria/orchestrator/workflows/core/task.py +++ b/aria/orchestrator/workflows/core/task.py @@ -146,7 +146,8 @@ class OperationTask(BaseTask): resource_storage=self._workflow_context.resource, deployment_id=self._workflow_context._deployment_id, task_id=operation_task.id, - actor_id=api_task.actor.id) + actor_id=api_task.actor.id, + base_workdir=self._workflow_context._workdir) self._task_id = operation_task.id self._update_fields = None http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9ffcd9c2/tests/orchestrator/context/test_operation.py ---------------------------------------------------------------------- diff --git a/tests/orchestrator/context/test_operation.py b/tests/orchestrator/context/test_operation.py index b5f52a3..79259fd 100644 --- a/tests/orchestrator/context/test_operation.py +++ b/tests/orchestrator/context/test_operation.py @@ -13,6 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os + import pytest from aria import ( @@ -35,7 +37,8 @@ global_test_holder = {} @pytest.fixture def ctx(tmpdir): - context = mock.context.simple(storage.get_sqlite_api_kwargs(str(tmpdir))) + context = mock.context.simple(storage.get_sqlite_api_kwargs(str(tmpdir)), + workdir=str(tmpdir.join('workdir'))) yield context storage.release_sqlite_storage(context.model) @@ -173,6 +176,31 @@ def test_invalid_task_operation_id(ctx, executor): assert op_node_instance_id != other_node_instance.id +def test_plugin_workdir(ctx, executor, tmpdir): + op = 'test.op' + plugin_name = 'mock_plugin' + node = ctx.model.node.get_by_name(mock.models.DEPENDENCY_NODE_NAME) + node.operations[op] = {'operation': '{0}.{1}'.format(__name__, _test_plugin_workdir.__name__), + 'plugin': plugin_name} + node.plugins = [{'name': plugin_name}] + ctx.model.node.update(node) + node_instance = ctx.model.node_instance.get_by_name(mock.models.DEPENDENCY_NODE_INSTANCE_NAME) + + filename = 'test_file' + content = 'file content' + inputs = {'filename': filename, 'content': content} + + @workflow + def basic_workflow(graph, **_): + graph.add_tasks(api.task.OperationTask.node_instance( + name=op, instance=node_instance, inputs=inputs)) + + execute(workflow_func=basic_workflow, workflow_context=ctx, executor=executor) + expected_file = tmpdir.join('workdir', 'plugins', '{0}-{1}'.format( + ctx.deployment.id, plugin_name), filename) + assert expected_file.read() == content + + @operation def my_operation(ctx, **_): global_test_holder[ctx.name] = ctx @@ -183,6 +211,12 @@ def get_node_instance_id(ctx, **_): global_test_holder[ctx.name] = ctx.node_instance.id +@operation +def _test_plugin_workdir(ctx, filename, content): + with open(os.path.join(ctx.plugin_workdir, filename), 'w') as f: + f.write(content) + + @pytest.fixture(autouse=True) def cleanup(): global_test_holder.clear() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/9ffcd9c2/tests/orchestrator/context/test_serialize.py ---------------------------------------------------------------------- diff --git a/tests/orchestrator/context/test_serialize.py b/tests/orchestrator/context/test_serialize.py index ed0afcd..76930b1 100644 --- a/tests/orchestrator/context/test_serialize.py +++ b/tests/orchestrator/context/test_serialize.py @@ -49,9 +49,13 @@ def test_illegal_serialize_of_memory_model_storage(memory_model_storage): @workflow def _mock_workflow(ctx, graph): + op = 'test.op' + plugin_name = 'mock_plugin' node_instance = ctx.model.node_instance.get_by_name(mock.models.DEPENDENCY_NODE_INSTANCE_NAME) - node_instance.node.operations['test.op'] = {'operation': _operation_mapping()} - task = api.task.OperationTask.node_instance(instance=node_instance, name='test.op') + node = node_instance.node + node.operations[op] = {'operation': _operation_mapping(), 'plugin': plugin_name} + node.plugins = [{'name': plugin_name}] + task = api.task.OperationTask.node_instance(instance=node_instance, name=op) graph.add_tasks(task) return graph @@ -72,6 +76,8 @@ def _mock_operation(ctx): # Here we test that the resource storage was properly re-created test_file_content = ctx.resource.blueprint.read(TEST_FILE_ENTRY_ID, TEST_FILE_NAME) assert test_file_content == TEST_FILE_CONTENT + # a non empty plugin workdir tells us that we kept the correct base_workdir + assert ctx.plugin_workdir is not None def _operation_mapping(): @@ -88,7 +94,8 @@ def executor(): @pytest.fixture def context(tmpdir): result = mock.context.simple(storage.get_sqlite_api_kwargs(str(tmpdir)), - resources_dir=str(tmpdir.join('resources'))) + resources_dir=str(tmpdir.join('resources')), + workdir=str(tmpdir.join('workdir'))) yield result storage.release_sqlite_storage(result.model)