def log_and_exit(msg: str, build_info: buildinfo.BuildInfo, code: int = 4000, exception: Optional[Exception] = None, collect: bool = True): """Logs a user-facing error message and exits. This function handles all Glazier Exceptions by sequentially: - (Optional) Collecting logs to a zip folder on disk - Logging the full traceback to the debug log - Constructing the user-facing failure string, consisting of: * The message to accompany the failure * (Optional) The exception object, and if available, the file and line number of the root exception * The user-facing help message containing where to look for logs and where to go for further assistance. - Log the user-facing failure string - Exit Glazier with code 1 Args: msg: The error message to accompany the failure. build_info: The active BuildInfo class. code: Error code to append to the failure message. exception: The exception object. collect: Whether to collect log files. """ if collect: try: logs.Collect(os.path.join(build_info.CachePath(), r'\glazier_logs.zip')) except logs.LogError as e: logging.error('logs collection failed with %s', e) # Log the full traceback to _BUILD_LOG to assist in troubleshooting logging.debug(traceback.format_exc()) string = f'{msg}\n\n' if exception: # Index 2 contains the traceback from the sys.exc_info() tuple trace = sys.exc_info()[2] if trace: # Index -1 contains the traceback object of the root exception trace_obj = traceback.extract_tb(trace)[-1] # The trace object contains the full file path, grab just the file name file = os.path.split(trace_obj.filename)[1] lineno = trace_obj.lineno string += f'Exception: {file}:{lineno}] {exception}\n\n' else: string += f'Exception] {exception}\n\n' build_log = constants.SYS_BUILD_LOG if winpe.check_winpe(): build_log = constants.WINPE_BUILD_LOG string += (f'See {build_log} for more info. ' f'Need help? Visit {constants.HELP_URI}#{code}') logging.critical(string) sys.exit(1)
def testDriverWIM(self, mkdir, exe, dl, sha, rpath): bi = BuildInfo() # Setup remote = '@Drivers/Lenovo/W54x-Win10-Storage.wim' local = r'c:\W54x-Win10-Storage.wim' sha_256 = ( 'D30F9DB0698C87901DF6824D11203BDC2D6DAAF0CE14ABD7C0A7B75974936748') conf = { 'data': { 'driver': [[remote, local, sha_256]] }, 'path': ['/autobuild'] } rpath.return_value = '/' # Success dw = drivers.DriverWIM(conf['data']['driver'], bi) dw.Run() dl.assert_called_with(mock.ANY, ('https://glazier-server.example.com/' 'bin/Drivers/Lenovo/W54x-Win10-Storage.wim'), local, show_progress=True) sha.assert_called_with(mock.ANY, local, sha_256) cache = drivers.constants.SYS_CACHE exe.assert_called_with( f'{drivers.constants.WINPE_SYSTEM32}/dism.exe', ['/Unmount-Image', f'/MountDir:{cache}\\Drivers\\', '/Discard'], shell=True) mkdir.assert_called_with('%s\\Drivers\\' % cache) # Invalid format conf['data']['driver'][0][1] = 'C:\\W54x-Win10-Storage.zip' dw = drivers.DriverWIM(conf['data']['driver'], bi) self.assertRaises(drivers.ActionError, dw.Run) conf['data']['driver'][0][1] = 'C:\\W54x-Win10-Storage.wim' # Mount Fail exe.side_effect = drivers.execute.Error with self.assertRaises(drivers.ActionError): dw.Run() # Dism Fail exe.side_effect = iter([0, drivers.execute.Error]) with self.assertRaises(drivers.ActionError): dw.Run() # Unmount Fail exe.side_effect = iter([0, 0, drivers.execute.Error]) with self.assertRaises(drivers.ActionError): dw.Run()
def testUpdateMSU(self, mkdir, exe, dl, sha, rpath): bi = BuildInfo() # Setup remote = '@Drivers/HP/KB2990941-v3-x64.msu' local = r'c:\KB2990941-v3-x64.msu' sha_256 = ( 'd1acbdd8652d6c78ce284bf511f3a7f5f776a0a91357aca060039a99c6a93a16') conf = { 'data': { 'update': [[remote, local, sha_256]] }, 'path': ['/autobuild'] } rpath.return_value = '/' # Success um = updates.UpdateMSU(conf['data']['update'], bi) um.Run() dl.assert_called_with(mock.ANY, ('https://glazier-server.example.com/' 'bin/Drivers/HP/KB2990941-v3-x64.msu'), local, show_progress=True) sha.assert_called_with(mock.ANY, local, sha_256) cache = updates.constants.SYS_CACHE exe.assert_called_with(f'{updates.constants.SYS_SYSTEM32}/dism.exe', [ '/image:c:\\', '/Add-Package', '/PackagePath:c:\\KB2990941-v3-x64.msu', f'/ScratchDir:{cache}\\Updates\\' ], shell=True) mkdir.assert_called_with('%s\\Updates\\' % cache) # Invalid format conf['data']['update'][0][1] = 'C:\\Windows6.1-KB2990941-v3-x64.cab' um = updates.UpdateMSU(conf['data']['update'], bi) self.assertRaises(updates.ActionError, um.Run) conf['data']['update'][0][1] = 'C:\\Windows6.1-KB2990941-v3-x64.msu' # Dism Fail exe.side_effect = updates.execute.Error with self.assertRaises(updates.ActionError): um.Run()