Esempio n. 1
0
    def destroy(self,
                context,
                instance,
                network_info,
                block_device_info=None,
                destroy_disks=True,
                migrate_data=None):
        """Destroy the specified instance from the Hypervisor.

        If the instance is not found (for example if networking failed), this
        function should still succeed.  It's probably a good idea to log a
        warning in that case.

        :param context: security context
        :param instance: Instance object as returned by DB layer.
        :param network_info:
           :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
        :param block_device_info: Information about block devices that should
                                  be detached from the instance.
        :param destroy_disks: Indicates if disks should be destroyed
        :param migrate_data: implementation specific params
        """
        compute, project, zone = self.gce_svc, self.gce_project, self.gce_zone
        gce_id = self._get_gce_id_from_instance(instance)
        LOG.info(_LI('Deleting instance %s') % instance.uuid)
        operation = gceutils.delete_instance(compute, project, zone, gce_id)
        gceutils.wait_for_operation(compute, project, zone, operation)
        LOG.info(_LI("Destroy Complete %s") % instance.uuid)
Esempio n. 2
0
    def spawn(self, context, instance, image_meta, injected_files,
              admin_password, network_info=None, block_device_info=None):
        """Create a new instance/VM/domain on the virtualization platform.
        Once this successfully completes, the instance should be
        running (power_state.RUNNING). If this fails, any partial instance
        should be completely cleaned up, and the virtualization platform should
        be in the state that it was before this call began.

        :param context: security context <Not Yet Implemented>
        :param instance: nova.objects.instance.Instance
                         This function should use the data there to guide
                         the creation of the new instance.
        :param image_meta: image object returned by nova.image.glance that
                           defines the image from which to boot this instance
        :param injected_files: User files to inject into instance.
        :param admin_password: set in instance. <Not Yet Implemented>
        :param network_info:
           :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
        :param block_device_info: Information about block devices to be
                                  attached to the instance.
        """
        compute, project, zone = self.gce_svc, self.gce_project, self.gce_zone
        # GCE expects instance name in format
        # "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?"
        # So we need to construct it for GCE from uuid
        gce_instance_name = 'inst-' + instance.uuid
        LOG.info("Creating instance %s as %s on GCE." %
                 (instance.display_name, gce_instance_name))
        # Image Info
        image_link = instance.system_metadata['image_gce_link']
        # Flavor Info
        flavor_name = instance.flavor.name
        flavor_link = "zones/%s/machineTypes/%s" % (self.gce_zone, flavor_name)
        # Network Info
        network_interfaces = self._process_network_info(network_info)
        # Create Instance
        operation = gceutils.create_instance(compute, project, zone,
                                             gce_instance_name, image_link,
                                             flavor_link, network_interfaces)
        gceutils.wait_for_operation(compute, project, operation)
        gce_instance = gceutils.get_instance(compute, project, zone,
                                             gce_instance_name)
        # Update GCE info in openstack instance metadata
        instance.metadata.update({'gce_id': gce_instance['name']})
        gce_metadata = [
            {
                'key': 'openstack_id',
                'value': instance.uuid
            },
        ]
        ssh_keys = self._process_ssh_keys(instance)
        if ssh_keys:
            gce_metadata.append(ssh_keys)
        operation = gceutils.set_instance_metadata(
            compute, project, zone, gce_instance['name'], gce_metadata,
            operation='add')
        gceutils.wait_for_operation(compute, project, operation)
        self._uuid_to_gce_instance[instance.uuid] = gceutils.get_instance(
            compute, project, zone, gce_instance_name)
Esempio n. 3
0
 def power_on(self, context, instance, network_info, block_device_info):
     """Power on the specified instance."""
     compute, project, zone = self.gce_svc, self.gce_project, self.gce_zone
     gce_id = self._get_gce_id_from_instance(instance)
     LOG.info(_LI('Starting instance %s') % instance.uuid)
     operation = gceutils.start_instance(compute, project, zone, gce_id)
     gceutils.wait_for_operation(compute, project, zone, operation)
     LOG.info(_LI("Power on Complete %s") % instance.uuid)
Esempio n. 4
0
 def _hard_reboot(self, context, instance, network_info,
                  block_device_info=None):
     compute, project, zone = self.gce_svc, self.gce_project, self.gce_zone
     gce_id = self._get_gce_id_from_instance(instance)
     LOG.info('Resetting instance %s' % instance.uuid)
     operation = gceutils.reset_instance(compute, project, zone, gce_id)
     gceutils.wait_for_operation(compute, project, operation)
     LOG.info('Hard Reboot Complete %s' % instance.uuid)
Esempio n. 5
0
 def _soft_reboot(self, context, instance, network_info,
                  block_device_info=None):
     compute, project, zone = self.gce_svc, self.gce_project, self.gce_zone
     gce_id = self._get_gce_id_from_instance(instance)
     LOG.info('Stopping instance %s' % instance.uuid)
     operation = gceutils.stop_instance(compute, project, zone, gce_id)
     gceutils.wait_for_operation(compute, project, operation)
     LOG.info('Starting instance %s' % instance.uuid)
     operation = gceutils.start_instance(compute, project, zone, gce_id)
     gceutils.wait_for_operation(compute, project, operation)
     LOG.info('Soft Reboot Complete for instance %s' % instance.uuid)
Esempio n. 6
0
 def detach_volume(self, connection_info, instance, mountpoint,
                   encryption=None):
     """Detach the disk attached to the instance."""
     compute, project, zone = self.gce_svc, self.gce_project, self.gce_zone
     gce_id = self._get_gce_id_from_instance(instance)
     gce_volume = connection_info['data']
     disk_name = gce_volume['name']
     operation = gceutils.detach_disk(compute, project, zone, gce_id,
                                      disk_name)
     gceutils.wait_for_operation(compute, project, operation)
     LOG.info("Volume %s detached from instace %s" %
              (disk_name, instance.uuid))
Esempio n. 7
0
 def attach_volume(self, context, connection_info, instance, mountpoint,
                   disk_bus=None, device_type=None, encryption=None):
     """Attach the disk to the instance at mountpoint using info."""
     compute, project, zone = self.gce_svc, self.gce_project, self.gce_zone
     gce_id = self._get_gce_id_from_instance(instance)
     gce_volume = connection_info['data']
     disk_name = gce_volume['name']
     disk_link = gce_volume['selfLink']
     operation = gceutils.attach_disk(compute, project, zone, gce_id,
                                      disk_name, disk_link)
     gceutils.wait_for_operation(compute, project, operation)
     LOG.info("Volume %s attached to instace %s" %
              (disk_name, instance.uuid))
Esempio n. 8
0
 def power_off(self, instance, timeout=0, retry_interval=0):
     """
     Power off the specified instance.
     :param instance: nova.objects.instance.Instance
     :param timeout: time to wait for GuestOS to shutdown
     :param retry_interval: How often to signal guest while
                            waiting for it to shutdown
     """
     compute, project, zone = self.gce_svc, self.gce_project, self.gce_zone
     gce_id = self._get_gce_id_from_instance(instance)
     LOG.info(_LI('Stopping instance %s') % instance.uuid)
     operation = gceutils.stop_instance(compute, project, zone, gce_id)
     gceutils.wait_for_operation(compute, project, zone, operation)
     LOG.info(_LI('Power off complete %s') % instance.uuid)
Esempio n. 9
0
    def destroy(self,
                context,
                instance,
                network_info,
                block_device_info=None,
                destroy_disks=True,
                migrate_data=None):
        """Destroy the specified instance from the Hypervisor.
        If the instance is not found (for example if networking failed), this
        function should still succeed.  It's probably a good idea to log a
        warning in that case.

        :param context: security context
        :param instance: Instance object as returned by DB layer.
        :param network_info:
           :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
        :param block_device_info: Information about block devices that should
                                  be detached from the instance.
        :param destroy_disks: Indicates if disks should be destroyed
        :param migrate_data: implementation specific params
        """
        compute, project, zone = self.gce_svc, self.gce_project, self.gce_zone
        LOG.info('Deleting instance %s' % instance.uuid)
        try:
            gce_id = self._get_gce_name_from_instance(instance)
        except exception.InstanceNotFound:
            LOG.error("Unable to find GCE mapping for instance %s" %
                      instance.uuid)
            return
        try:
            operation = gceutils.delete_instance(compute, project, zone,
                                                 gce_id)
        except HttpError:
            # Sometimes instance may not exist in GCE, in that case we just
            # allow deleting VM from openstack
            LOG.error(
                "Instance {0} not found in GCE, removing from openstack.".
                format(instance.uuid))
            return
        gceutils.wait_for_operation(compute,
                                    project,
                                    operation,
                                    interval=5,
                                    timeout=300)
        LOG.info("Destroy Complete %s" % instance.uuid)
Esempio n. 10
0
    def snapshot(self, context, instance, image_id, update_task_state):
        """Snapshot an image of the specified instance

        :param context: security context
        :param instance: nova.objects.instance.Instance
        :param image_id: Reference to a pre-created image holding the snapshot.

        Steps:
        1. Find boot disk
        2. Stop instance
        3. Create temporary boot disk snapshot
        4. Start instance
        5. Create temporary disk from snapshot
        6. Create image from disk
        7. Add Image info to glance
        8. Delete temporary disk
        9. Delete temporary snapshot
        """
        instance_stopped = False
        temp_disk_snapshot = False
        temp_disk_from_snapshot = False
        image_created = False

        compute, project, zone = self.gce_svc, self.gce_project, self.gce_zone

        try:
            gce_id = self._get_gce_name_from_instance(instance)
            LOG.info("Taking snapshot of instance %s" % instance.uuid)
            try:
                boot_disk = gceutils.get_instance_boot_disk(
                    compute, project, zone, gce_id)
            except AssertionError:
                reason = "Unable to find boot disk from instance metadata {0}"
                reason = reason.format(instance.uuid)
                raise exception.InvalidMetadata(reason=reason)
            disk_name = boot_disk['name']
            LOG.debug("1. Found boot disk %s for instance %s" %
                      (disk_name, instance.uuid))

            operation = gceutils.stop_instance(compute, project, zone, gce_id)
            gceutils.wait_for_operation(compute, project, operation)
            instance_stopped = True
            LOG.debug("2. Temporarily stopped instance %s" % instance.uuid)

            snapshot_name = 'nsnap-' + disk_name + time.strftime("%s")
            operation = gceutils.snapshot_disk(compute, project, zone,
                                               boot_disk['name'],
                                               snapshot_name)
            gceutils.wait_for_operation(compute, project, operation)
            temp_disk_snapshot = True
            LOG.debug("3. Created boot disk snapshot %s" % snapshot_name)

            operation = gceutils.start_instance(compute, project, zone, gce_id)
            gceutils.wait_for_operation(compute, project, operation)
            instance_stopped = False
            LOG.debug("4. Restart instance after disk snapshot %s" %
                      instance.uuid)

            snapshot_disk_name = 'vol-' + snapshot_name
            operation = gceutils.create_disk_from_snapshot(
                compute, project, zone, snapshot_disk_name, snapshot_name)
            gceutils.wait_for_operation(compute, project, operation)
            snapshot_disk_info = gceutils.get_disk(compute, project, zone,
                                                   snapshot_disk_name)
            temp_disk_from_snapshot = True
            LOG.debug("5. Created disk %s from snapshot %s" %
                      (snapshot_disk_name, snapshot_name))

            update_task_state(task_state=task_states.IMAGE_PENDING_UPLOAD)
            image_api = glance.get_default_image_service()
            image_data = image_api.show(context, image_id)
            name = image_data['name']
            operation = gceutils.create_image_from_disk(
                compute, project, name, snapshot_disk_info['selfLink'])
            gceutils.wait_for_operation(compute,
                                        project,
                                        operation,
                                        timeout=120)
            image_created = True
            LOG.debug("6. Created image %s from disk %s" %
                      (name, snapshot_disk_name))
            LOG.info("Created GCE image %s from instance %s" %
                     (name, instance.uuid))

            update_task_state(task_state=task_states.IMAGE_UPLOADING,
                              expected_state=task_states.IMAGE_PENDING_UPLOAD)
            gce_img_data = gceutils.get_image(compute, project, name)
            image_metadata = {
                'name': name,
                'container_format': 'bare',
                'disk_format': 'raw',
                'is_public': False,
                'status': 'active',
                'properties': {
                    'image_state': 'available',
                    'owner_id': instance.project_id,
                    'ramdisk_id': instance.ramdisk_id,
                    'location': 'gce://%s/%s/%s' % (project, name, image_id),
                    'gce_image_id': gce_img_data['id'],
                    'gce_link': gce_img_data['selfLink'],
                    'gce_size': gce_img_data['diskSizeGb']
                },
            }
            image_api.update(context, image_id, image_metadata)
            LOG.debug("7. Added image to glance %s" % name)

            disk_operation = gceutils.delete_disk(compute, project, zone,
                                                  snapshot_disk_name)
            snap_operation = gceutils.delete_snapshot(compute, project,
                                                      snapshot_name)
            gceutils.wait_for_operation(compute, project, disk_operation)
            temp_disk_from_snapshot = False
            LOG.debug("8. Delete temporary disk %s" % snapshot_disk_name)

            gceutils.wait_for_operation(compute, project, snap_operation)
            temp_disk_snapshot = False
            LOG.debug("9. Delete temporary disk snapshot %s" % snapshot_name)
            LOG.info("Completed snapshot for instance %s" % instance.uuid)

        except Exception as e:
            LOG.exception("An error occured during image creation: %s" % e)
            if instance_stopped:
                operation = gceutils.start_instance(compute, project, zone,
                                                    gce_id)
                gceutils.wait_for_operation(compute, project, operation)
                LOG.debug("Restart instance after disk snapshot %s" %
                          instance.uuid)
            if image_created:
                LOG.info("Rollback snapshot for instance %s, deleting image "
                         "%s from GCE" % (instance.uuid, name))
                operation = gceutils.delete_image(compute, project, name)
                gceutils.wait_for_operation(compute, project, operation)
            if temp_disk_from_snapshot:
                disk_operation = gceutils.delete_disk(compute, project, zone,
                                                      snapshot_disk_name)
                gceutils.wait_for_operation(compute, project, disk_operation)
                LOG.debug("Rollback snapshot for instace %s, delete temporary"
                          " disk %s" % (instance.uuid, snapshot_disk_name))
            if temp_disk_snapshot:
                snap_operation = gceutils.delete_snapshot(
                    compute, project, snapshot_name)
                gceutils.wait_for_operation(compute, project, snap_operation)
                LOG.debug("Rollback snapshot for instance %s, delete temporary"
                          " disk snapshot %s" % (instance.uuid, snapshot_name))
            raise e
Esempio n. 11
0
    def spawn(self,
              context,
              instance,
              image_meta,
              injected_files,
              admin_password,
              network_info=None,
              block_device_info=None):
        """Create a new instance/VM/domain on the virtualization platform.
        Once this successfully completes, the instance should be
        running (power_state.RUNNING).

        If this fails, any partial instance should be completely
        cleaned up, and the virtualization platform should be in the state
        that it was before this call began.

        :param context: security context <Not Yet Implemented>
        :param instance: nova.objects.instance.Instance
                         This function should use the data there to guide
                         the creation of the new instance.
        :param image_meta: image object returned by nova.image.glance that
                           defines the image from which to boot this instance
        :param injected_files: User files to inject into instance.
        :param admin_password: set in instance. <Not Yet Implemented>
        :param network_info:
           :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
        :param block_device_info: Information about block devices to be
                                  attached to the instance.
        """
        compute, project, zone = self.gce_svc, self.gce_project, self.gce_zone
        instance_name = instance.name
        LOG.info("Creating instance %s as %s on GCE." %
                 (instance.display_name, instance.name))
        image_link = instance.system_metadata['image_gce_link']
        flavor_name = instance.flavor.name
        flavor_link = "zones/%s/machineTypes/%s" % (self.gce_zone, flavor_name)
        operation = gceutils.create_instance(compute, project, zone,
                                             instance_name, image_link,
                                             flavor_link)
        gceutils.wait_for_operation(compute, project, zone, operation)
        gce_instance = gceutils.get_instance(compute, project, zone,
                                             instance_name)
        # Update GCE info in openstack instance metadata
        instance.metadata.update({'gce_id': gce_instance['name']})
        public_ip_address = gceutils.get_external_ip(compute, project, zone,
                                                     gce_instance)
        if public_ip_address:
            instance.metadata.update({'public_ip_address': public_ip_address})
        operation = gceutils.set_instance_metadata(
            compute,
            project,
            zone,
            gce_instance['name'], [
                {
                    'key': 'openstack_id',
                    'value': instance.uuid
                },
            ],
            operation='add')
        gceutils.wait_for_operation(compute, project, zone, operation)
        self._uuid_to_gce_instance[instance.uuid] = gceutils.get_instance(
            compute, project, zone, instance_name)