Fix USB backup permission issues

**Problem:**
- USB drives mounted as root were not writable by regular user
- Caused "Permission denied" errors on backup
- Required running application as root (not secure)

**Solution:**
- Better permission error messages with fix suggestions
- Try to create backup directory first (more flexible)
- Show helpful error: "run sudo chown -R \$USER /media/usb0"

**USB Setup Script (setup_usb.sh):**
- Interactive USB drive mounting
- Automatically detects USB devices
- Mounts with user ownership (uid/gid)
- Tests write permissions
- Shows free space
- Offers to add to /etc/fstab
- Color-coded output

**Documentation Updates:**
- Added 3 methods for mounting with permissions
- Recommended method: mount with uid/gid options
- Added fstab auto-mount example
- Added quick setup script example
- Clear instructions for each method

**Usage:**
```bash
# Easiest method
sudo ./setup_usb.sh

# Or manual mounting
sudo mount -o uid=$(id -u),gid=$(id -g) /dev/sda1 /media/usb0

# Or fix existing mount
sudo chown -R $USER /media/usb0
```

**Security:**
- No need to run wedding phone as root
- User-owned USB mount points
- Proper permission checking
- Clear error messages

**Web Interface:**
- Shows helpful permission error messages
- Includes fix command in error text
- Better UX for permission issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-24 17:04:21 +07:00
parent d0bbaf6d4e
commit 42041006b7
3 changed files with 215 additions and 9 deletions

View File

@@ -325,18 +325,70 @@ Automatically backup all recordings and greeting files to USB drives:
6. Corrupted copies deleted automatically
7. Success/failure logged to console
**Mount USB Drives:**
**Mount USB Drives with Proper Permissions:**
**Automated Setup (Easiest):**
```bash
# Run the USB setup script
sudo ./setup_usb.sh
```
This interactive script will:
- Detect your USB devices
- Mount them with proper user permissions
- Test write access
- Optionally add to /etc/fstab for auto-mounting
**Option 1: Mount with user permissions (Recommended)**
```bash
# Find your USB device
lsblk
# Create mount point
sudo mkdir -p /media/usb0
# Mount with user ownership (replace $USER with your username if needed)
sudo mount -o uid=$(id -u),gid=$(id -g) /dev/sda1 /media/usb0
# Verify it's writable
touch /media/usb0/test.txt && rm /media/usb0/test.txt
```
**Option 2: Auto-mount in /etc/fstab with user permissions**
```bash
# Get USB UUID
sudo blkid /dev/sda1
# Edit fstab
sudo nano /etc/fstab
# Add line (replace UUID and username):
UUID=XXXX-XXXX /media/usb0 vfat defaults,nofail,uid=1000,gid=1000 0 0
# Note: uid=1000 is usually the first user, check with: id -u
```
**Option 3: Change ownership after mounting**
```bash
# Mount normally
sudo mount /dev/sda1 /media/usb0
# Change ownership (replace with your username)
sudo chown -R $USER:$USER /media/usb0
```
**Quick Setup Script:**
```bash
#!/bin/bash
# setup_usb.sh - Mount USB drives with proper permissions
# Create mount points
sudo mkdir -p /media/usb0 /media/usb1
# Auto-mount in /etc/fstab (example)
UUID=XXXX-XXXX /media/usb0 vfat defaults,nofail 0 0
UUID=YYYY-YYYY /media/usb1 vfat defaults,nofail 0 0
# Mount USB drives with user ownership
sudo mount -o uid=$(id -u),gid=$(id -g) /dev/sda1 /media/usb0
sudo mount -o uid=$(id -u),gid=$(id -g) /dev/sdb1 /media/usb1
# Or mount manually
sudo mount /dev/sda1 /media/usb0
sudo mount /dev/sdb1 /media/usb1
echo "USB drives mounted!"
ls -la /media/usb0 /media/usb1
```
## File Structure
@@ -347,6 +399,7 @@ wedding-phone/
├── test_complete.py # Audio testing script
├── configure_hifiberry.sh # HiFiBerry setup script
├── install_service.sh # Systemd service installer
├── setup_usb.sh # USB drive setup with permissions
├── wedding-phone.service # Systemd service file
├── Makefile # Make commands for easy running
├── config.example.json # Example configuration (copy to config.json)

View File

@@ -186,18 +186,30 @@ def get_usb_backup_status():
if drive_info["mounted"]:
try:
# Check if writable
test_file = os.path.join(usb_path, ".wedding_phone_test")
# Try to create backup directory first
backup_dir = os.path.join(usb_path, "wedding-phone-backup")
try:
os.makedirs(backup_dir, exist_ok=True)
test_location = backup_dir
except PermissionError:
# Can't create backup dir, try root
test_location = usb_path
# Check if writable in backup directory
test_file = os.path.join(test_location, ".wedding_phone_test")
with open(test_file, 'w') as f:
f.write("test")
os.remove(test_file)
drive_info["writable"] = True
drive_info["backup_dir"] = backup_dir if test_location == backup_dir else None
# Get free space
stat = os.statvfs(usb_path)
drive_info["free_space"] = stat.f_bavail * stat.f_frsize
drive_info["free_space_mb"] = drive_info["free_space"] / (1024 * 1024)
except PermissionError as e:
drive_info["error"] = f"Permission denied. Mount with proper permissions or run: sudo chown -R $USER {usb_path}"
except Exception as e:
drive_info["error"] = str(e)

141
setup_usb.sh Normal file
View File

@@ -0,0 +1,141 @@
#!/bin/bash
#
# USB Drive Setup Script
# Mounts USB drives with proper user permissions for wedding phone backups
#
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo "=========================================="
echo "USB Drive Setup for Wedding Phone"
echo "=========================================="
echo ""
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}This script needs sudo privileges${NC}"
echo "Please run with: sudo ./setup_usb.sh"
exit 1
fi
# Get the real user (not root when using sudo)
REAL_USER=${SUDO_USER:-$USER}
REAL_UID=$(id -u $REAL_USER)
REAL_GID=$(id -g $REAL_USER)
echo "Setting up USB mounts for user: $REAL_USER (UID:$REAL_UID, GID:$REAL_GID)"
echo ""
# Create mount points
echo "Creating mount points..."
mkdir -p /media/usb0 /media/usb1
echo -e "${GREEN}✓ Mount points created${NC}"
echo ""
# Detect USB devices
echo "Detecting USB devices..."
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,FSTYPE | grep -E "disk|part"
echo ""
# Function to mount a USB drive
mount_usb() {
local device=$1
local mount_point=$2
if [ ! -b "$device" ]; then
echo -e "${YELLOW}⚠ Device $device not found, skipping${NC}"
return
fi
# Unmount if already mounted
if mountpoint -q "$mount_point"; then
echo "Unmounting existing mount at $mount_point..."
umount "$mount_point" 2>/dev/null || true
fi
echo "Mounting $device to $mount_point..."
mount -o uid=$REAL_UID,gid=$REAL_GID "$device" "$mount_point"
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ Mounted $device${NC}"
# Test write permissions
if sudo -u $REAL_USER touch "$mount_point/.test" 2>/dev/null; then
sudo -u $REAL_USER rm "$mount_point/.test"
echo -e "${GREEN}✓ Write test successful${NC}"
else
echo -e "${RED}✗ Write test failed${NC}"
fi
# Show available space
df -h "$mount_point" | tail -n 1 | awk '{print " Free space: " $4}'
else
echo -e "${RED}✗ Failed to mount $device${NC}"
fi
echo ""
}
# Prompt for devices
echo "Enter device paths or press Enter to skip"
echo ""
read -p "USB 0 device (e.g., /dev/sda1) [Enter to skip]: " USB0_DEVICE
if [ ! -z "$USB0_DEVICE" ]; then
mount_usb "$USB0_DEVICE" "/media/usb0"
fi
read -p "USB 1 device (e.g., /dev/sdb1) [Enter to skip]: " USB1_DEVICE
if [ ! -z "$USB1_DEVICE" ]; then
mount_usb "$USB1_DEVICE" "/media/usb1"
fi
# Summary
echo "=========================================="
echo "Mount Summary"
echo "=========================================="
ls -la /media/usb0 /media/usb1 2>/dev/null | grep -E "^d|^total" || echo "No mounts found"
echo ""
# Offer to add to fstab
read -p "Add these mounts to /etc/fstab for automatic mounting? (y/n) " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo ""
echo "Add the following lines to /etc/fstab:"
echo ""
if [ ! -z "$USB0_DEVICE" ]; then
UUID0=$(blkid -s UUID -o value "$USB0_DEVICE")
if [ ! -z "$UUID0" ]; then
echo "UUID=$UUID0 /media/usb0 vfat defaults,nofail,uid=$REAL_UID,gid=$REAL_GID 0 0"
fi
fi
if [ ! -z "$USB1_DEVICE" ]; then
UUID1=$(blkid -s UUID -o value "$USB1_DEVICE")
if [ ! -z "$UUID1" ]; then
echo "UUID=$UUID1 /media/usb1 vfat defaults,nofail,uid=$REAL_UID,gid=$REAL_GID 0 0"
fi
fi
echo ""
echo "To add automatically, run:"
echo " sudo nano /etc/fstab"
fi
echo ""
echo "=========================================="
echo "Setup Complete!"
echo "=========================================="
echo ""
echo "USB drives are now accessible by user: $REAL_USER"
echo "Wedding Phone can now backup to these drives"
echo ""