def find_all_executables(executable_name): # create a list of all available executables found and then return the best # match if applicable executables_found = [] ####### Look in $PATH path_executable = which(executable_name) if path_executable is not None: add_to_executables_found(executables_found, path_executable) #### Look in $MONGO_HOME if set mongo_home = os.getenv(MONGO_HOME_ENV_VAR) if mongo_home is not None: mongo_home = resolve_path(mongo_home) mongo_home_exe = get_mongo_home_exe(mongo_home, executable_name) add_to_executables_found(executables_found, mongo_home_exe) # Look in mongod_installs_dir if set mongo_installs_dir = config.get_mongodb_installs_dir() if mongo_installs_dir is not None: if os.path.exists(mongo_installs_dir): for mongo_installation in os.listdir(mongo_installs_dir): child_mongo_home = os.path.join(mongo_installs_dir, mongo_installation) child_mongo_exe = get_mongo_home_exe(child_mongo_home, executable_name) add_to_executables_found(executables_found, child_mongo_exe) return get_exe_version_tuples(executables_found)
def get_mongo_executable(version_info, executable_name, version_check_pref=VersionPreference.EXACT): mongo_home = os.getenv(MONGO_HOME_ENV_VAR) mongo_installs_dir = config.get_mongodb_installs_dir() version_number = version_info and version_info.version_number mongodb_edition = version_info and (version_info.edition or MongoDBEdition.COMMUNITY) ver_disp = "[Unspecified]" if version_number is None else version_number log_verbose("Looking for a compatible %s for mongoVersion=%s." % (executable_name, ver_disp)) exe_version_tuples = find_all_executables(executable_name) if len(exe_version_tuples) > 0: selected_exe = best_executable_match(executable_name, exe_version_tuples, version_info, version_check_pref= version_check_pref) if selected_exe is not None: log_info("Using %s at '%s' version '%s'..." % (executable_name, selected_exe.path, selected_exe.version)) return selected_exe ## ok nothing found at all. wtf case msg = ("Unable to find a compatible '%s' executable " "for version %s (edition %s). You may need to run 'mongoctl " "install-mongodb %s %s' to install it.\n\n" "Here is your enviroment:\n\n" "$PATH=%s\n\n" "$MONGO_HOME=%s\n\n" "mongoDBInstallationsDirectory=%s (in mongoctl.config)" % (executable_name, ver_disp, mongodb_edition, ver_disp, "--edition %s" % mongodb_edition if mongodb_edition != MongoDBEdition.COMMUNITY else "", os.getenv("PATH"), mongo_home, mongo_installs_dir)) raise MongoctlException(msg)
def get_mongo_executable(version_info, executable_name, version_check_pref=VersionPreference.EXACT): mongo_home = os.getenv(MONGO_HOME_ENV_VAR) mongo_installs_dir = config.get_mongodb_installs_dir() version_number = version_info and version_info.version_number mongodb_edition = version_info and (version_info.edition or MongoDBEdition.COMMUNITY) ver_disp = "[Unspecified]" if version_number is None else version_number log_verbose("Looking for a compatible %s for mongoVersion=%s." % (executable_name, ver_disp)) exe_version_tuples = find_all_executables(executable_name) if len(exe_version_tuples) > 0: selected_exe = best_executable_match(executable_name, exe_version_tuples, version_info, version_check_pref= version_check_pref) if selected_exe is not None: log_info("Using %s at '%s' version '%s'..." % (executable_name, selected_exe.path, selected_exe.version)) return selected_exe ## ok nothing found at all log_error("Unable to find a compatible '%s' executable " "for version %s (edition %s). You may need to run 'mongoctl " "install-mongodb %s %s' to install it.\n\n" "Here is your enviroment:\n\n" "$PATH=%s\n\n" "$MONGO_HOME=%s\n\n" "mongoDBInstallationsDirectory=%s (in mongoctl.config)" % (executable_name, ver_disp, mongodb_edition, ver_disp, "--edition %s" % mongodb_edition if mongodb_edition != MongoDBEdition.COMMUNITY else "", os.getenv("PATH"), mongo_home, mongo_installs_dir)) raise MongoctlException("Unable to find a compatible '%s' executable." % executable_name)
def get_mongo_executable(server_version, executable_name, version_check_pref=VERSION_PREF_EXACT): mongo_home = os.getenv(MONGO_HOME_ENV_VAR) mongo_installs_dir = config.get_mongodb_installs_dir() ver_disp = "[Unspecified]" if server_version is None else server_version log_verbose("Looking for a compatible %s for mongoVersion=%s." % (executable_name, ver_disp)) exe_version_tuples = find_all_executables(executable_name) if len(exe_version_tuples) > 0: selected_exe = best_executable_match(executable_name, exe_version_tuples, server_version, version_check_pref= version_check_pref) if selected_exe is not None: log_info("Using %s at '%s' version '%s'..." % (executable_name, selected_exe.path, selected_exe.version)) return selected_exe ## ok nothing found at all. wtf case msg = ("Unable to find a compatible '%s' executable " "for version %s. You may need to run 'mongoctl install-mongodb %s'" " to install it.\n\n" "Here is your enviroment:\n\n" "$PATH=%s\n\n" "$MONGO_HOME=%s\n\n" "mongoDBInstallationsDirectory=%s (in mongoctl.config)" % (executable_name, ver_disp, ver_disp, os.getenv("PATH"), mongo_home, mongo_installs_dir)) raise MongoctlException(msg)
def install_mongodb(mongodb_version=None, mongodb_edition=None, from_source=False, build_threads=1, build_tmp_dir=None, include_only=None): if mongodb_version is None: mongodb_version = fetch_latest_stable_version() log_info("Installing latest stable MongoDB version '%s'..." % mongodb_version) version_info = make_version_info(mongodb_version, mongodb_edition) mongo_installation = get_mongo_installation(version_info) mongodb_edition = version_info.edition if mongo_installation is not None: # no-op log_info("You already have MongoDB %s installed ('%s'). " "Nothing to do." % (version_info, mongo_installation)) return mongo_installation target_dir = get_install_target_dir(mongodb_version, mongodb_edition) if os.path.exists(target_dir): raise MongoctlException("Target directory '%s' already exists" % target_dir) if mongodb_edition not in MongoDBEdition.ALL: raise MongoctlException("Unknown edition '%s'. Please select from %s" % (mongodb_edition, MongoDBEdition.ALL)) if from_source: install_from_source(mongodb_version, mongodb_edition, build_threads=build_threads, build_tmp_dir=build_tmp_dir) return bits = platform.architecture()[0].replace("bit", "") os_name = platform.system().lower() if os_name == 'darwin' and platform.mac_ver(): os_name = "osx" mongodb_installs_dir = config.get_mongodb_installs_dir() if not mongodb_installs_dir: raise MongoctlException("No mongoDBInstallationsDirectory configured" " in mongoctl.config") # ensure the mongo installs dir ensure_dir(mongodb_installs_dir) platform_spec = get_validate_platform_spec(os_name, bits) log_verbose("INSTALL_MONGODB: OS='%s' , BITS='%s' , VERSION='%s', " "PLATFORM_SPEC='%s'" % (os_name, bits, version_info, platform_spec)) # XXX LOOK OUT! Two processes installing same version simultaneously => BAD. # TODO: mutex to protect the following try: ## download the url archive_path = download_mongodb_binary(mongodb_version, mongodb_edition) archive_name = os.path.basename(archive_path) mongo_dir_name = extract_archive(archive_name) # apply include_only if specified if include_only: apply_include_only(mongo_dir_name, include_only) log_info("Deleting archive %s" % archive_name) os.remove(archive_name) target_dir_name = os.path.basename(target_dir) os.rename(mongo_dir_name, target_dir_name) # move target to mongodb install dir (Unless target is already there! # i.e current working dir == mongodb_installs_dir if os.getcwd() != mongodb_installs_dir: log_info("Moving extracted folder to %s" % mongodb_installs_dir) shutil.move(target_dir_name, mongodb_installs_dir) install_dir = os.path.join(mongodb_installs_dir, mongo_dir_name) # install validation validate_mongodb_install(target_dir) log_info("MongoDB %s installed successfully!" % version_info) return install_dir except Exception, e: log_exception(e) msg = "Failed to install MongoDB '%s'. Cause: %s" % (version_info, e) raise MongoctlException(msg)
def get_install_target_dir(mongodb_version, mongodb_edition): template = "mongodb-{platform_spec}-{mongodb_edition}-{mongodb_version}" args = get_template_args(mongodb_version, mongodb_edition) dir_name = template.format(**args) return os.path.join(config.get_mongodb_installs_dir(), dir_name)
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import unittest import os import shutil import mongoctl.config as config from mongoctl.tests.test_base import MongoctlTestBase TEMP_MONGO_INSTALL_DIR = "temp_mongo_installs_dir" MONGO_INSTALL_DIR = config.get_mongodb_installs_dir() class InstallTest(MongoctlTestBase): ########################################################################### def setUp(self): print("setUp(): Temporarily setting mongoDBInstallationsDirectory=%s" % TEMP_MONGO_INSTALL_DIR) config.set_mongodb_installs_dir(TEMP_MONGO_INSTALL_DIR) super(InstallTest, self).setUp() ########################################################################### def tearDown(self): super(InstallTest, self).tearDown()
def do_install_mongodb(os_name, bits, version_info): mongodb_installs_dir = config.get_mongodb_installs_dir() if not mongodb_installs_dir: raise MongoctlException("No mongoDBInstallationsDirectory configured" " in mongoctl.config") platform_spec = get_validate_platform_spec(os_name, bits) log_verbose("INSTALL_MONGODB: OS='%s' , BITS='%s' , VERSION='%s', " "PLATFORM_SPEC='%s'" % (os_name, bits, version_info, platform_spec)) os_dist_name, os_dist_version = get_os_dist_info() if os_dist_name: dist_info = "(%s %s)" % (os_dist_name, os_dist_version) else: dist_info = "" log_info("Running install for %s %sbit %s to " "mongoDBInstallationsDirectory (%s)..." % (os_name, bits, dist_info, mongodb_installs_dir)) mongo_installation = get_mongo_installation(version_info) if mongo_installation is not None: # no-op log_info("You already have MongoDB %s installed ('%s'). " "Nothing to do." % (version_info, mongo_installation)) return mongo_installation url = get_download_url(os_name, platform_spec, os_dist_name, os_dist_version, version_info) archive_name = url.split("/")[-1] # Validate if the version exists response = urllib.urlopen(url) if response.getcode() != 200: msg = ("Unable to download from url '%s' (response code '%s'). " "It could be that version '%s' you specified does not exist." " Please double check the version you provide" % (url, response.getcode(), version_info)) raise MongoctlException(msg) mongo_dir_name = archive_name.replace(".tgz", "") install_dir = os.path.join(mongodb_installs_dir, mongo_dir_name) ensure_dir(mongodb_installs_dir) # XXX LOOK OUT! Two processes installing same version simultaneously => BAD. # TODO: mutex to protect the following if not dir_exists(install_dir): try: ## download the url download(url) extract_archive(archive_name) log_info("Moving extracted folder to %s" % mongodb_installs_dir) shutil.move(mongo_dir_name, mongodb_installs_dir) os.remove(archive_name) log_info("Deleting archive %s" % archive_name) log_info("MongoDB %s installed successfully!" % version_info) return install_dir except Exception, e: log_exception(e) log_error("Failed to install MongoDB '%s'. Cause: %s" % (version_info, e))
def do_install_mongodb(os_name, bits, version): if version is None: version = fetch_latest_stable_version() log_info("Installing latest stable MongoDB version '%s'..." % version) # validate version string elif not is_valid_version(version): raise MongoctlException("Invalid version '%s'. Please provide a" " valid MongoDB version." % version) mongodb_installs_dir = config.get_mongodb_installs_dir() if not mongodb_installs_dir: raise MongoctlException("No mongoDBInstallationsDirectory configured" " in mongoctl.config") platform_spec = get_validate_platform_spec(os_name, bits) log_info("Running install for %s %sbit to " "mongoDBInstallationsDirectory (%s)..." % (os_name, bits, mongodb_installs_dir)) mongo_installation = get_mongo_installation(version) if mongo_installation is not None: # no-op log_info("You already have MongoDB %s installed ('%s'). " "Nothing to do." % (version, mongo_installation)) return mongo_installation archive_name = "mongodb-%s-%s.tgz" % (platform_spec, version) url = "http://fastdl.mongodb.org/%s/%s" % (os_name, archive_name) # Validate if the version exists response = urllib.urlopen(url) if response.getcode() != 200: msg = ("Unable to download from url '%s' (response code '%s'). " "It could be that version '%s' you specified does not exist." " Please double check the version you provide" % (url, response.getcode(), version)) raise MongoctlException(msg) mongo_dir_name = "mongodb-%s-%s" % (platform_spec, version) install_dir = os.path.join(mongodb_installs_dir, mongo_dir_name) ensure_dir(mongodb_installs_dir) # XXX LOOK OUT! Two processes installing same version simultaneously => BAD. # TODO: mutex to protect the following if not dir_exists(install_dir): try: ## download the url download(url) extract_archive(archive_name) log_info("Moving extracted folder to %s" % mongodb_installs_dir) shutil.move(mongo_dir_name, mongodb_installs_dir) os.remove(archive_name) log_info("Deleting archive %s" % archive_name) log_info("MongoDB %s installed successfully!" % version) return install_dir except Exception, e: log_exception(e) log_error("Failed to install MongoDB '%s'. Cause: %s" % (version, e))
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import unittest import os import shutil import mongoctl.config as config from mongoctl.tests.test_base import MongoctlTestBase TEMP_MONGO_INSTALL_DIR = "temp_mongo_installs_dir" MONGO_INSTALL_DIR = config.get_mongodb_installs_dir() class InstallTest(MongoctlTestBase): ########################################################################### def setUp(self): print("setUp(): Temporarily setting mongoDBInstallationsDirectory=%s" % TEMP_MONGO_INSTALL_DIR) config.set_mongodb_installs_dir(TEMP_MONGO_INSTALL_DIR) super(InstallTest, self).setUp() ########################################################################### def tearDown(self): super(InstallTest, self).tearDown() if os.path.exists(TEMP_MONGO_INSTALL_DIR):