main.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include "jliball.hpp"
  14. #include "XMLTags.h"
  15. #include "configengcallback.hpp"
  16. #include "deploy.hpp"
  17. #include "build-config.h"
  18. #include "jutil.hpp"
  19. #include "jhash.ipp"
  20. #include "portlist.h"
  21. #define STANDARD_INDIR COMPONENTFILES_DIR"/configxml"
  22. #define STANDARD_OUTDIR RUNTIME_DIR
  23. void usage()
  24. {
  25. const char* version = "1.2";
  26. printf("HPCC Systems® configuration generator. version %s. Usage:\n", version);
  27. puts(" configgen -env <environment file> -ip <ip addr> [options]");
  28. puts("");
  29. puts("options: ");
  30. puts(" -env : The configuration environment to be parsed.");
  31. puts(" -ip : The ip address that will be matched against a component ");
  32. puts(" instance's ip address. If matched, configuration files are ");
  33. puts(" generated for that component");
  34. puts(" -c <component name>: Optional component name for which the ");
  35. puts(" configuration is generated. If -t is also specified, it is ");
  36. puts(" ignored");
  37. puts(" -t <component type>: Optional component type for which the ");
  38. puts(" configuration is generated. If -c is also specified, the ");
  39. puts(" component name is used");
  40. puts(" -id <input directory>: The input directory for the supporting ");
  41. puts(" xml environment files like xsd's, xsl's and ");
  42. puts(" configgencomplist.xml. If not specified, the following ");
  43. puts(" defaults are used. ");
  44. puts(" For win32, 'c:\\trunk\\initfiles\\componentfiles\\configxml'");
  45. puts(" For Linux, '" COMPONENTFILES_DIR "/configxml/'");
  46. puts(" -od <output directory>: The output directory for the generated files.");
  47. puts(" If not specified, the following defaults are used. ");
  48. puts(" For win32, '.'");
  49. puts(" For Linux, '" CONFIG_DIR "'");
  50. puts(" -ldapconfig : Generates a .ldaprc file and puts it in the specified");
  51. puts(" output directory. If output directory is not specified,");
  52. puts(" default output directory is used as mentioned in -od option");
  53. puts(" if a LDAPServer is not defined in the environment, the .ldaprc ");
  54. puts(" file is not generated. If an -ip is not provided, the first");
  55. puts(" instance of the first LDAPserver is used to generate the ");
  56. puts(" .ldaprc file");
  57. puts(" -list: Lists out the components for a specific ip in the format");
  58. puts(" componentType=componentName;config file directory. Does not ");
  59. puts(" generate any output files. If masters and slaves exist for ");
  60. puts(" a component like Roxie or thor, then only the master entry ");
  61. puts(" is returned. ");
  62. puts(" -listall: Lists out all the components specified in the environment");
  63. puts(" that have an instance defined. Does not require an ip. Does ");
  64. puts(" not generate any output files. Output is written to stdout ");
  65. puts(" in the csv format as follows");
  66. puts(" ProcessType,componentName,instanceip,instanceport,runtimedir,logdir");
  67. puts(" Missing fields will be empty.");
  68. puts(" -listall2: Same as -listall but includes ThorSlaveProcesses and ThorSpareProcess.");
  69. puts(" -listespservices: List all esp and their bound services and ports. Does ");
  70. puts(" not require an ip. Does not generate any output files. Output is written to stdout ");
  71. puts(" in the csv format as follows");
  72. puts(" componentType,componentName,serviceType,serviceBindingName,instanceIP,instanceport,protocol");
  73. puts(" Missing fields will be empty.");
  74. puts(" -listdirs: Lists out any directories that need to be created during ");
  75. puts(" init time. Currently, directories for any drop zones ");
  76. puts(" with the same ip as the -ip option are returned. Format is ");
  77. puts(" one directory per line.");
  78. puts(" -listdropzones: Lists out all the dropzones defined in the environment ");
  79. puts(" Does not require an ip. Does not generate any output files.");
  80. puts(" Output is written to stdout. Format is as follows,");
  81. puts(" one entry per line");
  82. puts(" dropzone node ip,dropzone directory");
  83. puts(" -listcommondirs: Lists out all directories that are listed under ");
  84. puts(" Software/Directories section in the following format. ");
  85. puts(" <CategoryName>=<DirectoryValue>");
  86. puts(" Each directory will be listed on a new line.");
  87. puts(" -listldaps: Lists out all LDAPServer instances defined in the ");
  88. puts(" environment in the following format. If the same component");
  89. puts(" has more than one instance, it will be listed as two separate.");
  90. puts(" entries in the output");
  91. puts(" componentName,instanceip");
  92. puts(" -listldapservers: Lists out all LDAP Server components and associated tags");
  93. puts(" -machines: Lists out all names or ips of machines specified in the environment");
  94. puts(" Output is written to stdout, one machine per line.");
  95. puts(" -validateonly: Validates the environment, without generating permanent ");
  96. puts(" configurations. Returns 0 if environment is valid and non zero ");
  97. puts(" in other cases. Validation errors are printed to stderr.");
  98. puts(" Ignores -od flag, if supplied.");
  99. puts(" -v : Print verbose output to stdout");
  100. puts(" -help: print out this usage.");
  101. }
  102. void deleteRecursive(const char* path)
  103. {
  104. Owned<IFile> pDir = createIFile(path);
  105. if (pDir->exists())
  106. {
  107. if (pDir->isDirectory())
  108. {
  109. Owned<IDirectoryIterator> it = pDir->directoryFiles(NULL, false, true);
  110. ForEach(*it)
  111. {
  112. StringBuffer name;
  113. it->getName(name);
  114. StringBuffer childPath(path);
  115. childPath.append(PATHSEPCHAR);
  116. childPath.append(name);
  117. deleteRecursive(childPath.str());
  118. }
  119. }
  120. pDir->remove();
  121. }
  122. }
  123. void copyDirectoryRecursive(const char *source, const char *target)
  124. {
  125. bool first = true;
  126. Owned<IDirectoryIterator> dir = createDirectoryIterator(source, "*");
  127. ForEach (*dir)
  128. {
  129. IFile &sourceFile = dir->query();
  130. if (sourceFile.isFile())
  131. {
  132. StringBuffer targetname(target);
  133. targetname.append(PATHSEPCHAR);
  134. dir->getName(targetname);
  135. OwnedIFile destFile = createIFile(targetname.str());
  136. if (first)
  137. {
  138. if (!recursiveCreateDirectory(target))
  139. throw MakeStringException(-1,"Cannot create directory %s",target);
  140. first = false;
  141. }
  142. copyFile(destFile, &sourceFile);
  143. }
  144. else if (sourceFile.isDirectory())
  145. {
  146. StringBuffer newSource(source);
  147. StringBuffer newTarget(target);
  148. newSource.append(PATHSEPCHAR);
  149. newTarget.append(PATHSEPCHAR);
  150. dir->getName(newSource);
  151. dir->getName(newTarget);
  152. copyDirectoryRecursive(newSource.str(), newTarget.str());
  153. }
  154. }
  155. }
  156. //returns temp path that ends with path sep
  157. //
  158. #ifdef _WIN32
  159. extern DWORD getLastError() { return ::GetLastError(); }
  160. void getTempPath(char* tempPath, unsigned int bufsize, const char* subdir/*=NULL*/)
  161. {
  162. ::GetTempPath(bufsize, tempPath);
  163. ::GetLongPathName(tempPath, tempPath, bufsize);
  164. if (subdir && *subdir)
  165. {
  166. const int len = strlen(tempPath);
  167. char* p = tempPath + len;
  168. strcpy(p, subdir);
  169. p += strlen(subdir);
  170. *p++ = '\\';
  171. *p = '\0';
  172. }
  173. }
  174. #else//Linux specifics follow
  175. extern DWORD getLastError() { return errno; }
  176. void getTempPath(char* tempPath, unsigned int bufsize, const char* subdir/*=NULL*/)
  177. {
  178. assert(bufsize > 5);
  179. strcpy(tempPath, "/tmp/");
  180. if (subdir && *subdir)
  181. {
  182. strcat(tempPath, subdir);
  183. strcat(tempPath, "/");
  184. }
  185. }
  186. #endif
  187. void replaceDotWithHostIp(IPropertyTree* pTree, bool verbose)
  188. {
  189. StringBuffer ip;
  190. queryHostIP().getIpText(ip);
  191. const char* attrs[] = {"@netAddress", "@roxieAddress", "@daliAddress"};
  192. StringBuffer xPath;
  193. for (int i = 0; i < sizeof(attrs)/sizeof(char*); i++)
  194. {
  195. xPath.clear().appendf(".//*[%s]", attrs[i]);
  196. Owned<IPropertyTreeIterator> iter = pTree->getElements(xPath.str());
  197. ForEach(*iter)
  198. {
  199. IPropertyTree* pComponent = &iter->query();
  200. Owned<IAttributeIterator> iAttr = pComponent->getAttributes();
  201. ForEach(*iAttr)
  202. {
  203. const char* attrName = iAttr->queryName();
  204. if (!strcmp(attrName, attrs[i]))
  205. {
  206. String sAttrVal(iAttr->queryValue());
  207. String dot(".");
  208. if (sAttrVal.equals(dot) || sAttrVal.indexOf(".:") == 0 || sAttrVal.indexOf("http://.:") == 0)
  209. {
  210. StringBuffer sb(sAttrVal);
  211. if (sAttrVal.equals(dot))
  212. sb.replaceString(".", ip.str());
  213. else
  214. {
  215. ip.append(":");
  216. sb.replaceString(".:", ip.str());
  217. ip.remove(ip.length() - 1, 1);
  218. }
  219. pComponent->setProp(attrName, sb.str());
  220. if (verbose)
  221. fprintf(stdout, "Replacing '.' with host ip '%s' for component/attribute '%s'[@'%s']\n", ip.str(), pComponent->queryName(), attrName);
  222. }
  223. }
  224. }
  225. }
  226. }
  227. }
  228. int processRequest(const char* in_cfgname, const char* out_dirname, const char* in_dirname,
  229. const char* compName, const char* compType, const char* in_filename,
  230. const char* out_filename, bool generateOutput, const char* ipAddr,
  231. bool listComps, bool verbose, bool listallComps, bool listallCompsAllThors, bool listESPServices, bool listdirs,
  232. bool listdropzones, bool listcommondirs, bool listMachines, bool validateOnly,
  233. bool listldaps, bool ldapconfig, bool ldapservers)
  234. {
  235. Owned<IPropertyTree> pEnv = createPTreeFromXMLFile(in_cfgname);
  236. short nodeIndex = 1;
  237. short index = 1;
  238. short compTypeIndex = 0;
  239. short buildSetIndex = 0;
  240. StringBuffer lastCompAdded;
  241. StringBuffer xPath("*");
  242. CConfigEngCallback callback(verbose);
  243. Owned<IPropertyTreeIterator> iter = pEnv->getElements(xPath.str());
  244. Owned<IConstEnvironment> m_pConstEnvironment;
  245. Owned<IEnvironment> m_pEnvironment;
  246. replaceDotWithHostIp(pEnv, verbose);
  247. StringBuffer envXML;
  248. toXML(pEnv, envXML);
  249. Owned<IEnvironmentFactory> factory = getEnvironmentFactory();
  250. m_pEnvironment.setown(factory->loadLocalEnvironment(envXML));
  251. m_pConstEnvironment.set(m_pEnvironment);
  252. if (validateOnly)
  253. {
  254. char tempdir[_MAX_PATH];
  255. StringBuffer sb;
  256. while(true)
  257. {
  258. sb.clear().appendf("%d", msTick());
  259. getTempPath(tempdir, sizeof(tempdir), sb.str());
  260. if (!checkDirExists(tempdir))
  261. {
  262. if (recursiveCreateDirectory(tempdir))
  263. break;
  264. }
  265. }
  266. try
  267. {
  268. Owned<IEnvDeploymentEngine> m_configGenMgr;
  269. CConfigEngCallback callback(verbose, true);
  270. m_configGenMgr.setown(createConfigGenMgr(*m_pConstEnvironment, callback, NULL, in_dirname?in_dirname:"", tempdir, NULL, NULL, NULL));
  271. m_configGenMgr->deploy(DEFLAGS_CONFIGFILES, DEBACKUP_NONE, false, false);
  272. deleteRecursive(tempdir);
  273. }
  274. catch(IException* e)
  275. {
  276. deleteRecursive(tempdir);
  277. throw e;
  278. }
  279. }
  280. else if (ldapconfig)
  281. {
  282. char tempdir[_MAX_PATH];
  283. StringBuffer sb;
  284. while(true)
  285. {
  286. sb.clear().appendf("%d", msTick());
  287. getTempPath(tempdir, sizeof(tempdir), sb.str());
  288. if (!checkDirExists(tempdir))
  289. {
  290. if (recursiveCreateDirectory(tempdir))
  291. break;
  292. }
  293. }
  294. StringBuffer out;
  295. xPath.clear().append(XML_TAG_SOFTWARE "/" XML_TAG_LDAPSERVERPROCESS);
  296. Owned<IPropertyTreeIterator> ldaps = pEnv->getElements(xPath.str());
  297. Owned<IPropertyTree> pSelComps(createPTree("SelectedComponents"));
  298. bool flag = false;
  299. ForEach(*ldaps)
  300. {
  301. IPropertyTree* ldap = &ldaps->query();
  302. IPropertyTree* inst;
  303. int count = 1;
  304. xPath.clear().appendf(XML_TAG_INSTANCE"[%d]", count);
  305. while ((inst = ldap->queryPropTree(xPath.str())) != NULL)
  306. {
  307. if (ipAddr && *ipAddr && strcmp(ipAddr, inst->queryProp(XML_ATTR_NETADDRESS)))
  308. {
  309. ldap->removeTree(inst);
  310. continue;
  311. }
  312. if (!flag)
  313. {
  314. inst->addProp(XML_ATTR_DIRECTORY, ".");
  315. sb.clear().append(tempdir).append(PATHSEPCHAR).append(ldap->queryProp(XML_ATTR_NAME));
  316. xPath.clear().appendf(XML_TAG_INSTANCE"[%d]", ++count);
  317. flag = true;
  318. }
  319. else
  320. {
  321. ldap->removeTree(inst);
  322. }
  323. }
  324. if (flag)
  325. {
  326. pSelComps->addPropTree(XML_TAG_LDAPSERVERPROCESS, createPTreeFromIPT(ldap));
  327. break;
  328. }
  329. }
  330. if (flag)
  331. {
  332. try
  333. {
  334. toXML(pEnv, envXML.clear());
  335. m_pEnvironment.setown(factory->loadLocalEnvironment(envXML));
  336. m_pConstEnvironment.set(m_pEnvironment);
  337. Owned<IEnvDeploymentEngine> m_configGenMgr;
  338. m_configGenMgr.setown(createConfigGenMgr(*m_pConstEnvironment, callback, pSelComps, in_dirname?in_dirname:"", tempdir, compName, compType, ipAddr));
  339. m_configGenMgr->deploy(DEFLAGS_CONFIGFILES, DEBACKUP_NONE, false, false);
  340. copyDirectoryRecursive(sb.str(), out_dirname);
  341. deleteRecursive(tempdir);
  342. }
  343. catch (IException* e)
  344. {
  345. deleteRecursive(tempdir);
  346. throw e;
  347. }
  348. }
  349. }
  350. else if (ldapservers)
  351. {
  352. //first, build a map of all ldapServer/IP
  353. StringBuffer sb1,sb2;
  354. typedef MapStringTo<StringBuffer> strMap;
  355. strMap ldapServers;
  356. {
  357. xPath.appendf("Software/%s/", XML_TAG_LDAPSERVERPROCESS);
  358. Owned<IPropertyTreeIterator> ldaps = pEnv->getElements(xPath.str());
  359. ForEach(*ldaps)
  360. {
  361. IPropertyTree* ldap = &ldaps->query();
  362. Owned<IPropertyTreeIterator> insts = ldap->getElements(XML_TAG_INSTANCE);
  363. ForEach(*insts)
  364. {
  365. IPropertyTree* inst = &insts->query();
  366. StringBuffer computerName(inst->queryProp(XML_ATTR_COMPUTER));
  367. xPath.clear().appendf("Hardware/Computer[@name=\"%s\"]", computerName.str());
  368. IPropertyTree* pComputer = pEnv->queryPropTree(xPath.str());
  369. if (pComputer)
  370. {
  371. if (NULL == ldapServers.getValue(ldap->queryProp(XML_ATTR_NAME)))//only add once
  372. ldapServers.setValue(ldap->queryProp(XML_ATTR_NAME), pComputer->queryProp("@netAddress"));
  373. }
  374. }
  375. }
  376. }
  377. //Lookup and output all LDAPServer components
  378. StringBuffer out;
  379. xPath.clear().append(XML_TAG_SOFTWARE "/" XML_TAG_LDAPSERVERPROCESS);
  380. Owned<IPropertyTreeIterator> ldaps = pEnv->getElements(xPath.str());
  381. ForEach(*ldaps)
  382. {
  383. IPropertyTree* ldap = &ldaps->query();
  384. out.appendf("%s\n",ldap->queryName());
  385. Owned<IAttributeIterator> attrs = ldap->getAttributes();
  386. ForEach(*attrs)
  387. {
  388. out.appendf("%s,%s\n", attrs->queryName(), attrs->queryValue());
  389. //If this is ldap server name, lookup and add its IP address
  390. if (0==strcmp(attrs->queryName(), "@name"))
  391. {
  392. StringBuffer * ldapIP = ldapServers.getValue(attrs->queryValue());
  393. if (ldapIP)
  394. {
  395. out.appendf("@ldapAddress,%s\n",ldapIP->str());
  396. ldapServers.remove(attrs->queryValue());//ensure this server only listed once
  397. }
  398. else
  399. {
  400. out.clear();
  401. break;
  402. }
  403. }
  404. }
  405. if (out.length())
  406. {
  407. fprintf(stdout, "%s", out.str());
  408. out.clear();
  409. }
  410. }
  411. }
  412. else if (!listComps && !listallComps && !listdirs && !listdropzones && !listcommondirs && !listMachines
  413. && !listldaps && !listESPServices)
  414. {
  415. Owned<IEnvDeploymentEngine> m_configGenMgr;
  416. m_configGenMgr.setown(createConfigGenMgr(*m_pConstEnvironment, callback, NULL, in_dirname?in_dirname:"", out_dirname?out_dirname:"", compName, compType, ipAddr));
  417. m_configGenMgr->deploy(DEFLAGS_CONFIGFILES, DEBACKUP_NONE, false, false);
  418. }
  419. else if (listldaps)
  420. {
  421. StringBuffer out;
  422. xPath.appendf("Software/%s/", XML_TAG_LDAPSERVERPROCESS);
  423. Owned<IPropertyTreeIterator> ldaps = pEnv->getElements(xPath.str());
  424. ForEach(*ldaps)
  425. {
  426. IPropertyTree* ldap = &ldaps->query();
  427. Owned<IPropertyTreeIterator> insts = ldap->getElements(XML_TAG_INSTANCE);
  428. ForEach(*insts)
  429. {
  430. IPropertyTree* inst = &insts->query();
  431. StringBuffer computerName(inst->queryProp(XML_ATTR_COMPUTER));
  432. xPath.clear().appendf("Hardware/Computer[@name=\"%s\"]", computerName.str());
  433. IPropertyTree* pComputer = pEnv->queryPropTree(xPath.str());
  434. if (pComputer)
  435. {
  436. const char* netAddr = pComputer->queryProp("@netAddress");
  437. out.appendf("%s,%s\n", ldap->queryProp(XML_ATTR_NAME), netAddr);
  438. }
  439. }
  440. }
  441. fprintf(stdout, "%s", out.str());
  442. }
  443. else if (listdirs || listdropzones)
  444. {
  445. StringBuffer out;
  446. xPath.clear().appendf("Software/%s", XML_TAG_DROPZONE);
  447. Owned<IPropertyTreeIterator> dropZonesInsts = pEnv->getElements(xPath.str());
  448. ForEach(*dropZonesInsts)
  449. {
  450. IPropertyTree* pDropZone = &dropZonesInsts->query();
  451. StringBuffer computerName(pDropZone->queryProp(XML_ATTR_COMPUTER));
  452. xPath.clear().appendf("Hardware/Computer[@name=\"%s\"]", computerName.str());
  453. IPropertyTree* pComputer = pEnv->queryPropTree(xPath.str());
  454. if (pComputer)
  455. {
  456. const char* netAddr = pComputer->queryProp("@netAddress");
  457. if (listdropzones)
  458. out.appendf("%s,%s\n", netAddr, pDropZone->queryProp(XML_ATTR_DIRECTORY));
  459. else if (matchDeployAddress(ipAddr, netAddr))
  460. out.appendf("%s\n", pDropZone->queryProp(XML_ATTR_DIRECTORY));
  461. }
  462. }
  463. fprintf(stdout, "%s", out.str());
  464. }
  465. else if (listcommondirs)
  466. {
  467. StringBuffer out;
  468. StringBuffer name;
  469. xPath.clear().appendf("Software/Directories/@name");
  470. name.append(pEnv->queryProp(xPath.str()));
  471. xPath.clear().appendf("Software/Directories/Category");
  472. Owned<IPropertyTreeIterator> dirInsts = pEnv->getElements(xPath.str());
  473. ForEach(*dirInsts)
  474. {
  475. IPropertyTree* pDir = &dirInsts->query();
  476. StringBuffer dirName(pDir->queryProp("@dir"));
  477. int len = strrchr(dirName.str(), '/') - dirName.str();
  478. dirName.setLength(len);
  479. if (strstr(dirName.str(), "/[INST]") || strstr(dirName.str(), "/[COMPONENT]"))
  480. continue;
  481. dirName.replaceString("[NAME]", name.str());
  482. out.appendf("%s=%s\n", pDir->queryProp(XML_ATTR_NAME), dirName.str());
  483. }
  484. fprintf(stdout, "%s", out.str());
  485. }
  486. else if (listESPServices == true)
  487. {
  488. StringBuffer out;
  489. Owned<IPropertyTreeIterator> espProcesses = pEnv->getElements(XML_TAG_SOFTWARE "/" XML_TAG_ESPPROCESS);
  490. ForEach(*espProcesses)
  491. {
  492. StringBuffer strNetAddr;
  493. StringBuffer strPort;
  494. IPropertyTree *pComponent = &espProcesses->query();
  495. StringBuffer processName(pComponent->queryName()); // component type
  496. if(strcmp(processName.str(), XML_TAG_ESPPROCESS) != 0)
  497. {
  498. continue;
  499. }
  500. StringBuffer strEspName(pComponent->queryProp(XML_ATTR_NAME)); //esp name
  501. Owned<IPropertyTreeIterator> itInstances = pComponent->getElements(XML_TAG_INSTANCE);
  502. ForEach(*itInstances)
  503. {
  504. StringBuffer strInstanceName;
  505. IPropertyTree* pInst = &itInstances->query();
  506. strNetAddr.clear().append(pInst->queryProp(XML_ATTR_NETADDRESS));
  507. strInstanceName.clear().append(pInst->queryProp(XML_ATTR_NAME));
  508. Owned<IPropertyTreeIterator> itBinding = pComponent->getElements(XML_TAG_ESPBINDING);
  509. ForEach(*itBinding)
  510. {
  511. IPropertyTree* pBinding = &itBinding->query();
  512. StringBuffer strServiceName(pBinding->queryProp(XML_ATTR_SERVICE));
  513. StringBuffer strBindingName(pBinding->queryProp(XML_ATTR_NAME));
  514. StringBuffer strProtocol(pBinding->queryProp(XML_ATTR_PROTOCOL));
  515. strPort.clear().append(pBinding->queryProp(XML_ATTR_PORT));
  516. out.appendf("%s,%s,%s,%s,%s,%s,%s\n", processName.str(), strEspName.str(), strServiceName.str(),strBindingName.str(), strNetAddr.str(), strPort.str(),strProtocol.str());
  517. }
  518. }
  519. }
  520. fprintf(stdout, "%s", out.str());
  521. }
  522. else if (listMachines)
  523. {
  524. MapStringTo<bool> mapOfMachineIPs;
  525. StringBuffer out;
  526. Owned<IPropertyTreeIterator> computers = pEnv->getElements("Hardware/Computer");
  527. ForEach(*computers)
  528. {
  529. IPropertyTree* pComputer = &computers->query();
  530. const char *netAddress = pComputer->queryProp("@netAddress");
  531. if (mapOfMachineIPs.getValue(netAddress) != NULL)
  532. {
  533. continue;
  534. }
  535. else
  536. {
  537. mapOfMachineIPs.setValue(netAddress, true);
  538. }
  539. StringBuffer xpath;
  540. const char* name = pComputer->queryProp(XML_ATTR_NAME);
  541. bool isNonHPCCNode = true;
  542. xpath.clear().appendf(XML_TAG_SOFTWARE "/*[//" XML_ATTR_COMPUTER "='%s']", name);
  543. Owned<IPropertyTreeIterator> it = pEnv->getElements(xpath.str());
  544. ForEach(*it)
  545. {
  546. IPropertyTree* pComponent = &it->query();
  547. if (!strcmp(pComponent->queryName(), "LDAPServerProcess") ||
  548. !strcmp(pComponent->queryName(), "MySQLProcess"))
  549. // because if either blacklisted components are also on a machine that
  550. // has a valid component, we still want to show that machine.
  551. continue;
  552. else
  553. // iterator is valid, and not blacklisted
  554. isNonHPCCNode = false;
  555. break;
  556. }
  557. if (isNonHPCCNode)
  558. continue;
  559. out.appendf("%s,", netAddress ? netAddress : "");
  560. const char *computerType = pComputer->queryProp("@computerType");
  561. if (computerType)
  562. {
  563. xpath.clear().appendf("Hardware/ComputerType[@name='%s']", computerType);
  564. IPropertyTree *pType = pEnv->queryPropTree(xpath.str());
  565. out.appendf("%s", pType->queryProp("@opSys"));
  566. }
  567. out.newline();
  568. }
  569. fprintf(stdout, "%s", out.str());
  570. }
  571. else
  572. {
  573. StringBuffer out;
  574. Owned<IPropertyTree> pSelectedComponents = getInstances(&m_pConstEnvironment->getPTree(), compName, compType, ipAddr, true);
  575. Owned<IPropertyTreeIterator> it = pSelectedComponents->getElements("*");
  576. ForEach(*it)
  577. {
  578. IPropertyTree* pComponent = &it->query();
  579. if (listComps)
  580. {
  581. if (!strcmp(pComponent->queryProp("@buildSet"), "roxie") || !strcmp(pComponent->queryProp("@buildSet"), "thor"))
  582. {
  583. Owned<IPropertyTreeIterator> itInst = pComponent->getElements("*");
  584. ForEach(*itInst)
  585. {
  586. IPropertyTree* pInst = &itInst->query();
  587. String instName(pInst->queryName());
  588. if (!strcmp(instName.str(), "ThorMasterProcess") || instName.startsWith("RoxieServerProcess"))
  589. {
  590. out.appendf("%s=%s;%s%c%s;%s\n", pComponent->queryProp("@name"), pComponent->queryProp("@buildSet"), out_dirname, PATHSEPCHAR, pComponent->queryProp("@name"),"master");
  591. }
  592. }
  593. }
  594. else
  595. out.appendf("%s=%s;%s%c%s\n", pComponent->queryProp("@name"), pComponent->queryProp("@buildSet"), out_dirname, PATHSEPCHAR, pComponent->queryProp("@name"));
  596. }
  597. else if (listallComps)
  598. {
  599. StringBuffer netAddr;
  600. StringBuffer port;
  601. StringBuffer processName(pComponent->queryName());
  602. bool multiInstances = false;
  603. if(!strcmp(processName.str(), "ThorCluster") || !strcmp(processName.str(), "RoxieCluster"))
  604. {
  605. processName.clear();
  606. multiInstances = true;
  607. }
  608. if (pComponent->numChildren())
  609. {
  610. Owned<IPropertyTreeIterator> itComp = pComponent->getElements("*");
  611. ForEach(*itComp)
  612. {
  613. IPropertyTree* pInst = &itComp->query();
  614. if (listallCompsAllThors == false && (!strcmp(pInst->queryName(), "ThorSlaveProcess") || !strcmp(pInst->queryName(), "ThorSpareProcess")))
  615. continue;
  616. netAddr.clear().append(pInst->queryProp("@netAddress"));
  617. port.clear();
  618. if (strcmp(pInst->queryName(), XML_TAG_THORMASTERPROCESS) == 0)
  619. {
  620. if (pInst->queryProp(XML_ATTR_MASTERPORT) == NULL || (pInst->queryProp(XML_ATTR_MASTERPORT))[0] == 0)
  621. port.append(THOR_BASE_PORT);
  622. else
  623. port.append(pInst->queryProp(XML_ATTR_MASTERPORT));
  624. }
  625. else
  626. port.append(pInst->queryProp("@port"));
  627. if (multiInstances)
  628. processName.clear().append(pInst->queryName());
  629. out.appendf("%s,%s,%s,%s,%s%c%s,%s\n", processName.str(),
  630. pComponent->queryProp("@name"), netAddr.str(), port.str(),
  631. STANDARD_OUTDIR, PATHSEPCHAR, pComponent->queryProp("@name"), pComponent->queryProp("@logDir"));
  632. }
  633. }
  634. else
  635. {
  636. netAddr.clear().append(pComponent->queryProp("@netAddress"));
  637. port.clear().append(pComponent->queryProp("@port"));
  638. out.appendf("%s,%s,%s,%s,%s%c%s,%s\n", pComponent->queryName(),
  639. pComponent->queryProp("@name"), netAddr.str(), port.str(),
  640. STANDARD_OUTDIR, PATHSEPCHAR, pComponent->queryProp("@name"), pComponent->queryProp("@logDir"));
  641. }
  642. }
  643. }
  644. fprintf(stdout, "%s", out.str());
  645. }
  646. return 0;
  647. }
  648. int main(int argc, char** argv)
  649. {
  650. InitModuleObjects();
  651. Owned<IProperties> globals = createProperties(true);
  652. const char* in_filename = NULL;
  653. const char* in_cfgname = NULL;
  654. const char* out_dirname = STANDARD_OUTDIR;
  655. const char* in_dirname = STANDARD_INDIR;
  656. const char* out_filename = NULL;
  657. const char* compName = NULL;
  658. const char* compType = NULL;
  659. StringBuffer ipAddr;
  660. bool generateOutput = true;
  661. bool listComps = false;
  662. bool verbose = false;
  663. bool listallComps = false;
  664. bool listallCompsAllThors = false;
  665. bool listdirs = false;
  666. bool listdropzones = false;
  667. bool listcommondirs = false;
  668. bool listMachines = false;
  669. bool validateOnly = false;
  670. bool ldapconfig = false;
  671. bool listldaps = false;
  672. bool listespservices = false;
  673. bool ldapservers = false;
  674. int i = 1;
  675. bool writeToFiles = false;
  676. int port = 80;
  677. while(i<argc)
  678. {
  679. if(stricmp(argv[i], "-help") == 0 || stricmp(argv[i], "-?") == 0)
  680. {
  681. usage();
  682. releaseAtoms();
  683. return 0;
  684. }
  685. else if (stricmp(argv[i], "-env") == 0)
  686. {
  687. i++;
  688. in_cfgname = argv[i++];
  689. }
  690. else if (stricmp(argv[i], "-c") == 0)
  691. {
  692. i++;
  693. compName = argv[i++];
  694. }
  695. else if (stricmp(argv[i], "-t") == 0)
  696. {
  697. i++;
  698. compType = argv[i++];
  699. }
  700. else if (stricmp(argv[i], "-ip") == 0)
  701. {
  702. i++;
  703. ipAddr.append(argv[i++]);
  704. if (strcmp(ipAddr, ".")!=0)
  705. {
  706. IpAddress ip(ipAddr.str());
  707. ipAddr.clear();
  708. if (ip.isLoopBack()) // assume they meant any local ip... not sure this is a good idea
  709. ipAddr.append('.');
  710. else
  711. ip.getIpText(ipAddr);
  712. }
  713. }
  714. else if(stricmp(argv[i], "-od") == 0)
  715. {
  716. i++;
  717. out_dirname = argv[i++];
  718. }
  719. else if(stricmp(argv[i], "-id") == 0)
  720. {
  721. i++;
  722. in_dirname = argv[i++];
  723. }
  724. else if (stricmp(argv[i], "-ldapconfig") == 0)
  725. {
  726. i++;
  727. ldapconfig = true;
  728. }
  729. else if (stricmp(argv[i], "-list") == 0)
  730. {
  731. i++;
  732. listComps = true;
  733. }
  734. else if (stricmp(argv[i], "-listall") == 0)
  735. {
  736. i++;
  737. listallComps = true;
  738. }
  739. else if (stricmp(argv[i], "-listall2") == 0)
  740. {
  741. i++;
  742. listallComps = true;
  743. listallCompsAllThors = true;
  744. }
  745. else if (stricmp(argv[i], "-listespservices") == 0)
  746. {
  747. i++;
  748. listespservices = true;
  749. }
  750. else if (stricmp(argv[i], "-listdirs") == 0)
  751. {
  752. i++;
  753. listdirs = true;
  754. }
  755. else if (stricmp(argv[i], "-listdropzones") == 0)
  756. {
  757. i++;
  758. listdropzones = true;
  759. }
  760. else if (stricmp(argv[i], "-listcommondirs") == 0)
  761. {
  762. i++;
  763. listcommondirs = true;
  764. }
  765. else if (stricmp(argv[i], "-listldaps") == 0)
  766. {
  767. i++;
  768. listldaps = true;
  769. }
  770. else if (stricmp(argv[i], "-listldapservers") == 0)
  771. {
  772. i++;
  773. ldapservers = true;
  774. }
  775. else if (stricmp(argv[i], "-machines") == 0)
  776. {
  777. i++;
  778. listMachines = true;
  779. }
  780. else if (stricmp(argv[i], "-validateonly") == 0)
  781. {
  782. i++;
  783. validateOnly = true;
  784. }
  785. else if (stricmp(argv[i], "-v") == 0)
  786. {
  787. i++;
  788. verbose = true;
  789. }
  790. else
  791. {
  792. fprintf(stderr, "Error: unknown command line parameter: %s\n", argv[i]);
  793. usage();
  794. releaseAtoms();
  795. return 1;
  796. }
  797. }
  798. if (!in_cfgname)
  799. {
  800. fprintf(stderr, "Error: Environment xml file is required. Please specify.\n");
  801. usage();
  802. releaseAtoms();
  803. return 1;
  804. }
  805. if (ipAddr.length() == 0 && !listallComps && !validateOnly && !listcommondirs && !listMachines && !listldaps && !ldapconfig)
  806. ipAddr.clear().append("."); // Meaning match any local address
  807. try
  808. {
  809. processRequest(in_cfgname, out_dirname, in_dirname, compName,
  810. compType,in_filename, out_filename, generateOutput, ipAddr.length() ? ipAddr.str(): NULL,
  811. listComps, verbose, listallComps, listallCompsAllThors, listespservices, listdirs, listdropzones, listcommondirs, listMachines,
  812. validateOnly, listldaps, ldapconfig, ldapservers);
  813. }
  814. catch(IException *excpt)
  815. {
  816. StringBuffer errMsg;
  817. fprintf(stderr, "Exception: %d:\n%s\n", excpt->errorCode(), excpt->errorMessage(errMsg).str());
  818. releaseAtoms();
  819. excpt->Release();
  820. return 1;
  821. }
  822. catch(...)
  823. {
  824. fprintf(stderr, "Unknown exception\n");
  825. releaseAtoms();
  826. return 1;
  827. }
  828. releaseAtoms();
  829. return 0;
  830. }