diff options
Diffstat (limited to 'ms/command-executor/src/main/python')
-rw-r--r-- | ms/command-executor/src/main/python/command_executor_handler.py | 79 | ||||
-rw-r--r-- | ms/command-executor/src/main/python/proto/CommandExecutor_pb2.py | 146 |
2 files changed, 150 insertions, 75 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 index 4ae575b0f..248e44308 100644 --- a/ms/command-executor/src/main/python/command_executor_handler.py +++ b/ms/command-executor/src/main/python/command_executor_handler.py @@ -13,32 +13,51 @@ # See the License for the specific language governing permissions and # limitations under the License. # +from builtins import Exception, open, dict +from subprocess import CalledProcessError, PIPE + import logging import os import subprocess import virtualenv import venv -from builtins import Exception, open, dict -from subprocess import CalledProcessError, PIPE - import utils +import proto.CommandExecutor_pb2 as CommandExecutor_pb2 -class CommandExecutorHandler: +class CommandExecutorHandler(): def __init__(self, request): + self.request = request self.logger = logging.getLogger(self.__class__.__name__) self.blueprint_id = utils.get_blueprint_id(request) self.venv_home = '/opt/app/onap/blueprints/deploy/' + self.blueprint_id + self.installed = self.venv_home + '/.installed' - def prepare_env(self, request, results): - self.create_venv() - if not self.activate_venv(): + def is_installed(self): + if os.path.exists(self.installed): + return True + else: return False - for package in request.packages: - if not self.install(package, results): + def prepare_env(self, request, results): + if not self.is_installed(): + self.create_venv() + if not self.activate_venv(): + return False + + f = open(self.installed, "w+") + if not self.install_packages(request, CommandExecutor_pb2.PYTHON, f, results): + return False + f.write("\r\n") + results.append("\n") + if not self.install_packages(request, CommandExecutor_pb2.ANSIBLE, f, results): return False + f.close() + else: + f = open(self.installed, "r") + results.append(f.read()) + f.close() # deactivate_venv(blueprint_id) return True @@ -57,16 +76,50 @@ class CommandExecutorHandler: # deactivate_venv(blueprint_id) return True - def install(self, package, results): - self.logger.info("{} - Install package({}) in Python Virtual Environment".format(self.blueprint_id, package)) + def install_packages(self, request, type, f, results): + for package in request.packages: + if package.type == type: + f.write("Installed %s packages:\r\n" % CommandExecutor_pb2.PackageType.Name(type)) + for python_package in package.package: + f.write(" %s\r\n" % python_package) + if package.type == CommandExecutor_pb2.PYTHON: + success = self.install_python_packages(python_package, results) + else: + success = self.install_ansible_packages(python_package, results) + if not success: + f.close() + os.remove(self.installed) + return False + return True + + def install_python_packages(self, package, results): + self.logger.info( + "{} - Install Python package({}) in Python Virtual Environment".format(self.blueprint_id, package)) command = ["pip", "install", package] env = dict(os.environ) - # fixme - parameterize - # env['https_proxy'] = "https://fastweb.int.bell.ca:8083" + env['https_proxy'] = os.environ['https_proxy'] + + try: + results.append(subprocess.run(command, check=True, stdout=PIPE, stderr=PIPE, env=env).stdout.decode()) + results.append("\n") + return True + except CalledProcessError as e: + results.append(e.stderr.decode()) + return False + + def install_ansible_packages(self, package, results): + self.logger.info( + "{} - Install Ansible Role package({}) in Python Virtual Environment".format(self.blueprint_id, package)) + command = ["ansible-galaxy", "install", package, "-p", "Scripts/ansible/roles"] + + env = dict(os.environ) + # ansible galaxy uses https_proxy environment variable, but requires it to be set with http proxy value. + env['https_proxy'] = os.environ['http_proxy'] try: results.append(subprocess.run(command, check=True, stdout=PIPE, stderr=PIPE, env=env).stdout.decode()) + results.append("\n") return True except CalledProcessError as e: results.append(e.stderr.decode()) diff --git a/ms/command-executor/src/main/python/proto/CommandExecutor_pb2.py b/ms/command-executor/src/main/python/proto/CommandExecutor_pb2.py index 637d37d87..76fc19d02 100644 --- a/ms/command-executor/src/main/python/proto/CommandExecutor_pb2.py +++ b/ms/command-executor/src/main/python/proto/CommandExecutor_pb2.py @@ -22,7 +22,7 @@ DESCRIPTOR = _descriptor.FileDescriptor( package='org.onap.ccsdk.cds.controllerblueprints.command.api', syntax='proto3', serialized_options=_b('P\001'), - serialized_pb=_b('\n\x15\x43ommandExecutor.proto\x12\x33org.onap.ccsdk.cds.controllerblueprints.command.api\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xe4\x02\n\x0e\x45xecutionInput\x12\x11\n\trequestId\x18\x01 \x01(\t\x12\x15\n\rcorrelationId\x18\x02 \x01(\t\x12U\n\x0bidentifiers\x18\x03 \x01(\x0b\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers\x12S\n\nscriptType\x18\x04 \x01(\x0e\x32?.org.onap.ccsdk.cds.controllerblueprints.command.api.ScriptType\x12\x0f\n\x07\x63ommand\x18\x05 \x01(\t\x12\x0f\n\x07timeOut\x18\x06 \x01(\x05\x12+\n\nproperties\x18\x07 \x01(\x0b\x32\x17.google.protobuf.Struct\x12-\n\ttimestamp\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xe6\x02\n\x0fPrepareEnvInput\x12U\n\x0bidentifiers\x18\x01 \x01(\x0b\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers\x12\x11\n\trequestId\x18\x02 \x01(\t\x12\x15\n\rcorrelationId\x18\x03 \x01(\t\x12S\n\nscriptType\x18\x04 \x01(\x0e\x32?.org.onap.ccsdk.cds.controllerblueprints.command.api.ScriptType\x12\x10\n\x08packages\x18\x05 \x03(\t\x12\x0f\n\x07timeOut\x18\x06 \x01(\x05\x12+\n\nproperties\x18\x07 \x01(\x0b\x32\x17.google.protobuf.Struct\x12-\n\ttimestamp\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\">\n\x0bIdentifiers\x12\x15\n\rblueprintName\x18\x01 \x01(\t\x12\x18\n\x10\x62lueprintVersion\x18\x02 \x01(\t\"\xba\x01\n\x0f\x45xecutionOutput\x12\x11\n\trequestId\x18\x01 \x01(\t\x12\x10\n\x08response\x18\x02 \x01(\t\x12S\n\x06status\x18\x03 \x01(\x0e\x32\x43.org.onap.ccsdk.cds.controllerblueprints.command.api.ResponseStatus\x12-\n\ttimestamp\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp**\n\x0eResponseStatus\x12\x0b\n\x07SUCCESS\x10\x00\x12\x0b\n\x07\x46\x41ILURE\x10\x01*9\n\nScriptType\x12\n\n\x06PYTHON\x10\x00\x12\x0b\n\x07\x41NSIBLE\x10\x01\x12\n\n\x06KOTLIN\x10\x02\x12\x06\n\x02SH\x10\x03\x32\xd1\x02\n\x16\x43ommandExecutorService\x12\x98\x01\n\nprepareEnv\x12\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput\x1a\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutput\x12\x9b\x01\n\x0e\x65xecuteCommand\x12\x43.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput\x1a\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutputB\x02P\x01\x62\x06proto3') + serialized_pb=_b('\n\x15\x43ommandExecutor.proto\x12\x33org.onap.ccsdk.cds.controllerblueprints.command.api\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x8f\x02\n\x0e\x45xecutionInput\x12\x11\n\trequestId\x18\x01 \x01(\t\x12\x15\n\rcorrelationId\x18\x02 \x01(\t\x12U\n\x0bidentifiers\x18\x03 \x01(\x0b\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers\x12\x0f\n\x07\x63ommand\x18\x04 \x01(\t\x12\x0f\n\x07timeOut\x18\x05 \x01(\x05\x12+\n\nproperties\x18\x06 \x01(\x0b\x32\x17.google.protobuf.Struct\x12-\n\ttimestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xd0\x02\n\x0fPrepareEnvInput\x12U\n\x0bidentifiers\x18\x01 \x01(\x0b\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers\x12\x11\n\trequestId\x18\x02 \x01(\t\x12\x15\n\rcorrelationId\x18\x03 \x01(\t\x12O\n\x08packages\x18\x04 \x03(\x0b\x32=.org.onap.ccsdk.cds.controllerblueprints.command.api.Packages\x12\x0f\n\x07timeOut\x18\x05 \x01(\x05\x12+\n\nproperties\x18\x06 \x01(\x0b\x32\x17.google.protobuf.Struct\x12-\n\ttimestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\">\n\x0bIdentifiers\x12\x15\n\rblueprintName\x18\x01 \x01(\t\x12\x18\n\x10\x62lueprintVersion\x18\x02 \x01(\t\"\xba\x01\n\x0f\x45xecutionOutput\x12\x11\n\trequestId\x18\x01 \x01(\t\x12\x10\n\x08response\x18\x02 \x01(\t\x12S\n\x06status\x18\x03 \x01(\x0e\x32\x43.org.onap.ccsdk.cds.controllerblueprints.command.api.ResponseStatus\x12-\n\ttimestamp\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"k\n\x08Packages\x12N\n\x04type\x18\x01 \x01(\x0e\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.PackageType\x12\x0f\n\x07package\x18\x02 \x03(\t**\n\x0eResponseStatus\x12\x0b\n\x07SUCCESS\x10\x00\x12\x0b\n\x07\x46\x41ILURE\x10\x01*&\n\x0bPackageType\x12\n\n\x06PYTHON\x10\x00\x12\x0b\n\x07\x41NSIBLE\x10\x01\x32\xd1\x02\n\x16\x43ommandExecutorService\x12\x98\x01\n\nprepareEnv\x12\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput\x1a\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutput\x12\x9b\x01\n\x0e\x65xecuteCommand\x12\x43.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput\x1a\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutputB\x02P\x01\x62\x06proto3') , dependencies=[google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,]) @@ -43,15 +43,15 @@ _RESPONSESTATUS = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=1114, - serialized_end=1156, + serialized_start=1116, + serialized_end=1158, ) _sym_db.RegisterEnumDescriptor(_RESPONSESTATUS) ResponseStatus = enum_type_wrapper.EnumTypeWrapper(_RESPONSESTATUS) -_SCRIPTTYPE = _descriptor.EnumDescriptor( - name='ScriptType', - full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ScriptType', +_PACKAGETYPE = _descriptor.EnumDescriptor( + name='PackageType', + full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PackageType', filename=None, file=DESCRIPTOR, values=[ @@ -63,29 +63,19 @@ _SCRIPTTYPE = _descriptor.EnumDescriptor( name='ANSIBLE', index=1, number=1, serialized_options=None, type=None), - _descriptor.EnumValueDescriptor( - name='KOTLIN', index=2, number=2, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='SH', index=3, number=3, - serialized_options=None, - type=None), ], containing_type=None, serialized_options=None, - serialized_start=1158, - serialized_end=1215, + serialized_start=1160, + serialized_end=1198, ) -_sym_db.RegisterEnumDescriptor(_SCRIPTTYPE) +_sym_db.RegisterEnumDescriptor(_PACKAGETYPE) -ScriptType = enum_type_wrapper.EnumTypeWrapper(_SCRIPTTYPE) +PackageType = enum_type_wrapper.EnumTypeWrapper(_PACKAGETYPE) SUCCESS = 0 FAILURE = 1 PYTHON = 0 ANSIBLE = 1 -KOTLIN = 2 -SH = 3 @@ -118,36 +108,29 @@ _EXECUTIONINPUT = _descriptor.Descriptor( is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='scriptType', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.scriptType', index=3, - number=4, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='command', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.command', index=4, - number=5, type=9, cpp_type=9, label=1, + name='command', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.command', index=3, + number=4, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='timeOut', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.timeOut', index=5, - number=6, type=5, cpp_type=1, label=1, + name='timeOut', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.timeOut', index=4, + number=5, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='properties', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.properties', index=6, - number=7, type=11, cpp_type=10, label=1, + name='properties', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.properties', index=5, + number=6, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='timestamp', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.timestamp', index=7, - number=8, type=11, cpp_type=10, label=1, + name='timestamp', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput.timestamp', index=6, + number=7, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, @@ -165,7 +148,7 @@ _EXECUTIONINPUT = _descriptor.Descriptor( oneofs=[ ], serialized_start=142, - serialized_end=498, + serialized_end=413, ) @@ -198,36 +181,29 @@ _PREPAREENVINPUT = _descriptor.Descriptor( is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='scriptType', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.scriptType', index=3, - number=4, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='packages', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.packages', index=4, - number=5, type=9, cpp_type=9, label=3, + name='packages', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.packages', index=3, + number=4, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='timeOut', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.timeOut', index=5, - number=6, type=5, cpp_type=1, label=1, + name='timeOut', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.timeOut', index=4, + number=5, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='properties', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.properties', index=6, - number=7, type=11, cpp_type=10, label=1, + name='properties', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.properties', index=5, + number=6, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='timestamp', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.timestamp', index=7, - number=8, type=11, cpp_type=10, label=1, + name='timestamp', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput.timestamp', index=6, + number=7, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, @@ -244,8 +220,8 @@ _PREPAREENVINPUT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=501, - serialized_end=859, + serialized_start=416, + serialized_end=752, ) @@ -282,8 +258,8 @@ _IDENTIFIERS = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=861, - serialized_end=923, + serialized_start=754, + serialized_end=816, ) @@ -334,26 +310,65 @@ _EXECUTIONOUTPUT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=926, - serialized_end=1112, + serialized_start=819, + serialized_end=1005, +) + + +_PACKAGES = _descriptor.Descriptor( + name='Packages', + full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.Packages', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='type', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.Packages.type', index=0, + number=1, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='package', full_name='org.onap.ccsdk.cds.controllerblueprints.command.api.Packages.package', index=1, + number=2, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1007, + serialized_end=1114, ) _EXECUTIONINPUT.fields_by_name['identifiers'].message_type = _IDENTIFIERS -_EXECUTIONINPUT.fields_by_name['scriptType'].enum_type = _SCRIPTTYPE _EXECUTIONINPUT.fields_by_name['properties'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT _EXECUTIONINPUT.fields_by_name['timestamp'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP _PREPAREENVINPUT.fields_by_name['identifiers'].message_type = _IDENTIFIERS -_PREPAREENVINPUT.fields_by_name['scriptType'].enum_type = _SCRIPTTYPE +_PREPAREENVINPUT.fields_by_name['packages'].message_type = _PACKAGES _PREPAREENVINPUT.fields_by_name['properties'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT _PREPAREENVINPUT.fields_by_name['timestamp'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP _EXECUTIONOUTPUT.fields_by_name['status'].enum_type = _RESPONSESTATUS _EXECUTIONOUTPUT.fields_by_name['timestamp'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP +_PACKAGES.fields_by_name['type'].enum_type = _PACKAGETYPE DESCRIPTOR.message_types_by_name['ExecutionInput'] = _EXECUTIONINPUT DESCRIPTOR.message_types_by_name['PrepareEnvInput'] = _PREPAREENVINPUT DESCRIPTOR.message_types_by_name['Identifiers'] = _IDENTIFIERS DESCRIPTOR.message_types_by_name['ExecutionOutput'] = _EXECUTIONOUTPUT +DESCRIPTOR.message_types_by_name['Packages'] = _PACKAGES DESCRIPTOR.enum_types_by_name['ResponseStatus'] = _RESPONSESTATUS -DESCRIPTOR.enum_types_by_name['ScriptType'] = _SCRIPTTYPE +DESCRIPTOR.enum_types_by_name['PackageType'] = _PACKAGETYPE _sym_db.RegisterFileDescriptor(DESCRIPTOR) ExecutionInput = _reflection.GeneratedProtocolMessageType('ExecutionInput', (_message.Message,), dict( @@ -384,6 +399,13 @@ ExecutionOutput = _reflection.GeneratedProtocolMessageType('ExecutionOutput', (_ )) _sym_db.RegisterMessage(ExecutionOutput) +Packages = _reflection.GeneratedProtocolMessageType('Packages', (_message.Message,), dict( + DESCRIPTOR = _PACKAGES, + __module__ = 'CommandExecutor_pb2' + # @@protoc_insertion_point(class_scope:org.onap.ccsdk.cds.controllerblueprints.command.api.Packages) + )) +_sym_db.RegisterMessage(Packages) + DESCRIPTOR._options = None @@ -393,8 +415,8 @@ _COMMANDEXECUTORSERVICE = _descriptor.ServiceDescriptor( file=DESCRIPTOR, index=0, serialized_options=None, - serialized_start=1218, - serialized_end=1555, + serialized_start=1201, + serialized_end=1538, methods=[ _descriptor.MethodDescriptor( name='prepareEnv', |