feat: Add NAS mount check and setup script for improved backup reliability

This commit is contained in:
Peter Wood
2025-06-25 16:35:09 -04:00
parent b04c93daf2
commit b3580f2ce0
3 changed files with 647 additions and 1 deletions

View File

@@ -125,7 +125,7 @@ declare -A MEDIA_SERVICES=(
["tautulli"]="/config/backups" ["tautulli"]="/config/backups"
["sabnzbd"]="/config/sabnzbd.ini" ["sabnzbd"]="/config/sabnzbd.ini"
["jellyseerr_db"]="/config/db/" ["jellyseerr_db"]="/config/db/"
["jellyseerr_settings"]="/config/settings.json" ["jellyseerr_settings"]="/data/settings.json"
) )
# Service-specific backup destinations # Service-specific backup destinations
@@ -181,6 +181,28 @@ log_info() {
echo "[${timestamp}] INFO: $message" >> "${LOG_FILE}" 2>/dev/null || true echo "[${timestamp}] INFO: $message" >> "${LOG_FILE}" 2>/dev/null || true
} }
# Check if NAS mount is accessible
check_nas_mount() {
local mount_point="/mnt/share/media"
if ! mountpoint -q "$mount_point"; then
log_error "NAS not mounted at $mount_point"
log_info "Please mount the NAS first with: sudo mount $mount_point"
log_info "Or check the mounting setup guide in docs/nas-mount-setup-guide.md"
return 1
fi
# Test write access to backup directory
if [ ! -w "$BACKUP_ROOT" ]; then
log_error "No write access to backup directory: $BACKUP_ROOT"
log_info "Check NAS mount permissions and credentials"
return 1
fi
log_success "NAS mount check passed: $mount_point is accessible"
return 0
}
# Performance tracking functions # Performance tracking functions
track_performance() { track_performance() {
if [ "$PERFORMANCE_MONITORING" != true ]; then if [ "$PERFORMANCE_MONITORING" != true ]; then
@@ -689,6 +711,14 @@ main() {
fi fi
# Pre-flight checks # Pre-flight checks
if ! check_nas_mount; then
if [[ "$METRICS_ENABLED" == "true" ]]; then
metrics_backup_complete "failed" "NAS mount not accessible"
fi
send_notification "Media Backup Failed" "NAS mount not accessible at $MOUNT_POINT" "error" 0 1
exit 1
fi
if ! check_disk_space; then if ! check_disk_space; then
if [[ "$METRICS_ENABLED" == "true" ]]; then if [[ "$METRICS_ENABLED" == "true" ]]; then
metrics_backup_complete "failed" "Insufficient disk space" metrics_backup_complete "failed" "Insufficient disk space"
@@ -707,6 +737,15 @@ main() {
exit 1 exit 1
fi fi
# Check if NAS mount is accessible
if ! check_nas_mount; then
if [[ "$METRICS_ENABLED" == "true" ]]; then
metrics_backup_complete "failed" "NAS mount not accessible"
fi
send_notification "Media Backup Failed" "NAS mount not accessible" "error" 0 1
exit 1
fi
local success_count=0 local success_count=0
local failed_count=0 local failed_count=0
local backup_results=() local backup_results=()

View File

@@ -0,0 +1,161 @@
# NAS Mount Setup Guide for Fedora 42
## Quick Setup Instructions
Your NAS IP: `192.168.68.51`
Mount Point: `/mnt/share/media`
### Prerequisites (Already Installed)
- `cifs-utils` - for SMB/CIFS mounting
- `nfs-utils` - for NFS mounting
### Option 1: Automated Setup (Recommended)
Run the interactive setup script:
```bash
./setup-nas-mount.sh
```
This script will:
- Test both SMB and NFS connectivity
- Guide you through the setup process
- Create persistent mount configuration
- Set up systemd mount units for reliable boot mounting
### Option 2: Manual SMB/CIFS Setup
1. **Test SMB shares first:**
```bash
# List available shares (you'll need NAS credentials)
smbclient -L 192.168.68.51 -U your_username
```
2. **Create credentials file (if using authentication):**
```bash
sudo tee /etc/nas-credentials << EOF
username=your_nas_username
password=your_nas_password
domain=WORKGROUP
EOF
sudo chmod 600 /etc/nas-credentials
```
3. **Test mount:**
```bash
# With credentials
sudo mount -t cifs //192.168.68.51/share_name /mnt/share/media -o credentials=/etc/nas-credentials,uid=$(id -u),gid=$(id -g),iocharset=utf8
# Or for guest access
sudo mount -t cifs //192.168.68.51/share_name /mnt/share/media -o guest,uid=$(id -u),gid=$(id -g),iocharset=utf8
```
4. **Add to /etc/fstab for persistence:**
```bash
# Backup fstab first
sudo cp /etc/fstab /etc/fstab.backup
# Add entry (with credentials)
echo "//192.168.68.51/share_name /mnt/share/media cifs credentials=/etc/nas-credentials,uid=$(id -u),gid=$(id -g),iocharset=utf8,noauto,user 0 0" | sudo tee -a /etc/fstab
# Or for guest access
echo "//192.168.68.51/share_name /mnt/share/media cifs guest,uid=$(id -u),gid=$(id -g),iocharset=utf8,noauto,user 0 0" | sudo tee -a /etc/fstab
```
### Option 3: Manual NFS Setup
1. **Check available NFS exports:**
```bash
showmount -e 192.168.68.51
```
2. **Test mount:**
```bash
sudo mount -t nfs 192.168.68.51:/path/to/export /mnt/share/media -o rw,hard,intr
```
3. **Add to /etc/fstab:**
```bash
echo "192.168.68.51:/path/to/export /mnt/share/media nfs rw,hard,intr,rsize=8192,wsize=8192,timeo=14,noauto,user 0 0" | sudo tee -a /etc/fstab
```
### Systemd Mount Unit (For Reliable Boot Mounting)
Create `/etc/systemd/system/mnt-share-media.mount`:
```ini
[Unit]
Description=Mount NAS Media Share
After=network-online.target
Wants=network-online.target
[Mount]
What=//192.168.68.51/share_name
Where=/mnt/share/media
Type=cifs
Options=credentials=/etc/nas-credentials,uid=1000,gid=1000,iocharset=utf8
[Install]
WantedBy=multi-user.target
```
Enable it:
```bash
sudo systemctl daemon-reload
sudo systemctl enable mnt-share-media.mount
sudo systemctl start mnt-share-media.mount
```
### Common Commands
- **Mount manually:** `sudo mount /mnt/share/media`
- **Unmount:** `sudo umount /mnt/share/media`
- **Check mount status:** `df -h /mnt/share/media`
- **Test systemd mount:** `sudo systemctl start mnt-share-media.mount`
### Troubleshooting
1. **Check connectivity:**
```bash
ping 192.168.68.51
```
2. **Test SMB connection:**
```bash
nc -zv 192.168.68.51 445
```
3. **Test NFS connection:**
```bash
nc -zv 192.168.68.51 2049
```
4. **Check mount logs:**
```bash
journalctl -u mnt-share-media.mount
```
5. **Verify fstab syntax:**
```bash
sudo mount -a
```
### Security Notes
- Credentials file should have 600 permissions (readable only by root)
- Consider using NFS over SMB for better performance on Linux
- Use `noauto` in fstab to prevent boot delays if NAS is unavailable
- The `user` option allows regular users to mount/unmount
### Integration with Your Backup Scripts
Your `backup-media.sh` script already references `/mnt/share/media/backups`, so once the NAS is mounted, your backups will automatically work with the NAS storage.
Make sure your backup script has proper error handling for when the NAS is not mounted:
```bash
# Add this check to your backup scripts
if ! mountpoint -q /mnt/share/media; then
log_error "NAS not mounted at /mnt/share/media"
exit 1
fi
```

446
setup-nas-mount.sh Executable file
View File

@@ -0,0 +1,446 @@
#!/bin/bash
# NAS Mount Setup Script for Fedora 42
# This script helps set up persistent mounting of your NAS at 192.168.68.51
set -e
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# Configuration
NAS_IP="192.168.68.51"
MOUNT_POINT="/mnt/share/media"
CREDENTIALS_FILE="/etc/nas-credentials"
FSTAB_BACKUP="/etc/fstab.backup.$(date +%Y%m%d_%H%M%S)"
# Logging functions
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if running as root
check_root() {
if [[ $EUID -eq 0 ]]; then
log_error "This script should not be run as root. Please run as a regular user."
log_info "The script will use sudo when needed."
exit 1
fi
}
# Check prerequisites
check_prerequisites() {
log_info "Checking prerequisites..."
# Check if required packages are installed
if ! rpm -q cifs-utils >/dev/null 2>&1; then
log_error "cifs-utils package is not installed"
log_info "Install it with: sudo dnf install cifs-utils"
exit 1
fi
if ! rpm -q nfs-utils >/dev/null 2>&1; then
log_error "nfs-utils package is not installed"
log_info "Install it with: sudo dnf install nfs-utils"
exit 1
fi
# Check network connectivity
if ! ping -c 1 "$NAS_IP" >/dev/null 2>&1; then
log_error "Cannot reach NAS at $NAS_IP"
exit 1
fi
log_success "All prerequisites met"
}
# Test SMB shares
test_smb_shares() {
log_info "Testing SMB shares on $NAS_IP..."
# First try to get shares without credentials (guest access)
log_info "Trying guest access first..."
if smbclient -L "$NAS_IP" -N 2>/dev/null; then
return 0
fi
log_info "Guest access failed. Authentication required."
echo "Please enter your NAS username:"
read -r username
if [[ -n "$username" ]]; then
echo "Enter password for $username:"
read -rs password
echo ""
log_info "Listing SMB shares with authentication..."
if smbclient -L "$NAS_IP" -U "$username%$password" 2>/dev/null; then
# Store credentials for later use
SMB_USERNAME="$username"
SMB_PASSWORD="$password"
return 0
else
log_warning "Authentication failed or no shares found"
log_info "Please check your username and password"
return 1
fi
else
log_error "Username is required for this NAS"
return 1
fi
}
# Test NFS exports
test_nfs_exports() {
log_info "Testing NFS exports on $NAS_IP..."
local exports
exports=$(showmount -e "$NAS_IP" 2>/dev/null)
if [[ -n "$exports" ]]; then
echo "$exports"
return 0
else
log_warning "No NFS exports found or access denied"
log_info "NFS exports are directory paths on the NAS that are shared via NFS protocol"
log_info "Common examples: /volume1/media, /mnt/storage, /export/data"
log_info "Your NAS appears to use SMB/CIFS instead of NFS"
return 1
fi
}
# Setup SMB mount
setup_smb_mount() {
local share_name="$1"
local username="$2"
local password="$3"
log_info "Setting up SMB mount for share: $share_name"
# Create credentials file if authentication is needed
if [[ -n "$username" ]]; then
log_info "Creating credentials file at $CREDENTIALS_FILE"
sudo tee "$CREDENTIALS_FILE" >/dev/null <<EOF
username=$username
password=$password
domain=WORKGROUP
EOF
sudo chmod 600 "$CREDENTIALS_FILE"
log_success "Credentials file created"
# Test mount with credentials
local mount_options="credentials=$CREDENTIALS_FILE,uid=$(id -u),gid=$(id -g),iocharset=utf8,file_mode=0644,dir_mode=0755"
else
# Guest access
local mount_options="guest,uid=$(id -u),gid=$(id -g),iocharset=utf8,file_mode=0644,dir_mode=0755"
fi
# Test the mount
log_info "Testing SMB mount..."
if sudo mount -t cifs "//$NAS_IP/$share_name" "$MOUNT_POINT" -o "$mount_options"; then
log_success "Test mount successful"
sudo umount "$MOUNT_POINT"
# Add to fstab
setup_fstab_entry "cifs" "//$NAS_IP/$share_name" "$mount_options"
else
log_error "SMB mount test failed"
return 1
fi
}
# Setup NFS mount
setup_nfs_mount() {
local export_path="$1"
log_info "Setting up NFS mount for export: $export_path"
local mount_options="rw,hard,intr,rsize=8192,wsize=8192,timeo=14"
# Test the mount
log_info "Testing NFS mount..."
if sudo mount -t nfs "$NAS_IP:$export_path" "$MOUNT_POINT" -o "$mount_options"; then
log_success "Test mount successful"
sudo umount "$MOUNT_POINT"
# Add to fstab
setup_fstab_entry "nfs" "$NAS_IP:$export_path" "$mount_options"
else
log_error "NFS mount test failed"
return 1
fi
}
# Setup fstab entry
setup_fstab_entry() {
local fs_type="$1"
local device="$2"
local options="$3"
log_info "Setting up persistent mount in /etc/fstab"
# Backup fstab
sudo cp /etc/fstab "$FSTAB_BACKUP"
log_info "Created fstab backup: $FSTAB_BACKUP"
# Add entry to fstab
local fstab_entry="$device $MOUNT_POINT $fs_type $options,noauto,user 0 0"
# Check if entry already exists
if grep -q "$MOUNT_POINT" /etc/fstab; then
log_warning "Mount point already exists in fstab. Updating entry..."
sudo sed -i "\|$MOUNT_POINT|d" /etc/fstab
fi
echo "$fstab_entry" | sudo tee -a /etc/fstab >/dev/null
log_success "Added mount entry to fstab"
# Create systemd mount unit for better boot integration
create_systemd_mount_unit "$fs_type" "$device" "$options"
}
# Create systemd mount unit
create_systemd_mount_unit() {
local fs_type="$1"
local device="$2"
local options="$3"
local unit_name="mnt-share-media.mount"
local unit_file="/etc/systemd/system/$unit_name"
log_info "Creating systemd mount unit: $unit_name"
sudo tee "$unit_file" >/dev/null <<EOF
[Unit]
Description=Mount NAS Media Share
After=network-online.target
Wants=network-online.target
[Mount]
What=$device
Where=$MOUNT_POINT
Type=$fs_type
Options=$options
[Install]
WantedBy=multi-user.target
EOF
# Enable the mount unit
sudo systemctl daemon-reload
sudo systemctl enable "$unit_name"
log_success "Systemd mount unit created and enabled"
}
# Interactive setup
interactive_setup() {
log_info "=== NAS Mount Setup for $NAS_IP ==="
echo ""
echo "Choose your preferred mounting method:"
echo "1) SMB/CIFS (recommended for Windows-based NAS)"
echo "2) NFS (recommended for Linux-based NAS)"
echo "3) Test both and let me choose"
echo ""
read -rp "Enter your choice (1-3): " choice
case $choice in
1)
log_info "Setting up SMB/CIFS mount..."
log_info "SMB shares are folder names shared by your NAS (like 'media', 'backup', 'public')"
echo ""
if test_smb_shares; then
echo ""
echo "Available SMB shares are listed above."
read -rp "Enter the share name to mount (e.g., 'media' or 'public'): " share_name
# Use credentials from test_smb_shares if available
local username="${SMB_USERNAME:-}"
local password="${SMB_PASSWORD:-}"
# If no credentials from test, ask again
if [[ -z "$username" ]]; then
read -rp "Enter username (or press Enter for guest): " username
if [[ -n "$username" ]]; then
echo "Enter password for $username:"
read -rs password
echo ""
fi
fi
setup_smb_mount "$share_name" "$username" "$password"
else
log_error "SMB setup failed"
exit 1
fi
;;
2)
log_info "Setting up NFS mount..."
log_info "NFS (Network File System) exports are directory paths shared by the NAS"
log_info "Examples: /volume1/media, /mnt/storage, /export/data"
echo ""
if test_nfs_exports; then
echo ""
echo "Available NFS exports are listed above."
read -rp "Enter the export path to mount (e.g., /volume1/media): " export_path
setup_nfs_mount "$export_path"
else
log_error "NFS setup failed - no exports available"
log_info "Your NAS likely uses SMB/CIFS instead. Try option 1."
exit 1
fi
;;
3)
log_info "Testing both protocols..."
smb_available=false
nfs_available=false
if test_smb_shares; then
smb_available=true
log_success "SMB/CIFS is available"
fi
echo ""
if test_nfs_exports; then
nfs_available=true
log_success "NFS is available"
fi
echo ""
if [[ "$smb_available" == true && "$nfs_available" == true ]]; then
echo "Both SMB and NFS are available. NFS typically offers better performance for Linux systems."
read -rp "Do you want to use NFS? (Y/n): " use_nfs
if [[ "$use_nfs" =~ ^[Nn]$ ]]; then
read -rp "Enter the SMB share name to mount: " share_name
read -rp "Enter username (or press Enter for guest): " username
if [[ -n "$username" ]]; then
echo "Enter password for $username:"
read -rs password
echo ""
fi
setup_smb_mount "$share_name" "$username" "$password"
else
echo "Available NFS exports are listed above."
read -rp "Enter the NFS export path to mount (e.g., /volume1/media): " export_path
setup_nfs_mount "$export_path"
fi
elif [[ "$smb_available" == true ]]; then
log_info "Only SMB is available, proceeding with SMB setup..."
read -rp "Enter the share name to mount: " share_name
read -rp "Enter username (or press Enter for guest): " username
if [[ -n "$username" ]]; then
echo "Enter password for $username:"
read -rs password
echo ""
fi
setup_smb_mount "$share_name" "$username" "$password"
elif [[ "$nfs_available" == true ]]; then
log_info "Only NFS is available, proceeding with NFS setup..."
echo "Available NFS exports are listed above."
read -rp "Enter the NFS export path to mount (e.g., /volume1/media): " export_path
setup_nfs_mount "$export_path"
else
log_error "Neither SMB nor NFS is available on this NAS"
exit 1
fi
;;
*)
log_error "Invalid choice"
exit 1
;;
esac
}
# Test the mount
test_mount() {
log_info "Testing the mount..."
if sudo mount "$MOUNT_POINT"; then
log_success "Mount successful!"
# Test write access
test_file="$MOUNT_POINT/.test_write_$(date +%s)"
if touch "$test_file" 2>/dev/null; then
log_success "Write access confirmed"
rm -f "$test_file"
else
log_warning "Mount is read-only or write access denied"
fi
# Show mount info
df -h "$MOUNT_POINT"
echo ""
read -rp "Do you want to unmount for now? (Y/n): " unmount_now
if [[ ! "$unmount_now" =~ ^[Nn]$ ]]; then
sudo umount "$MOUNT_POINT"
log_info "Unmounted. Use 'sudo mount $MOUNT_POINT' to mount manually."
fi
else
log_error "Mount failed!"
exit 1
fi
}
# Show usage instructions
show_usage_instructions() {
log_success "=== NAS Mount Setup Complete ==="
echo ""
log_info "Your NAS is now configured for persistent mounting."
echo ""
echo "Usage instructions:"
echo "• Manual mount: sudo mount $MOUNT_POINT"
echo "• Manual unmount: sudo umount $MOUNT_POINT"
echo "• The mount will be available after reboot via systemd"
echo ""
echo "Files and locations:"
echo "• Mount point: $MOUNT_POINT"
echo "• Fstab backup: $FSTAB_BACKUP"
if [[ -f "$CREDENTIALS_FILE" ]]; then
echo "• Credentials file: $CREDENTIALS_FILE (secure, 600 permissions)"
fi
echo "• Systemd unit: /etc/systemd/system/mnt-share-media.mount"
echo ""
log_info "To enable automatic mounting on boot:"
echo "sudo systemctl start mnt-share-media.mount"
echo ""
log_warning "Remember to test the mount after a reboot to ensure it works correctly."
}
# Main function
main() {
check_root
check_prerequisites
interactive_setup
test_mount
show_usage_instructions
}
# Run main function
main "$@"