summaryrefslogtreecommitdiff
path: root/buildscripts/resmokelib/setup_multiversion
diff options
context:
space:
mode:
authorMikhail Shchatko <mikhail.shchatko@mongodb.com>2020-11-18 18:30:54 +0300
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-12-01 07:00:30 +0000
commitda2fa0281d30cbb0f320b868a4af1ea77dfb97c5 (patch)
tree9c586c5bd8b300cfe7c0a35a1a3418f877f2a2f2 /buildscripts/resmokelib/setup_multiversion
parent0345f786151b19602c3ef9136db68eda9af5ebe3 (diff)
downloadmongo-da2fa0281d30cbb0f320b868a4af1ea77dfb97c5.tar.gz
SERVER-52535 Use evergreen and github API to get the bin version for each release and for the latest
Diffstat (limited to 'buildscripts/resmokelib/setup_multiversion')
-rw-r--r--buildscripts/resmokelib/setup_multiversion/config.py37
-rw-r--r--buildscripts/resmokelib/setup_multiversion/download.py141
-rw-r--r--buildscripts/resmokelib/setup_multiversion/evergreen_conn.py143
-rw-r--r--buildscripts/resmokelib/setup_multiversion/github_conn.py28
-rw-r--r--buildscripts/resmokelib/setup_multiversion/setup_multiversion.py236
5 files changed, 502 insertions, 83 deletions
diff --git a/buildscripts/resmokelib/setup_multiversion/config.py b/buildscripts/resmokelib/setup_multiversion/config.py
new file mode 100644
index 00000000000..72cb82a4fb3
--- /dev/null
+++ b/buildscripts/resmokelib/setup_multiversion/config.py
@@ -0,0 +1,37 @@
+"""Setup multiversion config."""
+from typing import List
+
+SETUP_MULTIVERSION_CONFIG = "etc/setup_multiversion_config.yml"
+
+
+class Buildvariant:
+ """Class represents buildvariant in setup multiversion config."""
+
+ name: str
+ edition: str
+ platform: str
+ architecture: str
+ versions: List[str]
+
+ def __init__(self, buildvariant_yaml: dict):
+ """Initialize."""
+ self.name = buildvariant_yaml.get("name", "")
+ self.edition = buildvariant_yaml.get("edition", "")
+ self.platform = buildvariant_yaml.get("platform", "")
+ self.architecture = buildvariant_yaml.get("architecture", "")
+ self.versions = buildvariant_yaml.get("versions", [])
+
+
+class SetupMultiversionConfig:
+ """Class represents setup multiversion config."""
+
+ evergreen_projects: List[str]
+ evergreen_buildvariants: List[Buildvariant]
+
+ def __init__(self, raw_yaml: dict):
+ """Initialize."""
+ self.evergreen_projects = raw_yaml.get("evergreen_projects", [])
+ self.evergreen_buildvariants = []
+ buildvariants_raw_yaml = raw_yaml.get("evergreen_buildvariants", "")
+ for buildvariant_yaml in buildvariants_raw_yaml:
+ self.evergreen_buildvariants.append(Buildvariant(buildvariant_yaml))
diff --git a/buildscripts/resmokelib/setup_multiversion/download.py b/buildscripts/resmokelib/setup_multiversion/download.py
new file mode 100644
index 00000000000..fc9368dec0b
--- /dev/null
+++ b/buildscripts/resmokelib/setup_multiversion/download.py
@@ -0,0 +1,141 @@
+"""Helper functions to download."""
+import contextlib
+import errno
+import os
+import shutil
+import tarfile
+import tempfile
+import zipfile
+
+import boto3
+import structlog
+from botocore import UNSIGNED
+from botocore.config import Config
+from botocore.exceptions import ClientError
+
+S3_BUCKET = "mciuploads"
+
+LOGGER = structlog.getLogger(__name__)
+
+
+class DownloadError(Exception):
+ """Errors in download.py."""
+
+ pass
+
+
+def download_mongodb(url):
+ """Download file from S3 bucket by a given URL."""
+
+ if not url:
+ raise DownloadError("Download URL not found.")
+
+ LOGGER.info("Downloading mongodb.", url=url)
+ s3_key = url.split('/', 3)[-1].replace(f"{S3_BUCKET}/", "")
+ filename = os.path.join(tempfile.gettempdir(), url.split('/')[-1])
+
+ LOGGER.debug("Downloading mongodb from S3.", s3_bucket=S3_BUCKET, s3_key=s3_key,
+ filename=filename)
+ s3_client = boto3.client("s3", config=Config(signature_version=UNSIGNED))
+ try:
+ s3_client.download_file(S3_BUCKET, s3_key, filename)
+ except ClientError as s3_client_error:
+ LOGGER.error("Download failed due to S3 client error.")
+ raise s3_client_error
+ except Exception as ex: # pylint: disable=broad-except
+ LOGGER.error("Download failed.")
+ raise ex
+ else:
+ LOGGER.info("Download completed.", filename=filename)
+
+ return filename
+
+
+def extract_archive(archive_file, install_dir):
+ """Uncompress file and return root of extracted directory."""
+
+ LOGGER.info("Extracting archive data.", archive=archive_file, install_dir=install_dir)
+ temp_dir = tempfile.mkdtemp()
+ archive_name = os.path.basename(archive_file)
+ install_subdir, file_suffix = os.path.splitext(archive_name)
+
+ if file_suffix == ".zip":
+ # Support .zip downloads, used for Windows binaries.
+ with zipfile.ZipFile(archive_file) as zip_handle:
+ first_file = zip_handle.namelist()[0]
+ zip_handle.extractall(temp_dir)
+ elif file_suffix == ".tgz":
+ # Support .tgz downloads, used for Linux binaries.
+ with contextlib.closing(tarfile.open(archive_file, "r:gz")) as tar_handle:
+ first_file = tar_handle.getnames()[0]
+ tar_handle.extractall(path=temp_dir)
+ else:
+ raise DownloadError(f"Unsupported file extension {file_suffix}")
+
+ extracted_root_dir = os.path.join(temp_dir, os.path.dirname(first_file))
+ temp_install_dir = tempfile.mkdtemp()
+ shutil.move(extracted_root_dir, os.path.join(temp_install_dir, install_subdir))
+
+ try:
+ os.makedirs(install_dir)
+ except OSError as exc:
+ if exc.errno == errno.EEXIST and os.path.isdir(install_dir):
+ pass
+ else:
+ raise
+
+ already_downloaded = os.path.isdir(os.path.join(install_dir, install_subdir))
+ if not already_downloaded:
+ shutil.move(os.path.join(temp_install_dir, install_subdir), install_dir)
+
+ shutil.rmtree(temp_dir)
+ shutil.rmtree(temp_install_dir)
+
+ installed_dir = os.path.join(install_dir, install_subdir)
+ LOGGER.info("Extract archive completed.", installed_dir=installed_dir)
+
+ return installed_dir
+
+
+def symlink_version(version, installed_dir, link_dir):
+ """Symlink the binaries in the 'installed_dir' to the 'link_dir'."""
+ try:
+ os.makedirs(link_dir)
+ except OSError as exc:
+ if exc.errno == errno.EEXIST and os.path.isdir(link_dir):
+ pass
+ else:
+ raise
+
+ for executable in os.listdir(os.path.join(installed_dir, "bin")):
+
+ executable_name, executable_extension = os.path.splitext(executable)
+ link_name = f"{executable_name}-{version}{executable_extension}"
+
+ try:
+ executable = os.path.join(installed_dir, "bin", executable)
+ executable_link = os.path.join(link_dir, link_name)
+
+ if os.name == "nt":
+ # os.symlink is not supported on Windows, use a direct method instead.
+ def symlink_ms(source, symlink_name):
+ """Provide symlink for Windows."""
+ import ctypes
+ csl = ctypes.windll.kernel32.CreateSymbolicLinkW
+ csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32)
+ csl.restype = ctypes.c_ubyte
+ flags = 1 if os.path.isdir(source) else 0
+ if csl(symlink_name, source.replace("/", "\\"), flags) == 0:
+ raise ctypes.WinError()
+
+ os.symlink = symlink_ms
+ os.symlink(executable, executable_link)
+ LOGGER.debug("Symlink created.", executable=executable, executable_link=executable_link)
+
+ except OSError as exc:
+ if exc.errno == errno.EEXIST:
+ pass
+ else:
+ raise
+
+ LOGGER.info("Symlinks for all executables are created in the directory.", link_dir=link_dir)
diff --git a/buildscripts/resmokelib/setup_multiversion/evergreen_conn.py b/buildscripts/resmokelib/setup_multiversion/evergreen_conn.py
new file mode 100644
index 00000000000..26511a71bbc
--- /dev/null
+++ b/buildscripts/resmokelib/setup_multiversion/evergreen_conn.py
@@ -0,0 +1,143 @@
+"""Helper functions to interact with evergreen."""
+import os
+
+import structlog
+from evergreen import RetryingEvergreenApi
+from requests import HTTPError
+
+EVERGREEN_HOST = "https://evergreen.mongodb.com"
+EVERGREEN_CONFIG_LOCATIONS = (
+ # Common for machines in Evergreen
+ os.path.join(os.getcwd(), ".evergreen.yml"),
+ # Common for local machines
+ os.path.expanduser(os.path.join("~", ".evergreen.yml")),
+)
+
+GENERIC_EDITION = "base"
+GENERIC_PLATFORM = "linux_x86_64"
+GENERIC_ARCHITECTURE = "x86_64"
+
+LOGGER = structlog.getLogger(__name__)
+
+
+class EvergreenConnError(Exception):
+ """Errors in evergreen_conn.py."""
+
+ pass
+
+
+def get_evergreen_api(evergreen_config):
+ """Return evergreen API."""
+ config_to_pass = evergreen_config
+ if not config_to_pass:
+ # Pickup the first config file found in common locations.
+ for file in EVERGREEN_CONFIG_LOCATIONS:
+ if os.path.isfile(file):
+ config_to_pass = file
+ break
+ try:
+ evg_api = RetryingEvergreenApi.get_api(config_file=config_to_pass)
+ except Exception as ex:
+ LOGGER.error("Most likely something is wrong with evergreen config file.",
+ config_file=config_to_pass)
+ raise ex
+ else:
+ return evg_api
+
+
+def get_buildvariant_name(config, edition, platform, architecture, major_minor_version):
+ """Return Evergreen buildvariant name."""
+
+ buildvariant_name = ""
+ evergreen_buildvariants = config.evergreen_buildvariants
+
+ for buildvariant in evergreen_buildvariants:
+ if (buildvariant.edition == edition and buildvariant.platform == platform
+ and buildvariant.architecture == architecture):
+ versions = buildvariant.versions
+ if major_minor_version in versions:
+ buildvariant_name = buildvariant.name
+ break
+ elif not versions:
+ buildvariant_name = buildvariant.name
+
+ return buildvariant_name
+
+
+def get_generic_buildvariant_name(config, major_minor_version):
+ """Return Evergreen buildvariant name for generic platform."""
+
+ LOGGER.info("Falling back to generic architecture.", edition=GENERIC_EDITION,
+ platform=GENERIC_PLATFORM, architecture=GENERIC_ARCHITECTURE)
+
+ generic_buildvariant_name = get_buildvariant_name(
+ config=config, edition=GENERIC_EDITION, platform=GENERIC_PLATFORM,
+ architecture=GENERIC_ARCHITECTURE, major_minor_version=major_minor_version)
+
+ if not generic_buildvariant_name:
+ raise EvergreenConnError("Generic architecture buildvariant not found.")
+
+ return generic_buildvariant_name
+
+
+def get_evergreen_project_and_version(config, evg_api, commit_hash):
+ """Return evergreen project and version by commit hash."""
+
+ for evg_project in config.evergreen_projects:
+ try:
+ version_id = evg_project.replace("-", "_") + "_" + commit_hash
+ evg_version = evg_api.version_by_id(version_id)
+ except HTTPError:
+ continue
+ else:
+ LOGGER.debug("Found evergreen version.",
+ evergreen_version=f"{EVERGREEN_HOST}/version/{evg_version.version_id}")
+ return evg_project, evg_version
+
+ raise EvergreenConnError(f"Evergreen version for commit hash {commit_hash} not found.")
+
+
+def get_evergreen_versions(evg_api, evg_project):
+ """Return the list of evergreen versions by evergreen project name."""
+ return evg_api.versions_by_project(evg_project)
+
+
+def get_compile_artifact_urls(evg_api, evg_version, buildvariant_name):
+ """Return compile urls from buildvariant in Evergreen version."""
+ compile_artifact_urls = {}
+
+ try:
+ build_id = evg_version.build_variants_map[buildvariant_name]
+ except KeyError:
+ raise EvergreenConnError(f"Buildvariant {buildvariant_name} not found.")
+ else:
+ evg_build = evg_api.build_by_id(build_id)
+ LOGGER.debug("Found evergreen build.", evergreen_build=f"{EVERGREEN_HOST}/build/{build_id}")
+ evg_tasks = evg_build.get_tasks()
+ compile_task = None
+ push_task = None
+
+ for evg_task in evg_tasks:
+ if evg_task.display_name == "compile":
+ compile_task = evg_task
+ if evg_task.display_name == "push":
+ push_task = evg_task
+ if compile_task and push_task:
+ break
+
+ if compile_task and push_task and compile_task.status == push_task.status == "success":
+ LOGGER.info("Found successful evergreen tasks.",
+ compile_task=f"{EVERGREEN_HOST}/task/{compile_task.task_id}",
+ push_task=f"{EVERGREEN_HOST}/task/{push_task.task_id}")
+ evg_artifacts = compile_task.artifacts
+ for artifact in evg_artifacts:
+ compile_artifact_urls[artifact.name] = artifact.url
+ elif compile_task and push_task:
+ LOGGER.warning("Found evergreen tasks, but they are not both successful.",
+ compile_task=f"{EVERGREEN_HOST}/task/{compile_task.task_id}",
+ push_task=f"{EVERGREEN_HOST}/task/{push_task.task_id}")
+ else:
+ LOGGER.error("There are no `compile` and/or 'push' tasks in the evergreen build.",
+ evergreen_build=f"{EVERGREEN_HOST}/build/{build_id}")
+
+ return compile_artifact_urls
diff --git a/buildscripts/resmokelib/setup_multiversion/github_conn.py b/buildscripts/resmokelib/setup_multiversion/github_conn.py
new file mode 100644
index 00000000000..83f31817a23
--- /dev/null
+++ b/buildscripts/resmokelib/setup_multiversion/github_conn.py
@@ -0,0 +1,28 @@
+"""Helper functions to interact with github."""
+from github import Github, GithubException
+
+
+class GithubConnError(Exception):
+ """Errors in github_conn.py."""
+
+ pass
+
+
+def get_git_tag_and_commit(github_oauth_token, version):
+ """Return git tag and commit hash by associating the version with git tag."""
+
+ github = Github(github_oauth_token)
+ repo = github.get_repo("mongodb/mongo")
+
+ try:
+ git_ref_list = list(repo.get_git_matching_refs(f"tags/r{version}"))
+ # If git tag fully matches the version, it will be only one git_ref in the list,
+ # otherwise picking up the latest git_ref
+ git_ref = git_ref_list[-1]
+ git_tag = repo.get_git_tag(git_ref.object.sha)
+ git_commit = repo.get_commit(git_tag.object.sha)
+
+ except (GithubException, IndexError):
+ raise GithubConnError(f"Commit hash for a version {version} not found.")
+
+ return git_tag.tag, git_commit.sha
diff --git a/buildscripts/resmokelib/setup_multiversion/setup_multiversion.py b/buildscripts/resmokelib/setup_multiversion/setup_multiversion.py
index a230476cba0..b8b2e46affb 100644
--- a/buildscripts/resmokelib/setup_multiversion/setup_multiversion.py
+++ b/buildscripts/resmokelib/setup_multiversion/setup_multiversion.py
@@ -7,102 +7,170 @@ enterprise builds.
"""
import logging
import os
+import re
import sys
-import tempfile
-import boto3
import structlog
-from botocore import UNSIGNED
-from botocore.config import Config
-from botocore.exceptions import ClientError
-from evergreen import RetryingEvergreenApi
+import yaml
from buildscripts.resmokelib.plugin import PluginInterface, Subcommand
+from buildscripts.resmokelib.setup_multiversion import config, download, evergreen_conn, github_conn
SUBCOMMAND = "setup-multiversion"
-EVERGREEN_CONFIG_LOCATIONS = (
- # Common for machines in Evergreen
- os.path.join(os.getcwd(), ".evergreen.yml"),
- # Common for local machines
- os.path.expanduser(os.path.join("~", ".evergreen.yml")),
-)
-S3_BUCKET = "mciuploads"
LOGGER = structlog.getLogger(__name__)
-def setup_logging():
- """Enable INFO level logging."""
+def setup_logging(debug=False):
+ """Enable logging."""
+ log_level = logging.DEBUG if debug else logging.INFO
logging.basicConfig(
format="[%(asctime)s - %(name)s - %(levelname)s] %(message)s",
- level=logging.INFO,
+ level=log_level,
stream=sys.stdout,
)
+ logging.getLogger("urllib3").setLevel(logging.WARNING)
+ logging.getLogger("s3transfer").setLevel(logging.WARNING)
+ logging.getLogger("botocore").setLevel(logging.WARNING)
+ logging.getLogger("boto3").setLevel(logging.WARNING)
+ logging.getLogger("evergreen").setLevel(logging.WARNING)
+ logging.getLogger("github").setLevel(logging.WARNING)
structlog.configure(logger_factory=structlog.stdlib.LoggerFactory())
-def get_evergreen_api(evergreen_config):
- """Return evergreen API."""
- config_to_pass = evergreen_config
- if not config_to_pass:
- # Pickup the first config file found in common locations.
- for file in EVERGREEN_CONFIG_LOCATIONS:
- if os.path.isfile(file):
- config_to_pass = file
- break
- try:
- evg_api = RetryingEvergreenApi.get_api(config_file=config_to_pass)
- except Exception as ex:
- LOGGER.error("Most likely something is wrong with evergreen config file.",
- config_file=config_to_pass)
- raise ex
- else:
- return evg_api
-
-
-def download_mongodb(url):
- """Download file from S3 bucket by a given URL."""
-
- LOGGER.info("Downloading mongodb.", url=url)
- s3_key = url.split('/', 3)[-1].replace(f"{S3_BUCKET}/", "")
- filename = os.path.join(tempfile.gettempdir(), url.split('/')[-1])
-
- LOGGER.info("Downloading mongodb from S3.", s3_bucket=S3_BUCKET, s3_key=s3_key,
- filename=filename)
- s3_client = boto3.client("s3", config=Config(signature_version=UNSIGNED))
- try:
- s3_client.download_file(S3_BUCKET, s3_key, filename)
- except ClientError as s3_client_error:
- LOGGER.error("Download failed due to S3 client error.")
- raise s3_client_error
- except Exception as ex: # pylint: disable=broad-except
- LOGGER.error("Download failed.")
- raise ex
- else:
- LOGGER.info("Download completed.", filename=filename)
-
- return filename
-
-
class SetupMultiversion(Subcommand):
- """Main class for the hang analyzer subcommand."""
+ """Main class for the setup multiversion subcommand."""
# pylint: disable=too-many-instance-attributes
def __init__(self, options):
"""Initialize."""
- self.install_dir = options.install_dir
- self.link_dir = options.link_dir
- self.edition = options.edition.lower()
- self.platform = options.platform.lower()
- self.architecture = options.architecture.lower()
+ setup_logging(options.debug)
+ cwd = os.getcwd()
+ self.install_dir = os.path.join(cwd, options.install_dir)
+ self.link_dir = os.path.join(cwd, options.link_dir)
+
+ self.edition = options.edition.lower() if options.edition else None
+ self.platform = options.platform.lower() if options.platform else None
+ self.architecture = options.architecture.lower() if options.architecture else None
self.use_latest = options.use_latest
self.versions = options.versions
- self.evg_api = get_evergreen_api(options.evergreen_config)
- self.git_token = options.git_token
+
+ self.evg_api = evergreen_conn.get_evergreen_api(options.evergreen_config)
+ # In evergreen github oauth token is stored as `token ******`, so we remove the leading part
+ self.github_oauth_token = options.github_oauth_token.replace(
+ "token ", "") if options.github_oauth_token else None
+ with open(config.SETUP_MULTIVERSION_CONFIG) as file_handle:
+ raw_yaml = yaml.safe_load(file_handle)
+ self.config = config.SetupMultiversionConfig(raw_yaml)
def execute(self):
"""Execute setup multiversion mongodb."""
- pass # Not implemented yet.
+
+ for version in self.versions:
+ LOGGER.info("Setting up version.", version=version)
+ LOGGER.info("Fetching download URL from Evergreen.")
+
+ try:
+ re.match(r"\d+\.\d+", version).group(0)
+ except AttributeError:
+ LOGGER.error(
+ "Input version is not recognized. Some correct examples: 4.0, 4.0.1, 4.0.0-rc0")
+ exit(1)
+
+ try:
+ urls = {}
+ if self.use_latest:
+ urls = self.get_latest_urls(version)
+ if not urls:
+ LOGGER.warning("Latest URL is not available or not requested, "
+ "we fallback to getting the URL for the version.")
+ urls = self.get_urls(version)
+
+ binaries_url = urls.get("Binaries", "")
+ mongodb_archive = download.download_mongodb(binaries_url)
+ installed_dir = download.extract_archive(mongodb_archive, self.install_dir)
+ os.remove(mongodb_archive)
+ download.symlink_version(version, installed_dir, self.link_dir)
+
+ except (github_conn.GithubConnError, evergreen_conn.EvergreenConnError,
+ download.DownloadError) as ex:
+ LOGGER.error(ex)
+ exit(1)
+
+ else:
+ LOGGER.info("Setup version completed.", version=version)
+ LOGGER.info("-" * 50)
+
+ def get_latest_urls(self, version):
+ """Return latest urls."""
+ urls = {}
+
+ evg_project = f"mongodb-mongo-v{version}"
+ if evg_project not in self.config.evergreen_projects:
+ return urls
+
+ LOGGER.debug("Found evergreen project.", evergreen_project=evg_project)
+ # Assuming that project names contain <major>.<minor> version
+ major_minor_version = version
+
+ buildvariant_name = self.get_buildvariant_name(major_minor_version)
+ LOGGER.debug("Found buildvariant.", buildvariant_name=buildvariant_name)
+
+ evg_versions = evergreen_conn.get_evergreen_versions(self.evg_api, evg_project)
+
+ for evg_version in evg_versions:
+ if buildvariant_name not in evg_version.build_variants_map:
+ buildvariant_name = self.fallback_to_generic_buildvariant(major_minor_version)
+
+ curr_urls = evergreen_conn.get_compile_artifact_urls(self.evg_api, evg_version,
+ buildvariant_name)
+ if "Binaries" in curr_urls:
+ urls = curr_urls
+ break
+
+ return urls
+
+ def get_urls(self, version):
+ """Return urls."""
+ git_tag, commit_hash = github_conn.get_git_tag_and_commit(self.github_oauth_token, version)
+ LOGGER.info("Found git attributes.", git_tag=git_tag, commit_hash=commit_hash)
+
+ evg_project, evg_version = evergreen_conn.get_evergreen_project_and_version(
+ self.config, self.evg_api, commit_hash)
+ LOGGER.debug("Found evergreen project.", evergreen_project=evg_project)
+ try:
+ major_minor_version = re.findall(r"\d+\.\d+", evg_project)[-1]
+ except IndexError:
+ major_minor_version = "master"
+
+ buildvariant_name = self.get_buildvariant_name(major_minor_version)
+ LOGGER.debug("Found buildvariant.", buildvariant_name=buildvariant_name)
+ if buildvariant_name not in evg_version.build_variants_map:
+ buildvariant_name = self.fallback_to_generic_buildvariant(major_minor_version)
+
+ urls = evergreen_conn.get_compile_artifact_urls(self.evg_api, evg_version,
+ buildvariant_name)
+
+ return urls
+
+ def get_buildvariant_name(self, major_minor_version):
+ """Return buildvariant name.
+
+ Wrapper around evergreen_conn.get_buildvariant_name().
+ """
+
+ return evergreen_conn.get_buildvariant_name(
+ config=self.config, edition=self.edition, platform=self.platform,
+ architecture=self.architecture, major_minor_version=major_minor_version)
+
+ def fallback_to_generic_buildvariant(self, major_minor_version):
+ """Return generic buildvariant name.
+
+ Wrapper around evergreen_conn.get_generic_buildvariant_name().
+ """
+
+ return evergreen_conn.get_generic_buildvariant_name(config=self.config,
+ major_minor_version=major_minor_version)
class SetupMultiversionPlugin(PluginInterface):
@@ -110,7 +178,6 @@ class SetupMultiversionPlugin(PluginInterface):
def parse(self, subcommand, parser, parsed_args, **kwargs):
"""Parse command-line options."""
- setup_logging()
if subcommand == SUBCOMMAND:
return SetupMultiversion(parsed_args)
@@ -128,33 +195,36 @@ class SetupMultiversionPlugin(PluginInterface):
help="Directory to contain links to all binaries for each version "
"in the install directory. [REQUIRED]")
editions = ("base", "enterprise", "targeted")
- parser.add_argument("-e", "--edition", dest="edition", choices=editions, default="base",
+ parser.add_argument("-e", "--edition", dest="edition", choices=editions,
+ default="enterprise",
help="Edition of the build to download, [default: %(default)s].")
parser.add_argument(
"-p", "--platform", dest="platform", required=True,
- help="Platform to download [REQUIRED]. Examples include: 'linux', "
- "'ubuntu1804', 'osx', 'rhel62', 'windows'.")
+ help="Platform to download [REQUIRED]. "
+ f"Available platforms can be found in {config.SETUP_MULTIVERSION_CONFIG}.")
parser.add_argument(
"-a", "--architecture", dest="architecture", default="x86_64",
help="Architecture to download, [default: %(default)s]. Examples include: "
"'arm64', 'ppc64le', 's390x' and 'x86_64'.")
parser.add_argument(
"-u", "--useLatest", dest="use_latest", action="store_true",
- help="If specified, the latest (nightly) version will be downloaded, "
- "if it exists, for the version specified. For example, if specifying "
- "version 3.2 for download, the nightly version for 3.2 will be "
- "downloaded if it exists, otherwise the 'highest' version will be "
- "downloaded, i.e., '3.2.17'")
+ help="If specified, the latest version from Evergreen will be downloaded, if it exists, "
+ "for the version specified. For example, if specifying version 4.4 for download, the latest "
+ "version from `mongodb-mongo-v4.4` Evergreen project will be downloaded. Otherwise the latest "
+ "by git tag version will be downloaded.")
parser.add_argument(
"versions", nargs="*", help=
- "Examples: 4.2 4.2.1 4.4. If 'rc' is included in the version name, we'll use the exact rc, "
+ "Examples: 4.0, 4.0.1, 4.0.0-rc0. If 'rc' is included in the version name, we'll use the exact rc, "
"otherwise we'll pull the highest non-rc version compatible with the version specified."
)
parser.add_argument(
- "--evergreen-config", dest="evergreen_config",
+ "-ec", "--evergreenConfig", dest="evergreen_config",
help="Location of evergreen configuration file. If not specified it will look "
- f"for it in the following locations: {EVERGREEN_CONFIG_LOCATIONS}")
+ f"for it in the following locations: {evergreen_conn.EVERGREEN_CONFIG_LOCATIONS}")
parser.add_argument(
- "--git-token", dest="git_token", help=
- "In most cases it works without git auth. Otherwise you can pass OAth token to increase "
- "the github API rate limit. See https://developer.github.com/v3/#rate-limiting")
+ "-gt", "--githubOauthToken", dest="github_oauth_token",
+ help="Set the token to increase your rate limit. In most cases it works without auth. "
+ "Otherwise you can pass OAuth token to increase the github API rate limit. See "
+ "https://developer.github.com/v3/#rate-limiting")
+ parser.add_argument("-d", "--debug", dest="debug", action="store_true", default=False,
+ help="Set DEBUG logging level.")