#NEWLINE# @ classmethod #NEWLINE# def from_spec( cls , spec , validator_map , resource_roots ) : #NEWLINE# #INDENT# 'Builds a script validator from a specification.\n\n        :param spec: May be a string or a single-length dictionary of name to\n            configuration values. Configuration values include:\n            env_vars: A list of environment variable names to send to the\n                script.\n            output: A key into which to put the stdout of the script in the\n                env_map of the validation run.\n        :param validator_map: A map of validator name to class.\n        :param resource_roots: The roots from which relative paths to\n            resources (scripts and such) will be referenced. Any resource will\n            be pulled from the first path in the list at which a file exists.\n        :return: A validator that will run a script on the image.\n        ' #NEWLINE# jsonschema . validate ( spec , cls . SPEC_SCHEMA ) #NEWLINE# if isinstance ( spec , six . string_types ) : #NEWLINE# #INDENT# script_path = spec #NEWLINE# ( env_vars , output_var ) = ( cls . _DEFAULT_ENV_VARS , None ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# ( script_path , properties ) = list ( six . iteritems ( spec ) ) [ 0 ] #NEWLINE# env_vars = ( cls . _DEFAULT_ENV_VARS + properties . get ( 'env_vars' , [ ] ) ) #NEWLINE# output_var = properties . get ( 'output' , None ) #NEWLINE# #UNINDENT# script_contents = None #NEWLINE# for root in resource_roots : #NEWLINE# #INDENT# file_path = path . join ( root , script_path ) #NEWLINE# script_contents = files . try_get_file_text ( file_path ) #NEWLINE# if script_contents : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# #UNINDENT# if ( not script_contents ) : #NEWLINE# #INDENT# raise p_ex . ImageValidationSpecificationError ( ( _ ( 'Script %s not found in any resource roots.' ) % script_path ) ) #NEWLINE# #UNINDENT# return SaharaScriptValidator ( script_contents , file_path , output_var )