server: 'local_copy_dir' config/options to automate offline repo signing

This allows a dir to be specified in config.py that `fdroid server update`
will automatically rsync the repo to.  The idea is that the path would
point to an SD card on a fully offline machine that serves as the secure
repo signing machine.
This commit is contained in:
Hans-Christoph Steiner 2014-06-26 11:57:40 -04:00
parent 0ee6fc8c22
commit d73b43c5fc
3 changed files with 112 additions and 5 deletions

View file

@ -140,6 +140,20 @@ def update_serverwebroot(repo_section):
sys.exit(1)
def update_localcopy(repo_section, local_copy_dir):
rsyncargs = ['rsync', '--update', '--recursive', '--delete']
# use stricter rsync checking on all files since people using offline mode
# are already prioritizing security above ease and speed
rsyncargs += ['--checksum']
if options.verbose:
rsyncargs += ['--verbose']
if options.quiet:
rsyncargs += ['--quiet']
# local_copy_dir is guaranteed to have a trailing slash in main() below
if subprocess.call(rsyncargs + [repo_section, local_copy_dir]) != 0:
sys.exit(1)
def main():
global config, options
@ -147,6 +161,8 @@ def main():
parser = OptionParser()
parser.add_option("-i", "--identity-file", default=None,
help="Specify an identity file to provide to SSH for rsyncing")
parser.add_option("--local-copy-dir", default=None,
help="Specify a local folder to sync the repo to")
parser.add_option("-v", "--verbose", action="store_true", default=False,
help="Spew out even more information than normal")
parser.add_option("-q", "--quiet", action="store_true", default=False,
@ -171,15 +187,49 @@ def main():
if config.get('serverwebroot'):
serverwebroot = config['serverwebroot']
host, fdroiddir = serverwebroot.rstrip('/').split(':')
serverrepobase = os.path.basename(fdroiddir)
if serverrepobase != 'fdroid' and standardwebroot:
repobase = os.path.basename(fdroiddir)
if standardwebroot and repobase != 'fdroid':
logging.error('serverwebroot does not end with "fdroid", '
+ 'perhaps you meant one of these:\n\t'
+ serverwebroot.rstrip('/') + '/fdroid\n\t'
+ serverwebroot.rstrip('/').rstrip(serverrepobase) + 'fdroid')
+ serverwebroot.rstrip('/').rstrip(repobase) + 'fdroid')
sys.exit(1)
elif not config.get('awsbucket'):
logging.warn('No serverwebroot or awsbucket set! Edit your config.py to set one or both.')
if options.local_copy_dir is not None:
local_copy_dir = options.local_copy_dir
elif config.get('local_copy_dir'):
local_copy_dir = config['local_copy_dir']
else:
local_copy_dir = None
if local_copy_dir is not None:
fdroiddir = local_copy_dir.rstrip('/')
if os.path.exists(fdroiddir) and not os.path.isdir(fdroiddir):
logging.error('local_copy_dir must be directory, not a file!')
sys.exit(1)
if not os.path.exists(os.path.dirname(fdroiddir)):
logging.error('The root dir for local_copy_dir "'
+ os.path.dirname(fdroiddir)
+ '" does not exist!')
sys.exit(1)
if not os.path.isabs(fdroiddir):
logging.error('local_copy_dir must be an absolute path!')
sys.exit(1)
repobase = os.path.basename(fdroiddir)
if standardwebroot and repobase != 'fdroid':
logging.error('local_copy_dir does not end with "fdroid", '
+ 'perhaps you meant: ' + fdroiddir + '/fdroid')
sys.exit(1)
if local_copy_dir[-1] != '/':
local_copy_dir += '/'
local_copy_dir = local_copy_dir.replace('//', '/')
if not os.path.exists(fdroiddir):
os.mkdir(fdroiddir)
if not config.get('awsbucket') \
and not config.get('serverwebroot') \
and local_copy_dir is None:
logging.warn('No serverwebroot, local_copy_dir, or awsbucket set!'
+ 'Edit your config.py to set at least one.')
sys.exit(1)
repo_sections = ['repo']
@ -205,6 +255,8 @@ def main():
update_serverwebroot(repo_section)
if config.get('awsbucket'):
update_awsbucket(repo_section)
if local_copy_dir is not None:
update_localcopy(repo_section, local_copy_dir)
sys.exit(0)