diff --git a/slapos/cli/TODO b/slapos/cli/TODO deleted file mode 100644 index 260e53977999bbecc5610a2891b235dd39368d99..0000000000000000000000000000000000000000 --- a/slapos/cli/TODO +++ /dev/null @@ -1,16 +0,0 @@ - -for slapgrid: - refactor loggers -- maybe reduce their number? - pay attention to mandatory parameters and related dependencies - - - * enable --debug by default - * multiline help from docstring - -instance -software -report - -issues: - slapformat --log_file vs cliff --log-file - diff --git a/slapos/grid/slapgrid.py b/slapos/grid/slapgrid.py index 3d1026e45b9b534300ba97305c5175a7a875d602..dad787507629c689c59170b9fed32e6d6e60e7a7 100644 --- a/slapos/grid/slapgrid.py +++ b/slapos/grid/slapgrid.py @@ -85,95 +85,97 @@ class _formatXMLError(Exception): pass -def parseArgumentTupleAndReturnSlapgridObject(*argument_tuple): - """Parses arguments either from command line, from method parameters or from - config file. Then returns a new instance of slapgrid.Slapgrid with those - parameters. Also returns the options dict and unused variable list, and - configures logger. - """ - parser = argparse.ArgumentParser() - parser.add_argument("--instance-root", - help="The instance root directory location.") - parser.add_argument("--software-root", - help="The software_root directory location.") - parser.add_argument("--master-url", - help="The master server URL. Mandatory.") - parser.add_argument("--computer-id", - help="The computer id defined in the server.") - parser.add_argument("--supervisord-socket", - help="The socket supervisor will use.") - parser.add_argument("--supervisord-configuration-path", - help="The location where supervisord configuration will be stored.") - parser.add_argument("--buildout", default=None, - help="Location of buildout binary.") - parser.add_argument("--pidfile", - help="The location where pidfile will be created.") - parser.add_argument("--logfile", - help="The location where slapgrid logfile will be created.") - parser.add_argument("--key_file", help="SSL Authorisation key file.") - parser.add_argument("--cert_file", - help="SSL Authorisation certificate file.") - parser.add_argument("--signature_private_key_file", - help="Signature private key file.") - parser.add_argument("--master_ca_file", - help="Root certificate of SlapOS master key.") - parser.add_argument("--certificate_repository_path", - help="Path to directory where downloaded certificates would be stored.") - parser.add_argument("-v", "--verbose", action="store_true", - help="Be verbose.") - parser.add_argument("--maximum-periodicity", type=int, default=None, - help="Periodicity at which buildout should be run in instance.") - parser.add_argument("--promise-timeout", type=int, default=3, - help="Promise timeout in seconds.") - parser.add_argument("--now", action="store_true", - help="Launch slapgrid without delay. Default behavior.") - parser.add_argument("--all", action="store_true", - help="Launch slapgrid to process all Softare Releases " - "and/or Computer Partitions.") - parser.add_argument("--only-sr", - help="Force the update of a single software release (use url hash), " - "even if is already installed. This option will make all others " - "sofware releases be ignored.") - parser.add_argument("--only-cp", - help="Update a single or a list of computer partitions " - "(ie.:slappartX, slappartY)," - "this option will make all others computer partitions be ignored.") - - parser.add_argument("configuration_file", nargs=1, type=argparse.FileType(), - help="SlapOS configuration file.") +def parse_arguments_merge_config(*argument_tuple): + """Parse arguments and return options dictionary + merged with the config file.""" + + ap = argparse.ArgumentParser() + ap.add_argument('--instance-root', + help='The instance root directory location.') + ap.add_argument('--software-root', + help='The software_root directory location.') + ap.add_argument('--master-url', + help='The master server URL. Mandatory.') + ap.add_argument('--computer-id', + help='The computer id defined in the server.') + ap.add_argument('--supervisord-socket', + help='The socket supervisor will use.') + ap.add_argument('--supervisord-configuration-path', + help='The location where supervisord configuration will be stored.') + ap.add_argument('--buildout', default=None, + help='Location of buildout binary.') + ap.add_argument('--pidfile', + help='The location where pidfile will be created.') + ap.add_argument('--logfile', + help='The location where slapgrid logfile will be created.') + ap.add_argument('--key_file', + help='SSL Authorisation key file.') + ap.add_argument('--cert_file', + help='SSL Authorisation certificate file.') + ap.add_argument('--signature_private_key_file', + help='Signature private key file.') + ap.add_argument('--master_ca_file', + help='Root certificate of SlapOS master key.') + ap.add_argument('--certificate_repository_path', + help='Path to directory where downloaded certificates would be stored.') + ap.add_argument('-v', '--verbose', action='store_true', + help='Be verbose.') + ap.add_argument('--maximum-periodicity', type=int, default=None, + help='Periodicity at which buildout should be run in instance.') + ap.add_argument('--promise-timeout', type=int, default=3, + help='Promise timeout in seconds.') + ap.add_argument('--now', action='store_true', + help='Launch slapgrid without delay. Default behavior.') + ap.add_argument('--all', action='store_true', + help='Launch slapgrid to process all Softare Releases ' + 'and/or Computer Partitions.') + ap.add_argument('--only-sr', + help='Force the update of a single software release (use url hash), ' + 'even if is already installed. This option will make all others ' + 'sofware releases be ignored.') + ap.add_argument("--only-cp", + help='Update a single or a list of computer partitions ' + '(ie.:slappartX, slappartY), ' + 'this option will make all others computer partitions be ignored.') + + ap.add_argument('configuration_file', type=argparse.FileType(), + help='SlapOS configuration file.') # Deprecated options - parser.add_argument("-c", "--console", action="store_true", - help="Deprecated, doesn't do anything.") - parser.add_argument("--develop", action="store_true", - help="Deprecated, same as --all.") - parser.add_argument("--only_sr", - help="Deprecated, same as --only-sr.") - parser.add_argument("--only_cp", - help="Deprecated, same as --only-cp.") - parser.add_argument("--maximal_delay", - help="Deprecated. Will only work from configuration file in the future.") + ap.add_argument('-c', '--console', action='store_true', + help="Deprecated, doesn't do anything.") + ap.add_argument('--develop', action='store_true', + help='Deprecated, same as --all.') + ap.add_argument('--only_sr', + help='Deprecated, same as --only-sr.') + ap.add_argument('--only_cp', + help='Deprecated, same as --only-cp.') + ap.add_argument('--maximal_delay', + help='Deprecated. Will only work from configuration file in the future.') # Parses arguments if not argument_tuple: # No arguments given to entry point : we parse sys.argv. - argument_option_instance = parser.parse_args() + args = ap.parse_args() else: - argument_option_instance = parser.parse_args(list(argument_tuple)) + args = ap.parse_args(list(argument_tuple)) # Parses arguments from config file, if needed, then merge previous arguments options = {} - configuration_file = argument_option_instance.configuration_file[0] # Loads config (if config specified) - slapgrid_configuration = ConfigParser.SafeConfigParser() - slapgrid_configuration.readfp(configuration_file) + config = ConfigParser.SafeConfigParser() + config.readfp(args.configuration_file) # Merges the two dictionnaries - options = dict(slapgrid_configuration.items("slapos")) - if slapgrid_configuration.has_section("networkcache"): - options.update(dict(slapgrid_configuration.items("networkcache"))) - for argument_key, argument_value in vars(argument_option_instance - ).iteritems(): - if argument_value is not None: - options.update({argument_key: argument_value}) + options = dict(config.items('slapos')) + if config.has_section('networkcache'): + options.update(dict(config.items('networkcache'))) + for key, value in vars(args).iteritems(): + if value is not None: + options[key] = value + + return options + + +def setup_logger(options): # Configures logger. if options['verbose']: level = logging.DEBUG @@ -189,10 +191,21 @@ def parseArgumentTupleAndReturnSlapgridObject(*argument_tuple): '%(asctime)s %(name)-18s: %(levelname)-8s %(message)s')) logging.getLogger('').addHandler(console) - missing_mandatory_parameter_list = [] + # XXX return and use logger object + + +def parseArgumentTupleAndReturnSlapgridObject(*argument_tuple): + """Returns a new instance of slapgrid.Slapgrid created with argument+config parameters. + Also returns the options dict and unused variable list, and configures logger. + """ + options = parse_arguments_merge_config(*argument_tuple) + + setup_logger(options) + + missing = [] for mandatory_parameter in MANDATORY_PARAMETER_LIST: if not mandatory_parameter in options: - missing_mandatory_parameter_list.append(mandatory_parameter) + missing.append(mandatory_parameter) if options.get('all'): options['develop'] = True @@ -204,18 +217,18 @@ def parseArgumentTupleAndReturnSlapgridObject(*argument_tuple): if 'key_file' in options: repository_required = True if not 'cert_file' in options: - missing_mandatory_parameter_list.append('cert_file') + missing.append('cert_file') if 'cert_file' in options: repository_required = True if not 'key_file' in options: - missing_mandatory_parameter_list.append('key_file') + missing.append('key_file') if repository_required: if 'certificate_repository_path' not in options: - missing_mandatory_parameter_list.append('certificate_repository_path') + missing.append('certificate_repository_path') - if len(missing_mandatory_parameter_list) > 0: - parser.error('Missing mandatory parameters:\n%s' % '\n'.join( - missing_mandatory_parameter_list)) + if missing: + raise RuntimeError('Missing mandatory parameters:\n%s' % '\n'.join( + missing)) key_file = options.get('key_file') cert_file = options.get('cert_file') @@ -235,12 +248,12 @@ def parseArgumentTupleAndReturnSlapgridObject(*argument_tuple): for f in mandatory_file_list: if f is not None: if not os.path.exists(f): - parser.error('File %r does not exist.' % f) + raise RuntimeError('File %r does not exist.' % f) certificate_repository_path = options.get('certificate_repository_path') if certificate_repository_path: if not os.path.isdir(certificate_repository_path): - parser.error('Directory %r does not exist' % certificate_repository_path) + raise RuntimeError('Directory %r does not exist' % certificate_repository_path) # Supervisord configuration location if not options.get('supervisord_configuration_path'):