1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 import os,time,shutil,tempfile
16
17 UUCP_DIR = "/var/spool/uucp"
18 CMD_UUX = "/usr/bin/uux2"
19 CMD_UUCP = "/usr/bin/uucp2"
20 LOG_FILE = "/tmp/rapport.zephir"
21 LOCK = "/var/spool/uucp/lock"
22 IGNORE_LIST = ['.ssh','.Status','.Temp','.Received','.bash_history','dead.letter']
23
24 COMMANDS = {"zephir_client save_files":"Sauvegarde complète",
25 "zephir_client save_files 0":"Sauvegarde (complète)",
26 "zephir_client save_files 1":"Sauvegarde (configuration)",
27 "zephir_client save_files 2":"Sauvegarde (configuration/patchs/dicos)",
28 "zephir_client save_files 3":"Sauvegarde (fichiers divers)",
29 "zephir_client maj_auto":"Mise à jour",
30 "zephir_client maj_auto E":"Mise à jour complète",
31 "zephir_client maj_client":"Mise à jour de zephir-client",
32 "zephir_client download_upgrade":"Préchargement des paquets (Upgrade-Auto)",
33 "zephir_client configure":"Envoi de configuration",
34 "zephir_client reboot":"Redémarrage du serveur",
35 "zephir_client service_restart":"Redémarrage du service",
36 "zephir_client reconfigure":"Reconfiguration",
37 "zephir_client update_key regen_certs":"Renouvellement des clés d'enregistrement et certificats ssl",
38 "zephir_client update_key":"Renouvellement des clés d'enregistrement",
39 "zephir_client change_ip":"Préparation au changement d'adresse de zephir",
40 "zephir_client purge_ip":"Annulation du changement d'adresse de zephir",}
41
42 UUCPError = 'UUCPError'
43
44
45 NUMBERS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z','a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
46
47
49 result=0
50 digits = range(len(chaine))
51
52 digits.reverse()
53 for i in range(len(chaine)):
54
55 digit = NUMBERS.index(chaine[digits[i]])
56
57 result = result + digit * len(NUMBERS).__pow__(i)
58 return result
59
61 """wrapper d'uucp pour permettre la gestion des files dans zephir"""
62
64 """initialisation de l'objet"""
65 self.peers_ori=peers
66 self.pool={}
67 self._scan_pool()
68
70 """crée la liste d'attente en mémoire"""
71
72
73 if peer is not None:
74 peers = [peer]
75 else:
76 if self.peers_ori is None:
77 peers = os.listdir(UUCP_DIR)
78 for peer in IGNORE_LIST:
79 if peer in peers:
80 peers.remove(peer)
81 else:
82 peers = self.peers_ori
83
84 for peer in peers:
85
86 peer_dir = os.path.abspath(UUCP_DIR+os.sep+peer)
87
88 lst={}
89 if os.path.isdir(peer_dir+"/C."):
90 for fic in os.listdir(peer_dir+"/C."):
91
92 date_creat = os.stat(peer_dir+"/C./"+fic)[-1]
93 f=file(peer_dir+"/C./"+fic)
94 l=f.read().strip().split('\n')[0]
95 f.close()
96
97
98
99
100 args=l.split()[1]
101 script=l.split()[5]
102 seq_number=convert_num(script[-4:])
103
104 type_cmd = "transfert"
105 if args.startswith("D.X"):
106 type_cmd = "execute"
107
108 f=file(peer_dir+"/D.X/"+script)
109 l=f.read().strip().split('\n')
110 f.close()
111 for line in l:
112 line = line.strip()
113 if line[:2] == "C ":
114 args = line[2:]
115
116 cmds = COMMANDS.keys()
117 cmds.sort(reverse=True)
118 for cmd in cmds:
119 if line[2:].startswith(cmd):
120 args = line[2:].replace(cmd, COMMANDS[cmd])
121 break
122
123 lst[seq_number]=(type_cmd,args,script,fic,date_creat)
124
125 self.pool[peer]=lst
126
127
129 """met en place une commande distante"""
130 peer_dir = os.path.abspath(UUCP_DIR+os.sep+peer)
131
132 timeout = 0
133 while os.path.isfile(LOCK):
134
135 timeout += 1
136
137 if timeout > 10:
138
139 raise UUCPError, "Problème d'accès concurrent, fichier %s présent" % LOCK
140 time.sleep(0.5)
141
142
143 lock=file(LOCK,"w")
144 lock.close()
145
146 self._scan_pool(peer)
147 used_grades = []
148 if peer in self.pool:
149 cmd_files = [uucmd[3] for uucmd in self.pool[peer].values()]
150 for uucmd in cmd_files:
151 cmd_grade = convert_num(uucmd[2])
152 if cmd_grade not in used_grades:
153 used_grades.append(cmd_grade)
154 if used_grades != []:
155 new_grade = max(used_grades) + 1
156 else:
157
158 new_grade = 24
159
160 if new_grade >= len(NUMBERS):
161 new_grade = NUMBERS[-1]
162 else:
163 new_grade = NUMBERS[new_grade]
164
165 cmd = "%s -g %s -r '%s!%s >%s!%s'" % (CMD_UUX,new_grade,peer,commande,peer,LOG_FILE)
166 try:
167
168 res=os.system(cmd)
169
170 if res == 0:
171
172 tempbuf=tempfile.mktemp()
173 os.system("/bin/ls -t %s" % peer_dir+"/C./ > %s" % tempbuf)
174 output=file(tempbuf)
175 res2=output.read()
176 output.close()
177 os.unlink(tempbuf)
178
179 filename = res2.split()[0]
180
181 f=file(peer_dir+"/C./"+filename)
182 l=f.read().strip().split('\n')[0]
183 f.close()
184 script = l.split()[5]
185
186 seq_num=convert_num(script[-4:])
187 if not self.pool.has_key(peer):
188 self.pool[peer]={}
189 self.pool[peer][seq_num]=("execute",commande,script,filename)
190
191 os.unlink(LOCK)
192 return seq_num
193 else:
194 os.unlink(LOCK)
195 raise Exception("uux2 a retourné une erreur")
196 except Exception,e:
197 os.unlink(LOCK)
198
199 raise UUCPError, """erreur lors de la préparation de l'exécution de %s : %s""" % (commande,str(e))
200
201 - def add_file(self,peer,fichier,destination="~"):
202 """prépare l'envoi d'un fichier"""
203 peer_dir = os.path.abspath(UUCP_DIR+os.sep+peer)
204
205 cmd = "%s -r %s %s\\!%s" % (CMD_UUCP,fichier,peer,destination)
206
207 timeout = 0
208 while os.path.isfile(LOCK):
209
210 timeout += 1
211
212 if timeout > 10:
213
214 raise UUCPError, "Problème d'accès concurrent, fichier %s présent" % LOCK
215 time.sleep(0.5)
216
217
218 lock=file(LOCK,"w")
219 lock.close()
220 try:
221
222 res=os.system(cmd)
223
224 if res == 0:
225
226 tempbuf=tempfile.mktemp()
227 os.system("/bin/ls -t %s" % peer_dir+"/C./ > %s" % tempbuf)
228 output=file(tempbuf)
229 res2=output.read()
230 output.close()
231 os.unlink(tempbuf)
232
233 filename = res2.split()[0]
234
235 f=file(peer_dir+"/C./"+filename)
236 l=f.read().strip().split('\n')[0]
237 f.close()
238 script = l.split()[5]
239
240 seq_num=convert_num(script[-4:])
241 if not self.pool.has_key(peer):
242 self.pool[peer]={}
243 self.pool[peer][seq_num]=("transfert",fichier,script,filename)
244
245 os.unlink(LOCK)
246 return 0
247 else:
248 os.unlink(LOCK)
249 raise UUCPError, """echec à l'exécution de uucp"""
250 except Exception,e:
251 os.unlink(LOCK)
252 raise UUCPError, """erreur lors de la préparation du transfert de %s : %s""" % (fichier,e)
253
255 """fonction interne qui liste les actions d'un type particulier"""
256 cmds = {}
257
258 for peer in peers:
259 cmds[peer] = []
260 if not self.pool.has_key(peer):
261 continue
262
263 numeros = self.pool[peer].keys()
264 numeros.sort()
265 for n in numeros:
266 action=self.pool[peer][n]
267
268 if action[0] == type_cmd:
269
270 cmds[peer].append((n,action[1]))
271 return cmds
272
274 """vérifie si il existe des commandes plus anciennes
275 que max_time pour un serveur donné (ou tous)
276 @param max_time: age maximum en seconde accepté pour une commande
277 retourne un dictionnaire {serveur:liste des ids de commande trop anciens}"""
278 dic_res = {}
279 if peer is not None:
280 peers=[peer]
281 else:
282 self._scan_pool()
283 peers=self.pool.keys()
284 for serveur in peers:
285 timeouts = []
286 if self.pool.has_key(serveur):
287 for seq_num, data in self.pool[serveur].items():
288 test_time = time.localtime(float(data[-1] + max_time))
289
290 if test_time < time.localtime():
291
292 timeouts.append((seq_num, time.ctime(data[-1])))
293 if timeouts != []:
294 dic_res[serveur] = timeouts
295 return dic_res
296
298 """renvoie la liste des commandes en attente"""
299 if peer is not None:
300 peers=[peer]
301 else:
302 self._scan_pool()
303 peers=self.pool.keys()
304 return self._create_liste("execute",peers)
305
307 """renvoie la liste des transferts en attente"""
308 if peer is not None:
309 peers=[peer]
310 else:
311 self._scan_pool()
312 peers=self.pool.keys()
313 return self._create_liste("transfert",peers)
314
316 """supprime une commande ou un transfert"""
317 type_cmd,fichier,script,filename,date_creat = self.pool[peer][int(num_cmd)]
318 peer_dir = os.path.abspath(UUCP_DIR+os.sep+peer)
319
320 timeout = 0
321 while os.path.isfile(LOCK):
322
323 timeout += 1
324
325 if timeout > 10:
326
327 raise UUCPError, "Problème d'accès concurrent, fichier %s présent" % LOCK
328 time.sleep(0.5)
329
330
331 lock=file(LOCK,"w")
332 lock.close()
333
334 try:
335 os.unlink(peer_dir+'/C./'+filename)
336 if type_cmd == "transfert":
337
338 os.unlink(peer_dir+'/D./'+script)
339 else:
340
341 os.unlink(peer_dir+'/D.X/'+script)
342
343 os.unlink(LOCK)
344 except:
345
346 os.unlink(LOCK)
347 raise UUCPError, "erreur lors de la suppression des fichiers"
348
349 del(self.pool[peer][int(num_cmd)])
350 return 0
351
352
353 - def flush(self,peers=None):
354 """supprime toute la file d'attente"""
355 if peers is None:
356 for i in os.listdir(UUCP_DIR):
357 if i not in IGNORE_LIST:
358 try:
359
360 if os.path.isdir(UUCP_DIR+os.sep+i):
361 shutil.rmtree(UUCP_DIR+os.sep+i)
362 self.pool[i]={}
363 except:
364 raise UUCPError, """erreur de suppression de la file d'attente de %s""" % i
365 else:
366 try:
367 for peer in peers:
368 if os.path.isdir(UUCP_DIR+os.sep+peer):
369 shutil.rmtree(UUCP_DIR+os.sep+peer)
370 self.pool[peer]={}
371 except:
372 raise UUCPError, """erreur de supression de la file d'attente"""
373 return 0
374
375 uucp_pool = UUCP()
376
377 if __name__ == '__main__':
378 peers = ["0210056X-1","0210056X-2","0210056X-3","0210056X-4","0210056X-5"]
379 uucp=UUCP(peers)
380 peer = ""
381 while not peer in peers:
382 peer = raw_input("\nvoir la file d'attente de : ")
383 print "\ncommandes :\n"
384 for cmd in uucp.list_cmd(peer)[peer]:
385 print " "+str(cmd)
386
387 print "\ntransferts :\n"
388 for cmd in uucp.list_files(peer)[peer]:
389 print " "+str(cmd)
390 print '\n'
391