summaryrefslogtreecommitdiff
path: root/distbuild
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2015-05-05 11:53:39 +0000
committerBaserock Gerrit <gerrit@baserock.org>2015-05-07 15:43:13 +0000
commit0b2b24a53316bee939d8921d8eb11254be7ce8a2 (patch)
treefdf43a078d026d954fc36a1b19eb1afef89608bb /distbuild
parentf6e36277bb06620f1f25ef10caed950fa22c1f5b (diff)
downloadmorph-0b2b24a53316bee939d8921d8eb11254be7ce8a2.tar.gz
distbuild: Fix initiator hanging when protocol errors occur
If the initiator sends an invalid build-request message, it will now exit with the following sort of error: ERROR: Failed to build baserock:baserock/definitions f2d78e9b7221bca65cba53af3f3b50d50d90628f systems/build-system-x86_64.morph: Invalid build-request message. Check you are using a supported version of Morph. This distbuild network uses protocol version 2. Previously, the controller would log an error to its log file, but it would not send any response to the initiator so the initiator would hang forever. Behaviour is the same as before for the case where the initiator sends a build-request message with the wrong protocol version: the initiator will exit with an error message. Change-Id: I94fdee02bc701d4a679a0261b3c46dbdf14cfcaf
Diffstat (limited to 'distbuild')
-rw-r--r--distbuild/initiator_connection.py53
1 files changed, 34 insertions, 19 deletions
diff --git a/distbuild/initiator_connection.py b/distbuild/initiator_connection.py
index 7fd45d4d..f0586d9d 100644
--- a/distbuild/initiator_connection.py
+++ b/distbuild/initiator_connection.py
@@ -100,7 +100,7 @@ class InitiatorConnection(distbuild.StateMachine):
('closing', self, _Close, None, self._close),
]
self.add_transitions(spec)
-
+
def _handle_msg(self, event_source, event):
'''Handle message from initiator.'''
@@ -114,25 +114,40 @@ class InitiatorConnection(distbuild.StateMachine):
'build-status': self._handle_build_status,
}
try:
- if event.msg.get('protocol_version') != distbuild.protocol.VERSION:
- msg = distbuild.message('build-failed',
- # use build-failed as it is understood by older versions of
- # morph; if morph is old enough (protocol_version < 1) it
- # won't understand a new message and ignore it or cause the
- # request to hang
- id=event.msg['id'],
- reason=('Protocol version mismatch between server & '
- 'initiator: distbuild network uses distbuild '
- 'protocol version %i, but client uses version %i.'
- % (distbuild.protocol.VERSION,
- event.msg.get('protocol_version'))))
- self.jm.send(msg)
- self._log_send(msg)
- return
- msg_handler[event.msg['type']](event)
+ if event.msg.get('protocol_version') == distbuild.protocol.VERSION:
+ msg_handler[event.msg['type']](event)
+ else:
+ response = (
+ 'Protocol version mismatch between server & initiator: '
+ 'distbuild network uses distbuild protocol version %i, '
+ 'but client uses version %i.' %
+ (distbuild.protocol.VERSION,
+ event.msg.get('protocol_version')))
+ self._refuse_build_request(event.msg, response)
except (KeyError, ValueError) as ex:
- logging.error('Invalid message from initiator: %s: exception %s',
- event.msg, ex)
+ response = (
+ 'Invalid build-request message. Check you are using a '
+ 'supported version of Morph. This distbuild network uses '
+ 'protocol version %i.' % distbuild.protocol.VERSION)
+ self._refuse_build_request(event.msg, response)
+ logging.info('Invalid message from initiator: %s: exception %r',
+ event.msg, ex)
+
+ def _refuse_build_request(self, build_request_message, reason):
+ '''Send an error message back to the initiator.
+
+ In order for this to be understood by all versions of Morph, we use the
+ 'build-failed' message. Morph initiators ignore any messages they don't
+ understand right now, so will hang forever without giving feedback if
+ we ignore the request without sending 'build-failed'.
+
+ '''
+ # If there was no 'id' in the incoming request, we send a fake one in
+ # the hope that initiator still does the right thing.
+ response_id = build_request_message.get('id', '000')
+ msg = distbuild.message('build-failed', id=response_id, reason=reason)
+ self.jm.send(msg)
+ self._log_send(msg)
def _handle_build_request(self, event):
new_id = self._idgen.next()