1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """
23 Objects related to the state of workers.
24 """
25
26 import os
27 import signal
28
29 from twisted.spread import pb
30 from twisted.internet import protocol
31
32 from flumotion.twisted import flavors
33 from flumotion.common import log, errors, messages
34
35 from flumotion.common.messages import N_
36 T_ = messages.gettexter('flumotion')
37
39 - def __init__(self, loggable, avatarId, processType, where):
40 self.loggable = loggable
41 self.avatarId = avatarId
42 self.processType = processType
43 self.where = where
44
45 self.setPid(None)
46
49
51 raise NotImplementedError
52
54
55
56
57
58 message = None
59 obj = self.loggable
60 pid = None
61
62
63 if self.pid:
64 pid = str(self.pid)
65 else:
66 pid = "unknown"
67 if status.value.exitCode is not None:
68 obj.info("Reaped child with pid %s, exit value %d.",
69 pid, status.value.exitCode)
70 signum = status.value.signal
71
72
73
74
75 if signum is not None:
76 if signum == signal.SIGKILL:
77 obj.warning("Child with pid %s killed.", pid)
78 message = messages.Error(T_(N_("The %s was killed.\n"),
79 self.processType))
80 else:
81 message = messages.Error(T_(N_("The %s crashed.\n"),
82 self.processType),
83 debug='Terminated with signal number %d' % signum)
84
85
86 if signum == signal.SIGSEGV:
87 obj.warning("Child with pid %s segfaulted.", pid)
88 elif signum == signal.SIGTRAP:
89
90 obj.warning("Child with pid %s received a SIGTRAP.",
91 pid)
92 else:
93
94 obj.info("Reaped child with pid %s signaled by "
95 "signal %d.", pid, signum)
96
97 if not os.WCOREDUMP(status.value.status):
98 obj.warning("No core dump generated. "
99 "Were core dumps enabled at the start ?")
100 message.add(T_(N_(
101 "However, no core dump was generated. "
102 "You may need to configure the environment "
103 "if you want to further debug this problem.")))
104 else:
105 obj.info("Core dumped.")
106 corepath = os.path.join(os.getcwd(), 'core.%s' % pid)
107 if os.path.exists(corepath):
108 obj.info("Core file is probably '%s'." % corepath)
109 message.add(T_(N_(
110 "The core dump is '%s' on the host running '%s'."),
111 corepath, self.where))
112
113
114
115
116 if message:
117 obj.debug('sending message to manager/admin')
118 self.sendMessage(message)
119
120 self.setPid(None)
121
123 """
124 A list of ports that keeps track of which are available for use on a
125 given machine.
126 """
127
129 self.logName = logName
130 self.ports = ports
131 self.used = [0] * len(ports)
132
134 ret = []
135 while numPorts > 0:
136 if not 0 in self.used:
137 raise errors.ComponentStartError(
138 'could not allocate port on worker %s' % self.logName)
139 i = self.used.index(0)
140 ret.append(self.ports[i])
141 self.used[i] = 1
142 numPorts -= 1
143 return ret
144
146 for port in ports:
147 try:
148 i = self.ports.index(port)
149 except IndexError:
150 self.warning('portset does not include port %d', port)
151 else:
152 if self.used[i]:
153 self.warning('port %d already in use!', port)
154 else:
155 self.used[i] = 1
156
158 """
159 @param ports: list of ports to release
160 @type ports: list of int
161 """
162 for p in ports:
163 try:
164 i = self.ports.index(p)
165 if self.used[i]:
166 self.used[i] = 0
167 else:
168 self.warning('releasing unallocated port: %d' % p)
169 except ValueError:
170 self.warning('releasing unknown port: %d' % p)
171
173 return len(self.ports) - self.numUsed()
174
176 return len(filter(None, self.used))
177
178
180 """
181 I represent the state of the worker heaven on the manager.
182
183 I have the following keys:
184
185 - names (list): list of worker names that we have state for
186 - workers (list): list of L{ManagerWorkerState}
187 """
192
194 return "%r" % self._dict
195
197 """
198 I represent the state of the worker heaven in the admin.
199 See L{ManagerWorkerHeavenState}
200 """
201 pass
202
203 pb.setUnjellyableForClass(ManagerWorkerHeavenState, AdminWorkerHeavenState)
204
206 """
207 I represent the state of a worker in the manager.
208
209 - name: name of the worker
210 - host: the IP address of the worker as seen by the manager
211 """
218
220 return ("<ManagerWorkerState for %s on %s>"
221 % (self.get('name'), self.get('host')))
222
224 """
225 I represent the state of a worker in the admin.
226
227 See L{ManagerWorkerState}
228 """
229 pass
230
231 pb.setUnjellyableForClass(ManagerWorkerState, AdminWorkerState)
232