1 | |
---|
2 | import sys |
---|
3 | import tempfile |
---|
4 | import threading |
---|
5 | import os |
---|
6 | import glob |
---|
7 | from jinja2 import Environment |
---|
8 | from jinja2.loaders import FileSystemLoader |
---|
9 | |
---|
10 | |
---|
11 | class OpenSysClone: |
---|
12 | |
---|
13 | # Templates variables |
---|
14 | TEMPLATES_PATH="/usr/share/n4d/templates/OpenSysClone/" |
---|
15 | SAVE_IMAGE_TPL="SaveImage.tpl" |
---|
16 | PXE_DESTINATION="/var/www/ipxeboot/pxemenu.d/70-OpenSysClone.php" |
---|
17 | PATH_FILE="/net/OpenSysClone/" |
---|
18 | USER_PATH_FILE="imagenes" |
---|
19 | NAME_FILE="autoname" |
---|
20 | HDD_DISK="sda1" |
---|
21 | FINAL_ACTION="poweroff" |
---|
22 | MIN_CLIENTS = "8" |
---|
23 | MAX_WAIT = "100" |
---|
24 | UDP_PATH="/net/OpenSysClone/prueba" |
---|
25 | INTERFACE="eth0" |
---|
26 | HOST_OPERATION="hostnamesaver.sh" |
---|
27 | EXPORT_NFS_PATH="/etc/exports.d/" |
---|
28 | EXPORT_NFS_NAME="opensysclone_nfs.exports" |
---|
29 | |
---|
30 | |
---|
31 | def __init__(self): |
---|
32 | pass |
---|
33 | #def init |
---|
34 | |
---|
35 | def startup(self,options): |
---|
36 | if objects["VariablesManager"].get_variable('OPENSYSCLONE_SQUASHFS_PROTOCOL') is None: |
---|
37 | objects["VariablesManager"].init_variable('OPENSYSCLONE_SQUASHFS_PROTOCOL') |
---|
38 | |
---|
39 | #def startup |
---|
40 | |
---|
41 | def write_menu_pxe(self, aux_save_image_tpl=SAVE_IMAGE_TPL, aux_user_path_file = USER_PATH_FILE, aux_name_file = NAME_FILE , aux_hdd_disk = HDD_DISK ,aux_final_action=FINAL_ACTION, aux_host_operation=HOST_OPERATION): |
---|
42 | |
---|
43 | try: |
---|
44 | # save_path, name_file, hdd_disk, final_action |
---|
45 | environment_variables = {} |
---|
46 | aux_path_file=self.PATH_FILE+aux_user_path_file |
---|
47 | |
---|
48 | # Get the values from free server |
---|
49 | if objects.has_key("VariablesManager"): |
---|
50 | environment_variables=objects["VariablesManager"].get_variable_list(["SRV_IP","OPENSYSCLONE_SQUASHFS_PROTOCOL"]) |
---|
51 | |
---|
52 | #Prepare PATH to TFTP or HTTP protocol |
---|
53 | protocolo=objects["VariablesManager"].get_variable("OPENSYSCLONE_SQUASHFS_PROTOCOL") |
---|
54 | |
---|
55 | if protocolo=="http": |
---|
56 | path_squashfs="ipxeboot/opensysclone-system" |
---|
57 | else: |
---|
58 | path_squashfs="opensysclone-system" |
---|
59 | |
---|
60 | |
---|
61 | environment_variables["PATH_SQUASHFS"]=path_squashfs |
---|
62 | environment_variables["PATH_FILE"]=aux_path_file |
---|
63 | environment_variables["NAME_FILE"]=aux_name_file |
---|
64 | environment_variables["HDD_DISK"]=aux_hdd_disk |
---|
65 | environment_variables["FINAL_ACTION"]=aux_final_action |
---|
66 | environment_variables["HOST_OPERATION"]=aux_host_operation |
---|
67 | |
---|
68 | |
---|
69 | path_to_work=tempfile.mkdtemp() |
---|
70 | filename=path_to_work+"OpenSysClone.pxe" |
---|
71 | |
---|
72 | # Create temporal environment for jinja |
---|
73 | env = Environment(loader=FileSystemLoader(OpenSysClone.TEMPLATES_PATH)) |
---|
74 | tmpl = env.get_template(aux_save_image_tpl) |
---|
75 | |
---|
76 | # Render the template with diferent values |
---|
77 | textrendered=tmpl.render(environment_variables) |
---|
78 | |
---|
79 | #Create a temporal for nsswitch |
---|
80 | tmp,filename=tempfile.mkstemp() |
---|
81 | f = open(filename,'w') |
---|
82 | f.writelines(textrendered) |
---|
83 | f.close() |
---|
84 | |
---|
85 | # Using the ultimate chmod |
---|
86 | self.uchmod(filename,0644) |
---|
87 | |
---|
88 | # Copy unitaria |
---|
89 | shutil.copy(filename,OpenSysClone.PXE_DESTINATION) |
---|
90 | COMMENT_END = "PXE menu is prepared with protocol %s for SQUASHFS, your requirements have writed in this file %s" %(protocolo,OpenSysClone.PXE_DESTINATION) |
---|
91 | return [True,str(COMMENT_END)] |
---|
92 | |
---|
93 | except Exception as e: |
---|
94 | |
---|
95 | return [False,str(e)] |
---|
96 | |
---|
97 | |
---|
98 | #def write_menu_pxe |
---|
99 | |
---|
100 | |
---|
101 | |
---|
102 | def del_menu_pxe(self, AUX_PXE_DESTINATION=PXE_DESTINATION): |
---|
103 | |
---|
104 | try: |
---|
105 | # Remove obsolete file for PXE menu |
---|
106 | if os.path.isfile(AUX_PXE_DESTINATION): |
---|
107 | os.remove (AUX_PXE_DESTINATION) |
---|
108 | COMMENT_END = "Remove obsolete file %s for PXE menu" %(AUX_PXE_DESTINATION) |
---|
109 | |
---|
110 | return [True, str(COMMENT_END)] |
---|
111 | else: |
---|
112 | COMMENT_END = "PXE file was delete before" |
---|
113 | return [True, str(COMMENT_END)] |
---|
114 | |
---|
115 | except Exception as e: |
---|
116 | |
---|
117 | return [False,str(e)] |
---|
118 | #def del_menu_pxe |
---|
119 | |
---|
120 | |
---|
121 | |
---|
122 | def nfs_export_start (self, AUX_USER_PATH_FILE=USER_PATH_FILE): |
---|
123 | |
---|
124 | try: |
---|
125 | AUX_PATH_FILE=self.PATH_FILE+AUX_USER_PATH_FILE |
---|
126 | # Get the values from free server |
---|
127 | if objects.has_key("VariablesManager"): |
---|
128 | INTERNAL_NETWORK_VARIABLES=objects["VariablesManager"].get_variable_list(["INTERNAL_NETWORK","INTERNAL_MASK"]) |
---|
129 | |
---|
130 | #Export file to write or read OpenSysClone in the server to network range |
---|
131 | #With new file arguments |
---|
132 | if os.path.dirname(AUX_PATH_FILE): |
---|
133 | result = os.system('mkdir -p %s'%self.EXPORT_NFS_PATH) |
---|
134 | try: |
---|
135 | fich = open(self.EXPORT_NFS_PATH+"/"+self.EXPORT_NFS_NAME,"w") |
---|
136 | fich.write(str(AUX_PATH_FILE)+"\t"+str(INTERNAL_NETWORK_VARIABLES["INTERNAL_NETWORK"])+"/"+str(INTERNAL_NETWORK_VARIABLES["INTERNAL_MASK"])+"(rw,insecure,no_root_squash,async,no_subtree_check)\n") |
---|
137 | fich.close() |
---|
138 | except Exception as e: |
---|
139 | return [False,'Export failed: '+str(e)] |
---|
140 | #cmd='exportfs -o rw,insecure,no_root_squash,async,no_subtree_check %s/%s:%s'%(INTERNAL_NETWORK_VARIABLES["INTERNAL_NETWORK"],INTERNAL_NETWORK_VARIABLES["INTERNAL_MASK"],AUX_PATH_FILE) |
---|
141 | cmd='service nfs-kernel-server restart' |
---|
142 | #print cmd |
---|
143 | os.system(cmd) |
---|
144 | COMMENT_END = "NFS is sharing %s to my internal network %s/%s" %(AUX_PATH_FILE,INTERNAL_NETWORK_VARIABLES["INTERNAL_NETWORK"],INTERNAL_NETWORK_VARIABLES["INTERNAL_MASK"]) |
---|
145 | return [True, str(COMMENT_END)] |
---|
146 | else: |
---|
147 | return [False,str(e)] |
---|
148 | |
---|
149 | except Exception as e: |
---|
150 | |
---|
151 | return [False,str(e)] |
---|
152 | #def nfs_export |
---|
153 | |
---|
154 | |
---|
155 | |
---|
156 | def nfs_export_stop (self,AUX_USER_PATH_FILE=USER_PATH_FILE): |
---|
157 | |
---|
158 | #Restart nfs service to restart default parameters and stop extra parameters |
---|
159 | |
---|
160 | #try: |
---|
161 | # os.system('service nfs-kernel-server restart') |
---|
162 | # COMMENT_END = "The NFS system is restarted with defaults parameters and suprimed OpeSysClone shared parameters" |
---|
163 | # return [True, str(COMMENT_END)] |
---|
164 | |
---|
165 | #except Exception as e: |
---|
166 | |
---|
167 | # return [False,str(e)] |
---|
168 | try: |
---|
169 | AUX_PATH_FILE=self.PATH_FILE+AUX_USER_PATH_FILE |
---|
170 | |
---|
171 | # Get the values from free server |
---|
172 | if objects.has_key("VariablesManager"): |
---|
173 | INTERNAL_NETWORK_VARIABLES=objects["VariablesManager"].get_variable_list(["INTERNAL_NETWORK","INTERNAL_MASK"]) |
---|
174 | |
---|
175 | |
---|
176 | #Cancel the export file to write or read OpenSysClone in the server to network range |
---|
177 | #Deleting file with arguments and restarting the service |
---|
178 | |
---|
179 | if os.path.dirname(AUX_PATH_FILE): |
---|
180 | result = os.system("rm -f %s"%self.EXPORT_NFS_PATH+"/"+self.EXPORT_NFS_NAME) |
---|
181 | os.system('service nfs-kernel-server restart') |
---|
182 | #os.system('exportfs -u %s/%s:%s'%(INTERNAL_NETWORK_VARIABLES["INTERNAL_NETWORK"],INTERNAL_NETWORK_VARIABLES["INTERNAL_MASK"],AUX_PATH_FILE)) |
---|
183 | COMMENT_END = "NFS is NOT SHARING %s to my internal network %s/%s" %(AUX_PATH_FILE,INTERNAL_NETWORK_VARIABLES["INTERNAL_NETWORK"],INTERNAL_NETWORK_VARIABLES["INTERNAL_MASK"]) |
---|
184 | return [True, str(COMMENT_END)] |
---|
185 | else: |
---|
186 | return [False,str(e)] |
---|
187 | |
---|
188 | except Exception as e: |
---|
189 | |
---|
190 | return [False,str(e)] |
---|
191 | |
---|
192 | |
---|
193 | #def nfs_export_stop |
---|
194 | |
---|
195 | |
---|
196 | def uchmod(self,file,mode): |
---|
197 | |
---|
198 | try: |
---|
199 | #Method to change file attributes |
---|
200 | |
---|
201 | prevmask = os.umask(0) |
---|
202 | os.chmod(file,mode) |
---|
203 | os.umask(prevmask) |
---|
204 | |
---|
205 | except Exception as e: |
---|
206 | |
---|
207 | return [False,str(e)] |
---|
208 | #def uchmod |
---|
209 | |
---|
210 | |
---|
211 | def aux_send_multicast_file (self, AUX_USER_PATH_FILE=USER_PATH_FILE, AUX_NAME_FILE=NAME_FILE, AUX_MIN_CLIENTS=MIN_CLIENTS, AUX_MAX_WAIT=MAX_WAIT,AUX_INTERFACE=INTERFACE,AUX_UDP_PATH=UDP_PATH): |
---|
212 | |
---|
213 | try: |
---|
214 | #Method to restart nfs service to restart default parameters and stop extra parameters |
---|
215 | AUX_PATH_FILE=self.PATH_FILE+AUX_USER_PATH_FILE |
---|
216 | os.system('killall udp-sender') |
---|
217 | #Inicializo el puerto de UDP que debe ser 2232 para la primera particion y +2 para cada una de las siguientes |
---|
218 | AUX_UDP_PORT=2232 |
---|
219 | INSTRUCTION = '' |
---|
220 | |
---|
221 | #Obtengo las particiones a clonar y las meto en una lista |
---|
222 | tmp=set() |
---|
223 | |
---|
224 | for item in glob.glob(AUX_UDP_PATH+"/*.gz.*"): |
---|
225 | #Para obtener las particiones he de eliminar primero la primera parte del path puesto que puede llevar puntos y luego no haria bien el split |
---|
226 | item=item.replace(AUX_UDP_PATH+"/","") |
---|
227 | #Corto por el primer punto y me quedo con la primera parte |
---|
228 | item=item.split(".")[0] |
---|
229 | #Elimino las cadenas iguales |
---|
230 | tmp.add(item) |
---|
231 | |
---|
232 | AUX_PARTITIONS_LIST=sorted(tmp) |
---|
233 | |
---|
234 | print AUX_PARTITIONS_LIST |
---|
235 | |
---|
236 | #Recorro la lista de particiones y creo la instruccion |
---|
237 | |
---|
238 | for PARTITION in AUX_PARTITIONS_LIST : |
---|
239 | INSTRUCTION += 'cat %s/%s*.gz.* | udp-sender --full-duplex --retries-until-drop 100 --min-clients %s --max-wait %s --interface %s --nokbd --mcast-all-addr 224.0.0.1 --portbase %s --ttl 1;'%((AUX_UDP_PATH),(PARTITION),(AUX_MIN_CLIENTS),(AUX_MAX_WAIT),(AUX_INTERFACE),(AUX_UDP_PORT)) |
---|
240 | AUX_UDP_PORT=AUX_UDP_PORT+2 |
---|
241 | |
---|
242 | os.system ('%s'%INSTRUCTION) |
---|
243 | COMMENT_END = "Instruction in server for MULTICAST is: %s" %(INSTRUCTION) |
---|
244 | |
---|
245 | #print COMMENT_END |
---|
246 | |
---|
247 | return [True, str(COMMENT_END)] |
---|
248 | |
---|
249 | except Exception as e: |
---|
250 | |
---|
251 | return [False,str(e)] |
---|
252 | |
---|
253 | #os.system('cat %(AUX_UDP_PATH)s/*.gz.* | udp-sender --full-duplex --min-clients %(AUX_MIN_CLIENTS)s --max-wait %(AUX_MAX_WAIT)s --interface %(AUX_INTERFACE)s --nokbd --mcast-all-addr 224.0.0.1 --portbase %(AUX_UDP_PORT)s --ttl 1' % locals ()) |
---|
254 | |
---|
255 | #def aux_send_multicast_file |
---|
256 | |
---|
257 | |
---|
258 | def send_multicast_file (self, AUX_USER_PATH_FILE=USER_PATH_FILE, AUX_NAME_FILE=NAME_FILE, AUX_MIN_CLIENTS=MIN_CLIENTS, AUX_MAX_WAIT=MAX_WAIT): |
---|
259 | |
---|
260 | #Method to execute multiprocess |
---|
261 | |
---|
262 | try: |
---|
263 | AUX_PATH_FILE=self.PATH_FILE+AUX_USER_PATH_FILE |
---|
264 | # Get the values from free server |
---|
265 | if objects.has_key("VariablesManager"): |
---|
266 | INTERFACE=objects["VariablesManager"].get_variable("INTERNAL_INTERFACE") |
---|
267 | |
---|
268 | |
---|
269 | #Get the UDP path to export in multicast mode |
---|
270 | UDP_PATH=AUX_PATH_FILE+"/"+AUX_NAME_FILE |
---|
271 | |
---|
272 | if os.path.exists(UDP_PATH): |
---|
273 | |
---|
274 | COMMENT_END = "UDP is in multicast mode for my internal network interface %s" %(INTERFACE) |
---|
275 | |
---|
276 | |
---|
277 | #Instructions to execute multiprocess |
---|
278 | t = threading.Thread(target=self.aux_send_multicast_file,args=(AUX_PATH_FILE,AUX_NAME_FILE,AUX_MIN_CLIENTS,AUX_MAX_WAIT,INTERFACE,UDP_PATH)) |
---|
279 | t.daemon=True |
---|
280 | t.start() |
---|
281 | return [True, str(COMMENT_END)] |
---|
282 | else: |
---|
283 | COMMENT_END = "Your image don't exists in this directory" |
---|
284 | return [False,str(COMMENT_END)] |
---|
285 | |
---|
286 | except Exception as e: |
---|
287 | |
---|
288 | return [False,str(e)] |
---|
289 | |
---|
290 | #def send_multicast_file |
---|
291 | |
---|
292 | |
---|
293 | def list_img (self, AUX_USER_PATH_FILE=USER_PATH_FILE): |
---|
294 | |
---|
295 | #Method to list our ISOS in Server |
---|
296 | |
---|
297 | try: |
---|
298 | AUX_PATH_FILE=self.PATH_FILE+AUX_USER_PATH_FILE |
---|
299 | LIST_DIR=os.listdir(AUX_PATH_FILE) |
---|
300 | |
---|
301 | return [True,LIST_DIR] |
---|
302 | |
---|
303 | except Exception as e: |
---|
304 | |
---|
305 | return [False,str(e)] |
---|
306 | |
---|
307 | def check_path (self, AUX_USER_PATH_FILE=USER_PATH_FILE): |
---|
308 | |
---|
309 | #Method to make our dir to save images |
---|
310 | |
---|
311 | try: |
---|
312 | AUX_PATH_FILE=self.PATH_FILE+AUX_USER_PATH_FILE |
---|
313 | |
---|
314 | if os.path.exists(AUX_PATH_FILE): |
---|
315 | COMMENT_END = "Path file exists, do nothing" |
---|
316 | return [True, str(COMMENT_END)] |
---|
317 | else: |
---|
318 | os.makedirs(AUX_PATH_FILE,0777) |
---|
319 | os.chmod(AUX_PATH_FILE,0777) |
---|
320 | COMMENT_END = "Path file is created now %s" %(AUX_PATH_FILE) |
---|
321 | return [True, str(COMMENT_END)] |
---|
322 | |
---|
323 | except Exception as e: |
---|
324 | |
---|
325 | return [False,str(e)] |
---|
326 | |
---|
327 | |
---|
328 | def del_image (self, DIR_FILE_DELETE): |
---|
329 | |
---|
330 | #Method to delete our save images |
---|
331 | |
---|
332 | try: |
---|
333 | AUX1_PATH_FILE=self.PATH_FILE+self.USER_PATH_FILE |
---|
334 | AUX_PATH_FILE=AUX1_PATH_FILE+"/"+DIR_FILE_DELETE |
---|
335 | |
---|
336 | if os.path.exists(AUX_PATH_FILE): |
---|
337 | os.system('rm -R %s'%(AUX_PATH_FILE)) |
---|
338 | COMMENT_END = "Path file is deleted %s" %(AUX_PATH_FILE) |
---|
339 | return [True, str(COMMENT_END)] |
---|
340 | else: |
---|
341 | COMMENT_END = "Path file isn't exists %s" %(AUX_PATH_FILE) |
---|
342 | return [True, str(COMMENT_END)] |
---|
343 | |
---|
344 | except Exception as e: |
---|
345 | |
---|
346 | return [False,str(e)] |
---|
347 | |
---|
348 | #def list_img |
---|
349 | |
---|
350 | |
---|
351 | |
---|
352 | |
---|
353 | |
---|
354 | |
---|