# 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
# 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 = {
+# 'foo.com:/usr/share/nginx/www/fdroid',
+# 'bar.info:/var/www/fdroid',
+# }
# optionally specific which identity file to use when using rsync over SSH
if k in config:
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 config['serverwebroot'][-1] != '/':
- config['serverwebroot'] += '/'
- config['serverwebroot'] = config['serverwebroot'].replace('//', '/')
+ if isinstance(config['serverwebroot'], basestring):
+ roots = [config['serverwebroot']]
+ 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
logging.info(' skipping ' + s3url)
-def update_serverwebroot(repo_section):
+def update_serverwebroot(serverwebroot, repo_section):
rsyncargs = ['rsync', '--archive', '--delete']
if options.verbose:
rsyncargs += ['--verbose']
# serverwebroot is guaranteed to have a trailing slash in common.py
if subprocess.call(rsyncargs +
['--exclude', indexxml, '--exclude', indexjar,
- repo_section, config['serverwebroot']]) != 0:
+ repo_section, serverwebroot]) != 0:
sys.exit(1)
# use stricter checking on the indexes since they provide the signature
rsyncargs += ['--checksum']
- sectionpath = config['serverwebroot'] + repo_section
+ sectionpath = serverwebroot + repo_section
if subprocess.call(rsyncargs + [indexxml, sectionpath]) != 0:
sys.exit(1)
if subprocess.call(rsyncargs + [indexjar, sectionpath]) != 0:
else:
standardwebroot = True
- if config.get('serverwebroot'):
- serverwebroot = config['serverwebroot']
+ for serverwebroot in config.get('serverwebroot', []):
host, fdroiddir = serverwebroot.rstrip('/').split(':')
repobase = os.path.basename(fdroiddir)
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'
+ serverwebroot.rstrip('/') + '/fdroid\n\t'
+ serverwebroot.rstrip('/').rstrip(repobase) + 'fdroid')
os.mkdir('archive')
if args[0] == 'init':
- if config.get('serverwebroot'):
- ssh = paramiko.SSHClient()
- ssh.load_system_host_keys()
- sshstr, remotepath = config['serverwebroot'].rstrip('/').split(':')
+ ssh = paramiko.SSHClient()
+ ssh.load_system_host_keys()
+ for serverwebroot in config.get('serverwebroot', []):
+ sshstr, remotepath = serverwebroot.rstrip('/').split(':')
if sshstr.find('@') >= 0:
username, hostname = sshstr.split('@')
else:
sync_from_localcopy(repo_section, local_copy_dir)
else:
update_localcopy(repo_section, local_copy_dir)
- if config.get('serverwebroot'):
- update_serverwebroot(repo_section)
+ for serverwebroot in config.get('serverwebroot', []):
+ update_serverwebroot(serverwebroot, repo_section)
if config.get('awsbucket'):
update_awsbucket(repo_section)