summaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2015-09-02 17:13:27 +0800
committerJeremy Kerr <jk@ozlabs.org>2015-09-02 17:13:27 +0800
commit94fe62686228cf49dc055c50ce8f7ced3bf3cb96 (patch)
tree5aa51d1b08cbd3acadf7d64075c58ba6ae013360 /utils
parente75fa5f6bf36233c3bd72e9854d244908af9a391 (diff)
downloadpetitboot-94fe62686228cf49dc055c50ce8f7ced3bf3cb96.zip
petitboot-94fe62686228cf49dc055c50ce8f7ced3bf3cb96.tar.gz
pb-plugin: Implement plugin ABI versioning
If a future update to plugins is not compatbile with the installed plugin infrastructure, we want to abort the scan / install process. This change adds an ABI version to the script, as well as version (and minimum-supported version) to the plugin metadata. This means we can check before plugin execution. Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'utils')
-rwxr-xr-xutils/pb-plugin85
1 files changed, 84 insertions, 1 deletions
diff --git a/utils/pb-plugin b/utils/pb-plugin
index c6c9ef9..f87e5fb 100755
--- a/utils/pb-plugin
+++ b/utils/pb-plugin
@@ -2,6 +2,7 @@
__dest=/
__pb_mount_dir=/var/petitboot/mnt/dev/
+plugin_abi=1
plugin_ext=pb-plugin
plugin_meta=pb-plugin.conf
plugin_meta_dir=etc/preboot-plugins/
@@ -62,6 +63,23 @@ plugin_info()
echo " (version $PLUGIN_VERSION)"
}
+# How the ABI versioning works:
+#
+# - This script has an ABI defined ($plugin_abi)
+#
+# - Plugins have a current ABI number ($PLUGIN_ABI), and a minimum supported
+# ABI number ($PLUGIN_ABI_MIN).
+#
+# - A plugin is OK to run if:
+# - the plugin's ABI matches the script ABI, or
+# - the plugin's minimum ABI is lower than or equal to the script ABI
+plugin_abi_check()
+{
+ [ -n "$PLUGIN_ABI" ] &&
+ ( [ $PLUGIN_ABI -eq $plugin_abi ] ||
+ [ $PLUGIN_ABI_MIN -le $plugin_abi ] )
+}
+
do_wrap()
{
local base binary dir
@@ -145,6 +163,7 @@ do_install()
echo
sha256sum "$file" | cut -f1 -d' '
echo
+
echo "Do you want to install this plugin? (y/N)"
read resp
@@ -169,6 +188,14 @@ do_install()
. $__dest/$plugin_meta_path
+ if ! plugin_abi_check
+ then
+ echo "Plugin at $url is incompatible with this firmware," \
+ "exiting."
+ rm -rf $__dest
+ exit 1
+ fi
+
for binary in ${PLUGIN_EXECUTABLES}
do
__create_wrapper "$__dest" "$binary"
@@ -203,6 +230,8 @@ do_scan_mount()
(
. $__meta_tmp/$plugin_meta_path
+ plugin_abi_check || exit 1
+
printf "Plugin found on %s:\n" $dev
plugin_info
printf "\n"
@@ -210,8 +239,11 @@ do_scan_mount()
printf " $0 run $plugin_path\n"
printf "\n"
)
+ if [ $? = 0 ]
+ then
+ found=1
+ fi
rm -rf $__meta_tmp
- found=1
done
}
@@ -290,6 +322,8 @@ EOF
mkdir -p $(dirname $file)
cat <<EOF > $file
+PLUGIN_ABI='$plugin_abi'
+PLUGIN_ABI_MIN='1'
PLUGIN_VENDOR='$vendorname'
PLUGIN_VENDOR_ID='$vendorshortname'
PLUGIN_NAME='$pluginname'
@@ -337,6 +371,15 @@ do_create()
# Sanity check metadata file
. $meta_file
+ if [ ! -n "$PLUGIN_ABI" ]
+ then
+ echo "error: no PLUGIN_ABI defined in metadata" &>2
+ exit 1
+ fi
+ if [ "$PLUGIN_ABI" != "$plugin_abi" ]
+ then
+ echo "warning: PLUGIN_ABI (=$PLUGIN_ABI) is not $plugin_abi" &>2
+ fi
if [ ! -n "$PLUGIN_VENDOR" ]
then
echo "error: no PLUGIN_VENDOR defined in metadata" &>2
@@ -436,12 +479,23 @@ test_ftp_download()
cmp -s "$ref" "$tmp"
}
+test_abi_check()
+{
+ (
+ plugin_abi=$1
+ PLUGIN_ABI=$2
+ PLUGIN_ABI_MIN=$3
+ plugin_abi_check
+ )
+}
+
test_scan()
{
__pb_mount_dir="$test_tmpdir/mnt"
mnt_dir="$__pb_mount_dir/sda"
mkdir -p $mnt_dir/$plugin_meta_dir
(
+ echo "PLUGIN_ABI=$plugin_abi"
echo "PLUGIN_NAME=test"
echo "PLUGIN_VERSION=1"
echo "PLUGIN_EXECUTABLES=/bin/sh"
@@ -510,6 +564,7 @@ test_scan_multiple()
do
mkdir -p $mnt_dir/$plugin_meta_dir
(
+ echo "PLUGIN_ABI=$plugin_abi"
echo "PLUGIN_NAME=test-$i"
echo "PLUGIN_VERSION=1"
echo "PLUGIN_EXECUTABLES=/bin/sh"
@@ -526,6 +581,26 @@ test_scan_multiple()
grep -q 'test-1' $outfile && grep -q 'test-2' $outfile
}
+test_scan_wrongabi()
+{
+ __pb_mount_dir="$test_tmpdir/mnt"
+ mnt_dir="$__pb_mount_dir/sda"
+ mkdir -p $mnt_dir/$plugin_meta_dir
+ (
+ echo "PLUGIN_ABI=$(($plugin_abi + 1))"
+ echo "PLUGIN_ABI_MIN=$(($plugin_abi + 1))"
+ echo "PLUGIN_NAME=test"
+ echo "PLUGIN_VERSION=1"
+ echo "PLUGIN_EXECUTABLES=/bin/sh"
+ ) > $mnt_dir/$plugin_meta_path
+ (
+ cd $mnt_dir;
+ find -mindepth 1 | cpio -o -Hnewc 2>/dev/null
+ ) | gzip -c > $mnt_dir/test.$plugin_ext
+
+ do_scan | grep -q 'No plugins'
+}
+
test_empty_scan()
{
__pb_mount_dir="$test_tmpdir/mnt"
@@ -590,10 +665,18 @@ do_tests()
do_test is_url "git+ssh://example.com/path"
do_test test_http_download
do_test test_ftp_download
+ do_test ! test_abi_check
+ do_test ! test_abi_check 1
+ do_test test_abi_check 1 1
+ do_test test_abi_check 1 1 1
+ do_test test_abi_check 1 2 0
+ do_test test_abi_check 1 2 1
+ do_test ! test_abi_check 1 2 2
do_test test_scan
do_test test_scan_nogzip
do_test test_scan_nocpio
do_test test_scan_multiple
+ do_test test_scan_wrongabi
do_test test_empty_scan
if [ $test_failed = 0 ]
OpenPOWER on IntegriCloud