Пример #1
0
def _ReadAllBundleInstallerFiles(installers_txt_files_path):
    """Enumerates all the .*_installers.txt files in the installers_txt_files_path
     directory, and creates bundles corresponding to the info in each line in
     the *_installers.txt file.
  Returns:
    Returns a dictionary of Bundles with key=lang.
  """
    bundles = {}
    files = os.listdir(installers_txt_files_path)
    for file in files:
        regex = re.compile('^(.*)_installers.txt$')
        if not regex.match(file):
            continue

        installer_file = os.path.join(installers_txt_files_path, file)

        # Read in the installer file.
        read_bundles = tag_meta_installers.ReadBundleInstallerFile(
            installer_file)

        for (key, bundle_list) in read_bundles.items():
            if not bundle_list or not key:
                continue
            if not bundles.has_key(key):
                bundles[key] = bundle_list
            else:
                new_bundles_list = bundles[key] + bundle_list
                bundles[key] = new_bundles_list
    return bundles
Пример #2
0
def BuildOfflineInstaller(
        env,
        offline_installer,
        omaha_version_info,
        omaha_files_path,
        empty_metainstaller_path,
        offline_installers_file_path,
        manifest_files_path,
        prefix='',
        is_official=False,
        installers_sources_path='$MAIN_DIR/installers',
        enterprise_installers_sources_path='$MAIN_DIR/enterprise/installer',
        lzma_path='$THIRD_PARTY/lzma/files/lzma.exe',
        resmerge_path='$MAIN_DIR/tools/resmerge'):
    """Builds the standalone installers specified by offline_installer.

  Args:
    env: Environment.
    offline_installer: OfflineInstaller containing the information about the
        standalone installer to build.
    omaha_version_info: info about the version of the Omaha files
    omaha_files_path: Path to the directory containing the Omaha binaries.
    empty_metainstaller_path: Path to empty (no tarball) metainstaller binary.
    offline_installers_file_path: Path to file specifying installers to build.
    manifest_files_path: Path to the directory containing the manifests for the
        apps specified in offline_installers_file_path.
    prefix: Optional prefix for the resulting installer.
    is_official: Whether to build official (vs. test) standalone installers.
    installers_sources_path: path to the directory containing the source files
        for building the metainstaller
    enterprise_installers_sources_path: path to the directory containing the
        source files for building enterprise installers
    lzma_path: path to lzma.exe
    resmerge_path: path to resmerge.exe

  Returns:
    Target nodes.

  Raises:
    Exception: Missing or invalid data specified in offline_installer.
  """
    standalone_installer_base_name = offline_installer.exe_base_name
    if not standalone_installer_base_name:
        raise Exception('Product name not specified.')

    output_dir = '$STAGING_DIR'
    if not is_official:
        standalone_installer_base_name = ('UNOFFICIAL_' +
                                          standalone_installer_base_name)
        output_dir = '$TARGET_ROOT/Test_Installers'

    target_base = prefix + standalone_installer_base_name
    target_name = target_base + '.exe'
    log_name = target_base + '_Contents.txt'

    # Write Omaha's version.
    log_text = '*** Omaha Version ***\n\n'
    log_text += omaha_version_info.GetVersionString() + '\n'

    # Rename the checked in binaries by adding the application guid as the
    # extension. This is needed as the meta-installer expects the
    # extension.
    # Also, log information about each app.
    additional_payload_contents = []
    if not offline_installer.binaries:
        raise Exception('No binaries specified.')

    manifest_source = []
    version_list = []
    for binary in offline_installer.binaries:
        (version, installer_path, guid) = binary
        if not installer_path or not guid or not version:
            raise Exception('Application specification is incomplete.')

        installer_path_modified = os.path.basename(installer_path) + '.' + guid
        # Have to use Command('copy') here instead of replicate, as the
        # file is being renamed in the process.
        env.Command(target=installer_path_modified,
                    source=installer_path,
                    action='@copy /y $SOURCES $TARGET')

        manifest_source.extend([
            manifest_files_path + '/' + guid + '.gup', installer_path_modified
        ])
        version_list.append(version)
        additional_payload_contents.append(installer_path_modified)

        # Log info about the app.
        log_text += '\n\n*** App: ' + guid + ' ***\n'
        log_text += '\nVersion:' + version + '\n'
        log_text += '\nINSTALLER:\n' + installer_path + '\n'

    # Place the generated manifests in a subdirectory. This allows a single
    # build to generate installers for multiple versions of the same app.
    manifest_file_path = env.Command(target=target_name +
                                     '_manifest/OfflineManifest.gup',
                                     source=manifest_source,
                                     action=[_GenerateUpdateResponseFile],
                                     INSTALLER_VERSIONS=version_list)

    # Use the BCJ2 tool from the official build we're using to generate this
    # metainstaller, not the current build directory.
    bcj2_path = omaha_files_path + '/bcj2.exe'

    additional_payload_contents.append(manifest_file_path)

    def WriteLog(target, source, env):
        """Legacy scons wrapper for utils.WriteInstallerLog()."""
        return standalone.utils.WriteInstallerLog(str(target[0]),
                                                  env['write_data'],
                                                  str(source[0]))

    env.Command(target='%s/%s' % (output_dir, log_name),
                source=manifest_file_path,
                action=WriteLog,
                write_data=log_text)

    results = []
    results += build_metainstaller.BuildMetaInstaller(
        env=env,
        target_name=target_name,
        omaha_version_info=omaha_version_info,
        empty_metainstaller_path=empty_metainstaller_path,
        omaha_files_path=omaha_files_path,
        prefix=prefix,
        suffix='_' + standalone_installer_base_name,
        additional_payload_contents=additional_payload_contents,
        additional_payload_contents_dependencies=offline_installers_file_path,
        output_dir=output_dir,
        installers_sources_path=installers_sources_path,
        lzma_path=lzma_path,
        resmerge_path=resmerge_path,
        bcj2_path=bcj2_path)

    standalone_installer_path = '%s/%s' % (output_dir, target_name)

    # Build an enterprise installer.
    if offline_installer.should_build_enterprise_msi:
        # TODO(omaha): Add support for bundles here and to
        #   BuildEnterpriseInstallerFromStandaloneInstaller().
        # TODO(omaha): Determine how product_version should be decided for MSI in
        #   bundle scenarios.
        # TODO(omaha): custom tag, silent uninstall args, distribution data may need
        #   to be made per-app.
        if 1 < len(offline_installer.binaries):
            raise Exception(
                'Enterprise installers do not currently support bundles.')
        (product_version, installer_path,
         product_guid) = offline_installer.binaries[0]

        # Note: msi_base_name should not include version info and cannot change!
        friendly_product_name = offline_installer.friendly_product_name
        msi_base_name = offline_installer.msi_base_name
        custom_tag_params = offline_installer.custom_tag_params
        silent_uninstall_args = offline_installer.silent_uninstall_args
        msi_installer_data = offline_installer.msi_installer_data

        # custom_tag_params and msi_installer_data are optional.
        if (not product_version or not friendly_product_name
                or not msi_base_name or not silent_uninstall_args):
            raise Exception(
                'Field required to build enterprise MSI is missing.')

        if not is_official:
            msi_base_name = ('UNOFFICIAL_' + msi_base_name)

        results += (build_enterprise_installer.
                    BuildEnterpriseInstallerFromStandaloneInstaller(
                        env,
                        friendly_product_name,
                        product_version,
                        product_guid,
                        custom_tag_params,
                        silent_uninstall_args,
                        msi_installer_data,
                        standalone_installer_path,
                        omaha_files_path + '/msi_custom_action.dll',
                        prefix + msi_base_name,
                        enterprise_installers_sources_path,
                        output_dir=output_dir))

    # Tag the meta-installer if an installers.txt file was specified.
    if offline_installer.installers_txt_filename:
        installers_txt_path = env.File(
            offline_installer.installers_txt_filename).abspath
        app_bundles = tag_meta_installers.ReadBundleInstallerFile(
            installers_txt_path)

        bundles = {}
        for (key, bundle_list) in app_bundles.items():
            if not bundle_list or not key:
                continue
            if not key in bundles:
                bundles[key] = bundle_list
            else:
                new_bundles_list = bundles[key] + bundle_list
                bundles[key] = new_bundles_list

        tag_meta_installers.SetOutputFileNames(target_name, bundles, '')
        for bundles_lang in bundles.itervalues():
            for bundle in bundles_lang:
                results += tagged_installer.TagOneBundle(
                    env=env,
                    bundle=bundle,
                    untagged_binary_path=standalone_installer_path,
                    output_dir='$TARGET_ROOT/Tagged_Offline_Installers',
                )

    return results