[WIP] cobbling together a command line - DO NOT MERGE

Change-Id: I9caefe557ac827ca7a3b8f9a1693d623cf369080
This commit is contained in:
Davanum Srinivas 2016-05-08 22:10:46 -04:00
parent 2100868fab
commit dd7a378304
9 changed files with 419 additions and 1 deletions

View File

View File

@ -0,0 +1,46 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from cliff import command
from oslo_config import cfg
from oslo_log import log
from kolla_kubernetes import service
CONF = cfg.CONF
LOG = log.getLogger(__name__)
class Run(command.Command):
"""Run a service."""
def get_parser(self, prog_name):
parser = super(Run, self).get_parser(prog_name)
parser.add_argument('service')
return parser
def take_action(self, parsed_args):
service.run_service(parsed_args.service,
CONF.service_dir)
class Kill(command.Command):
"""Kill a service."""
def get_parser(self, prog_name):
parser = super(Kill, self).get_parser(prog_name)
parser.add_argument('service')
return parser
def take_action(self, parsed_args):
service.kill_service(parsed_args.service)

View File

View File

@ -0,0 +1,157 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os.path
import shlex
import sys
from cliff import app
from cliff import commandmanager
from cliff import interactive
from oslo_config import cfg
from oslo_log import log
from kolla_kubernetes.common import file_utils
from kolla_kubernetes.common import utils
PROJECT = 'kolla_kubernetes'
VERSION = '1.0'
CONF = cfg.CONF
log.register_options(CONF)
log.set_defaults(
default_log_levels='requests.packages.urllib3.connectionpool=WARNING')
cli_opts = [
cfg.StrOpt('service-dir',
default=utils.env(
'KM_SERVICE_DIR', default=os.path.join(
file_utils.find_base_dir(), 'services')),
help='Directory with services, (Env: KM_SERVICE_DIR)'),
]
CONF.register_cli_opts(cli_opts)
class KollaKubernetesInteractiveApp(interactive.InteractiveApp):
def do_run(self, arg):
self.default(arg)
def do_help(self, arg):
line_parts = shlex.split(arg)
try:
self.command_manager.find_command(line_parts)
return self.default(self.parsed('help ' + arg))
except ValueError:
# There is a builtin cmd2 command
pass
return interactive.InteractiveApp.do_help(self, arg)
class KollaKubernetesShell(app.App):
def __init__(self):
super(KollaKubernetesShell, self).__init__(
description='Kolla-kubernetes command-line interface',
version=VERSION,
command_manager=commandmanager.CommandManager('kolla_kubernetes.cli'),
deferred_help=True,
interactive_app_factory=KollaKubernetesInteractiveApp
)
def configure_logging(self):
return
def initialize_app(self, argv):
self.options.service_dir = CONF.service_dir
def print_help(self):
outputs = []
max_len = 0
self.stdout.write('\nCommands :\n')
for name, ep in sorted(self.command_manager):
factory = ep.load()
cmd = factory(self, None)
one_liner = cmd.get_description().split('\n')[0]
outputs.append((name, one_liner))
max_len = max(len(name), max_len)
for name, one_liner in outputs:
self.stdout.write(' %s %s\n' % (name.ljust(max_len), one_liner))
def _separate_args(argv):
conf_opts = _config_opts_map()
config_args = []
command_args = argv[:]
while command_args:
nargs = conf_opts.get(command_args[0])
if nargs:
config_args.extend(command_args[:nargs])
command_args = command_args[nargs:]
else:
break
return config_args, command_args
def _config_opts_map():
opts = {'--help': 1, '-h': 1, '--config-dir': 2, '--config-file': 2,
'--version': 1}
for opt in CONF._all_cli_opts():
if opt[1]:
arg = '%s-%s' % (opt[1].name, opt[0].name)
else:
arg = opt[0].name
if isinstance(opt[0], cfg.BoolOpt):
nargs = 1
opts['--no%s' % arg] = 1
else:
nargs = 2
opts['--%s' % arg] = nargs
if opt[0].short:
opts['-%s' % opt[0].short] = nargs
for dep_opt in opt[0].deprecated_opts:
if getattr(dep_opt, 'group'):
opts['--%s-%s' % (dep_opt.group, dep_opt.name)] = nargs
else:
opts['--%s' % dep_opt.name] = nargs
return opts
def main(argv=sys.argv[1:]):
config_args, command_args = _separate_args(argv)
need_help = (['help'] == command_args or '-h' in config_args or
'--help' in config_args)
if need_help:
CONF([], project=PROJECT, version=VERSION)
CONF.print_help()
return KollaKubernetesShell().print_help()
CONF(config_args, project=PROJECT, version=VERSION)
log.setup(CONF, PROJECT, VERSION)
if '-d' in config_args or '--debug' in config_args:
command_args.insert(0, '--debug')
CONF.log_opt_values(
log.getLogger(PROJECT), log.INFO)
return KollaKubernetesShell().run(command_args)
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

View File

View File

@ -0,0 +1,108 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import errno
import logging
import os
import platform
import sys
from oslo_utils import importutils
LOG = logging.getLogger(__name__)
class KollaException(Exception):
pass
class KollaDirNotFoundException(KollaException):
pass
class KollaNotFoundException(KollaException):
def __init__(self, message, entity='file'):
super(KollaNotFoundException, self).__init__(
'The %s "%s" was not found' % (entity, message))
def find_os_type():
return platform.linux_distribution()[0]
def mkdir_p(path):
try:
os.makedirs(path)
except OSError as exc: # Python >2.5
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
else:
raise
def get_src_dir():
kolla_kubernetes = importutils.import_module('kolla_kubernetes')
mod_path = os.path.abspath(kolla_kubernetes.__file__)
# remove the file and module to get to the base.
return os.path.dirname(os.path.dirname(mod_path))
def find_base_dir():
script_path = os.path.dirname(os.path.realpath(sys.argv[0]))
base_script_path = os.path.basename(script_path)
if base_script_path == 'kolla-kubernetes':
return script_path
if base_script_path == 'kolla_kubernetes':
return os.path.join(script_path, '..')
if base_script_path == 'cmd':
return os.path.join(script_path, '..', '..')
if base_script_path == 'subunit':
return get_src_dir()
if base_script_path == 'bin':
if find_os_type() in ['Ubuntu', 'debian']:
base_dir = '/usr/local/share/kolla-kubernetes'
else:
base_dir = '/usr/share/kolla-kubernetes'
if os.path.exists(base_dir):
return base_dir
else:
return get_src_dir()
raise KollaDirNotFoundException(
'I do not know where your Kolla directory is'
)
def find_config_file(filename):
filepath = os.path.join('/etc/kolla-kubernetes', filename)
if os.access(filepath, os.R_OK):
config_file = filepath
else:
config_file = os.path.join(find_base_dir(),
'etc', filename)
return config_file
POSSIBLE_PATHS = set([
'/usr/share/kolla-kubernetes',
get_src_dir(),
find_base_dir()
])
def find_file(filename):
for path in POSSIBLE_PATHS:
file_path = os.path.join(path, filename)
if os.path.exists(file_path):
return file_path
raise KollaNotFoundException(filename, entity='file')

View File

@ -0,0 +1,46 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import collections
import os
from six.moves.urllib import parse
def env(*args, **kwargs):
for arg in args:
value = os.environ.get(arg)
if value:
return value
return kwargs.get('default', '')
def dict_update(d, u):
"""Recursively update 'd' with 'u' and return the result."""
if not isinstance(u, collections.Mapping):
return u
for k, v in u.items():
if isinstance(v, collections.Mapping):
d[k] = dict_update(d.get(k, {}), v)
else:
d[k] = u[k]
return d
def get_query_string(search_opts):
if search_opts:
qparams = sorted(search_opts.items(), key=lambda x: x[0])
query_string = "?%s" % parse.urlencode(qparams, doseq=True)
else:
query_string = ""
return query_string

View File

@ -0,0 +1,51 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
def run_service(service_name, service_dir, variables=None):
# generate zk variables
if service_name == 'nova-compute':
service_list = ['nova-compute', 'nova-libvirt', 'openvswitch-vswitchd',
'neutron-openvswitch-agent', 'openvswitch-db']
elif service_name == 'network-node':
service_list = ['neutron-openvswitch-agent', 'neutron-dhcp-agent',
'neutron-metadata-agent', 'openvswitch-vswitchd',
'openvswitch-db neutron-l3-agent']
#TODO: load this service _list from config
elif service_name == 'all':
service_list = ['keystone-init', 'keystone-api', 'keystone-db-sync',
'glance-init', 'mariadb', 'rabbitmq', 'glance-registry',
'glance-api', 'nova-init', 'nova-api', 'nova-scheduler',
'nova-conductor', 'nova-consoleauth', 'neutron-init',
'neutron-server', 'horizon', 'nova-compute',
'nova-libvirt', 'openvswitch-vswitchd',
'neutron-openvswitch-agent', 'openvswitch-db',
'neutron-dhcp-agent', 'neutron-metadata-agent',
'openvswitch-db neutron-l3-agent']
elif service_name == 'zookeeper':
service_list = []
else:
service_list = [service_name]
# for service in service_list:
# _build_runner(service, service_dir, variables=variables)
# _deploy_instance(service_name)
def kill_service(service_name):
# if service_name == "all":
# with zk_utils.connection() as zk:
# status_node = os.path.join('kolla', CONF.kolla.deployment_id,
# 'status')
# zk.delete(status_node, recursive=True)
# _delete_instance(service_name)
pass

View File

@ -21,7 +21,17 @@ classifier =
[files]
packages =
kolla-kubernetes
kolla_kubernetes
data_files =
share/kolla-kubernetes/services = services/*
[entry_points]
console_scripts =
kolla-kubernetes = kolla_kubernetes.cmd.shell:main
kolla_kubernetes.cli =
run = kolla_kubernetes.cli.service:Run
kill = kolla_kubernetes.cli.service:Kill
[build_sphinx]
source-dir = doc/source