Esempio n. 1
0
 def setUp(self):
     super(TestConsistencyGroupStatus, self).setUp()
     self.field = fields.ConsistencyGroupStatusField()
     self.coerce_good_values = [('error', 'error'),
                                ('available', 'available'),
                                ('creating', 'creating'),
                                ('deleting', 'deleting'),
                                ('deleted', 'deleted'),
                                ('updating', 'updating'),
                                ('error_deleting', 'error_deleting')]
     self.coerce_bad_values = ['acme']
     self.to_primitive_values = self.coerce_good_values[0:1]
     self.from_primitive_values = self.coerce_good_values[0:1]
Esempio n. 2
0
 def setUp(self):
     super(TestConsistencyGroupStatus, self).setUp()
     self.field = fields.ConsistencyGroupStatusField()
     self.coerce_good_values = [
         ('error', fields.ConsistencyGroupStatus.ERROR),
         ('available', fields.ConsistencyGroupStatus.AVAILABLE),
         ('creating', fields.ConsistencyGroupStatus.CREATING),
         ('deleting', fields.ConsistencyGroupStatus.DELETING),
         ('deleted', fields.ConsistencyGroupStatus.DELETED),
         ('updating', fields.ConsistencyGroupStatus.UPDATING),
         ('error_deleting', fields.ConsistencyGroupStatus.ERROR_DELETING)]
     self.coerce_bad_values = ['acme']
     self.to_primitive_values = self.coerce_good_values[0:1]
     self.from_primitive_values = self.coerce_good_values[0:1]
Esempio n. 3
0
class ConsistencyGroup(base.CinderPersistentObject, base.CinderObject,
                       base.CinderObjectDictCompat, base.ClusteredObject):
    # Version 1.0: Initial version
    # Version 1.1: Added cgsnapshots and volumes relationships
    # Version 1.2: Changed 'status' field to use ConsistencyGroupStatusField
    # Version 1.3: Added cluster fields
    # Version 1.4: Added from_group
    VERSION = '1.4'

    OPTIONAL_FIELDS = ('cgsnapshots', 'volumes', 'cluster')

    fields = {
        'id': fields.UUIDField(),
        'user_id': fields.StringField(),
        'project_id': fields.StringField(),
        'cluster_name': fields.StringField(nullable=True),
        'cluster': fields.ObjectField('Cluster', nullable=True,
                                      read_only=True),
        'host': fields.StringField(nullable=True),
        'availability_zone': fields.StringField(nullable=True),
        'name': fields.StringField(nullable=True),
        'description': fields.StringField(nullable=True),
        'volume_type_id': fields.StringField(nullable=True),
        'status': c_fields.ConsistencyGroupStatusField(nullable=True),
        'cgsnapshot_id': fields.UUIDField(nullable=True),
        'source_cgid': fields.UUIDField(nullable=True),
        'cgsnapshots': fields.ObjectField('CGSnapshotList', nullable=True),
        'volumes': fields.ObjectField('VolumeList', nullable=True),
    }

    def obj_make_compatible(self, primitive, target_version):
        """Make a CG representation compatible with a target version."""
        # Convert all related objects
        super(ConsistencyGroup,
              self).obj_make_compatible(primitive, target_version)

        target_version = versionutils.convert_version_to_tuple(target_version)
        # Before v1.3 we didn't have cluster fields so we have to remove them.
        if target_version < (1, 3):
            for obj_field in ('cluster', 'cluster_name'):
                primitive.pop(obj_field, None)

    @classmethod
    def _from_db_object(cls,
                        context,
                        consistencygroup,
                        db_consistencygroup,
                        expected_attrs=None):
        if expected_attrs is None:
            expected_attrs = []
        for name, field in consistencygroup.fields.items():
            if name in cls.OPTIONAL_FIELDS:
                continue
            value = db_consistencygroup.get(name)
            setattr(consistencygroup, name, value)

        if 'cgsnapshots' in expected_attrs:
            cgsnapshots = base.obj_make_list(
                context, objects.CGSnapshotList(context), objects.CGSnapshot,
                db_consistencygroup['cgsnapshots'])
            consistencygroup.cgsnapshots = cgsnapshots

        if 'volumes' in expected_attrs:
            volumes = base.obj_make_list(context, objects.VolumeList(context),
                                         objects.Volume,
                                         db_consistencygroup['volumes'])
            consistencygroup.volumes = volumes

        if 'cluster' in expected_attrs:
            db_cluster = db_consistencygroup.get('cluster')
            # If this consistency group doesn't belong to a cluster the cluster
            # field in the ORM instance will have value of None.
            if db_cluster:
                consistencygroup.cluster = objects.Cluster(context)
                objects.Cluster._from_db_object(context,
                                                consistencygroup.cluster,
                                                db_cluster)
            else:
                consistencygroup.cluster = None

        consistencygroup._context = context
        consistencygroup.obj_reset_changes()
        return consistencygroup

    def create(self, cg_snap_id=None, cg_id=None):
        """Create a consistency group.

        If cg_snap_id or cg_id are specified then volume_type_id,
        availability_zone, and host will be taken from the source Consistency
        Group.
        """
        if self.obj_attr_is_set('id'):
            raise exception.ObjectActionError(action='create',
                                              reason=_('already_created'))
        updates = self.cinder_obj_get_changes()

        if 'cgsnapshots' in updates:
            raise exception.ObjectActionError(action='create',
                                              reason=_('cgsnapshots assigned'))

        if 'volumes' in updates:
            raise exception.ObjectActionError(action='create',
                                              reason=_('volumes assigned'))

        if 'cluster' in updates:
            raise exception.ObjectActionError(action='create',
                                              reason=_('cluster assigned'))

        db_consistencygroups = db.consistencygroup_create(
            self._context, updates, cg_snap_id, cg_id)
        self._from_db_object(self._context, self, db_consistencygroups)

    def from_group(self, group):
        """Convert a generic volume group object to a cg object."""
        self.id = group.id
        self.user_id = group.user_id
        self.project_id = group.project_id
        self.cluster_name = group.cluster_name
        self.host = group.host
        self.availability_zone = group.availability_zone
        self.name = group.name
        self.description = group.description
        self.volume_type_id = ""
        for v_type in group.volume_types:
            self.volume_type_id += v_type.id + ","
        self.status = group.status
        self.cgsnapshot_id = group.group_snapshot_id
        self.source_cgid = group.source_group_id

    def obj_load_attr(self, attrname):
        if attrname not in self.OPTIONAL_FIELDS:
            raise exception.ObjectActionError(
                action='obj_load_attr',
                reason=_('attribute %s not lazy-loadable') % attrname)
        if not self._context:
            raise exception.OrphanedObjectError(method='obj_load_attr',
                                                objtype=self.obj_name())

        if attrname == 'cgsnapshots':
            self.cgsnapshots = objects.CGSnapshotList.get_all_by_group(
                self._context, self.id)

        if attrname == 'volumes':
            self.volumes = objects.VolumeList.get_all_by_group(
                self._context, self.id)

        # If this consistency group doesn't belong to a cluster (cluster_name
        # is empty), then cluster field will be None.
        if attrname == 'cluster':
            if self.cluster_name:
                self.cluster = objects.Cluster.get_by_id(
                    self._context, name=self.cluster_name)
            else:
                self.cluster = None

        self.obj_reset_changes(fields=[attrname])

    def save(self):
        updates = self.cinder_obj_get_changes()
        if updates:
            if 'cgsnapshots' in updates:
                raise exception.ObjectActionError(
                    action='save', reason=_('cgsnapshots changed'))
            if 'volumes' in updates:
                raise exception.ObjectActionError(action='save',
                                                  reason=_('volumes changed'))
            if 'cluster' in updates:
                raise exception.ObjectActionError(action='save',
                                                  reason=_('cluster changed'))

            db.consistencygroup_update(self._context, self.id, updates)
            self.obj_reset_changes()

    def destroy(self):
        with self.obj_as_admin():
            updated_values = db.consistencygroup_destroy(
                self._context, self.id)
        self.update(updated_values)
        self.obj_reset_changes(updated_values.keys())
Esempio n. 4
0
class ConsistencyGroup(base.CinderPersistentObject, base.CinderObject,
                       base.CinderObjectDictCompat):
    # Version 1.0: Initial version
    # Version 1.1: Added cgsnapshots and volumes relationships
    # Version 1.2: Changed 'status' field to use ConsistencyGroupStatusField
    VERSION = '1.2'

    fields = {
        'id': fields.UUIDField(),
        'user_id': fields.UUIDField(),
        'project_id': fields.UUIDField(),
        'host': fields.StringField(nullable=True),
        'availability_zone': fields.StringField(nullable=True),
        'name': fields.StringField(nullable=True),
        'description': fields.StringField(nullable=True),
        'volume_type_id': fields.UUIDField(nullable=True),
        'status': c_fields.ConsistencyGroupStatusField(nullable=True),
        'cgsnapshot_id': fields.UUIDField(nullable=True),
        'source_cgid': fields.UUIDField(nullable=True),
        'cgsnapshots': fields.ObjectField('CGSnapshotList', nullable=True),
        'volumes': fields.ObjectField('VolumeList', nullable=True),
    }

    @staticmethod
    def _from_db_object(context, consistencygroup, db_consistencygroup,
                        expected_attrs=None):
        if expected_attrs is None:
            expected_attrs = []
        for name, field in consistencygroup.fields.items():
            if name in OPTIONAL_FIELDS:
                continue
            value = db_consistencygroup.get(name)
            setattr(consistencygroup, name, value)

        if 'cgsnapshots' in expected_attrs:
            cgsnapshots = base.obj_make_list(
                context, objects.CGSnapshotsList(context),
                objects.CGSnapshot,
                db_consistencygroup['cgsnapshots'])
            consistencygroup.cgsnapshots = cgsnapshots

        if 'volumes' in expected_attrs:
            volumes = base.obj_make_list(
                context, objects.VolumeList(context),
                objects.Volume,
                db_consistencygroup['volumes'])
            consistencygroup.cgsnapshots = volumes

        consistencygroup._context = context
        consistencygroup.obj_reset_changes()
        return consistencygroup

    @base.remotable
    def create(self):
        if self.obj_attr_is_set('id'):
            raise exception.ObjectActionError(action='create',
                                              reason=_('already_created'))
        updates = self.cinder_obj_get_changes()

        if 'cgsnapshots' in updates:
            raise exception.ObjectActionError(action='create',
                                              reason=_('cgsnapshots assigned'))

        if 'volumes' in updates:
            raise exception.ObjectActionError(action='create',
                                              reason=_('volumes assigned'))

        db_consistencygroups = db.consistencygroup_create(self._context,
                                                          updates)
        self._from_db_object(self._context, self, db_consistencygroups)

    def obj_load_attr(self, attrname):
        if attrname not in OPTIONAL_FIELDS:
            raise exception.ObjectActionError(
                action='obj_load_attr',
                reason=_('attribute %s not lazy-loadable') % attrname)
        if not self._context:
            raise exception.OrphanedObjectError(method='obj_load_attr',
                                                objtype=self.obj_name())

        if attrname == 'cgsnapshots':
            self.cgsnapshots = objects.CGSnapshotList.get_all_by_group(
                self._context, self.id)

        if attrname == 'volumes':
            self.volumes = objects.VolumeList.get_all_by_group(self._context,
                                                               self.id)

        self.obj_reset_changes(fields=[attrname])

    @base.remotable
    def save(self):
        updates = self.cinder_obj_get_changes()
        if updates:
            if 'cgsnapshots' in updates:
                raise exception.ObjectActionError(
                    action='save', reason=_('cgsnapshots changed'))
            if 'volumes' in updates:
                raise exception.ObjectActionError(
                    action='save', reason=_('volumes changed'))

            db.consistencygroup_update(self._context, self.id, updates)
            self.obj_reset_changes()

    @base.remotable
    def destroy(self):
        with self.obj_as_admin():
            db.consistencygroup_destroy(self._context, self.id)