import glob
import subprocess
import re
+import resource
import tarfile
import traceback
import time
# Helper to copy the contents of a directory to the server...
def send_dir(path):
logging.debug("rsyncing " + path + " to " + ftp.getcwd())
- subprocess.check_call(['rsync', '-rple',
- 'ssh -o StrictHostKeyChecking=no' +
- ' -o UserKnownHostsFile=/dev/null' +
- ' -o LogLevel=FATAL' +
- ' -o IdentitiesOnly=yes' +
- ' -o PasswordAuthentication=no' +
- ' -p ' + str(sshinfo['port']) +
- ' -i ' + sshinfo['idfile'],
- path,
- sshinfo['user'] +
- "@" + sshinfo['hostname'] +
- ":" + ftp.getcwd()])
+ # TODO this should move to `vagrant rsync` from >= v1.5
+ try:
+ subprocess.check_output(['rsync', '--recursive', '--perms', '--links', '--quiet', '--rsh=' +
+ 'ssh -o StrictHostKeyChecking=no' +
+ ' -o UserKnownHostsFile=/dev/null' +
+ ' -o LogLevel=FATAL' +
+ ' -o IdentitiesOnly=yes' +
+ ' -o PasswordAuthentication=no' +
+ ' -p ' + str(sshinfo['port']) +
+ ' -i ' + sshinfo['idfile'],
+ path,
+ sshinfo['user'] + "@" + sshinfo['hostname'] + ":" + ftp.getcwd()],
+ stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError as e:
+ raise FDroidException(str(e), e.output.decode())
logging.info("Preparing server for build...")
serverpath = os.path.abspath(os.path.dirname(__file__))
path)
+def _get_build_timestamp():
+ return time.strftime("%Y-%m-%d %H:%M:%SZ", time.gmtime())
+
+
def transform_first_char(string, method):
"""Uses method() on the first character of string."""
if len(string) == 0:
raise BuildException("Error running sudo command for %s:%s" %
(app.id, build.versionName), p.output)
+ p = FDroidPopen(['sudo', 'passwd', '--lock', 'root'])
+ if p.returncode != 0:
+ raise BuildException("Error locking root account for %s:%s" %
+ (app.id, build.versionName), p.output)
+
+ p = FDroidPopen(['sudo', 'SUDO_FORCE_REMOVE=yes', 'dpkg', '--purge', 'sudo'])
+ if p.returncode != 0:
+ raise BuildException("Error removing sudo for %s:%s" %
+ (app.id, build.versionName), p.output)
+
log_path = os.path.join(log_dir,
common.get_toolsversion_logname(app, build))
with open(log_path, 'w') as f:
if server:
# When using server mode, still keep a local cache of the repo, by
# grabbing the source now.
- vcs.gotorevision(build.commit)
+ vcs.gotorevision(build.commit, refresh)
build_server(app, build, vcs, build_dir, output_dir, log_dir, force)
else:
options = None
config = None
buildserverid = None
+starttime = _get_build_timestamp()
def main():
# Read all app and srclib metadata
pkgs = common.read_pkg_args(options.appid, True)
- allapps = metadata.read_metadata(not options.onserver, pkgs)
+ allapps = metadata.read_metadata(not options.onserver, pkgs, options.refresh, sort_by_time=True)
apps = common.read_app_args(options.appid, allapps, True)
for appid, app in list(apps.items()):
if not apps:
raise FDroidException("No apps to process.")
+ # make sure enough open files are allowed to process everything
+ soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
+ if len(apps) > soft:
+ try:
+ soft = len(apps) * 2
+ if soft > hard:
+ soft = hard
+ resource.setrlimit(resource.RLIMIT_NOFILE, (soft, hard))
+ logging.debug(_('Set open file limit to {integer}')
+ .format(integer=soft))
+ except (OSError, ValueError) as e:
+ logging.warning(_('Setting open file limit failed: ') + str(e))
+
if options.latest:
for app in apps.values():
for build in reversed(app.builds):
# Build applications...
failed_apps = {}
build_succeeded = []
+ max_apps_per_run = 10
for appid, app in apps.items():
+ max_apps_per_run -= 1
+ if max_apps_per_run < 1:
+ break
first = True
for build in app.builds:
wikilog = None
+ build_starttime = _get_build_timestamp()
tools_version_log = ''
if not options.onserver:
tools_version_log = get_android_tools_version_log(build.ndk_path())
# there are any.
if first:
vcs, build_dir = common.setup_vcs(app)
- logging.info("Using %s" % vcs.clientversion())
first = False
+ logging.info("Using %s" % vcs.clientversion())
logging.debug("Checking " + build.versionName)
if trybuild(app, build, build_dir, output_dir, log_dir,
also_check_dir, srclib_dir, extlib_dir,
f.write('versionCode: %s\nversionName: %s\ncommit: %s\n' %
(build.versionCode, build.versionName, build.commit))
f.write('Build completed at '
- + time.strftime("%Y-%m-%d %H:%M:%SZ", time.gmtime()) + '\n')
+ + _get_build_timestamp() + '\n')
f.write('\n' + tools_version_log + '\n')
f.write(str(e))
logging.error("Could not build app %s: %s" % (appid, e))
newpage = site.Pages[lastbuildpage]
with open(os.path.join('tmp', 'fdroidserverid')) as fp:
fdroidserverid = fp.read().rstrip()
- txt = "* build completed at " + time.strftime("%Y-%m-%d %H:%M:%SZ", time.gmtime()) + '\n' \
+ txt = "* build session started at " + starttime + '\n' \
+ + "* this build started at " + build_starttime + '\n' \
+ + "* this build completed at " + _get_build_timestamp() + '\n' \
+ '* fdroidserverid: [https://gitlab.com/fdroid/fdroidserver/commit/' \
+ fdroidserverid + ' ' + fdroidserverid + ']\n\n'
if options.onserver:
logging.info(ngettext("{} build failed",
"{} builds failed", len(failed_apps)).format(len(failed_apps)))
- sys.exit(0)
+ # hack to ensure this exits, even is some threads are still running
+ sys.stdout.flush()
+ sys.stderr.flush()
+ os._exit(0)
if __name__ == "__main__":