class Lun(resources.LogicalDrive): class Meta: identifier = ScopedId("lun_id") charts = [ {"title": "Bandwidth", "series": ["read_bytes_sec", "write_bytes_sec"]}, {"title": "Latency distribution", "series": ["write_latency_hist"]}, ] lun_id = attributes.String() couplet = attributes.ResourceReference() read_bytes_sec = statistics.Gauge(units="B/s", label="Read bandwidth") write_bytes_sec = statistics.Gauge(units="B/s", label="Write bandwidth") write_latency_hist = statistics.BytesHistogram( label="Write latency", bins=[ (0, 16), (17, 32), (33, 64), (65, 128), (129, 256), (257, 512), (513, 1024), (1024, 2048), (2049, 4096), (4097, 8192), (8193, 16384), (16385, 32768), ], ) def get_label(self): return self.lun_id
class LvmVolume(resources.LogicalDriveSlice): # Q: Why is this identified by LV UUID and VG UUID rather than just # LV UUID? Isn't the LV UUID unique enough? # A: We're matching LVM2's behaviour. If you e.g. imagine a machine that # has some VGs and LVs, then if you want to disambiguate them you run # 'vgchange -u' to get a new VG UUID. However, there is no equivalent # command to reset LV uuid, because LVM finds two LVs with the same UUID # in VGs with different UUIDs to be unique enough. class Meta: identifier = GlobalId("uuid", "vg") icon = "lvm_lv" label = "Logical volume" vg = attributes.ResourceReference() uuid = attributes.Uuid() name = attributes.String() def get_label(self): return "%s-%s" % (self.vg.name, self.name) """ This has to be a class method today because at the point we call it we only has the type not the object""" @classmethod def device_type(cls): return "lvm_volume"
def test_validate(self): rr = attributes.ResourceReference(optional = True) rr.validate(None) with self.assertRaises(ValueError): rr.validate("not a resource") from chroma_core.models import StorageResourceRecord resource = StorageResourceRecord.objects.get(id = self.record_pk).to_resource() rr.validate(resource) rr = attributes.ResourceReference() rr.validate(resource) with self.assertRaises(ValueError): rr.validate(None) with self.assertRaises(ValueError): rr.validate("not a resource")
class Partition(resources.LogicalDriveSlice): class Meta: identifier = GlobalId("container", "number") number = attributes.Integer() container = attributes.ResourceReference() def get_label(self): return "%s-%s" % (self.container.get_label(), self.number)
class Lun(resources.LogicalDrive): class Meta: identifier = ScopedId("lun_id") lun_id = attributes.String() couplet = attributes.ResourceReference() def get_label(self): return self.lun_id
class Disk(resources.PhysicalDisk): class Meta: identifier = GlobalId('wwid') lun = attributes.ResourceReference(optional=True) size = attributes.Bytes() wwid = attributes.Uuid() read_bytes_sec = statistics.Gauge(units="B/s", label="Read bandwidth") write_bytes_sec = statistics.Gauge(units="B/s", label="Write bandwidth")
class Lun(resources.LogicalDrive): class Meta: identifier = GlobalId('serial') relations = [ relations.Provide( provide_to=('linux', 'ScsiDevice'), attributes=['serial']), ] charts = [ { 'title': "Bandwidth", 'series': ['read_bytes_sec', 'write_bytes_sec'] }, { 'title': "Ops", 'series': ['read_ops_sec', 'write_ops_sec'] }, { 'title': "Latency distribution", 'series': ['write_latency_hist'] } ] couplet = attributes.ResourceReference() lun_id = attributes.String() serial = attributes.String() read_bytes_sec = statistics.Gauge(units="B/s", label="Read bandwidth") write_bytes_sec = statistics.Gauge(units="B/s", label="Write bandwidth") read_ops_sec = statistics.Gauge(units="op/s", label="Read operations") write_ops_sec = statistics.Gauge(units="op/s", label="Write operations") write_latency_hist = statistics.BytesHistogram( label="Write latency", bins=[(0, 16), (17, 32), (33, 64), (65, 128), (129, 256), (257, 512), (513, 1024), (1024, 2048), (2049, 4096), (4097, 8192), (8193, 16384), (16385, 32768) ]) def get_label(self): return self.lun_id
def test_markup(self): rr = attributes.ResourceReference() self.assertEqual(rr.to_markup(None), '') from chroma_core.models import StorageResourceRecord resource = StorageResourceRecord.objects.get(id = self.record_pk).to_resource() markup = rr.to_markup(resource) self.assertEqual(markup, conditional_escape(resource.get_label())) record = StorageResourceRecord.objects.get(pk = self.record_pk) record.alias = 'test alias' record.save() markup = rr.to_markup(resource) self.assertEqual(markup, conditional_escape('test alias'))
class DeviceNode(BaseStorageResource): host_id = attributes.Integer() path = attributes.PosixPath() logical_drive = attributes.ResourceReference(optional=True) class Meta: label = "Device node" def get_label(self): path = self.path strip_strings = [ "/dev/", "/dev/mapper/", "/dev/disk/by-id/", "/dev/disk/by-path/" ] strip_strings.sort(lambda a, b: cmp(len(b), len(a))) for s in strip_strings: if path.startswith(s): path = path[len(s):] return "%s:%s" % (self.host_id, path)