Support database version image tags for creating instance
Change-Id: If6ffacb5bab1aa5ffc51dd5678bd110c0beeb51d
This commit is contained in:
parent
1d24b65052
commit
c1be8a41d9
@ -60,8 +60,8 @@ To create a datastore version:
|
|||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
openstack datastore version create 5.7.29 mysql mysql "" \
|
openstack datastore version create 5.7.29 mysql mysql "" \
|
||||||
--image-tags trove,mysql \
|
--image-tags trove,mysql \
|
||||||
--active --default
|
--active --default
|
||||||
|
|
||||||
#. Load validation rules for configuration groups
|
#. Load validation rules for configuration groups
|
||||||
|
|
||||||
@ -121,4 +121,19 @@ version for testing purpose, to do that:
|
|||||||
|
|
||||||
.. code-block:: console
|
.. 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.
|
||||||
|
@ -33,7 +33,9 @@ Verify operation of the Database service.
|
|||||||
|
|
||||||
.. code-block:: console
|
.. 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
|
#. Create a database `instance
|
||||||
<http://docs.openstack.org/user-guide/create_db.html>`_.
|
<http://docs.openstack.org/user-guide/create_db.html>`_.
|
||||||
|
@ -26,6 +26,8 @@ def get_image_id(client, image_id, image_tags):
|
|||||||
return image_id
|
return image_id
|
||||||
|
|
||||||
elif image_tags:
|
elif image_tags:
|
||||||
|
if isinstance(image_tags, str):
|
||||||
|
image_tags = image_tags.split(',')
|
||||||
filters = {'tag': image_tags, 'status': 'active'}
|
filters = {'tag': image_tags, 'status': 'active'}
|
||||||
images = list(client.images.list(
|
images = list(client.images.list(
|
||||||
filters=filters, sort='created_at:desc', limit=1))
|
filters=filters, sort='created_at:desc', limit=1))
|
||||||
|
@ -24,6 +24,7 @@ import trove.common.apischema as apischema
|
|||||||
from trove.common import cfg
|
from trove.common import cfg
|
||||||
from trove.common import clients
|
from trove.common import clients
|
||||||
from trove.common import exception
|
from trove.common import exception
|
||||||
|
from trove.common import glance as common_glance
|
||||||
from trove.common.i18n import _
|
from trove.common.i18n import _
|
||||||
from trove.common import neutron
|
from trove.common import neutron
|
||||||
from trove.common import notification
|
from trove.common import notification
|
||||||
@ -414,7 +415,13 @@ class InstanceController(wsgi.Controller):
|
|||||||
datastore, datastore_version = ds_models.get_datastore_version(
|
datastore, datastore_version = ds_models.get_datastore_version(
|
||||||
**datastore_args)
|
**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(
|
databases = populate_validated_databases(
|
||||||
body['instance'].get('databases', []))
|
body['instance'].get('databases', []))
|
||||||
|
@ -50,11 +50,7 @@ class TestDatastoreVersionController(trove_testtools.TestCase):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
versions = models.DatastoreVersions.load_all(only_active=False)
|
util.cleanup_db()
|
||||||
for ver in versions:
|
|
||||||
ver.delete()
|
|
||||||
|
|
||||||
cls.ds.delete()
|
|
||||||
|
|
||||||
super(TestDatastoreVersionController, cls).tearDownClass()
|
super(TestDatastoreVersionController, cls).tearDownClass()
|
||||||
|
|
||||||
|
80
trove/tests/unittests/instance/test_service.py
Normal file
80
trove/tests/unittests/instance/test_service.py
Normal file
@ -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
|
||||||
|
)
|
@ -31,3 +31,11 @@ def init_db():
|
|||||||
db_api.db_sync(CONF)
|
db_api.db_sync(CONF)
|
||||||
session.configure_db(CONF)
|
session.configure_db(CONF)
|
||||||
DB_SETUP = True
|
DB_SETUP = True
|
||||||
|
|
||||||
|
|
||||||
|
def cleanup_db():
|
||||||
|
with LOCK:
|
||||||
|
global DB_SETUP
|
||||||
|
if DB_SETUP:
|
||||||
|
session.clean_db()
|
||||||
|
DB_SETUP = False
|
||||||
|
Loading…
Reference in New Issue
Block a user