From dd02a682cae1701a2e2fe2ab6f78e94309e97ab9 Mon Sep 17 00:00:00 2001 From: Jack Harper Date: Fri, 13 Dec 2024 15:32:01 +0000 Subject: [PATCH 1/9] install vs redist on instrument deploy --- .../ibex_install_utils/install_tasks.py | 1 + .../ibex_install_utils/tasks/system_tasks.py | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/installation_and_upgrade/ibex_install_utils/install_tasks.py b/installation_and_upgrade/ibex_install_utils/install_tasks.py index b0cdd6d..b11cb9e 100644 --- a/installation_and_upgrade/ibex_install_utils/install_tasks.py +++ b/installation_and_upgrade/ibex_install_utils/install_tasks.py @@ -248,6 +248,7 @@ def run_instrument_deploy_main(self) -> None: self._server_tasks.update_icp(self.icp_in_labview_modules()) self._python_tasks.install_genie_python3() self._mysql_tasks.install_mysql() + self._system_tasks.install_or_upgrade_vc_redist() self._client_tasks.install_ibex_client() self._git_tasks.checkout_to_release_branch() diff --git a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py index 77bb826..9e4487e 100644 --- a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py +++ b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py @@ -1,7 +1,10 @@ +import datetime import glob import os import shutil import subprocess +from pathlib import Path +import platform import psutil from ibex_install_utils.admin_runner import AdminCommandBuilder @@ -15,9 +18,11 @@ from ibex_install_utils.tasks.common_paths import ( APPS_BASE_DIR, EPICS_PATH, + VAR_DIR ) from ibex_install_utils.version_check import version_check from win32com.client import Dispatch +from time import sleep GIGABYTE = 1024**3 @@ -45,6 +50,8 @@ SECI = "SECI User interface.lnk" SECI_ONE_PATH = os.path.join("C:\\", "Program Files (x86)", "CCLRC ISIS Facility") SECI_AUTOSTART_LOCATIONS = [os.path.join(USER_STARTUP, SECI), os.path.join(ALLUSERS_STARTUP, SECI)] +EPICS_CRTL_PATH = os.path.join(EPICS_PATH, "crtl") + DESKTOP_TRAINING_FOLDER_PATH = os.path.join( os.environ["userprofile"], "desktop", "Mantid+IBEX training" @@ -402,6 +409,38 @@ def install_or_upgrade_git(self): "Download and Install Git from https://git-scm.com/downloads" ) + @task("Update visual studio redistributable files") + def install_or_upgrade_vc_redist(self): + """ + Install the latest visual studio redistributable files + """ + + is_64_bit = platform.machine().endswith("64") + exe_file = Path(EPICS_CRTL_PATH, f"vc_redist.{'x64' if is_64_bit else 'x86'}.exe") + if exe_file.exists() and exe_file.is_file(): + log_file = Path(VAR_DIR, "logs", "deploy", f"vc_redist_log{datetime.datetime.now()}.txt") + admin_commands = AdminCommandBuilder() + admin_commands.add_command( + f'"{exe_file}"', f"/install /norestart /passive /quiet /log {log_file}", expected_return_val=None + ) + admin_commands.run_all() + + # vc_redist helpfully finishes with errorlevel 0 before actually copying the files over. + # therefore we'll sleep for 5 seconds here + sleep(5) + + with open(log_file, "r") as f: + last_line = f.readlines()[-1] + + if "Exit code: 0x0" not in last_line: + self.prompt.prompt_and_raise_if_not_yes( + "Press Y/N if Git has installed correctly", default="Y" + ) + else: + self.prompt.prompt_and_raise_if_not_yes( + f"VC redistributable files not found in {exe_file.parent}, please check and make sure {exe_file} is present. " + ) + def confirm(self, message): """ Ask user to confirm correct script was chosen. From 2648eed6968f7100526e3e03066d4073db22a1f7 Mon Sep 17 00:00:00 2001 From: Jack Harper Date: Fri, 13 Dec 2024 16:45:56 +0000 Subject: [PATCH 2/9] install vs redist on instrument deploy --- .../ibex_install_utils/tasks/system_tasks.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py index 9e4487e..aca163c 100644 --- a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py +++ b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py @@ -425,17 +425,18 @@ def install_or_upgrade_vc_redist(self): ) admin_commands.run_all() + print("waiting for install to finish") # vc_redist helpfully finishes with errorlevel 0 before actually copying the files over. # therefore we'll sleep for 5 seconds here sleep(5) with open(log_file, "r") as f: - last_line = f.readlines()[-1] + for line in f.readlines(): + print("vc_redist install output: {}".format(line.rstrip())) - if "Exit code: 0x0" not in last_line: - self.prompt.prompt_and_raise_if_not_yes( - "Press Y/N if Git has installed correctly", default="Y" - ) + self.prompt.prompt_and_raise_if_not_yes( + "Installing vc redistributable files finished. Please check log output above for errors.", default="Y" + ) else: self.prompt.prompt_and_raise_if_not_yes( f"VC redistributable files not found in {exe_file.parent}, please check and make sure {exe_file} is present. " From 731886ae538f4e0bf6cbb7f6dae18992086af1f4 Mon Sep 17 00:00:00 2001 From: Jack Harper Date: Mon, 16 Dec 2024 12:54:24 +0000 Subject: [PATCH 3/9] fix - adminrunner does not work --- .../ibex_install_utils/tasks/system_tasks.py | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py index aca163c..e5427fe 100644 --- a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py +++ b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py @@ -1,4 +1,4 @@ -import datetime +import time import glob import os import shutil @@ -8,7 +8,7 @@ import psutil from ibex_install_utils.admin_runner import AdminCommandBuilder -from ibex_install_utils.exceptions import UserStop +from ibex_install_utils.exceptions import UserStop, ErrorInTask from ibex_install_utils.kafka_utils import add_required_topics from ibex_install_utils.run_process import RunProcess from ibex_install_utils.software_dependency.git import Git @@ -418,27 +418,30 @@ def install_or_upgrade_vc_redist(self): is_64_bit = platform.machine().endswith("64") exe_file = Path(EPICS_CRTL_PATH, f"vc_redist.{'x64' if is_64_bit else 'x86'}.exe") if exe_file.exists() and exe_file.is_file(): - log_file = Path(VAR_DIR, "logs", "deploy", f"vc_redist_log{datetime.datetime.now()}.txt") - admin_commands = AdminCommandBuilder() - admin_commands.add_command( - f'"{exe_file}"', f"/install /norestart /passive /quiet /log {log_file}", expected_return_val=None - ) - admin_commands.run_all() + log_file = Path(VAR_DIR, "logs", "deploy", f"vc_redist_log{time.strftime('%Y%m%d%H%M%S')}.txt") + + # AdminRunner doesn't seem to work here, saying it can't find a handle, so just run as a normal command as the process itself prompts for admin. + RunProcess(working_dir=str(exe_file.parent), executable_file=exe_file.name, prog_args=["/install", "/norestart", "/passive", "/quiet", "/log", str(log_file)], expected_return_codes=[0] ).run() - print("waiting for install to finish") # vc_redist helpfully finishes with errorlevel 0 before actually copying the files over. # therefore we'll sleep for 5 seconds here + print("waiting for install to finish") sleep(5) with open(log_file, "r") as f: for line in f.readlines(): print("vc_redist install output: {}".format(line.rstrip())) + last_line = line + + status = "It looked like it installed correctly, but " if "Exit code: 0x0" in last_line else "it looked like the process errored," self.prompt.prompt_and_raise_if_not_yes( - "Installing vc redistributable files finished. Please check log output above for errors.", default="Y" + f"Installing vc redistributable files finished.\n" + f"{status}" + f"please check log output above for errors,\nor alternatively {log_file}", default="Y" ) else: - self.prompt.prompt_and_raise_if_not_yes( + raise ErrorInTask( f"VC redistributable files not found in {exe_file.parent}, please check and make sure {exe_file} is present. " ) From 80eb68a5501501a4bad86ac7e0ffa82393a7e307 Mon Sep 17 00:00:00 2001 From: Jack Harper Date: Mon, 16 Dec 2024 12:55:28 +0000 Subject: [PATCH 4/9] run ruff format --- .../ibex_install_utils/tasks/system_tasks.py | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py index e5427fe..44e591e 100644 --- a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py +++ b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py @@ -15,11 +15,7 @@ from ibex_install_utils.software_dependency.java import Java from ibex_install_utils.task import task from ibex_install_utils.tasks import BaseTasks -from ibex_install_utils.tasks.common_paths import ( - APPS_BASE_DIR, - EPICS_PATH, - VAR_DIR -) +from ibex_install_utils.tasks.common_paths import APPS_BASE_DIR, EPICS_PATH, VAR_DIR from ibex_install_utils.version_check import version_check from win32com.client import Dispatch from time import sleep @@ -418,10 +414,17 @@ def install_or_upgrade_vc_redist(self): is_64_bit = platform.machine().endswith("64") exe_file = Path(EPICS_CRTL_PATH, f"vc_redist.{'x64' if is_64_bit else 'x86'}.exe") if exe_file.exists() and exe_file.is_file(): - log_file = Path(VAR_DIR, "logs", "deploy", f"vc_redist_log{time.strftime('%Y%m%d%H%M%S')}.txt") + log_file = Path( + VAR_DIR, "logs", "deploy", f"vc_redist_log{time.strftime('%Y%m%d%H%M%S')}.txt" + ) # AdminRunner doesn't seem to work here, saying it can't find a handle, so just run as a normal command as the process itself prompts for admin. - RunProcess(working_dir=str(exe_file.parent), executable_file=exe_file.name, prog_args=["/install", "/norestart", "/passive", "/quiet", "/log", str(log_file)], expected_return_codes=[0] ).run() + RunProcess( + working_dir=str(exe_file.parent), + executable_file=exe_file.name, + prog_args=["/install", "/norestart", "/passive", "/quiet", "/log", str(log_file)], + expected_return_codes=[0], + ).run() # vc_redist helpfully finishes with errorlevel 0 before actually copying the files over. # therefore we'll sleep for 5 seconds here @@ -433,12 +436,17 @@ def install_or_upgrade_vc_redist(self): print("vc_redist install output: {}".format(line.rstrip())) last_line = line - status = "It looked like it installed correctly, but " if "Exit code: 0x0" in last_line else "it looked like the process errored," + status = ( + "It looked like it installed correctly, but " + if "Exit code: 0x0" in last_line + else "it looked like the process errored," + ) self.prompt.prompt_and_raise_if_not_yes( f"Installing vc redistributable files finished.\n" f"{status}" - f"please check log output above for errors,\nor alternatively {log_file}", default="Y" + f"please check log output above for errors,\nor alternatively {log_file}", + default="Y", ) else: raise ErrorInTask( From b2f03b116535198add5d387a4da77813db708ae0 Mon Sep 17 00:00:00 2001 From: Jack Harper Date: Mon, 16 Dec 2024 13:08:03 +0000 Subject: [PATCH 5/9] ruff check fixes --- .../ibex_install_utils/tasks/system_tasks.py | 138 ++++++++++-------- 1 file changed, 80 insertions(+), 58 deletions(-) diff --git a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py index 44e591e..470d0c5 100644 --- a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py +++ b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py @@ -1,14 +1,17 @@ -import time import glob import os +import platform import shutil import subprocess +import time from pathlib import Path -import platform +from time import sleep import psutil +from win32com.client import Dispatch + from ibex_install_utils.admin_runner import AdminCommandBuilder -from ibex_install_utils.exceptions import UserStop, ErrorInTask +from ibex_install_utils.exceptions import ErrorInTask, UserStop from ibex_install_utils.kafka_utils import add_required_topics from ibex_install_utils.run_process import RunProcess from ibex_install_utils.software_dependency.git import Git @@ -17,8 +20,6 @@ from ibex_install_utils.tasks import BaseTasks from ibex_install_utils.tasks.common_paths import APPS_BASE_DIR, EPICS_PATH, VAR_DIR from ibex_install_utils.version_check import version_check -from win32com.client import Dispatch -from time import sleep GIGABYTE = 1024**3 @@ -56,11 +57,12 @@ class SystemTasks(BaseTasks): """ - Tasks relating to the system e.g. installed software other than core IBEX components, windows, firewalls, etc. + Tasks relating to the system e.g. installed software other than core IBEX components, windows, + firewalls, etc. """ @task("Record running LabVIEW VIs or any relevant looking other programs") - def record_running_vis(self): + def record_running_vis(self) -> None: """ Get user to record running vis """ @@ -69,7 +71,7 @@ def record_running_vis(self): ) @task("Upgrading Notepad++. Please follow system dialogs") - def upgrade_notepad_pp(self): + def upgrade_notepad_pp(self) -> None: """ Install (start installation of) notepad ++ Returns: @@ -84,7 +86,7 @@ def upgrade_notepad_pp(self): ).run() @task("Removing training folder on desktop ...") - def clean_up_desktop_ibex_training_folder(self): + def clean_up_desktop_ibex_training_folder(self) -> None: """ Remove training folder from the desktop Returns: @@ -93,7 +95,7 @@ def clean_up_desktop_ibex_training_folder(self): self._file_utils.remove_tree(DESKTOP_TRAINING_FOLDER_PATH, self.prompt) @task("Remove SECI shortcuts") - def remove_seci_shortcuts(self): + def remove_seci_shortcuts(self) -> None: """ Remove (or at least ask the user to remove) all Seci shortcuts """ @@ -108,7 +110,7 @@ def remove_seci_shortcuts(self): self.prompt.prompt_and_raise_if_not_yes("Remove start menu shortcut to SECI") @task("Remove Treesize shortcuts") - def remove_treesize_shortcuts(self): + def remove_treesize_shortcuts(self) -> None: """ Remove (or at least ask the user to remove) all Treesize shortcuts. @@ -121,7 +123,7 @@ def remove_treesize_shortcuts(self): ) @task("Remove SECI 1 Path") - def remove_seci_one(self): + def remove_seci_one(self) -> None: """ Removes SECI 1 """ @@ -137,7 +139,7 @@ def remove_seci_one(self): @version_check(Java()) @task("Install java") - def check_java_installation(self): + def check_java_installation(self) -> None: """ Checks Java installation """ @@ -148,24 +150,27 @@ def check_java_installation(self): subprocess.call(f"msiexec /i {installer}") self.prompt.prompt_and_raise_if_not_yes( "Make sure java installed correctly.\r\n" - "After following the installer, ensure you close and then re-open your remote desktop session (This " + "After following the installer, ensure you close and then re-open" + " your remote desktop session (This " "is a workaround for windows not immediately picking up new environment variables)" ) else: self.prompt.prompt_and_raise_if_not_yes( "Upgrade openJDK installation by following:\r\n" "https://github.com/ISISComputingGroup/ibex_developers_manual/wiki/Upgrade-Java\r\n\r\n" - "After following the installer, ensure you close and then re-open your remote desktop session (This " + "After following the installer, ensure you close and then re-open" + " your remote desktop session (This " "is a workaround for windows not immediately picking up new environment variables)" ) @task("Configure COM ports") - def configure_com_ports(self): + def configure_com_ports(self) -> None: """ Configure the COM ports """ self.prompt.prompt_and_raise_if_not_yes( - "Using NPort Administrator (available under /Kits$/CompGroup/Utilities/), check that the COM ports " + "Using NPort Administrator (available under /Kits$/CompGroup/Utilities/), " + "check that the COM ports " "on this machine are configured to standard, i.e.:\n" "- Moxa 1 starts at COM5\n" "- Moxa 2 starts at COM21\n" @@ -173,17 +178,18 @@ def configure_com_ports(self): ) @task("Reapply Hotfixes") - def reapply_hotfixes(self): + def reapply_hotfixes(self) -> None: """ Reapply any hotfixes to the build. """ self.prompt.prompt_and_raise_if_not_yes( - "Have you applied any hotfixes listed that are not fixed by the release, as on the instrument " + "Have you applied any hotfixes listed that are not fixed by the release," + " as on the instrument " "release notes at https://github.com/ISISComputingGroup/IBEX/wiki?" ) @task("Restart VIs") - def restart_vis(self): + def restart_vis(self) -> None: """ Restart Vis which were running on upgrade start. """ @@ -192,7 +198,7 @@ def restart_vis(self): ) @task("Update release notes") - def update_release_notes(self): + def update_release_notes(self) -> None: """ Update the release notes. """ @@ -201,7 +207,7 @@ def update_release_notes(self): ) @task("Update Instrument List") - def update_instlist(self): + def update_instlist(self) -> None: """ Prompt user to add instrument to the list of known IBEX instruments """ @@ -210,14 +216,14 @@ def update_instlist(self): ) @task("Update kafka topics") - def update_kafka_topics(self): + def update_kafka_topics(self) -> None: """ Adds the required kafka topics to the cluster. """ add_required_topics("livedata.isis.cclrc.ac.uk:9092", self._get_instrument_name()) @task("Add Nagios checks") - def add_nagios_checks(self): + def add_nagios_checks(self) -> None: """ Prompt user to add nagios checks. """ @@ -228,7 +234,7 @@ def add_nagios_checks(self): ) @task("Inform instrument scientists") - def inform_instrument_scientists(self): + def inform_instrument_scientists(self) -> None: """ Inform instrument scientists that the machine has been upgraded. """ @@ -243,21 +249,22 @@ def inform_instrument_scientists(self): Please let us know if you have any queries or find any problems with the upgrade. Thank you, - """ + """ # noqa: E501 self.prompt.prompt_and_raise_if_not_yes(email_template) @task("Apply changes in release notes") - def apply_changes_noted_in_release_notes(self): + def apply_changes_noted_in_release_notes(self) -> None: """ Apply any changes noted in the release notes. """ # For future reference, genie_python can send emails! self.prompt.prompt_and_raise_if_not_yes( - "Look in the IBEX wiki at the release notes for the version you are deploying. Apply needed fixes." + "Look in the IBEX wiki at the release notes for the version you are deploying." + " Apply needed fixes." ) - def check_resources(self): + def check_resources(self) -> None: """ Check the machine's resources meet minimum requirements. """ @@ -265,14 +272,15 @@ def check_resources(self): self._check_disk_usage() @task("Check virtual machine memory") - def check_virtual_memory(self): + def check_virtual_memory(self) -> None: """ Checks the machine's virtual memory meet minimum requirements. """ ram = psutil.virtual_memory().total machine_type = self.prompt.prompt( - "Is this machine an instrument (e.g. NDXALF) or a test machine (e.g. NDXSELAB)? (instrument/test) ", + "Is this machine an instrument (e.g. NDXALF) or a test machine (e.g. NDXSELAB)?" + " (instrument/test) ", possibles=["instrument", "test"], default="test", ) @@ -284,15 +292,18 @@ def check_virtual_memory(self): if ram >= min_memory: print( - "Virtual memory ({:.1f}GB) is already at or above the recommended level for this machine type " + "Virtual memory ({:.1f}GB) is already at or above the recommended level" + " for this machine type " "({:.1f}GB). Nothing to do in this step.".format( ram / GIGABYTE, min_memory / GIGABYTE ) ) else: self.prompt.prompt_and_raise_if_not_yes( - "Current machine memory is {:.1f}GB, the recommended amount for this machine is {:.1f}GB.\n\n" - "If appropriate, upgrade this machine's memory allowance by following the instructions in " + "Current machine memory is {:.1f}GB, the recommended amount for" + " this machine is {:.1f}GB.\n\n" + "If appropriate, upgrade this machine's memory allowance by following" + " the instructions in " "https://github.com/ISISComputingGroup/ibex_developers_manual/wiki/Increase-VM-memory.\n\n" "Note, this will require a machine restart.".format( ram / GIGABYTE, min_memory / GIGABYTE @@ -300,7 +311,7 @@ def check_virtual_memory(self): ) @task("Check there is {:.1e}B free disk space".format(FREE_DISK_MIN)) - def _check_disk_usage(self): + def _check_disk_usage(self) -> None: """ Checks the machine's free disk space meets minimum requirements. """ @@ -314,20 +325,22 @@ def _check_disk_usage(self): ) @task("Put IBEX autostart script into startup for current user") - def put_autostart_script_in_startup_area(self): + def put_autostart_script_in_startup_area(self) -> None: """ - Checks the startup location for all users for the autostart script and removes any instances. + Checks the startup location for all users for the autostart script and removes + any instances. - Checks the startup location of the current user and removes the autostart script if it was copied. + Checks the startup location of the current user and removes the autostart script + if it was copied. Creates a shortcut of the ibex server autostart script into the current user startup folder so that the IBEX server starts automatically on startup. """ - AUTOSTART_SCRIPT_NAME = "ibex_system_boot" + autostart_script_name = "ibex_system_boot" # Check all users startup folder. - paths = glob.glob(os.path.join(ALLUSERS_STARTUP, f"{AUTOSTART_SCRIPT_NAME}*")) + paths = glob.glob(os.path.join(ALLUSERS_STARTUP, f"{autostart_script_name}*")) if len(paths): admin_commands = AdminCommandBuilder() for path in paths: @@ -336,38 +349,42 @@ def put_autostart_script_in_startup_area(self): admin_commands.run_all() # Check current user startup folder for copied batch file. - autostart_batch_path = os.path.join(USER_STARTUP, f"{AUTOSTART_SCRIPT_NAME}.bat") + autostart_batch_path = os.path.join(USER_STARTUP, f"{autostart_script_name}.bat") if os.path.exists(autostart_batch_path): print(f"Removing: '{autostart_batch_path}'.") os.remove(autostart_batch_path) # Create shortcut to autostart batch file. - autostart_shortcut_path = os.path.join(USER_STARTUP, f"{AUTOSTART_SCRIPT_NAME}.lnk") + autostart_shortcut_path = os.path.join(USER_STARTUP, f"{autostart_script_name}.lnk") if not os.path.exists(autostart_shortcut_path): print(f"Adding shortcut: '{autostart_shortcut_path}'.") shell = Dispatch("WScript.Shell") shortcut = shell.CreateShortCut(autostart_shortcut_path) - shortcut.Targetpath = os.path.join(EPICS_PATH, f"{AUTOSTART_SCRIPT_NAME}.bat") + shortcut.Targetpath = os.path.join(EPICS_PATH, f"{autostart_script_name}.bat") shortcut.save() else: print("Shortcut already exists.") @task("Restrict Internet Explorer") - def restrict_ie(self): + def restrict_ie(self) -> None: """ - Restrict access of external websites to address a security vulnerability in Internet Explorer. + Restrict access of external websites to address a security vulnerability + in Internet Explorer. """ self.prompt.prompt_and_raise_if_not_yes( - "Configure Internet Explorer to restrict access to the web except for select whitelisted sites:\n" - "- Open 'Internet Options' (from the gear symbol in the top right corner of the window).\n" + "Configure Internet Explorer to restrict access to the web except for" + " select whitelisted sites:\n" + "- Open 'Internet Options' (from the gear symbol in the top right corner of the window)" + ".\n" "- Go to the 'Connections' tab and open 'Lan Settings'\n" - "- Check 'Use Automatic configuration script' and enter http://dataweb.isis.rl.ac.uk/proxy.pac for 'Address'\n" + "- Check 'Use Automatic configuration script' and enter" + " http://dataweb.isis.rl.ac.uk/proxy.pac for 'Address'\n" "- Click 'Ok' on all dialogs." ) @version_check(Git()) @task("Update Git") - def install_or_upgrade_git(self): + def install_or_upgrade_git(self) -> None: """ Install the latest git version """ @@ -375,7 +392,8 @@ def install_or_upgrade_git(self): if os.path.exists(git_path): if "program files" in os.path.realpath(git_path).lower(): print( - f"git installed as admin detected in '{git_path}', attempting to upgrade as admin." + f"git installed as admin detected in '{git_path}', attempting to" + f" upgrade as admin." ) admin_commands = AdminCommandBuilder() admin_commands.add_command( @@ -388,7 +406,8 @@ def install_or_upgrade_git(self): print("git update output: {}".format(line.rstrip())) else: print( - f"git installed as normal user detected in '{git_path}', attempting upgrade as normal user." + f"git installed as normal user detected in '{git_path}', attempting upgrade " + f"as normal user." ) RunProcess( working_dir=os.curdir, @@ -406,7 +425,7 @@ def install_or_upgrade_git(self): ) @task("Update visual studio redistributable files") - def install_or_upgrade_vc_redist(self): + def install_or_upgrade_vc_redist(self) -> None: """ Install the latest visual studio redistributable files """ @@ -418,7 +437,8 @@ def install_or_upgrade_vc_redist(self): VAR_DIR, "logs", "deploy", f"vc_redist_log{time.strftime('%Y%m%d%H%M%S')}.txt" ) - # AdminRunner doesn't seem to work here, saying it can't find a handle, so just run as a normal command as the process itself prompts for admin. + # AdminRunner doesn't seem to work here, saying it can't find a handle, so just run as a + # normal command as the process itself prompts for admin. RunProcess( working_dir=str(exe_file.parent), executable_file=exe_file.name, @@ -431,6 +451,7 @@ def install_or_upgrade_vc_redist(self): print("waiting for install to finish") sleep(5) + last_line = "" with open(log_file, "r") as f: for line in f.readlines(): print("vc_redist install output: {}".format(line.rstrip())) @@ -450,16 +471,17 @@ def install_or_upgrade_vc_redist(self): ) else: raise ErrorInTask( - f"VC redistributable files not found in {exe_file.parent}, please check and make sure {exe_file} is present. " + f"VC redistributable files not found in {exe_file.parent}, please check" + f" and make sure {exe_file} is present. " ) - def confirm(self, message): + def confirm(self, message: str) -> None: """ Ask user to confirm correct script was chosen. """ self.prompt.prompt_and_raise_if_not_yes(message, default="Y") - def _read_file(self, path, error_text): + def _read_file(self, path: str | os.PathLike[str], error_text: str) -> str: """ print a file contents to screen """ @@ -467,11 +489,11 @@ def _read_file(self, path, error_text): try: with open(path, "r") as fin: data = fin.read() - except: + except OSError: data = error_text return data - def user_confirm_upgrade_type_on_machine(self, machine_type): + def user_confirm_upgrade_type_on_machine(self, machine_type: str) -> None: """ Print information about the current upgrade and prompt the user Returns: From f1a76d1a68f95e8041850e77c2d823dd31d56927 Mon Sep 17 00:00:00 2001 From: Jack Harper Date: Mon, 16 Dec 2024 13:09:12 +0000 Subject: [PATCH 6/9] sort imports --- .../ibex_install_utils/tasks/system_tasks.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py index 470d0c5..753c567 100644 --- a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py +++ b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py @@ -8,8 +8,6 @@ from time import sleep import psutil -from win32com.client import Dispatch - from ibex_install_utils.admin_runner import AdminCommandBuilder from ibex_install_utils.exceptions import ErrorInTask, UserStop from ibex_install_utils.kafka_utils import add_required_topics @@ -20,6 +18,7 @@ from ibex_install_utils.tasks import BaseTasks from ibex_install_utils.tasks.common_paths import APPS_BASE_DIR, EPICS_PATH, VAR_DIR from ibex_install_utils.version_check import version_check +from win32com.client import Dispatch GIGABYTE = 1024**3 From c91650618e7be1e090c93a46cd550e4f321b790d Mon Sep 17 00:00:00 2001 From: Jack Harper Date: Mon, 16 Dec 2024 15:14:05 +0000 Subject: [PATCH 7/9] get x86 from server arch arg, install both if x86 --- installation_and_upgrade/IBEX_upgrade.py | 8 +- .../ibex_install_utils/default_args.py | 1 + .../ibex_install_utils/tasks/system_tasks.py | 99 +++++++++++-------- 3 files changed, 65 insertions(+), 43 deletions(-) create mode 100644 installation_and_upgrade/ibex_install_utils/default_args.py diff --git a/installation_and_upgrade/IBEX_upgrade.py b/installation_and_upgrade/IBEX_upgrade.py index 8a17ecd..1eba95a 100644 --- a/installation_and_upgrade/IBEX_upgrade.py +++ b/installation_and_upgrade/IBEX_upgrade.py @@ -7,6 +7,7 @@ import re import sys +import ibex_install_utils.default_args import semantic_version from ibex_install_utils.exceptions import ErrorInTask, UserStop from ibex_install_utils.file_utils import FileUtils @@ -108,7 +109,10 @@ def _get_latest_existing_dir_path(release_dir, component): ) parser.add_argument("--kits_icp_dir", default=None, help="Directory of kits/ICP") parser.add_argument( - "--server_arch", default="x64", choices=["x64", "x86"], help="Server build architecture." + "--server_arch", + default=ibex_install_utils.default_args.SERVER_ARCH, + choices=["x64", "x86"], + help="Server build architecture.", ) deployment_types = [ @@ -122,6 +126,8 @@ def _get_latest_existing_dir_path(release_dir, component): args = parser.parse_args() + ibex_install_utils.default_args.SERVER_ARCH = args.server_arch + if not args.no_log_to_var: Logger.set_up() diff --git a/installation_and_upgrade/ibex_install_utils/default_args.py b/installation_and_upgrade/ibex_install_utils/default_args.py new file mode 100644 index 0000000..118fff8 --- /dev/null +++ b/installation_and_upgrade/ibex_install_utils/default_args.py @@ -0,0 +1 @@ +SERVER_ARCH = "x64" diff --git a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py index 753c567..9dcc346 100644 --- a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py +++ b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py @@ -428,51 +428,66 @@ def install_or_upgrade_vc_redist(self) -> None: """ Install the latest visual studio redistributable files """ + import ibex_install_utils.default_args - is_64_bit = platform.machine().endswith("64") - exe_file = Path(EPICS_CRTL_PATH, f"vc_redist.{'x64' if is_64_bit else 'x86'}.exe") - if exe_file.exists() and exe_file.is_file(): - log_file = Path( - VAR_DIR, "logs", "deploy", f"vc_redist_log{time.strftime('%Y%m%d%H%M%S')}.txt" - ) + arch = ibex_install_utils.default_args.SERVER_ARCH - # AdminRunner doesn't seem to work here, saying it can't find a handle, so just run as a - # normal command as the process itself prompts for admin. - RunProcess( - working_dir=str(exe_file.parent), - executable_file=exe_file.name, - prog_args=["/install", "/norestart", "/passive", "/quiet", "/log", str(log_file)], - expected_return_codes=[0], - ).run() - - # vc_redist helpfully finishes with errorlevel 0 before actually copying the files over. - # therefore we'll sleep for 5 seconds here - print("waiting for install to finish") - sleep(5) - - last_line = "" - with open(log_file, "r") as f: - for line in f.readlines(): - print("vc_redist install output: {}".format(line.rstrip())) - last_line = line - - status = ( - "It looked like it installed correctly, but " - if "Exit code: 0x0" in last_line - else "it looked like the process errored," - ) + print(f"Installing vc_redist for arch: {arch}") - self.prompt.prompt_and_raise_if_not_yes( - f"Installing vc redistributable files finished.\n" - f"{status}" - f"please check log output above for errors,\nor alternatively {log_file}", - default="Y", - ) - else: - raise ErrorInTask( - f"VC redistributable files not found in {exe_file.parent}, please check" - f" and make sure {exe_file} is present. " - ) + files_to_run = [f"vc_redist.x64.exe"] + if arch == "x86": + files_to_run.insert(0, "vc_redist.x86.exe") + for file in files_to_run: + exe_file = Path(EPICS_CRTL_PATH, file) + if exe_file.exists() and exe_file.is_file(): + log_file = Path( + VAR_DIR, "logs", "deploy", f"vc_redist_log{time.strftime('%Y%m%d%H%M%S')}.txt" + ) + + # AdminRunner doesn't seem to work here, saying it can't find a handle, so just run as a + # normal command as the process itself prompts for admin. + RunProcess( + working_dir=str(exe_file.parent), + executable_file=exe_file.name, + prog_args=[ + "/install", + "/norestart", + "/passive", + "/quiet", + "/log", + str(log_file), + ], + expected_return_codes=[0], + ).run() + + # vc_redist helpfully finishes with errorlevel 0 before actually copying the files over. + # therefore we'll sleep for 5 seconds here + print("waiting for install to finish") + sleep(5) + + last_line = "" + with open(log_file, "r") as f: + for line in f.readlines(): + print("vc_redist install output: {}".format(line.rstrip())) + last_line = line + + status = ( + "It looked like it installed correctly, but " + if "Exit code: 0x0" in last_line + else "it looked like the process errored," + ) + + self.prompt.prompt_and_raise_if_not_yes( + f"Installing vc redistributable files finished.\n" + f"{status}" + f"please check log output above for errors,\nor alternatively {log_file}", + default="Y", + ) + else: + raise ErrorInTask( + f"VC redistributable files not found in {exe_file.parent}, please check" + f" and make sure {exe_file} is present. " + ) def confirm(self, message: str) -> None: """ From 585bf1d014b87d31f585a6aea51aefd52d049172 Mon Sep 17 00:00:00 2001 From: Jack Harper Date: Mon, 16 Dec 2024 15:20:03 +0000 Subject: [PATCH 8/9] ruff --- installation_and_upgrade/IBEX_upgrade.py | 8 ++++---- .../ibex_install_utils/tasks/system_tasks.py | 11 +++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/installation_and_upgrade/IBEX_upgrade.py b/installation_and_upgrade/IBEX_upgrade.py index 1eba95a..bac772f 100644 --- a/installation_and_upgrade/IBEX_upgrade.py +++ b/installation_and_upgrade/IBEX_upgrade.py @@ -16,7 +16,7 @@ from ibex_install_utils.user_prompt import UserPrompt -def _get_latest_release_path(release_dir): +def _get_latest_release_path(release_dir: str) -> str: regex = re.compile(r"^\d+\.\d+\.\d+$") releases = [ @@ -32,7 +32,7 @@ def _get_latest_release_path(release_dir): return os.path.join(release_dir, f"{current_release}") -def _get_latest_existing_dir_path(release_dir, component): +def _get_latest_existing_dir_path(release_dir: str, component: str) -> str: regex = re.compile(r"^\d+\.\d+\.\d+$") releases = [ @@ -171,8 +171,8 @@ def _get_latest_existing_dir_path(release_dir, component): ) except UserStop: print( - "To specify the directory you want use --server_dir, --client_dir, and --genie_python3_dir " - "when running the IBEX_upgrade.py script." + "To specify the directory you want use --server_dir, --client_dir, and" + " --genie_python3_dir when running the IBEX_upgrade.py script." ) sys.exit(2) diff --git a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py index 9dcc346..7210fea 100644 --- a/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py +++ b/installation_and_upgrade/ibex_install_utils/tasks/system_tasks.py @@ -1,6 +1,5 @@ import glob import os -import platform import shutil import subprocess import time @@ -434,7 +433,7 @@ def install_or_upgrade_vc_redist(self) -> None: print(f"Installing vc_redist for arch: {arch}") - files_to_run = [f"vc_redist.x64.exe"] + files_to_run = ["vc_redist.x64.exe"] if arch == "x86": files_to_run.insert(0, "vc_redist.x86.exe") for file in files_to_run: @@ -444,8 +443,8 @@ def install_or_upgrade_vc_redist(self) -> None: VAR_DIR, "logs", "deploy", f"vc_redist_log{time.strftime('%Y%m%d%H%M%S')}.txt" ) - # AdminRunner doesn't seem to work here, saying it can't find a handle, so just run as a - # normal command as the process itself prompts for admin. + # AdminRunner doesn't seem to work here, saying it can't find a handle, so just + # run as a normal command as the process itself prompts for admin. RunProcess( working_dir=str(exe_file.parent), executable_file=exe_file.name, @@ -460,8 +459,8 @@ def install_or_upgrade_vc_redist(self) -> None: expected_return_codes=[0], ).run() - # vc_redist helpfully finishes with errorlevel 0 before actually copying the files over. - # therefore we'll sleep for 5 seconds here + # vc_redist helpfully finishes with errorlevel 0 before actually + # copying the files over, therefore we'll sleep for 5 seconds here print("waiting for install to finish") sleep(5) From ded1e34776e992e6a0649bff2acf4be09909d157 Mon Sep 17 00:00:00 2001 From: Jack Harper Date: Mon, 16 Dec 2024 15:24:26 +0000 Subject: [PATCH 9/9] pyright --- installation_and_upgrade/IBEX_upgrade.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installation_and_upgrade/IBEX_upgrade.py b/installation_and_upgrade/IBEX_upgrade.py index bac772f..6e31309 100644 --- a/installation_and_upgrade/IBEX_upgrade.py +++ b/installation_and_upgrade/IBEX_upgrade.py @@ -8,7 +8,7 @@ import sys import ibex_install_utils.default_args -import semantic_version +import semantic_version # pyright: ignore from ibex_install_utils.exceptions import ErrorInTask, UserStop from ibex_install_utils.file_utils import FileUtils from ibex_install_utils.install_tasks import UPGRADE_TYPES, UpgradeInstrument