Загрузить файлы в «/»
This commit is contained in:
1 parent
3a427b1001
commit
a9f0571e0d
1 file changed
+417
@@ -0,0 +1,417 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -u
|
||||
PATH=/usr/sbin:/usr/bin:/sbin:/bin
|
||||
export PATH
|
||||
|
||||
die() {
|
||||
echo "ZBX_NOTSUPPORTED"
|
||||
exit 1
|
||||
}
|
||||
|
||||
BASE="${2:-}"
|
||||
|
||||
[ -n "$BASE" ] || die
|
||||
[ -d "$BASE" ] || die
|
||||
|
||||
BASE="${BASE%/}"
|
||||
|
||||
#
|
||||
# Convert:
|
||||
#
|
||||
# 260924-0949
|
||||
# 260924-0949_Image_C
|
||||
#
|
||||
# to Unix timestamp.
|
||||
#
|
||||
name_to_epoch() {
|
||||
local n="$1"
|
||||
local yy mm dd hh mi year
|
||||
|
||||
# Remove Image suffix
|
||||
n="${n%%_Image_*}"
|
||||
|
||||
if [[ "$n" =~ ^([0-9]{2})([0-9]{2})([0-9]{2})-([0-9]{2})([0-9]{2})$ ]]; then
|
||||
|
||||
yy="${BASH_REMATCH[1]}"
|
||||
mm="${BASH_REMATCH[2]}"
|
||||
dd="${BASH_REMATCH[3]}"
|
||||
hh="${BASH_REMATCH[4]}"
|
||||
mi="${BASH_REMATCH[5]}"
|
||||
|
||||
if (( 10#$yy >= 70 )); then
|
||||
year="19$yy"
|
||||
else
|
||||
year="20$yy"
|
||||
fi
|
||||
|
||||
date -d "${year}-${mm}-${dd} ${hh}:${mi}:00" +%s 2>/dev/null
|
||||
return
|
||||
fi
|
||||
|
||||
echo 0
|
||||
}
|
||||
|
||||
valid_client() {
|
||||
[[ -n "$1" ]] || return 1
|
||||
[[ "$1" != "." ]] || return 1
|
||||
[[ "$1" != ".." ]] || return 1
|
||||
[[ "$1" != *"/"* ]] || return 1
|
||||
}
|
||||
|
||||
client_dir() {
|
||||
local client="$1"
|
||||
|
||||
valid_client "$client" || die
|
||||
|
||||
printf '%s/%s\n' "$BASE" "$client"
|
||||
}
|
||||
|
||||
#
|
||||
# File backup:
|
||||
#
|
||||
# 260924-0936
|
||||
#
|
||||
is_file_backup() {
|
||||
local d="$1"
|
||||
local n="${1##*/}"
|
||||
|
||||
[[ "$n" =~ ^[0-9]{6}-[0-9]{4}$ ]] || return 1
|
||||
[ -d "$d" ] || return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#
|
||||
# Image backup:
|
||||
#
|
||||
# 260924-0949_Image_C
|
||||
#
|
||||
# Must also contain a non-empty image file (.vhdz, .vhd or .raw).
|
||||
#
|
||||
is_image_backup() {
|
||||
local d="$1"
|
||||
local n="${1##*/}"
|
||||
local vhdz
|
||||
|
||||
[[ "$n" =~ ^[0-9]{6}-[0-9]{4}_Image_.*$ ]] || return 1
|
||||
[ -d "$d" ] || return 1
|
||||
|
||||
# Ищет любые типы виртуальных дисков, которые создает UrBackup
|
||||
vhdz="$(find "$d" \
|
||||
-maxdepth 1 \
|
||||
-type f \
|
||||
\( -name '*.vhdz' -o -name '*.vhd' -o -name '*.raw' \) \
|
||||
-size +0c \
|
||||
-print -quit 2>/dev/null)"
|
||||
|
||||
[ -n "$vhdz" ]
|
||||
}
|
||||
|
||||
#
|
||||
# Find latest backup timestamp.
|
||||
#
|
||||
latest_epoch() {
|
||||
|
||||
local dir="$1"
|
||||
local kind="$2"
|
||||
|
||||
local best=0
|
||||
local d
|
||||
local n
|
||||
local e
|
||||
|
||||
[ -d "$dir" ] || {
|
||||
echo 0
|
||||
return
|
||||
}
|
||||
|
||||
while IFS= read -r -d '' d; do
|
||||
|
||||
n="${d##*/}"
|
||||
|
||||
case "$kind" in
|
||||
|
||||
file)
|
||||
is_file_backup "$d" || continue
|
||||
;;
|
||||
|
||||
image)
|
||||
is_image_backup "$d" || continue
|
||||
;;
|
||||
|
||||
*)
|
||||
echo 0
|
||||
return
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
e="$(name_to_epoch "$n")"
|
||||
|
||||
if (( e > best )); then
|
||||
best="$e"
|
||||
fi
|
||||
|
||||
done < <(
|
||||
find "$dir" \
|
||||
-mindepth 1 \
|
||||
-maxdepth 1 \
|
||||
-type d \
|
||||
-print0 2>/dev/null
|
||||
)
|
||||
|
||||
echo "$best"
|
||||
}
|
||||
|
||||
#
|
||||
# Determine whether directory is a real UrBackup client.
|
||||
#
|
||||
is_client_dir() {
|
||||
|
||||
local dir="$1"
|
||||
local d
|
||||
|
||||
while IFS= read -r -d '' d; do
|
||||
|
||||
if is_file_backup "$d"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if is_image_backup "$d"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
done < <(
|
||||
find "$dir" \
|
||||
-mindepth 1 \
|
||||
-maxdepth 1 \
|
||||
-type d \
|
||||
-print0 2>/dev/null
|
||||
)
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
#
|
||||
# MAIN
|
||||
#
|
||||
|
||||
case "${1:-}" in
|
||||
|
||||
discovery)
|
||||
|
||||
printf '{"data":['
|
||||
|
||||
first=1
|
||||
|
||||
while IFS= read -r -d '' d; do
|
||||
|
||||
client="${d##*/}"
|
||||
|
||||
valid_client "$client" || continue
|
||||
|
||||
is_client_dir "$d" || continue
|
||||
|
||||
[ "$first" -eq 1 ] || printf ','
|
||||
|
||||
esc="$(printf '%s' "$client" | \
|
||||
sed 's/\\/\\\\/g; s/"/\\"/g')"
|
||||
|
||||
printf '{"{#CLIENT}":"%s"}' "$esc"
|
||||
|
||||
first=0
|
||||
|
||||
done < <(
|
||||
find "$BASE" \
|
||||
-mindepth 1 \
|
||||
-maxdepth 1 \
|
||||
-type d \
|
||||
-print0 2>/dev/null |
|
||||
sort -z
|
||||
)
|
||||
|
||||
printf ']}\n'
|
||||
|
||||
;;
|
||||
|
||||
last_ts)
|
||||
|
||||
[ "$#" -eq 4 ] || die
|
||||
|
||||
client="$3"
|
||||
kind="$4"
|
||||
|
||||
latest_epoch \
|
||||
"$(client_dir "$client")" \
|
||||
"$kind"
|
||||
|
||||
;;
|
||||
|
||||
last_age)
|
||||
|
||||
[ "$#" -eq 4 ] || die
|
||||
|
||||
client="$3"
|
||||
kind="$4"
|
||||
|
||||
ts="$(
|
||||
latest_epoch \
|
||||
"$(client_dir "$client")" \
|
||||
"$kind"
|
||||
)"
|
||||
|
||||
if [ "$ts" -le 0 ]; then
|
||||
|
||||
# No backup found.
|
||||
echo 999999999
|
||||
|
||||
else
|
||||
|
||||
now="$(date +%s)"
|
||||
|
||||
age=$((now - ts))
|
||||
|
||||
(( age < 0 )) && age=0
|
||||
|
||||
echo "$age"
|
||||
|
||||
fi
|
||||
|
||||
;;
|
||||
|
||||
count)
|
||||
|
||||
[ "$#" -eq 4 ] || die
|
||||
|
||||
client="$3"
|
||||
kind="$4"
|
||||
|
||||
dir="$(client_dir "$client")"
|
||||
|
||||
count=0
|
||||
|
||||
while IFS= read -r -d '' d; do
|
||||
|
||||
case "$kind" in
|
||||
|
||||
file)
|
||||
is_file_backup "$d" || continue
|
||||
;;
|
||||
|
||||
image)
|
||||
is_image_backup "$d" || continue
|
||||
;;
|
||||
|
||||
all)
|
||||
|
||||
if is_file_backup "$d"; then
|
||||
:
|
||||
elif is_image_backup "$d"; then
|
||||
:
|
||||
else
|
||||
continue
|
||||
fi
|
||||
|
||||
;;
|
||||
|
||||
*)
|
||||
die
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
count=$((count + 1))
|
||||
|
||||
done < <(
|
||||
find "$dir" \
|
||||
-mindepth 1 \
|
||||
-maxdepth 1 \
|
||||
-type d \
|
||||
-print0 2>/dev/null
|
||||
)
|
||||
|
||||
echo "$count"
|
||||
|
||||
;;
|
||||
|
||||
image_size)
|
||||
|
||||
[ "$#" -eq 3 ] || die
|
||||
|
||||
client="$3"
|
||||
|
||||
dir="$(client_dir "$client")"
|
||||
|
||||
ts="$(latest_epoch "$dir" image)"
|
||||
|
||||
[ "$ts" -gt 0 ] || {
|
||||
echo 0
|
||||
exit
|
||||
}
|
||||
|
||||
best=""
|
||||
|
||||
while IFS= read -r -d '' d; do
|
||||
|
||||
is_image_backup "$d" || continue
|
||||
|
||||
n="${d##*/}"
|
||||
|
||||
e="$(name_to_epoch "$n")"
|
||||
|
||||
[ "$e" -eq "$ts" ] || continue
|
||||
|
||||
best="$d"
|
||||
|
||||
break
|
||||
|
||||
done < <(
|
||||
find "$dir" \
|
||||
-mindepth 1 \
|
||||
-maxdepth 1 \
|
||||
-type d \
|
||||
-print0 2>/dev/null
|
||||
)
|
||||
|
||||
[ -n "$best" ] || {
|
||||
echo 0
|
||||
exit
|
||||
}
|
||||
|
||||
# Ищет размер для любых форматов образов (.vhdz, .vhd, .raw)
|
||||
vhdz="$(
|
||||
find "$best" \
|
||||
-maxdepth 1 \
|
||||
-type f \
|
||||
\( -name '*.vhdz' -o -name '*.vhd' -o -name '*.raw' \) \
|
||||
-size +0c \
|
||||
-print -quit 2>/dev/null
|
||||
)"
|
||||
|
||||
[ -n "$vhdz" ] || {
|
||||
echo 0
|
||||
exit
|
||||
}
|
||||
|
||||
stat -c '%s' "$vhdz" 2>/dev/null || echo 0
|
||||
|
||||
;;
|
||||
|
||||
disk_free_pct)
|
||||
|
||||
df -P "$BASE" 2>/dev/null |
|
||||
awk 'NR==2 {
|
||||
gsub(/%/,"",$5);
|
||||
print 100-$5
|
||||
}'
|
||||
|
||||
;;
|
||||
|
||||
*)
|
||||
|
||||
die
|
||||
|
||||
;;
|
||||
|
||||
esac
|
||||
Reference in new issue
Block a user