aboutsummaryrefslogtreecommitdiff
path: root/gitosis/gitdaemon.py
blob: 1e430473a0ff79c7f047c8438d82e57251f1cdff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
"""
Gitosis git-daemon functionality.
 
Handles the ``git-daemon-export-ok`` marker files for all repositories managed
by Gitosis.
"""
import errno
import logging
import os
 
# C0103 - 'log' is a special name 
# pylint: disable-msg=C0103 
log = logging.getLogger('gitosis.gitdaemon')
 
from gitosis import util
from gitosis.configutil import getboolean_default
 
def export_ok_path(repopath):
    """
    Return the path the ``git-daemon-export-ok`` marker for a given repository.
    """
    path = os.path.join(repopath'git-daemon-export-ok')
    return path
 
def allow_export(repopath):
    """Create the ``git-daemon-export-ok`` marker for a given repository."""
    path = export_ok_path(repopath)
    file(path'a').close()
 
def deny_export(repopath):
    """Remove the ``git-daemon-export-ok`` marker for a given repository."""
    path = export_ok_path(repopath)
    util.unlink(path)
 
def _extract_reldir(topdir, dirpath):
    """
    Find the relative directory given a base directory & a child directory.
    """
    if topdir == dirpath:
        return '.'
    prefix = topdir + '/'
    assert dirpath.startswith(prefix)
    reldir = dirpath[len(prefix):]
    return reldir
 
def _is_global_repo_export_ok(config):
    """
    Does the global Gitosis configuration allow daemon exporting?
    """
    global_enable = getboolean_default(config'gitosis''daemon'False)
    log.debug(
        'Global default is %r',
        {True: 'allow', False: 'deny'}.get(global_enable),
        )
    return global_enable
 
def _is_repo_export_ok(global_enable, config, reponame):
    """
    Does the Gitosis configuration for the named reposistory allow daemon
    exporting?
    """
    section = 'repo %s' % reponame
    return getboolean_default(configsection'daemon'global_enable)
 
def _set_export_ok_single(enable, name, dirpath, repo):
    """
    Manage the ``git-daemon-export-ok`` marker for a single repository.
    """
    repopath = os.path.join(dirpathrepo)
    if enable:
        log.debug('Allow %r'name)
        allow_export(repopath)
    else:
        log.debug('Deny %r'name)
        deny_export(repopath)
 
def set_export_ok(config):
    """
    Walk all repositories owned by Gitosis, and manage the
    ``git-daemon-export-ok`` markers.
    """
    repositories = util.getRepositoryDir(config)
    global_enable = _is_global_repo_export_ok(config)
 
    def _error(ex): #pragma: no cover 
        """Ignore non-existant items."""
        if ex.errno == errno.ENOENT:
            pass
        else:
            raise ex
 
    for (dirpathdirnames_) \ 
            in os.walk(repositoriesonerror=_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'reldirdirnames)
 
        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:
            nameext = os.path.splitext(repo)
            if reldir != '.':
                name = os.path.join(reldirname)
            assert ext == '.git'
            
            enable = _is_repo_export_ok(global_enableconfigname)
            _set_export_ok_single(enablenamedirpathrepo)