PluginDeploymentEngine.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*##############################################################################
  2. Copyright (C) 2011 HPCC Systems.
  3. All rights reserved. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ############################################################################## */
  14. #include "PluginDeploymentEngine.hpp"
  15. #include <Shlwapi.h> // for path functions
  16. //#####################################################################################################
  17. //# NOTE: Plugins can no longer be shared and deployed as a component. To avoid version conflicts, #
  18. //# any component using a plugin (currently only ecl/attr servers) must deploy any necessary #
  19. //# plugins as part of its deployment. #
  20. //# This (pre-existing) class merely serves as a base class for components that need plugins. #
  21. //#####################################################################################################
  22. //---------------------------------------------------------------------------
  23. // CPluginDeploymentEngine
  24. //---------------------------------------------------------------------------
  25. CPluginDeploymentEngine::CPluginDeploymentEngine(IEnvDeploymentEngine& envDepEngine,
  26. IConstEnvironment& environment,
  27. IPropertyTree& process,
  28. const char* instanceType/*=NULL*/)
  29. : CDeploymentEngine(envDepEngine, environment, process, instanceType)
  30. {
  31. }
  32. //---------------------------------------------------------------------------
  33. // getPluginDirectory
  34. //
  35. // returns absolute path where plugins are to be deployed
  36. //---------------------------------------------------------------------------
  37. void CPluginDeploymentEngine::getPluginDirectory(const char* destPath, StringBuffer& sPluginDest) const
  38. {
  39. sPluginDest.clear().append(destPath);
  40. sPluginDest.replace('\\', '/');
  41. StringBuffer sPluginsDir; //relative path (from ECL server installation directory) for plugins
  42. m_process.getProp("@pluginsPath", sPluginsDir);
  43. if (sPluginsDir.length())
  44. {
  45. sPluginsDir.replace('\\', '/');
  46. sPluginsDir.replace('$', ':');
  47. if (! ::PathIsRelative(sPluginsDir.str()))
  48. throw MakeStringExceptionDirect(-1, "Plugins path for ECL server must be relative to its installation directory!");
  49. if (!strncmp(sPluginsDir.str(), "./", 2))
  50. sPluginsDir.remove(0, 2);
  51. sPluginDest.append(sPluginsDir);
  52. }
  53. const char* pchLast = sPluginDest.str() + sPluginDest.length() - 1;
  54. if (*pchLast != '/')
  55. sPluginDest.append('/');
  56. }
  57. //---------------------------------------------------------------------------
  58. // getDefaultPlugins
  59. //---------------------------------------------------------------------------
  60. void CPluginDeploymentEngine::getDefaultPlugins(StringArray& plugins,
  61. StringBuffer& sPluginsPath,
  62. const char* destDir) const
  63. {
  64. mmapStr2PairStrStr fileMap;
  65. CDeploymentEngine::createInstallFileMap(m_process, ".", fileMap);
  66. // Get install file list and sort out plugins
  67. mmapStr2PairStrStr::const_iterator i;
  68. mmapStr2PairStrStr::const_iterator iEnd = fileMap.end();
  69. for (i=fileMap.begin(); i != iEnd; i++)
  70. {
  71. const char* dest = (*i).first.c_str();
  72. const char* ext = ::PathFindExtension(dest);
  73. if (ext && *ext)
  74. {
  75. if (stricmp(ext, ".ecl")==0 || stricmp(ext, ".eclmod")==0)
  76. {
  77. if (plugins.find(dest) == NotFound)
  78. {
  79. plugins.append(dest);
  80. sPluginsPath.append(dest).append(';');
  81. }
  82. }
  83. else
  84. // Check that file matches plugin path .\plugins or ./plugins as specified in the release_eclserver file
  85. if (strlen(dest) > 2 && *dest == '.' && (*(dest+1)=='\\' || *(dest+1)=='/') &&
  86. strnicmp(dest+2, "plugins", sizeof("plugins")-1) == 0)
  87. {
  88. // Append plugin to files list - only care about dlls
  89. if (stricmp(ext, ".dll")==0 || stricmp(ext, ".so")==0)
  90. {
  91. StringBuffer path(destDir);
  92. path.append(::PathFindFileName( dest ));
  93. if (plugins.find(path.str()) == NotFound)
  94. {
  95. plugins.append(path.str());
  96. sPluginsPath.append(path.str()).append(';');
  97. }
  98. }
  99. }
  100. }
  101. }
  102. }
  103. //---------------------------------------------------------------------------
  104. // getPlugins
  105. //---------------------------------------------------------------------------
  106. void CPluginDeploymentEngine::getPlugins(StringArray& plugins,
  107. StringBuffer& sPluginsPath,
  108. const char* pluginDest) const
  109. {
  110. // Iterate through plugin references
  111. Owned<IPropertyTreeIterator> iter = m_process.getElements("PluginRef");
  112. ForEach(*iter)
  113. {
  114. // Lookup plugin process
  115. const char* pluginName = iter->query().queryProp("@process");
  116. IPropertyTree* pluginProcess = lookupProcess("PluginProcess", pluginName);
  117. if (!pluginProcess)
  118. throw MakeStringException(0, "Process %s references unknown plugin %s", m_name, pluginName);
  119. // Get plugin file list from the plugin process
  120. mmapStr2PairStrStr fileMap;
  121. CDeploymentEngine::createInstallFileMap(*pluginProcess, pluginDest, fileMap);
  122. mmapStr2PairStrStr::const_iterator i;
  123. mmapStr2PairStrStr::const_iterator iEnd = fileMap.end();
  124. for (i=fileMap.begin(); i != iEnd; i++)
  125. {
  126. const char* dest = (*i).first.c_str();
  127. const char* ext = ::PathFindExtension(dest);
  128. // Append plugin to files list - only care about dll/so
  129. if (ext && (stricmp(ext, ".dll")==0 || stricmp(ext, ".so")==0) &&
  130. plugins.find(dest) == NotFound)
  131. {
  132. plugins.append(dest);
  133. sPluginsPath.append(dest).append(';');
  134. }
  135. }
  136. }
  137. }
  138. //---------------------------------------------------------------------------
  139. // createInstallFileMap
  140. //---------------------------------------------------------------------------
  141. int CPluginDeploymentEngine::createInstallFileMap(IPropertyTree& node,
  142. const char* destPath,
  143. mmapStr2PairStrStr& fileMap) const
  144. {
  145. CDeploymentEngine::createInstallFileMap(node, destPath, fileMap);
  146. //get files for plugin references...
  147. //
  148. StringBuffer sPluginDest;
  149. getPluginDirectory(destPath, sPluginDest);//get absolute path where plugins are to be deployed
  150. //process plugin references for this eclserver process and add files for each service used by
  151. //each binding before adding files for this esp process
  152. Owned<IPropertyTreeIterator> iter = m_process.getElements("PluginRef");
  153. ForEach(*iter)
  154. {
  155. // Lookup plugin process
  156. const char* pluginName = iter->query().queryProp("@process");
  157. IPropertyTree* pluginProcess = lookupProcess("PluginProcess", pluginName);
  158. if (!pluginProcess)
  159. throw MakeStringException(0, "Process %s references unknown plugin %s", m_name, pluginName);
  160. // Get plugin file list from the plugin process
  161. CDeploymentEngine::createInstallFileMap(*pluginProcess, sPluginDest.str(), fileMap);
  162. }
  163. return fileMap.size();
  164. }