133 lines
5.3 KiB
Bash
133 lines
5.3 KiB
Bash
#!/bin/bash
|
|
# -----------------------------------------------------------------------------------------------
|
|
# --------------------------------- Bulk Permissions Repair ------------------------------------
|
|
# -----------------------------------------------------------------------------------------------
|
|
# Applies correct permissions to a single share or specific path.
|
|
# Faster than running media_shares_permissions.sh which processes all shares.
|
|
# Use when a specific share has wrong ownership or permissions after:
|
|
# - A failed transfer that left files owned by wrong user
|
|
# - A container writing files as root instead of nobody:users
|
|
# - Manual file operations that bypassed normal permission handling
|
|
# - A new share that needs permissions applied before the next nightly run
|
|
#
|
|
# Usage:
|
|
# bulk_permissions_repair.sh /mnt/user/Movies
|
|
# bulk_permissions_repair.sh /mnt/user/Movies --dry-run
|
|
# bulk_permissions_repair.sh /mnt/user/Movies /mnt/user/Tv_Shows
|
|
#
|
|
# Uses PERMISSIONS_MODE and PERMISSIONS_OWNER from Master.conf.
|
|
# Supports --dry-run to show what would be changed without applying.
|
|
# -----------------------------------------------------------------------------------------------
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
source "$SCRIPT_DIR/../Master.conf"
|
|
source "$SCRIPT_DIR/../common.sh"
|
|
|
|
parse_args "$@"
|
|
|
|
# -----------------------------------------------------------------------------------------------
|
|
# ━━━ $ICON_GEAR Setup ━━━
|
|
# -----------------------------------------------------------------------------------------------
|
|
echo ""
|
|
echo "━━━ $ICON_GEAR Setup ━━━"
|
|
|
|
if [[ "$EUID" -ne 0 ]]; then
|
|
error "Must be run as root"
|
|
exit 1
|
|
fi
|
|
|
|
success "Running as root"
|
|
|
|
if [[ ${#PARSED_ARGS[@]} -eq 0 ]]; then
|
|
error "No paths specified"
|
|
error "Usage: bulk_permissions_repair.sh /path/to/share [/another/path]"
|
|
error " bulk_permissions_repair.sh /mnt/user/Movies --dry-run"
|
|
exit 1
|
|
fi
|
|
|
|
info "Mode: $PERMISSIONS_MODE"
|
|
info "Owner: $PERMISSIONS_OWNER"
|
|
[[ "$DRY_RUN" == true ]] && warn "DRY RUN — no permissions will be changed"
|
|
|
|
# -----------------------------------------------------------------------------------------------
|
|
# ━━━ $ICON_PERMS Apply Permissions ━━━
|
|
# -----------------------------------------------------------------------------------------------
|
|
echo ""
|
|
echo "━━━ $ICON_PERMS Permissions Repair ━━━"
|
|
|
|
START=$(date +%s)
|
|
PASS=()
|
|
FAIL=()
|
|
|
|
for share_path in "${PARSED_ARGS[@]}"; do
|
|
[[ -z "$share_path" ]] && continue
|
|
|
|
echo ""
|
|
echo "━━━ $ICON_PERMS $(basename "$share_path") ━━━"
|
|
|
|
if [[ ! -d "$share_path" ]]; then
|
|
error "$share_path — not found"
|
|
FAIL+=("$share_path")
|
|
continue
|
|
fi
|
|
|
|
# Count files for progress context
|
|
FILE_COUNT=$(find "$share_path" -type f 2>/dev/null | wc -l)
|
|
DIR_COUNT=$(find "$share_path" -type d 2>/dev/null | wc -l)
|
|
SIZE=$(du -sh "$share_path" 2>/dev/null | cut -f1)
|
|
|
|
info "$share_path — $FILE_COUNT files, $DIR_COUNT dirs ($SIZE)"
|
|
|
|
if [[ "$DRY_RUN" == true ]]; then
|
|
warn "DRY RUN — would apply: chmod -R $PERMISSIONS_MODE $share_path"
|
|
warn "DRY RUN — would apply: chown -R $PERMISSIONS_OWNER $share_path"
|
|
PASS+=("$(basename "$share_path")")
|
|
continue
|
|
fi
|
|
|
|
# Apply ownership first — chmod after so files are owned correctly before mode change
|
|
info "Applying ownership: $PERMISSIONS_OWNER..."
|
|
chown -R "$PERMISSIONS_OWNER" "$share_path" 2>/dev/null
|
|
CHOWN_EXIT=$?
|
|
|
|
info "Applying permissions: $PERMISSIONS_MODE..."
|
|
chmod -R "$PERMISSIONS_MODE" "$share_path" 2>/dev/null
|
|
CHMOD_EXIT=$?
|
|
|
|
if [[ "$CHOWN_EXIT" -eq 0 && "$CHMOD_EXIT" -eq 0 ]]; then
|
|
success "$ICON_UNLOCKED $(basename "$share_path") — permissions applied"
|
|
PASS+=("$(basename "$share_path")")
|
|
else
|
|
error "$(basename "$share_path") — permission repair failed"
|
|
FAIL+=("$(basename "$share_path")")
|
|
fi
|
|
done
|
|
|
|
END=$(date +%s)
|
|
|
|
# -----------------------------------------------------------------------------------------------
|
|
# ━━━ $ICON_SUMMARY Summary ━━━
|
|
# -----------------------------------------------------------------------------------------------
|
|
echo ""
|
|
echo "━━━━━ $ICON_SUMMARY PERMISSIONS REPAIR SUMMARY ━━━━━"
|
|
echo "$ICON_PERMS Mode: $PERMISSIONS_MODE"
|
|
echo "$ICON_PERMS Owner: $PERMISSIONS_OWNER"
|
|
echo "$ICON_TIME Duration: $(format_duration $((END - START)))"
|
|
echo ""
|
|
echo " $ICON_SUCCESS Pass: ${#PASS[@]} $ICON_ERROR Fail: ${#FAIL[@]}"
|
|
echo ""
|
|
[[ ${#PASS[@]} -gt 0 ]] && for p in "${PASS[@]}"; do echo " $ICON_UNLOCKED $p"; done
|
|
[[ ${#FAIL[@]} -gt 0 ]] && for f in "${FAIL[@]}"; do echo " $ICON_ERROR $f"; done
|
|
echo ""
|
|
|
|
if [[ "$DRY_RUN" == true ]]; then
|
|
echo "$ICON_WARN Status: DRY RUN — no changes made"
|
|
elif [[ ${#FAIL[@]} -gt 0 ]]; then
|
|
echo "$ICON_ERROR Status: SOME REPAIRS FAILED"
|
|
notify "Permissions repair failed on $(hostname) — failed shares: ${FAIL[*]}" "Permissions Repair" "warning"
|
|
else
|
|
echo "$ICON_DONE Status: $ICON_SUCCESS DONE"
|
|
notify "Permissions repair complete on $(hostname) — ${#PASS[@]} share(s) repaired" "Permissions Repair" "normal"
|
|
fi
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" |