source: lliurex-backup/trunk/fuentes/install-files/usr/sbin/lliurex-backup @ 2266

Last change on this file since 2266 was 2266, checked in by Juanma, 5 years ago

Added nfs backup/restore

  • Property svn:executable set to *
File size: 10.6 KB
Line 
1#!/usr/bin/env python
2import gi
3gi.require_version('Gtk','3.0')
4from gi.repository import Gtk, Gdk, GObject,GLib
5import os
6import xmlrpclib
7import sys
8import signal
9import time
10import threading
11
12signal.signal(signal.SIGINT, signal.SIG_DFL)
13
14import gettext
15_=gettext.gettext
16gettext.textdomain('lliurex-backup')
17
18
19class LliurexBackup:
20       
21        def __init__(self):
22               
23                self.services=[(_("LliureX Server basic services"),"Hostname, Network, DNSmasq,\nProxy, LDAP, Samba",True,-1,"ServerBackupManager"),
24                ("Apache",_("HTTP Server"),False,0,"ApacheManager"),
25                ("CUPS",_("Printing service"),False,0,"CupsManager"),
26                ("MySQL",_("MySQL Database"),False,0,"MysqlManager"),
27                ("NFS",_("NFS configuration"),False,0,"NfsManager"),
28                ("Moodle",_("Moodle"),False,0,"MoodleManager"),
29                ("PMB",_("Pmb"),False,0,"PmbManager")]
30               
31                #self.n4d_key=self.get_n4d_key()
32                self.n4d=xmlrpclib.ServerProxy("https://localhost:9779",allow_none=True)
33
34                self.pulsating=False
35                self.backup_thread=threading.Thread()
36                self.backup_ret=None
37                self.restore_thread=threading.Thread()
38                self.restore_thread=None
39                self.last_action=-1
40               
41                self.user=None
42                self.password=None
43               
44               
45        #def init
46       
47        def get_n4d_key(self):
48               
49                try:
50                        f=open("/etc/n4d/key")
51                        key=f.readline().strip("\n")
52                        f.close()
53                        return key
54                except:
55                        return None
56               
57        #def get_n4d_key
58               
59       
60        def start_gui(self):
61               
62                builder=Gtk.Builder()
63                builder.set_translation_domain("lliurex-backup")
64                if os.path.exists("install-files/usr/share/lliurex-backup/rsrc/lliurex-backup.glade"):
65                        builder.add_from_file("install-files/usr/share/lliurex-backup/rsrc/lliurex-backup.glade")
66                else:
67                        builder.add_from_file("/usr/share/lliurex-backup/rsrc/lliurex-backup.glade")
68               
69                self.window=builder.get_object("window1")
70                self.window.connect("destroy",self.destroy)
71               
72                self.add_button=builder.get_object("add_button")
73                self.add_button.connect("clicked",self.add_clicked)
74       
75                self.remove_button=builder.get_object("remove_button")
76                self.remove_button.connect("clicked",self.remove_clicked)
77               
78                self.backup_button=builder.get_object("backup_button")
79                self.backup_button.connect("clicked",self.backup_clicked)
80               
81                self.restore_button=builder.get_object("restore_button")
82                self.restore_button.connect("clicked",self.restore_clicked)
83               
84                self.backup_file=builder.get_object("backupfile_chooserbutton")
85                self.backup_dir=builder.get_object("backup_dir_chooserbutton")
86               
87                self.restore_file=builder.get_object("restorefile_chooserbutton")
88               
89                self.treeview=builder.get_object("backup_treeview")
90                self.selection=self.treeview.get_selection()
91                self.selection.connect("changed",self.service_selected)
92                self.build_treeview()
93               
94                self.msg_label=builder.get_object("msg_label")
95                self.msg_folder_label=builder.get_object("msg_folder_label")
96               
97               
98               
99                self.add_folder_window=builder.get_object("window2")
100                self.add_folder_button=builder.get_object("add_folder_button")
101                self.add_folder_button.connect("clicked",self.add_folder_clicked)
102                self.add_folder_window.connect("delete-event",self.on_delete_event)
103               
104                self.cancel_folder_button=builder.get_object("cancel_folder_button")
105                self.cancel_folder_button.connect("clicked",self.cancel_folder_clicked)
106                self.add_folder_window.hide()
107               
108                self.progress_window=builder.get_object("window3")
109                self.progress_label=builder.get_object("progress_label")
110                self.progress_window.connect("delete-event",self.on_delete_event)
111                self.progress_bar=builder.get_object("progressbar")
112               
113                self.login_window=builder.get_object("window4")
114
115                self.login_window.connect("destroy",self.destroy)
116                self.accept_login_button=builder.get_object("accept_login_button")
117                self.accept_login_button.connect("clicked",self.validate_user)
118                self.cancel_login_button=builder.get_object("cancel_login_button")
119                self.cancel_login_button.connect("clicked",self.destroy)
120                self.login_label=builder.get_object("login_label")
121               
122                self.user_entry=builder.get_object("user_entry")
123                self.user_entry.set_text(os.environ["USER"])
124                self.user_entry.set_sensitive(False)
125                self.pass_entry=builder.get_object("password_entry")
126                self.pass_entry.connect("activate",self.validate_user)
127               
128                self.login_window.show_all()
129               
130                Gtk.main()
131               
132        #def start_gui
133       
134        def validate_user(self,widget):
135               
136                self.user=self.user_entry.get_text()
137                self.password=self.pass_entry.get_text()
138                self.n4d_key=(self.user,self.password)
139               
140                if self.n4d.validate_user(self.user,self.password)[0]:
141                        self.login_window.hide()
142                        self.window.show_all()
143                else:
144                        self.login_label.set_markup("<span foreground='red'>%s</span>"%(_("Authentication error")))
145               
146        #def validate_user
147       
148        def on_delete_event(self,widget,data):
149               
150                return True
151               
152        #def on_delete_event
153       
154        def build_treeview(self):
155               
156                self.backup_store=Gtk.ListStore(str,str,bool,int,str)
157                self.treeview.set_model(self.backup_store)
158               
159                column=Gtk.TreeViewColumn(_("Service"))
160                renderer=Gtk.CellRendererText()
161                column.pack_start(renderer,True)
162                column.add_attribute(renderer,"text",0)
163                self.treeview.append_column(column)
164               
165                column=Gtk.TreeViewColumn(_("Description"))
166                renderer=Gtk.CellRendererText()
167                column.pack_start(renderer,True)
168                column.add_attribute(renderer,"text",1)
169                self.treeview.append_column(column)
170               
171                column=Gtk.TreeViewColumn(_("Backup"))
172                renderer=Gtk.CellRendererToggle()
173                renderer.connect("toggled",self.service_toggled)
174                column.pack_start(renderer,True)
175                column.add_attribute(renderer,"active",2)
176                self.treeview.append_column(column)
177               
178                for service in self.services:
179                        self.backup_store.append(service)
180               
181               
182        #def set_values
183       
184        def service_selected(self,selection):
185               
186                model,treeiter=selection.get_selected()
187               
188                if treeiter!=None:
189                        pass
190                        #print model[treeiter][0],model[treeiter][1]
191               
192        #def service_selected
193       
194        def service_toggled(self,widget,path):
195               
196                self.backup_store[path][2]=not self.backup_store[path][2]
197               
198        #def service-toggled
199       
200        def add_clicked(self,widget):
201               
202                self.msg_label.set_markup("")
203                self.add_folder_window.show_all()
204               
205        #def add_clicked
206       
207        def add_folder_clicked(self,widget):
208               
209                if self.backup_dir.get_filename()!=None:
210                        for item in self.backup_store:
211                                if self.backup_dir.get_filename().startswith(item[0]):
212                                        self.msg_folder_label.set_markup("<span foreground='red'>"+_("%s or its parent path is already in the backup list")%(self.backup_dir.get_filename())+"</span>")
213                                        return
214                       
215                        self.backup_store.append([self.backup_dir.get_filename(),_("Custom directory"),True,1,"NetFoldersManager"])             
216                        self.msg_folder_label.set_markup("")
217                        self.add_folder_window.hide()
218               
219        #def add_folder_clicked
220       
221        def cancel_folder_clicked(self,widget):
222               
223                self.add_folder_window.hide()
224               
225        #def cancel_folder_button
226       
227       
228        def remove_clicked(self,widget):
229               
230                self.msg_label.set_markup("")
231                selection=self.treeview.get_selection()
232                if selection!=None:
233                        model,treeiter=selection.get_selected()
234                        if treeiter!=None:
235                                if model[treeiter][3]==1:
236                                        self.backup_store.remove(treeiter)
237                                        self.msg_label.set_markup("")
238                                else:
239                                        self.msg_label.set_markup("<span foreground='red'>%s</span>"%_("Select a 'Custom directory' entry from the data table to remove it"))
240               
241        #def remove-clicked
242
243       
244        def backup_clicked(self,widget):
245               
246                path=self.backup_file.get_filename()
247                if path==None:
248                        self.msg_label.set_markup("<span foreground='red'>%s</span>"%_("Select a backup file path first"))
249                        return
250               
251                folder_list=[]
252                service_list=[]
253                use_basics=False
254                for item in self.backup_store:
255                        if item[2]:
256                                class_name=item[4]
257                                if class_name=="ServerBackupManager":
258                                        use_basics=True
259                                else:
260                                        service_list.append(class_name)
261                                if item[3]!=1:
262                                        print "n4d.backup %s"%class_name
263                                       
264                                        #print self.n4d.backup(self.n4d_key,class_name,path)
265                                else:
266                                        folder_list.append(item[0])
267                               
268                if use_basics:
269                        try:
270                                server_basics=self.n4d.get_basic_services_list("","ServerBackupManager")
271                        except:
272                                server_basics=[]
273                        for service in service_list:
274                                if service not in server_basics:
275                                        server_basics.append(service)
276                                       
277                        service_list=server_basics
278                               
279                if len(folder_list)>0:
280                        if "NetFoldersManager" not in service_list:
281                                service_list.append("NetFoldersManager")
282                else:
283                        folder_list=None
284               
285                self.last_action=0
286                self.pulsating=True
287                GLib.timeout_add(250,self.pulse_bar)
288                self.progress_label.set_text(_("Creating backup file..."))
289                self.progress_window.show()
290                self.backup_thread=threading.Thread(target=self.backup,args=(path,service_list,folder_list))
291                self.backup_thread.start()
292               
293               
294        #def remove-clicked
295       
296        def backup(self,path,services,folders):
297
298                try:
299                        self.last_action=0
300                        self.backup_ret=self.n4d.backup(self.n4d_key,"ServerBackupManager",path,services,folders)
301                        self.backup_ret=[True,self.backup_ret[2]]
302               
303                except Exception as e:
304                        self.backup_ret=[False,str(e)]
305                       
306                #self.pulsating=False
307               
308                return False
309               
310        #def backup
311       
312       
313        def restore(self,path):
314
315                try:
316                        self.last_action=1
317                        self.restore_ret=self.n4d.restore(self.n4d_key,"ServerBackupManager",path)
318
319                except Exception as e:
320                        self.restore_ret=[False,str(e)]
321                       
322                #self.pulsating=False
323                return False
324               
325        #def backup     
326       
327       
328        def pulse_bar(self):
329               
330               
331                self.progress_bar.pulse()
332                #print "pulsating"
333               
334                if self.last_action==0:
335                       
336                        if self.backup_thread.is_alive():
337                                return True
338                       
339                        elif self.backup_ret!=None:
340                                if self.backup_ret[0]:
341                                        self.msg_label.set_markup("<b>"+_("Backup file created")+":</b> %s"%self.backup_ret[1])
342                                else:
343                                        self.msg_label.set_markup("<span foreground='red'>"+_("Creation of backup file failed:")+"\n%s</span>"%( self.backup_ret[1] ))
344                                               
345                                self.progress_window.hide()
346                                self.pulsating=False
347                                return False
348                                               
349                if self.last_action==1:
350                               
351                        if self.restore_thread.is_alive():
352                                       
353                                return True
354                               
355                        elif self.restore_ret!=None:
356                                               
357                                if self.restore_ret[0]:
358                                        self.msg_label.set_markup(_("<b>Restoration complete</b>"))
359                                else:
360                                        self.msg_label.set_markup("<span foreground='red'>"+_("Restoration failed:")+"\n%s</span>"%( self.restore_ret[1] ))
361                               
362                                self.progress_window.hide()
363                                self.pulsating=False
364                                return False
365                       
366                return self.pulsating
367               
368        #def pulse_bar
369       
370        def restore_clicked(self,widget):
371               
372                self.msg_label.set_markup("")
373                path=self.restore_file.get_filename()
374                if path==None:
375                        self.msg_label.set_markup("<span foreground='red'>%s</span>"%_("Select a restoration file first"))
376                        return
377                       
378                self.last_action=1
379                self.pulsating=True
380                GLib.timeout_add(250,self.pulse_bar)
381                self.progress_label.set_text(_("Restoring services..."))
382                self.progress_window.show()
383                self.restore_thread=threading.Thread(target=self.restore,args=(path,))
384                self.restore_thread.start()
385               
386               
387        #def remove-clicked
388       
389       
390       
391        def destroy(self,widget):
392                #sys.exit(0)
393                Gtk.main_quit()
394               
395        #def destroy
396       
397       
398#class LliurexBackup
399
400
401
402if __name__=="__main__":
403       
404       
405        lb=LliurexBackup()
406        lb.start_gui()
Note: See TracBrowser for help on using the repository browser.