Example #1
0
 def get(self, vm_name=None):
     """get info on virtual machine(s)"""
     data = []
     #if no vm name get all
     if vm_name == None:
         #get list of all inactive and active
         vm_defined_list = self.conn.listDefinedDomains()
         vm_active_list = self.conn.listDomainsID()
         #iterate over these lists and get some info on each domain
         for vmid in vm_active_list:
             dom = self.conn.lookupByID(vmid)
             data.append(dom.XMLDesc(3))
         for name in vm_defined_list:
             dom = self.conn.lookupByName(name)
             data.append(dom.XMLDesc(3))
     else:
         vm_name = common.validate_hostname(vm_name)
         try:
             dom = self.conn.lookupByName(vm_name)
         except libvirt.libvirtError:
             result = common.process_results(data, 'VM')
             self.log.debug('Result: %s' % result)
             return result
         info = dom.XMLDesc(3)
         data.append(info)
     #self.conn.close() # Connection closing left to calling app - bad?
     result = common.process_results(data, 'VM')
     self.log.debug('Result: %s' % result)
     return result
Example #2
0
 def __init__(self, hv_uri, vm_name):
     '''Get some basic config and connect to hypervisor'''
     SpokeVMPower.__init__(self, vm_name)
     self.hv_uri = hv_uri
     self.vm_name = common.validate_hostname(vm_name)
     self.conn = None
     try:
         self.conn = libvirt.open(self.hv_uri)
         msg = "Successfully connected to: " + self.hv_uri
         self.log.debug(msg)
     except libvirt.libvirtError:
         trace = traceback.format_exc()
         msg = 'Libvirt connection to URI %s failed' % self.hv_uri
         raise error.LibvirtError(msg, trace)
     except Exception:
         trace = traceback.format_exc()
         msg = 'Unknown error'
         raise error.SpokeError(msg, trace)
     finally:
         if self.conn == None:
             msg = 'Libvirt connection to URI %s failed' % self.hv_uri
             raise error.LibvirtError(msg)
         try:
             self.dom = self.conn.lookupByName(self.vm_name)
         except libvirt.libvirtError:
             msg = "VM %s not found." % self.vm_name
             raise error.NotFound(msg)
Example #3
0
 def __init__(self, hv_uri, vm_name):
     '''Get some basic config and connect to hypervisor'''
     SpokeVMPower.__init__(self, vm_name)
     self.hv_uri = hv_uri
     self.vm_name = common.validate_hostname(vm_name)
     self.conn = None
     try:
         self.conn = libvirt.open(self.hv_uri)
         msg = "Successfully connected to: " + self.hv_uri
         self.log.debug(msg)
     except libvirt.libvirtError:
         trace = traceback.format_exc()
         msg = 'Libvirt connection to URI %s failed' % self.hv_uri
         raise error.LibvirtError(msg, trace)
     except Exception:
         trace = traceback.format_exc()
         msg = 'Unknown error'
         raise error.SpokeError(msg, trace)
     finally:
         if self.conn == None:
             msg = 'Libvirt connection to URI %s failed' % self.hv_uri
             raise error.LibvirtError(msg)
         try:
             self.dom = self.conn.lookupByName(self.vm_name)
         except libvirt.libvirtError:
             msg = "VM %s not found." % self.vm_name
             raise error.NotFound(msg)   
Example #4
0
File: host.py Project: mattmb/spoke
 def delete(self, host_name):
     """Delete a Host entry; return an empty search result."""
     host_name = common.validate_hostname(host_name)
     dn = '%s=%s,%s' % (self.host_key, host_name, self.host_container_dn)
     msg = 'Deleting %s' % dn
     self.log.debug(msg)
     result = self._delete_object(dn)
     self.log.debug('Result: %s' % result)
     return result
Example #5
0
 def delete(self, host_name):
     """Delete a Host entry; return an empty search result."""
     host_name = common.validate_hostname(host_name)
     dn = '%s=%s,%s' % (self.host_key, host_name, self.host_container_dn)
     msg = 'Deleting %s' % dn
     self.log.debug(msg)
     result = self._delete_object(dn)
     self.log.debug('Result: %s' % result)
     return result
Example #6
0
File: lvm.py Project: mattmb/spoke
    def create(self, lv_name, lv_size):
        """Create logical volume; return True"""
        lv_size = str(lv_size) + self.lv_units
        lv_name = common.validate_hostname(
            lv_name)  # LV names are always hostnames
        lv_size = common.validate_storage_format(lv_size)

        args = ['lvcreate', '-n', lv_name, '-L', lv_size, self.vg_name]
        str_args = " ".join(args)
        msg = "Running " + str_args
        self.log.debug(msg)
        try:
            result = subprocess.Popen(args,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE,
                                      close_fds=True)
        except Exception:
            msg = 'Running command %s failed' % str_args
            #            trace = traceback.format_exec()
            raise error.SpokeError(msg)

        data = result.communicate()
        stdout = data[0]
        stderr = data[1]
        msg = "Command stdout was: %s, stderr was: %s" % (stdout, stderr)
        self.log.debug(msg)

        # Errors we know about
        if "Volume group \"%s\" not found" % self.vg_name in stderr:
            msg = "volume group '%s' was not found." % self.vg_name
            raise error.NotFound(msg)
        elif "Insufficient free extents" in stderr:
            msg = "Not enough free space to create LV"
            raise error.InsufficientResource(msg)
        elif "Logical volume \"%s\" already exists in volume group \"%s\"" % (
                lv_name, self.vg_name) in stderr:
            msg = "Logical volume '%s' already exists in volume group '%s'" % (
                lv_name, self.vg_name)
            raise error.AlreadyExists(msg)
        # Catch unexpected errors
        if result.returncode != 0:
            msg = "Create command returned non-zero: %s stdout was: %s, stderr was: %s" % \
                                                        (result.returncode, stdout, stderr)
            raise error.LVMError(msg)

        result = self.get(lv_name)
        if result['exit_code'] == 0 and result['count'] == 1:
            result['msg'] = "Created %s:" % result['type']
            return result
        else:
            msg = 'Create operation returned OK, but unable to find object'
            raise error.NotFound(msg)
        self.log.debug('Result: %s' % result)
        return result
Example #7
0
    def get(self, lv_name=None):
        """Get logical volume; return list of volume attributes."""
        if lv_name is not None:
            lv_name = common.validate_hostname(lv_name) # LV names are always hostnames
            args = ['lvs', '--noheadings', '--units', self.lv_units, '-o', 'lv_name,lv_size', '--separator', ':', '/dev/%s/%s' % (self.vg_name, lv_name)]
        else:
            args = ['lvs', '--noheadings', '--units', self.lv_units, '-o', 'lv_name,lv_size', '--separator', ':', '/dev/%s' % self.vg_name]
        str_args = " ".join(args)
        msg = "Running " + str_args
        self.log.debug(msg)
        try:
            result = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
        except Exception:
            msg = 'Running command %s failed' % str_args
            #trace = traceback.format_exec()
            raise error.SpokeError, msg
            
        out = result.communicate()
        (stdout, stderr) = (out[0], out[1])
        msg = "Command stdout was: %s, stderr was: %s" % (stdout, stderr)
        self.log.debug(msg)

        data = []
        # Errors we know about
        if "Volume group \"%s\" not found" % self.vg_name in stderr:
            msg = "Volume group '%s' was not found." % self.vg_name 
            raise error.NotFound(msg)
        elif "logical volume(s) not found" in stderr:
            result = common.process_results(data)
            self.log.debug('Result: %s' % result)
            return result
        elif stderr == "" and stdout == "":
            result = common.process_results(data)
            self.log.debug('Result: %s' % result)
            return result
        # Catch unexpected errors
        if result.returncode != 0:
            msg = "Search command returned non-zero: %s stdout was: %s, stderr was: %s" % \
                                                        (result.returncode, stdout, stderr)
            raise error.LVMError(msg)
        output = stdout.strip()
        output = re.compile('\n').split(output)
        for item in output:
            item = item.strip()
            dic = {}
            name, size = item.split(':')
            dic['lv_size'] = size
            dic['lv_name'] = name
            data.append(dic)
        result = common.process_results(data)
        self.log.debug('Result: %s' % result)
        return result
Example #8
0
File: host.py Project: mattmb/spoke
 def get(self, host_name=None):
     """Search for a Host entry; return a search result."""
     dn = self.host_container_dn
     if host_name is None:
         filter = '%s=*' % self.host_key
     else:
         host_name = common.validate_hostname(host_name)
         filter = '%s=%s' % (self.host_key, host_name)
     msg = 'Searching at %s with scope %s and filter %s' % \
         (dn, self.search_scope, filter)
     self.log.debug(msg)
     result = self._get_object(dn, self.search_scope, filter)
     self.log.debug('Result: %s' % result)
     return result
Example #9
0
 def get(self, host_name=None):
     """Search for a Host entry; return a search result."""
     dn = self.host_container_dn
     if host_name is None:
         filter = '%s=*' % self.host_key
     else:
         host_name = common.validate_hostname(host_name)
         filter = '%s=%s' % (self.host_key, host_name)
     msg = 'Searching at %s with scope %s and filter %s' % \
         (dn, self.search_scope, filter)
     self.log.debug(msg)
     result = self._get_object(dn, self.search_scope, filter)
     self.log.debug('Result: %s' % result)
     return result
Example #10
0
File: host.py Project: mattmb/spoke
    def create(self,
               host_name,
               host_uuid,
               host_mem,
               host_cpu,
               host_family,
               host_type,
               host_storage_layout,
               host_network_layout,
               host_extra_opts=None):
        """Create a VM Host; return a VM Host search result."""
        host_name = common.validate_hostname(host_name)
        host_uuid = common.validate_uuid(host_uuid)
        host_mem = common.validate_mem(host_mem)
        host_cpu = common.validate_cpu(host_cpu)
        host_family = common.validate_host_family(host_family)
        # Verifies that the interfaces referenced in the storage layout
        # exist in the configuration file
        host_storage_layout = self._validate_storage_layout(
            host_storage_layout)
        # and for network layouts.
        host_network_layout = self._validate_network_layout(
            host_network_layout)
        host_type = common.validate_host_type(host_type)
        host_extra_opts = common.is_shell_safe(host_extra_opts)

        filter = '%s=%s' % (self.host_key, host_name)
        dn = '%s=%s,%s' % (self.host_key, host_name, self.host_container_dn)
        dn_attr = {
            'objectClass': ['top', self.host_class],
            self.host_key: [host_name],
            self.host_cpu_attr: [str(host_cpu)],
            self.host_mem_attr: [str(host_mem)],
            self.host_family_attr: [host_family],
            self.host_name_attr: [host_name],
            self.host_network_layout_attr: [host_network_layout],
            self.host_storage_layout_attr: [host_storage_layout],
            self.host_type_attr: [host_type],
            self.host_uuid_attr: [host_uuid],
        }
        if host_extra_opts is not None:
            dn_attr[self.host_extra_opts_attr] = [host_extra_opts]

        dn_info = [(k, v) for (k, v) in dn_attr.items()]

        msg = 'Creating %s with attributes %s' % (dn, dn_info)
        self.log.debug(msg)
        result = self._create_object(dn, dn_info)
        self.log.debug('Result: %s' % result)
        return result
Example #11
0
    def create(self, lv_name, lv_size):
        """Create logical volume; return True"""
        lv_size = str(lv_size) + self.lv_units
        lv_name = common.validate_hostname(lv_name) # LV names are always hostnames
        lv_size = common.validate_storage_format(lv_size)
        
        args = ['lvcreate', '-n', lv_name, '-L', lv_size, self.vg_name]
        str_args = " ".join(args)
        msg = "Running " + str_args
        self.log.debug(msg)
        try:
            result = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
        except Exception:
            msg = 'Running command %s failed' % str_args
#            trace = traceback.format_exec()
            raise error.SpokeError(msg)

        data = result.communicate()
        stdout = data[0]
        stderr = data[1]
        msg = "Command stdout was: %s, stderr was: %s" % (stdout, stderr)
        self.log.debug(msg)
        
        # Errors we know about
        if "Volume group \"%s\" not found" % self.vg_name in stderr:
            msg = "volume group '%s' was not found." % self.vg_name 
            raise error.NotFound(msg)
        elif "Insufficient free extents" in stderr:
            msg = "Not enough free space to create LV"
            raise error.InsufficientResource(msg)
        elif "Logical volume \"%s\" already exists in volume group \"%s\"" % (lv_name, self.vg_name) in stderr:
            msg = "Logical volume '%s' already exists in volume group '%s'" % (lv_name, self.vg_name)
            raise error.AlreadyExists(msg)
        # Catch unexpected errors
        if result.returncode != 0:
            msg = "Create command returned non-zero: %s stdout was: %s, stderr was: %s" % \
                                                        (result.returncode, stdout, stderr)
            raise error.LVMError(msg)

        result = self.get(lv_name)
        if result['exit_code'] == 0 and result['count'] == 1:
            result['msg'] = "Created %s:" % result['type']
            return result
        else:
            msg = 'Create operation returned OK, but unable to find object'
            raise error.NotFound(msg)
        self.log.debug('Result: %s' % result)
        return result
Example #12
0
File: lvm.py Project: mattmb/spoke
    def delete(self, lv_name):
        """Delete logical volume; return True."""
        lv_name = common.validate_hostname(
            lv_name)  # LV names are always hostnames

        args = ['lvremove', '-f', '%s/%s' % (self.vg_name, lv_name)]
        str_args = " ".join(args)
        msg = "Running " + str_args
        self.log.debug(msg)
        try:
            result = subprocess.Popen(args,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE,
                                      close_fds=True)
        except Exception:
            msg = 'Running command %s failed' % str_args
            #trace = traceback.format_exec()
            raise error.SpokeError(msg)

        data = result.communicate()
        stdout = data[0]
        stderr = data[1]
        msg = "Command stdout was: %s, stderr was: %s" % (stdout, stderr)
        self.log.debug(msg)

        if "Volume group \"%s\" not found" % self.vg_name in stderr:
            msg = "volume group '%s' was not found." % self.vg_name
            raise error.NotFound(msg)
        elif "logical volume(s) not found" in stderr:
            msg = "logical volume '%s' not found." % lv_name
            raise error.NotFound(msg)

        # Catch non-specific errors
        if result.returncode != 0:
            msg = "Delete command returned non-zero: %s stdout was: %s, stderr was: %s" % \
                                                        (result.returncode, stdout, stderr)
            raise error.LVMError(msg)

        result = self.get(lv_name)
        if result['exit_code'] == 3 and result['count'] == 0:
            result['msg'] = "Deleted %s:" % result['type']
            self.log.debug('Result: %s' % result)
            return result
        else:
            msg = 'Delete operation returned OK, but object still there?'
            raise error.SearchError(msg)
Example #13
0
    def delete(self, lv_name):
        """Delete logical volume; return True."""
        lv_name = common.validate_hostname(lv_name) # LV names are always hostnames

        args = ['lvremove', '-f', '%s/%s' % (self.vg_name, lv_name)]
        str_args = " ".join(args)
        msg = "Running " + str_args
        self.log.debug(msg)
        try:
            result = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
        except Exception:
            msg = 'Running command %s failed' % str_args
            #trace = traceback.format_exec()
            raise error.SpokeError(msg)

        data = result.communicate()
        stdout = data[0]
        stderr = data[1]
        msg = "Command stdout was: %s, stderr was: %s" % (stdout, stderr)
        self.log.debug(msg)

        if "Volume group \"%s\" not found" % self.vg_name in stderr:
            msg = "volume group '%s' was not found." % self.vg_name 
            raise error.NotFound(msg)
        elif "logical volume(s) not found" in stderr:
            msg = "logical volume '%s' not found." % lv_name
            raise error.NotFound(msg)
        
        # Catch non-specific errors
        if result.returncode != 0:
            msg = "Delete command returned non-zero: %s stdout was: %s, stderr was: %s" % \
                                                        (result.returncode, stdout, stderr)
            raise error.LVMError(msg)

        result = self.get(lv_name)
        if result['exit_code'] == 3 and result['count'] == 0:
            result['msg'] = "Deleted %s:" % result['type']
            self.log.debug('Result: %s' % result)
            return result
        else:
            msg = 'Delete operation returned OK, but object still there?'
            raise error.SearchError(msg)
Example #14
0
File: host.py Project: mattmb/spoke
 def create(self, host_name, host_uuid, host_mem, host_cpu, host_family, 
            host_type, host_storage_layout, host_network_layout, 
            host_extra_opts=None):
     """Create a VM Host; return a VM Host search result."""
     host_name = common.validate_hostname(host_name)
     host_uuid = common.validate_uuid(host_uuid)
     host_mem = common.validate_mem(host_mem)
     host_cpu = common.validate_cpu(host_cpu)
     host_family = common.validate_host_family(host_family)
     # Verifies that the interfaces referenced in the storage layout
     # exist in the configuration file
     host_storage_layout = self._validate_storage_layout(host_storage_layout)
     # and for network layouts.
     host_network_layout = self._validate_network_layout(host_network_layout)
     host_type = common.validate_host_type(host_type)
     host_extra_opts = common.is_shell_safe(host_extra_opts)
         
     filter = '%s=%s' % (self.host_key, host_name)
     dn = '%s=%s,%s' % (self.host_key, host_name, self.host_container_dn)
     dn_attr = {'objectClass': ['top', self.host_class],
                self.host_key: [host_name],
                self.host_cpu_attr: [str(host_cpu)],
                self.host_mem_attr: [str(host_mem)],
                self.host_family_attr: [host_family],
                self.host_name_attr: [host_name],
                self.host_network_layout_attr: [host_network_layout],
                self.host_storage_layout_attr: [host_storage_layout],
                self.host_type_attr: [host_type],
                self.host_uuid_attr: [host_uuid],
                }
     if host_extra_opts is not None:
         dn_attr[self.host_extra_opts_attr] = [host_extra_opts]
         
     dn_info = [(k, v) for (k, v) in dn_attr.items()]
     
     msg = 'Creating %s with attributes %s' % (dn, dn_info)
     self.log.debug(msg)
     result = self._create_object(dn, dn_info)
     self.log.debug('Result: %s' % result)
     return result
Example #15
0
File: lvm.py Project: mattmb/spoke
    def get(self, lv_name=None):
        """Get logical volume; return list of volume attributes."""
        if lv_name is not None:
            lv_name = common.validate_hostname(
                lv_name)  # LV names are always hostnames
            args = [
                'lvs', '--noheadings', '--units', self.lv_units, '-o',
                'lv_name,lv_size', '--separator', ':',
                '/dev/%s/%s' % (self.vg_name, lv_name)
            ]
        else:
            args = [
                'lvs', '--noheadings', '--units', self.lv_units, '-o',
                'lv_name,lv_size', '--separator', ':',
                '/dev/%s' % self.vg_name
            ]
        str_args = " ".join(args)
        msg = "Running " + str_args
        self.log.debug(msg)
        try:
            result = subprocess.Popen(args,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE,
                                      close_fds=True)
        except Exception:
            msg = 'Running command %s failed' % str_args
            #trace = traceback.format_exec()
            raise error.SpokeError, msg

        out = result.communicate()
        (stdout, stderr) = (out[0], out[1])
        msg = "Command stdout was: %s, stderr was: %s" % (stdout, stderr)
        self.log.debug(msg)

        data = []
        # Errors we know about
        if "Volume group \"%s\" not found" % self.vg_name in stderr:
            msg = "Volume group '%s' was not found." % self.vg_name
            raise error.NotFound(msg)
        elif "logical volume(s) not found" in stderr:
            result = common.process_results(data)
            self.log.debug('Result: %s' % result)
            return result
        elif stderr == "" and stdout == "":
            result = common.process_results(data)
            self.log.debug('Result: %s' % result)
            return result
        # Catch unexpected errors
        if result.returncode != 0:
            msg = "Search command returned non-zero: %s stdout was: %s, stderr was: %s" % \
                                                        (result.returncode, stdout, stderr)
            raise error.LVMError(msg)
        output = stdout.strip()
        output = re.compile('\n').split(output)
        for item in output:
            item = item.strip()
            dic = {}
            name, size = item.split(':')
            dic['lv_size'] = size
            dic['lv_name'] = name
            data.append(dic)
        result = common.process_results(data)
        self.log.debug('Result: %s' % result)
        return result
Example #16
0
    def create(self, vm_name, vm_uuid, vm_mem, vm_cpu, vm_family, vm_storage_layout,
               vm_network_layout, vm_install=False, vm_disks=None, vm_interfaces=None):
        """Define a new VM and add to hypervisor's store (does not start)."""
        try:
            vm_name = common.validate_hostname(vm_name)
            vm_cpu = common.validate_cpu(vm_cpu)
            vm_mem = common.validate_mem(vm_mem)
            #vm_type = common.validate_host_type(vm_type)
            vm_family = common.validate_host_family(vm_family)
            #vm_extra_opts = common.is_shell_safe(vm_extra_opts)
            vm_uuid = common.validate_uuid(vm_uuid)
        except error.InputError as e:
            self.log.error(e)
            raise e
        
        try:
            self.conn.lookupByName(vm_name)
        except libvirt.libvirtError:
            pass
        else:
            msg = "Domain %s already exists, cannot create." % vm_name
            raise error.AlreadyExists(msg)
        
        # Create a UUID in hypervisor format
        formatted_uuid = self._format_uuid(vm_uuid)
        
        #-1 means XEN will give the right XenID when it starts
        vm_id=-1
        
        #Initial xml structure
        doc = xml.createDoc("doc")
        domain = xml.createElement(doc, "domain", {"type": vm_family})
        #Variable config options
        #xml.createChild(doc, domain, "arch name", None, 'i686')
        xml.createChild(doc, domain, "name", None, vm_name)
        xml.createChild(doc, domain, "memory", None, vm_mem)
        xml.createChild(doc, domain, "currentMemory", None, vm_mem)
        xml.createChild(doc, domain, "vcpu", None, vm_cpu)
        xml.createChild(doc, domain, "uuid", None, formatted_uuid)
        
        #fixed(ish) config options
        os = xml.createChild(doc, domain, "os", None, None)
        #ks - the below is going to have to change for 64bit
        xml.createChild(doc, os, "type", {"arch": "i686"}, "hvm")
        xml.createChild(doc, domain, "clock", {"offset": "utc"}, None)
        xml.createChild(doc, domain, "on_poweroff", None, "destroy")
        xml.createChild(doc, domain, "on_reboot", None, "restart")
        xml.createChild(doc, domain, "on_crash", None, "restart")
        
        devices = xml.createChild(doc, domain, "devices", None, None)
        console = xml.createChild(doc, devices, "console", {"type": "pty"}, None)
        xml.createChild(doc, console, "target", {"type": "xen", "port": "0"}, None)
        #ks
        #xml.createChild(doc, devices, "input", {"type": "mouse", "bus": "xen"}, None)
        # TODO Change the port such that it is associated with the UUID and change listen to internal interface only
        xml.createChild(doc, devices, "graphics", {"type": "vnc", "port": "-1", "autoport": "yes", "listen": "0.0.0.0"}, None)
        xml.createChild(doc, devices, "emulator", None, "/usr/lib/xen/bin/qemu-dm")
        
#        #parse disk info
#        for item in vm_disks:
#            #local1 means hda and vg01
#            if item[0] == "local1":
#                disk = xml.createChild(doc, devices, "disk", {"type": "block", "device": "disk"}, None)
#                xml.createChild(doc, disk, "driver", {"name": "phy"}, None)
#                xml.createChild(doc, disk, "source", {"dev": "/dev/vg01/%s" % vm_name}, None)
#                xml.createChild(doc, disk, "target", {"dev": "hda", "bus": "ide"}, None)
#            #local2 means hdb and vg02
#            if item[0] == "local2":
#                disk = xml.createChild(doc, devices, "disk", {"type": "block", "device": "disk"}, None)
#                xml.createChild(doc, disk, "driver", {"name": "phy"}, None)
#                xml.createChild(doc, disk, "source", {"dev": "/dev/vg01/ko-test-02"}, None)
#                xml.createChild(doc, disk, "target", {"dev": "hdb", "bus": "ide"}, None)                                                      

        if vm_disks is not None:
            for item in vm_disks:
                if item[0] == "local1":
                    disk = xml.createChild(doc, devices, "disk", {"type": "block", "device": "disk"}, None)
                    xml.createChild(doc, disk, "driver", {"name": "phy"}, None)
                    xml.createChild(doc, disk, "source", {"dev": "/dev/vg01/%s" % vm_name}, None)
                    xml.createChild(doc, disk, "target", {"dev": "hda", "bus": "ide"}, None)
                #local2 means hdb and vg02
                if item[0] == "local2":
                    disk = xml.createChild(doc, devices, "disk", {"type": "block", "device": "disk"}, None)
                    xml.createChild(doc, disk, "driver", {"name": "phy"}, None)
                    xml.createChild(doc, disk, "source", {"dev": "/dev/vg02/%s" % vm_name}, None)
                    xml.createChild(doc, disk, "target", {"dev": "hdb", "bus": "ide"}, None)                                                      

        elif vm_storage_layout is not None:
            try:
                disks = self.dtypes[vm_storage_layout]
            except KeyError as e:
                msg = "The disk type %s is not present in config file." % e
                raise error.InputError, msg
            for item in disks:
                item = common.validate_disks_in_conf(self.dnames[item])
                hv_dev = item[0] + "/" + vm_name
                dom_dev = item[1]
                disk = xml.createChild(doc, devices, "disk", {"type": "block", "device": "disk"}, None)
                xml.createChild(doc, disk, "driver", {"name": "phy"}, None)
                xml.createChild(doc, disk, "source", {"dev": hv_dev}, None)
                xml.createChild(doc, disk, "target", {"dev": dom_dev, "bus": "ide"}, None)                                                      

        #parse interface info
        if vm_interfaces is not None:
            for interface in vm_interfaces:
                #get input from interface list
                bridge = int( interface[0].lstrip('breth') )
                mac = interface[1]
                source_interface = interface[2]
                
                interface = xml.createChild(doc, devices, "interface", {"type": "bridge"}, None)
                xml.createChild(doc, interface, "mac", {"address": mac}, None)
                xml.createChild(doc, interface, "source", {"bridge": source_interface}, None)
                xml.createChild(doc, interface, "script", {"path": "vif-bridge"}, None)
                xml.createChild(doc, interface, "target", {"dev": "vif%i.%i" % (vm_id, bridge)}, None)
        elif vm_network_layout is not None:
            try:
                interfaces = self.ifacedef[vm_network_layout]
            except KeyError:
                msg = "The interface type %s is not present in config file." % vm_network_layout
                raise error.InputError(msg)
            
            # Ensure that br0,x is done first as xen cares about order in xml.
            interfaces = sorted(interfaces, key=itemgetter(0))
            for interface in interfaces:
                interface = common.validate_interfaces_in_conf(interface)
                iface_number = int( interface[0].lstrip('breth') )
                if iface_number == 0:
                    boot_mac = common.mac_from_uuid(vm_uuid, iface_number)                   
                    boot_int = interface[1]
                mac = common.mac_from_uuid(vm_uuid, iface_number)
                                   
                source_interface = interface[1]
                # KS enumerate avail interfaces via facter, not remote socket op 
                #if not source_interface in self._all_interfaces():
                #    msg = "%s does not exist on this machine so we cant bridge to it!" % source_interface
                #    raise error.InsufficientResource, msg
                                    
                interface = xml.createChild(doc, devices, "interface", {"type": "bridge"}, None)
                xml.createChild(doc, interface, "mac", {"address": mac}, None)
                xml.createChild(doc, interface, "source", {"bridge": source_interface}, None)
                xml.createChild(doc, interface, "script", {"path": "vif-bridge"}, None)
                xml.createChild(doc, interface, "target", {"dev": "vif%i.%i" % (vm_id, iface_number)}, None)
        
        if vm_install: # Add network boot lines
            xml.createChild(doc, domain, "bootloader", None, "/usr/sbin/pypxeboot" )
            try:
                xml.createChild(doc, domain, "bootloader_args", None, "--udhcpc=/usr/local/pkg/udhcp/sbin/udhcpc --interface=%s mac=%s --label=install-aethernet" % (boot_int, boot_mac) )
            except UnboundLocalError:
                msg = "In config there must be an interface br0 as the provisioning interface!"
                raise error.ConfigError(msg)
        else:
            xml.createChild(doc, domain, "bootloader", None, "/usr/bin/pygrub" )

        try:
            out = self.conn.defineXML(xml.out(doc))
        except Exception, e:
            trace = traceback.format_exc()
            raise error.LibvirtError(e, trace)