Mercurial > bitten > bitten-test
annotate bitten/master.py @ 19:9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
author | cmlenz |
---|---|
date | Fri, 17 Jun 2005 11:23:22 +0000 |
parents | 591a5a836ecc |
children | cad6d28b8975 |
rev | line source |
---|---|
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
1 # -*- coding: iso8859-1 -*- |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
2 # |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
3 # Copyright (C) 2005 Christopher Lenz <cmlenz@gmx.de> |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
4 # |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
5 # Bitten is free software; you can redistribute it and/or |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
6 # modify it under the terms of the GNU General Public License as |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
7 # published by the Free Software Foundation; either version 2 of the |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
8 # License, or (at your option) any later version. |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
9 # |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
10 # Trac is distributed in the hope that it will be useful, |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
13 # General Public License for more details. |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
14 # |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
15 # You should have received a copy of the GNU General Public License |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
16 # along with this program; if not, write to the Free Software |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
18 # |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
19 # Author: Christopher Lenz <cmlenz@gmx.de> |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
20 |
15
06207499c58c
* Use logging in the BEEP core as well as in the master and slave scripts. Closes #4.
cmlenz
parents:
14
diff
changeset
|
21 import logging |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
22 import os.path |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
23 import time |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
24 |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
25 from trac.env import Environment |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
26 |
19
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
27 from bitten import __version__ as VERSION |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
28 from bitten.util import beep |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
29 from bitten.util.xmlio import Element, parse_xml |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
30 |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
31 |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
32 class Master(beep.Listener): |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
33 |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
34 TRIGGER_INTERVAL = 10 |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
35 |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
36 def __init__(self, env_path, ip, port): |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
37 beep.Listener.__init__(self, ip, port) |
19
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
38 self.profiles[OrchestrationProfileHandler.URI] = OrchestrationProfileHandler() |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
39 |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
40 self.env = Environment(env_path) |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
41 self.youngest_rev = None |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
42 self.slaves = {} |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
43 self.schedule(self.TRIGGER_INTERVAL, self.check_trigger) |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
44 |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
45 def check_trigger(self, master, when): |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
46 logging.debug('Checking for build triggers... (%s)' |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
47 % time.strftime('%x %X', time.localtime(when))) |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
48 repos = self.env.get_repository() |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
49 repos.sync() |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
50 if repos.youngest_rev != self.youngest_rev: |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
51 logging.debug('New changesets detected: %s' |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
52 % repos.youngest_rev) |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
53 self.youngest_rev = repos.youngest_rev |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
54 repos.close() |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
55 self.schedule(self.TRIGGER_INTERVAL, self.check_trigger) |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
56 |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
57 |
19
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
58 class OrchestrationProfileHandler(beep.ProfileHandler): |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
59 """Handler for communication on the Bitten build orchestration profile from |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
60 the perspective of the build master. |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
61 """ |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
62 URI = 'http://bitten.cmlenz.net/beep/orchestration' |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
63 |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
64 def handle_connect(self): |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
65 self.master = self.session.listener |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
66 assert self.master |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
67 |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
68 def handle_msg(self, msgno, msg): |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
69 assert msg.get_content_type() == beep.BEEP_XML |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
70 elem = parse_xml(msg.get_payload()) |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
71 |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
72 if elem.tagname == 'register': |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
73 platform, os, os_family, os_version = None, None, None, None |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
74 for child in elem['*']: |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
75 if child.tagname == 'platform': |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
76 platform = child.gettext() |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
77 elif child.tagname == 'os': |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
78 os = child.gettext() |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
79 os_family = child.family |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
80 os_version = child.version |
14
1733c601d2f8
Refactored the asyncore loop and shutdown procedure into {{{beep.Initiator}}}.
cmlenz
parents:
13
diff
changeset
|
81 |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
82 self.master.slaves[elem.name] = self |
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
83 |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
84 rpy = beep.MIMEMessage(Element('ok'), beep.BEEP_XML) |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
85 self.channel.send_rpy(msgno, rpy) |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
86 logging.info('Registered slave %s (%s running %s %s [%s])', |
15
06207499c58c
* Use logging in the BEEP core as well as in the master and slave scripts. Closes #4.
cmlenz
parents:
14
diff
changeset
|
87 elem.name, platform, os, os_version, os_family) |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
88 |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
89 |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
90 if __name__ == '__main__': |
19
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
91 from optparse import OptionParser |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
92 |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
93 parser = OptionParser(usage='usage: %prog [options] env-path', |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
94 version='%%prog %s' % VERSION) |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
95 parser.add_option('-p', '--port', action='store', type='int', dest='port', |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
96 help='port number to use') |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
97 parser.add_option('-H', '--host', action='store', dest='host', |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
98 help='the host name of IP address to bind to') |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
99 parser.add_option('--debug', action='store_const', dest='loglevel', |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
100 const=logging.DEBUG, help='enable debugging output') |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
101 parser.add_option('-v', '--verbose', action='store_const', dest='loglevel', |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
102 const=logging.INFO, help='print as much as possible') |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
103 parser.add_option('-q', '--quiet', action='store_const', dest='loglevel', |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
104 const=logging.ERROR, help='print as little as possible') |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
105 parser.set_defaults(port=7633, loglevel=logging.WARNING) |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
106 options, args = parser.parse_args() |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
107 |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
108 if len(args) < 1: |
19
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
109 parser.error('incorrect number of arguments') |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
110 env_path = args[0] |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
111 |
19
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
112 logging.getLogger().setLevel(options.loglevel) |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
113 port = options.port |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
114 if not (1 <= port <= 65535): |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
115 parser.error('port must be an integer in the range 1-65535') |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
116 |
19
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
117 host = options.host |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
118 if not host: |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
119 import socket |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
120 ip = socket.gethostbyname(socket.gethostname()) |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
121 try: |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
122 host = socket.gethostbyaddr(ip)[0] |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
123 except socket.error, e: |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
124 logging.warning('Reverse host name lookup failed (%s)', e) |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
125 host = ip |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
126 |
9db5f8eddb0d
Proper {{{optparse}}}-based command-line interface for master and slave.
cmlenz
parents:
18
diff
changeset
|
127 master = Master(env_path, host, port) |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
128 try: |
18
591a5a836ecc
* {{{beep.Listener}}} now has an event loop (based on code mostly from medusa)
cmlenz
parents:
15
diff
changeset
|
129 master.run() |
13
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
130 except KeyboardInterrupt: |
21aa17f97522
Initial code for build master and slave... these don't do a lot yet.
cmlenz
parents:
diff
changeset
|
131 pass |