zoukankan      html  css  js  c++  java
  • Python脚本实现KVM虚机添加磁盘

    Python脚本实现KVM虚机添加磁盘

    实现方式:①远程Linux下载到本地  ②本地修改  ③上传到Linux远程并覆盖原文件

    import os
    import paramiko
    from TSDRM import settings
    from lxml import etree
    from xml.dom.minidom import parse
    
    ip = '192.168.1.61'
    username = 'root'
    password = '******'
    system_tag = 'Linux'
    kvm_name = 'Test-1'
    disk_file = '/home/images/disk-image/10GB.qcow2'
    
    try:
        linux_file_path = '/etc/libvirt/qemu/{0}.xml'.format(kvm_name)
        file_path = os.path.join(
            os.path.join(
                os.path.join(settings.BASE_DIR, "drm"),
                "upload"
            ),
            "kvmxml"
        )
        local_file_path = file_path + os.sep + "{0}.xml".format(kvm_name)
        ssh = paramiko.Transport((ip, 22))
        ssh.connect(username=username, password=password)
        sftp = paramiko.SFTPClient.from_transport(ssh)
    except paramiko.ssh_exception.SSHException as e:
        kvmlog = "连接服务器失败:{0}。".format(e)
    else:
        # ①开始下载
        sftp.get(linux_file_path, local_file_path)
        except Exception as e:
          kvmlog = "下载linux脚本文件失败:{0}。".format(e)
        else:
            # ②修改本地xml文件:xml文件内容转成dom
            domtree = parse(local_file_path)
            rootnode = domtree.documentElement
    
            # 找到磁盘父节点
            devices_node = rootnode.getElementsByTagName("devices")[0]
    
            # 新建disk节点
            """
            <disk type='file' device='disk'>
                <driver name='qemu' type='qcow2'/>
                <source file='/home/images/disk-image/10GB.qcow2'/>
                <target dev='vdb' bus='virtio'/>
                <boot order='2'/>
                <address type='pci'/>
            </disk>
            """
            config = etree.XML(rootnode.toxml())
            kvm_devices = config.xpath("//devices//disk")
            disk_list = []
            for disk in kvm_devices:
                file = disk.xpath('source')
                if file:
                    file = disk.xpath('source')[0].attrib['file']
                    device = disk.xpath('target')[0].attrib['dev']
                    order = disk.xpath('boot')[0].attrib['order']
                    disk_list.append({
                        'name': device,
                        'file': file,
                        'order': order
                    })
            """
            disk_list:
            [{'order': '1', 'name': 'vda', 'file': '/data/vmdata/Test-4/Test-4.qcow2'},
            {'order': '2', 'name': 'vdb', 'file': '/home/images/disk-image/10GB.qcow2'},
            {'order': '3', 'name': 'vdc', 'file': '/opt/1GB.qcow2'}]
    
            """
            count = len(disk_list)
            disk_order = count + 1
            disk_dev = ''
            disk_dev_dict = {
                0: 'vda', 1: 'vdb', 2: 'vdc', 3: 'vdd', 4: 'vde', 5: 'vdf', 6: 'vdg',
                7: 'vdh', 8: 'vdi', 9: 'vdj', 10: 'vdk', 11: 'vdl', 12: 'vdm', 13: 'vdn'
            }
            # 动态加载order字段属性和dev字段属性,使之与存在的磁盘数据不同
            for i in disk_list:
                if disk_order == i['order']:
                    disk_order += 1
                if disk_dev_dict[count] == i['name']:
                    disk_dev = disk_dev_dict[count + 1]
                else:
                    disk_dev = disk_dev_dict[count]
    
            disk_node = domtree.createElement("disk")
            disk_node.setAttribute("type", "file")
            disk_node.setAttribute("device", "disk")
    
            # 新建driver节点
            driver_node = domtree.createElement("driver")
            driver_node.setAttribute("name", "qemu")
            driver_node.setAttribute("type", "qcow2")
    
            # 新建source节点
            source_node = domtree.createElement("source")
            source_node.setAttribute("file", disk_file)
    
            # 新建target节点
            target_node = domtree.createElement("target")
            target_node.setAttribute("dev", disk_dev)
            target_node.setAttribute("bus", "virtio")
    
            # 新建boot节点
            boot_node = domtree.createElement("boot")
            boot_node.setAttribute("order", str(disk_order))
    
            # 新建address节点
            address_node = domtree.createElement("address")
            address_node.setAttribute("type", "pci")
    
            # 磁盘节点添加子节点
            disk_node.appendChild(driver_node)
            disk_node.appendChild(source_node)
            disk_node.appendChild(target_node)
            disk_node.appendChild(boot_node)
            disk_node.appendChild(address_node)
    
            # 父节点添加子节点:磁盘节点
            devices_node.appendChild(disk_node)
    
            # 重新覆盖写入本地文件
            try:
                with open(local_file_path, 'w') as f:
                    domtree.writexml(f, addindent=' ', encoding='utf-8')
            except Exception as e:
                kvmlog = "修改文件失败:{0}。".format(e)
            else:
                # ③上传到服务器
                try:
                    ssh = paramiko.Transport((ip, 22))
                    ssh.connect(username=username, password=password)
                    sftp = paramiko.SFTPClient.from_transport(ssh)
                except paramiko.ssh_exception.SSHException as e:
                    kvmlog = "连接服务器失败:{0}。".format(e)
                else:
                    try:
                        # 开始上传
                        sftp.put(local_file_path, linux_file_path)
                    except Exception as e:
                        kvmlog = "上传linux脚本文件失败:{0}。".format(e)
                    else:
                        log = '上传成功'

    查看:

  • 相关阅读:
    Android 从上层到底层-----kernel层
    同时支持来自多个源头的域名的跨域调用
    Redis
    很好用的工具网站
    PHP array_combine()
    php 统计某个目录中所有文件的大小
    strchr()
    PHP $_SERVER
    Laravel5使用QQ邮箱发送邮件配置
    laravel 5.6
  • 原文地址:https://www.cnblogs.com/zhangguosheng1121/p/14861127.html
Copyright © 2011-2022 走看看