java中的接口是类吗
332
2022-08-31
Python脚本管理KVM虚拟机(虚拟机运行python)
python脚本:连接Linux
"""paramiko, pywinrm实现windows/linux脚本调用linux下脚本语法错误,或者命令不存在等没有通过stderr变量接收到,只能添加判断条件;windows下可以接收到错误信息并作出判断;"""import paramikoimport winrmimport socketimport requestsimport datetimefrom winrm.exceptions import WinRMTransportError, WinRMOperationTimeoutError, WinRMErrorfrom requests.exceptions import ConnectionError################################################################ 为实现 WINDOWS下执行脚本时长超时设置,对wimrm中相关类进行重写。################################################################# 重写Protocol类class Protocol(winrm.protocol.Protocol): def get_command_output(self, shell_id, command_id): """ Get the Output of the given shell and command @param string shell_id: The shell id on the remote machine. See #open_shell @param string command_id: The command id on the remote machine. See #run_command #@return [Hash] Returns a Hash with a key :exitcode and :data. Data is an Array of Hashes where the cooresponding key # is either :stdout or :stderr. The reason it is in an Array so so we can get the output in the order it ocurrs on # the console. """ stdout_buffer, stderr_buffer = [], [] command_done = False ############################################################################ # 限时6*60s # # 程序反复查看相应,如果相应成功,且在超时时限内则命令成功,否则报超时异常。 # # 获取响应的时长较长。 # ############################################################################ return_code = -1 limited_seconds = 6 * 60 start_time = datetime.datetime.now() while not command_done: print('get the response from windows...') try: stdout, stderr, return_code, command_done = \ self._raw_get_command_output(shell_id, command_id) stdout_buffer.append(stdout) stderr_buffer.append(stderr) except WinRMOperationTimeoutError as e: # this is an expected error when waiting for a long-running process, just silently retry pass end_time = datetime.datetime.now() delta_time = end_time - start_time total_seconds = delta_time.total_seconds() if total_seconds > limited_seconds: raise WinRMOperationTimeoutError() return b''.join(stdout_buffer), b''.join(stderr_buffer), return_code# 重写Session类class Session(winrm.Session): # TODO implement context manager methods 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)class ServerByPara(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 def exec_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) as e: 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) if stderr.read(): exec_tag = 1 data_init = str(stderr.read(), encoding='utf-8') # for data in stderr.readlines(): # data_init += data log = "" else: exec_tag = 0 log = "" try: data_init = str(stdout.read(), encoding='utf-8') if data_init: data_init = " ".join(data_init.split("\r\n")) if "command not found" in data_init: # 命令不存在 exec_tag = 1 log = "命令不存在" elif "syntax error" in data_init: # 语法错误 exec_tag = 1 log = "语法错误" elif "No such file or directory" in data_init: # 脚本不存在 exec_tag = 1 log = "脚本不存在" elif succeedtext is not None: if succeedtext not in data_init: exec_tag = 1 log = "未匹配" except Exception as e: print(e) exec_tag = 0 # 不抛错 log = "编码错误" data_init = "编码错误" except socket.timeout as e: print("脚本执行超时") return { "exec_tag": 1, "data": "脚本执行超时", "log": "脚本执行超时", } return { "exec_tag": exec_tag, "data": data_init, "log": log, } def exec_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) as e: if type(e) == WinRMOperationTimeoutError: print("脚本执行超时") exec_tag = 1 data = "脚本执行超时 {0}".format(e) log = "脚本执行超时" elif type(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: if ret.std_err: data_init = str(ret.std_err, encoding='gbk') exec_tag = 1 # for data in ret.std_err.decode().split("\r\n"): # data_init += data log = "" else: exec_tag = 0 try: data_init = str(ret.std_out, encoding='gbk') if data_init: data_init = "".join(data_init.split("\r\n")) # for data in ret.std_out.decode().split("\r\n"): # data_init += data except Exception as e: print(e) exec_tag = 0 # 不抛错 log = "编码错误" data_init = "编码错误" else: if succeedtext is not None: if succeedtext not in data_init: exec_tag = 1 log = "未匹配" return { "exec_tag": exec_tag, "data": data_init, "log": log, } def run(self, succeedtext,linux_timeout=6* 60): if self.system_choice == "Linux": result = self.exec_linux_cmd(succeedtext, linux_timeout) if self.client: self.client.close() elif self.system_choice == "AIX": result = self.exec_linux_cmd(succeedtext, linux_timeout, port=22) if self.client: self.client.close() else: result = self.exec_win_cmd(succeedtext) # print(result) return resultif __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虚拟机开机、关机、克隆、快照等。
from drm import remotefrom lxml import etreeimport timeimport jsonclass KVMApi(): def __init__(self, credit): self.ip = credit['KvmHost'] self.username = credit['KvmUser'] self.password = credit['KvmPasswd'] self.system_tag = credit['SystemType'] def remote_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) return result def list_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) for i in list_of_group] count = len(list_info) % per_list_len end_list.append(list_info[-count:]) if count != 0 else end_list return end_list def domstate(self, kvm_name): # 获取虚拟机的状态 exe_cmd = r'virsh domstate {0}'.format(kvm_name) result = self.remote_linux(exe_cmd) result = result['data'].strip() return result def kvm_all_list(self): # 获取所有kvm虚拟机 exe_cmd = r'virsh list --all' result = self.remote_linux(exe_cmd) kvm_list = [x for x in result['data'].split(' ') if x] del kvm_list[0:4] kvm_list_filter = [] for i in kvm_list: if i == 'shut': continue if i == 'off': i = '关闭' if i == 'running': i = '运行中' if i == 'paused': i = '暂停' kvm_list_filter.append(i) end_list = self.list_of_groups(kvm_list_filter, 3) kvm_all_list_dict = [] for item in end_list: data = {} data['id'] = item[0] data['name'] = item[1] data['state'] = item[2] kvm_all_list_dict.append(data) return kvm_all_list_dict def kvm_exclude_copy_list(self): # 获取除实例之外所有kvm虚拟机 exe_cmd = r'virsh list --all' result = self.remote_linux(exe_cmd) kvm_list = [x for x in result['data'].split(' ') if x] del kvm_list[0:4] kvm_list_filter = [] for i in kvm_list: if i == 'shut': continue if i == 'off': i = '关闭' if i == 'running': i = '运行中' if i == 'paused': i = '暂停' kvm_list_filter.append(i) end_list = self.list_of_groups(kvm_list_filter, 3) kvm_all_list_dict = [] for item in end_list: data = {} if '@' not in item[1]: data['id'] = item[0] data['name'] = item[1] data['state'] = item[2] kvm_all_list_dict.append(data) return kvm_all_list_dict def kvm_include_copy_list(self, kvm_copy_name): # 获取所有实例虚拟机 exe_cmd = r'virsh list --all' result = self.remote_linux(exe_cmd) kvm_list = [x for x in result['data'].split(' ') if x] del kvm_list[0:4] kvm_list_filter = [] for i in kvm_list: if i == 'shut': continue if i == 'off': i = '关闭' if i == 'running': i = '运行中' if i == 'paused': i = '暂停' kvm_list_filter.append(i) end_list = self.list_of_groups(kvm_list_filter, 3) kvm_all_list_dict = [] for item in end_list: data = {} copyname = kvm_copy_name + '@' if copyname in item[1]: data['id'] = item[0] data['name'] = item[1] data['state'] = item[2] kvm_all_list_dict.append(data) return kvm_all_list_dict def kvm_run_list(self): # 获取正在运行的虚拟机 exe_cmd = r'virsh list' result = self.remote_linux(exe_cmd) kvm_list = [x for x in result['data'].split(' ') if x] del kvm_list[0:3] end_list = self.list_of_groups(kvm_list, 3) kvm_all_list_dict = [] for item in end_list: data = {} data['id'] = item[0] data['name'] = item[1] data['state'] = item[2] kvm_all_list_dict.append(data) return kvm_all_list_dict def kvm_start(self, kvm_state, kvm_name): # 开启虚拟机:是关闭的状态(shut off/关闭) if kvm_state == 'shut off' or kvm_state == '关闭': exe_cmd = r'virsh start {0}'.format(kvm_name) result = self.remote_linux(exe_cmd) if result['data'].strip() == 'Domain {0} started'.format(kvm_name) or \ result['data'].strip() == '域 {0} 已开始'.format(kvm_name): result = '开机成功。' else: result = '开机失败。' else: result = '虚拟机已开启。' return result def kvm_shutdown(self, kvm_state, kvm_name): # 关闭虚拟机:是开启的状态(running) if kvm_state == 'running' or kvm_state == '运行中': exe_cmd = r'virsh shutdown {0}'.format(kvm_name) result = self.remote_linux(exe_cmd) if result['data'].strip() == 'Domain {0} is being shutdown'.format(kvm_name) or \ result['data'].strip() == '域 {0} 被关闭'.format(kvm_name): time.sleep(5) state = self.domstate(kvm_name) if state == 'shut off' or state == '关闭': result = '关闭成功。' else: result = '关闭失败。' else: result = '关闭失败。' elif kvm_state == '暂停' or kvm_state == 'paused': result = '虚拟机未运行。' else: result = '虚拟机未开启。' return result def kvm_destroy(self, kvm_state, kvm_name): # 断电虚拟机:是开启的状态(running)或者是暂停状态(pasued) if kvm_state == 'running' or kvm_state == '运行中' or kvm_state == 'paused' or kvm_state == '暂停': exe_cmd = r'virsh destroy {0}'.format(kvm_name) result = self.remote_linux(exe_cmd) if result['data'].strip() == 'Domain {0} destroyed'.format(kvm_name) or \ result['data'].strip() == '域 {0} 被删除'.format(kvm_name): result = '断电成功。' else: result = '断电失败。' else: result = '虚拟机未开启。' return result def filesystem_del(self, filesystem): try: exe_cmd = r'zfs destroy {0}'.format(filesystem) result = self.remote_linux(exe_cmd) if result['data'] == '': result = '删除文件系统成功。' else: result = '删除文件系统成功。' except Exception as e: print(e) result = '删除文件系统失败。' return result def undefine(self, kvm_name, state): """ 删除虚拟机 停止主机:virsh shutdown linux65 删除主机定义:virsh undefine linux65 删除KVM虚拟机文件系统: zfs destroy tank/CentOS-7@test3 """ # 这里需要先判断虚拟机的状态 # 如果是关闭(shut off)的虚拟机直接删除,然后删除磁盘文件,如果是开启(running)的虚拟机,先关闭再删除虚拟机,在删除磁盘文件 # 如果虚拟机中创建了快照,虚拟机是无法删除的,需要删除所有的快照,然后在执行删除虚拟机操作 if state == 'shut off' or state == '关闭': snapshot_list = self.snapshot_list(kvm_name) if not snapshot_list: try: exe_cmd = r'virsh undefine {0}'.format(kvm_name) result = self.remote_linux(exe_cmd) if result['data'].strip() == 'Domain {0} has been undefined'.format(kvm_name) or \ result['data'].strip() == '域 {0} 已经被取消定义'.format(kvm_name): result = '取消定义成功。' else: result = '取消定义失败。' except Exception as e: print(e) result = '取消定义失败。' else: result = '虚拟机已创建快照,无法删除。' else: result = '虚拟机未关闭。' return result def kvm_suspend(self, kvm_state, kvm_name): """ 暂停虚机:开启(ruuning)/暂停(paused)的状态,关闭状态提醒错误。 """ if kvm_state == 'running' or kvm_state == '运行中' or kvm_state == 'paused' or kvm_state == '暂停': exe_cmd = r'virsh suspend {0}'.format(kvm_name) result = self.remote_linux(exe_cmd) if result['data'].strip() == 'Domain {0} suspended'.format(kvm_name) or \ result['data'].strip() == '域 {0} 被挂起'.format(kvm_name): result = '暂停成功。' else: result = '暂停失败。' else: result = '虚拟机未开启。' return result def kvm_resume(self, kvm_state, kvm_name): """ 恢复暂停的虚机:必须是暂停(paused)状态的虚拟机才可以执行恢复操作 """ if kvm_state == 'paused' or kvm_state == '暂停': exe_cmd = r'virsh resume {0}'.format(kvm_name) result = self.remote_linux(exe_cmd) if result['data'].strip() == 'Domain {0} resumed'.format(kvm_name) or \ result['data'].strip() == '域 {0} 被重新恢复'.format(kvm_name): result = '运行成功。' else: result = '运行失败。' else: result = '虚拟机非暂停状态,无法执行此操作。' return result def kvm_reboot(self, kvm_state, kvm_name): """ 重启虚机:必须是开启(running)/暂停(paused)状态的虚拟机才可以执行重启操作 """ if kvm_state == 'running' or kvm_state == '运行中' or kvm_state == '暂停' or kvm_state == 'paused': exe_cmd = r'virsh reboot {0}'.format(kvm_name) result = self.remote_linux(exe_cmd) if result['data'].strip() == 'Domain {0} is being rebooted'.format(kvm_name) or \ result['data'].strip() == '域 {0} 正在被重新启动'.format(kvm_name): result = '重启成功。' else: result = '重启失败。' else: result = '虚拟机未开启。' return result def kvm_clone(self, kvm_state, kvm_name, kvm_name_clone, filesystem): """ 克隆虚拟机:需要在关机或者暂停的状态下才可以进行克隆 克隆出错:ERROR Domain with devices to clone must be paused or shutoff. 克隆成功:Allocating 'Test-3.qcow2' | 80 GB 00:02 Clone 'Test-3' created successfully. virt-clone -o win2k16 -n Test-1 -f /var/lib/libvirt/images/Test—1.qcow2 注:-o:original 后面跟要克隆的虚拟机名字 -n:name 克隆后虚拟机的名字 -f:file 指定镜像存放的路径:默认路径:/var/lib/libvirt/images 新的虚拟机存在报错:ERROR Invalid name for new guest: Guest name 'Test-3' is already in use. """ # 判断虚拟机的状态 disk_path = '/' + filesystem + '/' + kvm_name_clone + '.qcow2' if kvm_state == 'shut off' or kvm_state == 'paused' or kvm_state == '关闭' or kvm_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}' created successfully.".format(kvm_name_clone) or \ "成功克隆 '{0}'".format(kvm_name_clone) in result['data']: result = '克隆成功。' else: result = '克隆失败。' else: result = '虚拟机未关闭。' return result def kvm_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 } return kvm_info def snapshot_create(self, kvm_name): # 创建快照 # 创建成功提示信息:Domain snapshot 1596685828 created exe_cmd = r'virsh snapshot-create {0}'.format(kvm_name) result = self.remote_linux(exe_cmd) if 'created' in result['data'] or '已生成域快照' in result['data']: result = '虚拟机{0}创建快照成功。'.format(kvm_name) else: result = '虚拟机{0}创建快照失败。'.format(kvm_name) return result def snapshot_list(self, kvm_name): # 查看快照列表 exe_cmd = r'virsh snapshot-list {0}'.format(kvm_name) result = self.remote_linux(exe_cmd) list = [x for x in result['data'].split(' ') if x] del list[0:4] end_list = self.list_of_groups(list, 5) snapshot_list_dict = [] for item in end_list: data = {} data['name'] = item[0] snapshot_list_dict.append(data) """ [{'name': '1596684491'}, {'name': '1596685828'}] """ return snapshot_list_dict def snapshot_del(self, kvm_name, snapshotname): # 删除快照 exe_cmd = r'virsh snapshot-delete {0} --snapshotname {1}'.format(kvm_name, snapshotname) result = self.remote_linux(exe_cmd) if result['data'] == 'Domain snapshot {0} deleted'.format(snapshotname) or result['data'] == '已删除域快照': result = '快照{0}删除成功。'.format(snapshotname) else: result = '快照{0}删除失败。'.format(snapshotname) return result def snapshot_revert(self, kvm_name, snapshotname): # 恢复快照:虚拟机是关机的状态 state = self.domstate(kvm_name) if state == 'shut off': exe_cmd = r'virsh snapshot-revert {0} --snapshotname {1}'.format(kvm_name, snapshotname) self.remote_linux(exe_cmd) result = '恢复到快照{0}成功。'.format(snapshotname) else: result = '请先关闭虚拟机,再执行恢复操作。'.format(kvm_name) return result def zfs_kvm_filesystem(self): exe_cmd = r'ls /data/vmdata'.format() result = self.remote_linux(exe_cmd) kvm_filesystem = [x.replace('\t', '') for x in result['data'].split(' ') if x] return kvm_filesystem def create_filesystem(self, filesystem): """ 为每一台虚拟机分别创建一个文件系统 tank/kvm_1 tank/kvm_2 tank/kvm_3 zfs创建文件系统:zfs create tank/kvm_1 zfs_pool_data:文件系统路径 """ try: exe_cmd = r'zfs create {0}'.format(filesystem) result = self.remote_linux(exe_cmd) if result['data'] == '': result = '文件系统创建成功。' else: result = '文件系统创建失败。' except: result = '文件系统创建失败。' return result def zfs_create_snapshot(self, snapshot_name): """ 创建快照:zfs snapshot tank/kvm_1@2020-07-28 kvm_name:虚拟机 zfs_snapshot_name:快照名字 """ try: exe_cmd = r'zfs snapshot {0}'.format(snapshot_name) result = self.remote_linux(exe_cmd) if result['data'] == '': info = '创建成功。' else: info = '创建失败。' except: info = '创建失败。' return info def zfs_snapshot_list(self, filesystem): """ 查看zfs快照:zfs list -t snapshot -r tank/kvm_1 """ exe_cmd = r'zfs list -t snapshot -r {0}'.format(filesystem) result = self.remote_linux(exe_cmd) snapshot_list = [x for x in result['data'].split(' ') if x] del snapshot_list[0:5] end_list = self.list_of_groups(snapshot_list, 5) zfs_snapshot_list_dict = [] for item in end_list: data = {} item = item[0].split('@') data['name'] = item[1] zfs_snapshot_list_dict.append(data) return zfs_snapshot_list_dict def zfs_snapshot_del(self, snapshot_name): """ 删除快照:zfs destroy mypool/data@2020-07-28 """ try: exe_cmd = r'zfs destroy {0}'.format(snapshot_name) result = self.remote_linux(exe_cmd) if result['data'] == '': info = '删除快照成功。' else: info = '删除快照失败。' except: info = '快照已挂载,删除失败。' return info def zfs_clone_snapshot(self, snapshot_name, filesystem_name): """ 克隆快照:zfs clone tank/kvm_1@2020-08-20 tank/kvm_1@2020-08-20 kvm_name kvm_snapshot_name kvm_snapshot_clone_name """ try: exe_cmd = r'zfs clone {0} {1}'.format(snapshot_name, filesystem_name) result = self.remote_linux(exe_cmd) if result['data'] == '': info = '克隆成功。' else: info = '克隆失败。' except: info = '克隆失败。' return info def create_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] if copycpu != '' and copymemory != '': 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) elif copycpu != '' and copymemory == '': kvm_cpu = config.xpath("//vcpu")[0] kvm_cpu.text = copycpu elif copycpu == '' and copymemory != '': 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 = '生成失败。' return info def define_kvm(self, copy_name): """ 通过xml文件定义虚拟机 virsh define /etc/libvirt/qemu/kvm_1.xml """ xml_path = '/etc/libvirt/qemu/{0}.xml'.format(copy_name) exe_cmd = r'virsh define {0}'.format(xml_path) result = self.remote_linux(exe_cmd) # 定义域 CentOS-7@test4(从 /etc/libvirt/qemu/CentOS-7@test4.xml) if result['data'].strip() == 'Domain {0} defined from {1}'.format(copy_name, xml_path) or \ result['data'].strip() == '定义域 {0}(从 {1})'.format(copy_name, xml_path): result = '定义成功。' else: result = '定义失败。' return result def guestmount(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} && sleep 1'.format(kvm_disk_path, kvm_mount) self.remote_linux(exe_cmd) result = '挂载成功。' except Exception as e: print(e) result = '挂载失败。' return result def alert_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地址 echo CentOS-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) if result['data'] == '': result = '修改成功。' else: result = '修改失败。' except Exception as e: print(e) result = '修改失败。' return result def umount(self): """ 取消挂载:umount /etc/libvirt/kvm_mount """ try: exe_cmd = r'umount /etc/libvirt/kvm_mount' result = self.remote_linux(exe_cmd) if result['data'] == '': result = '取消挂载成功。' else: result = '取消挂载失败' except Exception as e: print(e) result = '取消挂载失败。' return result def kvm_disk_space(self): """ 获取kvm文件系统磁盘使用情况:zfs list """ exe_cmd = r'zfs list' result = self.remote_linux(exe_cmd) kvm_space_list = [x for x in result['data'].split(' ') if x] del kvm_space_list[0:5] end_list = self.list_of_groups(kvm_space_list, 5) data = {} for item in end_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 return data def memory_disk_cpu_data(self): """ 宿主机查看内存使用率:cat /proc/meminfo 查看cpu使用率 查看磁盘使用率 查看操作系统 查看主机名 """ data = '' try: # 内存 exe_cmd = r'cat /proc/meminfo' result = self.remote_linux(exe_cmd) memory_info = [x for x in result['data'].split(' ') if x] 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 = [x for x in result['data'].split(' ') if x] del disk_info[0:6] end_list = self.list_of_groups(disk_info, 6) disk_info_list = [] for item in end_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 for i in disk_info_list: if i['mount'] == '/' or i['mount'] == '/data' or i['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 "physical id"| 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 } except Exception as e: print(e) return data def kvm_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'] except Exception as e: 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, } return data def kvm_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 = [x for x in result['data'].split(' ') if x] del kvm_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] } except Exception as e: print(e) data = {"kvm_disk_usage": kvm_disk_usage} return data def kvm_template(self): # kvm虚拟机模板文件: cd /home/images try: exe_cmd = r'ls /home/images' result = self.remote_linux(exe_cmd) result = [x.replace('\t', ' ').split(' ') for x in result['data'].split(' ') if x][0] except Exception as e: print(e) result = '查找kvm模板文件失败。' return result def copy_disk(self, kvm_template_path, filesystem): try: exe_cmd = r'cp {0} {1}'.format(kvm_template_path, filesystem) result = self.remote_linux(exe_cmd) if result['data'] == '': result = '拷贝磁盘文件成功。' else: result = '拷贝磁盘文件失败。' except Exception as e: print(e) result = '拷贝磁盘文件失败。' return result def create_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 = '生成失败。' return infolinuxserver_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/pythonimport libvirtimport timeconn = libvirt.open("qemu:///system")import sysimport jsoninfo = {}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_usageprint(json.dumps(info))
test4.py
kvm虚拟机内存使用率(正在运行的kvm虚拟机)
#!/usr/bin/pythonimport libvirtconn = libvirt.open("qemu:///system")import jsonimport sysid = 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_memmem_usage = round(((total_mem-free_mem) / total_mem)*100, 2)info['mem_usage'] = mem_usageinfo['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
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~