blob: e683727ed75a30d8226187aa2cbfb8b640cb3a16 [file] [log] [blame]
#!/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
# a single line). Escape slashes in uri.
sed -i "$ s/$/ ${uri//\//\\/}/" "${srcuris}"
fi
done
else
cros_config_host -c "${yaml_config}" get-firmware-uris > "${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 "$@"