Fix pep8 violations.
Change-Id: I12e304c567b92178e193c60599c3be606cc70d38
This commit is contained in:
parent
826319befd
commit
cf3f671a05
|
@ -18,11 +18,11 @@ from keystone import cli
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
dev_conf = os.path.join(possible_topdir,
|
||||
'etc',
|
||||
'keystone.conf')
|
||||
config_files = None
|
||||
if os.path.exists(dev_conf):
|
||||
config_files = [dev_conf]
|
||||
dev_conf = os.path.join(possible_topdir,
|
||||
'etc',
|
||||
'keystone.conf')
|
||||
config_files = None
|
||||
if os.path.exists(dev_conf):
|
||||
config_files = [dev_conf]
|
||||
|
||||
cli.main(argv=sys.argv, config_files=config_files)
|
||||
cli.main(argv=sys.argv, config_files=config_files)
|
||||
|
|
463
keystone/cli.py
463
keystone/cli.py
|
@ -33,316 +33,317 @@ config.register_cli_bool('id-only',
|
|||
|
||||
|
||||
class BaseApp(cli.log.LoggingApp):
|
||||
def __init__(self, *args, **kw):
|
||||
kw.setdefault('name', self.__class__.__name__.lower())
|
||||
super(BaseApp, self).__init__(*args, **kw)
|
||||
def __init__(self, *args, **kw):
|
||||
kw.setdefault('name', self.__class__.__name__.lower())
|
||||
super(BaseApp, self).__init__(*args, **kw)
|
||||
|
||||
def add_default_params(self):
|
||||
for args, kw in DEFAULT_PARAMS:
|
||||
self.add_param(*args, **kw)
|
||||
def add_default_params(self):
|
||||
for args, kw in DEFAULT_PARAMS:
|
||||
self.add_param(*args, **kw)
|
||||
|
||||
def _parse_keyvalues(self, args):
|
||||
kv = {}
|
||||
for x in args:
|
||||
key, value = x.split('=', 1)
|
||||
# make lists if there are multiple values
|
||||
if key.endswith('[]'):
|
||||
key = key[:-2]
|
||||
existing = kv.get(key, [])
|
||||
existing.append(value)
|
||||
kv[key] = existing
|
||||
else:
|
||||
kv[key] = value
|
||||
return kv
|
||||
def _parse_keyvalues(self, args):
|
||||
kv = {}
|
||||
for x in args:
|
||||
key, value = x.split('=', 1)
|
||||
# make lists if there are multiple values
|
||||
if key.endswith('[]'):
|
||||
key = key[:-2]
|
||||
existing = kv.get(key, [])
|
||||
existing.append(value)
|
||||
kv[key] = existing
|
||||
else:
|
||||
kv[key] = value
|
||||
return kv
|
||||
|
||||
|
||||
class DbSync(BaseApp):
|
||||
"""Sync the database."""
|
||||
"""Sync the database."""
|
||||
|
||||
name = 'db_sync'
|
||||
name = 'db_sync'
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
super(DbSync, self).__init__(*args, **kw)
|
||||
def __init__(self, *args, **kw):
|
||||
super(DbSync, self).__init__(*args, **kw)
|
||||
|
||||
def main(self):
|
||||
for k in ['identity', 'catalog', 'policy', 'token']:
|
||||
driver = utils.import_object(getattr(CONF, k).driver)
|
||||
if hasattr(driver, 'db_sync'):
|
||||
driver.db_sync()
|
||||
def main(self):
|
||||
for k in ['identity', 'catalog', 'policy', 'token']:
|
||||
driver = utils.import_object(getattr(CONF, k).driver)
|
||||
if hasattr(driver, 'db_sync'):
|
||||
driver.db_sync()
|
||||
|
||||
|
||||
class ClientCommand(BaseApp):
|
||||
ACTION_MAP = None
|
||||
ACTION_MAP = None
|
||||
|
||||
def _attr_name(self):
|
||||
return '%ss' % self.__class__.__name__.lower()
|
||||
def _attr_name(self):
|
||||
return '%ss' % self.__class__.__name__.lower()
|
||||
|
||||
def _cmd_name(self):
|
||||
return self.__class__.__name__.lower()
|
||||
def _cmd_name(self):
|
||||
return self.__class__.__name__.lower()
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
super(ClientCommand, self).__init__(*args, **kw)
|
||||
if not self.ACTION_MAP:
|
||||
self.ACTION_MAP = {'help': 'help'}
|
||||
self.add_param('action', nargs='?', default='help')
|
||||
self.add_param('keyvalues', nargs='*')
|
||||
self.client = kc.Client(CONF.endpoint, token=CONF.auth_token)
|
||||
self.handle = getattr(self.client, self._attr_name())
|
||||
self._build_action_map()
|
||||
def __init__(self, *args, **kw):
|
||||
super(ClientCommand, self).__init__(*args, **kw)
|
||||
if not self.ACTION_MAP:
|
||||
self.ACTION_MAP = {'help': 'help'}
|
||||
self.add_param('action', nargs='?', default='help')
|
||||
self.add_param('keyvalues', nargs='*')
|
||||
self.client = kc.Client(CONF.endpoint, token=CONF.auth_token)
|
||||
self.handle = getattr(self.client, self._attr_name())
|
||||
self._build_action_map()
|
||||
|
||||
def _build_action_map(self):
|
||||
actions = {}
|
||||
for k in dir(self.handle):
|
||||
if not k.startswith('_'):
|
||||
actions[k] = k
|
||||
self.ACTION_MAP.update(actions)
|
||||
def _build_action_map(self):
|
||||
actions = {}
|
||||
for k in dir(self.handle):
|
||||
if not k.startswith('_'):
|
||||
actions[k] = k
|
||||
self.ACTION_MAP.update(actions)
|
||||
|
||||
def main(self):
|
||||
"""Given some keyvalues create the appropriate data in Keystone."""
|
||||
action_name = self.ACTION_MAP[self.params.action]
|
||||
if action_name == 'help':
|
||||
self.print_help()
|
||||
sys.exit(1)
|
||||
def main(self):
|
||||
"""Given some keyvalues create the appropriate data in Keystone."""
|
||||
action_name = self.ACTION_MAP[self.params.action]
|
||||
if action_name == 'help':
|
||||
self.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
kv = self._parse_keyvalues(self.params.keyvalues)
|
||||
try:
|
||||
f = getattr(self.handle, action_name)
|
||||
resp = f(**kv)
|
||||
except Exception:
|
||||
logging.exception('')
|
||||
raise
|
||||
kv = self._parse_keyvalues(self.params.keyvalues)
|
||||
try:
|
||||
f = getattr(self.handle, action_name)
|
||||
resp = f(**kv)
|
||||
except Exception:
|
||||
logging.exception('')
|
||||
raise
|
||||
|
||||
if CONF.id_only and getattr(resp, 'id'):
|
||||
print resp.id
|
||||
return
|
||||
if CONF.id_only and getattr(resp, 'id'):
|
||||
print resp.id
|
||||
return
|
||||
|
||||
if resp is None:
|
||||
return
|
||||
if resp is None:
|
||||
return
|
||||
|
||||
# NOTE(termie): this is ugly but it is mostly because the keystoneclient
|
||||
# code doesn't give us very serializable instance objects
|
||||
if type(resp) in [type(list()), type(tuple())]:
|
||||
o = []
|
||||
for r in resp:
|
||||
d = {}
|
||||
for k, v in sorted(r.__dict__.iteritems()):
|
||||
if k[0] == '_' or k == 'manager':
|
||||
continue
|
||||
d[k] = v
|
||||
o.append(d)
|
||||
else:
|
||||
o = {}
|
||||
for k, v in sorted(resp.__dict__.iteritems()):
|
||||
if k[0] == '_' or k == 'manager':
|
||||
continue
|
||||
o[k] = v
|
||||
# NOTE(termie): this is ugly but it is mostly because the
|
||||
# keystoneclient code doesn't give us very
|
||||
# serializable instance objects
|
||||
if type(resp) in [type(list()), type(tuple())]:
|
||||
o = []
|
||||
for r in resp:
|
||||
d = {}
|
||||
for k, v in sorted(r.__dict__.iteritems()):
|
||||
if k[0] == '_' or k == 'manager':
|
||||
continue
|
||||
d[k] = v
|
||||
o.append(d)
|
||||
else:
|
||||
o = {}
|
||||
for k, v in sorted(resp.__dict__.iteritems()):
|
||||
if k[0] == '_' or k == 'manager':
|
||||
continue
|
||||
o[k] = v
|
||||
|
||||
print json.dumps(o)
|
||||
print json.dumps(o)
|
||||
|
||||
def print_help(self):
|
||||
CONF.set_usage(CONF.usage.replace(
|
||||
'COMMAND', '%s SUBCOMMAND' % self._cmd_name()))
|
||||
CONF.print_help()
|
||||
def print_help(self):
|
||||
CONF.set_usage(CONF.usage.replace(
|
||||
'COMMAND', '%s SUBCOMMAND' % self._cmd_name()))
|
||||
CONF.print_help()
|
||||
|
||||
methods = self._get_methods()
|
||||
print_commands(methods)
|
||||
methods = self._get_methods()
|
||||
print_commands(methods)
|
||||
|
||||
def _get_methods(self):
|
||||
o = {}
|
||||
for k in dir(self.handle):
|
||||
if k.startswith('_'):
|
||||
continue
|
||||
if k in ('find', 'findall', 'api', 'resource_class'):
|
||||
continue
|
||||
o[k] = getattr(self.handle, k)
|
||||
return o
|
||||
def _get_methods(self):
|
||||
o = {}
|
||||
for k in dir(self.handle):
|
||||
if k.startswith('_'):
|
||||
continue
|
||||
if k in ('find', 'findall', 'api', 'resource_class'):
|
||||
continue
|
||||
o[k] = getattr(self.handle, k)
|
||||
return o
|
||||
|
||||
|
||||
class Role(ClientCommand):
|
||||
"""Role CRUD functions."""
|
||||
pass
|
||||
"""Role CRUD functions."""
|
||||
pass
|
||||
|
||||
|
||||
class Service(ClientCommand):
|
||||
"""Service CRUD functions."""
|
||||
pass
|
||||
"""Service CRUD functions."""
|
||||
pass
|
||||
|
||||
|
||||
class Token(ClientCommand):
|
||||
"""Token CRUD functions."""
|
||||
pass
|
||||
"""Token CRUD functions."""
|
||||
pass
|
||||
|
||||
|
||||
class Tenant(ClientCommand):
|
||||
"""Tenant CRUD functions."""
|
||||
pass
|
||||
"""Tenant CRUD functions."""
|
||||
pass
|
||||
|
||||
|
||||
class User(ClientCommand):
|
||||
"""User CRUD functions."""
|
||||
"""User CRUD functions."""
|
||||
|
||||
pass
|
||||
pass
|
||||
|
||||
|
||||
class Ec2(ClientCommand):
|
||||
def _attr_name(self):
|
||||
return self.__class__.__name__.lower()
|
||||
def _attr_name(self):
|
||||
return self.__class__.__name__.lower()
|
||||
|
||||
|
||||
CMDS = {'db_sync': DbSync,
|
||||
'role': Role,
|
||||
'service': Service,
|
||||
'token': Token,
|
||||
'tenant': Tenant,
|
||||
'user': User,
|
||||
'ec2': Ec2,
|
||||
}
|
||||
'role': Role,
|
||||
'service': Service,
|
||||
'token': Token,
|
||||
'tenant': Tenant,
|
||||
'user': User,
|
||||
'ec2': Ec2,
|
||||
}
|
||||
|
||||
|
||||
class CommandLineGenerator(object):
|
||||
"""A keystoneclient lookalike to generate keystone-manage commands.
|
||||
"""A keystoneclient lookalike to generate keystone-manage commands.
|
||||
|
||||
One would use it like so:
|
||||
One would use it like so:
|
||||
|
||||
>>> gen = CommandLineGenerator(id_only=None)
|
||||
>>> cl = gen.ec2.create(user_id='foo', tenant_id='foo')
|
||||
>>> cl.to_argv()
|
||||
... ['keystone-manage',
|
||||
'--id-only',
|
||||
'ec2',
|
||||
'create',
|
||||
'user_id=foo',
|
||||
'tenant_id=foo']
|
||||
>>> gen = CommandLineGenerator(id_only=None)
|
||||
>>> cl = gen.ec2.create(user_id='foo', tenant_id='foo')
|
||||
>>> cl.to_argv()
|
||||
... ['keystone-manage',
|
||||
'--id-only',
|
||||
'ec2',
|
||||
'create',
|
||||
'user_id=foo',
|
||||
'tenant_id=foo']
|
||||
|
||||
"""
|
||||
"""
|
||||
|
||||
cmd = 'keystone-manage'
|
||||
cmd = 'keystone-manage'
|
||||
|
||||
def __init__(self, cmd=None, execute=False, **kw):
|
||||
if cmd:
|
||||
self.cmd = cmd
|
||||
self.flags = kw
|
||||
self.execute = execute
|
||||
def __init__(self, cmd=None, execute=False, **kw):
|
||||
if cmd:
|
||||
self.cmd = cmd
|
||||
self.flags = kw
|
||||
self.execute = execute
|
||||
|
||||
def __getattr__(self, key):
|
||||
return _Manager(self, key)
|
||||
def __getattr__(self, key):
|
||||
return _Manager(self, key)
|
||||
|
||||
|
||||
class _Manager(object):
|
||||
def __init__(self, parent, name):
|
||||
self.parent = parent
|
||||
self.name = name
|
||||
def __init__(self, parent, name):
|
||||
self.parent = parent
|
||||
self.name = name
|
||||
|
||||
def __getattr__(self, key):
|
||||
return _CommandLine(cmd=self.parent.cmd,
|
||||
flags=self.parent.flags,
|
||||
manager=self.name,
|
||||
method=key,
|
||||
execute=self.parent.execute)
|
||||
def __getattr__(self, key):
|
||||
return _CommandLine(cmd=self.parent.cmd,
|
||||
flags=self.parent.flags,
|
||||
manager=self.name,
|
||||
method=key,
|
||||
execute=self.parent.execute)
|
||||
|
||||
|
||||
class _CommandLine(object):
|
||||
def __init__(self, cmd, flags, manager, method, execute=False):
|
||||
self.cmd = cmd
|
||||
self.flags = flags
|
||||
self.manager = manager
|
||||
self.method = method
|
||||
self.execute = execute
|
||||
self.kw = {}
|
||||
def __init__(self, cmd, flags, manager, method, execute=False):
|
||||
self.cmd = cmd
|
||||
self.flags = flags
|
||||
self.manager = manager
|
||||
self.method = method
|
||||
self.execute = execute
|
||||
self.kw = {}
|
||||
|
||||
def __call__(self, **kw):
|
||||
self.kw = kw
|
||||
if self.execute:
|
||||
logging.debug('generated cli: %s', str(self))
|
||||
out = StringIO.StringIO()
|
||||
old_out = sys.stdout
|
||||
sys.stdout = out
|
||||
try:
|
||||
main(self.to_argv())
|
||||
except SystemExit as e:
|
||||
pass
|
||||
finally:
|
||||
sys.stdout = old_out
|
||||
rv = out.getvalue().strip().split('\n')[-1]
|
||||
try:
|
||||
loaded = json.loads(rv)
|
||||
if type(loaded) in [type(list()), type(tuple())]:
|
||||
return [DictWrapper(**x) for x in loaded]
|
||||
elif type(loaded) is type(dict()):
|
||||
return DictWrapper(**loaded)
|
||||
except Exception:
|
||||
logging.exception('Could not parse JSON: %s', rv)
|
||||
return rv
|
||||
return self
|
||||
def __call__(self, **kw):
|
||||
self.kw = kw
|
||||
if self.execute:
|
||||
logging.debug('generated cli: %s', str(self))
|
||||
out = StringIO.StringIO()
|
||||
old_out = sys.stdout
|
||||
sys.stdout = out
|
||||
try:
|
||||
main(self.to_argv())
|
||||
except SystemExit as e:
|
||||
pass
|
||||
finally:
|
||||
sys.stdout = old_out
|
||||
rv = out.getvalue().strip().split('\n')[-1]
|
||||
try:
|
||||
loaded = json.loads(rv)
|
||||
if type(loaded) in [type(list()), type(tuple())]:
|
||||
return [DictWrapper(**x) for x in loaded]
|
||||
elif type(loaded) is type(dict()):
|
||||
return DictWrapper(**loaded)
|
||||
except Exception:
|
||||
logging.exception('Could not parse JSON: %s', rv)
|
||||
return rv
|
||||
return self
|
||||
|
||||
def __flags(self):
|
||||
o = []
|
||||
for k, v in self.flags.iteritems():
|
||||
k = k.replace('_', '-')
|
||||
if v is None:
|
||||
o.append('--%s' % k)
|
||||
else:
|
||||
o.append('--%s=%s' % (k, str(v)))
|
||||
return o
|
||||
def __flags(self):
|
||||
o = []
|
||||
for k, v in self.flags.iteritems():
|
||||
k = k.replace('_', '-')
|
||||
if v is None:
|
||||
o.append('--%s' % k)
|
||||
else:
|
||||
o.append('--%s=%s' % (k, str(v)))
|
||||
return o
|
||||
|
||||
def __manager(self):
|
||||
if self.manager.endswith('s'):
|
||||
return self.manager[:-1]
|
||||
return self.manager
|
||||
def __manager(self):
|
||||
if self.manager.endswith('s'):
|
||||
return self.manager[:-1]
|
||||
return self.manager
|
||||
|
||||
def __kw(self):
|
||||
o = []
|
||||
for k, v in self.kw.iteritems():
|
||||
o.append('%s=%s' % (k, str(v)))
|
||||
return o
|
||||
def __kw(self):
|
||||
o = []
|
||||
for k, v in self.kw.iteritems():
|
||||
o.append('%s=%s' % (k, str(v)))
|
||||
return o
|
||||
|
||||
def to_argv(self):
|
||||
return ([self.cmd]
|
||||
+ self.__flags()
|
||||
+ [self.__manager(), self.method]
|
||||
+ self.__kw())
|
||||
def to_argv(self):
|
||||
return ([self.cmd]
|
||||
+ self.__flags()
|
||||
+ [self.__manager(), self.method]
|
||||
+ self.__kw())
|
||||
|
||||
def __str__(self):
|
||||
args = self.to_argv()
|
||||
return ' '.join(args[:1] + ['"%s"' % x for x in args[1:]])
|
||||
def __str__(self):
|
||||
args = self.to_argv()
|
||||
return ' '.join(args[:1] + ['"%s"' % x for x in args[1:]])
|
||||
|
||||
|
||||
class DictWrapper(dict):
|
||||
def __getattr__(self, key):
|
||||
try:
|
||||
return self[key]
|
||||
except KeyError:
|
||||
raise AttributeError(key)
|
||||
def __getattr__(self, key):
|
||||
try:
|
||||
return self[key]
|
||||
except KeyError:
|
||||
raise AttributeError(key)
|
||||
|
||||
|
||||
def print_commands(cmds):
|
||||
print
|
||||
print "Available commands:"
|
||||
o = []
|
||||
max_length = max([len(k) for k in cmds]) + 2
|
||||
for k, cmd in sorted(cmds.iteritems()):
|
||||
initial_indent = '%s%s: ' % (' ' * (max_length - len(k)), k)
|
||||
tw = textwrap.TextWrapper(initial_indent=initial_indent,
|
||||
subsequent_indent=' ' * (max_length + 2),
|
||||
width=80)
|
||||
o.extend(tw.wrap(
|
||||
(cmd.__doc__ and cmd.__doc__ or 'no docs').strip().split('\n')[0]))
|
||||
print '\n'.join(o)
|
||||
print
|
||||
print "Available commands:"
|
||||
o = []
|
||||
max_length = max([len(k) for k in cmds]) + 2
|
||||
for k, cmd in sorted(cmds.iteritems()):
|
||||
initial_indent = '%s%s: ' % (' ' * (max_length - len(k)), k)
|
||||
tw = textwrap.TextWrapper(initial_indent=initial_indent,
|
||||
subsequent_indent=' ' * (max_length + 2),
|
||||
width=80)
|
||||
o.extend(tw.wrap(
|
||||
(cmd.__doc__ and cmd.__doc__ or 'no docs').strip().split('\n')[0]))
|
||||
print '\n'.join(o)
|
||||
|
||||
|
||||
def run(cmd, args):
|
||||
return CMDS[cmd](argv=args).run()
|
||||
return CMDS[cmd](argv=args).run()
|
||||
|
||||
|
||||
def main(argv=None, config_files=None):
|
||||
CONF.reset()
|
||||
args = CONF(config_files=config_files, args=argv)
|
||||
CONF.reset()
|
||||
args = CONF(config_files=config_files, args=argv)
|
||||
|
||||
if len(args) < 2:
|
||||
CONF.print_help()
|
||||
print_commands(CMDS)
|
||||
sys.exit(1)
|
||||
if len(args) < 2:
|
||||
CONF.print_help()
|
||||
print_commands(CMDS)
|
||||
sys.exit(1)
|
||||
|
||||
cmd = args[1]
|
||||
if cmd in CMDS:
|
||||
return run(cmd, (args[:1] + args[2:]))
|
||||
cmd = args[1]
|
||||
if cmd in CMDS:
|
||||
return run(cmd, (args[:1] + args[2:]))
|
||||
|
|
|
@ -45,11 +45,11 @@ SysLogHandler = SysLogHandler
|
|||
|
||||
|
||||
def log_debug(f):
|
||||
@functools.wraps(f)
|
||||
def wrapper(*args, **kw):
|
||||
logging.debug('%s(%s, %s) ->', f.func_name, str(args), str(kw))
|
||||
rv = f(*args, **kw)
|
||||
logging.debug(pprint.pformat(rv, indent=2))
|
||||
logging.debug('')
|
||||
return rv
|
||||
return wrapper
|
||||
@functools.wraps(f)
|
||||
def wrapper(*args, **kw):
|
||||
logging.debug('%s(%s, %s) ->', f.func_name, str(args), str(kw))
|
||||
rv = f(*args, **kw)
|
||||
logging.debug(pprint.pformat(rv, indent=2))
|
||||
logging.debug('')
|
||||
return rv
|
||||
return wrapper
|
||||
|
|
|
@ -161,38 +161,38 @@ def check_password(password, hashed):
|
|||
|
||||
# From python 2.7
|
||||
def check_output(*popenargs, **kwargs):
|
||||
r"""Run command with arguments and return its output as a byte string.
|
||||
r"""Run command with arguments and return its output as a byte string.
|
||||
|
||||
If the exit code was non-zero it raises a CalledProcessError. The
|
||||
CalledProcessError object will have the return code in the returncode
|
||||
attribute and output in the output attribute.
|
||||
If the exit code was non-zero it raises a CalledProcessError. The
|
||||
CalledProcessError object will have the return code in the returncode
|
||||
attribute and output in the output attribute.
|
||||
|
||||
The arguments are the same as for the Popen constructor. Example:
|
||||
The arguments are the same as for the Popen constructor. Example:
|
||||
|
||||
>>> check_output(["ls", "-l", "/dev/null"])
|
||||
'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
|
||||
>>> check_output(["ls", "-l", "/dev/null"])
|
||||
'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n'
|
||||
|
||||
The stdout argument is not allowed as it is used internally.
|
||||
To capture standard error in the result, use stderr=STDOUT.
|
||||
The stdout argument is not allowed as it is used internally.
|
||||
To capture standard error in the result, use stderr=STDOUT.
|
||||
|
||||
>>> check_output(["/bin/sh", "-c",
|
||||
... "ls -l non_existent_file ; exit 0"],
|
||||
... stderr=STDOUT)
|
||||
'ls: non_existent_file: No such file or directory\n'
|
||||
"""
|
||||
if 'stdout' in kwargs:
|
||||
raise ValueError('stdout argument not allowed, it will be overridden.')
|
||||
logging.debug(' '.join(popenargs[0]))
|
||||
process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
|
||||
output, unused_err = process.communicate()
|
||||
retcode = process.poll()
|
||||
if retcode:
|
||||
cmd = kwargs.get("args")
|
||||
if cmd is None:
|
||||
cmd = popenargs[0]
|
||||
raise subprocess.CalledProcessError(retcode, cmd)
|
||||
return output
|
||||
>>> check_output(["/bin/sh", "-c",
|
||||
... "ls -l non_existent_file ; exit 0"],
|
||||
... stderr=STDOUT)
|
||||
'ls: non_existent_file: No such file or directory\n'
|
||||
"""
|
||||
if 'stdout' in kwargs:
|
||||
raise ValueError('stdout argument not allowed, it will be overridden.')
|
||||
logging.debug(' '.join(popenargs[0]))
|
||||
process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
|
||||
output, unused_err = process.communicate()
|
||||
retcode = process.poll()
|
||||
if retcode:
|
||||
cmd = kwargs.get("args")
|
||||
if cmd is None:
|
||||
cmd = popenargs[0]
|
||||
raise subprocess.CalledProcessError(retcode, cmd)
|
||||
return output
|
||||
|
||||
|
||||
def git(*args):
|
||||
return check_output(['git'] + list(args))
|
||||
return check_output(['git'] + list(args))
|
||||
|
|
3
setup.py
3
setup.py
|
@ -1,5 +1,6 @@
|
|||
from setuptools import setup, find_packages
|
||||
|
||||
|
||||
setup(name='keystone',
|
||||
version='2012.1',
|
||||
description="Authentication service for OpenStack",
|
||||
|
@ -10,5 +11,5 @@ setup(name='keystone',
|
|||
packages=find_packages(exclude=['test', 'bin']),
|
||||
scripts=['bin/keystone', 'bin/keystone-manage'],
|
||||
zip_safe=False,
|
||||
install_requires = ['setuptools', 'python-keystoneclient'],
|
||||
install_requires=['setuptools', 'python-keystoneclient'],
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue