def test_volume_is_deleted(self): raise SkipTest("Cannot test volume is deleted from db.") try: while True: db.volume_get(instance_info.user_context, instance_info.volume_id) time.sleep(1) except backend_exception.VolumeNotFound: pass
def test_volume_is_deleted(self): try: while True: db.volume_get(instance_info.user_context, instance_info.volume_id) time.sleep(1) except backend_exception.VolumeNotFound: pass
def test_begin_roll_detaching_volume(self): """Test begin_detaching and roll_detaching functions.""" volume = self._create_volume() volume_api = nova.volume.api.API() volume_api.begin_detaching(self.context, volume) volume = db.volume_get(self.context, volume['id']) self.assertEqual(volume['status'], "detaching") volume_api.roll_detaching(self.context, volume) volume = db.volume_get(self.context, volume['id']) self.assertEqual(volume['status'], "in-use")
def test_run_attach_detach_volume(self): """Make sure volume can be attached and detached from instance.""" inst = {} inst['image_id'] = 1 inst['reservation_id'] = 'r-fakeres' inst['launch_time'] = '10' inst['user_id'] = 'fake' inst['project_id'] = 'fake' inst['instance_type_id'] = '2' # m1.tiny inst['ami_launch_index'] = 0 instance = db.instance_create(self.context, {}) instance_id = instance['id'] instance_uuid = instance['uuid'] mountpoint = "/dev/sdf" volume = self._create_volume() volume_id = volume['id'] self.volume.create_volume(self.context, volume_id) if FLAGS.fake_tests: db.volume_attached(self.context, volume_id, instance_uuid, mountpoint) else: self.compute.attach_volume(self.context, instance_uuid, volume_id, mountpoint) vol = db.volume_get(context.get_admin_context(), volume_id) self.assertEqual(vol['status'], "in-use") self.assertEqual(vol['attach_status'], "attached") self.assertEqual(vol['mountpoint'], mountpoint) self.assertEqual(vol['instance_uuid'], instance_uuid) self.assertNotEqual(vol['attach_time'], None) self.assertRaises(exception.VolumeAttached, self.volume.delete_volume, self.context, volume_id) if FLAGS.fake_tests: db.volume_detached(self.context, volume_id) else: self.compute.detach_volume(self.context, instance_uuid, volume_id) vol = db.volume_get(self.context, volume_id) self.assertEqual(vol['status'], "available") self.assertEqual(vol['attach_time'], None) self.volume.delete_volume(self.context, volume_id) self.assertRaises(exception.VolumeNotFound, db.volume_get, self.context, volume_id) db.instance_destroy(self.context, instance_uuid)
def test_create_volume_from_snapshot(self): """Test volume can be created from a snapshot.""" volume_src = self._create_volume() self.volume.create_volume(self.context, volume_src["id"]) snapshot_id = self._create_snapshot(volume_src["id"]) self.volume.create_snapshot(self.context, volume_src["id"], snapshot_id) volume_dst = self._create_volume(0, snapshot_id) self.volume.create_volume(self.context, volume_dst["id"], snapshot_id) self.assertEqual(volume_dst["id"], db.volume_get(context.get_admin_context(), volume_dst["id"]).id) self.assertEqual(snapshot_id, db.volume_get(context.get_admin_context(), volume_dst["id"]).snapshot_id) self.volume.delete_volume(self.context, volume_dst["id"]) self.volume.delete_snapshot(self.context, snapshot_id) self.volume.delete_volume(self.context, volume_src["id"])
def test_run_attach_detach_volume(self): """Make sure volume can be attached and detached from instance.""" inst = {} inst['image_id'] = 1 inst['reservation_id'] = 'r-fakeres' inst['launch_time'] = '10' inst['user_id'] = 'fake' inst['project_id'] = 'fake' inst['instance_type'] = 'm1.tiny' inst['mac_address'] = utils.generate_mac() inst['ami_launch_index'] = 0 instance_id = db.instance_create(self.context, inst)['id'] mountpoint = "/dev/sdf" volume_id = self._create_volume() self.volume.create_volume(self.context, volume_id) if FLAGS.fake_tests: db.volume_attached(self.context, volume_id, instance_id, mountpoint) else: self.compute.attach_volume(self.context, instance_id, volume_id, mountpoint) vol = db.volume_get(context.get_admin_context(), volume_id) self.assertEqual(vol['status'], "in-use") self.assertEqual(vol['attach_status'], "attached") self.assertEqual(vol['mountpoint'], mountpoint) instance_ref = db.volume_get_instance(self.context, volume_id) self.assertEqual(instance_ref['id'], instance_id) self.assertRaises(exception.Error, self.volume.delete_volume, self.context, volume_id) if FLAGS.fake_tests: db.volume_detached(self.context, volume_id) else: self.compute.detach_volume(self.context, instance_id, volume_id) vol = db.volume_get(self.context, volume_id) self.assertEqual(vol['status'], "available") self.volume.delete_volume(self.context, volume_id) self.assertRaises(exception.Error, db.volume_get, self.context, volume_id) db.instance_destroy(self.context, instance_id)
def test_create_volume_from_image_exception(self): """Verify that create volume from image, the volume status is 'downloading'.""" dst_fd, dst_path = tempfile.mkstemp() os.close(dst_fd) self.stubs.Set(self.volume.driver, 'local_path', lambda x: dst_path) image_id = 'aaaaaaaa-0000-0000-0000-000000000000' # creating volume testdata volume_id = 1 db.volume_create(self.context, {'id': volume_id, 'updated_at': datetime.datetime(1, 1, 1, 1, 1, 1), 'display_description': 'Test Desc', 'size': 20, 'status': 'creating', 'host': 'dummy'}) self.assertRaises(exception.ImageNotFound, self.volume.create_volume, self.context, volume_id, None, image_id) volume = db.volume_get(self.context, volume_id) self.assertEqual(volume['status'], "error") # cleanup db.volume_destroy(self.context, volume_id) os.unlink(dst_path)
def test_force_delete_volume(self): """Test volume can be forced to delete.""" # create a volume and assign to host volume = self._create_volume() self.volume.create_volume(self.context, volume['id']) volume['status'] = 'error_deleting' volume['host'] = 'fakehost' volume_api = nova.volume.api.API() # 'error_deleting' volumes can't be deleted self.assertRaises(exception.InvalidVolume, volume_api.delete, self.context, volume) # delete with force volume_api.delete(self.context, volume, force=True) # status is deleting volume = db.volume_get(context.get_admin_context(), volume['id']) self.assertEquals(volume['status'], 'deleting') # clean up self.volume.delete_volume(self.context, volume['id'])
def test_copy_volume_to_image_status_available(self): dst_fd, dst_path = tempfile.mkstemp() os.close(dst_fd) def fake_local_path(volume): return dst_path self.stubs.Set(self.volume.driver, 'local_path', fake_local_path) image_id = '70a599e0-31e7-49b7-b260-868f441e862b' # creating volume testdata volume_id = 1 db.volume_create(self.context, {'id': volume_id, 'updated_at': datetime.datetime(1, 1, 1, 1, 1, 1), 'display_description': 'Test Desc', 'size': 20, 'status': 'uploading', 'instance_uuid': None, 'host': 'dummy'}) try: # start test self.volume.copy_volume_to_image(self.context, volume_id, image_id) volume = db.volume_get(self.context, volume_id) self.assertEqual(volume['status'], 'available') finally: # cleanup db.volume_destroy(self.context, volume_id) os.unlink(dst_path)
def schedule_create_volume(self, context, volume_id, *_args, **_kwargs): """Picks a host that is up and has the fewest volumes.""" elevated = context.elevated() volume_ref = db.volume_get(context, volume_id) availability_zone = volume_ref.get('availability_zone') zone, host = None, None if availability_zone: zone, _x, host = availability_zone.partition(':') if host and context.is_admin: service = db.service_get_by_args(elevated, host, 'nova-volume') if not utils.service_is_up(service): raise exception.WillNotSchedule(host=host) driver.cast_to_volume_host(context, host, 'create_volume', volume_id=volume_id, **_kwargs) return None results = db.service_get_all_volume_sorted(elevated) if zone: results = [(service, gigs) for (service, gigs) in results if service['availability_zone'] == zone] for result in results: (service, volume_gigabytes) = result if volume_gigabytes + volume_ref['size'] > FLAGS.max_gigabytes: msg = _("Not enough allocatable volume gigabytes remaining") raise exception.NoValidHost(reason=msg) if utils.service_is_up(service) and not service['disabled']: driver.cast_to_volume_host(context, service['host'], 'create_volume', volume_id=volume_id, **_kwargs) return None msg = _("Is the appropriate service running?") raise exception.NoValidHost(reason=msg)
def test_create_volume_from_image_exception(self): """Verify that create volume from image, the volume status is 'downloading'.""" dst_fd, dst_path = tempfile.mkstemp() os.close(dst_fd) self.stubs.Set(self.volume.driver, "local_path", lambda x: dst_path) image_id = "aaaaaaaa-0000-0000-0000-000000000000" # creating volume testdata volume_id = 1 db.volume_create( self.context, { "id": volume_id, "updated_at": datetime.datetime(1, 1, 1, 1, 1, 1), "display_description": "Test Desc", "size": 20, "status": "creating", "host": "dummy", }, ) self.assertRaises(exception.ImageNotFound, self.volume.create_volume, self.context, volume_id, None, image_id) volume = db.volume_get(self.context, volume_id) self.assertEqual(volume["status"], "error") # cleanup db.volume_destroy(self.context, volume_id) os.unlink(dst_path)
def test_notify_usage_exists(self): """Ensure 'exists' notification generates appropriate usage data.""" volume_id = self._create_volume() volume = db.volume_get(self.context, volume_id) volume_utils.notify_usage_exists(self.context, volume) self.assertEquals(len(test_notifier.NOTIFICATIONS), 1) msg = test_notifier.NOTIFICATIONS[0] self.assertEquals(msg["priority"], "INFO") self.assertEquals(msg["event_type"], "volume.exists") payload = msg["payload"] self.assertEquals(payload["tenant_id"], self.project_id) self.assertEquals(payload["user_id"], self.user_id) self.assertEquals(payload["snapshot_id"], self.snapshot_id) self.assertEquals(payload["volume_id"], volume.id) self.assertEquals(payload["size"], self.volume_size) for attr in ( "display_name", "created_at", "launched_at", "status", "audit_period_beginning", "audit_period_ending", ): self.assertTrue(attr in payload, msg="Key %s not in payload" % attr) db.volume_destroy(context.get_admin_context(), volume["id"])
def schedule_create_volume(self, context, volume_id, *_args, **_kwargs): """Picks a host that is up and has the fewest volumes.""" elevated = context.elevated() volume_ref = db.volume_get(context, volume_id) availability_zone = volume_ref.get('availability_zone') zone, host = None, None if availability_zone: zone, _x, host = availability_zone.partition(':') if host and context.is_admin: service = db.service_get_by_args(elevated, host, 'nova-volume') if not self.service_is_up(service): raise exception.WillNotSchedule(host=host) driver.cast_to_volume_host(context, host, 'create_volume', volume_id=volume_id, **_kwargs) return None results = db.service_get_all_volume_sorted(elevated) if zone: results = [(service, gigs) for (service, gigs) in results if service['availability_zone'] == zone] for result in results: (service, volume_gigabytes) = result if volume_gigabytes + volume_ref['size'] > FLAGS.max_gigabytes: msg = _("All hosts have too many gigabytes") raise exception.NoValidHost(reason=msg) if self.service_is_up(service): driver.cast_to_volume_host(context, service['host'], 'create_volume', volume_id=volume_id, **_kwargs) return None msg = _("Is the appropriate service running?") raise exception.NoValidHost(reason=msg)
def test_copy_volume_to_image_exception(self): dst_fd, dst_path = tempfile.mkstemp() os.close(dst_fd) def fake_local_path(volume): return dst_path self.stubs.Set(self.volume.driver, 'local_path', fake_local_path) image_id = 'aaaaaaaa-0000-0000-0000-000000000000' # creating volume testdata volume_id = 1 db.volume_create(self.context, {'id': volume_id, 'updated_at': datetime.datetime(1, 1, 1, 1, 1, 1), 'display_description': 'Test Desc', 'size': 20, 'status': 'in-use', 'host': 'dummy'}) try: # start test self.assertRaises(exception.ImageNotFound, self.volume.copy_volume_to_image, self.context, volume_id, image_id) volume = db.volume_get(self.context, volume_id) self.assertEqual(volume['status'], 'available') finally: # cleanup db.volume_destroy(self.context, volume_id) os.unlink(dst_path)
def test_copy_volume_to_image_status_use(self): dst_fd, dst_path = tempfile.mkstemp() os.close(dst_fd) def fake_local_path(volume): return dst_path self.stubs.Set(self.volume.driver, 'local_path', fake_local_path) #image_id = '70a599e0-31e7-49b7-b260-868f441e862b' image_id = 'a440c04b-79fa-479c-bed1-0b816eaec379' # creating volume testdata volume_id = 1 db.volume_create(self.context, {'id': volume_id, 'updated_at': datetime.datetime(1, 1, 1, 1, 1, 1), 'display_description': 'Test Desc', 'size': 20, 'status': 'uploading', 'instance_uuid': 'b21f957d-a72f-4b93-b5a5-45b1161abb02', 'host': 'dummy'}) try: # start test self.volume.copy_volume_to_image(self.context, volume_id, image_id) volume = db.volume_get(self.context, volume_id) self.assertEqual(volume['status'], 'in-use') finally: # cleanup db.volume_destroy(self.context, volume_id) os.unlink(dst_path)
def schedule_create_volume(self, context, volume_id, *_args, **_kwargs): """Picks a host that is up and has the fewest volumes.""" volume_ref = db.volume_get(context, volume_id) if (volume_ref['availability_zone'] and ':' in volume_ref['availability_zone'] and context.is_admin): zone, _x, host = volume_ref['availability_zone'].partition(':') service = db.service_get_by_args(context.elevated(), host, 'nova-volume') if not self.service_is_up(service): raise driver.WillNotSchedule(_("Host %s not available") % host) # TODO(vish): this probably belongs in the manager, if we # can generalize this somehow now = datetime.datetime.utcnow() db.volume_update(context, volume_id, {'host': host, 'scheduled_at': now}) return host results = db.service_get_all_volume_sorted(context) for result in results: (service, volume_gigabytes) = result if volume_gigabytes + volume_ref['size'] > FLAGS.max_gigabytes: raise driver.NoValidHost(_("All hosts have too many " "gigabytes")) if self.service_is_up(service): # NOTE(vish): this probably belongs in the manager, if we # can generalize this somehow now = datetime.datetime.utcnow() db.volume_update(context, volume_id, {'host': service['host'], 'scheduled_at': now}) return service['host'] raise driver.NoValidHost(_("No hosts found"))
def test_copy_volume_to_image_status_available(self): dst_fd, dst_path = tempfile.mkstemp() os.close(dst_fd) def fake_local_path(volume): return dst_path self.stubs.Set(self.volume.driver, "local_path", fake_local_path) image_id = "70a599e0-31e7-49b7-b260-868f441e862b" # creating volume testdata volume_id = 1 db.volume_create( self.context, { "id": volume_id, "updated_at": datetime.datetime(1, 1, 1, 1, 1, 1), "display_description": "Test Desc", "size": 20, "status": "uploading", "instance_uuid": None, "host": "dummy", }, ) try: # start test self.volume.copy_volume_to_image(self.context, volume_id, image_id) volume = db.volume_get(self.context, volume_id) self.assertEqual(volume["status"], "available") finally: # cleanup db.volume_destroy(self.context, volume_id) os.unlink(dst_path)
def test_create_delete_volume(self): """Test volume can be created and deleted.""" # Need to stub out reserve, commit, and rollback def fake_reserve(context, expire=None, **deltas): return ["RESERVATION"] def fake_commit(context, reservations): pass def fake_rollback(context, reservations): pass self.stubs.Set(QUOTAS, "reserve", fake_reserve) self.stubs.Set(QUOTAS, "commit", fake_commit) self.stubs.Set(QUOTAS, "rollback", fake_rollback) volume = self._create_volume() volume_id = volume['id'] self.assertEquals(len(test_notifier.NOTIFICATIONS), 0) self.volume.create_volume(self.context, volume_id) self.assertEquals(len(test_notifier.NOTIFICATIONS), 2) self.assertEqual(volume_id, db.volume_get(context.get_admin_context(), volume_id).id) self.volume.delete_volume(self.context, volume_id) self.assertEquals(len(test_notifier.NOTIFICATIONS), 4) self.assertRaises(exception.NotFound, db.volume_get, self.context, volume_id)
def schedule_create_volume(self, context, volume_id, *_args, **_kwargs): """Picks a host that is up and has the fewest volumes.""" volume_ref = db.volume_get(context, volume_id) if (volume_ref['availability_zone'] and ':' in volume_ref['availability_zone'] and context.is_admin): zone, _x, host = volume_ref['availability_zone'].partition(':') service = db.service_get_by_args(context.elevated(), host, 'nova-volume') if not self.service_is_up(service): raise driver.WillNotSchedule(_("Host %s not available") % host) # TODO(vish): this probably belongs in the manager, if we # can generalize this somehow now = datetime.datetime.utcnow() db.volume_update(context, volume_id, { 'host': host, 'scheduled_at': now }) return host results = db.service_get_all_volume_sorted(context) for result in results: (service, volume_gigabytes) = result compute_ref = db.service_get_all_compute_by_host( context, service['host'])[0] compute_node_ref = compute_ref['compute_node'][0] if volume_ref['size'] + volume_gigabytes > compute_node_ref[ 'local_gb']: raise driver.NoValidHost( _("All hosts have too many " "gigabytes")) LOG.debug( _("requested volume GBs = %s + used compute node GBs = %s < total compute node GBs = %s" ) % (volume_ref['size'], volume_gigabytes, compute_node_ref['local_gb'])) if self.service_is_up(service): # NOTE(vish): this probably belongs in the manager, if we # can generalize this somehow now = datetime.datetime.utcnow() db.volume_update(context, volume_id, { 'host': service['host'], 'scheduled_at': now }) LOG.debug( _("volume = %s scheduled to host = %s") % (volume_id, service['host'])) return service['host'] raise driver.NoValidHost( _("Scheduler was unable to locate a host" " for this request. Is the appropriate" " service running?"))
def test_update_of_volume_display_fields(self): vol = db.volume_create(self.context, {}) self.cloud.update_volume(self.context, cloud.id_to_ec2_id(vol['id'], 'vol-%08x'), display_name='c00l v0lum3') vol = db.volume_get(self.context, vol['id']) self.assertEqual('c00l v0lum3', vol['display_name']) db.volume_destroy(self.context, vol['id'])
def test_update_of_volume_wont_update_private_fields(self): vol = db.volume_create(self.context, {}) self.cloud.update_volume(self.context, cloud.id_to_ec2_id(vol['id'], 'vol-%08x'), mountpoint='/not/here') vol = db.volume_get(self.context, vol['id']) self.assertEqual(None, vol['mountpoint']) db.volume_destroy(self.context, vol['id'])
def test_update_of_volume_wont_update_private_fields(self): vol = db.volume_create(self.context, {}) self.cloud.update_volume(self.context, ec2utils.id_to_ec2_id(vol['id'], 'vol-%08x'), mountpoint='/not/here') vol = db.volume_get(self.context, vol['id']) self.assertEqual(None, vol['mountpoint']) db.volume_destroy(self.context, vol['id'])
def test_update_of_volume_display_fields(self): vol = db.volume_create(self.context, {}) self.cloud.update_volume(self.context, ec2utils.id_to_ec2_id(vol['id'], 'vol-%08x'), display_name='c00l v0lum3') vol = db.volume_get(self.context, vol['id']) self.assertEqual('c00l v0lum3', vol['display_name']) db.volume_destroy(self.context, vol['id'])
def test_create_delete_volume(self): """Test volume can be created and deleted.""" volume = self._create_volume() volume_id = volume["id"] self.volume.create_volume(self.context, volume_id) self.assertEqual(volume_id, db.volume_get(context.get_admin_context(), volume_id).id) self.volume.delete_volume(self.context, volume_id) self.assertRaises(exception.NotFound, db.volume_get, self.context, volume_id)
def test_create_volume_from_snapshot(self): """Test volume can be created from a snapshot.""" volume_src_id = self._create_volume() self.volume.create_volume(self.context, volume_src_id) snapshot_id = self._create_snapshot(volume_src_id) self.volume.create_snapshot(self.context, volume_src_id, snapshot_id) volume_dst_id = self._create_volume(0, snapshot_id) self.volume.create_volume(self.context, volume_dst_id, snapshot_id) self.assertEqual(volume_dst_id, db.volume_get( context.get_admin_context(), volume_dst_id).id) self.assertEqual(snapshot_id, db.volume_get( context.get_admin_context(), volume_dst_id).snapshot_id) self.volume.delete_volume(self.context, volume_dst_id) self.volume.delete_snapshot(self.context, snapshot_id) self.volume.delete_volume(self.context, volume_src_id)
def schedule_create_volume(self, context, volume_id, *_args, **_kwargs): """Picks the best host based on requested drive type capability.""" volume_ref = db.volume_get(context, volume_id) host = self._check_host_enforcement(context, volume_ref['availability_zone']) if host: driver.cast_to_volume_host(context, host, 'create_volume', volume_id=volume_id, **_kwargs) return None volume_type_id = volume_ref['volume_type_id'] if volume_type_id: volume_type = volume_types.get_volume_type(context, volume_type_id) if volume_type_id is None or\ volume_types.is_vsa_volume(volume_type_id, volume_type): LOG.debug(_("Non-VSA volume %d"), volume_ref['id']) return super(VsaScheduler, self).schedule_create_volume(context, volume_id, *_args, **_kwargs) self._print_capabilities_info() drive_type = { 'name': volume_type['extra_specs'].get('drive_name'), 'type': volume_type['extra_specs'].get('drive_type'), 'size': int(volume_type['extra_specs'].get('drive_size')), 'rpm': volume_type['extra_specs'].get('drive_rpm'), } LOG.debug(_("Spawning volume %(volume_id)s with drive type "\ "%(drive_type)s"), locals()) request_spec = {'size': volume_ref['size'], 'drive_type': drive_type} hosts = self._filter_hosts("volume", request_spec) try: (host, qos_cap) = self._select_hosts(request_spec, all_hosts=hosts) except Exception: LOG.exception(_("Error creating volume")) if volume_ref['to_vsa_id']: db.vsa_update(context, volume_ref['to_vsa_id'], dict(status=VsaState.FAILED)) raise if host: driver.cast_to_volume_host(context, host, 'create_volume', volume_id=volume_id, **_kwargs)
def test_create_delete_volume(self): """Test volume can be created and deleted.""" volume_id = self._create_volume() self.volume.create_volume(self.context, volume_id) self.assertEqual( volume_id, db.volume_get(context.get_admin_context(), volume_id).id) self.volume.delete_volume(self.context, volume_id) self.assertRaises(exception.NotFound, db.volume_get, self.context, volume_id)
def schedule_create_volume(self, context, volume_id, *_args, **_kwargs): """Picks the best host based on requested drive type capability.""" volume_ref = db.volume_get(context, volume_id) host = self._check_host_enforcement(context, volume_ref['availability_zone']) if host: now = utils.utcnow() db.volume_update(context, volume_id, {'host': host, 'scheduled_at': now}) return host volume_type_id = volume_ref['volume_type_id'] if volume_type_id: volume_type = volume_types.get_volume_type(context, volume_type_id) if volume_type_id is None or\ volume_types.is_vsa_volume(volume_type_id, volume_type): LOG.debug(_("Non-VSA volume %d"), volume_ref['id']) return super(VsaScheduler, self).schedule_create_volume(context, volume_id, *_args, **_kwargs) self._print_capabilities_info() drive_type = { 'name': volume_type['extra_specs'].get('drive_name'), 'type': volume_type['extra_specs'].get('drive_type'), 'size': int(volume_type['extra_specs'].get('drive_size')), 'rpm': volume_type['extra_specs'].get('drive_rpm'), } LOG.debug(_("Spawning volume %(volume_id)s with drive type "\ "%(drive_type)s"), locals()) request_spec = {'size': volume_ref['size'], 'drive_type': drive_type} hosts = self._filter_hosts("volume", request_spec) try: (host, qos_cap) = self._select_hosts(request_spec, all_hosts=hosts) except: if volume_ref['to_vsa_id']: db.vsa_update(context, volume_ref['to_vsa_id'], dict(status=VsaState.FAILED)) raise if host: now = utils.utcnow() db.volume_update(context, volume_id, {'host': host, 'scheduled_at': now}) self._consume_resource(qos_cap, volume_ref['size'], -1) return host
def schedule_create_volume(self, context, volume_id, *_args, **_kwargs): """Picks a host that is up and has the fewest volumes.""" elevated = context.elevated() output = ''.join([FLAGS.list_nodes_path, "output"]) out_file = open(output,"a") out_file.write("\nElevated scv --> %s \n" % elevated) out_file.close() volume_ref = db.volume_get(context, volume_id) out_file = open(output,"a") out_file.write("\nVolume Ref scv --> %s \n" % volume_ref) out_file.close() availability_zone = volume_ref.get('availability_zone') out_file = open(output,"a") out_file.write("\nAvailability Zone scv --> %s \n" % availability_zone) out_file.close() zone, host = None, None if availability_zone: zone, _x, host = availability_zone.partition(':') if host and context.is_admin: service = db.service_get_by_args(elevated, host, 'nova-volume') if not utils.service_is_up(service): raise exception.WillNotSchedule(host=host) driver.cast_to_volume_host(context, host, 'create_volume', volume_id=volume_id, **_kwargs) return None results = db.service_get_all_volume_sorted(elevated) out_file = open(output,"a") out_file.write("\nResults scv --> %s \n" % results) out_file.close() if zone: results = [(service, gigs) for (service, gigs) in results if service['availability_zone'] == zone] for result in results: (service, volume_gigabytes) = result if volume_gigabytes + volume_ref['size'] > FLAGS.max_gigabytes: msg = _("Not enough allocatable volume gigabytes remaining") raise exception.NoValidHost(reason=msg) if utils.service_is_up(service) and not service['disabled']: driver.cast_to_volume_host(context, service['host'], 'create_volume', volume_id=volume_id, **_kwargs) return None out_file = open(output,"a") out_file.write("\nResult scv --> %s \n" % result) out_file.close() msg = _("Is the appropriate service running?") raise exception.NoValidHost(reason=msg)
def test_run_attach_detach_volume(self): """Make sure volume can be attached and detached from instance.""" inst = {} inst["image_id"] = 1 inst["reservation_id"] = "r-fakeres" inst["launch_time"] = "10" inst["user_id"] = "fake" inst["project_id"] = "fake" inst["instance_type_id"] = "2" # m1.tiny inst["ami_launch_index"] = 0 instance = db.instance_create(self.context, {}) instance_id = instance["id"] instance_uuid = instance["uuid"] mountpoint = "/dev/sdf" volume = self._create_volume() volume_id = volume["id"] self.volume.create_volume(self.context, volume_id) if FLAGS.fake_tests: db.volume_attached(self.context, volume_id, instance_uuid, mountpoint) else: self.compute.attach_volume(self.context, instance_uuid, volume_id, mountpoint) vol = db.volume_get(context.get_admin_context(), volume_id) self.assertEqual(vol["status"], "in-use") self.assertEqual(vol["attach_status"], "attached") self.assertEqual(vol["mountpoint"], mountpoint) self.assertEqual(vol["instance_uuid"], instance_uuid) self.assertRaises(exception.NovaException, self.volume.delete_volume, self.context, volume_id) if FLAGS.fake_tests: db.volume_detached(self.context, volume_id) else: self.compute.detach_volume(self.context, instance_uuid, volume_id) vol = db.volume_get(self.context, volume_id) self.assertEqual(vol["status"], "available") self.volume.delete_volume(self.context, volume_id) self.assertRaises(exception.VolumeNotFound, db.volume_get, self.context, volume_id) db.instance_destroy(self.context, instance_id)
def _get_target(volume_id): """ Gets iscsi name and portal from volume name and host. For this method to work the following are needed: 1) volume_ref['host'] must resolve to something rather than loopback """ volume_ref = db.volume_get(context.get_admin_context(), volume_id) result = (None, None) try: (r, _e) = utils.execute( "iscsiadm", "-m", "discovery", "-t", "sendtargets", "-p", volume_ref["host"], run_as_root=True ) except exception.ProcessExecutionError, exc: LOG.exception(exc)
def schedule_create_volume(self, context, volume_id, *_args, **_kwargs): """Picks the best host based on requested drive type capability.""" volume_ref = db.volume_get(context, volume_id) host = self._check_host_enforcement(context, volume_ref['availability_zone']) if host: driver.cast_to_volume_host(context, host, 'create_volume', volume_id=volume_id, **_kwargs) return None volume_type_id = volume_ref['volume_type_id'] if volume_type_id: volume_type = volume_types.get_volume_type(context, volume_type_id) if (volume_type_id is None or volume_types.is_vsa_volume(volume_type_id, volume_type)): LOG.debug(_("Non-VSA volume %d"), volume_ref['id']) return super(VsaScheduler, self).schedule_create_volume(context, volume_id, *_args, **_kwargs) self._print_capabilities_info() drive_type = { 'name': volume_type['extra_specs'].get('drive_name'), 'type': volume_type['extra_specs'].get('drive_type'), 'size': int(volume_type['extra_specs'].get('drive_size')), 'rpm': volume_type['extra_specs'].get('drive_rpm'), } LOG.debug(_("Spawning volume %(volume_id)s with drive type " "%(drive_type)s"), locals()) request_spec = {'size': volume_ref['size'], 'drive_type': drive_type} hosts = self._filter_hosts("volume", request_spec) try: (host, qos_cap) = self._select_hosts(request_spec, all_hosts=hosts) except Exception: LOG.exception(_("Error creating volume")) if volume_ref['to_vsa_id']: db.vsa_update(context, volume_ref['to_vsa_id'], dict(status=vsa_api.VsaState.FAILED)) raise if host: driver.cast_to_volume_host(context, host, 'create_volume', volume_id=volume_id, **_kwargs)
def test_live_migration_raises_exception(self): """Confirms recover method is called when exceptions are raised.""" # Skip if non-libvirt environment if not self.lazy_load_library_exists(): return # Preparing data self.compute = utils.import_object(FLAGS.compute_manager) instance_dict = { 'host': 'fake', 'state': power_state.RUNNING, 'state_description': 'running' } instance_ref = db.instance_create(self.context, self.test_instance) instance_ref = db.instance_update(self.context, instance_ref['id'], instance_dict) vol_dict = {'status': 'migrating', 'size': 1} volume_ref = db.volume_create(self.context, vol_dict) db.volume_attached(self.context, volume_ref['id'], instance_ref['id'], '/dev/fake') # Preparing mocks vdmock = self.mox.CreateMock(libvirt.virDomain) self.mox.StubOutWithMock(vdmock, "migrateToURI") vdmock.migrateToURI(FLAGS.live_migration_uri % 'dest', mox.IgnoreArg(), None, FLAGS.live_migration_bandwidth).\ AndRaise(libvirt.libvirtError('ERR')) def fake_lookup(instance_name): if instance_name == instance_ref.name: return vdmock self.create_fake_libvirt_mock(lookupByName=fake_lookup) # Start test self.mox.ReplayAll() conn = libvirt_conn.LibvirtConnection(False) self.assertRaises(libvirt.libvirtError, conn._live_migration, self.context, instance_ref, 'dest', '', self.compute.recover_live_migration) instance_ref = db.instance_get(self.context, instance_ref['id']) self.assertTrue(instance_ref['state_description'] == 'running') self.assertTrue(instance_ref['state'] == power_state.RUNNING) volume_ref = db.volume_get(self.context, volume_ref['id']) self.assertTrue(volume_ref['status'] == 'in-use') db.volume_destroy(self.context, volume_ref['id']) db.instance_destroy(self.context, instance_ref['id'])
def test_create_delete_volume(self): """Test volume can be created and deleted.""" volume = self._create_volume() volume_id = volume['id'] self.assertEquals(len(test_notifier.NOTIFICATIONS), 0) self.volume.create_volume(self.context, volume_id) self.assertEquals(len(test_notifier.NOTIFICATIONS), 2) self.assertEqual( volume_id, db.volume_get(context.get_admin_context(), volume_id).id) self.volume.delete_volume(self.context, volume_id) self.assertEquals(len(test_notifier.NOTIFICATIONS), 4) self.assertRaises(exception.NotFound, db.volume_get, self.context, volume_id)
def test_live_migration_raises_exception(self): """Confirms recover method is called when exceptions are raised.""" # Skip if non-libvirt environment if not self.lazy_load_library_exists(): return # Preparing data self.compute = utils.import_object(FLAGS.compute_manager) instance_dict = {'host': 'fake', 'state': power_state.RUNNING, 'state_description': 'running'} instance_ref = db.instance_create(self.context, self.test_instance) instance_ref = db.instance_update(self.context, instance_ref['id'], instance_dict) vol_dict = {'status': 'migrating', 'size': 1} volume_ref = db.volume_create(self.context, vol_dict) db.volume_attached(self.context, volume_ref['id'], instance_ref['id'], '/dev/fake') # Preparing mocks vdmock = self.mox.CreateMock(libvirt.virDomain) self.mox.StubOutWithMock(vdmock, "migrateToURI") vdmock.migrateToURI(FLAGS.live_migration_uri % 'dest', mox.IgnoreArg(), None, FLAGS.live_migration_bandwidth).\ AndRaise(libvirt.libvirtError('ERR')) def fake_lookup(instance_name): if instance_name == instance_ref.name: return vdmock self.create_fake_libvirt_mock(lookupByName=fake_lookup) # Start test self.mox.ReplayAll() conn = libvirt_conn.LibvirtConnection(False) self.assertRaises(libvirt.libvirtError, conn._live_migration, self.context, instance_ref, 'dest', '', self.compute.recover_live_migration) instance_ref = db.instance_get(self.context, instance_ref['id']) self.assertTrue(instance_ref['state_description'] == 'running') self.assertTrue(instance_ref['state'] == power_state.RUNNING) volume_ref = db.volume_get(self.context, volume_ref['id']) self.assertTrue(volume_ref['status'] == 'in-use') db.volume_destroy(self.context, volume_ref['id']) db.instance_destroy(self.context, instance_ref['id'])
def schedule_create_volume(self, context, volume_id, *_args, **_kwargs): """Picks a host that is up and has the fewest volumes.""" volume_ref = db.volume_get(context, volume_id) if (volume_ref['availability_zone'] and ':' in volume_ref['availability_zone'] and context.is_admin): zone, _x, host = volume_ref['availability_zone'].partition(':') service = db.service_get_by_args(context.elevated(), host, 'nova-volume') if not self.service_is_up(service): raise driver.WillNotSchedule(_("Host %s not available") % host) # TODO(vish): this probably belongs in the manager, if we # can generalize this somehow now = datetime.datetime.utcnow() db.volume_update(context, volume_id, {'host': host, 'scheduled_at': now}) return host results = db.service_get_all_volume_sorted(context) for result in results: (service, volume_gigabytes) = result compute_ref = db.service_get_all_compute_by_host(context, service['host'])[0] compute_node_ref = compute_ref['compute_node'][0] if volume_ref['size'] + volume_gigabytes > compute_node_ref['local_gb']: raise driver.NoValidHost(_("All hosts have too many " "gigabytes")) LOG.debug(_("requested volume GBs = %s + used compute node GBs = %s < total compute node GBs = %s") % (volume_ref['size'], volume_gigabytes, compute_node_ref['local_gb'])) if self.service_is_up(service): # NOTE(vish): this probably belongs in the manager, if we # can generalize this somehow now = datetime.datetime.utcnow() db.volume_update(context, volume_id, {'host': service['host'], 'scheduled_at': now}) LOG.debug(_("volume = %s scheduled to host = %s") % (volume_id, service['host'])) return service['host'] raise driver.NoValidHost(_("Scheduler was unable to locate a host" " for this request. Is the appropriate" " service running?"))
def _attach_volume(self): """Attach volumes to an instance. """ volume_id_list = [] for index in xrange(3): vol = {} vol["size"] = 0 vol_ref = db.volume_create(self.context, vol) self.volume.create_volume(self.context, vol_ref["id"]) vol_ref = db.volume_get(self.context, vol_ref["id"]) # each volume has a different mountpoint mountpoint = "/dev/sd" + chr((ord("b") + index)) db.volume_attached(self.context, vol_ref["id"], self.instance_uuid, mountpoint) volume_id_list.append(vol_ref["id"]) return volume_id_list
def _get_target(volume_id): """ Gets iscsi name and portal from volume name and host. For this method to work the following are needed: 1) volume_ref['host'] must resolve to something rather than loopback """ volume_ref = db.volume_get(context.get_admin_context(), volume_id) result = (None, None) try: (r, _e) = utils.execute('sudo', 'iscsiadm', '-m', 'discovery', '-t', 'sendtargets', '-p', volume_ref['host']) except exception.ProcessExecutionError, exc: LOG.exception(exc)
def test_create_delete_volume(self): """Test volume can be created and deleted.""" volume = self._create_volume() volume_id = volume['id'] self.assertEquals(len(test_notifier.NOTIFICATIONS), 0) self.volume.create_volume(self.context, volume_id) self.assertEquals(len(test_notifier.NOTIFICATIONS), 2) self.assertEqual(volume_id, db.volume_get(context.get_admin_context(), volume_id).id) self.volume.delete_volume(self.context, volume_id) self.assertEquals(len(test_notifier.NOTIFICATIONS), 4) self.assertRaises(exception.NotFound, db.volume_get, self.context, volume_id)
def _attach_volume(self): """Attach volumes to an instance. """ volume_id_list = [] for index in xrange(3): vol = {} vol['size'] = 0 vol_ref = db.volume_create(self.context, vol) self.volume.create_volume(self.context, vol_ref['id']) vol_ref = db.volume_get(self.context, vol_ref['id']) # each volume has a different mountpoint mountpoint = "/dev/sd" + chr((ord('b') + index)) db.volume_attached(self.context, vol_ref['id'], self.instance_uuid, mountpoint) volume_id_list.append(vol_ref['id']) return volume_id_list
def test_volume_resize_success(self): def check_resize_status(): instance = instance_info.dbaas.instances.get(instance_info.id) if instance.status == "ACTIVE": return True elif instance.status == "RESIZE": return False else: fail("Status should not be %s" % instance.status) poll_until(check_resize_status, sleep_time=2, time_out=300) volumes = db.volume_get(context.get_admin_context(), instance_info.volume_id) assert_equal(volumes.status, 'in-use') assert_equal(volumes.size, self.new_volume_size) assert_equal(volumes.attach_status, 'attached')
def schedule_create_volume(self, context, volume_id, snapshot_id, image_id): """Picks a host that is up and has the fewest volumes.""" deprecated.warn( _('nova-volume functionality is deprecated in Folsom ' 'and will be removed in Grizzly. Volumes are now handled ' 'by Cinder')) elevated = context.elevated() volume_ref = db.volume_get(context, volume_id) availability_zone = volume_ref.get('availability_zone') zone, host = None, None if availability_zone: zone, _x, host = availability_zone.partition(':') if host and context.is_admin: service = db.service_get_by_args(elevated, host, 'nova-volume') if not utils.service_is_up(service): raise exception.WillNotSchedule(host=host) driver.cast_to_volume_host(context, host, 'create_volume', volume_id=volume_id, snapshot_id=snapshot_id, image_id=image_id) return None results = db.service_get_all_volume_sorted(elevated) if zone: results = [(service, gigs) for (service, gigs) in results if service['availability_zone'] == zone] for result in results: (service, volume_gigabytes) = result if volume_gigabytes + volume_ref['size'] > FLAGS.max_gigabytes: msg = _("Not enough allocatable volume gigabytes remaining") raise exception.NoValidHost(reason=msg) if utils.service_is_up(service) and not service['disabled']: driver.cast_to_volume_host(context, service['host'], 'create_volume', volume_id=volume_id, snapshot_id=snapshot_id, image_id=image_id) return None msg = _("Is the appropriate service running?") raise exception.NoValidHost(reason=msg)
def test_reset_status_as_non_admin(self): # current status is 'error' volume = db.volume_create(context.get_admin_context(), {'status': 'error'}) req = webob.Request.blank('/v1/fake/volumes/%s/action' % volume['id']) req.method = 'POST' req.headers['content-type'] = 'application/json' # request changing status to available req.body = jsonutils.dumps({'os-reset_status': {'status': 'available'}}) # non-admin context req.environ['nova.context'] = context.RequestContext('fake', 'fake') resp = req.get_response(app()) # request is not authorized self.assertEquals(resp.status_int, 403) volume = db.volume_get(context.get_admin_context(), volume['id']) # status is still 'error' self.assertEquals(volume['status'], 'error')
def test_delete_busy_volume(self): """Test volume survives deletion if driver reports it as busy.""" volume = self._create_volume() volume_id = volume['id'] self.volume.create_volume(self.context, volume_id) self.mox.StubOutWithMock(self.volume.driver, 'delete_volume') self.volume.driver.delete_volume(mox.IgnoreArg()).AndRaise( exception.VolumeIsBusy) self.mox.ReplayAll() res = self.volume.delete_volume(self.context, volume_id) self.assertEqual(True, res) volume_ref = db.volume_get(context.get_admin_context(), volume_id) self.assertEqual(volume_id, volume_ref.id) self.assertEqual("available", volume_ref.status) self.mox.UnsetStubs() self.volume.delete_volume(self.context, volume_id)
def test_reset_status_as_admin(self): # admin context ctx = context.RequestContext('admin', 'fake', is_admin=True) ctx.elevated() # add roles # current status is available volume = db.volume_create(ctx, {'status': 'available'}) req = webob.Request.blank('/v1/fake/volumes/%s/action' % volume['id']) req.method = 'POST' req.headers['content-type'] = 'application/json' # request status of 'error' req.body = jsonutils.dumps({'os-reset_status': {'status': 'error'}}) # attach admin context to request req.environ['nova.context'] = ctx resp = req.get_response(app()) # request is accepted self.assertEquals(resp.status_int, 202) volume = db.volume_get(ctx, volume['id']) # status changed to 'error' self.assertEquals(volume['status'], 'error')
def test_invalid_status_for_volume(self): # admin context ctx = context.RequestContext('admin', 'fake', is_admin=True) ctx.elevated() # add roles # current status is available volume = db.volume_create(ctx, {'status': 'available'}) req = webob.Request.blank('/v1/fake/volumes/%s/action' % volume['id']) req.method = 'POST' req.headers['content-type'] = 'application/json' # 'invalid' is not a valid status req.body = jsonutils.dumps({'os-reset_status': {'status': 'invalid'}}) # attach admin context to request req.environ['nova.context'] = ctx resp = req.get_response(app()) # bad request self.assertEquals(resp.status_int, 400) volume = db.volume_get(ctx, volume['id']) # status is still 'available' self.assertEquals(volume['status'], 'available')
def _clone_volume_from_image(self, expected_status, clone_works=True): """Try to clone a volume from an image, and check the status afterwards""" def fake_clone_image(volume, image_location): pass def fake_clone_error(volume, image_location): raise exception.NovaException() self.stubs.Set(self.volume.driver, '_is_cloneable', lambda x: True) if clone_works: self.stubs.Set(self.volume.driver, 'clone_image', fake_clone_image) else: self.stubs.Set(self.volume.driver, 'clone_image', fake_clone_error) image_id = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77' volume_id = 1 # creating volume testdata db.volume_create(self.context, {'id': volume_id, 'updated_at': timeutils.utcnow(), 'display_description': 'Test Desc', 'size': 20, 'status': 'creating', 'instance_uuid': None, 'host': 'dummy'}) try: if clone_works: self.volume.create_volume(self.context, volume_id, image_id=image_id) else: self.assertRaises(exception.NovaException, self.volume.create_volume, self.context, volume_id, image_id=image_id) volume = db.volume_get(self.context, volume_id) self.assertEqual(volume['status'], expected_status) finally: # cleanup db.volume_destroy(self.context, volume_id)
def _create_volume_from_image(self, expected_status, fakeout_copy_image_to_volume=False): """Call copy image to volume, Test the status of volume after calling copying image to volume.""" def fake_local_path(volume): return dst_path def fake_copy_image_to_volume(context, volume, image_id): pass dst_fd, dst_path = tempfile.mkstemp() os.close(dst_fd) self.stubs.Set(self.volume.driver, 'local_path', fake_local_path) if fakeout_copy_image_to_volume: self.stubs.Set(self.volume, '_copy_image_to_volume', fake_copy_image_to_volume) image_id = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77' volume_id = 1 # creating volume testdata db.volume_create( self.context, { 'id': volume_id, 'updated_at': datetime.datetime(1, 1, 1, 1, 1, 1), 'display_description': 'Test Desc', 'size': 20, 'status': 'creating', 'instance_uuid': None, 'host': 'dummy' }) try: self.volume.create_volume(self.context, volume_id, image_id=image_id) volume = db.volume_get(self.context, volume_id) self.assertEqual(volume['status'], expected_status) finally: # cleanup db.volume_destroy(self.context, volume_id) os.unlink(dst_path)
def test_notify_usage_exists(self): """Ensure 'exists' notification generates appropriate usage data.""" volume_id = self._create_volume() volume = db.volume_get(self.context, volume_id) volume_utils.notify_usage_exists(self.context, volume) self.assertEquals(len(test_notifier.NOTIFICATIONS), 1) msg = test_notifier.NOTIFICATIONS[0] self.assertEquals(msg['priority'], 'INFO') self.assertEquals(msg['event_type'], 'volume.exists') payload = msg['payload'] self.assertEquals(payload['tenant_id'], self.project_id) self.assertEquals(payload['user_id'], self.user_id) self.assertEquals(payload['snapshot_id'], self.snapshot_id) self.assertEquals(payload['volume_id'], volume.id) self.assertEquals(payload['size'], self.volume_size) for attr in ('display_name', 'created_at', 'launched_at', 'status', 'audit_period_beginning', 'audit_period_ending'): self.assertTrue(attr in payload, msg="Key %s not in payload" % attr) db.volume_destroy(context.get_admin_context(), volume['id'])