Skip to content

Instantly share code, notes, and snippets.

@syci
Created February 19, 2018 21:30
Show Gist options
  • Save syci/32b3854941f2c073d423b28cc8c2259e to your computer and use it in GitHub Desktop.
Save syci/32b3854941f2c073d423b28cc8c2259e to your computer and use it in GitHub Desktop.
Migración de Xen Server a Xen Source
#!/usr/bin/env python
"""
xenmigrate.py
Xen Migrate
Migrate XenServer to Open Source Xen
(c)2011 Jolokia Networks and Mark Pace -- jolokianetworks.com
pace@jolokianetworks.com
AGPL License
USE THIS SOFTWARE AT YOUR OWN RISK!
PLEASE REPORT BUGS SO THEY CAN GET FIXED!
"""
import gzip
import fnmatch
import os
import subprocess
import sys
def docmd(cmd):
"""
run a command and return the communicate PIPE
"""
if debug:
print 'running cmd :',cmd
execute=subprocess.Popen([cmd],shell=True,stdout=subprocess.PIPE)
return execute.communicate()[0]
def exportvm(vmname,lvdev,destfile,gz=False):
"""
export lvdev to dest
"""
if debug:
print 'exporting vm :',vmuuid
# we'll need to handle difference block sizes at some point
blocksize=1024*1024
notification=float(2**30) # 2**30=GB
if gz:
notification=notification/4
vmuuid=getvmuuid(vmname)
vmstatus=getvmstatus(vmuuid)
if vmstatus=='running':
cmd='xe vm-shutdown -u root uuid='+vmuuid
if debug:
print 'halting vm uuid :',vmuuid
docmd(cmd)
vmstatus=getvmstatus(vmuuid)
if vmstatus=='halted':
if not os.path.exists(destfile):
try:
print '\nActivating Volume:'
cmd='lvchange -v -ay '+lvdev
lvchange=docmd(cmd)
source=open(lvdev,'rb')
if gz:
dest=gzip.GzipFile(destfile,'wb')
else:
dest=open(destfile,'wb')
noticetick=notification/(2**30)
print '\nRW notification every: '+str(noticetick)+'GB'
notification=notification/blocksize
sys.stdout.write('Exporting: ')
write=0
while True:
write=write+1
data=source.read(blocksize)
if write%notification==0:
print 'vmdk :',vmdkfile
print 'to raw :',rawfile
print 'gzip :',gz
if (not gz and not os.path.exists(rawfile)) or ((gz and not os.path.exists(rawfile+'.gz')) and (gz and not os.path.exists(rawfile))):
try:
cmd='qemu-img convert '+vmdkfile+' -O raw '+rawfile
print 'Converting...'
response=docmd(cmd)
print response
if gz:
cmd='gzip -v '+rawfile
print 'Gzipping...'
response=docmd(cmd)
print 'Sucessful convert'
except:
print 'ERROR: problem converting file (do you have qemu-img installed?)'
else:
if gz:
print 'ERROR: rawfile '+rawfile+' or '+rawfile+'.gz exists'
else:
print 'ERROR: rawfile '+rawfile+' exists'
##
## Main Program
##
if __name__=='__main__':
# globals
global debug
debug=False
# Hello world
print 'xenmigrate 0.7.4 -- 2011.09.13\n(c)2011 Jolokia Networks and Mark Pace -- jolokianetworks.com\n'
# process arguments
from optparse import OptionParser
parser=OptionParser(usage='%prog [-cdhiltvxz] [vmname]|[exportLVdev]|[importVolGroup]|[importdiskuuid]|[converttofile]')
parser.add_option('-c','--convert',action='store',type='string',dest='convert',metavar='DIR',help='convert DIR or vmdk to importable rawfile')
parser.add_option('-d','--disk',action='store_true',dest='disk',help='display vm disk uuids',default=False)
parser.add_option('--debug',action='store_true',dest='debug',help='display debug info',default=False)
parser.add_option('-i','--import',action='store',type='string',dest='doimport',metavar='FILE',help='import from FILE to [type=xen:importVolGroup]|\n[type=xenserver:importdiskuuid]')
parser.add_option('-l','--lvdev',action='store_true',dest='lvdev',help='display vm logical volume devices',default=False)
parser.add_option('-t','--type',action='store',type='string',dest='type',metavar='TYPE',help='import to [xen]|[xenserver]',default='xen')
parser.add_option('-x','--export',action='store',type='string',dest='export',metavar='FILE',help='export from Xen Server or from Logical Volume dev to FILE')
parser.add_option('-z','--gzip',action='store_true',dest='gz',help='use compression for import, export, or convert (SLOW!)',default=False)
(opts,args)=parser.parse_args()
if len(args)<1:
parser.print_help()
sys.exit(1)
if opts.debug:
debug=True
if opts.disk or opts.lvdev or opts.export:
vmname=args[0]
if '/dev' in vmname and opts.export:
#print 'export dev :',vmname
pass
else:
vmuuid=getvmuuid(vmname)
print 'vm name-label :',vmname
print 'vm uuid :',vmuuid
vmdiskuuids=getvmdiskuuid(vmuuid)
for vmdiskuuid in vmdiskuuids:
print 'vm disk uuid :',vmdiskuuid[0]
print 'vm disk partid :',vmdiskuuid[1]
if opts.lvdev:
lvdev,lvsize=getlvdevxen(vmdiskuuid[0])
if lvdev is not None:
print 'vm disk dev name :',lvdev
print 'vm disk size :',lvsize+'GB'
else:
print 'vm disk dev name : not found in mounted storage repositories'
if opts.export and opts.doimport:
print 'ERROR: export and import cannot be run at the same time'
elif opts.export and opts.convert:
print 'ERROR: export and convert cannot be run at the same time'
elif opts.doimport and opts.convert:
print 'ERROR: import and convert cannot be run at the same time'
elif opts.export and opts.doimport and opts.convert:
print 'ERROR: you have got to be kidding me -- need some more options to run at the same time?'
elif opts.export:
if '/dev' in vmname:
vmdiskuuids=[vmname]
# need some logic here to test for logical volume so we don't just blow up
# we should get the lvsive of the dev 0.7.2 here we come!
# using type might be a good idea too 0.7.3 probably
else:
vmdiskuuids=getvmdiskuuid(vmuuid)
for vmdiskuuid in vmdiskuuids:
if '/dev' in vmname:
lvdev=vmname
lvsize='xen'
else:
lvdev,lvsize=getlvdevxen(vmdiskuuid[0])
if lvdev is not None:
exportname=opts.export
if exportname[-3:]=='.gz':
opts.gz=True
exportname=exportname[:-3]
exportname=exportname+'_'+vmdiskuuid[1]+'_'+lvsize
if opts.gz:
exportname=exportname+'.gz'
print 'export dev :',lvdev
print 'to raw file :',exportname
if lvdev:
exportvm(vmname,lvdev,exportname,opts.gz)
print 'You many need to restart your VM:'
print 'xe vm-startup -u root uuid='+vmuuid
elif opts.doimport:
importname=opts.doimport
if importname[-3:]=='.gz':
opts.gz=True
importname=importname[:-3]
if opts.type=='xen':
lvsize=importname.split('_')[-1]
lvpartid=importname.split('_')[-2]
lvdesttmp=importname.split('/')[-1]
for index in range(len(lvdesttmp.split('_'))-2):
if index==0:
lvdest=lvdesttmp.split('_')[0]
else:
lvdest=lvdest+'_'+lvdesttmp.split('_')[index]
print 'import raw file :',opts.doimport
print 'to lv :',lvdest
print 'in vg :',args[0]
print 'lv size :',lvsize+'GB'
print 'xen config partid :',lvpartid
importvm(lvdest,opts.doimport,args[0],lvsize,opts.gz)
elif opts.type=='xenserver':
print 'import raw file :',opts.doimport
print 'to disk uuid :',args[0]
vmuuid=getdiskuuidvm(args[0])
print 'vm uuid :',vmuuid
importxenserverdisk(opts.doimport,args[0],vmuuid,opts.gz)
else:
print 'ERROR: unknown Xen type for import'
elif opts.convert:
if os.path.isdir(opts.convert):
print 'convert ref dir :',opts.convert
print 'to raw file :',args[0]
reftoraw(opts.convert,args[0],opts.gz)
elif os.path.isfile(opts.convert):
if opts.convert[-5:]=='.vmdk':
filename=args[0]
if filename[-3:]=='.gz':
opts.gz=True
filename=filename[:-3]
print 'convert vmdk file :',opts.convert
print 'to raw file :',filename
vmdktoraw(opts.convert,filename,opts.gz)
else:
print 'ERROR: unknown file convert format'
else:
print 'ERROR: convert source directory or file does not exist'
sys.exit(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment