📄 xapi.py
字号:
#!/usr/bin/python#============================================================================# This library is free software; you can redistribute it and/or# modify it under the terms of version 2.1 of the GNU Lesser General Public# License as published by the Free Software Foundation.## This library is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU# Lesser General Public License for more details.## You should have received a copy of the GNU Lesser General Public# License along with this library; if not, write to the Free Software# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA#============================================================================# Copyright (C) 2006 XenSource Ltd.#============================================================================import sysimport timeimport reimport ossys.path.append('/usr/lib/python')from xen.util.xmlrpclib2 import ServerProxyfrom optparse import *from pprint import pprintfrom types import DictTypefrom getpass import getpass# Get default values from the environmentSERVER_URI = os.environ.get('XAPI_SERVER_URI', 'http://localhost:9363/')SERVER_USER = os.environ.get('XAPI_SERVER_USER', '')SERVER_PASS = os.environ.get('XAPI_SERVER_PASS', '')MB = 1024 * 1024HOST_INFO_FORMAT = '%-20s: %-50s'VM_LIST_FORMAT = '%(name_label)-18s %(memory_actual)-5s %(VCPUs_number)-5s'\ ' %(power_state)-10s %(uuid)-36s'SR_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(physical_size)-10s' \ '%(type)-10s'VDI_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(virtual_size)-8s'VBD_LIST_FORMAT = '%(device)-6s %(uuid)-36s %(VDI)-8s'TASK_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(status)-8s %(progress)-4s'VIF_LIST_FORMAT = '%(name)-8s %(device)-7s %(uuid)-36s %(MAC)-10s'CONSOLE_LIST_FORMAT = '%(uuid)-36s %(protocol)-8s %(location)-32s'COMMANDS = { 'host-info': ('', 'Get Xen Host Info'), 'host-set-name': ('', 'Set host name'), 'pif-list': ('', 'List all PIFs'), 'sr-list': ('', 'List all SRs'), 'vbd-list': ('', 'List all VBDs'), 'vbd-create': ('<domname> <pycfg> [opts]', 'Create VBD attached to domname'), 'vdi-create': ('<pycfg> [opts]', 'Create a VDI'), 'vdi-list' : ('', 'List all VDI'), 'vdi-rename': ('<vdi_uuid> <new_name>', 'Rename VDI'), 'vdi-destroy': ('<vdi_uuid>', 'Delete VDI'), 'vif-create': ('<domname> <pycfg>', 'Create VIF attached to domname'), 'vtpm-create' : ('<domname> <pycfg>', 'Create VTPM attached to domname'), 'vm-create': ('<pycfg>', 'Create VM with python config'), 'vm-destroy': ('<domname>', 'Delete VM'), 'vm-list': ('[--long]', 'List all domains.'), 'vm-name': ('<uuid>', 'Name of UUID.'), 'vm-shutdown': ('<name> [opts]', 'Shutdown VM with name'), 'vm-start': ('<name>', 'Start VM with name'), 'vm-uuid': ('<name>', 'UUID of a domain by name.'), 'async-vm-start': ('<name>', 'Start VM asynchronously'),}OPTIONS = { 'sr-list': [(('-l', '--long'), {'action':'store_true', 'help':'List all properties of SR'}) ], 'vdi-list': [(('-l', '--long'), {'action':'store_true', 'help':'List all properties of VDI'}) ], 'vif-list': [(('-l', '--long'), {'action':'store_true', 'help':'List all properties of VIF'}) ], 'vm-list': [(('-l', '--long'), {'action':'store_true', 'help':'List all properties of VMs'}) ], 'vm-shutdown': [(('-f', '--force'), {'help': 'Shutdown Forcefully', 'action': 'store_true'})], 'vdi-create': [(('--name-label',), {'help': 'Name for VDI'}), (('--name-description',), {'help': 'Description for VDI'}), (('--virtual-size',), {'type': 'int', 'default': 0, 'help': 'Size of VDI in bytes'}), (('--type',), {'choices': ['system', 'user', 'ephemeral'], 'default': 'system', 'help': 'VDI type'}), (('--sharable',), {'action': 'store_true', 'help': 'VDI sharable'}), (('--read-only',), {'action': 'store_true', 'help': 'Read only'}), (('--sr',), {})], 'vbd-create': [(('--VDI',), {'help': 'UUID of VDI to attach to.'}), (('--mode',), {'choices': ['RO', 'RW'], 'help': 'device mount mode'}), (('--driver',), {'choices':['paravirtualised', 'ioemu'], 'help': 'Driver for VBD'}), (('--device',), {'help': 'Device name on guest domain'})] }class OptionError(Exception): passclass XenAPIError(Exception): pass# # Extra utility functions#class IterableValues(Values): """Better interface to the list of values from optparse.""" def __iter__(self): for opt, val in self.__dict__.items(): if opt[0] == '_' or callable(val): continue yield opt, val def parse_args(cmd_name, args, set_defaults = False): argstring, desc = COMMANDS[cmd_name] parser = OptionParser(usage = 'xapi %s %s' % (cmd_name, argstring), description = desc) if cmd_name in OPTIONS: for optargs, optkwds in OPTIONS[cmd_name]: parser.add_option(*optargs, **optkwds) if set_defaults: default_values = parser.get_default_values() defaults = IterableValues(default_values.__dict__) else: defaults = IterableValues() (opts, extraargs) = parser.parse_args(args = list(args), values = defaults) return opts, extraargsdef execute(server, fn, args, async = False): if async: func = eval('server.Async.%s' % fn) else: func = eval('server.%s' % fn) result = func(*args) if type(result) != DictType: raise TypeError("Function returned object of type: %s" % str(type(result))) if 'Value' not in result: raise XenAPIError(*result['ErrorDescription']) return result['Value']_initialised = False_server = None_session = Nonedef connect(*args): global _server, _session, _initialised if not _initialised: # try without password or default credentials try: _server = ServerProxy(SERVER_URI) _session = execute(_server.session, 'login_with_password', (SERVER_USER, SERVER_PASS)) except: login = raw_input("Login: ") password = getpass() creds = (login, password) _server = ServerProxy(SERVER_URI) _session = execute(_server.session, 'login_with_password', creds) _initialised = True return (_server, _session)def _stringify(adict): return dict([(k, str(v)) for k, v in adict.items()])def _read_python_cfg(filename): cfg = {} execfile(filename, {}, cfg) return cfgdef resolve_vm(server, session, vm_name): vm_uuid = execute(server, 'VM.get_by_name_label', (session, vm_name)) if not vm_uuid: return None else: return vm_uuid[0]def resolve_vdi(server, session, vdi_name): vdi_uuid = execute(server, 'VDI.get_by_name_label', (session, vdi_name)) if not vdi_uuid: return None else: return vdi_uuid[0]## Actual commands#def xapi_host_info(args, async = False): server, session = connect() hosts = execute(server, 'host.get_all', (session,)) for host in hosts: # there is only one, but .. hostinfo = execute(server, 'host.get_record', (session, host)) print HOST_INFO_FORMAT % ('Name', hostinfo['name_label']) print HOST_INFO_FORMAT % ('Version', hostinfo['software_version']) print HOST_INFO_FORMAT % ('CPUs', len(hostinfo['host_CPUs'])) print HOST_INFO_FORMAT % ('VMs', len(hostinfo['resident_VMs'])) print HOST_INFO_FORMAT % ('UUID', host) for host_cpu_uuid in hostinfo['host_CPUs']: host_cpu = execute(server, 'host_cpu.get_record', (session, host_cpu_uuid)) print 'CPU %s Util: %.2f' % (host_cpu['number'], float(host_cpu['utilisation'])) def xapi_host_set_name(args, async = False): if len(args) < 1: raise OptionError("No hostname specified") server, session = connect() hosts = execute(server, 'host.get_all', (session,)) if len(hosts) > 0: execute(server, 'host.set_name_label', (session, hosts[0], args[0])) print 'Hostname: %s' % execute(server, 'host.get_name_label', (session, hosts[0]))def xapi_vm_uuid(args, async = False): if len(args) < 1: raise OptionError("No domain name specified") server, session = connect() vm_uuid = resolve_vm(server, session, args[0]) print vm_uuiddef xapi_vm_name(args, async = False): if len(args) < 1: raise OptionError("No UUID specified") server, session = connect() vm_name = execute(server, 'VM.get_name_label', (session, args[0])) print vm_namedef xapi_vm_list(args, async = False): opts, args = parse_args('vm-list', args, set_defaults = True) is_long = opts and opts.long list_only = args server, session = connect() vm_uuids = execute(server, 'VM.get_all', (session,)) if not is_long: print VM_LIST_FORMAT % {'name_label':'Name', 'memory_actual':'Mem', 'VCPUs_number': 'VCPUs', 'power_state': 'State', 'uuid': 'UUID'} for uuid in vm_uuids: vm_info = execute(server, 'VM.get_record', (session, uuid)) # skip domain if we don't want if list_only and vm_info['name_label'] not in list_only: continue if is_long: vbds = vm_info['VBDs'] vifs = vm_info['VIFs'] vtpms = vm_info['VTPMs'] vif_infos = [] vbd_infos = [] vtpm_infos = [] for vbd in vbds: vbd_info = execute(server, 'VBD.get_record', (session, vbd)) vbd_infos.append(vbd_info) for vif in vifs: vif_info = execute(server, 'VIF.get_record', (session, vif)) vif_infos.append(vif_info) for vtpm in vtpms: vtpm_info = execute(server, 'VTPM.get_record', (session, vtpm)) vtpm_infos.append(vtpm_info) vm_info['VBDs'] = vbd_infos vm_info['VIFs'] = vif_infos vm_info['VTPMs'] = vtpm_infos pprint(vm_info) else: print VM_LIST_FORMAT % _stringify(vm_info)def xapi_vm_create(args, async = False): if len(args) < 1: raise OptionError("Configuration file not specified") filename = args[0] cfg = _read_python_cfg(filename) print 'Creating VM from %s ..' % filename server, session = connect() uuid = execute(server, 'VM.create', (session, cfg), async = async) print 'Done. (%s)' % uuid print uuiddef xapi_vm_destroy(args, async = False): if len(args) < 1: raise OptionError("No domain name specified.") server, session = connect() vm_uuid = resolve_vm(server, session, args[0]) print 'Destroying VM %s (%s)' % (args[0], vm_uuid) success = execute(server, 'VM.destroy', (session, vm_uuid), async = async) print 'Done.' def xapi_vm_start(args, async = False): if len(args) < 1: raise OptionError("No Domain name specified.") server, session = connect() vm_uuid = resolve_vm(server, session, args[0]) print 'Starting VM %s (%s)' % (args[0], vm_uuid) success = execute(server, 'VM.start', (session, vm_uuid, False), async = async) if async: print 'Task started: %s' % success else: print 'Done.'def xapi_vm_suspend(args, async = False): if len(args) < 1: raise OptionError("No Domain name specified.") server, session = connect() vm_uuid = resolve_vm(server, session, args[0]) print 'Suspending VM %s (%s)' % (args[0], vm_uuid) success = execute(server, 'VM.suspend', (session, vm_uuid), async = async) if async: print 'Task started: %s' % success else: print 'Done.' def xapi_vm_resume(args, async = False): if len(args) < 1: raise OptionError("No Domain name specified.") server, session = connect() vm_uuid = resolve_vm(server, session, args[0]) print 'Resuming VM %s (%s)' % (args[0], vm_uuid) success = execute(server, 'VM.resume', (session, vm_uuid, False), async = async) if async: print 'Task started: %s' % success else: print 'Done.'def xapi_vm_pause(args, async = False): if len(args) < 1: raise OptionError("No Domain name specified.") server, session = connect() vm_uuid = resolve_vm(server, session, args[0]) print 'Pausing VM %s (%s)' % (args[0], vm_uuid) success = execute(server, 'VM.pause', (session, vm_uuid), async = async) if async: print 'Task started: %s' % success else: print 'Done.'def xapi_vm_unpause(args, async = False): if len(args) < 1: raise OptionError("No Domain name specified.") server, session = connect() vm_uuid = resolve_vm(server, session, args[0]) print 'Pausing VM %s (%s)' % (args[0], vm_uuid) success = execute(server, 'VM.unpause', (session, vm_uuid), async = async) if async: print 'Task started: %s' % success else: print 'Done.' def xapi_task_list(args, async = False): server, session = connect() all_tasks = execute(server, 'task.get_all', (session,)) print TASK_LIST_FORMAT % {'name_label': 'Task Name', 'uuid': 'UUID', 'status': 'Status', 'progress': '%'} for task_uuid in all_tasks: task = execute(server, 'task.get_record', (session, task_uuid)) print TASK_LIST_FORMAT % taskdef xapi_task_clear(args, async = False): server, session = connect() all_tasks = execute(server, 'task.get_all', (session,)) for task_uuid in all_tasks: success = execute(server, 'task.destroy', (session, task_uuid)) print 'Destroyed Task %s' % task_uuiddef xapi_vm_shutdown(args, async = False): opts, args = parse_args("vm-shutdown", args, set_defaults = True) if len(args) < 1: raise OptionError("No Domain name specified.") server, session = connect() vm_uuid = resolve_vm(server, session, args[0]) if opts.force: print 'Forcefully shutting down VM %s (%s)' % (args[0], vm_uuid) success = execute(server, 'VM.hard_shutdown', (session, vm_uuid), async = async) else: print 'Shutting down VM %s (%s)' % (args[0], vm_uuid) success = execute(server, 'VM.clean_shutdown', (session, vm_uuid), async = async) if async: print 'Task started: %s' % success else: print 'Done.'def xapi_vbd_create(args, async = False):
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -