Example #1
0
def init_admin_repository(
    git_dir,
    pubkey,
    user,
    ):
    repository.init(
        path=git_dir,
        template=resource_filename('gitosis.templates', 'admin')
        )
    repository.init(
        path=git_dir,
        )
    hook = os.path.join(git_dir, 'hooks', 'post-update')
    os.chmod(hook, 0755)
    if not repository.has_initial_commit(git_dir):
        log.info('Making initial commit...')
        # ConfigParser does not guarantee order, so jump through hoops
        # to make sure [gitosis] is first
        cfg_file = StringIO()
        print >>cfg_file, '[gitosis]'
        print >>cfg_file
        cfg = RawConfigParser()
        cfg.add_section('group gitosis-admin')
        cfg.set('group gitosis-admin', 'members', user)
        cfg.set('group gitosis-admin', 'writable', 'gitosis-admin')
        cfg.write(cfg_file)
        initial_commit(
            git_dir=git_dir,
            cfg=cfg_file.getvalue(),
            pubkey=pubkey,
            user=user,
            )
Example #2
0
def test_fast_import_parent():
    tmp = maketemp()
    path = os.path.join(tmp, 'repo.git')
    repository.init(path=path)
    repository.fast_import(
        git_dir=path,
        commit_msg='foo initial bar',
        committer='Mr. Unit Test <*****@*****.**>',
        files=[
            ('foo', 'bar\n'),
            ],
        )
    repository.fast_import(
        git_dir=path,
        commit_msg='another',
        committer='Sam One Else <*****@*****.**>',
        parent='refs/heads/master^0',
        files=[
            ('quux', 'thud\n'),
            ],
        )
    export = os.path.join(tmp, 'export')
    repository.export(
        git_dir=path,
        path=export,
        )
    eq(sorted(os.listdir(export)),
       sorted(['foo', 'quux']))
Example #3
0
def auto_init_repo(cfg,topdir,repopath):
    # create leading directories
    p = topdir

    assert repopath.endswith('.git'), 'must have .git extension'
    newdirmode = util.getConfigDefault(cfg,
                                       'repo %s' % repopath[:-4],
                                       'dirmode',
                                       None,
                                       'defaults')
    if newdirmode is not None:
        newdirmode = int(newdirmode, 8)
    else:
        newdirmode = 0750

    for segment in repopath.split(os.sep)[:-1]:
        p = os.path.join(p, segment)
        util.mkdir(p, newdirmode)

    fullpath = os.path.join(topdir, repopath)

    # init using a custom template, if required
    try:
        template = cfg.get('gitosis', 'init-template')
        repository.init(path=fullpath, template=template, mode=newdirmode)
    except (NoSectionError, NoOptionError):
        pass

    repository.init(path=fullpath, mode=newdirmode)
Example #4
0
def test_init_templates():
    tmp = maketemp()
    path = os.path.join(tmp, 'repo.git')
    templatedir = os.path.join(
        os.path.dirname(__file__),
        'mocktemplates',
        )
    repository.init(path, template=templatedir)
    repository.init(path)
    got = readFile(os.path.join(path, 'no-confusion'))
    eq(got, 'i should show up\n')
    check_mode(
        os.path.join(path, 'hooks', 'post-update'),
        0755,
        is_file=True,
        )
    got = readFile(os.path.join(path, 'hooks', 'post-update'))
    eq(got, '#!/bin/sh\n# i can override standard templates\n')
    # standard templates are there, too
    assert (
        # compatibility with git <1.6.0
        os.path.isfile(os.path.join(path, 'hooks', 'pre-rebase'))
        # for git >=1.6.0
        or os.path.isfile(os.path.join(path, 'hooks', 'pre-rebase.sample'))
        )
Example #5
0
def test_init_exist_git():
    tmp = maketemp()
    path = os.path.join(tmp, 'repo.git')
    repository.init(path)
    repository.init(path)
    check_mode(path, 0750, is_dir=True)
    check_bare(path)
Example #6
0
def test_dcontrol1():
    tmp = util.maketemp()
    projname = "foo"

    git_dir = os.path.join(tmp, projname + ".git")
    repository.init(path=git_dir)
    repository.fast_import(
        git_dir=git_dir,
        committer="John Doe 2 <*****@*****.**>",
        commit_msg="""\
Allow jdoe write access to foo
""",
        files=[("foo", "content"), ("bar/quux", "another")],
    )

    child = subprocess.Popen(
        args=["git", "--git-dir=%s" % git_dir, "cat-file", "commit", "HEAD"],
        cwd=git_dir,
        stdout=subprocess.PIPE,
        close_fds=True,
    )
    got = child.stdout.read().splitlines()
    returncode = child.wait()
    if returncode != 0:
        raise RuntimeError("git exit status %d" % returncode)
    eq(got[0].split(None, 1)[0], "tree")
    eq(got[1].rsplit(None, 2)[0], "author John Doe 2 <*****@*****.**>")
    eq(got[2].rsplit(None, 2)[0], "committer John Doe 2 <*****@*****.**>")
    eq(got[3], "")
    eq(got[4], "Allow jdoe write access to foo")
    eq(got[5:], [])
Example #7
0
def init_admin_repository(
    git_dir,
    pubkey,
    user,
    ):
    repository.init(
        path=git_dir,
        template=resource_filename('gitosis.templates', 'admin')
        )
    repository.init(
        path=git_dir,
        )
    if not repository.has_initial_commit(git_dir):
        log.info('Making initial commit...')

        cfg = GitoliteConfig()
        cfg.set_group_members('@gitosis-admin', [user])
        cfg.set_repo('gitosis-admin', 'RW+', ['@gitosis-admin'])

        cfg_file = cfg.serialize()
        initial_commit(
            git_dir=git_dir,
            cfg=cfg_file.getvalue(),
            pubkey=pubkey,
            user=user,
            )
Example #8
0
def test_typo_writeable():
    tmp = util.maketemp()
    repository.init(path.join(tmp, 'foo.git'))
    cfg = RawConfigParser()
    cfg.add_section('gitosis')
    cfg.set('gitosis', 'repositories', tmp)
    cfg.add_section('group foo')
    cfg.set('group foo', 'members', 'jdoe')
    cfg.set('group foo', 'writeable', 'foo')
    cfg.add_section('rsp')
    cfg.set('rsp', 'haveAccessURL', 'example.org')
    log = logging.getLogger('gitosis.serve')
    buf = StringIO()
    handler = logging.StreamHandler(buf)
    log.addHandler(handler)
    try:
        got = serve.serve(
            cfg=cfg,
            user='******',
            command="git-receive-pack 'foo'",
            )
    finally:
        log.removeHandler(handler)
    eq(got, "git-receive-pack '%s/foo.git'" % tmp)
    handler.flush()
    eq(
        buf.getvalue(),
        "Repository 'foo' config has typo \"writeable\", shou"
        +"ld be \"writable\"\n",
        )
Example #9
0
def test_init_environment():
    tmp = maketemp()
    path = os.path.join(tmp, "repo.git")
    mockbindir = os.path.join(tmp, "mockbin")
    os.mkdir(mockbindir)
    mockgit = os.path.join(mockbindir, "git")
    writeFile(
        mockgit,
        """\
#!/bin/sh
set -e
# git wrapper for gitosis unit tests
printf '%s' "$GITOSIS_UNITTEST_COOKIE" >"$(dirname "$0")/../cookie"

# strip away my special PATH insert so system git will be found
PATH="${PATH#*:}"

exec git "$@"
""",
    )
    os.chmod(mockgit, 0755)
    magic_cookie = "%d" % random.randint(1, 100000)
    good_path = os.environ["PATH"]
    try:
        os.environ["PATH"] = "%s:%s" % (mockbindir, good_path)
        os.environ["GITOSIS_UNITTEST_COOKIE"] = magic_cookie
        repository.init(path)
    finally:
        os.environ["PATH"] = good_path
        os.environ.pop("GITOSIS_UNITTEST_COOKIE", None)
    eq(sorted(os.listdir(tmp)), sorted(["mockbin", "cookie", "repo.git"]))
    got = readFile(os.path.join(tmp, "cookie"))
    eq(got, magic_cookie)
Example #10
0
def init_admin_repository(git_dir, pubkey, user, config):
    """Create the initial gitosis-admin reposistory."""
    repository.init(
        path=git_dir,
        template=resource_filename('gitosis.templates', 'admin')
        )
    repository.init(
        path=git_dir,
        )
    # Check that the config meets the min requirements
    if not config.has_section('gitosis'):
        config.add_section('gitosis')
    if not config.has_section('group gitosis-admin'):
        config.add_section('group gitosis-admin')
    if not config.has_option('group gitosis-admin', 'writable'):
        config.set('group gitosis-admin', 'writable', 'gitosis-admin')

    # Make sure the admin user is in the admin list, else they will lock themselves out!
    adminlist = config.get('group gitosis-admin', 'members', default=' ').split()
    if user not in adminlist:
        adminlist.append(user)
        config.set('group gitosis-admin', 'members', ' '.join(adminlist))

    if not repository.has_initial_commit(git_dir):
        log.info('Making initial commit...')
        # ConfigParser does not guarantee order, so jump through hoops
        # to make sure [gitosis] is first
        cfg_file = StringIO()
        config.write(cfg_file)
        initial_commit(
            git_dir=git_dir,
            cfg=cfg_file.getvalue(),
            pubkey=pubkey,
            user=user,
            )
Example #11
0
def test_has_initial_commit_environment():
    tmp = maketemp()
    git_dir = os.path.join(tmp, "repo.git")
    mockbindir = os.path.join(tmp, "mockbin")
    os.mkdir(mockbindir)
    mockgit = os.path.join(mockbindir, "git")
    writeFile(
        mockgit,
        """\
#!/bin/sh
set -e
# git wrapper for gitosis unit tests
printf '%s' "$GITOSIS_UNITTEST_COOKIE" >"$(dirname "$0")/../cookie"

# strip away my special PATH insert so system git will be found
PATH="${PATH#*:}"

exec git "$@"
""",
    )
    os.chmod(mockgit, 0755)
    repository.init(path=tmp)
    repository.fast_import(git_dir=tmp, commit_msg="fakecommit", committer="John Doe <*****@*****.**>", files=[])
    magic_cookie = "%d" % random.randint(1, 100000)
    good_path = os.environ["PATH"]
    try:
        os.environ["PATH"] = "%s:%s" % (mockbindir, good_path)
        os.environ["GITOSIS_UNITTEST_COOKIE"] = magic_cookie
        got = repository.has_initial_commit(git_dir=tmp)
    finally:
        os.environ["PATH"] = good_path
        os.environ.pop("GITOSIS_UNITTEST_COOKIE", None)
    eq(got, True)
    got = readFile(os.path.join(tmp, "cookie"))
    eq(got, magic_cookie)
Example #12
0
def init_admin_repository(
    git_dir,
    pubkey,
    user,
    ):
    repository.init(
        path=git_dir,
        template=resource_filename('gitosis.templates', 'admin')
        )
    repository.init(
        path=git_dir,
        )
    # hook = os.path.join(git_dir, 'hooks', 'post-update')
    # os.chmod(hook, 0755)
    log.info("Git dir: %s", git_dir)
    if not repository.has_initial_commit(git_dir):
        log.info('Making initial commit...')
        # ConfigParser does not guarantee order, so jump through hoops
        # to make sure [gitosis] is first
        cfg = RedisConfigParser()
        cfg.add_section('gitosis')
        cfg.add_section('group gitosis-admin')
        cfg.set('group gitosis-admin', 'members', user)
        cfg.set('group gitosis-admin', 'writable', 'gitosis-admin')
        initial_commit(
            git_dir=git_dir,
            cfg=cfg,
            pubkey=pubkey,
            user=user,
            )
Example #13
0
def test_init_default_templates():
    tmp = maketemp()
    path = os.path.join(tmp, "repo.git")
    repository.init(path)
    hook_path = os.path.join(path, "hooks", "post-receive")
    check_mode(hook_path, 0755, is_file=True)
    got = readFile(hook_path)
    eq(got, "#!/bin/sh\nset -e\ngit-update-server-info\ngitosis-run-hook update-mirrors")
Example #14
0
def test_init_exist_dir():
    tmp = maketemp()
    path = os.path.join(tmp, 'repo.git')
    mkdir(path, 0710)
    check_mode(path, 0710, is_dir=True)
    repository.init(path)
    # my weird access mode is preserved
    check_mode(path, 0710, is_dir=True)
    check_bare(path)
Example #15
0
def test_has_initial_commit_yes():
    tmp = maketemp()
    repository.init(path=tmp)
    repository.fast_import(
        git_dir=tmp,
        commit_msg='fakecommit',
        committer='John Doe <*****@*****.**>',
        files=[],
        )
    got = repository.has_initial_commit(git_dir=tmp)
    eq(got, True)
Example #16
0
def test_simple_write_space():
    tmp = util.maketemp()
    repository.init(os.path.join(tmp, "foo.git"))
    cfg = RawConfigParser()
    cfg.add_section("gitosis")
    cfg.set("gitosis", "repositories", tmp)
    cfg.add_section("group foo")
    cfg.set("group foo", "members", "jdoe")
    cfg.set("group foo", "writable", "foo")
    got = serve.serve(cfg=cfg, user="******", command="git receive-pack 'foo'")
    eq(got, "git receive-pack '%s/foo.git'" % tmp)
Example #17
0
def test_simple_read_archive():
    tmp = util.maketemp()
    repository.init(os.path.join(tmp, "foo.git"))
    cfg = RawConfigParser()
    cfg.add_section("gitosis")
    cfg.set("gitosis", "repositories", tmp)
    cfg.add_section("group foo")
    cfg.set("group foo", "members", "jdoe")
    cfg.set("group foo", "readonly", "foo")
    got = serve.serve(cfg=cfg, user="******", command="git upload-archive 'foo'")
    eq(got, "git upload-archive '%s/foo.git'" % tmp)
Example #18
0
def test_init_templates():
    tmp = maketemp()
    path = os.path.join(tmp, "repo.git")
    templatedir = os.path.join(os.path.dirname(__file__), "mocktemplates")
    os.umask(0022)
    repository.init(path, template=templatedir)
    repository.init(path)
    got = readFile(os.path.join(path, "no-confusion"))
    eq(got, "i should show up\n")
    check_mode(os.path.join(path, "hooks", "post-update"), 0755, is_file=True)
    got = readFile(os.path.join(path, "hooks", "post-update"))
    eq(got, "#!/bin/sh\n# i can override standard templates\n")
Example #19
0
def test_export_simple():
    tmp = maketemp()
    git_dir = os.path.join(tmp, 'repo.git')
    repository.init(path=git_dir)
    repository.fast_import(
        git_dir=git_dir,
        committer='John Doe <*****@*****.**>',
        commit_msg="""\
Reverse the polarity of the neutron flow.

Frobitz the quux and eschew obfuscation.
""",
        files=[
            ('foo', 'content'),
            ('bar/quux', 'another'),
            ],
        )
    export = os.path.join(tmp, 'export')
    repository.export(git_dir=git_dir, path=export)
    eq(sorted(os.listdir(export)),
       sorted(['foo', 'bar']))
    eq(readFile(os.path.join(export, 'foo')), 'content')
    eq(os.listdir(os.path.join(export, 'bar')), ['quux'])
    eq(readFile(os.path.join(export, 'bar', 'quux')), 'another')
    child = subprocess.Popen(
        args=[
            'git',
            '--git-dir=%s' % git_dir,
            'cat-file',
            'commit',
            'HEAD',
            ],
        cwd=git_dir,
        stdout=subprocess.PIPE,
        close_fds=True,
        )
    got = child.stdout.read().splitlines()
    returncode = child.wait()
    if returncode != 0:
        raise RuntimeError('git exit status %d' % returncode)
    eq(got[0].split(None, 1)[0], 'tree')
    eq(got[1].rsplit(None, 2)[0],
       'author John Doe <*****@*****.**>')
    eq(got[2].rsplit(None, 2)[0],
       'committer John Doe <*****@*****.**>')
    eq(got[3], '')
    eq(got[4], 'Reverse the polarity of the neutron flow.')
    eq(got[5], '')
    eq(got[6], 'Frobitz the quux and eschew obfuscation.')
    eq(got[7:], [])
Example #20
0
def test_simple_write_space():
    tmp = util.maketemp()
    repository.init(os.path.join(tmp, 'foo.git'))
    cfg = RawConfigParser()
    cfg.add_section('gitosis')
    cfg.set('gitosis', 'repositories', tmp)
    cfg.add_section('group foo')
    cfg.set('group foo', 'members', 'jdoe')
    cfg.set('group foo', 'writable', 'foo')
    got = serve.serve(
        cfg=cfg,
        user='******',
        command="git receive-pack 'foo'",
        )
    eq(got, "git receive-pack '%s/foo.git'" % tmp)
Example #21
0
def test_simple_write_space():
    tmp = util.maketemp()
    repository.init(os.path.join(tmp, 'foo.git'))
    cfg = RawConfigParser()
    cfg.add_section('gitosis')
    cfg.set('gitosis', 'repositories', tmp)
    cfg.add_section('group foo')
    cfg.set('group foo', 'members', 'jdoe')
    cfg.set('group foo', 'writable', 'foo')
    got = serve.serve(
        cfg=cfg,
        user='******',
        command="git receive-pack 'foo'",
    )
    eq(got, "git receive-pack '%s/foo.git'" % tmp)
Example #22
0
def test_simple_read_archive():
    tmp = util.maketemp()
    repository.init(os.path.join(tmp, 'foo.git'))
    cfg = RawConfigParser()
    cfg.add_section('gitosis')
    cfg.set('gitosis', 'repositories', tmp)
    cfg.add_section('group foo')
    cfg.set('group foo', 'members', 'jdoe')
    cfg.set('group foo', 'readonly', 'foo')
    got = serve.serve(
        cfg=cfg,
        user='******',
        command="git upload-archive 'foo'",
    )
    eq(got, "git upload-archive '%s/foo.git'" % tmp)
Example #23
0
def test_simple_read_leading_slash():
    tmp = util.maketemp()
    repository.init(os.path.join(tmp, 'foo.git'))
    cfg = RawConfigParser()
    cfg.add_section('gitosis')
    cfg.set('gitosis', 'repositories', tmp)
    cfg.add_section('group foo')
    cfg.set('group foo', 'members', 'jdoe')
    cfg.set('group foo', 'readonly', 'foo')
    got = serve.serve(
        cfg=cfg,
        user='******',
        command="git-upload-pack '/foo'",
        )
    eq(got, "git-upload-pack '%s/foo.git'" % tmp)
Example #24
0
def test_export_environment():
    tmp = maketemp()
    git_dir = os.path.join(tmp, "repo.git")
    mockbindir = os.path.join(tmp, "mockbin")
    os.mkdir(mockbindir)
    mockgit = os.path.join(mockbindir, "git")
    writeFile(
        mockgit,
        """\
#!/bin/sh
set -e
# git wrapper for gitosis unit tests
printf '%s\n' "$GITOSIS_UNITTEST_COOKIE" >>"$(dirname "$0")/../cookie"

# strip away my special PATH insert so system git will be found
PATH="${PATH#*:}"

exec git "$@"
""",
    )
    os.chmod(mockgit, 0755)
    repository.init(path=git_dir)
    repository.fast_import(
        git_dir=git_dir,
        committer="John Doe <*****@*****.**>",
        commit_msg="""\
Reverse the polarity of the neutron flow.

Frobitz the quux and eschew obfuscation.
""",
        files=[("foo", "content"), ("bar/quux", "another")],
    )
    export = os.path.join(tmp, "export")
    magic_cookie = "%d" % random.randint(1, 100000)
    good_path = os.environ["PATH"]
    try:
        os.environ["PATH"] = "%s:%s" % (mockbindir, good_path)
        os.environ["GITOSIS_UNITTEST_COOKIE"] = magic_cookie
        repository.export(git_dir=git_dir, path=export)
    finally:
        os.environ["PATH"] = good_path
        os.environ.pop("GITOSIS_UNITTEST_COOKIE", None)
    got = readFile(os.path.join(tmp, "cookie"))
    eq(
        got,
        # export runs git twice
        "%s\n%s\n" % (magic_cookie, magic_cookie),
    )
Example #25
0
def test_export_environment():
    tmp = maketemp()
    git_dir = os.path.join(tmp, 'repo.git')
    mockbindir = os.path.join(tmp, 'mockbin')
    os.mkdir(mockbindir)
    mockgit = os.path.join(mockbindir, 'git')
    writeFile(mockgit, '''\
#!/bin/sh
set -e
# git wrapper for gitosis unit tests
printf '%s\n' "$GITOSIS_UNITTEST_COOKIE" >>"$(dirname "$0")/../cookie"

# strip away my special PATH insert so system git will be found
PATH="${PATH#*:}"

exec git "$@"
''')
    os.chmod(mockgit, 0755)
    repository.init(path=git_dir)
    repository.fast_import(
        git_dir=git_dir,
        committer='John Doe <*****@*****.**>',
        commit_msg="""\
Reverse the polarity of the neutron flow.

Frobitz the quux and eschew obfuscation.
""",
        files=[
            ('foo', 'content'),
            ('bar/quux', 'another'),
            ],
        )
    export = os.path.join(tmp, 'export')
    magic_cookie = '%d' % random.randint(1, 100000)
    good_path = os.environ['PATH']
    try:
        os.environ['PATH'] = '%s:%s' % (mockbindir, good_path)
        os.environ['GITOSIS_UNITTEST_COOKIE'] = magic_cookie
        repository.export(git_dir=git_dir, path=export)
    finally:
        os.environ['PATH'] = good_path
        os.environ.pop('GITOSIS_UNITTEST_COOKIE', None)
    got = readFile(os.path.join(tmp, 'cookie'))
    eq(
        got,
        # export runs git twice
        '%s\n%s\n' % (magic_cookie, magic_cookie),
        )
Example #26
0
def test_export_environment():
    tmp = maketemp()
    git_dir = os.path.join(tmp, 'repo.git')
    mockbindir = os.path.join(tmp, 'mockbin')
    os.mkdir(mockbindir)
    mockgit = os.path.join(mockbindir, 'git')
    writeFile(mockgit, '''\
#!/bin/sh
set -e
# git wrapper for gitosis unit tests
printf '%s\n' "$GITOSIS_UNITTEST_COOKIE" >>"$(dirname "$0")/../cookie"

# strip away my special PATH insert so system git will be found
PATH="${PATH#*:}"

exec git "$@"
''')
    os.chmod(mockgit, 0755)
    repository.init(path=git_dir)
    repository.fast_import(
        git_dir=git_dir,
        committer='John Doe <*****@*****.**>',
        commit_msg="""\
Reverse the polarity of the neutron flow.

Frobitz the quux and eschew obfuscation.
""",
        files=[
            ('foo', 'content'),
            ('bar/quux', 'another'),
            ],
        )
    export = os.path.join(tmp, 'export')
    magic_cookie = '%d' % random.randint(1, 100000)
    good_path = os.environ['PATH']
    try:
        os.environ['PATH'] = '%s:%s' % (mockbindir, good_path)
        os.environ['GITOSIS_UNITTEST_COOKIE'] = magic_cookie
        repository.export(git_dir=git_dir, path=export)
    finally:
        os.environ['PATH'] = good_path
        os.environ.pop('GITOSIS_UNITTEST_COOKIE', None)
    got = readFile(os.path.join(tmp, 'cookie'))
    eq(
        got,
        # export runs git twice
        '%s\n%s\n' % (magic_cookie, magic_cookie),
        )
Example #27
0
def init_admin_repository(git_dir, pubkey, user):
    repository.init(path=git_dir, template=resource_filename("gitosis.templates", "admin"))
    repository.init(path=git_dir)
    if not repository.has_initial_commit(git_dir):
        log.info("Making initial commit...")
        # ConfigParser does not guarantee order, so jump through hoops
        # to make sure [gitosis] is first
        cfg_file = StringIO()
        print >> cfg_file, "[gitosis]"
        print >> cfg_file
        cfg = RawConfigParser()
        cfg.add_section("group gitosis-admin")
        cfg.set("group gitosis-admin", "members", user)
        cfg.set("group gitosis-admin", "writable", "gitosis-admin")
        cfg.write(cfg_file)
        initial_commit(git_dir=git_dir, cfg=cfg_file.getvalue(), pubkey=pubkey, user=user)
Example #28
0
def test_mirror():
    tmp = maketemp()
    main_path = os.path.join(tmp, "main.git")
    mirror_path = os.path.join(tmp, "mirror.git")
    repository.init(path=main_path, template=False)
    repository.init(path=mirror_path, template=False)
    repository.fast_import(
        git_dir=main_path,
        commit_msg="foo initial bar",
        committer="Mr. Unit Test <*****@*****.**>",
        files=[("foo", "bar\n")],
    )
    repository.mirror(main_path, mirror_path)
    export = os.path.join(tmp, "export")
    repository.export(git_dir=mirror_path, path=export)
    eq(os.listdir(export), ["foo"])
Example #29
0
def test_absolute():
    # as the only convenient way to use non-standard SSH ports with
    # git is via the ssh://user@host:port/path syntax, and that syntax
    # forces absolute urls, just force convert absolute paths to
    # relative paths; you'll never really want absolute paths via
    # gitosis, anyway.
    tmp = util.maketemp()
    repository.init(os.path.join(tmp, "foo.git"))
    cfg = RawConfigParser()
    cfg.add_section("gitosis")
    cfg.set("gitosis", "repositories", tmp)
    cfg.add_section("group foo")
    cfg.set("group foo", "members", "jdoe")
    cfg.set("group foo", "readonly", "foo")
    got = serve.serve(cfg=cfg, user="******", command="git-upload-pack '/foo'")
    eq(got, "git-upload-pack '%s/foo.git'" % tmp)
Example #30
0
def test_export_simple():
    tmp = maketemp()
    git_dir = os.path.join(tmp, 'repo.git')
    repository.init(path=git_dir)
    repository.fast_import(
        git_dir=git_dir,
        committer='John Doe <*****@*****.**>',
        commit_msg="""\
Reverse the polarity of the neutron flow.

Frobitz the quux and eschew obfuscation.
""",
        files=[
            ('foo', 'content'),
            ('bar/quux', 'another'),
        ],
    )
    export = os.path.join(tmp, 'export')
    repository.export(git_dir=git_dir, path=export)
    eq(sorted(os.listdir(export)), sorted(['foo', 'bar']))
    eq(readFile(os.path.join(export, 'foo')), 'content')
    eq(os.listdir(os.path.join(export, 'bar')), ['quux'])
    eq(readFile(os.path.join(export, 'bar', 'quux')), 'another')
    child = subprocess.Popen(
        args=[
            'git',
            '--git-dir=%s' % git_dir,
            'cat-file',
            'commit',
            'HEAD',
        ],
        cwd=git_dir,
        stdout=subprocess.PIPE,
        close_fds=True,
    )
    got = child.stdout.read().splitlines()
    returncode = child.wait()
    if returncode != 0:
        raise RuntimeError('git exit status %d' % returncode)
    eq(got[0].split(None, 1)[0], 'tree')
    eq(got[1].rsplit(None, 2)[0], 'author John Doe <*****@*****.**>')
    eq(got[2].rsplit(None, 2)[0], 'committer John Doe <*****@*****.**>')
    eq(got[3], '')
    eq(got[4], 'Reverse the polarity of the neutron flow.')
    eq(got[5], '')
    eq(got[6], 'Frobitz the quux and eschew obfuscation.')
    eq(got[7:], [])
Example #31
0
def auto_init_repo(cfg,topdir,repopath):
    # create leading directories
    p = topdir
    for segment in repopath.split(os.sep)[:-1]:
        p = os.path.join(p, segment)
        util.mkdir(p, 0750)

    fullpath = os.path.join(topdir, repopath)

    # init using a custom template, if required
    try:
        template = cfg.get('gitosis', 'init-template')
        repository.init(path=fullpath,template=template)
    except (NoSectionError, NoOptionError):
        pass

    repository.init(path=fullpath)
Example #32
0
def test_fast_import_environment():
    tmp = maketemp()
    path = os.path.join(tmp, 'repo.git')
    repository.init(path=path)
    mockbindir = os.path.join(tmp, 'mockbin')
    os.mkdir(mockbindir)
    mockgit = os.path.join(mockbindir, 'git')
    writeFile(
        mockgit, '''\
#!/bin/sh
set -e
# git wrapper for gitosis unit tests
printf '%s' "$GITOSIS_UNITTEST_COOKIE" >"$(dirname "$0")/../cookie"

# strip away my special PATH insert so system git will be found
PATH="${PATH#*:}"

exec git "$@"
''')
    os.chmod(mockgit, 0o755)
    magic_cookie = '%d' % random.randint(1, 100000)
    good_path = os.environ['PATH']
    try:
        os.environ['PATH'] = '%s:%s' % (mockbindir, good_path)
        os.environ['GITOSIS_UNITTEST_COOKIE'] = magic_cookie
        repository.fast_import(
            git_dir=path,
            commit_msg='foo initial bar',
            committer='Mr. Unit Test <*****@*****.**>',
            files=[
                ('foo', 'bar\n'),
            ],
        )
    finally:
        os.environ['PATH'] = good_path
        os.environ.pop('GITOSIS_UNITTEST_COOKIE', None)
    eq(
        sorted(os.listdir(tmp)),
        sorted([
            'mockbin',
            'cookie',
            'repo.git',
        ]),
    )
    got = readFile(os.path.join(tmp, 'cookie'))
    eq(got, magic_cookie)
Example #33
0
def test_simple_read_space():
    tmp = util.maketemp()
    repository.init(path.join(tmp, 'foo.git'))
    cfg = RawConfigParser()
    cfg.add_section('gitosis')
    cfg.set('gitosis', 'repositories', tmp)
    cfg.add_section('group foo')
    cfg.set('group foo', 'members', 'jdoe')
    cfg.set('group foo', 'readonly', 'foo')
    cfg.add_section('rsp')
    cfg.set('rsp', 'haveAccessURL', 'example.org')
    got = serve.serve(
        cfg=cfg,
        user='******',
        command="git upload-pack 'foo'",
        )
    eq(got, "git upload-pack '%s/foo.git'" % tmp)
Example #34
0
def test_fast_import_environment():
    tmp = maketemp()
    path = os.path.join(tmp, 'repo.git')
    repository.init(path=path)
    mockbindir = os.path.join(tmp, 'mockbin')
    os.mkdir(mockbindir)
    mockgit = os.path.join(mockbindir, 'git')
    writeFile(mockgit, '''\
#!/bin/sh
set -e
# git wrapper for gitosis unit tests
printf '%s' "$GITOSIS_UNITTEST_COOKIE" >"$(dirname "$0")/../cookie"

# strip away my special PATH insert so system git will be found
PATH="${PATH#*:}"

exec git "$@"
''')
    os.chmod(mockgit, 0755)
    magic_cookie = '%d' % random.randint(1, 100000)
    good_path = os.environ['PATH']
    try:
        os.environ['PATH'] = '%s:%s' % (mockbindir, good_path)
        os.environ['GITOSIS_UNITTEST_COOKIE'] = magic_cookie
        repository.fast_import(
            git_dir=path,
            commit_msg='foo initial bar',
            committer='Mr. Unit Test <*****@*****.**>',
            files=[
                ('foo', 'bar\n'),
                ],
            )
    finally:
        os.environ['PATH'] = good_path
        os.environ.pop('GITOSIS_UNITTEST_COOKIE', None)
    eq(
        sorted(os.listdir(tmp)),
        sorted([
                'mockbin',
                'cookie',
                'repo.git',
                ]),
        )
    got = readFile(os.path.join(tmp, 'cookie'))
    eq(got, magic_cookie)
Example #35
0
def test_init_templates():
    tmp = maketemp()
    path = os.path.join(tmp, 'repo.git')
    templatedir = os.path.join(
        os.path.dirname(__file__),
        'mocktemplates',
        )
    repository.init(path, template=templatedir)
    repository.init(path)
    got = readFile(os.path.join(path, 'no-confusion'))
    eq(got, 'i should show up\n')
    check_mode(
        os.path.join(path, 'hooks', 'post-update'),
        0755,
        is_file=True,
        )
    got = readFile(os.path.join(path, 'hooks', 'post-update'))
    eq(got, '#!/bin/sh\n# i can override standard templates\n')
Example #36
0
def test_init_templates():
    tmp = maketemp()
    path = os.path.join(tmp, 'repo.git')
    templatedir = os.path.join(
        os.path.dirname(__file__),
        'mocktemplates',
        )
    os.umask(0022)
    repository.init(path, template=templatedir)
    repository.init(path)
    got = readFile(os.path.join(path, 'no-confusion'))
    eq(got, 'i should show up\n')
    check_mode(
        os.path.join(path, 'hooks', 'post-update'),
        0755,
        is_file=True,
        )
    got = readFile(os.path.join(path, 'hooks', 'post-update'))
    eq(got, '#!/bin/sh\n# i can override standard templates\n')
Example #37
0
def test_absolute():
    # as the only convenient way to use non-standard SSH ports with
    # git is via the ssh://user@host:port/path syntax, and that syntax
    # forces absolute urls, just force convert absolute paths to
    # relative paths; you'll never really want absolute paths via
    # gitosis, anyway.
    tmp = util.maketemp()
    repository.init(os.path.join(tmp, 'foo.git'))
    cfg = RawConfigParser()
    cfg.add_section('gitosis')
    cfg.set('gitosis', 'repositories', tmp)
    cfg.add_section('group foo')
    cfg.set('group foo', 'members', 'jdoe')
    cfg.set('group foo', 'readonly', 'foo')
    got = serve.serve(
        cfg=cfg,
        user='******',
        command="git-upload-pack '/foo'",
    )
    eq(got, "git-upload-pack '%s/foo.git'" % tmp)
Example #38
0
def test_push_mirrors():
    tmp = maketemp()
    foo_path = os.path.join(tmp, 'foo.git')
    bar_path = os.path.join(tmp, 'bar.git')
    baz_path = os.path.join(tmp, 'baz.git')
    repository.init(path=foo_path, template=False)
    repository.init(path=bar_path, template=False)
    repository.init(path=baz_path, template=False)
    repository.fast_import(
        git_dir=foo_path,
        commit_msg='foo initial bar',
        committer='Mr. Unit Test <*****@*****.**>',
        files=[
            ('foo', 'bar\n'),
            ],
        )
    cfg = get_config()
    cfg.set('repo foo', 'mirrors', ' '.join([bar_path,baz_path]))
    mirror.push_mirrors(cfg, foo_path)
    export_bar = os.path.join(tmp, 'export_bar')
    export_baz = os.path.join(tmp, 'export_baz')
    repository.export(
        git_dir=bar_path,
        path=export_bar,
        )
    repository.export(
        git_dir=baz_path,
        path=export_baz,
        )
    eq(os.listdir(export_bar),
       ['foo'])
    eq(os.listdir(export_baz),
       ['foo'])
Example #39
0
def test_mirror():
    tmp = maketemp()
    main_path = os.path.join(tmp, 'main.git')
    mirror_path = os.path.join(tmp, 'mirror.git')
    repository.init(path=main_path, template=False)
    repository.init(path=mirror_path, template=False)
    repository.fast_import(
        git_dir=main_path,
        commit_msg='foo initial bar',
        committer='Mr. Unit Test <*****@*****.**>',
        files=[
            ('foo', 'bar\n'),
            ],
        )
    repository.mirror(main_path, mirror_path)
    export = os.path.join(tmp, 'export')
    repository.export(
        git_dir=mirror_path,
        path=export,
        )
    eq(os.listdir(export),
       ['foo'])
Example #40
0
def test_has_initial_commit_environment():
    tmp = maketemp()
    git_dir = os.path.join(tmp, 'repo.git')
    mockbindir = os.path.join(tmp, 'mockbin')
    os.mkdir(mockbindir)
    mockgit = os.path.join(mockbindir, 'git')
    writeFile(
        mockgit, '''\
#!/bin/sh
set -e
# git wrapper for gitosis unit tests
printf '%s' "$GITOSIS_UNITTEST_COOKIE" >"$(dirname "$0")/../cookie"

# strip away my special PATH insert so system git will be found
PATH="${PATH#*:}"

exec git "$@"
''')
    os.chmod(mockgit, 0o755)
    repository.init(path=tmp)
    repository.fast_import(
        git_dir=tmp,
        commit_msg='fakecommit',
        committer='John Doe <*****@*****.**>',
        files=[],
    )
    magic_cookie = '%d' % random.randint(1, 100000)
    good_path = os.environ['PATH']
    try:
        os.environ['PATH'] = '%s:%s' % (mockbindir, good_path)
        os.environ['GITOSIS_UNITTEST_COOKIE'] = magic_cookie
        got = repository.has_initial_commit(git_dir=tmp)
    finally:
        os.environ['PATH'] = good_path
        os.environ.pop('GITOSIS_UNITTEST_COOKIE', None)
    eq(got, True)
    got = readFile(os.path.join(tmp, 'cookie'))
    eq(got, magic_cookie)
Example #41
0
def test_init_templates():
    tmp = maketemp()
    path = os.path.join(tmp, 'repo.git')
    templatedir = os.path.join(
        os.path.dirname(__file__),
        'mocktemplates',
    )
    repository.init(path, template=templatedir)
    repository.init(path)
    got = readFile(os.path.join(path, 'no-confusion'))
    eq(got, 'i should show up\n')
    check_mode(
        os.path.join(path, 'hooks', 'post-update'),
        0755,
        is_file=True,
    )
    got = readFile(os.path.join(path, 'hooks', 'post-update'))
    eq(got, '#!/bin/sh\n# i can override standard templates\n')
    # standard templates are there, too
    assert (
        # compatibility with git <1.6.0
        os.path.isfile(os.path.join(path, 'hooks', 'pre-rebase'))
        # for git >=1.6.0
        or os.path.isfile(os.path.join(path, 'hooks', 'pre-rebase.sample')))
Example #42
0
def serve(
    cfg,
    user,
    command,
    ):
    if '\n' in command:
        raise CommandMayNotContainNewlineError()
    
    try:
        verb, args = command.split(None, 1)
    except ValueError:
        # all known "git-foo" commands take one argument; improve
        # if/when needed
        raise UnknownCommandError()

    if verb == 'git':
        try:
            subverb, args = args.split(None, 1)
        except ValueError:
            # all known "git foo" commands take one argument; improve
            # if/when needed
            raise UnknownCommandError()
        verb = '%s %s' % (verb, subverb)

    if (verb not in COMMANDS_WRITE
        and verb not in COMMANDS_READONLY):
        raise UnknownCommandError()

    match = ALLOW_RE.match(args)
    if match is None:
        raise UnsafeArgumentsError()

    path = match.group('path')

    # write access is always sufficient
    newpath = access.haveAccess(
        config=cfg,
        user=user,
        mode='writable',
        path=path)

    if newpath is None:
        # didn't have write access; try once more with the popular
        # misspelling
        newpath = access.haveAccess(
            config=cfg,
            user=user,
            mode='writeable',
            path=path)
        if newpath is not None:
            log.warning(
                'Repository %r config has typo "writeable", '
                +'should be "writable"',
                path,
                )

    if newpath is None:
        # didn't have write access

        newpath = access.haveAccess(
            config=cfg,
            user=user,
            mode='readonly',
            path=path)

        if newpath is None:
            raise ReadAccessDenied()

        if verb in COMMANDS_WRITE:
            # didn't have write access and tried to write
            raise WriteAccessDenied()

    (topdir, relpath) = newpath
    assert not relpath.endswith('.git'), \
           'git extension should have been stripped: %r' % relpath
    repopath = '%s.git' % relpath
    fullpath = os.path.join(topdir, repopath)
    if not os.path.exists(fullpath):
        # it doesn't exist on the filesystem, but the configuration
        # refers to it, we're serving a write request, and the user is
        # authorized to do that: create the repository on the fly

        # create leading directories
        p = topdir
        for segment in repopath.split(os.sep)[:-1]:
            p = os.path.join(p, segment)
            util.mkdir(p, 0750)

        repository.init(path=fullpath)
        gitweb.set_descriptions(
            config=cfg,
            )
        generated = util.getGeneratedFilesDir(config=cfg)
        gitweb.generate_project_list(
            config=cfg,
            path=os.path.join(generated, 'projects.list'),
            )
        gitdaemon.set_export_ok(
            config=cfg,
            )

    # put the verb back together with the new path
    newcmd = "%(verb)s '%(path)s'" % dict(
        verb=verb,
        path=fullpath,
        )
    return newcmd
Example #43
0
def serve(
    cfg,
    user,
    command,
):
    if '\n' in command:
        raise CommandMayNotContainNewlineError()

    try:
        verb, args = command.split(None, 1)
    except ValueError:
        # all known "git-foo" commands take one argument; improve
        # if/when needed
        raise UnknownCommandError()

    if verb == 'git':
        try:
            subverb, args = args.split(None, 1)
        except ValueError:
            # all known "git foo" commands take one argument; improve
            # if/when needed
            raise UnknownCommandError()
        verb = '%s %s' % (verb, subverb)

    if (verb not in COMMANDS_WRITE and verb not in COMMANDS_READONLY):
        raise UnknownCommandError()

    try:
        match = ALLOW_RE.match(unicode(args, 'utf-8'))
    except UnicodeDecodeError:
        raise UnsafeArgumentsError()

    if match is None:
        raise UnsafeArgumentsError()

    path = match.group('path')

    # admin access is always sufficient
    newpath = access.haveAccess(config=cfg, user=user, mode='admin', path=path)

    # write access is always sufficient
    if newpath is None:
        newpath = access.haveAccess(config=cfg,
                                    user=user,
                                    mode='write',
                                    path=path)

    if newpath is None:
        # didn't have write access

        newpath = access.haveAccess(config=cfg,
                                    user=user,
                                    mode='read',
                                    path=path)

        if newpath is None:
            raise ReadAccessDenied()

        if verb in COMMANDS_WRITE:
            # didn't have write access and tried to write
            raise WriteAccessDenied()

    (topdir, relpath, mode) = newpath
    assert not relpath.endswith('.git'), \
           'git extension should have been stripped: %r' % relpath
    repopath = '%s.git' % relpath
    fullpath = os.path.join(topdir, repopath)
    if not os.path.exists(fullpath) and verb in COMMANDS_WRITE:
        # it doesn't exist on the filesystem, but the configuration
        # refers to it, we're serving a write request, and the user is
        # authorized to do that: create the repository on the fly

        # If user not has admin permission, raise a Error
        if mode != 'admin':
            raise InitAccessDenied()

        # create leading directories
        p = topdir
        for segment in repopath.split(os.sep)[:-1]:
            p = os.path.join(p, segment)
            util.mkdir(p, 0755)

        repository.init(path=fullpath)

        # only update description of this repository
        gitweb.set_repo_descriptions(
            config=cfg,
            path=fullpath,
        )

        # not update projects.list here, but in gitosis-admin post-update

        # only update export flag of this repository
        gitdaemon.set_repo_export_ok(
            config=cfg,
            path=fullpath,
        )

    # put the verb back together with the new path
    newcmd = "%(verb)s '%(path)s'" % dict(
        verb=verb,
        path=fullpath,
    )
    return newcmd
Example #44
0
def test_has_initial_commit_no():
    tmp = maketemp()
    repository.init(path=tmp)
    got = repository.has_initial_commit(git_dir=tmp)
    eq(got, False)
Example #45
0
def test_init_simple():
    tmp = maketemp()
    path = os.path.join(tmp, 'repo.git')
    repository.init(path)
    check_mode(path, 0o750, is_dir=True)
    check_bare(path)
def test_post_update_simple():
    tmp = maketemp()
    repos = os.path.join(tmp, 'repositories')
    os.mkdir(repos)
    admin_repository = os.path.join(repos, 'gitosis-admin.git')
    pubkey = (
        'ssh-somealgo '
        +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
        +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
        +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
        +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= fakeuser@fakehost')
    user = '******'
    init.init_admin_repository(
        git_dir=admin_repository,
        pubkey=pubkey,
        user=user,
        )
    repository.init(path=os.path.join(repos, 'forweb.git'))
    repository.init(path=os.path.join(repos, 'fordaemon.git'))
    repository.fast_import(
        git_dir=admin_repository,
        committer='John Doe <*****@*****.**>',
        commit_msg="""\
stuff
""",
        parent='refs/heads/master^0',
        files=[
            ('gitosis.conf', """\
[gitosis]

[group gitosis-admin]
members = theadmin
writable = gitosis-admin

[repo fordaemon]
daemon = yes

[repo forweb]
gitweb = yes
owner = John Doe
description = blah blah
"""),
            ('keydir/jdoe.pub',
             'ssh-somealgo '
             +'0123456789ABCDEFBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'
             +'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'
             +'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'
             +'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB= [email protected]'),
            ],
        )
    cfg = RawConfigParser()
    cfg.add_section('gitosis')
    cfg.set('gitosis', 'repositories', repos)
    generated = os.path.join(tmp, 'generated')
    os.mkdir(generated)
    cfg.set('gitosis', 'generate-files-in', generated)
    ssh = os.path.join(tmp, 'ssh')
    os.mkdir(ssh)
    cfg.set(
        'gitosis',
        'ssh-authorized-keys-path',
        os.path.join(ssh, 'authorized_keys'),
        )
    run_hook.post_update(
        cfg=cfg,
        git_dir=admin_repository,
        )
    got = readFile(os.path.join(repos, 'forweb.git', 'description'))
    eq(got, 'blah blah\n')
    got = os.listdir(generated)
    eq(got, ['projects.list'])
    got = readFile(os.path.join(generated, 'projects.list'))
    eq(
        got,
        """\
forweb.git John+Doe
""",
        )
    got = os.listdir(os.path.join(repos, 'fordaemon.git'))
    assert 'git-daemon-export-ok' in got, \
        "git-daemon-export-ok not created: %r" % got
    got = os.listdir(ssh)
    eq(got, ['authorized_keys'])
    got = readFile(os.path.join(ssh, 'authorized_keys')).splitlines(True)
    assert 'command="gitosis-serve jdoe",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-somealgo 0123456789ABCDEFBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB= [email protected]\n' in got, \
        "SSH authorized_keys line for jdoe not found: %r" % got