Skip to content

Instantly share code, notes, and snippets.

@clayg
Created June 27, 2016 22:23
Show Gist options
  • Save clayg/f6f33b210e89ed550aa62d473ac16b7c to your computer and use it in GitHub Desktop.
Save clayg/f6f33b210e89ed550aa62d473ac16b7c to your computer and use it in GitHub Desktop.
diff --git a/bin/swift-get-nodes b/bin/swift-get-nodes
index f2e3046..0e9eea9 100755
--- a/bin/swift-get-nodes
+++ b/bin/swift-get-nodes
@@ -19,7 +19,8 @@ import os
from optparse import OptionParser
from swift.common.ring import Ring
-from swift.cli.info import print_item_locations, InfoSystemExit
+from swift.cli.info import (parse_get_node_args, print_item_locations,
+ InfoSystemExit)
if __name__ == '__main__':
@@ -50,32 +51,17 @@ if __name__ == '__main__':
dest='swift_dir', help='Path to swift directory')
options, args = parser.parse_args()
- # swift-get-nodes -P nada -p 1
- if len(args) == 0:
- if not options.policy_name or not options.partition:
- sys.exit(parser.print_help())
- elif len(args) > 4 or len(args) == 0:
- sys.exit(parser.print_help())
-
- # Parse single path arg, as noted in above help text.
- # if len(args) == 1 and options.policy_name and '/' in args[0]:
- if len(args) == 1 and not args[0].endswith('ring.gz'):
- path = args[0].lstrip('/')
- args = [p for p in path.split('/', 2) if p]
- if len(args) == 2 and '/' in args[1]:
- path = args[1].lstrip('/')
- args = [args[0]] + [p for p in path.split('/', 2) if p]
-
- ring = None
- ring_name = None
+ try:
+ ring_path, args = parse_get_node_args(options, args)
+ except InfoSystemExit as e:
+ sys.exit(parser.print_help() + '\nERROR: %s' % e)
- if options.policy_name is None and len(args) >= 1:
- if os.path.exists(args[0]) and args[0].endswith('ring.gz'):
- ring_name = args[0].rsplit('/', 1)[-1].split('.', 1)[0]
- ring = Ring(args[0])
- args.pop(0)
- else:
- sys.exit('Ring file does not exist')
+ ring = ring_name = None
+ if ring_path:
+ # it's really strange that print_items wants both of these args, but
+ # can also calculate the ring from the policy_name kwarg?!
+ ring_name = ring_path.rsplit('/', 1)[-1].split('.', 1)[0]
+ ring = Ring(ring_path)
try:
print_item_locations(ring, ring_name, *args, **vars(options))
diff --git a/swift/cli/info.py b/swift/cli/info.py
index c5dda94..4c8dc3b 100644
--- a/swift/cli/info.py
+++ b/swift/cli/info.py
@@ -37,6 +37,39 @@ class InfoSystemExit(Exception):
pass
+def parse_get_node_args(options, args):
+ """
+ Parse the get_nodes commandline args
+
+ :returns: a tuple, (ring_path, args)
+ """
+ # swift-get-nodes -P nada -p 1
+ if len(args) == 0:
+ if not options.policy_name or not options.partition:
+ raise InfoSystemExit('Need to specify policy_name or <ring.gz>')
+ elif len(args) > 4 or len(args) == 0:
+ raise InfoSystemExit('Invalid arguments')
+
+ # Parse single path arg, as noted in above help text.
+ # if len(args) == 1 and options.policy_name and '/' in args[0]:
+ if len(args) == 1 and not args[0].endswith('ring.gz'):
+ path = args[0].lstrip('/')
+ args = [p for p in path.split('/', 2) if p]
+ if len(args) == 2 and '/' in args[1]:
+ path = args[1].lstrip('/')
+ args = [args[0]] + [p for p in path.split('/', 2) if p]
+
+ ring_path = None
+
+ if options.policy_name is None and len(args) >= 1:
+ if os.path.exists(args[0]) and args[0].endswith('ring.gz'):
+ ring_path = args.pop(0)
+ else:
+ raise InfoSystemExit('Ring file does not exist')
+
+ return ring_path, args
+
+
def print_ring_locations(ring, datadir, account, container=None, obj=None,
tpart=None, all_nodes=False, policy_index=None):
"""
diff --git a/test/unit/cli/test_info.py b/test/unit/cli/test_info.py
index a97362d..405f23d 100644
--- a/test/unit/cli/test_info.py
+++ b/test/unit/cli/test_info.py
@@ -12,6 +12,7 @@
"""Tests for swift.cli.info"""
+from argparse import Namespace
import os
import unittest
import mock
@@ -26,7 +27,7 @@ from swift.common.swob import Request
from swift.common.storage_policy import StoragePolicy, POLICIES
from swift.cli.info import print_db_info_metadata, print_ring_locations, \
print_info, print_obj_metadata, print_obj, InfoSystemExit, \
- print_item_locations
+ print_item_locations, parse_get_node_args
from swift.account.server import AccountController
from swift.container.server import ContainerController
from swift.obj.diskfile import write_metadata
@@ -476,6 +477,34 @@ No user metadata found in db file''' % POLICIES[0].name
else:
self.fail("Expected an InfoSystemExit exception to be raised")
+ def test_parse_get_node_args(self):
+ # -P test a c o
+ options = Namespace(policy_name='test')
+ args = 'a c o'
+ ring_path, args = parse_get_node_args(options, args.split())
+ self.assertEqual(ring_path, None)
+ self.assertEqual(args, ['a', 'c', 'o'])
+ # objects.ring.gz /a/c/o
+ options = Namespace(policy_name=None)
+ args = 'object.ring.gz /a/c/o'
+ with mock.patch('swift.cli.info.os.path.exists', lambda p: True):
+ ring_path, args = parse_get_node_args(options, args.split())
+ self.assertEqual(ring_path, 'object.ring.gz')
+ self.assertEqual(args, ['a', 'c', 'o'])
+ # objects.ring.gz a c o
+ options = Namespace(policy_name=None)
+ args = 'object.ring.gz a c o'
+ with mock.patch('swift.cli.info.os.path.exists', lambda p: True):
+ ring_path, args = parse_get_node_args(options, args.split())
+ self.assertEqual(ring_path, 'object.ring.gz')
+ self.assertEqual(args, ['a', 'c', 'o'])
+ # -P test -p 1
+ options = Namespace(policy_name='test', partition='1')
+ args = ''
+ ring_path, args = parse_get_node_args(options, args.split())
+ self.assertEqual(ring_path, None)
+ self.assertEqual(args, [])
+
class TestPrintObj(TestCliInfoBase):
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment