Refactor and improve swift-rings.py
We can simplify and refactor swift_rings.py and swift_rings_check.py by moving to a "FULL_HOST_KEY" model where we simply compare the full string, rather than individual elements. To do this we need to adjust the contents template to use the same field values as used by swift: * rename repl_ip to replication_ip * rename repl_port to replication_port Additionally, this allows us the ability to change port values on the fly, by adjusting the "DEVICE_KEY" to only be the IP and device name the port will now automatically get changed if the service port changes. This is a precursor to adjusting the default swift storage service ports to match upstream defaults, and will reduce the upgrade impact of that task. Change-Id: I704edcba4facb2170990ebec2a67d4179a023fc2
This commit is contained in:
parent
a7f0e1bd7c
commit
750ccaa9e8
@ -81,6 +81,11 @@ swift_middleware_list:
|
|||||||
|
|
||||||
## Swift default ports
|
## Swift default ports
|
||||||
swift_proxy_port: "8080"
|
swift_proxy_port: "8080"
|
||||||
|
# You can change the object, container, account ports.
|
||||||
|
# This will update the ring, on the next playbook run,
|
||||||
|
# without requiring a rebalance.
|
||||||
|
# NB: There is service downtime, during the run, between
|
||||||
|
# the service restart and the ring updating.
|
||||||
swift_object_port: "6000"
|
swift_object_port: "6000"
|
||||||
swift_container_port: "6001"
|
swift_container_port: "6001"
|
||||||
swift_account_port: "6002"
|
swift_account_port: "6002"
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Change the port for devices in the ring by adjusting
|
||||||
|
the port value for services, hosts, or devices. This
|
||||||
|
will not involve a rebalance of the ring.
|
||||||
|
- Changing the port for a device, or group of devices,
|
||||||
|
carries a brief period of downtime to the swift
|
||||||
|
storage services for those devices. The devices will
|
||||||
|
be unavailable during period between when the
|
||||||
|
storage service restarts after the port update, and
|
||||||
|
the ring updates to match the new port.
|
@ -87,8 +87,8 @@
|
|||||||
{% set _update = device.update({'weight': weight}) %}
|
{% set _update = device.update({'weight': weight}) %}
|
||||||
{% set _update = device.update({'region': region}) %}
|
{% set _update = device.update({'region': region}) %}
|
||||||
{% set _update = device.update({'zone': zone}) %}
|
{% set _update = device.update({'zone': zone}) %}
|
||||||
{% set _update = device.update({'repl_ip': repl_ip}) %}
|
{% set _update = device.update({'replication_ip': repl_ip}) %}
|
||||||
{% set _update = device.update({'repl_port': repl_port|int}) %}
|
{% set _update = device.update({'replication_port': repl_port|int}) %}
|
||||||
{% set _update = device.update({'ip': storage_ip}) %}
|
{% set _update = device.update({'ip': storage_ip}) %}
|
||||||
{% set _update = device.update({'port': storage_port|int}) %}
|
{% set _update = device.update({'port': storage_port|int}) %}
|
||||||
{### Append the device to the drives list of the builder dict #}
|
{### Append the device to the drives list of the builder dict #}
|
||||||
|
@ -27,7 +27,9 @@ import threading
|
|||||||
|
|
||||||
USAGE = "usage: %prog -f <swift_ring.contents> -r <managed_region>"
|
USAGE = "usage: %prog -f <swift_ring.contents> -r <managed_region>"
|
||||||
|
|
||||||
DEVICE_KEY = "%(ip)s:%(port)d/%(device)s"
|
DEVICE_KEY = "%(ip)s/%(device)s"
|
||||||
|
FULL_HOST_KEY = "%(ip)s:%(port)dR%(replication_ip)s:" \
|
||||||
|
"%(replication_port)d/%(device)s"
|
||||||
|
|
||||||
|
|
||||||
class RingValidationError(Exception):
|
class RingValidationError(Exception):
|
||||||
@ -82,28 +84,22 @@ def update_host_in_ring(build_file, new_host, old_host, validate=False):
|
|||||||
'be done when the drive is added' % devstr)
|
'be done when the drive is added' % devstr)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
r_ip = new_host.get('repl_ip', new_host['ip'])
|
old_host_str = FULL_HOST_KEY % old_host
|
||||||
r_port = new_host.get('repl_port', new_host['port'])
|
new_host_str = FULL_HOST_KEY % new_host
|
||||||
weight = new_host.get('weight')
|
|
||||||
|
|
||||||
old_r_ip = old_host['replication_ip']
|
new_weight = new_host.get('weight')
|
||||||
old_r_port = old_host['replication_port']
|
old_weight = old_host.get('weight')
|
||||||
|
|
||||||
if r_ip != old_r_ip or r_port != old_r_port:
|
if new_host_str != old_host_str:
|
||||||
host_d = {'r_ip': r_ip, 'r_port': r_port}
|
|
||||||
host_d.update(new_host)
|
|
||||||
host_str = (
|
|
||||||
"%(ip)s:%(port)dR%(r_ip)s:%(r_port)d/%(device)s" % host_d
|
|
||||||
)
|
|
||||||
if not validate:
|
if not validate:
|
||||||
run_and_wait(rb_main, ["swift-ring-builder", build_file,
|
run_and_wait(rb_main, ["swift-ring-builder", build_file,
|
||||||
"set_info", DEVICE_KEY % new_host,
|
"set_info", old_host_str,
|
||||||
host_str])
|
new_host_str])
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
raise RingValidationError(ex)
|
raise RingValidationError(ex)
|
||||||
|
|
||||||
if weight != old_host['weight'] and not validate:
|
if new_weight != old_weight and not validate:
|
||||||
change_host_weight(build_file, DEVICE_KEY % new_host, weight)
|
change_host_weight(build_file, FULL_HOST_KEY % new_host, new_weight)
|
||||||
|
|
||||||
|
|
||||||
def add_host_to_ring(build_file, host, validate=False):
|
def add_host_to_ring(build_file, host, validate=False):
|
||||||
@ -111,17 +107,8 @@ def add_host_to_ring(build_file, host, validate=False):
|
|||||||
try:
|
try:
|
||||||
if host.get('region') is not None:
|
if host.get('region') is not None:
|
||||||
host_str += 'r%(region)d' % host
|
host_str += 'r%(region)d' % host
|
||||||
host_str += "z%d" % (host.get('zone'))
|
host_str += "z%(zone)d-" % host
|
||||||
host_str += "-%(ip)s:%(port)d" % host
|
host_str += FULL_HOST_KEY % host
|
||||||
if host.get('repl_ip'):
|
|
||||||
r_ip = host['repl_ip']
|
|
||||||
r_port = host.get('repl_port', host['port'])
|
|
||||||
host_str += "R%s:%d" % (r_ip, r_port)
|
|
||||||
elif host.get('repl_port'):
|
|
||||||
r_ip = host.get('repl_ip', host['ip'])
|
|
||||||
r_port = host['repl_port']
|
|
||||||
host_str += "R%s:%d" % (r_ip, r_port)
|
|
||||||
host_str += "/%(device)s" % host
|
|
||||||
weight = host.get('weight')
|
weight = host.get('weight')
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
raise RingValidationError(ex)
|
raise RingValidationError(ex)
|
||||||
@ -203,6 +190,11 @@ def build_ring(build_name, repl, min_part_hours, part_power, hosts,
|
|||||||
run_and_wait(
|
run_and_wait(
|
||||||
rb_main, ["swift-ring-builder", build_file, "rebalance"]
|
rb_main, ["swift-ring-builder", build_file, "rebalance"]
|
||||||
)
|
)
|
||||||
|
# In case no changes that require a rebalance have happened
|
||||||
|
# We may still need to write the ring for device changes.
|
||||||
|
run_and_wait(
|
||||||
|
rb_main, ["swift-ring-builder", build_file, "write_ring"]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def main(setup, region, reset_mph_clock):
|
def main(setup, region, reset_mph_clock):
|
||||||
|
@ -24,6 +24,8 @@ import sys
|
|||||||
USAGE = "usage: %prog -f <swift_ring.contentsa> -r <managed_region>"
|
USAGE = "usage: %prog -f <swift_ring.contentsa> -r <managed_region>"
|
||||||
|
|
||||||
DEVICE_KEY = "%(ip)s:%(port)d/%(device)s"
|
DEVICE_KEY = "%(ip)s:%(port)d/%(device)s"
|
||||||
|
FULL_HOST_KEY = "%(ip)s:%(port)dR%(replication_ip)s:" \
|
||||||
|
"%(replication_port)d/%(device)s_w%(weight)d"
|
||||||
|
|
||||||
|
|
||||||
class RingComparisonError(Exception):
|
class RingComparisonError(Exception):
|
||||||
@ -69,21 +71,12 @@ def check_host_settings(content_host, ring_host):
|
|||||||
raise RingComparisonError('Region on device %s differs to the ring.'
|
raise RingComparisonError('Region on device %s differs to the ring.'
|
||||||
% devstr)
|
% devstr)
|
||||||
|
|
||||||
content_repl_ip = content_host.get('repl_ip', content_host['ip'])
|
content_host_str = FULL_HOST_KEY % content_host
|
||||||
content_repl_port = content_host.get('repl_port', content_host['port'])
|
ring_host_str = FULL_HOST_KEY % ring_host
|
||||||
content_weight = content_host.get('weight')
|
|
||||||
ring_repl_ip = ring_host['replication_ip']
|
if content_host_str != ring_host_str:
|
||||||
ring_repl_port = ring_host['replication_port']
|
raise RingComparisonError('Content device %(content_host_str)s differs'
|
||||||
ring_weight = ring_host['weight']
|
' to the ring device %(ring_host_str)s.')
|
||||||
if content_repl_ip != ring_repl_ip:
|
|
||||||
raise RingComparisonError('Replication IP for device %s differs '
|
|
||||||
'to the ring.' % devstr)
|
|
||||||
if content_repl_port != ring_repl_port:
|
|
||||||
raise RingComparisonError('Replication Port for device %s differs '
|
|
||||||
'to the ring.' % devstr)
|
|
||||||
if content_weight != ring_weight:
|
|
||||||
raise RingComparisonError('Device weight for device %s differs to the '
|
|
||||||
'ring.' % devstr)
|
|
||||||
|
|
||||||
|
|
||||||
def check_ring(build_name, repl, min_part_hours, part_power, content_hosts,
|
def check_ring(build_name, repl, min_part_hours, part_power, content_hosts,
|
||||||
|
Loading…
Reference in New Issue
Block a user