예제 #1
0
파일: vmops.py 프로젝트: septimius/nova
    def _create_vm(self, instance, vdi_uuid, network_info=None):
        """Create VM instance"""
        instance_name = instance.name
        vm_ref = VMHelper.lookup(self._session, instance_name)
        if vm_ref is not None:
            raise exception.Duplicate(
                _('Attempted to create'
                  ' non-unique name %s') % instance_name)

        #ensure enough free memory is available
        if not VMHelper.ensure_free_mem(self._session, instance):
            LOG.exception(
                _('instance %(instance_name)s: not enough free '
                  'memory') % locals())
            db.instance_set_state(context.get_admin_context(), instance['id'],
                                  power_state.SHUTDOWN)
            return

        user = AuthManager().get_user(instance.user_id)
        project = AuthManager().get_project(instance.project_id)

        # Are we building from a pre-existing disk?
        vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', vdi_uuid)

        disk_image_type = VMHelper.determine_disk_image_type(instance)

        kernel = None
        if instance.kernel_id:
            kernel = VMHelper.fetch_image(self._session, instance.id,
                                          instance.kernel_id, user, project,
                                          ImageType.KERNEL_RAMDISK)

        ramdisk = None
        if instance.ramdisk_id:
            ramdisk = VMHelper.fetch_image(self._session, instance.id,
                                           instance.ramdisk_id, user, project,
                                           ImageType.KERNEL_RAMDISK)

        use_pv_kernel = VMHelper.determine_is_pv(self._session, instance.id,
                                                 vdi_ref, disk_image_type,
                                                 instance.os_type)
        vm_ref = VMHelper.create_vm(self._session, instance, kernel, ramdisk,
                                    use_pv_kernel)

        VMHelper.create_vbd(session=self._session,
                            vm_ref=vm_ref,
                            vdi_ref=vdi_ref,
                            userdevice=0,
                            bootable=True)

        # TODO(tr3buchet) - check to make sure we have network info, otherwise
        # create it now. This goes away once nova-multi-nic hits.
        if network_info is None:
            network_info = self._get_network_info(instance)
        self.create_vifs(vm_ref, network_info)
        self.inject_network_info(instance, vm_ref, network_info)
        return vm_ref
예제 #2
0
파일: vmops.py 프로젝트: superstack/nova
    def _create_vm(self, instance, vdi_uuid, network_info=None):
        """Create VM instance."""
        instance_name = instance.name
        vm_ref = VMHelper.lookup(self._session, instance_name)
        if vm_ref is not None:
            raise exception.InstanceExists(name=instance_name)

        #ensure enough free memory is available
        if not VMHelper.ensure_free_mem(self._session, instance):
            LOG.exception(_('instance %(instance_name)s: not enough free '
                          'memory') % locals())
            db.instance_set_state(context.get_admin_context(),
                                  instance['id'],
                                  power_state.SHUTDOWN)
            return

        user = AuthManager().get_user(instance.user_id)
        project = AuthManager().get_project(instance.project_id)

        # Are we building from a pre-existing disk?
        vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', vdi_uuid)

        disk_image_type = VMHelper.determine_disk_image_type(instance)

        kernel = None
        if instance.kernel_id:
            kernel = VMHelper.fetch_image(self._session, instance.id,
                instance.kernel_id, user, project, ImageType.KERNEL_RAMDISK)

        ramdisk = None
        if instance.ramdisk_id:
            ramdisk = VMHelper.fetch_image(self._session, instance.id,
                instance.ramdisk_id, user, project, ImageType.KERNEL_RAMDISK)

        use_pv_kernel = VMHelper.determine_is_pv(self._session, instance.id,
            vdi_ref, disk_image_type, instance.os_type)
        vm_ref = VMHelper.create_vm(self._session, instance, kernel, ramdisk,
                                    use_pv_kernel)

        VMHelper.create_vbd(session=self._session, vm_ref=vm_ref,
                vdi_ref=vdi_ref, userdevice=0, bootable=True)

        # TODO(tr3buchet) - check to make sure we have network info, otherwise
        # create it now. This goes away once nova-multi-nic hits.
        if network_info is None:
            network_info = self._get_network_info(instance)

        # Alter the image before VM start for, e.g. network injection
        if FLAGS.xenapi_inject_image:
            VMHelper.preconfigure_instance(self._session, instance,
                                           vdi_ref, network_info)

        self.create_vifs(vm_ref, network_info)
        self.inject_network_info(instance, network_info, vm_ref)
        return vm_ref
예제 #3
0
파일: vmops.py 프로젝트: pombredanne/nova
    def rescue(self, instance, callback):
        """Rescue the specified instance
            - shutdown the instance VM
            - set 'bootlock' to prevent the instance from starting in rescue
            - spawn a rescue VM (the vm name-label will be instance-N-rescue)

        """
        rescue_vm_ref = VMHelper.lookup(self._session,
                                        instance.name + "-rescue")
        if rescue_vm_ref:
            raise RuntimeError(_(
                "Instance is already in Rescue Mode: %s" % instance.name))

        vm_ref = self._get_vm_opaque_ref(instance)
        self._shutdown(instance, vm_ref)
        self._acquire_bootlock(vm_ref)

        instance._rescue = True
        self.spawn(instance)
        rescue_vm_ref = self._get_vm_opaque_ref(instance)

        vbd_ref = self._session.get_xenapi().VM.get_VBDs(vm_ref)[0]
        vdi_ref = self._session.get_xenapi().VBD.get_record(vbd_ref)["VDI"]
        rescue_vbd_ref = VMHelper.create_vbd(self._session, rescue_vm_ref,
                                             vdi_ref, 1, False)

        self._session.call_xenapi("Async.VBD.plug", rescue_vbd_ref)
예제 #4
0
파일: vmops.py 프로젝트: septimius/nova
    def rescue(self, instance, callback):
        """Rescue the specified instance
            - shutdown the instance VM
            - set 'bootlock' to prevent the instance from starting in rescue
            - spawn a rescue VM (the vm name-label will be instance-N-rescue)

        """
        rescue_vm_ref = VMHelper.lookup(self._session,
                                        instance.name + "-rescue")
        if rescue_vm_ref:
            raise RuntimeError(
                _("Instance is already in Rescue Mode: %s" % instance.name))

        vm_ref = self._get_vm_opaque_ref(instance)
        self._shutdown(instance, vm_ref)
        self._acquire_bootlock(vm_ref)

        instance._rescue = True
        self.spawn(instance)
        rescue_vm_ref = self._get_vm_opaque_ref(instance)

        vbd_ref = self._session.get_xenapi().VM.get_VBDs(vm_ref)[0]
        vdi_ref = self._session.get_xenapi().VBD.get_record(vbd_ref)["VDI"]
        rescue_vbd_ref = VMHelper.create_vbd(self._session, rescue_vm_ref,
                                             vdi_ref, 1, False)

        self._session.call_xenapi("Async.VBD.plug", rescue_vbd_ref)
예제 #5
0
파일: volumeops.py 프로젝트: septimius/nova
 description = 'Disk-for:%s' % instance_name
 # Create SR
 sr_ref = VolumeHelper.create_iscsi_storage(self._session, vol_rec,
                                            label, description)
 # Introduce VDI  and attach VBD to VM
 try:
     vdi_ref = VolumeHelper.introduce_vdi(self._session, sr_ref)
 except StorageError, exc:
     LOG.exception(exc)
     VolumeHelper.destroy_iscsi_storage(self._session, sr_ref)
     raise Exception(
         _('Unable to create VDI on SR %(sr_ref)s for'
           ' instance %(instance_name)s') % locals())
 else:
     try:
         vbd_ref = VMHelper.create_vbd(self._session, vm_ref, vdi_ref,
                                       vol_rec['deviceNumber'], False)
     except self.XenAPI.Failure, exc:
         LOG.exception(exc)
         VolumeHelper.destroy_iscsi_storage(self._session, sr_ref)
         raise Exception(
             _('Unable to use SR %(sr_ref)s for'
               ' instance %(instance_name)s') % locals())
     else:
         try:
             task = self._session.call_xenapi('Async.VBD.plug', vbd_ref)
             self._session.wait_for_task(task, vol_rec['deviceNumber'])
         except self.XenAPI.Failure, exc:
             LOG.exception(exc)
             VolumeHelper.destroy_iscsi_storage(self._session, sr_ref)
             raise Exception(
                 _('Unable to attach volume to instance %s') %
예제 #6
0
파일: vmops.py 프로젝트: anotherjesse/nova
    def spawn(self, instance):
        """Create VM instance"""
        vm = VMHelper.lookup(self._session, instance.name)
        if vm is not None:
            raise exception.Duplicate(_('Attempted to create'
            ' non-unique name %s') % instance.name)

        #ensure enough free memory is available
        if not VMHelper.ensure_free_mem(self._session, instance):
                name = instance['name']
                LOG.exception(_('instance %(name)s: not enough free memory')
                              % locals())
                db.instance_set_state(context.get_admin_context(),
                                      instance['id'],
                                      power_state.SHUTDOWN)
                return

        user = AuthManager().get_user(instance.user_id)
        project = AuthManager().get_project(instance.project_id)

        #if kernel is not present we must download a raw disk
        if instance.kernel_id:
            disk_image_type = ImageType.DISK
        else:
            disk_image_type = ImageType.DISK_RAW
        vdi_uuid = VMHelper.fetch_image(self._session, instance.id,
            instance.image_id, user, project, disk_image_type)
        vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', vdi_uuid)
        #Have a look at the VDI and see if it has a PV kernel
        pv_kernel = False
        if not instance.kernel_id:
            pv_kernel = VMHelper.lookup_image(self._session, instance.id,
                                              vdi_ref)
        kernel = None
        if instance.kernel_id:
            kernel = VMHelper.fetch_image(self._session, instance.id,
                instance.kernel_id, user, project, ImageType.KERNEL_RAMDISK)
        ramdisk = None
        if instance.ramdisk_id:
            ramdisk = VMHelper.fetch_image(self._session, instance.id,
                instance.ramdisk_id, user, project, ImageType.KERNEL_RAMDISK)
        vm_ref = VMHelper.create_vm(self._session,
                                          instance, kernel, ramdisk, pv_kernel)
        VMHelper.create_vbd(self._session, vm_ref, vdi_ref, 0, True)

        # write network info
        admin_context = context.get_admin_context()

        # TODO(tr3buchet) - remove comment in multi-nic
        # I've decided to go ahead and consider multiple IPs and networks
        # at this stage even though they aren't implemented because these will
        # be needed for multi-nic and there was no sense writing it for single
        # network/single IP and then having to turn around and re-write it
        IPs = db.fixed_ip_get_all_by_instance(admin_context, instance['id'])
        for network in db.network_get_all_by_instance(admin_context,
                                                      instance['id']):
            network_IPs = [ip for ip in IPs if ip.network_id == network.id]

            def ip_dict(ip):
                return {'netmask': network['netmask'],
                        'enabled': '1',
                        'ip': ip.address}

            mac_id = instance.mac_address.replace(':', '')
            location = 'vm-data/networking/%s' % mac_id
            mapping = {'label': network['label'],
                       'gateway': network['gateway'],
                       'mac': instance.mac_address,
                       'dns': [network['dns']],
                       'ips': [ip_dict(ip) for ip in network_IPs]}
            self.write_to_param_xenstore(vm_ref, {location: mapping})

            # TODO(tr3buchet) - remove comment in multi-nic
            # this bit here about creating the vifs will be updated
            # in multi-nic to handle multiple IPs on the same network
            # and multiple networks
            # for now it works as there is only one of each
            bridge = network['bridge']
            network_ref = \
                NetworkHelper.find_network_with_bridge(self._session, bridge)

            if network_ref:
                VMHelper.create_vif(self._session, vm_ref,
                                    network_ref, instance.mac_address)

        LOG.debug(_('Starting VM %s...'), vm_ref)
        self._session.call_xenapi('VM.start', vm_ref, False, False)
        instance_name = instance.name
        LOG.info(_('Spawning VM %(instance_name)s created %(vm_ref)s.')
                % locals())

        def _inject_onset_files():
            onset_files = instance.onset_files
            if onset_files:
                # Check if this is a JSON-encoded string and convert if needed.
                if isinstance(onset_files, basestring):
                    try:
                        onset_files = json.loads(onset_files)
                    except ValueError:
                        LOG.exception(_("Invalid value for onset_files: '%s'")
                                % onset_files)
                        onset_files = []
                # Inject any files, if specified
                for path, contents in instance.onset_files:
                    LOG.debug(_("Injecting file path: '%s'") % path)
                    self.inject_file(instance, path, contents)
        # NOTE(armando): Do we really need to do this in virt?
        # NOTE(tr3buchet): not sure but wherever we do it, we need to call
        #                  reset_network afterwards
        timer = utils.LoopingCall(f=None)

        def _wait_for_boot():
            try:
                state = self.get_info(instance['name'])['state']
                db.instance_set_state(context.get_admin_context(),
                                      instance['id'], state)
                if state == power_state.RUNNING:
                    LOG.debug(_('Instance %s: booted'), instance['name'])
                    timer.stop()
                    _inject_onset_files()
                    return True
            except Exception, exc:
                LOG.warn(exc)
                LOG.exception(_('instance %s: failed to boot'),
                              instance['name'])
                db.instance_set_state(context.get_admin_context(),
                                      instance['id'],
                                      power_state.SHUTDOWN)
                timer.stop()
                return False
예제 #7
0
        # But first, retrieve target info, like Host, IQN, LUN and SCSIID
        vol_rec = VolumeHelper.parse_volume_info(device_path, mountpoint)
        label = "SR-%s" % vol_rec["volumeId"]
        description = "Disk-for:%s" % instance_name
        # Create SR
        sr_ref = VolumeHelper.create_iscsi_storage(self._session, vol_rec, label, description)
        # Introduce VDI  and attach VBD to VM
        try:
            vdi_ref = VolumeHelper.introduce_vdi(self._session, sr_ref)
        except StorageError, exc:
            LOG.exception(exc)
            VolumeHelper.destroy_iscsi_storage(self._session, sr_ref)
            raise Exception(_("Unable to create VDI on SR %(sr_ref)s for" " instance %(instance_name)s") % locals())
        else:
            try:
                vbd_ref = VMHelper.create_vbd(self._session, vm_ref, vdi_ref, vol_rec["deviceNumber"], False)
            except self.XenAPI.Failure, exc:
                LOG.exception(exc)
                VolumeHelper.destroy_iscsi_storage(self._session, sr_ref)
                raise Exception(_("Unable to use SR %(sr_ref)s for" " instance %(instance_name)s") % locals())
            else:
                try:
                    task = self._session.call_xenapi("Async.VBD.plug", vbd_ref)
                    self._session.wait_for_task(task, vol_rec["deviceNumber"])
                except self.XenAPI.Failure, exc:
                    LOG.exception(exc)
                    VolumeHelper.destroy_iscsi_storage(self._session, sr_ref)
                    raise Exception(_("Unable to attach volume to instance %s") % instance_name)
        LOG.info(_("Mountpoint %(mountpoint)s attached to" " instance %(instance_name)s") % locals())

    def detach_volume(self, instance_name, mountpoint):
예제 #8
0
파일: vmops.py 프로젝트: yosh/nova
    def spawn(self, instance, disk):
        """Create VM instance"""
        instance_name = instance.name
        vm = VMHelper.lookup(self._session, instance_name)
        if vm is not None:
            raise exception.Duplicate(_('Attempted to create'
            ' non-unique name %s') % instance_name)

        #ensure enough free memory is available
        if not VMHelper.ensure_free_mem(self._session, instance):
            LOG.exception(_('instance %(instance_name)s: not enough free '
                          'memory') % locals())
            db.instance_set_state(context.get_admin_context(),
                                  instance['id'],
                                  power_state.SHUTDOWN)
            return

        user = AuthManager().get_user(instance.user_id)
        project = AuthManager().get_project(instance.project_id)

        vdi_ref = kernel = ramdisk = pv_kernel = None

        # Are we building from a pre-existing disk?
        if not disk:
            #if kernel is not present we must download a raw disk

            disk_image_type = VMHelper.determine_disk_image_type(instance)
            vdi_uuid = VMHelper.fetch_image(self._session, instance.id,
                    instance.image_id, user, project, disk_image_type)
            vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', vdi_uuid)

        else:
            vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', disk)

        if disk_image_type == ImageType.DISK_RAW:
            # Have a look at the VDI and see if it has a PV kernel
            pv_kernel = VMHelper.lookup_image(self._session, instance.id,
                                              vdi_ref)
        elif disk_image_type == ImageType.DISK_VHD:
            # TODO(sirp): Assuming PV for now; this will need to be
            # configurable as Windows will use HVM.
            pv_kernel = True

        if instance.kernel_id:
            kernel = VMHelper.fetch_image(self._session, instance.id,
                instance.kernel_id, user, project, ImageType.KERNEL_RAMDISK)

        if instance.ramdisk_id:
            ramdisk = VMHelper.fetch_image(self._session, instance.id,
                instance.ramdisk_id, user, project, ImageType.KERNEL_RAMDISK)

        vm_ref = VMHelper.create_vm(self._session,
                                          instance, kernel, ramdisk, pv_kernel)
        VMHelper.create_vbd(session=self._session, vm_ref=vm_ref,
                vdi_ref=vdi_ref, userdevice=0, bootable=True)

        # inject_network_info and create vifs
        networks = self.inject_network_info(instance)
        self.create_vifs(instance, networks)

        LOG.debug(_('Starting VM %s...'), vm_ref)
        self._start(instance, vm_ref)
        LOG.info(_('Spawning VM %(instance_name)s created %(vm_ref)s.')
                 % locals())

        def _inject_onset_files():
            onset_files = instance.onset_files
            if onset_files:
                # Check if this is a JSON-encoded string and convert if needed.
                if isinstance(onset_files, basestring):
                    try:
                        onset_files = json.loads(onset_files)
                    except ValueError:
                        LOG.exception(_("Invalid value for onset_files: '%s'")
                                % onset_files)
                        onset_files = []
                # Inject any files, if specified
                for path, contents in instance.onset_files:
                    LOG.debug(_("Injecting file path: '%s'") % path)
                    self.inject_file(instance, path, contents)
        # NOTE(armando): Do we really need to do this in virt?
        # NOTE(tr3buchet): not sure but wherever we do it, we need to call
        #                  reset_network afterwards
        timer = utils.LoopingCall(f=None)

        def _wait_for_boot():
            try:
                state = self.get_info(instance_name)['state']
                db.instance_set_state(context.get_admin_context(),
                                      instance['id'], state)
                if state == power_state.RUNNING:
                    LOG.debug(_('Instance %s: booted'), instance_name)
                    timer.stop()
                    _inject_onset_files()
                    return True
            except Exception, exc:
                LOG.warn(exc)
                LOG.exception(_('instance %s: failed to boot'),
                              instance_name)
                db.instance_set_state(context.get_admin_context(),
                                      instance['id'],
                                      power_state.SHUTDOWN)
                timer.stop()
                return False