ugly -> bad

This commit is contained in:
Darko Poljak 2016-12-03 18:24:37 +01:00
parent e6fc74c081
commit d0f5d2c459
2 changed files with 218 additions and 167 deletions

209
cdist/argparse.py Normal file
View file

@ -0,0 +1,209 @@
import argparse
import cdist
import multiprocessing
import os
import logging
import collections
# list of beta sub-commands
BETA_COMMANDS = ['install', ]
# list of beta arguments for sub-commands
BETA_ARGS = {
'config': ['jobs', ],
}
EPILOG = "Get cdist at http://www.nico.schottelius.org/software/cdist/"
# Parser others can reuse
parser = None
_verbosity_level = {
0: logging.ERROR,
1: logging.WARNING,
2: logging.INFO,
}
_verbosity_level = collections.defaultdict(
lambda: logging.DEBUG, _verbosity_level)
def add_beta_command(cmd):
if cmd not in BETA_COMMANDS:
BETA_COMMANDS.append(cmd)
def add_beta_arg(cmd, arg):
if cmd in BETA_ARGS:
if arg not in BETA_ARGS[cmd]:
BETA_ARGS[cmd].append(arg)
else:
BETA_ARGS[cmd] = [arg, ]
def check_beta(args_dict):
if 'beta' not in args_dict:
args_dict['beta'] = False
# Check only if beta is not enabled: if beta option is specified then
# raise error.
if not args_dict['beta']:
cmd = args_dict['command']
# first check if command is beta
if cmd in BETA_COMMANDS:
raise cdist.CdistBetaRequired(cmd)
# then check if some command's argument is beta
if cmd in BETA_ARGS:
for arg in BETA_ARGS[cmd]:
if arg in args_dict and args_dict[arg]:
raise cdist.CdistBetaRequired(cmd, arg)
def check_positive_int(value):
import argparse
try:
val = int(value)
except ValueError:
raise argparse.ArgumentTypeError(
"{} is invalid int value".format(value))
if val <= 0:
raise argparse.ArgumentTypeError(
"{} is invalid positive int value".format(val))
return val
def get_parsers():
global parser
# Construct parser others can reuse
if parser:
return parser
else:
parser = {}
# Options _all_ parsers have in common
parser['loglevel'] = argparse.ArgumentParser(add_help=False)
parser['loglevel'].add_argument(
'-d', '--debug',
help=('Set log level to debug (deprecated, use -vvv instead)'),
action='store_true', default=False)
parser['loglevel'].add_argument(
'-v', '--verbose',
help=('Increase log level, be more verbose. Use it more than once '
'to increase log level. The order of levels from the lowest '
'to the highest are: ERROR, WARNING, INFO, DEBUG.'),
action='count', default=0)
parser['beta'] = argparse.ArgumentParser(add_help=False)
parser['beta'].add_argument(
'-b', '--beta',
help=('Enable beta functionalities. '
'Can also be enabled using CDIST_BETA env var.'),
action='store_true', dest='beta',
default='CDIST_BETA' in os.environ)
# Main subcommand parser
parser['main'] = argparse.ArgumentParser(
description='cdist ' + cdist.VERSION, parents=[parser['loglevel']])
parser['main'].add_argument(
'-V', '--version', help='Show version', action='version',
version='%(prog)s ' + cdist.VERSION)
parser['sub'] = parser['main'].add_subparsers(
title="Commands", dest="command")
# Banner
parser['banner'] = parser['sub'].add_parser(
'banner', parents=[parser['loglevel']])
parser['banner'].set_defaults(func=cdist.banner.banner)
# Config
parser['config_main'] = argparse.ArgumentParser(add_help=False)
parser['config_main'].add_argument(
'-c', '--conf-dir',
help=('Add configuration directory (can be repeated, '
'last one wins)'), action='append')
parser['config_main'].add_argument(
'-i', '--initial-manifest',
help='path to a cdist manifest or \'-\' to read from stdin.',
dest='manifest', required=False)
parser['config_main'].add_argument(
'-j', '--jobs', nargs='?',
type=check_positive_int,
help=('Specify the maximum number of parallel jobs, currently '
'only global explorers are supported'),
action='store', dest='jobs',
const=multiprocessing.cpu_count())
parser['config_main'].add_argument(
'-n', '--dry-run',
help='do not execute code', action='store_true')
parser['config_main'].add_argument(
'-o', '--out-dir',
help='directory to save cdist output in', dest="out_path")
# remote-copy and remote-exec defaults are environment variables
# if set; if not then None - these will be futher handled after
# parsing to determine implementation default
parser['config_main'].add_argument(
'--remote-copy',
help='Command to use for remote copy (should behave like scp)',
action='store', dest='remote_copy',
default=os.environ.get('CDIST_REMOTE_COPY'))
parser['config_main'].add_argument(
'--remote-exec',
help=('Command to use for remote execution '
'(should behave like ssh)'),
action='store', dest='remote_exec',
default=os.environ.get('CDIST_REMOTE_EXEC'))
# Config
parser['config_args'] = argparse.ArgumentParser(add_help=False)
parser['config_args'].add_argument(
'host', nargs='*', help='host(s) to operate on')
parser['config_args'].add_argument(
'-f', '--file',
help=('Read additional hosts to operate on from specified file '
'or from stdin if \'-\' (each host on separate line). '
'If no host or host file is specified then, by default, '
'read hosts from stdin.'),
dest='hostfile', required=False)
parser['config_args'].add_argument(
'-p', '--parallel',
help='operate on multiple hosts in parallel',
action='store_true', dest='parallel')
parser['config_args'].add_argument(
'-s', '--sequential',
help='operate on multiple hosts sequentially (default)',
action='store_false', dest='parallel')
parser['config'] = parser['sub'].add_parser(
'config', parents=[parser['loglevel'], parser['beta'],
parser['config_main'],
parser['config_args']])
parser['config'].set_defaults(func=cdist.config.Config.commandline)
# Install
parser['install'] = parser['sub'].add_parser('install', add_help=False,
parents=[parser['config']])
parser['install'].set_defaults(func=cdist.install.Install.commandline)
# Shell
parser['shell'] = parser['sub'].add_parser(
'shell', parents=[parser['loglevel']])
parser['shell'].add_argument(
'-s', '--shell',
help=('Select shell to use, defaults to current shell. Used shell'
' should be POSIX compatible shell.'))
parser['shell'].set_defaults(func=cdist.shell.Shell.commandline)
for p in parser:
parser[p].epilog = EPILOG
return parser
def handle_loglevel(args):
if args.debug:
retval = "-d/--debug is deprecated, use -vvv instead"
args.verbose = 3
else:
retval = None
logging.root.setLevel(_verbosity_level[args.verbose])
return retval

176
scripts/cdist Executable file → Normal file
View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# 2010-2013 Nico Schottelius (nico-cdist at schottelius.org)
# 2010-2016 Nico Schottelius (nico-cdist at schottelius.org)
# 2016 Darko Poljak (darko.poljak at gmail.com)
#
# This file is part of cdist.
@ -24,182 +24,25 @@
import collections
import logging
# list of beta sub-commands
BETA_COMMANDS = ['install', ]
# list of beta arguments for sub-commands
BETA_ARGS = {
'config': ['jobs', ],
}
def check_positive_int(value):
import argparse
try:
val = int(value)
except ValueError as e:
raise argparse.ArgumentTypeError(
"{} is invalid int value".format(value))
if val <= 0:
raise argparse.ArgumentTypeError(
"{} is invalid positive int value".format(val))
return val
def check_beta(args_dict):
if 'beta' not in args_dict:
args_dict['beta'] = False
# Check only if beta is not enabled: if beta option is specified then
# raise error.
if not args_dict['beta']:
cmd = args_dict['command']
# first check if command is beta
if cmd in BETA_COMMANDS:
raise cdist.CdistBetaRequired(cmd)
# then check if command's argument is beta
if cmd in BETA_ARGS:
for arg in BETA_ARGS[cmd]:
if arg in args_dict and args_dict[arg]:
raise cdist.CdistBetaRequired(cmd, arg)
_verbosity_level = {
0: logging.ERROR,
1: logging.WARNING,
2: logging.INFO,
}
_verbosity_level = collections.defaultdict(
lambda: logging.DEBUG, _verbosity_level)
def commandline():
"""Parse command line"""
import argparse
import cdist.argparse
import cdist.banner
import cdist.config
import cdist.install
import cdist.shell
import shutil
import os
import multiprocessing
# Construct parser others can reuse
parser = {}
# Options _all_ parsers have in common
parser['loglevel'] = argparse.ArgumentParser(add_help=False)
parser['loglevel'].add_argument(
'-d', '--debug',
help=('Set log level to debug (deprecated, use -vvv instead)'),
action='store_true', default=False)
parser['loglevel'].add_argument(
'-v', '--verbose',
help=('Increase log level, be more verbose. Use it more than once '
'to increase log level. The order of levels from the lowest '
'to the highest are: ERROR, WARNING, INFO, DEBUG.'),
action='count', default=0)
# Main subcommand parser
parser['main'] = argparse.ArgumentParser(
description='cdist ' + cdist.VERSION, parents=[parser['loglevel']])
parser['main'].add_argument(
'-V', '--version', help='Show version', action='version',
version='%(prog)s ' + cdist.VERSION)
parser['sub'] = parser['main'].add_subparsers(
title="Commands", dest="command")
# Banner
parser['banner'] = parser['sub'].add_parser(
'banner', parents=[parser['loglevel']])
parser['banner'].set_defaults(func=cdist.banner.banner)
# Config
parser['config'] = parser['sub'].add_parser(
'config', parents=[parser['loglevel']])
parser['config'].add_argument(
'host', nargs='*', help='host(s) to operate on')
parser['config'].add_argument(
'-b', '--enable-beta',
help=('Enable beta functionalities. Beta functionalities '
'include the following options: -j/--jobs.'),
action='store_true', dest='beta', default=False)
parser['config'].add_argument(
'-c', '--conf-dir',
help=('Add configuration directory (can be repeated, '
'last one wins)'), action='append')
parser['config'].add_argument(
'-f', '--file',
help=('Read additional hosts to operate on from specified file '
'or from stdin if \'-\' (each host on separate line). '
'If no host or host file is specified then, by default, '
'read hosts from stdin.'),
dest='hostfile', required=False)
parser['config'].add_argument(
'-i', '--initial-manifest',
help='Path to a cdist manifest or \'-\' to read from stdin.',
dest='manifest', required=False)
parser['config'].add_argument(
'-j', '--jobs', nargs='?', type=check_positive_int,
help=('Specify the maximum number of parallel jobs, currently '
'only global explorers are supported (currently in beta'),
action='store', dest='jobs',
const=multiprocessing.cpu_count())
parser['config'].add_argument(
'-n', '--dry-run',
help='Do not execute code', action='store_true')
parser['config'].add_argument(
'-o', '--out-dir',
help='Directory to save cdist output in', dest="out_path")
parser['config'].add_argument(
'-p', '--parallel',
help='Operate on multiple hosts in parallel',
action='store_true', dest='parallel')
parser['config'].add_argument(
'-s', '--sequential',
help='Operate on multiple hosts sequentially (default)',
action='store_false', dest='parallel')
# remote-copy and remote-exec defaults are environment variables
# if set; if not then None - these will be futher handled after
# parsing to determine implementation default
parser['config'].add_argument(
'--remote-copy',
help='Command to use for remote copy (should behave like scp)',
action='store', dest='remote_copy',
default=os.environ.get('CDIST_REMOTE_COPY'))
parser['config'].add_argument(
'--remote-exec',
help=('Command to use for remote execution '
'(should behave like ssh)'),
action='store', dest='remote_exec',
default=os.environ.get('CDIST_REMOTE_EXEC'))
parser['config'].set_defaults(func=cdist.config.Config.commandline)
# Install
parser['install'] = parser['sub'].add_parser('install', add_help=False,
parents=[parser['config']])
parser['install'].set_defaults(func=cdist.install.Install.commandline)
# Shell
parser['shell'] = parser['sub'].add_parser(
'shell', parents=[parser['loglevel']])
parser['shell'].add_argument(
'-s', '--shell',
help=('Select shell to use, defaults to current shell. Used shell'
' should be POSIX compatible shell.'))
parser['shell'].set_defaults(func=cdist.shell.Shell.commandline)
for p in parser:
parser[p].epilog = (
"Get cdist at http://www.nico.schottelius.org/software/cdist/")
parser = cdist.argparse.get_parsers()
args = parser['main'].parse_args(sys.argv[1:])
# Loglevels are handled globally in here
if args.debug:
log.warning("-d/--debug is deprecated, use -vvv instead")
args.verbose = 3
logging.root.setLevel(_verbosity_level[args.verbose])
retval = cdist.argparse.handle_loglevel(args)
if retval:
log.warning(retval)
log.debug(args)
log.info("version %s" % cdist.VERSION)
@ -219,17 +62,16 @@ def commandline():
parser['main'].print_help()
sys.exit(0)
check_beta(vars(args))
cdist.argparse.check_beta(vars(args))
args.func(args)
if __name__ == "__main__":
# Sys is needed for sys.exit()
import sys
cdistpythonversion = '3.2'
if sys.version < cdistpythonversion:
print('Python >= ' + cdistpythonversion +
' is required on the source host.', file=sys.stderr)
print('Python >= {} is required on the source host.'.format(
cdistpythonversion), file=sys.stderr)
sys.exit(1)
exit_code = 0