blob: 5281d196c11865facb475f11fbb20231b4364c28 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
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
}
|