summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.zuul.yaml2
-rw-r--r--devstack/plugin.sh18
-rw-r--r--doc/source/user/manage-db-and-users.rst17
-rwxr-xr-xintegration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/31-guest-agent-install3
-rw-r--r--integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/guest-agent.logrotate7
-rw-r--r--releasenotes/source/index.rst1
-rw-r--r--releasenotes/source/xena.rst6
-rw-r--r--trove/common/cfg.py4
-rw-r--r--trove/guestagent/datastore/manager.py4
-rw-r--r--trove/guestagent/strategies/replication/mariadb_gtid.py9
-rw-r--r--trove/guestagent/strategies/replication/mysql_base.py8
-rw-r--r--trove/guestagent/strategies/replication/mysql_gtid.py8
-rw-r--r--trove/guestagent/strategies/replication/postgresql.py10
-rw-r--r--trove/instance/models.py40
-rwxr-xr-xtrove/taskmanager/models.py40
-rw-r--r--trove/tests/unittests/taskmanager/test_models.py44
16 files changed, 141 insertions, 80 deletions
diff --git a/.zuul.yaml b/.zuul.yaml
index 706d7fb3..acb0b24e 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -13,7 +13,7 @@
- check-requirements
- openstack-cover-jobs
# - openstack-lower-constraints-jobs
- - openstack-python3-xena-jobs
+ - openstack-python3-yoga-jobs
- periodic-stable-jobs
- publish-openstack-docs-pti
- release-notes-jobs-python3
diff --git a/devstack/plugin.sh b/devstack/plugin.sh
index 2c8b3b7a..01800907 100644
--- a/devstack/plugin.sh
+++ b/devstack/plugin.sh
@@ -479,8 +479,7 @@ function create_guest_image {
fi
echo "Add the image to glance"
- glance_image_id=$(openstack --os-region-name RegionOne --os-password ${SERVICE_PASSWORD} \
- --os-project-name service --os-username trove \
+ glance_image_id=$(openstack --os-cloud trove \
image create ${image_name} \
--disk-format qcow2 --container-format bare \
--tag trove \
@@ -593,16 +592,13 @@ function config_nova_keypair {
fi
echo "Creating Trove management keypair ${TROVE_MGMT_KEYPAIR_NAME}"
- openstack --os-region-name RegionOne --os-password ${SERVICE_PASSWORD} --os-project-name service --os-username trove \
- keypair create --public-key ${SSH_DIR}/id_rsa.pub ${TROVE_MGMT_KEYPAIR_NAME}
+ openstack --os-cloud trove keypair create --public-key ${SSH_DIR}/id_rsa.pub ${TROVE_MGMT_KEYPAIR_NAME}
iniset $TROVE_CONF DEFAULT nova_keypair ${TROVE_MGMT_KEYPAIR_NAME}
}
function config_cinder_volume_type {
- volume_type=$(openstack --os-region-name RegionOne --os-password ${SERVICE_PASSWORD} \
- --os-project-name service --os-username trove \
- volume type list -c Name -f value | awk 'NR==1 {print}')
+ volume_type=$(openstack --os-cloud trove volume type list -c Name -f value | awk 'NR==1 {print}')
iniset $TROVE_CONF DEFAULT cinder_volume_type ${volume_type}
}
@@ -611,14 +607,12 @@ function config_mgmt_security_group {
local sgid
echo "Creating Trove management security group."
- sgid=$(openstack --os-region-name RegionOne --os-password ${SERVICE_PASSWORD} --os-project-name service --os-username trove security group create ${TROVE_MGMT_SECURITY_GROUP} -f value -c id)
+ sgid=$(openstack --os-cloud trove security group create ${TROVE_MGMT_SECURITY_GROUP} -f value -c id)
# Allow ICMP
- openstack --os-region-name RegionOne --os-password ${SERVICE_PASSWORD} --os-project-name service --os-username trove \
- security group rule create --proto icmp $sgid
+ openstack --os-cloud trove security group rule create --proto icmp $sgid
# Allow SSH
- openstack --os-region-name RegionOne --os-password ${SERVICE_PASSWORD} --os-project-name service --os-username trove \
- security group rule create --protocol tcp --dst-port 22 $sgid
+ openstack --os-cloud trove security group rule create --protocol tcp --dst-port 22 $sgid
iniset $TROVE_CONF DEFAULT management_security_groups $sgid
}
diff --git a/doc/source/user/manage-db-and-users.rst b/doc/source/user/manage-db-and-users.rst
index ad25b1d8..e6be85d6 100644
--- a/doc/source/user/manage-db-and-users.rst
+++ b/doc/source/user/manage-db-and-users.rst
@@ -6,12 +6,17 @@ Assume that you installed Trove service and uploaded images with datastore of
your choice. This section shows how to manage users and databases in a MySQL
5.7 instance.
-.. warning::
+Currently, the Database and User API is only supported by mysql datastore.
- Currently, the Database and User API is only supported by mysql datastore.
- For others, the recommended way is to get root password (``POST
- /v1.0/{project_id}/instances/{instance_id}/root``) and communicate with the
- database service directly for database and user management.
+For database user management, there are two approaches:
+
+1. If the ``root_on_create`` option is enabled for the datastore in trove
+ service config file, the root user password is returned after creating
+ instance, which can be used directly to access the database.
+2. If ``root_on_create=False``, the recommended way is to get root password
+ (``POST /v1.0/{project_id}/instances/{instance_id}/root`` or ``openstack
+ database root enable`` in CLI) and communicate with the database service
+ directly for database and user management.
Manage root user
~~~~~~~~~~~~~~~~
@@ -32,7 +37,7 @@ further database operations.
If needed, ``openstack database root disable <instance_id>`` command could
disable the root user.
-Database and User management via Trove API
+Database and User management via Trove CLI
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Trove provides API to manage users and databases for mysql datastore.
diff --git a/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/31-guest-agent-install b/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/31-guest-agent-install
index 0cd63059..cfb6b61e 100755
--- a/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/31-guest-agent-install
+++ b/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/31-guest-agent-install
@@ -16,7 +16,8 @@ for folder in "/var/lib/trove" "/etc/trove" "/etc/trove/certs" "/etc/trove/conf.
chown -R ${GUEST_USERNAME}:root ${folder}
done
-install -D -g root -o ${GUEST_USERNAME} -m 0644 ${SCRIPTDIR}/guest-agent.logrotate /etc/logrotate.d/guest-agent
+# The logrotate file owner should be root or user with uid 0.
+install -D -g root -o root -m 0644 ${SCRIPTDIR}/guest-agent.logrotate /etc/logrotate.d/guest-agent
# Create a virtual environment (with dependencies installed) for guest agent service
/usr/bin/python3 -m venv ${GUEST_VENV}
diff --git a/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/guest-agent.logrotate b/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/guest-agent.logrotate
index 2a42143a..235b4c48 100644
--- a/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/guest-agent.logrotate
+++ b/integration/scripts/files/elements/guest-agent/install.d/guest-agent-source-install/guest-agent.logrotate
@@ -1,4 +1,4 @@
-/var/log/guest-agent.log {
+/var/log/trove/trove-guestagent.log {
daily
rotate 10
missingok
@@ -6,9 +6,4 @@
compress
delaycompress
sharedscripts
- postrotate
- # Signal name shall not have the SIG prefix in kill command
- # http://pubs.opengroup.org/onlinepubs/9699919799/utilities/kill.html
- kill -s USR1 $(cat /var/run/guest-agent.pid)
- endscript
}
diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst
index 6143e135..e43d0598 100644
--- a/releasenotes/source/index.rst
+++ b/releasenotes/source/index.rst
@@ -6,6 +6,7 @@
:maxdepth: 1
unreleased
+ xena
wallaby
victoria
ussuri
diff --git a/releasenotes/source/xena.rst b/releasenotes/source/xena.rst
new file mode 100644
index 00000000..1be85be3
--- /dev/null
+++ b/releasenotes/source/xena.rst
@@ -0,0 +1,6 @@
+=========================
+Xena Series Release Notes
+=========================
+
+.. release-notes::
+ :branch: stable/xena
diff --git a/trove/common/cfg.py b/trove/common/cfg.py
index eadb8514..65c030cf 100644
--- a/trove/common/cfg.py
+++ b/trove/common/cfg.py
@@ -23,9 +23,9 @@ from oslo_config import cfg
from oslo_config import types
from oslo_config.cfg import NoSuchOptError
from oslo_log import log as logging
+from oslo_log import versionutils
from oslo_middleware import cors
from osprofiler import opts as profiler
-from oslo_log import versionutils
from trove.common.i18n import _
from trove.version import version_info as version
@@ -245,7 +245,7 @@ common_opts = [
cfg.IntOpt('trove_conductor_workers',
help='Number of workers for the Conductor service. The default '
'will be the number of CPUs available.'),
- cfg.BoolOpt('use_nova_server_config_drive', default=True,
+ cfg.BoolOpt('use_nova_server_config_drive', default=False,
help='Use config drive for file injection when booting '
'instance.'),
cfg.StrOpt('device_path', default='/dev/vdb',
diff --git a/trove/guestagent/datastore/manager.py b/trove/guestagent/datastore/manager.py
index 097ccc99..442aea21 100644
--- a/trove/guestagent/datastore/manager.py
+++ b/trove/guestagent/datastore/manager.py
@@ -882,7 +882,7 @@ class Manager(periodic_task.PeriodicTasks):
self.replication.enable_as_master(self.app, replica_source_config)
LOG.info('Enabled as replication master')
- snapshot_id, log_position = self.replication.snapshot_for_replication(
+ snapshot_id, replica_conf = self.replication.snapshot_for_replication(
context, self.app, self.adm, None, snapshot_info)
volume_stats = self.get_filesystem_stats(context, None)
@@ -896,7 +896,7 @@ class Manager(periodic_task.PeriodicTasks):
},
'replication_strategy': self.replication_strategy,
'master': self.replication.get_master_ref(self.app, snapshot_info),
- 'log_position': log_position
+ 'replica_conf': replica_conf
}
return replication_snapshot
diff --git a/trove/guestagent/strategies/replication/mariadb_gtid.py b/trove/guestagent/strategies/replication/mariadb_gtid.py
index 4909ee66..66115806 100644
--- a/trove/guestagent/strategies/replication/mariadb_gtid.py
+++ b/trove/guestagent/strategies/replication/mariadb_gtid.py
@@ -31,15 +31,16 @@ class MariaDBGTIDReplication(mysql_base.MysqlReplicationBase):
master_info = super(MariaDBGTIDReplication, self).get_replica_context(
service, adm)
+ replica_conf = master_info['replica_conf']
get_pos_cmd = 'SELECT @@global.gtid_binlog_pos;'
gtid_pos = service.execute_sql(get_pos_cmd).first()[0]
LOG.debug('gtid_binlog_pos: %s', gtid_pos)
- master_info['log_position']['gtid_pos'] = gtid_pos
+ replica_conf['log_position']['gtid_pos'] = gtid_pos
return master_info
def connect_to_master(self, service, master_info):
- logging_config = master_info['log_position']
+ replica_conf = master_info['replica_conf']
last_gtid = ''
if 'dataset' in master_info:
@@ -59,8 +60,8 @@ class MariaDBGTIDReplication(mysql_base.MysqlReplicationBase):
{
'host': master_info['master']['host'],
'port': master_info['master']['port'],
- 'user': logging_config['replication_user']['name'],
- 'password': logging_config['replication_user']['password'],
+ 'user': replica_conf['replication_user']['name'],
+ 'password': replica_conf['replication_user']['password']
})
service.execute_sql(change_master_cmd)
diff --git a/trove/guestagent/strategies/replication/mysql_base.py b/trove/guestagent/strategies/replication/mysql_base.py
index 744aec6b..b6e8b6b9 100644
--- a/trove/guestagent/strategies/replication/mysql_base.py
+++ b/trove/guestagent/strategies/replication/mysql_base.py
@@ -92,10 +92,11 @@ class MysqlReplicationBase(base.Replication):
replication_user = self._create_replication_user(service, adm)
service.grant_replication_privilege(replication_user)
- log_position = {
+ replica_conf = {
+ 'log_position': {},
'replication_user': replication_user
}
- return snapshot_info['id'], log_position
+ return snapshot_info['id'], replica_conf
def enable_as_master(self, service, master_config):
if not service.exists_replication_source_overrides():
@@ -146,7 +147,8 @@ class MysqlReplicationBase(base.Replication):
service.grant_replication_privilege(replication_user)
return {
'master': self.get_master_ref(service, None),
- 'log_position': {
+ 'replica_conf': {
+ 'log_position': {},
'replication_user': replication_user
}
}
diff --git a/trove/guestagent/strategies/replication/mysql_gtid.py b/trove/guestagent/strategies/replication/mysql_gtid.py
index f0e8137b..ed0116d1 100644
--- a/trove/guestagent/strategies/replication/mysql_gtid.py
+++ b/trove/guestagent/strategies/replication/mysql_gtid.py
@@ -38,12 +38,12 @@ class MysqlGTIDReplication(mysql_base.MysqlReplicationBase):
set_gtid_cmd = "SET GLOBAL gtid_purged='%s'" % last_gtid
service.execute_sql(set_gtid_cmd)
- logging_config = master_info['log_position']
+ replica_conf = master_info['replica_conf']
LOG.info(
"Configure the slave, master: %s:%s, replication user: %s",
master_info['master']['host'],
master_info['master']['port'],
- logging_config['replication_user']['name']
+ replica_conf['replication_user']['name']
)
change_master_cmd = (
@@ -57,8 +57,8 @@ class MysqlGTIDReplication(mysql_base.MysqlReplicationBase):
{
'host': master_info['master']['host'],
'port': master_info['master']['port'],
- 'user': logging_config['replication_user']['name'],
- 'password': logging_config['replication_user']['password']
+ 'user': replica_conf['replication_user']['name'],
+ 'password': replica_conf['replication_user']['password']
})
service.execute_sql(change_master_cmd)
diff --git a/trove/guestagent/strategies/replication/postgresql.py b/trove/guestagent/strategies/replication/postgresql.py
index 5698d5e8..32935512 100644
--- a/trove/guestagent/strategies/replication/postgresql.py
+++ b/trove/guestagent/strategies/replication/postgresql.py
@@ -136,10 +136,11 @@ class PostgresqlReplicationStreaming(base.Replication):
LOG.info('Getting or creating replication user')
replication_user = self._get_or_create_replication_user(service)
- log_position = {
+ replica_conf = {
+ 'log_position': {},
'replication_user': replication_user
}
- return snapshot_info['id'], log_position
+ return snapshot_info['id'], replica_conf
def get_master_ref(self, service, snapshot_info):
master_ref = {
@@ -158,7 +159,7 @@ class PostgresqlReplicationStreaming(base.Replication):
as_root=True)
LOG.debug("Standby signal file created")
- user = snapshot['log_position']['replication_user']
+ user = snapshot['replica_conf']['replication_user']
conninfo = (f"host={snapshot['master']['host']} "
f"port={snapshot['master']['port']} "
f"dbname=postgres "
@@ -189,8 +190,9 @@ class PostgresqlReplicationStreaming(base.Replication):
repl_user_info = self._get_or_create_replication_user(service)
return {
+ 'log_position': {},
'master': self.get_master_ref(None, None),
- 'log_position': {'replication_user': repl_user_info}
+ 'replica_conf': {'replication_user': repl_user_info}
}
def cleanup_source_on_replica_detach(self, admin_service, replica_info):
diff --git a/trove/instance/models.py b/trove/instance/models.py
index b2659d08..4691b6b9 100644
--- a/trove/instance/models.py
+++ b/trove/instance/models.py
@@ -15,12 +15,14 @@
# under the License.
"""Model classes that form the core of instances functionality."""
-from datetime import datetime
-from datetime import timedelta
+import base64
import json
import os.path
import re
+from datetime import datetime
+from datetime import timedelta
+
from novaclient import exceptions as nova_exceptions
from oslo_config.cfg import NoSuchOptError
from oslo_log import log as logging
@@ -43,8 +45,8 @@ from trove.common.i18n import _
from trove.common.trove_remote import create_trove_client
from trove.configuration.models import Configuration
from trove.datastore import models as datastore_models
-from trove.datastore.models import DatastoreVersionMetadata as dvm
from trove.datastore.models import DBDatastoreVersionMetadata
+from trove.datastore.models import DatastoreVersionMetadata as dvm
from trove.db import get_db_api
from trove.db import models as dbmodels
from trove.extensions.security_group.models import SecurityGroup
@@ -614,9 +616,10 @@ def load_instance(cls, context, id, needs_server=False,
def update_service_status(task_status, service_status, ins_id):
"""Update service status as needed."""
+ RESTART_REQUIRED = srvstatus.ServiceStatuses.RESTART_REQUIRED
if (task_status == InstanceTasks.NONE and
- service_status.status != srvstatus.ServiceStatuses.RESTART_REQUIRED and
- not service_status.is_uptodate()):
+ service_status.status != RESTART_REQUIRED and
+ not service_status.is_uptodate()):
LOG.warning('Guest agent heartbeat for instance %s has expried',
ins_id)
service_status.status = \
@@ -718,7 +721,8 @@ class BaseInstance(SimpleInstance):
from trove.cluster.models import is_cluster_deleting
if (self.db_info.cluster_id is not None and not
- is_cluster_deleting(self.context, self.db_info.cluster_id)):
+ is_cluster_deleting(context=self.context,
+ cluster_id=self.db_info.cluster_id)):
raise exception.ClusterInstanceOperationNotSupported()
if self.slaves:
@@ -963,6 +967,25 @@ class BaseInstance(SimpleInstance):
self._server_group_loaded = True
return self._server_group
+ def prepare_cloud_config(self, files):
+ userdata = (
+ "#cloud-config\n"
+ "write_files:\n"
+ )
+
+ for filename, content in files.items():
+ ud = encodeutils.safe_encode(content)
+ body_userdata = (
+ "- encoding: b64\n"
+ " owner: trove:trove\n"
+ " path: %s\n"
+ " content: %s\n" % (
+ filename, encodeutils.safe_decode(base64.b64encode(ud)))
+ )
+ userdata = userdata + body_userdata
+
+ return userdata
+
def get_injected_files(self, datastore_manager, datastore_version):
injected_config_location = CONF.get('injected_config_location')
guest_info = CONF.get('guest_info')
@@ -1034,12 +1057,14 @@ class BaseInstance(SimpleInstance):
class FreshInstance(BaseInstance):
+
@classmethod
def load(cls, context, id):
return load_instance(cls, context, id, needs_server=False)
class BuiltInstance(BaseInstance):
+
@classmethod
def load(cls, context, id, needs_server=True):
return load_instance(cls, context, id, needs_server=needs_server)
@@ -1509,7 +1534,7 @@ class Instance(BuiltInstance):
if not self.slaves:
raise exception.BadRequest(_("Instance %s is not a replica"
- " source.") % self.id)
+ " source.") % self.id)
service = InstanceServiceStatus.find_by(instance_id=self.id)
last_heartbeat_delta = timeutils.utcnow() - service.updated_at
@@ -1934,6 +1959,7 @@ class DBInstance(dbmodels.DatabaseModelBase):
class instance_encryption_key_cache(object):
+
def __init__(self, func, lru_cache_size=10):
self._table = {}
self._lru = []
diff --git a/trove/taskmanager/models.py b/trove/taskmanager/models.py
index 49742af8..134aecb5 100755
--- a/trove/taskmanager/models.py
+++ b/trove/taskmanager/models.py
@@ -229,8 +229,8 @@ class ClusterTasks(Cluster):
)
def _all_instances_acquire_status(
- self, instance_ids, cluster_id, shard_id, expected_status,
- fast_fail_statuses=None):
+ self, instance_ids, cluster_id, shard_id, expected_status,
+ fast_fail_statuses=None):
def _is_fast_fail_status(status):
return ((fast_fail_statuses is not None) and
@@ -244,7 +244,7 @@ class ClusterTasks(Cluster):
task_status = DBInstance.find_by(
id=instance_id).get_task_status()
if (_is_fast_fail_status(status) or
- (task_status == InstanceTasks.BUILDING_ERROR_SERVER)):
+ (task_status == InstanceTasks.BUILDING_ERROR_SERVER)):
# if one has failed, no need to continue polling
LOG.debug("Instance %(id)s has acquired a fast-fail "
"status %(status)s and"
@@ -269,7 +269,7 @@ class ClusterTasks(Cluster):
task_status = DBInstance.find_by(
id=instance_id).get_task_status()
if (_is_fast_fail_status(status) or
- (task_status == InstanceTasks.BUILDING_ERROR_SERVER)):
+ (task_status == InstanceTasks.BUILDING_ERROR_SERVER)):
failed_instance_ids.append(instance_id)
return failed_instance_ids
@@ -373,8 +373,8 @@ class ClusterTasks(Cluster):
context.notification = (
DBaaSInstanceUpgrade(context, **request_info))
with StartNotification(
- context, instance_id=instance.id,
- datastore_version_id=datastore_version.id):
+ context, instance_id=instance.id,
+ datastore_version_id=datastore_version.id):
with EndNotification(context):
instance.update_db(
datastore_version_id=datastore_version.id,
@@ -781,8 +781,8 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
status = service.get_status()
if (status == srvstatus.ServiceStatuses.RUNNING or
- status == srvstatus.ServiceStatuses.INSTANCE_READY or
- status == srvstatus.ServiceStatuses.HEALTHY):
+ status == srvstatus.ServiceStatuses.INSTANCE_READY or
+ status == srvstatus.ServiceStatuses.HEALTHY):
return True
elif status not in [srvstatus.ServiceStatuses.NEW,
srvstatus.ServiceStatuses.BUILDING,
@@ -986,6 +986,16 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
config_drive = CONF.use_nova_server_config_drive
key_name = CONF.nova_keypair
+ # Use config_drive instead by userdata
+ # We will inject guest config by cloud-config
+ if not config_drive:
+ if not userdata:
+ userdata = self.prepare_cloud_config(files)
+ else:
+ userdata = userdata + self.prepare_cloud_config(files)
+
+ files = {}
+
server = self.nova_client.servers.create(
self.name, image_id, flavor_id, key_name=key_name, nics=nics,
block_device_mapping_v2=bdmap_v2,
@@ -1432,6 +1442,7 @@ class BuiltInstanceTasks(Instance, NotifyMixin, ConfigurationMixin):
class BackupTasks(object):
+
@classmethod
def _parse_manifest(cls, manifest):
# manifest is in the format 'container/prefix'
@@ -1530,11 +1541,11 @@ class ModuleTasks(object):
for instance_module in instance_modules:
instance_id = instance_module.instance_id
if (instance_module.md5 != current_md5 or force) and (
- not md5 or md5 == instance_module.md5):
+ not md5 or md5 == instance_module.md5):
instance = BuiltInstanceTasks.load(context, instance_id,
needs_server=False)
if instance and (
- include_clustered or not instance.cluster_id):
+ include_clustered or not instance.cluster_id):
try:
module_models.Modules.validate(
modules, instance.datastore.id,
@@ -1550,8 +1561,8 @@ class ModuleTasks(object):
# Sleep if we've fired off too many in a row.
if (batch_size and
- not reapply_count % batch_size and
- (reapply_count + skipped_count) < total_count):
+ not reapply_count % batch_size and
+ (reapply_count + skipped_count) < total_count):
LOG.debug("Applied module to %(cnt)d of %(total)d "
"instances - sleeping for %(batch)ds",
{'cnt': reapply_count,
@@ -1908,7 +1919,7 @@ class ResizeActionBase(object):
self._perform_nova_action()
finally:
if self.instance.db_info.task_status != (
- inst_models.InstanceTasks.NONE):
+ inst_models.InstanceTasks.NONE):
self.instance.reset_task_status()
def _guest_is_awake(self):
@@ -1988,6 +1999,7 @@ class ResizeActionBase(object):
class ResizeAction(ResizeActionBase):
+
def __init__(self, instance, old_flavor, new_flavor):
"""
:type instance: trove.taskmanager.models.BuiltInstanceTasks
@@ -2043,6 +2055,7 @@ class ResizeAction(ResizeActionBase):
class MigrateAction(ResizeActionBase):
+
def __init__(self, instance, host=None):
super(MigrateAction, self).__init__(instance)
self.instance = instance
@@ -2070,6 +2083,7 @@ class MigrateAction(ResizeActionBase):
class RebuildAction(ResizeActionBase):
+
def __init__(self, instance, image_id):
"""The action to perform rebuild.
diff --git a/trove/tests/unittests/taskmanager/test_models.py b/trove/tests/unittests/taskmanager/test_models.py
index fde42e35..5167bc04 100644
--- a/trove/tests/unittests/taskmanager/test_models.py
+++ b/trove/tests/unittests/taskmanager/test_models.py
@@ -12,43 +12,46 @@
# License for the specific language governing permissions and limitations
# under the License.
import os
+
from tempfile import NamedTemporaryFile
from unittest import mock
-from unittest.mock import call
from unittest.mock import MagicMock
from unittest.mock import Mock
-from unittest.mock import patch
from unittest.mock import PropertyMock
+from unittest.mock import call
+from unittest.mock import patch
-from cinderclient import exceptions as cinder_exceptions
-from cinderclient.v3 import volumes as cinderclient_volumes
import cinderclient.v3.client as cinderclient
import neutronclient.v2_0.client as neutronclient
-from novaclient import exceptions as nova_exceptions
import novaclient.v2.flavors
import novaclient.v2.servers
+
+from cinderclient import exceptions as cinder_exceptions
+from cinderclient.v3 import volumes as cinderclient_volumes
+from novaclient import exceptions as nova_exceptions
from oslo_config import cfg
from swiftclient.client import ClientException
from testtools.matchers import Equals
from testtools.matchers import Is
+import trove.backup.models
+import trove.common.context
+import trove.common.template as template
+import trove.db.models
+import trove.guestagent.api
+
from trove import rpc
from trove.backup import models as backup_models
from trove.backup import state
-import trove.backup.models
+from trove.common import exception
from trove.common import timeutils
from trove.common import utils
-import trove.common.context
-from trove.common import exception
from trove.common.exception import GuestError
from trove.common.exception import PollTimeOut
from trove.common.exception import TroveError
-import trove.common.template as template
from trove.datastore import models as datastore_models
-import trove.db.models
from trove.extensions.common import models as common_models
from trove.extensions.mysql import models as mysql_models
-import trove.guestagent.api
from trove.instance.models import BaseInstance
from trove.instance.models import DBInstance
from trove.instance.models import InstanceServiceStatus
@@ -64,6 +67,7 @@ VOLUME_ID = 'volume-id-1'
class FakeOptGroup(object):
+
def __init__(self, tcp_ports=['3306', '3301-3307'],
udp_ports=[], icmp=False):
self.tcp_ports = tcp_ports
@@ -72,6 +76,7 @@ class FakeOptGroup(object):
class fake_Server(object):
+
def __init__(self):
self.id = None
self.name = None
@@ -108,6 +113,7 @@ class fake_ServerManager(object):
class fake_nova_client(object):
+
def __init__(self):
self.servers = fake_ServerManager()
@@ -236,7 +242,8 @@ class FreshInstanceTasksTest(BaseFreshInstanceTasksTest):
server = self.freshinstancetasks._create_server(
None, None, datastore_manager, None, None, None)
- self.assertEqual(server.userdata, self.userdata)
+ userdata = self.userdata + "#cloud-config\nwrite_files:\n"
+ self.assertEqual(server.userdata, userdata)
def test_create_instance_with_keypair(self):
cfg.CONF.set_override('nova_keypair', 'fake_keypair')
@@ -310,7 +317,8 @@ class FreshInstanceTasksTest(BaseFreshInstanceTasksTest):
def test_servers_create_block_device_mapping_v2(self,
mock_hostname,
mock_name):
- self.freshinstancetasks.prepare_userdata = Mock(return_value=None)
+ self.freshinstancetasks.prepare_userdata = Mock(
+ return_value="#cloud-config\nwrite_files:\n")
mock_nova_client = self.freshinstancetasks.nova_client = Mock()
mock_servers_create = mock_nova_client.servers.create
self.freshinstancetasks._create_server('fake-flavor', 'fake-image',
@@ -318,14 +326,18 @@ class FreshInstanceTasksTest(BaseFreshInstanceTasksTest):
meta = {'trove_project_id': self.freshinstancetasks.tenant_id,
'trove_user_id': 'test_user',
'trove_instance_id': self.freshinstancetasks.id}
+
+ userdata = self.freshinstancetasks.prepare_userdata('mysql')
+ userdata = userdata + \
+ self.freshinstancetasks.prepare_cloud_config({})
mock_servers_create.assert_called_with(
'fake-name', 'fake-image',
'fake-flavor', files={},
- userdata=None,
+ userdata=userdata,
block_device_mapping_v2=None,
availability_zone=None,
nics=None,
- config_drive=True,
+ config_drive=False,
scheduler_hints=None,
key_name=None,
meta=meta,
@@ -599,6 +611,7 @@ class ResizeVolumeTest(trove_testtools.TestCase):
self.new_vol_size)
class FakeGroup(object):
+
def __init__(self):
self.mount_point = 'var/lib/mysql'
self.device_path = '/dev/vdb'
@@ -1105,6 +1118,7 @@ class BackupTasksTest(trove_testtools.TestCase):
class NotifyMixinTest(trove_testtools.TestCase):
+
def test_get_service_id(self):
id_map = {
'mysql': '123',