关于我们
技术分享
技术分享
openstack虚拟机迁移到ovirt环境脚本实现
openstack虚拟机迁移到ovirt环境脚本实现
2021-06-06
1、需求背景:
旧平台openstack虚拟机需要迁移到ovirt-engine环境,直接用ovirt自带的对接openstack环境一直cinder鉴权报错,调查是版本不支持,只能手动备份导入的ovirt平台。
思路:获取openstack环境虚拟机信息,读取迁移虚拟机表格,导出虚拟机为qcow2,上传到ovirt平台创建虚拟机挂盘。
2、获取openstack计算节点虚拟机信息
通过virsh list获取instance实例列表,再通过dumpxml获取虚拟机信息利用xml模块解析所需要的信息
def get_vms_list(self): # print("virsh list --all --name ...") list_cmd = "virsh list --all --name".split(" ") stdout, stderr = self.cmd_process(list_cmd) instance_names = list(filter(None, stdout.split("\n"))) return instance_names def get_dumpxml_info(self, instance_name): # print("virsh dumpxml...") info_cmd = "virsh dumpxml %s" % instance_name stdout, _ = self.cmd_process(info_cmd.split(" ")) return stdout def get_vms_info(self): instance_names = self.get_vms_list() vms_info = [] for instance_name in instance_names: xml_str = self.get_dumpxml_info(instance_name) DOMTree = xml.dom.minidom.parseString(xml_str) collection = DOMTree.documentElement vm_info = {} data_volume = [] vm_info["instance_name"] = collection.getElementsByTagName("name")[0].childNodes[0].data vm_info["vm_name"] = collection.getElementsByTagName("metadata")[0].getElementsByTagName("nova:instance")[ 0].getElementsByTagName("nova:name")[0].childNodes[0].data vm_info["vm_flavor"] = collection.getElementsByTagName("metadata")[0].getElementsByTagName("nova:instance")[ 0].getElementsByTagName("nova:flavor")[0].getAttribute("name") vm_info["instance_uuid"] = collection.getElementsByTagName("uuid")[0].childNodes[0].data vm_info["instance_vcpu"] = collection.getElementsByTagName("vcpu")[0].childNodes[0].data vm_info["instance_memory"] = collection.getElementsByTagName("memory")[0].childNodes[0].data for disk_info in collection.getElementsByTagName("devices")[0].getElementsByTagName("disk"): dev = disk_info.getElementsByTagName("target")[0].getAttribute("dev") if dev == "vda" or dev == "hda": vm_info["system_volume"] = disk_info.getElementsByTagName("source")[0].getAttribute("name") else: data_volume.append(disk_info.getElementsByTagName("source")[0].getAttribute("name")) vm_info["data_volume"] = data_volume vms_info.append(vm_info) return vms_info
计算节点都要执行,最后汇总到执行脚本的节点,并且汇总读取信息(注意系统卷和数据卷的判断根据具体环境修改适配)
run_first_time = False if run_first_time: for host in HOST_LIST: print("** get the vm info from %s" % host) os.system("scp get_vm_info.py root@%s:/home" % host) sshclient_execmd(host, "python /home/get_vm_info.py > /home/%s_vm_info.txt" % host) time.sleep(1) sshclient_execmd(host, "scp /home/%s_vm_info.txt root@cmp014:/home/test/info" % host) time.sleep(1) print("** update vm info successful") print("** read the info file") info_path = "/home/test/info" files = os.listdir(info_path) for file_name in files: print("** read the file : %s" % file_name) with open(info_path + "/" + file_name) as f: content = f.read() all_vms_info.extend(ast.literal_eval(content))
3、获取卷信息后转换格式
def rbd_export(self, volume_path, volume_name): rbd_cmd_str = "rbd export %s %s.qcow2" % (volume_path, volume_name) self.cmd_process(rbd_cmd_str.split(" ")) print ("**%s exported %s successfully." % (volume_path, volume_name)) def img_covert(self, qcow2_path, qcow2_name): img_covert_str = "qemu-img convert -O qcow2 %s %s" % (qcow2_path + ".qcow2", qcow2_name + ".qcow2") self.cmd_process(img_covert_str.split(" ")) print ("**%s coverted successfully." % qcow2_name) os.remove(qcow2_path + ".qcow2") print ("**remove tmp file:%s" % (qcow2_path + ".qcow2")) def clean_disks(self, qcow2_name): if os.path.exists(qcow2_name + ".qcow2"): os.remove(qcow2_name + ".qcow2") print ("** remove disk %s" % qcow2_name)
4、虚拟机disk转换之后利用ovirt sdk的方法上传系统盘和数据盘,创建虚拟机将盘挂载在虚拟机上,添加网卡,等等
def upload_disk(self): print ("--Step01:upload disk....") for volume_path in self.volumes_list: # Get image info using qemu-img image_info = self.get_image_info(volume_path) new_disk_format = self.get_disk_format(image_info) print("**Uploaded image format: %s" % image_info["format"]) print("**Disk content type: %s" % image_info["content_type"]) print("**Disk format: %s" % new_disk_format) print("**Transfer format: %s" % image_info["transfer_format"]) # This example will connect to the server and create a new `floating` # disk, one that isn't attached to any virtual machine. # Then using transfer service it will transfer disk data from local # qcow2 disk to the newly created disk in server. print("**Creating disk...") image_size = os.path.getsize(volume_path) disks_service = self.system_service.disks_service() disk = disks_service.add( disk=types.Disk( name=os.path.basename(volume_path[:-6]), content_type=image_info["content_type"], description='Uploaded disk', format=new_disk_format, initial_size=image_size, provisioned_size=image_info["virtual-size"], sparse=new_disk_format == types.DiskFormat.COW, storage_domains=[ types.StorageDomain( name=self.args.sd_name ) ] ) ) # Wait till the disk is up, as the transfer can't start if the # disk is locked: disk_service = disks_service.disk_service(disk.id) while True: time.sleep(5) disk = disk_service.get() if disk.status == types.DiskStatus.OK: break print("**Creating transfer session...") # Get a reference to the service that manages the image # transfer that was added in the previous step: transfers_service = self.system_service .image_transfers_service() # Add a new image transfer: transfer = transfers_service.add( types.ImageTransfer( image=types.Image( id=disk.id ), # 'format' can be used only for ovirt-engine 4.3 or above format=image_info["transfer_format"], ) ) # Get reference to the created transfer service: transfer_service = transfers_service.image_transfer_service(transfer.id) # After adding a new transfer for the disk, the transfer's status will be INITIALIZING. # Wait until the init phase is over. The actual transfer can start when its status is "Transferring". while transfer.phase == types.ImageTransferPhase.INITIALIZING: time.sleep(1) transfer = transfer_service.get() print("**Uploading image...") # At this stage, the SDK granted the permission to start transferring the disk, and the # user should choose its preferred tool for doing it - regardless of the SDK. # In this example, we will use Python's httplib.HTTPSConnection for transferring the data. if args.direct: if transfer.transfer_url is not None: destination_url = transfer.transfer_url else: print("**Direct upload to host not supported (requires ovirt-engine 4.2 or above).") sys.exit(1) else: destination_url = transfer.proxy_url with ui.ProgressBar(image_size) as pb: client.upload( volume_path, destination_url, self.args.cafile, secure=self.args.secure, progress=pb.update) print("**Finalizing transfer session...") # Successful cleanup transfer_service.finalize() print("**Upload %s completed successfully" % volume_path) def attach_disk(self, disk_attachments_service, disk_name, vm_name, bootable=True): disks_service = self.system_service.disks_service() while True: time.sleep(5) my_disk = disks_service.list(search='name=%s' % disk_name)[0] if my_disk.status == types.DiskStatus.OK: print ("**DiskStatus is ok") break disk_attachment = disk_attachments_service.add( types.DiskAttachment( disk=my_disk, interface=types.DiskInterface.VIRTIO, bootable=bootable, active=True, ), ) # Wait until the disk status is OK: disk_service = disks_service.disk_service(disk_attachment.disk.id) while True: time.sleep(5) disk = disk_service.get() if disk.status == types.DiskStatus.OK: print("**Disk '%s' added to '%s'." % (disk.name, vm_name)) break def attach_nics(self, vm_name): vms_service = self.system_service.vms_service() vm = vms_service.list(search='name=%s' % vm_name)[0] cluster = self.system_service.clusters_service().cluster_service(vm.cluster.id).get() dcs_service = self.system_service.data_centers_service() dc = dcs_service.list(search='Clusters.name=%s' % cluster.name)[0] networks_service = dcs_service.service(dc.id).networks_service() network = next( (n for n in networks_service.list() if n.name == 'Ext-Net'), None ) profiles_service = self.system_service.vnic_profiles_service() profile_id = None nic_name = random.choice(NIC_LIST) for profile in profiles_service.list(): if profile.name == nic_name: print ("**add nic : %s" % profile.name) profile_id = profile.id break # Locate the service that manages the network interface cards of the # virtual machine: nics_service = vms_service.vm_service(vm.id).nics_service() # Use the "add" method of the network interface cards service to add the # new network interface card: nics_service.add( types.Nic( name='mynic', description='My network interface card', vnic_profile=types.VnicProfile( id=profile_id, ), ), ) print("**Nic added successfully") def assign_permission(self, permissions_service, user, group): if user: print("**assign user permission.") permissions_service.add( types.Permission( user=types.User( id=user.id, ), role=types.Role( name=USER_ROLENAME, ), ), ) else: print ("**user is none, pass the user assign permission") if group: print ("**assign group permission.") permissions_service.add( types.Permission( group=types.Group( id=group.id, ), role=types.Role( name=GROUP_ROLENAME, ), ), ) else: print ("**group is none, pass the user assign permission") def create_vm(self): print ("--Step02:begin create vm") vms_service = self.system_service.vms_service() users_service = connection.system_service().users_service() groups_service = connection.system_service().groups_service() try: user = users_service.list(search='usrname=%s' % op.user_name)[0] except: user = None try: group = groups_service.list(search='name=%s' % op.group_name)[0] except: group = None vm = vms_service.add( types.Vm( name=op.vm_name, description='migrate from openstack', comment=group.name if group else None, cluster=types.Cluster( name='Default', ), cpu=types.Cpu( topology=types.CpuTopology( cores=1, sockets=int(self.vm_info.get("instance_vcpu")), threads=1 ) ), template=types.Template( name='Blank', ), high_availability=types.HighAvailability( enabled=True, priority=1 ), memory=int(self.vm_info.get("instance_memory"))*1024, ), ) # Find the service that manages the virtual machine: vm_service = vms_service.vm_service(vm.id) # Wait till the virtual machine is down, which means that it is # completely created: while True: time.sleep(5) vm = vm_service.get() if vm.status == types.VmStatus.DOWN: print("**The vm %s is created successfully." % self.vm_info.get("vm_name")) break print ("--Step03:begin to attach disk.") disk_attachments_service = vm_service.disk_attachments_service() for volume_path in self.volumes_list: print ("**begin to attach disk: %s" % volume_path) self.attach_disk(disk_attachments_service, str(volume_path[:-6]), vm.name, bootable=("system" in volume_path)) print ("--Step04:begin to attach nic.") self.attach_nics(vm.name) print ("--Step05:assign permission to vms.") permissions_service = vm_service.permissions_service() self.assign_permission(permissions_service, user, group)
5、执行结果
- 标签:
-
其他
您可能感兴趣的新闻 换一批
热门文章
现在下载,可享30天免费试用