Optionally drop common prefixes in swift-*-info output

Add a --drop-prefixes flag to swift-account-info, swift-container-info,
and swift-object-info. This makes the output between the three more
consistent.

Change-Id: I98252ff74c4983eaad0a93d9a9fc527c74ffce68
This commit is contained in:
Tim Burke 2016-07-14 11:16:29 -05:00
parent 07a157f98e
commit f95befb37f
5 changed files with 78 additions and 18 deletions

View File

@ -38,6 +38,9 @@ if __name__ == '__main__':
parser.add_option( parser.add_option(
'-d', '--swift-dir', default='/etc/swift', '-d', '--swift-dir', default='/etc/swift',
help="Pass location of swift directory") help="Pass location of swift directory")
parser.add_option(
'--drop-prefixes', default=False, action="store_true",
help="When outputting metadata, drop the per-section common prefixes")
options, args = parser.parse_args() options, args = parser.parse_args()

View File

@ -38,6 +38,9 @@ if __name__ == '__main__':
parser.add_option( parser.add_option(
'-d', '--swift-dir', default='/etc/swift', '-d', '--swift-dir', default='/etc/swift',
help="Pass location of swift directory") help="Pass location of swift directory")
parser.add_option(
'--drop-prefixes', default=False, action="store_true",
help="When outputting metadata, drop the per-section common prefixes")
options, args = parser.parse_args() options, args = parser.parse_args()

View File

@ -29,6 +29,9 @@ if __name__ == '__main__':
parser.add_option( parser.add_option(
'-d', '--swift-dir', default='/etc/swift', dest='swift_dir', '-d', '--swift-dir', default='/etc/swift', dest='swift_dir',
help="Pass location of swift directory") help="Pass location of swift directory")
parser.add_option(
'--drop-prefixes', default=False, action="store_true",
help="When outputting metadata, drop the per-section common prefixes")
parser.add_option( parser.add_option(
'-P', '--policy-name', dest='policy_name', '-P', '--policy-name', dest='policy_name',
help="Specify storage policy name") help="Specify storage policy name")

View File

@ -23,7 +23,7 @@ from swift.common.utils import hash_path, storage_directory, \
from swift.common.ring import Ring from swift.common.ring import Ring
from swift.common.request_helpers import is_sys_meta, is_user_meta, \ from swift.common.request_helpers import is_sys_meta, is_user_meta, \
strip_sys_meta_prefix, strip_user_meta_prefix, \ strip_sys_meta_prefix, strip_user_meta_prefix, \
is_object_transient_sysmeta is_object_transient_sysmeta, strip_object_transient_sysmeta_prefix
from swift.account.backend import AccountBroker, DATADIR as ABDATADIR from swift.account.backend import AccountBroker, DATADIR as ABDATADIR
from swift.container.backend import ContainerBroker, DATADIR as CBDATADIR from swift.container.backend import ContainerBroker, DATADIR as CBDATADIR
from swift.obj.diskfile import get_data_dir, read_metadata, DATADIR_BASE, \ from swift.obj.diskfile import get_data_dir, read_metadata, DATADIR_BASE, \
@ -141,13 +141,17 @@ def print_ring_locations(ring, datadir, account, container=None, obj=None,
'real value is set in the config file on each storage node.') 'real value is set in the config file on each storage node.')
def print_db_info_metadata(db_type, info, metadata): def print_db_info_metadata(db_type, info, metadata, drop_prefixes=False):
""" """
print out data base info/metadata based on its type print out data base info/metadata based on its type
:param db_type: database type, account or container :param db_type: database type, account or container
:param info: dict of data base info :param info: dict of data base info
:param metadata: dict of data base metadata :param metadata: dict of data base metadata
:param drop_prefixes: if True, strip "X-Account-Meta-",
"X-Container-Meta-", "X-Account-Sysmeta-", and
"X-Container-Sysmeta-" when displaying
User Metadata and System Metadata dicts
""" """
if info is None: if info is None:
raise ValueError('DB info is None') raise ValueError('DB info is None')
@ -224,9 +228,13 @@ def print_db_info_metadata(db_type, info, metadata):
sys_metadata = {} sys_metadata = {}
for key, (value, timestamp) in metadata.items(): for key, (value, timestamp) in metadata.items():
if is_user_meta(db_type, key): if is_user_meta(db_type, key):
user_metadata[strip_user_meta_prefix(db_type, key)] = value if drop_prefixes:
key = strip_user_meta_prefix(db_type, key)
user_metadata[key] = value
elif is_sys_meta(db_type, key): elif is_sys_meta(db_type, key):
sys_metadata[strip_sys_meta_prefix(db_type, key)] = value if drop_prefixes:
key = strip_sys_meta_prefix(db_type, key)
sys_metadata[key] = value
else: else:
title = key.replace('_', '-').title() title = key.replace('_', '-').title()
print(' %s: %s' % (title, value)) print(' %s: %s' % (title, value))
@ -241,7 +249,7 @@ def print_db_info_metadata(db_type, info, metadata):
print('No user metadata found in db file') print('No user metadata found in db file')
def print_obj_metadata(metadata): def print_obj_metadata(metadata, drop_prefixes=False):
""" """
Print out basic info and metadata from object, as returned from Print out basic info and metadata from object, as returned from
:func:`swift.obj.diskfile.read_metadata`. :func:`swift.obj.diskfile.read_metadata`.
@ -252,6 +260,10 @@ def print_obj_metadata(metadata):
Additional metadata is displayed unmodified. Additional metadata is displayed unmodified.
:param metadata: dict of object metadata :param metadata: dict of object metadata
:param drop_prefixes: if True, strip "X-Object-Meta-", "X-Object-Sysmeta-",
and "X-Object-Transient-Sysmeta-" when displaying
User Metadata, System Metadata, and Transient
System Metadata entries
:raises: ValueError :raises: ValueError
""" """
@ -291,10 +303,16 @@ def print_obj_metadata(metadata):
for key, value in metadata.items(): for key, value in metadata.items():
if is_user_meta('Object', key): if is_user_meta('Object', key):
if drop_prefixes:
key = strip_user_meta_prefix('Object', key)
user_metadata[key] = value user_metadata[key] = value
elif is_sys_meta('Object', key): elif is_sys_meta('Object', key):
if drop_prefixes:
key = strip_sys_meta_prefix('Object', key)
sys_metadata[key] = value sys_metadata[key] = value
elif is_object_transient_sysmeta(key): elif is_object_transient_sysmeta(key):
if drop_prefixes:
key = strip_object_transient_sysmeta_prefix(key)
transient_sys_metadata[key] = value transient_sys_metadata[key] = value
else: else:
other_metadata[key] = value other_metadata[key] = value
@ -313,7 +331,8 @@ def print_obj_metadata(metadata):
print_metadata('Other Metadata:', other_metadata) print_metadata('Other Metadata:', other_metadata)
def print_info(db_type, db_file, swift_dir='/etc/swift', stale_reads_ok=False): def print_info(db_type, db_file, swift_dir='/etc/swift', stale_reads_ok=False,
drop_prefixes=False):
if db_type not in ('account', 'container'): if db_type not in ('account', 'container'):
print("Unrecognized DB type: internal error") print("Unrecognized DB type: internal error")
raise InfoSystemExit() raise InfoSystemExit()
@ -338,7 +357,7 @@ def print_info(db_type, db_file, swift_dir='/etc/swift', stale_reads_ok=False):
raise raise
account = info['account'] account = info['account']
container = info['container'] if db_type == 'container' else None container = info['container'] if db_type == 'container' else None
print_db_info_metadata(db_type, info, broker.metadata) print_db_info_metadata(db_type, info, broker.metadata, drop_prefixes)
try: try:
ring = Ring(swift_dir, ring_name=db_type) ring = Ring(swift_dir, ring_name=db_type)
except Exception: except Exception:
@ -348,7 +367,7 @@ def print_info(db_type, db_file, swift_dir='/etc/swift', stale_reads_ok=False):
def print_obj(datafile, check_etag=True, swift_dir='/etc/swift', def print_obj(datafile, check_etag=True, swift_dir='/etc/swift',
policy_name=''): policy_name='', drop_prefixes=False):
""" """
Display information about an object read from the datafile. Display information about an object read from the datafile.
Optionally verify the datafile content matches the ETag metadata. Optionally verify the datafile content matches the ETag metadata.
@ -359,6 +378,10 @@ def print_obj(datafile, check_etag=True, swift_dir='/etc/swift',
metadata. metadata.
:param swift_dir: the path on disk to rings :param swift_dir: the path on disk to rings
:param policy_name: optionally the name to use when finding the ring :param policy_name: optionally the name to use when finding the ring
:param drop_prefixes: if True, strip "X-Object-Meta-", "X-Object-Sysmeta-",
and "X-Object-Transient-Sysmeta-" when displaying
User Metadata, System Metadata, and Transient
System Metadata entries
""" """
if not os.path.exists(datafile): if not os.path.exists(datafile):
print("Data file doesn't exist") print("Data file doesn't exist")
@ -408,7 +431,7 @@ def print_obj(datafile, check_etag=True, swift_dir='/etc/swift',
etag = metadata.pop('ETag', '') etag = metadata.pop('ETag', '')
length = metadata.pop('Content-Length', '') length = metadata.pop('Content-Length', '')
path = metadata.get('name', '') path = metadata.get('name', '')
print_obj_metadata(metadata) print_obj_metadata(metadata, drop_prefixes)
# Optional integrity check; it's useful, but slow. # Optional integrity check; it's useful, but slow.
file_len = None file_len = None

View File

@ -127,7 +127,7 @@ Metadata:
UUID: abadf100d0ddba11 UUID: abadf100d0ddba11
X-Other-Something: boo X-Other-Something: boo
No system metadata found in db file No system metadata found in db file
User Metadata: {'mydata': 'swift'}''' User Metadata: {'x-account-meta-mydata': 'swift'}'''
self.assertEqual(sorted(out.getvalue().strip().split('\n')), self.assertEqual(sorted(out.getvalue().strip().split('\n')),
sorted(exp_out.split('\n'))) sorted(exp_out.split('\n')))
@ -153,7 +153,7 @@ No system metadata found in db file
md = {'x-container-sysmeta-mydata': ('swift', '0000000000.00000')} md = {'x-container-sysmeta-mydata': ('swift', '0000000000.00000')}
out = StringIO() out = StringIO()
with mock.patch('sys.stdout', out): with mock.patch('sys.stdout', out):
print_db_info_metadata('container', info, md) print_db_info_metadata('container', info, md, True)
exp_out = '''Path: /acct/cont exp_out = '''Path: /acct/cont
Account: acct Account: acct
Container: cont Container: cont
@ -667,7 +667,7 @@ Other Metadata:
}) })
out = StringIO() out = StringIO()
with mock.patch('sys.stdout', out): with mock.patch('sys.stdout', out):
print_obj_metadata(metadata) print_obj_metadata(metadata, True)
exp_out = '''Path: /AUTH_admin/c/dummy exp_out = '''Path: /AUTH_admin/c/dummy
Account: AUTH_admin Account: AUTH_admin
Container: c Container: c
@ -676,8 +676,8 @@ Other Metadata:
Content-Type: application/octet-stream Content-Type: application/octet-stream
Timestamp: 1970-01-01T00:01:46.300000 (%s) Timestamp: 1970-01-01T00:01:46.300000 (%s)
System Metadata: System Metadata:
X-Object-Sysmeta-Mtime: 107.3 Mtime: 107.3
X-Object-Sysmeta-Name: Obj name Name: Obj name
Transient System Metadata: Transient System Metadata:
No metadata found No metadata found
User Metadata: User Metadata:
@ -747,7 +747,7 @@ Other Metadata:
del metadata['name'] del metadata['name']
out = StringIO() out = StringIO()
with mock.patch('sys.stdout', out): with mock.patch('sys.stdout', out):
print_obj_metadata(metadata) print_obj_metadata(metadata, True)
exp_out = '''Path: Not found in metadata exp_out = '''Path: Not found in metadata
Content-Type: application/octet-stream Content-Type: application/octet-stream
Timestamp: 1970-01-01T00:01:46.300000 (%s) Timestamp: 1970-01-01T00:01:46.300000 (%s)
@ -756,7 +756,7 @@ System Metadata:
Transient System Metadata: Transient System Metadata:
No metadata found No metadata found
User Metadata: User Metadata:
X-Object-Meta-Mtime: 107.3 Mtime: 107.3
Other Metadata: Other Metadata:
No metadata found''' % ( No metadata found''' % (
utils.Timestamp(106.3).internal) utils.Timestamp(106.3).internal)
@ -791,7 +791,7 @@ Other Metadata:
del metadata['X-Timestamp'] del metadata['X-Timestamp']
out = StringIO() out = StringIO()
with mock.patch('sys.stdout', out): with mock.patch('sys.stdout', out):
print_obj_metadata(metadata) print_obj_metadata(metadata, True)
exp_out = '''Path: /AUTH_admin/c/dummy exp_out = '''Path: /AUTH_admin/c/dummy
Account: AUTH_admin Account: AUTH_admin
Container: c Container: c
@ -804,7 +804,7 @@ System Metadata:
Transient System Metadata: Transient System Metadata:
No metadata found No metadata found
User Metadata: User Metadata:
X-Object-Meta-Mtime: 107.3 Mtime: 107.3
Other Metadata: Other Metadata:
No metadata found''' No metadata found'''
@ -838,6 +838,34 @@ Other Metadata:
self.assertEqual(out.getvalue().strip(), exp_out) self.assertEqual(out.getvalue().strip(), exp_out)
metadata = get_metadata({
'X-Object-Meta-Mtime': '107.3',
'X-Object-Sysmeta-Mtime': '106.3',
'X-Object-Transient-Sysmeta-Mtime': '105.3',
'X-Object-Mtime': '104.3',
})
out = StringIO()
with mock.patch('sys.stdout', out):
print_obj_metadata(metadata, True)
exp_out = '''Path: /AUTH_admin/c/dummy
Account: AUTH_admin
Container: c
Object: dummy
Object hash: 128fdf98bddd1b1e8695f4340e67a67a
Content-Type: application/octet-stream
Timestamp: 1970-01-01T00:01:46.300000 (%s)
System Metadata:
Mtime: 106.3
Transient System Metadata:
Mtime: 105.3
User Metadata:
Mtime: 107.3
Other Metadata:
X-Object-Mtime: 104.3''' % (
utils.Timestamp(106.3).internal)
self.assertEqual(out.getvalue().strip(), exp_out)
class TestPrintObjWeirdPath(TestPrintObjFullMeta): class TestPrintObjWeirdPath(TestPrintObjFullMeta):
def setUp(self): def setUp(self):