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
|
You cannot increase the volume to a size that is larger than the
|
||||||
API volume size limit.
|
API volume size limit.
|
||||||
|
|
||||||
|
For replication cluster, resizing volume of the primary will also resize
|
||||||
|
replicas automatically.
|
||||||
|
|
||||||
Normal response codes: 202
|
Normal response codes: 202
|
||||||
|
|
||||||
Request
|
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)
|
new_flavor)
|
||||||
|
|
||||||
def resize_volume(self, new_size):
|
def resize_volume(self, new_size):
|
||||||
def _resize_resources():
|
"""Resize instance volume.
|
||||||
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)
|
|
||||||
|
|
||||||
|
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:
|
if not self.volume_size:
|
||||||
raise exception.BadRequest(_("Instance %s has no volume.")
|
raise exception.BadRequest(_("Instance %s has no volume.")
|
||||||
% self.id)
|
% 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)
|
validate_volume_size(new_size_l)
|
||||||
return run_with_quotas(self.tenant_id,
|
self.validate_can_perform_action()
|
||||||
{'volumes': new_size_l - self.volume_size},
|
|
||||||
_resize_resources)
|
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):
|
def reboot(self):
|
||||||
LOG.info("Rebooting instance %s.", self.id)
|
LOG.info("Rebooting instance %s.", self.id)
|
||||||
|
|
|
@ -356,13 +356,13 @@ resources = [Resource(Resource.INSTANCES, 'max_instances_per_tenant'),
|
||||||
QUOTAS.register_resources(resources)
|
QUOTAS.register_resources(resources)
|
||||||
|
|
||||||
|
|
||||||
def run_with_quotas(tenant_id, deltas, f):
|
def run_with_quotas(tenant_id, deltas, f, *args, **kwargs):
|
||||||
"""Quota wrapper."""
|
"""Quota wrapper."""
|
||||||
|
|
||||||
reservations = QUOTAS.reserve(tenant_id, **deltas)
|
reservations = QUOTAS.reserve(tenant_id, **deltas)
|
||||||
result = None
|
result = None
|
||||||
try:
|
try:
|
||||||
result = f()
|
result = f(*args, **kwargs)
|
||||||
except Exception:
|
except Exception:
|
||||||
QUOTAS.rollback(reservations)
|
QUOTAS.rollback(reservations)
|
||||||
raise
|
raise
|
||||||
|
|
Loading…
Reference in New Issue