예제 #1
0
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)
예제 #2
0
    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()
예제 #3
0
    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()