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')
libvirt-host
最新推荐文章于 2024-07-22 14:16:57 发布