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