Beispiel #1
0
 def delete(self):
     """Delete a CA's file structure and configuration files."""
     # NB This will fail if you've been storing certs or reqs
     if self.get()['data'] == []:
         msg = '%s does not exist, cannot delete' % self.ca_name
         raise error.NotFound(msg)
     self.req_files.append(self.ca_req_file)
     for req_file in self.req_files:
         if (os.path.exists(req_file)):
             os.remove(req_file)
     self.req_dirs.sort(reverse=True)
     for directory in self.req_dirs:
         if (os.path.exists(directory)):
             try:
                 os.removedirs(directory)
             except Exception as e:
                 msg = 'Unable to delete directory %s: %s' % (directory, e)
                 self.log.debug(msg)
     result = self.get()
     if result['exit_code'] == 3 and result['count'] == 0:
         result['msg'] = "Deleted %s:" % result['type']
         return result
     else:
         msg = 'Delete operation returned OK, but object still there?'
         raise error.ValidationError(msg)
Beispiel #2
0
 def delete(self, force=False):
     '''Power off a VM'''
     if force:  # Hard shutdown
         try:
             result = self.dom.destroy()
             msg = "Forced powered off %s" % self.vm_name
             self.log.debug(msg)
         except libvirt.libvirtError:
             msg = "VM % is already powered off." % self.vm_name
             raise error.VMStopped, msg
     else:  # Regular shutdown
         try:
             result = self.dom.shutdown()
             msg = "Powered off %s" % self.vm_name
             self.log.debug(msg)
         except libvirt.libvirtError:
             msg = "VM %s is already powered off" % self.vm_name
             raise error.VMStopped, msg
     if result != 0:
         msg = 'Unknown error shutting down VM, libvirt returned %s' % result
         raise error.LibvirtError(msg)
     result = self.get()
     #For some reason if we force off then check state we get no state so the
     #ValidationError below gets raised, for now changing if statement so
     #we get success if forceoff
     if result['exit_code'] == 0 and (result['data'][0]['state'] == 'Off'
                                      or force == True):
         result['msg'] = "Powered off %s:" % result['type']
         return result
     else:
         msg = 'Power operation returned OK, but %s state is %s' % \
             (result['data'][0]['state'], result['data'][0]['state'])
         raise error.ValidationError(msg)
     return result
Beispiel #3
0
 def delete(self):
     """Delete a certificate and its associated key."""
     # NB This will fail if you've been storing certs or reqs
     for file in (self.key_file, self.cert_file):
         try:
             os.remove(file)
         except (OSError, IOError):
             msg = 'Unable to delete file %s' % file
             raise error.NotFound(msg)
     result = self.get()
     if result['exit_code'] == 3 and result['count'] == 0:
         result['msg'] = "Deleted %s:" % result['type']
         return result
     else:
         msg = 'Delete operation returned OK, but object still there?'
         raise error.ValidationError(msg)
Beispiel #4
0
 def delete(self, force=False):
     '''Power off a VM'''
     if force:  # Hard shutdown
         try:
             result = self.dom.destroy()
             msg = "Forced powered off %s" % self.vm_name
             self.log.debug(msg)
         except libvirt.libvirtError:
             msg = "VM % is already powered off." % self.vm_name
             raise error.VMStopped, msg
     else:  # Regular shutdown
         try:
             result = self.dom.shutdown()
             msg = "Shutting down %s" % self.vm_name
             self.log.debug(msg)
         except libvirt.libvirtError:
             msg = "VM %s is already powered off" % self.vm_name
             raise error.VMStopped, msg
     if result != 0:
         msg = 'Unknown error shutting down VM, libvirt returned %s' % result
         raise error.LibvirtError(msg)
     result = self.get()
     # For regular power off requests we have to wait for the OS to shutdown
     # so we retry a few times
     # persistent VMs should return 'Off' when shutdown
     # transient VMs should return 'No State' (as the VM is done)
     tries = 1
     wait = 3
     retries = self.config.get('VM', 'status_retries', 5)
     while tries < retries:
         state = result['data'][0]['state']
         if result['exit_code'] == 0 and (state == 'Off' or \
                                          state == 'No State'):
             result['msg'] = "Powered off %s:" % result['type']
             return result
         time.sleep(wait)
         result = self.get()
         wait += 3
         tries += 1
     # if we get here, VM state never returned Off
     msg = 'Power operation returned OK, but %s state is %s' % \
             (self.vm_name, result['data'][0]['state'])
     raise error.ValidationError(msg)
Beispiel #5
0
 def delete(self, delete_key=True):
     """Delete a certificate request; return True"""
     try:
         os.remove(self.req_file)
         if delete_key:
             os.remove(self.key_file)
     except (OSError, IOError):
         msg = 'Failed to delete request %s and/or key %s' \
                                         % (self.req_file, self.key_file)
         raise error.NotFound(msg)
     except Exception as e:
         raise e
     result = self.get()
     if result['exit_code'] == 3 and result['count'] == 0:
         result['msg'] = "Deleted %s:" % result['type']
         return result
     else:
         msg = 'Delete operation returned OK, but object still there?'
         raise error.ValidationError(msg)
Beispiel #6
0
    def create(self, cn, signer=None):
        """Create a CA with default file structure and configuration files."""
        # If signer is set, this CA cert will be signed by the signer,
        # otherwise a self-signed certificate will be produced.
        self.ca_cn = common.is_shell_safe(cn)
        if signer:
            signer = common.is_shell_safe(signer)
        if os.path.exists(self.ca_key_file) or \
        os.path.exists(self.ca_cert_file):
            msg = 'CA %s exists, delete first to continue' % self.ca_name
            raise error.AlreadyExists(msg)
        self.req_dirs.sort()
        for directory in self.req_dirs:
            if not (os.path.exists(directory)):
                try:
                    self.log.debug('Creating directory %s' % directory)
                    os.makedirs(directory)
                except Exception as e:
                    raise e

        msg = 'Creating CSR with cn=%s and requester=%s' % (cn, self.ca_name)
        self.log.debug(msg)
        csr = SpokeCSR(cn, self.ca_name, ca=True)
        csr.create()
        msg = 'Creating Cert with cn=%s, requester=%s and signer=%s' % \
                                                    (cn, self.ca_name, signer)
        self.log.debug(msg)
        cert = SpokeCACert(cn, self.ca_name, signer)
        cert.create()
        result = self.get()
        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.ValidationError(msg)
        return result
Beispiel #7
0
        except ldap.LDAPError, e:
            trace = traceback.format_exc()
            raise error.SpokeLDAPError(e, trace)
        except Exception, e:
            trace = traceback.format_exc()
            msg = 'Unknown error'
            raise error.SpokeError(msg, trace)
        result = self._get_object(dn, scope=ldap.SCOPE_BASE, filter=filter, 
                                  attr=attrlist)
        if del_type == 'del_dn': # we expect nothing back
            if result['exit_code'] == 3 and result['count'] == 0:
                result['msg'] = "Deleted %s:" % result['type']
                return result
            else:
                msg = 'Delete operation returned OK, but object still there?'
                raise error.ValidationError(msg)
        else: # we're deleting an attribute so we expect an object back
            if result['exit_code'] == 0 and result['count'] == 1:
                result['msg'] = "Deleted %s attribute:" % result['type']
                return result
            else:
                msg = 'Delete attribute operation returned OK, but unable to find object'
                raise error.NotFound(msg)

    def _validate_exists(self, dn, filter=None, unique=False, attr=None):
        """Return result under supplied dn; otherwise raise NotFound."""
        try:
            result = self._get_object(dn, self.search_scope, filter, attr)
        except ldap.NO_SUCH_OBJECT, e:
            result = []
        if not result:
Beispiel #8
0
class SpokeVMStorage:
    
    """Provide CRUD methods to Virtual machine definition objects."""
    
    def __init__(self):
        """Get config and setup loggings."""
        self.config = config.setup()
        self.log = logging.getLogger(__name__)
        #This block gets interface and interface type from config file
        self._lookupInterfaces()
        #And this one does the same for disks.
        self._lookupDisks()
        self.search_headers = self.config.get('VM', 'search_headers', 'name,uuid')
        self.headers = self.search_headers.split(',')
        def _error_handler(self, err):
            msg = "Ignoring Libvirt error %s)" % err
            pass
        # Prevent libvirt errors from reaching the console
        libvirt.registerErrorHandler(_error_handler, None)
        
    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)
        if out == None:
            msg = "Failed to create VM definition for %s" % vm_name
            self.log.error(msg)
            sys.exit(1)
        
        #print xml.out(doc) #useful for debug
        result = self.get(vm_name)
        if result['exit_code'] == 0 and result['count'] == 1:
            result['msg'] = "Created %s:" % result['type']
            self.log.debug('Result: %s' % result)
            return result
        else:
            msg = 'Create operation returned OK, but unable to find object'
            raise error.ValidationError(msg)
        return result