black and fix print statements.
x# modified: virt-back
This commit is contained in:
parent
3eeb196a84
commit
b42a1161ca
1 changed files with 359 additions and 218 deletions
577
virt-back
577
virt-back
|
|
@ -34,248 +34,271 @@ from shutil import move, copy2
|
||||||
try:
|
try:
|
||||||
from operator import methodcaller
|
from operator import methodcaller
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
|
||||||
def methodcaller(name, *args, **kwargs):
|
def methodcaller(name, *args, **kwargs):
|
||||||
def caller(obj):
|
def caller(obj):
|
||||||
return getattr(obj, name)(*args, **kwargs)
|
return getattr(obj, name)(*args, **kwargs)
|
||||||
|
|
||||||
return caller
|
return caller
|
||||||
|
|
||||||
|
|
||||||
class Domfetcher(object):
|
class Domfetcher(object):
|
||||||
"""Abstract libvirt API, supply methods to return dom object lists"""
|
"""Abstract libvirt API, supply methods to return dom object lists"""
|
||||||
def __init__(self, uri = None):
|
|
||||||
|
def __init__(self, uri=None):
|
||||||
"""Connect to hypervisor uri with read write access"""
|
"""Connect to hypervisor uri with read write access"""
|
||||||
# register logit as the error handler
|
# register logit as the error handler
|
||||||
libvirt.registerErrorHandler( logit, 'libvirt error' )
|
libvirt.registerErrorHandler(logit, "libvirt error")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.c = libvirt.open( uri )
|
self.c = libvirt.open(uri)
|
||||||
except:
|
except:
|
||||||
self.c = None
|
self.c = None
|
||||||
logit( "libvirt error", "Failed to open connection to the hypervisor" )
|
logit("libvirt error", "Failed to open connection to the hypervisor")
|
||||||
|
|
||||||
def get_running_doms(self):
|
def get_running_doms(self):
|
||||||
"""Return a list of running dom objects"""
|
"""Return a list of running dom objects"""
|
||||||
doms = []
|
doms = []
|
||||||
for id in self.c.listDomainsID(): # loop over the running ids
|
for id in self.c.listDomainsID(): # loop over the running ids
|
||||||
dom = self.c.lookupByID( id ) # fetch dom object by id
|
dom = self.c.lookupByID(id) # fetch dom object by id
|
||||||
if 'Domain-' not in dom.name(): # prevent actions on the Xen hypervisor
|
if "Domain-" not in dom.name(): # prevent actions on the Xen hypervisor
|
||||||
doms.append( dom ) # append dom object to doms
|
doms.append(dom) # append dom object to doms
|
||||||
return doms
|
return doms
|
||||||
|
|
||||||
def get_shutoff_doms(self):
|
def get_shutoff_doms(self):
|
||||||
"""Return a list of all shutoff but defined dom objects"""
|
"""Return a list of all shutoff but defined dom objects"""
|
||||||
return [self.c.lookupByName( name ) for name in self.c.listDefinedDomains()]
|
return [self.c.lookupByName(name) for name in self.c.listDefinedDomains()]
|
||||||
|
|
||||||
def get_doms_by_names(self, guest_names):
|
def get_doms_by_names(self, guest_names):
|
||||||
"""Accept a list of guest_names, return a list of related dom objects"""
|
"""Accept a list of guest_names, return a list of related dom objects"""
|
||||||
doms = []
|
doms = []
|
||||||
for name in guest_names:
|
for name in guest_names:
|
||||||
try:
|
try:
|
||||||
dom = self.c.lookupByName( name )
|
dom = self.c.lookupByName(name)
|
||||||
doms.append( dom )
|
doms.append(dom)
|
||||||
except libvirt.libvirtError: pass # logit reg'd as libvirt error handler
|
except libvirt.libvirtError:
|
||||||
|
pass # logit reg'd as libvirt error handler
|
||||||
return doms
|
return doms
|
||||||
|
|
||||||
def get_all_doms(self):
|
def get_all_doms(self):
|
||||||
"""Return a list of all dom objects"""
|
"""Return a list of all dom objects"""
|
||||||
return self.get_running_doms() + self.get_shutoff_doms()
|
return self.get_running_doms() + self.get_shutoff_doms()
|
||||||
|
|
||||||
|
|
||||||
def invoke( doms, method ):
|
|
||||||
|
def invoke(doms, method):
|
||||||
"""Pattern to invoke shutdown, destroy, and start on a list of doms"""
|
"""Pattern to invoke shutdown, destroy, and start on a list of doms"""
|
||||||
f = methodcaller( method )
|
f = methodcaller(method)
|
||||||
for dom in doms:
|
for dom in doms:
|
||||||
try:
|
try:
|
||||||
logit( method, 'invoking %s on %s' % (method, dom.name()) )
|
logit(method, "invoking %s on %s" % (method, dom.name()))
|
||||||
retcode = f(dom)
|
retcode = f(dom)
|
||||||
if retcode: # log retcode
|
if retcode: # log retcode
|
||||||
logit(
|
logit(
|
||||||
method,
|
method,
|
||||||
'{0} returned {1} on {2}'.format( method, retcode, dom.name() )
|
"{0} returned {1} on {2}".format(method, retcode, dom.name()),
|
||||||
)
|
)
|
||||||
except libvirt.libvirtError:
|
except libvirt.libvirtError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def backup( doms ):
|
|
||||||
|
def backup(doms):
|
||||||
"""Accept a list of dom objects, run backup proceedure on each"""
|
"""Accept a list of dom objects, run backup proceedure on each"""
|
||||||
for dom in doms:
|
for dom in doms:
|
||||||
recreate = dom.isActive()
|
recreate = dom.isActive()
|
||||||
|
|
||||||
if dom.isActive(): # if dom is active, shutdown
|
if dom.isActive(): # if dom is active, shutdown
|
||||||
shutdown([dom])
|
shutdown([dom])
|
||||||
|
|
||||||
if dom.isActive(): # if dom is active, error
|
|
||||||
logit(
|
|
||||||
'error',
|
|
||||||
'unable to shutdown or destroy %s and BACKUP FAILED!' % dom.name()
|
|
||||||
)
|
|
||||||
continue # skip to the next dom
|
|
||||||
|
|
||||||
xml = dom.XMLDesc( 0 )
|
if dom.isActive(): # if dom is active, error
|
||||||
xmlfile = path.join( options.backpath, dom.name() + '.xml' )
|
logit(
|
||||||
f = open( xmlfile, 'w')
|
"error",
|
||||||
f.write( xml )
|
"unable to shutdown or destroy %s and BACKUP FAILED!" % dom.name(),
|
||||||
|
)
|
||||||
|
continue # skip to the next dom
|
||||||
|
|
||||||
|
xml = dom.XMLDesc(0)
|
||||||
|
xmlfile = path.join(options.backpath, dom.name() + ".xml")
|
||||||
|
f = open(xmlfile, "w")
|
||||||
|
f.write(xml)
|
||||||
f.close()
|
f.close()
|
||||||
disklist = findall( "<source file='(.*)'/>\n", xml )
|
disklist = findall("<source file='(.*)'/>\n", xml)
|
||||||
|
|
||||||
logit( 'backup', 'invoking backup for ' + dom.name() )
|
logit("backup", "invoking backup for " + dom.name())
|
||||||
|
|
||||||
for disk_source in disklist:
|
|
||||||
disk_file = disk_source.split('/')[-1]
|
|
||||||
disk_dest = path.join( options.backpath, disk_file )
|
|
||||||
|
|
||||||
logit(
|
|
||||||
'backup',
|
|
||||||
'copying %s to %s for %s' % (disk_source, disk_dest, dom.name())
|
|
||||||
)
|
|
||||||
copy2( disk_source, disk_dest )
|
|
||||||
|
|
||||||
if recreate: # if true, start guest after backup
|
|
||||||
create([dom]) # start dom
|
|
||||||
|
|
||||||
ext, tarmode = '.tar.gz', 'w:gz'
|
|
||||||
if options.nogzip:
|
|
||||||
ext, tarmode = '.tar', 'w'
|
|
||||||
|
|
||||||
tarfilename = dom.name() + ext
|
|
||||||
if options.tardate:
|
|
||||||
tarfilename = dom.name() + '-' + TODAY + ext
|
|
||||||
|
|
||||||
tarpath = path.join( options.backpath, tarfilename )
|
|
||||||
|
|
||||||
if path.isfile( tarpath ): # if file exists, run rotate
|
|
||||||
logit( 'backup', 'rotating backup files for ' + dom.name() )
|
|
||||||
rotate( tarpath, options.retention )
|
|
||||||
|
|
||||||
logit(
|
|
||||||
'backup',
|
|
||||||
'archiving files for %s to %s' % (dom.name(), tarpath)
|
|
||||||
)
|
|
||||||
tar = tarfile.open( tarpath, tarmode )
|
|
||||||
|
|
||||||
logit(
|
|
||||||
'backup',
|
|
||||||
'archiving %s for %s' % (xmlfile, dom.name())
|
|
||||||
)
|
|
||||||
tar.add( xmlfile ) # add xml to tar
|
|
||||||
remove( xmlfile ) # cleanup tmp files
|
|
||||||
|
|
||||||
for disk_source in disklist:
|
for disk_source in disklist:
|
||||||
disk_file = disk_source.split('/')[-1]
|
disk_file = disk_source.split("/")[-1]
|
||||||
disk_dest = path.join( options.backpath, disk_file )
|
disk_dest = path.join(options.backpath, disk_file)
|
||||||
|
|
||||||
logit(
|
logit(
|
||||||
'backup',
|
"backup",
|
||||||
'archiving %s for %s' % (disk_dest, dom.name())
|
"copying %s to %s for %s" % (disk_source, disk_dest, dom.name()),
|
||||||
)
|
)
|
||||||
tar.add( disk_dest ) # add img to tar
|
copy2(disk_source, disk_dest)
|
||||||
remove( disk_dest ) # cleanup tmp files
|
|
||||||
|
if recreate: # if true, start guest after backup
|
||||||
|
create([dom]) # start dom
|
||||||
|
|
||||||
|
ext, tarmode = ".tar.gz", "w:gz"
|
||||||
|
if options.nogzip:
|
||||||
|
ext, tarmode = ".tar", "w"
|
||||||
|
|
||||||
|
tarfilename = dom.name() + ext
|
||||||
|
if options.tardate:
|
||||||
|
tarfilename = dom.name() + "-" + TODAY + ext
|
||||||
|
|
||||||
|
tarpath = path.join(options.backpath, tarfilename)
|
||||||
|
|
||||||
|
if path.isfile(tarpath): # if file exists, run rotate
|
||||||
|
logit("backup", "rotating backup files for " + dom.name())
|
||||||
|
rotate(tarpath, options.retention)
|
||||||
|
|
||||||
|
logit("backup", "archiving files for %s to %s" % (dom.name(), tarpath))
|
||||||
|
tar = tarfile.open(tarpath, tarmode)
|
||||||
|
|
||||||
|
logit("backup", "archiving %s for %s" % (xmlfile, dom.name()))
|
||||||
|
tar.add(xmlfile) # add xml to tar
|
||||||
|
remove(xmlfile) # cleanup tmp files
|
||||||
|
|
||||||
|
for disk_source in disklist:
|
||||||
|
disk_file = disk_source.split("/")[-1]
|
||||||
|
disk_dest = path.join(options.backpath, disk_file)
|
||||||
|
logit("backup", "archiving %s for %s" % (disk_dest, dom.name()))
|
||||||
|
tar.add(disk_dest) # add img to tar
|
||||||
|
remove(disk_dest) # cleanup tmp files
|
||||||
|
|
||||||
tar.close()
|
tar.close()
|
||||||
|
|
||||||
logit( 'backup', 'finished backup for ' + dom.name() )
|
logit("backup", "finished backup for " + dom.name())
|
||||||
|
|
||||||
def shutdown( doms, wait=180 ):
|
|
||||||
|
def shutdown(doms, wait=180):
|
||||||
"""Accept a list of dom objects, attempt to shutdown the active ones"""
|
"""Accept a list of dom objects, attempt to shutdown the active ones"""
|
||||||
# get all running guests from list and invoke shutdown
|
# get all running guests from list and invoke shutdown
|
||||||
invoke( get_all_running( doms ), 'shutdown' )
|
invoke(get_all_running(doms), "shutdown")
|
||||||
|
|
||||||
"""loop until all guests are shut off or destroy
|
"""loop until all guests are shut off or destroy
|
||||||
all active guests if wait timer is reached."""
|
all active guests if wait timer is reached."""
|
||||||
|
|
||||||
secs = 10
|
secs = 10
|
||||||
wait /= secs # divide wait by secs
|
wait /= secs # divide wait by secs
|
||||||
|
|
||||||
for i in range( 0, wait + 1 ):
|
for i in range(0, wait + 1):
|
||||||
|
|
||||||
# if all doms are shut off, leave loop
|
# if all doms are shut off, leave loop
|
||||||
if check_all_shutoff( doms ):
|
if check_all_shutoff(doms):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
logit(
|
logit(
|
||||||
'shutdown',
|
"shutdown",
|
||||||
'waited ' + str( i * secs ) + ' seconds for ' +
|
"waited "
|
||||||
', '.join( dom.name() for dom in get_all_running( doms ) ) +
|
+ str(i * secs)
|
||||||
' to shut off'
|
+ " seconds for "
|
||||||
|
+ ", ".join(dom.name() for dom in get_all_running(doms))
|
||||||
|
+ " to shut off",
|
||||||
)
|
)
|
||||||
|
|
||||||
# if the wait time is reached, destroy all active doms
|
# if the wait time is reached, destroy all active doms
|
||||||
if i == wait:
|
if i == wait:
|
||||||
invoke( get_all_running( doms ) ,'destroy' )
|
invoke(get_all_running(doms), "destroy")
|
||||||
|
|
||||||
sleep( secs )
|
|
||||||
|
|
||||||
def create( doms ):
|
sleep(secs)
|
||||||
|
|
||||||
|
|
||||||
|
def create(doms):
|
||||||
"""Accept a list of dom objects, attempt to start the inactive ones"""
|
"""Accept a list of dom objects, attempt to start the inactive ones"""
|
||||||
# get all shutoff guests from list and invoke create
|
# get all shutoff guests from list and invoke create
|
||||||
invoke( get_all_shutoff( doms ), 'create' )
|
invoke(get_all_shutoff(doms), "create")
|
||||||
|
|
||||||
def reboot( doms ):
|
|
||||||
|
def reboot(doms):
|
||||||
"""Accept a list of dom objects, attempt to shutdown then start"""
|
"""Accept a list of dom objects, attempt to shutdown then start"""
|
||||||
shutdown( doms )
|
shutdown(doms)
|
||||||
create( doms )
|
create(doms)
|
||||||
|
|
||||||
def info( doms ):
|
|
||||||
|
def info(doms):
|
||||||
"""Accept a list of dom objects, attempt to display info for all"""
|
"""Accept a list of dom objects, attempt to display info for all"""
|
||||||
#invoke( doms, 'name' )
|
# invoke( doms, 'name' )
|
||||||
#invoke( doms, 'info')
|
# invoke( doms, 'info')
|
||||||
if check_all_running( doms ): print "NOTE: All guests are running"
|
if check_all_running(doms):
|
||||||
if check_all_shutoff( doms ): print "NOTE: All guests are shut off"
|
print("NOTE: All guests are running")
|
||||||
|
if check_all_shutoff(doms):
|
||||||
print ''
|
print("NOTE: All guests are shut off")
|
||||||
print 'running guests: ' + ', '.join( [ dom.name() for dom in get_all_running( doms ) ] )
|
|
||||||
print 'shutoff guests: ' + ', '.join( [ dom.name() for dom in get_all_shutoff( doms ) ] )
|
print("")
|
||||||
print ''
|
print("running guests: " + ", ".join([dom.name() for dom in get_all_running(doms)]))
|
||||||
print 'DomName'.ljust(16) + 'Memory MB'.rjust(12) + 'vCPUs'.rjust(8) + 'CPUtime ms'.rjust(18)
|
print("shutoff guests: " + ", ".join([dom.name() for dom in get_all_shutoff(doms)]))
|
||||||
print '======================================================'
|
print("")
|
||||||
|
print(
|
||||||
|
"DomName".ljust(16)
|
||||||
|
+ "Memory MB".rjust(12)
|
||||||
|
+ "vCPUs".rjust(8)
|
||||||
|
+ "CPUtime ms".rjust(18)
|
||||||
|
)
|
||||||
|
print("======================================================")
|
||||||
for dom in doms:
|
for dom in doms:
|
||||||
name = dom.name()
|
name = dom.name()
|
||||||
rams = str(dom.info()[2]/1024) + '/' + str(dom.info()[1]/1024)
|
rams = str(dom.info()[2] / 1024) + "/" + str(dom.info()[1] / 1024)
|
||||||
cpus = str(dom.info()[3])
|
cpus = str(dom.info()[3])
|
||||||
time = str(dom.info()[4]/1000000)
|
time = str(dom.info()[4] / 1000000)
|
||||||
print name.ljust(16) + rams.rjust(12) + cpus.rjust(8) + time.rjust(18)
|
print(name.ljust(16) + rams.rjust(12) + cpus.rjust(8) + time.rjust(18))
|
||||||
|
|
||||||
def check_all_running( doms ):
|
|
||||||
|
def check_all_running(doms):
|
||||||
"""Accept a list of dom objects, check if all guest dom are active"""
|
"""Accept a list of dom objects, check if all guest dom are active"""
|
||||||
if sum( [dom.isActive() for dom in doms] ) == len( doms ):
|
if sum([dom.isActive() for dom in doms]) == len(doms):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def check_all_shutoff( doms ):
|
|
||||||
|
def check_all_shutoff(doms):
|
||||||
"""Accept a list of dom objects, check if all guest dom are shut off"""
|
"""Accept a list of dom objects, check if all guest dom are shut off"""
|
||||||
if sum( [dom.isActive() for dom in doms] ):
|
if sum([dom.isActive() for dom in doms]):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_all_running( doms ):
|
|
||||||
|
def get_all_running(doms):
|
||||||
"""Accept a list of dom objects, return a list of running dom objects"""
|
"""Accept a list of dom objects, return a list of running dom objects"""
|
||||||
return [ dom for dom in doms if dom.isActive() ]
|
return [dom for dom in doms if dom.isActive()]
|
||||||
|
|
||||||
def get_all_shutoff( doms ):
|
|
||||||
|
def get_all_shutoff(doms):
|
||||||
"""Accept a list of dom objects, return a list of shutoff dom objects"""
|
"""Accept a list of dom objects, return a list of shutoff dom objects"""
|
||||||
return [ dom for dom in doms if not dom.isActive() ]
|
return [dom for dom in doms if not dom.isActive()]
|
||||||
|
|
||||||
def logit( context, message, quiet = False ):
|
|
||||||
|
def logit(context, message, quiet=False):
|
||||||
"""syslog and error handler"""
|
"""syslog and error handler"""
|
||||||
if type( message ) is tuple:
|
if type(message) is tuple:
|
||||||
message = message[2] # libvirt message is a tuple
|
message = message[2] # libvirt message is a tuple
|
||||||
|
|
||||||
try: quiet = options.quiet
|
try:
|
||||||
except NameError: pass
|
quiet = options.quiet
|
||||||
|
except NameError:
|
||||||
|
pass
|
||||||
|
|
||||||
if quiet: pass
|
if quiet:
|
||||||
else: print context + ': ' + message
|
pass
|
||||||
|
else:
|
||||||
|
print(context + ": " + message)
|
||||||
|
|
||||||
syslog.openlog( 'virt-back', 0, syslog.LOG_LOCAL3 )
|
syslog.openlog("virt-back", 0, syslog.LOG_LOCAL3)
|
||||||
syslog.syslog( message )
|
syslog.syslog(message)
|
||||||
syslog.closelog()
|
syslog.closelog()
|
||||||
|
|
||||||
def rotate( target, retention = 3 ):
|
|
||||||
|
def rotate(target, retention=3):
|
||||||
"""file rotation routine"""
|
"""file rotation routine"""
|
||||||
for i in range( retention-2, 0, -1 ): # count backwards
|
for i in range(retention - 2, 0, -1): # count backwards
|
||||||
old_name = "%s.%s" % ( target, i )
|
old_name = "%s.%s" % (target, i)
|
||||||
new_name = "%s.%s" % ( target, i + 1 )
|
new_name = "%s.%s" % (target, i + 1)
|
||||||
try: move( old_name, new_name )
|
try:
|
||||||
except IOError: pass
|
move(old_name, new_name)
|
||||||
move( target, target + '.1' )
|
except IOError:
|
||||||
|
pass
|
||||||
|
move(target, target + ".1")
|
||||||
|
|
||||||
|
|
||||||
def getoptions():
|
def getoptions():
|
||||||
"""Fetch cli args, parse and map to python, test sanity"""
|
"""Fetch cli args, parse and map to python, test sanity"""
|
||||||
|
|
@ -283,101 +306,219 @@ def getoptions():
|
||||||
# create an option parcer object
|
# create an option parcer object
|
||||||
p = OptionParser()
|
p = OptionParser()
|
||||||
|
|
||||||
p.set_description( DESCRIPTION )
|
p.set_description(DESCRIPTION)
|
||||||
|
|
||||||
p.add_option( '-q', '--quiet', dest='quiet', action='store_true', default=False,
|
|
||||||
help='prevent output to stdout' )
|
|
||||||
|
|
||||||
p.add_option( '-d', '--date', dest='tardate', action='store_true', default=False,
|
p.add_option(
|
||||||
help='append date to tar filename [default: no date]' )
|
"-q",
|
||||||
|
"--quiet",
|
||||||
|
dest="quiet",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="prevent output to stdout",
|
||||||
|
)
|
||||||
|
|
||||||
p.add_option( '-g', '--no-gzip', dest='nogzip', action='store_true', default=False,
|
p.add_option(
|
||||||
help='do not gzip the resulting tar file' )
|
"-d",
|
||||||
|
"--date",
|
||||||
|
dest="tardate",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="append date to tar filename [default: no date]",
|
||||||
|
)
|
||||||
|
|
||||||
p.add_option( '-a', '--retention', dest='retention', metavar="amount", default=3,
|
p.add_option(
|
||||||
type='int', help="backups to retain [default: 3]" )
|
"-g",
|
||||||
|
"--no-gzip",
|
||||||
|
dest="nogzip",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="do not gzip the resulting tar file",
|
||||||
|
)
|
||||||
|
|
||||||
p.add_option( '-p', '--path', dest='backpath', metavar="'PATH'", default='/KVMBACK',
|
p.add_option(
|
||||||
help="backup path [default: '/KVMBACK']" )
|
"-a",
|
||||||
|
"--retention",
|
||||||
p.add_option( '-u', '--uri', dest='uri', metavar="'URI'",
|
dest="retention",
|
||||||
help="optional hypervisor uri" )
|
metavar="amount",
|
||||||
|
default=3,
|
||||||
|
type="int",
|
||||||
|
help="backups to retain [default: 3]",
|
||||||
|
)
|
||||||
|
|
||||||
|
p.add_option(
|
||||||
|
"-p",
|
||||||
|
"--path",
|
||||||
|
dest="backpath",
|
||||||
|
metavar="'PATH'",
|
||||||
|
default="/KVMBACK",
|
||||||
|
help="backup path [default: '/KVMBACK']",
|
||||||
|
)
|
||||||
|
|
||||||
|
p.add_option(
|
||||||
|
"-u", "--uri", dest="uri", metavar="'URI'", help="optional hypervisor uri"
|
||||||
|
)
|
||||||
|
|
||||||
# Actions for info testing: These options display info/ test a list of guests only.
|
# Actions for info testing: These options display info/ test a list of guests only.
|
||||||
|
|
||||||
g0 = OptionGroup( p, "Actions for info testing", "These options display info or test a list of guests." )
|
g0 = OptionGroup(
|
||||||
|
p,
|
||||||
g0.add_option( '-i', '--info', dest='info', action='store_true', default=False,
|
"Actions for info testing",
|
||||||
help='info/test a list of guests (space delimited dom names)' )
|
"These options display info or test a list of guests.",
|
||||||
|
)
|
||||||
g0.add_option( '--info-all', dest='infoall', action='store_true', default=False,
|
|
||||||
help='attempt to show info on ALL guests' )
|
g0.add_option(
|
||||||
|
"-i",
|
||||||
|
"--info",
|
||||||
|
dest="info",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="info/test a list of guests (space delimited dom names)",
|
||||||
|
)
|
||||||
|
|
||||||
|
g0.add_option(
|
||||||
|
"--info-all",
|
||||||
|
dest="infoall",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="attempt to show info on ALL guests",
|
||||||
|
)
|
||||||
|
|
||||||
# WARNING: Dangerous options below, option grouping for scary actions
|
# WARNING: Dangerous options below, option grouping for scary actions
|
||||||
|
|
||||||
g1 = OptionGroup( p, "Actions for a list of dom names", "WARNING: These options WILL bring down guests!" )
|
|
||||||
|
|
||||||
g1.add_option( '-b', '--backup', dest='backup', action='store_true', default=False,
|
|
||||||
help='backup a list of guests (space delimited dom names)' )
|
|
||||||
|
|
||||||
g1.add_option( '-r', '--reboot', dest='reboot', action='store_true', default=False,
|
|
||||||
help='reboot a list of guests (space delimited dom names)' )
|
|
||||||
|
|
||||||
g1.add_option( '-s', '--shutdown', dest='shutdown', action='store_true', default=False,
|
|
||||||
help='shutdown a list of guests (space delimited dom names)' )
|
|
||||||
|
|
||||||
g1.add_option( '-c', '--create', dest='create', action='store_true', default=False,
|
|
||||||
help='start a list of guests (space delimited dom names)' )
|
|
||||||
|
|
||||||
g2 = OptionGroup( p, "Actions for all doms", "WARNING: These options WILL bring down ALL guests!" )
|
|
||||||
|
|
||||||
g2.add_option( '--backup-all', dest='backupall', action='store_true', default=False,
|
g1 = OptionGroup(
|
||||||
help='attempt to shutdown, backup, and start ALL guests' )
|
p,
|
||||||
|
"Actions for a list of dom names",
|
||||||
|
"WARNING: These options WILL bring down guests!",
|
||||||
|
)
|
||||||
|
|
||||||
g2.add_option( '--reboot-all', dest='rebootall', action='store_true', default=False,
|
g1.add_option(
|
||||||
help='attempt to shutdown and then start ALL guests' )
|
"-b",
|
||||||
|
"--backup",
|
||||||
g2.add_option( '--shutdown-all', dest='shutdownall', action='store_true', default=False,
|
dest="backup",
|
||||||
help='attempt to shutdown ALL guests' )
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="backup a list of guests (space delimited dom names)",
|
||||||
|
)
|
||||||
|
|
||||||
g2.add_option( '--create-all', dest='createall', action='store_true', default=False,
|
g1.add_option(
|
||||||
help='attempt to start ALL guests' )
|
"-r",
|
||||||
|
"--reboot",
|
||||||
|
dest="reboot",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="reboot a list of guests (space delimited dom names)",
|
||||||
|
)
|
||||||
|
|
||||||
|
g1.add_option(
|
||||||
|
"-s",
|
||||||
|
"--shutdown",
|
||||||
|
dest="shutdown",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="shutdown a list of guests (space delimited dom names)",
|
||||||
|
)
|
||||||
|
|
||||||
|
g1.add_option(
|
||||||
|
"-c",
|
||||||
|
"--create",
|
||||||
|
dest="create",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="start a list of guests (space delimited dom names)",
|
||||||
|
)
|
||||||
|
|
||||||
|
g2 = OptionGroup(
|
||||||
|
p, "Actions for all doms", "WARNING: These options WILL bring down ALL guests!"
|
||||||
|
)
|
||||||
|
|
||||||
|
g2.add_option(
|
||||||
|
"--backup-all",
|
||||||
|
dest="backupall",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="attempt to shutdown, backup, and start ALL guests",
|
||||||
|
)
|
||||||
|
|
||||||
|
g2.add_option(
|
||||||
|
"--reboot-all",
|
||||||
|
dest="rebootall",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="attempt to shutdown and then start ALL guests",
|
||||||
|
)
|
||||||
|
|
||||||
|
g2.add_option(
|
||||||
|
"--shutdown-all",
|
||||||
|
dest="shutdownall",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="attempt to shutdown ALL guests",
|
||||||
|
)
|
||||||
|
|
||||||
|
g2.add_option(
|
||||||
|
"--create-all",
|
||||||
|
dest="createall",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="attempt to start ALL guests",
|
||||||
|
)
|
||||||
|
|
||||||
# attach groups g1 and g2 to the parser p object
|
# attach groups g1 and g2 to the parser p object
|
||||||
p.add_option_group( g0 )
|
p.add_option_group(g0)
|
||||||
p.add_option_group( g1 )
|
p.add_option_group(g1)
|
||||||
p.add_option_group( g2 )
|
p.add_option_group(g2)
|
||||||
|
|
||||||
# parse options and args
|
# parse options and args
|
||||||
options, guest_names = p.parse_args()
|
options, guest_names = p.parse_args()
|
||||||
|
|
||||||
# the actionsum should be 1 to continue, bool math ftw
|
# the actionsum should be 1 to continue, bool math ftw
|
||||||
actions = [ options.backup, options.reboot, options.shutdown,
|
actions = [
|
||||||
options.create, options.info, options.backupall, options.rebootall,
|
options.backup,
|
||||||
options.shutdownall, options.createall, options.infoall, ]
|
options.reboot,
|
||||||
actionsum = sum( actions )
|
options.shutdown,
|
||||||
|
options.create,
|
||||||
|
options.info,
|
||||||
|
options.backupall,
|
||||||
|
options.rebootall,
|
||||||
|
options.shutdownall,
|
||||||
|
options.createall,
|
||||||
|
options.infoall,
|
||||||
|
]
|
||||||
|
actionsum = sum(actions)
|
||||||
|
|
||||||
if actionsum == 1:
|
if actionsum == 1:
|
||||||
return options, guest_names
|
return options, guest_names
|
||||||
else:
|
else:
|
||||||
exit("\nYou must have 1 action, no more, no less.\n\nRun 'virt-back --help' for help.\n")
|
exit(
|
||||||
|
"\nYou must have 1 action, no more, no less.\n\nRun 'virt-back --help' for help.\n"
|
||||||
|
)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
TODAY = str( date.today() )
|
if __name__ == "__main__":
|
||||||
|
TODAY = str(date.today())
|
||||||
# Get the list of options and list of guest_names from cli
|
# Get the list of options and list of guest_names from cli
|
||||||
options, guest_names = getoptions()
|
options, guest_names = getoptions()
|
||||||
# connect to hypervisor with Domfetcher (read-only)
|
# connect to hypervisor with Domfetcher (read-only)
|
||||||
domfetcher = Domfetcher( options.uri )
|
domfetcher = Domfetcher(options.uri)
|
||||||
|
|
||||||
if options.backup or options.reboot or options.shutdown or options.create or options.info:
|
if (
|
||||||
doms = domfetcher.get_doms_by_names( guest_names )
|
options.backup
|
||||||
else:
|
or options.reboot
|
||||||
|
or options.shutdown
|
||||||
|
or options.create
|
||||||
|
or options.info
|
||||||
|
):
|
||||||
|
doms = domfetcher.get_doms_by_names(guest_names)
|
||||||
|
else:
|
||||||
doms = domfetcher.get_all_doms()
|
doms = domfetcher.get_all_doms()
|
||||||
|
|
||||||
if options.backup or options.backupall: backup( doms )
|
|
||||||
if options.reboot or options.rebootall: reboot( doms )
|
|
||||||
if options.shutdown or options.shutdownall: shutdown( doms )
|
|
||||||
if options.create or options.createall: create( doms )
|
|
||||||
if options.info or options.infoall: info( doms )
|
|
||||||
|
|
||||||
|
|
||||||
|
if options.backup or options.backupall:
|
||||||
|
backup(doms)
|
||||||
|
if options.reboot or options.rebootall:
|
||||||
|
reboot(doms)
|
||||||
|
if options.shutdown or options.shutdownall:
|
||||||
|
shutdown(doms)
|
||||||
|
if options.create or options.createall:
|
||||||
|
create(doms)
|
||||||
|
if options.info or options.infoall:
|
||||||
|
info(doms)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue