blob: bf83c3e7f82462f240e23e8b5ee52262e1c39afd [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
David Rochberg7c79a812011-01-19 14:24:45 -050018 Args:
19 command: A list of arguments, beginning with the executable
20 Returns:
21 The output of the command
22 Raises:
23 subprocess.CalledProcessError if the command fails
24 """
David Rochberg7c79a812011-01-19 14:24:45 -050025 command_name = ' '.join(command)
26 cherrypy.log('Executing: ' + command_name, 'BUILD')
27
28 p = subprocess.Popen(command, stdout=subprocess.PIPE)
29 output_blob = p.communicate()[0]
30 if p.returncode != 0:
31 raise subprocess.CalledProcessError(p.returncode, command_name)
32 return output_blob
33
34
35class Builder(object):
36 """Builds packages for the devserver."""
37
38 def _ShouldBeWorkedOn(self, board, pkg):
39 """Is pkg a package that could be worked on, but is not?"""
David James0bc33fd2011-03-02 13:33:38 -080040 if pkg in _OutputOf(['cros_workon', '--board=' + board, 'list']):
David Rochberg7c79a812011-01-19 14:24:45 -050041 return False
42
43 # If it's in the list of possible workon targets, we should be working on it
44 return pkg in _OutputOf([
David James0bc33fd2011-03-02 13:33:38 -080045 'cros_workon', '--board=' + board, 'list', '--all'])
David Rochberg7c79a812011-01-19 14:24:45 -050046
47 def SetError(self, text):
48 cherrypy.response.status = 500
49 cherrypy.log(text, 'BUILD')
50 return text
51
52 def Build(self, board, pkg, additional_args):
53 """Handles a build request from the cherrypy server."""
54 cherrypy.log('Additional build request arguments: '+ str(additional_args),
55 'BUILD')
56
57 original_use = os.environ.get('USE', '')
58 if 'use' in additional_args:
59 os.environ['USE'] = original_use + ' ' + additional_args['use']
60 cherrypy.log('USE flags modified to ' + os.environ['USE'], 'BUILD')
61
62 try:
63 if (self._ShouldBeWorkedOn(board, pkg) and
64 not additional_args.get('accept_stable')):
65 return self.SetError(
66 'Package is not cros_workon\'d on the devserver machine.\n'
67 'Either start working on the package or pass --accept_stable '
68 'to gmerge')
69
70 rc = subprocess.call(['emerge-%s' % board, pkg])
71 if rc != 0:
72 return self.SetError('Could not emerge ' + pkg)
73
74 cherrypy.log('ecleaning %s' % pkg, 'BUILD')
75 rc = subprocess.call(['eclean-' + board, '-d', 'packages'])
76 if rc != 0:
77 return self.SetError('eclean failed')
78
79 cherrypy.log('eclean complete %s' % pkg, 'BUILD')
80 return 'Success\n'
81 except OSError, e:
82 return self.SetError('Could not execute build command: ' + str(e))
83 finally:
84 os.environ['USE'] = original_use