| #!/bin/bash |
| |
| # Copyright (c) 2012 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. |
| |
| # Abort on error. |
| set -e |
| |
| LSB_FILE=/etc/lsb-release |
| |
| # Load common constants and variables. |
| . "$(dirname "$0")/common.sh" |
| |
| usage() { |
| echo "Usage $PROG image [config]" |
| } |
| |
| # Usage: lsbequals path-to-lsb-file key expected-value |
| # Returns 0 if they match, 1 otherwise. |
| # Also outputs a warning message if they don't match. |
| lsbequals() { |
| local lsbfile="$1" |
| local key="$2" |
| local expectval="$3" |
| local realval=$(lsbval "$lsbfile" $key) |
| if [ "$realval" != "$expectval" ]; then |
| error "${key} mismatch. Expected '${expectval}'," \ |
| "image contains '${realval}'" |
| return 1 |
| fi |
| return 0 |
| } |
| |
| # Usage: check_keyval_in_list lsbfile lsbkey [list of values] |
| # Extracts the lsb-release value for the specified key, and confirms it |
| # matches one of the allowed values specified in value_array. |
| # Implementation note: |
| # You can't really pass bash arrays to functions. Best you can do is either |
| # serialize to string/pass/deserialize (e.g. using whitspace/IFS hacks), or, |
| # let the array contents be received as multiple arguments to the target |
| # function. We take the latter approach here, hence the shift's to get the |
| # first 2 arguments out, before we process the rest of the varargs. |
| check_keyval_in_list() { |
| local lsbfile="$1" |
| shift |
| local lsbkey="$1" |
| shift |
| local lsbval=$(lsbval "$lsbfile" "$lsbkey") |
| while [ $# -gt 0 ]; do |
| if [ "$lsbval" == "$1" ]; then |
| return 0 |
| fi |
| shift |
| done |
| # If we get here, it wasn't found |
| error "${lsbkey}: Value '${lsbval}' was not recognized" |
| return 1 |
| } |
| |
| # Usage: lsb_syntaxcheck path-to-lsb-file |
| # Enforces a number of basic validity checks on the overall format and contents |
| # of the lsb-release file: |
| # - Every line is "key=value". |
| # - No space after key, no space before value. |
| # - key is all A-Z or _, but not starting with _. |
| # - value is made up of printable characters, or is empty. |
| # - The whole file is a reasonable size (4kb). |
| lsb_syntaxcheck() { |
| local lsbfile="$1" |
| syntaxbad=0 |
| # Checks for key being A-Z_, 1 or more characters, not starting with _. |
| # Also checks for = with no spaces on either side. |
| # Checks that the value contains printables (and not starting with space). |
| # Alternatively, the value is permitted to be empty (0 chars) too. |
| # Allow comments to start with #. |
| badlines=$(grep -Ev \ |
| -e '^[A-Z][A-Z_]*=([[:graph:]][[:print:]]*)?$' \ |
| -e '^[[:space:]]*#' "${lsbfile}") |
| if [ -n "$badlines" ]; then |
| syntaxbad=1 |
| error "${lsbfile}: Some lines seem non-well-formed:" |
| error "${badlines}" |
| fi |
| |
| # Overall file size check: |
| size=$(ls -sk "$lsbfile" | cut -d ' ' -f 1) |
| if [ $size -gt 4 ]; then |
| syntaxbad=1 |
| error "${lsbfile}: This file exceeds 4kb" |
| fi |
| return $syntaxbad |
| } |
| |
| main() { |
| # We want to catch all the discrepancies, not just the first one. |
| # So, any time we find one, we set testfail=1 and continue. |
| # When finished we will use testfail to determine our exit value. |
| local testfail=0 |
| |
| if [ $# -ne 1 ] && [ $# -ne 2 ]; then |
| usage |
| exit 1 |
| fi |
| |
| local image="$1" |
| |
| # Default config location: same directory as this script. |
| local configfile="$(dirname "$0")/default_lsb_release.config" |
| # Or, maybe a config was provided on the command line. |
| if [ $# -eq 2 ]; then |
| configfile="$2" |
| fi |
| # Either way, load test-expectations data from config. |
| info "Loading config from ${configfile}" |
| . "$configfile" || return 1 |
| |
| local loopdev rootfs |
| if [[ -d "${image}" ]]; then |
| # We're given a mounted rootfs. |
| rootfs="${image}" |
| else |
| # Mount the disk image. |
| loopdev=$(loopback_partscan "${image}") |
| rootfs=$(make_temp_dir) |
| mount_loop_image_partition_ro "${loopdev}" 3 "${rootfs}" |
| fi |
| local lsb="$rootfs/$LSB_FILE" |
| |
| # Basic syntax check first. |
| lsb_syntaxcheck "$lsb" || testfail=1 |
| |
| lsbequals $lsb CHROMEOS_AUSERVER "$expected_auserver" || testfail=1 |
| lsbequals $lsb CHROMEOS_RELEASE_NAME "$expected_release_name" || testfail=1 |
| check_keyval_in_list $lsb CHROMEOS_RELEASE_TRACK \ |
| "${expected_release_tracks[@]}" || testfail=1 |
| |
| local board=$(get_board_from_lsb_release "${rootfs}") |
| if check_keyval_in_list $lsb CHROMEOS_RELEASE_BOARD \ |
| "${expected_boards[@]}"; then |
| local boardvar=$(get_boardvar_from_lsb_release "${rootfs}") |
| channel=$(lsbval $lsb CHROMEOS_RELEASE_TRACK) |
| # For a canary or dogfood channel, appid maybe a different default value. |
| if [[ "${channel}" == 'canary-channel' || |
| "${channel}" == 'dogfood-channel' ]]; then |
| eval "expected_appid=\"\$expected_appid_${channel%\-channel}\"" |
| else |
| eval "expected_appid=\"\$expected_appid_$boardvar\"" |
| fi |
| lsbequals $lsb CHROMEOS_RELEASE_APPID "$expected_appid" || testfail=1 |
| else # unrecognized board |
| testfail=1 |
| error "Unknown board: ${board}" |
| fi |
| |
| exit $testfail |
| } |
| |
| main "$@" |