David Rochberg | 7c79a81 | 2011-01-19 14:24:45 -0500 | [diff] [blame] | 1 | #!/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.""" |
| 8 | import os |
| 9 | import subprocess |
Andrew de los Reyes | 2066687 | 2011-02-17 10:43:07 -0800 | [diff] [blame] | 10 | import sys |
David Rochberg | 7c79a81 | 2011-01-19 14:24:45 -0500 | [diff] [blame] | 11 | |
| 12 | import cherrypy |
| 13 | |
| 14 | |
| 15 | def _OutputOf(command): |
| 16 | """Runs command, a list of arguments beginning with an executable. |
| 17 | |
David Rochberg | 7c79a81 | 2011-01-19 14:24:45 -0500 | [diff] [blame] | 18 | 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 Rochberg | 7c79a81 | 2011-01-19 14:24:45 -0500 | [diff] [blame] | 25 | 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 | |
| 35 | class 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 James | 0bc33fd | 2011-03-02 13:33:38 -0800 | [diff] [blame] | 40 | if pkg in _OutputOf(['cros_workon', '--board=' + board, 'list']): |
David Rochberg | 7c79a81 | 2011-01-19 14:24:45 -0500 | [diff] [blame] | 41 | 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 James | 0bc33fd | 2011-03-02 13:33:38 -0800 | [diff] [blame] | 45 | 'cros_workon', '--board=' + board, 'list', '--all']) |
David Rochberg | 7c79a81 | 2011-01-19 14:24:45 -0500 | [diff] [blame] | 46 | |
| 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 |