support lists/tuples in 'serverwebroot' config item

This allows the user to specify multiple servers to put the repo to, and
`fdroid server update` will automatically push to them all.

fixes #22 https://gitlab.com/fdroid/fdroidserver/issues/22
This commit is contained in:
Hans-Christoph Steiner 2014-07-14 15:03:58 -04:00
parent 35ee4b1bc5
commit 8c8fb8b156
3 changed files with 32 additions and 18 deletions

View file

@ -102,9 +102,15 @@ keyaliases['com.example.another.plugin'] = '@com.example.another'
# rsync/ssh format for a remote host/path. This is used for syncing a locally # rsync/ssh format for a remote host/path. This is used for syncing a locally
# generated repo to the server that is it hosted on. It must end in the # generated repo to the server that is it hosted on. It must end in the
# standard public repo name of "/fdroid", but can be in up to three levels of # standard public repo name of "/fdroid", but can be in up to three levels of
# sub-directories (i.e. /var/www/packagerepos/fdroid). # sub-directories (i.e. /var/www/packagerepos/fdroid). You can include
# multiple servers to sync to by wrapping the whole thing in {} or [], and
# including the serverwebroot strings in a comma-separated list.
# #
# serverwebroot = 'user@example:/var/www/fdroid' # serverwebroot = 'user@example:/var/www/fdroid'
# serverwebroot = {
# 'foo.com:/usr/share/nginx/www/fdroid',
# 'bar.info:/var/www/fdroid',
# }
# optionally specific which identity file to use when using rsync over SSH # optionally specific which identity file to use when using rsync over SSH

View file

@ -168,12 +168,21 @@ def read_config(opts, config_file='config.py'):
if k in config: if k in config:
config[k] = clean_description(config[k]) config[k] = clean_description(config[k])
# since this is used with rsync, where trailing slashes have meaning,
# ensure there is always a trailing slash
if 'serverwebroot' in config: if 'serverwebroot' in config:
if config['serverwebroot'][-1] != '/': if isinstance(config['serverwebroot'], basestring):
config['serverwebroot'] += '/' roots = [config['serverwebroot']]
config['serverwebroot'] = config['serverwebroot'].replace('//', '/') elif all(isinstance(item, basestring) for item in config['serverwebroot']):
roots = config['serverwebroot']
else:
raise TypeError('only accepts strings, lists, and tuples')
rootlist = []
for rootstr in roots:
# since this is used with rsync, where trailing slashes have
# meaning, ensure there is always a trailing slash
if rootstr[-1] != '/':
rootstr += '/'
rootlist.append(rootstr.replace('//', '/'))
config['serverwebroot'] = rootlist
return config return config

View file

@ -116,7 +116,7 @@ def update_awsbucket(repo_section):
logging.info(' skipping ' + s3url) logging.info(' skipping ' + s3url)
def update_serverwebroot(repo_section): def update_serverwebroot(serverwebroot, repo_section):
rsyncargs = ['rsync', '--archive', '--delete'] rsyncargs = ['rsync', '--archive', '--delete']
if options.verbose: if options.verbose:
rsyncargs += ['--verbose'] rsyncargs += ['--verbose']
@ -131,11 +131,11 @@ def update_serverwebroot(repo_section):
# serverwebroot is guaranteed to have a trailing slash in common.py # serverwebroot is guaranteed to have a trailing slash in common.py
if subprocess.call(rsyncargs + if subprocess.call(rsyncargs +
['--exclude', indexxml, '--exclude', indexjar, ['--exclude', indexxml, '--exclude', indexjar,
repo_section, config['serverwebroot']]) != 0: repo_section, serverwebroot]) != 0:
sys.exit(1) sys.exit(1)
# use stricter checking on the indexes since they provide the signature # use stricter checking on the indexes since they provide the signature
rsyncargs += ['--checksum'] rsyncargs += ['--checksum']
sectionpath = config['serverwebroot'] + repo_section sectionpath = serverwebroot + repo_section
if subprocess.call(rsyncargs + [indexxml, sectionpath]) != 0: if subprocess.call(rsyncargs + [indexxml, sectionpath]) != 0:
sys.exit(1) sys.exit(1)
if subprocess.call(rsyncargs + [indexjar, sectionpath]) != 0: if subprocess.call(rsyncargs + [indexjar, sectionpath]) != 0:
@ -202,12 +202,11 @@ def main():
else: else:
standardwebroot = True standardwebroot = True
if config.get('serverwebroot'): for serverwebroot in config.get('serverwebroot', []):
serverwebroot = config['serverwebroot']
host, fdroiddir = serverwebroot.rstrip('/').split(':') host, fdroiddir = serverwebroot.rstrip('/').split(':')
repobase = os.path.basename(fdroiddir) repobase = os.path.basename(fdroiddir)
if standardwebroot and repobase != 'fdroid': if standardwebroot and repobase != 'fdroid':
logging.error('serverwebroot does not end with "fdroid", ' logging.error('serverwebroot path does not end with "fdroid", '
+ 'perhaps you meant one of these:\n\t' + 'perhaps you meant one of these:\n\t'
+ serverwebroot.rstrip('/') + '/fdroid\n\t' + serverwebroot.rstrip('/') + '/fdroid\n\t'
+ serverwebroot.rstrip('/').rstrip(repobase) + 'fdroid') + serverwebroot.rstrip('/').rstrip(repobase) + 'fdroid')
@ -257,10 +256,10 @@ def main():
os.mkdir('archive') os.mkdir('archive')
if args[0] == 'init': if args[0] == 'init':
if config.get('serverwebroot'): ssh = paramiko.SSHClient()
ssh = paramiko.SSHClient() ssh.load_system_host_keys()
ssh.load_system_host_keys() for serverwebroot in config.get('serverwebroot', []):
sshstr, remotepath = config['serverwebroot'].rstrip('/').split(':') sshstr, remotepath = serverwebroot.rstrip('/').split(':')
if sshstr.find('@') >= 0: if sshstr.find('@') >= 0:
username, hostname = sshstr.split('@') username, hostname = sshstr.split('@')
else: else:
@ -285,8 +284,8 @@ def main():
sync_from_localcopy(repo_section, local_copy_dir) sync_from_localcopy(repo_section, local_copy_dir)
else: else:
update_localcopy(repo_section, local_copy_dir) update_localcopy(repo_section, local_copy_dir)
if config.get('serverwebroot'): for serverwebroot in config.get('serverwebroot', []):
update_serverwebroot(repo_section) update_serverwebroot(serverwebroot, repo_section)
if config.get('awsbucket'): if config.get('awsbucket'):
update_awsbucket(repo_section) update_awsbucket(repo_section)