PageRenderTime 69ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/src/python/WMCore/Storage/StageInMgr.py

https://github.com/PerilousApricot/WMCore
Python | 291 lines | 227 code | 24 blank | 40 comment | 21 complexity | c17652904fbc8dd9ea5fe43dec3783ae MD5 | raw file
  1. #!/usr/bin/env python
  2. """
  3. _StageInMgr_
  4. Util class to provide stage in functionality as an interface object.
  5. Based on StageOutMgr class
  6. """
  7. import os
  8. from WMCore.Storage.SiteLocalConfig import loadSiteLocalConfig
  9. #do we want seperate exceptions - for the moment no
  10. from WMCore.Storage.StageOutError import StageOutFailure
  11. from WMCore.Storage.StageOutError import StageOutInitError
  12. from WMCore.Storage.Registry import retrieveStageOutImpl
  13. class StageInSuccess(Exception):
  14. """
  15. _StageOutSuccess_
  16. Exception used to escape stage out loop when stage out is successful
  17. """
  18. pass
  19. class StageInMgr:
  20. """
  21. _StageInMgr_
  22. Object that can be used to stage out a set of files
  23. using TFC or an override.
  24. """
  25. def __init__(self, **overrideParams):
  26. self.override = False
  27. self.overrideConf = overrideParams
  28. if overrideParams != {}:
  29. self.override = True
  30. self.fallbacks = []
  31. # //
  32. # // Try an get the TFC for the site
  33. #//
  34. self.tfc = None
  35. self.numberOfRetries = 3
  36. self.retryPauseTime = 600
  37. # //
  38. # // If override isnt None, we dont need SiteCfg, if it is
  39. #// then we need siteCfg otherwise we are dead.
  40. if self.override == False:
  41. self.siteCfg = loadSiteLocalConfig()
  42. if self.override:
  43. self.initialiseOverride()
  44. else:
  45. self.initialiseSiteConf()
  46. def initialiseSiteConf(self):
  47. """
  48. _initialiseSiteConf_
  49. Extract required information from site conf and TFC
  50. """
  51. implName = self.siteCfg.localStageOut.get("command", None)
  52. if implName == None:
  53. msg = "Unable to retrieve local stage out command\n"
  54. msg += "From site config file.\n"
  55. msg += "Unable to perform StageOut operation"
  56. raise StageOutInitError( msg)
  57. msg = "Local Stage Out Implementation to be used is:"
  58. msg += "%s\n" % implName
  59. seName = self.siteCfg.localStageOut.get("se-name", None)
  60. if seName == None:
  61. msg = "Unable to retrieve local stage out se-name\n"
  62. msg += "From site config file.\n"
  63. msg += "Unable to perform StageOut operation"
  64. raise StageOutInitError( msg)
  65. msg += "Local Stage Out SE Name to be used is %s\n" % seName
  66. catalog = self.siteCfg.localStageOut.get("catalog", None)
  67. if catalog == None:
  68. msg = "Unable to retrieve local stage out catalog\n"
  69. msg += "From site config file.\n"
  70. msg += "Unable to perform StageOut operation"
  71. raise StageOutInitError( msg)
  72. msg += "Local Stage Out Catalog to be used is %s\n" % catalog
  73. try:
  74. self.tfc = self.siteCfg.trivialFileCatalog()
  75. msg += "Trivial File Catalog has been loaded:\n"
  76. msg += str(self.tfc)
  77. except StandardError, ex:
  78. msg = "Unable to load Trivial File Catalog:\n"
  79. msg += "Local stage out will not be attempted\n"
  80. msg += str(ex)
  81. raise StageOutInitError( msg )
  82. print msg
  83. return
  84. def initialiseOverride(self):
  85. """
  86. _initialiseOverride_
  87. Extract and verify that the Override parameters are all present
  88. """
  89. overrideConf = self.overrideConf
  90. overrideParams = {
  91. "command" : None,
  92. "option" : None,
  93. "se-name" : None,
  94. "lfn-prefix" : None,
  95. }
  96. try:
  97. overrideParams['command'] = overrideConf['command']
  98. overrideParams['se-name'] = overrideConf['se-name']
  99. overrideParams['lfn-prefix'] = overrideConf['lfn-prefix']
  100. except StandardError, ex:
  101. msg = "Unable to extract Override parameters from config:\n"
  102. msg += str(overrideConf)
  103. raise StageOutInitError(msg)
  104. if overrideConf.has_key('option'):
  105. if len(overrideConf['option']) > 0:
  106. overrideParams['option'] = overrideConf['option']
  107. else:
  108. overrideParams['option'] = ""
  109. msg = "=======StageIn Override Initialised:================\n"
  110. for key, val in overrideParams.items():
  111. msg += " %s : %s\n" % (key, val)
  112. msg += "=====================================================\n"
  113. print msg
  114. self.fallbacks = []
  115. self.fallbacks.append(overrideParams)
  116. return
  117. def __call__(self, **fileToStage):
  118. """
  119. _operator()_
  120. Use call to invoke transfers
  121. """
  122. try:
  123. print "==>Working on file: %s" % fileToStage['LFN']
  124. lfn = fileToStage['LFN']
  125. # //
  126. # // No override => use local-stage-out from site conf
  127. #// invoke for all files and check failures/successes
  128. if not self.override:
  129. print "===> Attempting Local Stage In."
  130. try:
  131. pfn = self.localStageIn(lfn)
  132. fileToStage['PFN'] = pfn
  133. raise StageInSuccess
  134. except StageOutFailure, ex:
  135. msg = "===> Local Stage Out Failure for file:\n"
  136. msg += "======> %s\n" % fileToStage['LFN']
  137. msg += str(ex)
  138. # //
  139. # // Still here => override start using the fallback stage outs
  140. #// If override is set, then that will be the only fallback available
  141. print "===> Attempting %s Override Stage Outs" % len(self.fallbacks)
  142. for fallback in self.fallbacks:
  143. try:
  144. pfn = self.localStageIn(lfn, fallback)
  145. fileToStage['PFN'] = pfn
  146. raise StageInSuccess
  147. except StageOutFailure, ex:
  148. continue
  149. except StageInSuccess:
  150. msg = "===> Stage In Successful:\n"
  151. msg += "====> LFN: %s\n" % fileToStage['LFN']
  152. msg += "====> PFN: %s\n" % fileToStage['PFN']
  153. print msg
  154. return fileToStage
  155. msg = "Unable to stage out file:\n"
  156. msg += fileToStage['LFN']
  157. raise StageOutFailure(msg, **fileToStage)
  158. def localStageIn(self, lfn, override = None):
  159. """
  160. _localStageOut_
  161. Given the lfn and local stage out params, invoke the local stage in
  162. i.e. stage in lfn to pfn
  163. if override is used the follwoing params should be defined:
  164. command - the stage out impl plugin name to be used
  165. option - the option values to be passed to that command (None is allowed)
  166. lfn-prefix - the LFN prefix to generate the PFN
  167. se-name - the Name of the SE to which the file is being xferred
  168. """
  169. localPfn = os.path.join(os.getcwd(), os.path.basename(lfn))
  170. if override:
  171. seName = override['se-name']
  172. command = override['command']
  173. options = override['option']
  174. pfn = "%s%s" % (override['lfn-prefix'], lfn)
  175. protocol = command
  176. else:
  177. seName = self.siteCfg.localStageOut['se-name']
  178. command = self.siteCfg.localStageOut['command']
  179. options = self.siteCfg.localStageOut.get('option', None)
  180. pfn = self.searchTFC(lfn)
  181. protocol = self.tfc.preferredProtocol
  182. if pfn == None:
  183. msg = "Unable to match lfn to pfn: \n %s" % lfn
  184. raise StageOutFailure(msg, LFN = lfn, TFC = str(self.tfc))
  185. try:
  186. impl = retrieveStageOutImpl(command, stagein=True)
  187. except Exception, ex:
  188. msg = "Unable to retrieve impl for local stage in:\n"
  189. msg += "Error retrieving StageOutImpl for command named: %s\n" % (
  190. command,)
  191. raise StageOutFailure(msg, Command = command,
  192. LFN = lfn, ExceptionDetail = str(ex))
  193. impl.numRetries = self.numberOfRetries
  194. impl.retryPause = self.retryPauseTime
  195. try:
  196. impl(protocol, pfn, localPfn, options)
  197. except Exception, ex:
  198. msg = "Failure for local stage in:\n"
  199. msg += str(ex)
  200. raise StageOutFailure(msg, Command = command, Protocol = protocol,
  201. LFN = lfn, InputPFN = localPfn,
  202. TargetPFN = pfn)
  203. return localPfn
  204. def searchTFC(self, lfn):
  205. """
  206. _searchTFC_
  207. Search the Trivial File Catalog for the lfn provided,
  208. if a match is made, return the matched PFN
  209. """
  210. if self.tfc == None:
  211. msg = "Trivial File Catalog not available to match LFN:\n"
  212. msg += lfn
  213. print msg
  214. return None
  215. if self.tfc.preferredProtocol == None:
  216. msg = "Trivial File Catalog does not have a preferred protocol\n"
  217. msg += "which prevents local stage out for:\n"
  218. msg += lfn
  219. print msg
  220. return None
  221. pfn = self.tfc.matchLFN(self.tfc.preferredProtocol, lfn)
  222. if pfn == None:
  223. msg = "Unable to map LFN to PFN:\n"
  224. msg += "LFN: %s\n" % lfn
  225. return None
  226. msg = "LFN to PFN match made:\n"
  227. msg += "LFN: %s\nPFN: %s\n" % (lfn, pfn)
  228. print msg
  229. return pfn