Add policy support to dispersion tools
Doesn't work for anything other than policy 0. updated to allow user to specify policy name on cmd line (as with object-info) which then makes populate/report work with 3x, 2x, or EC style policies Change-Id: Ib7c298f0f6d666b1ecca25315b88539f45cf9f95 Closes-Bug: 1458688
This commit is contained in:
parent
e9a032f896
commit
e6165a7879
@ -31,16 +31,17 @@ except ImportError:
|
|||||||
from swift.common.internal_client import SimpleClient
|
from swift.common.internal_client import SimpleClient
|
||||||
from swift.common.ring import Ring
|
from swift.common.ring import Ring
|
||||||
from swift.common.utils import compute_eta, get_time_units, config_true_value
|
from swift.common.utils import compute_eta, get_time_units, config_true_value
|
||||||
|
from swift.common.storage_policy import POLICIES
|
||||||
|
|
||||||
|
|
||||||
insecure = False
|
insecure = False
|
||||||
|
|
||||||
|
|
||||||
def put_container(connpool, container, report):
|
def put_container(connpool, container, report, headers):
|
||||||
global retries_done
|
global retries_done
|
||||||
try:
|
try:
|
||||||
with connpool.item() as conn:
|
with connpool.item() as conn:
|
||||||
conn.put_container(container)
|
conn.put_container(container, headers=headers)
|
||||||
retries_done += conn.attempts - 1
|
retries_done += conn.attempts - 1
|
||||||
if report:
|
if report:
|
||||||
report(True)
|
report(True)
|
||||||
@ -105,6 +106,9 @@ Usage: %%prog [options] [conf_file]
|
|||||||
help='No overlap of partitions if running populate \
|
help='No overlap of partitions if running populate \
|
||||||
more than once. Will increase coverage by amount shown \
|
more than once. Will increase coverage by amount shown \
|
||||||
in dispersion.conf file')
|
in dispersion.conf file')
|
||||||
|
parser.add_option('-P', '--policy-name', dest='policy_name',
|
||||||
|
help="Specify storage policy name")
|
||||||
|
|
||||||
options, args = parser.parse_args()
|
options, args = parser.parse_args()
|
||||||
|
|
||||||
if args:
|
if args:
|
||||||
@ -114,6 +118,15 @@ Usage: %%prog [options] [conf_file]
|
|||||||
if not c.read(conffile):
|
if not c.read(conffile):
|
||||||
exit('Unable to read config file: %s' % conffile)
|
exit('Unable to read config file: %s' % conffile)
|
||||||
conf = dict(c.items('dispersion'))
|
conf = dict(c.items('dispersion'))
|
||||||
|
|
||||||
|
if options.policy_name is None:
|
||||||
|
policy = POLICIES.default
|
||||||
|
else:
|
||||||
|
policy = POLICIES.get_by_name(options.policy_name)
|
||||||
|
if policy is None:
|
||||||
|
exit('Unable to find policy: %s' % options.policy_name)
|
||||||
|
print 'Using storage policy: %s ' % policy.name
|
||||||
|
|
||||||
swift_dir = conf.get('swift_dir', '/etc/swift')
|
swift_dir = conf.get('swift_dir', '/etc/swift')
|
||||||
dispersion_coverage = float(conf.get('dispersion_coverage', 1))
|
dispersion_coverage = float(conf.get('dispersion_coverage', 1))
|
||||||
retries = int(conf.get('retries', 5))
|
retries = int(conf.get('retries', 5))
|
||||||
@ -141,6 +154,8 @@ Usage: %%prog [options] [conf_file]
|
|||||||
insecure=insecure)
|
insecure=insecure)
|
||||||
account = url.rsplit('/', 1)[1]
|
account = url.rsplit('/', 1)[1]
|
||||||
connpool = Pool(max_size=concurrency)
|
connpool = Pool(max_size=concurrency)
|
||||||
|
headers = {}
|
||||||
|
headers['X-Storage-Policy'] = policy.name
|
||||||
connpool.create = lambda: SimpleClient(
|
connpool.create = lambda: SimpleClient(
|
||||||
url=url, token=token, retries=retries)
|
url=url, token=token, retries=retries)
|
||||||
|
|
||||||
@ -152,7 +167,7 @@ Usage: %%prog [options] [conf_file]
|
|||||||
if options.no_overlap:
|
if options.no_overlap:
|
||||||
with connpool.item() as conn:
|
with connpool.item() as conn:
|
||||||
containers = [cont['name'] for cont in conn.get_account(
|
containers = [cont['name'] for cont in conn.get_account(
|
||||||
prefix='dispersion_', full_listing=True)[1]]
|
prefix='dispersion_%d' % policy.idx, full_listing=True)[1]]
|
||||||
containers_listed = len(containers)
|
containers_listed = len(containers)
|
||||||
if containers_listed > 0:
|
if containers_listed > 0:
|
||||||
for container in containers:
|
for container in containers:
|
||||||
@ -170,11 +185,12 @@ Usage: %%prog [options] [conf_file]
|
|||||||
next_report += 2
|
next_report += 2
|
||||||
suffix = 0
|
suffix = 0
|
||||||
while need_to_queue >= 1 and parts_left:
|
while need_to_queue >= 1 and parts_left:
|
||||||
container = 'dispersion_%d' % suffix
|
container = 'dispersion_%d_%d' % (policy.idx, suffix)
|
||||||
part = container_ring.get_part(account, container)
|
part = container_ring.get_part(account, container)
|
||||||
if part in parts_left:
|
if part in parts_left:
|
||||||
if suffix >= options.container_suffix_start:
|
if suffix >= options.container_suffix_start:
|
||||||
coropool.spawn(put_container, connpool, container, report)
|
coropool.spawn(put_container, connpool, container, report,
|
||||||
|
headers)
|
||||||
sleep()
|
sleep()
|
||||||
else:
|
else:
|
||||||
report(True)
|
report(True)
|
||||||
@ -195,9 +211,9 @@ Usage: %%prog [options] [conf_file]
|
|||||||
stdout.flush()
|
stdout.flush()
|
||||||
|
|
||||||
if object_populate:
|
if object_populate:
|
||||||
container = 'dispersion_objects'
|
container = 'dispersion_objects_%d' % policy.idx
|
||||||
put_container(connpool, container, None)
|
put_container(connpool, container, None, headers)
|
||||||
object_ring = Ring(swift_dir, ring_name='object')
|
object_ring = Ring(swift_dir, ring_name=policy.ring_name)
|
||||||
parts_left = dict((x, x) for x in xrange(object_ring.partition_count))
|
parts_left = dict((x, x) for x in xrange(object_ring.partition_count))
|
||||||
|
|
||||||
if options.no_overlap:
|
if options.no_overlap:
|
||||||
|
@ -36,6 +36,7 @@ from swift.common.internal_client import SimpleClient
|
|||||||
from swift.common.ring import Ring
|
from swift.common.ring import Ring
|
||||||
from swift.common.exceptions import ClientException
|
from swift.common.exceptions import ClientException
|
||||||
from swift.common.utils import compute_eta, get_time_units, config_true_value
|
from swift.common.utils import compute_eta, get_time_units, config_true_value
|
||||||
|
from swift.common.storage_policy import POLICIES
|
||||||
|
|
||||||
|
|
||||||
unmounted = []
|
unmounted = []
|
||||||
@ -73,10 +74,10 @@ def get_error_log(prefix):
|
|||||||
|
|
||||||
|
|
||||||
def container_dispersion_report(coropool, connpool, account, container_ring,
|
def container_dispersion_report(coropool, connpool, account, container_ring,
|
||||||
retries, output_missing_partitions):
|
retries, output_missing_partitions, policy):
|
||||||
with connpool.item() as conn:
|
with connpool.item() as conn:
|
||||||
containers = [c['name'] for c in conn.get_account(
|
containers = [c['name'] for c in conn.get_account(
|
||||||
prefix='dispersion_', full_listing=True)[1]]
|
prefix='dispersion_%d' % policy.idx, full_listing=True)[1]]
|
||||||
containers_listed = len(containers)
|
containers_listed = len(containers)
|
||||||
if not containers_listed:
|
if not containers_listed:
|
||||||
print >>stderr, 'No containers to query. Has ' \
|
print >>stderr, 'No containers to query. Has ' \
|
||||||
@ -169,8 +170,8 @@ def container_dispersion_report(coropool, connpool, account, container_ring,
|
|||||||
|
|
||||||
|
|
||||||
def object_dispersion_report(coropool, connpool, account, object_ring,
|
def object_dispersion_report(coropool, connpool, account, object_ring,
|
||||||
retries, output_missing_partitions):
|
retries, output_missing_partitions, policy):
|
||||||
container = 'dispersion_objects'
|
container = 'dispersion_objects_%d' % policy.idx
|
||||||
with connpool.item() as conn:
|
with connpool.item() as conn:
|
||||||
try:
|
try:
|
||||||
objects = [o['name'] for o in conn.get_container(
|
objects = [o['name'] for o in conn.get_container(
|
||||||
@ -196,6 +197,11 @@ def object_dispersion_report(coropool, connpool, account, object_ring,
|
|||||||
begun = time()
|
begun = time()
|
||||||
next_report = [time() + 2]
|
next_report = [time() + 2]
|
||||||
|
|
||||||
|
headers = None
|
||||||
|
if policy is not None:
|
||||||
|
headers = {}
|
||||||
|
headers['X-Backend-Storage-Policy-Index'] = int(policy)
|
||||||
|
|
||||||
def direct(obj, part, nodes):
|
def direct(obj, part, nodes):
|
||||||
found_count = 0
|
found_count = 0
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
@ -203,7 +209,8 @@ def object_dispersion_report(coropool, connpool, account, object_ring,
|
|||||||
try:
|
try:
|
||||||
attempts, _junk = direct_client.retry(
|
attempts, _junk = direct_client.retry(
|
||||||
direct_client.direct_head_object, node, part, account,
|
direct_client.direct_head_object, node, part, account,
|
||||||
container, obj, error_log=error_log, retries=retries)
|
container, obj, error_log=error_log, retries=retries,
|
||||||
|
headers=headers)
|
||||||
retries_done[0] += attempts - 1
|
retries_done[0] += attempts - 1
|
||||||
found_count += 1
|
found_count += 1
|
||||||
except ClientException as err:
|
except ClientException as err:
|
||||||
@ -290,9 +297,9 @@ def missing_string(partition_count, missing_copies, copy_count):
|
|||||||
verb_string = 'were'
|
verb_string = 'were'
|
||||||
partition_string = 'partitions'
|
partition_string = 'partitions'
|
||||||
|
|
||||||
copy_string = 'copy'
|
copy_string = 'copies'
|
||||||
if missing_copies > 1:
|
if missing_copies == 1:
|
||||||
copy_string = 'copies'
|
copy_string = 'copy'
|
||||||
|
|
||||||
return '%sThere %s %d %s missing %s %s.' % (
|
return '%sThere %s %d %s missing %s %s.' % (
|
||||||
exclamations, verb_string, partition_count, partition_string,
|
exclamations, verb_string, partition_count, partition_string,
|
||||||
@ -323,6 +330,9 @@ Usage: %%prog [options] [conf_file]
|
|||||||
parser.add_option('--insecure', action='store_true', default=False,
|
parser.add_option('--insecure', action='store_true', default=False,
|
||||||
help='Allow accessing insecure keystone server. '
|
help='Allow accessing insecure keystone server. '
|
||||||
'The keystone\'s certificate will not be verified.')
|
'The keystone\'s certificate will not be verified.')
|
||||||
|
parser.add_option('-P', '--policy-name', dest='policy_name',
|
||||||
|
help="Specify storage policy name")
|
||||||
|
|
||||||
options, args = parser.parse_args()
|
options, args = parser.parse_args()
|
||||||
|
|
||||||
if args:
|
if args:
|
||||||
@ -332,6 +342,15 @@ Usage: %%prog [options] [conf_file]
|
|||||||
if not c.read(conffile):
|
if not c.read(conffile):
|
||||||
exit('Unable to read config file: %s' % conffile)
|
exit('Unable to read config file: %s' % conffile)
|
||||||
conf = dict(c.items('dispersion'))
|
conf = dict(c.items('dispersion'))
|
||||||
|
|
||||||
|
if options.policy_name is None:
|
||||||
|
policy = POLICIES.default
|
||||||
|
else:
|
||||||
|
policy = POLICIES.get_by_name(options.policy_name)
|
||||||
|
if policy is None:
|
||||||
|
exit('Unable to find policy: %s' % options.policy_name)
|
||||||
|
print 'Using storage policy: %s ' % policy.name
|
||||||
|
|
||||||
swift_dir = conf.get('swift_dir', '/etc/swift')
|
swift_dir = conf.get('swift_dir', '/etc/swift')
|
||||||
retries = int(conf.get('retries', 5))
|
retries = int(conf.get('retries', 5))
|
||||||
concurrency = int(conf.get('concurrency', 25))
|
concurrency = int(conf.get('concurrency', 25))
|
||||||
@ -364,16 +383,16 @@ Usage: %%prog [options] [conf_file]
|
|||||||
url=url, token=token, retries=retries)
|
url=url, token=token, retries=retries)
|
||||||
|
|
||||||
container_ring = Ring(swift_dir, ring_name='container')
|
container_ring = Ring(swift_dir, ring_name='container')
|
||||||
object_ring = Ring(swift_dir, ring_name='object')
|
object_ring = Ring(swift_dir, ring_name=policy.ring_name)
|
||||||
|
|
||||||
output = {}
|
output = {}
|
||||||
if container_report:
|
if container_report:
|
||||||
output['container'] = container_dispersion_report(
|
output['container'] = container_dispersion_report(
|
||||||
coropool, connpool, account, container_ring, retries,
|
coropool, connpool, account, container_ring, retries,
|
||||||
options.partitions)
|
options.partitions, policy)
|
||||||
if object_report:
|
if object_report:
|
||||||
output['object'] = object_dispersion_report(
|
output['object'] = object_dispersion_report(
|
||||||
coropool, connpool, account, object_ring, retries,
|
coropool, connpool, account, object_ring, retries,
|
||||||
options.partitions)
|
options.partitions, policy)
|
||||||
if json_output:
|
if json_output:
|
||||||
print json.dumps(output)
|
print json.dumps(output)
|
||||||
|
@ -339,6 +339,12 @@ allows it to be more easily consumed by third party utilities::
|
|||||||
$ swift-dispersion-report -j
|
$ swift-dispersion-report -j
|
||||||
{"object": {"retries:": 0, "missing_two": 0, "copies_found": 7863, "missing_one": 0, "copies_expected": 7863, "pct_found": 100.0, "overlapping": 0, "missing_all": 0}, "container": {"retries:": 0, "missing_two": 0, "copies_found": 12534, "missing_one": 0, "copies_expected": 12534, "pct_found": 100.0, "overlapping": 15, "missing_all": 0}}
|
{"object": {"retries:": 0, "missing_two": 0, "copies_found": 7863, "missing_one": 0, "copies_expected": 7863, "pct_found": 100.0, "overlapping": 0, "missing_all": 0}, "container": {"retries:": 0, "missing_two": 0, "copies_found": 12534, "missing_one": 0, "copies_expected": 12534, "pct_found": 100.0, "overlapping": 15, "missing_all": 0}}
|
||||||
|
|
||||||
|
Note that you may select which storage policy to use by setting the option
|
||||||
|
'--policy-name silver' or '-P silver' (silver is the example policy name here).
|
||||||
|
If no policy is specified, the default will be used per the swift.conf file.
|
||||||
|
When you specify a policy the containers created also include the policy index,
|
||||||
|
thus even when running a container_only report, you will need to specify the
|
||||||
|
policy not using the default.
|
||||||
|
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
Geographically Distributed Clusters
|
Geographically Distributed Clusters
|
||||||
|
Loading…
Reference in New Issue
Block a user