blob: e7bccae718b3c8f24f35dc4b9d93953e590ffa22 [file] [log] [blame]
David Rochberg7c79a812011-01-19 14:24:45 -05001#!/usr/bin/python
2
3# Copyright (c) 2009-2011 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Package builder for the dev server."""
8import os
9import subprocess
Andrew de los Reyes20666872011-02-17 10:43:07 -080010import sys
David Rochberg7c79a812011-01-19 14:24:45 -050011
12import cherrypy
13
14
15def _OutputOf(command):
16 """Runs command, a list of arguments beginning with an executable.
17
18 If the executable begins with "scripts/", the path is adjusted to
19 the scripts directory of this chroot.
20
21 Args:
22 command: A list of arguments, beginning with the executable
23 Returns:
24 The output of the command
25 Raises:
26 subprocess.CalledProcessError if the command fails
27 """
28 scripts = 'scripts/'
29 if command[0].find(scripts) == 0:
Andrew de los Reyes20666872011-02-17 10:43:07 -080030 server_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
31 command[0] = command[0].replace(scripts, server_dir + '/../../' + scripts)
David Rochberg7c79a812011-01-19 14:24:45 -050032 command_name = ' '.join(command)
33 cherrypy.log('Executing: ' + command_name, 'BUILD')
34
35 p = subprocess.Popen(command, stdout=subprocess.PIPE)
36 output_blob = p.communicate()[0]
37 if p.returncode != 0:
38 raise subprocess.CalledProcessError(p.returncode, command_name)
39 return output_blob
40
41
42class Builder(object):
43 """Builds packages for the devserver."""
44
45 def _ShouldBeWorkedOn(self, board, pkg):
46 """Is pkg a package that could be worked on, but is not?"""
47 if pkg in _OutputOf(['scripts/cros_workon', '--board=' + board, 'list']):
48 return False
49
50 # If it's in the list of possible workon targets, we should be working on it
51 return pkg in _OutputOf([
52 'scripts/cros_workon', '--board=' + board, 'list', '--all'])
53
54 def SetError(self, text):
55 cherrypy.response.status = 500
56 cherrypy.log(text, 'BUILD')
57 return text
58
59 def Build(self, board, pkg, additional_args):
60 """Handles a build request from the cherrypy server."""
61 cherrypy.log('Additional build request arguments: '+ str(additional_args),
62 'BUILD')
63
64 original_use = os.environ.get('USE', '')
65 if 'use' in additional_args:
66 os.environ['USE'] = original_use + ' ' + additional_args['use']
67 cherrypy.log('USE flags modified to ' + os.environ['USE'], 'BUILD')
68
69 try:
70 if (self._ShouldBeWorkedOn(board, pkg) and
71 not additional_args.get('accept_stable')):
72 return self.SetError(
73 'Package is not cros_workon\'d on the devserver machine.\n'
74 'Either start working on the package or pass --accept_stable '
75 'to gmerge')
76
77 rc = subprocess.call(['emerge-%s' % board, pkg])
78 if rc != 0:
79 return self.SetError('Could not emerge ' + pkg)
80
81 cherrypy.log('ecleaning %s' % pkg, 'BUILD')
82 rc = subprocess.call(['eclean-' + board, '-d', 'packages'])
83 if rc != 0:
84 return self.SetError('eclean failed')
85
86 cherrypy.log('eclean complete %s' % pkg, 'BUILD')
87 return 'Success\n'
88 except OSError, e:
89 return self.SetError('Could not execute build command: ' + str(e))
90 finally:
91 os.environ['USE'] = original_use