mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-24 05:40:23 -07:00
* Fixes #38174: Add remove-brick operation for gluster_volume Existing gluster_volume module does not support removal of bricks from a gluster volume. Also, operation remove-brick needs to be followed by a commit operation. Signed-off-by: Devyani Kota <dkota@redhat.com> * Updates #38174: Add documentation for remove-brick operation Signed-off-by: Devyani Kota <dkota@redhat.com> * Updates #38174: Add support to reduce cluster configuration. An exceptional scenario exists where the user might want to reduce the gluster cluster configuration for replicated volumes from replica 3 to replica 2 that need to be handled in a different manner than the generic gluster commands, where the user is expected to mention the replica count of the new configuration in order to remove the bricks. Signed-off-by: Devyani Kota <dkota@redhat.com> * Updates #38174: Add checks for self-heal status prior remove operation. While reducing the cluster configuration from replica 3 to 2, it needs to be checked for status of self-heal prior remove-brick operation is executed. Signed-off-by: Devyani Kota <dkota@redhat.com>
This commit is contained in:
parent
960ebd981f
commit
363ec65062
1 changed files with 88 additions and 5 deletions
|
@ -153,6 +153,27 @@ EXAMPLES = """
|
||||||
- 192.0.2.10
|
- 192.0.2.10
|
||||||
- 192.0.2.11
|
- 192.0.2.11
|
||||||
run_once: true
|
run_once: true
|
||||||
|
|
||||||
|
- name: Remove the bricks from gluster volume
|
||||||
|
gluster_volume:
|
||||||
|
state: present
|
||||||
|
name: testvol
|
||||||
|
bricks: /bricks/brick1/b1,/bricks/brick2/b2
|
||||||
|
cluster:
|
||||||
|
- 10.70.42.85
|
||||||
|
force: true
|
||||||
|
run_once: true
|
||||||
|
|
||||||
|
- name: Reduce cluster configuration
|
||||||
|
gluster_volume:
|
||||||
|
state: present
|
||||||
|
name: testvol
|
||||||
|
bricks: /bricks/brick3/b1,/bricks/brick4/b2
|
||||||
|
replicas: 2
|
||||||
|
cluster:
|
||||||
|
- 10.70.42.85
|
||||||
|
force: true
|
||||||
|
run_once: true
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
@ -243,6 +264,8 @@ def get_volumes():
|
||||||
volume['arbiters'] = []
|
volume['arbiters'] = []
|
||||||
value = value[:-10]
|
value = value[:-10]
|
||||||
volume['arbiters'].append(value)
|
volume['arbiters'].append(value)
|
||||||
|
elif key.lower() == 'number of bricks':
|
||||||
|
volume['replicas'] = value[-1:]
|
||||||
if key.lower() != 'bricks' and key.lower()[:5] == 'brick':
|
if key.lower() != 'bricks' and key.lower()[:5] == 'brick':
|
||||||
if 'bricks' not in volume:
|
if 'bricks' not in volume:
|
||||||
volume['bricks'] = []
|
volume['bricks'] = []
|
||||||
|
@ -354,6 +377,57 @@ def add_bricks(name, new_bricks, stripe, replica, force):
|
||||||
run_gluster(args)
|
run_gluster(args)
|
||||||
|
|
||||||
|
|
||||||
|
def remove_bricks(name, removed_bricks, force):
|
||||||
|
# max-tries=12 with default_interval=10 secs
|
||||||
|
max_tries = 12
|
||||||
|
retries = 0
|
||||||
|
success = False
|
||||||
|
args = ['volume', 'remove-brick', name]
|
||||||
|
args.extend(removed_bricks)
|
||||||
|
# create a copy of args to use for commit operation
|
||||||
|
args_c = args[:]
|
||||||
|
args.append('start')
|
||||||
|
run_gluster(args)
|
||||||
|
# remove-brick operation needs to be followed by commit operation.
|
||||||
|
if not force:
|
||||||
|
module.fail_json(msg="Force option is mandatory.")
|
||||||
|
else:
|
||||||
|
while retries < max_tries:
|
||||||
|
last_brick = removed_bricks[-1]
|
||||||
|
out = run_gluster(['volume', 'remove-brick', name, last_brick, 'status'])
|
||||||
|
for row in out.split('\n')[1:]:
|
||||||
|
if 'completed' in row:
|
||||||
|
# remove-brick successful, call commit operation.
|
||||||
|
args_c.append('commit')
|
||||||
|
out = run_gluster(args_c)
|
||||||
|
success = True
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
time.sleep(10)
|
||||||
|
if success:
|
||||||
|
break
|
||||||
|
retries += 1
|
||||||
|
if not success:
|
||||||
|
# remove-brick still in process, needs to be committed after completion.
|
||||||
|
module.fail_json(msg="Exceeded number of tries, check remove-brick status.\n"
|
||||||
|
"Commit operation needs to be followed.")
|
||||||
|
|
||||||
|
|
||||||
|
def reduce_config(name, removed_bricks, replicas, force):
|
||||||
|
out = run_gluster(['volume', 'heal', name, 'info'])
|
||||||
|
summary = out.split("\n")
|
||||||
|
for line in summary:
|
||||||
|
if 'Number' in line and int(line.split(":")[1].strip()) != 0:
|
||||||
|
module.fail_json(msg="Operation aborted, self-heal in progress.")
|
||||||
|
args = ['volume', 'remove-brick', name, 'replica', replicas]
|
||||||
|
args.extend(removed_bricks)
|
||||||
|
if force:
|
||||||
|
args.append('force')
|
||||||
|
else:
|
||||||
|
module.fail_json(msg="Force option is mandatory")
|
||||||
|
run_gluster(args)
|
||||||
|
|
||||||
|
|
||||||
def do_rebalance(name):
|
def do_rebalance(name):
|
||||||
run_gluster(['volume', 'rebalance', name, 'start'])
|
run_gluster(['volume', 'rebalance', name, 'start'])
|
||||||
|
|
||||||
|
@ -465,22 +539,31 @@ def main():
|
||||||
new_bricks = []
|
new_bricks = []
|
||||||
removed_bricks = []
|
removed_bricks = []
|
||||||
all_bricks = []
|
all_bricks = []
|
||||||
|
bricks_in_volume = volumes[volume_name]['bricks']
|
||||||
|
|
||||||
for node in cluster:
|
for node in cluster:
|
||||||
for brick_path in brick_paths:
|
for brick_path in brick_paths:
|
||||||
brick = '%s:%s' % (node, brick_path)
|
brick = '%s:%s' % (node, brick_path)
|
||||||
all_bricks.append(brick)
|
all_bricks.append(brick)
|
||||||
if brick not in volumes[volume_name]['bricks']:
|
if brick not in bricks_in_volume:
|
||||||
new_bricks.append(brick)
|
new_bricks.append(brick)
|
||||||
|
|
||||||
# this module does not yet remove bricks, but we check those anyways
|
if not new_bricks and len(all_bricks) < bricks_in_volume:
|
||||||
for brick in volumes[volume_name]['bricks']:
|
for brick in bricks_in_volume:
|
||||||
if brick not in all_bricks:
|
if brick not in all_bricks:
|
||||||
removed_bricks.append(brick)
|
removed_bricks.append(brick)
|
||||||
|
|
||||||
if new_bricks:
|
if new_bricks:
|
||||||
add_bricks(volume_name, new_bricks, stripes, replicas, force)
|
add_bricks(volume_name, new_bricks, stripes, replicas, force)
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
|
if removed_bricks:
|
||||||
|
if replicas and int(replicas) < int(volumes[volume_name]['replicas']):
|
||||||
|
reduce_config(volume_name, removed_bricks, str(replicas), force)
|
||||||
|
else:
|
||||||
|
remove_bricks(volume_name, removed_bricks, force)
|
||||||
|
changed = True
|
||||||
|
|
||||||
# handle quotas
|
# handle quotas
|
||||||
if quota:
|
if quota:
|
||||||
if not volumes[volume_name]['quota']:
|
if not volumes[volume_name]['quota']:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue