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/01/29 13:23:10 UTC
[10/16] incubator-ariatosca git commit: ARIA-36 plugin workdir
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/84699172
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/84699172
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/84699172
Branch: refs/heads/ARIA-44-Merge-parser-and-storage-models
Commit: 84699172270e9d538958a9ff0dbb874243f962c6
Parents: e3056d4
Author: Dan Kilman <da...@gigaspaces.com>
Authored: Wed Jan 25 16:22:41 2017 +0200
Committer: Dan Kilman <da...@gigaspaces.com>
Committed: Thu Jan 26 12:03:49 2017 +0200
----------------------------------------------------------------------
aria/orchestrator/context/common.py | 2 ++
aria/orchestrator/context/operation.py | 15 +++++++++-
aria/orchestrator/context/serialization.py | 1 +
aria/orchestrator/workflows/core/task.py | 3 +-
aria/utils/file.py | 28 ++++++++++++++++++
tests/orchestrator/context/test_operation.py | 35 ++++++++++++++++++++++-
tests/orchestrator/context/test_serialize.py | 13 +++++++--
7 files changed, 91 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/84699172/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/84699172/aria/orchestrator/context/operation.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/context/operation.py b/aria/orchestrator/context/operation.py
index b33d107..23a6fd4 100644
--- a/aria/orchestrator/context/operation.py
+++ b/aria/orchestrator/context/operation.py
@@ -17,7 +17,7 @@
Workflow and operation contexts
"""
-
+from aria.utils import file
from .common import BaseContext
@@ -60,6 +60,19 @@ 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.task.plugin_name:
+ return None
+ plugin_workdir = '{0}/plugins/{1}/{2}'.format(self._workdir,
+ self.deployment.id,
+ self.task.plugin_name)
+ file.makedirs(plugin_workdir)
+ return plugin_workdir
+
class NodeOperationContext(BaseOperationContext):
"""
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/84699172/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/84699172/aria/orchestrator/workflows/core/task.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/workflows/core/task.py b/aria/orchestrator/workflows/core/task.py
index 4017ed0..f65fc0d 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,
+ 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/84699172/aria/utils/file.py
----------------------------------------------------------------------
diff --git a/aria/utils/file.py b/aria/utils/file.py
new file mode 100644
index 0000000..b515f70
--- /dev/null
+++ b/aria/utils/file.py
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import errno
+import os
+
+
+def makedirs(path):
+ """An extension of os.makedirs that doesn't fail if the directory already exists"""
+ if os.path.isdir(path):
+ return
+ try:
+ os.makedirs(path)
+ except IOError as e:
+ if e.errno != errno.EEXIST:
+ raise
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/84699172/tests/orchestrator/context/test_operation.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_operation.py b/tests/orchestrator/context/test_operation.py
index b5f52a3..b0918d1 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,30 @@ 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', str(ctx.deployment.id), plugin_name, filename)
+ assert expected_file.read() == content
+
+
@operation
def my_operation(ctx, **_):
global_test_holder[ctx.name] = ctx
@@ -183,6 +210,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/84699172/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)