gitmirror.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #!/usr/bin/env python3
  2. import os
  3. import sys
  4. from subprocess import run,Popen, PIPE
  5. source_server="git@git.annax.de"
  6. local_base=f"./repositories"
  7. mirror_base=f"{local_base}/{source_server}"
  8. COM=sys.argv[0]
  9. def git_info(source_server):
  10. proc = Popen(
  11. ["ssh",source_server,"info"],
  12. stdout=PIPE,
  13. stderr=PIPE,
  14. encoding="utf-8")
  15. for line in proc.stdout.readlines():
  16. yield line
  17. def repos_from_lines(lines):
  18. for line in lines:
  19. if line.find("gitolite") >= 0:
  20. continue
  21. fields = line.split()
  22. if len(fields) < 3:
  23. continue
  24. yield fields[2]
  25. async def run_parallel(target, args=[], procs=4, debug=False):
  26. import asyncio
  27. loop = asyncio.new_event_loop()
  28. jobs = []
  29. lock = asyncio.Lock()
  30. async def addJobs(target, args):
  31. for arg in args:
  32. print("addJobs:", len(jobs))
  33. while len(jobs) >= procs:
  34. lock.release()
  35. await asyncio.sleep(0.5)
  36. await lock.acquire()
  37. print("adding Job with arg:", arg)
  38. jobs.append(loop.create_task(target(arg)))
  39. jobmon = loop.create_task(addJobs(target, args))
  40. while True:
  41. while len(jobs)==0:
  42. await lock.acquire()
  43. if jobmon.done():
  44. break
  45. result = await jobs[0]
  46. print("Job done with result:", result, flush=True)
  47. jobs.pop(0)
  48. lock.release()
  49. print(jobmon)
  50. await jobmon
  51. def main2():
  52. import asyncio
  53. lines = git_info(source_server)
  54. repos = repos_from_lines(lines)
  55. asyncio.run(run_parallel(mirror_repo, repos, debug=True))
  56. def main():
  57. lines = git_info(source_server)
  58. repos = repos_from_lines(lines)
  59. for repo in repos:
  60. mirror_repo(repo)
  61. def mirror_repo(repo):
  62. print(f"{COM}: checking: {repo}")
  63. source_repo = f"{source_server}:{repo}"
  64. local_repo = f"{mirror_base}/{repo}"
  65. if os.path.isdir(f"{local_repo}/refs"):
  66. update_local_repo(local_repo)
  67. else:
  68. clone_repo(source_repo, local_repo)
  69. return True
  70. def update_local_repo(local_repo):
  71. print(f"{COM}: {local_repo} exists, updating...")
  72. run(["git","fetch","-p","origin"], cwd=local_repo)
  73. def clone_repo(source_repo, local_repo):
  74. print(f"{COM}: Cloning {source_repo} => {local_repo}")
  75. run(["rm","-rf",local_repo])
  76. run(["mkdir","-p",local_repo])
  77. run(["git","clone","--bare",source_repo,"."], cwd=local_repo)
  78. if __name__ == "__main__":
  79. main()