mirror of https://github.com/mongodb/mongo
144 lines
4.7 KiB
Python
144 lines
4.7 KiB
Python
# This script validates the msi can be installed, uninstalled, and checks for the default install location and some of the possible install files
|
|
import glob
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
|
|
common_files = [
|
|
"*\\*\\bin\\mongos.exe",
|
|
"*\\*\\bin\\mongos.pdb",
|
|
"*\\*\\bin\\mongod.exe",
|
|
"*\\*\\bin\\mongod.pdb",
|
|
"*\\*\\bin\\mongod.cfg",
|
|
"*\\*\\bin\\InstallCompass.ps1",
|
|
"*\\*\\MPL-2",
|
|
"*\\*\\README",
|
|
"*\\*\\THIRD-PARTY-NOTICES",
|
|
]
|
|
|
|
community_files = [
|
|
"*\\*\\LICENSE-Community.txt",
|
|
]
|
|
|
|
enterprise_files = [
|
|
"*\\*\\bin\\mongodecrypt.exe",
|
|
"*\\*\\bin\\mongokerberos.exe",
|
|
"*\\*\\bin\\mongoldap.exe",
|
|
"*\\*\\bin\\sasl2.dll",
|
|
"*\\*\\bin\\sasl2.pdb",
|
|
"*\\*\\LICENSE-Enterprise.txt",
|
|
"*\\*\\THIRD-PARTY-NOTICES.windows",
|
|
]
|
|
|
|
|
|
def execute_msi(msi_path, install=True):
|
|
"""
|
|
Run an MSI file to either install or uninstall.
|
|
|
|
:param msi_path: Path to the MSI file.
|
|
:return: None
|
|
"""
|
|
if not os.path.exists(msi_path):
|
|
print(f"Error: The file '{msi_path}' does not exist.")
|
|
sys.exit(1)
|
|
|
|
features = ["ServerNoService", "Router", "MiscellaneousTools", "InstallCompassFeature"]
|
|
# Should look like ADDLOCAL=feature1,feature2
|
|
features_install_string = "" if len(features) == 0 else "ADDLOCAL=" + ",".join(features)
|
|
|
|
try:
|
|
temp_log = tempfile.NamedTemporaryFile(mode="w", suffix=".log", delete=False)
|
|
process_type = "Install" if install else "Uninstall"
|
|
install_commands = [
|
|
"msiexec",
|
|
"/i" if install else "/x",
|
|
msi_path,
|
|
features_install_string,
|
|
"/quiet",
|
|
"/norestart",
|
|
"/l*v",
|
|
temp_log.name,
|
|
]
|
|
print(f"{process_type} '{msi_path}' with command: {' '.join(install_commands)}...")
|
|
subprocess.run(install_commands, check=True)
|
|
print(f"{process_type} completed successfully.")
|
|
with open(temp_log.name, "r") as file:
|
|
print(file.read())
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Error while {process_type} MSI: {e}")
|
|
with open(temp_log.name, "r") as file:
|
|
print(file.read())
|
|
sys.exit(1)
|
|
|
|
|
|
def validate_files(is_enterprise):
|
|
"""
|
|
Validate the files exist from the msi, and if its an exe the help command launches
|
|
"""
|
|
install_path = os.path.join(os.environ.get("ProgramFiles"), "MongoDB")
|
|
files_to_check = common_files + (enterprise_files if is_enterprise else community_files)
|
|
print("Validating some of the expected files exist in Program Files install directory.")
|
|
for file in files_to_check:
|
|
file_path = os.path.join(install_path, file)
|
|
print(f"Checking if {file_path} exists.")
|
|
file_match = glob.glob(file_path)
|
|
if file_match:
|
|
print(f"File exists: {file_match[0]}")
|
|
if file_match[0].endswith(".exe"):
|
|
validate_help(file_match[0])
|
|
if file_match[0].endswith("mongod.exe"):
|
|
validate_version(file_match[0])
|
|
else:
|
|
print(f"Error: {file_path} could not be found.")
|
|
sys.exit(1)
|
|
|
|
|
|
def validate_help(exe_path):
|
|
try:
|
|
install_commands = [exe_path, "--help"]
|
|
print(f"Calling '{exe_path}' with command: {' '.join(install_commands)}...")
|
|
subprocess.run(install_commands, check=True)
|
|
print(f"{exe_path} called help successfully.")
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Error while calling help for {exe_path}: {e}")
|
|
sys.exit(1)
|
|
|
|
|
|
# Make sure we have a proper git version in the windows release
|
|
def validate_version(exe_path):
|
|
try:
|
|
version_command = [exe_path, "--version"]
|
|
print(f"Calling '{exe_path}' with command: {' '.join(version_command)}...")
|
|
result = subprocess.run(version_command, check=True, stdout=subprocess.PIPE, text=True)
|
|
print(f"{exe_path} called version successfully.")
|
|
match = re.search('.*"gitVersion": "[0-9a-fA-F]{40}".*', result.stdout)
|
|
if match:
|
|
print("Found a valid git version.")
|
|
return
|
|
else:
|
|
print("--version command did not contain a valid git version in gitVersion. Stdout:")
|
|
print(result.stdout)
|
|
sys.exit(1)
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Error while calling version for {exe_path}: {e}")
|
|
sys.exit(1)
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) != 2:
|
|
print("Usage: python msi_validation.py <path_to_msi>")
|
|
sys.exit(1)
|
|
|
|
msi_path = sys.argv[1]
|
|
is_enterprise = "enterprise" in os.path.basename(msi_path).lower()
|
|
|
|
execute_msi(msi_path, install=True)
|
|
validate_files(is_enterprise)
|
|
execute_msi(msi_path, install=False)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|