1
2
3
4
5
6
7
8
9 """
10
11 """
12
13 try: _
14 except NameError: _ = str
15
16 import os, dircache
17 from twisted.python import log
18
19 from zephir.monitor.agentmanager import config as cfg
20 from zephir.monitor.agentmanager.agent import AgentData
21
22
23
24
26 """Structure d'accès aux agents d'un poste client donné (classe
27 abstraite).
28
29 Se comporte comme un dictionnaire C{{nom: agent}}.
30
31 TODO: utiliser UserDict.DictMixin
32 """
33
34 - def __init__(self, config, client_name):
35 """
36 @param config: dictionnaire des options de configuration de
37 l'application
38
39 @param client_name: nom du client qui possède les agents
40 """
41 self.config = config
42 self.client_name = client_name
43 self.structure = self.load_structure()
44
46 done = []
47
48 for item in order_list:
49 if item in liste:
50 done.append(item)
51
52 liste.sort()
53 for item in liste:
54 if item not in done:
55 done.append(item)
56 return done
57
59 """Recharge le classement en sections des agents.
60 utile si un nouvel agent est remonté dans un datamanager"""
61 self.structure = self.load_structure()
62
64 """Charge le classement en sections des agents.
65
66 Charge le fichier C{site.cfg} du répertoire de données
67 correspondant au poste client. Ce fichier doit déclarer une
68 variable C{SITE}. Cette variable doit contenir une liste de
69 couples C{('titre de section': liste d'agents)}, qui définit
70 le classement des agents dans la page du client.
71
72 Une structuration par défaut est créée si le C{site.cfg}
73 n'existe pas.
74 """
75 h = { 'SITE': None }
76 structure_file = os.path.join(
77 cfg.client_data_dir(self.config, self.client_name),
78 "site.cfg")
79 self.order_section = []
80 self.order_agent = {}
81 try:
82 execfile(structure_file, globals(), h)
83 assert h['SITE'] is not None and type(h['SITE']) is list
84 structure = h['SITE']
85 for sct, ag in structure:
86 self.order_section.append(sct)
87 self.order_agent[sct] = ag
88 except IOError:
89 pass
90
91 unclassified_agents = []
92 struct = {}
93 for name, agent in self.items():
94 if hasattr(agent, 'section'):
95 section = agent.section
96 else:
97 section = None
98
99 for sct, agents in self.order_agent.items():
100 if name in agents:
101 section = sct
102 if section is None:
103 unclassified_agents.append(name)
104 elif struct.has_key(section):
105 struct[section].append(name)
106 else:
107 struct[section] = [name]
108
109 final_struct = []
110 for section in self._sort_struct(struct.keys(), self.order_section):
111 agents = struct[section]
112 final_struct.append((section, self._sort_struct(agents, self.order_agent[section])))
113
114 if len(final_struct) == 0 and len(unclassified_agents) != 0:
115 final_struct.append((None, unclassified_agents))
116
117 return final_struct
118
121
123 """Renvoie les données stockées à la dernière mesure (sentinelle)
124 """
125 result = {}
126 for agent_name,data in self.items():
127 if hasattr(data, 'measure_data'):
128 result[agent_name] = data.measure_data
129 else:
130 result[agent_name] = {}
131 return result
132
134
135 result = []
136 for k in self.keys():
137 result.append([k, self[k]])
138 return result
139
142
143
144
145
147 """Implémentation de C{L{AgentManager}} chargeant les données des
148 agents depuis leurs archives sur disque exclusivement.
149
150 Le chargement des données se fait à travers un cache.
151 """
152
153
154 - def __init__(self, config, client_name):
157
159 """Accès par nom aux agents (opérateur [] d'un dictionnaire).
160 """
161
162 agent_dir = cfg.agent_data_dir(self.config, self.client_name, agent_name)
163
164 needs_refresh = False
165 try:
166 (mtime, agent) = self.cache[agent_name]
167 except KeyError: needs_refresh = True
168 disk_mtime = os.path.getmtime(os.path.join(agent_dir, 'agent.xml'))
169 if needs_refresh or (disk_mtime > mtime):
170 agent = AgentData.from_archive(agent_dir)
171 self.cache[agent_name] = (disk_mtime, agent)
172 return agent
173
174
176 """Affectation par nom aux agents (opérateur []= d'un
177 dictionnaire).
178 """
179 assert false, "Can't assign agent archives"
180
181
183 d = cfg.agent_data_dir(self.config, self.client_name, agent_name)
184 agent_data_dir_exists = os.path.isdir(d)
185 agent_metadata_exists = os.path.isfile(os.path.join(d, 'agent.xml'))
186 return agent_data_dir_exists and agent_metadata_exists
187
188
190 d = cfg.client_data_dir(self.config, self.client_name)
191 result = []
192 for k in dircache.listdir(d):
193 if self.has_key(k): result.append(k)
194 return result
195
197 """Méthode de compatibilité avec l'ancien système d'agents.
198 """
199
200 real_agents = []
201
202 ignore_list = []
203
204 fic_override = os.path.normpath(os.path.join(cfg.client_data_dir(self.config, self.client_name),'../ignore_list'))
205 if os.path.exists(fic_override):
206 f = open(fic_override)
207 ignore_list.extend(f.read().strip().split('\n'))
208 f.close()
209
210 fic_override = os.path.join(cfg.client_data_dir(self.config, self.client_name),'ignore_list')
211 if os.path.exists(fic_override):
212 f = open(fic_override)
213 ignore_list.extend(f.read().strip().split('\n'))
214 f.close()
215 for fam in self.structure:
216 real_agents.extend(fam[1])
217
218 for agent in ignore_list:
219 if agent in real_agents:
220 real_agents.remove(agent)
221 for agent_name in self.keys():
222 if self[agent_name].last_status.level() in ['Error']:
223 if agent_name in real_agents:
224 return 0
225 return 1
226
228 """Méthode de compatibilité avec l'ancien système d'agents.
229
230 @return: dictionnaire C{{'nom agent': (description, status, date de dernière mesure)}}.
231 """
232 result = {}
233 for agent_name,data in self.items():
234 if data.last_status.level() in ['Error']:
235 status=0
236 else:
237 status=1
238
239 libelle = data.description
240 if libelle == '':
241 libelle=agent_name
242 result[agent_name]=[libelle,status,data.last_measure_date]
243 return result
244
248
249
250
251
252
253
254
256 """Implémentation de C{L{AgentManager}} donnant accès direct aux
257 agents en mémoire.
258
259 Utile pour les agents chargés sur la même machine. La page web
260 sera mise à jour en temps réel plutôt qu'au rythme des envois de
261 données au serveur Zephir.
262 """
263
264 - def __init__(self, config, client_name, agents):
267
268
273
274
277
280
283