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