Skip to content

Commit

Permalink
SetEnv added for plugin Config as well (#1764)
Browse files Browse the repository at this point in the history
* SetEnv added for plugin Config as well

* SetEnv: JSON parameter passing through command is changed

* Update based on comments

* Update based on testing

* Review comments addressed

---------

Co-authored-by: Pierre Wielders <pierre@wielders.net>
  • Loading branch information
HaseenaSainul and pwielders authored Sep 30, 2024
1 parent aaf530c commit 0bffff0
Show file tree
Hide file tree
Showing 9 changed files with 242 additions and 73 deletions.
64 changes: 3 additions & 61 deletions Source/Thunder/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,64 +114,6 @@ namespace PluginHost {
// Configuration to get a server (PluginHost server) up and running.
class JSONConfig : public Core::JSON::Container {
public:
class Environment : public Core::JSON::Container {
public:
Environment()
: Core::JSON::Container()
, Key()
, Value()
, Override(false)
{
Add(_T("key"), &Key);
Add(_T("value"), &Value);
Add(_T("override"), &Override);
}
Environment(const Environment& copy)
: Core::JSON::Container()
, Key(copy.Key)
, Value(copy.Value)
, Override(copy.Override)
{
Add(_T("key"), &Key);
Add(_T("value"), &Value);
Add(_T("override"), &Override);
}
Environment(Environment&& move) noexcept
: Core::JSON::Container()
, Key(std::move(move.Key))
, Value(std::move(move.Value))
, Override(std::move(move.Override))
{
Add(_T("key"), &Key);
Add(_T("value"), &Value);
Add(_T("override"), &Override);
}
~Environment() override = default;
Environment& operator=(const Environment& RHS)
{
Key = RHS.Key;
Value = RHS.Value;
Override = RHS.Override;

return (*this);
}
Environment& operator=(Environment&& move) noexcept
{
if (this != &move) {
Key = std::move(move.Key);
Value = std::move(move.Value);
Override = std::move(move.Override);
}

return (*this);
}

public:
Core::JSON::String Key;
Core::JSON::String Value;
Core::JSON::Boolean Override;
};

class ProcessSet : public Core::JSON::Container {
public:
ProcessSet()
Expand Down Expand Up @@ -526,7 +468,7 @@ namespace PluginHost {
Core::JSON::String Configs;
Core::JSON::String EthernetCard;
Core::JSON::ArrayType<Plugin::Config> Plugins;
Core::JSON::ArrayType<Environment> Environments;
Core::JSON::ArrayType<Plugin::Config::Environment> Environments;
Core::JSON::ArrayType<Core::JSON::EnumType<PluginHost::IShell::reason>> ExitReasons;
Core::JSON::DecSInt32 Latitude;
Core::JSON::DecSInt32 Longitude;
Expand Down Expand Up @@ -773,12 +715,12 @@ namespace PluginHost {
}

bool status = true;
Core::JSON::ArrayType<JSONConfig::Environment>::ConstIterator index(static_cast<const JSONConfig&>(config).Environments.Elements());
Core::JSON::ArrayType<Plugin::Config::Environment>::ConstIterator index(static_cast<const JSONConfig&>(config).Environments.Elements());
while (index.Next() == true) {
if ((index.Current().Key.IsSet() == true) && (index.Current().Value.IsSet() == true)) {
string value = _substituter.Substitute(index.Current().Value.Value(), nullptr);
if (value.empty() != true) {
status = Core::SystemInfo::SetEnvironment(index.Current().Key.Value(), value, index.Current().Override.Value());
status = Core::SystemInfo::SetEnvironment(index.Current().Key.Value(), value, ((index.Current().Override.Value() == RPC::Object::Environment::Scope::GLOBAL) ? true : false));
if (status != true) {
SYSLOG(Logging::Startup, (_T("Failure in setting Key:Value:[%s]:[%s]\n"), index.Current().Key.Value().c_str(), index.Current().Value.Value().c_str()));
}
Expand Down
4 changes: 3 additions & 1 deletion Source/Thunder/IRemoteInstantiation.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace PluginHost {
struct IRemoteInstantiation : virtual public Core::IUnknown {

enum { ID = RPC::IDS::ID_REMOTE_INSTANTIATION };
using IEnvironmentIterator = RPC::IIteratorType<RPC::Object::Environment, RPC::ID_ENVIRONMENT_ITERATOR>;

~IRemoteInstantiation() override = default;

Expand Down Expand Up @@ -56,7 +57,8 @@ namespace PluginHost {
const string& systemRootPath,
const uint8_t threads,
const int8_t priority,
const string configuration) = 0;
const string configuration,
IEnvironmentIterator* const& environments) = 0;
};
}
}
66 changes: 59 additions & 7 deletions Source/Thunder/PluginServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,8 @@ namespace PluginHost {
DYNAMIC
};

using Services = std::unordered_map<string, Service*>;

private:
using BaseClass = PluginHost::Service;
using Jobs = Core::ThrottleQueueType<Core::ProxyType<Core::IDispatch>, ServiceMap&>;
Expand Down Expand Up @@ -1277,16 +1279,29 @@ namespace PluginHost {
string Substitute(const string& input) const override {
return (_administrator.Configuration().Substitute(input, PluginHost::Service::Configuration()));
}
Core::hresult Metadata(string& info /* @out */) const override {
Core::hresult Metadata(string& info /* @out */) const override {
Metadata::Service result;
GetMetadata(result);
result.ToString(info);
return (Core::ERROR_NONE);
}
std::vector<RPC::Object::Environment>& SubstituteList(const std::vector<RPC::Object::Environment>& environmentList) const {
std::vector<RPC::Object::Environment>& environments = const_cast<std::vector<RPC::Object::Environment>&>(environmentList);
for (auto& environment : environments) {
if ((environment.key.empty() != true) && (environment.value.empty() != true)) {
environment.value = Substitute(environment.value);
} else {
SYSLOG(Logging::Startup, (_T("Failure in Substituting Value of Key:Value:[%s]:[%s]\n"), environment.key.c_str(), environment.value.c_str()));
}
}
return environments;
}
void* Instantiate(const RPC::Object& object, const uint32_t waitTime, uint32_t& sessionId) override
{
ASSERT(_connection == nullptr);

const_cast<RPC::Object&>(object).Environments(SubstituteList(object.Environments()));

void* result(_administrator.Instantiate(object, waitTime, sessionId, DataPath(), PersistentPath(), VolatilePath(), _administrator.Configuration().LinkerPluginPaths()));

if (result != nullptr) {
Expand Down Expand Up @@ -1499,7 +1514,9 @@ namespace PluginHost {
else {
uint32_t pid;
Core::ServiceAdministrator::Instance().ReleaseLibrary(std::move(_library));

string environments;
PluginHost::Service::Configuration().Root.Environments.ToString(environments);

RPC::Object definition(locator,
classNameString,
Callsign(),
Expand All @@ -1512,7 +1529,8 @@ namespace PluginHost {
PluginHost::Service::Configuration().Root.HostType(),
SystemRootPath(),
PluginHost::Service::Configuration().Root.RemoteAddress.Value(),
PluginHost::Service::Configuration().Root.Configuration.Value());
PluginHost::Service::Configuration().Root.Configuration.Value(),
Plugin::Config::Environment::List(PluginHost::Service::Configuration().Root.Environments));

newIF = reinterpret_cast<IPlugin*>(Instantiate(definition, _administrator.Configuration().OutOfProcessWaitTime(), pid));
if (newIF == nullptr) {
Expand Down Expand Up @@ -2007,6 +2025,10 @@ namespace PluginHost {
if (instantiation == nullptr) {
result = Core::ERROR_ILLEGAL_STATE;
} else {

using Iterator = IRemoteInstantiation::IEnvironmentIterator;
Iterator* environment = Core::Service<RPC::IteratorType<Iterator>>::Create<Iterator>(_object.Environments());

result = instantiation->Instantiate(
RPC::Communicator::RemoteConnection::Id(),
_object.Locator(),
Expand All @@ -2019,7 +2041,8 @@ namespace PluginHost {
_object.SystemRootPath(),
_object.Threads(),
_object.Priority(),
_object.Configuration());
_object.Configuration(),
environment);

instantiation->Release();
}
Expand Down Expand Up @@ -2399,7 +2422,8 @@ namespace PluginHost {
const string& systemRootPath,
const uint8_t threads,
const int8_t priority,
const string configuration) override
const string configuration,
IRemoteInstantiation::IEnvironmentIterator* const& environments) override
{
string persistentPath(_comms.PersistentPath());
string dataPath(_comms.DataPath());
Expand All @@ -2411,10 +2435,17 @@ namespace PluginHost {
volatilePath += callsign + '/';
}

std::vector<RPC::Object::Environment> _environmentList;
if (environments != nullptr) {
RPC::Object::Environment environment;
while (environments->Next(environment) == true) {
_environmentList.push_back(environment);
}
}

uint32_t id;
RPC::Config config(_connector, _comms.Application(), persistentPath, _comms.SystemPath(), dataPath, volatilePath, _comms.AppPath(), _comms.ProxyStubPath(), _comms.PostMortemPath(), _comms.LinkerPaths());
RPC::Object instance(libraryName, className, callsign, interfaceId, version, user, group, threads, priority, RPC::Object::HostType::LOCAL, systemRootPath, _T(""), configuration);

RPC::Object instance(libraryName, className, callsign, interfaceId, version, user, group, threads, priority, RPC::Object::HostType::LOCAL, systemRootPath, _T(""), configuration, SubstituteList(callsign, _environmentList));
RPC::Communicator::Process process(requestId, config, instance);

return (process.Launch(id));
Expand All @@ -2424,6 +2455,16 @@ namespace PluginHost {
INTERFACE_ENTRY(IRemoteInstantiation)
END_INTERFACE_MAP

private:
std::vector<RPC::Object::Environment>& SubstituteList(const string& callsign, std::vector<RPC::Object::Environment>& environments) const
{
Core::ProxyType<Service> service = _parent.GetService(callsign);
if (service.IsValid() == true) {
environments = service->SubstituteList(environments);
}
return environments;
}

private:
mutable uint32_t _refCount;
ServiceMap& _parent;
Expand Down Expand Up @@ -3064,6 +3105,17 @@ namespace PluginHost {

_adminLock.Unlock();
}
inline Core::ProxyType<Service> GetService(const string& callsign)
{
Core::ProxyType<Service> service;
for (std::pair<const string, Core::ProxyType<Service>>& entry : _services) {
if (entry.first == callsign) {
service = entry.second;
break;
}
}
return service;
}
inline Iterator Services()
{
Shells workingList;
Expand Down
21 changes: 20 additions & 1 deletion Source/ThunderPlugin/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ POP_WARNING()
class ConsoleOptions : public Core::Options {
public:
ConsoleOptions(int argumentCount, TCHAR* arguments[])
: Core::Options(argumentCount, arguments, _T("h:l:c:C:r:p:s:d:a:m:i:u:g:t:e:x:V:v:P:S:f:"))
: Core::Options(argumentCount, arguments, _T("h:l:c:C:r:p:s:d:a:m:i:u:g:t:e:E:x:V:v:P:S:f:"))
, Locator(nullptr)
, ClassName(nullptr)
, Callsign(nullptr)
Expand Down Expand Up @@ -202,6 +202,7 @@ POP_WARNING()
string ProxyStubPath;
string PostMortemPath;
string SystemRootPath;
std::vector<RPC::Object::Environment> Environments;
const TCHAR* User;
const TCHAR* Group;
uint8_t Threads;
Expand Down Expand Up @@ -250,6 +251,13 @@ POP_WARNING()
case 'S':
SystemRootPath = Core::Directory::Normalize(Strip(argument));
break;
case 'e':
case 'E': {
Environments.push_back(Plugin::Config::Environment::Info(Strip(argument),
((option == 'E') ? RPC::Object::Environment::Scope::GLOBAL :
RPC::Object::Environment::Scope::LOCAL)));
break;
}
case 'v':
VolatilePath = Core::Directory::Normalize(Strip(argument));
break;
Expand Down Expand Up @@ -588,6 +596,8 @@ int main(int argc, char** argv)
printf(" [-d <data path>]\n");
printf(" [-v <volatile path>]\n");
printf(" [-f <linker_path>...\n");
printf(" [-e/-E <environment values>...]\n");
printf(" e: means set as local scope, E: means set as global scope\n");
printf(" [-a <app path>]\n");
printf(" [-m <proxy stub library path>]\n");
printf(" [-P <post mortem path>]\n\n");
Expand Down Expand Up @@ -664,6 +674,15 @@ int main(int argc, char** argv)
Core::ProcessCurrent().User(string(options.User));
}

for (const auto& info : options.Environments) {
if ((info.key.empty() != true) && (info.value.empty() != true)) {
uint32_t status = Core::SystemInfo::SetEnvironment(info.key, info.value.c_str(), ((info.overriding == RPC::Object::Environment::Scope::GLOBAL) ? true : false));
if (status != true) {
SYSLOG(Logging::Startup, (_T("Failure in setting Key:Value:[%s]:[%s]\n"), info.key.c_str(), info.value.c_str()));
}
}
}

process.Startup(options.Threads, remoteNode, callsign);

// Register an interface to handle incoming requests for interfaces.
Expand Down
8 changes: 8 additions & 0 deletions Source/com/Communicator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,4 +575,12 @@ namespace RPC {
constexpr uint32_t RPC::ProcessShutdown::DestructionStackSize;

}

ENUM_CONVERSION_BEGIN(RPC::Object::Environment::Scope)

{ RPC::Object::Environment::Scope::LOCAL, _TXT("Local") },
{ RPC::Object::Environment::Scope::GLOBAL, _TXT("Global") },

ENUM_CONVERSION_END(RPC::Object::Environment::Scope)

}
Loading

0 comments on commit 0bffff0

Please sign in to comment.