mirror_provider.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #!/usr/bin/env python2
  2. # -*- coding:utf-8 -*-
  3. import sh
  4. import os
  5. from datetime import datetime
  6. class MirrorProvider(object):
  7. '''
  8. Mirror method class, can be `rsync', `debmirror', etc.
  9. '''
  10. def __init__(self, name, local_dir, log_file="/dev/null",
  11. interval=120, hooks=[]):
  12. self.name = name
  13. self.local_dir = local_dir
  14. self.log_file = log_file
  15. self.interval = interval
  16. self.hooks = hooks
  17. self.p = None
  18. def ensure_log_dir(self):
  19. log_dir = os.path.dirname(self.log_file)
  20. if not os.path.exists(log_dir):
  21. sh.mkdir("-p", log_dir)
  22. def run(self):
  23. raise NotImplementedError("run method should be implemented")
  24. def terminate(self):
  25. if self.p is not None:
  26. self.p.process.terminate()
  27. print("{} terminated".format(self.name))
  28. self.p = None
  29. def wait(self):
  30. if self.p is not None:
  31. self.p.wait()
  32. self.p = None
  33. class RsyncProvider(MirrorProvider):
  34. _default_options = "-av --delete-after"
  35. def __init__(self, name, upstream_url, local_dir, useIPv6=True,
  36. exclude_file=None, log_file="/dev/null", interval=120,
  37. hooks=[]):
  38. super(RsyncProvider, self).__init__(name, local_dir, log_file,
  39. interval, hooks)
  40. self.upstream_url = upstream_url
  41. self.useIPv6 = useIPv6
  42. self.exclude_file = exclude_file
  43. @property
  44. def options(self):
  45. _options = self._default_options.split()
  46. if self.useIPv6:
  47. _options.append("-6")
  48. else:
  49. _options.append("-4")
  50. if self.exclude_file:
  51. _options.append("--exclude-from")
  52. _options.append(self.exclude_file)
  53. return _options
  54. def run(self):
  55. self.ensure_log_dir()
  56. _args = self.options
  57. _args.append(self.upstream_url)
  58. _args.append(self.local_dir)
  59. now = datetime.now().strftime("%Y-%m-%d_%H")
  60. log_file = self.log_file.format(date=now)
  61. self.p = sh.rsync(*_args, _out=log_file, _err=log_file,
  62. _out_bufsize=1, _bg=True)
  63. class ShellProvider(MirrorProvider):
  64. def __init__(self, name, command, local_dir,
  65. log_file="/dev/null", interval=120, hooks=[]):
  66. super(ShellProvider, self).__init__(name, local_dir, log_file,
  67. interval, hooks)
  68. self.command = command.split()
  69. def run(self):
  70. self.ensure_log_dir()
  71. now = datetime.now().strftime("%Y-%m-%d_%H")
  72. log_file = self.log_file.format(date=now)
  73. new_env = os.environ.copy()
  74. new_env["TUNASYNC_MIRROR_NAME"] = self.name
  75. new_env["TUNASYNC_LOCAL_DIR"] = self.local_dir
  76. new_env["TUNASYNC_LOG_FILE"] = log_file
  77. _cmd = self.command[0]
  78. _args = [] if len(self.command) == 1 else self.command[1:]
  79. cmd = sh.Command(_cmd)
  80. self.p = cmd(*_args, _env=new_env, _out=log_file,
  81. _err=log_file, _out_bufsize=1, _bg=True)
  82. # vim: ts=4 sw=4 sts=4 expandtab