main.cpp 30 KB

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