|  | #!/bin/bash | 
|  | # Copyright 2017 The Chromium OS Authors. All rights reserved. | 
|  | # Use of this source code is governed by a BSD-style license that can be | 
|  | # found in the LICENSE file. | 
|  |  | 
|  | # Loads script libraries. | 
|  | CONTRIB_DIR=$(dirname "$(readlink -f "$0")") | 
|  | . "${CONTRIB_DIR}/common.sh" || exit 1 | 
|  |  | 
|  | FLAGS_HELP=" | 
|  | Command to rebuild firmware after a config change. | 
|  |  | 
|  | After you make a change to the firmware version in the master configuration, | 
|  | run this script to test it. It will rebuild the master configuration, update | 
|  | the Manifest and build the new firmware. You can then submit your CL to update | 
|  | the master configuration, safe in the knowledge that you have tested it. | 
|  |  | 
|  | Usage: | 
|  | cros_update_firmware <board> [project] | 
|  |  | 
|  | where <board> is the board whose firmware needs updating (e.g. 'coral'). | 
|  | [project] is the project the board belongs to. | 
|  | " | 
|  |  | 
|  | # Flags | 
|  | DEFINE_string board "${DEFAULT_BOARD}" "Which board the firmware is for" b | 
|  | DEFINE_string project "${DEFAULT_PROJECT}" "Which project this board is for" p | 
|  | DEFINE_boolean quiet "${FLAGS_FALSE}" "Reduce emerge build output" q | 
|  | DEFINE_boolean append_srcuris "${FLAGS_TRUE}" "Only applicable when the project | 
|  | flag is set. Append firmware uris to srcuris instead of overwriting. This is | 
|  | usually needed if you have limited access to project config repos, so | 
|  | overwriting would delete some uris." | 
|  |  | 
|  | # Parse command line. | 
|  | FLAGS "$@" || exit 1 | 
|  | eval set -- "${FLAGS_ARGV}" | 
|  | set -e | 
|  |  | 
|  | # Script must be run inside the chroot. | 
|  | assert_inside_chroot | 
|  |  | 
|  | start_workon() { | 
|  | local board="$1" | 
|  | local pkg item | 
|  | if [[ -z "$2" ]]; then | 
|  | echo "Empty package.  Skipping..." | 
|  | return 1 | 
|  | fi | 
|  | pkg=$(cros workon --board="${board}" info "$2" | cut -d ' ' -f 1) | 
|  | shift 2 | 
|  | for item in "$@"; do | 
|  | if [[ "${pkg}" == "${item}" ]]; then | 
|  | echo "Already workon ${pkg}.  Skipping..." | 
|  | return 1 | 
|  | fi | 
|  | done | 
|  | cros workon --board="${board}" start "${pkg}" | 
|  | return $? | 
|  | } | 
|  |  | 
|  | stop_workon() { | 
|  | cros workon --board="$1" stop "$2" | 
|  | } | 
|  |  | 
|  | update_firmware() { | 
|  | local board="$1" | 
|  | local project="$2" | 
|  | local base ebuild srcuris cfg_bsp_pkg cfg_bsp_baseboard_pkg | 
|  | local current_workon_pkg_list start_pkg result i quiet | 
|  | [[ "$3" == "${FLAGS_TRUE}" ]] && quiet="--quiet-build" | 
|  | local append_srcuris="$4" | 
|  |  | 
|  | set -e | 
|  |  | 
|  | # query the current working package | 
|  | mapfile -t current_workon_pkg_list < <(cros workon --board="${board}" list) | 
|  |  | 
|  | # check if chromeos-config-bsp is a virtual package | 
|  | cfg_bsp_pkg="chromeos-config-bsp" | 
|  | equery-"${board}" w chromeos-base/chromeos-config-bsp > /dev/null 2>&1 \ | 
|  | || cfg_bsp_pkg="chromeos-config-bsp-${board}-private" | 
|  | # check if chromeos-config-bsp-baseboard is in use | 
|  | cfg_bsp_baseboard_pkg="chromeos-config-bsp-baseboard" | 
|  | equery-"${board}" w chromeos-base/chromeos-config-bsp-baseboard \ | 
|  | > /dev/null 2>&1 || cfg_bsp_baseboard_pkg= | 
|  |  | 
|  | start_pkg=("${cfg_bsp_pkg}") | 
|  | start_pkg+=("chromeos-firmware-${board}") | 
|  | start_pkg+=("${cfg_bsp_baseboard_pkg}") | 
|  |  | 
|  | for i in "${!start_pkg[@]}"; do | 
|  | result[i]=0 | 
|  | start_workon "${board}" "${start_pkg[i]}" "${current_workon_pkg_list[@]}" \ | 
|  | || result[i]=$? | 
|  | done | 
|  |  | 
|  | overlay="${GCLIENT_ROOT}/src/private-overlays/overlay-${board}-private" | 
|  | metadata="${overlay}/metadata" | 
|  | edb_cache="/var/cache/edb/dep/mnt/host/source/src/private-overlays/overlay-${board}-private" | 
|  | base="${overlay}/chromeos-base" | 
|  | ebuild="${base}/chromeos-firmware-${board}/chromeos-firmware-${board}-9999.ebuild" | 
|  | srcuris="${base}/chromeos-firmware-${board}/files/srcuris" | 
|  | yaml_config="/build/${board}/usr/share/chromeos-config/yaml/config.yaml" | 
|  |  | 
|  | # Check project config repo exists -- if so generate the config first. | 
|  | if [[ -d "${GCLIENT_ROOT}/src/project/${project}" ]]; then | 
|  | pushd "${GCLIENT_ROOT}/src/project/${project}" > /dev/null | 
|  | for brd in *; do | 
|  | if [[ -d "${brd}" && -x "${brd}/config/bin/gen_config" && -f "${brd}/config.star" ]]; then | 
|  | pushd "${brd}" > /dev/null | 
|  | ./config/bin/gen_config config.star | 
|  | popd > /dev/null | 
|  | fi | 
|  | done | 
|  | popd > /dev/null | 
|  | fi | 
|  |  | 
|  | "emerge-${board}" -j ${quiet} ${cfg_bsp_baseboard_pkg} "${cfg_bsp_pkg}" chromeos-config | 
|  |  | 
|  | # If the append_srcuris and project flags are set, append uris that aren't | 
|  | # already in srcuris. Otherwise, overwrite srcuris. | 
|  | if [[ -n "${project}" && "${append_srcuris}" == "${FLAGS_TRUE}" ]]; then | 
|  | for uri in $(cros_config_host -c "${yaml_config}" get-firmware-uris); do | 
|  | if ! grep -q "${uri}" "${srcuris}"; then | 
|  | # Append uri to the last line of srcuris (srcuris should be a file with | 
|  | # one line per-uri). | 
|  | echo "${uri}" >> "${srcuris}" | 
|  | fi | 
|  | done | 
|  | else | 
|  | # Put each uri on its own line for easier merging in git. | 
|  | cros_config_host -c "${yaml_config}" get-firmware-uris | tr ' ' '\n' > "${srcuris}" | 
|  | fi | 
|  |  | 
|  | touch "${ebuild}" | 
|  |  | 
|  | # Clean metadata cache to make sure SRC_URI is fetched from ${srcuris} | 
|  | # instead from portage cache which maybe out of sync. | 
|  | # Note: this workaround is needed because we break the SRC_URI API contract | 
|  | # which is supposed to be a static (see | 
|  | # https://devmanual.gentoo.org/general-concepts/portage-cache/index.html). | 
|  | # TODO(crbug.com/927917): find a different way to generate SRC_URI and remove | 
|  | # these cache cleanup code. | 
|  | rm -rf "${metadata}/cache" "${metadata}/md5-cache" "${edb_cache}" | 
|  | "ebuild-${board}" "${ebuild}" manifest | 
|  | "emerge-${board}" -j ${quiet} "chromeos-firmware-${board}" | 
|  |  | 
|  | for i in "${!result[@]}"; do | 
|  | if [[ "${result[i]}" -eq "0" ]]; then | 
|  | stop_workon "${board}" "${start_pkg[i]}" | 
|  | fi | 
|  | done | 
|  | } | 
|  |  | 
|  | main() { | 
|  | if [[ -z "${FLAGS_board}" ]]; then | 
|  | die "-b or --board required." | 
|  | fi | 
|  |  | 
|  | update_firmware "${FLAGS_board}" "${FLAGS_project}" "${FLAGS_quiet}" "${FLAGS_append_srcuris}" | 
|  | } | 
|  |  | 
|  | main "$@" |