Ver código fonte

HPCC-9486 Configmgr - Handle new level attribute

Signed-off-by: Gleb Aronsky <gleb.aronsky@lexisnexis.com>
Gleb Aronsky 12 anos atrás
pai
commit
f1920d3a1a

+ 3 - 2
deployment/deploy/XMLTags.h

@@ -97,6 +97,7 @@
 #define XML_ATTR_BREAKOUTLIMIT         "@breakoutLimit"
 #define XML_ATTR_BUILD                 "@build"
 #define XML_ATTR_BUILDSET              "@buildSet"
+#define XML_ATTR_CHANNEL               "@channel"
 #define XML_ATTR_CLUSTER               "@cluster"
 #define XML_ATTR_CLUSTERNAME           "@clusterName"
 #define XML_ATTR_CHECKCANCELLED        "@checkCancelled"
@@ -115,7 +116,7 @@
 #define XML_ATTR_CUSTOMERNAME          "@customerName"
 #define XML_ATTR_DALISERVER            "@daliServer"
 #define XML_ATTR_DATABUILD             "@dataBuild"
-#define XML_ATTR_DATADIRECTORY         "@dataDirectory"
+#define XML_ATTR_LEVEL                 "@level"
 #define XML_ATTR_DATAMODEL             "@dataModel"
 #define XML_ATTR_DATASEGMENT           "@dataSegment"
 #define XML_ATTR_DEBUGXML              "@debugXml"
@@ -254,7 +255,7 @@
 #define TAG_NETADDRESS                  "netAddress"
 #define TAG_DOMAIN                      "domain"
 #define TAG_PROCESS                     "process"
-#define TAG_DATADIRECTORY               "dataDirectory"
+#define TAG_LEVEL                       "level"
 #define TAG_COMPUTER                    "computer"
 #define TAG_LISTENQUEUE                 "listenQueue"
 #define TAG_NUMTHREADS                  "numThreads"

+ 48 - 79
deployment/deployutils/configenvhelper.cpp

@@ -121,6 +121,23 @@ bool CConfigEnvHelper::handleThorTopologyOp(const char* cmd, const char* xmlArg,
     return retVal;
 }
 
+void CConfigEnvHelper::addSlaveProcessConfig(IPropertyTree* pRoxie, IPropertyTree *pSlaveNode, int channel, int level, const char* netAddress)
+{
+  if (pRoxie == NULL || pSlaveNode == NULL || netAddress == NULL)
+    return;
+
+
+  IPropertyTree* pSlaveProcess = pRoxie->addPropTree(XML_TAG_ROXIE_SLAVE, createPTree());
+
+  if (pSlaveProcess == NULL)
+    return;
+
+  pSlaveProcess->addProp(XML_ATTR_COMPUTER, pSlaveNode->queryProp(XML_ATTR_COMPUTER));
+  pSlaveProcess->addPropInt(XML_ATTR_CHANNEL, channel);
+  pSlaveProcess->addPropInt(XML_ATTR_LEVEL, level);
+  pSlaveProcess->addProp(XML_ATTR_NETADDRESS, netAddress);
+}
+
 IPropertyTree* CConfigEnvHelper::getSoftwareNode(const char* compType, const char* compName)
 {
   StringBuffer xpath;
@@ -145,6 +162,10 @@ bool CConfigEnvHelper::addRoxieServers(const char* xmlArg)
   {
     xpath.clear().appendf("RoxieCluster[@name='%s']/"XML_TAG_ROXIE_FARM, pszRoxieCluster);
     pFarm = getSoftwareNode(xpath.str(), pszFarm);
+
+    if (pFarm == NULL)
+      return false;
+
     sFarmName = pFarm->queryProp(XML_ATTR_NAME);
     bNewFarm = false;
 
@@ -163,25 +184,7 @@ bool CConfigEnvHelper::addRoxieServers(const char* xmlArg)
     if (!pFarm->hasProp("@aclName"))
       pFarm->addProp("@aclName", "");
 
-    StringBuffer dataDir = pFarm->queryProp(XML_ATTR_DATADIRECTORY);
-    if (dataDir.length()==0)
-      dataDir.append(RUNTIME_DIR"/roxiedata");
-
-    if (!pFarm->queryPropTree(XML_TAG_ROXIE_SERVER"[1]")) //no servers in farm
-    {
-      //if (nComputers > 0)
-      //g_pDocument->makePlatformSpecificAbsolutePath(computers[0]->queryProp(XML_ATTR_NAME), dataDir);
-      Owned<IPropertyTreeIterator> iter = pSrcTree->getElements(XML_TAG_COMPONENT);
-      
-      ForEach (*iter)
-      {
-        IPropertyTree* pFolder = &iter->query();
-        makePlatformSpecificAbsolutePath(pFolder->queryProp(XML_ATTR_NAME), dataDir);
-        break;
-      }
-
-      pFarm->setProp(XML_ATTR_DATADIRECTORY, dataDir.str());
-    }
+    StringBuffer dataDir = pFarm->queryProp(XML_ATTR_LEVEL);
   }
   else
   {
@@ -189,31 +192,12 @@ bool CConfigEnvHelper::addRoxieServers(const char* xmlArg)
     createUniqueName("farm", xpath.str(), sFarmName);
     bNewFarm = true;
 
-    StringBuffer sDataDir;
-    sDataDir.append(RUNTIME_DIR"/roxiedata");
-
-    //get datadir from existing farm if any
-    xpath.clear().appendf("Software/RoxieCluster[@name='%s']/"XML_TAG_ROXIE_FARM"[1]", pszRoxieCluster);
-    IPropertyTree* pFarm1 =  m_pRoot->queryPropTree(xpath.str());
-    if (pFarm1)
-      sDataDir.clear().append(pFarm1->queryProp(XML_ATTR_DATADIRECTORY));
-
-    //if (nComputers > 0)
-    //g_pDocument->makePlatformSpecificAbsolutePath(computers[0]->queryProp(XML_ATTR_NAME), sDataDir);
     Owned<IPropertyTreeIterator> iter = pSrcTree->getElements(XML_TAG_COMPONENT);
       
-    ForEach (*iter)
-    {
-      IPropertyTree* pFolder = &iter->query();
-      makePlatformSpecificAbsolutePath(pFolder->queryProp(XML_ATTR_NAME), sDataDir);
-      break;
-    }
-
     xpath.clear().appendf("RoxieCluster[@name='%s']/"XML_TAG_ROXIE_FARM, pszRoxieCluster);
     pFarm = pParent->addPropTree(xpath.str(), createPTree());
     pFarm->addProp    (XML_ATTR_NAME,       sFarmName.str());
     pFarm->addPropInt("@port", pSrcTree->getPropInt("@port", 9876));
-    pFarm->addProp    (XML_ATTR_DATADIRECTORY,  sDataDir.str());
     pFarm->addPropInt("@listenQueue", 200);
     pFarm->addPropInt("@numThreads",    30);
     pFarm->addPropInt("@requestArrayThreads", 5);
@@ -961,25 +945,8 @@ bool CConfigEnvHelper::handleRoxieSlaveConfig(const char* xmlArg)
         pRoxie->setProp("@baseDataDir", sDataDir.str());
         pRoxie->setProp("@localSlave", computers.size() > 1 ? "false" : "true");
 
-        //update Roxie data directories for all farms and all legacy servers
-        //change all farms
-        Owned<IPropertyTreeIterator> iterFarms = pRoxie->getElements(XML_TAG_ROXIE_FARM);
-        ForEach (*iterFarms)
-        {
-            IPropertyTree* pTmpComp = &iterFarms->query();
-            if (strcmp(pTmpComp->queryProp(XML_ATTR_DATADIRECTORY), sDataDir.str()))
-                pTmpComp->setProp(XML_ATTR_DATADIRECTORY, sDataDir.str());
-        }
-
         //change all legacy servers
         Owned<IPropertyTreeIterator> iterServers = pRoxie->getElements(XML_TAG_ROXIE_SERVER);
-
-        ForEach (*iterServers)
-        {
-            IPropertyTree* pTmpComp = &iterServers->query();
-            if (strcmp(pTmpComp->queryProp(XML_ATTR_DATADIRECTORY), sDataDir.str()))
-                pTmpComp->setProp(XML_ATTR_DATADIRECTORY, sDataDir.str());
-        }
     }
     catch (IException *e)
     {
@@ -994,26 +961,6 @@ bool CConfigEnvHelper::handleRoxieSlaveConfig(const char* xmlArg)
     return true;
 }
 
-
-void CConfigEnvHelper::addReplicateConfig(IPropertyTree* pSlaveNode, int channel, const char* dir, 
-                                                                const char* netAddress, IPropertyTree* pRoxie)
-{
-    StringBuffer directory;
-    directory.appendf("%s", dir);
-    makePlatformSpecificAbsolutePath( pSlaveNode->queryProp(XML_ATTR_COMPUTER), directory);
-
-    IPropertyTree* pInstance = pSlaveNode->addPropTree(XML_TAG_ROXIE_CHANNEL, createPTree());
-    pInstance->setPropInt("@number", channel);
-    pInstance->addProp(XML_ATTR_DATADIRECTORY, directory.str());
-    
-    //maintain a copy as an old style slave procss
-    IPropertyTree* pSlaveProcess = pRoxie->addPropTree(XML_TAG_ROXIE_SLAVE, createPTree());
-    pSlaveProcess->addProp(XML_ATTR_COMPUTER, pSlaveNode->queryProp(XML_ATTR_COMPUTER));
-    pSlaveProcess->addPropInt("@channel", channel);
-    pSlaveProcess->addProp(XML_ATTR_DATADIRECTORY, directory.str());
-    pSlaveProcess->addProp(XML_ATTR_NETADDRESS, netAddress);
-}
-
 bool CConfigEnvHelper::GenerateCyclicRedConfig(IPropertyTree* pRoxie, IPropertyTreePtrArray& computers, 
                                                                                              const char* copies, const char* pszOffset,
                                                                                              const char* dir1, const char* dir2, const char* dir3)
@@ -1060,7 +1007,15 @@ bool CConfigEnvHelper::GenerateCyclicRedConfig(IPropertyTree* pRoxie, IPropertyT
             const char drive = 'c' + c;
             channel = 1 + ((baseChannel + c*(nComputers-offset)) % nComputers);
 
-            addReplicateConfig(pSlave, channel, c==0? dir1: (c==1?dir2:dir3), netAddress, pRoxie);
+            IPropertyTree* pInstance = pSlave->addPropTree(XML_TAG_ROXIE_CHANNEL, createPTree());
+            pInstance->setPropInt("@number", channel);
+
+            StringBuffer strTemp;
+            strTemp.append(c);
+
+            pInstance->addProp(XML_ATTR_LEVEL, strTemp.str());
+
+            addSlaveProcessConfig(pRoxie, pSlave, channel, c, netAddress);
         }
     }
     m_numChannels = nComputers;
@@ -1098,8 +1053,15 @@ bool CConfigEnvHelper::GenerateOverloadedConfig(IPropertyTree* pRoxie, IProperty
 
         for (int c=0; c<m_numDataCopies; c++)
         {
-            const char drive = 'c' + c;
-            addReplicateConfig(pSlave, channel + c*nComputers, c==0?dir1:(c==1?dir2:dir3), netAddress, pRoxie);
+            IPropertyTree* pInstance = pSlave->addPropTree(XML_TAG_ROXIE_CHANNEL, createPTree());
+            pInstance->setPropInt("@number", channel + c*nComputers);
+
+            StringBuffer strTemp;
+            strTemp.append(c);
+
+            pInstance->addProp(XML_ATTR_LEVEL, strTemp.str());
+
+            addSlaveProcessConfig(pRoxie, pSlave, channel + c*nComputers, c, netAddress);
         }
         channel++;
     }
@@ -1139,7 +1101,14 @@ bool CConfigEnvHelper::GenerateFullRedConfig(IPropertyTree* pRoxie, int copies,
         pSlave->addProp(XML_ATTR_NAME, name.str());
         pSlave->addProp(XML_ATTR_COMPUTER, szComputer);
 
-        addReplicateConfig(pSlave, 1 + (channel++ % maxChannel), dir1, netAddress, pRoxie);
+        IPropertyTree* pInstance = pSlave->addPropTree(XML_TAG_ROXIE_CHANNEL, createPTree());
+        pInstance->setPropInt("@number", 1 + (channel % maxChannel));
+        pInstance->addProp(XML_ATTR_LEVEL, "0");
+
+        addSlaveProcessConfig(pRoxie, pSlave, 1 + (channel % maxChannel), 0, netAddress);
+
+        channel++;
+
     }
     m_numChannels = maxChannel;
     return true;

+ 1 - 1
deployment/deployutils/configenvhelper.hpp

@@ -64,7 +64,7 @@ private:
     bool EnsureInRange(const char* psz, UINT low, UINT high, const char* caption);
     bool handleRoxieSlaveConfig(const char* params);
     bool handleReplaceRoxieServer(const char* xmlArg);
-    void addReplicateConfig(IPropertyTree* pSlaveNode, int channel, const char* drive, const char* netAddress, IPropertyTree* pRoxie);
+    void addSlaveProcessConfig(IPropertyTree *pRoxie, IPropertyTree *pSlaveNode, int channel, int level, const char* netAddress);
     bool GenerateCyclicRedConfig(IPropertyTree* pRoxie, IPropertyTreePtrArray& computers, const char* copies, const char* pszOffset,
                                                              const char* dir1, const char* dir2, const char* dir3);
     bool GenerateOverloadedConfig(IPropertyTree* pRoxie, IPropertyTreePtrArray& computers, const char* copies,

+ 4 - 4
deployment/deployutils/deployutils.cpp

@@ -506,7 +506,7 @@ public:
         addItem(jsStrBuf, m_pEnv.get(), XML_TAG_ROXIE_SERVER, TAG_PROCESS, "", 0, 1, "", 0);
         addItem(jsStrBuf, m_pEnv.get(), XML_TAG_ROXIE_FARM, TAG_NAME, "", 0, 1, "", 0);
         addItem(jsStrBuf, m_pEnv.get(), XML_TAG_ROXIE_FARM, TAG_PROCESS, "", 0, 1, "", 0);
-        addItem(jsStrBuf, m_pEnv.get(), XML_TAG_ROXIE_FARM, TAG_DATADIRECTORY, "", 0, 1, "", 0);
+        addItem(jsStrBuf, m_pEnv.get(), XML_TAG_ROXIE_FARM, TAG_LEVEL, "", 0, 1, "", 0);
         addItem(jsStrBuf, m_pEnv.get(), XML_TAG_ROXIE_FARM, TAG_LISTENQUEUE, "", 0, 1, "", 1);
         addItem(jsStrBuf, m_pEnv.get(), XML_TAG_ROXIE_FARM, TAG_NUMTHREADS, "", 0, 1, "", 1);
         addItem(jsStrBuf, m_pEnv.get(), XML_TAG_ROXIE_FARM, TAG_PORT, "", 0, 1, "", 1);
@@ -520,7 +520,7 @@ public:
         addItem(jsStrBuf, m_pEnv.get(), XML_TAG_ROXIE_CHANNEL, TAG_NAME, "", 0, 1, "", 0);
         addItem(jsStrBuf, m_pEnv.get(), XML_TAG_ROXIE_CHANNEL, TAG_ITEMTYPE, "", 0, 1, "", 0);
         addItem(jsStrBuf, m_pEnv.get(), XML_TAG_ROXIE_CHANNEL, TAG_COMPUTER, "", 0, 1, "", 0);
-        addItem(jsStrBuf, m_pEnv.get(), XML_TAG_ROXIE_CHANNEL, TAG_DATADIRECTORY, "", 0, 1, "", 0);
+        addItem(jsStrBuf, m_pEnv.get(), XML_TAG_ROXIE_CHANNEL, TAG_LEVEL, "", 0, 1, "", 0);
         addItem(jsStrBuf, m_pEnv.get(), XML_TAG_ROXIE_CHANNEL, TAG_NUMBER, "", 0, 1, "", 0);
       }
 
@@ -536,7 +536,7 @@ public:
           m_colIndex.appendf("colIndex['process%s']=%d;", serverStr, index++);
           m_colIndex.appendf("colIndex['netAddress%s']=%d;", serverStr, index++);
           m_colIndex.appendf("colIndex['port%s']=%d;", serverStr, index++);
-          m_colIndex.appendf("colIndex['dataDirectory%s']=%d;", serverStr, index++);
+          m_colIndex.appendf("colIndex['level%s']=%d;", serverStr, index++);
           m_colIndex.appendf("colIndex['listenQueue%s']=%d;", serverStr, index++);
           m_colIndex.appendf("colIndex['numThreads%s']=%d;", serverStr, index++);
           m_colIndex.appendf("colIndex['requestArrayThreads%s']=%d;", serverStr, index++);
@@ -547,7 +547,7 @@ public:
           m_colIndex.appendf("colIndex['name%s']=%d;", agentStr, index++); 
           m_colIndex.appendf("colIndex['itemType%s']=%d;", agentStr, index++);
           m_colIndex.appendf("colIndex['netAddress%s']=%d;", agentStr, index++);
-          m_colIndex.appendf("colIndex['dataDirectory%s']=%d;", agentStr, index++);
+          m_colIndex.appendf("colIndex['level%s']=%d;", agentStr, index++);
           m_colIndex.appendf("colIndex['number%s']=%d;", agentStr, index++);
         }
         else if (!strcmp(m_compName.str(), XML_TAG_THORCLUSTER))

+ 8 - 8
esp/files/scripts/configmgr/configmgr.js

@@ -708,9 +708,9 @@ function initItemForRoxieSlaves(item) {
   item.netAddress = "";
   item.netAddress_extra = "";
   item.netAddress_ctrlType = 0;
-  item.dataDirectory = "";
-  item.dataDirectory_extra = "";
-  item.dataDirectory_ctrlType = 0;
+  item.level = "";
+  item.level_extra = "";
+  item.level_ctrlType = 0;
   item.itemType = "";
   item.itemType_extra = "";
   item.itemType_ctrlType = 0;
@@ -745,9 +745,9 @@ function initItemForRoxieServers(item) {
   item.port = "";
   item.port_extra = "";
   item.port_ctrlType = 0;
-  item.dataDirectory = "";
-  item.dataDirectory_extra = "";
-  item.dataDirectory_ctrlType = 0;
+  item.level = "";
+  item.level_extra = "";
+  item.level_ctrlType = 0;
   item.listenQueue = "";
   item.listenQueue_extra = "";
   item.listenQueue_ctrlType = 0;
@@ -877,13 +877,13 @@ function handleConfigCellClickEvent(oArgs, caller, isComplex) {
       }
     }
 
-    if (bldSet === "roxie" && attrName === "dataDirectory") {
+    if (bldSet === "roxie" && attrName === "level") {
       if (newValue === '') {
         alert('Roxie data directory cannot be empty');
         return;
       }
 
-      if (!confirm("The primary data directory for other farms and agents will be changed to the same value. Do you want to continue?")) {
+      if (!confirm("The level for other farms and agents will be changed to the same value. Do you want to continue?")) {
         for (i = 1; i < 7; i++)
           if (caller.editors[i].isActive)
           caller.editors[i].cancel();

+ 1 - 88
esp/services/WsDeploy/WsDeployService.cpp

@@ -1467,93 +1467,6 @@ bool CWsDeployFileInfo::saveSetting(IEspContext &context, IEspSaveSettingRequest
           }
         }
 
-        //if dataDirectory for a roxie farm is being changed, also change baseDataDir for roxie
-        if(!strcmp(pszCompType, "Directories") && !strcmp(pszSubType, "Category"))
-        {
-          StringBuffer sbNewValue;
-          bool bdata = strstr(pszSubTypeKey, "[@name='data']") || strstr(pszSubTypeKey, "[@name=\"data\"]");\
-          bool bdata2 = strstr(pszSubTypeKey, "[@name='data2']") || strstr(pszSubTypeKey, "[@name=\"data2\"]");
-          bool bdata3 = strstr(pszSubTypeKey, "[@name='data3']") || strstr(pszSubTypeKey, "[@name=\"data3\"]");
-
-          if (bdata || bdata2 || bdata3)
-          {
-            Owned<IPropertyTreeIterator> iterRoxies = pEnvSoftware->getElements("RoxieCluster");
-            ForEach (*iterRoxies)
-            {
-              IPropertyTree* pRoxie = &iterRoxies->query();
-
-              if (bdata)
-              {
-                getCommonDir(pEnvRoot, "data", "roxie", pRoxie->queryProp(XML_ATTR_NAME), sbNewValue.clear());
-                pRoxie->setProp("@baseDataDir", sbNewValue.str());
-
-                //change all farms
-                Owned<IPropertyTreeIterator> iterFarms = pRoxie->getElements(XML_TAG_ROXIE_FARM);
-                ForEach (*iterFarms)
-                {
-                  IPropertyTree* pTmpComp = &iterFarms->query();
-                  if (strcmp(pTmpComp->queryProp(XML_ATTR_DATADIRECTORY), sbNewValue.str()))
-                    pTmpComp->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str());
-                }
-
-                //change all legacy Roxie servers
-                Owned<IPropertyTreeIterator> iterRoxieServers = pRoxie->getElements(XML_TAG_ROXIE_SERVER);
-
-                ForEach (*iterRoxieServers)
-                {
-                  IPropertyTree* pTmpComp = &iterRoxieServers->query();
-                  if (strcmp(pTmpComp->queryProp(XML_ATTR_DATADIRECTORY), sbNewValue.str()))
-                    pTmpComp->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str());
-                }
-
-                //also change roxie slave primary data directory for all RoxieSlave and RoxieSlaveProcess
-                Owned<IPropertyTreeIterator> iterSlvs = pRoxie->getElements(XML_TAG_ROXIE_ONLY_SLAVE);
-
-                ForEach (*iterSlvs)
-                {
-                  IPropertyTree* pTmpComp = &iterSlvs->query();
-                  const char* pRoxieComputer = pTmpComp->queryProp(XML_ATTR_COMPUTER);
-                  IPropertyTree* pChannel = pTmpComp->queryPropTree(XML_TAG_ROXIE_CHANNEL"[1]");
-                  if (pChannel)
-                  {
-                    pChannel->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str());
-                    const char* number = pChannel->queryProp("@number");
-                    xpath.clear().appendf(XML_TAG_ROXIE_SLAVE"[@channel='%s'][@computer='%s']", number, pRoxieComputer);
-                    
-                    IPropertyTree* pSlvProc = pRoxie->queryPropTree(xpath.str());
-                    if (pSlvProc)
-                      pSlvProc->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str());
-                  }
-                }
-              }
-              else if (bdata2 || bdata3)
-              {
-                getCommonDir(pEnvRoot, bdata2 ? "data2" : "data3" , "roxie", pRoxie->queryProp(XML_ATTR_NAME), sbNewValue.clear());
-                Owned<IPropertyTreeIterator> iterSlvs = pRoxie->getElements(XML_TAG_ROXIE_ONLY_SLAVE);
-                StringBuffer sb(XML_TAG_ROXIE_CHANNEL);
-                sb.appendf("%s", bdata2?"[2]":"[3]");
-
-                ForEach (*iterSlvs)
-                {
-                  IPropertyTree* pTmpComp = &iterSlvs->query();
-                  const char* pRoxieComputer = pTmpComp->queryProp(XML_ATTR_COMPUTER);
-                  IPropertyTree* pChannel = pTmpComp->queryPropTree(sb.str());
-                  if (pChannel)
-                  {
-                    pChannel->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str());
-                    const char* number = pChannel->queryProp("@number");
-                    xpath.clear().appendf(XML_TAG_ROXIE_SLAVE"[@channel='%s'][@computer='%s']", number, pRoxieComputer);
-                    
-                    IPropertyTree* pSlvProc = pRoxie->queryPropTree(xpath.str());
-                    if (pSlvProc)
-                      pSlvProc->setProp(XML_ATTR_DATADIRECTORY, sbNewValue.str());
-                  }
-                }
-              }
-            }
-          }
-        }
-
         //if we are changing the eclServer field of wsattributes, set the following 
         //extra params from that eclserver. dbPassword, dbUser, mySQL, repository
         if (!strcmp(pszCompType, "WsAttributes") && !strcmp(pszAttrName, "eclServer"))
@@ -3735,7 +3648,7 @@ bool CWsDeployFileInfo::getDeployableComps(IEspContext &context, IEspGetDeployab
                 if (*nodeName != 'R')// || //neither RoxieServerProcess nor RoxieSlaveProcess
                 {
                   IPropertyTree* pInstanceNode = pCompNode->addPropTree(XML_TAG_INSTANCES, createPTree());
-                  const char* directory = pNode->queryProp(*nodeName == 'R' ? XML_ATTR_DATADIRECTORY : XML_ATTR_DIRECTORY);
+                  const char* directory = pNode->queryProp(*nodeName == 'R' ? XML_ATTR_LEVEL : XML_ATTR_DIRECTORY);
                   if (directory && *directory)
                     pInstanceNode->addProp(XML_ATTR_BUILD, directory);