Skip to content

Commit

Permalink
Merge pull request #3 from thin-edge/feat-archive-sm-plugin
Browse files Browse the repository at this point in the history
add generic archive sm-plugin
  • Loading branch information
reubenmiller authored Jul 24, 2024
2 parents 11db5cc + 8914b76 commit ac92173
Showing 1 changed file with 188 additions and 0 deletions.
188 changes: 188 additions & 0 deletions src/tedge/sm-plugins/archive
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
#!/bin/sh
# Note: this script is maintained under https://github.com/thin-edge/tedge-archive-plugin/blob/main/src/sm-plugin/tedge-archive-plugin
set -e

EXIT_OK=0
EXIT_USAGE=1
EXIT_FAILURE=2
# EXIT_RETRY=3

usage() {
cat << EOF
USAGE
Generic archive plugin for thin-edge.io
$0 <COMMAND> [MODULE_NAME] [--module-version [VERSION]] [--file [FILE]]
$0 list
$0 prepare
$0 install <MODULE_NAME> [--module-version [VERSION]] [--file [FILE]]
$0 remove <MODULE_NAME> [--module-version [VERSION]]
$0 finalize
EOF
}

MODULE_NAME=
MODULE_VERSION=
FILE=

# Path to the root directory
ROOT_DIR=/data
ARCHIVE_SOFTWARE_DIR="$ROOT_DIR/.tedge-archive-plugin"
MAINTSCRIPT_DIR=SCRIPTS

log() { echo "$@" >&2; }

if [ $# -lt 1 ]; then
log "Invalid number of positional arguments"
usage
exit "$EXIT_USAGE"
fi

# argument parsing
while [ $# -gt 0 ]; do
case "$1" in
--module-version)
MODULE_VERSION="$2"
shift
;;
--file)
FILE="$2"
shift
;;
-h|--help)
usage
exit "$EXIT_USAGE"
;;
--*|-*)
log "Unknown option $1"
exit "$EXIT_USAGE"
;;
*)
if [ -z "$COMMAND" ]; then
COMMAND="$1"
elif [ -z "$MODULE_NAME" ]; then
MODULE_NAME="$1"
fi
;;
esac
shift
done

# Only read the file if it has the correct permissions, to prevent people from editing it
# and side-loading functions
SETTINGS_FILE=/etc/tedge-archive-plugin/env
FOUND_FILE=
if [ -f "$SETTINGS_FILE" ]; then
FOUND_FILE=$(find "$SETTINGS_FILE" -perm 644 | head -1)
fi

if [ -n "$FOUND_FILE" ]; then
log "Loading setting file: $SETTINGS_FILE"
# shellcheck disable=SC1091,SC1090
. "$SETTINGS_FILE"
fi

get_module_dir() {
echo "$ARCHIVE_SOFTWARE_DIR/${MODULE_NAME}@${MODULE_VERSION}"
}

case "$COMMAND" in
prepare)
;;
list)
find "$ARCHIVE_SOFTWARE_DIR" -type f -name "package" | while read -r ITEM; do
head -n1 "$ITEM"
done
;;
install)
if [ ! -f "$FILE" ]; then
log "File not found. path=$FILE"
exit "$EXIT_FAILURE"
fi

MODULE_DIR="$(get_module_dir)"
mkdir -p "$MODULE_DIR"

log "Installing from file: $FILE"
if tar -tzf "$FILE" >/dev/null 2>&1; then
#
# tarball/gzip
#
log "Unpacking tarball file"
mkdir -p "$ROOT_DIR"

log "Unpacking maintainer scripts"
# Run preinstall script (if found)
if tar -tf "$FILE" | grep -q "$MAINTSCRIPT_DIR/preinst"; then
tar -xvzf "$FILE" -C "$MODULE_DIR" "./$MAINTSCRIPT_DIR/preinst"
find "$MODULE_DIR" -type f -name "preinst" -perm 755 -exec {} \;
fi

log "Unpacking files"
tar --exclude="./$MAINTSCRIPT_DIR/**" -xvzf "$FILE" -C "$ROOT_DIR"

# Store list of files which are included in the package so they can be uninstalled later on
# by the user

# Note: When writing the list, the ROOT_DIR needs to be prefixed to the relative path
# so that the file path is fixed at install time to avoid problems incase if someone changes the ROOT_DIR
# and then tries to remove the package!
tar -tf "$FILE" | grep -v "$MAINTSCRIPT_DIR/" | grep -v '/$' | sed 's|^.|'"$ROOT_DIR"'|g' > "$MODULE_DIR/files"

# TODO: bsdtar list tar file contents output looks more like ls -l which includes meta information about each file
# so it requires additional parsing with awk
# tar -tf "$FILE" | grep -v "$MAINTSCRIPT_DIR/" | awk -F' ' '$6 !~ /\/$/ { print $6 }' > "$MODULE_DIR/files"

# Run postinst script (if found)
if tar -tf "$FILE" | grep -q "$MAINTSCRIPT_DIR/postinst"; then
tar -xvzf "$FILE" -C "$MODULE_DIR" "./$MAINTSCRIPT_DIR/postinst"

find "$MODULE_DIR" -type f -name "postinst" -perm 755 -exec {} \;
fi

elif unzip -t "$FILE" >/dev/null 2>&1; then
#
# zip
#
log "Unpacking zip file"
log "TODO: zip files are not yet supported"
exit $EXIT_FAILURE
unzip "$FILE" -d "$ROOT_DIR" -x "$POST_FILE"
else
log "Unknown file format. Only gzips and zip files are supported"
exit "$EXIT_FAILURE"
fi

# Store marker of the tarball
sha256sum "$FILE" | cut -d' ' -f1 > "$MODULE_DIR/sha256"
printf '%s\t%s' "$MODULE_NAME" "$MODULE_VERSION" > "$MODULE_DIR/package"
;;
remove)
# Remove module
MODULE_DIR="$(get_module_dir)"
if [ -f "$MODULE_DIR/files" ]; then
# cd "$ROOT_DIR"
while read -r package_file; do
if [ -f "$package_file" ]; then
log "Removing package file: $package_file"
rm -f "$package_file"
fi
done < "$MODULE_DIR/files"
fi

rm -rf "$MODULE_DIR"
;;
update-list)
# Not supported, use remove install and remove instead
exit "$EXIT_USAGE"
;;
finalize)
;;
*)
log "Unsupported command: $COMMAND"
exit 1
;;
esac

exit "$EXIT_OK"

0 comments on commit ac92173

Please sign in to comment.