gitosis/gitosis/gitdaemon.py

91 lines
2.4 KiB
Python

import errno
import logging
import os
from ConfigParser import NoSectionError, NoOptionError
log = logging.getLogger('gitosis.gitdaemon')
from gitosis import util
def export_ok_path(repopath):
p = os.path.join(repopath, 'git-daemon-export-ok')
return p
def allow_export(repopath):
p = export_ok_path(repopath)
file(p, 'a').close()
def deny_export(repopath):
p = export_ok_path(repopath)
try:
os.unlink(p)
except OSError, e:
if e.errno == errno.ENOENT:
pass
else:
raise
def _extract_reldir(topdir, dirpath):
if topdir == dirpath:
return '.'
prefix = topdir + '/'
assert dirpath.startswith(prefix)
reldir = dirpath[len(prefix):]
return reldir
def set_export_ok(config):
repositories = util.getRepositoryDir(config)
try:
global_enable = config.getboolean('gitosis', 'daemon')
except (NoSectionError, NoOptionError):
global_enable = False
log.debug(
'Global default is %r',
{True: 'allow', False: 'deny'}.get(global_enable),
)
def _error(e):
if e.errno == errno.ENOENT:
pass
else:
raise e
for (dirpath, dirnames, filenames) \
in os.walk(repositories, onerror=_error):
# oh how many times i have wished for os.walk to report
# topdir and reldir separately, instead of dirpath
reldir = _extract_reldir(
topdir=repositories,
dirpath=dirpath,
)
log.debug('Walking %r, seeing %r', reldir, dirnames)
to_recurse = []
repos = []
for dirname in dirnames:
if dirname.endswith('.git'):
repos.append(dirname)
else:
to_recurse.append(dirname)
dirnames[:] = to_recurse
for repo in repos:
name, ext = os.path.splitext(repo)
if reldir != '.':
name = os.path.join(reldir, name)
assert ext == '.git'
try:
enable = config.getboolean('repo %s' % name, 'daemon')
except (NoSectionError, NoOptionError):
enable = global_enable
if enable:
log.debug('Allow %r', name)
allow_export(os.path.join(dirpath, repo))
else:
log.debug('Deny %r', name)
deny_export(os.path.join(dirpath, repo))