chiark / gitweb /
Externalise makebuildserver config variables
[fdroidserver.git] / makebuildserver.py
1 #!/usr/bin/python
2
3 import os
4 import sys
5 import subprocess
6 import time
7
8 execfile('makebs.config.py', globals())
9
10 def vagrant(params, cwd=None, printout=False):
11     """Run vagrant.
12
13     :param: list of parameters to pass to vagrant
14     :cwd: directory to run in, or None for current directory
15     :printout: True to print output in realtime, False to just
16                return it
17     :returns: (ret, out) where ret is the return code, and out
18                is the stdout (and stderr) from vagrant
19     """
20     p = subprocess.Popen(['vagrant'] + params, cwd=cwd,
21             stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
22     out = ''
23     if printout:
24         while True:
25             line = p.stdout.readline()
26             if len(line) == 0:
27                 break
28             print line,
29             out += line
30         p.wait()
31     else:
32         out = p.communicate()[0]
33     return (p.returncode, out)
34
35 boxfile = 'buildserver.box'
36 serverdir = 'buildserver'
37
38 if not os.path.exists('makebuildserver.py') or not os.path.exists(serverdir):
39     print 'This must be run from the correct directory!'
40     sys.exit(1)
41
42 if os.path.exists(boxfile):
43     os.remove(boxfile)
44
45
46 # Update cached files.
47 cachedir = os.path.join('buildserver', 'cache')
48 if not os.path.exists(cachedir):
49     os.mkdir(cachedir)
50 cachefiles = [
51     ('android-sdk_r21.0.1-linux.tgz',
52      'http://dl.google.com/android/android-sdk_r21.0.1-linux.tgz')]
53 if arch64:
54     cachefiles.extend([
55     ('android-ndk-r8e-linux-x86_64.tar.bz2',
56      'http://dl.google.com/android/ndk/android-ndk-r8e-linux-x86_64.tar.bz2')])
57 else:
58     cachefiles.extend([
59     ('android-ndk-r8e-linux-x86.tar.bz2',
60      'http://dl.google.com/android/ndk/android-ndk-r8e-linux-x86.tar.bz2')])
61 wanted = []
62 for f, src in cachefiles:
63     if not os.path.exists(os.path.join(cachedir, f)):
64         print "Downloading " + f + " to cache"
65         if subprocess.call(['wget', src], cwd=cachedir) != 0:
66             print "...download of " + f + " failed."
67             sys.exit(1)
68     wanted.append(f)
69
70
71 # Generate an appropriate Vagrantfile for the buildserver, based on our
72 # settings...
73 vagrantfile = """
74 Vagrant::Config.run do |config|
75
76   config.vm.box = "{0}"
77   config.vm.box_url = "{1}"
78
79   config.vm.customize ["modifyvm", :id, "--memory", "{2}"]
80
81   config.vm.provision :shell, :path => "fixpaths.sh"
82 """.format(basebox, baseboxurl, memory)
83 if aptproxy:
84     vagrantfile += """
85   config.vm.provision :shell, :inline => 'sudo echo "Acquire::http {{ Proxy \\"{0}\\"; }};" > /etc/apt/apt.conf.d/02proxy && sudo apt-get update'
86 """.format(aptproxy)
87 vagrantfile += """
88   config.vm.provision :chef_solo do |chef|
89     chef.cookbooks_path = "cookbooks"
90     chef.log_level = :debug 
91     chef.json = {
92       :settings => {
93         :sdk_loc => "/home/vagrant/android-sdk",
94         :ndk_loc => "/home/vagrant/android-ndk",
95         :user => "vagrant"
96       }
97     }
98     chef.add_recipe "fdroidbuild-general"
99     chef.add_recipe "android-sdk"
100     chef.add_recipe "android-ndk"
101   end
102 end
103 """
104
105 # Check against the existing Vagrantfile, and if they differ, we need to
106 # create a new box:
107 vf = os.path.join(serverdir, 'Vagrantfile')
108 writevf = True
109 if os.path.exists(vf):
110     vagrant(['halt'], serverdir)
111     with open(vf, 'r') as f:
112         oldvf = f.read()
113     if oldvf != vagrantfile:
114         print "Server configuration has changed, rebuild from scratch is required"
115         vagrant(['destroy', '-f'], serverdir)
116     else:
117         print "Re-provisioning existing server"
118         writevf = False
119 else:
120     print "No existing server - building from scratch"
121 if writevf:
122     with open(vf, 'w') as f:
123         f.write(vagrantfile)
124
125
126 print "Configuring build server VM"
127 returncode, out = vagrant(['up'], serverdir, printout=True)
128 with open(os.path.join(serverdir, 'up.log'), 'w') as log:
129     log.write(out)
130 if returncode != 0:
131     print "Failed to configure server"
132     sys.exit(1)
133 print "Stopping build server VM"
134 vagrant(['halt'], serverdir)
135
136 print "Waiting for build server VM to be finished"
137 ready = False
138 while not ready:
139     time.sleep(2)
140     returncode, out = vagrant(['status'], serverdir)
141     if returncode != 0:
142         print "Error while checking status"
143         sys.exit(1)
144     for line in out.splitlines():
145         if line.startswith("default"):
146             if line.find("poweroff") != -1:
147                 ready = True
148             else:
149                 print "Status: " + line
150
151 print "Packaging"
152 vagrant(['package', '--output', os.path.join('..', boxfile)], serverdir)
153 print "Adding box"
154 vagrant(['box', 'add', 'buildserver', boxfile, '-f'])
155
156 os.remove(boxfile)
157