如何使用Python脚本高效管理KVM虚拟机?
- 内容介绍
- 文章标签
- 相关推荐
本文共计5873个文字,预计阅读时间需要24分钟。
Python脚本:连接Linux系统,使用paramiko和pywinrm实现Windows/Linux脚本调用。处理Linux下脚本语法错误或命令不存在等错误,通过stderr变量接收,只能添加判断条件;Windows下可接收错误信息并输出判断。
python脚本:连接Linux
"""paramiko,pywinrm实现windows/linux脚本调用
linux下脚本语法错误,或者命令不存在等没有通过stderr变量接收到,只能添加判断条件;
windows下可以接收到错误信息并作出判断;
"""
importparamiko
importwinrm
importsocket
importrequests
importdatetime
fromwinrm.exceptionsimportWinRMTransportError,WinRMOperationTimeoutError,WinRMError
fromrequests.exceptionsimportConnectionError
###############################################################
#为实现WINDOWS下执行脚本时长超时设置,对wimrm中相关类进行重写。#
###############################################################
#重写Protocol类
classProtocol(winrm.protocol.Protocol):
defget_command_output(self,shell_id,command_id):
"""
GettheOutputofthegivenshellandcommand
@paramstringshell_id:Theshellidontheremotemachine.
See#open_shell
@paramstringcommand_id:Thecommandidontheremotemachine.
See#run_command
#@return[Hash]ReturnsaHashwithakey:exitcodeand:data.
DataisanArrayofHasheswherethecoorespondingkey
#iseither:stdoutor:stderr.ThereasonitisinanArraysoso
wecangettheoutputintheorderitocurrson
#theconsole.
"""
stdout_buffer,stderr_buffer=[],[]
command_done=False
############################################################################
#限时6*60s#
#程序反复查看相应,如果相应成功,且在超时时限内则命令成功,否则报超时异常。#
#获取响应的时长较长。#
############################################################################
return_code=-1
limited_seconds=6*60
start_time=datetime.datetime.now()
whilenotcommand_done:
print('gettheresponsefromwindows...')
try:
stdout,stderr,return_code,command_done=\
self._raw_get_command_output(shell_id,command_id)
stdout_buffer.append(stdout)
stderr_buffer.append(stderr)
exceptWinRMOperationTimeoutErrorase:
#thisisanexpectederrorwhenwaitingforalong-runningprocess,justsilentlyretry
pass
end_time=datetime.datetime.now()
delta_time=end_time-start_time
total_seconds=delta_time.total_seconds()
iftotal_seconds>limited_seconds:
raiseWinRMOperationTimeoutError()
returnb''.join(stdout_buffer),b''.join(stderr_buffer),return_code
#重写Session类
classSession(winrm.Session):
#TODOimplementcontextmanagermethods
def__init__(self,target,auth,**kwargs):
username,password=auth
self.url=self._build_url(target,kwargs.get('transport','plaintext'))
self.protocol=Protocol(self.url,
username=username,password=password,**kwargs)
classServerByPara(object):
def__init__(self,cmd,host,user,password,system_choice):
self.cmd=cmd
self.client=paramiko.SSHClient()
self.host=host
self.user=user
self.pwd=password
self.system_choice=system_choice
defexec_linux_cmd(self,succeedtext,linux_timeout,port=22):
data_init=''
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
self.client.connect(hostname=self.host,username=self.user,password=self.pwd,timeout=5,port=port)
except(socket.timeout,paramiko.ssh_exception.SSHException)ase:
print("连接服务器失败")
return{
"exec_tag":1,
"data":"连接服务器失败{0}".format(e),
"log":"连接服务器失败",
}
try:
stdin,stdout,stderr=self.client.exec_command(self.cmd,get_pty=True,timeout=linux_timeout)
ifstderr.read():
exec_tag=1
data_init=str(stderr.read(),encoding='utf-8')
#fordatainstderr.readlines():
#data_init+=data
log=""
else:
exec_tag=0
log=""
try:
data_init=str(stdout.read(),encoding='utf-8')
ifdata_init:
data_init="".join(data_init.split("\r\n"))
if"commandnotfound"indata_init:#命令不存在
exec_tag=1
log="命令不存在"
elif"syntaxerror"indata_init:#语法错误
exec_tag=1
log="语法错误"
elif"Nosuchfileordirectory"indata_init:#脚本不存在
exec_tag=1
log="脚本不存在"
elifsucceedtextisnotNone:
ifsucceedtextnotindata_init:
exec_tag=1
log="未匹配"
exceptExceptionase:
print(e)
exec_tag=0#不抛错
log="编码错误"
data_init="编码错误"
exceptsocket.timeoutase:
print("脚本执行超时")
return{
"exec_tag":1,
"data":"脚本执行超时",
"log":"脚本执行超时",
}
return{
"exec_tag":exec_tag,
"data":data_init,
"log":log,
}
defexec_win_cmd(self,succeedtext):
data_init=""
log=""
try:
s=Session(self.host,auth=(self.user,self.pwd))
ret=s.run_cmd(self.cmd)
except(ConnectionError,WinRMOperationTimeoutError,WinRMTransportError,WinRMError)ase:
iftype(e)==WinRMOperationTimeoutError:
print("脚本执行超时")
exec_tag=1
data="脚本执行超时{0}".format(e)
log="脚本执行超时"
eliftype(e)in[ConnectionError,WinRMTransportError]:
print("连接windows失败")
exec_tag=1
data="连接windows失败{0}".format(e)
log="连接windows失败"
else:
print("执行windows脚本发生异常错误")
exec_tag=1
data="执行windows脚本发生异常错误{0}".format(e)
log="执行windows脚本发生异常错误"
return{
"exec_tag":exec_tag,
"data":data,
"log":log,
}
else:
ifret.std_err:
data_init=str(ret.std_err,encoding='gbk')
exec_tag=1
#fordatainret.std_err.decode().split("\r\n"):
#data_init+=data
log=""
else:
exec_tag=0
try:
data_init=str(ret.std_out,encoding='gbk')
ifdata_init:
data_init="".join(data_init.split("\r\n"))
#fordatainret.std_out.decode().split("\r\n"):
#data_init+=data
exceptExceptionase:
print(e)
exec_tag=0#不抛错
log="编码错误"
data_init="编码错误"
else:
ifsucceedtextisnotNone:
ifsucceedtextnotindata_init:
exec_tag=1
log="未匹配"
return{
"exec_tag":exec_tag,
"data":data_init,
"log":log,
}
defrun(self,succeedtext,linux_timeout=6*60):
ifself.system_choice=="Linux":
result=self.exec_linux_cmd(succeedtext,linux_timeout)
ifself.client:
self.client.close()
elifself.system_choice=="AIX":
result=self.exec_linux_cmd(succeedtext,linux_timeout,port=22)
ifself.client:
self.client.close()
else:
result=self.exec_win_cmd(succeedtext)
#print(result)
returnresult
if__name__=='__main__':
#server_obj=ServerByPara(sys.argv[1],sys.argv[2],sys.argv[3],sys.argv[4])
#server_obj=ServerByPara(r"C:\Users\Administrator\Desktop\test_python.bat","192.168.100.151","administrator","tesunet@2017","Windows")
server_obj=ServerByPara(r"echo中文>C:\Users\Administrator\Desktop\test.bat",
"192.168.100.154","administrator","tesunet@2017","Windows")
#linux_temp_script_file=r"/tmp/drm/954/tmp_script_6486.sh&&/tmp/drm/954/tmp_script_6486.sh"
#cmd=r"sed-i's/\r$//'{0}&&{0}".format(linux_temp_script_file)
#print(cmd)#sed-i's/\r$//'/tmp/drm/954/tmp_script_6486.sh&&/tmp/drm/954/tmp_script_6486.sh
#server_obj=ServerByPara("mkdir-p/tmp/drm/957",
#"10.64.7.43","root","qtdl2003","Linux")
#server_obj=ServerByPara("echo中文",
#"192.168.184.66","root","password","Linux")
#server_obj=ServerByPara(r"echo'你好你好你好你好你好你好你好';echo'你好你好你好你好你好你好你好';echo'你好你好你好你好你好你好你好'","192.168.184.66","root","password","Linux")
server_obj.run("")
print(11111111111111)
python脚本:操作kvm虚拟机,进行kvm虚拟机开机、关机、克隆、快照等。
fromdrmimportremotefromlxmlimportetree
importtime
importjson
classKVMApi():
def__init__(self,credit):
self.ip=credit['KvmHost']
self.username=credit['KvmUser']
self.password=credit['KvmPasswd']
self.system_tag=credit['SystemType']
defremote_linux(self,exe_cmd):
rm_obj=remote.ServerByPara(exe_cmd,self.ip,self.username,self.password,self.system_tag)
result=rm_obj.run(succeedtext='',linux_timeout=12*60)
returnresult
deflist_of_groups(self,list_info,per_list_len):
"""
list_info:列表元素
per_list_len:每个小列表的长度
"""
list_of_group=zip(*(iter(list_info),)*per_list_len)
end_list=[list(i)foriinlist_of_group]
count=len(list_info)%per_list_len
end_list.append(list_info[-count:])ifcount!=0elseend_list
returnend_list
defdomstate(self,kvm_name):
#获取虚拟机的状态
exe_cmd=r'virshdomstate{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
result=result['data'].strip()
returnresult
defkvm_all_list(self):
#获取所有kvm虚拟机
exe_cmd=r'virshlist--all'
result=self.remote_linux(exe_cmd)
kvm_list=[xforxinresult['data'].split('')ifx]
delkvm_list[0:4]
kvm_list_filter=[]
foriinkvm_list:
ifi=='shut':
continue
ifi=='off':
i='关闭'
ifi=='running':
i='运行中'
ifi=='paused':
i='暂停'
kvm_list_filter.append(i)
end_list=self.list_of_groups(kvm_list_filter,3)
kvm_all_list_dict=[]
foriteminend_list:
data={}
data['id']=item[0]
data['name']=item[1]
data['state']=item[2]
kvm_all_list_dict.append(data)
returnkvm_all_list_dict
defkvm_exclude_copy_list(self):
#获取除实例之外所有kvm虚拟机
exe_cmd=r'virshlist--all'
result=self.remote_linux(exe_cmd)
kvm_list=[xforxinresult['data'].split('')ifx]
delkvm_list[0:4]
kvm_list_filter=[]
foriinkvm_list:
ifi=='shut':
continue
ifi=='off':
i='关闭'
ifi=='running':
i='运行中'
ifi=='paused':
i='暂停'
kvm_list_filter.append(i)
end_list=self.list_of_groups(kvm_list_filter,3)
kvm_all_list_dict=[]
foriteminend_list:
data={}
if'@'notinitem[1]:
data['id']=item[0]
data['name']=item[1]
data['state']=item[2]
kvm_all_list_dict.append(data)
returnkvm_all_list_dict
defkvm_include_copy_list(self,kvm_copy_name):
#获取所有实例虚拟机
exe_cmd=r'virshlist--all'
result=self.remote_linux(exe_cmd)
kvm_list=[xforxinresult['data'].split('')ifx]
delkvm_list[0:4]
kvm_list_filter=[]
foriinkvm_list:
ifi=='shut':
continue
ifi=='off':
i='关闭'
ifi=='running':
i='运行中'
ifi=='paused':
i='暂停'
kvm_list_filter.append(i)
end_list=self.list_of_groups(kvm_list_filter,3)
kvm_all_list_dict=[]
foriteminend_list:
data={}
copyname=kvm_copy_name+'@'
ifcopynameinitem[1]:
data['id']=item[0]
data['name']=item[1]
data['state']=item[2]
kvm_all_list_dict.append(data)
returnkvm_all_list_dict
defkvm_run_list(self):
#获取正在运行的虚拟机
exe_cmd=r'virshlist'
result=self.remote_linux(exe_cmd)
kvm_list=[xforxinresult['data'].split('')ifx]
delkvm_list[0:3]
end_list=self.list_of_groups(kvm_list,3)
kvm_all_list_dict=[]
foriteminend_list:
data={}
data['id']=item[0]
data['name']=item[1]
data['state']=item[2]
kvm_all_list_dict.append(data)
returnkvm_all_list_dict
defkvm_start(self,kvm_state,kvm_name):
#开启虚拟机:是关闭的状态(shutoff/关闭)
ifkvm_state=='shutoff'orkvm_state=='关闭':
exe_cmd=r'virshstart{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
ifresult['data'].strip()=='Domain{0}started'.format(kvm_name)or\
result['data'].strip()=='域{0}已开始'.format(kvm_name):
result='开机成功。'
else:
result='开机失败。'
else:
result='虚拟机已开启。'
returnresult
defkvm_shutdown(self,kvm_state,kvm_name):
#关闭虚拟机:是开启的状态(running)
ifkvm_state=='running'orkvm_state=='运行中':
exe_cmd=r'virshshutdown{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
ifresult['data'].strip()=='Domain{0}isbeingshutdown'.format(kvm_name)or\
result['data'].strip()=='域{0}被关闭'.format(kvm_name):
time.sleep(5)
state=self.domstate(kvm_name)
ifstate=='shutoff'orstate=='关闭':
result='关闭成功。'
else:
result='关闭失败。'
else:
result='关闭失败。'
elifkvm_state=='暂停'orkvm_state=='paused':
result='虚拟机未运行。'
else:
result='虚拟机未开启。'
returnresult
defkvm_destroy(self,kvm_state,kvm_name):
#断电虚拟机:是开启的状态(running)或者是暂停状态(pasued)
ifkvm_state=='running'orkvm_state=='运行中'orkvm_state=='paused'orkvm_state=='暂停':
exe_cmd=r'virshdestroy{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
ifresult['data'].strip()=='Domain{0}destroyed'.format(kvm_name)or\
result['data'].strip()=='域{0}被删除'.format(kvm_name):
result='断电成功。'
else:
result='断电失败。'
else:
result='虚拟机未开启。'
returnresult
deffilesystem_del(self,filesystem):
try:
exe_cmd=r'zfsdestroy{0}'.format(filesystem)
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
result='删除文件系统成功。'
else:
result='删除文件系统成功。'
exceptExceptionase:
print(e)
result='删除文件系统失败。'
returnresult
defundefine(self,kvm_name,state):
"""
删除虚拟机
停止主机:virshshutdownlinux65
删除主机定义:virshundefinelinux65
删除KVM虚拟机文件系统:zfsdestroytank/CentOS-7@test3
"""
#这里需要先判断虚拟机的状态
#如果是关闭(shutoff)的虚拟机直接删除,然后删除磁盘文件,如果是开启(running)的虚拟机,先关闭再删除虚拟机,在删除磁盘文件
#如果虚拟机中创建了快照,虚拟机是无法删除的,需要删除所有的快照,然后在执行删除虚拟机操作
ifstate=='shutoff'orstate=='关闭':
snapshot_list=self.snapshot_list(kvm_name)
ifnotsnapshot_list:
try:
exe_cmd=r'virshundefine{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
ifresult['data'].strip()=='Domain{0}hasbeenundefined'.format(kvm_name)or\
result['data'].strip()=='域{0}已经被取消定义'.format(kvm_name):
result='取消定义成功。'
else:
result='取消定义失败。'
exceptExceptionase:
print(e)
result='取消定义失败。'
else:
result='虚拟机已创建快照,无法删除。'
else:
result='虚拟机未关闭。'
returnresult
defkvm_suspend(self,kvm_state,kvm_name):
"""
暂停虚机:开启(ruuning)/暂停(paused)的状态,关闭状态提醒错误。
"""
ifkvm_state=='running'orkvm_state=='运行中'orkvm_state=='paused'orkvm_state=='暂停':
exe_cmd=r'virshsuspend{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
ifresult['data'].strip()=='Domain{0}suspended'.format(kvm_name)or\
result['data'].strip()=='域{0}被挂起'.format(kvm_name):
result='暂停成功。'
else:
result='暂停失败。'
else:
result='虚拟机未开启。'
returnresult
defkvm_resume(self,kvm_state,kvm_name):
"""
恢复暂停的虚机:必须是暂停(paused)状态的虚拟机才可以执行恢复操作
"""
ifkvm_state=='paused'orkvm_state=='暂停':
exe_cmd=r'virshresume{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
ifresult['data'].strip()=='Domain{0}resumed'.format(kvm_name)or\
result['data'].strip()=='域{0}被重新恢复'.format(kvm_name):
result='运行成功。'
else:
result='运行失败。'
else:
result='虚拟机非暂停状态,无法执行此操作。'
returnresult
defkvm_reboot(self,kvm_state,kvm_name):
"""
重启虚机:必须是开启(running)/暂停(paused)状态的虚拟机才可以执行重启操作
"""
ifkvm_state=='running'orkvm_state=='运行中'orkvm_state=='暂停'orkvm_state=='paused':
exe_cmd=r'virshreboot{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
ifresult['data'].strip()=='Domain{0}isbeingrebooted'.format(kvm_name)or\
result['data'].strip()=='域{0}正在被重新启动'.format(kvm_name):
result='重启成功。'
else:
result='重启失败。'
else:
result='虚拟机未开启。'
returnresult
defkvm_clone(self,kvm_state,kvm_name,kvm_name_clone,filesystem):
"""
克隆虚拟机:需要在关机或者暂停的状态下才可以进行克隆
克隆出错:ERRORDomainwithdevicestoclonemustbepausedorshutoff.
克隆成功:Allocating'Test-3.qcow2'|80GB00:02Clone'Test-3'createdsuccessfully.
virt-clone-owin2k16-nTest-1-f/var/lib/libvirt/images/Test—1.qcow2
注:-o:original后面跟要克隆的虚拟机名字
-n:name克隆后虚拟机的名字
-f:file指定镜像存放的路径:默认路径:/var/lib/libvirt/images
新的虚拟机存在报错:ERRORInvalidnamefornewguest:Guestname'Test-3'isalreadyinuse.
"""
#判断虚拟机的状态
disk_path='/'+filesystem+'/'+kvm_name_clone+'.qcow2'
ifkvm_state=='shutoff'orkvm_state=='paused'orkvm_state=='关闭'orkvm_state=='暂停':
exe_cmd=r'virt-clone-o{0}-n{1}-f{2}'.format(kvm_name,kvm_name_clone,disk_path)
result=self.remote_linux(exe_cmd)
if"Clone'{0}'createdsuccessfully.".format(kvm_name_clone)or\
"成功克隆'{0}'".format(kvm_name_clone)inresult['data']:
result='克隆成功。'
else:
result='克隆失败。'
else:
result='虚拟机未关闭。'
returnresult
defkvm_info_data(self,kvm_name):
#获取虚拟机cpu、内存、系统类型、磁盘
exe_cmd=r'cat/etc/libvirt/qemu/{0}.xml'.format(kvm_name)
result=self.remote_linux(exe_cmd)
config=etree.XML(result['data'])
kvm_cpu=config.xpath("//vcpu")[0]
kvm_memory=config.xpath("//memory")[0]
kvm_os=config.xpath("//os/type")[0]
kvm_diskpath=config.xpath("//disk/source")[0]
kvm_os=kvm_os.text
kvm_cpu=int(kvm_cpu.text)
kvm_memory=int(int(kvm_memory.text)/1024)
kvm_disk=kvm_diskpath.attrib['file']
kvm_info={
'kvm_os':kvm_os,
'kvm_disk':kvm_disk,
'kvm_cpu':kvm_cpu,
'kvm_memory':kvm_memory
}
returnkvm_info
defsnapshot_create(self,kvm_name):
#创建快照
#创建成功提示信息:Domainsnapshot1596685828created
exe_cmd=r'virshsnapshot-create{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
if'created'inresult['data']or'已生成域快照'inresult['data']:
result='虚拟机{0}创建快照成功。'.format(kvm_name)
else:
result='虚拟机{0}创建快照失败。'.format(kvm_name)
returnresult
defsnapshot_list(self,kvm_name):
#查看快照列表
exe_cmd=r'virshsnapshot-list{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
list=[xforxinresult['data'].split('')ifx]
dellist[0:4]
end_list=self.list_of_groups(list,5)
snapshot_list_dict=[]
foriteminend_list:
data={}
data['name']=item[0]
snapshot_list_dict.append(data)
"""
[{'name':'1596684491'},
{'name':'1596685828'}]
"""
returnsnapshot_list_dict
defsnapshot_del(self,kvm_name,snapshotname):
#删除快照
exe_cmd=r'virshsnapshot-delete{0}--snapshotname{1}'.format(kvm_name,snapshotname)
result=self.remote_linux(exe_cmd)
ifresult['data']=='Domainsnapshot{0}deleted'.format(snapshotname)orresult['data']=='已删除域快照':
result='快照{0}删除成功。'.format(snapshotname)
else:
result='快照{0}删除失败。'.format(snapshotname)
returnresult
defsnapshot_revert(self,kvm_name,snapshotname):
#恢复快照:虚拟机是关机的状态
state=self.domstate(kvm_name)
ifstate=='shutoff':
exe_cmd=r'virshsnapshot-revert{0}--snapshotname{1}'.format(kvm_name,snapshotname)
self.remote_linux(exe_cmd)
result='恢复到快照{0}成功。'.format(snapshotname)
else:
result='请先关闭虚拟机,再执行恢复操作。'.format(kvm_name)
returnresult
defzfs_kvm_filesystem(self):
exe_cmd=r'ls/data/vmdata'.format()
result=self.remote_linux(exe_cmd)
kvm_filesystem=[x.replace('\t','')forxinresult['data'].split('')ifx]
returnkvm_filesystem
defcreate_filesystem(self,filesystem):
"""
为每一台虚拟机分别创建一个文件系统
tank/kvm_1
tank/kvm_2
tank/kvm_3
zfs创建文件系统:zfscreatetank/kvm_1
zfs_pool_data:文件系统路径
"""
try:
exe_cmd=r'zfscreate{0}'.format(filesystem)
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
result='文件系统创建成功。'
else:
result='文件系统创建失败。'
except:
result='文件系统创建失败。'
returnresult
defzfs_create_snapshot(self,snapshot_name):
"""
创建快照:zfssnapshottank/kvm_1@2020-07-28
kvm_name:虚拟机
zfs_snapshot_name:快照名字
"""
try:
exe_cmd=r'zfssnapshot{0}'.format(snapshot_name)
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
info='创建成功。'
else:
info='创建失败。'
except:
info='创建失败。'
returninfo
defzfs_snapshot_list(self,filesystem):
"""
查看zfs快照:zfslist-tsnapshot-rtank/kvm_1
"""
exe_cmd=r'zfslist-tsnapshot-r{0}'.format(filesystem)
result=self.remote_linux(exe_cmd)
snapshot_list=[xforxinresult['data'].split('')ifx]
delsnapshot_list[0:5]
end_list=self.list_of_groups(snapshot_list,5)
zfs_snapshot_list_dict=[]
foriteminend_list:
data={}
item=item[0].split('@')
data['name']=item[1]
zfs_snapshot_list_dict.append(data)
returnzfs_snapshot_list_dict
defzfs_snapshot_del(self,snapshot_name):
"""
删除快照:zfsdestroymypool/data@2020-07-28
"""
try:
exe_cmd=r'zfsdestroy{0}'.format(snapshot_name)
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
info='删除快照成功。'
else:
info='删除快照失败。'
except:
info='快照已挂载,删除失败。'
returninfo
defzfs_clone_snapshot(self,snapshot_name,filesystem_name):
"""
克隆快照:zfsclonetank/kvm_1@2020-08-20tank/kvm_1@2020-08-20
kvm_name
kvm_snapshot_name
kvm_snapshot_clone_name
"""
try:
exe_cmd=r'zfsclone{0}{1}'.format(snapshot_name,filesystem_name)
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
info='克隆成功。'
else:
info='克隆失败。'
except:
info='克隆失败。'
returninfo
defcreate_kvm_xml(self,kvm_machine,snapshotname,copyname,copycpu,copymemory):
"""
读取文件,修改文件,追加到新文件
kvm_name='Test-1老虚拟机
kvm_name_new='kvm_1新虚拟机
kvm_disk_path='/tank/kvm_1@kvm_1/Test-1.qcow2'新虚拟机磁盘
"""
try:
exe_cmd=r'cat/etc/libvirt/qemu/{0}.xml'.format(kvm_machine)
snapshot_clone_name=snapshotname.replace('@','-')
kvm_disk_path='/'+snapshot_clone_name+'/'+kvm_machine+'.qcow2'
result=self.remote_linux(exe_cmd)
#解析xml文件找出要修改的name、uuid、disk_path、mac、cpu、memory
config=etree.XML(result['data'])
kvm_name=config.xpath("//name")[0]
kvm_diskpath=config.xpath("//disk/source")[0]
kvm_uuid=config.xpath("//uuid")[0]
kvm_interface=config.xpath("//interface")[0]
kvm_mac=config.xpath("//mac")[0]
ifcopycpu!=''andcopymemory!='':
copymemory=int(copymemory)*1024
kvm_cpu=config.xpath("//vcpu")[0]
kvm_cpu.text=copycpu
kvm_memory=config.xpath("//memory")[0]
kvm_currentmemory=config.xpath("//currentMemory")[0]
kvm_memory.text=str(copymemory)
kvm_currentmemory.text=str(copymemory)
elifcopycpu!=''andcopymemory=='':
kvm_cpu=config.xpath("//vcpu")[0]
kvm_cpu.text=copycpu
elifcopycpu==''andcopymemory!='':
copymemory=int(copymemory)*1024
kvm_memory=config.xpath("//memory")[0]
kvm_currentmemory=config.xpath("//currentMemory")[0]
kvm_memory.text=str(copymemory)
kvm_currentmemory.text=str(copymemory)
#修改名字、修改磁盘路径、删除uuid、删除mac
kvm_name.text=copyname
kvm_diskpath.attrib['file']=kvm_disk_path
config.remove(kvm_uuid)
kvm_interface.remove(kvm_mac)
xml_content=etree.tounicode(config)
xml_path='/etc/libvirt/qemu/{0}.xml'.format(copyname)
exe_cmd=r'cat>{0}<<\EOH'.format(xml_path)+'\n'+xml_content+'\nEOH'
self.remote_linux(exe_cmd)
info='生成成功。'
except:
info='生成失败。'
returninfo
defdefine_kvm(self,copy_name):
"""
通过xml文件定义虚拟机
virshdefine/etc/libvirt/qemu/kvm_1.xml
"""
xml_path='/etc/libvirt/qemu/{0}.xml'.format(copy_name)
exe_cmd=r'virshdefine{0}'.format(xml_path)
result=self.remote_linux(exe_cmd)#定义域CentOS-7@test4(从/etc/libvirt/qemu/CentOS-7@test4.xml)
ifresult['data'].strip()=='Domain{0}definedfrom{1}'.format(copy_name,xml_path)or\
result['data'].strip()=='定义域{0}(从{1})'.format(copy_name,xml_path):
result='定义成功。'
else:
result='定义失败。'
returnresult
defguestmount(self,kvm_machine,filesystem):
"""
guestmount-a/data/vmdata/CentOS-7-2020-09-14/CentOS-7.qcow2-i/etc/libvirt/kvm_mount
/data/vmdata/CentOS-7-2020-09-14/CentOS-7.qcow2磁盘路径
/etc/libvirt/kvm_mount要挂载的目录
"""
try:
#filesystem:data/vmdata/CentOS-7-2020-09-14
kvm_disk_path='/'+filesystem+'/'+kvm_machine+'.qcow2'
kvm_mount='/etc/libvirt/kvm_mount'
exe_cmd=r'guestmount-a{0}-i{1}&&sleep1'.format(kvm_disk_path,kvm_mount)
self.remote_linux(exe_cmd)
result='挂载成功。'
exceptExceptionase:
print(e)
result='挂载失败。'
returnresult
defalert_ip_hostname(self,copy_ip,copy_hostname):
"""
sed-i"/IPADDR/s/=.*/=192.168.1.180/"/etc/libvirt/kvm_mount/etc/sysconfig/network-scripts/ifcfg-eth0修改ip
sed-i'/HWADDR/d'/etc/libvirt/kvm_mount/etc/sysconfig/network-scripts/ifcfg-eth0删除MAC地址
echoCentOS-7@test5>/etc/libvirt/kvm_mount/etc/hostname修改主机名
"""
try:
exe_cmd_ip='sed-i"/IPADDR/s/=.*/={0}/"/etc/libvirt/kvm_mount/etc/sysconfig/network-scripts/ifcfg-eth0'.format(copy_ip)
exe_cmd_mac='sed-i"/HWADDR/d"/etc/libvirt/kvm_mount/etc/sysconfig/network-scripts/ifcfg-eth0'
exe_cmd_hostname='echo{0}>/etc/libvirt/kvm_mount/etc/hostname'.format(copy_hostname)
exe_cmd=r'{0}&&{1}&&{2}'.format(exe_cmd_ip,exe_cmd_mac,exe_cmd_hostname)
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
result='修改成功。'
else:
result='修改失败。'
exceptExceptionase:
print(e)
result='修改失败。'
returnresult
defumount(self):
"""
取消挂载:umount/etc/libvirt/kvm_mount
"""
try:
exe_cmd=r'umount/etc/libvirt/kvm_mount'
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
result='取消挂载成功。'
else:
result='取消挂载失败'
exceptExceptionase:
print(e)
result='取消挂载失败。'
returnresult
defkvm_disk_space(self):
"""
获取kvm文件系统磁盘使用情况:zfslist
"""
exe_cmd=r'zfslist'
result=self.remote_linux(exe_cmd)
kvm_space_list=[xforxinresult['data'].split('')ifx]
delkvm_space_list[0:5]
end_list=self.list_of_groups(kvm_space_list,5)
data={}
foriteminend_list:
if'data'==item[0]:
data['used_total']=float(item[1].replace('G',''))
data['size_total']=float(item[2].replace('G',''))
data['used_percent']=round(float(item[1].replace('G',''))/float(item[2].replace('G','')),2)*100
returndata
defmemory_disk_cpu_data(self):
"""
宿主机查看内存使用率:cat/proc/meminfo
查看cpu使用率
查看磁盘使用率
查看操作系统
查看主机名
"""
data=''
try:
#内存
exe_cmd=r'cat/proc/meminfo'
result=self.remote_linux(exe_cmd)
memory_info=[xforxinresult['data'].split('')ifx]
end_list=self.list_of_groups(memory_info,3)[0:5]
memtotal=end_list[0][1]#总内存
memfree=end_list[1][1]#空闲内存
buffers=end_list[3][1]#给文件缓存大小
cached=end_list[4][1]#高速缓冲存储器使用的大小
free_mem=int(memfree)+int(buffers)+int(cached)
used_mem=int(memtotal)-free_mem
memory_usage=round(100*used_mem/float(memtotal),2)
#磁盘
exe_cmd=r'df'
result=self.remote_linux(exe_cmd)
disk_info=[xforxinresult['data'].split('')ifx]
deldisk_info[0:6]
end_list=self.list_of_groups(disk_info,6)
disk_info_list=[]
foriteminend_list:
data={}
data['name']=item[0]
data['total']=item[1]
data['used']=item[2]
data['mount']=item[5]
disk_info_list.append(data)
total=0
used=0
foriindisk_info_list:
ifi['mount']=='/'ori['mount']=='/data'ori['mount']=='/boot':
total+=int(i['total'])
used+=int(i['used'])
disk_usage=round(used/total*100,2)
#cpu使用率
exe_cmd=r"top-n1|awk'/Cpu/{print$2}'"
result=self.remote_linux(exe_cmd)
cpu_usage=float(result['data'])
#cpu个数
exe_cmd=r'cat/proc/cpuinfo|grep"physicalid"|sort|uniq|wc-l'
result=self.remote_linux(exe_cmd)
cpu_count=result['data']
#操作系统
exe_cmd=r"cat/etc/centos-release"
result=self.remote_linux(exe_cmd)
os=result['data']
#主机名
exe_cmd=r"cat/etc/hostname"
result=self.remote_linux(exe_cmd)
hostname=result['data']
data={
'mem_total':round(int(memtotal)/1024/1024,2),
'mem_used':round(used_mem/1024/1024,2),
'memory_usage':memory_usage,
'disk_total':round(total/1024/1024,2),
'disk_used':round(used/1024/1024,2),
'disk_usage':disk_usage,
'cpu_usage':cpu_usage,
'cpu_count':cpu_count,
'os':os,
'hostname':hostname
}
exceptExceptionase:
print(e)
returndata
defkvm_cpu_mem_usage(self,kvm_id):
kvm_mem_usage=''
kvm_cpu_usage=''
try:
#获取内存使用信息
exe_cmd=r"./test5.py{0}".format(kvm_id)
result=self.remote_linux(exe_cmd)
kvm_mem_usage=result['data']
#获取cpu使用信息
exe_cmd=r"./test4.py{0}".format(kvm_id)
result=self.remote_linux(exe_cmd)
kvm_cpu_usage=result['data']
exceptExceptionase:
print(e)
kvm_mem_usage=json.loads(kvm_mem_usage)
kvm_cpu_usage=json.loads(kvm_cpu_usage)
data={
"kvm_mem_usage":kvm_mem_usage,
"kvm_cpu_usage":kvm_cpu_usage,
}
returndata
defkvm_disk_usage(self,kvm_name):
kvm_disk_usage=''
try:
#获取磁盘使用信息
exe_cmd=r'virt-df-d{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
kvm_disk_list=[xforxinresult['data'].split('')ifx]
delkvm_disk_list[0:5]
#['CentOS-7:/dev/sda1','10474496','1004380','9470116','10%']
kvm_disk_usage={
'kvm_name':kvm_disk_list[0].split(':')[0],
'disk_filesystem':kvm_disk_list[0],
'disk_total':round(int(kvm_disk_list[1])/1024/1024,2),
'disk_used':round(int(kvm_disk_list[2])/1024/1024,2),
'disk_usage':kvm_disk_list[4]
}
exceptExceptionase:
print(e)
data={"kvm_disk_usage":kvm_disk_usage}
returndata
defkvm_template(self):
#kvm虚拟机模板文件:cd/home/images
try:
exe_cmd=r'ls/home/images'
result=self.remote_linux(exe_cmd)
result=[x.replace('\t','').split('')forxinresult['data'].split('')ifx][0]
exceptExceptionase:
print(e)
result='查找kvm模板文件失败。'
returnresult
defcopy_disk(self,kvm_template_path,filesystem):
try:
exe_cmd=r'cp{0}{1}'.format(kvm_template_path,filesystem)
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
result='拷贝磁盘文件成功。'
else:
result='拷贝磁盘文件失败。'
exceptExceptionase:
print(e)
result='拷贝磁盘文件失败。'
returnresult
defcreate_new_xml(self,kvm_xml,kvm_disk_path,kvmname):
try:
exe_cmd=r'cat/home/xml/{0}'.format(kvm_xml)
result=self.remote_linux(exe_cmd)
#解析xml文件找出要修改的name、uuid、disk_path、mac、
config=etree.XML(result['data'])
kvm_name=config.xpath("//name")[0]
kvm_diskpath=config.xpath("//disk/source")[0]
kvm_uuid=config.xpath("//uuid")[0]
kvm_interface=config.xpath("//interface")[0]
kvm_mac=config.xpath("//mac")[0]
#修改名字、修改磁盘路径、删除uuid、删除mac
kvm_name.text=kvmname
kvm_diskpath.attrib['file']=kvm_disk_path
config.remove(kvm_uuid)
kvm_interface.remove(kvm_mac)
xml_content=etree.tounicode(config)
xml_path='/etc/libvirt/qemu/{0}.xml'.format(kvmname)
exe_cmd=r'cat>{0}<<\EOH'.format(xml_path)+'\n'+xml_content+'\nEOH'
self.remote_linux(exe_cmd)
info='生成成功。'
except:
info='生成失败。'
returninfo
linuxserver_credit={
'KvmHost':'192.168.1.61',
'KvmUser':'root',
'KvmPasswd':'******',
'SystemType':'Linux',
}
#result=KVMApi(linuxserver_credit).kvm_all_list()
#result=KVMApi(linuxserver_credit).clone('Test-1','Test-3')
#result=KVMApi(linuxserver_credit).zfs_create_filesystem('kvm_1')
#result=KVMApi(linuxserver_credit).copy_kvm_disk('kvm_1','Test-1')
#result=KVMApi(linuxserver_credit).zfs_create_snapshot('kvm_1','2020-08-20')
#result=KVMApi(linuxserver_credit).zfs_snapshot_list('tank/CentOS-7')
#result=KVMApi(linuxserver_credit).zfs_clone_snapshot('tank/CentOS-7@2020-08-25')
#result=KVMApi(linuxserver_credit).create_kvm_xml('CentOS-7@test3','tank/CentOS-7@2020-08-28','CentOS-7@2020-08-28','2','1024')
#result=KVMApi(linuxserver_credit).define('kvm_1')
#result=KVMApi(linuxserver_credit).start('CentOS-7@2020-08-30')
#result=KVMApi(linuxserver_credit).shutdown('Test-1')
#result=KVMApi(linuxserver_credit).zfs_list()
#result=KVMApi(linuxserver_credit).zfs_kvm_filesystem()
#result=KVMApi(linuxserver_credit).snapshot_list('Test-1')
#print(result)
#result=KVMApi(linuxserver_credit).guestmount('CentOS-7','tank/CentOS-7@test1')
#result=KVMApi(linuxserver_credit).alert_ip('192.168.1.180')
#result=KVMApi(linuxserver_credit).alert_hostname('CentOS-7@test5')
#result=KVMApi(linuxserver_credit).guestmount_umount()
#result=KVMApi(linuxserver_credit).alert_ip_hostname_sh('CentOS-7','tank/CentOS-7-test2','192.168.1.197','CentOS-7-test2')
#print(result)
#result=KVMApi(linuxserver_credit).kvm_disk_space()
#result=KVMApi(linuxserver_credit).kvm_info_data('Test-1')
#result=KVMApi(linuxserver_credit).kvm_include_copy_list('CentOS-7')
#result=KVMApi(linuxserver_credit).zfs_kvm_filesystem()
#result=KVMApi(linuxserver_credit).kvm_template()
#print(result)
附:
kvm虚拟机cpu使用率(正在运行的kvm虚拟机)
#!/bin/pythonimportlibvirt
importtime
conn=libvirt.open("qemu:///system")
importsys
importjson
info={}
id=int(sys.argv[1])
dom=conn.lookupByID(id)
name=dom.name()
t1=time.time()
c1=int(dom.info()[4])
time.sleep(3)
t2=time.time();
c2=int(dom.info()[4])
c_nums=int(dom.info()[3])
cpu_usage=round((c2-c1)*100/((t2-t1)*c_nums*1e9),2)
info['cpu_usage']=cpu_usage
print(json.dumps(info))
test4.py
kvm虚拟机内存使用率(正在运行的kvm虚拟机)
#!/usr/bin/pythonimportlibvirt
conn=libvirt.open("qemu:///system")
importjson
importsys
id=int(sys.argv[1])
info={}
dom=conn.lookupByID(id)
infos=dom.info()
name=dom.name()
mem=infos[1]
dom.setMemoryStatsPeriod(10)
meminfo=dom.memoryStats()
free_mem=float(meminfo['unused'])
total_mem=float(meminfo['available'])
used_mem=total_mem-free_mem
mem_usage=round(((total_mem-free_mem)/total_mem)*100,2)
info['mem_usage']=mem_usage
info['mem_used']=round(used_mem/1024/1024,2)
info['mem_total']=round(total_mem/1024/1024,2)
info['mem_free']=round(free_mem/1024/1024,2)
print(json.dumps(info))
test4.py
本文共计5873个文字,预计阅读时间需要24分钟。
Python脚本:连接Linux系统,使用paramiko和pywinrm实现Windows/Linux脚本调用。处理Linux下脚本语法错误或命令不存在等错误,通过stderr变量接收,只能添加判断条件;Windows下可接收错误信息并输出判断。
python脚本:连接Linux
"""paramiko,pywinrm实现windows/linux脚本调用
linux下脚本语法错误,或者命令不存在等没有通过stderr变量接收到,只能添加判断条件;
windows下可以接收到错误信息并作出判断;
"""
importparamiko
importwinrm
importsocket
importrequests
importdatetime
fromwinrm.exceptionsimportWinRMTransportError,WinRMOperationTimeoutError,WinRMError
fromrequests.exceptionsimportConnectionError
###############################################################
#为实现WINDOWS下执行脚本时长超时设置,对wimrm中相关类进行重写。#
###############################################################
#重写Protocol类
classProtocol(winrm.protocol.Protocol):
defget_command_output(self,shell_id,command_id):
"""
GettheOutputofthegivenshellandcommand
@paramstringshell_id:Theshellidontheremotemachine.
See#open_shell
@paramstringcommand_id:Thecommandidontheremotemachine.
See#run_command
#@return[Hash]ReturnsaHashwithakey:exitcodeand:data.
DataisanArrayofHasheswherethecoorespondingkey
#iseither:stdoutor:stderr.ThereasonitisinanArraysoso
wecangettheoutputintheorderitocurrson
#theconsole.
"""
stdout_buffer,stderr_buffer=[],[]
command_done=False
############################################################################
#限时6*60s#
#程序反复查看相应,如果相应成功,且在超时时限内则命令成功,否则报超时异常。#
#获取响应的时长较长。#
############################################################################
return_code=-1
limited_seconds=6*60
start_time=datetime.datetime.now()
whilenotcommand_done:
print('gettheresponsefromwindows...')
try:
stdout,stderr,return_code,command_done=\
self._raw_get_command_output(shell_id,command_id)
stdout_buffer.append(stdout)
stderr_buffer.append(stderr)
exceptWinRMOperationTimeoutErrorase:
#thisisanexpectederrorwhenwaitingforalong-runningprocess,justsilentlyretry
pass
end_time=datetime.datetime.now()
delta_time=end_time-start_time
total_seconds=delta_time.total_seconds()
iftotal_seconds>limited_seconds:
raiseWinRMOperationTimeoutError()
returnb''.join(stdout_buffer),b''.join(stderr_buffer),return_code
#重写Session类
classSession(winrm.Session):
#TODOimplementcontextmanagermethods
def__init__(self,target,auth,**kwargs):
username,password=auth
self.url=self._build_url(target,kwargs.get('transport','plaintext'))
self.protocol=Protocol(self.url,
username=username,password=password,**kwargs)
classServerByPara(object):
def__init__(self,cmd,host,user,password,system_choice):
self.cmd=cmd
self.client=paramiko.SSHClient()
self.host=host
self.user=user
self.pwd=password
self.system_choice=system_choice
defexec_linux_cmd(self,succeedtext,linux_timeout,port=22):
data_init=''
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
self.client.connect(hostname=self.host,username=self.user,password=self.pwd,timeout=5,port=port)
except(socket.timeout,paramiko.ssh_exception.SSHException)ase:
print("连接服务器失败")
return{
"exec_tag":1,
"data":"连接服务器失败{0}".format(e),
"log":"连接服务器失败",
}
try:
stdin,stdout,stderr=self.client.exec_command(self.cmd,get_pty=True,timeout=linux_timeout)
ifstderr.read():
exec_tag=1
data_init=str(stderr.read(),encoding='utf-8')
#fordatainstderr.readlines():
#data_init+=data
log=""
else:
exec_tag=0
log=""
try:
data_init=str(stdout.read(),encoding='utf-8')
ifdata_init:
data_init="".join(data_init.split("\r\n"))
if"commandnotfound"indata_init:#命令不存在
exec_tag=1
log="命令不存在"
elif"syntaxerror"indata_init:#语法错误
exec_tag=1
log="语法错误"
elif"Nosuchfileordirectory"indata_init:#脚本不存在
exec_tag=1
log="脚本不存在"
elifsucceedtextisnotNone:
ifsucceedtextnotindata_init:
exec_tag=1
log="未匹配"
exceptExceptionase:
print(e)
exec_tag=0#不抛错
log="编码错误"
data_init="编码错误"
exceptsocket.timeoutase:
print("脚本执行超时")
return{
"exec_tag":1,
"data":"脚本执行超时",
"log":"脚本执行超时",
}
return{
"exec_tag":exec_tag,
"data":data_init,
"log":log,
}
defexec_win_cmd(self,succeedtext):
data_init=""
log=""
try:
s=Session(self.host,auth=(self.user,self.pwd))
ret=s.run_cmd(self.cmd)
except(ConnectionError,WinRMOperationTimeoutError,WinRMTransportError,WinRMError)ase:
iftype(e)==WinRMOperationTimeoutError:
print("脚本执行超时")
exec_tag=1
data="脚本执行超时{0}".format(e)
log="脚本执行超时"
eliftype(e)in[ConnectionError,WinRMTransportError]:
print("连接windows失败")
exec_tag=1
data="连接windows失败{0}".format(e)
log="连接windows失败"
else:
print("执行windows脚本发生异常错误")
exec_tag=1
data="执行windows脚本发生异常错误{0}".format(e)
log="执行windows脚本发生异常错误"
return{
"exec_tag":exec_tag,
"data":data,
"log":log,
}
else:
ifret.std_err:
data_init=str(ret.std_err,encoding='gbk')
exec_tag=1
#fordatainret.std_err.decode().split("\r\n"):
#data_init+=data
log=""
else:
exec_tag=0
try:
data_init=str(ret.std_out,encoding='gbk')
ifdata_init:
data_init="".join(data_init.split("\r\n"))
#fordatainret.std_out.decode().split("\r\n"):
#data_init+=data
exceptExceptionase:
print(e)
exec_tag=0#不抛错
log="编码错误"
data_init="编码错误"
else:
ifsucceedtextisnotNone:
ifsucceedtextnotindata_init:
exec_tag=1
log="未匹配"
return{
"exec_tag":exec_tag,
"data":data_init,
"log":log,
}
defrun(self,succeedtext,linux_timeout=6*60):
ifself.system_choice=="Linux":
result=self.exec_linux_cmd(succeedtext,linux_timeout)
ifself.client:
self.client.close()
elifself.system_choice=="AIX":
result=self.exec_linux_cmd(succeedtext,linux_timeout,port=22)
ifself.client:
self.client.close()
else:
result=self.exec_win_cmd(succeedtext)
#print(result)
returnresult
if__name__=='__main__':
#server_obj=ServerByPara(sys.argv[1],sys.argv[2],sys.argv[3],sys.argv[4])
#server_obj=ServerByPara(r"C:\Users\Administrator\Desktop\test_python.bat","192.168.100.151","administrator","tesunet@2017","Windows")
server_obj=ServerByPara(r"echo中文>C:\Users\Administrator\Desktop\test.bat",
"192.168.100.154","administrator","tesunet@2017","Windows")
#linux_temp_script_file=r"/tmp/drm/954/tmp_script_6486.sh&&/tmp/drm/954/tmp_script_6486.sh"
#cmd=r"sed-i's/\r$//'{0}&&{0}".format(linux_temp_script_file)
#print(cmd)#sed-i's/\r$//'/tmp/drm/954/tmp_script_6486.sh&&/tmp/drm/954/tmp_script_6486.sh
#server_obj=ServerByPara("mkdir-p/tmp/drm/957",
#"10.64.7.43","root","qtdl2003","Linux")
#server_obj=ServerByPara("echo中文",
#"192.168.184.66","root","password","Linux")
#server_obj=ServerByPara(r"echo'你好你好你好你好你好你好你好';echo'你好你好你好你好你好你好你好';echo'你好你好你好你好你好你好你好'","192.168.184.66","root","password","Linux")
server_obj.run("")
print(11111111111111)
python脚本:操作kvm虚拟机,进行kvm虚拟机开机、关机、克隆、快照等。
fromdrmimportremotefromlxmlimportetree
importtime
importjson
classKVMApi():
def__init__(self,credit):
self.ip=credit['KvmHost']
self.username=credit['KvmUser']
self.password=credit['KvmPasswd']
self.system_tag=credit['SystemType']
defremote_linux(self,exe_cmd):
rm_obj=remote.ServerByPara(exe_cmd,self.ip,self.username,self.password,self.system_tag)
result=rm_obj.run(succeedtext='',linux_timeout=12*60)
returnresult
deflist_of_groups(self,list_info,per_list_len):
"""
list_info:列表元素
per_list_len:每个小列表的长度
"""
list_of_group=zip(*(iter(list_info),)*per_list_len)
end_list=[list(i)foriinlist_of_group]
count=len(list_info)%per_list_len
end_list.append(list_info[-count:])ifcount!=0elseend_list
returnend_list
defdomstate(self,kvm_name):
#获取虚拟机的状态
exe_cmd=r'virshdomstate{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
result=result['data'].strip()
returnresult
defkvm_all_list(self):
#获取所有kvm虚拟机
exe_cmd=r'virshlist--all'
result=self.remote_linux(exe_cmd)
kvm_list=[xforxinresult['data'].split('')ifx]
delkvm_list[0:4]
kvm_list_filter=[]
foriinkvm_list:
ifi=='shut':
continue
ifi=='off':
i='关闭'
ifi=='running':
i='运行中'
ifi=='paused':
i='暂停'
kvm_list_filter.append(i)
end_list=self.list_of_groups(kvm_list_filter,3)
kvm_all_list_dict=[]
foriteminend_list:
data={}
data['id']=item[0]
data['name']=item[1]
data['state']=item[2]
kvm_all_list_dict.append(data)
returnkvm_all_list_dict
defkvm_exclude_copy_list(self):
#获取除实例之外所有kvm虚拟机
exe_cmd=r'virshlist--all'
result=self.remote_linux(exe_cmd)
kvm_list=[xforxinresult['data'].split('')ifx]
delkvm_list[0:4]
kvm_list_filter=[]
foriinkvm_list:
ifi=='shut':
continue
ifi=='off':
i='关闭'
ifi=='running':
i='运行中'
ifi=='paused':
i='暂停'
kvm_list_filter.append(i)
end_list=self.list_of_groups(kvm_list_filter,3)
kvm_all_list_dict=[]
foriteminend_list:
data={}
if'@'notinitem[1]:
data['id']=item[0]
data['name']=item[1]
data['state']=item[2]
kvm_all_list_dict.append(data)
returnkvm_all_list_dict
defkvm_include_copy_list(self,kvm_copy_name):
#获取所有实例虚拟机
exe_cmd=r'virshlist--all'
result=self.remote_linux(exe_cmd)
kvm_list=[xforxinresult['data'].split('')ifx]
delkvm_list[0:4]
kvm_list_filter=[]
foriinkvm_list:
ifi=='shut':
continue
ifi=='off':
i='关闭'
ifi=='running':
i='运行中'
ifi=='paused':
i='暂停'
kvm_list_filter.append(i)
end_list=self.list_of_groups(kvm_list_filter,3)
kvm_all_list_dict=[]
foriteminend_list:
data={}
copyname=kvm_copy_name+'@'
ifcopynameinitem[1]:
data['id']=item[0]
data['name']=item[1]
data['state']=item[2]
kvm_all_list_dict.append(data)
returnkvm_all_list_dict
defkvm_run_list(self):
#获取正在运行的虚拟机
exe_cmd=r'virshlist'
result=self.remote_linux(exe_cmd)
kvm_list=[xforxinresult['data'].split('')ifx]
delkvm_list[0:3]
end_list=self.list_of_groups(kvm_list,3)
kvm_all_list_dict=[]
foriteminend_list:
data={}
data['id']=item[0]
data['name']=item[1]
data['state']=item[2]
kvm_all_list_dict.append(data)
returnkvm_all_list_dict
defkvm_start(self,kvm_state,kvm_name):
#开启虚拟机:是关闭的状态(shutoff/关闭)
ifkvm_state=='shutoff'orkvm_state=='关闭':
exe_cmd=r'virshstart{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
ifresult['data'].strip()=='Domain{0}started'.format(kvm_name)or\
result['data'].strip()=='域{0}已开始'.format(kvm_name):
result='开机成功。'
else:
result='开机失败。'
else:
result='虚拟机已开启。'
returnresult
defkvm_shutdown(self,kvm_state,kvm_name):
#关闭虚拟机:是开启的状态(running)
ifkvm_state=='running'orkvm_state=='运行中':
exe_cmd=r'virshshutdown{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
ifresult['data'].strip()=='Domain{0}isbeingshutdown'.format(kvm_name)or\
result['data'].strip()=='域{0}被关闭'.format(kvm_name):
time.sleep(5)
state=self.domstate(kvm_name)
ifstate=='shutoff'orstate=='关闭':
result='关闭成功。'
else:
result='关闭失败。'
else:
result='关闭失败。'
elifkvm_state=='暂停'orkvm_state=='paused':
result='虚拟机未运行。'
else:
result='虚拟机未开启。'
returnresult
defkvm_destroy(self,kvm_state,kvm_name):
#断电虚拟机:是开启的状态(running)或者是暂停状态(pasued)
ifkvm_state=='running'orkvm_state=='运行中'orkvm_state=='paused'orkvm_state=='暂停':
exe_cmd=r'virshdestroy{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
ifresult['data'].strip()=='Domain{0}destroyed'.format(kvm_name)or\
result['data'].strip()=='域{0}被删除'.format(kvm_name):
result='断电成功。'
else:
result='断电失败。'
else:
result='虚拟机未开启。'
returnresult
deffilesystem_del(self,filesystem):
try:
exe_cmd=r'zfsdestroy{0}'.format(filesystem)
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
result='删除文件系统成功。'
else:
result='删除文件系统成功。'
exceptExceptionase:
print(e)
result='删除文件系统失败。'
returnresult
defundefine(self,kvm_name,state):
"""
删除虚拟机
停止主机:virshshutdownlinux65
删除主机定义:virshundefinelinux65
删除KVM虚拟机文件系统:zfsdestroytank/CentOS-7@test3
"""
#这里需要先判断虚拟机的状态
#如果是关闭(shutoff)的虚拟机直接删除,然后删除磁盘文件,如果是开启(running)的虚拟机,先关闭再删除虚拟机,在删除磁盘文件
#如果虚拟机中创建了快照,虚拟机是无法删除的,需要删除所有的快照,然后在执行删除虚拟机操作
ifstate=='shutoff'orstate=='关闭':
snapshot_list=self.snapshot_list(kvm_name)
ifnotsnapshot_list:
try:
exe_cmd=r'virshundefine{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
ifresult['data'].strip()=='Domain{0}hasbeenundefined'.format(kvm_name)or\
result['data'].strip()=='域{0}已经被取消定义'.format(kvm_name):
result='取消定义成功。'
else:
result='取消定义失败。'
exceptExceptionase:
print(e)
result='取消定义失败。'
else:
result='虚拟机已创建快照,无法删除。'
else:
result='虚拟机未关闭。'
returnresult
defkvm_suspend(self,kvm_state,kvm_name):
"""
暂停虚机:开启(ruuning)/暂停(paused)的状态,关闭状态提醒错误。
"""
ifkvm_state=='running'orkvm_state=='运行中'orkvm_state=='paused'orkvm_state=='暂停':
exe_cmd=r'virshsuspend{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
ifresult['data'].strip()=='Domain{0}suspended'.format(kvm_name)or\
result['data'].strip()=='域{0}被挂起'.format(kvm_name):
result='暂停成功。'
else:
result='暂停失败。'
else:
result='虚拟机未开启。'
returnresult
defkvm_resume(self,kvm_state,kvm_name):
"""
恢复暂停的虚机:必须是暂停(paused)状态的虚拟机才可以执行恢复操作
"""
ifkvm_state=='paused'orkvm_state=='暂停':
exe_cmd=r'virshresume{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
ifresult['data'].strip()=='Domain{0}resumed'.format(kvm_name)or\
result['data'].strip()=='域{0}被重新恢复'.format(kvm_name):
result='运行成功。'
else:
result='运行失败。'
else:
result='虚拟机非暂停状态,无法执行此操作。'
returnresult
defkvm_reboot(self,kvm_state,kvm_name):
"""
重启虚机:必须是开启(running)/暂停(paused)状态的虚拟机才可以执行重启操作
"""
ifkvm_state=='running'orkvm_state=='运行中'orkvm_state=='暂停'orkvm_state=='paused':
exe_cmd=r'virshreboot{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
ifresult['data'].strip()=='Domain{0}isbeingrebooted'.format(kvm_name)or\
result['data'].strip()=='域{0}正在被重新启动'.format(kvm_name):
result='重启成功。'
else:
result='重启失败。'
else:
result='虚拟机未开启。'
returnresult
defkvm_clone(self,kvm_state,kvm_name,kvm_name_clone,filesystem):
"""
克隆虚拟机:需要在关机或者暂停的状态下才可以进行克隆
克隆出错:ERRORDomainwithdevicestoclonemustbepausedorshutoff.
克隆成功:Allocating'Test-3.qcow2'|80GB00:02Clone'Test-3'createdsuccessfully.
virt-clone-owin2k16-nTest-1-f/var/lib/libvirt/images/Test—1.qcow2
注:-o:original后面跟要克隆的虚拟机名字
-n:name克隆后虚拟机的名字
-f:file指定镜像存放的路径:默认路径:/var/lib/libvirt/images
新的虚拟机存在报错:ERRORInvalidnamefornewguest:Guestname'Test-3'isalreadyinuse.
"""
#判断虚拟机的状态
disk_path='/'+filesystem+'/'+kvm_name_clone+'.qcow2'
ifkvm_state=='shutoff'orkvm_state=='paused'orkvm_state=='关闭'orkvm_state=='暂停':
exe_cmd=r'virt-clone-o{0}-n{1}-f{2}'.format(kvm_name,kvm_name_clone,disk_path)
result=self.remote_linux(exe_cmd)
if"Clone'{0}'createdsuccessfully.".format(kvm_name_clone)or\
"成功克隆'{0}'".format(kvm_name_clone)inresult['data']:
result='克隆成功。'
else:
result='克隆失败。'
else:
result='虚拟机未关闭。'
returnresult
defkvm_info_data(self,kvm_name):
#获取虚拟机cpu、内存、系统类型、磁盘
exe_cmd=r'cat/etc/libvirt/qemu/{0}.xml'.format(kvm_name)
result=self.remote_linux(exe_cmd)
config=etree.XML(result['data'])
kvm_cpu=config.xpath("//vcpu")[0]
kvm_memory=config.xpath("//memory")[0]
kvm_os=config.xpath("//os/type")[0]
kvm_diskpath=config.xpath("//disk/source")[0]
kvm_os=kvm_os.text
kvm_cpu=int(kvm_cpu.text)
kvm_memory=int(int(kvm_memory.text)/1024)
kvm_disk=kvm_diskpath.attrib['file']
kvm_info={
'kvm_os':kvm_os,
'kvm_disk':kvm_disk,
'kvm_cpu':kvm_cpu,
'kvm_memory':kvm_memory
}
returnkvm_info
defsnapshot_create(self,kvm_name):
#创建快照
#创建成功提示信息:Domainsnapshot1596685828created
exe_cmd=r'virshsnapshot-create{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
if'created'inresult['data']or'已生成域快照'inresult['data']:
result='虚拟机{0}创建快照成功。'.format(kvm_name)
else:
result='虚拟机{0}创建快照失败。'.format(kvm_name)
returnresult
defsnapshot_list(self,kvm_name):
#查看快照列表
exe_cmd=r'virshsnapshot-list{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
list=[xforxinresult['data'].split('')ifx]
dellist[0:4]
end_list=self.list_of_groups(list,5)
snapshot_list_dict=[]
foriteminend_list:
data={}
data['name']=item[0]
snapshot_list_dict.append(data)
"""
[{'name':'1596684491'},
{'name':'1596685828'}]
"""
returnsnapshot_list_dict
defsnapshot_del(self,kvm_name,snapshotname):
#删除快照
exe_cmd=r'virshsnapshot-delete{0}--snapshotname{1}'.format(kvm_name,snapshotname)
result=self.remote_linux(exe_cmd)
ifresult['data']=='Domainsnapshot{0}deleted'.format(snapshotname)orresult['data']=='已删除域快照':
result='快照{0}删除成功。'.format(snapshotname)
else:
result='快照{0}删除失败。'.format(snapshotname)
returnresult
defsnapshot_revert(self,kvm_name,snapshotname):
#恢复快照:虚拟机是关机的状态
state=self.domstate(kvm_name)
ifstate=='shutoff':
exe_cmd=r'virshsnapshot-revert{0}--snapshotname{1}'.format(kvm_name,snapshotname)
self.remote_linux(exe_cmd)
result='恢复到快照{0}成功。'.format(snapshotname)
else:
result='请先关闭虚拟机,再执行恢复操作。'.format(kvm_name)
returnresult
defzfs_kvm_filesystem(self):
exe_cmd=r'ls/data/vmdata'.format()
result=self.remote_linux(exe_cmd)
kvm_filesystem=[x.replace('\t','')forxinresult['data'].split('')ifx]
returnkvm_filesystem
defcreate_filesystem(self,filesystem):
"""
为每一台虚拟机分别创建一个文件系统
tank/kvm_1
tank/kvm_2
tank/kvm_3
zfs创建文件系统:zfscreatetank/kvm_1
zfs_pool_data:文件系统路径
"""
try:
exe_cmd=r'zfscreate{0}'.format(filesystem)
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
result='文件系统创建成功。'
else:
result='文件系统创建失败。'
except:
result='文件系统创建失败。'
returnresult
defzfs_create_snapshot(self,snapshot_name):
"""
创建快照:zfssnapshottank/kvm_1@2020-07-28
kvm_name:虚拟机
zfs_snapshot_name:快照名字
"""
try:
exe_cmd=r'zfssnapshot{0}'.format(snapshot_name)
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
info='创建成功。'
else:
info='创建失败。'
except:
info='创建失败。'
returninfo
defzfs_snapshot_list(self,filesystem):
"""
查看zfs快照:zfslist-tsnapshot-rtank/kvm_1
"""
exe_cmd=r'zfslist-tsnapshot-r{0}'.format(filesystem)
result=self.remote_linux(exe_cmd)
snapshot_list=[xforxinresult['data'].split('')ifx]
delsnapshot_list[0:5]
end_list=self.list_of_groups(snapshot_list,5)
zfs_snapshot_list_dict=[]
foriteminend_list:
data={}
item=item[0].split('@')
data['name']=item[1]
zfs_snapshot_list_dict.append(data)
returnzfs_snapshot_list_dict
defzfs_snapshot_del(self,snapshot_name):
"""
删除快照:zfsdestroymypool/data@2020-07-28
"""
try:
exe_cmd=r'zfsdestroy{0}'.format(snapshot_name)
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
info='删除快照成功。'
else:
info='删除快照失败。'
except:
info='快照已挂载,删除失败。'
returninfo
defzfs_clone_snapshot(self,snapshot_name,filesystem_name):
"""
克隆快照:zfsclonetank/kvm_1@2020-08-20tank/kvm_1@2020-08-20
kvm_name
kvm_snapshot_name
kvm_snapshot_clone_name
"""
try:
exe_cmd=r'zfsclone{0}{1}'.format(snapshot_name,filesystem_name)
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
info='克隆成功。'
else:
info='克隆失败。'
except:
info='克隆失败。'
returninfo
defcreate_kvm_xml(self,kvm_machine,snapshotname,copyname,copycpu,copymemory):
"""
读取文件,修改文件,追加到新文件
kvm_name='Test-1老虚拟机
kvm_name_new='kvm_1新虚拟机
kvm_disk_path='/tank/kvm_1@kvm_1/Test-1.qcow2'新虚拟机磁盘
"""
try:
exe_cmd=r'cat/etc/libvirt/qemu/{0}.xml'.format(kvm_machine)
snapshot_clone_name=snapshotname.replace('@','-')
kvm_disk_path='/'+snapshot_clone_name+'/'+kvm_machine+'.qcow2'
result=self.remote_linux(exe_cmd)
#解析xml文件找出要修改的name、uuid、disk_path、mac、cpu、memory
config=etree.XML(result['data'])
kvm_name=config.xpath("//name")[0]
kvm_diskpath=config.xpath("//disk/source")[0]
kvm_uuid=config.xpath("//uuid")[0]
kvm_interface=config.xpath("//interface")[0]
kvm_mac=config.xpath("//mac")[0]
ifcopycpu!=''andcopymemory!='':
copymemory=int(copymemory)*1024
kvm_cpu=config.xpath("//vcpu")[0]
kvm_cpu.text=copycpu
kvm_memory=config.xpath("//memory")[0]
kvm_currentmemory=config.xpath("//currentMemory")[0]
kvm_memory.text=str(copymemory)
kvm_currentmemory.text=str(copymemory)
elifcopycpu!=''andcopymemory=='':
kvm_cpu=config.xpath("//vcpu")[0]
kvm_cpu.text=copycpu
elifcopycpu==''andcopymemory!='':
copymemory=int(copymemory)*1024
kvm_memory=config.xpath("//memory")[0]
kvm_currentmemory=config.xpath("//currentMemory")[0]
kvm_memory.text=str(copymemory)
kvm_currentmemory.text=str(copymemory)
#修改名字、修改磁盘路径、删除uuid、删除mac
kvm_name.text=copyname
kvm_diskpath.attrib['file']=kvm_disk_path
config.remove(kvm_uuid)
kvm_interface.remove(kvm_mac)
xml_content=etree.tounicode(config)
xml_path='/etc/libvirt/qemu/{0}.xml'.format(copyname)
exe_cmd=r'cat>{0}<<\EOH'.format(xml_path)+'\n'+xml_content+'\nEOH'
self.remote_linux(exe_cmd)
info='生成成功。'
except:
info='生成失败。'
returninfo
defdefine_kvm(self,copy_name):
"""
通过xml文件定义虚拟机
virshdefine/etc/libvirt/qemu/kvm_1.xml
"""
xml_path='/etc/libvirt/qemu/{0}.xml'.format(copy_name)
exe_cmd=r'virshdefine{0}'.format(xml_path)
result=self.remote_linux(exe_cmd)#定义域CentOS-7@test4(从/etc/libvirt/qemu/CentOS-7@test4.xml)
ifresult['data'].strip()=='Domain{0}definedfrom{1}'.format(copy_name,xml_path)or\
result['data'].strip()=='定义域{0}(从{1})'.format(copy_name,xml_path):
result='定义成功。'
else:
result='定义失败。'
returnresult
defguestmount(self,kvm_machine,filesystem):
"""
guestmount-a/data/vmdata/CentOS-7-2020-09-14/CentOS-7.qcow2-i/etc/libvirt/kvm_mount
/data/vmdata/CentOS-7-2020-09-14/CentOS-7.qcow2磁盘路径
/etc/libvirt/kvm_mount要挂载的目录
"""
try:
#filesystem:data/vmdata/CentOS-7-2020-09-14
kvm_disk_path='/'+filesystem+'/'+kvm_machine+'.qcow2'
kvm_mount='/etc/libvirt/kvm_mount'
exe_cmd=r'guestmount-a{0}-i{1}&&sleep1'.format(kvm_disk_path,kvm_mount)
self.remote_linux(exe_cmd)
result='挂载成功。'
exceptExceptionase:
print(e)
result='挂载失败。'
returnresult
defalert_ip_hostname(self,copy_ip,copy_hostname):
"""
sed-i"/IPADDR/s/=.*/=192.168.1.180/"/etc/libvirt/kvm_mount/etc/sysconfig/network-scripts/ifcfg-eth0修改ip
sed-i'/HWADDR/d'/etc/libvirt/kvm_mount/etc/sysconfig/network-scripts/ifcfg-eth0删除MAC地址
echoCentOS-7@test5>/etc/libvirt/kvm_mount/etc/hostname修改主机名
"""
try:
exe_cmd_ip='sed-i"/IPADDR/s/=.*/={0}/"/etc/libvirt/kvm_mount/etc/sysconfig/network-scripts/ifcfg-eth0'.format(copy_ip)
exe_cmd_mac='sed-i"/HWADDR/d"/etc/libvirt/kvm_mount/etc/sysconfig/network-scripts/ifcfg-eth0'
exe_cmd_hostname='echo{0}>/etc/libvirt/kvm_mount/etc/hostname'.format(copy_hostname)
exe_cmd=r'{0}&&{1}&&{2}'.format(exe_cmd_ip,exe_cmd_mac,exe_cmd_hostname)
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
result='修改成功。'
else:
result='修改失败。'
exceptExceptionase:
print(e)
result='修改失败。'
returnresult
defumount(self):
"""
取消挂载:umount/etc/libvirt/kvm_mount
"""
try:
exe_cmd=r'umount/etc/libvirt/kvm_mount'
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
result='取消挂载成功。'
else:
result='取消挂载失败'
exceptExceptionase:
print(e)
result='取消挂载失败。'
returnresult
defkvm_disk_space(self):
"""
获取kvm文件系统磁盘使用情况:zfslist
"""
exe_cmd=r'zfslist'
result=self.remote_linux(exe_cmd)
kvm_space_list=[xforxinresult['data'].split('')ifx]
delkvm_space_list[0:5]
end_list=self.list_of_groups(kvm_space_list,5)
data={}
foriteminend_list:
if'data'==item[0]:
data['used_total']=float(item[1].replace('G',''))
data['size_total']=float(item[2].replace('G',''))
data['used_percent']=round(float(item[1].replace('G',''))/float(item[2].replace('G','')),2)*100
returndata
defmemory_disk_cpu_data(self):
"""
宿主机查看内存使用率:cat/proc/meminfo
查看cpu使用率
查看磁盘使用率
查看操作系统
查看主机名
"""
data=''
try:
#内存
exe_cmd=r'cat/proc/meminfo'
result=self.remote_linux(exe_cmd)
memory_info=[xforxinresult['data'].split('')ifx]
end_list=self.list_of_groups(memory_info,3)[0:5]
memtotal=end_list[0][1]#总内存
memfree=end_list[1][1]#空闲内存
buffers=end_list[3][1]#给文件缓存大小
cached=end_list[4][1]#高速缓冲存储器使用的大小
free_mem=int(memfree)+int(buffers)+int(cached)
used_mem=int(memtotal)-free_mem
memory_usage=round(100*used_mem/float(memtotal),2)
#磁盘
exe_cmd=r'df'
result=self.remote_linux(exe_cmd)
disk_info=[xforxinresult['data'].split('')ifx]
deldisk_info[0:6]
end_list=self.list_of_groups(disk_info,6)
disk_info_list=[]
foriteminend_list:
data={}
data['name']=item[0]
data['total']=item[1]
data['used']=item[2]
data['mount']=item[5]
disk_info_list.append(data)
total=0
used=0
foriindisk_info_list:
ifi['mount']=='/'ori['mount']=='/data'ori['mount']=='/boot':
total+=int(i['total'])
used+=int(i['used'])
disk_usage=round(used/total*100,2)
#cpu使用率
exe_cmd=r"top-n1|awk'/Cpu/{print$2}'"
result=self.remote_linux(exe_cmd)
cpu_usage=float(result['data'])
#cpu个数
exe_cmd=r'cat/proc/cpuinfo|grep"physicalid"|sort|uniq|wc-l'
result=self.remote_linux(exe_cmd)
cpu_count=result['data']
#操作系统
exe_cmd=r"cat/etc/centos-release"
result=self.remote_linux(exe_cmd)
os=result['data']
#主机名
exe_cmd=r"cat/etc/hostname"
result=self.remote_linux(exe_cmd)
hostname=result['data']
data={
'mem_total':round(int(memtotal)/1024/1024,2),
'mem_used':round(used_mem/1024/1024,2),
'memory_usage':memory_usage,
'disk_total':round(total/1024/1024,2),
'disk_used':round(used/1024/1024,2),
'disk_usage':disk_usage,
'cpu_usage':cpu_usage,
'cpu_count':cpu_count,
'os':os,
'hostname':hostname
}
exceptExceptionase:
print(e)
returndata
defkvm_cpu_mem_usage(self,kvm_id):
kvm_mem_usage=''
kvm_cpu_usage=''
try:
#获取内存使用信息
exe_cmd=r"./test5.py{0}".format(kvm_id)
result=self.remote_linux(exe_cmd)
kvm_mem_usage=result['data']
#获取cpu使用信息
exe_cmd=r"./test4.py{0}".format(kvm_id)
result=self.remote_linux(exe_cmd)
kvm_cpu_usage=result['data']
exceptExceptionase:
print(e)
kvm_mem_usage=json.loads(kvm_mem_usage)
kvm_cpu_usage=json.loads(kvm_cpu_usage)
data={
"kvm_mem_usage":kvm_mem_usage,
"kvm_cpu_usage":kvm_cpu_usage,
}
returndata
defkvm_disk_usage(self,kvm_name):
kvm_disk_usage=''
try:
#获取磁盘使用信息
exe_cmd=r'virt-df-d{0}'.format(kvm_name)
result=self.remote_linux(exe_cmd)
kvm_disk_list=[xforxinresult['data'].split('')ifx]
delkvm_disk_list[0:5]
#['CentOS-7:/dev/sda1','10474496','1004380','9470116','10%']
kvm_disk_usage={
'kvm_name':kvm_disk_list[0].split(':')[0],
'disk_filesystem':kvm_disk_list[0],
'disk_total':round(int(kvm_disk_list[1])/1024/1024,2),
'disk_used':round(int(kvm_disk_list[2])/1024/1024,2),
'disk_usage':kvm_disk_list[4]
}
exceptExceptionase:
print(e)
data={"kvm_disk_usage":kvm_disk_usage}
returndata
defkvm_template(self):
#kvm虚拟机模板文件:cd/home/images
try:
exe_cmd=r'ls/home/images'
result=self.remote_linux(exe_cmd)
result=[x.replace('\t','').split('')forxinresult['data'].split('')ifx][0]
exceptExceptionase:
print(e)
result='查找kvm模板文件失败。'
returnresult
defcopy_disk(self,kvm_template_path,filesystem):
try:
exe_cmd=r'cp{0}{1}'.format(kvm_template_path,filesystem)
result=self.remote_linux(exe_cmd)
ifresult['data']=='':
result='拷贝磁盘文件成功。'
else:
result='拷贝磁盘文件失败。'
exceptExceptionase:
print(e)
result='拷贝磁盘文件失败。'
returnresult
defcreate_new_xml(self,kvm_xml,kvm_disk_path,kvmname):
try:
exe_cmd=r'cat/home/xml/{0}'.format(kvm_xml)
result=self.remote_linux(exe_cmd)
#解析xml文件找出要修改的name、uuid、disk_path、mac、
config=etree.XML(result['data'])
kvm_name=config.xpath("//name")[0]
kvm_diskpath=config.xpath("//disk/source")[0]
kvm_uuid=config.xpath("//uuid")[0]
kvm_interface=config.xpath("//interface")[0]
kvm_mac=config.xpath("//mac")[0]
#修改名字、修改磁盘路径、删除uuid、删除mac
kvm_name.text=kvmname
kvm_diskpath.attrib['file']=kvm_disk_path
config.remove(kvm_uuid)
kvm_interface.remove(kvm_mac)
xml_content=etree.tounicode(config)
xml_path='/etc/libvirt/qemu/{0}.xml'.format(kvmname)
exe_cmd=r'cat>{0}<<\EOH'.format(xml_path)+'\n'+xml_content+'\nEOH'
self.remote_linux(exe_cmd)
info='生成成功。'
except:
info='生成失败。'
returninfo
linuxserver_credit={
'KvmHost':'192.168.1.61',
'KvmUser':'root',
'KvmPasswd':'******',
'SystemType':'Linux',
}
#result=KVMApi(linuxserver_credit).kvm_all_list()
#result=KVMApi(linuxserver_credit).clone('Test-1','Test-3')
#result=KVMApi(linuxserver_credit).zfs_create_filesystem('kvm_1')
#result=KVMApi(linuxserver_credit).copy_kvm_disk('kvm_1','Test-1')
#result=KVMApi(linuxserver_credit).zfs_create_snapshot('kvm_1','2020-08-20')
#result=KVMApi(linuxserver_credit).zfs_snapshot_list('tank/CentOS-7')
#result=KVMApi(linuxserver_credit).zfs_clone_snapshot('tank/CentOS-7@2020-08-25')
#result=KVMApi(linuxserver_credit).create_kvm_xml('CentOS-7@test3','tank/CentOS-7@2020-08-28','CentOS-7@2020-08-28','2','1024')
#result=KVMApi(linuxserver_credit).define('kvm_1')
#result=KVMApi(linuxserver_credit).start('CentOS-7@2020-08-30')
#result=KVMApi(linuxserver_credit).shutdown('Test-1')
#result=KVMApi(linuxserver_credit).zfs_list()
#result=KVMApi(linuxserver_credit).zfs_kvm_filesystem()
#result=KVMApi(linuxserver_credit).snapshot_list('Test-1')
#print(result)
#result=KVMApi(linuxserver_credit).guestmount('CentOS-7','tank/CentOS-7@test1')
#result=KVMApi(linuxserver_credit).alert_ip('192.168.1.180')
#result=KVMApi(linuxserver_credit).alert_hostname('CentOS-7@test5')
#result=KVMApi(linuxserver_credit).guestmount_umount()
#result=KVMApi(linuxserver_credit).alert_ip_hostname_sh('CentOS-7','tank/CentOS-7-test2','192.168.1.197','CentOS-7-test2')
#print(result)
#result=KVMApi(linuxserver_credit).kvm_disk_space()
#result=KVMApi(linuxserver_credit).kvm_info_data('Test-1')
#result=KVMApi(linuxserver_credit).kvm_include_copy_list('CentOS-7')
#result=KVMApi(linuxserver_credit).zfs_kvm_filesystem()
#result=KVMApi(linuxserver_credit).kvm_template()
#print(result)
附:
kvm虚拟机cpu使用率(正在运行的kvm虚拟机)
#!/bin/pythonimportlibvirt
importtime
conn=libvirt.open("qemu:///system")
importsys
importjson
info={}
id=int(sys.argv[1])
dom=conn.lookupByID(id)
name=dom.name()
t1=time.time()
c1=int(dom.info()[4])
time.sleep(3)
t2=time.time();
c2=int(dom.info()[4])
c_nums=int(dom.info()[3])
cpu_usage=round((c2-c1)*100/((t2-t1)*c_nums*1e9),2)
info['cpu_usage']=cpu_usage
print(json.dumps(info))
test4.py
kvm虚拟机内存使用率(正在运行的kvm虚拟机)
#!/usr/bin/pythonimportlibvirt
conn=libvirt.open("qemu:///system")
importjson
importsys
id=int(sys.argv[1])
info={}
dom=conn.lookupByID(id)
infos=dom.info()
name=dom.name()
mem=infos[1]
dom.setMemoryStatsPeriod(10)
meminfo=dom.memoryStats()
free_mem=float(meminfo['unused'])
total_mem=float(meminfo['available'])
used_mem=total_mem-free_mem
mem_usage=round(((total_mem-free_mem)/total_mem)*100,2)
info['mem_usage']=mem_usage
info['mem_used']=round(used_mem/1024/1024,2)
info['mem_total']=round(total_mem/1024/1024,2)
info['mem_free']=round(free_mem/1024/1024,2)
print(json.dumps(info))
test4.py

