mdt: Add a device-side package installation tool
This is a simple script that atomically updates the local package archive and
installs the given package file to the system.
Change-Id: I6c00c6e747497068d4a7c60d2c3d47fe9721a10b
diff --git a/debian/mdt-services.install b/debian/mdt-services.install
index 45bf8b7..08f38f8 100644
--- a/debian/mdt-services.install
+++ b/debian/mdt-services.install
@@ -1 +1,2 @@
etc /
+usr /
diff --git a/usr/sbin/mdt-install-package b/usr/sbin/mdt-install-package
new file mode 100644
index 0000000..9bf10ec
--- /dev/null
+++ b/usr/sbin/mdt-install-package
@@ -0,0 +1,126 @@
+#!/bin/bash
+
+set -e
+
+PROGRAM=$(basename $0)
+BASEDIR=/var/cache/mdt
+REPOSITORY_PATH=$BASEDIR/packages
+LOCKFILE=$BASEDIR/mdt-lock
+
+# Exits the program gracefully with an error message.
+#
+function die
+{
+ echo $PROGRAM: $@
+ exit 1
+}
+
+# Given a package filename, returns the actual Debian base package name,
+# excluding the version number.
+#
+function get-package-name
+{
+ local package_filename="$1"; shift
+
+ dpkg-deb -I $package_filename \
+ | grep -E '^ Package: ' \
+ | awk '{ print $2 }'
+}
+
+# Given a package filename, copies the package into the local MDT package
+# repository for later installation.
+#
+function add-package
+{
+ local package_filename="$1"; shift
+
+ if [[ ! -f $package_filename ]]; then
+ die No such file or directory: $package_filename
+ fi
+
+ local package_name=$(get-package-name $package_filename)
+
+ (
+ flock -n -E 254 200
+ (
+ cp $package_filename $REPOSITORY_PATH
+ cd $REPOSITORY_PATH
+ apt-ftparchive packages . > Packages
+ )
+ ) 200>$LOCKFILE
+
+ local exitcode=$?
+ if [[ $exitcode == 254 ]]; then
+ die Couldn\'t acquire lockfile: $LOCKFILE
+ fi
+
+ return $exitcode
+}
+
+# Given a package filename, removes the package from the local MDT package
+# repository.
+#
+function remove-package
+{
+ local package_filename="$1"; shift
+ local package_basename=$(basename $package_filename)
+ local package_path=$REPOSITORY_PATH/$package_basename
+
+ if [[ ! -f $package_path ]]; then
+ die No such file or directory: $package_path
+ fi
+
+ (
+ flock -n -E 254 200
+ (
+ rm -f $package_path
+ cd $BASEDIR
+ apt-ftparchive packages packages > Packages
+ )
+ ) 200>$LOCKFILE
+
+ local exitcode=$?
+ if [[ $exitcode == 254 ]]; then
+ die Couldn\'t acquire lockfile: $LOCKFILE
+ fi
+
+ return $exitcode
+}
+
+function main
+{
+ local package_to_install="$1"; shift
+
+ if [[ -z $package_to_install ]]; then
+ echo "Usage: mdt-install-package <package>"
+ echo
+ echo "Installs a given Debian package to the system using a local repository"
+ echo "to help install all dependent packages. Forces reinstalls."
+ echo
+ exit 1
+ fi
+
+ if [[ ! -f $package_to_install ]]; then
+ die No such file or directory: $PACKAGE_TO_INSTALL
+ fi
+
+ if [[ ! -d $REPOSITORY_PATH ]]; then
+ die Can\'t find local repository: $REPOSITORY_PATH
+ fi
+
+ if [[ ! -x /usr/bin/apt-ftparchive ]]; then
+ die apt-utils is not installed: can\'t find apt-ftparchive
+ fi
+
+ add-package $package_to_install \
+ || die failed to add package to repository: $package_to_install
+
+ local package_name=$(get-package-name $package_to_install)
+ apt-get -qq update
+ apt-get install --reinstall $package_name
+
+ remove-package $package_to_install \
+ || die failed to remove package from repository: $package
+}
+
+main "$@"