diff options
Diffstat (limited to 'lib/utils')
-rw-r--r-- | lib/utils | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/lib/utils b/lib/utils new file mode 100644 index 0000000..5281d19 --- /dev/null +++ b/lib/utils @@ -0,0 +1,119 @@ +# vim: ft=sh + +die() { + echo "$@" >&2 + kill $$ +} + +# Returns name of this module +module_id() { + $(basename "$0") +} + +# Status file for this module +MC_STATUS_FILE="$MC_STATUS_DIR/$(module_id)" + +# Return hash of given file from status file +# First argument have to be a path to output file +installed_hash() { + awk -F '\t' -v regex="^$1$" '/$2 ~ regex { print $1 }' "$MC_STATUS_FILE" +} + +# Hash of currently installed file +# Access remote resource +# It connects to remote server and requests resource for given plugin. +# It expects only one argument and that is resource identifier. +remote_source() { + local res="$1" + local mod_id="$(module_id)" + if [ -n "$MC_LOCAL_DIR" ]; then + "$MC_LOCAL_DIR/request.sh" "$mod_id:$res" + else + ssh -i ~/.ssh/multiconfig multiconfig@cynerd.cz -- "$mod_id:$res" + fi +} + +# Defined and create QUEUE file for this instance +MC_QUEUE_FILE="$(mktemp multiconfig-$(module_id).queue.XXXXXX)" +touch "$MC_QUEUE_FILE" + +# Variable signaling if file was updated or not +change=false + +# Install given file +# First argument has to be a identifier string for remote script +# Second argument has to be an output file (absolute path). +inst() { + local src="$1" + local out="$2" + [ -f "$MC_QUEUE_FILE" ] || die "inst can be called only before apply call!" + grep -q "\t$out$" || die "inst can be called on one output only once!" + # TODO verify that this output is not already in queue + local tmp="$(mktemp multiconfig.XXXXXXXXXX)" + remote_source "$src" > "$tmp" + local refhash="$(installed_hash "$out")" + if [ -n "$refhash" ]; then + change=false + if [ -f "$out" ]; then + local cursha="$(sha256 "$out")" + if [ "$cursha" != "$(sha256 "$tmp")" ]; then + echo "Updating file ($src): $out" + [ "$cursha" = "$refhash" ] || echo "File was edited manually! $out" + echo "$tmp $out" >> "$MC_QUEUE_FILE" + change=true + fi + else + echo "Output is not a file! $out" + echo "$tmp $out" >> "$MC_QUEUE_FILE" + change=true + fi + else + echo "New file ($src): $out" + echo "$tmp $out" >> "$MC_QUEUE_FILE" + change=true + fi +} + +# Apply all queued changes and cleanup +apply() { + local new="$MC_STATUS_FILE.new" + echo -n > "$new" + while IFS=\t read src out; do + if [ -e "$out" ]; then + local trash="$MC_TRASH_DIR/$out.$(date +%y%m%d%H%M%S)" + if [ -f "$out" ]; then + if [ "$(installed_hash "$out")" != "$(sha256 "$out")" ]; then + echo "File was manually changed: $out -> $trash" + cp "$out" "$trash" + fi + else + echo "Path exists but is not a file: $out -> $trash" + mv "$out" "$trash" + fi + fi + echo "Updating: $out" + mv "$src" "$out" + sha256 "$out" >> "$new" + done < "$MC_QUEUE_FILE" + rm "$MC_QUEUE_FILE" + mv "$new" "$MC_STATUS_FILE" + change= +} + +# TODO somehow add support for installing directories. Most probably by having +# remote script returning list of files in directory and then calling inst on +# them. + +# Returns string informing you of distribution type but only if given distribution +# is supported. If ditribution is not supported then it returns "unknown". +distribution() { + if [ -f /etc/gentoo-release ]; then + echo "gentoo" + elif [ -f /etc/alpine-release ]; then + echo "alpine" + elif [ -f /etc/openwrt_version ]; then + echo "openwrt" + else + echo "unknown" + fi +} |