mirror_config.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #!/usr/bin/env python2
  2. # -*- coding:utf-8 -*-
  3. import os
  4. from datetime import datetime
  5. from .mirror_provider import RsyncProvider, TwoStageRsyncProvider, ShellProvider
  6. from .btrfs_snapshot import BtrfsHook
  7. from .loglimit import LogLimitHook
  8. from .exec_pre_post import CmdExecHook
  9. class MirrorConfig(object):
  10. _valid_providers = set(("rsync", "two-stage-rsync", "shell", ))
  11. def __init__(self, parent, options):
  12. self._parent = parent
  13. self._popt = self._parent._settings
  14. self.options = dict(options.items()) # copy
  15. self._validate()
  16. def _validate(self):
  17. provider = self.options.get("provider", None)
  18. assert provider in self._valid_providers
  19. if provider == "rsync":
  20. assert "upstream" in self.options
  21. elif provider == "shell":
  22. assert "command" in self.options
  23. local_dir_tmpl = self.options.get(
  24. "local_dir", self._popt["global"]["local_dir"])
  25. self.options["local_dir"] = local_dir_tmpl.format(
  26. mirror_root=self._popt["global"]["mirror_root"],
  27. mirror_name=self.name,
  28. )
  29. if "interval" not in self.options:
  30. self.options["interval"] = self._popt["global"]["interval"]
  31. assert isinstance(self.options["interval"], int)
  32. log_dir = self.options.get(
  33. "log_dir", self._popt["global"]["log_dir"])
  34. if "log_file" not in self.options:
  35. self.options["log_file"] = os.path.join(
  36. log_dir, self.name, self.name + "_{date}.log")
  37. self.log_dir = os.path.dirname(self.log_file)
  38. if "use_btrfs" not in self.options:
  39. self.options["use_btrfs"] = self._parent.use_btrfs
  40. assert self.options["use_btrfs"] in (True, False)
  41. def __getattr__(self, key):
  42. if key in self.__dict__:
  43. return self.__dict__[key]
  44. else:
  45. return self.__dict__["options"].get(key, None)
  46. def to_provider(self, hooks=[], no_delay=False):
  47. kwargs = {
  48. 'name': self.name,
  49. 'upstream_url': self.upstream,
  50. 'local_dir': self.local_dir,
  51. 'log_dir': self.log_dir,
  52. 'log_file': self.log_file,
  53. 'interval': self.interval,
  54. 'hooks': hooks,
  55. }
  56. if self.provider == "rsync":
  57. kwargs.update({
  58. 'useIPv6': self.use_ipv6,
  59. 'password': self.password,
  60. 'exclude_file': self.exclude_file,
  61. })
  62. provider = RsyncProvider(**kwargs)
  63. elif self.provider == "two-stage-rsync":
  64. kwargs.update({
  65. 'useIPv6': self.use_ipv6,
  66. 'password': self.password,
  67. 'exclude_file': self.exclude_file,
  68. })
  69. provider = TwoStageRsyncProvider(**kwargs)
  70. provider.set_stage1_profile(self.stage1_profile)
  71. elif self.options["provider"] == "shell":
  72. kwargs.update({
  73. 'command': self.command,
  74. 'log_stdout': self.options.get("log_stdout", True),
  75. })
  76. provider = ShellProvider(**kwargs)
  77. if not no_delay:
  78. sm = self._parent.status_manager
  79. last_update = sm.get_info(self.name, 'last_update')
  80. if last_update not in (None, '-'):
  81. last_update = datetime.strptime(
  82. last_update, '%Y-%m-%d %H:%M:%S')
  83. delay = int(last_update.strftime("%s")) \
  84. + self.interval * 60 - int(datetime.now().strftime("%s"))
  85. if delay < 0:
  86. delay = 0
  87. provider.set_delay(delay)
  88. return provider
  89. def compare(self, other):
  90. assert self.name == other.name
  91. for key, val in self.options.iteritems():
  92. if other.options.get(key, None) != val:
  93. return False
  94. return True
  95. def hooks(self):
  96. hooks = []
  97. parent = self._parent
  98. if self.options["use_btrfs"]:
  99. working_dir = parent.btrfs_working_dir_tmpl.format(
  100. mirror_root=parent.mirror_root,
  101. mirror_name=self.name
  102. )
  103. service_dir = parent.btrfs_service_dir_tmpl.format(
  104. mirror_root=parent.mirror_root,
  105. mirror_name=self.name
  106. )
  107. gc_dir = parent.btrfs_gc_dir_tmpl.format(
  108. mirror_root=parent.mirror_root,
  109. mirror_name=self.name
  110. )
  111. hooks.append(BtrfsHook(service_dir, working_dir, gc_dir))
  112. hooks.append(LogLimitHook())
  113. if self.exec_pre_sync:
  114. hooks.append(
  115. CmdExecHook(self.exec_pre_sync, CmdExecHook.PRE_SYNC))
  116. if self.exec_post_sync:
  117. hooks.append(
  118. CmdExecHook(self.exec_post_sync, CmdExecHook.POST_SYNC))
  119. return hooks
  120. # vim: ts=4 sw=4 sts=4 expandtab