Skip to content

Commit

Permalink
macOS Signing Scripts: Refactor pipeline.sign_all
Browse files Browse the repository at this point in the history
Split this large function into helper functions to reduce the nesting
level and make the higher-order pipeline more apparent.

Bug: 1442256
Change-Id: Ice373871bec22ef695898fa6181ed92a67a083bb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4545579
Commit-Queue: Robert Sesek <rsesek@chromium.org>
Reviewed-by: Mark Mentovai <mark@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1145611}
  • Loading branch information
rsesek authored and Chromium LUCI CQ committed May 17, 2023
1 parent 6ca62c3 commit 3b9ab93
Showing 1 changed file with 119 additions and 84 deletions.
203 changes: 119 additions & 84 deletions chrome/installer/mac/signing/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -666,55 +666,13 @@ def sign_all(orig_paths,
produced. The string 'stable' matches the None channel.
"""
with commands.WorkDirectory(orig_paths) as notary_paths:
# First, sign all the distributions and optionally submit the
# notarization requests.
uuids_to_config = {}
signed_frameworks = {}
created_app_bundles = set()

distributions = _filter_distributions(config.distributions, skip_brands,
channels)

for dist in distributions:
with commands.WorkDirectory(orig_paths) as paths:
dist_config = dist.to_config(config)
do_packaging = (dist.package_as_dmg or
dist.package_as_pkg) and not disable_packaging

# If not packaging and not notarizing, then simply drop the
# signed bundle in the output directory when done signing.
if not do_packaging and not config.notarize.should_notarize():
dest_dir = paths.output
else:
dest_dir = notary_paths.work

dest_dir = os.path.join(dest_dir,
_intermediate_work_dir_name(dist))

# Different distributions might share the same underlying app
# bundle, and if they do, then the _intermediate_work_dir_name
# function will return the same value. Skip creating another app
# bundle if that is the case.
if dest_dir in created_app_bundles:
continue
created_app_bundles.add(dest_dir)

_customize_and_sign_chrome(paths, dist_config, dest_dir,
signed_frameworks)

# If the build products are to be notarized, ZIP the app bundle
# and submit it for notarization.
if config.notarize.should_notarize():
zip_file = os.path.join(
notary_paths.work,
dist_config.packaging_basename + '.zip')
commands.run_command([
'zip', '--recurse-paths', '--symlinks', '--quiet',
zip_file, dist_config.app_dir
],
cwd=dest_dir)
uuid = notarize.submit(zip_file, dist_config)
uuids_to_config[uuid] = dist_config
# First, sign all the distributions and optionally submit the
# notarization requests.
uuids_to_config = _sign_and_maybe_notarize_distributions(
config, distributions, notary_paths, disable_packaging)

# If needed, wait for app notarization results to come back, and staple
# if required.
Expand All @@ -731,43 +689,120 @@ def sign_all(orig_paths,

# After all apps are optionally notarized, package as required.
if not disable_packaging:
uuids_to_package_path = {}
for dist in distributions:
dist_config = dist.to_config(config)
paths = orig_paths.replace_work(
os.path.join(
notary_paths.work,
_intermediate_work_dir_name(dist_config.distribution)))

if dist.inflation_kilobytes:
inflation_path = os.path.join(
paths.packaging_dir(config), 'inflation.bin')
commands.run_command([
'dd', 'if=/dev/urandom', 'of=' + inflation_path,
'bs=1000', 'count={}'.format(dist.inflation_kilobytes)
])

if dist.package_as_dmg:
dmg_path = _package_and_sign_dmg(paths, dist_config)

if config.notarize.should_notarize():
uuid = notarize.submit(dmg_path, dist_config)
uuids_to_package_path[uuid] = dmg_path

if dist.package_as_pkg:
pkg_path = _package_and_sign_pkg(paths, dist_config)

if config.notarize.should_notarize():
uuid = notarize.submit(pkg_path, dist_config)
uuids_to_package_path[uuid] = pkg_path

# If needed, wait for package notarization results to come back, and
# staple if required.
if config.notarize.should_wait():
for result in notarize.wait_for_results(
uuids_to_package_path.keys(), config):
if config.notarize.should_staple():
package_path = uuids_to_package_path[result]
notarize.staple(package_path)
_package_and_maybe_notarize_distributions(config, distributions,
notary_paths)

_package_installer_tools(orig_paths, config)


def _sign_and_maybe_notarize_distributions(config, distributions, notary_paths,
disable_packaging):
"""Iterates each distribution in |distributions|, codesigns it according to
the |config|, and potentially uploads it for notarization.
Args:
config: The |config.CodeSignConfig| object.
distributions: The |model.Distribution|s to sign.
notary_paths: A |model.Paths| object where artifacts will be placed when
notarizing.
disable_packaging: Whether all packaging is disabled.
Returns:
A dict mapping the notarization submission UUID to the
|config.CodeSignConfig.dist_config| for the |model.Distribution|. If
notarization is not performed, returns an empty dict.
"""
uuids_to_config = {}
signed_frameworks = {}
created_app_bundles = set()

for dist in distributions:
with commands.WorkDirectory(notary_paths) as paths:
dist_config = dist.to_config(config)
do_packaging = (dist.package_as_dmg or
dist.package_as_pkg) and not disable_packaging

# If not packaging and not notarizing, then simply drop the
# signed bundle in the output directory when done signing.
if not do_packaging and not config.notarize.should_notarize():
dest_dir = paths.output
else:
dest_dir = notary_paths.work

dest_dir = os.path.join(dest_dir, _intermediate_work_dir_name(dist))

# Different distributions might share the same underlying app
# bundle, and if they do, then the _intermediate_work_dir_name
# function will return the same value. Skip creating another app
# bundle if that is the case.
if dest_dir in created_app_bundles:
continue
created_app_bundles.add(dest_dir)

_customize_and_sign_chrome(paths, dist_config, dest_dir,
signed_frameworks)

# If the build products are to be notarized, ZIP the app bundle
# and submit it for notarization.
if config.notarize.should_notarize():
zip_file = os.path.join(notary_paths.work,
dist_config.packaging_basename + '.zip')
commands.run_command([
'zip', '--recurse-paths', '--symlinks', '--quiet', zip_file,
dist_config.app_dir
],
cwd=dest_dir)
uuid = notarize.submit(zip_file, dist_config)
uuids_to_config[uuid] = dist_config
return uuids_to_config


def _package_and_maybe_notarize_distributions(config, distributions,
notary_paths):
"""Iterates each |model.Distribution| in |distributions| and packages it
according to its specification. If notarization is requested, that is
performed on the assembled package.
Args:
config: The |config.CodeSignConfig| object.
distributions: The |model.Distribution|s to sign.
notary_paths: A |model.Paths| object where artifacts will be placed when
notarizing.
"""
uuids_to_package_path = {}
for dist in distributions:
dist_config = dist.to_config(config)
paths = notary_paths.replace_work(
os.path.join(notary_paths.work,
_intermediate_work_dir_name(dist_config.distribution)))

if dist.inflation_kilobytes:
inflation_path = os.path.join(
paths.packaging_dir(config), 'inflation.bin')
commands.run_command([
'dd', 'if=/dev/urandom', 'of=' + inflation_path, 'bs=1000',
'count={}'.format(dist.inflation_kilobytes)
])

if dist.package_as_dmg:
dmg_path = _package_and_sign_dmg(paths, dist_config)

if config.notarize.should_notarize():
uuid = notarize.submit(dmg_path, dist_config)
uuids_to_package_path[uuid] = dmg_path

if dist.package_as_pkg:
pkg_path = _package_and_sign_pkg(paths, dist_config)

if config.notarize.should_notarize():
uuid = notarize.submit(pkg_path, dist_config)
uuids_to_package_path[uuid] = pkg_path

# If needed, wait for package notarization results to come back, and
# staple if required.
if config.notarize.should_wait():
for result in notarize.wait_for_results(uuids_to_package_path.keys(),
config):
if config.notarize.should_staple():
package_path = uuids_to_package_path[result]
notarize.staple(package_path)

0 comments on commit 3b9ab93

Please sign in to comment.