<s> import yaml <EOL> from copy import deepcopy <EOL> import util <EOL> from project import Project <EOL> from service import Service <EOL> from exceptions import AlaudaInputError <EOL> import os <EOL> def load_project ( filepath , namespace , region ) : <EOL> abspath = os . path . abspath ( filepath ) <EOL> compose_data = _load_yaml ( abspath ) <EOL> vertex_list = [ abspath ] <EOL> edge_list = [ ] <EOL> resolve_extends ( compose_data , abspath , vertex_list , edge_list ) <EOL> services = load_services ( compose_data , namespace , region ) <EOL> project = Project ( services ) <EOL> return project <EOL> def _get_linked_services ( link_list ) : <EOL> parsed_links = util . parse_links ( link_list ) <EOL> return [ x [ <NUM_LIT:0> ] for x in parsed_links ] <EOL> def sort_services ( compose_data ) : <EOL> src_dict = compose_data . copy ( ) <EOL> src_keys = src_dict . keys ( ) <EOL> sorted_list = [ ] <EOL> while len ( src_dict ) > <NUM_LIT:0> : <EOL> for key , value in src_dict . items ( ) : <EOL> links = _get_linked_services ( value . get ( '<STR_LIT>' ) ) <EOL> if links is None : <EOL> sorted_list . append ( key ) <EOL> del src_dict [ key ] <EOL> elif not set ( links ) . issubset ( set ( src_keys ) ) : <EOL> raise AlaudaInputError ( "<STR_LIT>" . format ( links ) ) <EOL> elif set ( links ) . issubset ( set ( sorted_list ) ) : <EOL> sorted_list . append ( key ) <EOL> del src_dict [ key ] <EOL> else : <EOL> continue <EOL> return sorted_list <EOL> def toposort_services ( compose_data ) : <EOL> service_vertex = [ ] <EOL> service_edge = [ ] <EOL> src_keys = compose_data . keys ( ) <EOL> for key , value in compose_data . items ( ) : <EOL> links = _get_linked_services ( value . get ( '<STR_LIT>' ) ) <EOL> if key not in service_vertex : <EOL> service_vertex . append ( key ) <EOL> if not set ( links ) . issubset ( set ( src_keys ) ) : <EOL> raise AlaudaInputError ( "<STR_LIT>" . format ( links ) ) <EOL> else : <EOL> for link in links : <EOL> if link not in service_vertex : <EOL> service_vertex . append ( link ) <EOL> service_edge . append ( ( link , key ) ) <EOL> sorted_result = util . topoSort ( service_vertex , service_edge ) <EOL> if sorted_result == - <NUM_LIT:1> : <EOL> raise AlaudaInputError ( "<STR_LIT>" ) <EOL> return sorted_result <EOL> def load_services ( compose_data , namespace , region ) : <EOL> sorted_services = [ ] <EOL> sorted_list = toposort_services ( compose_data ) <EOL> for services in sorted_list : <EOL> service_list = [ ] <EOL> for service_name in services : <EOL> service = load_service ( service_name , compose_data [ service_name ] , namespace , region ) <EOL> service_list . append ( service ) <EOL> sorted_services . append ( service_list ) <EOL> return sorted_services <EOL> def load_service ( service_name , service_data , namespace , region ) : <EOL> image = service_data . get ( '<STR_LIT:image>' ) <EOL> if not image : <EOL> raise AlaudaInputError ( '<STR_LIT>' ) <EOL> image_name , image_tag = util . parse_image_name_tag ( image ) <EOL> ports = load_ports ( service_data ) <EOL> run_command = load_command ( service_data ) <EOL> links = load_links ( service_data ) <EOL> volumes = load_volumes ( service_data ) <EOL> envvars = load_envvars ( service_data ) <EOL> domain = load_domain ( service_data ) <EOL> instance_num , instance_size = load_instance ( service_data ) <EOL> scaling_mode , autoscaling_config = load_scaling_info ( service_data ) <EOL> service = Service ( name = service_name , <EOL> image_name = image_name , <EOL> image_tag = image_tag , <EOL> run_command = run_command , <EOL> instance_envvars = envvars , <EOL> instance_ports = ports , <EOL> volumes = volumes , <EOL> links = links , <EOL> target_num_instances = instance_num , <EOL> instance_size = instance_size , <EOL> namespace = namespace , <EOL> scaling_mode = scaling_mode , <EOL> autoscaling_config = autoscaling_config , <EOL> custom_domain_name = domain , <EOL> region_name = region ) <EOL> return service <EOL> def load_domain ( service_data ) : <EOL> return service_data . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> def load_instance ( service_data ) : <EOL> size = service_data . get ( '<STR_LIT:size>' , '<STR_LIT>' ) <EOL> number = service_data . get ( '<STR_LIT>' , <NUM_LIT:1> ) <EOL> return number , size <EOL> def load_scaling_info ( service_data ) : <EOL> autoscaling_config = service_data . get ( '<STR_LIT>' ) <EOL> if autoscaling_config is None : <EOL> return util . parse_autoscale_info ( None ) <EOL> return util . parse_autoscale_info ( ( True , autoscaling_config ) ) <EOL> def load_links ( service_data ) : <EOL> return util . parse_links ( service_data . get ( '<STR_LIT>' ) ) <EOL> def load_ports ( service_data ) : <EOL> instance_ports , port_list = util . parse_instance_ports ( service_data . get ( '<STR_LIT>' ) ) <EOL> expose_list = util . merge_internal_external_ports ( port_list , service_data . get ( '<STR_LIT>' , [ ] ) ) <EOL> instance_ports . extend ( expose_list ) <EOL> return instance_ports <EOL> def load_command ( service_data ) : <EOL> return service_data . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> def load_volumes ( service_data ) : <EOL> return util . parse_volumes ( service_data . get ( '<STR_LIT>' ) ) <EOL> def load_envvars ( service_data ) : <EOL> return util . parse_envvars ( service_data . get ( '<STR_LIT>' ) ) <EOL> def resolve_extends ( compose_data , file_name , vertex_list , edge_list ) : <EOL> for local_service_name , local_service_data in compose_data . items ( ) : <EOL> if '<STR_LIT>' in local_service_data . keys ( ) : <EOL> extends = local_service_data [ '<STR_LIT>' ] <EOL> extends_file_name = os . path . abspath ( extends [ '<STR_LIT:file>' ] ) <EOL> original_service_name = extends [ '<STR_LIT>' ] <EOL> if extends_file_name not in vertex_list : <EOL> vertex_list . append ( extends_file_name ) <EOL> edge = ( file_name , extends_file_name ) <EOL> if edge not in edge_list : <EOL> edge_list . append ( edge ) <EOL> vertex_list_tmp = deepcopy ( vertex_list ) <EOL> edge_list_tmp = deepcopy ( edge_list ) <EOL> result = util . topoSort ( vertex_list_tmp , edge_list_tmp ) <EOL> if result is None : <EOL> raise AlaudaInputError ( '<STR_LIT>' ) <EOL> original_compose_data = _load_yaml ( extends_file_name ) <EOL> resolve_extends ( original_compose_data , extends_file_name , vertex_list , edge_list ) <EOL> original_service_data = original_compose_data [ original_service_name ] <EOL> for key , value in original_service_data . items ( ) : <EOL> if key == '<STR_LIT>' or key == '<STR_LIT>' : <EOL> continue <EOL> elif key == '<STR_LIT>' : <EOL> merge_ports ( local_service_data , value ) <EOL> elif key == '<STR_LIT>' : <EOL> merge_expose ( local_service_data , value ) <EOL> elif key == '<STR_LIT>' : <EOL> merge_environment ( local_service_data , value ) <EOL> elif key == '<STR_LIT>' : <EOL> merge_volumes ( local_service_data , value ) <EOL> elif key not in local_service_data . keys ( ) : <EOL> local_service_data [ key ] = value <EOL> else : <EOL> continue <EOL> def merge_ports ( local_service_data , original_ports ) : <EOL> pass <EOL> def merge_expose ( local_service_data , original_expose ) : <EOL> if local_service_data . get ( '<STR_LIT>' ) is None : <EOL> local_service_data [ '<STR_LIT>' ] = original_expose <EOL> else : <EOL> local_service_data [ '<STR_LIT>' ] += [ v for v in original_expose if v not in local_service_data [ '<STR_LIT>' ] ] <EOL> def merge_environment ( local_service_data , original_environment ) : <EOL> if local_service_data . get ( '<STR_LIT>' ) is None : <EOL> local_service_data [ '<STR_LIT>' ] = original_environment <EOL> else : <EOL> local_envs = util . parse_envvars ( local_service_data [ '<STR_LIT>' ] ) <EOL> for env in original_environment : <EOL> key , _ = util . parse_envvar ( env ) <EOL> if key not in local_envs . keys ( ) : <EOL> local_service_data [ '<STR_LIT>' ] . append ( env ) <EOL> def merge_volumes ( local_service_data , original_volumes ) : <EOL> pass <EOL> def _load_yaml ( filepath ) : <EOL> try : <EOL> with open ( filepath , '<STR_LIT:r>' ) as f : <EOL> return yaml . safe_load ( f ) <EOL> except : <EOL> raise AlaudaInputError ( '<STR_LIT>' . format ( filepath ) ) </s>
