#!/bin/bash # linaro-hwpack-install - Install a Linaro Hardware Pack. # This script is meant to run inside a chroot containing nothing other than # ubuntu-minimal, so it must not depend on anything that's not in # there. # TODO: When upgrading to a newer hwpack, make sure packages and apt sources # that are no longer needed are removed. # Copyright (C) 2010, 2011 Linaro # # Author: Guilherme Salgado # # This file is part of Linaro Image Tools. # # Linaro Image Tools is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # Linaro Image Tools is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Linaro Image Tools; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. set -e LOCKFILE="/var/lock/hwpack" TEMP_DIR=$(mktemp -d) HWPACK_DIR="${TEMP_DIR}/unpacked" INSTALL_LATEST="no" FORCE_YES="no" SOURCES_LIST_FILE="${TEMP_DIR}/sources.list" APT_GET_OPTIONS="Dir::Etc::SourceList=${SOURCES_LIST_FILE}" SUPPORTED_FORMATS="1.0 2.0" # A space-separated list of hwpack formats. sudo="sudo" if [ $(id -u) -eq 0 ]; then sudo="" fi die() { echo -e "$@" exit 1 } usage_msg="Usage: $(basename $0) [--install-latest] [--force-yes] HWPACK_TARBALL" if [ $# -eq 0 ]; then die $usage_msg fi HWPACK_TARBALL_FOUND="no" while [ $# -gt 0 ]; do case "$1" in --install-latest) INSTALL_LATEST="yes" shift;; --force-yes) FORCE_YES="yes" shift;; --*) die $usage_msg "\nUnrecognized option: \"$1\"";; *) [ "$HWPACK_TARBALL_FOUND" = "yes" ] && die $usage_msg HWPACK_TARBALL="$1" HWPACK_TARBALL_FOUND="yes" shift;; esac done [ "$HWPACK_TARBALL_FOUND" = "no" ] && die $usage_msg # Try to acquire fd #9 (i.e. /var/lock/hwpack) for 2 seconds. # Using 9 as the file descriptor because of https://launchpad.net/bugs/249620 exec 9>$LOCKFILE flock -w2 9 || die "Could not acquire lock: $LOCKFILE" cleanup() { # Ensure our temp dir and apt sources are removed. echo -n "Cleaning up ..." rm -rf $TEMP_DIR $sudo apt-get update -qq echo "Done" } # From now on we'll be making changes to the system, so we need to clean # things up when the script exits. trap cleanup EXIT # This creates all the directories we need. mkdir -p "$HWPACK_DIR" # Unpack the hwpack tarball. We don't download it here because the chroot may # not contain any tools that would allow us to do that. echo -n "Unpacking hardware pack ..." tar zxf "$HWPACK_TARBALL" -C "$HWPACK_DIR" echo "Done" # Check the format of the hwpack is supported. hwpack_format=$(cat ${HWPACK_DIR}/FORMAT) supported="false" for format in $SUPPORTED_FORMATS; do if [ $hwpack_format == $format ]; then supported="true" break fi done [ $supported == "true" ] || \ die "Unsupported hwpack format: $hwpack_format. "\ "Try using a newer version of $(basename $0)." # Check the architecture of the hwpack matches that of the host system. HWPACK_ARCH=`grep ARCHITECTURE "${HWPACK_DIR}/metadata" | cut -d "=" -f2` [ "$HWPACK_ARCH" == `dpkg --print-architecture` ] || \ die "Hardware pack architecture ($HWPACK_ARCH) does not match the host's architecture" # Install the apt sources that contain the packages we need. for filename in $(ls "${HWPACK_DIR}"/sources.list.d/); do file="${HWPACK_DIR}"/sources.list.d/$filename should_install=0 stripped_file=${TEMP_DIR}/$filename grep -v "\(^#\|^\s*$\)" $file > $stripped_file while read line; do # Only install files that have at least one line not present in the # existing sources lists. grep -qF "$line" /etc/apt/sources.list.d/* /etc/apt/sources.list \ || should_install=1 done < $stripped_file if [ $should_install -eq 1 ]; then $sudo cp $file /etc/apt/sources.list.d/hwpack.$filename fi done # Import the OpenPGP keys for the files installed above. for filename in $(ls "${HWPACK_DIR}"/sources.list.d.gpg/); do file="${HWPACK_DIR}"/sources.list.d.gpg/$filename $sudo apt-key add $file done # Add one extra apt source for the packages included in the hwpack and make # sure it's the first on the list of sources so that it gets precedence over # the others. echo "deb file:${HWPACK_DIR}/pkgs ./" > "$SOURCES_LIST_FILE" cat /etc/apt/sources.list >> "$SOURCES_LIST_FILE" echo "Updating apt package lists ..." $sudo apt-get -o "$APT_GET_OPTIONS" update -q echo -n "Installing packages ..." if [ "$FORCE_YES" == "yes" ]; then FORCE_OPTIONS="--yes --force-yes" else FORCE_OPTIONS="" fi # "newer" hwpacks contain a dependency package whose Depends is the # same as the packages config setting from the file the hwpack was # build from. But if we just installed that, a newer version of a # package than that in the hwpack might have made it to the main # archive and apt-get would install that instead. So we install the # specific package versions that make up the hwpack. /That/ however # would leave all the packages from the hwpack marked as manually # installed, so if a newer hwpack was installed over the top which no # longer depended on one of the packages the older one did, the # package would not be eligible for autoremoval. So we mark the all # packages newly installed as part of hwpack installed (apart from the # dependency package) as automatically installed with apt-get # markauto. # # For "older" hwpacks that don't have a dependency package, we just # manually install the contents of the hwpack. HWPACK_NAME=`grep NAME "${HWPACK_DIR}/metadata" | cut -d "=" -f2` HWPACK_VERSION=`grep VERSION "${HWPACK_DIR}/metadata" | cut -d "=" -f2` dependency_package="hwpack-${HWPACK_NAME}" if grep -q "^${dependency_package}=${HWPACK_VERSION}\$" "${HWPACK_DIR}"/manifest; then DEP_PACKAGE_PRESENT="yes" else DEP_PACKAGE_PRESENT="no" fi packages_without_versions=`sed 's/=.*//' "${HWPACK_DIR}"/manifest` packages_with_versions=`cat "${HWPACK_DIR}"/manifest` if [ "$INSTALL_LATEST" == "yes" ]; then packages="${packages_without_versions}" else packages="${packages_with_versions}" fi if [ "$DEP_PACKAGE_PRESENT" == "yes" ]; then to_be_installed= for package in $packages_without_versions; do if [ "${package}" != "${dependency_package}" ]; then { dpkg --get-selections $package 2>/dev/null| grep -qw 'install$'; } || to_be_installed="$to_be_installed $package" fi done fi $sudo apt-get $FORCE_OPTIONS -o "$APT_GET_OPTIONS" install ${packages} if [ "$DEP_PACKAGE_PRESENT" == "yes" ]; then if [ -n "${to_be_installed}" ]; then $sudo apt-get $FORCE_OPTIONS -o "$APT_GET_OPTIONS" markauto ${to_be_installed} fi fi echo "Done"