blob: e752e3a2b840389682fb67635393331e22cb8547 [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.
#
# This script creates a self-extraction bundle for v3 ChromeOS HWID.
# Syntax: $0 [-o output_file_name] [-f factory_par] \
# file_name [file_name [file_name...]]
SCRIPT="$0"
SCRIPT_BASE="$(readlink -f "$(dirname "$SCRIPT")")"
. "$SCRIPT_BASE/lib/shflags" || exit 1
# DEFINE_string name default_value description flag
DEFINE_string output "" "Output file path" "o"
DEFINE_string factory_par "" "file name of the factory.par tool" "f"
# Internal variable to track temporary objects
TMP_STACK=""
# Prefix string of the output bundle name.
BUNDLE_PREFIX="hwid_v3_bundle"
# Tool for verifying HWID Databases.
FACTORY_TOOL=""
# Tool for creating self-extractable script.
SHAR_TOOL="$(which shar)"
# Stub for generated bundle (updater). Note that this stub must be same as
# src/platform/chromeos-hwid/lib/stub_updater since HWID bundles generated from
# CPFE will use the stub from there.
# <======================= START OF STUB CODE
STUB_UPDATER='#!/bin/sh
#
# 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.
#
# This is a self-extraction package for ChromeOS HWID.
# Syntax: $0 [stateful_partition_device]
START_DIR="$(pwd)"
MOUNT_DIR=""
TARGET_BASE_MOUNT="dev_image/factory"
TARGET_BASE_LIVE="/usr/local/factory"
TARGET_NAME="hwid"
on_exit() {
cd "$START_DIR"
if [ -d "$MOUNT_DIR" ]; then
sudo umount "$MOUNT_DIR" || true
rmdir "$MOUNT_DIR" || true
fi
}
die() {
echo "ERROR: $*" 1>&2
exit 1
}
die_usage() {
die "Usage: $0 [stateful_partition_device_or_folder]"
}
setup_target() {
local target_dir=""
local recreate_folder="TRUE"
case "$#" in
0 )
target_dir="$TARGET_BASE_LIVE/$TARGET_NAME"
echo "Updating live image path $target_dir..."
;;
1 )
local state_dev="$1"
if [ -b "$state_dev" ]; then
echo "Updating to stateful partition $state_dev..."
MOUNT_DIR="$(mktemp -d /tmp/hwid_XXXXXXXX)"
sudo mount "$state_dev" "$MOUNT_DIR" || die "Failed to mount."
target_dir="$MOUNT_DIR/$TARGET_BASE_MOUNT/$TARGET_NAME"
elif [ -d "$state_dev" ]; then
echo "Updating to folder $state_dev..."
target_dir="$state_dev"
# This is usually for manually debugging so do not remove existing files
recreate_folder=""
else
die_usage
fi
;;
* )
die_usage
;;
esac
if [ -n "$recreate_folder" ]; then
# For a valid target, the parent folder should already exist.
if [ ! -d "$(dirname "$target_dir")" ]; then
die "Invalid target ($target_dir). Missing required folders."
fi
# Now, update $target_dir
sudo rm -rf "$target_dir" || die "Failed to erase $target_dir"
sudo mkdir -p "$target_dir" || die "Failed to mkdir $target_dir"
fi
# Move to $target_dir for file extraction
cd "$target_dir"
}
set -e
trap on_exit EXIT
setup_target "$@"
# force shar to overwrite files
set -- "-c"
# ----- Following data is generated by shar -----'
# <======================= END OF STUB CODE
# Usage string of this script
FLAGS_HELP="USAGE: $0 [flags] PROJECT [PROJECT [PROJECT ...]]"
push_tmp() {
TMP_STACK="$* $TMP_STACK"
}
pop_tmp() {
local tmp
for tmp in $TMP_STACK; do
if [ -d "$tmp" ]; then
rm -rf "$tmp" || true
else
rm -f "$tmp" || true
fi
done
TMP_STACK=""
}
warn() {
echo "$*" >&2
}
die() {
warn "ERROR: $*"
exit 1
}
die_usage() {
flags_help >&2
exit 1
}
hwid_tool_wrapper() {
shift
"${CROS_WORKON_SRCROOT}/src/platform/factory/bin/hwid" "${@}"
}
find_hwid_tool() {
if [ -n "${FLAGS_factory_par}" ]; then
FACTORY_TOOL="${FLAGS_factory_par}"
elif [ -n "${CROS_WORKON_SRCROOT}" ]; then
FACTORY_TOOL="hwid_tool_wrapper"
elif [ -x "${SCRIPT_BASE}/../shopfloor/factory.par" ]; then
FACTORY_TOOL="${SCRIPT_BASE}/../shopfloor/factory.par hwid"
else
warn "HWID tool is not found. The given HWID databases will not be" \
"verified before packing."
fi
}
main() {
find_hwid_tool
# Check the dependent commands
[ -n "${SHAR_TOOL}" ] || \
die 'This script needs the utility tool `shar`, please install it first.'
# Check that we have project arguments.
if [ $# -lt 1 ]; then
die_usage
fi
# Decide default output filename.
local output_file="${FLAGS_output}"
[ -z "${output_file}" ] && output_file="$(basename "${1}")"
[[ "${output_file}" = *'.sh' ]] ||
output_file="${BUNDLE_PREFIX}_${output_file}.sh"
# Prepare staging temporary space
local bundle_dir="$(mktemp -d --tmp)"
push_tmp "$bundle_dir"
warn "Building v3 bundle in folder: $bundle_dir"
for file_name in "${@}"; do
[ -n "${file_name}" ] || die "An empty string is not a valid file name!"
[ -f "${file_name}" ] || die "File ${file_name} not found."
# Determine if the given file is a HWID bundle or a HWID database by
# the existance of shebang.
if [ "$(head -c 2 "${file_name}")" = '#!' ]; then
warn "Unpack the HWID bundle: ${file_name}"
sh "${file_name}" "${bundle_dir}"
else
cp -f "${file_name}" "${bundle_dir}"
fi
done
# Verify the HWID databases
if [ -n "${FACTORY_TOOL}" ]; then
for database_file in "${bundle_dir}"/*; do
warn "Verify the HWID database: $(basename "${database_file}")"
"${FACTORY_TOOL}" hwid verify-database \
--hwid-db-path "$(dirname "${database_file}")" \
--project "$(basename "${database_file}")"
done
else
for database_file in "${bundle_dir}"/*; do
warn "Skip verifying the HWID database: $(basename "${database_file}")"
done
fi
local staging_name="$(mktemp)"
push_tmp "$staging_name"
echo "$STUB_UPDATER" >"${staging_name}"
(cd "${bundle_dir}"; shar -T .) >>"${staging_name}"
mv -f "${staging_name}" "${output_file}"
chmod a+rx "${output_file}"
warn "HWID bundle created in: ${output_file}"
}
# Parse command line
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
set -e
trap pop_tmp EXIT
main "$@"