<s> __author__ = '<STR_LIT>' <EOL> import os <EOL> import re <EOL> import mongoctl . repository as repository <EOL> from mongoctl . mongoctl_logging import * <EOL> from mongoctl import config <EOL> from mongoctl . errors import MongoctlException <EOL> from mongoctl . utils import is_exe , which , resolve_path , execute_command <EOL> from mongoctl . mongodb_version import make_version_info , MongoDBEdition <EOL> from mongoctl . mongo_uri_tools import is_mongo_uri <EOL> MONGO_HOME_ENV_VAR = "<STR_LIT>" <EOL> MONGO_VERSIONS_ENV_VAR = "<STR_LIT>" <EOL> class VersionPreference ( object ) : <EOL> EXACT = "<STR_LIT>" <EOL> MAJOR_GE = "<STR_LIT>" <EOL> LATEST_STABLE = "<STR_LIT>" <EOL> EXACT_OR_MINOR = "<STR_LIT>" <EOL> LATEST_MINOR = "<STR_LIT>" <EOL> DEFAULT = "<STR_LIT>" <EOL> def extract_mongo_exe_options ( parsed_args , supported_options ) : <EOL> options_extract = { } <EOL> for ( option_name , option_val ) in parsed_args . __dict__ . items ( ) : <EOL> if option_name in supported_options and option_val is not None : <EOL> options_extract [ option_name ] = option_val <EOL> return options_extract <EOL> def get_mongo_executable ( version_info , <EOL> executable_name , <EOL> version_check_pref = VersionPreference . EXACT ) : <EOL> mongo_home = os . getenv ( MONGO_HOME_ENV_VAR ) <EOL> mongo_installs_dir = config . get_mongodb_installs_dir ( ) <EOL> version_number = version_info and version_info . version_number <EOL> mongodb_edition = version_info and ( version_info . edition or <EOL> MongoDBEdition . COMMUNITY ) <EOL> ver_disp = "<STR_LIT>" if version_number is None else version_number <EOL> log_verbose ( "<STR_LIT>" % <EOL> ( executable_name , ver_disp ) ) <EOL> exe_version_tuples = find_all_executables ( executable_name ) <EOL> if len ( exe_version_tuples ) > <NUM_LIT:0> : <EOL> selected_exe = best_executable_match ( executable_name , <EOL> exe_version_tuples , <EOL> version_info , <EOL> version_check_pref = <EOL> version_check_pref ) <EOL> if selected_exe is not None : <EOL> log_info ( "<STR_LIT>" % <EOL> ( executable_name , <EOL> selected_exe . path , <EOL> selected_exe . version ) ) <EOL> return selected_exe <EOL> msg = ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % <EOL> ( executable_name , ver_disp , mongodb_edition , ver_disp , <EOL> "<STR_LIT>" % mongodb_edition if <EOL> mongodb_edition != MongoDBEdition . COMMUNITY else "<STR_LIT>" , <EOL> os . getenv ( "<STR_LIT>" ) , <EOL> mongo_home , <EOL> mongo_installs_dir ) ) <EOL> raise MongoctlException ( msg ) <EOL> def find_all_executables ( executable_name ) : <EOL> executables_found = [ ] <EOL> path_executable = which ( executable_name ) <EOL> if path_executable is not None : <EOL> add_to_executables_found ( executables_found , path_executable ) <EOL> mongo_home = os . getenv ( MONGO_HOME_ENV_VAR ) <EOL> if mongo_home is not None : <EOL> mongo_home = resolve_path ( mongo_home ) <EOL> mongo_home_exe = get_mongo_home_exe ( mongo_home , executable_name ) <EOL> add_to_executables_found ( executables_found , mongo_home_exe ) <EOL> mongo_installs_dir = config . get_mongodb_installs_dir ( ) <EOL> if mongo_installs_dir is not None : <EOL> if os . path . exists ( mongo_installs_dir ) : <EOL> for mongo_installation in os . listdir ( mongo_installs_dir ) : <EOL> child_mongo_home = os . path . join ( mongo_installs_dir , <EOL> mongo_installation ) <EOL> child_mongo_exe = get_mongo_home_exe ( child_mongo_home , <EOL> executable_name ) <EOL> add_to_executables_found ( executables_found , child_mongo_exe ) <EOL> return get_exe_version_tuples ( executables_found ) <EOL> def add_to_executables_found ( executables_found , executable ) : <EOL> if is_valid_mongo_exe ( executable ) : <EOL> if executable not in executables_found : <EOL> executables_found . append ( executable ) <EOL> else : <EOL> log_verbose ( "<STR_LIT>" % executable ) <EOL> def best_executable_match ( executable_name , <EOL> exe_version_tuples , <EOL> version_object , <EOL> version_check_pref = VersionPreference . EXACT ) : <EOL> exe_versions_str = exe_version_tuples_to_strs ( exe_version_tuples ) <EOL> log_verbose ( "<STR_LIT>" <EOL> "<STR_LIT>" % ( executable_name , version_object , <EOL> exe_versions_str ) ) <EOL> if version_object is None : <EOL> log_verbose ( "<STR_LIT>" <EOL> "<STR_LIT>" % executable_name ) <EOL> version_check_pref = VersionPreference . DEFAULT <EOL> mapping = { <EOL> VersionPreference . EXACT : exact_exe_version_match , <EOL> VersionPreference . MAJOR_GE : major_ge_exe_version_match , <EOL> VersionPreference . LATEST_STABLE : latest_stable_exe , <EOL> VersionPreference . EXACT_OR_MINOR : exact_or_minor_exe_version_match , <EOL> VersionPreference . LATEST_MINOR : minor_exe_version_match , <EOL> VersionPreference . DEFAULT : default_match , <EOL> } <EOL> match_func = mapping [ version_check_pref ] <EOL> return match_func ( executable_name , exe_version_tuples , version_object ) <EOL> def default_match ( executable_name , exe_version_tuples , version ) : <EOL> default_exe = latest_stable_exe ( executable_name , exe_version_tuples ) <EOL> if default_exe is None : <EOL> log_verbose ( "<STR_LIT>" <EOL> "<STR_LIT>" % ( executable_name , executable_name ) ) <EOL> default_exe = latest_exe ( executable_name , exe_version_tuples ) <EOL> return default_exe <EOL> def exact_exe_version_match ( executable_name , exe_version_tuples , version ) : <EOL> for mongo_exe , exe_version in exe_version_tuples : <EOL> if exe_version == version : <EOL> return mongo_exe_object ( mongo_exe , exe_version ) <EOL> return None <EOL> def latest_stable_exe ( executable_name , exe_version_tuples , version = None ) : <EOL> log_verbose ( "<STR_LIT>" % executable_name ) <EOL> stable_exes = [ ] <EOL> for mongo_exe , exe_version in exe_version_tuples : <EOL> release_num = exe_version . parts [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] <EOL> if ( release_num % <NUM_LIT:2> ) == <NUM_LIT:0> : <EOL> stable_exes . append ( ( mongo_exe , exe_version ) ) <EOL> return latest_exe ( executable_name , stable_exes ) <EOL> def latest_exe ( executable_name , exe_version_tuples , version = None ) : <EOL> if len ( exe_version_tuples ) == <NUM_LIT:0> : <EOL> return None <EOL> exe_version_tuples . sort ( key = lambda t : t [ <NUM_LIT:1> ] , reverse = True ) <EOL> exe = exe_version_tuples [ <NUM_LIT:0> ] <EOL> return mongo_exe_object ( exe [ <NUM_LIT:0> ] , exe [ <NUM_LIT:1> ] ) <EOL> def major_ge_exe_version_match ( executable_name , exe_version_tuples , version ) : <EOL> compatible_exes = [ ] <EOL> for mongo_exe , exe_version in exe_version_tuples : <EOL> if ( exe_version . edition == version . edition and <EOL> exe_version . parts [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] >= version . parts [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] ) : <EOL> compatible_exes . append ( ( mongo_exe , exe_version ) ) <EOL> if len ( compatible_exes ) == <NUM_LIT:0> : <EOL> return None <EOL> compatible_exes . sort ( key = lambda t : t [ <NUM_LIT:1> ] ) <EOL> exe = compatible_exes [ - <NUM_LIT:1> ] <EOL> return mongo_exe_object ( exe [ <NUM_LIT:0> ] , exe [ <NUM_LIT:1> ] ) <EOL> def exact_or_minor_exe_version_match ( executable_name , <EOL> exe_version_tuples , <EOL> version ) : <EOL> """<STR_LIT>""" <EOL> exe = exact_exe_version_match ( executable_name , <EOL> exe_version_tuples , <EOL> version ) <EOL> if not exe : <EOL> exe = minor_exe_version_match ( executable_name , <EOL> exe_version_tuples , <EOL> version ) <EOL> return exe <EOL> def minor_exe_version_match ( executable_name , <EOL> exe_version_tuples , <EOL> version ) : <EOL> compatible_exes = [ ] <EOL> for mongo_exe , exe_version in exe_version_tuples : <EOL> if ( exe_version . edition == version . edition and <EOL> exe_version . parts [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] == version . parts [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] and <EOL> exe_version . parts [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] == version . parts [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] ) : <EOL> compatible_exes . append ( ( mongo_exe , exe_version ) ) <EOL> if len ( compatible_exes ) == <NUM_LIT:0> : <EOL> return None <EOL> compatible_exes . sort ( key = lambda t : t [ <NUM_LIT:1> ] ) <EOL> exe = compatible_exes [ - <NUM_LIT:1> ] <EOL> return mongo_exe_object ( exe [ <NUM_LIT:0> ] , exe [ <NUM_LIT:1> ] ) <EOL> def get_exe_version_tuples ( executables ) : <EOL> exe_ver_tuples = [ ] <EOL> for mongo_exe in executables : <EOL> try : <EOL> exe_version = mongo_exe_version ( mongo_exe ) <EOL> exe_ver_tuples . append ( ( mongo_exe , exe_version ) ) <EOL> except Exception , e : <EOL> log_exception ( e ) <EOL> log_verbose ( "<STR_LIT>" % ( mongo_exe , e ) ) <EOL> return exe_ver_tuples <EOL> def exe_version_tuples_to_strs ( exe_ver_tuples ) : <EOL> strs = [ ] <EOL> for mongo_exe , exe_version in exe_ver_tuples : <EOL> strs . append ( "<STR_LIT>" % ( mongo_exe , exe_version ) ) <EOL> return "<STR_LIT:\n>" . join ( strs ) <EOL> def is_valid_mongo_exe ( path ) : <EOL> return path is not None and is_exe ( path ) <EOL> def get_mongo_home_exe ( mongo_home , executable_name ) : <EOL> return os . path . join ( mongo_home , '<STR_LIT>' , executable_name ) <EOL> def mongo_exe_version ( mongo_exe ) : <EOL> mongod_path = os . path . join ( os . path . dirname ( mongo_exe ) , "<STR_LIT>" ) <EOL> try : <EOL> re_expr = "<STR_LIT>" <EOL> vers_spew = execute_command ( [ mongod_path , "<STR_LIT>" ] ) <EOL> vers_spew_line = vers_spew . split ( '<STR_LIT:\n>' ) [ <NUM_LIT:0> ] <EOL> vers_grep = re . findall ( re_expr , vers_spew_line ) <EOL> help_spew = execute_command ( [ mongod_path , "<STR_LIT>" ] ) <EOL> full_version = vers_grep [ - <NUM_LIT:1> ] [ <NUM_LIT:0> ] <EOL> if "<STR_LIT>" in vers_spew or "<STR_LIT>" in vers_spew : <EOL> edition = MongoDBEdition . ENTERPRISE <EOL> elif "<STR_LIT>" in help_spew : <EOL> edition = MongoDBEdition . COMMUNITY_SSL <EOL> else : <EOL> edition = MongoDBEdition . COMMUNITY <EOL> result = make_version_info ( full_version , edition = edition ) <EOL> if result is not None : <EOL> return result <EOL> else : <EOL> raise MongoctlException ( "<STR_LIT>" <EOL> "<STR_LIT>" % mongod_path ) <EOL> except Exception , e : <EOL> log_exception ( e ) <EOL> raise MongoctlException ( "<STR_LIT>" <EOL> "<STR_LIT>" % ( mongod_path , e ) ) <EOL> class MongoExeObject ( ) : <EOL> pass <EOL> def mongo_exe_object ( exe_path , exe_version ) : <EOL> exe_obj = MongoExeObject ( ) <EOL> exe_obj . path = exe_path <EOL> exe_obj . version = exe_version <EOL> return exe_obj <EOL> def options_to_command_args ( args ) : <EOL> command_args = [ ] <EOL> for ( arg_name , arg_val ) in sorted ( args . iteritems ( ) ) : <EOL> if not arg_val : <EOL> continue <EOL> elif arg_val is True : <EOL> command_args . append ( "<STR_LIT>" % arg_name ) <EOL> else : <EOL> command_args . append ( "<STR_LIT>" % arg_name ) <EOL> command_args . append ( str ( arg_val ) ) <EOL> return command_args <EOL> def is_server_or_cluster_db_address ( value ) : <EOL> """<STR_LIT>""" <EOL> id_path = value . split ( "<STR_LIT:/>" ) <EOL> id = id_path [ <NUM_LIT:0> ] <EOL> return len ( id_path ) <= <NUM_LIT:2> and ( repository . lookup_server ( id ) or <EOL> repository . lookup_cluster ( id ) ) <EOL> def is_db_address ( value ) : <EOL> """<STR_LIT>""" <EOL> return value and ( is_mongo_uri ( value ) or <EOL> is_server_or_cluster_db_address ( value ) ) <EOL> def is_dbpath ( value ) : <EOL> """<STR_LIT>""" <EOL> value = resolve_path ( value ) <EOL> return os . path . exists ( value ) <EOL> def find__all_mongo_installations ( ) : <EOL> all_installs = [ ] <EOL> all_mongod_exes = find_all_executables ( '<STR_LIT>' ) <EOL> for exe_path , exe_version in all_mongod_exes : <EOL> install_dir = os . path . dirname ( os . path . dirname ( exe_path ) ) <EOL> all_installs . append ( ( install_dir , exe_version ) ) <EOL> return all_installs <EOL> def get_mongo_installation ( version_info ) : <EOL> for install_dir , install_version in find__all_mongo_installations ( ) : <EOL> if install_version == version_info : <EOL> return install_dir <EOL> return None </s>
