This change uses a chroot for all plugins, so that plugins have complete
flexibility with their libraries, dependencies and configuration.
We remove the 'install' action, as we simply run the plugin once.
Running involves extracting the archive, setting up a root filesystem,
and running a chroot.
To simplify plugin discovery behaviour, we standardise the plugin file
to be at pb-plugin.conf of attached devices, and read the metadatafile
straight out of the archive.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
__dest=/
__pb_mount_dir=/var/petitboot/mnt/dev/
__dest=/
__pb_mount_dir=/var/petitboot/mnt/dev/
-plugin_dev_meta=pb-plugin.conf
-plugin_installed_meta_dir=/etc/preboot-plugins/
+__plugin_basedir=/tmp/
+plugin_file=pb-plugin.cpio.gz
+plugin_meta=pb-plugin.conf
+plugin_meta_dir=etc/preboot-plugins/
+plugin_meta_path=$plugin_meta_dir$plugin_meta
Usage: $0 <command>
Where <command> is one of:
Usage: $0 <command>
Where <command> is one of:
- install <FILE|URL> - install plugin from FILE/URL
+ run <FILE|URL> - run plugin from FILE/URL
scan - look for available plugins on attached devices
scan - look for available plugins on attached devices
- list - list currently-installed plugins
create <DIR> - create a new plugin archive from DIR
EOF
}
create <DIR> - create a new plugin archive from DIR
EOF
}
echo " (version $PLUGIN_VERSION)"
}
echo " (version $PLUGIN_VERSION)"
}
+ local base dir
+
+ base=$1
+
+ for dir in etc dev sys proc
+ do
+ mkdir -p $base/$dir
+ done
+
+ cp /etc/resolv.conf $base/etc
+ mount -o bind /dev $base/dev
+ mount -o bind /sys $base/sys
+ mount -o bind /proc $base/proc
+}
+
+__run_cleanup()
+{
+ local base
+
+ base=$1
+
+ [ -e $base/dev/null ] && umount $base/dev
+ [ -e $base/sys/kernel ] && umount $base/sys
+ [ -e $base/proc/stat ] && umount $base/proc
+ rm -rf $base
+}
+
+do_run()
+{
+ local url executable
- if [ ! -d "$__dest" ]
- then
- echo "error: destination directory '$__dest' doesn't exist" >&2
- exit 1
- fi
-
- if [ ! -w "$__dest" ]
- then
- echo "error: destination directory isn't writeable" >&2
- exit 1
- fi
-
name=${url##*/}
if is_url "$url"
name=${url##*/}
if is_url "$url"
echo
sha256sum "$file" | cut -f1 -d' '
echo
echo
sha256sum "$file" | cut -f1 -d' '
echo
- echo "Do you want to install into the pre-boot environment? (y/N)"
+ echo "Do you want to run this plugin? (y/N)"
gunzip -c "$file" | ( cd $__dest && cpio -i -d)
if [ $? -ne 0 ]
then
echo "error: Failed to extract archive $url, exiting"
gunzip -c "$file" | ( cd $__dest && cpio -i -d)
if [ $? -ne 0 ]
then
echo "error: Failed to extract archive $url, exiting"
+
+ . $__dest/$plugin_meta_path
+
+ (
+ executable=${PLUGIN_EXECUTABLE:-$executable}
+
+ __run_init $__dest
+
+ printf "Entering plugin\n"
+ plugin_info
+
+ chroot $__dest $executable
+
+ printf "\nExiting plugin & cleaning up\n"
+ __run_cleanup $__dest
+ )
+
+ local found dev plugin_path __meta_tmp
found=0
for mnt in $__pb_mount_dir/*
do
dev=$(basename $mnt)
found=0
for mnt in $__pb_mount_dir/*
do
dev=$(basename $mnt)
- metafile="$mnt/$plugin_dev_meta"
- [ -e "$metafile" ] || continue
+ plugin_path="$mnt/$plugin_file"
+
+ [ -e "$plugin_path" ] || continue
+
+ # extract plugin metadata to a temporary directory
+ __meta_tmp=$(mktemp -d)
+ [ -d $__meta_tmp ] || continue
+ gunzip -c "$plugin_path" |
+ (cd $__meta_tmp &&
+ cpio -i -d $plugin_meta_path 2>/dev/null)
+ if ! [ $? = 0 -a -e "$plugin_path" ]
+ then
+ rm -rf $__meta_tmp
+ continue
+ fi
+
+ . $__meta_tmp/$plugin_meta_path
+
printf "Plugin found on %s:\n" $dev
plugin_info
printf "\n"
printf "Plugin found on %s:\n" $dev
plugin_info
printf "\n"
- printf "To install this plugin, run:\n"
- printf " $0 install $mnt/$PLUGIN_FILE\n"
+ printf "To run this plugin:\n"
+ printf " $0 run $plugin_path\n"
-do_list()
-{
- local found
- found=0
- for meta in $plugin_installed_meta_dir/*
- do
- [ -e "$meta" ] || continue
- [ $found = 0 ] && printf "Installed plugins:\n"
- found=1
- (
- . $meta
- plugin_info
- echo
- )
- done
-
- if [ "$found" = 0 ]
- then
- echo "No plugins installed"
- fi
-}
-
guided_meta()
{
local vendorname vendorshortname
local pluginname pluginnhortname
guided_meta()
{
local vendorname vendorshortname
local pluginname pluginnhortname
- local version date
- local dir
+ local version date executable
+ local file
+cat <<EOF
+
+Enter the full path (within the plugin root) to the plugin executable file.
+This will be the default action when the plugin is run. (eg /usr/bin/my-util)
+EOF
+ read executable
+
+ mkdir -p $(dirname $file)
- cat <<EOF > $dir/$vendorshortname-$pluginshortname
PLUGIN_VENDOR='$vendorname'
PLUGIN_NAME='$pluginname'
PLUGIN_VERSION='$version'
PLUGIN_DATE='$date'
PLUGIN_VENDOR='$vendorname'
PLUGIN_NAME='$pluginname'
PLUGIN_VERSION='$version'
PLUGIN_DATE='$date'
+PLUGIN_EXECUTABLE='$executable'
- local src found meta_dir_abs meta_file
+ local src meta_dir_abs meta_file
- meta_dir_abs="$src/$plugin_installed_meta_dir"
- found=0
- for meta in $meta_dir_abs/*
- do
- [ -e "$meta" ] || continue
- found=$(($found+1))
- meta_file=$meta
- done
+ meta_file=$src/$plugin_meta_path
then
echo "No plugin metadata file found. " \
"Would you like to create one? (Y/n)"
then
echo "No plugin metadata file found. " \
"Would you like to create one? (Y/n)"
- guided_meta $meta_dir_abs || exit
- meta_file=$meta_dir_abs/*
- fi
-
- if [ $found -gt 1 ]
- then
- echo "error: Multiple metadata files found in $meta_dir_abs" >&2
- exit 1
+ guided_meta $meta_file || exit
fi
# Sanity check metadata file
fi
# Sanity check metadata file
echo "error: no PLUGIN_DATE defined in metadata" &>2
exit 1
fi
echo "error: no PLUGIN_DATE defined in metadata" &>2
exit 1
fi
+ if [ ! -n "$PLUGIN_EXECUTABLE" ]
+ then
+ echo "error: no PLUGIN_EXECUTABLE defined in metadata" \
+ &>2
+ exit 1
+ fi
- outfile=pb-plugin.cpio.gz
(
cd $src
find -mindepth 1 | cpio -o -Hnewc -v
(
cd $src
find -mindepth 1 | cpio -o -Hnewc -v
- ) | gzip -c > pb-plugin.cpio.gz
-
- cp $meta_file $plugin_dev_meta
- echo "PLUGIN_FILE='$outfile'" >> $plugin_dev_meta
echo
echo "Plugin metadata:"
echo
echo "Plugin metadata:"
cat <<EOF
Plugin created in:
$outfile
cat <<EOF
Plugin created in:
$outfile
-
-Metadata in:
- $plugin_dev_meta
-If you rename $outfile (or distribute it in a non-root directory), then
-also update the PLUGIN_FILE variable in $plugin_dev_meta.
+Ship this file in the top-level-directory of a USB device or CD to have it
+automatically discoverable by 'pb-plugin scan'.
{
__pb_mount_dir="$test_tmpdir/mnt"
mnt_dir="$__pb_mount_dir/sda"
{
__pb_mount_dir="$test_tmpdir/mnt"
mnt_dir="$__pb_mount_dir/sda"
+ mkdir -p $mnt_dir/$plugin_meta_dir
(
echo "PLUGIN_NAME=test"
echo "PLUGIN_VERSION=1"
(
echo "PLUGIN_NAME=test"
echo "PLUGIN_VERSION=1"
- echo "PLUGIN_FILE=data/pb-plugin.cpio.gz"
- ) > $mnt_dir/$plugin_dev_meta
+ echo "PLUGIN_EXECUTABLE=/bin/sh"
+ ) > $mnt_dir/$plugin_meta_path
+ (
+ cd $mnt_dir;
+ find -mindepth 1 | cpio -o -Hnewc 2>/dev/null
+ ) | gzip -c > $mnt_dir/$plugin_file
do_scan | grep -q 'test 1'
rc=$?
do_scan | grep -q 'test 1'
rc=$?
+ __pb_mount_dir="$test_tmpdir/mnt"
+ mkdir -p $__pb_mount_dir
do_scan | grep -q "No plugins"
}
do_scan | grep -q "No plugins"
}
test_tmpdir="$tests_tmpdir/$n"
mkdir "$test_tmpdir"
test_tmpdir="$tests_tmpdir/$n"
mkdir "$test_tmpdir"
- __test_dest="$test_tmpdir/base"
- mkdir "$__test_dest"
- [ -d "$__test_dest" ] || exit 1
- __dest=$__test_dest
;;
scan)
shift
do_scan $@
;;
;;
scan)
shift
do_scan $@
;;
-list)
- shift
- do_list $@
- ;;
create)
shift
do_create $@
create)
shift
do_create $@