import os
import settings
from urlparse import urlparse
from socket import gethostname
from redis import Redis
from api.repositories import Repository
from bugzscout import report_exception
from mercurial.node import hex
def _get_redis():
return Redis(host=settings.SYNC_REDIS_HOST, port=settings.SYNC_REDIS_PORT, db=settings.SYNC_REDIS_DB)
def _get_host(url):
"""
Returns the host portion of the URL passed in, or just the hostname
if the string was not a url.
"""
o = urlparse(url)
return o.netloc.split(':')[0] or o.path
def _do_sync():
return getattr(settings, 'HOSTED', False) and getattr(settings, 'DO_SYNCSTATUS', False)
def update_status(repo, redis=None, hostname=None):
"""
Grab all of the heads, in order, and put them in the hostname's Redis hash
so that we can tell what needs syncing and what doesn't.
"""
if _do_sync():
try:
if not redis:
redis = _get_redis()
if not hostname:
hostname = gethostname()
if repo.meta_deleted():
status = 'deleted'
else:
status = ','.join(sorted(map(hex, repo.repo.heads())))
redis.hset(hostname, repo.uuid, status)
except Exception, e:
# We never want to error out from here since it would break sync.
report_exception(e)
def remove_repo(repo, redis=None, hostname=None):
"""
Remove a repo from the Redis hash of this machine.
"""
if _do_sync():
try:
if not redis:
redis = _get_redis()
if not hostname:
hostname = gethostname()
redis.hdel(hostname, repo.uuid)
except Exception, e:
report_exception(e)
def need_sync(src, dest=None):
if _do_sync():
src = _get_host(src)
dest = _get_host(dest) if dest else gethostname()
redis = _get_redis()
src_dict = redis.hgetall(src)
dest_dict = redis.hgetall(dest)
repos = [k for k in src_dict if src_dict[k] != dest_dict.get(k, None)]
return repos
else:
return []
def main():
if _do_sync():
redis = _get_redis()
hostname = gethostname()
redis.delete(hostname)
for d1 in os.listdir(settings.KILN_REPOSITORY_ROOT):
p1 = os.path.join(settings.KILN_REPOSITORY_ROOT, d1)
if len(d1) != 2 or not os.path.isdir(p1):
continue
for d2 in os.listdir(p1):
p2 = os.path.join(p1, d2)
if len(d2) != 2 or not os.path.isdir(p2):
continue
for repo in os.listdir(p2):
r = Repository(repo, suppresshooks=True)
if r.exists():
update_status(r)
else:
print "We don't do sync status on this box."
if __name__ == '__main__':
main()
|
Loading...