| # Copyright 2018 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import("//build/compiled_action.gni") |
| import("//build/packages/package_metadata.gni") |
| |
| amber_repository_dir = "$root_out_dir/amber-files" |
| |
| # Directory containing developer signing keys. |
| amber_keys_dir = "//src/sys/pkg/bin/amber/keys" |
| |
| # Directory containing files named by their merkleroot content IDs in |
| # ASCII hex. The //build/image:pm_publish_blobs target populates |
| # this with copies of build products, but never removes old files. |
| amber_repository_blobs_dir = "$amber_repository_dir/repository/blobs" |
| |
| template("_pm") { |
| compiled_action(target_name) { |
| tool = "//src/sys/pkg/bin/pm:pm_bin" |
| tool_output_name = "pm" |
| forward_variables_from(invoker, |
| [ |
| "args", |
| "data_deps", |
| "depfile", |
| "deps", |
| "inputs", |
| "metadata", |
| "outputs", |
| "public_deps", |
| "testonly", |
| "visibility", |
| ]) |
| } |
| } |
| |
| # Generate a sealed package file from a manifest. |
| # |
| # Parameters |
| # |
| # manifest (required) |
| # [label] A generate_manifest() target defined earlier in the same file. |
| # This provides the contents for the package. |
| # |
| # The following two items are only required in order to produce metadata about |
| # the package sets, and may be removed in the future: |
| # |
| # package_name (default: the target name) |
| # [string] Name of the package (should match what is in meta/package) |
| # |
| # package_variant (default: "0") |
| # [string] Variant of the package (should match what is in meta/package) |
| # |
| # deps (optional) |
| # test (optional) |
| # visibility (optional) |
| # Same as for any GN `action()` target. |
| template("pm_build") { |
| forward_variables_from(invoker, |
| [ |
| "package_name", |
| "package_variant", |
| ]) |
| if (!defined(package_name)) { |
| package_name = target_name |
| } |
| |
| if (!defined(package_variant)) { |
| package_variant = "0" |
| } |
| |
| pkg_out_dir = "$target_out_dir/$target_name" |
| pkg_output_manifest = "$pkg_out_dir/package_manifest.json" |
| |
| metadata_target_name = "${target_name}_metadata" |
| define_package_metadata(metadata_target_name) { |
| package_name = package_name |
| snapshot_entry = "$package_name/$package_variant=" + |
| rebase_path("$pkg_out_dir/blobs.json", root_build_dir) |
| blob_manifest = "$pkg_out_dir/blobs.manifest" |
| meta_far_merkle_index_entry = |
| "$package_name/$package_variant=" + |
| rebase_path("$pkg_out_dir/meta.far.merkle", root_build_dir) |
| package_output_manifest = pkg_output_manifest |
| } |
| |
| _pm(target_name) { |
| forward_variables_from(invoker, |
| [ |
| "data_deps", |
| "deps", |
| "public_deps", |
| "testonly", |
| "visibility", |
| ]) |
| if (!defined(deps)) { |
| deps = [] |
| } |
| pkg_manifest_outputs = get_target_outputs(invoker.manifest) |
| pkg_manifest_file = pkg_manifest_outputs[0] |
| deps += [ invoker.manifest ] |
| inputs = [ pkg_manifest_file ] |
| depfile = "$pkg_out_dir/meta.far.d" |
| |
| metadata = { |
| if (defined(invoker.metadata)) { |
| forward_variables_from(invoker.metadata, "*") |
| } |
| package_barrier = [ ":$metadata_target_name" ] |
| } |
| deps += [ ":$metadata_target_name" ] |
| |
| outputs = [ |
| # produced by seal, must be listed first because of depfile rules. |
| "$pkg_out_dir/meta.far", |
| |
| # update |
| "$pkg_out_dir/meta/contents", |
| |
| # seal |
| "$pkg_out_dir/meta.far.merkle", |
| |
| # package blob json manifest |
| "$pkg_out_dir/blobs.json", |
| |
| # package blob manifest |
| "$pkg_out_dir/blobs.manifest", |
| |
| # package output manifest |
| pkg_output_manifest, |
| ] |
| |
| args = [ |
| "-o", |
| rebase_path(pkg_out_dir, root_build_dir), |
| "-m", |
| rebase_path(pkg_manifest_file, root_build_dir), |
| "-n", |
| package_name, |
| "-version", |
| package_variant, |
| "build", |
| "-output-package-manifest", |
| rebase_path(pkg_output_manifest, root_build_dir), |
| "-depfile", |
| "-blobsfile", |
| "-blobs-manifest", |
| ] |
| } |
| } |
| |
| template("pm_prepare_publish") { |
| # These files are copied from amber_keys_dir into $amber_repository_dir/keys. |
| copy("${target_name}__keys") { |
| sources = [ |
| "$amber_keys_dir/snapshot.json", |
| "$amber_keys_dir/targets.json", |
| "$amber_keys_dir/timestamp.json", |
| ] |
| |
| outputs = [ "$amber_repository_dir/keys/{{source_file_part}}" ] |
| } |
| |
| # TODO(fxbug.dev/38262) In order to be TUF-1.0 conformant, we need to have |
| # versioned-prefixed root metadata files. Fow now this just hard-codes |
| # copying the current metadata to the correct place, but long term this |
| # should be computed so we don't forget to copy the file when we rotate the |
| # root metadata. |
| copy("${target_name}__root_manifest") { |
| sources = [ "$amber_keys_dir/metadata/7.root.json" ] |
| |
| outputs = [ "$amber_repository_dir/repository/root.json" ] |
| } |
| |
| # TODO(fxbug.dev/38262) See the comment on `root_manifest`. |
| copy("${target_name}__versioned_root_manifest") { |
| sources = [ |
| "$amber_keys_dir/metadata/1.root.json", |
| "$amber_keys_dir/metadata/2.root.json", |
| "$amber_keys_dir/metadata/3.root.json", |
| "$amber_keys_dir/metadata/4.root.json", |
| "$amber_keys_dir/metadata/5.root.json", |
| "$amber_keys_dir/metadata/6.root.json", |
| "$amber_keys_dir/metadata/7.root.json", |
| ] |
| |
| outputs = [ "$amber_repository_dir/repository/{{source_file_part}}" ] |
| } |
| group(target_name) { |
| forward_variables_from(invoker, |
| [ |
| "deps", |
| "testonly", |
| "visibility", |
| ]) |
| if (!defined(deps)) { |
| deps = [] |
| } |
| deps += [ |
| ":${target_name}__keys", |
| ":${target_name}__root_manifest", |
| ":${target_name}__versioned_root_manifest", |
| ] |
| |
| metadata = { |
| package_repository = [ |
| { |
| path = rebase_path("$amber_repository_dir/repository", root_build_dir) |
| targets = rebase_path("$amber_repository_dir/repository/targets.json", |
| root_build_dir) |
| blobs = rebase_path("$amber_repository_dir/repository/blobs", |
| root_build_dir) |
| }, |
| ] |
| } |
| } |
| } |
| |
| template("pm_publish") { |
| _pm(target_name) { |
| forward_variables_from(invoker, |
| [ |
| "deps", |
| "data_deps", |
| "inputs", |
| "testonly", |
| "visibility", |
| ]) |
| depfile = "${target_gen_dir}/${target_name}.d" |
| |
| assert(inputs == [ inputs[0] ], |
| "pm_publish(\"$target_name\") requires exactly one input") |
| |
| outputs = [ |
| # Note: the first output is the one that appears in the depfile. |
| "$amber_repository_dir/repository/timestamp.json", |
| "$amber_repository_dir/repository/snapshot.json", |
| "$amber_repository_dir/repository/targets.json", |
| ] |
| |
| args = [ |
| "publish", |
| "-depfile", |
| rebase_path(depfile, root_build_dir), |
| "-C", |
| "-r", |
| rebase_path(amber_repository_dir, root_build_dir), |
| "-lp", |
| "-f", |
| rebase_path(inputs[0], root_build_dir), |
| "-vt", |
| ] |
| } |
| } |