diff --git a/files/usr/local/bin/mkbackup-btrfs b/files/usr/local/bin/mkbackup-btrfs index 8905cc3..509bd92 100755 --- a/files/usr/local/bin/mkbackup-btrfs +++ b/files/usr/local/bin/mkbackup-btrfs @@ -32,8 +32,13 @@ except: import dbus import dbus.service -import dbus.glib -from mkbackup.system_notification_emitter import Emitter +# deprecated +#import dbus.glib +# replaces by this 2 lines +from dbus.mainloop.glib import DBusGMainLoop +DBusGMainLoop(set_as_default=True) + +from mkbackup.system_notification_emitter import Emitter from mkbackup.mkbackup_emitter import Emitter as EM #from mksnapshotconfig import Config @@ -43,6 +48,10 @@ from mkbackup.mkbackup_btrfs_config import __version__ as confversion __author__ = "Jakobus Schürz " __version__ = "1.01.0" +class EmDBUSDesktop(EM): + def __init__(self): + super().__init__(conn=dbus.SystemBus(), object_path='/at/xundeenergie/notifications/advanced') + class Notification(Emitter): def __init__(self): super().__init__(conn=dbus.SystemBus(), object_path='/at/xundeenergie/notifications/advanced/Notification') @@ -79,7 +88,7 @@ class progress_timer: def initialize(self): #initialize timer - widgets = [self.description, pb.Percentage(), ' ', + widgets = [self.description, pb.Percentage(), ' ', pb.Bar(marker=pb.RotatingMarker()), ' ', pb.ETA()] self.timer = pb.ProgressBar(widgets=widgets, maxval=self.n_iter).start() @@ -109,7 +118,7 @@ else: def DEBUG(*msg,level=0,verbose=0): if verbose < level : return - else: + else: #print(' '.join(msg)) for i in msg: print(i) return @@ -131,15 +140,15 @@ def check_lockfile(args,lf): file.close() #if len(pid) > 0 and Myos().path_isfile('/proc/'+pid+'/cmdline',args.config.ssh[args.tag][st]): if len(pid) > 0 and os.path.isfile('/proc/'+pid+'/cmdline'): - logger.warn('lockfile %s in use with process %s' % (lf,pid)) + logger.warning('lockfile %s in use with process %s' % (lf,pid)) #DEBUG('lockfile %s in use with process %s' % (lf,pid),level=3,verbose=args.verbose) return(True) else: - logger.warn('lockfile %s unused' % (lf)) + logger.warning('lockfile %s unused' % (lf)) #DEBUG('lockfile %s unused' % (lf),level=3,verbose=args.verbose) return(False) else: - logger.warn('lockfile %s not existing' % (lf)) + logger.warning('lockfile %s not existing' % (lf)) #DEBUG('lockfile %s not existing' % (lf),level=3,verbose=args.verbose) return(None) @@ -222,7 +231,7 @@ class BtrfsListing: self.scanfs() def scanfs(self): - logger.warn('SCAN btrfs-drive: %s' % (self.StorePath)) + logger.warning('SCAN btrfs-drive: %s' % (self.StorePath)) if self.single: cmd=['btrfs','subvolume','list','-R','-u','-q','-c','-o',self.StorePath] else: @@ -235,7 +244,7 @@ class BtrfsListing: #argmts = line.split(' ') argmts = line.split() #ID 2412 gen 8547 cgen 8547 top level 2393 parent_uuid 7991115b-8a6b-6d4d-b664-03db01e902d0 received_uuid - uuid 368490e7-5aca-0d4d-9b7a-becff0487ebd path aldebaran/__ALWAYSCURRENT__.2016-10-15_22:40:25.hourly.part/var-spool-dovecot - self.svols[argmts[1]] = dict() + self.svols[argmts[1]] = dict() self.svols[argmts[1]]['id'] = argmts[1] self.svols[argmts[1]]['gen'] = argmts[3] self.svols[argmts[1]]['cgen'] = argmts[5] @@ -263,7 +272,7 @@ class BtrfsListing: for sub in sorted(self.svols.keys(),key=int): if self.svols[sub]['path'] == snap: stroot = self.svols[sub]['uuid'] ext = " (gen: "+str(self.svols[sub]['gen'])+" cgen: "+str(self.svols[sub]['gen'])+")" - try: + try: vars()[str(self.svols[sub]['uuid'])] = Node(str(self.svols[sub]['path'])+ext,parent=vars()[self.svols[sub]['puuid']]) except: vars()[str(self.svols[sub]['uuid'])] = Node(str(self.svols[sub]['path'])+ext,parent=wood) @@ -271,10 +280,10 @@ class BtrfsListing: for pre, fill, node in RenderTree(wood if snap == None else vars()[stroot]): print("%s%s" % (pre, node.name)) else: - print("""anytree is not available. Please ask your sysadmin to install anytree with + print("""anytree is not available. Please ask your sysadmin to install anytree with pip3 install anytree""") - + def list_sisters(self,ID,rev=False,older=None,younger=None,names=True): result = [] if older == None: older = self.args.older @@ -333,7 +342,7 @@ class BtrfsListing: def list_subvolumes(self,id,rev=False,names=True,incl_self=True): result= [] - first = '' if names else id + first = '' if names else id if incl_self: result.append(first) for sub in self._lssub(id): result.append(self.svols[sub]['path'].partition(self.svols[id]['path']+'/')[2]) if names else result.append(sub) @@ -359,7 +368,7 @@ class BtrfsListing: result.append(self.svols[sub]['path']) if names else result.append(sub) return(self._ret(result,reverse=rev)) - + def _isbtrfs(self,path,store='SRC',tag='DEFAULT'): mi = MountInfo(conn=self.args.config.getssh(tag,store)) logger.info("Filesysem for »%s« is %s" % (path,mi.fstype(path))) @@ -420,14 +429,14 @@ class SubVolumeInfo(BtrfsListing): for line in output.splitlines(): #argmnts = [arg.strip() for arg in str(line, encoding='utf8').split(': ')] argmnts = [arg.strip() for arg in line.replace('\t',' ').split(': ')] - + if len(argmnts) > 1: #setattr(self, self.tr_att(argmnts[0].strip()), argmnts[1].strip()) setattr(self, self.tr_att(argmnts[0]), argmnts[1]) elif sv: snaps.append(argmnts[0].strip()) else: - if argmnts[0].strip() == 'Snapshot(s):': + if argmnts[0].strip() == 'Snapshot(s):': sv = True else: self.path=argmnts[0].strip() @@ -449,7 +458,7 @@ class SubVolume(SubVolumeInfo): self.exist = True self.args = args - self.timestamp = args.timestamp + self.timestamp = args.timestamp self.verbose = args.verbose self.tag = args.tag self.config = args.config #Config() @@ -462,7 +471,7 @@ class SubVolume(SubVolumeInfo): self.trans_ts = name.split('.')[1] self.trans_tag = name.split('.')[2] - regexpart = re.compile('\.part') + regexpart = re.compile('\.part') self.OrigName = re.sub('\.part$','',self.SourceName) self.OrigLock = self.OrigName+'.part' @@ -480,29 +489,29 @@ class SubVolume(SubVolumeInfo): self.SnapLock = self.SnapName+'.part' self.SLockFile = '.'+self.SnapName+'.~lock' self.SnapID = None - logger.warn('OrigName : %s' % (self.OrigName)) - logger.warn('SourceName: %s' % (self.SourceName)) - logger.warn('OrigLock : %s' % (self.OrigLock)) - logger.warn('OLockFile : %s' % (self.OLockFile)) - logger.warn('SnapName : %s' % (self.SnapName)) - logger.warn('SnapLock : %s' % (self.SnapLock)) - logger.warn('SLockFile : %s' % (self.SLockFile)) + logger.warning('OrigName : %s' % (self.OrigName)) + logger.warning('SourceName: %s' % (self.SourceName)) + logger.warning('OrigLock : %s' % (self.OrigLock)) + logger.warning('OLockFile : %s' % (self.OLockFile)) + logger.warning('SnapName : %s' % (self.SnapName)) + logger.warning('SnapLock : %s' % (self.SnapLock)) + logger.warning('SLockFile : %s' % (self.SLockFile)) self.parent = '' self.subvolsshort = [] self.subvolumes = [] self.stderr = args.stderr self.DEBUG('[II] <%s> is %s: ' % (self.store, self.config.getStorePath(self.store,self.args.tag,original=True)),level=2) - #self.partstep = (100 / (self.args.mdbpart * self.args.mdbsteps)) / len(self.list_subvolumes(self.id)) - self.partstep = mdbslice / len(self.list_subvolumes(self.id)) + #self.partstep = (100 / (self.args.mdbpart * self.args.mdbsteps)) / len(self.list_subvolumes(self.id)) + self.partstep = mdbslice / len(self.list_subvolumes(self.id)) logger.debug("""Steps mdpart: %i count subvolumes: %i len list_subvolumes: %i mdparts (mdbpart * mdbsteps): %i pparts: %i - partstep: %f""" % (self.args.mdbpart, - self.count_subvolumes(self.id), + partstep: %f""" % (self.args.mdbpart, + self.count_subvolumes(self.id), len(self.list_subvolumes(self.id)), self.args.mdbpart * self.args.mdbsteps, 100, @@ -534,8 +543,8 @@ class SubVolume(SubVolumeInfo): Myos(dry=self.args.dry_run).remove(path+lf,args.config.getssh(self.tag,self.store)) except OSError as e: if e.errno == errno.EEXIST or errno.ENOENT: - pass - # if lockfile doesn't exist, continue + pass + # if lockfile doesn't exist, continue #self.DEBUG('INFO - lockfile is not existing: <%s - %s>/%s' % (self.store,self.StorePath,path+lf),level=2) else: raise e @@ -563,7 +572,7 @@ class SubVolume(SubVolumeInfo): st = self.store if store == None else store StorePath = self.config.getStorePath(st,self.args.tag) - if not issubvol(self.args,StorePath,store,self.args.tag): + if not issubvol(self.args,StorePath,store,self.args.tag): self.DEBUG("Failed to rename »<%s>%s«, is no btrfs-subvolume, or not existing" % (st,From),level=3) return @@ -581,8 +590,8 @@ class SubVolume(SubVolumeInfo): return else: if issubvol(self.args,StorePath+'/'+From,store,self.args.tag): - self.DEBUG(' =%s-rename> »<%s>/%s« --> %s' % (Action,st,From,To), level=1) - else: + self.DEBUG(' =%s-rename> »<%s>/%s« --> %s' % (Action,st,From,To), level=1) + else: return try: #print('DRY',self.args.dry_run) @@ -593,7 +602,7 @@ class SubVolume(SubVolumeInfo): print(e) except: raise - + return def lock(self,store=None): @@ -631,7 +640,7 @@ class SubVolume(SubVolumeInfo): raise self.scanfs() return - + def unlock(self,checked=False,store=None): store = self.store self.DEBUG('try to unlock on action %s' % (self.args.action),level=4) @@ -698,7 +707,7 @@ class SubVolume(SubVolumeInfo): def setprop(self,ro=True): if self.args.action == 'create': sname = self.SnapLock - elif self.args.action == 'setprop': + elif self.args.action == 'setprop': sname = self.OrigName else: sname = self.OrigLock @@ -718,10 +727,10 @@ class SubVolume(SubVolumeInfo): self.args.config.remotecommand(tag=self.args.tag, store=self.store, cmd=cmd) except: self.DEBUG('setprop error',level=1) - + else: pass - + def create(self): self.DEBUG(' =create-snapshot=> from »<%s>/%s«' % (self.store, self.SourceName),level=1) #compile regular expression for ignoring subvolume-names @@ -784,7 +793,7 @@ class SubVolume(SubVolumeInfo): self.SnapID = self.svols[i]['id'] BtrfsListing.CreatedSubvolumes.push((self.store,self.SnapName)) return(list([self.svols[i]['id'],self.svols[i]['path']])) - + raise CreateError('FAILURE - create new snapshot failed %s' % (self.SnapLock), 0) except: raise CreateError @@ -805,7 +814,7 @@ class SubVolume(SubVolumeInfo): sname = self.OrigLock sid = self.id - + #get uuids of SNP/SRC and BKP and compare. If they are the same, no transfer, if they are different, make transfer to external media #print(self.config.getDevice(store='BKP')) try: @@ -833,7 +842,7 @@ class SubVolume(SubVolumeInfo): logger.critical(" |no-transfer: Filesystem for »%s« not mounted: »%s«" % ('BKP',self.config.getMountPath(store='BKP',tag=args.tag))) return - if uuidS == uuidB: + if uuidS == uuidB: # Same Filesystem on SRC/SNP and BKP. No transfer logger.critical(" |no-transfer: external backupmedia obviously not mounted") return @@ -853,7 +862,7 @@ class SubVolume(SubVolumeInfo): # try: # print("%s exists; is directory" % (self.BkpPath)) # print("%s -> change to subvolume, this may take a while" % (self.BkpPath)) -# # rename original BKPStore +# # rename original BKPStore # print('A ren') # cmd = ['mv',self.BkpPath,self.BkpPath+'.orig'] # sp_call(self.args,cmd) @@ -909,7 +918,7 @@ class SubVolume(SubVolumeInfo): if BKP.svols[bsub]['ruuid'] == self.svols[sis]['uuid']: plist[self.svols[sis]['id']] = self.svols[sis]['id'] - + transfers[self.svols[sub]['path']] = dict() if len(plist) > 0: v=[int(i) for i in plist.values()] @@ -1016,7 +1025,7 @@ class SubVolume(SubVolumeInfo): #output = args.config.remotecommand(tag=args.tag, store=store, cmd=cmd) - + if not self.args.transferinfo: # print("S->R",first,second) # stdin_send,stdout_send,stderr_send = cmdsh(self.tag,self.store,first) @@ -1053,7 +1062,7 @@ class SubVolume(SubVolumeInfo): # self.DEBUG("[II] TARGET => LINKNAME: %s => %s" % (target.strip(),link_name.strip()),level=3) # else: # raise e - + def symlink(self): for st in list(self.args.sourcepath.keys())[0], list(self.args.destpath.keys())[0]: StorePath = self.config.getStorePath(st,self.args.tag) @@ -1061,7 +1070,7 @@ class SubVolume(SubVolumeInfo): linkName = self.basename+'.'+args.config.getSymLink(args.tag) self.DEBUG('%-12s =>»<%s>/%s«' % (' =symlink>',st,linkName),level=0) self.symlink_force('./'+self.SnapName, StorePath+'/'+linkName,st) - if args.config.getSymLink(args.tag) != args.config.getSymLink(): + if args.config.getSymLink(args.tag) != args.config.getSymLink(): self.DEBUG('%-12s =>»<%s>/%s«' % (' =symlink>',st,self.basename+'.LAST'),level=0) self.symlink_force('./'+self.SnapName, StorePath+'/'+self.basename+'.LAST',st) @@ -1073,7 +1082,7 @@ class SubVolume(SubVolumeInfo): linkName = self.basename self.DEBUG('%-12s =>»<%s>/%s«' % (' =symlink>',st,linkName),level=0) self.symlink_force('./'+self.SnapName, StorePath+'/'+linkName,st) -# if args.config.getSymLink(args.tag) != args.config.getSymLink(): +# if args.config.getSymLink(args.tag) != args.config.getSymLink(): # self.DEBUG('%-12s =>»<%s>/%s«' % (' =symlink>',st,self.basename+'.LAST'),level=0) # self.symlink_force('./'+self.SnapName, StorePath+'/'+self.basename+'.LAST',st) @@ -1087,7 +1096,7 @@ class SubVolume(SubVolumeInfo): sname = self.OrigLock slock = self.OLockFile sid = self.id - + #print('delete %s - %s with %s and action %s' % (sname,sid,slock,self.args.action)) @@ -1140,10 +1149,10 @@ class SubVolume(SubVolumeInfo): if self.args.npb: pt.update() if self.args.npb: pt.finish() - - + + def main(self): - #print(self.svols) + #print(self.svols) #print(self.list_sisters(self.ID)) #try: self.parse_btrfs_show() @@ -1163,7 +1172,7 @@ def main(args): #L.main() #L.list_sisters() #X=SubVolume(BtrfsListing) - + def issubvol(args,path,store='SRC',tag=None): #print("issubvol-store",store,tag,path) if not path == None: @@ -1173,17 +1182,17 @@ def issubvol(args,path,store='SRC',tag=None): except: return False return True if int(output) == 256 else False - + def cleanup(args): args.mdbsteps = 4 #create, setprop, transfer, cleanup args.mdbslice = 100 / 4 DEBUG(' --== cleanup ==-->',verbose=args.verbose,level=1) - #self.partstep = (100 / (args.mdbpart * args.mdbsteps)) / len(self.list_subvolumes(self.id)) + #self.partstep = (100 / (args.mdbpart * args.mdbsteps)) / len(self.list_subvolumes(self.id)) if args.npb: pt = progress_timer(description= ' --== cleanup ==-->', n_iter=6) args.action = 'cleanup' - #DEL = dict() + #DEL = dict() DEL = Stack() ST = dict() explock = re.compile('.*.~lock$') @@ -1226,7 +1235,7 @@ def cleanup(args): DEBUG(args,' --cleanup *.part$-Snapshots',level=3) for i in ST[st].svols: subvol = ST[st].svols[i]['path'] - if exppart.search(subvol): + if exppart.search(subvol): DEL.push([st,subvol]) # Delete them @@ -1272,7 +1281,7 @@ def create(args): SRC[snap].unlock() SRC[snap].symlink() except RuntimeError as e: - if e.args[1] == 0: + if e.args[1] == 0: print('nicht so schlimm') else: raise e @@ -1299,7 +1308,7 @@ def rollback(args): SRC[snap].symlink_sysvol() #SRC[snap].rename() except RuntimeError as e: - if e.args[1] == 0: + if e.args[1] == 0: print('nicht so schlimm') else: raise e @@ -1323,7 +1332,7 @@ def delete(args): SRC[snap].setprop(ro=False) SRC[snap].delete() except RuntimeError as e: - if e.args[1] == 0: + if e.args[1] == 0: print("delete error - nicht so schlimm") else: raise e @@ -1333,7 +1342,7 @@ def delete(args): except: raise return - + def setprop(args): args.mdbsteps = 4 #create, setprop, transfer, cleanup args.mdbslice = 100 / 4 @@ -1347,7 +1356,7 @@ def setprop(args): SRC[snap].unlock() except RuntimeError as e: print(e.args,e.args[1]) - if e.args[1] == 0: + if e.args[1] == 0: print("setprop error - nicht so schlimm") else: raise e @@ -1357,7 +1366,7 @@ def setprop(args): except: raise return - + def lists(args): args.mdbsteps = 4 #create, setprop, transfer, cleanup args.mdbslice = 100 / 4 @@ -1382,7 +1391,7 @@ def lists(args): if args.print_config: args.config.PrintConfig(tag = None if args.tagset else args.tag, of=args.of) - + if args.showyoungest: ST=dict() for st in args.store: @@ -1397,7 +1406,7 @@ def lists(args): dirlist = dict() for snps in glob.glob(args.config.getStorePath(st,args.tag)+'/'+vol+'.*'): #print("snps",snps) - if len(os.path.basename(snps).split('.')) == 3: + if len(os.path.basename(snps).split('.')) == 3: if not os.path.basename(snps).split('.')[1] in dirlist: dirlist[os.path.basename(snps).split('.')[1]] = list() dirlist[os.path.basename(snps).split('.')[1]].append(os.path.basename(snps)) @@ -1405,7 +1414,7 @@ def lists(args): for snp in dirlist[t]: #print("T",dirlist[t],snp) for intv in ST[st][vol].keys(): - R = re.compile(intv +'$') + R = re.compile(intv +'$') #print("I",intv) if R.search(snp): #print("snp",st,vol,intv,snp) @@ -1447,14 +1456,14 @@ def lists(args): s['dirlist'] = ST[st][vol]['dirlist'][sorted(dirlist.keys()).pop()] else: #print("C",i) - #if i.split('.')[2] == args.tag: + #if i.split('.')[2] == args.tag: #print("D",i) #s[i.split('.')[1]] = i if intv == args.tag: s[k] = i else: missing.append(intv) - + lo = 0 for i in reversed(sorted(s.keys())): #for j in s[i] if i == 'dirlist' else [s[i]]: @@ -1480,18 +1489,18 @@ def lists(args): res = subprocess.Popen(cmd,stdout=subprocess.PIPE, stderr=args.stderr) output,error = res.communicate() if res.returncode > 0: - raise + raise except: raise #if output[0] == 0: cut = 120 for line in output.splitlines(): l = line.decode() - if "ACTIVATES" in l: + if "ACTIVATES" in l: cut = l.find("ACTIVATES") i = l.find("UNIT") print(l[:cut]) - elif reintv.search(l): + elif reintv.search(l): l = l[:cut] o = l.replace("timer-","").replace(".timer","").rstrip() x = o[i:].rstrip(), @@ -1552,7 +1561,7 @@ def lists(args): for i in SRC[snap].list_subvolumes(SRC[snap].id,rev=args.reverse): print(fp+i) except RuntimeError as e: print(e.args,e.args[1]) - if e.args[1] == 0: + if e.args[1] == 0: print("list error - nicht so schlimm") else: raise e @@ -1595,7 +1604,7 @@ def restore(args): #print('RESTORE FILES', args) # if User running "mkbackup restore" is root, set uroot=True if os.getuid() == 0: - uroot = True + uroot = True else: uroot = False @@ -1662,23 +1671,22 @@ def restore(args): else: raise #shutil.copy(src,dest) mounts.close() - + #class desktop_notification: # def __init__(self, args, urgency=1): # self.args = args -# self.dbus_path = "/at/xundeenergie/notifications" -# self.dbus_iface = "at.xundeenergie.notifications.advanced" -# self.dbus_busname = "at.xundeenergie.notifications" +# self.dbus_path = "/at/xundeenergie/notifications/advanced" +# self.dbus_iface = "at.xundeenergie.Notification" # self.timestamp = datetime.datetime.now() # self.time = self.timestamp.strftime('%H:%M:%S') # self.date = self.timestamp.strftime('%d. %B %Y') # self.bus = dbus.SystemBus() # if int(urgency) == 0: -# self.signal_name = 'Notification_low' +# self.signal_name = 'low' # elif int(urgency) == 1: -# self.signal_name = 'Notification_normal' +# self.signal_name = 'normal' # else: -# self.signal_name = 'Notification_critical' +# self.signal_name = 'critical' # print('NO',int(urgency),self.signal_name) # # def send_signal(self, intv='default', *args): @@ -1686,15 +1694,16 @@ def restore(args): # msg = dict() # msg['sender'] = "mkbackup" # msg['msgheader'] = "%s-backup" % (self.args.tag) -# msg['msgbody'] = """am %s +# msg['msgbody'] = """am %s #um %s Uhr abgeschlossen. # -#%s +#%s #(Ugency: %s) #""" % (self.date, self.time, '\n'.join(args), self.signal_name) # msg['expiration_timeout'] = '-1' # message = dbus.lowlevel.SignalMessage(self.dbus_path, self.dbus_iface, self.signal_name) -# message.append(msg) +# #message.append(msg) +# message.append({'body': 'blafoo'}) # self.bus.send_message(message) # PARSER @@ -1713,21 +1722,21 @@ parser.add_argument('-L', '--logfile', default=None, help='''Write output also t parser.add_argument('-i', '--ignore', action='append', help='''Regular expression pattern for ignoring several subvolumes to be not backed up (and subvolumes unter them) Use it more than once''') parser.add_argument('-n', '--no-progressbar', dest='npb', action='store_false', default=True, help='''Dont show progressbar (for use in systemctl-unit for example)''') -parser.add_argument('-B', '--backup-mount-path', - dest='bkpmount', - default=config.getMountPath('BKP'), +parser.add_argument('-B', '--backup-mount-path', + dest='bkpmount', + default=config.getMountPath('BKP'), help='''set path to destination mountpoint of backup-mountpoint. (default=%s) overrides 'BKP-Path':''' % (config.getMountPath('BKP'))) -parser.add_argument('-b', '--backup-store', - dest='bkpstore', - default=config.getStoreName('BKP'), +parser.add_argument('-b', '--backup-store', + dest='bkpstore', + default=config.getStoreName('BKP'), help='''set storename in backup-mount. (default=%s) overrides 'BKP-Store':''' % (config.getStoreName('BKP'))) -parser.add_argument('-S', '--snapshot-mount-path', - dest='snpmount', - default=config.getMountPath('SNP'), +parser.add_argument('-S', '--snapshot-mount-path', + dest='snpmount', + default=config.getMountPath('SNP'), help='''set path to destination mountpoint of snapshot-mountpoint. (default=%s) overrides 'SNP-Path':''' % (config.getMountPath('SNP'))) -parser.add_argument('-s', '--snapshot-store', - dest='snpstore', - default=config.getStoreName('SNP'), +parser.add_argument('-s', '--snapshot-store', + dest='snpstore', + default=config.getStoreName('SNP'), help='''set storename in snapshot-mount. (default=%s) overrides 'BKP-Store':''' % (config.getStoreName('SNP'))) parser.add_argument('-N', '--notification', default=None, help='''Send notification. Possible values are "desktop" ''') parser.add_argument('-U', '--notification_urgency', default=None, help='''Send notification. Possible values are 0=low, 1=normal, 2=critical ''') @@ -1736,8 +1745,8 @@ parser.add_argument('-U', '--notification_urgency', default=None, help='''Send n subparsers = parser.add_subparsers() list_parser=subparsers.add_parser('list') -list_parser.add_argument("store", - default='SRC', +list_parser.add_argument("store", + default='SRC', metavar='stores and snapshots', nargs='*', help="""one of SRC, BKP or SNP - where is the snapshot @@ -1766,8 +1775,8 @@ list_parser.set_defaults(func=lists) list_parser.set_defaults(action='list') create_parser=subparsers.add_parser('create') -create_parser.add_argument("store", - default='SRC', +create_parser.add_argument("store", + default='SRC', metavar='stores and snapshots', nargs='*', help="""one of SRC or SNP - where is the snapshot located and one ore more snapshots @@ -1778,8 +1787,8 @@ create_parser.set_defaults(func=create) create_parser.set_defaults(action='create') rollback_parser=subparsers.add_parser('rollback') -rollback_parser.add_argument("store", - default='SRC', +rollback_parser.add_argument("store", + default='SRC', metavar='stores and snapshots', nargs='*', help="""one of SRC, BKP or SNP - where is the snapshot @@ -1789,8 +1798,8 @@ rollback_parser.set_defaults(func=rollback) rollback_parser.set_defaults(action='rollback') delete_parser=subparsers.add_parser('delete') -delete_parser.add_argument("store", - default='SRC', +delete_parser.add_argument("store", + default='SRC', metavar='stores and snapshots', nargs='*', help="""one of SRC, BKP or SNP - where is the snapshot @@ -1799,23 +1808,23 @@ delete_parser.set_defaults(func=delete) delete_parser.set_defaults(action='delete') transfer_parser=subparsers.add_parser('transfer') -transfer_parser.add_argument("snapshots", - default='SRC', +transfer_parser.add_argument("snapshots", + default='SRC', nargs='*', help="""one of SRC or SNP - where is the snapshot located and one ore more snapshots which to be transfered to the external backup-device. BKP is ignored!!!""") transfer_parser.add_argument('--no-clones', action='store_true', default=False, help="""do not use clones for transfer, only parent (if present)""") -transfer_parser.add_argument('-i', '--info', - dest='transferinfo', - action='store_true', - default=False, +transfer_parser.add_argument('-i', '--info', + dest='transferinfo', + action='store_true', + default=False, help="""show only if initial or incremental transfer is done and the parents""") transfer_parser.set_defaults(func=transfer) transfer_parser.set_defaults(action='transfer') cleanup_parser=subparsers.add_parser('cleanup') -cleanup_parser.add_argument("snapshots", +cleanup_parser.add_argument("snapshots", nargs='*', help='''cleanup all snapshots, which are older and more than allowed in config''') @@ -1823,13 +1832,13 @@ cleanup_parser.set_defaults(func=cleanup) cleanup_parser.set_defaults(action='cleanup') setprop_parser=subparsers.add_parser('setprop') -setprop_parser.add_argument("store", - default='SRC', +setprop_parser.add_argument("store", + default='SRC', metavar='stores and snapshots', nargs='*', help='''one of SRC, BKP or SNP - where is the snapshot located and one ore more snapshots''') -setprop_parser.add_argument("-r", "--ro", +setprop_parser.add_argument("-r", "--ro", default=False, action='store_true', help='''setproperty to readonly. If -r is not given, @@ -1838,10 +1847,10 @@ setprop_parser.set_defaults(func=setprop) setprop_parser.set_defaults(action='setprop') restore_parser=subparsers.add_parser('restore') -restore_parser.add_argument("file", +restore_parser.add_argument("file", nargs='*', help="""restore all given files""") -restore_parser.add_argument("-n", "--no-preserve", +restore_parser.add_argument("-n", "--no-preserve", default=False, action='store_true', help="""if set, the original file will be overwritten. If not set, @@ -1861,7 +1870,7 @@ if __name__ == '__main__': # args.notification['bool']=False # args.notification['type']=None - # --- Logger --- + # --- Logger --- levels = (logging.CRITICAL, logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG, logging.NOTSET) #print(logging.CRITICAL, logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG, logging.NOTSET) print('verbose', args.verbose, levels[args.verbose]) @@ -1887,19 +1896,19 @@ if __name__ == '__main__': # 'application' code logger.debug('debug message') logger.info('info message') - logger.warn('warn message') + logger.warning('warn message') logger.error('error message') logger.critical('critical message') if not 'dry_run' in args: args.dry_run=False - if 'store' in args: + if 'store' in args: if isstring(args.store): args.store = args.store.split(' ') else: args.store = [] - if 'snapshots' in args: + if 'snapshots' in args: if isstring(args.snapshots): args.snapshots = args.snapshots.split() else: args.snapshots = [] @@ -1930,7 +1939,7 @@ if __name__ == '__main__': # tag = None is not allowed. Set it to misc, if not set args.tagset = False - if args.tag == None: + if args.tag == None: args.tag = 'misc' args.tagset = True # if no tag was given, and tag is set here, this value is true - it indicates, tag was set automatically to 'misc' @@ -1957,7 +1966,7 @@ if __name__ == '__main__': for st in args.store: args.sourcepath[st] = args.config.getStorePath(st,args.tag) args.destpath[st] = args.config.getStorePath(st,args.tag) - logger.warn('''Action is %s + logger.warning('''Action is %s Source is %s Destination is %s''' % (args.action,args.sourcepath,args.destpath)) else: @@ -1993,8 +2002,8 @@ Author: %s""" % (confversion,__version__,__author__)) args.stderr=None if args.verbose > 0: - args.npb = False - + args.npb = False + #DEBUG("Arguments",args,verbose=args.verbose) if args.verbose > 3: @@ -2008,6 +2017,12 @@ Author: %s""" % (confversion,__version__,__author__)) args.mdb = EmDBUS() args.mdb.reset(args.tag) args.mdb.start(args.tag) + args.mdbd = EmDBUSDesktop() +# msg = dict() +# msg['sender'] = "mkbackup" +# msg['header'] = "%s-backup" % (args.tag) +# msg['body'] = "Start" +# args.mdbd.critical(msg) ################################################################# ## Run action ## ################################################################# @@ -2052,9 +2067,9 @@ Author: %s""" % (confversion,__version__,__author__)) # for s in args.config.ssh[t].keys(): # if not args.config.ssh[t][s]['ssh'] == None: # print("CLOSE",t,s) -# args.config.ssh[t][s]['ssh'].close() +# args.config.ssh[t][s]['ssh'].close() - # print summary over all actions + # print summary over all actions volumes = list() if not args.action == 'list' and not args.action == 'restore': @@ -2064,7 +2079,7 @@ snapshots: %s """ % (args.store,args.snapshots)) DEBUG("Created Subvolumes:",level=0,verbose=args.verbose) volumes.append('Volumes created:') - if BtrfsListing.CreatedSubvolumes.is_empty(): + if BtrfsListing.CreatedSubvolumes.is_empty(): volumes.append('---') print('''--- ''') @@ -2076,7 +2091,7 @@ snapshots: %s DEBUG("Transfered Subvolumes:",level=0,verbose=args.verbose) volumes.append('Volumes transfered:') - if BtrfsListing.TransferedSubvolumes.is_empty(): + if BtrfsListing.TransferedSubvolumes.is_empty(): volumes.append('---') print('''--- ''') @@ -2085,10 +2100,10 @@ snapshots: %s volumes.append(i[1]) print(i) volumes.append('') - + DEBUG("Deleted Subvolumes:",level=0,verbose=args.verbose) volumes.append('Volumes deleted:') - if BtrfsListing.DeletedSubvolumes.is_empty(): + if BtrfsListing.DeletedSubvolumes.is_empty(): volumes.append('---') print(''' --- ''') @@ -2100,49 +2115,48 @@ snapshots: %s print(args.notification, config.getNotification(intv=args.tag), args.notification_urgency, config.getUrgency(intv=args.tag)) - if args.notification == None: + if args.notification == None: args.notification = config.getNotification(intv=args.tag) - if args.notification_urgency == None: + if args.notification_urgency == None: args.notification_urgency = config.getUrgency(intv=args.tag) print(args.notification, args.notification_urgency) if args.notification == 'desktop': # notify = desktop_notification(args, urgency=args.notification_urgency) -# notify.send_signal(args, *volumes) +# notify.send_signal(args, *volumes) # print(volumes) # print(*volumes) msg = dict() msg['sender'] = "mkbackup" msg['header'] = "%s-backup" % (args.tag) - msg['body'] = """am %s + msg['body'] = """am %s um %s Uhr abgeschlossen. -%s -http://www.google.com -TEST +%s (Ugency: normal) """ % (args.ts.strftime('%Y-%m-%d'), args.ts.strftime('%H:%M:%S'), '\r'.join(volumes)) # msg['action'] = dict() # msg['action']['action1'] = dict() # msg['action']['action1']['title'] = 'Open Backup' # msg['action']['action1']['loc'] = 'file:~/backup' - + advnotify = Notification() advnotify.normal(msg) + args.mdbd.critical(msg) elif args.notification == None: logger.critical("No notification at all") else: logger.critical("No notification at all") - + logger.critical("---== (%s) finnished %s %s at %s ==---" % (os.getpid(),args.func.__name__, args.tag, args.timestamp)) args.mdb.finished(args.tag) - + #import ntfy - + # import smtplib # server = smtplib.SMTP('localhost', 587) # @@ -2153,4 +2167,4 @@ http://www.google.com # msg = """ # Hello!""" # The /n separates the message from the headers # server.sendmail("first.recipient@provider1.example", "second.recipient@provider2.example", msg) -# +#header