main.cpp 25 KB

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