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

Last change on this file since 629 was 629, checked in by jrpelegrina, 4 years ago

First release to xenial

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