Samba Backup

This commit is contained in:
2023-07-23 09:37:27 -05:00
parent 0b8e7992e7
commit 6a6368e10f
23 changed files with 1549 additions and 0 deletions
+190
View File
@@ -0,0 +1,190 @@
#!/command/with-contenv bashio
# shellcheck shell=bash
declare SAMBA_STATUS=(IDLE RUNNING SUCCEEDED FAILED)
declare SENSOR_NAME="sensor.samba_backup"
declare SENSOR_URL="/core/api/states/${SENSOR_NAME}"
declare STORAGE_FILE="/backup/.samba_backup.sensor"
declare CURRENT_STATUS
declare BACKUPS_LOCAL="0"
declare BACKUPS_REMOTE="0"
declare TOTAL_SUCCESS="0"
declare TOTAL_FAIL="0"
declare LAST_BACKUP="never"
# ------------------------------------------------------------------------------
# Get the current sensor values and store them in internal variables.
# ------------------------------------------------------------------------------
function get-sensor {
local storage
local result
if [ -f "$STORAGE_FILE" ]; then
storage=$(cat "$STORAGE_FILE")
if result=$(echo "$storage" | jq -r ".attributes.backups_local" 2>/dev/null); then
[[ "$result" != null ]] && BACKUPS_LOCAL="$result"
fi
if result=$(echo "$storage" | jq -r ".attributes.backups_remote" 2>/dev/null); then
[[ "$result" != null ]] && BACKUPS_REMOTE="$result"
fi
if result=$(echo "$storage" | jq -r ".attributes.total_backups_succeeded" 2>/dev/null); then
[[ "$result" != null ]] && TOTAL_SUCCESS="$result"
fi
if result=$(echo "$storage" | jq -r ".attributes.total_backups_failed" 2>/dev/null); then
[[ "$result" != null ]] && TOTAL_FAIL="$result"
fi
if result=$(echo "$storage" | jq -r ".attributes.last_backup" 2>/dev/null); then
[[ "$result" != null ]] && LAST_BACKUP="$result"
fi
fi
bashio::log.debug "Backups local/remote: ${BACKUPS_LOCAL}/${BACKUPS_REMOTE}"
bashio::log.debug "Total backups succeeded/failed: ${TOTAL_SUCCESS}/${TOTAL_FAIL}"
bashio::log.debug "Last backup: ${LAST_BACKUP}"
return 0
}
# ------------------------------------------------------------------------------
# Update the Home Assistant sensor.
#
# Arguments
# $1 The status
# $2 Whether to update all values
# ------------------------------------------------------------------------------
function update-sensor {
local status=${1}
local all=${2:-}
local data
local response
CURRENT_STATUS="$status"
if bashio::var.has_value "${all}"; then
if response=$(ha backups --raw-json | jq ".data.backups[].slug"); then
[ -n "$response" ] && BACKUPS_LOCAL=$(echo "$response" | wc -l) || BACKUPS_LOCAL="0"
fi
if response=$(eval "${SMB} -c 'cd \"${TARGET_DIR}\"; ls'"); then
# grep returns non-zero exit code if there are no matches
if response=$(echo "$response" | grep -E '\<([0-9a-f]{8}|Samba_Backup_.*)\.tar\>'); then
BACKUPS_REMOTE=$(echo "$response" | wc -l)
else
BACKUPS_REMOTE="0"
fi
fi
if [ "$CURRENT_STATUS" = "${SAMBA_STATUS[2]}" ]; then
TOTAL_SUCCESS=$((TOTAL_SUCCESS + 1))
LAST_BACKUP=$(date +'%Y-%m-%d %H:%M')
elif [ "$CURRENT_STATUS" = "${SAMBA_STATUS[3]}" ]; then
TOTAL_FAIL=$((TOTAL_FAIL + 1))
fi
fi
data=$(jq -n \
--arg s "$CURRENT_STATUS" \
--arg bl "$BACKUPS_LOCAL" \
--arg br "$BACKUPS_REMOTE" \
--arg ts "$TOTAL_SUCCESS" \
--arg tf "$TOTAL_FAIL" \
--arg lb "$LAST_BACKUP" \
'{
"state": $s,
"attributes": {
"friendly_name": "Samba Backup",
"backups_local": $bl,
"backups_remote": $br,
"total_backups_succeeded": $ts,
"total_backups_failed": $tf,
"last_backup": $lb
}
}')
if ! response=$(ha-post-sensor "$data"); then
bashio::log.error "Unable to update sensor ${SENSOR_NAME} in Home Assistant"
fi
echo "$data" > "$STORAGE_FILE"
return 0
}
# ------------------------------------------------------------------------------
# Restore the Home Assistant sensor with the last known values.
# ------------------------------------------------------------------------------
function restore-sensor {
local data
local response
if [ -f "$STORAGE_FILE" ]; then
data=$(cat "$STORAGE_FILE")
if ! response=$(ha-post-sensor "$data"); then
bashio::log.error "Unable to restore sensor ${SENSOR_NAME} in Home Assistant"
fi
fi
return 0
}
# ------------------------------------------------------------------------------
# Reset the counter variables of the Home Assistant sensor.
# ------------------------------------------------------------------------------
function reset-counter {
TOTAL_SUCCESS="0"
TOTAL_FAIL="0"
update-sensor "$CURRENT_STATUS"
return 0
}
# ------------------------------------------------------------------------------
# ----------------------- INTERNAL FUNCTION ------------------------------------
# ------------------------------------------------------------------------------
# Post a sensor via the REST API of Home Assistant.
#
# Arguments:
# $1 The JSON data to POST
# ------------------------------------------------------------------------------
function ha-post-sensor {
local data=${1}
local status
local response
bashio::log.debug "Posting sensor data to API at ${SENSOR_URL}"
if ! response=$(curl --silent --show-error \
--write-out '\n%{http_code}' --request "POST" \
-H "Authorization: Bearer ${__BASHIO_SUPERVISOR_TOKEN}" \
-H "Content-Type: application/json" \
-d "${data}" \
"${__BASHIO_SUPERVISOR_API}${SENSOR_URL}"
); then
bashio::log.debug "${response}"
bashio::log.error "Something went wrong contacting the API"
return 1
fi
status=${response##*$'\n'}
response=${response%$status}
bashio::log.debug "API Status: ${status}"
bashio::log.debug "API Response: ${response}"
if [[ "${status}" -eq 401 ]]; then
bashio::log.error "Unable to authenticate with the API, permission denied"
return 1
fi
echo "${response}"
return 0
}