forked from ungleich-public/cdist
		
	ugly -> bad
This commit is contained in:
		
					parent
					
						
							
								e6fc74c081
							
						
					
				
			
			
				commit
				
					
						d0f5d2c459
					
				
			
		
					 2 changed files with 218 additions and 167 deletions
				
			
		
							
								
								
									
										209
									
								
								cdist/argparse.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								cdist/argparse.py
									
										
									
									
									
										Normal 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
									
								
							
							
						
						
									
										176
									
								
								scripts/cdist
									
										
									
									
									
										
										
										Executable file → Normal 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 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue