source: zero-server-wizard/trunk/fuentes/install-files/usr/share/zero-server-wizard/master.py @ 5755

Last change on this file since 5755 was 5755, checked in by hectorgh, 2 years ago

adding replication interface support

File size: 18.2 KB
Line 
1import os
2import os.path
3import xmlrpclib
4import datetime
5import subprocess
6import sys
7import multiprocessing
8from cStringIO import StringIO
9
10
11import lliurex.net
12
13try:
14        import gi
15        gi.require_version('Gtk', '3.0')
16        from gi.repository import Gtk,Gdk,GLib
17except:
18        pass
19
20import gettext
21gettext.textdomain('zero-server-wizard')
22_=gettext.gettext
23
24
25DNS1="172.27.111.5"
26DNS2="172.27.111.6"
27
28class Master:
29       
30       
31        def __init__(self,core,server_conf=None):
32               
33                self.id="MASTER"
34                self.scripts_path="/usr/share/zero-server-wizard/types/master/actions/"
35                self.template={}
36                if server_conf!=None:
37                        try:
38                                for item in server_conf["variables"]:
39                                        self.template[item]=None
40                        except:
41                                pass
42                               
43
44               
45                self.core=core
46               
47        #def __init__
48       
49        def start_gui(self,standalone=False):
50               
51                self.standalone=standalone
52               
53                builder=self.core.builder
54
55               
56               
57                self.apply_button=builder.get_object("apply_button1")
58                self.internal_speed_label=builder.get_object("internal_iface_speed_label1")
59                self.external_speed_label=builder.get_object("external_iface_speed_label1")
60                self.replication_speed_label=builder.get_object("replication_iface_speed_label")
61                self.password_entry=builder.get_object("password_entry2")
62                self.password_entry1=builder.get_object("password_entry3")
63                self.password_entry.connect("changed",self.password_changed)
64                self.password_entry1.connect("changed",self.password_changed)
65                self.srv_name_entry=builder.get_object("srv_name_entry1")
66                self.srv_domain_entry=builder.get_object("srv_domain_entry1")
67                self.internal_combobox=builder.get_object("internal_combobox1")
68                self.internal_combobox.set_name("Button")
69                self.external_combobox=builder.get_object("external_combobox1")
70                self.replication_combobox=builder.get_object("replication_combobox")
71               
72                self.internal_ip_entry=builder.get_object("srvip_entry1")
73                self.internal_mask_entry=builder.get_object("internal_mask_entry1")
74                self.external_ip_entry=builder.get_object("external_ip_entry1")
75                self.external_mask_entry=builder.get_object("external_mask_entry1")
76                self.external_gateway_entry=builder.get_object("external_gateway_entry1")
77                self.dns1_entry=builder.get_object("dns1_entry1")
78                self.dns2_entry=builder.get_object("dns2_entry1")
79                self.pass_label=builder.get_object("pass_label1")
80                self.dhcp_radiobutton=builder.get_object("dhcp_radiobutton1")
81                self.dhcp_radiobutton.connect("toggled",self.radio_button_changed)
82                self.manual_radiobutton=builder.get_object("manual_radiobutton1")
83                self.manual_expander=builder.get_object("manual_expander1")
84                self.manual_expander.set_sensitive(False)
85                self.apply_button.connect("clicked",self.apply_clicked)
86                self.apply_button.set_sensitive(False)
87                self.apply_button.set_name("Button")
88                #self.replication_cbutton=builder.get_object("data_cbutton")
89                #self.replication_cbutton.connect("toggled",self.nfs_options_toggled)
90                self.replication_disabled_rbutton=builder.get_object("disabled_nfs_master_radiobutton")
91                self.nfs_frame=builder.get_object("nfs_frame")
92                self.mount_nfs_radiobutton=builder.get_object("mount_nfs_radiobutton")
93                self.mount_nfs_radiobutton.connect("toggled",self.mount_nfs_rb_toggled)
94                self.export_nfs_radiobutton=builder.get_object("export_nfs_radiobutton")
95                self.nfs_ip_entry=builder.get_object("nfs_ip_entry")
96                               
97                self.set_default_gui_values()
98               
99
100                if standalone:
101                       
102                        Gtk.main()
103
104               
105        #def start_gui
106       
107        def mount_nfs_rb_toggled(self,widget):
108               
109                self.nfs_ip_entry.set_sensitive(widget.get_active())
110               
111        #def mount_nfs_rb_toggled
112       
113        def nfs_options_toggled(self,widget):
114               
115                self.nfs_frame.set_sensitive(widget.get_active())
116               
117        #def nfs_options_toggled
118       
119       
120        def radio_button_changed(self,widget):
121
122                self.manual_expander.set_sensitive(not self.dhcp_radiobutton.get_active())
123                self.manual_expander.set_expanded(not self.dhcp_radiobutton.get_active())
124               
125        #def radio_button_changed
126       
127        def password_changed(self,widget):
128               
129                if self.password_entry.get_text()!=self.password_entry1.get_text():
130                        self.pass_label.set_markup("<span fgcolor='red'>" + _("Passwords do not match") +"</span>")
131                        self.apply_button.set_sensitive(False)
132                else:
133                        self.pass_label.set_markup("")
134                        self.apply_button.set_sensitive(True)
135               
136        #def
137       
138        def set_default_gui_values(self):
139               
140
141                self.iiface_model=Gtk.ListStore(str)
142                self.eiface_model=Gtk.ListStore(str)
143                self.riface_model=Gtk.ListStore(str)
144               
145                self.internal_combobox.set_model(self.iiface_model)
146                self.external_combobox.set_model(self.eiface_model)
147                self.replication_combobox.set_model(self.riface_model)
148                rendi=Gtk.CellRendererText()
149                self.internal_combobox.pack_start(rendi,True)
150                self.internal_combobox.add_attribute(rendi,"text",0)
151                self.internal_combobox.connect("changed",self.get_link_speed,0)
152                rende=Gtk.CellRendererText()
153                self.external_combobox.pack_start(rende,True)
154                self.external_combobox.add_attribute(rende,"text",0)
155                self.external_combobox.connect("changed",self.get_link_speed,1)
156                rendr=Gtk.CellRendererText()
157                self.replication_combobox.pack_start(rende,True)
158                self.replication_combobox.add_attribute(rende,"text",0)
159                self.replication_combobox.connect("changed",self.get_link_speed,2)
160                self.interfaces=lliurex.net.get_devices_info()         
161               
162                self.riface_model.append(["External interface alias (Recommended)"])
163               
164                for item in self.interfaces:
165                        if "eth" in item["name"]:
166                                self.iiface_model.append([item["name"]])
167                                self.eiface_model.append([item["name"]])
168                                self.riface_model.append([item["name"]])
169
170                               
171                self.replication_combobox.set_active(0)
172                self.internal_combobox.set_active(0)
173                if len(self.iiface_model)>1:
174                        self.external_combobox.set_active(1)
175                else:
176                        self.external_combobox.set_active(0)
177                       
178               
179                self.srv_domain_entry.set_text(self.template.setdefault("srv_domain_name","lliurex"))
180                self.srv_domain_entry.set_sensitive(False)
181                self.internal_ip_entry.set_text(self.template.setdefault("srv_ip","10.2.0.254"))
182                self.internal_mask_entry.set_text(self.template.setdefault("internal_mask","255.255.255.0"))
183                self.dns1_entry.set_text(DNS1)
184                self.dns2_entry.set_text(DNS2)
185               
186                try:
187                       
188                        f=open("/etc/hostname")
189                        line=f.readline().strip("\n")
190                        f.close()
191                        self.srv_name_entry.set_text(self.template.setdefault("srv_name",line))
192                except:
193                        pass
194                       
195                self.nfs_ip_entry.set_sensitive(False)
196               
197        #def set_default_gui_values
198       
199        def apply_clicked(self,widget):
200               
201
202                self.get_gui_values()
203               
204               
205        #def apply_clicked
206       
207        def get_gui_values(self):
208               
209                iter=self.internal_combobox.get_active_iter()
210                if iter!=None:
211                        self.template["internal_iface"]=self.iiface_model.get(iter,0)[0]
212                else:
213                        self.template["internal_iface"]=None
214                iter=self.external_combobox.get_active_iter()
215                if iter!=None:
216                        self.template["external_iface"]=self.eiface_model.get(iter,0)[0]
217                else:
218                        self.template["external_iface"]=None
219                iter=self.replication_combobox.get_active_iter()
220                if iter!=None:
221                        self.template["replication_iface"]=self.riface_model.get(iter,0)[0]
222                else:
223                        self.template["replication_iface"]=None
224               
225               
226                self.template["adminpassword"]=self.password_entry.get_text()
227                self.template["enable_data_replication"]=str(not self.replication_disabled_rbutton.get_active()).lower()
228                self.template["mount_nfs"]=str(self.mount_nfs_radiobutton.get_active()).lower()
229                self.template["export_nfs"]=str(self.export_nfs_radiobutton.get_active()).lower()
230                self.template["nfs_ip"]=self.nfs_ip_entry.get_text()
231                self.template["srv_name"]=self.srv_name_entry.get_text()
232                self.template["srv_name"]=''.join(e for e in self.template["srv_name"] if e.isalnum())
233                self.template["srv_domain_name"]=self.srv_domain_entry.get_text()
234                self.template["srv_domain_name"]=''.join(e for e in self.template["srv_domain_name"] if e.isalnum())
235                self.template["srv_ip"]=self.internal_ip_entry.get_text()
236                self.template["internal_mask"]=self.internal_mask_entry.get_text()
237                if self.dhcp_radiobutton.get_active():
238                        self.template["external_mode"]="dhcp"
239
240                else:
241                        self.template["external_mode"]="manual"
242
243                self.template["external_ip"]=self.external_ip_entry.get_text()
244                self.template["external_mask"]=self.external_mask_entry.get_text()
245                self.template["external_gateway"]=self.external_gateway_entry.get_text()
246                self.template["dns1"]=self.dns1_entry.get_text()
247                self.template["dns2"]=self.dns2_entry.get_text()
248               
249                self.check_values()
250       
251       
252        def check_values(self):
253               
254
255                        error_msg=""
256                        '''
257                        if self.template["internal_iface"]==self.template["external_iface"]:
258                                error_msg+="* External and internal interfaces must be different.\n"
259                        '''
260                        if not lliurex.net.is_valid_ip(self.template["srv_ip"]):
261                                error_msg+="* "+_("Internal IP must be a valid IP.")+"\n"
262
263                        if not lliurex.net.is_valid_ip(self.template["internal_mask"]):
264                                error_msg+="* "+_("Internal mask must be a valid IP.")+"\n"
265                               
266                        if self.template["srv_name"]=="":
267                                error_msg+="* "+_("Server name cannot be an empty string.")+"\n"
268                        if self.template["srv_domain_name"]=="":
269                                error_msg+="* "+_("Server domain name cannot be an empty string.")+"\n"
270                       
271                       
272                        if self.template["external_mode"]=="manual":
273
274                                if self.template["external_ip"]=='' or not lliurex.net.is_valid_ip(self.template["external_ip"]):
275                                        error_msg+="* "+_("External IP must be a valid IP.")+"\n"
276                                if self.template["external_mask"]=="" or not lliurex.net.is_valid_ip(self.template["external_mask"]):
277                                        error_msg+="* "+_("External mask must be a valid IP.")+"\n"
278                                if self.template["external_gateway"]=="" or not lliurex.net.is_valid_ip(self.template["external_gateway"]):
279                                        error_msg+="* "+_("External gateway must be a valid IP.")+"\n"
280                               
281                               
282                        if self.template["dns1"]=="" or not lliurex.net.is_valid_ip(self.template["dns1"]):
283                                error_msg+="* "+_("DNS1 must be a valid IP.")+"\n"
284                        if self.template["dns2"]=="" or not lliurex.net.is_valid_ip(self.template["dns2"]):
285                                error_msg+="* "+_("DNS2 must be a valid IP.")+"\n"
286                               
287                        if self.template["enable_data_replication"]=="true" and self.template["mount_nfs"]=="true":
288                                if len(self.template["nfs_ip"])<3:
289                                        error_msg+="* "+_("NFS mount point doesn't seem to be valid.")+"\n"
290                                       
291                                       
292                               
293                        if error_msg!="":
294                                builder = Gtk.Builder()
295                                if os.path.exists("/srv/svn/pandora/zero-server-wizard/trunk/install-files/usr/share/zero-server-wizard/rsrc/warning.glade"):
296                                        builder.add_from_file("/srv/svn/pandora/zero-server-wizard/trunk/install-files/usr/share/zero-server-wizard/rsrc/warning.glade")
297                                else:
298                                        builder.add_from_file("/usr/share/zero-server-wizard/rsrc/warning.glade")
299                                       
300                                       
301                                window=builder.get_object("window1")
302                                msg_label=builder.get_object("msg_label")
303                                close_button=builder.get_object("close_button")
304                                def hide(widget):
305                                        window.destroy()
306                                close_button.connect("clicked",hide)
307                                msg_label.set_text(error_msg.strip("\n"))
308                                window.show()                           
309                       
310                        else:
311                               
312                                builder=Gtk.Builder()
313                                if os.path.exists("/srv/svn/pandora/zero-server-wizard/trunk/install-files/usr/share/zero-server-wizard/rsrc/progress_window.glade"):
314                                        builder.add_from_file("/srv/svn/pandora/zero-server-wizard/trunk/install-files/usr/share/zero-server-wizard/rsrc/progress_window.glade")
315                                else:
316                                        builder.add_from_file("/usr/share/zero-server-wizard/rsrc/progress_window.glade")                               
317                                       
318                                       
319                                self.error_msg=None
320                                window=builder.get_object("window1")
321                                review_textview=builder.get_object("textbuffer1")
322                                exec_textview=builder.get_object("textbuffer2")
323                                apply_button=builder.get_object("apply_button")
324                                close_button=builder.get_object("close_button")
325                                pbar=builder.get_object("progressbar1")
326                                terminal_box=builder.get_object("scrolledwindow2")
327                               
328                               
329                               
330                                #ret_textview=builder.get_object("ret_textview")
331                                widgets=[close_button,pbar]
332                                self.pulsating=False
333                               
334                               
335                                msg=""
336                               
337                                msg+="[ "+"SERVER NAME"+" ] = " + self.template["srv_name"] + "\n"
338                                msg+="[ "+"SERVER DOMAIN NAME"+" ] = " + self.template["srv_domain_name"] + "\n"
339                                msg+="[ " + "NFS /NET OPTIONS" + " ] = " + self.template["enable_data_replication"]+ "\n"
340                               
341                                if self.template["enable_data_replication"]=="true":
342                                        if self.template["export_nfs"]=="true":
343                                                msg+="[ NFS MOUNT OPTION ] = EXPORT /NET"  + "\n"
344                                        else:
345                                                msg+="[ NFS MOUNT OPTION ] = MOUNT FROM EXTERNAL SERVER"  + "\n"
346                                                msg+="[ NFS MOUNT OPTION ] = " + self.template["nfs_ip"] + "\n"
347                                               
348                                msg+="[ "+"INTERNAL INTERFACE"+" ] = " + self.template["internal_iface"] + "\n"
349                                msg+="[ "+"INTERNAL IP"+" ] = " + self.template["srv_ip"] + "\n"
350                                msg+="[ "+"INTERNAL MASK"+" ] = " + self.template["internal_mask"] + "\n"
351                                msg+="[ "+"EXTERNAL INTERFACE"+" ] = " + self.template["external_iface"] + "\n"
352                                msg+="[ "+"EXTERNAL MODE"+" ] = " + self.template["external_mode"] + "\n"
353                                if self.template["external_mode"]!="dhcp":
354                                        msg+="[ "+"EXTERNAL IP"+" ] = " + self.template["external_ip"] + "\n"
355                                        msg+="[ "+"EXTERNAL MASK"+" ] = " + self.template["external_mask"] + "\n"
356                                        msg+="[ "+"EXTERNAL GATEWAY"+" ] = " + self.template["external_gateway"] + "\n"
357                                msg+="[ REPLICATION INTERFACE ] = " + self.template["replication_interface"] + "\n"
358                                msg+="[ "+"DNS"+" ] = " + str(self.template["dns1"]) + ", " + str(self.template["dns2"])+ "\n"
359                                       
360
361                               
362                                review_textview.set_text(msg)
363                                       
364                               
365                               
366                                def pulsating():
367                                        pbar.pulse()
368                                       
369
370                                        try:
371                                                f=open("/tmp/.zsw-log","r")
372                                                tmp="".join(f.readlines())
373                                                if self.msg_thread!=tmp:
374                                                        self.msg_thread=tmp
375                                                        exec_textview.set_text(tmp)
376                                                       
377                                                f.close()
378                                        except:
379                                                pass
380                                       
381                                        if not os.path.exists("/tmp/.zsw-on"):
382                                                pbar.set_fraction(1)
383                                                close_button.set_sensitive(True)
384                                               
385                                                if os.path.exists("/tmp/.zsw-error"):
386                                               
387                                                        f=open("/tmp/.zsw-error","r")
388                                                        self.error_msg=f.readline()
389                                                        f.close()
390                                                        os.remove("/tmp/.zsw-error")
391                                                       
392                                                        builder = Gtk.Builder()
393                                                        if os.path.exists("/srv/svn/pandora/zero-server-wizard/trunk/install-files/usr/share/zero-server-wizard/rsrc/warning.glade"):
394                                                                builder.add_from_file("/srv/svn/pandora/zero-server-wizard/trunk/install-files/usr/share/zero-server-wizard/rsrc/warning.glade")
395                                                        else:
396                                                                builder.add_from_file("/usr/share/zero-server-wizard/rsrc/warning.glade")
397                                                               
398                                                               
399                                                        window2=builder.get_object("window1")
400                                                        msg_label=builder.get_object("msg_label")
401                                                        close_button2=builder.get_object("close_button")
402                                                        def hide(widget):
403                                                                window2.destroy()
404                                                        close_button2.connect("clicked",hide)
405                                                        msg_label.set_markup("<b>"+self.error_msg+"</b>")
406                                                        window2.set_title("Error")
407                                                        window2.show()
408                                                       
409                                                        return False
410                                                       
411                                                else:
412                                                        label = Gtk.Label(_("Initialization complete. A reboot is required."))
413                                                        dialog = Gtk.Dialog("Zero Server Wizard", None, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, (Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT))
414                                                        img=Gtk.Image.new_from_stock(Gtk.STOCK_APPLY,Gtk.IconSize.DIALOG)
415                                                        hbox=Gtk.HBox()
416                                                        hbox.pack_start(img,True,True,5)
417                                                        hbox.pack_start(label,True,True,5)
418                                                        hbox.show_all()
419                                                        dialog.vbox.pack_start(hbox,True,True,10)
420                                                        label.show()
421                                                        dialog.set_border_width(6)
422                                                        response = dialog.run()
423
424                                                        sys.exit(0)
425                                               
426                                               
427                                               
428                                        return True
429                               
430                                def apply_clicked(widget,data):
431                                       
432                                        self.pulsating=True
433                                        f=open("/tmp/.zsw-on","w")
434                                        f.close()
435                                        self.msg_thread=""
436                                        self.prv_msg=None
437                                        widget.set_sensitive(False)
438                                        t=multiprocessing.Process(target=self.execute,args=(self.template,True,))
439                                        #t.daemon=True
440                                        t.start()
441                                        close_button.set_sensitive(False)
442                                        GLib.timeout_add(100,pulsating)
443                                       
444                                def destroy(uno,dos):
445                                        try:
446                                                if self.pulsating:
447                                                        return True
448                                                else:
449                                                        window.destroy()
450                                        except:
451                                                pass
452                                               
453
454                                       
455                                #def apply_clicked
456                               
457                               
458                                def close(widget):
459                                        window.destroy()
460
461
462
463                                apply_button.connect("clicked",apply_clicked,None)
464                                close_button.connect("clicked",close)
465                               
466                                window.connect("delete_event",destroy)
467                               
468                                window.show()
469                               
470                                pass
471                                #def init_done
472                               
473
474        #def check_values
475       
476        def get_link_speed(self,widget,id):
477               
478                tree_iter = widget.get_active_iter()
479                if tree_iter != None:
480                        model = widget.get_model()
481                        try:
482                                speed=lliurex.net.get_device_info(model[tree_iter][0])["Speed"][0]
483                        except:
484                                speed=""
485                        if id==0:
486                                self.internal_speed_label.set_text(speed)
487                        elif id==1:
488                                self.external_speed_label.set_text(speed)
489                        else:
490                                self.replication_speed_label.set_text(speed)
491                               
492               
493        #def get_link_speed
494       
495        def external_mode_signal(self,widget):
496               
497                self.manual_external_box.set_sensitive(not self.dhcp_radiobutton.get_active())
498               
499        #def ems
500       
501       
502        def close_window(self,widget):
503                if self.standalone:
504                        Gtk.main_quit()
505               
506               
507        #def close_window
508       
509       
510        def execute(self,template,gui=False):
511               
512                print("[MASTER] Executing master configuration...")
513                       
514                #self.template=template
515                self.log("Executing Master configuration...")
516
517                self.core.template=dict(self.core.template.items() + self.template.items())
518                self.template=self.core.template
519
520                if not self.template.has_key("remote_ip"):
521                        self.template["remote_ip"]="localhost"
522
523               
524                if os.path.exists("/tmp/.zsw-log"):
525                        os.remove("/tmp/.zsw-log")
526               
527                for f in sorted(os.listdir("/usr/share/zero-server-wizard/types/master/actions/")):
528                        if os.path.isfile(self.scripts_path+f):
529                               
530                                try:
531                                        if f.endswith(".py"):
532                                                self.log("Excuting " + f + " ...")
533                                                print("[MASTER] Executing " + f + " ...")
534                                                if not gui:
535                                                        execfile(self.scripts_path+f,locals())
536                                                else:
537                                                       
538                                                        #.set_text(ret_textview.get_buffer().get_text(ret_textview.get_buffer().get_start_iter(),ret_textview.get_buffer().get_end_iter(),True)+ "\npor aqui")
539                                                        #msg+=("[INDEPENDENT] Executing " + f + " ... ")
540                                                        f_=open("/tmp/.zsw-log","a")
541                                                        f_.write("[MASTER] Executing " + f + " ... ")
542                                                        f_.close()                                                     
543                                                        execfile(self.scripts_path+f,locals())
544                                                        f_=open("/tmp/.zsw-log","a")
545                                                        f_.write(" OK\n")
546                                                        f_.close()
547                                                       
548
549
550                                                       
551                                except Exception as e:
552                                        print "[ERROR!] " + str(e)
553
554                                        try:
555                                                f=open("/tmp/.zsw-error","w")
556                                                f.write(e.message)
557                                                f.close()
558                                        except:
559                                                pass
560                                       
561                                        if os.path.exists("/tmp/.zsw-on"):
562                                                os.remove("/tmp/.zsw-on")
563                                        return False
564                                       
565                if gui:
566                        if os.path.exists("/tmp/.zsw-on"):
567                                os.remove("/tmp/.zsw-on")
568               
569                return True     
570               
571        #def execute
572       
573        def log(self,line):
574               
575                independent_log="/tmp/master"
576                f=open(independent_log,"a")
577                f.write( "[ "+datetime.datetime.today().strftime("%d/%m/%y %H:%M:%S") + " ] " + line + "\n")
578                f.close()
579               
580               
581        #def log
582       
583       
584       
585       
586#class Independent
Note: See TracBrowser for help on using the repository browser.