DeployLog.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  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 "deploy.hpp"
  14. #include "jptree.hpp"
  15. #include "jstring.hpp"
  16. #include <time.h>
  17. #include "jfile.hpp"
  18. class CDeployLog : public CInterface, implements IDeployLog
  19. {
  20. public:
  21. IMPLEMENT_IINTERFACE;
  22. //---------------------------------------------------------------------------
  23. // CDeployLog
  24. //---------------------------------------------------------------------------
  25. CDeployLog( IDeploymentCallback& callback, const char* filename, const char* envFilename )
  26. : m_pCallback(&callback),
  27. m_filename(filename)
  28. {
  29. assertex(filename);
  30. m_tree.setown(createPTree("DeployLog"));
  31. m_tree->addProp("@environmentArchive", envFilename);
  32. m_tree->addProp("@startTime", getTimestamp());
  33. }
  34. //---------------------------------------------------------------------------
  35. // ~CDeployLog
  36. //---------------------------------------------------------------------------
  37. virtual ~CDeployLog()
  38. {
  39. m_tree->addProp("@stopTime", getTimestamp());
  40. writeLog();
  41. }
  42. //---------------------------------------------------------------------------
  43. // addTask
  44. //---------------------------------------------------------------------------
  45. IPropertyTree* addTask(IDeployTask& task)
  46. {
  47. // Get or add Component node
  48. IPropertyTree* compNode = addComponent(task.getCompName());
  49. assertex(compNode);
  50. // Get Tasks node
  51. IPropertyTree* tasksNode = compNode->queryPropTree("Tasks");
  52. assertex(tasksNode);
  53. // Add new task
  54. IPropertyTree* node = createPTree("Task");
  55. node->addProp("@action", task.getCaption());
  56. node->addProp("@source", task.getFileSpec(DT_SOURCE));
  57. node->addProp("@target", task.getFileSpec(DT_TARGET));
  58. CDateTime modifiedTime;
  59. Owned<IFile> pTargetFile = createIFile(task.getFileSpec(DT_TARGET));
  60. if (pTargetFile->getTime(NULL, &modifiedTime, NULL))
  61. {
  62. StringBuffer timestamp;
  63. modifiedTime.getString(timestamp);
  64. offset_t filesize = pTargetFile->size();
  65. node->addProp("@date", timestamp.str());
  66. node->addPropInt64("@size", filesize);
  67. }
  68. if (task.getErrorCode())
  69. {
  70. node->addProp("@error", task.getErrorString());
  71. compNode->setProp("@error", "true");
  72. }
  73. return tasksNode->addPropTree("Task", node);
  74. }
  75. //---------------------------------------------------------------------------
  76. // addDirList
  77. //---------------------------------------------------------------------------
  78. IPropertyTree* addDirList(const char* comp, const char* path)
  79. {
  80. // Get or add Component node
  81. IPropertyTree* compNode = addComponent(comp);
  82. assertex(compNode);
  83. // Add new Directory node
  84. assertex(path);
  85. char ppath[_MAX_PATH];
  86. strcpy(ppath, path);
  87. removeTrailingPathSepChar(ppath);
  88. IPropertyTree* node = createPTree("Directory");
  89. node->addProp("@name", ppath);
  90. getDirList(ppath, node);
  91. return compNode->addPropTree("Directory", node);
  92. }
  93. private:
  94. //---------------------------------------------------------------------------
  95. // addComponent
  96. //---------------------------------------------------------------------------
  97. IPropertyTree* addComponent(const char* comp)
  98. {
  99. assertex(comp);
  100. // Add component node if necessary
  101. Owned<IPropertyTreeIterator> iter = m_tree->getElements("./Component");
  102. for (iter->first(); iter->isValid(); iter->next())
  103. {
  104. if (strcmp(comp, iter->query().queryProp("@name"))==0)
  105. return &iter->query();
  106. }
  107. // If node not found, create it and add Tasks subnode
  108. IPropertyTree* compNode = createPTree("Component");
  109. compNode->addProp("@name", comp);
  110. compNode->addPropTree("Tasks", createPTree("Tasks"));
  111. return m_tree->addPropTree("Component", compNode);
  112. }
  113. //---------------------------------------------------------------------------
  114. // getDirList
  115. //---------------------------------------------------------------------------
  116. void getDirList(const char* path, IPropertyTree* parentNode)
  117. {
  118. Owned<IDirectoryIterator> pDirIter = createDirectoryIterator(path, "*");
  119. ForEach(*pDirIter)
  120. {
  121. IFile& iFile = pDirIter->query();
  122. const char* dirEntryName = iFile.queryFilename();
  123. // Process directories, but not the "." and ".." directories
  124. if (iFile.isDirectory() && *dirEntryName != '.')
  125. {
  126. // Create prop tree, add to parent, and recurse
  127. StringBuffer newPath(path);
  128. newPath.append('\\').append(dirEntryName);
  129. IPropertyTree* node = createPTree("Directory");
  130. node->addProp("@name", newPath.str());
  131. getDirList(newPath.str(), parentNode->addPropTree("Directory", node));
  132. }
  133. else
  134. {
  135. // Create prop tree and add to parent
  136. CDateTime modifiedTime;
  137. iFile.getTime(NULL, &modifiedTime, NULL);
  138. StringBuffer timestamp;
  139. modifiedTime.getString(timestamp);
  140. offset_t filesize = iFile.size();
  141. IPropertyTree* node = createPTree("File");
  142. node->addProp("@name", dirEntryName);
  143. node->addProp("@date", timestamp.str());
  144. node->addPropInt64("@size", filesize);
  145. parentNode->addPropTree("File", node);
  146. }
  147. }
  148. }
  149. //---------------------------------------------------------------------------
  150. // getTimestamp
  151. //---------------------------------------------------------------------------
  152. const char* getTimestamp()
  153. {
  154. time_t t = time(NULL);
  155. struct tm* now = localtime(&t);
  156. strftime(m_timestamp, sizeof(m_timestamp), "%Y-%m-%d %H:%M:%S", now);
  157. return m_timestamp;
  158. }
  159. //---------------------------------------------------------------------------
  160. // writeLog
  161. //---------------------------------------------------------------------------
  162. void writeLog()
  163. {
  164. StringBuffer xml;
  165. toXML(m_tree, xml);
  166. Owned<IDeployTask> task = createDeployTask(*m_pCallback, "Create File", NULL, NULL, NULL, NULL,
  167. m_filename, "", "", "", false);
  168. task->createFile(xml.str());
  169. Owned<IFile> pFile = createIFile(m_filename);
  170. pFile->setReadOnly(true);
  171. }
  172. private:
  173. Owned<IDeploymentCallback> m_pCallback;
  174. Owned<IPropertyTree> m_tree;
  175. StringAttr m_filename;
  176. char m_timestamp[40];
  177. };
  178. //---------------------------------------------------------------------------
  179. // Factory functions
  180. //---------------------------------------------------------------------------
  181. IDeployLog* createDeployLog(IDeploymentCallback& callback, const char* filename, const char* envFilename)
  182. {
  183. return new CDeployLog(callback, filename, envFilename);
  184. }