示例#1
0
def InstallCgpt(index_page, force):
    """Install necessary cgpt utility on the sudo path.

  Args:
    index_page: html page to download au-generator containing correct cgpt
    force: a boolean, True when all existing bundle files can be deleted
  Raises:
    BundlingError when resource fetch and extract fails or overwrite is denied
  """
    au_gen_url = os.path.join(index_page, cb_constants.AU_GEN)
    if not Download(au_gen_url):
        raise cb_constants.BundlingError(
            'Necessary resource %s could not be fetched.' % au_gen_url)
    au_gen_name = os.path.join(cb_constants.WORKDIR, cb_constants.AU_GEN)
    cgpt_name = os.path.join(cb_constants.WORKDIR, 'cgpt')
    if not ZipExtract(au_gen_name, 'cgpt', path=cb_constants.WORKDIR):
        raise cb_constants.BundlingError(
            'Could not extract necesary resource %s from %s.' %
            (cgpt_name, au_gen_name))
    cgpt_dest = os.path.join(cb_constants.SUDO_DIR, 'cgpt')
    if os.path.exists(cgpt_dest):
        if force:
            MoveCgpt(cgpt_name, cgpt_dest)
        else:
            msg = 'cgpt exists at %s, please confirm update' % cgpt_dest
            if AskUserConfirmation(msg):
                MoveCgpt(cgpt_name, cgpt_dest)
            else:
                raise cb_constants.BundlingError(
                    'Necessary utility cgpt already exists at %s, use -f to overwrite '
                    'with newest version.' % cgpt_dest)
    else:
        MoveCgpt(cgpt_name, cgpt_dest)
示例#2
0
def ExtractFirmware(image_name, firmware_dest, mount_point, board):
    """Extract firmware from an SSD image to help prepare a factory bundle.

  See docstring of CheckEnvironment() for environmental prerequisites.

  Args:
    image_name: a string, absolute file path to SSD release image binary.
    firmware_dest: a string, absolute path to directory firmware should go.
    mount_point: a string, directory to mount SSD image.
    board: a string, target board.
  Raises:
    BundlingError when necessary tools are missing or SSD mounting fails.
  """
    if not CheckEnvironment(image_name, firmware_dest, mount_point):
        raise cb_constants.BundlingError(
            'Environment check failed, please fix conditions listed above.')

    image = os.path.basename(image_name)
    try:
        logging.info('Mounting SSD image.')
        cmd_result = RunCommand([
            './mount_gpt_image.sh', '--read_only', '--safe',
            '='.join(['--from',
                      cb_constants.WORKDIR]), '='.join(['--image', image]),
            '='.join(['--rootfs_mountpt', mount_point])
        ])
        if not os.path.exists(mount_point) or not os.listdir(mount_point):
            err = ('Failed to mount SSD image at %s: cmd_result = %r' %
                   (mount_point, cmd_result))
            raise cb_constants.BundlingError(err)

        cros_fw = os.path.join(mount_point, 'usr', 'sbin',
                               'chromeos-firmwareupdate')
        fw_name = ListFirmware(image_name, cros_fw, board)
        firmdir = ExtractFiles(cros_fw)
        if not firmdir:
            raise cb_constants.BundlingError(
                'Failed to extract firmware files.')

        for k, v in FIRMWARE_MAP[board].iteritems():
            src_path = os.path.join(firmdir, v['name'])
            if not os.path.exists(src_path):
                logging.debug('shutil: skip non-existing file %s', src_path)
                continue
            dst_path = os.path.join(firmware_dest, fw_name[k])
            shutil.copy(src_path, dst_path)

        # Per yongjaek in 11/2011, also copy chromeos-firmwareupdate shellball
        shutil.copy(cros_fw, firmware_dest)
    finally:
        RunCommand(['./mount_gpt_image.sh', '--unmount'])

    filename = os.path.join(cb_constants.WORKDIR, image_name)
    md5filename = filename + '.md5'
    if not CheckMd5(filename, md5filename):
        raise cb_constants.BundlingError(
            'SSD image MD5 check failed, image was corrupted!')
示例#3
0
def RecoveryToStandardSsd(image_name, options):
    """Converts a recovery image into an SSD image.

  Assumes a chroot setup.
  Requires sudo privileges to run cros_sdk.
  Requires the script to run in <ChromeOS_root>/src/scripts.

  Args:
    image_name: absolute path name of recovery image to convert
    options: an object containing inputs to the script
      please see cros_bundle_lib/CheckBundleInputs for possibilities
  Returns:
    a string, the absolute path name of the extracted SSD image
  Raises:
    BundlingError when resources not found or conversion fails.
  """
    force = options.force
    chromeos_root = options.chromeos_root
    if not re.search('/src/scripts$', os.getcwd()):
        raise cb_constants.BundlingError(
            'ConvertRecoveryToSsd must be run from src/scripts.')
    image_dir = os.path.dirname(image_name)
    ssd_name = image_name.replace('recovery', 'ssd')
    HandleSsdExists(ssd_name, force)
    # make copy of recovery image to consume
    if not options.chromeos_root:
        chroot_work_dir = os.path.join(CHROOT_ROOT, CHROOT_REL_DIR)
    else:
        if not (chromeos_root and os.path.isdir(chromeos_root)):
            raise cb_constants.BundlingError(
                'Provided ChromeOS source tree root %s does not exist or '
                'is not a directory' % chromeos_root)
        chroot_work_dir = os.path.join(chromeos_root, 'chroot', CHROOT_REL_DIR)
    # ensure we have a chroot to work in
    chroot_work_parent_dir = re.match('(.*/).*', chroot_work_dir).group(1)
    if not os.path.exists(chroot_work_parent_dir):
        raise cb_constants.BundlingError(
            'Chroot environment could not be inferred, failed to create link %s.'
            % chroot_work_dir)
    if not (chroot_work_dir and os.path.isdir(chroot_work_dir)):
        os.mkdir(chroot_work_dir)
    ssd_chroot_name = ssd_name.replace(image_dir, chroot_work_dir)
    shutil.copy(image_name, ssd_chroot_name)
    cmd = ([
        'cros_sdk', '--',
        os.path.join(IMG_SIGN_DIR, 'convert_recovery_to_ssd.sh'),
        ssd_name.replace(image_dir, ReinterpretPathForChroot(chroot_work_dir))
    ])
    if options.force:
        cmd.insert(5, '--force')
    RunCommand(cmd)
    # move ssd out, clean up folder
    shutil.move(ssd_chroot_name, ssd_name)
    shutil.rmtree(chroot_work_dir)
    return ssd_name
示例#4
0
def ListFirmware(image_name, cros_fw, board):
    """Gets list of strings representing contents of firmware.

  As of 11/2011, only handles Alex and Stumpy firmwares.

  Args:
    image_name: a string, absolute file path to SSD release image binary.
    cros_fw: a string, absolute path of firmware extraction script.
    board: a string, target board.

  Returns:
    a dict, {fw_type: fw_name}.

  Raises:
    BundlingError when necessary files missing.
  """
    if not os.path.exists(cros_fw):
        err = 'File chromeos-firmwareupdate missing from %s.' % image_name
        raise cb_constants.BundlingError(err)

    cmd_result = RunCommand([cros_fw, '-V'], redirect_stdout=True)
    output = cmd_result.output
    if not output:
        err = 'Failed to get output from script %s.' % cros_fw
        raise cb_constants.BundlingError(err)

    logging.debug('ListFirmware(): chromeos-firmwareupdate output = %s',
                  output)
    fw_content = output.split('\n')
    pat = re.compile('[.]/(.*)')
    # Look for mandatory firmware files in chromeos-firmwareupdate output.
    # For example, if fw_content = """
    # Package Content:
    #   57350ea0958cb39a715ddd4ccf2f0e92 *./bios.bin"""
    # searches = [None, None, <sre.SRE_Match object at 0x...>, ]
    # fw_files = ['bios.bin']
    searches = [pat.search(line) for line in fw_content]
    fw_files = [match.group(1) for match in searches if match]
    for f in [
            FIRMWARE_MAP[board][k]['name'] for k in FIRMWARE_MAP[board].keys()
    ]:
        if f not in fw_files:
            raise cb_constants.BundlingError(
                'Necessary file %s missing from %s.' % (f, cros_fw))

    fw_names = dict()
    for fw_type in FIRMWARE_MAP[board].keys():
        fw_names[fw_type] = _ExtractFirmwareFilename(fw_type, board,
                                                     fw_content)
    return fw_names
示例#5
0
def RecoveryToFullSsdNoChroot(image_name, options):
    """Converts a recovery image into an SSD image with stateful partition.

  This method does not depend on a chroot setup.

  Args:
    image_name: absolute path name of recovery image to convert
    options: an object containing inputs to the script
      please see cros_bundle_lib/CheckBundleInputs for possibilities
  Returns:
    a string, the absolute path name of the extracted SSD image
  Raises:
    BundlingError when resources not found or conversion fails.
  """
    force = options.force
    board = options.board
    recovery = options.recovery
    ssd_name = image_name.replace('recovery', 'ssd')
    HandleSsdExists(ssd_name, force)
    # fetch convert_recovery_to_full_ssd.sh
    HandleGitExists(force)
    RunCommand(['git', 'clone', cb_constants.GITURL, cb_constants.GITDIR])
    # fetch zip containing chromiumos_base_image
    (rec_url, index_page) = RunWithNamingRetries(None, ResolveRecoveryUrl,
                                                 board, recovery)
    if not index_page:
        raise cb_constants.BundlingError(
            'All naming schemes failed attempting to resolve recovery URL '
            'for recovery version %s' % recovery)
    if not rec_url:
        raise cb_constants.BundlingError(
            'Could not find URL match for recovery version %s on page %s' %
            (recovery, index_page))
    rec_no = recovery.split('/')[0]
    token_list = ['chromeos', rec_no, board, '.zip']
    zip_url = DetermineUrl(index_page, token_list)
    if not zip_url:
        raise cb_constants.BundlingError(
            'Failed to determine name of zip file for token_list %s on page %s'
            % (token_list, index_page))
    if not Download(zip_url):
        raise cb_constants.BundlingError('Failed to download %s.' % zip_url)
    zip_name = os.path.join(cb_constants.WORKDIR, os.path.basename(zip_url))
    InstallCgpt(index_page, force)
    script_name = os.path.join(cb_constants.GITDIR, 'scripts', 'image_signing',
                               'convert_recovery_to_full_ssd.sh')
    RunCommand([script_name, image_name, zip_name, ssd_name])
    # TODO(benwin) consider cleaning up resources based on command line flag
    return ssd_name
示例#6
0
def UploadToGsd(filename):
    """Uploads a file or directory to Google Storage for Developers

  Assuming proper keys for gsutil are set up for current user.

  Args:
    filename: absolute path name of file or directory to upload
  Raises:
    BundlingError when file specified by filename does not exist
  """
    if not (filename and os.path.exists(filename)):
        raise cb_constants.BundlingError('File %s does not exist.' % filename)
    RunCommand(['gsutil', 'cp', filename, cb_constants.GSD_BUCKET])
 def testInstallCgptFails(self):
   """Verify error when installing cgpt utility fails."""
   cb_command_lib.HandleGitExists(self.force)
   cb_command_lib.RunCommand(mox.IsA(list))
   cb_command_lib.ResolveRecoveryUrl(
       self.board, self.recovery, alt_naming=0).AndReturn(
           (self.rec_url, self.index_page))
   cb_command_lib.DetermineUrl(self.index_page, mox.IsA(list)).AndReturn(
       self.zip_url)
   cb_command_lib.Download(self.zip_url).AndReturn(True)
   cb_command_lib.HandleSsdExists(self.ssd_name, self.force)
   cb_command_lib.InstallCgpt(self.index_page, self.force).AndRaise(
       cb_constants.BundlingError(''))
   _AssertConvertRecoveryError(self)
示例#8
0
def HandleSsdExists(ssd_name, force):
    """Detect if ssd image already exists and handle overwrite confirmation.

  Args:
    ssd_name: absolute path name of ssd image to check for
    force: a boolean, True when all existing bundle files can be deleted
  Raises:
    BundlingError when ssd image exists and user does not confirm overwrite
  """
    if os.path.exists(ssd_name):
        if not force:
            msg = 'SSD file %s already exists, please confirm overwrite' % ssd_name
            if not AskUserConfirmation(msg):
                raise cb_constants.BundlingError(
                    'File %s already exists, use -f to overwrite' % ssd_name)
示例#9
0
def ReinterpretPathForChroot(path):
    """Returns reinterpreted path from outside the chroot for use inside.

  Modified insignificantly from <ChromeOS_root>/chromite/lib/cros_build_lib.py.

  Args:
    path: The path to reinterpret.  Must be in src tree.
  Returns:
    a string, the reinterpreted path from outside the chroot for use inside.
  Raises:
    BundlingError when given a path not in src tree.
  """
    root_path = os.path.join(FindRepoDir(path), '..')
    path_abs_path = os.path.abspath(path)
    root_abs_path = os.path.abspath(root_path)
    # Strip the repository root from the path and strip first /.
    relative_path = path_abs_path.replace(root_abs_path, '')[1:]
    if relative_path == path_abs_path:
        raise cb_constants.BundlingError(
            'Error: '
            'path is outside your src tree, cannot reinterpret.')
    new_path = os.path.join('/home', os.getenv('USER'), 'trunk', relative_path)
    return new_path
示例#10
0
def HandleGitExists(force):
    """Detect if git directory already exists and handle overwrite confirmation.

  Args:
    force: a boolean, True when all existing bundle files can be deleted
  Raises:
    BundlingError when git directory exists and user does not confirm overwrite
  """
    if os.path.exists(cb_constants.GITDIR):
        if force:
            shutil.rmtree(cb_constants.GITDIR)
            os.mkdir(cb_constants.GITDIR)
        else:
            msg = ('Old recovery conversion script git repo exists, please '
                   'confirm overwrite')
            if AskUserConfirmation(msg):
                shutil.rmtree(cb_constants.GITDIR)
                os.mkdir(cb_constants.GITDIR)
            else:
                raise cb_constants.BundlingError(
                    'Vboot git repo exists, use -f to update')
    else:
        os.mkdir(cb_constants.GITDIR)
 def testSsdImageExistsNoConfirm(self):
   """Verify error when SSD image exists, user does not confirm overwrite."""
   cb_command_lib.HandleSsdExists(self.ssd_name, self.force).AndRaise(
       cb_constants.BundlingError(''))
   _AssertConvertRecoveryError(self)
 def testGitExistsNotHandled(self):
   """Verify error when git files exist, user does not confirm overwrite."""
   cb_command_lib.HandleSsdExists(self.ssd_name, self.force)
   cb_command_lib.HandleGitExists(self.force).AndRaise(
       cb_constants.BundlingError(''))
   _AssertConvertRecoveryError(self)