def test_edit_attachments(self): PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_set_mount_point'] settings.OPENSTACK_HYPERVISOR_FEATURES['can_set_mount_point'] = True volume = self.cinder_volumes.first() servers = [s for s in self.servers.list() if s.tenant_id == self.request.user.tenant_id] volume.attachments = [{'id': volume.id, 'volume_id': volume.id, 'volume_name': volume.name, 'instance': servers[0], 'device': '/dev/vdb', 'server_id': servers[0].id}] cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume) api.nova.server_list(IsA(http.HttpRequest)).AndReturn([servers, False]) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:attach', args=[volume.id]) res = self.client.get(url) msg = 'Volume %s on instance %s' % (volume.name, servers[0].name) self.assertContains(res, msg) # Asserting length of 2 accounts for the one instance option, # and the one 'Choose Instance' option. form = res.context['form'] self.assertEqual(len(form.fields['instance']._choices), 1) self.assertEqual(res.status_code, 200) self.assertTrue(isinstance(form.fields['device'].widget, widgets.TextInput)) settings.OPENSTACK_HYPERVISOR_FEATURES['can_set_mount_point'] = PREV
def test_detail_view(self): volume = self.cinder_volumes.first() server = self.servers.first() volume.attachments = [{"server_id": server.id}] cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume) api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:detail', args=[volume.id]) res = self.client.get(url) self.assertContains(res, "<h2>Volume Details: Volume name</h2>", 1, 200) self.assertContains(res, "<dd>Volume name</dd>", 1, 200) self.assertContains(res, "<dd>%s</dd>" % volume.id, 1, 200) self.assertContains(res, "<dd>Available</dd>", 1, 200) self.assertContains(res, "<dd>40 GB</dd>", 1, 200) self.assertContains(res, ("<a href=\"/project/instances/1/\">%s</a>" % server.name), 1, 200) self.assertNoMessages()
def test_create_volume_from_snapshot_invalid_size(self): usage_limit = { "maxTotalVolumeGigabytes": 100, "gigabytesUsed": 20, "volumesUsed": len(self.cinder_volumes.list()), "maxTotalVolumes": 6, } snapshot = self.cinder_volume_snapshots.first() formData = { "name": u"A Volume I Am Making", "description": u"This is a volume I am making for a test.", "method": u"CreateForm", "size": 20, "snapshot_source": snapshot.id, } cinder.volume_type_list(IsA(http.HttpRequest)).AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) cinder.volume_snapshot_get(IsA(http.HttpRequest), str(snapshot.id)).AndReturn(snapshot) cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).AndReturn(self.cinder_volumes.first()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) self.mox.ReplayAll() url = reverse("horizon:project:volumes:volumes:create") res = self.client.post("?".join([url, "snapshot_id=" + str(snapshot.id)]), formData, follow=True) self.assertEqual(res.redirect_chain, []) self.assertFormError(res, "form", None, "The volume size cannot be less than the " "snapshot size (40GB)")
def test_create_volume_from_snapshot_invalid_size(self): usage_limit = {'maxTotalVolumeGigabytes': 100, 'gigabytesUsed': 20, 'volumesUsed': len(self.cinder_volumes.list()), 'maxTotalVolumes': 6} snapshot = self.cinder_volume_snapshots.first() formData = {'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 20, 'snapshot_source': snapshot.id} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_snapshot_get(IsA(http.HttpRequest), str(snapshot.id)).AndReturn(snapshot) cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).\ AndReturn(self.cinder_volumes.first()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:create') res = self.client.post("?".join([url, "snapshot_id=" + str(snapshot.id)]), formData, follow=True) self.assertEqual(res.redirect_chain, []) self.assertFormError(res, 'form', None, "The volume size cannot be less than the " "snapshot size (40GB)")
def test_create_volume_from_snapshot(self): volume = self.volumes.first() usage = {'gigabytes': {'available': 250}, 'volumes': {'available': 6}} snapshot = self.volume_snapshots.first() formData = {'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 50, 'type': '', 'snapshot_source': snapshot.id} # first call- with url param cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(usage) cinder.volume_snapshot_get(IsA(http.HttpRequest), str(snapshot.id)).AndReturn(snapshot) cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).\ AndReturn(self.volumes.first()) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], '', snapshot_id=snapshot.id).\ AndReturn(volume) # second call- with dropdown cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(usage) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_snapshots.list()) cinder.volume_snapshot_get(IsA(http.HttpRequest), str(snapshot.id)).AndReturn(snapshot) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], '', snapshot_id=snapshot.id).\ AndReturn(volume) self.mox.ReplayAll() # get snapshot from url url = reverse('horizon:project:volumes:create') res = self.client.post("?".join([url, "snapshot_id=" + str(snapshot.id)]), formData) redirect_url = reverse('horizon:project:volumes:index') self.assertRedirectsNoFollow(res, redirect_url) # get snapshot from dropdown list url = reverse('horizon:project:volumes:create') res = self.client.post(url, formData) redirect_url = reverse('horizon:project:volumes:index') self.assertRedirectsNoFollow(res, redirect_url)
def test_create_volume_from_volume(self): volume = self.cinder_volumes.first() usage_limit = {'maxTotalVolumeGigabytes': 250, 'gigabytesUsed': 20, 'volumesUsed': len(self.cinder_volumes.list()), 'maxTotalVolumes': 6} formData = {'name': u'A copy of a volume', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 50, 'type': '', 'volume_source_type': 'volume_source', 'volume_source': volume.id} cinder.volume_list(IsA(http.HttpRequest)).\ AndReturn(self.cinder_volumes.list()) cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).\ AndReturn(self.cinder_volume_snapshots.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(self.cinder_volumes.first()) cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones').AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'is_public': True, 'status': 'active'}) \ .AndReturn([self.images.list(), False]) api.glance.image_list_detailed(IsA(http.HttpRequest), filters={'property-owner_id': self.tenant.id, 'status': 'active'}) \ .AndReturn([[], False]) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], '', metadata={}, snapshot_id=None, image_id=None, availability_zone=None, source_volid=volume.id).AndReturn(volume) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:create') redirect_url = VOLUME_VOLUMES_TAB_URL res = self.client.post(url, formData) self.assertNoFormErrors(res) self.assertMessageCount(info=1) self.assertRedirectsNoFollow(res, redirect_url)
def test_volume_migrate_get_volume_get_exception(self): volume = self.cinder_volumes.get(name="v2_volume") cinder.volume_get(IsA(http.HttpRequest), volume.id).AndRaise(self.exceptions.cinder) self.mox.ReplayAll() url = reverse("horizon:admin:volumes:volumes:migrate", args=[volume.id]) res = self.client.get(url) self.assertRedirectsNoFollow(res, INDEX_URL)
def test_update_volume_status(self): volume = self.volumes.first() formData = {"status": "error"} cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume) cinder.volume_reset_state(IsA(http.HttpRequest), volume.id, formData["status"]) self.mox.ReplayAll() res = self.client.post(reverse("horizon:admin:volumes:volumes:update_status", args=(volume.id,)), formData) self.assertNoFormErrors(res)
def test_update_volume_status_get(self): volume = self.cinder_volumes.get(name="v2_volume") cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume) self.mox.ReplayAll() url = reverse("horizon:admin:volumes:volumes:update_status", args=[volume.id]) res = self.client.get(url) status_option = '<option value="%s"></option>' % volume.status self.assertNotContains(res, status_option)
def test_create_volume_from_volume(self): volume = self.cinder_volumes.first() usage_limit = { "maxTotalVolumeGigabytes": 250, "gigabytesUsed": 20, "volumesUsed": len(self.cinder_volumes.list()), "maxTotalVolumes": 6, } formData = { "name": u"A copy of a volume", "description": u"This is a volume I am making for a test.", "method": u"CreateForm", "size": 50, "type": "", "volume_source_type": "volume_source", "volume_source": volume.id, } cinder.volume_list(IsA(http.HttpRequest)).AndReturn(self.cinder_volumes.list()) cinder.volume_type_list(IsA(http.HttpRequest)).AndReturn(self.volume_types.list()) cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn(self.cinder_volume_snapshots.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).AndReturn(usage_limit) cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(self.cinder_volumes.first()) cinder.extension_supported(IsA(http.HttpRequest), "AvailabilityZones").AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn(self.cinder_availability_zones.list()) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"is_public": True, "status": "active"} ).AndReturn([self.images.list(), False, False]) api.glance.image_list_detailed( IsA(http.HttpRequest), filters={"property-owner_id": self.tenant.id, "status": "active"} ).AndReturn([[], False, False]) cinder.volume_create( IsA(http.HttpRequest), formData["size"], formData["name"], formData["description"], "", metadata={}, snapshot_id=None, image_id=None, availability_zone=None, source_volid=volume.id, ).AndReturn(volume) self.mox.ReplayAll() url = reverse("horizon:project:volumes:volumes:create") redirect_url = VOLUME_VOLUMES_TAB_URL res = self.client.post(url, formData) self.assertNoFormErrors(res) self.assertMessageCount(info=1) self.assertRedirectsNoFollow(res, redirect_url)
def test_volume_migrate_get(self): volume = self.cinder_volumes.get(name="v2_volume") cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume) cinder.pool_list(IsA(http.HttpRequest)).AndReturn(self.cinder_pools.list()) self.mox.ReplayAll() url = reverse("horizon:admin:volumes:volumes:migrate", args=[volume.id]) res = self.client.get(url) self.assertTemplateUsed(res, "admin/volumes/volumes/migrate_volume.html")
def test_unmanage_volume(self): # important - need to get the v2 cinder volume which has host data volume_list = [x for x in self.cinder_volumes.list() if x.name == "v2_volume"] volume = volume_list[0] formData = {"volume_name": volume.name, "host_name": "host@backend-name#pool", "volume_id": volume.id} cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume) cinder.volume_unmanage(IsA(http.HttpRequest), volume.id).AndReturn(volume) self.mox.ReplayAll() res = self.client.post(reverse("horizon:admin:volumes:volumes:unmanage", args=(volume.id,)), formData) self.assertNoFormErrors(res)
def test_update_volume(self): volume = self.cinder_volumes.get(name="my_volume") cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume) cinder.volume_update(IsA(http.HttpRequest), volume.id, volume.name, volume.description) self.mox.ReplayAll() formData = {"method": "UpdateForm", "name": volume.name, "description": volume.description} url = reverse("horizon:project:volumes:volumes:update", args=[volume.id]) res = self.client.post(url, formData) self.assertRedirectsNoFollow(res, VOLUME_INDEX_URL)
def test_volume_migrate_list_pool_get_exception(self): volume = self.cinder_volumes.get(name='v2_volume') cinder.volume_get(IsA(http.HttpRequest), volume.id) \ .AndReturn(volume) cinder.pool_list(IsA(http.HttpRequest)) \ .AndRaise(self.exceptions.cinder) self.mox.ReplayAll() url = reverse('horizon:admin:volumes:volumes:migrate', args=[volume.id]) res = self.client.get(url) self.assertRedirectsNoFollow(res, INDEX_URL)
def test_volume_migrate_post_api_exception(self): volume = self.cinder_volumes.get(name="v2_volume") host = self.cinder_pools.first().name cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume) cinder.pool_list(IsA(http.HttpRequest)).AndReturn(self.cinder_pools.list()) cinder.volume_migrate(IsA(http.HttpRequest), volume.id, host, False).AndRaise(self.exceptions.cinder) self.mox.ReplayAll() url = reverse("horizon:admin:volumes:volumes:migrate", args=[volume.id]) res = self.client.post(url, {"host": host, "volume_id": volume.id}) self.assertRedirectsNoFollow(res, INDEX_URL)
def test_detail_view_with_exception(self): volume = self.cinder_volumes.first() server = self.servers.first() volume.attachments = [{"server_id": server.id}] cinder.volume_get(IsA(http.HttpRequest), volume.id).AndRaise(self.exceptions.cinder) self.mox.ReplayAll() url = reverse("horizon:project:volumes:volumes:detail", args=[volume.id]) res = self.client.get(url) self.assertRedirectsNoFollow(res, VOLUME_INDEX_URL)
def test_edit_attachments_cannot_set_mount_point(self): volume = self.cinder_volumes.first() servers = [s for s in self.servers.list() if s.tenant_id == self.request.user.tenant_id] cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume) api.nova.server_list(IsA(http.HttpRequest)).AndReturn([servers, False]) self.mox.ReplayAll() url = reverse("horizon:project:volumes:volumes:attach", args=[volume.id]) res = self.client.get(url) # Assert the device field is hidden. form = res.context["form"] self.assertTrue(isinstance(form.fields["device"].widget, widgets.HiddenInput))
def test_get_data(self): volume = self.cinder_volumes.get(name="v2_volume") volume._apiresource.name = "" cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume) self.mox.ReplayAll() url = VOLUME_INDEX_URL + "?action=row_update&table=volumes&obj_id=" + volume.id res = self.client.get(url, {}, HTTP_X_REQUESTED_WITH="XMLHttpRequest") self.assertEqual(res.status_code, 200) self.assertEqual(volume.name, volume.id)
def test_extend_volume(self): volume = self.cinder_volumes.first() formData = {"name": u"A Volume I Am Making", "orig_size": volume.size, "new_size": 100} cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(self.cinder_volumes.first()) cinder.volume_extend(IsA(http.HttpRequest), volume.id, formData["new_size"]).AndReturn(volume) self.mox.ReplayAll() url = reverse("horizon:project:volumes:volumes:extend", args=[volume.id]) res = self.client.post(url, formData) redirect_url = VOLUME_INDEX_URL self.assertRedirectsNoFollow(res, redirect_url)
def get_data(self): try: volume_id = self.kwargs['volume_id'] volume = cinder.volume_get(self.request, volume_id) search_opts = self.get_search_opts(volume) snapshots = cinder.volume_snapshot_list( self.request, search_opts=search_opts) if snapshots: setattr(volume, 'has_snapshot', True) for att in volume.attachments: att['instance'] = nova.server_get(self.request, att['server_id']) except Exception: redirect = self.get_redirect_url() exceptions.handle(self.request, _('Unable to retrieve volume details.'), redirect=redirect) try: volume.messages = cinder.message_list( self.request, {'resource_type': 'volume', 'resource_uuid': volume.id}, ) except Exception: volume.messages = [] exceptions.handle( self.request, _('Unable to retrieve volume messages.'), ignore=True, ) return volume, snapshots
def prepare_source_fields_if_snapshot_specified(self, request): try: snapshot = self.get_snapshot(request, request.GET["snapshot_id"]) self.fields['name'].initial = snapshot.name self.fields['size'].initial = snapshot.size self.fields['snapshot_source'].choices = ((snapshot.id, snapshot),) try: # Set the volume type from the original volume orig_volume = cinder.volume_get(request, snapshot.volume_id) self.fields['type'].initial = orig_volume.volume_type except Exception: pass self.fields['size'].help_text = ( _('Volume size must be equal to or greater than the ' 'snapshot size (%sGB)') % snapshot.size) del self.fields['image_source'] del self.fields['volume_source'] del self.fields['volume_source_type'] del self.fields['availability_zone'] except Exception: exceptions.handle(request, _('Unable to load the specified snapshot.'))
def handle(self, request, data): instance_choices = dict(self.fields['instance'].choices) instance_name = instance_choices.get(data['instance'], _("Unknown instance (None)")) # The name of the instance in the choices list has the ID appended to # it, so let's slice that off... instance_name = instance_name.rsplit(" (")[0] try: attach = api.nova.instance_volume_attach(request, data['volume_id'], data['instance'], data.get('device', '')) volume = cinder.volume_get(request, data['volume_id']) if not volume.display_name: volume_name = volume.id else: volume_name = volume.display_name message = _('Attaching volume %(vol)s to instance ' '%(inst)s on %(dev)s.') % {"vol": volume_name, "inst": instance_name, "dev": attach.device} messages.info(request, message) return True except: redirect = reverse("horizon:project:volumes:index") exceptions.handle(request, _('Unable to attach volume.'), redirect=redirect)
def test_get_data(self): volume = self.volumes.first() volume.display_name = '' cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume) self.mox.ReplayAll() url = reverse('horizon:project:volumes:index') + \ "?action=row_update&table=volumes&obj_id=" + volume.id res = self.client.get(url, {}, HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(res.status_code, 200) self.assertEqual(volume.display_name, volume.id)
def get_data(self): try: volume_id = self.kwargs["volume_id"] volume = cinder.volume_get(self.request, volume_id) except Exception: exceptions.handle(self.request, _("Unable to retrieve volume details."), redirect=self.success_url) return volume
def get_object(self): volume_id = self.kwargs["volume_id"] try: return cinder.volume_get(self.request, volume_id) except Exception: self._object = None exceptions.handle(self.request, _("Unable to retrieve volume information."))
def handle(self, request, data): instance_choices = dict(self.fields['instance'].choices) instance_name = instance_choices.get(data['instance'], _("Unknown instance (None)")) # The name of the instance in the choices list has the ID appended to # it, so let's slice that off... instance_name = instance_name.rsplit(" (")[0] # api requires non-empty device name or None device = data.get('device') or None try: attach = api.nova.instance_volume_attach(request, data['volume_id'], data['instance'], device) volume = cinder.volume_get(request, data['volume_id']) message = _('Attaching volume %(vol)s to instance ' '%(inst)s on %(dev)s.') % {"vol": volume.name, "inst": instance_name, "dev": attach.device} messages.info(request, message) return True except Exception: redirect = reverse("horizon:sdscontroller:sds_volumes:index") exceptions.handle(request, _('Unable to attach volume.'), redirect=redirect)
def handle(self, request, data): try: volume = cinder.volume_get(request, data['volume_id']) force = False message = _('Creating volume snapshot "%s".') % data['name'] if volume.status == 'in-use': force = True message = _('Forcing to create snapshot "%s" ' 'from attached volume.') % data['name'] snapshot = cinder.volume_snapshot_create(request, data['volume_id'], data['name'], data['description'], force=force) messages.info(request, message) return snapshot except Exception as e: redirect = reverse("horizon:project:volumes:index") msg = _('Unable to create volume snapshot.') if e.code == 413: msg = _('Requested snapshot would exceed the allowed quota.') exceptions.handle(request, msg, redirect=redirect)
def test_create_volume_from_snapshot(self): volume = self.volumes.first() usage_limit = {'maxTotalVolumeGigabytes': 250, 'gigabytesUsed': 20, 'volumesUsed': len(self.volumes.list()), 'maxTotalVolumes': 6} snapshot = self.volume_snapshots.first() formData = {'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 50, 'type': '', 'snapshot_source': snapshot.id} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_snapshot_get(IsA(http.HttpRequest), str(snapshot.id)).AndReturn(snapshot) cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).\ AndReturn(self.volumes.first()) cinder.extension_supported(IsA(http.HttpRequest), 'AvailabilityZones')\ .AndReturn(True) cinder.availability_zone_list(IsA(http.HttpRequest)).AndReturn( self.cinder_availability_zones.list()) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], '', metadata={}, snapshot_id=snapshot.id, image_id=None, availability_zone=None).AndReturn(volume) self.mox.ReplayAll() # get snapshot from url url = reverse('horizon:project:volumes:create') res = self.client.post("?".join([url, "snapshot_id=" + str(snapshot.id)]), formData) redirect_url = reverse('horizon:project:volumes:index') self.assertRedirectsNoFollow(res, redirect_url)
def test_get_volume_snapshot_details(self): volume = self.cinder_volumes.first() snapshot = self.cinder_volume_snapshots.first() cinder.volume_get(IsA(http.HttpRequest), volume.id). \ AndReturn(volume) cinder.volume_snapshot_get(IsA(http.HttpRequest), snapshot.id). \ AndReturn(snapshot) self.mox.ReplayAll() url = reverse('horizon:admin:volumes:snapshots:detail', args=[snapshot.id]) res = self.client.get(url) self.assertTemplateUsed(res, 'horizon/common/_detail.html') self.assertEqual(res.context['snapshot'].id, snapshot.id)
def get_data(self, request, backup_id): backup = cinder.volume_backup_get(request, backup_id) try: backup.volume = cinder.volume_get(request, backup.volume_id) except Exception: pass return backup
def instance_volume_attach(request, volume_id, instance_id, device): # If we have a multiattach volume, we need to use microversion>=2.60. volume = cinder.volume_get(request, volume_id) if volume.multiattach: version = get_microversion(request, 'multiattach') if version: client = _nova.novaclient(request, version) else: raise VolumeMultiattachNotSupported( _('Multiattach volumes are not yet supported.')) else: client = _nova.novaclient(request) return client.volumes.create_server_volume(instance_id, volume_id, device)
def get_data(self): try: volume_id = self.kwargs['volume_id'] volume = cinder.volume_get(self.request, volume_id) except Exception: error_message = _( 'Unable to retrieve volume information for volume: "%s"') \ % volume_id exceptions.handle(self.request, error_message, redirect=self.success_url) return volume
def get_data(self): try: volume_id = self.kwargs['volume_id'] volume = cinder.volume_get(self.request, volume_id) for att in volume.attachments: att['instance'] = api.nova.server_get(self.request, att['server_id']) except Exception: redirect = reverse('horizon:project:volumes:index') exceptions.handle(self.request, _('Unable to retrieve volume details.'), redirect=redirect) return volume
def test_extend_volume(self): volume = self.cinder_volumes.first() formData = { 'name': u'A Volume I Am Making', 'orig_size': volume.size, 'new_size': 100 } cinder.volume_get(IsA(http.HttpRequest), volume.id).\ AndReturn(self.cinder_volumes.first()) cinder.volume_extend(IsA(http.HttpRequest), volume.id, formData['new_size']).AndReturn(volume) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:extend', args=[volume.id]) res = self.client.post(url, formData) redirect_url = VOLUME_INDEX_URL self.assertRedirectsNoFollow(res, redirect_url)
def get_data(self, request, snapshot_id): snapshot = cinder.volume_snapshot_get(request, snapshot_id) snapshot._volume = cinder.volume_get(request, snapshot.volume_id) snapshot.host_name = getattr(snapshot._volume, 'os-vol-host-attr:host') tenant_id = getattr(snapshot._volume, 'os-vol-tenant-attr:tenant_id') try: tenant = keystone.tenant_get(request, tenant_id) snapshot.tenant_name = getattr(tenant, "name") except Exception: msg = _('Unable to retrieve volume project information.') exceptions.handle(request, msg) return snapshot
def test_create_volume_from_snapshot_invalid_size(self): usage_limit = { 'maxTotalVolumeGigabytes': 100, 'gigabytesUsed': 20, 'volumesUsed': len(self.volumes.list()), 'maxTotalVolumes': 6 } snapshot = self.volume_snapshots.first() formData = { 'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 20, 'snapshot_source': snapshot.id } cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) cinder.volume_snapshot_get(IsA(http.HttpRequest), str(snapshot.id)).AndReturn(snapshot) cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).\ AndReturn(self.volumes.first()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) self.mox.ReplayAll() url = reverse('horizon:project:volumes:create') res = self.client.post("?".join( [url, "snapshot_id=" + str(snapshot.id)]), formData, follow=True) self.assertEqual(res.redirect_chain, []) self.assertFormError( res, 'form', None, "The volume size cannot be less than the " "snapshot size (40GB)")
def test_extend_volume_with_wrong_size(self): volume = self.cinder_volumes.first() usage_limit = {'maxTotalVolumeGigabytes': 100, 'gigabytesUsed': 20, 'volumesUsed': len(self.cinder_volumes.list()), 'maxTotalVolumes': 6} formData = {'name': u'A Volume I Am Making', 'orig_size': volume.size, 'new_size': 10} cinder.volume_get(IsA(http.HttpRequest), volume.id).\ AndReturn(self.cinder_volumes.first()) quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:extend', args=[volume.id]) res = self.client.post(url, formData) self.assertFormError(res, 'form', None, "New size for extend must be greater than " "current size.")
def test_create_snapshot_get(self): volume = self.cinder_volumes.first() cinder.volume_get(IsA(http.HttpRequest), volume.id) \ .AndReturn(volume) snapshot_used = len(self.cinder_volume_snapshots.list()) usage_limit = { 'maxTotalVolumeGigabytes': 250, 'gigabytesUsed': 20, 'snapshotsUsed': snapshot_used, 'maxTotalSnapshots': 6 } quotas.tenant_limit_usages(IsA(http.HttpRequest)).\ AndReturn(usage_limit) self.mox.ReplayAll() url = reverse('horizon:virtual:volumes:' 'volumes:create_snapshot', args=[volume.id]) res = self.client.get(url) self.assertTemplateUsed( res, 'virtual/volumes/volumes/' 'create_snapshot.html')
def get_context_data(self, request): try: snapshot = self.tab_group.kwargs['snapshot'] volume = cinder.volume_get(request, snapshot.volume_id) except Exception: redirect = self.get_redirect_url() exceptions.handle(self.request, _('Unable to retrieve snapshot details.'), redirect=redirect) return { "snapshot": snapshot, "volume": volume, "group_snapshot": snapshot.group_snapshot }
def test_force_create_snapshot(self): volume = self.cinder_volumes.get(name='my_volume') snapshot = self.cinder_volume_snapshots.first() cinder.volume_get(IsA(http.HttpRequest), volume.id) \ .AndReturn(volume) cinder.volume_snapshot_create(IsA(http.HttpRequest), volume.id, snapshot.name, snapshot.description, force=True) \ .AndReturn(snapshot) self.mox.ReplayAll() formData = {'method': 'CreateSnapshotForm', 'tenant_id': self.tenant.id, 'volume_id': volume.id, 'name': snapshot.name, 'description': snapshot.description} url = reverse('horizon:project:volumes:create_snapshot', args=[volume.id]) res = self.client.post(url, formData) self.assertRedirectsNoFollow(res, INDEX_URL)
def get_context_data(self, request): try: backup = self.tab_group.kwargs['backup'] try: volume = cinder.volume_get(request, backup.volume_id) except Exception: volume = None return {'backup': backup, 'volume': volume} except Exception: redirect = reverse('horizon:storage:volumes:index') exceptions.handle(self.request, _('Unable to retrieve backup details.'), redirect=redirect)
def test_create_volume_from_snapshot(self): volume = self.volumes.first() usage = {'gigabytes': {'available': 250}, 'volumes': {'available': 6}} snapshot = self.volume_snapshots.first() formData = {'name': u'A Volume I Am Making', 'description': u'This is a volume I am making for a test.', 'method': u'CreateForm', 'size': 50, 'type': '', 'snapshot_source': snapshot.id} cinder.volume_type_list(IsA(http.HttpRequest)).\ AndReturn(self.volume_types.list()) quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(usage) cinder.volume_snapshot_get(IsA(http.HttpRequest), str(snapshot.id)).AndReturn(snapshot) cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).\ AndReturn(self.volumes.first()) cinder.volume_create(IsA(http.HttpRequest), formData['size'], formData['name'], formData['description'], '', metadata={}, snapshot_id=snapshot.id, image_id=None).\ AndReturn(volume) self.mox.ReplayAll() # get snapshot from url url = reverse('horizon:project:volumes:create') res = self.client.post("?".join([url, "snapshot_id=" + str(snapshot.id)]), formData) redirect_url = reverse('horizon:project:volumes:index') self.assertRedirectsNoFollow(res, redirect_url)
def get_data(self, request, backup_id): backup = cinder.volume_backup_get(request, backup_id) try: backup.volume = cinder.volume_get(request, backup.volume_id) except Exception: pass if backup.snapshot_id is not None: try: backup.snapshot = cinder.volume_snapshot_get( request, backup.snapshot_id) except Exception: pass else: backup.snapshot = None return backup
def get_data(self, request, volume_id): volume = cinder.volume_get(request, volume_id) try: tenants, has_more = api.keystone.tenant_list(request) except Exception: tenants = [] msg = _('Unable to retrieve volume project information.') exceptions.handle(request, msg) tenant_dict = SortedDict([(t.id, t) for t in tenants]) tenant_id = getattr(volume, "os-vol-tenant-attr:tenant_id", None) tenant = tenant_dict.get(tenant_id, None) volume.tenant_name = getattr(tenant, "name", None) return volume
def test_edit_attachments(self): PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_set_mount_point'] settings.OPENSTACK_HYPERVISOR_FEATURES['can_set_mount_point'] = True volume = self.volumes.first() servers = [s for s in self.servers.list() if s.tenant_id == self.request.user.tenant_id] cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume) api.nova.server_list(IsA(http.HttpRequest)).AndReturn([servers, False]) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:attach', args=[volume.id]) res = self.client.get(url) # Asserting length of 2 accounts for the one instance option, # and the one 'Choose Instance' option. form = res.context['form'] self.assertEqual(len(form.fields['instance']._choices), 2) self.assertEqual(res.status_code, 200) self.assertTrue(isinstance(form.fields['device'].widget, widgets.TextInput)) settings.OPENSTACK_HYPERVISOR_FEATURES['can_set_mount_point'] = PREV
def test_edit_attachments_attached_volume(self): servers = [s for s in self.servers.list() if s.tenant_id == self.request.user.tenant_id] server = servers[0] volume = self.cinder_volumes.list()[0] cinder.volume_get(IsA(http.HttpRequest), volume.id) \ .AndReturn(volume) api.nova.server_list(IsA(http.HttpRequest)) \ .AndReturn([servers, False]) self.mox.ReplayAll() url = reverse('horizon:project:volumes:volumes:attach', args=[volume.id]) res = self.client.get(url) self.assertEqual(res.context['form'].fields['instance']._choices[0][1], "Select an instance") self.assertEqual(len(res.context['form'].fields['instance'].choices), 2) self.assertEqual(res.context['form'].fields['instance']._choices[1][0], server.id) self.assertEqual(res.status_code, 200)
def get_data(self, request, snapshot_id): snapshot = cinder.volume_snapshot_get(request, snapshot_id) snapshot._volume = cinder.volume_get(request, snapshot.volume_id) try: tenants, has_more = api.keystone.tenant_list(request) except Exception: tenants = [] msg = _('Unable to retrieve volume project information.') tenant_dict = SortedDict([(t.id, t) for t in tenants]) tenant_id = getattr(snapshot, "os-extended-snapshot-attributes:project_id", None) tenant = tenant_dict.get(tenant_id, None) snapshot.tenant_name = getattr(tenant, "name", None) return snapshot
def handle(self, request, data): try: result = None volume = cinder.volume_get(request, data['volume_id']) if not volume: message = _('Volume not exist,id:"%s".') % data['volume_id'] else: message = _('Enabling volume "%s".') % data['name'] result = sg_api.volume_enable(request, data['volume_id'], data['name'], data['description']) messages.info(request, message) return result except Exception: redirect = reverse("horizon:storage-gateway:volumes:index") msg = _('Unable to enable volume:%s.') % data['volume_id'] exceptions.handle(request, msg, redirect=redirect)
def get_data(self): try: volume_id = self.kwargs['volume_id'] volume = cinder.volume_get(self.request, volume_id) snapshots = cinder.volume_snapshot_list( self.request, search_opts={'volume_id': volume.id}) if snapshots: setattr(volume, 'has_snapshot', True) for att in volume.attachments: att['instance'] = api.nova.server_get(self.request, att['server_id']) except Exception: redirect = self.get_redirect_url() exceptions.handle(self.request, _('Unable to retrieve volume details.'), redirect=redirect) return volume
def get_data(self): try: snapshot_id = self.kwargs['snapshot_id'] snapshot = cinder.volume_snapshot_get(self.request, snapshot_id) snapshot._volume = cinder.volume_get(self.request, snapshot.volume_id) if getattr(snapshot, 'group_snapshot_id', None): snapshot.group_snapshot = cinder.group_snapshot_get( self.request, snapshot.group_snapshot_id) else: snapshot.group_snapshot = None except Exception: redirect = self.get_redirect_url() exceptions.handle(self.request, _('Unable to retrieve snapshot details.'), redirect=redirect) return snapshot
def get_context_data(self, **kwargs): context = super(CreateSnapshotView, self).get_context_data(**kwargs) context['volume_id'] = self.kwargs['volume_id'] try: volume = cinder.volume_get(self.request, context['volume_id']) if (volume.status == 'in-use'): context['attached'] = True context['form'].set_warning(_("This volume is currently " "attached to an instance. " "In some cases, creating a " "snapshot from an attached " "volume can result in a " "corrupted snapshot.")) context['usages'] = quotas.tenant_limit_usages(self.request) except Exception: exceptions.handle(self.request, _('Unable to retrieve volume information.')) return context
def handle(self, request, data): try: volume=cinder.volume_get(request,data['volume_id']) if data['Confirm to rollback?'] == "yes": rollback = cinder.volume_snapshot_rollback(request, volume, data['snapshot_id'], force=True) msg = _('Rolling back the current volume...') messages.success(request, msg) return volume return "not do it" except Exception: exceptions.handle(request, _('Unable to rollback snapshot.'))
def handle(self, request, data): instance_choices = dict(self.fields['instance'].choices) instance_name = instance_choices.get(data['instance'], _("Unknown instance (None)")) # The name of the instance in the choices list has the ID appended to # it, so let's slice that off... instance_name = instance_name.rsplit(" (")[0] try: attach = api.nova.instance_volume_attach(request, data['volume_id'], data['instance'], data.get('device', '')) volume = cinder.volume_get(request, data['volume_id']) message = _('Attaching volume %(vol)s to instance ' '%(inst)s on %(dev)s.') % { "vol": volume.name, "inst": instance_name, "dev": attach.device } messages.info(request, message) # operation log api.logger.Logger(request).create( resource_type='volume', action_name='Attach Volume To Instance', resource_name='Volume', config=_('Volume ID: %s') % data['volume_id'], status='Success') return True except Exception: redirect = reverse("horizon:storage:volumes:index") exceptions.handle(request, _('Unable to attach volume.'), redirect=redirect) # operation log api.logger.Logger(request).create( resource_type='volume', action_name='Attach Volume To Instance', resource_name='Volume', config='Unable to attach volume.', status='Error')
def __init__(self, request, *args, **kwargs): super(CreateForm, self).__init__(request, *args, **kwargs) volume_types = cinder.volume_type_list(request) self.fields['type'].choices = [("", "")] + \ [(type.name, type.name) for type in volume_types] if ("snapshot_id" in request.GET): try: snapshot = self.get_snapshot(request, request.GET["snapshot_id"]) self.fields['name'].initial = snapshot.display_name self.fields['size'].initial = snapshot.size self.fields['snapshot_source'].choices = ((snapshot.id, snapshot), ) try: # Set the volume type from the original volume orig_volume = cinder.volume_get(request, snapshot.volume_id) self.fields['type'].initial = orig_volume.volume_type except: pass self.fields['size'].help_text = _( 'Volume size must be equal ' 'to or greater than the snapshot size (%sGB)' % snapshot.size) except: exceptions.handle(request, _('Unable to load the specified snapshot.')) else: try: snapshots = cinder.volume_snapshot_list(request) if snapshots: choices = [('', _("Choose a snapshot"))] + \ [(s.id, s) for s in snapshots] self.fields['snapshot_source'].choices = choices else: del self.fields['snapshot_source'] except: exceptions.handle(request, _("Unable to retrieve " "volume snapshots."))
def handle(self, request, data): try: volume = cinder.volume_get(request, data['volume_id']) force = False message = _('Creating volume snapshot "%s".') % data['name'] if volume.status == 'in-use': force = True message = _('Forcing to create snapshot "%s" ' 'from attached volume.') % data['name'] snapshot = cinder.volume_snapshot_create(request, data['volume_id'], data['name'], data['description'], force=force) messages.info(request, message) # operation log config = _("Snapshot Name: %s Volume ID: %s") % (data['name'], data['volume_id']) api.logger.Logger(request).create(resource_type='volume', action_name='Create Snapshot', resource_name='Volume', config=config, status='Success') return snapshot except Exception as e: redirect = reverse("horizon:storage:volumes:index") msg = _('Unable to create volume snapshot.') if e.code == 413: msg = _('Requested snapshot would exceed the allowed quota.') exceptions.handle(request, msg, redirect=redirect) # operation log api.logger.Logger(request).create( resource_type='volume', action_name='Create Snapshot', resource_name='Volume', config=_('Unable to create volume snapshot.'), status='Error')
def handle(self, request, data): try: volume = cinder.volume_get(request, data['volume_id']) force = False message = _('Creating volume snapshot "%s".') % data['name'] if volume.status == 'in-use': force = True message = _('Forcing to create snapshot "%s" ' 'from attached volume.') % data['name'] snapshot = cinder.volume_snapshot_create(request, data['volume_id'], data['name'], data['description'], force=force) messages.info(request, message) return snapshot except Exception: redirect = reverse("horizon:project:volumes:index") exceptions.handle(request, _('Unable to create volume snapshot.'), redirect=redirect)
def get_context_data(self, request): try: backup = self.tab_group.kwargs['backup'] try: volume = cinder.volume_get(request, backup.volume_id) except Exception: volume = None try: if backup.snapshot_id: snapshot = cinder.volume_snapshot_get( request, backup.snapshot_id) else: snapshot = None except Exception: snapshot = None return {'backup': backup, 'volume': volume, 'snapshot': snapshot} except Exception: redirect = reverse('horizon:project:backups:index') exceptions.handle(self.request, _('Unable to retrieve backup details.'), redirect=redirect)
def prepare_source_fields_if_snapshot_specified(self, request): try: snapshot = self.get_snapshot(request, request.GET["snapshot_id"]) self.fields['name'].initial = snapshot.name self.fields['size'].initial = snapshot.size self.fields['snapshot_source'].choices = ((snapshot.id, snapshot), ) try: # Set the volume type from the original volume orig_volume = cinder.volume_get(request, snapshot.volume_id) self.fields['type'].initial = orig_volume.volume_type except Exception: pass self.fields['size'].help_text = ( _('Volume size must be equal to or greater than the ' 'snapshot size (%sGiB)') % snapshot.size) del self.fields['image_source'] del self.fields['volume_source'] del self.fields['volume_source_type'] del self.fields['availability_zone'] except Exception: exceptions.handle(request, _('Unable to load the specified snapshot.'))
def handle(self, request, data): try: volume = cinder.volume_get(request, data['volume_id']) force = False message = _('Creating volume snapshot "%s".') % data['name'] if volume.status == 'in-use': force = True message = _('Forcing to create snapshot "%s" ' 'from attached volume.') % data['name'] snapshot = cinder.volume_snapshot_create(request, data['volume_id'], data['name'], data['description'], force=force) messages.info(request, message) return snapshot except Exception as e: redirect = reverse("horizon:admin:volumes:index") msg = _('Unable to create volume snapshot.') if e.code == 413: msg = _('Requested snapshot would exceed the allowed quota.') exceptions.handle(request, msg, redirect=redirect)
def get_data(self): try: volume_id = self.kwargs['volume_id'] volume = cinder.volume_get(self.request, volume_id) search_opts = self.get_search_opts(volume) snapshots = cinder.volume_snapshot_list(self.request, search_opts=search_opts) if snapshots: setattr(volume, 'has_snapshot', True) for att in volume.attachments: att['instance'] = nova.server_get(self.request, att['server_id']) if getattr(volume, 'group_id', None): volume.group = cinder.group_get(self.request, volume.group_id) else: volume.group = None except Exception: redirect = self.get_redirect_url() exceptions.handle(self.request, _('Unable to retrieve volume details.'), redirect=redirect) try: volume.messages = cinder.message_list( self.request, { 'resource_type': 'volume', 'resource_uuid': volume.id }, ) except Exception: volume.messages = [] exceptions.handle( self.request, _('Unable to retrieve volume messages.'), ignore=True, ) return volume, snapshots