Advertisement
Guest User

Untitled

a guest
Feb 11th, 2016
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.62 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. try:
  4. import rados
  5. import sys
  6. import hashlib
  7. import argparse
  8. import os
  9. import logging
  10. except ImportError:
  11. raise ImportError('unable to import modules')
  12. sys.stderr.write("unable to import modules")
  13. exit(1)
  14.  
  15. logging.basicConfig(level=logging.INFO)
  16. logger = logging.getLogger(__name__)
  17.  
  18.  
  19. def create_argparser():
  20. """
  21. This creates a set of common command-line options that we will use
  22. in our scripts'''
  23. :return: argparse.ArgumentParser() object
  24. """
  25.  
  26. p = argparse.ArgumentParser()
  27.  
  28. p.add_argument('--directory', help='Directory to copy', required=True)
  29. p.add_argument('--ceph-pool',
  30. default=os.environ.get('CEPH_POOL'),
  31. help='Ceph pool to use, defaults to environment variable CEPH_POOL')
  32. p.add_argument('--ceph-id',
  33. default=os.environ.get('CEPH_ID'),
  34. help='Ceph id, defaults to environment variable CEPH_ID, note: the name must start with client.')
  35. p.add_argument('--ceph-conf',
  36. default=os.environ.get('CEPH_CONF'),
  37. help='Ceph configuration file, default to environment variable CEPH_CONF')
  38. p.add_argument('--ceph-keyring',
  39. default=os.environ.get('CEPH_KEYRING'),
  40. help='Ceph keyring file, default to environment variable CEPH_KEYRING')
  41. p.add_argument('--block-size',
  42. default=65536, help='Block size used to copy, defaults to 65536 bytes')
  43.  
  44. return p
  45.  
  46.  
  47. def copy_to_ceph(afile, key, ioctx_handler, blocksize=65536):
  48. """
  49. Copy file to rados and calculate md5 on the fly and put it as xattr attribute
  50. :param afile: path of the file
  51. :param key: the object name for rados
  52. :param ioctx_handler: rados IOctx handler
  53. :param blocksize: blocksize defaults to 65536
  54. :return: True if there where no errors
  55. """
  56.  
  57. try:
  58. f = open(afile, 'r')
  59. buf = f.read(blocksize)
  60. h = hashlib.md5()
  61. offset = 0
  62. while len(buf) > 0:
  63. h.update(buf)
  64. ioctx_handler.write(key, buf, offset)
  65. offset += len(buf)
  66. buf = f.read(blocksize)
  67.  
  68. ioctx_handler.set_xattr(key, "MD5", h.hexdigest())
  69.  
  70. return True
  71.  
  72. except Exception as e:
  73. logger.error('Error opening file %s' % f)
  74. return False
  75.  
  76.  
  77. def get_filepaths(directory):
  78. """
  79. This function will generate the file names in a directory
  80. tree by walking the tree either top-down or bottom-up. For each
  81. directory in the tree rooted at directory top (including top itself),
  82. it yields a 3-tuple (dirpath, dirnames, filenames).
  83. """
  84. file_paths = [] # List which will store all of the full filepaths.
  85.  
  86. # Walk the tree.
  87. for root, directories, files in os.walk(directory):
  88. for filename in files:
  89. # Join the two strings in order to form the full filepath.
  90. filepath = os.path.join(root, filename)
  91. file_paths.append(filepath) # Add it to the list.
  92.  
  93. return file_paths # Self-explanatory.
  94.  
  95.  
  96. def connect_to_ceph(ceph_conf, ceph_id, ceph_pool, ceph_keyring):
  97.  
  98. if not 'client.' in ceph_id:
  99. ceph_id = 'client.%s' % ceph_id
  100.  
  101. cluster = rados.Rados(conffile=ceph_conf, conf=dict(keyring=ceph_keyring), name=ceph_id)
  102.  
  103. try:
  104. cluster.connect()
  105. logger.info("Connect to ceph cluster with id: %s " % cluster.get_fsid())
  106. except Exception as e:
  107. print RuntimeError(e)
  108.  
  109. try:
  110. cluster.pool_exists(ceph_pool)
  111. except Exception as e:
  112. print RuntimeError(e)
  113.  
  114. ioctx = cluster.open_ioctx(ceph_pool)
  115.  
  116. return ioctx
  117.  
  118.  
  119. def parse_args():
  120. """
  121. Parse the arguments
  122. :return: argparse parse_args() object
  123. """
  124. p = create_argparser()
  125. return p.parse_args()
  126.  
  127.  
  128. def start_copy(files, ioctx, block_size):
  129. """
  130. Start the copy to rados
  131. :param files: A dict with all files to be copied
  132. :param ioctx: The rados IOCtx Handler
  133. :param block_size: The block to size for copying.
  134. :return:
  135. """
  136. count = len(files)
  137. count_done = 0
  138. logger.info('Start copying: %s files' % count)
  139. for f in files:
  140. if copy_to_ceph(f, f, ioctx, block_size):
  141. logger.info('Status copying: %s of %s' % (count_done, count))
  142. count_done += 1
  143. else:
  144. logger.error('Error copying file %s' % f)
  145. os.exit(1)
  146.  
  147. logger.info('Finised copying %s' % count)
  148.  
  149.  
  150. def main():
  151. args = parse_args()
  152.  
  153. ioctx = connect_to_ceph(args.ceph_conf, args.ceph_id, args.ceph_pool, args.ceph_keyring)
  154. files = get_filepaths(args.directory)
  155. start_copy(files, ioctx, args.block_size)
  156.  
  157.  
  158. if __name__ == "__main__":
  159. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement