annotate bitten/util/beep.py @ 14:1733c601d2f8

Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
author cmlenz
date Thu, 16 Jun 2005 20:37:38 +0000
parents 21aa17f97522
children 06207499c58c
rev   line source
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
1 # -*- coding: iso8859-1 -*-
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
2 #
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
3 # Copyright (C) 2005 Christopher Lenz <cmlenz@gmx.de>
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
4 #
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
5 # Bitten is free software; you can redistribute it and/or
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
6 # modify it under the terms of the GNU General Public License as
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
7 # published by the Free Software Foundation; either version 2 of the
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
8 # License, or (at your option) any later version.
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
9 #
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
10 # Trac is distributed in the hope that it will be useful,
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
13 # General Public License for more details.
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
14 #
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
15 # You should have received a copy of the GNU General Public License
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
16 # along with this program; if not, write to the Free Software
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
18 #
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
19 # Author: Christopher Lenz <cmlenz@gmx.de>
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
20
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
21 """Minimal implementation of the BEEP protocol (IETF RFC 3080) based on the
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
22 `asyncore` module.
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
23
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
24 Current limitations:
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
25 * No support for the TSL and SASL profiles.
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
26 * No support for mapping frames (SEQ frames for TCP mapping).
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
27 """
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
28
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
29 import asynchat
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
30 import asyncore
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
31 from email.Message import Message
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
32 from email.Parser import Parser
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
33 import socket
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
34 import sys
14
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
35 import time
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
36
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
37 from bitten.util.xmlio import Element, parse_xml
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
38
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
39 __all__ = ['Listener', 'Initiator', 'Profile']
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
40
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
41
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
42 BEEP_XML = 'application/beep+xml'
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
43
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
44
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
45 class ProtocolError(Exception):
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
46 """Generic root class for BEEP exceptions."""
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
47
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
48
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents: 12
diff changeset
49 class TerminateSession(Exception):
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents: 12
diff changeset
50 """Signal termination of a session."""
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents: 12
diff changeset
51
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents: 12
diff changeset
52
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
53 class Listener(asyncore.dispatcher):
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
54 """BEEP peer in the listener role.
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
55
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
56 This peer opens a socket for listening to incoming connections. For each
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
57 connection, it opens a new session: an instance of `Session` that handle
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
58 communication with the connected peer.
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
59 """
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
60 def __init__(self, ip, port):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
61 asyncore.dispatcher.__init__(self)
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
62 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
63 self.set_reuse_addr()
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
64 self.bind((ip, port))
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
65 self.profiles = {}
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
66 self.listen(5)
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
67
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
68 def writable(self):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
69 return False
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
70
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
71 def handle_read(self):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
72 pass
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
73
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
74 def readable(self):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
75 return True
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
76
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
77 def handle_connect(self):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
78 pass
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
79
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
80 def handle_accept(self):
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
81 """Start a new BEEP session."""
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
82 conn, addr = self.accept()
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
83 print 'Connected to %s:%s' % addr
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
84 Session(conn, addr, self.profiles, first_channelno=2)
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
85
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
86
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
87 class Session(asynchat.async_chat):
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
88 """A BEEP session between two peers."""
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
89
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
90 def __init__(self, conn, addr, profiles, first_channelno=1):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
91 asynchat.async_chat.__init__(self, conn)
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
92 self.addr = addr
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
93 self.set_terminator('\r\n')
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
94
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
95 self.profiles = profiles or {}
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
96 self.inbuf = []
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
97 self.header = self.payload = None
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
98
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
99 self.channelno = cycle_through(first_channelno, 2147483647, step=2)
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
100 self.channels = {0: Channel(self, 0, ManagementProfile())}
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
101
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
102 def handle_connect(self):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
103 pass
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
104
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
105 def handle_error(self):
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents: 12
diff changeset
106 """Called by asyncore when an exception is raised."""
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
107 t, v = sys.exc_info()[:2]
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents: 12
diff changeset
108 if t is TerminateSession:
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
109 raise t, v
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents: 12
diff changeset
110 asynchat.async_chat.handle_error(self)
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
111
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
112 def collect_incoming_data(self, data):
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents: 12
diff changeset
113 """Called by async_chat when data is received.
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents: 12
diff changeset
114
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents: 12
diff changeset
115 Buffer the data and wait until a terminator is found."""
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
116 self.inbuf.append(data)
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
117
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
118 def found_terminator(self):
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
119 """Called by async_chat when a terminator is found in the input
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
120 stream.
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
121
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
122 Parse the incoming data depending on whether it terminated on the frame
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
123 header, playload or trailer. For the header, extract the payload size
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
124 parameter and use it as terminator or the payload. When the trailer has
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
125 been received, delegate to `_handle_frame()`.
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
126 """
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
127 if self.header is None:
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
128 # Frame header received
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
129 self.header = ''.join(self.inbuf).split(' ')
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
130 self.inbuf = []
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
131 if self.header[0] == 'SEQ':
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
132 # TCP mapping frame
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
133 raise NotImplementedError
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
134 else:
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
135 # Extract payload size to use as next terminator
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
136 try:
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
137 size = int(self.header[int(self.header[0] != 'ANS') - 2])
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
138 except ValueError:
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
139 # TODO: Malformed frame... should we terminate the session
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
140 # here?
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
141 self.header = None
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
142 return
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
143 if size == 0:
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
144 self.payload = ''
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
145 self.set_terminator('END\r\n')
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
146 else:
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
147 self.set_terminator(size)
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
148 elif self.payload is None:
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
149 # Frame payload received
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
150 self.payload = ''.join(self.inbuf)
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
151 self.inbuf = []
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
152 self.set_terminator('END\r\n')
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
153 else:
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
154 # Frame trailer received
14
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
155 try:
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
156 self._handle_frame(self.header, self.payload)
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
157 finally:
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
158 self.header = self.payload = None
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
159 self.inbuf = []
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
160 self.set_terminator('\r\n')
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
161
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
162 def _handle_frame(self, header, payload):
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
163 """Handle an incoming frame.
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
164
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
165 This parses the frame header and decides which channel to pass it to.
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
166 """
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
167 msgno = None
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
168 channel = None
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
169 try:
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
170 cmd = header[0].upper()
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
171 channel = int(header[1])
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
172 msgno = int(header[2])
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
173 more = header[3] == '*'
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
174 seqno = int(header[4])
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
175 size = int(header[5])
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
176 ansno = None
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
177 if cmd == 'ANS':
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
178 ansno = int(header[6])
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
179 self.channels[channel].handle_frame(cmd, msgno, more, seqno,
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
180 ansno, payload)
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
181 except (ValueError, TypeError, ProtocolError), e:
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
182 if channel == 0 and msgno is not None:
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
183 self.channels[0].profile.send_error(msgno, 550, e)
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
184
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
185 def send_frame(self, cmd, channel, msgno, more, seqno, ansno=None,
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
186 payload=''):
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
187 """Send the specified data frame to the peer."""
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
188 headerbits = [cmd, channel, msgno, more and '*' or '.', seqno,
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
189 len(payload)]
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
190 if cmd == 'ANS':
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
191 assert ansno is not None
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
192 headerbits.append(ansno)
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
193 header = ' '.join([str(hb) for hb in headerbits])
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
194 self.push('\r\n'.join((header, payload, 'END', '')))
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
195
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
196
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
197 class Initiator(Session):
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
198 """Root class for BEEP peers in the initiating role."""
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
199
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
200 def __init__(self, ip, port, profiles=None):
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
201 """Create the BEEP session.
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
202
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
203 @param ip: The IP address to connect to
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
204 @param port: The port to connect to
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
205 @param profiles: A dictionary of the supported profiles, where the key
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
206 is the URI identifying the profile, and the value is a
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
207 `Profile` instance that will handle the communication
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
208 for that profile
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
209 """
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
210 Session.__init__(self, None, None, profiles or {})
14
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
211 self.terminated = False
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
212 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
213 self.connect((ip, port))
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
214
14
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
215 def handle_close(self):
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
216 self.terminated = True
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
217
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
218 def greeting_received(self, profiles):
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
219 """Sub-classes should override this to start the channels they need.
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
220
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
221 @param profiles: A list of URIs of the profiles the peer claims to
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
222 support.
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
223 """
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
224
14
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
225 def run(self):
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
226 """Start this peer, which will try to connect to the server and send a
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
227 greeting.
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
228 """
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
229 while not self.terminated:
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
230 try:
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
231 asyncore.loop()
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
232 print 'Normal exit'
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
233 self.terminated = True
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
234 except (KeyboardInterrupt, TerminateSession):
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
235 self._quit()
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
236 time.sleep(.25)
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
237
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
238 def _quit(self):
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
239 channelno = max(self.channels.keys())
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
240 def handle_ok():
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
241 if channelno == 0:
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
242 self.terminated = True
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
243 else:
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
244 self._quit()
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
245 def handle_error(code, message):
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
246 raise ProtocolError, '%s (%d)' % (message, code)
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
247 self.channels[0].profile.send_close(channelno, handle_ok=handle_ok,
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
248 handle_error=handle_error)
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
249
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
250
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
251 class Channel(object):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
252 """A specific channel of a BEEP session."""
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
253
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
254 def __init__(self, session, channelno, profile):
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
255 """Create the channel.
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
256
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
257 @param session The `Session` object that the channel belongs to
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
258 @param channelno The channel number
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
259 @param profile The associated `Profile` object
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
260 """
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
261 self.session = session
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
262 self.channelno = channelno
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
263 self.inqueue = {}
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
264 self.outqueue = []
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
265 self.reply_handlers = {}
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
266
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
267 self.msgno = cycle_through(0, 2147483647)
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
268 self.msgnos = {} # message numbers currently in use
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
269 self.ansnos = {} # answer numbers keyed by msgno, each 0-2147483647
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
270 self.seqno = [serial(), serial()] # incoming, outgoing sequence numbers
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
271 self.mime_parser = Parser()
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
272
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
273 self.profile = profile
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
274 self.profile.session = self.session
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
275 self.profile.channel = self
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
276 self.profile.handle_connect()
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
277
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
278 def handle_frame(self, cmd, msgno, more, seqno, ansno, payload):
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
279 """Process a single data frame.
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
280
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
281 @param cmd: The frame keyword (MSG, RPY, ERR, ANS or NUL)
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
282 @param msgno: The message number
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
283 @param more: `True` if more frames are pending for this message
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
284 @param seqno: Sequence number of the frame
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
285 @param ansno: The answer number for 'ANS' messages, otherwise `None`
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
286 @param payload: The frame payload as a string
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
287 """
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
288 # Validate and update sequence number
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
289 if seqno != self.seqno[0]:
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
290 raise ProtocolError, 'Out of sync with peer' # TODO: Be nice
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
291 self.seqno[0] += len(payload)
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
292
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
293 if more:
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
294 # More of this message pending, so push it on the queue
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
295 self.inqueue.setdefault(msgno, []).append(payload)
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
296 return
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
297
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
298 # Complete message received, so handle it
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
299 if msgno in self.inqueue.keys():
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
300 # Recombine queued messages
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
301 payload = ''.join(self.inqueue[msgno]) + payload
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
302 del self.inqueue[msgno]
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
303 if cmd == 'RPY' and msgno in self.msgnos.keys():
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
304 # Final reply using this message number, so dealloc
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
305 del self.msgnos[msgno]
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
306 message = None
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
307 if payload:
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
308 message = self.mime_parser.parsestr(payload)
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
309
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
310 if cmd == 'MSG':
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
311 self.profile.handle_msg(msgno, message)
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
312 else:
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
313 if msgno in self.reply_handlers.keys():
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
314 self.reply_handlers[msgno](cmd, msgno, message)
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
315 del self.reply_handlers[msgno]
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
316 elif cmd == 'RPY':
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
317 self.profile.handle_rpy(msgno, message)
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
318 elif cmd == 'ERR':
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
319 self.profile.handle_err(msgno, message)
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
320 elif cmd == 'ANS':
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
321 self.profile.handle_ans(msgno, ansno, message)
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
322 elif cmd == 'NUL':
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
323 self.profile.handle_nul(msgno)
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
324
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
325 def _send(self, cmd, msgno, ansno=None, message=None):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
326 # TODO: Fragment and queue the message if necessary;
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
327 # First need TCP mapping (RFC 3081) for that to make real sense
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
328 payload = ''
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
329 if message is not None:
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
330 payload = message.as_string()
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
331 self.session.send_frame(cmd, self.channelno, msgno, False,
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
332 self.seqno[1].value, payload=payload,
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
333 ansno=ansno)
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
334 self.seqno[1] += len(payload)
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
335
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
336 def send_msg(self, message, handle_reply=None):
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
337 while True: # Find a unique message number
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
338 msgno = self.msgno.next()
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
339 if msgno not in self.msgnos.keys():
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
340 break
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
341 self.msgnos[msgno] = True # Flag the chosen message number as in use
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
342 if handle_reply is not None:
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
343 self.reply_handlers[msgno] = handle_reply
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
344 self._send('MSG', msgno, None, message)
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
345 return msgno
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
346
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
347 def send_rpy(self, msgno, message):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
348 self._send('RPY', msgno, None, message)
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
349
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
350 def send_err(self, msgno, message):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
351 self._send('ERR', msgno, None, message)
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
352
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
353 def send_ans(self, msgno, message):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
354 if not msgno in self.ansnos.keys():
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
355 ansno = cycle_through(0, 2147483647)
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
356 self.ansnos[msgno] = ansno
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
357 else:
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
358 ansno = self.ansnos[msgno]
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
359 next_ansno = ansno.next()
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
360 self._send('ANS', msgno, next_ansno, message)
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
361 return next_ansno
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
362
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
363 def send_nul(self, msgno):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
364 self._send('NUL', msgno)
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
365 del self.ansnos[msgno] # dealloc answer numbers for the message
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
366
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
367
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
368 class Profile(object):
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
369 """Abstract base class for handlers of specific BEEP profiles.
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
370
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
371 Concrete subclasses need to at least implement the `handle_msg()` method,
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
372 and may override any of the others.
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
373 """
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
374
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
375 def __init__(self):
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
376 """Create the profile."""
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
377 self.session = None
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
378 self.channel = None
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
379
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
380 def handle_connect(self):
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
381 """Called when the channel this profile is associated with is
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
382 initially started."""
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
383 pass
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
384
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
385 def handle_msg(self, msgno, message):
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
386 raise NotImplementedError
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
387
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
388 def handle_rpy(self, msgno, message):
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
389 pass
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
390
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
391 def handle_err(self, msgno, message):
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
392 pass
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
393
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
394 def handle_ans(self, msgno, ansno, message):
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
395 pass
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
396
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
397 def handle_nul(self, msgno):
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
398 pass
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
399
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
400
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
401 class ManagementProfile(Profile):
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
402 """Implementation of the BEEP management profile."""
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
403
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
404 def handle_connect(self):
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
405 """Send a greeting reply directly after connecting to the peer."""
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
406 greeting = Element('greeting')[
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
407 [Element('profile', uri=k) for k in self.session.profiles.keys()]
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
408 ]
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
409 self.channel.send_rpy(0, MIMEMessage(greeting, BEEP_XML))
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
410
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
411 def handle_msg(self, msgno, message):
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
412 assert message.get_content_type() == BEEP_XML
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
413 elem = parse_xml(message.get_payload())
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
414
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents: 12
diff changeset
415 if elem.tagname == 'start':
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
416 for profile in elem['profile']:
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
417 if profile.uri in self.session.profiles.keys():
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
418 print 'Start channel %s for profile <%s>' % (elem.number,
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
419 profile.uri)
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
420 channel = Channel(self.session, int(elem.number),
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
421 self.session.profiles[profile.uri])
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
422 self.session.channels[int(elem.number)] = channel
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
423 message = MIMEMessage(Element('profile', uri=profile.uri),
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
424 BEEP_XML)
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
425 self.channel.send_rpy(msgno, message)
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
426 return
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
427 self.send_error(msgno, 550,
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
428 'All requested profiles are unsupported')
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
429
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents: 12
diff changeset
430 elif elem.tagname == 'close':
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
431 channelno = int(elem.number)
14
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
432 if not channelno in self.session.channels:
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
433 self.send_error(msgno, 550, 'Channel not open')
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
434 return
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
435 if channelno == 0:
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
436 if len(self.session.channels) > 1:
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
437 self.send_error(msgno, 550, 'Other channels still open')
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
438 return
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
439 if self.session.channels[channelno].msgnos:
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
440 self.send_error(msgno, 550, 'Channel waiting for replies')
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
441 return
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
442 del self.session.channels[channelno]
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
443 message = MIMEMessage(Element('ok'), BEEP_XML)
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
444 self.channel.send_rpy(msgno, message)
14
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
445 if not self.session.channels:
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
446 self.session.close()
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
447
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
448 def handle_rpy(self, msgno, message):
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
449 assert message.get_content_type() == BEEP_XML
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
450 elem = parse_xml(message.get_payload())
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
451
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents: 12
diff changeset
452 if elem.tagname == 'greeting':
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
453 if isinstance(self.session, Initiator):
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
454 profiles = [profile.uri for profile in elem['profile']]
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
455 self.session.greeting_received(profiles)
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
456
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
457 else: # <profile/> and <ok/> are handled by callbacks
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
458 self.send_error(msgno, 501, 'What are you replying to, son?')
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
459
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
460 def handle_err(self, msgno, message):
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
461 # Probably an error on connect, because other errors should get handled
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
462 # by the corresponding callbacks
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
463 # TODO: Terminate the session, I guess
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
464 assert message.get_content_type() == BEEP_XML
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
465 elem = parse_xml(message.get_payload())
13
21aa17f97522 Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents: 12
diff changeset
466 assert elem.tagname == 'error'
14
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
467 print 'Received error in response to message #%d: %s (%s)' \
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
468 % (msgno, elem.gettext(), elem.code)
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
469
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
470 def send_close(self, channelno=0, code=200, handle_ok=None,
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
471 handle_error=None):
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
472 def handle_reply(cmd, msgno, message):
14
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
473 if cmd == 'RPY':
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
474 del self.session.channels[channelno]
14
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
475 if handle_ok is not None:
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
476 handle_ok()
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
477 if not self.session.channels:
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
478 self.session.close()
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
479 elif cmd == 'ERR':
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
480 elem = parse_xml(message.get_payload())
14
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
481 if handle_error is not None:
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
482 handle_error(int(elem.code), elem.gettext())
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
483 xml = Element('close', number=channelno, code=code)
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
484 return self.channel.send_msg(MIMEMessage(xml, BEEP_XML), handle_reply)
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
485
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
486 def send_error(self, msgno, code, message=''):
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
487 xml = Element('error', code=code)[message]
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
488 self.channel.send_err(msgno, MIMEMessage(xml, BEEP_XML))
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
489
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
490 def send_start(self, profiles, handle_ok=None, handle_error=None):
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
491 channelno = self.session.channelno.next()
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
492 def handle_reply(cmd, msgno, message):
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
493 if handle_ok is not None and cmd == 'RPY':
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
494 elem = parse_xml(message.get_payload())
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
495 for profile in [p for p in profiles if p.URI == elem.uri]:
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
496 self.session.channels[channelno] = Channel(self.session,
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
497 channelno,
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
498 profile())
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
499 break
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
500 handle_ok(channelno, elem.uri)
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
501 if handle_error is not None and cmd == 'ERR':
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
502 elem = parse_xml(message.get_payload())
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
503 handle_error(int(elem.code), elem.gettext())
12
fd802a55be55 Added unit tests for frame sequence numbers.
cmlenz
parents: 11
diff changeset
504
10
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
505 xml = Element('start', number=channelno)[
2269b705deb9 Improved the BEEP protocol implementation:
cmlenz
parents: 7
diff changeset
506 [Element('profile', uri=profile.URI) for profile in profiles]
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
507 ]
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
508 return self.channel.send_msg(MIMEMessage(xml, BEEP_XML), handle_reply)
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
509
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
510
14
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
511 class MIMEMessage(Message):
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
512 """Simplified construction of generic MIME messages for transmission as
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
513 payload with BEEP."""
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
514
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
515 def __init__(self, payload, content_type=None):
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
516 Message.__init__(self)
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
517 if content_type:
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
518 self.set_type(content_type)
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
519 self.set_payload(str(payload))
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
520 del self['MIME-Version']
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
521
1733c601d2f8 Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents: 13
diff changeset
522
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
523 def cycle_through(start, stop=None, step=1):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
524 """Utility generator that cycles through a defined range of numbers."""
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
525 if stop is None:
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
526 stop = start
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
527 start = 0
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
528 cur = start
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
529 while True:
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
530 yield cur
11
4d31bd0c3eba Improved BEEP implementation.
cmlenz
parents: 10
diff changeset
531 cur += step
7
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
532 if cur > stop:
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
533 cur = start
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
534
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
535
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
536 class serial(object):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
537 """Serial number (RFC 1982)."""
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
538
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
539 def __init__(self, limit=4294967295L):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
540 self.value = 0L
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
541 self.limit = limit
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
542
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
543 def __ne__(self, num):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
544 return self.value != num
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
545
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
546 def __eq__(self, num):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
547 return self.value == num
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
548
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
549 def __iadd__(self, num):
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
550 self.value += num
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
551 if self.value > self.limit:
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
552 self.value -= self.limit
8442bcb47a03 Initial draft of a minimal [http://www.beepcore.org/ BEEP] protocol implementation for communication between the build master and build slaves.
cmlenz
parents:
diff changeset
553 return self
Copyright (C) 2012-2017 Edgewall Software