1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-07-07 01:40:10 +02:00
fdroidserver/makebuildserver
Hans-Christoph Steiner 8d66742dd7 makebuildserver: set debian mirror in config file only
Setting it in the config file was not working, and right now, all of the
options are in the config file and not as command line flags, so remove
--debian-mirror to keep that consistent.
2016-01-26 11:31:40 +01:00

450 lines
19 KiB
Python
Executable File

#!/usr/bin/env python2
import os
import sys
import subprocess
import time
import hashlib
from optparse import OptionParser
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()
# set up default config
cachedir = os.path.join(os.getenv('HOME'), '.cache', 'fdroidserver')
config = {
'arch64': False,
'basebox': 'jessie32',
# TODO in py3, convert this to pathlib.Path(absolute_path_string).as_uri()
'baseboxurl': [
'file://' + os.path.join(cachedir, 'jessie32.box'),
'https://f-droid.org/jessie32.box',
],
'cachedir': cachedir,
'cpus': 1,
'memory': 3584,
}
# load config file, if present
if os.path.exists('makebuildserver.config.py'):
execfile('makebuildserver.config.py', config)
elif os.path.exists('makebs.config.py'):
# this is the old name for the config file
execfile('makebs.config.py', config)
if not os.path.exists('makebuildserver') 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 = config['cachedir']
if not os.path.exists(cachedir):
os.makedirs(cachedir, 0755)
cachefiles = [
('android-sdk_r24.4.1-linux.tgz',
'https://dl.google.com/android/android-sdk_r24.4.1-linux.tgz',
'e16917ad685c1563ccbc5dd782930ee1a700a1b6a6fd3e44b83ac694650435e9'),
('android-platform-3.zip',
'https://dl.google.com/android/repository/android-1.5_r04-linux.zip',
'85b6c8f9797e56aa415d3a282428bb640c96b0acb17c11d41621bb2a5302fe64'),
('android-platform-4.zip',
'https://dl.google.com/android/repository/android-1.6_r03-linux.zip',
'a8c4e3b32269c6b04c2adeabd112fce42f292dab1a40ef3b08ea7d4212be0df4'),
('android-platform-5.zip',
'https://dl.google.com/android/repository/android-2.0_r01-linux.zip',
'e70e2151b49613f23f40828c771ab85e241eed361cab037c6312df77f2612f0a'),
('android-platform-6.zip',
'https://dl.google.com/android/repository/android-2.0.1_r01-linux.zip',
'f47b46177b17f6368461f85bc2a27d0d2c437929f588ea27105712bc3185f664'),
('android-platform-7.zip',
'https://dl.google.com/android/repository/android-2.1_r03-linux.zip',
'b9cc140a9b879586181b22cfc7d4aa18b979251e16e9b17771c5d0acb71ba940'),
('android-platform-8.zip',
'https://dl.google.com/android/repository/android-2.2_r03-linux.zip',
'7c9ea1bd7cb225504bd085d7c93ae27d52bd88d29b621d28108f82fef68177c0'),
('android-platform-9.zip',
'https://dl.google.com/android/repository/android-2.3.1_r02-linux.zip',
'b2ab4896d0a4857e4f688f69eb08b0e1a8074709d4445a92a83ece7ec7cd198c'),
('android-platform-10.zip',
'https://dl.google.com/android/repository/android-2.3.3_r02-linux.zip',
'54bdb0f1ca06ba5747061ddeea20f431af72c448334fd4d3d7f84ea2ccd29fea'),
('android-platform-11.zip',
'https://dl.google.com/android/repository/android-3.0_r02-linux.zip',
'1cacae7b6e1b5a5d73c06f5d29d2ea92d16674df8fd5507681290e77d1647a1c'),
('android-platform-12.zip',
'https://dl.google.com/android/repository/android-3.1_r03-linux.zip',
'7570c86a86488a146aa2141a65a24d81800959c1907ff4f1d2c13bbafab230c5'),
('android-platform-13.zip',
'https://dl.google.com/android/repository/android-3.2_r01-linux.zip',
'ff6b26ad34d7060a72ba504b0314cef8ba3138005561705adec5ad470a073d9b'),
('android-platform-14.zip',
'https://dl.google.com/android/repository/android-14_r04.zip',
'da1af15c77ba41d062eb6d0ef5921cc424ab6167587033b830609d65f04802b6'),
('android-platform-15.zip',
'https://dl.google.com/android/repository/android-15_r05.zip',
'5bc1f93aae86b4336ffc4cae9eb8ec41a9a8fd677582dd86a9629798f019bed9'),
('android-platform-16.zip',
'https://dl.google.com/android/repository/android-16_r05.zip',
'fd7f269a423d1f1d079eabf9f918ceab49108702a1c6bb2589d57c23393503d3'),
('android-platform-17.zip',
'https://dl.google.com/android/repository/android-17_r03.zip',
'b66e73fb2639f8c916fde4369aa29012a5c531e156dbb205fe3788fe998fbbe8'),
('android-platform-18.zip',
'https://dl.google.com/android/repository/android-18_r03.zip',
'166ae9cf299747a5faa8f04168f0ee47cd7466a975d8b44acaaa62a43e767568'),
('android-platform-19.zip',
'https://dl.google.com/android/repository/android-19_r04.zip',
'5efc3a3a682c1d49128daddb6716c433edf16e63349f32959b6207524ac04039'),
('android-platform-20.zip',
'https://dl.google.com/android/repository/android-20_r02.zip',
'ef08c453e16ab6e656cf5d9413ef61cb8c650607d33b24ee4ce08dafdfe965a7'),
('android-platform-21.zip',
'https://dl.google.com/android/repository/android-21_r02.zip',
'a76cd7ad3080ac6ce9f037cb935b399a1bad396c0605d4ff42f693695f1dcefe'),
('android-platform-22.zip',
'https://dl.google.com/android/repository/android-22_r02.zip',
'45eb581bbe53c9256f34c26b2cea919543c0079140897ac721cf88c0b9f6789e'),
('android-platform-23.zip',
'https://dl.google.com/android/repository/android-23_r01.zip',
'16e828bec35521f5529c998a6d312aaa6155cd4aabb5507d9eb2d4b3c9a1aff0'),
('build-tools-17.0.0.zip',
'https://dl.google.com/android/repository/build-tools_r17-linux.zip',
'4c8444972343a19045236f6924bd7f12046287c70dace96ab88b2159c8ec0e74'),
('build-tools-18.0.1.zip',
'https://dl.google.com/android/repository/build-tools_r18.0.1-linux.zip',
'a9b7b1bdfd864780fdd03fa1683f3fe712a4276cf200646833808cb9159bafc0'),
('build-tools-18.1.0.zip',
'https://dl.google.com/android/repository/build-tools_r18.1-linux.zip',
'0753606738f31cc346426db1d46b7d021bc1bdaff63085f9ee9d278ee054d3c9'),
('build-tools-18.1.1.zip',
'https://dl.google.com/android/repository/build-tools_r18.1.1-linux.zip',
'7e4ed326b53078f4f23276ddab52c400011f7593dfbb6508c0a6671954dba8b0'),
('build-tools-19.0.0.zip',
'https://dl.google.com/android/repository/build-tools_r19-linux.zip',
'9442e1c5212ed594e344a231fa93e7a017a5ef8cc661117011f1d3142eca7acc'),
('build-tools-19.0.1.zip',
'https://dl.google.com/android/repository/build-tools_r19.0.1-linux.zip',
'b068edaff05c3253a63e9c8f0e1786429799b7e4b01514a847a8b291beb9232e'),
('build-tools-19.0.2.zip',
'https://dl.google.com/android/repository/build-tools_r19.0.2-linux.zip',
'06124fad0d4bde21191240d61df2059a8546c085064a9a57d024c36fa2c9bebb'),
('build-tools-19.0.3.zip',
'https://dl.google.com/android/repository/build-tools_r19.0.3-linux.zip',
'bc9b3db0de4a3e233a170274293359051a758f1e3f0d0d852ff4ad6d90d0a794'),
('build-tools-19.1.0.zip',
'https://dl.google.com/android/repository/build-tools_r19.1-linux.zip',
'3833b409f78c002a83244e220be380ea6fa44d604e0d47de4b7e5daefe7cd3f4'),
('build-tools-20.0.0.zip',
'https://dl.google.com/android/repository/build-tools_r20-linux.zip',
'296e09d62095d80e6eaa06a64cfa4c6f9f317c2d67ad8da6514523ec66f5c871'),
('build-tools-21.0.0.zip',
'https://dl.google.com/android/repository/build-tools_r21-linux.zip',
'12b818f38fe1b68091b94545988317438efbf41eb61fd36b72cd79f536044065'),
('build-tools-21.0.1.zip',
'https://dl.google.com/android/repository/build-tools_r21.0.1-linux.zip',
'a8922e80d3dd0cf6df14b29a7862448fa111b48086c639168d4b18c92431f559'),
('build-tools-21.0.2.zip',
'https://dl.google.com/android/repository/build-tools_r21.0.2-linux.zip',
'859b17a6b65d063dfd86c163489b736b12bdeecd9173fdddb3e9f32e0fe584b7'),
('build-tools-21.1.0.zip',
'https://dl.google.com/android/repository/build-tools_r21.1-linux.zip',
'022a85b92360272379b2f04b8a4d727e754dbe7eb8ab5a9568190e33e480d8f1'),
('build-tools-21.1.1.zip',
'https://dl.google.com/android/repository/build-tools_r21.1.1-linux.zip',
'29b612484de6b5cde0df6de655e413f7611b0557b440538397afa69b557e2f08'),
('build-tools-21.1.2.zip',
'https://dl.google.com/android/repository/build-tools_r21.1.2-linux.zip',
'3f88efc2d5316fb73f547f35b472610eed5e6f3f56762750ddad1c7d1d81660d'),
('build-tools-22.0.0.zip',
'https://dl.google.com/android/repository/build-tools_r22-linux.zip',
'061c021243f04c80c19568a6e3a027c00d8e269c9311d7bf07fced60fbde7bd5'),
('build-tools-22.0.1.zip',
'https://dl.google.com/android/repository/build-tools_r22.0.1-linux.zip',
'91e5524bf227aad1135ddd10905518ac49f74797d33d48920dcf8364b9fde214'),
('build-tools-23.0.0.zip',
'https://dl.google.com/android/repository/build-tools_r23-linux.zip',
'56bf4fc6c43638c55fef4a0937bad38281945725459841879b436c6922df786c'),
('build-tools-23.0.1.zip',
'https://dl.google.com/android/repository/build-tools_r23.0.1-linux.zip',
'e56b3ef7b760ad06a7cee9b2d52ba7f43133dcecedfa5357f8845b3a80aeeecf'),
('build-tools-23.0.2.zip',
'https://dl.google.com/android/repository/build-tools_r23.0.2-linux.zip',
'82754f551a6e36eaf516fbdd00c95ff0ccd19f81d1e134125b6ac4916f7ed9b6'),
# the binaries that Google uses are here:
# https://android.googlesource.com/platform/tools/external/gradle/+/studio-1.5/
('gradle-1.4-bin.zip',
'https://services.gradle.org/distributions/gradle-1.4-bin.zip',
'cd99e85fbcd0ae8b99e81c9992a2f10cceb7b5f009c3720ef3a0078f4f92e94e'),
('gradle-1.6-bin.zip',
'https://services.gradle.org/distributions/gradle-1.6-bin.zip',
'de3e89d2113923dcc2e0def62d69be0947ceac910abd38b75ec333230183fac4'),
('gradle-1.7-bin.zip',
'https://services.gradle.org/distributions/gradle-1.7-bin.zip',
'360c97d51621b5a1ecf66748c718594e5f790ae4fbc1499543e0c006033c9d30'),
('gradle-1.8-bin.zip',
'https://services.gradle.org/distributions/gradle-1.8-bin.zip',
'a342bbfa15fd18e2482287da4959588f45a41b60910970a16e6d97959aea5703'),
('gradle-1.9-bin.zip',
'https://services.gradle.org/distributions/gradle-1.9-bin.zip',
'097ddc2bcbc9da2bb08cbf6bf8079585e35ad088bafd42e8716bc96405db98e9'),
('gradle-1.10-bin.zip',
'https://services.gradle.org/distributions/gradle-1.10-bin.zip',
'6e6db4fc595f27ceda059d23693b6f6848583950606112b37dfd0e97a0a0a4fe'),
('gradle-1.11-bin.zip',
'https://services.gradle.org/distributions/gradle-1.11-bin.zip',
'07e235df824964f0e19e73ea2327ce345c44bcd06d44a0123d29ab287fc34091'),
('gradle-1.12-bin.zip',
'https://services.gradle.org/distributions/gradle-1.12-bin.zip',
'8734b13a401f4311ee418173ed6ca8662d2b0a535be8ff2a43ecb1c13cd406ea'),
('gradle-2.1-bin.zip',
'https://services.gradle.org/distributions/gradle-2.1-bin.zip',
'3eee4f9ea2ab0221b89f8e4747a96d4554d00ae46d8d633f11cfda60988bf878'),
('gradle-2.2.1-bin.zip',
'https://services.gradle.org/distributions/gradle-2.2.1-bin.zip',
'420aa50738299327b611c10b8304b749e8d3a579407ee9e755b15921d95ff418'),
('gradle-2.3-bin.zip',
'https://services.gradle.org/distributions/gradle-2.3-bin.zip',
'010dd9f31849abc3d5644e282943b1c1c355f8e2635c5789833979ce590a3774'),
('gradle-2.4-bin.zip',
'https://services.gradle.org/distributions/gradle-2.4-bin.zip',
'c4eaecc621a81f567ded1aede4a5ddb281cc02a03a6a87c4f5502add8fc2f16f'),
('gradle-2.5-bin.zip',
'https://services.gradle.org/distributions/gradle-2.5-bin.zip',
'3f953e0cb14bb3f9ebbe11946e84071547bf5dfd575d90cfe9cc4e788da38555'),
('gradle-2.6-bin.zip',
'https://services.gradle.org/distributions/gradle-2.6-bin.zip',
'18a98c560af231dfa0d3f8e0802c20103ae986f12428bb0a6f5396e8f14e9c83'),
('gradle-2.7-bin.zip',
'https://services.gradle.org/distributions/gradle-2.7-bin.zip',
'cde43b90945b5304c43ee36e58aab4cc6fb3a3d5f9bd9449bb1709a68371cb06'),
('gradle-2.8-bin.zip',
'https://services.gradle.org/distributions/gradle-2.8-bin.zip',
'a88db9c2f104defdaa8011c58cf6cda6c114298ae3695ecfb8beb30da3a903cb'),
('gradle-2.9-bin.zip',
'https://services.gradle.org/distributions/gradle-2.9-bin.zip',
'c9159ec4362284c0a38d73237e224deae6139cbde0db4f0f44e1c7691dd3de2f'),
('gradle-2.10-bin.zip',
'https://services.gradle.org/distributions/gradle-2.10-bin.zip',
'66406247f745fc6f05ab382d3f8d3e120c339f34ef54b86f6dc5f6efc18fbb13'),
('Kivy-1.7.2.tar.gz',
'https://pypi.python.org/packages/source/K/Kivy/Kivy-1.7.2.tar.gz',
'0485e2ef97b5086df886eb01f8303cb542183d2d71a159466f99ad6c8a1d03f1'),
]
if config['arch64']:
cachefiles.extend([
('android-ndk-r10e-linux-x86_64.bin',
'https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin',
'102d6723f67ff1384330d12c45854315d6452d6510286f4e5891e00a5a8f1d5a'),
('android-ndk-r9b-linux-x86_64.tar.bz2',
'https://dl.google.com/android/ndk/android-ndk-r9b-linux-x86_64.tar.bz2',
'8956e9efeea95f49425ded8bb697013b66e162b064b0f66b5c75628f76e0f532'),
('android-ndk-r9b-linux-x86_64-legacy-toolchains.tar.bz2',
'https://dl.google.com/android/ndk/android-ndk-r9b-linux-x86_64-legacy-toolchains.tar.bz2',
'de93a394f7c8f3436db44568648f87738a8d09801a52f459dcad3fc047e045a1')])
else:
cachefiles.extend([
('android-ndk-r10e-linux-x86.bin',
'https://dl.google.com/android/ndk/android-ndk-r10e-linux-x86.bin',
'92b07d25aaad9b341a7f2b2a62402d508e948bf2dea3ee7b65a6aeb18bca7df5'),
('android-ndk-r9b-linux-x86.tar.bz2',
'https://dl.google.com/android/ndk/android-ndk-r9b-linux-x86.tar.bz2',
'748104b829dd12afb2fdb3044634963abb24cdb0aad3b26030abe2e9e65bfc81'),
('android-ndk-r9b-linux-x86-legacy-toolchains.tar.bz2',
'https://dl.google.com/android/ndk/android-ndk-r9b-linux-x86-legacy-toolchains.tar.bz2',
'606aadf815ae28cc7b0154996247c70d609f111b14e44bcbcd6cad4c87fefb6f')])
wanted = []
def sha256_for_file(path):
with open(path, 'r') as f:
s = hashlib.sha256()
while True:
data = f.read(4096)
if not data:
break
s.update(data)
return s.hexdigest()
for f, src, shasum in cachefiles:
relpath = os.path.join(cachedir, f)
# if download fails to connect, it'll make a zero size file
if os.path.exists(relpath) and os.stat(relpath).st_size == 0:
os.remove(relpath)
if not os.path.exists(relpath):
print "Downloading " + f + " to cache"
if subprocess.call(['wget', src, '-O', f], cwd=cachedir) != 0:
print "...download of " + f + " failed."
sys.exit(1)
if shasum:
v = sha256_for_file(relpath)
if v != shasum:
print "Invalid shasum of '" + v + "' detected for " + f
sys.exit(1)
else:
print "...shasum verified for " + f
wanted.append(f)
# allow specifying a list/tuple that includes cached local copy
if type(config['baseboxurl']) in (list, tuple) or config['baseboxurl'][0] in ('(', '['):
baseboxurl = config['baseboxurl']
else:
baseboxurl = '"{0}"'.format(config['baseboxurl'])
# Generate an appropriate Vagrantfile for the buildserver, based on our
# settings...
vagrantfile = """
Vagrant.configure("2") do |config|
if Vagrant.has_plugin?("vagrant-cachier")
config.cache.scope = :box
config.cache.auto_detect = false
config.cache.enable :apt
config.cache.enable :chef
end
config.vm.box = "{0}"
config.vm.box_url = {1}
config.vm.provider "virtualbox" do |v|
v.customize ["modifyvm", :id, "--memory", "{2}"]
v.customize ["modifyvm", :id, "--cpus", "{3}"]
end
config.vm.provision :shell, :path => "fixpaths.sh"
""".format(config['basebox'],
baseboxurl,
config['memory'],
config.get('cpus', 1))
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",
:debian_mirror => "%s",
:user => "vagrant"
}
}
chef.add_recipe "fdroidbuild-general"
chef.add_recipe "android-sdk"
chef.add_recipe "android-ndk"
chef.add_recipe "gradle"
chef.add_recipe "kivy"
end
end
""" % (config['debian_mirror'])
# 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', '--provision'], 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,
printout=options.verbose)
print "Adding box"
vagrant(['box', 'add', 'buildserver', boxfile, '-f'],
printout=options.verbose)
os.remove(boxfile)