Unfinished backend code for centralized agent packages deployment
authorVictor Kirhenshtein <victor@netxms.org>
Sat, 5 Feb 2005 23:19:14 +0000 (23:19 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Sat, 5 Feb 2005 23:19:14 +0000 (23:19 +0000)
include/nms_cscp.h
src/server/core/netobj.cpp
src/server/core/package.cpp
src/server/core/session.cpp
src/server/include/nms_core.h
src/server/include/nms_objects.h
src/server/include/nms_pkg.h

index 7635fd8..50d61a0 100644 (file)
@@ -426,6 +426,8 @@ typedef struct
 #define VID_POLLER_NODE_ID          ((DWORD)135)
 #define VID_SERVICE_STATUS          ((DWORD)136)
 #define VID_NUM_PARAMETERS          ((DWORD)137)
+#define VID_NUM_OBJECTS             ((DWORD)138)
+#define VID_OBJECT_LIST             ((DWORD)139)
 
 // Variable ranges for object's ACL
 #define VID_ACL_USER_BASE           ((DWORD)0x00001000)
index ff65d63..393c774 100644 (file)
@@ -689,3 +689,34 @@ void NetObj::SendPollerMsg(DWORD dwRqId, TCHAR *pszFormat, ...)
       m_pPollRequestor->SendPollerMsg(dwRqId, szBuffer);
    }
 }
+
+
+//
+// Add child node objects (direct and indirect childs) to list
+//
+
+void NetObj::AddChildNodesToList(DWORD *pdwNumNodes, Node ***pppNodeList, DWORD dwUserId)
+{
+   DWORD i;
+
+   Lock();
+
+   // Walk through our own child list
+   for(i = 0; i < m_dwChildCount; i++)
+   {
+      if (m_pChildList[i]->Type() == OBJECT_NODE)
+      {
+         m_pChildList[i]->IncRefCount();
+         *pppNodeList = (Node **)realloc(*pppNodeList, sizeof(Node *) * (*pdwNumNodes + 1));
+         (*pppNodeList)[*pdwNumNodes] = (Node *)m_pChildList[i];
+         (*pdwNumNodes)++;
+      }
+      else
+      {
+         if (m_pChildList[i]->CheckAccessRights(dwUserId, OBJECT_ACCESS_READ))
+            m_pChildList[i]->AddChildNodesToList(pdwNumNodes, pppNodeList, dwUserId);
+      }
+   }
+
+   Unlock();
+}
index 4c101a5..57a626b 100644 (file)
@@ -53,6 +53,27 @@ BOOL IsPackageInstalled(TCHAR *pszName, TCHAR *pszVersion, TCHAR *pszPlatform)
 }
 
 
+//
+// Check if given package ID is valid
+//
+
+BOOL IsValidPackageId(DWORD dwPkgId)
+{
+   DB_RESULT hResult;
+   TCHAR szQuery[256];
+   BOOL bResult = FALSE;
+
+   _sntprintf(szQuery, 256, _T("SELECT pkg_name FROM agent_pkg WHERE pkg_id=%ld"), dwPkgId);
+   hResult = DBSelect(g_hCoreDB, szQuery);
+   if (hResult != NULL)
+   {
+      bResult = (DBGetNumRows(hResult) > 0);
+      DBFreeResult(hResult);
+   }
+   return bResult;
+}
+
+
 //
 // Check if package file with given name exist
 //
@@ -114,3 +135,25 @@ DWORD UninstallPackage(DWORD dwPkgId)
    }
    return dwResult;
 }
+
+
+//
+// Package deployment thread
+//
+
+THREAD_RESULT THREAD_CALL DeploymentThread(void *pArg)
+{
+   DT_STARTUP_INFO *pStartup = (DT_STARTUP_INFO *)pArg;
+
+   // Wait for parent initialization completion
+   MutexLock(pStartup->mutex, INFINITE);
+   MutexUnlock(pStartup->mutex);
+
+
+   // Cleanup
+   MutexDestroy(pStartup->mutex);
+   safe_free(pStartup->ppNodeList);
+   free(pStartup);
+
+   return THREAD_OK;
+}
index d11adca..b6e75c6 100644 (file)
@@ -722,6 +722,9 @@ void ClientSession::ProcessingThread(void)
          case CMD_GET_PARAMETER_LIST:
             SendParametersList(pMsg);
             break;
+         case CMD_DEPLOY_PACKAGE:
+            DeployPackage(pMsg);
+            break;
          default:
             // Pass message to loaded modules
             for(i = 0; i < g_dwNumModules; i++)
@@ -3899,3 +3902,113 @@ void ClientSession::SendParametersList(CSCPMessage *pRequest)
    // Send responce
    SendMessage(&msg);
 }
+
+
+//
+// Deplay package to node(s)
+//
+
+void ClientSession::DeployPackage(CSCPMessage *pRequest)
+{
+   CSCPMessage msg;
+   DWORD i, dwNumObjects, *pdwObjectList, dwNumNodes, dwPkgId;
+   Node **ppNodeList;
+   NetObj *pObject;
+   BOOL bSuccess = TRUE;
+   MUTEX hMutex;
+
+   // Prepare responce message
+   msg.SetCode(CMD_REQUEST_COMPLETED);
+   msg.SetId(pRequest->GetId());
+
+   if (m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_PACKAGES)
+   {
+      dwNumNodes = 0;
+      ppNodeList = NULL;
+
+      // Get package ID
+      dwPkgId = pRequest->GetVariableLong(VID_PACKAGE_ID);
+      if (IsValidPackageId(dwPkgId))
+      {
+         // Create list of nodes to be upgraded
+         dwNumObjects = pRequest->GetVariableLong(VID_NUM_OBJECTS);
+         pdwObjectList = (DWORD *)malloc(sizeof(DWORD) * dwNumObjects);
+         pRequest->GetVariableInt32Array(VID_OBJECT_LIST, dwNumObjects, pdwObjectList);
+         for(i = 0; i < dwNumObjects; i++)
+         {
+            pObject = FindObjectById(pdwObjectList[i]);
+            if (pObject != NULL)
+            {
+               if (pObject->CheckAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
+               {
+                  if (pObject->Type() == OBJECT_NODE)
+                  {
+                     pObject->IncRefCount();
+                     ppNodeList = (Node **)realloc(ppNodeList, sizeof(Node *) * (dwNumNodes + 1));
+                     ppNodeList[dwNumNodes] = (Node *)pObject;
+                     dwNumNodes++;
+                  }
+                  else
+                  {
+                     pObject->AddChildNodesToList(&dwNumNodes, &ppNodeList, m_dwUserId);
+                  }
+               }
+               else
+               {
+                  msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
+                  bSuccess = FALSE;
+                  break;
+               }
+            }
+            else
+            {
+               msg.SetVariable(VID_RCC, RCC_INVALID_OBJECT_ID);
+               bSuccess = FALSE;
+               break;
+            }
+         }
+         safe_free(pdwObjectList);
+      }
+      else
+      {
+         msg.SetVariable(VID_RCC, RCC_INVALID_PACKAGE_ID);
+         bSuccess = FALSE;
+      }
+
+      // On success, start upgrade thread
+      if (bSuccess)
+      {
+         DT_STARTUP_INFO *pInfo;
+
+         hMutex = MutexCreate();
+         MutexLock(hMutex, INFINITE);
+
+         pInfo = (DT_STARTUP_INFO *)malloc(sizeof(DT_STARTUP_INFO));
+         pInfo->dwNumNodes = dwNumNodes;
+         pInfo->ppNodeList = ppNodeList;
+         pInfo->pSession = this;
+         pInfo->mutex = hMutex;
+
+         ThreadCreate(DeploymentThread, 0, pInfo);
+         msg.SetVariable(VID_RCC, RCC_SUCCESS);
+      }
+      else
+      {
+         for(i = 0; i < dwNumNodes; i++)
+            ppNodeList[i]->DecRefCount();
+         safe_free(ppNodeList);
+      }
+   }
+   else
+   {
+      msg.SetVariable(VID_RCC, RCC_ACCESS_DENIED);
+      bSuccess = FALSE;
+   }
+
+   // Send responce
+   SendMessage(&msg);
+
+   // Allow deployment thread to run
+   if (bSuccess)
+      MutexUnlock(hMutex);
+}
index b5a50b3..9b6751b 100644 (file)
@@ -334,6 +334,7 @@ private:
    void SendAllPackages(DWORD dwRqId);
    void InstallPackage(CSCPMessage *pRequest);
    void RemovePackage(CSCPMessage *pRequest);
+   void DeployPackage(CSCPMessage *pRequest);
    void SendParametersList(CSCPMessage *pRequest);
 
 public:
index cd45575..5e7faed 100644 (file)
@@ -83,6 +83,8 @@ extern DWORD g_dwConfigurationPollingInterval;
 // Base class for network objects
 //
 
+class NXCORE_EXPORTABLE Node;
+
 class NXCORE_EXPORTABLE NetObj
 {
 protected:
@@ -168,6 +170,8 @@ public:
    BOOL CheckAccessRights(DWORD dwUserId, DWORD dwRequiredRights);
    void DropUserAccess(DWORD dwUserId);
 
+   void AddChildNodesToList(DWORD *pdwNumNodes, Node ***pppNodeList, DWORD dwUserId);
+
    // Debug methods
    const char *ParentList(char *szBuffer);
    const char *ChildList(char *szBuffer);
@@ -259,8 +263,6 @@ public:
 // Interface class
 //
 
-class NXCORE_EXPORTABLE Node;
-
 class NXCORE_EXPORTABLE Interface : public NetObj
 {
 protected:
index 01a9fcc..446837d 100644 (file)
 #ifndef _nms_pkg_h_
 #define _nms_pkg_h_
 
+//
+// Deployment thread startup info
+//
+
+typedef struct
+{
+   MUTEX mutex;    // Synchronization mutex
+   DWORD dwNumNodes;
+   Node **ppNodeList;
+   ClientSession *pSession;
+} DT_STARTUP_INFO;
+
+
 //
 // Package functions
 //
 
 BOOL IsPackageInstalled(TCHAR *pszName, TCHAR *pszVersion, TCHAR *pszPlatform);
 BOOL IsPackageFileExist(TCHAR *pszFileName);
+BOOL IsValidPackageId(DWORD dwPkgId);
 DWORD UninstallPackage(DWORD dwPkgId);
+THREAD_RESULT THREAD_CALL DeploymentThread(void *pArg);
 
 
 #endif   /* _nms_pkg_h_ */