Merge "Add pool capacity pollsters"
This commit is contained in:
commit
d5b6d7966a
@ -5,7 +5,8 @@
|
|||||||
required-projects:
|
required-projects:
|
||||||
- opendev.org/openstack/grenade
|
- opendev.org/openstack/grenade
|
||||||
- opendev.org/openstack/ceilometer
|
- opendev.org/openstack/ceilometer
|
||||||
- gnocchixyz/gnocchi
|
- name: gnocchixyz/gnocchi
|
||||||
|
override-checkout: stable/4.6
|
||||||
vars:
|
vars:
|
||||||
configure_swap_size: 8192
|
configure_swap_size: 8192
|
||||||
grenade_devstack_localrc:
|
grenade_devstack_localrc:
|
||||||
|
@ -134,6 +134,34 @@ BACKUP_LIST = [
|
|||||||
'size': 1})
|
'size': 1})
|
||||||
]
|
]
|
||||||
|
|
||||||
|
POOL_LIST = [
|
||||||
|
type('VolumePool', (object,),
|
||||||
|
{'name': 'localhost.localdomain@lvmdriver-1#lvmdriver-1',
|
||||||
|
'pool_name': 'lvmdriver-1',
|
||||||
|
'total_capacity_gb': 28.5,
|
||||||
|
'free_capacity_gb': 28.39,
|
||||||
|
'reserved_percentage': 0,
|
||||||
|
'location_info':
|
||||||
|
'LVMVolumeDriver:localhost.localdomain:stack-volumes:thin:0',
|
||||||
|
'QoS_support': False,
|
||||||
|
'provisioned_capacity_gb': 4.0,
|
||||||
|
'max_over_subscription_ratio': 20.0,
|
||||||
|
'thin_provisioning_support': True,
|
||||||
|
'thick_provisioning_support': False,
|
||||||
|
'total_volumes': 3,
|
||||||
|
'filter_function': None,
|
||||||
|
'goodness_function': None,
|
||||||
|
'multiattach': True,
|
||||||
|
'backend_state': 'up',
|
||||||
|
'allocated_capacity_gb': 4,
|
||||||
|
'cacheable': True,
|
||||||
|
'volume_backend_name': 'lvmdriver-1',
|
||||||
|
'storage_protocol': 'iSCSI',
|
||||||
|
'vendor_name': 'Open Source',
|
||||||
|
'driver_version': '3.0.0',
|
||||||
|
'timestamp': '2025-03-21T14:19:02.901750'})
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class TestVolumeSizePollster(base.BaseTestCase):
|
class TestVolumeSizePollster(base.BaseTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -203,3 +231,94 @@ class TestVolumeBackupSizePollster(base.BaseTestCase):
|
|||||||
self.assertEqual(1, volume_backup_size_samples[0].volume)
|
self.assertEqual(1, volume_backup_size_samples[0].volume)
|
||||||
self.assertEqual('75a52125-85ff-4a8d-b2aa-580f3b22273f',
|
self.assertEqual('75a52125-85ff-4a8d-b2aa-580f3b22273f',
|
||||||
volume_backup_size_samples[0].resource_id)
|
volume_backup_size_samples[0].resource_id)
|
||||||
|
|
||||||
|
|
||||||
|
class TestVolumeProviderPoolCapacityTotalPollster(base.BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestVolumeProviderPoolCapacityTotalPollster, self).setUp()
|
||||||
|
conf = service.prepare_service([], [])
|
||||||
|
self.manager = manager.AgentManager(0, conf)
|
||||||
|
self.pollster = cinder.VolumeProviderPoolCapacityTotal(conf)
|
||||||
|
|
||||||
|
def test_volume_provider_pool_capacity_total_pollster(self):
|
||||||
|
volume_pool_size_total_samples = list(
|
||||||
|
self.pollster.get_samples(self.manager, {}, resources=POOL_LIST))
|
||||||
|
self.assertEqual(1, len(volume_pool_size_total_samples))
|
||||||
|
self.assertEqual('volume.provider.pool.capacity.total',
|
||||||
|
volume_pool_size_total_samples[0].name)
|
||||||
|
self.assertEqual(28.5, volume_pool_size_total_samples[0].volume)
|
||||||
|
self.assertEqual('localhost.localdomain@lvmdriver-1#lvmdriver-1',
|
||||||
|
volume_pool_size_total_samples[0].resource_id)
|
||||||
|
|
||||||
|
|
||||||
|
class TestVolumeProviderPoolCapacityFreePollster(base.BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestVolumeProviderPoolCapacityFreePollster, self).setUp()
|
||||||
|
conf = service.prepare_service([], [])
|
||||||
|
self.manager = manager.AgentManager(0, conf)
|
||||||
|
self.pollster = cinder.VolumeProviderPoolCapacityFree(conf)
|
||||||
|
|
||||||
|
def test_volume_provider_pool_capacity_free_pollster(self):
|
||||||
|
volume_pool_size_free_samples = list(
|
||||||
|
self.pollster.get_samples(self.manager, {}, resources=POOL_LIST))
|
||||||
|
self.assertEqual(1, len(volume_pool_size_free_samples))
|
||||||
|
self.assertEqual('volume.provider.pool.capacity.free',
|
||||||
|
volume_pool_size_free_samples[0].name)
|
||||||
|
self.assertEqual(28.39, volume_pool_size_free_samples[0].volume)
|
||||||
|
self.assertEqual('localhost.localdomain@lvmdriver-1#lvmdriver-1',
|
||||||
|
volume_pool_size_free_samples[0].resource_id)
|
||||||
|
|
||||||
|
|
||||||
|
class TestVolumeProviderPoolCapacityProvisionedPollster(base.BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestVolumeProviderPoolCapacityProvisionedPollster, self).setUp()
|
||||||
|
conf = service.prepare_service([], [])
|
||||||
|
self.manager = manager.AgentManager(0, conf)
|
||||||
|
self.pollster = cinder.VolumeProviderPoolCapacityProvisioned(conf)
|
||||||
|
|
||||||
|
def test_volume_provider_pool_capacity_provisioned_pollster(self):
|
||||||
|
volume_pool_size_provisioned_samples = list(
|
||||||
|
self.pollster.get_samples(self.manager, {}, resources=POOL_LIST))
|
||||||
|
self.assertEqual(1, len(volume_pool_size_provisioned_samples))
|
||||||
|
self.assertEqual('volume.provider.pool.capacity.provisioned',
|
||||||
|
volume_pool_size_provisioned_samples[0].name)
|
||||||
|
self.assertEqual(4.0, volume_pool_size_provisioned_samples[0].volume)
|
||||||
|
self.assertEqual('localhost.localdomain@lvmdriver-1#lvmdriver-1',
|
||||||
|
volume_pool_size_provisioned_samples[0].resource_id)
|
||||||
|
|
||||||
|
|
||||||
|
class TestVolumeProviderPoolCapacityVirtualFreePollster(base.BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestVolumeProviderPoolCapacityVirtualFreePollster, self).setUp()
|
||||||
|
conf = service.prepare_service([], [])
|
||||||
|
self.manager = manager.AgentManager(0, conf)
|
||||||
|
self.pollster = cinder.VolumeProviderPoolCapacityVirtualFree(conf)
|
||||||
|
|
||||||
|
def test_volume_provider_pool_capacity_virtual_free_pollster(self):
|
||||||
|
volume_pool_size_virtual_free_samples = list(
|
||||||
|
self.pollster.get_samples(self.manager, {}, resources=POOL_LIST))
|
||||||
|
self.assertEqual(1, len(volume_pool_size_virtual_free_samples))
|
||||||
|
self.assertEqual('volume.provider.pool.capacity.virtual_free',
|
||||||
|
volume_pool_size_virtual_free_samples[0].name)
|
||||||
|
self.assertEqual(566.0,
|
||||||
|
volume_pool_size_virtual_free_samples[0].volume)
|
||||||
|
self.assertEqual('localhost.localdomain@lvmdriver-1#lvmdriver-1',
|
||||||
|
volume_pool_size_virtual_free_samples[0].resource_id)
|
||||||
|
|
||||||
|
|
||||||
|
class TestVolumeProviderPoolCapacityAllocatedPollster(base.BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestVolumeProviderPoolCapacityAllocatedPollster, self).setUp()
|
||||||
|
conf = service.prepare_service([], [])
|
||||||
|
self.manager = manager.AgentManager(0, conf)
|
||||||
|
self.pollster = cinder.VolumeProviderPoolCapacityAllocated(conf)
|
||||||
|
|
||||||
|
def test_volume_provider_pool_capacity_allocated_pollster(self):
|
||||||
|
volume_pool_size_allocated_samples = list(
|
||||||
|
self.pollster.get_samples(self.manager, {}, resources=POOL_LIST))
|
||||||
|
self.assertEqual(1, len(volume_pool_size_allocated_samples))
|
||||||
|
self.assertEqual('volume.provider.pool.capacity.allocated',
|
||||||
|
volume_pool_size_allocated_samples[0].name)
|
||||||
|
self.assertEqual(4, volume_pool_size_allocated_samples[0].volume)
|
||||||
|
self.assertEqual('localhost.localdomain@lvmdriver-1#lvmdriver-1',
|
||||||
|
volume_pool_size_allocated_samples[0].resource_id)
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
"""Common code for working with volumes
|
"""Common code for working with volumes
|
||||||
"""
|
"""
|
||||||
|
import math
|
||||||
|
|
||||||
from ceilometer.polling import plugin_base
|
from ceilometer.polling import plugin_base
|
||||||
from ceilometer import sample
|
from ceilometer import sample
|
||||||
@ -117,3 +118,119 @@ class VolumeBackupSize(_Base):
|
|||||||
resource_id=backup.id,
|
resource_id=backup.id,
|
||||||
resource_metadata=self.extract_metadata(backup),
|
resource_metadata=self.extract_metadata(backup),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class VolumeProviderPoolCapacityTotal(_Base):
|
||||||
|
@property
|
||||||
|
def default_discovery(self):
|
||||||
|
return 'volume_pools'
|
||||||
|
|
||||||
|
FIELDS = ['pool_name']
|
||||||
|
|
||||||
|
def get_samples(self, manager, cache, resources):
|
||||||
|
for pool in resources:
|
||||||
|
yield sample.Sample(
|
||||||
|
name='volume.provider.pool.capacity.total',
|
||||||
|
type=sample.TYPE_GAUGE,
|
||||||
|
unit='GB',
|
||||||
|
volume=pool.total_capacity_gb,
|
||||||
|
user_id=None,
|
||||||
|
project_id=None,
|
||||||
|
resource_id=pool.name,
|
||||||
|
resource_metadata=self.extract_metadata(pool),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class VolumeProviderPoolCapacityFree(_Base):
|
||||||
|
@property
|
||||||
|
def default_discovery(self):
|
||||||
|
return 'volume_pools'
|
||||||
|
|
||||||
|
FIELDS = ['pool_name']
|
||||||
|
|
||||||
|
def get_samples(self, manager, cache, resources):
|
||||||
|
for pool in resources:
|
||||||
|
yield sample.Sample(
|
||||||
|
name='volume.provider.pool.capacity.free',
|
||||||
|
type=sample.TYPE_GAUGE,
|
||||||
|
unit='GB',
|
||||||
|
volume=pool.free_capacity_gb,
|
||||||
|
user_id=None,
|
||||||
|
project_id=None,
|
||||||
|
resource_id=pool.name,
|
||||||
|
resource_metadata=self.extract_metadata(pool),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class VolumeProviderPoolCapacityProvisioned(_Base):
|
||||||
|
@property
|
||||||
|
def default_discovery(self):
|
||||||
|
return 'volume_pools'
|
||||||
|
|
||||||
|
FIELDS = ['pool_name']
|
||||||
|
|
||||||
|
def get_samples(self, manager, cache, resources):
|
||||||
|
for pool in resources:
|
||||||
|
yield sample.Sample(
|
||||||
|
name='volume.provider.pool.capacity.provisioned',
|
||||||
|
type=sample.TYPE_GAUGE,
|
||||||
|
unit='GB',
|
||||||
|
volume=pool.provisioned_capacity_gb,
|
||||||
|
user_id=None,
|
||||||
|
project_id=None,
|
||||||
|
resource_id=pool.name,
|
||||||
|
resource_metadata=self.extract_metadata(pool),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class VolumeProviderPoolCapacityVirtualFree(_Base):
|
||||||
|
@property
|
||||||
|
def default_discovery(self):
|
||||||
|
return 'volume_pools'
|
||||||
|
|
||||||
|
FIELDS = ['pool_name']
|
||||||
|
|
||||||
|
def get_samples(self, manager, cache, resources):
|
||||||
|
for pool in resources:
|
||||||
|
reserved_size = math.floor(
|
||||||
|
(pool.reserved_percentage / 100) * pool.total_capacity_gb
|
||||||
|
)
|
||||||
|
max_over_subscription_ratio = 1.0
|
||||||
|
if pool.thin_provisioning_support:
|
||||||
|
max_over_subscription_ratio = pool.max_over_subscription_ratio
|
||||||
|
value = (
|
||||||
|
max_over_subscription_ratio *
|
||||||
|
(pool.total_capacity_gb - reserved_size) -
|
||||||
|
pool.provisioned_capacity_gb
|
||||||
|
)
|
||||||
|
yield sample.Sample(
|
||||||
|
name='volume.provider.pool.capacity.virtual_free',
|
||||||
|
type=sample.TYPE_GAUGE,
|
||||||
|
unit='GB',
|
||||||
|
volume=value,
|
||||||
|
user_id=None,
|
||||||
|
project_id=None,
|
||||||
|
resource_id=pool.name,
|
||||||
|
resource_metadata=self.extract_metadata(pool),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class VolumeProviderPoolCapacityAllocated(_Base):
|
||||||
|
@property
|
||||||
|
def default_discovery(self):
|
||||||
|
return 'volume_pools'
|
||||||
|
|
||||||
|
FIELDS = ['pool_name']
|
||||||
|
|
||||||
|
def get_samples(self, manager, cache, resources):
|
||||||
|
for pool in resources:
|
||||||
|
yield sample.Sample(
|
||||||
|
name='volume.provider.pool.capacity.allocated',
|
||||||
|
type=sample.TYPE_GAUGE,
|
||||||
|
unit='GB',
|
||||||
|
volume=pool.allocated_capacity_gb,
|
||||||
|
user_id=None,
|
||||||
|
project_id=None,
|
||||||
|
resource_id=pool.name,
|
||||||
|
resource_metadata=self.extract_metadata(pool),
|
||||||
|
)
|
||||||
|
@ -61,3 +61,10 @@ class VolumeBackupsDiscovery(_BaseDiscovery):
|
|||||||
"""Discover volume resources to monitor."""
|
"""Discover volume resources to monitor."""
|
||||||
|
|
||||||
return self.client.backups.list(search_opts={'all_tenants': True})
|
return self.client.backups.list(search_opts={'all_tenants': True})
|
||||||
|
|
||||||
|
|
||||||
|
class VolumePoolsDiscovery(_BaseDiscovery):
|
||||||
|
def discover(self, manager, param=None):
|
||||||
|
"""Discover volume resources to monitor."""
|
||||||
|
|
||||||
|
return self.client.pools.list(detailed=True)
|
||||||
|
@ -443,22 +443,24 @@ The following meters are collected for OpenStack Block Storage:
|
|||||||
| | | | | | on host |
|
| | | | | | on host |
|
||||||
+--------------------+-------+--------+----------+----------+-----------------+
|
+--------------------+-------+--------+----------+----------+-----------------+
|
||||||
| volume.provider.po\| Gauge | GB | hostname\| Notifica\| Total volume |
|
| volume.provider.po\| Gauge | GB | hostname\| Notifica\| Total volume |
|
||||||
| ol.capacity.total | | | #pool | tion | capacity in pool|
|
| ol.capacity.total | | | #pool | tion, Po\| capacity in pool|
|
||||||
|
| | | | | llster | |
|
||||||
+--------------------+-------+--------+----------+----------+-----------------+
|
+--------------------+-------+--------+----------+----------+-----------------+
|
||||||
| volume.provider.po\| Gauge | GB | hostname\| Notifica\| Free volume |
|
| volume.provider.po\| Gauge | GB | hostname\| Notifica\| Free volume |
|
||||||
| ol.capacity.free | | | #pool | tion | capacity in pool|
|
| ol.capacity.free | | | #pool | tion, Po\| capacity in pool|
|
||||||
|
| | | | | llster | |
|
||||||
+--------------------+-------+--------+----------+----------+-----------------+
|
+--------------------+-------+--------+----------+----------+-----------------+
|
||||||
| volume.provider.po\| Gauge | GB | hostname\| Notifica\| Assigned volume |
|
| volume.provider.po\| Gauge | GB | hostname\| Notifica\| Assigned volume |
|
||||||
| ol.capacity.alloca\| | | #pool | tion | capacity in pool|
|
| ol.capacity.alloca\| | | #pool | tion, Po\| capacity in pool|
|
||||||
| ted | | | | | by Cinder |
|
| ted | | | | llster | by Cinder |
|
||||||
+--------------------+-------+--------+----------+----------+-----------------+
|
+--------------------+-------+--------+----------+----------+-----------------+
|
||||||
| volume.provider.po\| Gauge | GB | hostname\| Notifica\| Assigned volume |
|
| volume.provider.po\| Gauge | GB | hostname\| Notifica\| Assigned volume |
|
||||||
| ol.capacity.provis\| | | #pool | tion | capacity in pool|
|
| ol.capacity.provis\| | | #pool | tion, Po\| capacity in pool|
|
||||||
| ioned | | | | | |
|
| ioned | | | | llster | |
|
||||||
+--------------------+-------+--------+----------+----------+-----------------+
|
+--------------------+-------+--------+----------+----------+-----------------+
|
||||||
| volume.provider.po\| Gauge | GB | hostname\| Notifica\| Virtual free |
|
| volume.provider.po\| Gauge | GB | hostname\| Notifica\| Virtual free |
|
||||||
| ol.capacity.virtua\| | | #pool | tion | volume capacity |
|
| ol.capacity.virtua\| | | #pool | tion, Po\| volume capacity |
|
||||||
| l_free | | | | | in pool |
|
| l_free | | | | llster | in pool |
|
||||||
+--------------------+-------+--------+----------+----------+-----------------+
|
+--------------------+-------+--------+----------+----------+-----------------+
|
||||||
|
|
||||||
OpenStack File Share
|
OpenStack File Share
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Added the following meters to the central agent to capture these metrics
|
||||||
|
for each storage pool by API.
|
||||||
|
|
||||||
|
- `volume.provider.pool.capacity.total`
|
||||||
|
- `volume.provider.pool.capacity.free`
|
||||||
|
- `volume.provider.pool.capacity.provisioned`
|
||||||
|
- `volume.provider.pool.capacity.virtual_free`
|
||||||
|
- `volume.provider.pool.capacity.allocated`
|
@ -60,6 +60,7 @@ ceilometer.discover.central =
|
|||||||
fip_services = ceilometer.network.services.discovery:FloatingIPDiscovery
|
fip_services = ceilometer.network.services.discovery:FloatingIPDiscovery
|
||||||
images = ceilometer.image.discovery:ImagesDiscovery
|
images = ceilometer.image.discovery:ImagesDiscovery
|
||||||
volumes = ceilometer.volume.discovery:VolumeDiscovery
|
volumes = ceilometer.volume.discovery:VolumeDiscovery
|
||||||
|
volume_pools = ceilometer.volume.discovery:VolumePoolsDiscovery
|
||||||
volume_snapshots = ceilometer.volume.discovery:VolumeSnapshotsDiscovery
|
volume_snapshots = ceilometer.volume.discovery:VolumeSnapshotsDiscovery
|
||||||
volume_backups = ceilometer.volume.discovery:VolumeBackupsDiscovery
|
volume_backups = ceilometer.volume.discovery:VolumeBackupsDiscovery
|
||||||
|
|
||||||
@ -137,6 +138,11 @@ ceilometer.poll.central =
|
|||||||
volume.size = ceilometer.volume.cinder:VolumeSizePollster
|
volume.size = ceilometer.volume.cinder:VolumeSizePollster
|
||||||
volume.snapshot.size = ceilometer.volume.cinder:VolumeSnapshotSize
|
volume.snapshot.size = ceilometer.volume.cinder:VolumeSnapshotSize
|
||||||
volume.backup.size = ceilometer.volume.cinder:VolumeBackupSize
|
volume.backup.size = ceilometer.volume.cinder:VolumeBackupSize
|
||||||
|
volume.provider.pool.capacity.total = ceilometer.volume.cinder:VolumeProviderPoolCapacityTotal
|
||||||
|
volume.provider.pool.capacity.free = ceilometer.volume.cinder:VolumeProviderPoolCapacityFree
|
||||||
|
volume.provider.pool.capacity.provisioned = ceilometer.volume.cinder:VolumeProviderPoolCapacityProvisioned
|
||||||
|
volume.provider.pool.capacity.virtual_free = ceilometer.volume.cinder:VolumeProviderPoolCapacityVirtualFree
|
||||||
|
volume.provider.pool.capacity.allocated = ceilometer.volume.cinder:VolumeProviderPoolCapacityAllocated
|
||||||
|
|
||||||
ceilometer.compute.virt =
|
ceilometer.compute.virt =
|
||||||
libvirt = ceilometer.compute.virt.libvirt.inspector:LibvirtInspector
|
libvirt = ceilometer.compute.virt.libvirt.inspector:LibvirtInspector
|
||||||
|
Loading…
x
Reference in New Issue
Block a user