summaryrefslogtreecommitdiffstats
path: root/ms/command-executor/src/main/python
diff options
context:
space:
mode:
authorAlexis de Talhouët <adetalhouet89@gmail.com>2019-04-12 18:52:29 -0400
committerAlexis de Talhouët <adetalhouet89@gmail.com>2019-04-16 10:38:51 -0400
commit5a47fe8d6a7c665db048e1959f484af297a74315 (patch)
treefa629210d02e2b37168d3846d210fc6e9f3443de /ms/command-executor/src/main/python
parentee120a54f32d3643eefbef03ca0f4ca9c423e58b (diff)
Add CommandExecutor handler
Change-Id: I7a4fbd13d11618ed6b2c85827ec2ced1cb65b31f Issue-ID: CCCSDK-1215 Signed-off-by: Alexis de Talhouët <adetalhouet89@gmail.com>
Diffstat (limited to 'ms/command-executor/src/main/python')
-rw-r--r--ms/command-executor/src/main/python/command_executor_handler.py100
-rw-r--r--ms/command-executor/src/main/python/command_executor_server.py26
-rw-r--r--ms/command-executor/src/main/python/utils.py39
3 files changed, 163 insertions, 2 deletions
diff --git a/ms/command-executor/src/main/python/command_executor_handler.py b/ms/command-executor/src/main/python/command_executor_handler.py
new file mode 100644
index 000000000..3027859b3
--- /dev/null
+++ b/ms/command-executor/src/main/python/command_executor_handler.py
@@ -0,0 +1,100 @@
+#
+# Copyright (C) 2019 Bell Canada.
+#
+# Licensed 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 os
+import subprocess
+import virtualenv
+import venv
+from builtins import Exception, open, dict
+from subprocess import CalledProcessError, PIPE
+
+import utils
+
+
+class CommandExecutorHandler:
+
+ def __init__(self, request):
+ self.blueprint_id = utils.get_blueprint_id(request)
+ self.venv_home = '/opt/app/onap/blueprints/deploy/' + self.blueprint_id
+
+ def prepare_env(self, request, results):
+ self.create_venv()
+ if not self.activate_venv():
+ return False
+
+ for package in request.packages:
+ if not self.install(package, results):
+ return False
+
+ # deactivate_venv(blueprint_id)
+ return True
+
+ def execute_command(self, request, results):
+ if not self.activate_venv():
+ return False
+
+ try:
+ results.append(os.popen(request.command).read())
+ except Exception as e:
+ print("{} - Failed to execute command. Error: {}".format(self.blueprint_id, e))
+ results.append(e)
+ return False
+
+ # deactivate_venv(blueprint_id)
+ return True
+
+ def install(self, package, results):
+ print("{} - Install package({}) in Python Virtual Environment".format(self.blueprint_id, package))
+ command = ["pip", "install", package]
+
+ env = dict(os.environ)
+ # env['https_proxy'] = "https://fastweb.int.bell.ca:8083"
+
+ try:
+ results.append(subprocess.run(command, check=True, stdout=PIPE, stderr=PIPE, env=env).stdout.decode())
+ return True
+ except CalledProcessError as e:
+ results.append(e.stderr.decode())
+ return False
+
+ def create_venv(self):
+ print("{} - Create Python Virtual Environment".format(self.blueprint_id))
+ try:
+ bin_dir = self.venv_home + "/bin"
+ # venv doesn't populate the activate_this.py script, hence we use from virtualenv
+ venv.create(self.venv_home, with_pip=True, system_site_packages=True)
+ virtualenv.writefile(os.path.join(bin_dir, "activate_this.py"), virtualenv.ACTIVATE_THIS)
+ except Exception as err:
+ print("{} - Failed to provision Python Virtual Environment. Error: {}".format(self.blueprint_id, err))
+
+ def activate_venv(self):
+ print("{} - Activate Python Virtual Environment".format(self.blueprint_id))
+
+ path = "%s/bin/activate_this.py" % self.venv_home
+ try:
+ exec (open(path).read(), {'__file__': path})
+ return True
+ except Exception as err:
+ print("{} - Failed to activate Python Virtual Environment. Error: {}".format(self.blueprint_id, err))
+ return False
+
+ def deactivate_venv(self):
+ print("{} - Deactivate Python Virtual Environment".format(self.blueprint_id))
+ command = ["deactivate"]
+ try:
+ subprocess.run(command, check=True)
+ except Exception as err:
+ print("{} - Failed to deactivate Python Virtual Environment. Error: {}".format(self.blueprint_id, err))
diff --git a/ms/command-executor/src/main/python/command_executor_server.py b/ms/command-executor/src/main/python/command_executor_server.py
index 35eed8e57..b62f15011 100644
--- a/ms/command-executor/src/main/python/command_executor_server.py
+++ b/ms/command-executor/src/main/python/command_executor_server.py
@@ -25,6 +25,8 @@ import grpc
import proto.CommandExecutor_pb2_grpc as CommandExecutor_pb2_grpc
from request_header_validator_interceptor import RequestHeaderValidatorInterceptor
+from command_executor_handler import CommandExecutorHandler
+import utils
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
@@ -32,10 +34,30 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24
class CommandExecutorServer(CommandExecutor_pb2_grpc.CommandExecutorServiceServicer):
def prepareEnv(self, request, context):
- return
+ blueprint_id = utils.get_blueprint_id(request)
+ print("{} - Received prepareEnv request".format(blueprint_id))
+ print (request)
+
+ results = []
+ handler = CommandExecutorHandler(request)
+ if not handler.prepare_env(request, results):
+ print("{} - Failed to prepare python environment. {}".format(blueprint_id, results))
+ return utils.build_response(request, results, False)
+ print("{} - Package installation logs {}".format(blueprint_id, results))
+ return utils.build_response(request, results)
def executeCommand(self, request, context):
- return
+ blueprint_id = utils.get_blueprint_id(request)
+ print("{} - Received executeCommand request".format(blueprint_id))
+ print(request)
+
+ results = []
+ handler = CommandExecutorHandler(request)
+ if not handler.execute_command(request, results):
+ print("{} - Failed to executeCommand. {}".format(blueprint_id, results))
+ return utils.build_response(request, results, False)
+ print("{} - Execute command logs: {}".format(blueprint_id, results))
+ return utils.build_response(request, results)
def serve():
diff --git a/ms/command-executor/src/main/python/utils.py b/ms/command-executor/src/main/python/utils.py
new file mode 100644
index 000000000..b0013b996
--- /dev/null
+++ b/ms/command-executor/src/main/python/utils.py
@@ -0,0 +1,39 @@
+#
+# Copyright (C) 2019 Bell Canada.
+#
+# Licensed 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.
+#
+from builtins import map, bytes
+
+from google.protobuf.timestamp_pb2 import Timestamp
+
+import proto.CommandExecutor_pb2 as CommandExecutor_pb2
+
+
+def get_blueprint_id(request):
+ blueprint_name = request.identifiers.blueprintName
+ blueprint_version = request.identifiers.blueprintVersion
+ return blueprint_name + '/' + blueprint_version
+
+
+def build_response(request, results, is_success=True):
+ if is_success:
+ status = CommandExecutor_pb2.SUCCESS
+ else:
+ status = CommandExecutor_pb2.FAILURE
+
+ timestamp = Timestamp()
+ timestamp.GetCurrentTime()
+
+ return CommandExecutor_pb2.ExecutionOutput(requestId=request.requestId, response="".join(results), status=status,
+ timestamp=timestamp)