def _ensure(self):

        garbage_can = []
        zone = os.path.basename(__node__['gce']['zone'])
        project_id = __node__['gce']['project_id']
        server_name = __node__['server_id']

        try:
            connection = __node__['gce'].connect_compute()
        except:
            e = sys.exc_info()[1]
            LOG.debug('Can not get GCE connection: %s' % e)
            """ No connection, implicit check """
            try:
                self._check_attr('name')
            except:
                raise storage2.StorageError(
                    'Disk is not created yet, and GCE connection is unavailable'
                )
            device = gce_util.devicename_to_device(self.name)
            if not device:
                raise storage2.StorageError(
                    "Disk is not attached and GCE connection is unavailable")

            self.device = device
        else:
            LOG.debug('Successfully created connection to cloud engine')
            try:
                create = False
                if not self.link:
                    # Disk does not exist, create it first
                    create_request_body = dict(name=self.name)
                    if self.snap:
                        snap_dict = dict(self.snap)
                        snap_dict['type'] = STORAGE_TYPE
                        self.snap = storage2.snapshot(snap_dict)
                        LOG.debug(
                            'Ensuring that snapshot is ready, before creating disk from it'
                        )
                        gce_util.wait_snapshot_ready(self.snap)
                        create_request_body[
                            'sourceSnapshot'] = to_current_api_version(
                                self.snap.link)
                    else:
                        create_request_body['sizeGb'] = self.size

                    create = True
                else:
                    self._check_attr('zone')
                    LOG.debug('Checking that disk already exists')
                    try:
                        disk_dict = connection.disks().get(
                            disk=self.name, project=project_id,
                            zone=zone).execute()
                        self.link = disk_dict['selfLink']
                    except HttpError, e:
                        code = int(e.resp['status'])
                        if code == 404:
                            raise storage2.VolumeNotExistsError(self.name)
                        else:
                            raise

                    if self.zone != zone:
                        # Volume is in different zone, snapshot it,
                        # create new volume from this snapshot, then attach
                        temp_snap = self.snapshot('volume')
                        garbage_can.append(temp_snap)
                        new_name = self.name + zone
                        create_request_body = dict(
                            name=new_name,
                            sourceSnapshot=to_current_api_version(
                                temp_snap.link))
                        create = True

                attach = False
                if create:
                    disk_name = create_request_body['name']
                    if "pd-standard" != self.disk_type:
                        disk_type = gce_util.get_disktype(
                            conn=connection,
                            project_id=project_id,
                            zone=zone,
                            disktype=self.disk_type)
                        create_request_body.update(
                            {'type': disk_type['selfLink']})

                    LOG.debug('Creating new GCE disk %s' % disk_name)
                    op = connection.disks().insert(
                        project=project_id,
                        zone=zone,
                        body=create_request_body).execute()
                    gce_util.wait_for_operation(connection, project_id,
                                                op['name'], zone)
                    disk_dict = connection.disks().get(disk=disk_name,
                                                       project=project_id,
                                                       zone=zone).execute()
                    self.id = disk_dict['id']
                    self.link = disk_dict['selfLink']
                    self.zone = zone
                    self.name = disk_name
                    attach = True

                else:
                    if self.last_attached_to and self.last_attached_to != server_name:
                        LOG.debug(
                            "Making sure that disk %s detached from previous attachment place."
                            % self.name)
                        try:
                            gce_util.ensure_disk_detached(
                                connection, project_id, zone,
                                self.last_attached_to, self.link)
                        except:
                            e = sys.exc_info()[1]
                            if 'resource was not found' in str(e):
                                raise storage2.VolumeNotExistsError(self.link)
                            raise

                    attachment_inf = self._attachment_info(connection)
                    if attachment_inf:
                        disk_devicename = attachment_inf['deviceName']
                    else:
                        attach = True

                if attach:
                    LOG.debug('Attaching disk %s to current instance' %
                              self.name)
                    try:
                        op = connection.instances().attachDisk(
                            instance=server_name,
                            project=project_id,
                            zone=zone,
                            body=dict(deviceName=self.name,
                                      source=self.link,
                                      mode="READ_WRITE",
                                      type="PERSISTENT")).execute()
                    except:
                        e = sys.exc_info()[1]
                        if 'resource was not found' in str(e):
                            raise storage2.VolumeNotExistsError(self.link)
                        raise

                    gce_util.wait_for_operation(connection,
                                                project_id,
                                                op['name'],
                                                zone=zone)
                    disk_devicename = self.name

                for i in range(10):
                    device = gce_util.devicename_to_device(disk_devicename)
                    if device:
                        break
                    LOG.debug('Device not found in system. Retrying in 1s.')
                    time.sleep(1)
                else:
                    raise storage2.StorageError(
                        "Disk should be attached, but corresponding device not found in system"
                    )

                self.device = device
                self.last_attached_to = server_name
                self.snap = None

            finally:
                # Perform cleanup
                for garbage in garbage_can:
                    try:
                        garbage.destroy(force=True)
                    except:
                        e = sys.exc_info()[1]
                        LOG.debug(
                            'Failed to destroy temporary storage object %s: %s',
                            garbage, e)
Example #2
0
    def _ensure(self):

        garbage_can = []
        zone = os.path.basename(__node__['gce']['zone'])
        project_id = __node__['gce']['project_id']
        server_name = __node__['server_id']

        try:
            connection = __node__['gce'].connect_compute()
        except:
            e = sys.exc_info()[1]
            LOG.debug('Can not get GCE connection: %s' % e)
            """ No connection, implicit check """
            try:
                self._check_attr('name')
            except:
                raise storage2.StorageError('Disk is not created yet, and GCE connection is unavailable')
            device = gce_util.devicename_to_device(self.name)
            if not device:
                raise storage2.StorageError("Disk is not attached and GCE connection is unavailable")

            self.device = device
        else:
            LOG.debug('Successfully created connection to cloud engine')
            try:
                create = False
                if not self.link:
                    # Disk does not exist, create it first
                    create_request_body = dict(name=self.name)
                    if self.snap:
                        snap_dict = dict(self.snap)
                        snap_dict['type'] = STORAGE_TYPE
                        self.snap = storage2.snapshot(snap_dict)
                        LOG.debug('Ensuring that snapshot is ready, before creating disk from it')
                        gce_util.wait_snapshot_ready(self.snap)
                        create_request_body['sourceSnapshot'] = to_current_api_version(self.snap.link)
                    else:
                        create_request_body['sizeGb'] = self.size

                    create = True
                else:
                    self._check_attr('zone')
                    LOG.debug('Checking that disk already exists')
                    try:
                        disk_dict = connection.disks().get(disk=self.name, project=project_id,
                                                                            zone=zone).execute()
                        self.link = disk_dict['selfLink']
                    except HttpError, e:
                        code = int(e.resp['status'])
                        if code == 404:
                            raise storage2.VolumeNotExistsError(self.name)
                        else:
                            raise

                    if self.zone != zone:
                        # Volume is in different zone, snapshot it,
                        # create new volume from this snapshot, then attach
                        temp_snap = self.snapshot('volume')
                        garbage_can.append(temp_snap)
                        new_name = self.name + zone
                        create_request_body = dict(name=new_name,
                                                   sourceSnapshot=to_current_api_version(temp_snap.link))
                        create = True

                attach = False
                if create:
                    disk_name = create_request_body['name']
                    LOG.debug('Creating new GCE disk %s' % disk_name)
                    op = connection.disks().insert(project=project_id,
                                                   zone=zone,
                                                   body=create_request_body).execute()
                    gce_util.wait_for_operation(connection, project_id, op['name'], zone)
                    disk_dict = connection.disks().get(disk=disk_name,
                                                       project=project_id,
                                                       zone=zone).execute()
                    self.id = disk_dict['id']
                    self.link = disk_dict['selfLink']
                    self.zone = zone
                    self.name = disk_name
                    attach = True

                else:
                    if self.last_attached_to and self.last_attached_to != server_name:
                        LOG.debug("Making sure that disk %s detached from previous attachment place." % self.name)
                        try:
                            gce_util.ensure_disk_detached(connection,
                                                          project_id,
                                                          zone,
                                                          self.last_attached_to,
                                                          self.link)
                        except:
                            e = sys.exc_info()[1]
                            if 'resource was not found' in str(e):
                                raise storage2.VolumeNotExistsError(self.link)
                            raise
                        
                    attachment_inf = self._attachment_info(connection)
                    if attachment_inf:
                        disk_devicename = attachment_inf['deviceName']
                    else:
                        attach = True

                if attach:
                    LOG.debug('Attaching disk %s to current instance' % self.name)
                    try:
                        op = connection.instances().attachDisk(instance=server_name, project=project_id,
                                            zone=zone, body=dict(deviceName=self.name,
                                                                    source=self.link,
                                                                    mode="READ_WRITE",
                                                                    type="PERSISTENT")).execute()
                    except:
                        e = sys.exc_info()[1]
                        if 'resource was not found' in str(e):
                            raise storage2.VolumeNotExistsError(self.link)
                        raise

                    gce_util.wait_for_operation(connection, project_id, op['name'], zone=zone)
                    disk_devicename = self.name

                for i in range(10):
                    device = gce_util.devicename_to_device(disk_devicename)
                    if device:
                        break
                    LOG.debug('Device not found in system. Retrying in 1s.')
                    time.sleep(1)
                else:
                    raise storage2.StorageError("Disk should be attached, but corresponding device not found in system")

                self.device = device
                self.last_attached_to = server_name
                self.snap = None

            finally:
                # Perform cleanup
                for garbage in garbage_can:
                    try:
                        garbage.destroy(force=True)
                    except:
                        e = sys.exc_info()[1]
                        LOG.debug('Failed to destroy temporary storage object %s: %s', garbage, e)
Example #3
0
    def _ensure(self):

        garbage_can = []
        zone = os.path.basename(__node__['gce']['zone'])
        project_id = __node__['gce']['project_id']
        server_name = __node__['server_id']

        try:
            connection = __node__['gce']['compute_connection']
        except:
            """ No connection, implicit check """
            try:
                self._check_attr('name')
            except:
                raise storage2.StorageError(
                    'Disk is not created yet, and GCE connection'
                    ' is unavailable')
            device = gce_util.devicename_to_device(self.name)
            if not device:
                raise storage2.StorageError(
                    "Disk is not attached and GCE connection is unavailable")

            self.device = device
        else:

            try:
                # TODO(spike) raise VolumeNotExistsError when link passed disk not exists
                create = False
                if not self.link:
                    # Disk does not exist, create it first
                    create_request_body = dict(name=self.name,
                                               sizeGb=self.size)
                    if self.snap:
                        self.snap = storage2.snapshot(self.snap)
                        create_request_body['sourceSnapshot'] = self.snap.link
                    create = True
                else:
                    self._check_attr('zone')
                    if self.zone != zone:
                        # Volume is in different zone, snapshot it,
                        # create new volume from this snapshot, then attach
                        temp_snap = self.snapshot('volume')
                        garbage_can.append(temp_snap)
                        new_name = self.name + zone
                        create_request_body = dict(
                            name=new_name,
                            sizeGb=self.size,
                            sourceSnapshot=temp_snap.link)
                        create = True

                attach = False
                if create:
                    disk_name = create_request_body['name']
                    LOG.debug('Creating new GCE disk %s' % disk_name)
                    op = connection.disks().insert(
                        project=project_id,
                        zone=zone,
                        body=create_request_body).execute()
                    gce_util.wait_for_operation(connection, project_id,
                                                op['name'], zone)
                    disk_dict = connection.disks().get(disk=disk_name,
                                                       project=project_id,
                                                       zone=zone).execute()
                    self.id = disk_dict['id']
                    self.link = disk_dict['selfLink']
                    self.zone = zone
                    self.name = disk_name
                    attach = True

                else:
                    if self.last_attached_to and self.last_attached_to != server_name:
                        LOG.debug(
                            "Making sure that disk %s detached from previous attachment place."
                            % self.name)
                        gce_util.ensure_disk_detached(connection, project_id,
                                                      zone,
                                                      self.last_attached_to,
                                                      self.link)

                    attachment_inf = self._attachment_info(connection)
                    if attachment_inf:
                        disk_devicename = attachment_inf['deviceName']
                    else:
                        attach = True

                if attach:
                    LOG.debug('Attaching disk %s to current instance' %
                              self.name)
                    op = connection.instances().attachDisk(
                        instance=server_name,
                        project=project_id,
                        zone=zone,
                        body=dict(deviceName=self.name,
                                  source=self.link,
                                  mode="READ_WRITE",
                                  type="PERSISTENT")).execute()
                    gce_util.wait_for_operation(connection,
                                                project_id,
                                                op['name'],
                                                zone=zone)
                    disk_devicename = self.name

                device = gce_util.devicename_to_device(disk_devicename)
                if not device:
                    raise storage2.StorageError(
                        "Disk should be attached, but corresponding"
                        " device not found in system")
                self.device = device
                self.last_attached_to = server_name
                self.snap = None

            finally:
                # Perform cleanup
                for garbage in garbage_can:
                    try:
                        garbage.destroy(force=True)
                    except:
                        pass
Example #4
0
    def _ensure(self):

        garbage_can = []
        zone = os.path.basename(__node__['gce']['zone'])
        project_id = __node__['gce']['project_id']
        server_name = __node__['server_id']

        try:
            connection = __node__['gce']['compute_connection']
        except:
            """ No connection, implicit check """
            try:
                self._check_attr('name')
            except:
                raise storage2.StorageError('Disk is not created yet, and GCE connection'
                                            ' is unavailable')
            device = gce_util.devicename_to_device(self.name)
            if not device:
                raise storage2.StorageError("Disk is not attached and GCE connection is unavailable")

            self.device = device
        else:

            try:
                # TODO(spike) raise VolumeNotExistsError when link passed disk not exists
                create = False
                if not self.link:
                    # Disk does not exist, create it first
                    create_request_body = dict(name=self.name, sizeGb=self.size)
                    if self.snap:
                        self.snap = storage2.snapshot(self.snap)
                        create_request_body['sourceSnapshot'] = self.snap.link
                    create = True
                else:
                    self._check_attr('zone')
                    if self.zone != zone:
                        # Volume is in different zone, snapshot it,
                        # create new volume from this snapshot, then attach
                        temp_snap = self.snapshot('volume')
                        garbage_can.append(temp_snap)
                        new_name = self.name + zone
                        create_request_body = dict(name=new_name,
                                                   sizeGb=self.size,
                                                   sourceSnapshot=temp_snap.link)
                        create = True

                attach = False
                if create:
                    disk_name = create_request_body['name']
                    LOG.debug('Creating new GCE disk %s' % disk_name)
                    op = connection.disks().insert(project=project_id,
                                                   zone=zone,
                                                   body=create_request_body).execute()
                    gce_util.wait_for_operation(connection, project_id, op['name'], zone)
                    disk_dict = connection.disks().get(disk=disk_name,
                                                       project=project_id,
                                                       zone=zone).execute()
                    self.id = disk_dict['id']
                    self.link = disk_dict['selfLink']
                    self.zone = zone
                    self.name = disk_name
                    attach = True

                else:
                    if self.last_attached_to and self.last_attached_to != server_name:
                        LOG.debug("Making sure that disk %s detached from previous attachment place." % self.name)
                        gce_util.ensure_disk_detached(connection, project_id, zone, self.last_attached_to, self.link)

                    attachment_inf = self._attachment_info(connection)
                    if attachment_inf:
                        disk_devicename = attachment_inf['deviceName']
                    else:
                        attach = True

                if attach:
                    LOG.debug('Attaching disk %s to current instance' % self.name)
                    op = connection.instances().attachDisk(
                                            instance=server_name,
                                            project=project_id,
                                            zone=zone,
                                            body=dict(
                                                            deviceName=self.name,
                                                            source=self.link,
                                                            mode="READ_WRITE",
                                                            type="PERSISTENT"
                                            )).execute()
                    gce_util.wait_for_operation(connection, project_id, op['name'], zone=zone)
                    disk_devicename = self.name

                device = gce_util.devicename_to_device(disk_devicename)
                if not device:
                    raise storage2.StorageError("Disk should be attached, but corresponding"
                                                                            " device not found in system")
                self.device = device
                self.last_attached_to = server_name
                self.snap = None

            finally:
                # Perform cleanup
                for garbage in garbage_can:
                    try:
                        garbage.destroy(force=True)
                    except:
                        pass