X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=utils%2Fpb-plugin;h=45bf19dea924eebd4c8194892227e44524113cdc;hp=f87e5fb0e6f15f2ec9c151704c15529722a3c4d8;hb=aa596b2c10344e0664e0c98cd6db43af3e20fdb9;hpb=94fe62686228cf49dc055c50ce8f7ced3bf3cb96 diff --git a/utils/pb-plugin b/utils/pb-plugin index f87e5fb..45bf19d 100755 --- a/utils/pb-plugin +++ b/utils/pb-plugin @@ -16,8 +16,9 @@ Usage: $0 Where is one of: install - install plugin from FILE/URL - scan - look for available plugins on attached devices + scan - look for available plugins on attached devices create - create a new plugin archive from DIR + lint - perform a pre-distribution check on FILE EOF } @@ -63,6 +64,27 @@ plugin_info() echo " (version $PLUGIN_VERSION)" } +parse_meta() +{ + local file name value IFS + + file=$1 + + IFS='=' + while read -r name value + do + # Ensure we have a sensible variable name + echo "$name" | grep -q '^PLUGIN_[A-Z_]*$' || continue + + # we know that $name has no quoting/expansion chars, but we + # may need to do some basic surrounding-quote removal for + # $value, without evaluating it + value=$(echo "$value" | sed "s/^\([\"']\)\(.*\)\1\$/\2/g") + + export $name="$value" + done < $file +} + # How the ABI versioning works: # # - This script has an ABI defined ($plugin_abi) @@ -128,7 +150,12 @@ EOF do_install() { - local url name file __dest + local url name file __dest auto + + if [ "$1" == "auto" ]; then + auto=y + shift; + fi url=$1 @@ -164,17 +191,20 @@ do_install() sha256sum "$file" | cut -f1 -d' ' echo - echo "Do you want to install this plugin? (y/N)" - read resp + if [ -z "$auto" ] + then + echo "Do you want to install this plugin? (y/N)" + read resp - case $resp in - [yY]|[yY][eE][sS]) - ;; - *) - echo "Cancelled" - exit 0 - ;; - esac + case $resp in + [yY]|[yY][eE][sS]) + ;; + *) + echo "Cancelled" + exit 0 + ;; + esac + fi __dest=$(mktemp -d) gunzip -c "$file" | ( cd $__dest && cpio -i -d) @@ -186,7 +216,7 @@ do_install() exit 1 fi - . $__dest/$plugin_meta_path + parse_meta $__dest/$plugin_meta_path if ! plugin_abi_check then @@ -201,6 +231,12 @@ do_install() __create_wrapper "$__dest" "$binary" done + pb-event plugin@local \ + name="$PLUGIN_NAME" id=$PLUGIN_ID version=$PLUGIN_VERSION \ + vendor="$PLUGIN_VENDOR" vendor_id=$PLUGIN_VENDOR_ID \ + date=$PLUGIN_DATE executables="$PLUGIN_EXECUTABLES" \ + source_file=$url installed="yes" + echo "Plugin installed" plugin_info } @@ -228,7 +264,7 @@ do_scan_mount() fi ( - . $__meta_tmp/$plugin_meta_path + parse_meta $__meta_tmp/$plugin_meta_path plugin_abi_check || exit 1 @@ -236,8 +272,11 @@ do_scan_mount() plugin_info printf "\n" printf "To run this plugin:\n" - printf " $0 run $plugin_path\n" + printf " $0 install $plugin_path\n" printf "\n" + + pb-event plugin@$dev name=$PLUGIN_NAME \ + path=$plugin_path installed="no" ) if [ $? = 0 ] then @@ -249,9 +288,18 @@ do_scan_mount() do_scan() { - local found mnt + local found mnt dev locations found=0 - for mnt in $__pb_mount_dir/* + dev=$1 + + if [ -z $dev ]; then + locations=$__pb_mount_dir/* + else + echo "Scanning device $dev" + locations=$dev + fi + + for mnt in $locations do do_scan_mount $mnt done @@ -370,49 +418,15 @@ do_create() fi # 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 - exit 1 - fi - if [ ! -n "$PLUGIN_VENDOR_ID" ] - then - echo "error: no PLUGIN_VENDOR_ID defined in metadata" &>2 - exit 1 - fi - if [ ! -n "$PLUGIN_NAME" ] - then - echo "error: no PLUGIN_NAME defined in metadata" &>2 - exit 1 - fi - if [ ! -n "$PLUGIN_ID" ] - then - echo "error: no PLUGIN_ID defined in metadata" &>2 - exit 1 - fi - if [ ! -n "$PLUGIN_VERSION" ] - then - echo "error: no PLUGIN_VERSION defined in metadata" &>2 - exit 1 - fi - if [ ! -n "$PLUGIN_DATE" ] - then - echo "error: no PLUGIN_DATE defined in metadata" &>2 - exit 1 - fi - if [ ! -n "$PLUGIN_EXECUTABLES" ] + parse_meta $meta_file + + errors=0 + warnings=0 + + lint_metadata + + if [ $errors -ne 0 ] then - echo "error: no PLUGIN_EXECUTABLES defined in metadata" &>2 exit 1 fi @@ -443,6 +457,131 @@ but must retain the .$plugin_ext extension to be discoverable. EOF } +lint_fatal() +{ + echo "fatal:" "$@" + [ -d "$__dest" ] && rm -rf "$__dest" + exit 1 +} + +lint_err() +{ + echo "error:" "$@" + errors=$(($errors+1)) +} + +lint_warn() +{ + echo "warning:" "$@" + warnings=$(($warnings+1)) +} + +lint_metadata() +{ + [ -n "$PLUGIN_ABI" ] || + lint_err "no PLUGIN_ABI defined in metadata" + + printf '%s' "$PLUGIN_ABI" | grep -q '[^0-9]' && + lint_err "PLUGIN_ABI has non-numeric characters" + + [ -n "$PLUGIN_ABI_MIN" ] || + lint_err "no PLUGIN_ABI_MIN defined in metadata" + + printf '%s' "$PLUGIN_ABI_MIN" | grep -q '[^0-9]' && + lint_err "PLUGIN_ABI_MIN has non-numeric characters" + + [ "$PLUGIN_ABI" = "$plugin_abi" ] || + lint_warn "PLUGIN_ABI (=$PLUGIN_ABI) is not $plugin_abi" + + [ -n "$PLUGIN_VENDOR" ] || + lint_err "no PLUGIN_VENDOR defined in metadata" + + [ -n "$PLUGIN_VENDOR_ID" ] || + lint_err "no PLUGIN_VENDOR_ID defined in metadata" + + printf '%s' "$PLUGIN_VENDOR_ID" | grep -q '[^a-z0-9-]' && + lint_err "PLUGIN_VENDOR_ID should only contain lowercase" \ + "alphanumerics and hyphens" + + [ -n "$PLUGIN_NAME" ] || + lint_err "no PLUGIN_NAME defined in metadata" + + [ -n "$PLUGIN_ID" ] || + lint_err "no PLUGIN_ID defined in metadata" + + printf '%s' "$PLUGIN_ID" | grep -q '[^a-z0-9-]' && + lint_err "PLUGIN_ID should only contain lowercase" \ + "alphanumerics and hyphens" + + [ "$PLUGIN_VERSION" ] || + lint_err "no PLUGIN_VERSION defined in metadata" + + [ -n "$PLUGIN_DATE" ] || + lint_err "no PLUGIN_DATE defined in metadata" + + [ -n "$PLUGIN_EXECUTABLES" ] || + lint_err "no PLUGIN_EXECUTABLES defined in metadata" +} + +do_lint() +{ + local plugin_file errors warnings __dest executable dir + + plugin_file=$1 + errors=0 + warnings=0 + __dest= + + [ "${plugin_file##*.}" = $plugin_ext ] || + lint_err "Plugin file does not end with $plugin_ext" + + gunzip -c "$plugin_file" > /dev/null 2>&1 || + lint_fatal "Plugin can't be gunzipped" + + gunzip -c "$plugin_file" 2>/dev/null | cpio -t >/dev/null 2>&1 || + lint_fatal "Plugin can't be cpioed" + + __dest=$(mktemp -d) + gunzip -c "$plugin_file" | ( cd $__dest && cpio -i -d 2>/dev/null) + + [ -e "$__dest/$plugin_meta_path" ] || + lint_fatal "No metadata file present (expecting" \ + "$plugin_meta_path)" + + parse_meta "$__dest/$plugin_meta_path" + lint_metadata + + for executable in ${PLUGIN_EXECUTABLES} + do + exec_path="$__dest/$executable" + [ -e "$exec_path" ] || { + lint_err "PLUGIN_EXECUTABLES item $executable" \ + "doesn't exist" + continue + } + + [ -x "$exec_path" ] || + lint_err "PLUGIN_EXECUTABLES item $executable" \ + "isn't executable" + done + + for dir in dev sys proc var + do + [ -e "$__dest/$dir" ] || continue + + [ -d "$__dest/$dir" ] || + lint_err "/$dir exists, but isn't a directory" + + [ "$(find $__dest/$dir -mindepth 1)" ] && + lint_warn "/$dir contains files/directories," \ + "these will be lost during chroot setup" + done + + printf '%s: %d errors, %d warnings\n' $plugin_file $errors $warnings + rm -rf $__dest + [ $errors = 0 ] +} + test_http_download() { local tmp ref @@ -703,6 +842,10 @@ create) shift do_create $@ ;; +lint) + shift + do_lint $@ + ;; __wrap) shift do_wrap $@ @@ -717,7 +860,7 @@ __test) exit 1 ;; *) - echo "Invalid command: $s" >&2 + echo "Invalid command: $1" >&2 usage exit 1 esac