Add a VolumeUsage object

This change adds a VolumeUsage object to replace db calls currently
proxying through conductor.

Related to blueprint liberty-objects

Change-Id: I2290a7c8dc85833fab21d2cd467e93ff19564245
This commit is contained in:
Hans Lindgren
2015-04-30 14:43:48 +02:00
parent afd264ac36
commit 54cfd2a860
4 changed files with 150 additions and 0 deletions

View File

@@ -65,3 +65,4 @@ def register_all():
__import__('nova.objects.vcpu_model')
__import__('nova.objects.virt_cpu_topology')
__import__('nova.objects.virtual_interface')
__import__('nova.objects.volume_usage')

View File

@@ -0,0 +1,59 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from nova import db
from nova.objects import base
from nova.objects import fields
@base.NovaObjectRegistry.register
class VolumeUsage(base.NovaPersistentObject, base.NovaObject):
# Version 1.0: Initial version
VERSION = '1.0'
fields = {
'id': fields.IntegerField(read_only=True),
'volume_id': fields.UUIDField(),
'instance_uuid': fields.UUIDField(nullable=True),
'project_id': fields.StringField(nullable=True),
'user_id': fields.StringField(nullable=True),
'availability_zone': fields.StringField(nullable=True),
'tot_last_refreshed': fields.DateTimeField(nullable=True,
read_only=True),
'tot_reads': fields.IntegerField(read_only=True),
'tot_read_bytes': fields.IntegerField(read_only=True),
'tot_writes': fields.IntegerField(read_only=True),
'tot_write_bytes': fields.IntegerField(read_only=True),
'curr_last_refreshed': fields.DateTimeField(nullable=True,
read_only=True),
'curr_reads': fields.IntegerField(),
'curr_read_bytes': fields.IntegerField(),
'curr_writes': fields.IntegerField(),
'curr_write_bytes': fields.IntegerField()
}
@staticmethod
def _from_db_object(context, vol_usage, db_vol_usage):
for field in vol_usage.fields:
setattr(vol_usage, field, db_vol_usage[field])
vol_usage._context = context
vol_usage.obj_reset_changes()
return vol_usage
@base.remotable
def save(self, update_totals=False):
db_vol_usage = db.vol_usage_update(
self._context, self.volume_id, self.curr_reads,
self.curr_read_bytes, self.curr_writes, self.curr_write_bytes,
self.instance_uuid, self.project_id, self.user_id,
self.availability_zone, update_totals=update_totals)
self._from_db_object(self._context, self, db_vol_usage)

View File

@@ -1170,6 +1170,7 @@ object_data = {
'VirtCPUTopology': '1.0-fc694de72e20298f7c6bab1083fd4563',
'VirtualInterface': '1.0-19921e38cba320f355d56ecbf8f29587',
'VirtualInterfaceList': '1.0-9750e2074437b3077e46359102779fc6',
'VolumeUsage': '1.0-6c8190c46ce1469bb3286a1f21c2e475',
}

View File

@@ -0,0 +1,89 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
from oslo_utils import timeutils
from nova import objects
from nova.tests.unit.objects import test_objects
NOW = timeutils.utcnow().replace(microsecond=0)
fake_vol_usage = {
'created_at': NOW,
'updated_at': None,
'deleted_at': None,
'deleted': 0,
'id': 1,
'volume_id': 'fake-vol-id',
'instance_uuid': 'fake-inst-uuid',
'project_id': 'fake-project-id',
'user_id': 'fake-user-id',
'availability_zone': None,
'tot_last_refreshed': None,
'tot_reads': 0,
'tot_read_bytes': 0,
'tot_writes': 0,
'tot_write_bytes': 0,
'curr_last_refreshed': NOW,
'curr_reads': 10,
'curr_read_bytes': 20,
'curr_writes': 30,
'curr_write_bytes': 40,
}
class _TestVolumeUsage(object):
@mock.patch('nova.db.vol_usage_update', return_value=fake_vol_usage)
def test_save(self, mock_upd):
vol_usage = objects.VolumeUsage(self.context)
vol_usage.volume_id = 'fake-vol-id'
vol_usage.instance_uuid = 'fake-inst-uuid'
vol_usage.project_id = 'fake-project-id'
vol_usage.user_id = 'fake-user-id'
vol_usage.availability_zone = None
vol_usage.curr_reads = 10
vol_usage.curr_read_bytes = 20
vol_usage.curr_writes = 30
vol_usage.curr_write_bytes = 40
vol_usage.save()
mock_upd.assert_called_once_with(
self.context, 'fake-vol-id', 10, 20, 30, 40, 'fake-inst-uuid',
'fake-project-id', 'fake-user-id', None, update_totals=False)
self.compare_obj(vol_usage, fake_vol_usage)
@mock.patch('nova.db.vol_usage_update', return_value=fake_vol_usage)
def test_save_update_totals(self, mock_upd):
vol_usage = objects.VolumeUsage(self.context)
vol_usage.volume_id = 'fake-vol-id'
vol_usage.instance_uuid = 'fake-inst-uuid'
vol_usage.project_id = 'fake-project-id'
vol_usage.user_id = 'fake-user-id'
vol_usage.availability_zone = None
vol_usage.curr_reads = 10
vol_usage.curr_read_bytes = 20
vol_usage.curr_writes = 30
vol_usage.curr_write_bytes = 40
vol_usage.save(update_totals=True)
mock_upd.assert_called_once_with(
self.context, 'fake-vol-id', 10, 20, 30, 40, 'fake-inst-uuid',
'fake-project-id', 'fake-user-id', None, update_totals=True)
self.compare_obj(vol_usage, fake_vol_usage)
class TestVolumeUsage(test_objects._LocalTest, _TestVolumeUsage):
pass
class TestRemoteVolumeUsage(test_objects._RemoteTest, _TestVolumeUsage):
pass