diff options
Diffstat (limited to 'distbuild/initiator.py')
-rw-r--r-- | distbuild/initiator.py | 91 |
1 files changed, 62 insertions, 29 deletions
diff --git a/distbuild/initiator.py b/distbuild/initiator.py index aaae7d62..eef4c9ec 100644 --- a/distbuild/initiator.py +++ b/distbuild/initiator.py @@ -1,6 +1,6 @@ # distbuild/initiator.py -- state machine for the initiator # -# Copyright (C) 2012, 2014 Codethink Limited +# Copyright (C) 2012, 2014-2015 Codethink Limited # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -12,15 +12,15 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.. +# with this program. If not, see <http://www.gnu.org/licenses/>. import cliapp +import itertools import logging import os import random -import sys +import time import distbuild @@ -37,6 +37,20 @@ class _Failed(object): self.msg = msg +def create_build_directory(prefix='build'): + '''Create a new directory to store build logs. + + The directory will be named build-0, unless that directory already exists, + in which case it will be named build-1, and so on. + + ''' + for i in itertools.count(): + path = '%s-%02i' % (prefix, i) + if not os.path.exists(path): + os.mkdir(path) + return path + + class Initiator(distbuild.StateMachine): def __init__(self, cm, conn, app, repo_name, ref, morphology, @@ -49,11 +63,14 @@ class Initiator(distbuild.StateMachine): self._ref = ref self._morphology = morphology self._original_ref = original_ref - self._steps = None self._step_outputs = {} - self._step_output_dir = app.settings['initiator-step-output-dir'] self.debug_transitions = False + if app.settings['initiator-step-output-dir'] == '': + self._step_output_dir = create_build_directory() + else: + self._step_output_dir = app.settings['initiator-step-output-dir'] + def setup(self): distbuild.crash_point() @@ -83,11 +100,12 @@ class Initiator(distbuild.StateMachine): repo=self._repo_name, ref=self._ref, morphology=self._morphology, - original_ref=self._original_ref + original_ref=self._original_ref, + protocol_version=distbuild.protocol.VERSION ) self._jm.send(msg) logging.debug('Initiator: sent to controller: %s', repr(msg)) - + def _handle_json_message(self, event_source, event): distbuild.crash_point() @@ -97,7 +115,6 @@ class Initiator(distbuild.StateMachine): 'build-finished': self._handle_build_finished_message, 'build-failed': self._handle_build_failed_message, 'build-progress': self._handle_build_progress_message, - 'build-steps': self._handle_build_steps_message, 'step-started': self._handle_step_started_message, 'step-already-started': self._handle_step_already_started_message, 'step-output': self._handle_step_output_message, @@ -117,12 +134,6 @@ class Initiator(distbuild.StateMachine): def _handle_build_progress_message(self, msg): self._app.status(msg='Progress: %(msgtext)s', msgtext=msg['message']) - def _handle_build_steps_message(self, msg): - self._steps = msg['steps'] - self._app.status( - msg='Build steps in total: %(steps)d', - steps=len(self._steps)) - def _open_output(self, msg): assert msg['step_name'] not in self._step_outputs if self._step_output_dir: @@ -137,23 +148,33 @@ class Initiator(distbuild.StateMachine): self._step_outputs[msg['step_name']].close() del self._step_outputs[msg['step_name']] + def _get_output(self, msg): + return self._step_outputs[msg['step_name']] + + def _write_status_to_build_log(self, f, status): + f.write(time.strftime('%Y-%m-%d %H:%M:%S ') + status + '\n') + f.flush() + def _handle_step_already_started_message(self, msg): - self._app.status( - msg='%s is already building on %s' % (msg['step_name'], - msg['worker_name'])) + status = '%s is already building on %s' % ( + msg['step_name'], msg['worker_name']) + self._app.status(msg=status) + self._open_output(msg) + self._write_status_to_build_log(self._get_output(msg), status) def _handle_step_started_message(self, msg): - self._app.status( - msg='Started building %(step_name)s on %(worker_name)s', - step_name=msg['step_name'], - worker_name=msg['worker_name']) + status = 'Started building %s on %s' % ( + msg['step_name'], msg['worker_name']) + self._app.status(msg=status) + self._open_output(msg) + self._write_status_to_build_log(self._get_output(msg), status) def _handle_step_output_message(self, msg): step_name = msg['step_name'] if step_name in self._step_outputs: - f = self._step_outputs[step_name] + f = self._get_output(msg) f.write(msg['stdout']) f.write(msg['stderr']) f.flush() @@ -164,9 +185,10 @@ class Initiator(distbuild.StateMachine): def _handle_step_finished_message(self, msg): step_name = msg['step_name'] if step_name in self._step_outputs: - self._app.status( - msg='Finished building %(step_name)s', - step_name=step_name) + status = 'Finished building %s' % step_name + self._app.status(msg=status) + + self._write_status_to_build_log(self._get_output(msg), status) self._close_output(msg) else: logging.warning( @@ -175,9 +197,10 @@ class Initiator(distbuild.StateMachine): def _handle_step_failed_message(self, msg): step_name = msg['step_name'] if step_name in self._step_outputs: - self._app.status( - msg='Build failed: %(step_name)s', - step_name=step_name) + status = 'Build of %s failed.' % step_name + self._app.status(msg=status) + + self._write_status_to_build_log(self._get_output(msg), status) self._close_output(msg) else: logging.warning( @@ -208,3 +231,13 @@ class Initiator(distbuild.StateMachine): self.mainloop.queue_event(self._cm, distbuild.StopConnecting()) self._jm.close() + def handle_cancel(self): + # Note in each build-step.log file that the initiator cancelled: this + # makes it easier to tell whether a build was aborted due to a bug or + # dropped connection, or if the user cancelled with CTRL+C / SIGINT. + + for f in self._step_outputs.itervalues(): + self._write_status_to_build_log(f, 'Initiator cancelled') + f.close() + + self._step_outputs = {} |