Resize replicas (volume) together with primary
When resizing volume for an instance which is the primary of a replication, cluster, Trove also resizes the volume for all the replicas automatically. Change-Id: I2e719772fe7abc719255ea2a705d9ec342aced2a
This commit is contained in:
parent
be6f8565f5
commit
8e48d757e6
@ -82,6 +82,9 @@ size. A valid volume size is an integer value in gigabytes (GB).
|
||||
You cannot increase the volume to a size that is larger than the
|
||||
API volume size limit.
|
||||
|
||||
For replication cluster, resizing volume of the primary will also resize
|
||||
replicas automatically.
|
||||
|
||||
Normal response codes: 202
|
||||
|
||||
Request
|
||||
|
@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- When resizing volume for an instance which is the primary of a replication
|
||||
cluster, Trove also resizes the volume for all the replicas automatically.
|
@ -1353,28 +1353,41 @@ class Instance(BuiltInstance):
|
||||
new_flavor)
|
||||
|
||||
def resize_volume(self, new_size):
|
||||
def _resize_resources():
|
||||
self.validate_can_perform_action()
|
||||
LOG.info("Resizing volume of instance %s.", self.id)
|
||||
if self.db_info.cluster_id is not None:
|
||||
raise exception.ClusterInstanceOperationNotSupported()
|
||||
old_size = self.volume_size
|
||||
if int(new_size) <= old_size:
|
||||
raise exception.BadRequest(_("The new volume 'size' must be "
|
||||
"larger than the current volume "
|
||||
"size of '%s'.") % old_size)
|
||||
# Set the task to Resizing before sending off to the taskmanager
|
||||
self.update_db(task_status=InstanceTasks.RESIZING)
|
||||
task_api.API(self.context).resize_volume(new_size, self.id)
|
||||
"""Resize instance volume.
|
||||
|
||||
If the instance is primary in a replication cluster, volumes of all the
|
||||
replicas are also resized.
|
||||
"""
|
||||
|
||||
def _resize_resources(instance):
|
||||
LOG.info("Resizing volume of instance %s.", instance.id)
|
||||
instance.update_db(task_status=InstanceTasks.RESIZING)
|
||||
task_api.API(self.context).resize_volume(new_size, instance.id)
|
||||
|
||||
new_size_l = int(new_size)
|
||||
|
||||
if self.db_info.cluster_id is not None:
|
||||
raise exception.ClusterInstanceOperationNotSupported()
|
||||
if not self.volume_size:
|
||||
raise exception.BadRequest(_("Instance %s has no volume.")
|
||||
% self.id)
|
||||
new_size_l = int(new_size)
|
||||
if new_size_l <= self.volume_size:
|
||||
raise exception.BadRequest(_("The new volume 'size' must be "
|
||||
"larger than the current volume "
|
||||
"size of '%s'.") % self.volume_size)
|
||||
validate_volume_size(new_size_l)
|
||||
return run_with_quotas(self.tenant_id,
|
||||
{'volumes': new_size_l - self.volume_size},
|
||||
_resize_resources)
|
||||
self.validate_can_perform_action()
|
||||
|
||||
instances = [self]
|
||||
for dbinfo in self.slaves:
|
||||
replica = Instance.load(self.context, dbinfo.id, needs_server=True)
|
||||
replica.validate_can_perform_action()
|
||||
instances.append(replica)
|
||||
|
||||
for instance in instances:
|
||||
run_with_quotas(
|
||||
self.tenant_id, {'volumes': new_size_l - self.volume_size},
|
||||
_resize_resources, instance)
|
||||
|
||||
def reboot(self):
|
||||
LOG.info("Rebooting instance %s.", self.id)
|
||||
|
@ -356,13 +356,13 @@ resources = [Resource(Resource.INSTANCES, 'max_instances_per_tenant'),
|
||||
QUOTAS.register_resources(resources)
|
||||
|
||||
|
||||
def run_with_quotas(tenant_id, deltas, f):
|
||||
def run_with_quotas(tenant_id, deltas, f, *args, **kwargs):
|
||||
"""Quota wrapper."""
|
||||
|
||||
reservations = QUOTAS.reserve(tenant_id, **deltas)
|
||||
result = None
|
||||
try:
|
||||
result = f()
|
||||
result = f(*args, **kwargs)
|
||||
except Exception:
|
||||
QUOTAS.rollback(reservations)
|
||||
raise
|
||||
|
Loading…
Reference in New Issue
Block a user