blob: 7a6af9cc62475c9c36f669cf2f0c10e67b0757ff [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."""
Chris Sosadda923d2011-04-13 13:12:01 -070054 cherrypy.log('Additional build request arguments: ' + str(additional_args),
David Rochberg7c79a812011-01-19 14:24:45 -050055 'BUILD')
56
Chris Sosadda923d2011-04-13 13:12:01 -070057 def _AppendStrToEnvVar(env, var, additional_string):
58 env[var] = env.get(var, '') + ' ' + additional_string
59 cherrypy.log('%s flags modified to %s' % (var, env[var]), 'BUILD')
60
61 env_copy = os.environ.copy()
David Rochberg7c79a812011-01-19 14:24:45 -050062 if 'use' in additional_args:
Chris Sosadda923d2011-04-13 13:12:01 -070063 _AppendStrToEnvVar(env_copy, 'USE', additional_args['use'])
64
65 if 'features' in additional_args:
66 _AppendStrToEnvVar(env_copy, 'FEATURES', additional_args['features'])
David Rochberg7c79a812011-01-19 14:24:45 -050067
68 try:
69 if (self._ShouldBeWorkedOn(board, pkg) and
70 not additional_args.get('accept_stable')):
71 return self.SetError(
72 'Package is not cros_workon\'d on the devserver machine.\n'
73 'Either start working on the package or pass --accept_stable '
74 'to gmerge')
75
Chris Sosadda923d2011-04-13 13:12:01 -070076 rc = subprocess.call(['emerge-%s' % board, pkg], env=env_copy)
David Rochberg7c79a812011-01-19 14:24:45 -050077 if rc != 0:
78 return self.SetError('Could not emerge ' + pkg)
79
80 cherrypy.log('ecleaning %s' % pkg, 'BUILD')
81 rc = subprocess.call(['eclean-' + board, '-d', 'packages'])
82 if rc != 0:
83 return self.SetError('eclean failed')
84
85 cherrypy.log('eclean complete %s' % pkg, 'BUILD')
86 return 'Success\n'
87 except OSError, e:
88 return self.SetError('Could not execute build command: ' + str(e))