-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcloud-davfs-encfs.sh
executable file
·408 lines (351 loc) · 10.1 KB
/
cloud-davfs-encfs.sh
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
#!/bin/bash
#
# Mount webdav (davfs2) encrypted with encfs
#
# check prerequisites are available
command -v encfs >/dev/null || (echo "Error: can not find required 'encfs'" && exit 5)
[ -e /usr/sbin/mount.davfs ] ||
[ -e /sbin/mount.davfs ] ||
whereis mount |grep -q davfs ||
(echo "Error: can not find required 'davfs2'" && exit 5)
# Basic top-level configuration items here.
# These should be set once and not be changed,
# unless of course everything gets re-installed.
#
CLOUD_ROOT=~/cloud
readonly FMT_FSTAB="%s %s davfs user,rw,noauto,_netdev 0 0"
readonly ETCFSTAB=/etc/fstab
readonly WEBDAV_MPOINT_NAME=webdav
readonly CLOUD_ENCFS_NAME=encoded
readonly CLOUD_ENCFS_MP_NAME=cloudfiles
readonly CONF_FILE_NAME=cloud-davfs-encfs.conf
WEBDAV_REMOTE_PATH=""
#
# Script starts here.
# Do not modify, unless you know what you are doing.
#
CLOUD_ROOT=$(realpath $CLOUD_ROOT)
mapfile -t CLOUDALL < <(ls -d "$CLOUD_ROOT"/*/ 2>/dev/null)
readonly -a CLOUDALL
#
# Note: PID files:
# /var/run/mount.davfs/mnt-nextcloud-kmu.pid
#
# TODO: make this more elegant.
ACTION="$1"
CLOUDNAME="$2"
shift 2
# Utility functions
function y-or-n () {
while true
do
read -r -p "$1" yn
case $yn in
[Yy]* ) return 0 ;;
[Nn]* ) return 1 ;;
* ) echo "Please answer yes or no?"
esac
done
}
# define directories
function cloud-dirs () {
readonly DIR_CLOUDNAME=$CLOUD_ROOT/$CLOUDNAME
readonly WEBDAV_MPOINT=$DIR_CLOUDNAME/$WEBDAV_MPOINT_NAME
readonly DIR_CLOUD_ENC=$WEBDAV_MPOINT/$CLOUD_ENCFS_NAME
readonly DIR_CLOUD_ENC_MP=$DIR_CLOUDNAME/$CLOUD_ENCFS_MP_NAME
readonly DIR_PRIVATE=$DIR_CLOUD_ENC_MP
}
function cloud-definitions () {
cloud-dirs
readonly CONF_FILE_PATH="$DIR_CLOUDNAME/$CONF_FILE_NAME"
# using FMT_FSTAB, but variables not allowed in printf
printf -v FSTAB_TXT "%s %s davfs user,rw,noauto,_netdev 0 0" \
"$WEBDAV_REMOTE_PATH" "$WEBDAV_MPOINT"
}
# check cloudname is valid
function check_new_cloudname () {
local name="$1"
case "$name" in
*[[:space:]/]*) echo "Error: invalid CLOUDNAME '$name'"
exit 31 ;;
"") echo "Error: empty CLOUDNAME"
exit 32 ;;
*)
esac
if ! in_cloudall "$name" ; then
printf 'Error: CLOUDNAME '\''%s'\'' already exists\n' "$name"
exit 33
fi
}
function cloud-list () {
local d
for d in "${CLOUDALL[@]}"
do
basename "$d"
done
}
# in_cloudall: check if value exists in array CLOUDALL.
# returns 0 if value found in CLOUDALL, 1 if not.
# -v : verbose, display a yes/no message
function in_cloudall () {
local name="$1"
local d v=
if [[ "$name" == "-v" ]] ; then
v=1
shift
name="$1"
fi
for d in "${CLOUDALL[@]}"
do
if [[ "$name" == $(basename "$d") ]] ; then
[[ $v ]] && echo "yes"
return 0
fi
done
[[ $v ]] && echo "no"
return 1
}
function read-conf-file () {
local fconf="$1"
local cloudn
[ -z "$fconf" ] &&
fconf="$CLOUD_ROOT/$CLOUDNAME/$CONF_FILE_NAME" &&
cloudn="$CLOUDNAME"
WEBDAV_REMOTE_PATH=
CLOUDNAME=
if [ -r "$fconf" ] ; then
. "$fconf"
else
echo "Error: can not read file '$fconf'"
exit 3
fi
#
# check the configuration is valid
#
# identifier mismatch
if [[ -n "$cloudn" && "$CLOUDNAME" != "$cloudn" ]] ; then
echo "Error: identifier mismatch"
printf ' '\''%s'\'' given as argument\n' "$cloudn"
printf ' '\''%s'\'' read in config file\n' "$CLOUDNAME"
exit 20
fi
# paths not set
if [[ -z "$WEBDAV_REMOTE_PATH" || -z "$CLOUDNAME" ]] ; then
echo "Error: something wrong with definitions"
printf ' File: %s\n, WEBDAV_REMOTE_PATH: %s\nCLOUDNAME: %s\n' \
"$fconf" "$WEBDAV_REMOTE_PATH" "$CLOUDNAME"
exit 21
fi
return 0
}
# add line to /etc/fstab
function davfs-fstab-add () {
if mountpoint -q "$WEBDAV_MPOINT" ; then
printf 'Error: '\''%s'\'' is already used and mounted\n' "$WEBDAV_MPOINT"
exit 26
fi
if grep -q "$WEBDAV_MPOINT" $ETCFSTAB ; then
printf '*Warning*: '\''%s'\'' is already listed in %s.\n' "$WEBDAV_MPOINT" $ETCFSTAB
echo " Check the entry for errors and remove if needed."
echo " If removed, rerun the create action."
elif echo "$FSTAB_TXT" | sudo tee -a $ETCFSTAB > /dev/null ; then
echo "Created davfs entry to $ETCFSTAB"
else
echo "Error: failed to append davfs entry to $ETCFSTAB"
exit 27
fi
}
# create setup
function cloud-create () {
local createfile="$1"
read-conf-file "$createfile"
# check the name is new
if in_cloudall "$CLOUDNAME" ; then
echo "Error: cloud-davfs instance '$CLOUDNAME' already exists."
exit 22
fi
# setup the directory structure
cloud-definitions
for i in "$DIR_CLOUDNAME" "$WEBDAV_MPOINT" "$DIR_CLOUD_ENC" "$DIR_CLOUD_ENC_MP"
do
test -d "$i" || mkdir -p "$i" ||
{ echo "Error: failed creating directory '$i'" &&
exit 23 ; }
done
echo "Created directory structure for $CLOUDNAME"
if [ -f "$CONF_FILE_PATH" ] ; then
echo "Error: Configuration file $CONF_FILE_PATH aleady exists."
echo " Create failed."
exit 24
fi
cp -av "$createfile" "$CONF_FILE_PATH" ||
printf 'WEBDAV_REMOTE_PATH=%s\nCLOUDNAME=%s\n' \
"$WEBDAV_REMOTE_PATH" "$CLOUDNAME" > "$CONF_FILE_PATH" ||
{ echo "Error: could not create config file '$CONF_FILE_PATH'" &&
exit 25 ; }
echo "Created configuration file '$CONF_FILE_PATH'"
davfs-fstab-add
echo "Created cloud setup for $CLOUDNAME"
}
#
#functions to mount and unmount various mountpoints
#
function cloud-mount-webdav () {
if [ ! -d "$WEBDAV_MPOINT" ] ; then
printf 'Error: webdav mount point '%s' not found\n' "$WEBDAV_MPOINT"
exit 9
fi
if mountpoint -q "$WEBDAV_MPOINT" ; then
return 0 # already mounted
else
# check fstab entry, add if missing
grep -q "$WEBDAV_MPOINT" $ETCFSTAB ||
{ echo "$FSTAB_TXT" | sudo tee -a $ETCFSTAB > /dev/null ; } ||
{ echo "Error: failed to append $ETCFSTAB entry" ; exit 27 ; }
printf 'Added '%s' line to %s (%d)\n' $CLOUDNAME $ETCFSTAB $?
fi
# do the mount
mount "$WEBDAV_MPOINT" ||
{ echo "Error: failed to mount webdav for $CLOUDNAME" ; exit 31 ; }
printf 'webdav-%s mounted\n' $CLOUDNAME
}
function cloud-umount-webdav () {
mountpoint -q "$WEBDAV_MPOINT" &&
umount "$WEBDAV_MPOINT" &&
printf 'webdav-%s unmounted\n' $CLOUDNAME ||
{ printf 'Error: failed to un-mount webdav-%s\n %s\n' \
"$CLOUDNAME" "$WEBDAV_MPOINT"
exit 35 ; }
}
function cloud-mount-encfs () {
local d
# check the directories for encfs exist
for d in "$DIR_CLOUD_ENC" "$DIR_CLOUD_ENC_MP"
do
if [ ! -d "$d" ] ; then
printf 'Error: encfs directory '\''%s'\'' not found\n' "$d"
exit 9
fi
done
# is it mounted ?
if ! mountpoint -q "$DIR_CLOUD_ENC_MP" ; then
encfs "$DIR_CLOUD_ENC" "$DIR_CLOUD_ENC_MP" ||
{ printf 'Error: failed to mount encfs '\''%s'\'' to:\n '\''%s'\''\n' \
"$DIR_CLOUD_ENC" "$DIR_CLOUD_ENC_MP"
exit 33 ; }
fi
printf 'encfs-%s mounted\n' $CLOUDNAME
}
function cloud-umount-encfs () {
local mp="$DIR_CLOUD_ENC_MP"
mountpoint -q "$mp" &&
fusermount -u "$mp" &&
echo "encfs-$CLOUDNAME stopped" ||
{ printf 'Error: encfs-%s failed to un-mount\n %s\n' \
"$CLOUDNAME" "$mp"
exit 34 ; }
}
#
# Actions w/o a cloudname
#
case "$ACTION" in
create )
CONF_FILE=$CLOUDNAME
WEBDAV_REMOTE_PATH=""
CLOUDNAME=""
cloud-create "$CONF_FILE"
exit $?
;;
statusall) cloud-status-all ; exit ;;
list|ls ) cloud-list ; exit ;;
*) # continue
esac
#
# check the CLOUDNAME is valid
#
if ! in_cloudall $CLOUDNAME ; then
echo "Error: cloud instance name '$CLOUDNAME' does not exist"
exit 10
fi
function cloud-start () {
# mount the webdav path
cloud-mount-webdav
# mount encfs
cloud-mount-encfs
}
function cloud-stop () {
# unmount encfs
cloud-umount-encfs
# umount nextcloud
cloud-umount-webdav
}
function cloud-status-webdav () {
if mountpoint -q "$WEBDAV_MPOINT" ; then
printf 'webdav-%s mounted\n' $CLOUDNAME
else
printf 'webdav-%s NOT mounted\n' $CLOUDNAME
return 1
fi
}
function cloud-status-encfs () {
if mountpoint -q "$DIR_CLOUD_ENC_MP" ; then
printf 'encfs-%s mounted\n' $CLOUDNAME
else
printf 'encfs-%s NOT mounted\n' $CLOUDNAME
return 1
fi
}
function cloud-status () {
cloud-status-webdav
cloud-status-encfs
}
function cloud-sync () {
if ! cloud-status-encfs ; then
echo "Error: can not sync $CLOUDNAME"
exit 36
fi
if [ -z "$SYNC_CMD" ] ; then
echo "Error: sync command not defined '$SYNC_CMD'"
exit 41
fi
$SYNC_CMD
}
function cloud-config-show () {
if [ -f "$CONF_FILE_PATH" ] ; then
cat "$CONF_FILE_PATH"
else
echo "Error: missing config file '$CONF_FILE_PATH'"
exit 38
fi
}
read-conf-file
cloud-definitions
#
# Actions that need CLOUDNAME defined
#
case "$ACTION" in
start ) cloud-start ;;
stop ) cloud-stop ;;
status) cloud-status ;;
sync ) cloud-sync ;;
config-show) cloud-config-show ;;
*) echo "Error: invalid action '$ACTION'"
exit 2
esac
exit;
#
# Not used functions
#
function read-cloud-path () {
local rpath=""
while true
do
read -r -p "Give cloud http path for webdav: " rpath
echo "Cloud Path: $rpath"
if y-or-n "Is this correct ?(Y/N)" ; then
WEBDAV_REMOTE_PATH="$rpath"
return 0
fi
done
return 1
}