Compare commits

...

14 commits

Author SHA1 Message Date
4bb3c5f107 change logging format for python 3 2021-10-31 12:12:59 +01:00
0934212421 change lineend for authorized_keys 2021-10-31 12:07:57 +01:00
f839d08232 change description of repositories 2021-10-31 12:02:28 +01:00
daadb52b9c change print for python3 2021-10-31 11:58:12 +01:00
a6205344b1 fix _levelNames error 2021-10-02 20:08:52 +02:00
1504a33496 Python 3 2021-10-02 19:50:36 +02:00
74adca7e7e Merge remote-tracking branch 'mgukov/master' 2021-10-02 19:41:20 +02:00
b005b18e89 Merge branch 'principals-with-host' 2019-10-29 11:25:50 +01:00
98be92f149 debug 2019-09-06 00:35:17 +02:00
9defb275d3 fix logging if GIT_DIR is none 2019-09-06 00:23:52 +02:00
2039e7fb10 Add sshd_config snippet for users not git
Added another snippet for sshd_config to use principal-files for users
which are NOT git. There you can also use another
AuthorizedPrincipalsCommand, if you want instead.
2019-08-28 09:17:18 +02:00
Michael Gukov
a5c8c2022b Python3 2018-12-17 01:47:01 +05:00
Michael
35a9a8a8ba Python3 2018-12-17 00:38:12 +05:00
Michael
aca25db85d Python 3 2018-12-11 12:38:41 +05:00
25 changed files with 108 additions and 81 deletions

2
.gitignore vendored
View file

@ -5,3 +5,5 @@
/apidocs
/gitosis/test/tmp
/.coverage
.idea
venv

View file

@ -24,7 +24,17 @@ more information.
You can get ``gitosis`` via ``git`` by saying::
git clone https://github.com/tv42/gitosis.git
This repositories are from jakob@schuerz.at, support python3 and ssh-certificates
git clone git@codeberg.org:xundeenergie/gitosis.git (fetch)
git clone git@github.com:xundeenergie/gitosis.git (fetch)
git clone git@git.schuerz.at:public/gitosis.git (fetch)
This repository translates gitosis to python3, but not fully.
git clone git@github.com:mgukov/gitosis.git (push)
Original repository seems unmaintained
git clone git@github.com:tv42/gitosis.git (fetch)
And install it via::
@ -216,6 +226,12 @@ To use principals and ssh-certificates with this fork of gitosis, please add thi
AuthorizedPrincipalsCommandUser git
AuthorizedPrincipalsCommand /usr/local/bin/gitosis-authorized-principals %i
And for all users except git, use only principal-files::
Match User !git,*
AuthorizedPrincipalsFile /etc/ssh/userprincipals/%u
This will run the command as user "git", which will you have installed, when you serve your gitrepos with gitosis.
%i is the key-identity of your certificate, which will you give on your sign-process to the user-certificate.

View file

@ -40,9 +40,9 @@
- can't trust "~"::
[0 tv@musti ~]$ sudo python -c 'import os; print os.path.expanduser("~")'
[0 tv@musti ~]$ sudo python -c 'import os; print(os.path.expanduser("~"))'
/home/tv
[0 tv@musti ~]$ sudo -H python -c 'import os; print os.path.expanduser("~")'
[0 tv@musti ~]$ sudo -H python -c 'import os; print(os.path.expanduser("~"))'
/root
- command line options

View file

@ -1,5 +1,5 @@
import os, logging
from ConfigParser import NoSectionError, NoOptionError
from configparser import NoSectionError, NoOptionError
from gitosis import group

View file

@ -3,7 +3,7 @@ import sys
import logging
import optparse
import errno
import ConfigParser
import configparser
log = logging.getLogger('gitosis.app')
@ -31,7 +31,7 @@ class App(object):
cfg = self.create_config(options)
try:
self.read_config(options, cfg)
except CannotReadConfigError, e:
except CannotReadConfigError as e:
log.error(str(e))
sys.exit(1)
self.setup_logging(cfg)
@ -53,13 +53,13 @@ class App(object):
return parser
def create_config(self, options):
cfg = ConfigParser.RawConfigParser()
cfg = configparser.RawConfigParser()
return cfg
def read_config(self, options, cfg):
try:
conffile = file(options.config)
except (IOError, OSError), e:
conffile = open(options.config)
except (IOError, OSError) as e:
if e.errno == errno.ENOENT:
# special case this because gitosis-init wants to
# ignore this particular error case
@ -74,12 +74,12 @@ class App(object):
def setup_logging(self, cfg):
try:
loglevel = cfg.get('gitosis', 'loglevel')
except (ConfigParser.NoSectionError,
ConfigParser.NoOptionError):
except (configparser.NoSectionError,
configparser.NoOptionError):
pass
else:
try:
symbolic = logging._levelNames[loglevel]
symbolic = logging._nameToLevel[loglevel]
except KeyError:
log.warning(
'Ignored invalid loglevel configuration: %r',

View file

@ -2,7 +2,7 @@ import errno
import logging
import os
from ConfigParser import NoSectionError, NoOptionError
from configparser import NoSectionError, NoOptionError
log = logging.getLogger('gitosis.gitdaemon')
@ -14,13 +14,13 @@ def export_ok_path(repopath):
def allow_export(repopath):
p = export_ok_path(repopath)
file(p, 'a').close()
open(p, 'a').close()
def deny_export(repopath):
p = export_ok_path(repopath)
try:
os.unlink(p)
except OSError, e:
except OSError as e:
if e.errno == errno.ENOENT:
pass
else:

View file

@ -27,7 +27,7 @@ To plug this into ``gitweb``, you have two choices.
import os, urllib, logging
from ConfigParser import NoSectionError, NoOptionError
from configparser import NoSectionError, NoOptionError
from gitosis import util
@ -91,8 +91,9 @@ def generate_project_list_fp(config, fp):
else:
response.append(owner)
line = ' '.join([urllib.quote_plus(s) for s in response])
print >>fp, line
line = ' '.join([urllib.parse.quote_plus(s) for s in response])
#print >>fp, line
print(line, end="", file=fp)
def generate_project_list(config, path):
"""
@ -106,7 +107,7 @@ def generate_project_list(config, path):
"""
tmp = '%s.%d.tmp' % (path, os.getpid())
f = file(tmp, 'w')
f = open(tmp, 'w')
try:
generate_project_list_fp(config=config, fp=f)
finally:
@ -157,9 +158,10 @@ def set_descriptions(config):
'description',
)
tmp = '%s.%d.tmp' % (path, os.getpid())
f = file(tmp, 'w')
f = open(tmp, 'w')
try:
print >>f, description
#print >>f, description
print(description, end="", file=f)
finally:
f.close()
os.rename(tmp, path)

View file

@ -1,5 +1,5 @@
import logging
from ConfigParser import NoSectionError, NoOptionError
from configparser import NoSectionError, NoOptionError
def _getMembership(config, user, seen):
log = logging.getLogger('gitosis.group.getMembership')

View file

@ -9,8 +9,8 @@ import sys
import re
from pkg_resources import resource_filename
from cStringIO import StringIO
from ConfigParser import RawConfigParser
from io import StringIO
from configparser import RawConfigParser
from gitosis import repository
from gitosis import run_hook
@ -68,7 +68,7 @@ def symlink_config(git_dir):
tmp = '%s.%d.tmp' % (dst, os.getpid())
try:
os.unlink(tmp)
except OSError, e:
except OSError as e:
if e.errno == errno.ENOENT:
pass
else:
@ -94,15 +94,18 @@ def init_admin_repository(
# can't rely on setuptools and all kinds of distro packaging to
# have kept our templates executable, it seems
os.chmod(os.path.join(git_dir, 'hooks', 'post-update'), 0755)
os.chmod(os.path.join(git_dir, 'hooks', 'post-update'), 0o755)
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
print('[gitosis]', file=cfg_file)
#print('', end="", file=cfg_file)
#print >>cfg_file, '[gitosis]'
#print >>cfg_file
cfg = RawConfigParser()
cfg.add_section('group gitosis-admin')
cfg.set('group gitosis-admin', 'members', user)
@ -133,7 +136,7 @@ class Main(app.App):
def handle_args(self, parser, cfg, options, args):
super(Main, self).handle_args(parser, cfg, options, args)
os.umask(0022)
os.umask(0o022)
log.info('Reading SSH public key...')
pubkey = read_ssh_pubkey()
@ -158,7 +161,7 @@ class Main(app.App):
user=user,
)
log.info('Running post-update hook...')
util.mkdir(os.path.expanduser('~/.ssh'), 0700)
util.mkdir(os.path.expanduser('~/.ssh'), 0o700)
run_hook.post_update(cfg=cfg, git_dir=admin_repository)
log.info('Symlinking ~/.gitosis.conf to repository...')
symlink_config(git_dir=admin_repository)

View file

@ -22,7 +22,7 @@ def serve_principal(cfg, sshUser, principals):
+'no-X11-forwarding,no-agent-forwarding,no-pty %(principals)s')
for p in util.getAllowedSSHPrincipals(config=cfg).split() :
print TEMPLATE % dict(user=sshUser.partition('@')[0], principals=p)
print(TEMPLATE % dict(user=sshUser.partition('@')[0], principals=p))
class Main(app.App):
def create_parser(self):

View file

@ -36,7 +36,7 @@ def init(
if _git is None:
_git = 'git'
util.mkdir(path, 0750)
util.mkdir(path, 0o750)
args = [
_git,
'--git-dir=.',
@ -131,7 +131,7 @@ class GitCheckoutIndexError(GitExportError):
def export(git_dir, path):
try:
os.mkdir(path)
except OSError, e:
except OSError as e:
if e.errno == errno.EEXIST:
pass
else:
@ -185,7 +185,7 @@ def has_initial_commit(git_dir):
stdout=subprocess.PIPE,
close_fds=True,
)
got = child.stdout.read()
got = child.stdout.read().decode('utf-8')
returncode = child.wait()
if returncode != 0:
raise GitRevParseError('exit status %d' % returncode)

View file

@ -19,7 +19,7 @@ def post_update(cfg, git_dir):
export = os.path.join(git_dir, 'gitosis-export')
try:
shutil.rmtree(export)
except OSError, e:
except OSError as e:
if e.errno == errno.ENOENT:
pass
else:
@ -63,16 +63,18 @@ class Main(app.App):
parser.error('Missing argument HOOK.')
log = logging.getLogger('gitosis.run_hook')
os.umask(0022)
os.umask(0o022)
git_dir = os.environ.get('GIT_DIR')
if git_dir is None:
log.error('Must have GIT_DIR set in enviroment')
sys.exit(1)
else:
log.debug("GIT_DIR %s".format(git_dir))
if hook == 'post-update':
log.info('Running hook %s', hook)
log.info('Running hook %s'.format(hook))
post_update(cfg, git_dir)
log.info('Done.')
else:
log.warning('Ignoring unknown hook: %r', hook)
log.warning('Ignoring unknown hook: %r'.format(hook))

View file

@ -141,7 +141,7 @@ def serve(
p = topdir
for segment in repopath.split(os.sep)[:-1]:
p = os.path.join(p, segment)
util.mkdir(p, 0750)
util.mkdir(p, 0o750)
repository.init(path=fullpath)
gitweb.set_descriptions(
@ -178,7 +178,7 @@ class Main(app.App):
parser.error('Missing argument USER.')
main_log = logging.getLogger('gitosis.serve.main')
os.umask(0022)
os.umask(0o022)
cmd = os.environ.get('SSH_ORIGINAL_COMMAND', None)
if cmd is None:
@ -197,7 +197,7 @@ class Main(app.App):
user=user,
command=cmd,
)
except ServingError, e:
except ServingError as e:
main_log.error('%s', e)
sys.exit(1)

View file

@ -25,7 +25,7 @@ def readKeys(keydir):
continue
path = os.path.join(keydir, filename)
f = file(path)
f = open(path)
for line in f:
line = line.rstrip('\n')
yield (basename, line)
@ -64,23 +64,25 @@ def writeAuthorizedKeys(path, keydir):
tmp = '%s.%d.tmp' % (path, os.getpid())
log.debug("writeAuthorizedKeys " + str(tmp) )
try:
in_ = file(path)
except IOError, e:
in_ = open(path)
except IOError as e:
if e.errno == errno.ENOENT:
in_ = None
else:
raise
try:
out = file(tmp, 'w')
out = open(tmp, 'w')
try:
if in_ is not None:
for line in filterAuthorizedKeys(in_):
print >>out, line
#print >>out, line
print(line, file=out)
keygen = readKeys(keydir)
for line in generateAuthorizedKeys(keygen):
print >>out, line
#print >>out, line
print(line, file=out)
os.fsync(out)
finally:

View file

@ -1,7 +1,7 @@
from nose.tools import eq_ as eq
import logging
from ConfigParser import RawConfigParser
from configparser import RawConfigParser
from gitosis import access

View file

@ -1,7 +1,7 @@
from nose.tools import eq_ as eq
import os
from ConfigParser import RawConfigParser
from configparser import RawConfigParser
from gitosis import gitdaemon
from gitosis.test.util import maketemp, writeFile

View file

@ -1,8 +1,8 @@
from nose.tools import eq_ as eq
import os
from ConfigParser import RawConfigParser
from cStringIO import StringIO
from configparser import RawConfigParser
from io import StringIO
from gitosis import gitweb
from gitosis.test.util import mkdir, maketemp, readFile, writeFile

View file

@ -1,6 +1,6 @@
from nose.tools import eq_ as eq, assert_raises
from ConfigParser import RawConfigParser
from configparser import RawConfigParser
from gitosis import group

View file

@ -2,7 +2,7 @@ from nose.tools import eq_ as eq
from gitosis.test.util import assert_raises, maketemp
import os
from ConfigParser import RawConfigParser
from configparser import RawConfigParser
from gitosis import init
from gitosis import repository
@ -113,7 +113,7 @@ def test_init_admin_repository():
'hooks',
'post-update',
)
util.check_mode(hook, 0755, is_file=True)
util.check_mode(hook, 0o755, is_file=True)
got = util.readFile(hook).splitlines()
assert 'gitosis-run-hook post-update' in got
export_dir = os.path.join(tmp, 'export')

View file

@ -23,17 +23,17 @@ def test_init_simple():
tmp = maketemp()
path = os.path.join(tmp, 'repo.git')
repository.init(path)
check_mode(path, 0750, is_dir=True)
check_mode(path, 0o750, is_dir=True)
check_bare(path)
def test_init_exist_dir():
tmp = maketemp()
path = os.path.join(tmp, 'repo.git')
mkdir(path, 0710)
check_mode(path, 0710, is_dir=True)
mkdir(path, 0o710)
check_mode(path, 0o710, is_dir=True)
repository.init(path)
# my weird access mode is preserved
check_mode(path, 0710, is_dir=True)
check_mode(path, 0o710, is_dir=True)
check_bare(path)
def test_init_exist_git():
@ -41,7 +41,7 @@ def test_init_exist_git():
path = os.path.join(tmp, 'repo.git')
repository.init(path)
repository.init(path)
check_mode(path, 0750, is_dir=True)
check_mode(path, 0o750, is_dir=True)
check_bare(path)
def test_init_templates():
@ -53,7 +53,7 @@ def test_init_templates():
)
# for reproducibility
os.umask(0022)
os.umask(0o022)
repository.init(path, template=templatedir)
repository.init(path)
@ -61,7 +61,7 @@ def test_init_templates():
eq(got, 'i should show up\n')
check_mode(
os.path.join(path, 'hooks', 'post-update'),
0755,
0o755,
is_file=True,
)
got = readFile(os.path.join(path, 'hooks', 'post-update'))
@ -91,7 +91,7 @@ PATH="${PATH#*:}"
exec git "$@"
''')
os.chmod(mockgit, 0755)
os.chmod(mockgit, 0o755)
magic_cookie = '%d' % random.randint(1, 100000)
good_path = os.environ['PATH']
try:
@ -130,7 +130,7 @@ PATH="${PATH#*:}"
exec git "$@"
''')
os.chmod(mockgit, 0755)
os.chmod(mockgit, 0o755)
magic_cookie = '%d' % random.randint(1, 100000)
good_path = os.environ['PATH']
try:
@ -226,7 +226,7 @@ PATH="${PATH#*:}"
exec git "$@"
''')
os.chmod(mockgit, 0755)
os.chmod(mockgit, 0o755)
repository.init(path=git_dir)
repository.fast_import(
git_dir=git_dir,
@ -301,7 +301,7 @@ PATH="${PATH#*:}"
exec git "$@"
''')
os.chmod(mockgit, 0755)
os.chmod(mockgit, 0o755)
repository.init(path=tmp)
repository.fast_import(
git_dir=tmp,

View file

@ -1,8 +1,8 @@
from nose.tools import eq_ as eq
import os
from ConfigParser import RawConfigParser
from cStringIO import StringIO
from configparser import RawConfigParser
from io import StringIO
from gitosis import init, repository, run_hook
from gitosis.test.util import maketemp, readFile

View file

@ -3,8 +3,8 @@ from gitosis.test.util import assert_raises
import logging
import os
from cStringIO import StringIO
from ConfigParser import RawConfigParser
from io import StringIO
from configparser import RawConfigParser
from gitosis import serve
from gitosis import repository
@ -354,7 +354,7 @@ def test_push_inits_subdir_parent_missing():
)
eq(os.listdir(repositories), ['foo'])
foo = os.path.join(repositories, 'foo')
util.check_mode(foo, 0750, is_dir=True)
util.check_mode(foo, 0o750, is_dir=True)
eq(os.listdir(foo), ['bar.git'])
assert os.path.isfile(os.path.join(repositories, 'foo', 'bar.git', 'HEAD'))
@ -366,7 +366,7 @@ def test_push_inits_subdir_parent_exists():
os.mkdir(repositories)
foo = os.path.join(repositories, 'foo')
# silly mode on purpose; not to be touched
os.mkdir(foo, 0751)
os.mkdir(foo, 0o751)
cfg.set('gitosis', 'repositories', repositories)
generated = os.path.join(tmp, 'generated')
os.mkdir(generated)
@ -380,7 +380,7 @@ def test_push_inits_subdir_parent_exists():
command="git-receive-pack 'foo/bar.git'",
)
eq(os.listdir(repositories), ['foo'])
util.check_mode(foo, 0751, is_dir=True)
util.check_mode(foo, 0o751, is_dir=True)
eq(os.listdir(foo), ['bar.git'])
assert os.path.isfile(os.path.join(repositories, 'foo', 'bar.git', 'HEAD'))

View file

@ -1,7 +1,7 @@
from nose.tools import eq_ as eq, assert_raises
import os
from cStringIO import StringIO
from io import StringIO
from gitosis import ssh
from gitosis.test.util import mkdir, maketemp, writeFile, readFile
@ -171,7 +171,7 @@ class WriteAuthorizedKeys_Test(object):
def test_simple(self):
tmp = maketemp()
path = os.path.join(tmp, 'authorized_keys')
f = file(path, 'w')
f = open(path, 'w')
try:
f.write('''\
# foo

View file

@ -9,7 +9,7 @@ import sys
def mkdir(*a, **kw):
try:
os.mkdir(*a, **kw)
except OSError, e:
except OSError as e:
if e.errno == errno.EEXIST:
pass
else:
@ -27,7 +27,7 @@ def maketemp():
tmp = os.path.join(tmp, name)
try:
shutil.rmtree(tmp)
except OSError, e:
except OSError as e:
if e.errno == errno.ENOENT:
pass
else:
@ -37,7 +37,7 @@ def maketemp():
def writeFile(path, content):
tmp = '%s.tmp' % path
f = file(tmp, 'w')
f = open(tmp, 'w')
try:
f.write(content)
finally:
@ -45,7 +45,7 @@ def writeFile(path, content):
os.rename(tmp, path)
def readFile(path):
f = file(path)
f = open(path)
try:
data = f.read()
finally:
@ -58,7 +58,7 @@ def assert_raises(excClass, callableObj, *args, **kwargs):
"""
try:
callableObj(*args, **kwargs)
except excClass, e:
except excClass as e:
return e
else:
if hasattr(excClass,'__name__'): excName = excClass.__name__

View file

@ -1,11 +1,11 @@
import errno
import os
from ConfigParser import NoSectionError, NoOptionError
from configparser import NoSectionError, NoOptionError
def mkdir(*a, **kw):
try:
os.mkdir(*a, **kw)
except OSError, e:
except OSError as e:
if e.errno == errno.EEXIST:
pass
else: