summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/admin/datastore.rst21
-rw-r--r--doc/source/install/verify.rst4
-rw-r--r--trove/common/glance.py2
-rw-r--r--trove/instance/service.py9
-rw-r--r--trove/tests/unittests/extensions/mgmt/datastores/test_service.py6
-rw-r--r--trove/tests/unittests/instance/test_service.py80
-rw-r--r--trove/tests/unittests/util/util.py8
7 files changed, 120 insertions, 10 deletions
diff --git a/doc/source/admin/datastore.rst b/doc/source/admin/datastore.rst
index d98fdef4..59e2b26d 100644
--- a/doc/source/admin/datastore.rst
+++ b/doc/source/admin/datastore.rst
@@ -60,8 +60,8 @@ To create a datastore version:
.. code-block:: console
openstack datastore version create 5.7.29 mysql mysql "" \
- --image-tags trove,mysql \
- --active --default
+ --image-tags trove,mysql \
+ --active --default
#. Load validation rules for configuration groups
@@ -121,4 +121,19 @@ version for testing purpose, to do that:
.. code-block:: console
- $ openstack datastore version <version-id> --disable
+ $ openstack datastore version set <version-id> --disable
+
+Replace image ID with tags
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For datastore versions what are created using image ID, it's easy to switch to
+image tags without affecting the existing instances. New instances will be
+created by the image ID (the most recently uploaded) that getting from Glance
+using image tags. To do that, as the cloud admin user:
+
+ .. code-block:: console
+
+ $ openstack datastore version set <version-id> --image-tags trove,mysql
+
+Ignoring ``--image`` means removing the image ID from the datastore version if
+it's associated.
diff --git a/doc/source/install/verify.rst b/doc/source/install/verify.rst
index a607ee58..3fd0960a 100644
--- a/doc/source/install/verify.rst
+++ b/doc/source/install/verify.rst
@@ -33,7 +33,9 @@ Verify operation of the Database service.
.. code-block:: console
- $ openstack datastore version create 5.7.29 mysql mysql "" trove,mysql --active --default
+ $ openstack datastore version create 5.7.29 mysql mysql "" \
+ --image-tags trove,mysql \
+ --active --default
#. Create a database `instance
<http://docs.openstack.org/user-guide/create_db.html>`_.
diff --git a/trove/common/glance.py b/trove/common/glance.py
index 7461ae90..3bf8a6d9 100644
--- a/trove/common/glance.py
+++ b/trove/common/glance.py
@@ -26,6 +26,8 @@ def get_image_id(client, image_id, image_tags):
return image_id
elif image_tags:
+ if isinstance(image_tags, str):
+ image_tags = image_tags.split(',')
filters = {'tag': image_tags, 'status': 'active'}
images = list(client.images.list(
filters=filters, sort='created_at:desc', limit=1))
diff --git a/trove/instance/service.py b/trove/instance/service.py
index 883c1cd3..66c55470 100644
--- a/trove/instance/service.py
+++ b/trove/instance/service.py
@@ -24,6 +24,7 @@ import trove.common.apischema as apischema
from trove.common import cfg
from trove.common import clients
from trove.common import exception
+from trove.common import glance as common_glance
from trove.common.i18n import _
from trove.common import neutron
from trove.common import notification
@@ -414,7 +415,13 @@ class InstanceController(wsgi.Controller):
datastore, datastore_version = ds_models.get_datastore_version(
**datastore_args)
- image_id = datastore_version.image_id
+ # If only image_tags is configured in the datastore version, get
+ # the image ID using the tags.
+ glance_client = clients.create_glance_client(context)
+ image_id = common_glance.get_image_id(
+ glance_client, datastore_version.image_id,
+ datastore_version.image_tags)
+ LOG.info(f'Using image {image_id} for creating instance')
databases = populate_validated_databases(
body['instance'].get('databases', []))
diff --git a/trove/tests/unittests/extensions/mgmt/datastores/test_service.py b/trove/tests/unittests/extensions/mgmt/datastores/test_service.py
index be1d49fc..185a740e 100644
--- a/trove/tests/unittests/extensions/mgmt/datastores/test_service.py
+++ b/trove/tests/unittests/extensions/mgmt/datastores/test_service.py
@@ -50,11 +50,7 @@ class TestDatastoreVersionController(trove_testtools.TestCase):
@classmethod
def tearDownClass(cls):
- versions = models.DatastoreVersions.load_all(only_active=False)
- for ver in versions:
- ver.delete()
-
- cls.ds.delete()
+ util.cleanup_db()
super(TestDatastoreVersionController, cls).tearDownClass()
diff --git a/trove/tests/unittests/instance/test_service.py b/trove/tests/unittests/instance/test_service.py
new file mode 100644
index 00000000..e2635654
--- /dev/null
+++ b/trove/tests/unittests/instance/test_service.py
@@ -0,0 +1,80 @@
+# Copyright 2020 Catalyst Cloud
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+from unittest import mock
+
+from trove.common import clients
+from trove.datastore import models as ds_models
+from trove.instance import service
+from trove.tests.unittests import trove_testtools
+from trove.tests.unittests.util import util
+
+
+class TestInstanceController(trove_testtools.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ util.init_db()
+
+ cls.ds_name = cls.random_name('datastore',
+ prefix='TestInstanceController')
+ ds_models.update_datastore(name=cls.ds_name, default_version=None)
+ cls.ds = ds_models.Datastore.load(cls.ds_name)
+
+ ds_models.update_datastore_version(
+ cls.ds_name, 'test_image_id', 'mysql', cls.random_uuid(), [], '',
+ 1)
+ ds_models.update_datastore_version(
+ cls.ds_name, 'test_image_tags', 'mysql', '', ['trove', 'mysql'],
+ '', 1)
+ cls.ds_version_imageid = ds_models.DatastoreVersion.load(
+ cls.ds, 'test_image_id')
+ cls.ds_version_imagetags = ds_models.DatastoreVersion.load(
+ cls.ds, 'test_image_tags')
+
+ cls.controller = service.InstanceController()
+
+ super(TestInstanceController, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ util.cleanup_db()
+
+ super(TestInstanceController, cls).tearDownClass()
+
+ @mock.patch.object(clients, 'create_glance_client')
+ @mock.patch('trove.instance.models.Instance.create')
+ def test_create_by_ds_version_image_tags(self, mock_model_create,
+ mock_create_client):
+ mock_glance_client = mock.MagicMock()
+ mock_glance_client.images.list.return_value = [
+ {'id': self.random_uuid()}]
+ mock_create_client.return_value = mock_glance_client
+
+ body = {
+ 'instance': {
+ 'name': self.random_name(name='instance',
+ prefix='TestInstanceController'),
+ 'flavorRef': self.random_uuid(),
+ 'datastore': {
+ 'type': self.ds_name,
+ 'version': self.ds_version_imagetags.name
+ }
+ }
+ }
+ ret = self.controller.create(mock.MagicMock(), body, mock.ANY)
+
+ self.assertEqual(200, ret.status)
+ mock_glance_client.images.list.assert_called_once_with(
+ filters={'tag': ['trove', 'mysql'], 'status': 'active'},
+ sort='created_at:desc', limit=1
+ )
diff --git a/trove/tests/unittests/util/util.py b/trove/tests/unittests/util/util.py
index bf1eda66..ce22ed7b 100644
--- a/trove/tests/unittests/util/util.py
+++ b/trove/tests/unittests/util/util.py
@@ -31,3 +31,11 @@ def init_db():
db_api.db_sync(CONF)
session.configure_db(CONF)
DB_SETUP = True
+
+
+def cleanup_db():
+ with LOCK:
+ global DB_SETUP
+ if DB_SETUP:
+ session.clean_db()
+ DB_SETUP = False