From 142f6f6d3e7ce63e0a34cf68c8473d047766e093 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 18 Aug 2010 04:08:32 -0700 Subject: tests pass --- nova/models.py | 10 +++++-- nova/network/service.py | 6 ++--- nova/tests/volume_unittest.py | 26 +++++++++++++----- nova/volume/service.py | 62 ++++++++++++++++++++++++------------------- 4 files changed, 65 insertions(+), 39 deletions(-) (limited to 'nova') diff --git a/nova/models.py b/nova/models.py index 110a4fc80..6342a86c5 100644 --- a/nova/models.py +++ b/nova/models.py @@ -199,8 +199,6 @@ class Volume(Base, NovaBase): __tablename__ = 'volumes' id = Column(Integer, primary_key=True) volume_id = Column(String) - shelf_id = Column(Integer) - blade_id = Column(Integer) user_id = Column(String) #, ForeignKey('users.id'), nullable=False) project_id = Column(String) #, ForeignKey('projects.id')) @@ -215,6 +213,14 @@ class Volume(Base, NovaBase): status = Column(String) # FIXME enum? attach_status = Column(String) # FIXME enum +class ExportDevice(Base, NovaBase): + __tablename__ = 'export_devices' + id = Column(Integer, primary_key=True) + shelf_id = Column(Integer) + blade_id = Column(Integer) + volume_id = Column(Integer, ForeignKey('volumes.id'), nullable=True) + volume = relationship(Volume, backref=backref('export_device', + uselist=False)) class Network(Base, NovaBase): __tablename__ = 'networks' diff --git a/nova/network/service.py b/nova/network/service.py index 9bbb833b7..26ceaca25 100644 --- a/nova/network/service.py +++ b/nova/network/service.py @@ -135,7 +135,7 @@ class BaseNetworkService(service.Service): fixed_ip.allocated = True session.add(fixed_ip) try: - fixed_ip.save() + session.commit() return fixed_ip.ip_str except exc.ConcurrentModificationError: pass @@ -171,7 +171,7 @@ class BaseNetworkService(service.Service): elastic_ip.project_id = project_id session.add(elastic_ip) try: - elastic_ip.save() + session.commit() return elastic_ip.ip_str except exc.ConcurrentModificationError: pass @@ -341,7 +341,7 @@ class VlanNetworkService(BaseNetworkService): network_index.network = network session.add(network_index) try: - network_index.save() + session.commit() return network_index.index except exc.ConcurrentModificationError: pass diff --git a/nova/tests/volume_unittest.py b/nova/tests/volume_unittest.py index 91706580f..f29464cab 100644 --- a/nova/tests/volume_unittest.py +++ b/nova/tests/volume_unittest.py @@ -39,6 +39,20 @@ class VolumeTestCase(test.TrialTestCase): self.flags(connection_type='fake', fake_storage=True) self.volume = volume_service.VolumeService() + self.total_slots = 10 + # FIXME this should test actual creation method + self.devices = [] + for i in xrange(self.total_slots): + export_device = models.ExportDevice() + export_device.shelf_id = 0 + export_device.blade_id = i + export_device.save() + self.devices.append(export_device) + + def tearDown(self): + super(VolumeTestCase, self).tearDown() + for device in self.devices: + device.delete() @defer.inlineCallbacks def test_run_create_volume(self): @@ -68,14 +82,11 @@ class VolumeTestCase(test.TrialTestCase): vol_size = '1' user_id = 'fake' project_id = 'fake' - num_shelves = FLAGS.last_shelf_id - FLAGS.first_shelf_id + 1 - total_slots = FLAGS.blades_per_shelf * num_shelves vols = [] - from nova import datastore - redis = datastore.Redis.instance() - for i in xrange(total_slots): + for i in xrange(self.total_slots): vid = yield self.volume.create_volume(vol_size, user_id, project_id) vols.append(vid) + print models.Volume.find(vid).export_device.volume_id self.assertFailure(self.volume.create_volume(vol_size, user_id, project_id), @@ -127,13 +138,14 @@ class VolumeTestCase(test.TrialTestCase): shelf_blades = [] def _check(volume_id): vol = models.Volume.find(volume_id) - shelf_blade = '%s.%s' % (vol.shelf_id, vol.blade_id) + shelf_blade = '%s.%s' % (vol.export_device.shelf_id, + vol.export_device.blade_id) self.assert_(shelf_blade not in shelf_blades) shelf_blades.append(shelf_blade) logging.debug("got %s" % shelf_blade) vol.delete() deferreds = [] - for i in range(5): + for i in range(self.total_slots): d = self.volume.create_volume(vol_size, user_id, project_id) d.addCallback(_check) d.addErrback(self.fail) diff --git a/nova/volume/service.py b/nova/volume/service.py index 4d959aadb..c056e5513 100644 --- a/nova/volume/service.py +++ b/nova/volume/service.py @@ -25,6 +25,7 @@ Currently uses Ata-over-Ethernet. import logging from twisted.internet import defer +from sqlalchemy.orm import exc from nova import exception from nova import flags @@ -42,12 +43,6 @@ flags.DEFINE_string('volume_group', 'nova-volumes', 'Name for the VG that will contain exported volumes') flags.DEFINE_string('aoe_eth_dev', 'eth0', 'Which device to export the volumes on') -flags.DEFINE_integer('first_shelf_id', - utils.last_octet(utils.get_my_ip()) * 10, - 'AoE starting shelf_id for this service') -flags.DEFINE_integer('last_shelf_id', - utils.last_octet(utils.get_my_ip()) * 10 + 9, - 'AoE starting shelf_id for this service') flags.DEFINE_string('aoe_export_dir', '/var/lib/vblade-persist/vblades', 'AoE directory where exports are created') @@ -120,7 +115,7 @@ class VolumeService(service.Service): @defer.inlineCallbacks def _exec_create_volume(self, vol): if FLAGS.fake_storage: - return + defer.returnValue(None) if str(vol.size) == '0': sizestr = '100M' else: @@ -134,39 +129,52 @@ class VolumeService(service.Service): @defer.inlineCallbacks def _exec_delete_volume(self, vol): if FLAGS.fake_storage: - return + defer.returnValue(None) yield process.simple_execute( "sudo lvremove -f %s/%s" % (FLAGS.volume_group, vol.volume_id), error_ok=1) @defer.inlineCallbacks def _setup_export(self, vol): - # FIXME: device needs to be a pool - device = "1.1" - if not device: - raise NoMoreBlades() - (shelf_id, blade_id) = device.split('.') - vol.aoe_device = "e%s.%s" % (shelf_id, blade_id) - vol.shelf_id = shelf_id - vol.blade_id = blade_id + # FIXME: abstract this. also remove vol.export_device.xxx cheat + session = models.NovaBase.get_session() + query = session.query(models.ExportDevice) + query = query.filter_by(volume=None) + print 'free devices', query.count() + while(True): + export_device = query.first() + if not export_device: + raise NoMoreBlades() + print 'volume id', vol.id + export_device.volume_id = vol.id + session.add(export_device) + try: + session.commit() + break + except exc.ConcurrentModificationError: + print 'concur' + pass + vol.aoe_device = "e%s.%s" % (export_device.shelf_id, + export_device.blade_id) + print 'id is', vol.export_device.volume_id vol.save() yield self._exec_setup_export(vol) @defer.inlineCallbacks def _exec_setup_export(self, vol): if FLAGS.fake_storage: - return + defer.returnValue(None) yield process.simple_execute( "sudo vblade-persist setup %s %s %s /dev/%s/%s" % - (self, vol['shelf_id'], - vol.blade_id, + (self, vol.export_device.shelf_id, + vol.export_device.blade_id, FLAGS.aoe_eth_dev, FLAGS.volume_group, vol.volume_id), error_ok=1) @defer.inlineCallbacks def _remove_export(self, vol): - if not vol.shelf_id or not vol.blade_id: + if not vol.export_device: defer.returnValue(False) yield self._exec_remove_export(vol) defer.returnValue(True) @@ -174,17 +182,17 @@ class VolumeService(service.Service): @defer.inlineCallbacks def _exec_remove_export(self, vol): if FLAGS.fake_storage: - return + defer.returnValue(None) yield process.simple_execute( - "sudo vblade-persist stop %s %s" % (self, vol.shelf_id, - vol.blade_id), error_ok=1) + "sudo vblade-persist stop %s %s" % (self, vol.export_device.shelf_id, + vol.export_device.blade_id), error_ok=1) yield process.simple_execute( - "sudo vblade-persist destroy %s %s" % (self, vol.shelf_id, - vol.blade_id), error_ok=1) + "sudo vblade-persist destroy %s %s" % (self, vol.export_device.shelf_id, + vol.export_device.blade_id), error_ok=1) @defer.inlineCallbacks def _exec_ensure_exports(self): if FLAGS.fake_storage: - return + defer.returnValue(None) # NOTE(vish): these commands sometimes sends output to stderr for warnings yield process.simple_execute("sudo vblade-persist auto all", error_ok=1) yield process.simple_execute("sudo vblade-persist start all", error_ok=1) @@ -192,7 +200,7 @@ class VolumeService(service.Service): @defer.inlineCallbacks def _exec_init_volumes(self): if FLAGS.fake_storage: - return + defer.returnValue(None) yield process.simple_execute( "sudo pvcreate %s" % (FLAGS.storage_dev)) yield process.simple_execute( -- cgit