libvirt-host

import libvirt
import random
from libvirt_domain import Domain
from xml.dom import minidom


# KVM连接类:管理连接
class Connection:
    def __init__(self, ip):
        self.ip = ip
        try:
            # self.conn = libvirt.open("qemu:///system")
            # self.conn = libvirt.open("qemu+ssh://root@{}/system".format(self.ip))
            self.conn = libvirt.open("qemu+tcp://root@{}/system".format(self.ip))
            print("连接成功!")

        except libvirt.libvirtError:
            print("连接失败!")

    def __del__(self):
        try:
            self.conn.close()
            print("断开连接!")
        except libvirt.libvirtError:
            print("断开失败!")

    # 打印主机信息
    def getHostInfo(self):
        res = ""

        res += "------节点:{}----------\n".format(self.conn.getHostname())
        nodeinfo = self.conn.getInfo()                      # 获取虚拟化主机信息
        res += '模型: ' + str(nodeinfo[0])                  # cpu模型
        res += '\n内存大小: ' + str(nodeinfo[1]) + 'MB'     # 内存
        res += '\nCPU数量: ' + str(nodeinfo[2])             # cpu数量
        res += '\n虚拟类型: ' + self.conn.getType()         # 虚拟化类型
        uri = self.conn.getURI()                            # 目前链接的uri
        res += '\n连接URI: : ' + uri
        mem = self.conn.getFreeMemory()
        res += "\n空闲内存: " + str(mem // pow(2, 20)) + " MB"
        res += "\n-------------------------"

        return res

    # 创建 虚拟机,但不启动它
    def define(self, nodeName, vcpu='1', memery='1048576'):
        if nodeName in self.get_All_domains_name():
            return "虚拟机:{} 已存在,无法创建!".format(nodeName)
        try:
            f = open('/etc/libvirt/qemu/{}.xml'.format(nodeName))  # xml文件需要事先准备好
        except FileNotFoundError:
            # self.creatXML_by_copy(nodeName, vcpu, memery)
            self.get_xml(nodeName)
            # f = open('/etc/libvirt/qemu/{}.xml'.format(nodeName))
            f = open('generic.xml')

        xml = f.read()
        try:
            self.conn.defineXML(xml)
            f.close()
            return "{}创建成功".format(nodeName)
        except libvirt.libvirtError as err:
            f.close()
            print("{}创建失败".format(nodeName))
            return str(err)

    # 启动 虚拟机
    def creat(self, nodeName):
        try:
            dom = self.conn.lookupByName(nodeName)
            dom.create()
            return "{}启动成功".format(nodeName)
        except libvirt.libvirtError as err:
            return err

    # 关闭 正在运行的虚拟机
    def shutdown(self, nodeName):
        try:
            dom = self.conn.lookupByName(nodeName)
            dom.destroy()
            return "{} 关闭成功".format(nodeName)
        except libvirt.libvirtError as err:
            return err

    # 挂起 虚拟机
    def suspend(self, nodeName):
        try:
            dom = self.conn.lookupByName(nodeName)
            dom.suspend()
            return "{} 挂起成功".format(nodeName)
        except libvirt.libvirtError as err:
            return err

    # 恢复 被挂起的虚拟机
    def resume(self, nodeName):
        try:
            dom = self.conn.lookupByName(nodeName)
            dom.resume()
            return "{} 运行成功".format(nodeName)
        except libvirt.libvirtError as ret:
            return ret

    # 删除 虚拟机,xml也会被删除
    def undefine(self, nodeName):
        if nodeName == 'node0':
            print("node0 是0号虚拟机,不可删除!")
            return "node0 是0号虚拟机,不可删除!"
        try:
            dom = self.conn.lookupByName(nodeName)
            dom.undefine()
            print("{} 已取消定义".format(nodeName))
            return "{} 已取消定义".format(nodeName)
        except libvirt.libvirtError as err:
            return err

    # 查看所有虚拟机状态
    def domains_Statue(self):

        print("--------运行中--------")
        for _id in self.conn.listDomainsID():
            print(self.conn.lookupByID(_id).name(), end='\t')
        if len(self.conn.listDomainsID()) == 0:
            print("None", end=' ')

        print("\n--------未运行--------")
        for i in self.conn.listDefinedDomains():
            print(i, end='\t')
        if len(self.conn.listDefinedDomains()) == 0:
            print("None", end=' ')

        print("\n----------------")

    # 输入 name 创建 xml memory的单位是kb
    def creatXML_by_copy(self, nodeName, vcpu, memory):
        # 获取 源xml 文档
        # xml = minidom.parse('/etc/libvirt/qemu/node0.xml')
        xml = minidom.parse()
        collection = xml.documentElement
        # 修改 name
        name = collection.getElementsByTagName('name')[0]
        name.childNodes[0].data = nodeName
        # 修改 uuid
        uuid = collection.getElementsByTagName('uuid')[0]

        # 防止 uuid 冲突, 随机生成一个不存在的 uuid
        uid = random.randint(10, 99)
        while uid:
            if uid not in self.get_All_domains_uuid():
                uuid.childNodes[0].data = uuid.childNodes[0].data[:-2] + str(uid)
                break
            uid = random.randint(10, 99)
        # 修改 memory
        mem = collection.getElementsByTagName('memory')[0]
        mem.childNodes[0].data = memory

        # 修改 cpu 数量
        vc = collection.getElementsByTagName("vcpu")[0]
        vc.childNodes[0].data = vcpu

        # 创建新的 xml
        with open('/etc/libvirt/qemu/{}.xml'.format(nodeName), 'w') as file:
            xml.writexml(file, encoding='utf-8', addindent= ' ')
            file.close()

        return True

    def get_All_domains_name(self):
        ret = []
        for dom in self.conn.listAllDomains():
            ret .append(dom.name())
        return ret

    # 获取所以虚拟机的名字 和状态
    def get_All_domains_Names_status(self):
        res = []
        for _id in self.conn.listDomainsID():
            res.append(self.conn.lookupByID(_id).name())
        for _i in self.conn.listDefinedDomains():
            res.append(_i)

        # 再根据名字查看状态
        status = []
        for _name in res:
            node = Domain(self.conn.lookupByName(_name))
            status.append(node.state())

        return res, status

    # 获取所有虚拟机 uuid
    def get_All_domains_uuid(self):
        res = []
        for dom in self.conn.listAllDomains():
            node = Domain(dom)
            res.append(int(node.getUUid()[-2:]))
        return res

    def get_xml(self, nodeName,  vcpu='1', memory='1048576'):
        import paramiko
        # ssh_cli = paramiko.SSHClient()  # 创建SSHClient实例
        # ssh_cli.load_system_host_keys()  # 加载系统默认ssh_keys
        # ssh_cli.connect(hostname='172.20.10.6', username='root', password='root')  # 建立ssh连接
        # stdin, stdout, stderr = ssh_cli.exec_command('cat /etc/libvirt/qemu/generic.xml')  # 在远程服务器上执行命令
        # # print(stdout.read().decode('utf-8'))  # 输出命令返回结果
        # ssh_cli.close()  # 关闭连接

        server = ('172.20.10.6', 22)  # 服务器地址及端口
        t = paramiko.Transport(server)  # 实例化连接对象
        t.connect(username='root', password='root')  # 建立连接
        sftp = paramiko.SFTPClient.from_transport(t)  # 使用链接建立sftp对象
        print(sftp.listdir('/etc/libvirt/qemu'))  # 列出目录所有文件
        # 下载
        remote_file = '/etc/libvirt/qemu/generic.xml'  # 服务器上的文件
        local_file = 'generic.xml'  # 要保存的本地文件
        sftp.get(remote_file, local_file)  # 下载文件

        # 解析
        xml = minidom.parse('generic.xml')
        collection = xml.documentElement
        # 修改 name
        name = collection.getElementsByTagName('name')[0]
        name.childNodes[0].data = nodeName
        # 修改 uuid
        uuid = collection.getElementsByTagName('uuid')[0]

        # 防止 uuid 冲突, 随机生成一个不存在的 uuid
        # uid = random.randint(10, 99)
        # while uid:
        #     if uid not in self.get_All_domains_uuid():
        #         uuid.childNodes[0].data = uuid.childNodes[0].data[:-2] + str(uid)
        #         break
        #     uid = random.randint(10, 99)
        uuid.childNodes[0].data = "586dcfc1-dce0-46b4-bd62-52c974dad7ff"
        # 修改 memory
        mem = collection.getElementsByTagName('memory')[0]
        mem.childNodes[0].data = memory

        # 修改 cpu 数量
        vc = collection.getElementsByTagName("vcpu")[0]
        vc.childNodes[0].data = vcpu

        # 创建新的 xml
        with open('generic.xml'.format(nodeName), 'w') as file:
            xml.writexml(file, encoding='utf-8', addindent=' ')
            file.close()

        # 上传
        # sftp.mkdir('/root/put2') # 创建目录
        local_file = 'generic.xml'  # 本地文件
        remote_file = '/etc/libvirt/qemu/{}.xml'.format(nodeName)  # 要保存到服务器上的文件
        sftp.put(local_file, remote_file)  # 上传
        t.close()  # 关闭连接
        print("上传成功!")


if __name__ == "__main__":
    conn = Connection("172.20.10.6")
    conn.domains_Statue()
    conn.undefine('node5')
    # conn.define('node2')
    # conn.define('nhf', '123456', '2')
    # conn.creat('nhf')
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艺千秋录

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值