aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2018-09-12 00:19:18 +0200
committerKarel Kočí <cynerd@email.cz>2018-09-12 00:19:18 +0200
commita8bfe6abb693150e9ee01ea6e8d672fc074d1f1c (patch)
treec5e6cc5166c56ad45a396d9af6d4063ad755d9d5 /lib
parent4e4d389127254c7404bc71a308129966bd9a8b07 (diff)
downloadmulticonfig-a8bfe6abb693150e9ee01ea6e8d672fc074d1f1c.tar.gz
multiconfig-a8bfe6abb693150e9ee01ea6e8d672fc074d1f1c.tar.bz2
multiconfig-a8bfe6abb693150e9ee01ea6e8d672fc074d1f1c.zip
New multiconfig design
Diffstat (limited to 'lib')
-rw-r--r--lib/utils119
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
+}