mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-11-14 02:50:12 +01:00
aa98a8d64a
The ID of the buildserver is just the corresponding commit hash in fdroidserver at the point where it was built, which should be enough to uniquely identify a version of it. The idea is that this will ultimately end up as metadata in an apk, such that its precise lineage can be traced, and the exact same binary can be reproduced.
201 lines
6.6 KiB
Python
Executable File
201 lines
6.6 KiB
Python
Executable File
#!/usr/bin/env python2
|
|
|
|
import os
|
|
import sys
|
|
import subprocess
|
|
import time
|
|
from optparse import OptionParser
|
|
from fdroidserver import common
|
|
|
|
def vagrant(params, cwd=None, printout=False):
|
|
"""Run vagrant.
|
|
|
|
:param: list of parameters to pass to vagrant
|
|
:cwd: directory to run in, or None for current directory
|
|
:printout: True to print output in realtime, False to just
|
|
return it
|
|
:returns: (ret, out) where ret is the return code, and out
|
|
is the stdout (and stderr) from vagrant
|
|
"""
|
|
p = subprocess.Popen(['vagrant'] + params, cwd=cwd,
|
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
out = ''
|
|
if printout:
|
|
while True:
|
|
line = p.stdout.readline()
|
|
if len(line) == 0:
|
|
break
|
|
print line,
|
|
out += line
|
|
p.wait()
|
|
else:
|
|
out = p.communicate()[0]
|
|
return (p.returncode, out)
|
|
|
|
boxfile = 'buildserver.box'
|
|
serverdir = 'buildserver'
|
|
|
|
parser = OptionParser()
|
|
parser.add_option("-v", "--verbose", action="store_true", default=False,
|
|
help="Spew out even more information than normal")
|
|
parser.add_option("-c", "--clean", action="store_true", default=False,
|
|
help="Build from scratch, rather than attempting to update the existing server")
|
|
options, args = parser.parse_args()
|
|
|
|
config = common.read_config(options, 'makebs.config.py')
|
|
|
|
if not os.path.exists('makebuildserver.py') or not os.path.exists(serverdir):
|
|
print 'This must be run from the correct directory!'
|
|
sys.exit(1)
|
|
|
|
if os.path.exists(boxfile):
|
|
os.remove(boxfile)
|
|
|
|
if options.clean:
|
|
vagrant(['destroy', '-f'], cwd=serverdir, printout=options.verbose)
|
|
|
|
# Update cached files.
|
|
cachedir = os.path.join('buildserver', 'cache')
|
|
if not os.path.exists(cachedir):
|
|
os.mkdir(cachedir)
|
|
cachefiles = [
|
|
('android-sdk_r22.3-linux.tgz',
|
|
'http://dl.google.com/android/android-sdk_r22.3-linux.tgz',
|
|
'4077575c98075480e0156c10e48a1521e31c7952768271a206870e6813057f4f'),
|
|
('gradle-1.8-bin.zip',
|
|
'http://services.gradle.org/distributions/gradle-1.8-bin.zip',
|
|
'a342bbfa15fd18e2482287da4959588f45a41b60910970a16e6d97959aea5703')]
|
|
if config['arch64']:
|
|
cachefiles.extend([
|
|
('android-ndk-r9-linux-x64_64.tar.bz2',
|
|
'http://dl.google.com/android/ndk/android-ndk-r9-linux-x86_64.tar.bz2',
|
|
'8a6013bfd8a8709592c53086c4f841933f5f2b175dd030326406d24ff4daa267'),
|
|
('android-ndk-r9-linux-x86_64-legacy-toolchains.tar.bz2',
|
|
'http://dl.google.com/android/ndk/android-ndk-r9-linux-x86_64-legacy-toolchains.tar.bz2',
|
|
'087fbca38a1a2c1a309de272d22e84bbc1c3e2254211761180572fde75faab27')])
|
|
else:
|
|
cachefiles.extend([
|
|
('android-ndk-r9-linux-x86.tar.bz2',
|
|
'http://dl.google.com/android/ndk/android-ndk-r9-linux-x86.tar.bz2',
|
|
'30f3da01e4d8d3415777b5d88a0b70fac5a4620807fd28110f9bc4c8093f6b6e'),
|
|
('android-ndk-r9-linux-x86-legacy-toolchains.tar.bz2',
|
|
'http://dl.google.com/android/ndk/android-ndk-r9-linux-x86-legacy-toolchains.tar.bz2',
|
|
'26b94f0a5d686b4892cb22b06094751efded0958baed380b2ccce56517fd830b')])
|
|
wanted = []
|
|
for f, src, shasum in cachefiles:
|
|
if not os.path.exists(os.path.join(cachedir, f)):
|
|
print "Downloading " + f + " to cache"
|
|
if subprocess.call(['wget', src], cwd=cachedir) != 0:
|
|
print "...download of " + f + " failed."
|
|
sys.exit(1)
|
|
if shasum:
|
|
p = subprocess.Popen(['shasum', '-a', '256', os.path.join(cachedir, f)],
|
|
stdout=subprocess.PIPE)
|
|
v = p.communicate()[0].split(' ')[0]
|
|
if v != shasum:
|
|
print "Invalid shasum of '" + v + "' detected for " + f
|
|
sys.exit(1)
|
|
else:
|
|
print "...shasum verified for " + f
|
|
|
|
wanted.append(f)
|
|
|
|
|
|
# Generate an appropriate Vagrantfile for the buildserver, based on our
|
|
# settings...
|
|
vagrantfile = """
|
|
Vagrant::Config.run do |config|
|
|
|
|
config.vm.box = "{0}"
|
|
config.vm.box_url = "{1}"
|
|
|
|
config.vm.customize ["modifyvm", :id, "--memory", "{2}"]
|
|
|
|
config.vm.provision :shell, :path => "fixpaths.sh"
|
|
""".format(config['basebox'], config['baseboxurl'], config['memory'])
|
|
if 'aptproxy' in config and config['aptproxy']:
|
|
vagrantfile += """
|
|
config.vm.provision :shell, :inline => 'sudo echo "Acquire::http {{ Proxy \\"{0}\\"; }};" > /etc/apt/apt.conf.d/02proxy && sudo apt-get update'
|
|
""".format(config['aptproxy'])
|
|
vagrantfile += """
|
|
config.vm.provision :chef_solo do |chef|
|
|
chef.cookbooks_path = "cookbooks"
|
|
chef.log_level = :debug
|
|
chef.json = {
|
|
:settings => {
|
|
:sdk_loc => "/home/vagrant/android-sdk",
|
|
:ndk_loc => "/home/vagrant/android-ndk",
|
|
:user => "vagrant"
|
|
}
|
|
}
|
|
chef.add_recipe "fdroidbuild-general"
|
|
chef.add_recipe "android-sdk"
|
|
chef.add_recipe "android-ndk"
|
|
end
|
|
end
|
|
"""
|
|
|
|
# Check against the existing Vagrantfile, and if they differ, we need to
|
|
# create a new box:
|
|
vf = os.path.join(serverdir, 'Vagrantfile')
|
|
writevf = True
|
|
if os.path.exists(vf):
|
|
vagrant(['halt'], serverdir)
|
|
with open(vf, 'r') as f:
|
|
oldvf = f.read()
|
|
if oldvf != vagrantfile:
|
|
print "Server configuration has changed, rebuild from scratch is required"
|
|
vagrant(['destroy', '-f'], serverdir)
|
|
else:
|
|
print "Re-provisioning existing server"
|
|
writevf = False
|
|
else:
|
|
print "No existing server - building from scratch"
|
|
if writevf:
|
|
with open(vf, 'w') as f:
|
|
f.write(vagrantfile)
|
|
|
|
|
|
print "Configuring build server VM"
|
|
returncode, out = vagrant(['up'], serverdir, printout=True)
|
|
with open(os.path.join(serverdir, 'up.log'), 'w') as log:
|
|
log.write(out)
|
|
if returncode != 0:
|
|
print "Failed to configure server"
|
|
sys.exit(1)
|
|
|
|
print "Writing buildserver ID"
|
|
p = subprocess.Popen(['git', 'rev-parse', 'HEAD'], stdout=subprocess.PIPE)
|
|
buildserverid = p.communicate()[0].strip()
|
|
print "...ID is " + buildserverid
|
|
subprocess.call(
|
|
['vagrant', 'ssh', '-c', 'sh -c "echo {0} >/home/vagrant/buildserverid"'
|
|
.format(buildserverid)],
|
|
cwd=serverdir)
|
|
|
|
print "Stopping build server VM"
|
|
vagrant(['halt'], serverdir)
|
|
|
|
print "Waiting for build server VM to be finished"
|
|
ready = False
|
|
while not ready:
|
|
time.sleep(2)
|
|
returncode, out = vagrant(['status'], serverdir)
|
|
if returncode != 0:
|
|
print "Error while checking status"
|
|
sys.exit(1)
|
|
for line in out.splitlines():
|
|
if line.startswith("default"):
|
|
if line.find("poweroff") != -1:
|
|
ready = True
|
|
else:
|
|
print "Status: " + line
|
|
|
|
print "Packaging"
|
|
vagrant(['package', '--output', os.path.join('..', boxfile)], serverdir)
|
|
print "Adding box"
|
|
vagrant(['box', 'add', 'buildserver', boxfile, '-f'])
|
|
|
|
os.remove(boxfile)
|
|
|