From d34a6e7495bc6295aa5f01cb440eb4c093f0f73f Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Wed, 9 Dec 2015 18:26:39 -0430 Subject: [PATCH] Remove the gridfs driver The gridfs driver was marked as deprecated some releases ago. This patch removes the deprecated driver from the tree. Change-Id: I72785eb77447909fc67d42e17d805eaa77cf45a2 --- glance_store/_drivers/gridfs.py | 225 ------------------ glance_store/tests/unit/test_gridfs_store.py | 96 -------- glance_store/tests/unit/test_opts.py | 2 - ...remove-gridfs-driver-09286e27613b4353.yaml | 7 + setup.cfg | 4 - tox.ini | 2 +- 6 files changed, 8 insertions(+), 328 deletions(-) delete mode 100644 glance_store/_drivers/gridfs.py delete mode 100644 glance_store/tests/unit/test_gridfs_store.py create mode 100644 releasenotes/notes/remove-gridfs-driver-09286e27613b4353.yaml diff --git a/glance_store/_drivers/gridfs.py b/glance_store/_drivers/gridfs.py deleted file mode 100644 index 1d858677..00000000 --- a/glance_store/_drivers/gridfs.py +++ /dev/null @@ -1,225 +0,0 @@ -# Copyright 2013 Red Hat, Inc -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Storage backend for GridFS""" -from __future__ import absolute_import - -import logging - -from oslo_config import cfg -from oslo_utils import excutils -from six.moves import urllib - -from glance_store import capabilities -import glance_store.driver -from glance_store import exceptions -from glance_store.i18n import _ -import glance_store.location - -try: - import gridfs - import gridfs.errors - import pymongo - import pymongo.uri_parser as uri_parser -except ImportError: - pymongo = None - -LOG = logging.getLogger(__name__) - -_GRIDFS_OPTS = [ - cfg.StrOpt('mongodb_store_uri', - help="Hostname or IP address of the instance to connect to, " - "or a mongodb URI, or a list of hostnames / mongodb URIs. " - "If host is an IPv6 literal it must be enclosed " - "in '[' and ']' characters following the RFC2732 " - "URL syntax (e.g. '[::1]' for localhost)"), - cfg.StrOpt('mongodb_store_db', help='Database to use'), -] - - -class StoreLocation(glance_store.location.StoreLocation): - """ - Class describing an gridfs URI: - - gridfs:// - - Connection information has been consciously omitted for - security reasons, since this location will be stored in glance's - database and can be queried from outside. - - Note(flaper87): Make connection info available if user wants so - by adding a new configuration parameter `mongdb_store_insecure`. - """ - - def get_uri(self): - return "gridfs://%s" % self.specs.get("image_id") - - def parse_uri(self, uri): - """ - This method should fix any issue with the passed URI. Right now, - it just sets image_id value in the specs dict. - - :param uri: Current set URI - """ - parsed = urllib.parse.urlparse(uri) - assert parsed.scheme in ('gridfs',) - self.specs["image_id"] = parsed.netloc - - -class Store(glance_store.driver.Store): - """GridFS adapter""" - - _CAPABILITIES = capabilities.BitMasks.RW_ACCESS - OPTIONS = _GRIDFS_OPTS - EXAMPLE_URL = "gridfs://" - - def __init__(self, *args, **kwargs): - LOG.warn('The gridfs store has been deprecated and it\'ll be removed ' - 'in future versions of this library. Please, consider ' - 'maintaining it yourself or adopting a different store.') - super(Store, self).__init__(*args, **kwargs) - - def get_schemes(self): - return ('gridfs',) - - def configure_add(self): - """ - Configure the Store to use the stored configuration options - Any store that needs special configuration should implement - this method. If the store was not able to successfully configure - itself, it should raise `exceptions.BadStoreConfiguration` - """ - if pymongo is None: - msg = _("Missing dependencies: pymongo") - raise exceptions.BadStoreConfiguration(store_name="gridfs", - reason=msg) - - self.mongodb_uri = self._option_get('mongodb_store_uri') - - parsed = uri_parser.parse_uri(self.mongodb_uri) - self.mongodb_db = self._option_get('mongodb_store_db') or \ - parsed.get("database") - - self.mongodb = pymongo.MongoClient(self.mongodb_uri) - self.fs = gridfs.GridFS(self.mongodb[self.mongodb_db]) - - def _option_get(self, param): - result = getattr(self.conf.glance_store, param) - if not result: - reason = (_("Could not find %(param)s in configuration " - "options.") % {'param': param}) - LOG.debug(reason) - raise exceptions.BadStoreConfiguration(store_name="gridfs", - reason=reason) - return result - - @capabilities.check - def get(self, location, offset=0, chunk_size=None, context=None): - """ - Takes a `glance_store.location.Location` object that indicates - where to find the image file, and returns a tuple of generator - (for reading the image file) and image_size - - :param location `glance_store.location.Location` object, supplied - from glance_store.location.get_location_from_uri() - :raises `glance_store.exceptions.NotFound` if image does not exist - """ - image = self._get_file(location) - return (image, image.length) - - def get_size(self, location, context=None): - """ - Takes a `glance_store.location.Location` object that indicates - where to find the image file, and returns the image_size (or 0 - if unavailable) - - :param location `glance_store.location.Location` object, supplied - from glance_store.location.get_location_from_uri() - """ - try: - key = self._get_file(location) - return key.length - except Exception: - return 0 - - def _get_file(self, location): - store_location = location - if isinstance(location, glance_store.location.Location): - store_location = location.store_location - try: - - parsed = urllib.parse.urlparse(store_location.get_uri()) - return self.fs.get(parsed.netloc) - except gridfs.errors.NoFile: - msg = _("Could not find %s image in GridFS") % \ - store_location.get_uri() - LOG.debug(msg) - raise exceptions.NotFound(msg) - - @capabilities.check - def add(self, image_id, image_file, image_size, context=None): - """ - Stores an image file with supplied identifier to the backend - storage system and returns a tuple containing information - about the stored image. - - :param image_id: The opaque image identifier - :param image_file: The image data to write, as a file-like object - :param image_size: The size of the image data to write, in bytes - - :retval tuple of URL in backing store, bytes written, checksum - and a dictionary with storage system specific information - :raises `glance_store.exceptions.Duplicate` if the image already - existed - """ - loc = StoreLocation({'image_id': image_id}, self.conf) - - if self.fs.exists(image_id): - raise exceptions.Duplicate(_("GridFS already has an image at " - "location %s") % loc.get_uri()) - - LOG.debug(_("Adding a new image to GridFS with " - "id %(iid)s and size %(size)s") - % dict(iid=image_id, size=image_size)) - - try: - self.fs.put(image_file, _id=image_id) - image = self._get_file(loc) - except Exception: - # Note(zhiyan): clean up already received data when - # error occurs such as ImageSizeLimitExceeded exception. - with excutils.save_and_reraise_exception(): - self.fs.delete(image_id) - - LOG.debug(_("Uploaded image %(iid)s, " - "md5 %(md)s, length %(len)s to GridFS") % - dict(iid=image._id, md=image.md5, len=image.length)) - - return (loc.get_uri(), image.length, image.md5, {}) - - @capabilities.check - def delete(self, location, context=None): - """ - Takes a `glance_store.location.Location` object that indicates - where to find the image file to delete - - :location `glance_store.location.Location` object, supplied - from glance_store.location.get_location_from_uri() - - :raises NotFound if image does not exist - """ - image = self._get_file(location) - self.fs.delete(image._id) - LOG.debug("Deleted image %s from GridFS") diff --git a/glance_store/tests/unit/test_gridfs_store.py b/glance_store/tests/unit/test_gridfs_store.py deleted file mode 100644 index 066b0b88..00000000 --- a/glance_store/tests/unit/test_gridfs_store.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import gridfs -import mock -import pymongo -import six - -from glance_store._drivers import gridfs as gfs -from glance_store.tests import base -from glance_store.tests.unit import test_store_capabilities - - -GRIDFS_CONF = {'mongodb_store_uri': 'mongodb://fake_store_uri', - 'mongodb_store_db': 'fake_store_db'} - - -class FakeMongoClient(object): - def __init__(self, *args, **kwargs): - pass - - def __getitem__(self, key): - return None - - -class FakeGridFS(object): - image_data = {} - called_commands = [] - - def __init__(self, *args, **kwargs): - pass - - def exists(self, image_id): - self.called_commands.append('exists') - return False - - def put(self, image_file, _id): - self.called_commands.append('put') - data = None - while True: - data = image_file.read(64) - if data: - self.image_data[_id] = \ - self.image_data.setdefault(_id, '') + data - else: - break - - def delete(self, _id): - self.called_commands.append('delete') - - def get(self, location): - self.called_commands.append('get') - - class Image(object): - _id = "test" - length = 6 - md5 = "yoyo" - - return Image - - -class TestStore(base.StoreBaseTest, - test_store_capabilities.TestStoreCapabilitiesChecking): - - def setUp(self): - """Establish a clean test environment.""" - super(TestStore, self).setUp() - - conn = mock.patch.object(pymongo, 'MongoClient').start() - conn.side_effect = FakeMongoClient - self.addCleanup(conn.stop) - - pgfs = mock.patch.object(gridfs, 'GridFS').start() - pgfs.side_effect = FakeGridFS - self.addCleanup(pgfs.stop) - - self.store = gfs.Store(self.conf) - self.config(group='glance_store', **GRIDFS_CONF) - self.store.configure() - - def test_cleanup_when_add_image_exception(self): - self.store.add('fake_image_id', six.StringIO('xx'), 2) - self.assertEqual(self.store.fs.called_commands, - ['exists', 'put', 'get']) diff --git a/glance_store/tests/unit/test_opts.py b/glance_store/tests/unit/test_opts.py index e99d0479..0964e0b6 100644 --- a/glance_store/tests/unit/test_opts.py +++ b/glance_store/tests/unit/test_opts.py @@ -69,8 +69,6 @@ class OptsTestCase(base.StoreBaseTest): 'filesystem_store_datadirs', 'filesystem_store_file_perm', 'filesystem_store_metadata_file', - 'mongodb_store_db', - 'mongodb_store_uri', 'os_region_name', 'rbd_store_ceph_conf', 'rbd_store_chunk_size', diff --git a/releasenotes/notes/remove-gridfs-driver-09286e27613b4353.yaml b/releasenotes/notes/remove-gridfs-driver-09286e27613b4353.yaml new file mode 100644 index 00000000..50c942d7 --- /dev/null +++ b/releasenotes/notes/remove-gridfs-driver-09286e27613b4353.yaml @@ -0,0 +1,7 @@ +--- +prelude: > + glance_store._drivers.gridfs +deprecations: + - The gridfs driver has been removed from the tree. + The environments using this driver that were not + migrated will stop working after the upgrade. \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index f169b30d..dd705d44 100644 --- a/setup.cfg +++ b/setup.cfg @@ -32,7 +32,6 @@ glance_store.drivers = s3 = glance_store._drivers.s3:Store sheepdog = glance_store._drivers.sheepdog:Store cinder = glance_store._drivers.cinder:Store - gridfs = glance_store._drivers.gridfs:Store vmware = glance_store._drivers.vmware_datastore:Store # TESTS ONLY @@ -46,7 +45,6 @@ glance_store.drivers = glance.store.s3.Store = glance_store._drivers.s3:Store glance.store.sheepdog.Store = glance_store._drivers.sheepdog:Store glance.store.cinder.Store = glance_store._drivers.cinder:Store - glance.store.gridfs.Store = glance_store._drivers.gridfs:Store glance.store.vmware_datastore.Store = glance_store._drivers.vmware_datastore:Store oslo.config.opts = @@ -61,8 +59,6 @@ vmware = swift = httplib2>=0.7.5 # MIT python-swiftclient>=2.2.0 # Apache-2.0 -gridfs = - pymongo>=3.0.2 # Apache-2.0 cinder = python-cinderclient>=1.3.1 # Apache-2.0 diff --git a/tox.ini b/tox.ini index 170a8b6c..faf708ac 100644 --- a/tox.ini +++ b/tox.ini @@ -9,7 +9,7 @@ usedevelop = True install_command = pip install --allow-all-external --allow-insecure netaddr -U {opts} {packages} deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt - .[s3,vmware,swift,gridfs,cinder] + .[s3,vmware,swift,cinder] commands = python setup.py testr --slowest --testr-args='{posargs}' [testenv:docs]