From 94b82106ac8c34cf561abca2994262b3c981ba9d Mon Sep 17 00:00:00 2001 From: Thomas S Hatch Date: Tue, 28 May 2013 16:37:40 -0600 Subject: [PATCH] Deprecate kvm_hyper in favor of virt --- salt/modules/kvm_hyper.py | 504 -------------------------------------- 1 file changed, 504 deletions(-) delete mode 100644 salt/modules/kvm_hyper.py diff --git a/salt/modules/kvm_hyper.py b/salt/modules/kvm_hyper.py deleted file mode 100644 index 2c52646c91..0000000000 --- a/salt/modules/kvm_hyper.py +++ /dev/null @@ -1,504 +0,0 @@ -''' -Provide the hyper module for kvm hypervisors. This is the interface used to -interact with kvm on behalf of the salt-virt interface - -:depends: - libvirt Python module -''' - -# This is a test interface for the salt-virt system. The API in this file is -# VERY likely to change. - - -# Import python libs -import logging -import os -import shutil -import string -import subprocess -from xml.dom import minidom - -# Import third party libs -import yaml -try: - import libvirt - HAS_LIBVIRT = True -except ImportError: - HAS_LIBVIRT = False - -# Import salt libs -import salt.utils -from salt._compat import StringIO - -log = logging.getLogger(__name__) - -VIRT_STATE_NAME_MAP = {0: "running", - 1: "running", - 2: "running", - 3: "paused", - 4: "shutdown", - 5: "shutdown", - 6: "crashed"} - - -def __virtual__(): - ''' - Apply this module as the hyper module if the minion is a kvm hypervisor - ''' - if 'virtual' not in __grains__: - return False - if __grains__['virtual'] != 'physical': - return False - if __grains__['kernel'] != 'Linux': - return False - if not os.path.exists('/proc/modules'): - return False - try: - if 'kvm_' not in salt.utils.fopen('/proc/modules').read(): - return False - except IOError: - return False - if not HAS_LIBVIRT: - return False - - #Libvirt is very noisy. This will quiet it down - def quiet_errors(ignored, err): - log.debug(err[2]) - - libvirt.registerErrorHandler(quiet_errors, None) - try: - libvirt_conn = libvirt.open('qemu:///system') - libvirt_conn.close() - return 'hyper' - except libvirt.libvirtError: - return False - - -def __get_conn(): - ''' - Connects to the libvirt daemon for qemu/kvm - ''' - return libvirt.open("qemu:///system") - - -def _get_dom(vm_): - ''' - Return a domain object for the named vm - ''' - conn = __get_conn() - if vm_ not in list_virts(): - raise Exception('The specified vm is not present') - return conn.lookupByName(vm_) - -# Define tier 1 Virt functions, all hyper interfaces have these: -# hyper_type -# list_virts -# hyper_info -# get_conf - - -def hyper_type(): - ''' - Return that type of hypervisor this is - - CLI Example:: - - salt '*' hyper.hyper_type - ''' - return 'kvm' - - -def freemem(): - ''' - Return an int representing the amount of memory that has not been given - to virtual machines on this node - - CLI Example:: - - salt '*' hyper.freemem - ''' - conn = __get_conn() - mem = conn.getInfo()[1] - # Take off just enough to sustain the hypervisor - mem -= 256 - for vm_ in list_virts(): - dom = _get_dom(vm_) - if dom.ID() > 0: - mem -= dom.info()[2] / 1024 - return mem - - -def freecpu(): - ''' - Return an int representing the number of unallocated cpus on this - hypervisor - - CLI Example:: - - salt '*' hyper.freecpu - ''' - conn = __get_conn() - cpus = conn.getInfo()[2] - for vm_ in list_virts(): - dom = _get_dom(vm_) - if dom.ID() > 0: - cpus -= dom.info()[3] - return cpus - - -def list_virts(): - ''' - Return a list of virtual machine names on the minion - - CLI Example:: - - salt '*' hyper.list_virts - ''' - # Expand to include down vms - conn = __get_conn() - vms = [] - for id_ in conn.listDomainsID(): - vms.append(conn.lookupByID(id_).name()) - return vms - - -def virt_info(): - ''' - Return detailed information about the vms on this hyper in a dict:: - - {'cpu': , - 'maxMem': , - 'mem': , - 'state': '', - 'cputime' } - - CLI Example:: - - salt '*' hyper.virt_info - ''' - info = {} - for vm_ in list_virts(): - dom = _get_dom(vm_) - raw = dom.info() - info[vm_] = { - 'state': VIRT_STATE_NAME_MAP.get(raw[0], 'unknown'), - 'maxMem': int(raw[1]), - 'mem': int(raw[2]), - 'cpu': raw[3], - 'cputime': int(raw[4]), - 'disks': get_disks(vm_), - } - return info - - -def hyper_info(): - ''' - Return a dict with information about this hypervisor - - CLI Example:: - - salt '*' hyper.hyper_info - ''' - conn = __get_conn() - raw = conn.getInfo() - info = { - 'phymemory': raw[1], - 'cpus': raw[2], - 'cpumhz': raw[3], - 'cpucores': raw[6], - 'cputhreads': raw[7], - 'type': hyper_type(), - 'freecpu': freecpu(), - 'freemem': freemem(), - 'virt_info': virt_info(), - } - return info - -# Level 2 - vm class specific -# init - Create a vm from options -# start - Start a down vm -# halt -# purge -# pause -# resume -# set_autostart -# get_disks -# get_conf - - -def _get_image(image, vda): - ''' - Copy the image into place - ''' - if ':' in image: - if not os.path.isabs(image) or not image.startswith('file://'): - # The image is on a network resource - env = 'base' - if image.rindex(':') != 4: - env = image.split(':')[-1] - image = image[:image.rindex(':')] - __salt__['cp.get_url'](image, vda, env) - if os.path.isabs(image) or image.startswith('file://'): - # This is a local file, copy it into place - if image.startswith('file://'): - # Condition this into a standard path - for ind in range(6, len(image)): - if image[ind].isalpha(): - image = os.path.join('/', image[ind:]) - break - shutil.copy2(image, vda) - - -def _gen_xml(name, - cpus, - mem, - vmdir, - disks, - network, - desc, - opts): - ''' - Generate the XML used for the libvirt configuration - ''' - # Don't generate the libvirt config if it already exists - vda = os.path.join(vmdir, 'vda') - data = ''' - - %%NAME%% - %%CPU%% - %%MEM%% - - hvm - - - - /usr/bin/kvm - - - - - - %%DISK%% - %%NICS%% - - - - - - - ''' - data = data.replace('%%NAME%%', name) - data = data.replace('%%CPU%%', str(cpus)) - data = data.replace('%%MEM%%', str(int(mem) * 1024)) - data = data.replace('%%VDA%%', vda) - nics = '' - for interface, data in network.items(): - for bridge, mac in data.items(): - if not mac: - # Generate this interface's mac addr, use the qemu default - # prefix, 52:54 - mac = salt.utils.gen_mac('52:54:') - nic = ''' - - - - - \n''' - nic = nic.replace('%%BRIDGE%%', bridge) - nic = nic.replace('%%MAC%%', mac) - nics += nic - data = data.replace('%%NICS%%', nics) - - if disks: - letters = string.ascii_lowercase - disk_str = '' - for ind in range(0, len(disks)): - disk = disks[ind] - disk_d = ''' - - - - - - ''' - - disk_d = disk_d.replace('%%DISK_PATH%%', disk['path']) - disk_d = disk_d.replace('%%TYPE%%', disk['format']) - disk_d = disk_d.replace('%%VD%%', 'vd' + letters[ind + 1]) - - disk_str += disk_d - data = data.replace('%%DISK%%', disk_str) - else: - data = data.replace('%%DISK%%', '') - return data - - -def init( - name, - cpus, - mem, - image, - storage_dir, - network=None, - desc='', - opts=None): - ''' - Create a KVM virtual machine based on these passed options, the virtual - machine will be started upon creation - - CLI Example: - - salt '*' hyper.init webserver 2 2048 salt://fedora/f16.img:virt /srv/vm/images - ''' - if network is None: - network = {'eth0': {'bridge': 'br0', 'mac': ''}} - vmdir = os.path.join(storage_dir, name) - if not os.path.exists(vmdir): - os.makedirs(vmdir) - vda = os.path.join(vmdir, 'vda') - _get_image(image, vda) - # The image is in place - xml = _gen_xml(name, cpus, mem, vmdir, network, desc, opts or {}) - config = os.path.join(vmdir, 'config.xml') - salt.utils.fopen(config, 'w+').write(xml) - return start(config) - - -def start(config): - ''' - Start an already defined virtual machine that has been shut down - - CLI Example:: - - salt '*' hyper.start webserver - ''' - # change this to use the libvirt API and add more logging and a verbose - # return - cmd = 'virsh create {0}'.format(config) - return not __salt__['cmd.retcode'](cmd) - - -def halt(name): - ''' - Hard power down a virtual machine - - CLI Example:: - - salt '*' hyper.halt webserver - ''' - try: - dom = _get_dom(name) - dom.destroy() - except Exception: - return False - return True - - -def purge(name): - ''' - Hard power down and purge a virtual machine, this will destroy a vm and - all associated vm data - - CLI Example:: - - salt '*' hyper.purge webserver - ''' - disks = get_disks(name) - halt(name) - directories = set() - for disk in disks: - os.remove(disks[disk]['file']) - directories.add(os.path.dirname(disks[disk]['file'])) - if directories: - for dir_ in directories: - shutil.rmtree(dir_) - return True - - -def pause(name): - ''' - Pause the named virtual machine - - CLI Example:: - - salt '*' hyper.pause webserver - ''' - dom = _get_dom(name) - dom.suspend() - return True - - -def resume(name): - ''' - Resume the named virtual machine - - CLI Example:: - - salt '*' hyper.resume webserver - ''' - dom = _get_dom(name) - dom.resume() - return True - - -def set_autostart(name, state='on'): - ''' - Set the named virtual machine to autostart when the hypervisor boots - - CLI Example:: - - salt '*' hyper.set_autostart webserver - ''' - dom = _get_dom(name) - - if state == 'on': - return dom.setAutostart(1) == 0 - - elif state == 'off': - return dom.setAutostart(0) == 0 - - else: - # return False if state is set to something other then on or off - return False - - -def get_disks(name): - ''' - Return the disks of a named virt - - CLI Example:: - - salt '*' hyper.get_disks - ''' - disks = {} - doc = minidom.parse(StringIO(get_conf(name))) - for elem in doc.getElementsByTagName('disk'): - sources = elem.getElementsByTagName('source') - targets = elem.getElementsByTagName('target') - if len(sources) > 0: - source = sources[0] - else: - continue - if len(targets) > 0: - target = targets[0] - else: - continue - if 'dev' in list(target.attributes) and 'file' in list(source.attributes): - disks[target.getAttribute('dev')] = {'file': source.getAttribute('file')} - for dev in disks: - disks[dev].update(yaml.safe_load(subprocess.Popen( - 'qemu-img info ' + disks[dev]['file'], - shell=True, - stdout=subprocess.PIPE).communicate()[0])) - return disks - - -def get_conf(name): - ''' - Returns the XML for a given vm - - CLI Example:: - - salt '*' hyper.get_conf - ''' - dom = _get_dom(name) - return dom.XMLDesc(0)