blob: 567f4d061c29fbd6e759558931c2d473a7dc429d [file] [log] [blame]
Fathi Boudracd8f58d2012-06-15 17:43:39 +03001#!/usr/bin/python
2
Andy Doan15aa23b2012-02-02 16:40:58 -06003# Copyright (C) 2012 Linaro
4#
5# Author: Andy Doan <andy.doan@linaro.org>
6#
7# This file is part of Linaro Daily Prebuilt Images.
8#
9# Linaro Daily Prebuilt Images is free software; you can redistribute it and/or
10# modify it under the terms of the GNU General Public License
11# as published by the Free Software Foundation; either version 2
12# of the License, or (at your option) any later version.
13#
14# Linaro Daily Prebuilt Images is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with Linaro Image Tools; if not, write to the Free Software
21# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22# USA.
23
Andy Doanfccf4842012-03-08 10:42:19 -060024from linaro_fetch_image import fetch_image
Andy Doan15aa23b2012-02-02 16:40:58 -060025from linaro_image_tools import cmd_runner
26
Andy Doan8ff38f02012-02-20 16:32:37 -060027import crawler
28
Andy Doan15aa23b2012-02-02 16:40:58 -060029import argparse
30import bz2
31import datetime
Ricardo Salveti de Araujob39eb802012-06-23 00:55:31 -030032import time
Andy Doan3634c472012-04-17 12:50:58 -050033import hashlib
Andy Doanc6500af2012-03-15 14:44:39 -050034import os
Andy Doan15aa23b2012-02-02 16:40:58 -060035import re
Andy Doane449bce2012-03-21 15:22:31 -050036import urlparse
Andy Doan35ee9dc2012-05-11 01:10:12 -050037import string
Andy Doan4202d882012-03-29 21:36:09 -050038import sys
Andy Doan15aa23b2012-02-02 16:40:58 -060039
Andy Doanea2e1ea2012-04-23 11:56:29 -050040class HwPack:
41 def __init__(self, lmcname, eula=False, pre_inst_script=None):
42 self.lmcname = lmcname
43 if eula:
44 self.eula = 'EULA.txt'
45 else:
Andy Doan4aabf022012-04-26 14:30:29 -050046 self.eula = 'OPEN-EULA.txt'
Andy Doanea2e1ea2012-04-23 11:56:29 -050047 self.pre_inst_script = pre_inst_script
48
49 def do_eula(self, imgfile):
50 fname = '%s/%s' % (os.path.dirname(imgfile), self.eula)
51 with file(fname, 'a'):
52 pass #just need the file to exist
53
Andy Doan15aa23b2012-02-02 16:40:58 -060054# a mapping of hwpack name to l-m-c name
55HWPACKS = {
Andy Doanea2e1ea2012-04-23 11:56:29 -050056 'beagleboard': HwPack('beagle'),
57 'overo': HwPack('overo'),
58 'lt-panda': HwPack('panda'),
Andy Doan7a8cc102012-04-26 09:25:33 -050059 'lt-panda-x11-base': HwPack('panda'),
Andy Doanea2e1ea2012-04-23 11:56:29 -050060 'lt-mx5': HwPack('mx53loco'),
61 'lt-mx6': HwPack('mx6qsabrelite'),
Andy Doan490f6202012-04-25 10:56:08 -050062 'lt-origen': HwPack('origen'),
63 'leb-origen': HwPack('origen'),
Andy Doanea2e1ea2012-04-23 11:56:29 -050064 'lt-snowball': HwPack('snowball_sd', True, 'ste-preinstall.sh'),
65 'lt-snowball-x11-base': HwPack('snowball_sd', True, 'ste-preinstall.sh'),
Andy Doanedffb5d2012-04-25 11:22:19 -050066 'vexpress': HwPack('vexpress'),
Andy Doanea2e1ea2012-04-23 11:56:29 -050067 'efikamx': HwPack('efikamx'),
68 'igep': HwPack('igep'),
Andy Doan15aa23b2012-02-02 16:40:58 -060069}
70# a mapping of binary image to its image_file size
71BINARIES = {
Andy Doan4202d882012-03-29 21:36:09 -050072 # release images
Andy Doan08485da2012-05-31 22:24:29 +080073 'nano': '1G', #512 is big enough, but this gives us free disk space
Andy Doan4202d882012-03-29 21:36:09 -050074 'alip': '2G',
75 'ubuntu-desktop': '3G',
76 'linarotv-xbmc': '3G',
Andy Doan15aa23b2012-02-02 16:40:58 -060077}
78
Andy Doan15aa23b2012-02-02 16:40:58 -060079def today():
80 d = datetime.date.today()
81 return "%d%02d%02d" % (d.year, d.month, d.day)
82
Ricardo Salveti de Araujob39eb802012-06-23 00:55:31 -030083def download(dm, url):
84 print "INFO: Fetching", url
85 before = time.time()
86 dfile = dm.download(url, None, verbose=False)
87 delta_min, delta_secs = divmod(int(time.time() - before), 60)
88 print "INFO: Downloaded file '%s' in %d min(s) and %d sec(s)" % (
89 dfile, delta_min, delta_secs)
90 return dfile
91
Andy Doan15aa23b2012-02-02 16:40:58 -060092def compress_image(imgfile):
Ricardo Salveti de Araujoba7dacf2012-06-23 01:08:24 -030093 print "INFO: compressing %s" % imgfile
Andy Doan15aa23b2012-02-02 16:40:58 -060094 args = ('bzip2', imgfile)
95 cmd_runner.run(args).wait()
Andy Doan23ce4e12012-03-21 12:46:21 -050096 return '%s.bz2' % imgfile
97
98def zsync_image(imgfile):
Ricardo Salveti de Araujoba7dacf2012-06-23 01:08:24 -030099 print "INFO: making zsync file for %s" % imgfile
Andy Doan23ce4e12012-03-21 12:46:21 -0500100 args = ('zsyncmake', '-o', '%s.zsync'%imgfile, imgfile)
101 cmd_runner.run(args).wait()
Andy Doan15aa23b2012-02-02 16:40:58 -0600102
Andy Doan3634c472012-04-17 12:50:58 -0500103def md5sum(fname):
104 md5 = hashlib.md5()
105 with open(fname, 'rb') as f:
106 while True:
107 data = f.read(4096)
108 if not data: break
109 md5.update(data)
110 return md5.hexdigest()
111
Ricardo Salveti de Araujob93a7ec2012-05-29 14:07:53 -0300112def create_image_info(infofile, bz2file, binary_file, hwpack_url, rootfs_url):
113 ''' prints out the md5sum and hwpack/rootfs info for the given image
Andy Doan3634c472012-04-17 12:50:58 -0500114 '''
Ricardo Salveti de Araujoba7dacf2012-06-23 01:08:24 -0300115 print "INFO: building image info for: %s" % bz2file
Andy Doan3634c472012-04-17 12:50:58 -0500116 md5 = md5sum(bz2file)
117
118 binary_file = os.path.basename(binary_file)
Andy Doan35ee9dc2012-05-11 01:10:12 -0500119 tfile = '%s/image_info_template.html' % os.path.dirname(__file__)
Andy Doan3634c472012-04-17 12:50:58 -0500120
Andy Doan35ee9dc2012-05-11 01:10:12 -0500121 tmpl = None
122 with open(tfile) as f:
123 buff = f.read()
124 tmpl = string.Template(buff)
125
126 title = 'Pre-Built Image Info'
Ricardo Salveti de Araujob93a7ec2012-05-29 14:07:53 -0300127
128 # build hwpack manifest and rootfs packages links
129 hwpack_re = re.search(r'(hwpack_linaro.*\d\w*)(.*)$', hwpack_url)
130 hwpack_name = "".join(hwpack_re.groups())
131 hwpack_manifest = hwpack_name + '.manifest.txt'
132 hwpack_manifest_url = re.sub('.tar.gz$', '.manifest.txt', hwpack_url)
133
134 rootfs_re = re.search(r'(linaro-.*\d)(.*)$', rootfs_url)
135 rootfs_name = "".join(rootfs_re.groups())
136 rootfs_packages = rootfs_name + '.packages'
137 rootfs_packages_url = re.sub('.tar.gz$', '.packages', rootfs_url)
138
Ricardo Salveti de Araujo894040a2012-05-29 14:07:55 -0300139 # try to get information from Jenkins, if available
140 jenkins_buildn = os.environ.get('BUILD_NUMBER') or 'Not Found'
141 jenkins_build_url = os.environ.get('BUILD_URL') or 'http://ci.linaro.org'
142
Ricardo Salveti de Araujob93a7ec2012-05-29 14:07:53 -0300143 buff = tmpl.substitute(
144 title=title, md5=md5, image_name=os.path.basename(bz2file),
145 hwpack_name=hwpack_name, hwpack_url=hwpack_url,
146 rootfs_name=rootfs_name, rootfs_url=rootfs_url,
147 hwpack_manifest_name=hwpack_manifest,
148 hwpack_manifest_url=hwpack_manifest_url,
149 rootfs_packages_name=rootfs_packages,
Ricardo Salveti de Araujo894040a2012-05-29 14:07:55 -0300150 rootfs_packages_url=rootfs_packages_url,
151 jenkins_buildn=jenkins_buildn,
152 jenkins_build_url=jenkins_build_url)
Andy Doan3c0c3892012-04-25 11:09:53 -0500153 with open(infofile, 'w') as f:
Andy Doan35ee9dc2012-05-11 01:10:12 -0500154 f.write(buff)
Andy Doan3634c472012-04-17 12:50:58 -0500155
Andy Doanb00dbc02012-03-15 16:23:06 -0500156def build_image(lmc, imgfile, hwpack, hwpack_file, binary, binary_file):
Ricardo Salveti de Araujoba7dacf2012-06-23 01:08:24 -0300157 print "INFO: building image: %s" % imgfile
Andy Doanea2e1ea2012-04-23 11:56:29 -0500158 hwpi = HWPACKS[hwpack]
Andy Doan15aa23b2012-02-02 16:40:58 -0600159 size = BINARIES[binary]
160
Andy Doanc6500af2012-03-15 14:44:39 -0500161 args = [lmc,
Andy Doanea2e1ea2012-04-23 11:56:29 -0500162 '--dev', hwpi.lmcname,
Andy Doan15aa23b2012-02-02 16:40:58 -0600163 '--image_file', imgfile,
164 '--image_size', size,
165 '--hwpack-force-yes',
166 '--hwpack', hwpack_file,
167 '--binary', binary_file,
Andy Doanc6500af2012-03-15 14:44:39 -0500168 ]
169
Andy Doanea2e1ea2012-04-23 11:56:29 -0500170 if hwpi.pre_inst_script is not None:
Andy Doanc6500af2012-03-15 14:44:39 -0500171 sdir = os.path.abspath(os.path.dirname(__file__))
Andy Doanea2e1ea2012-04-23 11:56:29 -0500172 script = "%s/%s" % (sdir, hwpi.pre_inst_script)
Andy Doanc6500af2012-03-15 14:44:39 -0500173 print "using presintall script: %s" % script
174 args.append('--preinstall-script')
175 args.append(script)
176
Ricardo Salveti de Araujoba7dacf2012-06-23 01:08:24 -0300177 print "INFO: running l-m-c:", " ".join([str(arg) for arg in args])
178
Andy Doanea2e1ea2012-04-23 11:56:29 -0500179 hwpi.do_eula(imgfile)
Andy Doan15aa23b2012-02-02 16:40:58 -0600180 cmd_runner.run(args, as_root=True).wait()
Andy Doan15aa23b2012-02-02 16:40:58 -0600181
Andy Doan184cd3b2012-03-29 22:20:02 -0500182class SnapshotCrawler:
Ricardo Salveti de Araujo0352cb92012-06-22 21:48:34 -0300183 def __init__(self, platform, hwpacks, binaries):
Andy Doan184cd3b2012-03-29 22:20:02 -0500184 self.platform = platform
185 self.hwpacks = hwpacks
186 self.binaries = binaries
Andy Doane449bce2012-03-21 15:22:31 -0500187
Andy Doan184cd3b2012-03-29 22:20:02 -0500188 def get_binaries(self):
189 '''return a hash table of binary->url'''
190 binaryf = {}
191 for binary in self.binaries:
Andy Doan540a4b12012-04-17 11:48:11 -0500192 url = 'http://snapshots.linaro.org/%s/images/%s' % (self.platform, binary)
Andy Doan184cd3b2012-03-29 22:20:02 -0500193 (date, url) = crawler.latest_rfs(url)
Andy Doan4202d882012-03-29 21:36:09 -0500194 binaryf[binary] = url
Andy Doan4202d882012-03-29 21:36:09 -0500195
Andy Doan184cd3b2012-03-29 22:20:02 -0500196 return binaryf
Andy Doana3977372012-03-29 12:22:44 -0500197
Ricardo Salveti de Araujo0352cb92012-06-22 21:48:34 -0300198 def get_hwpacks(self):
199 '''return a hash table of hwpack->urls (date, url)'''
200 hwpackf = {}
201 for hwpack in self.hwpacks:
202 url = 'http://snapshots.linaro.org/%s/hwpacks/%s' % (self.platform, hwpack)
203 hwpackf[hwpack] = crawler.latest_hwpacks(url)
204
205 return hwpackf
Andy Doan4202d882012-03-29 21:36:09 -0500206
Andy Doan184cd3b2012-03-29 22:20:02 -0500207 def get_image_name(self, odir, hwpack, hwpack_url, binary):
208
209 #covert a url like:
Andy Doan540a4b12012-04-17 11:48:11 -0500210 # http://snapshots.linaro.org/precise/hwpacks/lt-panda/87/hwpack_linaro-lt-panda_20120417-87_armhf_supported.tar.gz
Andy Doan184cd3b2012-03-29 22:20:02 -0500211 # to:
Andy Doan66e2d5c2012-04-18 23:01:59 -0500212 # precise/pre-built/lt-panda/87/<file>.img
Andy Doan184cd3b2012-03-29 22:20:02 -0500213 path = urlparse.urlparse(hwpack_url).path
Andy Doan66e2d5c2012-04-18 23:01:59 -0500214 parts = path.split('/')
215 name = parts[-1] #use for the file name below
216 path = '/'.join(parts[-3:-1])
Andy Doan184cd3b2012-03-29 22:20:02 -0500217
218 path = '%s/%s' % (odir, path)
219 if not os.path.exists(path):
220 os.makedirs(path)
Andy Doan66e2d5c2012-04-18 23:01:59 -0500221
222 date = re.search(r'_(\d+-\d+)_', name).group(1)
Ricardo Salveti de Araujo99d52482012-06-22 16:05:09 -0300223 return "%s/%s-%s_%s_%s.img" % (path, hwpack, self.platform, binary, date)
Andy Doan184cd3b2012-03-29 22:20:02 -0500224
Andy Doan15aa23b2012-02-02 16:40:58 -0600225def main():
Andy Doan15aa23b2012-02-02 16:40:58 -0600226 hwpacks = HWPACKS.keys()
227 binaries = BINARIES.keys()
228
229 p = argparse.ArgumentParser(description=
Andy Doana3977372012-03-29 12:22:44 -0500230 'Builds a matrix of builds from the latest build on '
231 'snapshots.linaro.org or release images on releases.linaro.org')
Andy Doan15aa23b2012-02-02 16:40:58 -0600232
Andy Doan94bfe312012-02-09 17:57:29 -0800233 p.add_argument('-o', dest='out_dir', default='./out',
Andy Doan15aa23b2012-02-02 16:40:58 -0600234 help='The out directory for downloaded and built files, default=./')
Ricardo Salveti de Araujo0352cb92012-06-22 21:48:34 -0300235 p.add_argument('-d', dest='date', default="",
236 help='The date (YYYYMMDD) as reference for hwpack')
Andy Doan15aa23b2012-02-02 16:40:58 -0600237 p.add_argument('-w', dest='hwpacks', action='append',
238 help='The hwpacks to generate for, default=%s' %
239 ', '.join(hwpacks))
240 p.add_argument('-b', dest='binaries', action='append',
241 help='The binaries to generate for, default=%s' %
242 ', '.join(binaries))
Andy Doan540a4b12012-04-17 11:48:11 -0500243 p.add_argument('-p', dest='platform', default='precise',
244 help='The platform, default=precise')
Andy Doan4202d882012-03-29 21:36:09 -0500245 p.add_argument('-r', dest='release', action='store_true', default=False,
246 help='If this is for release images. NOTE: the "date" arg'
247 'will then become the cycle ie -d 12.03')
Andy Doan15aa23b2012-02-02 16:40:58 -0600248
249 args = p.parse_args()
Andy Doana3977372012-03-29 12:22:44 -0500250
Andy Doan15aa23b2012-02-02 16:40:58 -0600251 if args.hwpacks:
252 hwpacks = args.hwpacks
253 if args.binaries:
254 binaries = args.binaries
255
Andy Doan1c6ef8b2012-04-23 12:28:50 -0500256 crawler.cookie_setup()
257
Andy Doan15aa23b2012-02-02 16:40:58 -0600258 dm = fetch_image.DownloadManager(args.out_dir)
Andy Doan15aa23b2012-02-02 16:40:58 -0600259
Andy Doan4202d882012-03-29 21:36:09 -0500260 if args.release:
Andy Doan184cd3b2012-03-29 22:20:02 -0500261 site = ReleaseCrawler(args.date, args.platform, hwpacks, binaries)
Andy Doan4202d882012-03-29 21:36:09 -0500262 else:
Ricardo Salveti de Araujo0352cb92012-06-22 21:48:34 -0300263 site = SnapshotCrawler(args.platform, hwpacks, binaries)
Andy Doan184cd3b2012-03-29 22:20:02 -0500264
Ricardo Salveti de Araujo0352cb92012-06-22 21:48:34 -0300265 hwpackf = site.get_hwpacks()
Andy Doan184cd3b2012-03-29 22:20:02 -0500266 binaryf = site.get_binaries()
Andy Doan15aa23b2012-02-02 16:40:58 -0600267
Andy Doanb00dbc02012-03-15 16:23:06 -0500268 lmc = '%s/linaro-image-tools/linaro-media-create' % args.out_dir
Andy Doan184cd3b2012-03-29 22:20:02 -0500269 odir = '%s/pre-built' % args.out_dir
Andy Doanb00dbc02012-03-15 16:23:06 -0500270
Andy Doan15aa23b2012-02-02 16:40:58 -0600271 for hwpack in hwpacks:
Ricardo Salveti de Araujo0352cb92012-06-22 21:48:34 -0300272 url = None
273 # check if the user wanted a hwpack from a specific date
274 if args.date:
275 try:
276 dates = [elem[0] for elem in hwpackf[hwpack]]
277 index = dates.index(args.date)
278 url = hwpackf[hwpack][index][1]
279 except:
280 print "ERROR: Could not find hwpack '%s' with date '%s'" \
281 ", skipping pre-built image for it" % (hwpack, args.date)
282 else:
283 # just grab the latest hwpack
284 try:
285 url = hwpackf[hwpack][0][1]
286 except:
287 print "ERROR: Could not find a valid hwpack url for '%s'" \
288 ", skipping pre-built image for it" % (hwpack)
Andy Doanb00dbc02012-03-15 16:23:06 -0500289
Andy Doan2cfe5e62012-02-09 17:41:45 -0800290 if url is not None and url is not False:
Ricardo Salveti de Araujob39eb802012-06-23 00:55:31 -0300291 hwpf = download(dm, url)
Andy Doan15aa23b2012-02-02 16:40:58 -0600292 for binary in binaries:
Ricardo Salveti de Araujob93a7ec2012-05-29 14:07:53 -0300293 # create the image and metadata
Ricardo Salveti de Araujo99d52482012-06-22 16:05:09 -0300294 imgfile = site.get_image_name(odir, hwpack, url, binary)
Ricardo Salveti de Araujob93a7ec2012-05-29 14:07:53 -0300295 infofile = '%s.html' % os.path.splitext(imgfile)[0]
Ricardo Salveti de Araujob39eb802012-06-23 00:55:31 -0300296 rfsf = download(dm, binaryf[binary])
Andy Doanb00dbc02012-03-15 16:23:06 -0500297 build_image(lmc, imgfile, hwpack, hwpf, binary, rfsf)
Ricardo Salveti de Araujob93a7ec2012-05-29 14:07:53 -0300298 bz2file = compress_image(imgfile)
299 zsync_image(bz2file)
300 create_image_info(infofile, bz2file,
301 imgfile, url, binaryf[binary])
Andy Doan15aa23b2012-02-02 16:40:58 -0600302
303if __name__ == '__main__':
304 main()
305