浏览代码

Fixes #1184 Add support for support nodes in envgen.

If any valid number of support nodes are specified, all non-thor and non-roxie
nodes are assigned to the support nodes. Otherwise, environment is generated
as it is being done currently (i.e. thor/roxie and other components can be
assigned to the same node).

Signed-off-by: Sridhar Meda <sridhar.meda@lexisnexis.com>
Sridhar Meda 13 年之前
父节点
当前提交
b389e53441
共有 3 个文件被更改,包括 120 次插入24 次删除
  1. 103 20
      deployment/deployutils/wizardInputs.cpp
  2. 5 2
      deployment/deployutils/wizardInputs.hpp
  3. 12 2
      deployment/envgen/main.cpp

+ 103 - 20
deployment/deployutils/wizardInputs.cpp

@@ -38,7 +38,8 @@
 CWizardInputs::CWizardInputs(const char* xmlArg,const char *service, 
                              IPropertyTree * cfg, 
                              MapStringTo<StringBuffer>* dirMap): m_service(service), 
-                             m_cfg(cfg), m_overrideDirs(dirMap), m_roxieOnDemand(true)
+                             m_cfg(cfg), m_overrideDirs(dirMap), m_roxieOnDemand(true),
+                             m_supportNodes(0)
 {
   m_pXml.setown(createPTreeFromXMLString(xmlArg && *xmlArg ? xmlArg : "<XmlArgs/>"));
 }
@@ -75,6 +76,24 @@ void CWizardInputs::setEnvironment()
   if(m_pXml->hasProp("@ipList"))
     formIPList(m_pXml->queryProp("@ipList"), m_ipaddress);
 
+  if(m_pXml->hasProp("@supportNodes"))
+  {
+    m_supportNodes = atoi(m_pXml->queryProp("@supportNodes"));
+
+    if (m_supportNodes)
+    {
+      if (m_ipaddress.length() > 0 && m_ipaddress.length() > m_supportNodes)
+      {
+        for(unsigned i = 0; i < m_supportNodes; i++)
+          m_ipaddressSupport.append(m_ipaddress.item(i));
+
+        m_ipaddress.removen(0, m_supportNodes);
+      }
+      else
+        m_supportNodes = 0;
+    }
+  }
+
   if(m_pXml->hasProp("@roxieNodes"))
     m_roxieNodes = atoi(m_pXml->queryProp("@roxieNodes"));
 
@@ -175,7 +194,6 @@ void CWizardInputs::setWizardRules()
                    serverCompArr = new StringArray();
                    serverCompArr->append(x == 0 ? eachpair.item(1): eachpair.item(0));
                    m_invalidServerCombo.setValue(eachpair.item(x),serverCompArr);
-                   serverCompArr->kill();
                  }
                }
              }
@@ -246,7 +264,8 @@ CInstDetails* CWizardInputs::getServerIPMap(const char* compName, const char* bu
     if(m_compOnAllNodes.find(buildSetName) != NotFound)
       return instDetails;
     
-    if(m_ipaddress.ordinality() == 1)
+    if (m_ipaddress.ordinality() + m_supportNodes == 1 ||
+        (m_supportNodes == 1 && strcmp(buildSetName, "roxie") && strcmp(buildSetName, "thor" )))
     {
       instDetails = new CInstDetails(compName, m_ipaddress.item(0));
       m_compIpMap.setValue(buildSetName,instDetails);
@@ -256,14 +275,14 @@ CInstDetails* CWizardInputs::getServerIPMap(const char* compName, const char* bu
     {
       for(unsigned x = 0; x < numOfNodes ; x++)
       {
-        unsigned numOfIPSAlreadyTaken = getCntForAlreadyAssignedIPS();
-        if( numOfIPSAlreadyTaken < m_ipaddress.ordinality())
+        unsigned numOfIPSAlreadyTaken = getCntForAlreadyAssignedIPS(buildSetName);
+        if( numOfIPSAlreadyTaken < getIpAddrMap(buildSetName).ordinality())
         {
-          addToCompIPMap(buildSetName, m_ipaddress.item(numOfIPSAlreadyTaken), compName);
+          addToCompIPMap(buildSetName, getIpAddrMap(buildSetName).item(numOfIPSAlreadyTaken), compName);
         }
         else
         {
-          applyOverlappingRules(compName, buildSetName);
+          applyOverlappingRules(compName, buildSetName, numOfIPSAlreadyTaken);
         }
       }
  
@@ -282,7 +301,7 @@ CInstDetails* CWizardInputs::getServerIPMap(const char* compName, const char* bu
   return NULL;
 }
 
-void CWizardInputs::applyOverlappingRules(const char* compName,const char* buildSetName)
+void CWizardInputs::applyOverlappingRules(const char* compName,const char* buildSetName, unsigned startpos)
 {
   StringArray dontAssign , ignoredForOverlap;
   bool assignedIP = false;
@@ -313,23 +332,26 @@ void CWizardInputs::applyOverlappingRules(const char* compName,const char* build
     ForEachItemIn(i, ipArr)
       dontAssign.append(ipArr.item(i));
   }
-  
-  for(unsigned ii = 0; ii < m_ipaddress.ordinality() ; ii++)
+
+  unsigned pos = startpos % getIpAddrMap(buildSetName).ordinality();
+
+  for (unsigned j=pos; j < pos + getIpAddrMap(buildSetName).ordinality(); j++)
   {
-    count_t ipAssignedCount = 0;
-    ipAssignedCount = getNumOfInstForIP(m_ipaddress.item(ii));
+    unsigned ii = (j >= getIpAddrMap(buildSetName).ordinality()) ? 0 : j;
+    count_t ipAssignedCount = getNumOfInstForIP(getIpAddrMap(buildSetName).item(ii));
+
     if(dontAssign.ordinality() > 0)
     {
-      if( dontAssign.find(m_ipaddress.item(ii)) == NotFound)
+      if( dontAssign.find(getIpAddrMap(buildSetName).item(ii)) == NotFound)
       {
         if(ipAssignedCount >= m_maxCompOnNode )
         {
-          ignoredForOverlap.append(m_ipaddress.item(ii));
+          ignoredForOverlap.append(getIpAddrMap(buildSetName).item(ii));
         }
         else
         {
           assignedIP = true;
-          addToCompIPMap(buildSetName, m_ipaddress.item(ii), compName);
+          addToCompIPMap(buildSetName, getIpAddrMap(buildSetName).item(ii), compName);
           break;
         }
       }
@@ -338,12 +360,12 @@ void CWizardInputs::applyOverlappingRules(const char* compName,const char* build
     {
       if(ipAssignedCount >= m_maxCompOnNode )
       {
-        ignoredForOverlap.append(m_ipaddress.item(ii));
+        ignoredForOverlap.append(getIpAddrMap(buildSetName).item(ii));
       } 
       else
       {
         assignedIP = true;
-        addToCompIPMap(buildSetName, m_ipaddress.item(ii), compName);
+        addToCompIPMap(buildSetName, getIpAddrMap(buildSetName).item(ii), compName);
         break;
       }
     }
@@ -443,15 +465,27 @@ IPropertyTree* CWizardInputs::createEnvironment()
   pCompTree->setProp(xpath.str(), "linuxmachine"); 
   xpath.clear().append(XML_TAG_COMPUTERTYPE).append("/").append(XML_ATTR_OPSYS);    
   pCompTree->setProp(xpath.str(), "linux"); 
+
+  for(unsigned i = 0; i < m_ipaddressSupport.ordinality(); i++)
+  {
+    IPropertyTree* pComputer = pCompTree->addPropTree(XML_TAG_COMPUTER,createPTree());
+    name.clear().appendf("node%03d", (i + 1));
+    pComputer->addProp(XML_ATTR_COMPUTERTYPE, "linuxmachine");
+    pComputer->addProp(XML_ATTR_DOMAIN, "localdomain");
+    pComputer->addProp(XML_ATTR_NAME, name.str());
+    pComputer->addProp(XML_ATTR_NETADDRESS, m_ipaddressSupport.item(i));
+  }
+
   for(unsigned i = 0; i < m_ipaddress.ordinality(); i++)
   { 
     IPropertyTree* pComputer = pCompTree->addPropTree(XML_TAG_COMPUTER,createPTree());
-    name.clear().appendf("node%03d", (i + 1));
+    name.clear().appendf("node%03d", (m_ipaddressSupport.ordinality() + i + 1));
     pComputer->addProp(XML_ATTR_COMPUTERTYPE, "linuxmachine");
     pComputer->addProp(XML_ATTR_DOMAIN, "localdomain");
     pComputer->addProp(XML_ATTR_NAME, name.str());
     pComputer->addProp(XML_ATTR_NETADDRESS, m_ipaddress.item(i));
   }
+
   pNewEnvTree->addPropTree(XML_TAG_HARDWARE, createPTreeFromIPT(pCompTree));
   //Before we generate software tree check for dependencies of component for do_not_generate ,roxie, thor
   checkForDependencies();
@@ -682,13 +716,42 @@ void CWizardInputs::addToCompIPMap(const char* buildSetName, const char* value,
   }
 }
 
-unsigned CWizardInputs::getCntForAlreadyAssignedIPS()
+unsigned CWizardInputs::getCntForAlreadyAssignedIPS(const char* buildSetName)
 {
    unsigned cnt = 0;
+   CInstDetails* pInstRoxie = NULL, *pInstThor = NULL;
+
+   if (!strcmp(buildSetName, "roxie") || !strcmp(buildSetName, "thor" ))
+   {
+     if (m_compIpMap.find("roxie") != NULL)
+     {
+       CInstDetails* pInst = m_compIpMap.getValue("roxie");
+       cnt += pInst->getIpAssigned().length();
+     }
+
+     if (m_compIpMap.find("thor") != NULL)
+     {
+       CInstDetails* pInst = m_compIpMap.getValue("thor");
+       cnt += pInst->getIpAssigned().length();
+     }
+
+     return cnt;
+   }
+   else
+   {
+     if (m_compIpMap.find("roxie") != NULL)
+       pInstRoxie = m_compIpMap.getValue("roxie");
+
+     if (m_compIpMap.find("thor") != NULL)
+       pInstThor = m_compIpMap.getValue("thor");
+   }
+
    HashIterator ips(m_compIpMap);
    ForEach(ips)
    {
      CInstDetails* comp = m_compIpMap.mapToValue(&ips.query());
+     if (pInstRoxie == comp || pInstThor == comp)
+       continue;
      StringArray& ipArray = comp->getIpAssigned();
      cnt += ipArray.length();
    }
@@ -1065,9 +1128,16 @@ void CWizardInputs::addComponentToSoftware(IPropertyTree* pNewEnvTree, IProperty
     {
       if (m_compOnAllNodes.find(buildSetName) != NotFound)
       {
-        for (unsigned i = 0; i < m_ipaddress.ordinality(); i++)
+        for (unsigned i = 0; i < m_ipaddressSupport.ordinality(); i++)
         {
           sbl.clear().appendf("s").append(i+1);
+          assignedIP.clear().append(m_ipaddressSupport.item(i));
+          addInstanceToTree(pNewEnvTree, assignedIP, processName, buildSetName,sbl.str());
+        }
+
+        for (unsigned i = 0; i < m_ipaddress.ordinality(); i++)
+        {
+          sbl.clear().appendf("s").append(m_ipaddressSupport.ordinality() + i+1);
           assignedIP.clear().append(m_ipaddress.item(i));
           addInstanceToTree(pNewEnvTree, assignedIP, processName, buildSetName,sbl.str());
         }
@@ -1110,3 +1180,16 @@ void CWizardInputs::addComponentToSoftware(IPropertyTree* pNewEnvTree, IProperty
     }
   }
 }
+
+StringArray& CWizardInputs::getIpAddrMap(const char* buildSetName)
+{
+  if (m_supportNodes == 0)
+    return m_ipaddress;
+  else
+  {
+    if (!strcmp(buildSetName, "roxie") || !strcmp(buildSetName, "thor" ))
+      return m_ipaddress;
+  }
+
+  return m_ipaddressSupport;
+}

+ 5 - 2
deployment/deployutils/wizardInputs.hpp

@@ -93,13 +93,13 @@ public:
   void setWizardIPList(const StringArray ipArray);
   void setWizardRules();
   CInstDetails* getServerIPMap(const char* compName, const char* buildSetName,const IPropertyTree* pEnvTree, unsigned numOfNode = 1);
-  void applyOverlappingRules(const char* compName, const char* buildSetName);
+  void applyOverlappingRules(const char* compName, const char* buildSetName, unsigned startpos);
   count_t getNumOfInstForIP(StringBuffer ip);
   void generateSoftwareTree(IPropertyTree* pTree);
   void addInstanceToTree(IPropertyTree* pTree, StringBuffer attrName, const char* processName, const char* buildSetName, const char* instName);
   void getDefaultsForWizard(IPropertyTree* pTree);
   void addRoxieThorClusterToEnv(IPropertyTree* pNewEnvTree, CInstDetails* pInstDetails, const char* buildSetName, bool genRoxieOnDemand = false);
-  unsigned getCntForAlreadyAssignedIPS();
+  unsigned getCntForAlreadyAssignedIPS(const char* buildsetName);
   void addToCompIPMap(const char* buildSetName, const char* value, const char* compName);
   void getEspBindingInformation(IPropertyTree* pNewEnvTree);
   StringBuffer& getDbUser() { return m_dbuser;}
@@ -119,6 +119,7 @@ public:
 
 private:
   void addComponentToSoftware(IPropertyTree* pNewEnvTree, IPropertyTree* pBuildSet);
+  StringArray& getIpAddrMap(const char* buildsetName);
 
 private:
   typedef StringArray* StringArrayPtr;
@@ -133,6 +134,7 @@ private:
    MapStringToStringArray m_compForTopology; 
    GenOptional m_genOptForAllComps;
    MapStringToStringArray m_invalidServerCombo;
+   unsigned m_supportNodes;
    unsigned m_roxieNodes;
    unsigned m_thorNodes;
    unsigned m_thorSlavesPerNode;
@@ -141,6 +143,7 @@ private:
    bool m_roxieOnDemand;
    
    StringArray m_ipaddress;
+   StringArray m_ipaddressSupport;
    MapStringToMyClass<CInstDetails> m_compIpMap; 
    Owned<IPropertyTree> m_pXml;
    IPropertyTree* m_cfg;

+ 12 - 2
deployment/envgen/main.cpp

@@ -42,6 +42,11 @@ void usage()
   puts("          Allowed formats are ");
   puts("          X.X.X.X;");
   puts("          X.X.X.X-XXX;");
+  puts("   -supportnodes <number of support nodes>: Number of nodes to be used");
+  puts("           for non-Thor and non-Roxie components. If not specified or ");
+  puts("           specified as 0, thor and roxie nodes may overlap with support");
+  puts("           nodes. If an invalid value is provided, support nodes are ");
+  puts("           treated to be 0");
   puts("   -roxienodes <number of roxie nodes>: Number of nodes to be generated ");
   puts("          for roxie. If not specified or specified as 0, no roxie nodes");
   puts("          are generated");
@@ -70,7 +75,7 @@ int main(int argc, char** argv)
   const char* out_envname = NULL;
   const char* in_ipfilename;
   StringBuffer ipAddrs;
-  int roxieNodes=0, thorNodes=0, slavesPerNode=1;
+  int roxieNodes=0, thorNodes=0, slavesPerNode=1, supportNodes=0;
   bool roxieOnDemand = true;
   MapStringTo<StringBuffer> dirMap;
 
@@ -91,6 +96,11 @@ int main(int argc, char** argv)
       i++;
       out_envname = argv[i++];
     }
+    else if (stricmp(argv[i], "-supportnodes") == 0)
+    {
+      i++;
+      supportNodes = atoi(argv[i++]);
+    }
     else if (stricmp(argv[i], "-roxienodes") == 0)
     {
       i++;
@@ -173,7 +183,7 @@ int main(int argc, char** argv)
     const char* pServiceName = "WsDeploy_wsdeploy_esp";
     Owned<IPropertyTree> pCfg = createPTreeFromXMLFile(ENVGEN_PATH_TO_ESP_CONFIG);
 
-    optionsXml.appendf("<XmlArgs roxieNodes=\"%d\" thorNodes=\"%d\" slavesPerNode=\"%d\" roxieOnDemand=\"%s\" ipList=\"%s\"/>", roxieNodes,
+    optionsXml.appendf("<XmlArgs supportNodes=\"%d\" roxieNodes=\"%d\" thorNodes=\"%d\" slavesPerNode=\"%d\" roxieOnDemand=\"%s\" ipList=\"%s\"/>", supportNodes, roxieNodes,
       thorNodes, slavesPerNode, roxieOnDemand?"true":"false", ipAddrs.str());
 
     buildEnvFromWizard(optionsXml, pServiceName, pCfg, envXml, &dirMap);