def get_size(self, location, context=None): """ Takes a `glance_store.location.Location` object that indicates where to find the image file, and returns the size :param location `glance_store.location.Location` object, supplied from glance_store.location.get_location_from_uri() :retval int: size of image file in bytes """ img_data = gceutils.get_image(self.gce_svc, location.store_location.gce_project, location.store_location.gce_id) img_size = int(img_data['diskSizeGb']) * units.Gi return img_size
def get_size(self, location, context=None): """ Takes a `glance_store.location.Location` object that indicates where to find the image file, and returns the size :param location `glance_store.location.Location` object, supplied from glance_store.location.get_location_from_uri() :retval int: size of image file in bytes """ gce_svc = self.gce_svc if not gce_svc: # GCE service is unavailable can't determine image size return 0 try: img_data = gceutils.get_image(self.gce_svc, location.store_location.gce_project, location.store_location.gce_id) img_size = int(img_data['diskSizeGb']) * units.Gi return img_size except HttpError: raise exceptions.NotFound(image=location.store_location.gce_id)
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