1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 from flumotion.twisted import pb as fpb
24 from flumotion.common import log, planet
25 from flumotion.admin import admin
26
27
33
34
36 class Watched(type):
37 def __init__(self):
38 type.__init__(self)
39 self.watch_id = 0
40 self.watch_procs = {}
41
42 def watch(self, proc):
43 self.watch_id += 1
44 self.watch_procs[self.watch_id] = proc
45 return self.watch_id
46
47 def unwatch(self, id):
48 del self.watch_procs[id]
49
50 def notify_changed(self):
51 for proc in self.watch_procs.values():
52 proc(self)
53
54 def mutate(method):
55 def do_mutate(self, *args, **kwargs):
56 method(self, *args, **kwargs)
57 self.notify_changed()
58 setattr(Watched, method.__name__, do_mutate)
59 for i in mutators:
60 mutate(getattr(type, i))
61
62 return Watched
63
64 WatchedList = _make_watched(list, 'append', 'insert', 'remove', 'pop',
65 'sort', 'reverse')
66 WatchedDict = _make_watched(dict, '__setitem__', '__delitem__', 'pop',
67 'popitem', 'update')
68
69
71 logCategory = 'multiadmin'
72
74
75 self.admins = WatchedDict()
76
77 self.listeners = []
78
79
80 - def emit(self, signal_name, *args, **kwargs):
81 self.debug('emit %r %r %r' % (signal_name, args, kwargs))
82 assert signal_name != 'handler'
83 for c in self.listeners:
84 if getattr(c, 'model_handler', None):
85 c.model_handler(c, signal_name, *args, **kwargs)
86 elif getattr(c, 'model_%s' % signal_name):
87 getattr(c, 'model_%s' % signal_name)(*args, **kwargs)
88 else:
89 s = 'No model_%s in %r and no model_handler' % (signal_name, c)
90 raise NotImplementedError(s)
91
93 assert not obj in self.listeners
94 self.listeners.append(obj)
95
96
97 - def addManager(self, host, port, use_insecure, authenticator,
98 tenacious=False):
105
106 def disconnected_cb(admin):
107 self.info('Disconnected from manager')
108 if admin.managerId in self.admins:
109 self.emit('removePlanet', admin, admin.planet)
110 del self.admins[admin.managerId]
111 else:
112 self.warning('Could not find admin model %r' % admin)
113
114 def connection_refused_cb(admin):
115 self.info('Connection to %s:%d refused.' % (host, port))
116
117 def connection_failed_cb(admin, string):
118 self.info('Connection to %s:%d failed: %s' % (host, port, string))
119
120 a = admin.AdminModel(authenticator)
121
122 a.connectToHost(host, port, use_insecure, keep_trying=tenacious)
123 a.connect('connected', connected_cb)
124 a.connect('disconnected', disconnected_cb)
125 a.connect('connection-refused', connection_refused_cb)
126 a.connect('connection-failed', connection_failed_cb)
127 return a
128
131
145
147 '''Call a method on the remote component object associated with
148 a component state'''
149 admin = get_admin_for_object(object)
150 def do_op(object):
151 admin.callRemote('component'+op, object)
152 self.for_each_component(object, do_op)
153