From ad9a28d70e33c0fa99a65d6c52a7b81665a88105 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Fri, 18 Aug 2023 18:16:13 +0200 Subject: [PATCH] [EDF27816] : methods to position environment of slave containers. --- idl/SALOME_Component.idl | 5 ++ idl/SALOME_ContainerManager.idl | 12 ++++ src/Container/Container_i.cxx | 75 +++++++++++++++++++---- src/Container/SALOME_ContainerManager.cxx | 35 +++++++++++ src/Container/SALOME_ContainerManager.hxx | 12 +++- src/Container/SALOME_Container_i.hxx | 4 ++ src/KERNEL_PY/__init__.py | 6 ++ 7 files changed, 134 insertions(+), 15 deletions(-) diff --git a/idl/SALOME_Component.idl b/idl/SALOME_Component.idl index a759d0528..37c8d809a 100644 --- a/idl/SALOME_Component.idl +++ b/idl/SALOME_Component.idl @@ -63,6 +63,7 @@ module Engines typedef sequence FieldsDict; typedef sequence vectorOfDouble; + typedef sequence vectorOfString; interface EngineComponent ; interface fileRef ; @@ -77,6 +78,10 @@ module Engines interface Container { + void override_environment( in FieldsDict env ); + + FieldsDict get_os_environment(); + /*! \brief Loads a new component class (dynamic library). \param componentName like COMPONENT, (Python or C++ implementation) diff --git a/idl/SALOME_ContainerManager.idl b/idl/SALOME_ContainerManager.idl index ecba48ad9..f4de98ae1 100644 --- a/idl/SALOME_ContainerManager.idl +++ b/idl/SALOME_ContainerManager.idl @@ -67,6 +67,14 @@ struct ContainerParameters ResourceParameters resource_params; }; +struct KeyValPairString +{ + string key; + string val; +}; + +typedef sequence KeyValDict; + /*! \brief Interface of the %containerManager This interface is used for interaction with the unique instance of ContainerManager @@ -80,6 +88,10 @@ interface ContainerManager //! Shutdown all containers that have been launched by the container manager void ShutdownContainers(); + + void SetOverrideEnvForContainers(in KeyValDict env); + + KeyValDict GetOverrideEnvForContainers(); } ; }; diff --git a/src/Container/Container_i.cxx b/src/Container/Container_i.cxx index 79a7e8bc0..de015e08f 100644 --- a/src/Container/Container_i.cxx +++ b/src/Container/Container_i.cxx @@ -31,11 +31,14 @@ #include #include #include +#include #ifndef WIN32 #include #include #include #include +#include +#include #else #include #include @@ -990,7 +993,7 @@ Abstract_Engines_Container_i::load_component_ExecutableImplementation(const char //! Create a new component instance /*! * CORBA method: Creates a new servant instance of a component. -* The servant registers itself to naming service and Registry. +* The servant registers itself to naming service and Registry.tdlib * \param genericRegisterName Name of the component instance to register * in Registry & Name Service (without _inst_n suffix) * \return a loaded component @@ -1007,6 +1010,63 @@ Abstract_Engines_Container_i::create_component_instance(const char*genericRegist return compo; } +void EffectiveOverrideEnvironment( const Engines::FieldsDict& env ) +{ + MESSAGE("Positionning environment on container "); + for (CORBA::ULong i=0; i < env.length(); i++) + { + if (env[i].value.type()->kind() == CORBA::tk_string) + { + const char* value; + env[i].value >>= value; + MESSAGE( env[i].key << " = " << value); +#ifndef WIN32 + if( setenv(env[i].key,value,1) != 0 ) + { + int errsv = errno; + std::string sErr( strerror( errsv) ); + MESSAGE(sErr); + } +#endif + } + } +} + +std::vector< std::pair > GetOSEnvironment() +{ + std::vector< std::pair > ret; +#ifndef WIN32 + char **envPt( environ ); + for(;*envPt != nullptr; ++envPt) + { + std::string s( *envPt ); + auto pos = s.find_first_of('='); + std::string k( s.substr(0,pos) ),v( s.substr(pos+1) ); + ret.emplace_back( std::pair(k,v) ); + } +#endif + return ret; +} + +void Abstract_Engines_Container_i::override_environment( const Engines::FieldsDict& env ) +{ + EffectiveOverrideEnvironment(env); +} + +Engines::FieldsDict *Abstract_Engines_Container_i::get_os_environment() +{ + std::unique_ptr ret( new Engines::FieldsDict ); + std::vector< std::pair > retCpp( GetOSEnvironment() ); + auto sz = retCpp.size(); + ret->length( sz ); + for(auto i = 0 ; i < sz ; ++i) + { + (*ret)[i].key = CORBA::string_dup( retCpp[i].first.c_str() ); + (*ret)[i].value <<= CORBA::string_dup( retCpp[i].second.c_str() ); + } + return ret.release(); +} + //============================================================================= //! Create a new component instance with environment variables specified /*! @@ -1128,18 +1188,7 @@ Abstract_Engines_Container_i::createExecutableInstance(std::string CompName, pid_t pid = fork(); if(pid == 0) // child { - for (CORBA::ULong i=0; i < env.length(); i++) - { - if (env[i].value.type()->kind() == CORBA::tk_string) - { - const char* value; - env[i].value >>= value; - std::string s(env[i].key); - s+='='; - s+=value; - putenv(strdup(s.c_str())); - } - } + EffectiveOverrideEnvironment(env); execl("/bin/sh", "sh", "-c", command.c_str() , (char *)0); status=-1; diff --git a/src/Container/SALOME_ContainerManager.cxx b/src/Container/SALOME_ContainerManager.cxx index e9b7e23a1..bad409f90 100644 --- a/src/Container/SALOME_ContainerManager.cxx +++ b/src/Container/SALOME_ContainerManager.cxx @@ -279,6 +279,27 @@ void SALOME_ContainerManager::ShutdownContainers() } } +void SALOME_ContainerManager::SetOverrideEnvForContainers(const Engines::KeyValDict& env) +{ + this->_override_env.clear(); + auto sz = env.length(); + for(auto i = 0 ; i < sz ; ++i) + _override_env.emplace_back( std::pair(env[i].key,env[i].val) ); +} + +Engines::KeyValDict *SALOME_ContainerManager::GetOverrideEnvForContainers() +{ + std::unique_ptr ret( new Engines::KeyValDict ); + auto sz = _override_env.size(); + ret->length(sz); + for(auto i = 0 ; i < sz ; ++i) + { + (*ret)[i].key = CORBA::string_dup( _override_env[i].first.c_str() ); + (*ret)[i].val = CORBA::string_dup( _override_env[i].second.c_str() ); + } + return ret.release(); +} + //============================================================================= //! Give a suitable Container given constraints /*! CORBA Method: @@ -439,6 +460,20 @@ Engines::Container_ptr SALOME_ContainerManager::GiveContainer(const Engines::Con if (!CORBA::is_nil(cont)) { INFOS("[GiveContainer] container " << containerNameInNS << " launched"); + std::ostringstream envInfo; + std::for_each( _override_env.begin(), _override_env.end(), [&envInfo](const std::pair& p) { envInfo << p.first << " = " << p.second << std::endl; } ); + INFOS("[GiveContainer] container " << containerNameInNS << " override " << envInfo.str()); + Engines::FieldsDict envCorba; + { + auto sz = _override_env.size(); + envCorba.length(sz); + for(auto i = 0 ; i < sz ; ++i) + { + envCorba[i].key = CORBA::string_dup( _override_env[i].first.c_str() ); + envCorba[i].value <<= CORBA::string_dup( _override_env[i].second.c_str() ); + } + } + cont->override_environment( envCorba ); return cont._retn(); } else diff --git a/src/Container/SALOME_ContainerManager.hxx b/src/Container/SALOME_ContainerManager.hxx index 9c75c71d2..1e458769f 100644 --- a/src/Container/SALOME_ContainerManager.hxx +++ b/src/Container/SALOME_ContainerManager.hxx @@ -32,7 +32,9 @@ #include "Utils_Mutex.hxx" +#include #include +#include #include class SALOME_NamingService_Abstract; @@ -46,9 +48,13 @@ public: ~SALOME_ContainerManager(); // Corba Methods - Engines::Container_ptr GiveContainer(const Engines::ContainerParameters& params); + Engines::Container_ptr GiveContainer(const Engines::ContainerParameters& params) override; - void ShutdownContainers(); + void ShutdownContainers() override; + + void SetOverrideEnvForContainers(const Engines::KeyValDict& env) override; + + Engines::KeyValDict *GetOverrideEnvForContainers() override; // C++ Methods void Shutdown(); @@ -193,5 +199,7 @@ public: static const int TIME_OUT_TO_LAUNCH_CONT; static Utils_Mutex _getenvMutex; static Utils_Mutex _systemMutex; +private: + std::vector< std::pair > _override_env; }; #endif diff --git a/src/Container/SALOME_Container_i.hxx b/src/Container/SALOME_Container_i.hxx index b1ad655ec..96996e5f9 100644 --- a/src/Container/SALOME_Container_i.hxx +++ b/src/Container/SALOME_Container_i.hxx @@ -72,6 +72,10 @@ public: virtual Engines::EngineComponent_ptr create_component_instance(const char *componentName); + void override_environment( const Engines::FieldsDict& env ) override; + + Engines::FieldsDict *get_os_environment() override; + virtual Engines::EngineComponent_ptr create_component_instance_env(const char *componentName, const Engines::FieldsDict &env, diff --git a/src/KERNEL_PY/__init__.py b/src/KERNEL_PY/__init__.py index 50a4803d4..ee39881d4 100644 --- a/src/KERNEL_PY/__init__.py +++ b/src/KERNEL_PY/__init__.py @@ -248,6 +248,7 @@ def salome_init_without_session(path=None, embedded=False, iorfakensfile=None): global lcc,cm,dsm,esm,rm import KernelLauncher cm = KernelLauncher.myContainerManager() + type(cm).SetOverrideEnvForContainersSimple = ContainerManagerSetOverrideEnvForContainersSimple rm = KernelLauncher.myResourcesManager() from LifeCycleCORBA import LifeCycleCORBASSL lcc = LifeCycleCORBASSL() @@ -290,6 +291,7 @@ def salome_init_without_session_attached(path=None, embedded=False): import SALOME CM_NAME_IN_NS = "/ContainerManager" cm = orb.string_to_object( nsAbroad.Resolve(CM_NAME_IN_NS).decode() ) + type(cm).SetOverrideEnvForContainersSimple = ContainerManagerSetOverrideEnvForContainersSimple naming_service.Register(cm,CM_NAME_IN_NS) RM_NAME_IN_NS = "/ResourcesManager" rm = orb.string_to_object( nsAbroad.Resolve(RM_NAME_IN_NS).decode() ) @@ -438,5 +440,9 @@ class SessionContextManager: def __exit__(self, type, value, traceback): salome_close() +def ContainerManagerSetOverrideEnvForContainersSimple(self,env): + envEff = [ Engines.KeyValPairString(key=k,val=v) for k,v in env ] + return self.SetOverrideEnvForContainers( envEff ) + #to expose all objects to pydoc __all__=dir() -- 2.39.2