Clean up: remove stale scripts/docs, fix debug prints, update PLAN.md
Deploy Dashboard / deploy (push) Successful in 37s
Deploy Dashboard / deploy (push) Successful in 37s
This commit is contained in:
@@ -45,19 +45,25 @@ Existing VPS (158.101.140.85): xray VLESS+REALITY on :443 — untouched
|
||||
|
||||
```
|
||||
nas-tools/
|
||||
PLAN.md
|
||||
backup.sh # Daily backup cron script
|
||||
notify.sh # Telegram notification utility
|
||||
dashboard/
|
||||
docker-compose.yml # Dashboard + docker-socket-proxy
|
||||
docker-compose.yml
|
||||
Dockerfile
|
||||
.env.example
|
||||
backend/
|
||||
main.py
|
||||
config.py
|
||||
auth.py
|
||||
requirements.txt
|
||||
routers/
|
||||
auth.py
|
||||
docker.py
|
||||
gitea.py
|
||||
files.py
|
||||
terminal.py
|
||||
system.py
|
||||
frontend/
|
||||
package.json
|
||||
vite.config.js
|
||||
@@ -83,9 +89,6 @@ nas-tools/
|
||||
docker-compose.yml
|
||||
openclaw/
|
||||
docker-compose.yml
|
||||
|
||||
cloud-monitor/
|
||||
oci-amd-monitor.py # New: grab AMD free-tier instance
|
||||
```
|
||||
|
||||
## Implementation Phases
|
||||
@@ -154,21 +157,21 @@ cloud-monitor/
|
||||
35. ~~Telegram failure alerts~~ — Done (sources creds from nas-dashboard .env)
|
||||
36. Periodic restore test to verify backups work
|
||||
|
||||
### Phase 10 — Monitoring & Alerts (partial)
|
||||
### Phase 10 — Monitoring & Alerts ✅
|
||||
36. ~~Add system stats to dashboard overview: CPU, RAM, disk usage~~ — Done
|
||||
37. ~~Container health checks in docker-compose files~~ — Done
|
||||
38. Notification on failure (Telegram bot or email)
|
||||
38. ~~Notification on failure (Telegram bot)~~ — Done (container monitor + failed login alerts)
|
||||
|
||||
### Phase 11 — Polish (partial)
|
||||
### Phase 11 — Polish ✅
|
||||
39. ~~Light/dark theme toggle~~ — Done
|
||||
40. ~~Add Jellyfin link to dashboard sidebar (port 8096)~~ — Done (replaced Emby)
|
||||
|
||||
### Phase 12 — Additional Services
|
||||
41. Deploy Audiobookshelf on port 13378 — Done, add to dashboard sidebar
|
||||
42. Deploy Stirling PDF on port 8030 — Done, add to dashboard sidebar
|
||||
43. Deploy Vaultwarden on port 8222 — Done, add to dashboard sidebar
|
||||
44. Deploy Watchtower for auto-updates — Done (internal, no sidebar link needed)
|
||||
45. Deploy Speedtest on port 8080 — Done, already in dashboard sidebar
|
||||
### Phase 12 — Additional Services ✅
|
||||
41. ~~Deploy Audiobookshelf on port 13378~~ — Done, in dashboard sidebar
|
||||
42. ~~Deploy Stirling PDF on port 8030~~ — Done, in dashboard sidebar
|
||||
43. ~~Deploy Vaultwarden on port 8222~~ — Done, in dashboard sidebar
|
||||
44. ~~Deploy Watchtower for auto-updates~~ — Done (internal, no sidebar link needed)
|
||||
45. ~~Deploy Speedtest on port 8080~~ — Done, in dashboard sidebar
|
||||
|
||||
### Phase 13 — Off-site Backup
|
||||
46. Add cloud backup (OneDrive or Google Drive) for critical data
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Aggressive Free System Data (351GB)
|
||||
# When normal methods don't work
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Aggressive Free System Data (351GB) ==="
|
||||
echo ""
|
||||
echo "Since normal methods didn't work, we need to be more aggressive."
|
||||
echo ""
|
||||
|
||||
FREE_SPACE_BEFORE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_BEFORE=$(echo "scale=2; $FREE_SPACE_BEFORE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB_BEFORE}GB"
|
||||
echo ""
|
||||
|
||||
echo "🔍 Checking Time Machine configuration..."
|
||||
TM_DEST=$(defaults read /Library/Preferences/com.apple.TimeMachine LastDestinationID 2>/dev/null || echo "NONE")
|
||||
if [ "$TM_DEST" != "NONE" ]; then
|
||||
echo " ⚠️ Time Machine destination still configured: $TM_DEST"
|
||||
echo " This means snapshots may still be created!"
|
||||
echo ""
|
||||
echo " You MUST remove it in System Settings:"
|
||||
echo " System Settings → Time Machine → Remove backup disk"
|
||||
echo ""
|
||||
read -p " Have you removed it? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo " ⚠️ Please remove it first!"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo " ✅ Time Machine destination removed"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "🔧 Method 1: Force delete all local snapshots..."
|
||||
SNAPSHOTS=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$")
|
||||
if [ -n "$SNAPSHOTS" ]; then
|
||||
echo "$SNAPSHOTS" | while read snapshot; do
|
||||
if [ -n "$snapshot" ]; then
|
||||
SNAP_DATE=$(echo "$snapshot" | sed 's/.*\.\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}\)\.backup/\1/')
|
||||
if [ -n "$SNAP_DATE" ]; then
|
||||
echo " Deleting: $snapshot"
|
||||
sudo tmutil deletelocalsnapshots "$SNAP_DATE" 2>&1 || echo " ⚠️ Failed (ghost entry)"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo " No snapshots found"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "🔧 Method 2: Aggressive thinning (keep only 1GB, 1 day)..."
|
||||
sudo tmutil thinlocalsnapshots / 1000000000 1 2>&1
|
||||
echo " ✓ Completed"
|
||||
echo ""
|
||||
|
||||
echo "🔧 Method 3: Disable Time Machine completely..."
|
||||
sudo tmutil disable 2>/dev/null || echo " ⚠️ Could not disable (may already be disabled)"
|
||||
echo ""
|
||||
|
||||
echo "🔧 Method 4: Clear Time Machine database..."
|
||||
echo " ⚠️ This will clear Time Machine's local database"
|
||||
read -p " Proceed? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
# Backup first
|
||||
sudo cp -r /Library/Preferences/com.apple.TimeMachine.plist /Library/Preferences/com.apple.TimeMachine.plist.backup 2>/dev/null || true
|
||||
echo " Backed up preferences"
|
||||
|
||||
# Clear local snapshots database
|
||||
sudo rm -rf /System/Volumes/Data/.timemachine/* 2>/dev/null || true
|
||||
echo " ✓ Cleared Time Machine local data"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "🔧 Method 5: Force filesystem sync and purge..."
|
||||
sync
|
||||
if command -v purge &> /dev/null; then
|
||||
sudo purge
|
||||
echo " ✓ Purged"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "🔧 Method 6: Use macOS storage optimization..."
|
||||
echo ""
|
||||
echo " ⚠️ CRITICAL: You need to use macOS's built-in tool:"
|
||||
echo ""
|
||||
echo " 1. Apple Menu → About This Mac → Storage"
|
||||
echo " 2. Click 'Manage...'"
|
||||
echo " 3. Look for 'Optimize Storage' or similar option"
|
||||
echo " 4. This will release purgeable space"
|
||||
echo ""
|
||||
echo " OR use Terminal:"
|
||||
echo " sudo tmutil thinlocalsnapshots / 1000000000 1"
|
||||
echo " sudo purge"
|
||||
echo ""
|
||||
|
||||
echo "⏳ Waiting for system to update..."
|
||||
sleep 15
|
||||
|
||||
# Check results
|
||||
FREE_SPACE_AFTER=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_AFTER=$(echo "scale=2; $FREE_SPACE_AFTER / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $FREE_SPACE_GB_AFTER - $FREE_SPACE_GB_BEFORE" | bc)
|
||||
|
||||
echo ""
|
||||
echo "=== Results ==="
|
||||
echo " Before: ${FREE_SPACE_GB_BEFORE}GB free"
|
||||
echo " After: ${FREE_SPACE_GB_AFTER}GB free"
|
||||
if (( $(echo "$FREED_GB > 100" | bc -l) )); then
|
||||
echo " ✅ Successfully freed: ${FREED_GB}GB!"
|
||||
elif (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo " ✅ Freed: ${FREED_GB}GB"
|
||||
else
|
||||
echo " ⚠️ No space freed yet"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=== If Still No Change ==="
|
||||
echo ""
|
||||
echo "The 351GB in System Data is likely:"
|
||||
echo " 1. Purgeable space that macOS won't release until needed"
|
||||
echo " 2. APFS snapshot overhead (the OS update snapshot)"
|
||||
echo " 3. Reserved space for system operations"
|
||||
echo ""
|
||||
echo "Try these:"
|
||||
echo ""
|
||||
echo "1. **Create a large file to force purge**:"
|
||||
echo " This forces macOS to release purgeable space:"
|
||||
echo " dd if=/dev/zero of=~/test_large_file bs=1g count=50"
|
||||
echo " (This creates a 50GB file, forcing purge)"
|
||||
echo " Then delete it: rm ~/test_large_file"
|
||||
echo ""
|
||||
echo "2. **Use Activity Monitor**:"
|
||||
echo " Open Activity Monitor → Disk tab"
|
||||
echo " Look for 'Purgeable' space"
|
||||
echo ""
|
||||
echo "3. **Check Storage Management again**:"
|
||||
echo " The System Data may show as 'Purgeable'"
|
||||
echo " macOS will release it when space is actually needed"
|
||||
echo ""
|
||||
echo "4. **The space may already be available**:"
|
||||
echo " Even though System Data shows 351GB, the space"
|
||||
echo " may be purgeable and available when needed"
|
||||
echo ""
|
||||
@@ -1,70 +0,0 @@
|
||||
# Apple Support Issue Summary
|
||||
|
||||
## Problem Description
|
||||
|
||||
**Main Issue:** Cannot free disk space to install macOS update due to OS update snapshot preserving all deleted/moved files.
|
||||
|
||||
## Symptoms
|
||||
|
||||
1. **System Data is 351GB** (should be ~20-30GB)
|
||||
2. **Disk is 99.8% full** (only 800MB free out of 494GB)
|
||||
3. **macOS update requires 17.64GB** but cannot free space
|
||||
4. **Every file deletion/move makes System Data grow** instead of freeing space
|
||||
|
||||
## Root Cause
|
||||
|
||||
**OS Update Snapshot is blocking space recovery:**
|
||||
- Snapshot name: `com.apple.os.update-C6AB179000F92C4C211177BC5C840A511D1AA2A227C324AA9C14FC599E9873`
|
||||
- Status: **NOT purgeable**
|
||||
- Note: "This snapshot limits the minimum size of APFS Container"
|
||||
- The snapshot preserves ALL deleted/moved files, preventing space recovery
|
||||
|
||||
## What I've Tried (All Failed)
|
||||
|
||||
1. ✅ Moved files to NAS (Synology DS224plus) - Files moved but space not freed
|
||||
2. ✅ Moved files to external drive - Files moved but space not freed
|
||||
3. ✅ Cleaned caches (`~/Library/Caches`, `~/.cache`, npm cache) - No effect
|
||||
4. ✅ Deleted local Time Machine snapshots - Ghost entry, can't delete
|
||||
5. ✅ Attempted `tmutil deletelocalsnapshots` - Error: "Stale NFS file handle"
|
||||
6. ✅ Attempted `tmutil thinlocalsnapshots` - No effect
|
||||
7. ✅ Restarted Mac multiple times - No effect
|
||||
8. ✅ Tried `softwareupdate --download --all` - Failed: "Not enough free disk space: 17.64 GB required"
|
||||
|
||||
## Current System Status
|
||||
|
||||
- **macOS Version:** macOS Tahoe (need to update to 26.2)
|
||||
- **Disk:** 494.4GB APFS container, 99.8% full
|
||||
- **Free Space:** 800MB (need 17.64GB for update)
|
||||
- **System Data:** 351GB (should be ~20-30GB)
|
||||
- **Snapshot:** OS update snapshot, NOT purgeable, cannot be deleted manually
|
||||
|
||||
## The Catch-22
|
||||
|
||||
- **Need:** 17.64GB free space to install macOS update
|
||||
- **Problem:** Cannot free space because OS update snapshot preserves all deleted/moved files
|
||||
- **Result:** Stuck - cannot update, cannot free space
|
||||
|
||||
## What I Need from Apple Support
|
||||
|
||||
1. **Tool to force-clear the OS update snapshot** (it's blocking space recovery)
|
||||
2. **Alternative method to install macOS update** with limited space
|
||||
3. **Recovery options** to break out of this catch-22 situation
|
||||
4. **System-level intervention** to release the 351GB in System Data
|
||||
|
||||
## Technical Details
|
||||
|
||||
- **Snapshot UUID:** F63E39F3-D495-4586-88A4-A1406A7EF46A
|
||||
- **Snapshot XID:** 6557111
|
||||
- **Container:** disk3 (494.4GB)
|
||||
- **Volume:** Macintosh HD (disk3s3)
|
||||
- **Snapshot Disk:** disk3s3s1
|
||||
|
||||
## Files Are Safe
|
||||
|
||||
- Files have been moved to NAS and external drive
|
||||
- Data is safe, but space cannot be recovered until snapshot is cleared
|
||||
- The issue is purely about freeing space, not data loss
|
||||
|
||||
---
|
||||
|
||||
**Request:** Please provide system-level tools or recovery methods to clear the OS update snapshot so I can free space and install the macOS update.
|
||||
@@ -1,53 +0,0 @@
|
||||
# Cellular Data Proxy Solution
|
||||
|
||||
## The Problem
|
||||
- ✅ Wi-Fi proxy works (configured in Wi-Fi settings)
|
||||
- ❌ Cellular data proxy doesn't work (iOS doesn't allow HTTP proxy for cellular)
|
||||
- ❌ Can't disable Tailscale VPN (proxy only listens on Tailscale IP: 100.70.115.1)
|
||||
|
||||
## Solution Options
|
||||
|
||||
### Solution 1: Use Shadowrocket VPN Mode (Recommended)
|
||||
|
||||
Shadowrocket's VPN mode works on **both Wi-Fi and cellular**, and can route through Tailscale's network.
|
||||
|
||||
**Setup:**
|
||||
1. **Keep Tailscale VPN ON** (needed to reach 100.70.115.1)
|
||||
2. In Shadowrocket:
|
||||
- Go to **Home** tab
|
||||
- Add server: `100.70.115.1:7890` (HTTP)
|
||||
- Enable Shadowrocket VPN mode
|
||||
3. Shadowrocket will:
|
||||
- Intercept all traffic (Wi-Fi + cellular)
|
||||
- Route through Tailscale network to reach proxy
|
||||
- Forward to server2's proxy
|
||||
|
||||
**Wait - iOS only allows one VPN!** This won't work...
|
||||
|
||||
### Solution 2: Make Clash Listen on Public IP (Less Secure)
|
||||
|
||||
Configure Clash to also listen on the public IP, then use Shadowrocket VPN mode.
|
||||
|
||||
**Pros:** Works on cellular, Shadowrocket can use it
|
||||
**Cons:** Less secure (exposed to public internet, but firewall should protect)
|
||||
|
||||
### Solution 3: Use Tailscale's Built-in Proxy Feature
|
||||
|
||||
Tailscale has a built-in proxy feature that might work better.
|
||||
|
||||
### Solution 4: Use Shadowrocket with Tailscale Subnet Router
|
||||
|
||||
Configure server2 as a Tailscale subnet router, then use Shadowrocket.
|
||||
|
||||
## Recommended: Solution 2 (Make Clash Listen on Public IP with Firewall)
|
||||
|
||||
Since you need cellular access, let's make Clash accessible via public IP but keep it secure with firewall rules.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check Real Disk Space - Verify what's actually using space
|
||||
# Sometimes the snapshot is a ghost but space is actually available
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Real Disk Space Analysis ==="
|
||||
echo ""
|
||||
|
||||
# Multiple methods to check space
|
||||
echo "Method 1: df command:"
|
||||
df -h / | tail -1
|
||||
echo ""
|
||||
|
||||
echo "Method 2: diskutil info:"
|
||||
diskutil info / | grep -E "Volume (Free|Used|Total) Space" | sed 's/^/ /'
|
||||
echo ""
|
||||
|
||||
# Check if snapshot actually exists
|
||||
echo "Method 3: APFS Snapshot Check:"
|
||||
APFS_TM_SNAPS=$(diskutil apfs listSnapshots / 2>/dev/null | grep -i "timemachine" || echo "None")
|
||||
if [ "$APFS_TM_SNAPS" = "None" ]; then
|
||||
echo " ✅ No Time Machine snapshot in APFS (ghost entry only)"
|
||||
else
|
||||
echo " ⚠️ Found: $APFS_TM_SNAPS"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check Time Machine status
|
||||
echo "Method 4: Time Machine Status:"
|
||||
TM_RUNNING=$(tmutil status 2>/dev/null | grep "Running" | awk '{print $3}' | tr -d ';')
|
||||
if [ "$TM_RUNNING" = "1" ]; then
|
||||
echo " ⚠️ Time Machine is running (may be creating new snapshots)"
|
||||
else
|
||||
echo " ✅ Time Machine is not running"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Calculate actual space
|
||||
FREE_KB=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_GB=$(echo "scale=2; $FREE_KB / 1024 / 1024" | bc)
|
||||
|
||||
echo "=== Summary ==="
|
||||
echo " Current free space: ${FREE_GB}GB"
|
||||
echo ""
|
||||
|
||||
if (( $(echo "$FREE_GB < 5" | bc -l) )); then
|
||||
echo "⚠️ Still low on space. The ghost snapshot entry is not the issue."
|
||||
echo ""
|
||||
echo "The real issue: Your disk is actually full (or nearly full)."
|
||||
echo ""
|
||||
echo "The 20GB from deleted files may have been:"
|
||||
echo " 1. Used by Time Machine creating a new snapshot"
|
||||
echo " 2. Used by other processes/files"
|
||||
echo " 3. Actually freed but macOS hasn't updated the count yet"
|
||||
echo ""
|
||||
echo "Solutions:"
|
||||
echo ""
|
||||
echo "1. **Restart your Mac** - This will:"
|
||||
echo " - Release any held snapshots"
|
||||
echo " - Update disk space accounting"
|
||||
echo " - Clear stuck processes"
|
||||
echo ""
|
||||
echo "2. Check what's really using space:"
|
||||
echo " du -h -d 1 ~ | sort -hr | head -20"
|
||||
echo ""
|
||||
echo "3. Clean up large files:"
|
||||
echo " - Downloads folder: $(du -sh ~/Downloads 2>/dev/null | awk '{print $1}')"
|
||||
echo " - Library/Caches: $(du -sh ~/Library/Caches 2>/dev/null | awk '{print $1}')"
|
||||
echo ""
|
||||
echo "4. The ghost snapshot entry is harmless - ignore it."
|
||||
echo " It will clear when Time Machine successfully backs up."
|
||||
else
|
||||
echo "✅ You have ${FREE_GB}GB free - this should be enough!"
|
||||
echo ""
|
||||
echo "The ghost snapshot entry can be ignored - it's not using space."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,115 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check Snapshot Size
|
||||
# Determine how much space the snapshot is actually using
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Check Snapshot Size ==="
|
||||
echo ""
|
||||
|
||||
# Current disk space
|
||||
FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB=$(echo "scale=2; $FREE_SPACE / 1024 / 1024" | bc)
|
||||
USED_SPACE=$(df / | tail -1 | awk '{print $3}')
|
||||
USED_SPACE_GB=$(echo "scale=2; $USED_SPACE / 1024 / 1024" | bc)
|
||||
|
||||
echo "📊 Current Disk Status:"
|
||||
echo " Used: ${USED_SPACE_GB}GB"
|
||||
echo " Free: ${FREE_SPACE_GB}GB"
|
||||
echo ""
|
||||
|
||||
# Check if snapshot exists in APFS
|
||||
echo "🔍 Checking if snapshot exists in APFS..."
|
||||
APFS_CHECK=$(diskutil apfs listSnapshots / 2>/dev/null | grep -i "timemachine" || echo "NOT_FOUND")
|
||||
if [ "$APFS_CHECK" = "NOT_FOUND" ]; then
|
||||
echo " ❌ Snapshot NOT found in APFS"
|
||||
echo " This means it's a GHOST ENTRY - not taking any space!"
|
||||
echo ""
|
||||
echo " The snapshot entry you see is just a stale database record."
|
||||
echo " It's not actually consuming disk space."
|
||||
echo ""
|
||||
echo " ✅ Your space is already available!"
|
||||
echo " The ghost entry will clear on restart."
|
||||
else
|
||||
echo " ✅ Snapshot found in APFS"
|
||||
echo " $APFS_CHECK"
|
||||
echo ""
|
||||
echo " This snapshot IS taking up space."
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Try to get snapshot size
|
||||
SNAPSHOT=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$" | head -1)
|
||||
if [ -n "$SNAPSHOT" ]; then
|
||||
echo "📸 Snapshot Details:"
|
||||
echo " Name: $SNAPSHOT"
|
||||
echo ""
|
||||
|
||||
echo " Attempting to calculate snapshot size..."
|
||||
SNAP_DATE=$(echo "$SNAPSHOT" | sed 's/.*\.\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}\)\.backup/\1/')
|
||||
|
||||
# Try calculatedrift
|
||||
DRIFT_OUTPUT=$(sudo tmutil calculatedrift "$SNAPSHOT" 2>&1 || echo "ERROR")
|
||||
if echo "$DRIFT_OUTPUT" | grep -qi "size\|bytes\|GB\|MB"; then
|
||||
echo " Size information:"
|
||||
echo "$DRIFT_OUTPUT" | grep -i "size\|bytes\|GB\|MB" | head -5 | sed 's/^/ /'
|
||||
else
|
||||
echo " ⚠️ Could not calculate size (snapshot may be corrupted/stuck)"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Container vs Volume analysis
|
||||
echo "📦 Container Analysis:"
|
||||
CONTAINER_TOTAL=$(diskutil info / | grep 'Container Total' | awk '{print $4, $5}')
|
||||
CONTAINER_FREE=$(diskutil info / | grep 'Container Free' | awk '{print $4, $5}')
|
||||
VOLUME_USED=$(diskutil info / | grep 'Volume Used Space' | awk '{print $4, $5, $6}')
|
||||
|
||||
echo " Container Total: $CONTAINER_TOTAL"
|
||||
echo " Container Free: $CONTAINER_FREE"
|
||||
echo " Volume Used: $VOLUME_USED"
|
||||
echo ""
|
||||
|
||||
# Calculate if there's unaccounted space
|
||||
CONTAINER_TOTAL_GB=$(diskutil info / | grep 'Container Total' | awk '{print $3}' | tr -d 'GB')
|
||||
CONTAINER_FREE_GB=$(diskutil info / | grep 'Container Free' | awk '{print $3}' | tr -d 'GB')
|
||||
VOLUME_USED_GB=$(diskutil info / | grep 'Volume Used Space' | awk '{print $4}' | tr -d 'GB')
|
||||
|
||||
CONTAINER_USED_GB=$(echo "$CONTAINER_TOTAL_GB - $CONTAINER_FREE_GB" | bc)
|
||||
DISCREPANCY=$(echo "$CONTAINER_USED_GB - $VOLUME_USED_GB" | bc)
|
||||
|
||||
echo " Container Used: ~${CONTAINER_USED_GB}GB"
|
||||
echo " Volume Used: ~${VOLUME_USED_GB}GB"
|
||||
if (( $(echo "$DISCREPANCY > 1" | bc -l) )); then
|
||||
echo " ⚠️ Unaccounted: ~${DISCREPANCY}GB"
|
||||
echo " This could be:"
|
||||
echo " - APFS snapshots"
|
||||
echo " - Other volumes"
|
||||
echo " - Reserved space"
|
||||
else
|
||||
echo " ✅ Space accounting looks normal"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Summary
|
||||
echo "=== Summary ==="
|
||||
echo ""
|
||||
if [ "$APFS_CHECK" = "NOT_FOUND" ]; then
|
||||
echo "✅ The snapshot is a GHOST ENTRY - it's NOT taking any space!"
|
||||
echo ""
|
||||
echo " Your disk space is already available."
|
||||
echo " The entry will clear on restart."
|
||||
echo ""
|
||||
echo " If 'System Data' is still growing when you delete files,"
|
||||
echo " it's because Time Machine is creating NEW snapshots,"
|
||||
echo " not because of this old ghost entry."
|
||||
else
|
||||
echo "⚠️ The snapshot IS in APFS and may be taking space."
|
||||
echo ""
|
||||
echo " To free the space, you need to:"
|
||||
echo " 1. Remove Time Machine destination"
|
||||
echo " 2. Restart your Mac"
|
||||
echo " 3. The snapshot should be cleared"
|
||||
fi
|
||||
echo ""
|
||||
@@ -1,64 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check Space After Unmounting Photo Volume
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Space Check After Unmounting Photo Volume ==="
|
||||
echo ""
|
||||
|
||||
FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB=$(echo "scale=2; $FREE_SPACE / 1024 / 1024" | bc)
|
||||
CONTAINER_FREE=$(diskutil info / | grep 'Container Free' | awk '{print $4, $5}')
|
||||
CONTAINER_USED=$(diskutil apfs list 2>/dev/null | grep "Capacity In Use" | awk '{print $6, $7}')
|
||||
|
||||
echo "📊 Current Status:"
|
||||
echo " Free space: ${FREE_SPACE_GB}GB"
|
||||
echo " Container free: $CONTAINER_FREE"
|
||||
echo " Container used: $CONTAINER_USED"
|
||||
echo ""
|
||||
|
||||
# Check if photo is still mounted
|
||||
if mount | grep -q photo; then
|
||||
echo "⚠️ Photo volume is still mounted"
|
||||
else
|
||||
echo "✅ Photo volume is unmounted"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "🔍 What's Actually Using Space:"
|
||||
echo ""
|
||||
echo "Top directories in /System/Volumes/Data:"
|
||||
sudo du -h -d 1 /System/Volumes/Data 2>/dev/null | sort -hr | head -10 | awk '{printf " %8s %s\n", $1, $2}'
|
||||
echo ""
|
||||
|
||||
echo "Your home directory:"
|
||||
du -h -d 1 ~ 2>/dev/null | sort -hr | head -10 | awk '{printf " %8s %s\n", $1, $2}'
|
||||
echo ""
|
||||
|
||||
echo "=== Analysis ==="
|
||||
echo ""
|
||||
if (( $(echo "$FREE_SPACE_GB < 5" | bc -l) )); then
|
||||
echo "⚠️ Still critically low on space!"
|
||||
echo ""
|
||||
echo " The photo volume unmount didn't free space because:"
|
||||
echo " - Those files were on the NAS (network), not local"
|
||||
echo " - The 179GB was just the size of the network mount"
|
||||
echo " - It wasn't actually consuming local disk space"
|
||||
echo ""
|
||||
echo " Your REAL space usage:"
|
||||
echo " - Container: 492.9GB used (99.7% full)"
|
||||
echo " - Your home: 130GB"
|
||||
echo " - Other system files: ~360GB"
|
||||
echo ""
|
||||
echo " To free space, you need to:"
|
||||
echo " 1. Clean Downloads: 8.7GB"
|
||||
echo " 2. Clean Library/Caches: ~6GB"
|
||||
echo " 3. Review Documents: 40GB (move large files to NAS)"
|
||||
echo " 4. Review .ollama: 17GB (remove unused models)"
|
||||
echo ""
|
||||
else
|
||||
echo "✅ You have ${FREE_SPACE_GB}GB free - this should be enough!"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,139 +0,0 @@
|
||||
# Clash Proxy Server Configuration
|
||||
|
||||
## Server Details
|
||||
- **Server:** server2 (oracle-tokyo)
|
||||
- **Tailscale IP:** 100.70.115.1
|
||||
- **Status:** ✅ Running
|
||||
|
||||
## Proxy Endpoints
|
||||
|
||||
### HTTP Proxy
|
||||
- **Type:** HTTP
|
||||
- **Server:** 100.70.115.1
|
||||
- **Port:** 7890
|
||||
|
||||
### SOCKS5 Proxy
|
||||
- **Type:** SOCKS5
|
||||
- **Server:** 100.70.115.1
|
||||
- **Port:** 7891
|
||||
|
||||
### Mixed Port (Recommended)
|
||||
- **Type:** HTTP/SOCKS5 (auto-detected)
|
||||
- **Server:** 100.70.115.1
|
||||
- **Port:** 7892
|
||||
|
||||
### Web Dashboard
|
||||
- **URL:** http://100.70.115.1:9090/ui
|
||||
- Use this to monitor traffic and manage settings
|
||||
|
||||
## Client Configuration
|
||||
|
||||
### For Clash Clients (Clash for Windows, ClashX, Clash Verge, etc.)
|
||||
|
||||
#### Option 1: Direct Proxy Configuration
|
||||
In your Clash client settings, add a proxy:
|
||||
|
||||
```yaml
|
||||
proxies:
|
||||
- name: "server2-proxy"
|
||||
type: http
|
||||
server: 100.70.115.1
|
||||
port: 7890
|
||||
# Or use mixed port:
|
||||
# port: 7892
|
||||
```
|
||||
|
||||
#### Option 2: Use as Upstream Proxy
|
||||
If you want to route through server2:
|
||||
|
||||
```yaml
|
||||
proxies:
|
||||
- name: "server2"
|
||||
type: http
|
||||
server: 100.70.115.1
|
||||
port: 7892
|
||||
```
|
||||
|
||||
Then add it to your proxy groups:
|
||||
```yaml
|
||||
proxy-groups:
|
||||
- name: "Proxy"
|
||||
type: select
|
||||
proxies:
|
||||
- server2
|
||||
- DIRECT
|
||||
```
|
||||
|
||||
### For System-Wide Proxy (macOS/Windows)
|
||||
|
||||
#### macOS:
|
||||
1. System Settings → Network → Advanced → Proxies
|
||||
2. Check "Web Proxy (HTTP)" and "Secure Web Proxy (HTTPS)"
|
||||
3. Server: 100.70.115.1
|
||||
4. Port: 7890 (or 7892 for mixed)
|
||||
|
||||
#### Windows:
|
||||
1. Settings → Network & Internet → Proxy
|
||||
2. Manual proxy setup
|
||||
3. Address: 100.70.115.1
|
||||
4. Port: 7890
|
||||
|
||||
### For Mobile Apps (iOS/Android)
|
||||
|
||||
Most apps support HTTP/SOCKS5 proxy:
|
||||
- **Type:** HTTP or SOCKS5
|
||||
- **Host:** 100.70.115.1
|
||||
- **Port:** 7890 (HTTP) or 7891 (SOCKS5) or 7892 (Mixed)
|
||||
|
||||
## Testing the Connection
|
||||
|
||||
### Test HTTP Proxy:
|
||||
```bash
|
||||
curl -x http://100.70.115.1:7890 https://api.ipify.org
|
||||
```
|
||||
|
||||
### Test SOCKS5 Proxy:
|
||||
```bash
|
||||
curl --socks5 100.70.115.1:7891 https://api.ipify.org
|
||||
```
|
||||
|
||||
### Check if proxy is working:
|
||||
Visit http://100.70.115.1:9090/ui in your browser to see the Clash dashboard.
|
||||
|
||||
## Management Commands
|
||||
|
||||
### Check Status:
|
||||
```bash
|
||||
ssh server2 'sudo systemctl status clash-meta'
|
||||
```
|
||||
|
||||
### View Logs:
|
||||
```bash
|
||||
ssh server2 'sudo journalctl -u clash-meta -f'
|
||||
```
|
||||
|
||||
### Restart Service:
|
||||
```bash
|
||||
ssh server2 'sudo systemctl restart clash-meta'
|
||||
```
|
||||
|
||||
### Stop Service:
|
||||
```bash
|
||||
ssh server2 'sudo systemctl stop clash-meta'
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- All traffic routed through server2 will use server2's internet connection
|
||||
- The proxy is accessible only via Tailscale network (secure)
|
||||
- No authentication required (protected by Tailscale)
|
||||
- The proxy uses "direct" mode - all traffic goes directly through server2's connection
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
FROM node:20-slim
|
||||
RUN apt-get update && apt-get install -y git openssh-client tmux && rm -rf /var/lib/apt/lists/*
|
||||
RUN npm install -g @anthropic-ai/claude-code
|
||||
WORKDIR /workspace
|
||||
ENTRYPOINT ["tmux", "new-session", "-A", "-s", "main"]
|
||||
@@ -1,20 +0,0 @@
|
||||
services:
|
||||
claude-dev:
|
||||
build: .
|
||||
image: claude-dev:latest
|
||||
container_name: claude-dev
|
||||
restart: unless-stopped
|
||||
stdin_open: true
|
||||
tty: true
|
||||
environment:
|
||||
- ANTHROPIC_BASE_URL=${ANTHROPIC_BASE_URL}
|
||||
- ANTHROPIC_AUTH_TOKEN=${ANTHROPIC_AUTH_TOKEN}
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_AUTH_TOKEN}
|
||||
volumes:
|
||||
- /volume1/docker/claude-dev/workspace:/workspace
|
||||
- /volume1/docker/claude-dev/claude-config:/root/.claude
|
||||
logging:
|
||||
driver: json-file
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
@@ -1,142 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Clean Time Machine System Files
|
||||
# This script safely removes Time Machine files from system locations
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Time Machine System Files Cleanup ==="
|
||||
echo ""
|
||||
echo "⚠️ WARNING: This script will delete Time Machine system files."
|
||||
echo " Make sure you understand what will be deleted."
|
||||
echo ""
|
||||
|
||||
# Check current free space
|
||||
FREE_SPACE_BEFORE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_BEFORE=$(echo "scale=2; $FREE_SPACE_BEFORE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB_BEFORE}GB"
|
||||
echo ""
|
||||
|
||||
# Ask for confirmation
|
||||
read -p "Do you want to proceed? This will delete Time Machine system files. (yes/no) " -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy][Ee][Ss]$ ]]; then
|
||||
echo "Cancelled."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🧹 Cleaning Time Machine system files..."
|
||||
echo ""
|
||||
|
||||
FREED_TOTAL=0
|
||||
|
||||
# 1. Delete local snapshots
|
||||
echo "1. Deleting local snapshots..."
|
||||
SNAPSHOTS=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$")
|
||||
if [ -n "$SNAPSHOTS" ]; then
|
||||
echo "$SNAPSHOTS" | while read snapshot; do
|
||||
if [ -n "$snapshot" ]; then
|
||||
echo " Deleting snapshot: $snapshot"
|
||||
sudo tmutil deletelocalsnapshots "$snapshot" 2>/dev/null || {
|
||||
echo " ⚠️ Could not delete $snapshot (may require different method)"
|
||||
}
|
||||
fi
|
||||
done
|
||||
echo " ✓ Local snapshots deleted"
|
||||
else
|
||||
echo " ✓ No local snapshots to delete"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 2. Disable local snapshots temporarily (they'll recreate but this helps)
|
||||
echo "2. Disabling local snapshots (to prevent immediate recreation)..."
|
||||
sudo tmutil disablelocal 2>/dev/null || echo " ⚠️ Could not disable local snapshots"
|
||||
echo ""
|
||||
|
||||
# 3. Clean MobileBackups (if they exist and are safe to remove)
|
||||
echo "3. Checking MobileBackups..."
|
||||
if [ -d "/.MobileBackups" ] || [ -d "/System/Volumes/Data/.MobileBackups" ]; then
|
||||
echo " ⚠️ MobileBackups directory found."
|
||||
echo " These are APFS snapshots. They're usually managed automatically."
|
||||
echo " Deleting them manually can cause issues."
|
||||
echo " Recommendation: Let macOS manage these automatically."
|
||||
echo " They will be deleted when space is needed."
|
||||
read -p " Do you want to try deleting MobileBackups? (yes/no) " -r
|
||||
if [[ $REPLY =~ ^[Yy][Ee][Ss]$ ]]; then
|
||||
if [ -d "/.MobileBackups" ]; then
|
||||
echo " Attempting to delete /.MobileBackups..."
|
||||
sudo rm -rf /.MobileBackups/* 2>/dev/null || echo " ⚠️ Could not delete (may be in use)"
|
||||
fi
|
||||
if [ -d "/System/Volumes/Data/.MobileBackups" ]; then
|
||||
echo " Attempting to delete /System/Volumes/Data/.MobileBackups..."
|
||||
sudo rm -rf /System/Volumes/Data/.MobileBackups/* 2>/dev/null || echo " ⚠️ Could not delete (may be in use)"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo " ✓ No MobileBackups directory found"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 4. Find and remove orphaned sparse bundles
|
||||
echo "4. Searching for orphaned Time Machine sparse bundles..."
|
||||
find /private/var -name "*.sparsebundle" -o -name "*.sparseimage" 2>/dev/null | while read bundle; do
|
||||
if [ -e "$bundle" ]; then
|
||||
SIZE=$(sudo du -sh "$bundle" 2>/dev/null | awk '{print $1}')
|
||||
echo " Found: $bundle ($SIZE)"
|
||||
read -p " Delete this bundle? (yes/no) " -r
|
||||
if [[ $REPLY =~ ^[Yy][Ee][Ss]$ ]]; then
|
||||
sudo rm -rf "$bundle" 2>/dev/null && echo " ✓ Deleted" || echo " ⚠️ Could not delete"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
# 5. Clean Time Machine logs (safe, will regenerate)
|
||||
echo "5. Cleaning Time Machine logs..."
|
||||
sudo rm -rf /private/var/log/com.apple.TimeMachine* 2>/dev/null || true
|
||||
echo " ✓ Logs cleaned"
|
||||
echo ""
|
||||
|
||||
# 6. Re-enable local snapshots (they're useful, just need space first)
|
||||
echo "6. Re-enabling local snapshots..."
|
||||
sudo tmutil enablelocal 2>/dev/null || echo " ⚠️ Could not re-enable (may already be enabled)"
|
||||
echo ""
|
||||
|
||||
# Check new free space
|
||||
FREE_SPACE_AFTER=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_AFTER=$(echo "scale=2; $FREE_SPACE_AFTER / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $FREE_SPACE_GB_AFTER - $FREE_SPACE_GB_BEFORE" | bc)
|
||||
|
||||
echo ""
|
||||
echo "=== Results ==="
|
||||
echo " Before: ${FREE_SPACE_GB_BEFORE}GB free"
|
||||
echo " After: ${FREE_SPACE_GB_AFTER}GB free"
|
||||
if (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo " Freed: ${FREED_GB}GB"
|
||||
else
|
||||
echo " Freed: 0GB (files may be in use or protected)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
if (( $(echo "$FREE_SPACE_GB_AFTER < 10" | bc -l) )); then
|
||||
echo "⚠️ Still low on space. The 100GB+ may be in a protected location."
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Check macOS Storage Management:"
|
||||
echo " Apple Menu → About This Mac → Storage → Manage"
|
||||
echo " Look for 'System Files' and see what's taking space"
|
||||
echo ""
|
||||
echo "2. The files may be APFS snapshots that need special handling:"
|
||||
echo " sudo tmutil listlocalsnapshots /"
|
||||
echo " # Then delete each one:"
|
||||
echo " sudo tmutil deletelocalsnapshots <snapshot-name>"
|
||||
echo ""
|
||||
echo "3. Check for large files in system locations:"
|
||||
echo " sudo du -h -d 1 /System/Volumes/Data | sort -hr | head -20"
|
||||
echo ""
|
||||
else
|
||||
echo "✅ Good! You should have enough space for Time Machine now."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,93 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Cleanup Ghost Time Machine Snapshot
|
||||
# Sometimes snapshots appear in the list but don't actually exist or take space
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Cleanup Ghost Time Machine Snapshot ==="
|
||||
echo ""
|
||||
|
||||
# Check current free space
|
||||
FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB=$(echo "scale=2; $FREE_SPACE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB}GB"
|
||||
echo ""
|
||||
|
||||
# List snapshots
|
||||
SNAPSHOTS=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$")
|
||||
if [ -z "$SNAPSHOTS" ]; then
|
||||
echo "✅ No snapshots found - all clean!"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Found snapshot(s):"
|
||||
echo "$SNAPSHOTS" | sed 's/^/ - /'
|
||||
echo ""
|
||||
|
||||
# The snapshot might be a ghost entry. Let's try several methods:
|
||||
|
||||
echo "Attempting cleanup methods..."
|
||||
echo ""
|
||||
|
||||
# Method 1: Try deleting with date format
|
||||
echo "Method 1: Delete by date..."
|
||||
echo "$SNAPSHOTS" | while read snapshot; do
|
||||
if [ -n "$snapshot" ]; then
|
||||
# Extract date: com.apple.TimeMachine.2025-12-31-101235.backup -> 2025-12-31-101235
|
||||
SNAP_DATE=$(echo "$snapshot" | sed 's/.*\.\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}\)\.backup/\1/')
|
||||
if [ -n "$SNAP_DATE" ]; then
|
||||
echo " Trying: sudo tmutil deletelocalsnapshots $SNAP_DATE"
|
||||
if sudo tmutil deletelocalsnapshots "$SNAP_DATE" 2>/dev/null; then
|
||||
echo " ✅ Success!"
|
||||
else
|
||||
echo " ⚠️ Failed (may be ghost entry)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
|
||||
# Method 2: Thin all snapshots (aggressive)
|
||||
echo "Method 2: Aggressive thinning..."
|
||||
sudo tmutil thinlocalsnapshots / 1000000000 1 2>&1 || true
|
||||
echo " ✓ Thinning completed"
|
||||
|
||||
echo ""
|
||||
|
||||
# Method 3: Check if it's actually taking space
|
||||
echo "Method 3: Checking if snapshot actually exists..."
|
||||
APFS_SNAPSHOTS=$(diskutil apfs listSnapshots / 2>/dev/null | grep -i "timemachine" || echo "")
|
||||
if [ -z "$APFS_SNAPSHOTS" ]; then
|
||||
echo " ℹ️ Snapshot not found in APFS snapshot list"
|
||||
echo " This confirms it's likely a ghost entry in Time Machine's database"
|
||||
echo ""
|
||||
echo " The snapshot entry may persist in Time Machine's database but:"
|
||||
echo " - It's not taking up space (space was already freed)"
|
||||
echo " - It will likely clear when Time Machine successfully backs up"
|
||||
echo " - Or it may clear on the next macOS update/restart"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Final check
|
||||
sleep 2
|
||||
REMAINING=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$" | wc -l | tr -d ' ')
|
||||
|
||||
if [ "$REMAINING" -gt 0 ]; then
|
||||
echo "⚠️ Snapshot still listed, but this is likely a ghost entry."
|
||||
echo ""
|
||||
echo "✅ Good news: Your space was already freed (${FREE_SPACE_GB}GB free)!"
|
||||
echo ""
|
||||
echo "The ghost entry should clear when:"
|
||||
echo " 1. Time Machine successfully completes a backup"
|
||||
echo " 2. macOS updates"
|
||||
echo " 3. Or it may persist but won't cause issues"
|
||||
echo ""
|
||||
echo "You can safely ignore it - it's not taking up space."
|
||||
else
|
||||
echo "✅ Snapshot successfully removed!"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -102,7 +102,7 @@ async def monitor_containers():
|
||||
)
|
||||
previous_states[c.id] = current_status
|
||||
except Exception as e:
|
||||
print(f"Error in container monitor: {e}")
|
||||
logging.getLogger(__name__).error("Error in container monitor: %s", e)
|
||||
|
||||
await asyncio.sleep(60)
|
||||
|
||||
|
||||
@@ -11,11 +11,13 @@ from slowapi.util import get_remote_address
|
||||
import jwt
|
||||
import config
|
||||
import auth
|
||||
import logging
|
||||
import pyotp
|
||||
from webauthn import generate_registration_options, verify_registration_response, generate_authentication_options, verify_authentication_response
|
||||
from webauthn.helpers.structs import PublicKeyCredentialDescriptor, UserVerificationRequirement
|
||||
from webauthn.helpers import bytes_to_base64url, base64url_to_bytes, options_to_json
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
router = APIRouter()
|
||||
limiter = Limiter(key_func=get_remote_address)
|
||||
|
||||
@@ -43,9 +45,9 @@ class Verify2FARequest(BaseModel):
|
||||
code: str
|
||||
|
||||
async def send_failed_login_alert(ip_address: str, username: str, reason: str):
|
||||
print(f"Triggering Telegram alert for {username} from {ip_address}: {reason}", flush=True)
|
||||
logger.info("Triggering Telegram alert for %s from %s: %s", username, ip_address, reason)
|
||||
if not config.TELEGRAM_BOT_TOKEN or not config.TELEGRAM_CHAT_ID:
|
||||
print("Skipping Telegram alert: missing config", flush=True)
|
||||
logger.warning("Skipping Telegram alert: missing config")
|
||||
return
|
||||
msg = f"🚨 *Dashboard Security Alert* 🚨\nFailed login attempt detected.\n\n👤 User: `{username}`\n🌐 IP: `{ip_address}`\n❌ Reason: {reason}"
|
||||
try:
|
||||
@@ -59,9 +61,9 @@ async def send_failed_login_alert(ip_address: str, username: str, reason: str):
|
||||
data={"chat_id": config.TELEGRAM_CHAT_ID, "text": msg, "parse_mode": "Markdown"},
|
||||
timeout=10.0
|
||||
)
|
||||
print(f"Telegram alert sent, status: {res.status_code}", flush=True)
|
||||
logger.info("Telegram alert sent, status: %s", res.status_code)
|
||||
except Exception as e:
|
||||
print(f"Failed to send Telegram alert: {e}", flush=True)
|
||||
logger.warning("Failed to send Telegram alert: %s", e)
|
||||
|
||||
@router.post("/login", response_model=Token)
|
||||
@limiter.limit("5/minute")
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# EnConvo Settings Crash Debug Script
|
||||
# Run this script, then click Settings in EnConvo to capture the crash
|
||||
|
||||
echo "=== EnConvo Settings Crash Debugger ==="
|
||||
echo ""
|
||||
echo "This script will:"
|
||||
echo "1. Monitor crash logs"
|
||||
echo "2. Capture Console output"
|
||||
echo "3. Show process info"
|
||||
echo ""
|
||||
echo "Press Ctrl+C to stop monitoring"
|
||||
echo ""
|
||||
echo "Starting monitoring... (Now click Settings in EnConvo)"
|
||||
echo ""
|
||||
|
||||
# Get the current time for filtering logs
|
||||
START_TIME=$(date +"%Y-%m-%d %H:%M:%S")
|
||||
|
||||
# Function to check for crash reports
|
||||
check_crashes() {
|
||||
echo "=== Checking for Crash Reports ==="
|
||||
CRASH_DIR="$HOME/Library/Logs/DiagnosticReports"
|
||||
if [ -d "$CRASH_DIR" ]; then
|
||||
echo "Recent EnConvo crash reports:"
|
||||
find "$CRASH_DIR" -name "*EnConvo*" -type f -mmin -5 2>/dev/null | head -5
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to monitor Console logs
|
||||
monitor_console() {
|
||||
echo "=== Monitoring Console Logs (last 20 lines) ==="
|
||||
log show --predicate 'process == "EnConvo"' --last 1m --style compact 2>/dev/null | tail -20
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Function to check running processes
|
||||
check_processes() {
|
||||
echo "=== EnConvo Processes ==="
|
||||
ps aux | grep -i enconvo | grep -v grep
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Run initial checks
|
||||
check_processes
|
||||
|
||||
# Monitor in a loop
|
||||
while true; do
|
||||
sleep 2
|
||||
check_crashes
|
||||
monitor_console
|
||||
check_processes
|
||||
echo "--- Waiting for crash (click Settings now if you haven't) ---"
|
||||
echo ""
|
||||
done
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deep Space Analysis - Find where the 20GB actually went
|
||||
# When deleted files don't free space even after restart
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Deep Space Analysis ==="
|
||||
echo ""
|
||||
|
||||
# Container vs Volume space
|
||||
echo "📊 Container vs Volume Space:"
|
||||
echo " Container Total: $(diskutil info / | grep 'Container Total' | awk '{print $4, $5}')"
|
||||
echo " Container Free: $(diskutil info / | grep 'Container Free' | awk '{print $4, $5}')"
|
||||
echo " Volume Used: $(diskutil info / | grep 'Volume Used Space' | awk '{print $4, $5, $6}')"
|
||||
echo ""
|
||||
|
||||
# Calculate discrepancy
|
||||
CONTAINER_TOTAL=$(diskutil info / | grep 'Container Total' | awk '{print $3}' | tr -d 'GB')
|
||||
CONTAINER_FREE=$(diskutil info / | grep 'Container Free' | awk '{print $3}' | tr -d 'GB')
|
||||
VOLUME_USED=$(diskutil info / | grep 'Volume Used Space' | awk '{print $4}' | tr -d 'GB')
|
||||
|
||||
CONTAINER_USED=$(echo "$CONTAINER_TOTAL - $CONTAINER_FREE" | bc)
|
||||
DISCREPANCY=$(echo "$CONTAINER_USED - $VOLUME_USED" | bc)
|
||||
|
||||
echo " Container Used: ~${CONTAINER_USED}GB"
|
||||
echo " Volume Used: ~${VOLUME_USED}GB"
|
||||
if (( $(echo "$DISCREPANCY > 5" | bc -l) )); then
|
||||
echo " ⚠️ Discrepancy: ~${DISCREPANCY}GB unaccounted for!"
|
||||
echo " This space may be in:"
|
||||
echo " - Other APFS volumes"
|
||||
echo " - APFS snapshots"
|
||||
echo " - Reserved space"
|
||||
echo " - System files"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check all APFS volumes
|
||||
echo "📦 APFS Volumes:"
|
||||
diskutil apfs list 2>/dev/null | grep -E "Volume Name|Used Space|Free Space" | head -20 | sed 's/^/ /'
|
||||
echo ""
|
||||
|
||||
# Check snapshots
|
||||
echo "📸 APFS Snapshots:"
|
||||
SNAP_COUNT=$(diskutil apfs listSnapshots / 2>/dev/null | grep -c "Name:" || echo "0")
|
||||
echo " Found $SNAP_COUNT snapshot(s)"
|
||||
if [ "$SNAP_COUNT" -gt 0 ]; then
|
||||
diskutil apfs listSnapshots / 2>/dev/null | grep -E "Name|Purgeable" | head -6 | sed 's/^/ /'
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check for large directories that might have been missed
|
||||
echo "🔍 Large Directories Check:"
|
||||
echo " Home directory: $(du -sh ~ 2>/dev/null | awk '{print $1}')"
|
||||
echo " Documents: $(du -sh ~/Documents 2>/dev/null | awk '{print $1}')"
|
||||
echo " Library: $(du -sh ~/Library 2>/dev/null | awk '{print $1}')"
|
||||
echo " Downloads: $(du -sh ~/Downloads 2>/dev/null | awk '{print $1}')"
|
||||
echo " Movies: $(du -sh ~/Movies 2>/dev/null | awk '{print $1}')"
|
||||
echo ""
|
||||
|
||||
# Check if files were actually deleted
|
||||
echo "❓ Verification:"
|
||||
echo " You mentioned deleting 20GB from Movies/Videos folder"
|
||||
echo " Current Movies folder: $(du -sh ~/Movies 2>/dev/null | awk '{print $1}')"
|
||||
echo ""
|
||||
echo " Questions:"
|
||||
echo " 1. Did you delete from ~/Movies or another location?"
|
||||
echo " 2. Did you empty Trash after deleting?"
|
||||
echo " 3. Are the files still in Trash?"
|
||||
echo ""
|
||||
|
||||
# Check trash
|
||||
TRASH_SIZE=$(du -sh ~/.Trash 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " Trash size: $TRASH_SIZE"
|
||||
echo ""
|
||||
|
||||
# Summary
|
||||
echo "=== Analysis ==="
|
||||
echo ""
|
||||
if (( $(echo "$DISCREPANCY > 15" | bc -l) )); then
|
||||
echo "⚠️ Found ${DISCREPANCY}GB+ unaccounted space in container!"
|
||||
echo ""
|
||||
echo " This suggests:"
|
||||
echo " 1. Files may not have been actually deleted"
|
||||
echo " 2. Space is in another APFS volume"
|
||||
echo " 3. APFS snapshots are holding space"
|
||||
echo " 4. System reserved space"
|
||||
echo ""
|
||||
echo " Next steps:"
|
||||
echo " 1. Verify files were actually deleted (not just moved to Trash)"
|
||||
echo " 2. Empty Trash: rm -rf ~/.Trash/*"
|
||||
echo " 3. Check other volumes: diskutil apfs list"
|
||||
echo " 4. Check for large files: find ~ -size +1G -type f 2>/dev/null"
|
||||
echo ""
|
||||
else
|
||||
echo " Space accounting looks normal."
|
||||
echo " The 20GB may have been:"
|
||||
echo " - Used by other files growing"
|
||||
echo " - Actually still present (not deleted)"
|
||||
echo " - In Trash (not emptied)"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,81 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Delete Local Snapshot to Free Space
|
||||
# Since files are on NAS, it's safe to remove the snapshot
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Delete Local Snapshot to Free Space ==="
|
||||
echo ""
|
||||
echo "Since your files are safely backed up on NAS, we can delete"
|
||||
echo "the local snapshot to free up space."
|
||||
echo ""
|
||||
|
||||
FREE_SPACE_BEFORE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_BEFORE=$(echo "scale=2; $FREE_SPACE_BEFORE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB_BEFORE}GB"
|
||||
echo ""
|
||||
|
||||
# Check snapshot
|
||||
SNAPSHOT=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$" | head -1)
|
||||
if [ -z "$SNAPSHOT" ]; then
|
||||
echo "✅ No snapshot found - you're all set!"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Found snapshot: $SNAPSHOT"
|
||||
echo ""
|
||||
|
||||
# Extract date
|
||||
SNAP_DATE=$(echo "$SNAPSHOT" | sed 's/.*\.\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}\)\.backup/\1/')
|
||||
|
||||
if [ -z "$SNAP_DATE" ]; then
|
||||
echo "⚠️ Could not parse snapshot date"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Attempting to delete snapshot: $SNAP_DATE"
|
||||
echo ""
|
||||
|
||||
# Try to delete
|
||||
if sudo tmutil deletelocalsnapshots "$SNAP_DATE" 2>/dev/null; then
|
||||
echo "✅ Successfully deleted snapshot!"
|
||||
echo ""
|
||||
echo "⏳ Waiting for space to be released..."
|
||||
sleep 5
|
||||
|
||||
FREE_SPACE_AFTER=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_AFTER=$(echo "scale=2; $FREE_SPACE_AFTER / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $FREE_SPACE_GB_AFTER - $FREE_SPACE_GB_BEFORE" | bc)
|
||||
|
||||
echo ""
|
||||
echo "=== Results ==="
|
||||
echo " Before: ${FREE_SPACE_GB_BEFORE}GB free"
|
||||
echo " After: ${FREE_SPACE_GB_AFTER}GB free"
|
||||
if (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo " ✅ Freed: ${FREED_GB}GB"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ Could not delete snapshot (Stale NFS file handle error)"
|
||||
echo ""
|
||||
echo "This is a known issue. The snapshot is stuck because:"
|
||||
echo " - Time Machine had a stale connection to NAS"
|
||||
echo " - The snapshot reference is corrupted"
|
||||
echo ""
|
||||
echo "=== Solutions ==="
|
||||
echo ""
|
||||
echo "Option 1: Restart your Mac (Recommended)"
|
||||
echo " This will release the stuck snapshot and free the space."
|
||||
echo " After restart, the snapshot should be gone."
|
||||
echo ""
|
||||
echo "Option 2: Wait for macOS to auto-clean"
|
||||
echo " macOS will eventually clean up stuck snapshots, but this"
|
||||
echo " can take hours or days."
|
||||
echo ""
|
||||
echo "The good news: The snapshot is a GHOST ENTRY (not in APFS)."
|
||||
echo "This means the space may already be available - the entry"
|
||||
echo "is just a stale database record that will clear on restart."
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,69 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Diagnose Synology USB Copy Issue
|
||||
# Connects to NAS and checks USB device status
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Synology USB Copy Diagnosis ==="
|
||||
echo ""
|
||||
|
||||
# Check if nas alias works
|
||||
if ! command -v nas &> /dev/null; then
|
||||
echo "⚠️ 'nas' alias not found. Using SSH directly."
|
||||
echo " Please provide: ssh user@nas-ip"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🔍 Checking USB device status on NAS..."
|
||||
echo ""
|
||||
|
||||
echo "1. USB Devices Connected:"
|
||||
nas "lsusb 2>/dev/null || echo 'lsusb not available, checking dmesg...' && dmesg | grep -i usb | tail -5" || echo " ⚠️ Could not check USB devices"
|
||||
echo ""
|
||||
|
||||
echo "2. USB Mount Points:"
|
||||
nas "mount | grep -i usb || echo ' No USB devices mounted'" || echo " ⚠️ Could not check mounts"
|
||||
echo ""
|
||||
|
||||
echo "3. USB Volumes:"
|
||||
nas "ls -la /volumeUSB*/ 2>/dev/null || echo ' No /volumeUSB* directories found'" || echo " ⚠️ Could not check USB volumes"
|
||||
echo ""
|
||||
|
||||
echo "4. Disk Partitions:"
|
||||
nas "cat /proc/partitions | grep -v '^major' | head -10" || echo " ⚠️ Could not check partitions"
|
||||
echo ""
|
||||
|
||||
echo "5. Disk Usage (USB devices):"
|
||||
nas "df -h | grep -i usb || echo ' No USB devices in df output'" || echo " ⚠️ Could not check disk usage"
|
||||
echo ""
|
||||
|
||||
echo "6. USB Copy Service Status:"
|
||||
nas "synoservice --status pkgctl-USB-Copy 2>/dev/null || echo ' Could not check USB Copy service status'" || echo " ⚠️ Could not check service"
|
||||
echo ""
|
||||
|
||||
echo "7. USB Copy Configuration:"
|
||||
nas "cat /usr/syno/etc/packages/USB-Copy/usbcopy.conf 2>/dev/null | head -20 || echo ' Could not read USB Copy config'" || echo " ⚠️ Could not read config"
|
||||
echo ""
|
||||
|
||||
echo "8. Check for USB devices in /dev:"
|
||||
nas "ls -la /dev/sd* /dev/hd* 2>/dev/null | head -10 || echo ' No USB block devices found'" || echo " ⚠️ Could not check devices"
|
||||
echo ""
|
||||
|
||||
echo "=== Diagnosis Summary ==="
|
||||
echo ""
|
||||
echo "Common issues to check:"
|
||||
echo ""
|
||||
echo "1. If no USB devices found:"
|
||||
echo " - USB device not connected to front port"
|
||||
echo " - USB device not recognized by Synology"
|
||||
echo " - Try different USB device"
|
||||
echo ""
|
||||
echo "2. If USB device mounted but USB Copy shows 'Unavailable':"
|
||||
echo " - USB device mounted as shared folder"
|
||||
echo " - Another task using the USB device"
|
||||
echo " - Need to unmount from other uses"
|
||||
echo ""
|
||||
echo "3. If USB Copy service not running:"
|
||||
echo " - Package Center → USB Copy → Start"
|
||||
echo ""
|
||||
@@ -1,104 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Emergency Free Space - When Time Machine is stuck and consuming space
|
||||
# This script provides the quickest way to free space
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Emergency Free Space Fix ==="
|
||||
echo ""
|
||||
echo "Time Machine is stuck and holding your deleted file space."
|
||||
echo ""
|
||||
|
||||
FREE_SPACE_BEFORE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_BEFORE=$(echo "scale=2; $FREE_SPACE_BEFORE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB_BEFORE}GB"
|
||||
echo ""
|
||||
|
||||
echo "🔧 Solution: Remove Time Machine destination to free the stuck snapshot"
|
||||
echo ""
|
||||
echo "The snapshot is stuck because Time Machine can't connect to your NAS."
|
||||
echo "Removing the destination will allow the snapshot to be deleted."
|
||||
echo ""
|
||||
|
||||
read -p "Have you removed the Time Machine destination in System Settings? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo ""
|
||||
echo "Please do this now:"
|
||||
echo "1. Open System Settings → General → Time Machine"
|
||||
echo "2. Click the '-' button to remove the backup disk"
|
||||
echo "3. Confirm removal"
|
||||
echo ""
|
||||
echo "Then run this script again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "⏳ Waiting for Time Machine to fully disconnect..."
|
||||
sleep 5
|
||||
|
||||
# Kill any remaining backup processes
|
||||
echo "🛑 Stopping any remaining Time Machine processes..."
|
||||
sudo killall backupd 2>/dev/null || true
|
||||
sleep 2
|
||||
|
||||
# Try to delete the snapshot now
|
||||
echo ""
|
||||
echo "🗑️ Attempting to delete stuck snapshot..."
|
||||
SNAPSHOTS=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$")
|
||||
if [ -n "$SNAPSHOTS" ]; then
|
||||
echo "$SNAPSHOTS" | while read snapshot; do
|
||||
if [ -n "$snapshot" ]; then
|
||||
SNAP_DATE=$(echo "$snapshot" | sed 's/.*\.\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}\)\.backup/\1/')
|
||||
if [ -n "$SNAP_DATE" ]; then
|
||||
echo " Deleting: $snapshot"
|
||||
if sudo tmutil deletelocalsnapshots "$SNAP_DATE" 2>/dev/null; then
|
||||
echo " ✅ Successfully deleted!"
|
||||
else
|
||||
echo " ⚠️ Still stuck. Try restarting your Mac."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo " ✅ No snapshots found"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📊 Checking results..."
|
||||
sleep 3
|
||||
|
||||
FREE_SPACE_AFTER=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_AFTER=$(echo "scale=2; $FREE_SPACE_AFTER / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $FREE_SPACE_GB_AFTER - $FREE_SPACE_GB_BEFORE" | bc)
|
||||
|
||||
echo ""
|
||||
echo "=== Results ==="
|
||||
echo " Before: ${FREE_SPACE_GB_BEFORE}GB free"
|
||||
echo " After: ${FREE_SPACE_GB_AFTER}GB free"
|
||||
if (( $(echo "$FREED_GB > 15" | bc -l) )); then
|
||||
echo " ✅ Successfully freed: ${FREED_GB}GB"
|
||||
echo ""
|
||||
echo " Your 20GB from deleted files should now be available!"
|
||||
elif (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo " ✅ Freed: ${FREED_GB}GB"
|
||||
echo " (May need restart to free remaining space)"
|
||||
else
|
||||
echo " ⚠️ Space not freed yet"
|
||||
echo ""
|
||||
echo " Try restarting your Mac - this often releases stuck snapshots."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Next Steps ==="
|
||||
echo ""
|
||||
echo "1. After space is freed, fix Time Machine connection:"
|
||||
echo " See: time_machine_troubleshooting.md"
|
||||
echo ""
|
||||
echo "2. Common fixes for NAS connection:"
|
||||
echo " - Clear credentials: Keychain Access → search 'DS224plus' → delete"
|
||||
echo " - Re-add Time Machine: System Settings → Time Machine → Add Backup Disk"
|
||||
echo ""
|
||||
echo "3. Once connection is fixed, Time Machine will work properly."
|
||||
echo ""
|
||||
@@ -1,84 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Emergency Options - When Update Can't Download
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Emergency Options ==="
|
||||
echo ""
|
||||
echo "Update download failed: Need 17.64GB, have less."
|
||||
echo "You're in a catch-22 situation."
|
||||
echo ""
|
||||
|
||||
FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB=$(echo "scale=2; $FREE_SPACE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB}GB"
|
||||
echo "Needed: 17.64GB"
|
||||
echo "Shortfall: ~$(echo "17.64 - $FREE_SPACE_GB" | bc)GB"
|
||||
echo ""
|
||||
|
||||
echo "🔧 OPTIONS:"
|
||||
echo ""
|
||||
|
||||
echo "1. **Use External Drive** (BEST OPTION)"
|
||||
echo ""
|
||||
echo " If you have an external USB drive:"
|
||||
echo " a) Connect it"
|
||||
echo " b) Move large files there (not NAS - external drive):"
|
||||
echo " - Downloads (8.7GB)"
|
||||
echo " - .ollama (17GB)"
|
||||
echo " - .local (18GB)"
|
||||
echo " c) Install macOS update"
|
||||
echo " d) After update clears snapshot, move files back"
|
||||
echo ""
|
||||
|
||||
echo "2. **Contact Apple Support** (RECOMMENDED)"
|
||||
echo ""
|
||||
echo " Phone: 1-800-275-2273"
|
||||
echo " Explain: 'OS update snapshot preventing space recovery'"
|
||||
echo " They may:"
|
||||
echo " - Have tools to force-clear snapshot"
|
||||
echo " - Help with update process"
|
||||
echo " - Provide other solutions"
|
||||
echo ""
|
||||
|
||||
echo "3. **Try System Settings Update** (Sometimes works differently)"
|
||||
echo ""
|
||||
echo " System Settings → General → Software Update"
|
||||
echo " Click 'Update Now'"
|
||||
echo " Sometimes GUI works when command line doesn't"
|
||||
echo ""
|
||||
|
||||
echo "4. **Check for External Storage**"
|
||||
echo ""
|
||||
echo " Do you have:"
|
||||
echo " - USB drive?"
|
||||
echo " - SD card?"
|
||||
echo " - Another Mac you can network to?"
|
||||
echo " - Cloud storage (iCloud, Dropbox, etc.)?"
|
||||
echo ""
|
||||
|
||||
echo "5. **Last Resort: Clean Install** (Loses data, not recommended)"
|
||||
echo ""
|
||||
echo " ⚠️ Only if you have everything backed up"
|
||||
echo " - Create bootable installer"
|
||||
echo " - Fresh install macOS"
|
||||
echo " - Restore from Time Machine"
|
||||
echo ""
|
||||
|
||||
echo "=== What You CAN Do Right Now ==="
|
||||
echo ""
|
||||
echo "Even though space isn't freed, your files ARE safe on NAS."
|
||||
echo ""
|
||||
echo "The space WILL be freed after updating macOS."
|
||||
echo ""
|
||||
echo "The blocker is: You need space to update, but can't free space"
|
||||
echo "because the snapshot preserves everything."
|
||||
echo ""
|
||||
|
||||
echo "🎯 IMMEDIATE ACTION:"
|
||||
echo ""
|
||||
echo "1. Check if you have external drive"
|
||||
echo "2. If yes: Use it to temporarily move files"
|
||||
echo "3. If no: Contact Apple Support (1-800-275-2273)"
|
||||
echo ""
|
||||
@@ -1,43 +0,0 @@
|
||||
EnConvo Settings Crash Report
|
||||
==============================
|
||||
|
||||
Environment:
|
||||
- Device: MacBook Air (M1)
|
||||
- macOS Version: Ventura 13.x
|
||||
- App Version: 2.2.22
|
||||
- Issue: App crashes when clicking Settings sidebar button
|
||||
|
||||
Error Output:
|
||||
-------------
|
||||
PostHog -> Error not initialized due to missing API key or host
|
||||
|
||||
[SwiftCPUDetect] Detected CPU type number: 16777228
|
||||
[SwiftCPUDetect] Detected CPU subtype number: 2
|
||||
[SwiftCPUDetect] Detected CPU family number: 458787763
|
||||
[SwiftCPUDetect] Detected cpu architecture of the current process is: arm64
|
||||
|
||||
WARNING: The sun_len field of a sockaddr_un structure passed to CFSocketSetAddress was not set correctly using the SUN_LEN macro.
|
||||
|
||||
(node) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
|
||||
|
||||
zsh: trace trap /Applications/EnConvo.app/Contents/MacOS/EnConvo
|
||||
|
||||
Crash Type:
|
||||
-----------
|
||||
"trace trap" indicates the app received a SIGTRAP signal, typically from:
|
||||
- Breakpoint hit
|
||||
- Assertion failure
|
||||
- Debugger attachment
|
||||
- Memory access violation
|
||||
|
||||
Note: This works fine on macOS 15 (MBP) with version 2.2.21
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
EnConvo Settings Crash Report - macOS Ventura
|
||||
==============================================
|
||||
|
||||
Environment:
|
||||
-----------
|
||||
- Device: MacBook Air (M1)
|
||||
- macOS Version: Ventura 13.6.4 (22G513)
|
||||
- App Version: 2.2.22 (Build 252)
|
||||
- Bundle ID: com.frostyeve.enconvo
|
||||
- Issue: App crashes when clicking Settings sidebar button
|
||||
|
||||
Note: Works fine on macOS 15 (MBP) with version 2.2.21
|
||||
|
||||
Crash Details:
|
||||
--------------
|
||||
Exception Type: EXC_BREAKPOINT
|
||||
Signal: SIGTRAP
|
||||
Termination Reason: Trace/BPT trap: 5
|
||||
Faulting Thread: 0 (Main Thread)
|
||||
|
||||
Crash Location:
|
||||
---------------
|
||||
The crash occurs in AttributeGraph framework during SwiftUI layout operations:
|
||||
|
||||
Stack Trace (Key Frames):
|
||||
- AG::Graph::UpdateStack::update() [AttributeGraph]
|
||||
- AG::Graph::update_attribute() [AttributeGraph]
|
||||
- AG::Graph::input_value_ref_slow() [AttributeGraph]
|
||||
- AGGraphGetValue [AttributeGraph]
|
||||
- NSView layout operations [AppKit]
|
||||
- NSWindow layoutIfNeeded [AppKit]
|
||||
- CATransaction commit [QuartzCore]
|
||||
- CFRunLoopRun [CoreFoundation]
|
||||
- NSApplicationMain [AppKit]
|
||||
|
||||
The crash happens during the layout phase when opening Settings, specifically in:
|
||||
- NSView _layoutSubtreeWithOldSize
|
||||
- NSWindow _layoutViewTree
|
||||
- AttributeGraph update cycle
|
||||
|
||||
Error Description:
|
||||
-----------------
|
||||
The app triggers a breakpoint (EXC_BREAKPOINT) during SwiftUI/AttributeGraph layout
|
||||
operations when the Settings view is being rendered. This suggests a compatibility
|
||||
issue between the SwiftUI/AttributeGraph version in macOS Ventura (13.6.4) and
|
||||
the app's layout code.
|
||||
|
||||
Possible Causes:
|
||||
---------------
|
||||
1. SwiftUI/AttributeGraph API incompatibility between macOS 13 and 15
|
||||
2. Layout constraint or view hierarchy issue specific to macOS 13
|
||||
3. Memory access issue during layout pass on Ventura
|
||||
|
||||
Reproduction Steps:
|
||||
------------------
|
||||
1. Launch EnConvo on macOS Ventura 13.6.4
|
||||
2. Click Settings button in sidebar
|
||||
3. App immediately crashes
|
||||
|
||||
Additional Info:
|
||||
---------------
|
||||
- App runs fine until Settings is clicked
|
||||
- No error dialog shown to user (silent crash)
|
||||
- Crash report generated: EnConvo-2025-11-28-002456.ips
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
EnConvo Pricing & Feature Clarification
|
||||
========================================
|
||||
|
||||
I'm trying to understand the differences between the free and paid versions of EnConvo, particularly regarding API usage and feature limitations.
|
||||
|
||||
Current Understanding:
|
||||
----------------------
|
||||
1. The paid version appears to cover:
|
||||
- API usage fees (for EnConvo's cloud plan)
|
||||
- App updates/maintenance
|
||||
|
||||
2. Free version limitations:
|
||||
- 10 uses/day limit (presumably for EnConvo's cloud plan API)
|
||||
|
||||
Questions:
|
||||
----------
|
||||
|
||||
1. **Using Own API Keys in Free Version:**
|
||||
If I use my own API keys (e.g., OpenAI, Anthropic, etc.) in the free version:
|
||||
- Are there any feature limitations or restrictions?
|
||||
- Does the 10 uses/day limit apply to my own API keys, or only to EnConvo's cloud plan?
|
||||
- Can I use unlimited requests with my own API keys on the free version?
|
||||
|
||||
2. **10 Uses/Day Limit Clarification:**
|
||||
My understanding is that the 10 uses/day limit applies only to EnConvo's cloud plan API usage, not to requests made with my own API keys. Is this correct?
|
||||
|
||||
3. **Cloud Plan vs Own API Keys:**
|
||||
- What are the advantages of using EnConvo's cloud plan (points system) versus using my own API keys?
|
||||
- Does the cloud plan provide access to multiple models that might not be available through direct API access?
|
||||
- Are there any models or features exclusive to the cloud plan?
|
||||
|
||||
4. **Paid Version Benefits:**
|
||||
Beyond covering API costs and updates, are there any additional features, capabilities, or benefits exclusive to the paid version when using your own API keys?
|
||||
|
||||
Summary:
|
||||
--------
|
||||
I want to clarify whether the free version with my own API keys provides full functionality (unlimited usage), or if there are still limitations/restrictions that would require upgrading to the paid version.
|
||||
|
||||
Thank you for your clarification!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
EnConvo Pricing Question - Free vs Paid
|
||||
========================================
|
||||
|
||||
I'm trying to clarify the differences between free and paid versions, especially regarding API usage.
|
||||
|
||||
My Understanding:
|
||||
-----------------
|
||||
- Paid version covers: API usage fees (EnConvo cloud plan) + app updates
|
||||
- Free version: 10 uses/day limit (for EnConvo's cloud plan API)
|
||||
|
||||
Questions:
|
||||
----------
|
||||
|
||||
1. **Using My Own API Keys:**
|
||||
If I use my own API keys (OpenAI, Anthropic, etc.) in the free version:
|
||||
- Is the 10 uses/day limit still applied, or does it only apply to EnConvo's cloud plan?
|
||||
- Are there any feature limitations when using my own keys?
|
||||
- Can I use unlimited requests with my own API keys on the free version?
|
||||
|
||||
2. **Cloud Plan Benefits:**
|
||||
What advantages does EnConvo's cloud plan offer over using my own API keys directly? (e.g., access to multiple models, better pricing, exclusive features?)
|
||||
|
||||
3. **Paid Version Benefits:**
|
||||
Beyond API costs and updates, are there additional features exclusive to the paid version when using my own API keys?
|
||||
|
||||
In summary: Does the free version with my own API keys provide full, unlimited functionality, or are there still restrictions that require upgrading?
|
||||
|
||||
Thanks!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Explain Why Moving Files Doesn't Free Space
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Why Moving Files Doesn't Free Space ==="
|
||||
echo ""
|
||||
echo "⚠️ THE PROBLEM:"
|
||||
echo ""
|
||||
echo "When you move/delete files, the OS update snapshot preserves them."
|
||||
echo "This means:"
|
||||
echo " - Files are moved to NAS ✅"
|
||||
echo " - But space isn't freed on Mac ❌"
|
||||
echo " - System Data grows instead 📈"
|
||||
echo ""
|
||||
|
||||
FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB=$(echo "scale=2; $FREE_SPACE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB}GB"
|
||||
echo ""
|
||||
|
||||
echo "📸 The OS Update Snapshot:"
|
||||
SNAPSHOT=$(diskutil apfs listSnapshots / 2>/dev/null | grep "Name:" | head -1)
|
||||
if [ -n "$SNAPSHOT" ]; then
|
||||
echo "$SNAPSHOT" | sed 's/^/ /'
|
||||
echo ""
|
||||
echo " This snapshot:"
|
||||
echo " - Is NOT purgeable"
|
||||
echo " - Preserves all deleted/moved files"
|
||||
echo " - Can't be deleted manually"
|
||||
echo " - Will only clear when you update macOS"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "🔍 What's Happening:"
|
||||
echo ""
|
||||
echo "1. You move files → Files go to NAS ✅"
|
||||
echo "2. macOS snapshot preserves them → System Data grows 📈"
|
||||
echo "3. Space isn't freed → Still full ❌"
|
||||
echo ""
|
||||
|
||||
echo "=== THE ONLY SOLUTION ==="
|
||||
echo ""
|
||||
echo "You MUST install the macOS update to clear the snapshot."
|
||||
echo ""
|
||||
echo "But you need space to install the update (17.64GB needed)."
|
||||
echo ""
|
||||
echo "This is a catch-22 situation:"
|
||||
echo " - Need space to update"
|
||||
echo " - Can't get space because snapshot preserves deleted files"
|
||||
echo ""
|
||||
|
||||
echo "=== WORKAROUND ==="
|
||||
echo ""
|
||||
echo "Option 1: Free space from sources that DON'T trigger snapshots:"
|
||||
echo " - Clean caches: rm -rf ~/Library/Caches/* (~6GB)"
|
||||
echo " - Clean user cache: rm -rf ~/.cache/* (~3GB)"
|
||||
echo " - Clean npm: npm cache clean --force (~1GB)"
|
||||
echo " Total: ~10GB (still not enough for 17.64GB update)"
|
||||
echo ""
|
||||
|
||||
echo "Option 2: Try downloading update with less space:"
|
||||
echo " sudo softwareupdate --download --all"
|
||||
echo " (Sometimes works with less than required space)"
|
||||
echo ""
|
||||
|
||||
echo "Option 3: Use external drive temporarily:"
|
||||
echo " - Move files to external drive (not NAS)"
|
||||
echo " - Install update"
|
||||
echo " - Move files back after snapshot clears"
|
||||
echo ""
|
||||
|
||||
echo "Option 4: Contact Apple Support:"
|
||||
echo " They may have tools to force-clear the snapshot"
|
||||
echo ""
|
||||
|
||||
echo "=== Current Status ==="
|
||||
echo ""
|
||||
echo "Files moved to NAS: ✅ (they're safe)"
|
||||
echo "Space freed on Mac: ❌ (snapshot preserving them)"
|
||||
echo "System Data: 📈 (growing because of snapshot)"
|
||||
echo ""
|
||||
echo "The files ARE moved, but the space won't be freed"
|
||||
echo "until the snapshot is cleared by updating macOS."
|
||||
echo ""
|
||||
@@ -1,93 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Final Explanation - Why Nothing Works
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== FINAL EXPLANATION ==="
|
||||
echo ""
|
||||
echo "You've tried everything:"
|
||||
echo " ✅ Moved files to NAS"
|
||||
echo " ✅ Moved files to external drive"
|
||||
echo " ✅ Cleaned caches"
|
||||
echo " ❌ Still no space freed"
|
||||
echo ""
|
||||
|
||||
FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB=$(echo "scale=2; $FREE_SPACE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB}GB"
|
||||
echo ""
|
||||
|
||||
echo "❌ WHY NOTHING WORKS:"
|
||||
echo ""
|
||||
echo "The OS update snapshot preserves EVERYTHING:"
|
||||
echo " - Deleted files → Preserved in snapshot"
|
||||
echo " - Moved files → Preserved in snapshot"
|
||||
echo " - Files on NAS → Still preserved in snapshot"
|
||||
echo " - Files on external drive → Still preserved in snapshot"
|
||||
echo ""
|
||||
echo "The snapshot doesn't care WHERE files went."
|
||||
echo "It preserves them regardless of destination."
|
||||
echo ""
|
||||
|
||||
echo "📸 The Snapshot:"
|
||||
SNAPSHOT=$(diskutil apfs listSnapshots / 2>/dev/null | grep "Name:" | head -1)
|
||||
if [ -n "$SNAPSHOT" ]; then
|
||||
echo "$SNAPSHOT" | sed 's/^/ /'
|
||||
echo ""
|
||||
echo " - NOT purgeable"
|
||||
echo " - Preserves ALL file operations"
|
||||
echo " - Can't be deleted"
|
||||
echo " - Only clears when macOS updates"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "🔒 THE CATCH-22:"
|
||||
echo ""
|
||||
echo " Need: 17.64GB to install macOS update"
|
||||
echo " Problem: Can't free space (snapshot preserves everything)"
|
||||
echo " Result: Stuck"
|
||||
echo ""
|
||||
|
||||
echo "✅ YOUR ONLY OPTIONS:"
|
||||
echo ""
|
||||
echo "1. **Contact Apple Support** (RECOMMENDED)"
|
||||
echo " Phone: 1-800-275-2273"
|
||||
echo " Explain: 'OS update snapshot preventing space recovery'"
|
||||
echo " They have system-level tools we don't have access to"
|
||||
echo ""
|
||||
echo "2. **Try GUI Update** (Sometimes works differently)"
|
||||
echo " System Settings → General → Software Update"
|
||||
echo " Click 'Update Now'"
|
||||
echo " GUI sometimes bypasses space checks"
|
||||
echo ""
|
||||
echo "3. **Boot from Recovery** (Advanced)"
|
||||
echo " - Restart holding Command+R"
|
||||
echo " - Try updating from Recovery Mode"
|
||||
echo " - May have different space requirements"
|
||||
echo ""
|
||||
echo "4. **Wait for Automatic Cleanup** (Unreliable)"
|
||||
echo " macOS may eventually clear old snapshots"
|
||||
echo " But this can take weeks/months"
|
||||
echo ""
|
||||
|
||||
echo "📊 Current Situation:"
|
||||
echo ""
|
||||
echo " Files moved: ✅ (Safe on NAS/external drive)"
|
||||
echo " Space freed: ❌ (Snapshot preserving them)"
|
||||
echo " System Data: 📈 (351GB+ and growing)"
|
||||
echo " Free space: ${FREE_SPACE_GB}GB (not enough)"
|
||||
echo ""
|
||||
|
||||
echo "⚠️ IMPORTANT:"
|
||||
echo ""
|
||||
echo "Your files ARE safe. The space WILL be freed after updating."
|
||||
echo "But you're in a system-level catch-22 that requires"
|
||||
echo "Apple Support intervention or advanced recovery methods."
|
||||
echo ""
|
||||
|
||||
echo "🎯 NEXT STEP:"
|
||||
echo ""
|
||||
echo "Call Apple Support: 1-800-275-2273"
|
||||
echo "They can help with this specific issue."
|
||||
echo ""
|
||||
@@ -1,94 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Final Solution Summary - Why Moving Files Doesn't Free Space
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== FINAL SOLUTION SUMMARY ==="
|
||||
echo ""
|
||||
echo "You've moved files (Music, Documents, etc.) to NAS,"
|
||||
echo "but space isn't being freed. Here's why and what to do:"
|
||||
echo ""
|
||||
|
||||
FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB=$(echo "scale=2; $FREE_SPACE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB}GB"
|
||||
echo ""
|
||||
|
||||
echo "❌ THE PROBLEM:"
|
||||
echo ""
|
||||
echo "The OS update snapshot is preserving ALL moved/deleted files."
|
||||
echo ""
|
||||
echo "What happens:"
|
||||
echo " 1. You move Music folder → Files go to NAS ✅"
|
||||
echo " 2. Snapshot preserves them → System Data grows 📈"
|
||||
echo " 3. Space NOT freed → Still full ❌"
|
||||
echo ""
|
||||
|
||||
echo "📸 The Snapshot:"
|
||||
SNAPSHOT=$(diskutil apfs listSnapshots / 2>/dev/null | grep "Name:" | head -1)
|
||||
if [ -n "$SNAPSHOT" ]; then
|
||||
echo "$SNAPSHOT" | sed 's/^/ /'
|
||||
echo ""
|
||||
echo " - NOT purgeable"
|
||||
echo " - Preserves all deleted/moved files"
|
||||
echo " - Can't be deleted manually"
|
||||
echo " - Only clears when you update macOS"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "✅ THE ONLY SOLUTION:"
|
||||
echo ""
|
||||
echo "You MUST install the macOS update to clear the snapshot."
|
||||
echo ""
|
||||
echo "But you need 17.64GB to install, and you can't free space"
|
||||
echo "because the snapshot preserves everything you delete/move."
|
||||
echo ""
|
||||
echo "This is a SYSTEM-LEVEL CATCH-22."
|
||||
echo ""
|
||||
|
||||
echo "🔧 WORKAROUNDS:"
|
||||
echo ""
|
||||
echo "1. **Try downloading update anyway** (may work with less space):"
|
||||
echo " sudo softwareupdate --download --all"
|
||||
echo ""
|
||||
echo "2. **Use external drive** (if available):"
|
||||
echo " - Connect external drive"
|
||||
echo " - Move large files there (not NAS)"
|
||||
echo " - Install update"
|
||||
echo " - Move files back after snapshot clears"
|
||||
echo ""
|
||||
echo "3. **Contact Apple Support**:"
|
||||
echo " - They may have tools to force-clear snapshot"
|
||||
echo " - Or can help with update process"
|
||||
echo " - Phone: 1-800-275-2273"
|
||||
echo ""
|
||||
echo "4. **Try restarting, then immediately download update**:"
|
||||
echo " - Restart Mac"
|
||||
echo " - Immediately run: sudo softwareupdate --download --all"
|
||||
echo " - Sometimes releases temporary space"
|
||||
echo ""
|
||||
|
||||
echo "📊 Current Status:"
|
||||
echo ""
|
||||
echo " Files moved to NAS: ✅ (they're safe)"
|
||||
echo " Space freed on Mac: ❌ (snapshot preserving them)"
|
||||
echo " System Data: 📈 (351GB+ and growing)"
|
||||
echo " Free space: ${FREE_SPACE_GB}GB (not enough for update)"
|
||||
echo ""
|
||||
|
||||
echo "⚠️ IMPORTANT:"
|
||||
echo ""
|
||||
echo " - Your files ARE safely on NAS"
|
||||
echo " - The space WILL be freed after updating macOS"
|
||||
echo " - But you need space to update (catch-22)"
|
||||
echo " - This requires external storage or Apple Support"
|
||||
echo ""
|
||||
|
||||
echo "🎯 RECOMMENDED ACTION:"
|
||||
echo ""
|
||||
echo " 1. Try: sudo softwareupdate --download --all"
|
||||
echo " (May work even with current space)"
|
||||
echo ""
|
||||
echo " 2. If that fails, use external drive or contact Apple Support"
|
||||
echo ""
|
||||
@@ -1,108 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Find ANY Freeable Space - Check everything
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Find Any Freeable Space ==="
|
||||
echo ""
|
||||
|
||||
FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB=$(echo "scale=2; $FREE_SPACE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB}GB"
|
||||
echo ""
|
||||
|
||||
echo "🔍 Checking all possible sources of space:"
|
||||
echo ""
|
||||
|
||||
TOTAL_POTENTIAL=0
|
||||
|
||||
# 1. Caches
|
||||
echo "1. Caches:"
|
||||
CACHE_SIZE=$(du -sh ~/Library/Caches 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " Library/Caches: $CACHE_SIZE"
|
||||
if [ "$CACHE_SIZE" != "0" ] && [ -n "$CACHE_SIZE" ]; then
|
||||
CACHE_GB=$(echo "$CACHE_SIZE" | sed 's/G//' | awk '{if ($1 ~ /[0-9]/) print $1; else print "0"}')
|
||||
TOTAL_POTENTIAL=$(echo "$TOTAL_POTENTIAL + $CACHE_GB" | bc 2>/dev/null || echo "$TOTAL_POTENTIAL")
|
||||
fi
|
||||
|
||||
USER_CACHE=$(du -sh ~/.cache 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " .cache: $USER_CACHE"
|
||||
|
||||
NPM_CACHE=$(du -sh ~/.npm 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " .npm: $NPM_CACHE"
|
||||
echo ""
|
||||
|
||||
# 2. Downloads
|
||||
DOWNLOADS=$(du -sh ~/Downloads 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo "2. Downloads: $DOWNLOADS"
|
||||
echo ""
|
||||
|
||||
# 3. Trash
|
||||
TRASH=$(du -sh ~/.Trash 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo "3. Trash: $TRASH"
|
||||
echo ""
|
||||
|
||||
# 4. Virtual memory
|
||||
VM_SIZE=$(sudo du -sh /private/var/vm 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo "4. Virtual Memory (swap): $VM_SIZE"
|
||||
echo ""
|
||||
|
||||
# 5. System temp
|
||||
TEMP_SIZE=$(sudo du -sh /private/var/folders 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo "5. System Temp: $TEMP_SIZE"
|
||||
echo ""
|
||||
|
||||
# 6. Large directories
|
||||
echo "6. Large Directories:"
|
||||
OLLAMA=$(du -sh ~/.ollama 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " .ollama: $OLLAMA"
|
||||
|
||||
LOCAL=$(du -sh ~/.local 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " .local: $LOCAL"
|
||||
echo ""
|
||||
|
||||
# 7. Documents remaining
|
||||
DOCS=$(du -sh ~/Documents 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo "7. Documents remaining: $DOCS"
|
||||
echo ""
|
||||
|
||||
echo "=== Analysis ==="
|
||||
echo ""
|
||||
echo "The problem: Even if we free space, the OS snapshot will preserve"
|
||||
echo "deleted files, making System Data grow instead."
|
||||
echo ""
|
||||
|
||||
echo "=== Desperate Measures ==="
|
||||
echo ""
|
||||
echo "Since normal methods don't work, try:"
|
||||
echo ""
|
||||
echo "1. **Restart your Mac**"
|
||||
echo " Sometimes releases some purgeable space temporarily"
|
||||
echo ""
|
||||
echo "2. **Try downloading update with current space**"
|
||||
echo " sudo softwareupdate --download --all"
|
||||
echo " (May work even with less than 17.64GB)"
|
||||
echo ""
|
||||
echo "3. **Check if update can install incrementally**"
|
||||
echo " System Settings → General → Software Update"
|
||||
echo " Click 'More Info' to see if it can download in parts"
|
||||
echo ""
|
||||
echo "4. **Use external drive** (if available)"
|
||||
echo " - Connect external drive"
|
||||
echo " - Move large files there (not NAS)"
|
||||
echo " - Install update"
|
||||
echo " - Move files back"
|
||||
echo ""
|
||||
echo "5. **Contact Apple Support**"
|
||||
echo " They may have tools to force-clear the snapshot"
|
||||
echo " Or can help with the update process"
|
||||
echo ""
|
||||
|
||||
echo "=== The Real Issue ==="
|
||||
echo ""
|
||||
echo "The OS update snapshot is blocking everything."
|
||||
echo "You need to update macOS, but need space to update."
|
||||
echo "This is a system-level catch-22 that may require"
|
||||
echo "Apple Support intervention or external storage."
|
||||
echo ""
|
||||
@@ -1,79 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Find Large Files - Help locate where space is actually being used
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Find Large Files ==="
|
||||
echo ""
|
||||
echo "Your container is 99.8% full (493.5GB used, 847MB free)"
|
||||
echo "Let's find where the space is actually being used..."
|
||||
echo ""
|
||||
|
||||
echo "📊 Top Space Users:"
|
||||
echo ""
|
||||
echo "Home directory breakdown:"
|
||||
du -h -d 1 ~ 2>/dev/null | sort -hr | head -10 | awk '{printf " %8s %s\n", $1, $2}'
|
||||
echo ""
|
||||
|
||||
echo "🔍 Large Files (>1GB) in Home:"
|
||||
echo " Searching... (this may take a moment)"
|
||||
find ~ -size +1G -type f 2>/dev/null | head -10 | while read file; do
|
||||
SIZE=$(du -h "$file" 2>/dev/null | awk '{print $1}')
|
||||
echo " $SIZE $file"
|
||||
done
|
||||
echo ""
|
||||
|
||||
echo "📁 Large Directories in Documents (40GB):"
|
||||
du -h -d 1 ~/Documents 2>/dev/null | sort -hr | head -10 | awk '{printf " %8s %s\n", $1, $2}'
|
||||
echo ""
|
||||
|
||||
echo "📚 Large Directories in Library (33GB):"
|
||||
du -h -d 1 ~/Library 2>/dev/null | sort -hr | head -10 | awk '{printf " %8s %s\n", $1, $2}'
|
||||
echo ""
|
||||
|
||||
echo "💾 Other Large Locations:"
|
||||
echo " .local: $(du -sh ~/.local 2>/dev/null | awk '{print $1}')"
|
||||
echo " .ollama: $(du -sh ~/.ollama 2>/dev/null | awk '{print $1}')"
|
||||
echo " Downloads: $(du -sh ~/Downloads 2>/dev/null | awk '{print $1}')"
|
||||
echo ""
|
||||
|
||||
echo "=== Questions ==="
|
||||
echo ""
|
||||
echo "1. Where exactly did you delete the 20GB from?"
|
||||
echo " - Was it from ~/Movies? (currently 6.7GB)"
|
||||
echo " - Or another location?"
|
||||
echo ""
|
||||
echo "2. Did you verify the files were actually deleted?"
|
||||
echo " - Check the original location"
|
||||
echo " - Check Trash (currently empty)"
|
||||
echo ""
|
||||
echo "3. The container shows 493.5GB used:"
|
||||
echo " - Data volume: 471.8GB"
|
||||
echo " - System volume: 12.2GB"
|
||||
echo " - Preboot: 8.1GB"
|
||||
echo " - Recovery: 1.2GB"
|
||||
echo ""
|
||||
echo " Your home directory is 130GB, but the Data volume is 471.8GB"
|
||||
echo " This means there are other users or system files using space."
|
||||
echo ""
|
||||
|
||||
echo "=== Recommendations ==="
|
||||
echo ""
|
||||
echo "To free space immediately:"
|
||||
echo ""
|
||||
echo "1. Clean Downloads: $(du -sh ~/Downloads 2>/dev/null | awk '{print $1}')"
|
||||
echo " rm -rf ~/Downloads/*"
|
||||
echo ""
|
||||
echo "2. Clean Library Caches:"
|
||||
echo " rm -rf ~/Library/Caches/*"
|
||||
echo ""
|
||||
echo "3. Review Documents folder (40GB):"
|
||||
echo " Move large files to NAS"
|
||||
echo ""
|
||||
echo "4. Review .ollama folder (17GB):"
|
||||
echo " Remove unused AI models"
|
||||
echo ""
|
||||
echo "5. Use macOS Storage Management:"
|
||||
echo " Apple Menu → About This Mac → Storage → Manage"
|
||||
echo ""
|
||||
@@ -1,110 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Find Real 351GB Usage in System Data
|
||||
# Since purgeable space test failed, the space is actually being used
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Find Real 351GB Usage in System Data ==="
|
||||
echo ""
|
||||
echo "The 50GB file creation FAILED, which means:"
|
||||
echo " - The 351GB is NOT purgeable"
|
||||
echo " - It's actually being used"
|
||||
echo " - We need to find what's using it"
|
||||
echo ""
|
||||
|
||||
echo "📊 Container Analysis:"
|
||||
CONTAINER_TOTAL=$(diskutil info / | grep 'Container Total' | awk '{print $4, $5}')
|
||||
CONTAINER_FREE=$(diskutil info / | grep 'Container Free' | awk '{print $4, $5}')
|
||||
CONTAINER_USED=$(diskutil apfs list 2>/dev/null | grep "Capacity In Use" | awk '{print $6, $7}')
|
||||
|
||||
echo " Container Total: $CONTAINER_TOTAL"
|
||||
echo " Container Free: $CONTAINER_FREE"
|
||||
echo " Container Used: $CONTAINER_USED"
|
||||
echo ""
|
||||
|
||||
echo "📦 APFS Volume Breakdown:"
|
||||
diskutil apfs list 2>/dev/null | grep -E "Volume|Capacity Consumed" | while read line; do
|
||||
if echo "$line" | grep -q "Volume"; then
|
||||
VOL_NAME=$(echo "$line" | sed 's/.*Name: *\([^(]*\).*/\1/')
|
||||
echo " Volume: $VOL_NAME"
|
||||
elif echo "$line" | grep -q "Capacity Consumed"; then
|
||||
SIZE=$(echo "$line" | awk '{print $3, $4}')
|
||||
echo " Size: $SIZE"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
echo "📸 APFS Snapshots:"
|
||||
APFS_SNAPS=$(diskutil apfs listSnapshots / 2>/dev/null)
|
||||
if [ -n "$APFS_SNAPS" ]; then
|
||||
echo "$APFS_SNAPS" | head -20 | sed 's/^/ /'
|
||||
echo ""
|
||||
echo " ⚠️ The OS update snapshot may be holding space"
|
||||
echo " This snapshot is NOT purgeable and can't be deleted"
|
||||
else
|
||||
echo " No snapshots found"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "🔍 Large System Directories:"
|
||||
echo " /System:"
|
||||
sudo du -h -d 2 /System/Volumes/Data/System 2>/dev/null | sort -hr | head -5 | awk '{printf " %8s %s\n", $1, $2}'
|
||||
echo ""
|
||||
echo " /Library:"
|
||||
sudo du -h -d 2 /System/Volumes/Data/Library 2>/dev/null | sort -hr | head -5 | awk '{printf " %8s %s\n", $1, $2}'
|
||||
echo ""
|
||||
|
||||
echo "🔍 Searching for large files (>10GB)..."
|
||||
echo " (This may take a moment)"
|
||||
LARGE_FILES=$(sudo find /System/Volumes/Data -type f -size +10G 2>/dev/null | head -5)
|
||||
if [ -n "$LARGE_FILES" ]; then
|
||||
echo "$LARGE_FILES" | while read file; do
|
||||
SIZE=$(sudo du -h "$file" 2>/dev/null | awk '{print $1}')
|
||||
echo " $SIZE $file"
|
||||
done
|
||||
else
|
||||
echo " No files >10GB found"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=== Analysis ==="
|
||||
echo ""
|
||||
echo "The 351GB in System Data is likely:"
|
||||
echo ""
|
||||
echo "1. **APFS Snapshot Overhead** (Most Likely)"
|
||||
echo " - The OS update snapshot (12.2GB visible)"
|
||||
echo " - May be holding 300+ GB of deleted file space"
|
||||
echo " - APFS snapshots preserve deleted files"
|
||||
echo " - This space is NOT purgeable until snapshot is deleted"
|
||||
echo ""
|
||||
echo "2. **Time Machine Local Snapshots**"
|
||||
echo " - The stuck snapshot entry"
|
||||
echo " - May be holding space even though it's a 'ghost'"
|
||||
echo ""
|
||||
echo "3. **System Reserved Space**"
|
||||
echo " - macOS reserves space for operations"
|
||||
echo " - Shown in System Data but not easily identifiable"
|
||||
echo ""
|
||||
|
||||
echo "=== Solution ==="
|
||||
echo ""
|
||||
echo "The OS update snapshot CANNOT be deleted (it's required)."
|
||||
echo "However, you can try:"
|
||||
echo ""
|
||||
echo "1. **Update macOS** (if available):"
|
||||
echo " System Settings → General → Software Update"
|
||||
echo " Installing updates may clear old snapshots"
|
||||
echo ""
|
||||
echo "2. **Check for macOS Install Data** (11GB found):"
|
||||
echo " sudo rm -rf /System/Volumes/Data/macOS\ Install\ Data"
|
||||
echo " (Safe to delete after installation completes)"
|
||||
echo ""
|
||||
echo "3. **The space may be in APFS snapshot overhead**:"
|
||||
echo " This is space held by the OS update snapshot"
|
||||
echo " It will be released when you update macOS"
|
||||
echo ""
|
||||
echo "4. **Check Storage Management for details**:"
|
||||
echo " Apple Menu → About This Mac → Storage"
|
||||
echo " Hover over 'System Data' for more details"
|
||||
echo ""
|
||||
@@ -1,78 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Find Real Space Usage
|
||||
# The snapshot is a ghost - find what's actually using space
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Find Real Space Usage ==="
|
||||
echo ""
|
||||
echo "Your container is 99.8% full (493.4GB used, 995MB free)"
|
||||
echo "The snapshot is a ghost entry (0GB)."
|
||||
echo "Let's find what's ACTUALLY using the space..."
|
||||
echo ""
|
||||
|
||||
echo "📊 Container Breakdown:"
|
||||
echo " Container Total: 494.4GB"
|
||||
echo " Container Used: 493.4GB (99.8%)"
|
||||
echo " Container Free: 995MB"
|
||||
echo ""
|
||||
|
||||
echo "🔍 Large Directories in /System/Volumes/Data:"
|
||||
sudo du -h -d 1 /System/Volumes/Data 2>/dev/null | sort -hr | head -10 | awk '{printf " %8s %s\n", $1, $2}'
|
||||
echo ""
|
||||
|
||||
# Check the suspicious Volumes directory
|
||||
VOLUMES_SIZE=$(sudo du -sh /System/Volumes/Data/Volumes 2>/dev/null | awk '{print $1}')
|
||||
echo "⚠️ CRITICAL FINDING:"
|
||||
echo " /System/Volumes/Data/Volumes: $VOLUMES_SIZE"
|
||||
echo ""
|
||||
echo " This directory is HUGE and likely contains:"
|
||||
echo " - Old Time Machine backup volumes"
|
||||
echo " - Mounted disk images"
|
||||
echo " - Stale mount points"
|
||||
echo ""
|
||||
|
||||
echo "🔍 Checking what's in /System/Volumes/Data/Volumes:"
|
||||
ls -la /System/Volumes/Data/Volumes/ 2>/dev/null | head -20 | sed 's/^/ /'
|
||||
echo ""
|
||||
|
||||
# Check for old backup volumes
|
||||
echo "📦 Checking for old Time Machine backup volumes:"
|
||||
BACKUP_VOLS=$(ls -d "/System/Volumes/Data/Volumes/Backups of"* 2>/dev/null || echo "")
|
||||
if [ -n "$BACKUP_VOLS" ]; then
|
||||
echo " Found old backup volumes:"
|
||||
echo "$BACKUP_VOLS" | while read vol; do
|
||||
SIZE=$(sudo du -sh "$vol" 2>/dev/null | awk '{print $1}')
|
||||
echo " - $vol ($SIZE)"
|
||||
done
|
||||
echo ""
|
||||
echo " ⚠️ These are likely old Time Machine backups taking up space!"
|
||||
else
|
||||
echo " No obvious backup volumes found"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check home directory
|
||||
echo "📁 Your Home Directory:"
|
||||
du -h -d 1 ~ 2>/dev/null | sort -hr | head -10 | awk '{printf " %8s %s\n", $1, $2}'
|
||||
echo ""
|
||||
|
||||
# Summary
|
||||
echo "=== Summary ==="
|
||||
echo ""
|
||||
echo "The snapshot is NOT the problem (it's a ghost, 0GB)."
|
||||
echo ""
|
||||
echo "The REAL problem:"
|
||||
echo " - Container is 99.8% full"
|
||||
echo " - /System/Volumes/Data/Volumes is $VOLUMES_SIZE (likely old backups)"
|
||||
echo " - Your home: 130GB"
|
||||
echo ""
|
||||
echo "To free space, you need to:"
|
||||
echo " 1. Check what's in /System/Volumes/Data/Volumes"
|
||||
echo " 2. Remove old backup volumes if found"
|
||||
echo " 3. Clean up your home directory:"
|
||||
echo " - Downloads: 8.7GB"
|
||||
echo " - Documents: 40GB"
|
||||
echo " - Library: 33GB"
|
||||
echo ""
|
||||
@@ -1,129 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Find What's in System Data (351GB)
|
||||
# System Data includes snapshots, caches, logs, VM files, etc.
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Find System Data Usage (351GB) ==="
|
||||
echo ""
|
||||
echo "System Data on macOS includes:"
|
||||
echo " - APFS snapshots"
|
||||
echo " - Time Machine local snapshots"
|
||||
echo " - Virtual memory swap files"
|
||||
echo " - System caches"
|
||||
echo " - Log files"
|
||||
echo " - Purgeable space"
|
||||
echo ""
|
||||
|
||||
TOTAL_FOUND=0
|
||||
|
||||
echo "🔍 Checking System Data Components:"
|
||||
echo ""
|
||||
|
||||
# 1. Check APFS snapshots
|
||||
echo "1. APFS Snapshots:"
|
||||
APFS_SNAPS=$(diskutil apfs listSnapshots / 2>/dev/null | grep -c "Name:" || echo "0")
|
||||
echo " Found: $APFS_SNAPS snapshot(s)"
|
||||
if [ "$APFS_SNAPS" -gt 0 ]; then
|
||||
diskutil apfs listSnapshots / 2>/dev/null | grep -E "Name|Purgeable" | head -4 | sed 's/^/ /'
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 2. Check Time Machine local snapshots
|
||||
echo "2. Time Machine Local Snapshots:"
|
||||
TM_SNAPS=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$" | wc -l | tr -d ' ')
|
||||
echo " Found: $TM_SNAPS snapshot(s)"
|
||||
if [ "$TM_SNAPS" -gt 0 ]; then
|
||||
tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$" | sed 's/^/ - /'
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 3. Check virtual memory (swap files)
|
||||
echo "3. Virtual Memory (Swap Files):"
|
||||
VM_SIZE=$(sudo du -sh /private/var/vm 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " /private/var/vm: $VM_SIZE"
|
||||
echo ""
|
||||
|
||||
# 4. Check system caches
|
||||
echo "4. System Caches:"
|
||||
CACHE_SIZE=$(sudo du -sh /private/var/folders 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " /private/var/folders: $CACHE_SIZE"
|
||||
echo ""
|
||||
|
||||
# 5. Check logs
|
||||
echo "5. System Logs:"
|
||||
LOG_SIZE=$(sudo du -sh /Library/Logs /private/var/log 2>/dev/null 2>/dev/null | awk '{sum+=$1} END {print sum}' || echo "0")
|
||||
echo " Logs: ~$LOG_SIZE"
|
||||
echo ""
|
||||
|
||||
# 6. Check MobileBackups
|
||||
echo "6. MobileBackups (APFS Local Snapshots):"
|
||||
MB_SIZE=$(sudo du -sh /System/Volumes/Data/.MobileBackups /.MobileBackups 2>/dev/null | awk '{sum+=$1} END {print sum}' || echo "0")
|
||||
if [ "$MB_SIZE" != "0" ] && [ -n "$MB_SIZE" ]; then
|
||||
echo " MobileBackups: $MB_SIZE"
|
||||
else
|
||||
echo " MobileBackups: Not found or empty"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 7. Check /private/var
|
||||
echo "7. /private/var (System Data):"
|
||||
PVAR_SIZE=$(sudo du -sh /System/Volumes/Data/private/var 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " /private/var: $PVAR_SIZE"
|
||||
echo ""
|
||||
|
||||
# 8. Check for sparse bundles
|
||||
echo "8. Sparse Bundles (Disk Images):"
|
||||
SPARSE_COUNT=$(sudo find /System/Volumes/Data -maxdepth 3 -name "*.sparsebundle" -o -name "*.sparseimage" 2>/dev/null | wc -l | tr -d ' ')
|
||||
echo " Found: $SPARSE_COUNT sparse bundle(s)"
|
||||
if [ "$SPARSE_COUNT" -gt 0 ]; then
|
||||
sudo find /System/Volumes/Data -maxdepth 3 -name "*.sparsebundle" -o -name "*.sparseimage" 2>/dev/null | head -5 | while read bundle; do
|
||||
SIZE=$(sudo du -sh "$bundle" 2>/dev/null | awk '{print $1}')
|
||||
echo " - $bundle ($SIZE)"
|
||||
done
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 9. Check Library
|
||||
echo "9. System Library:"
|
||||
LIB_SIZE=$(sudo du -sh /System/Volumes/Data/Library 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " /Library: $LIB_SIZE"
|
||||
echo ""
|
||||
|
||||
echo "=== Summary ==="
|
||||
echo ""
|
||||
echo "System Data is 351GB. The components above may not add up to 351GB"
|
||||
echo "because System Data also includes:"
|
||||
echo " - Purgeable space (not shown in du)"
|
||||
echo " - APFS snapshot overhead"
|
||||
echo " - Reserved space"
|
||||
echo " - Other system files"
|
||||
echo ""
|
||||
|
||||
echo "🔧 To Reduce System Data:"
|
||||
echo ""
|
||||
echo "1. Delete Time Machine local snapshots:"
|
||||
if [ "$TM_SNAPS" -gt 0 ]; then
|
||||
echo " sudo tmutil deletelocalsnapshots <date>"
|
||||
else
|
||||
echo " (No snapshots found)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "2. Thin local snapshots:"
|
||||
echo " sudo tmutil thinlocalsnapshots / 1000000000 1"
|
||||
echo ""
|
||||
|
||||
echo "3. Remove Time Machine destination (prevents new snapshots):"
|
||||
echo " System Settings → Time Machine → Remove backup disk"
|
||||
echo ""
|
||||
|
||||
echo "4. Clean system caches:"
|
||||
echo " sudo rm -rf /private/var/folders/*"
|
||||
echo " (⚠️ Be careful - this may affect running apps)"
|
||||
echo ""
|
||||
|
||||
echo "5. Restart your Mac:"
|
||||
echo " This often releases purgeable space and snapshots"
|
||||
echo ""
|
||||
@@ -1,146 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Find Time Machine System Files
|
||||
# This script identifies Time Machine files in system locations that may be taking up 100GB+
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Time Machine System Files Finder ==="
|
||||
echo ""
|
||||
echo "Searching for Time Machine files in system locations..."
|
||||
echo ""
|
||||
|
||||
TOTAL_SIZE=0
|
||||
|
||||
# Function to check and report size
|
||||
check_location() {
|
||||
local path=$1
|
||||
local description=$2
|
||||
|
||||
if [ -e "$path" ]; then
|
||||
SIZE=$(sudo du -sh "$path" 2>/dev/null | awk '{print $1}')
|
||||
SIZE_BYTES=$(sudo du -sb "$path" 2>/dev/null | awk '{print $1}')
|
||||
if [ -n "$SIZE_BYTES" ] && [ "$SIZE_BYTES" -gt 0 ]; then
|
||||
echo " ✓ $description: $SIZE"
|
||||
echo " Path: $path"
|
||||
TOTAL_SIZE=$((TOTAL_SIZE + SIZE_BYTES))
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
echo "🔍 Checking Time Machine locations:"
|
||||
echo ""
|
||||
|
||||
# 1. Local snapshots
|
||||
echo "1. Local Snapshots:"
|
||||
SNAPSHOTS=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$" | wc -l | tr -d ' ')
|
||||
if [ "$SNAPSHOTS" -gt 0 ]; then
|
||||
echo " Found $SNAPSHOTS snapshot(s):"
|
||||
tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$" | while read snapshot; do
|
||||
echo " - $snapshot"
|
||||
# Get snapshot size (requires root)
|
||||
SNAP_SIZE=$(sudo tmutil calculatedrift "$snapshot" 2>/dev/null | grep -i "size" | tail -1 || echo "")
|
||||
if [ -n "$SNAP_SIZE" ]; then
|
||||
echo " $SNAP_SIZE"
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo " No local snapshots found"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 2. MobileBackups (APFS snapshots location)
|
||||
echo "2. MobileBackups (APFS Snapshots):"
|
||||
check_location "/System/Volumes/Data/.MobileBackups" "MobileBackups (newer macOS)"
|
||||
check_location "/.MobileBackups" "MobileBackups (older macOS)"
|
||||
check_location "/private/var/.MobileBackups" "MobileBackups (alternate location)"
|
||||
echo ""
|
||||
|
||||
# 3. Time Machine sparse bundles in system locations
|
||||
echo "3. Time Machine Sparse Bundles:"
|
||||
find /private/var -name "*.sparsebundle" -o -name "*.sparseimage" 2>/dev/null | while read bundle; do
|
||||
if [ -e "$bundle" ]; then
|
||||
SIZE=$(sudo du -sh "$bundle" 2>/dev/null | awk '{print $1}')
|
||||
echo " Found: $bundle ($SIZE)"
|
||||
fi
|
||||
done
|
||||
find /System/Volumes/Data -maxdepth 3 -name "*.sparsebundle" -o -name "*.sparseimage" 2>/dev/null | while read bundle; do
|
||||
if [ -e "$bundle" ]; then
|
||||
SIZE=$(sudo du -sh "$bundle" 2>/dev/null | awk '{print $1}')
|
||||
echo " Found: $bundle ($SIZE)"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
# 4. Time Machine preferences and data
|
||||
echo "4. Time Machine System Data:"
|
||||
check_location "/Library/Preferences/com.apple.TimeMachine.plist" "Time Machine preferences"
|
||||
check_location "/private/var/db/timezone" "Timezone data (may contain backups)"
|
||||
echo ""
|
||||
|
||||
# 5. Check for old backup files in /private/var
|
||||
echo "5. System Backup Directories:"
|
||||
check_location "/private/var/backups" "System backups"
|
||||
check_location "/private/var/db" "Database files (may contain backup data)"
|
||||
echo ""
|
||||
|
||||
# 6. Check for Time Machine logs (usually small but let's check)
|
||||
echo "6. Time Machine Logs:"
|
||||
LOG_SIZE=$(sudo du -sh /private/var/log/com.apple.TimeMachine* 2>/dev/null | awk '{sum+=$1} END {print sum}' || echo "0")
|
||||
if [ "$LOG_SIZE" != "0" ] && [ -n "$LOG_SIZE" ]; then
|
||||
echo " Log files: $LOG_SIZE"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 7. Check System/Volumes/Data for large Time Machine related files
|
||||
echo "7. System Volumes Data:"
|
||||
echo " Checking for large directories in /System/Volumes/Data..."
|
||||
sudo du -h -d 2 /System/Volumes/Data 2>/dev/null | grep -i "timemachine\|backup\|snapshot" | sort -hr | head -10 | while read line; do
|
||||
echo " $line"
|
||||
done
|
||||
echo ""
|
||||
|
||||
# 8. Check for old Time Machine destinations
|
||||
echo "8. Time Machine Backup Destinations:"
|
||||
tmutil listbackups 2>/dev/null | head -5
|
||||
BACKUP_COUNT=$(tmutil listbackups 2>/dev/null | wc -l | tr -d ' ')
|
||||
if [ "$BACKUP_COUNT" -gt 0 ]; then
|
||||
echo " Total backups listed: $BACKUP_COUNT"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 9. Check disk space breakdown
|
||||
echo "9. Disk Space Analysis:"
|
||||
echo " Running disk space analysis..."
|
||||
df -h / | tail -1
|
||||
echo ""
|
||||
|
||||
# 10. Check what macOS Storage Management shows
|
||||
echo "10. System Files Category:"
|
||||
echo " 💡 To see what macOS considers 'System Files':"
|
||||
echo " Apple Menu → About This Mac → Storage → Manage"
|
||||
echo " Look under 'System Files' category"
|
||||
echo ""
|
||||
|
||||
# Summary
|
||||
echo "=== Summary ==="
|
||||
echo ""
|
||||
echo "To find the 100GB+ of Time Machine system files:"
|
||||
echo ""
|
||||
echo "1. Check macOS Storage Management:"
|
||||
echo " Apple Menu → About This Mac → Storage → Manage → System Files"
|
||||
echo ""
|
||||
echo "2. Check for local snapshots (APFS snapshots):"
|
||||
echo " tmutil listlocalsnapshots /"
|
||||
echo " sudo tmutil listlocalsnapshots /"
|
||||
echo ""
|
||||
echo "3. Check MobileBackups:"
|
||||
echo " sudo du -sh /.MobileBackups"
|
||||
echo " sudo du -sh /System/Volumes/Data/.MobileBackups"
|
||||
echo ""
|
||||
echo "4. Find all sparse bundles:"
|
||||
echo " sudo find / -name '*.sparsebundle' -o -name '*.sparseimage' 2>/dev/null"
|
||||
echo ""
|
||||
echo "5. Check system volumes:"
|
||||
echo " sudo du -h -d 1 /System/Volumes/Data | sort -hr | head -20"
|
||||
echo ""
|
||||
@@ -1,124 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Fix: Free Space After Deleting Files
|
||||
# When you delete files but don't see space back, this script fixes it
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Fix: Free Space After Deleting Files ==="
|
||||
echo ""
|
||||
echo "This script handles the common issue where deleted files don't free up space"
|
||||
echo "because APFS snapshots are holding onto them."
|
||||
echo ""
|
||||
|
||||
# Check current free space
|
||||
FREE_SPACE_BEFORE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_BEFORE=$(echo "scale=2; $FREE_SPACE_BEFORE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB_BEFORE}GB"
|
||||
echo ""
|
||||
|
||||
# Check for Time Machine local snapshots
|
||||
echo "📸 Checking for Time Machine local snapshots..."
|
||||
TM_SNAPSHOTS=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$")
|
||||
if [ -n "$TM_SNAPSHOTS" ]; then
|
||||
echo " Found snapshot(s) that may be holding space:"
|
||||
echo "$TM_SNAPSHOTS" | sed 's/^/ - /'
|
||||
echo ""
|
||||
|
||||
read -p "Delete these snapshots to free space? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo ""
|
||||
echo "🗑️ Deleting snapshots..."
|
||||
|
||||
# Disable local snapshots first (helps with stuck snapshots)
|
||||
echo " 1. Disabling local snapshots..."
|
||||
sudo tmutil disablelocal 2>/dev/null || true
|
||||
sleep 2
|
||||
|
||||
# Delete each snapshot
|
||||
echo " 2. Deleting snapshots..."
|
||||
echo "$TM_SNAPSHOTS" | while read snapshot; do
|
||||
if [ -n "$snapshot" ]; then
|
||||
# Extract date part from snapshot name
|
||||
SNAP_DATE=$(echo "$snapshot" | sed 's/.*\.\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}\)\.backup/\1/')
|
||||
if [ -n "$SNAP_DATE" ]; then
|
||||
echo " Deleting: $snapshot"
|
||||
sudo tmutil deletelocalsnapshots "$SNAP_DATE" 2>/dev/null && \
|
||||
echo " ✓ Deleted" || \
|
||||
echo " ⚠️ Could not delete (may need restart)"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Try to thin all snapshots
|
||||
echo " 3. Thinning all local snapshots..."
|
||||
sudo tmutil thinlocalsnapshots / 1000000000 4 2>/dev/null || true
|
||||
|
||||
# Re-enable local snapshots
|
||||
echo " 4. Re-enabling local snapshots..."
|
||||
sleep 2
|
||||
sudo tmutil enablelocal 2>/dev/null || true
|
||||
|
||||
echo " ✓ Snapshot cleanup completed"
|
||||
fi
|
||||
else
|
||||
echo " ✓ No Time Machine snapshots found"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Force purge of memory and disk caches
|
||||
echo "🧹 Purging system caches..."
|
||||
if command -v purge &> /dev/null; then
|
||||
sudo purge
|
||||
echo " ✓ Purge completed"
|
||||
else
|
||||
echo " ⚠️ Purge command not available"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Wait a moment for system to update
|
||||
echo "⏳ Waiting for system to update disk space..."
|
||||
sleep 5
|
||||
|
||||
# Check new free space
|
||||
FREE_SPACE_AFTER=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_AFTER=$(echo "scale=2; $FREE_SPACE_AFTER / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $FREE_SPACE_GB_AFTER - $FREE_SPACE_GB_BEFORE" | bc)
|
||||
|
||||
echo ""
|
||||
echo "=== Results ==="
|
||||
echo " Before: ${FREE_SPACE_GB_BEFORE}GB free"
|
||||
echo " After: ${FREE_SPACE_GB_AFTER}GB free"
|
||||
if (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo " ✅ Freed: ${FREED_GB}GB"
|
||||
else
|
||||
echo " ⚠️ No space freed yet"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
if (( $(echo "$FREED_GB < 15" | bc -l) )) && (( $(echo "$FREE_SPACE_GB_AFTER < 5" | bc -l) )); then
|
||||
echo "⚠️ If space still not freed, try these steps:"
|
||||
echo ""
|
||||
echo "1. **Restart your Mac** - This is often the most effective solution."
|
||||
echo " Snapshots are sometimes only released after a restart."
|
||||
echo ""
|
||||
echo "2. Check if Time Machine is trying to connect:"
|
||||
echo " - Open System Settings → Time Machine"
|
||||
echo " - If it says 'Connecting...', wait for it to finish or disconnect"
|
||||
echo " - Then try deleting snapshots again"
|
||||
echo ""
|
||||
echo "3. Manually delete the snapshot after disabling Time Machine:"
|
||||
echo " sudo tmutil disablelocal"
|
||||
echo " sudo tmutil deletelocalsnapshots <date>"
|
||||
echo " sudo tmutil enablelocal"
|
||||
echo ""
|
||||
echo "4. Use macOS Storage Management:"
|
||||
echo " Apple Menu → About This Mac → Storage → Manage"
|
||||
echo " This tool can identify and remove large system files"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Fix Oracle server firewall for WireGuard forwarding
|
||||
echo "Fixing Oracle server firewall rules..."
|
||||
|
||||
ssh server2 "sudo iptables -I FORWARD -i wg0 -j ACCEPT"
|
||||
ssh server2 "sudo iptables -I FORWARD -o wg0 -j ACCEPT"
|
||||
ssh server2 "sudo iptables -I FORWARD -s 10.0.0.0/24 -d 192.168.1.0/24 -j ACCEPT"
|
||||
|
||||
echo "Firewall rules applied successfully!"
|
||||
echo "Test connection: curl -I http://192.168.1.172:5000/"
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Fix iPhone Mirroring connection issues
|
||||
|
||||
set -e
|
||||
|
||||
echo "🔧 Fixing iPhone Mirroring issues..."
|
||||
echo ""
|
||||
|
||||
# Check macOS version
|
||||
echo "📱 Checking macOS version..."
|
||||
MACOS_VERSION=$(sw_vers -productVersion | cut -d. -f1)
|
||||
if [ "$MACOS_VERSION" -lt 15 ]; then
|
||||
echo "❌ Error: iPhone Mirroring requires macOS Sequoia 15.0 or later"
|
||||
echo " Current version: $(sw_vers -productVersion)"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ macOS version OK: $(sw_vers -productVersion)"
|
||||
echo ""
|
||||
|
||||
# Enable Handoff/Continuity
|
||||
echo "🔄 Enabling Handoff and Continuity features..."
|
||||
defaults write com.apple.coreservices.useractivityd.plist ActivityAdvertisingAllowed -bool true
|
||||
defaults write com.apple.coreservices.useractivityd.plist ActivityReceivingAllowed -bool true
|
||||
echo "✅ Handoff enabled"
|
||||
echo ""
|
||||
|
||||
# Restart Continuity services
|
||||
echo "🔄 Restarting Continuity services..."
|
||||
killall sharingd 2>/dev/null || true
|
||||
killall bluetoothd 2>/dev/null || true
|
||||
sleep 2
|
||||
|
||||
# Restart Bluetooth daemon
|
||||
echo "🔄 Restarting Bluetooth..."
|
||||
sudo launchctl stop com.apple.bluetoothd 2>/dev/null || true
|
||||
sleep 1
|
||||
sudo launchctl start com.apple.bluetoothd 2>/dev/null || true
|
||||
echo "✅ Services restarted"
|
||||
echo ""
|
||||
|
||||
# Check Bluetooth and Wi-Fi status
|
||||
echo "📡 Checking connectivity..."
|
||||
BLUETOOTH_STATUS=$(system_profiler SPBluetoothDataType 2>/dev/null | grep -i "state" | head -1 | grep -i "on" && echo "On" || echo "Off")
|
||||
WIFI_STATUS=$(networksetup -getairportpower en0 2>/dev/null | grep -i "on" && echo "On" || echo "Off")
|
||||
|
||||
if [ "$BLUETOOTH_STATUS" = "On" ]; then
|
||||
echo "✅ Bluetooth is enabled"
|
||||
else
|
||||
echo "⚠️ Bluetooth is disabled - please enable it in System Settings"
|
||||
fi
|
||||
|
||||
if [ "$WIFI_STATUS" = "On" ]; then
|
||||
echo "✅ Wi-Fi is enabled"
|
||||
else
|
||||
echo "⚠️ Wi-Fi is disabled - please enable it in System Settings"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Verify Handoff settings
|
||||
echo "✅ Verifying Handoff settings..."
|
||||
ADVERTISING=$(defaults read com.apple.coreservices.useractivityd.plist ActivityAdvertisingAllowed 2>/dev/null || echo "false")
|
||||
RECEIVING=$(defaults read com.apple.coreservices.useractivityd.plist ActivityReceivingAllowed 2>/dev/null || echo "false")
|
||||
|
||||
if [ "$ADVERTISING" = "1" ] && [ "$RECEIVING" = "1" ]; then
|
||||
echo "✅ Handoff is properly configured"
|
||||
else
|
||||
echo "❌ Handoff configuration incomplete"
|
||||
echo " ActivityAdvertisingAllowed: $ADVERTISING"
|
||||
echo " ActivityReceivingAllowed: $RECEIVING"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✅ Fix script completed!"
|
||||
echo ""
|
||||
echo "📋 Next steps:"
|
||||
echo " 1. Make sure your iPhone is:"
|
||||
echo " - Running iOS 18.0 or later"
|
||||
echo " - Unlocked and near this Mac"
|
||||
echo " - Signed in to the SAME iCloud account"
|
||||
echo " - Has Bluetooth and Wi-Fi enabled"
|
||||
echo ""
|
||||
echo " 2. Restart your Mac (recommended):"
|
||||
echo " sudo reboot"
|
||||
echo ""
|
||||
echo " 3. After restart, try iPhone Mirroring again"
|
||||
echo ""
|
||||
echo " 4. If still not working, check:"
|
||||
echo " - System Settings → General → AirDrop & Handoff"
|
||||
echo " → Ensure 'Handoff' is enabled"
|
||||
echo " - System Settings → Privacy & Security → Bluetooth"
|
||||
echo " → Ensure Bluetooth access is granted"
|
||||
echo " - System Settings → Network → Firewall"
|
||||
echo " → Temporarily disable to test"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
# Fix Network Security Group (NSG) Rules
|
||||
|
||||
## The Problem
|
||||
Your instance has a **Network Security Group (NSG)** called `ig-quick-action-NSG` that might be blocking traffic even though Security List rules are added.
|
||||
|
||||
Oracle Cloud has **two firewall layers**:
|
||||
1. **Security Lists** (VCN level) - ✅ You added rules here
|
||||
2. **Network Security Groups (NSG)** (Instance level) - ❌ Might be blocking!
|
||||
|
||||
## Solution: Add Rules to NSG
|
||||
|
||||
### Step 1: Go to Network Security Group
|
||||
From your instance details page (where you saw the VNIC info):
|
||||
|
||||
1. Find **"Network security groups"** section
|
||||
2. Click on **"ig-quick-action-NSG"** (the blue link)
|
||||
3. This opens the NSG details page
|
||||
|
||||
### Step 2: Add Ingress Rules
|
||||
1. Click on **"Ingress Rules"** tab
|
||||
2. Click **"Add Ingress Rules"**
|
||||
3. Add the same 4 rules:
|
||||
|
||||
**Rule 1:**
|
||||
- Source Type: CIDR
|
||||
- Source CIDR: `0.0.0.0/0`
|
||||
- IP Protocol: TCP
|
||||
- Destination Port Range: `7890`
|
||||
- Description: `Clash HTTP Proxy`
|
||||
|
||||
**Rule 2:**
|
||||
- Source Type: CIDR
|
||||
- Source CIDR: `0.0.0.0/0`
|
||||
- IP Protocol: TCP
|
||||
- Destination Port Range: `7891`
|
||||
- Description: `Clash SOCKS5`
|
||||
|
||||
**Rule 3:**
|
||||
- Source Type: CIDR
|
||||
- Source CIDR: `0.0.0.0/0`
|
||||
- IP Protocol: TCP
|
||||
- Destination Port Range: `7892`
|
||||
- Description: `Clash Mixed`
|
||||
|
||||
**Rule 4:**
|
||||
- Source Type: CIDR
|
||||
- Source CIDR: `0.0.0.0/0`
|
||||
- IP Protocol: TCP
|
||||
- Destination Port Range: `9090`
|
||||
- Description: `Clash Web UI`
|
||||
|
||||
### Step 3: Save and Test
|
||||
1. Click **"Add Ingress Rules"**
|
||||
2. Wait 30-60 seconds
|
||||
3. Test again: `curl --proxy http://proxy_user:Cs7yBx1Rh9oK@158.101.140.85:7890 http://httpbin.org/ip`
|
||||
|
||||
## Alternative: Remove NSG (If Not Needed)
|
||||
|
||||
If you don't need the NSG:
|
||||
1. Go to instance → Primary VNIC
|
||||
2. Click **"Edit"** next to Network security groups
|
||||
3. Remove `ig-quick-action-NSG`
|
||||
4. Save
|
||||
|
||||
Then Security List rules will be enough.
|
||||
|
||||
## Quick Path
|
||||
```
|
||||
Instance Details → Primary VNIC → Network security groups → ig-quick-action-NSG → Ingress Rules → Add Ingress Rules
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
# Fix Oracle Cloud Firewall for Proxy
|
||||
|
||||
## The Problem
|
||||
Connection times out because **Oracle Cloud Security List** is blocking the ports, even though UFW allows them.
|
||||
|
||||
## Solution: Add Security List Rules in Oracle Cloud
|
||||
|
||||
### Method 1: Via Web Console (Easiest)
|
||||
|
||||
1. **Log into Oracle Cloud Console**
|
||||
- Go to: https://cloud.oracle.com
|
||||
- Navigate to your instance
|
||||
|
||||
2. **Find Your VCN/Subnet:**
|
||||
- Go to **Networking** → **Virtual Cloud Networks**
|
||||
- Click on your VCN
|
||||
- Click on your **Subnet**
|
||||
|
||||
3. **Edit Security List:**
|
||||
- Click on **Security Lists** tab
|
||||
- Click on the default security list (or the one attached to your subnet)
|
||||
- Click **Edit All Rules**
|
||||
|
||||
4. **Add Ingress Rules:**
|
||||
Click **Add Ingress Rules** for each port:
|
||||
|
||||
**Rule 1: HTTP Proxy (7890)**
|
||||
- **Source Type:** CIDR
|
||||
- **Source CIDR:** `0.0.0.0/0` (or your IP for security)
|
||||
- **IP Protocol:** TCP
|
||||
- **Destination Port Range:** `7890`
|
||||
- **Description:** Clash HTTP Proxy
|
||||
|
||||
**Rule 2: SOCKS5 Proxy (7891)**
|
||||
- **Source Type:** CIDR
|
||||
- **Source CIDR:** `0.0.0.0/0`
|
||||
- **IP Protocol:** TCP
|
||||
- **Destination Port Range:** `7891`
|
||||
- **Description:** Clash SOCKS5 Proxy
|
||||
|
||||
**Rule 3: Mixed Proxy (7892)**
|
||||
- **Source Type:** CIDR
|
||||
- **Source CIDR:** `0.0.0.0/0`
|
||||
- **IP Protocol:** TCP
|
||||
- **Destination Port Range:** `7892`
|
||||
- **Description:** Clash Mixed Proxy
|
||||
|
||||
**Rule 4: Web UI (9090)**
|
||||
- **Source Type:** CIDR
|
||||
- **Source CIDR:** `0.0.0.0/0`
|
||||
- **IP Protocol:** TCP
|
||||
- **Destination Port Range:** `9090`
|
||||
- **Description:** Clash Web UI
|
||||
|
||||
5. **Save** the rules
|
||||
|
||||
6. **Wait 30 seconds** for rules to propagate
|
||||
|
||||
7. **Test again** from your iPhone
|
||||
|
||||
### Method 2: Via OCI CLI
|
||||
|
||||
If you have OCI CLI installed:
|
||||
|
||||
```bash
|
||||
# Get your security list OCID
|
||||
oci network security-list list --compartment-id <your-compartment-id>
|
||||
|
||||
# Add ingress rule
|
||||
oci network security-list update \
|
||||
--security-list-id <your-security-list-id> \
|
||||
--ingress-security-rules file://ingress-rules.json
|
||||
```
|
||||
|
||||
### Security Note
|
||||
|
||||
Using `0.0.0.0/0` allows access from anywhere. For better security:
|
||||
- Use your home IP: `YOUR_IP/32`
|
||||
- Or use a VPN IP range
|
||||
- The proxy has authentication, so it's somewhat protected
|
||||
|
||||
## Verify Rules Are Applied
|
||||
|
||||
After adding rules, test:
|
||||
|
||||
```bash
|
||||
# From your Mac (not iPhone)
|
||||
nc -zv 158.101.140.85 7890
|
||||
# Should show: Connection succeeded
|
||||
```
|
||||
|
||||
## Alternative: Use Tailscale Instead
|
||||
|
||||
If you don't want to open ports publicly:
|
||||
- Keep proxy on Tailscale IP only (100.70.115.1)
|
||||
- Use Tailscale VPN on iPhone
|
||||
- Access proxy via Tailscale network
|
||||
|
||||
But this requires Tailscale VPN, which conflicts with Shadowrocket VPN.
|
||||
|
||||
## Quick Checklist
|
||||
|
||||
- [ ] Logged into Oracle Cloud Console
|
||||
- [ ] Found VCN and Subnet
|
||||
- [ ] Opened Security List
|
||||
- [ ] Added ingress rules for ports 7890, 7891, 7892, 9090
|
||||
- [ ] Saved rules
|
||||
- [ ] Waited 30 seconds
|
||||
- [ ] Tested from iPhone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Fix OS Update Snapshot Issue (351GB System Data)
|
||||
# The OS update snapshot is preventing space from being freed
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Fix OS Update Snapshot Issue ==="
|
||||
echo ""
|
||||
echo "Your disk layout shows:"
|
||||
echo " - Container: 494.4 GB"
|
||||
echo " - Data volume: 472.5 GB"
|
||||
echo " - System volume: 12.2 GB"
|
||||
echo " - OS Update Snapshot: 12.2 GB (NOT purgeable)"
|
||||
echo ""
|
||||
echo "The 351GB in System Data is likely snapshot overhead"
|
||||
echo "that can't be freed until the snapshot is cleared."
|
||||
echo ""
|
||||
|
||||
FREE_SPACE_BEFORE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_BEFORE=$(echo "scale=2; $FREE_SPACE_BEFORE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB_BEFORE}GB"
|
||||
echo ""
|
||||
|
||||
echo "🔍 Checking for macOS updates..."
|
||||
UPDATES=$(softwareupdate --list 2>/dev/null | grep -i "update" | head -5)
|
||||
if [ -n "$UPDATES" ]; then
|
||||
echo " Found available updates:"
|
||||
echo "$UPDATES" | sed 's/^/ /'
|
||||
echo ""
|
||||
echo " ✅ SOLUTION: Install macOS updates"
|
||||
echo " This will create a new snapshot and clear the old one"
|
||||
echo " System Settings → General → Software Update"
|
||||
else
|
||||
echo " No updates found (or check failed)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "🔧 Immediate Space Savings:"
|
||||
echo ""
|
||||
|
||||
# Check macOS Install Data
|
||||
INSTALL_DATA="/System/Volumes/Data/macOS Install Data"
|
||||
if [ -d "$INSTALL_DATA" ]; then
|
||||
SIZE=$(sudo du -sh "$INSTALL_DATA" 2>/dev/null | awk '{print $1}')
|
||||
echo " 1. Delete macOS Install Data: $SIZE"
|
||||
echo " sudo rm -rf \"$INSTALL_DATA\""
|
||||
echo " (Safe to delete after installation completes)"
|
||||
echo ""
|
||||
read -p " Delete macOS Install Data now? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo " Deleting..."
|
||||
sudo rm -rf "$INSTALL_DATA" 2>/dev/null && \
|
||||
echo " ✅ Deleted ($SIZE freed)" || \
|
||||
echo " ⚠️ Could not delete (may be in use)"
|
||||
fi
|
||||
else
|
||||
echo " 1. macOS Install Data: Not found"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "📊 Understanding the Problem:"
|
||||
echo ""
|
||||
echo "The OS update snapshot (12.2GB visible) is holding much more"
|
||||
echo "space as 'overhead' or 'purgeable' that shows up in System Data."
|
||||
echo ""
|
||||
echo "APFS snapshots work by:"
|
||||
echo " - Preserving deleted files"
|
||||
echo " - Taking up space until cleared"
|
||||
echo " - The OS update snapshot can't be deleted manually"
|
||||
echo ""
|
||||
echo "The 351GB in System Data includes:"
|
||||
echo " - Snapshot overhead (space held by the snapshot)"
|
||||
echo " - Purgeable space (that can't be purged due to snapshot)"
|
||||
echo " - System reserved space"
|
||||
echo ""
|
||||
|
||||
echo "=== Solutions ==="
|
||||
echo ""
|
||||
echo "Option 1: Install macOS Updates (Recommended)"
|
||||
echo " - System Settings → General → Software Update"
|
||||
echo " - Install any available updates"
|
||||
echo " - This will clear the old snapshot"
|
||||
echo " - Should free the 351GB"
|
||||
echo ""
|
||||
|
||||
echo "Option 2: Wait for Automatic Cleanup"
|
||||
echo " - macOS may clear old snapshots automatically"
|
||||
echo " - But this can take weeks or months"
|
||||
echo ""
|
||||
|
||||
echo "Option 3: Free Other Space First"
|
||||
echo " - Clean Downloads: 8.7GB"
|
||||
echo " - Clean Caches: ~6GB"
|
||||
echo " - Review Documents: 40GB"
|
||||
echo " - This gives you ~55GB to work with"
|
||||
echo ""
|
||||
|
||||
echo "Option 4: Check Storage Management Details"
|
||||
echo " - Apple Menu → About This Mac → Storage"
|
||||
echo " - Hover over 'System Data' for breakdown"
|
||||
echo " - May show 'Purgeable' or 'Snapshots'"
|
||||
echo ""
|
||||
|
||||
# Check final space
|
||||
sleep 2
|
||||
FREE_SPACE_AFTER=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_AFTER=$(echo "scale=2; $FREE_SPACE_AFTER / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $FREE_SPACE_GB_AFTER - $FREE_SPACE_GB_BEFORE" | bc)
|
||||
|
||||
if (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo "✅ Freed: ${FREED_GB}GB"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,68 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Fix Photo Volume Taking 175GB
|
||||
# This is likely a mounted volume or disk image
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Fix Photo Volume (175GB) ==="
|
||||
echo ""
|
||||
echo "Found: /System/Volumes/Data/Volumes/photo is 175GB!"
|
||||
echo "This is likely what's consuming your space."
|
||||
echo ""
|
||||
|
||||
# Check what it is
|
||||
echo "🔍 Checking what 'photo' is:"
|
||||
if [ -d "/System/Volumes/Data/Volumes/photo" ]; then
|
||||
echo " It's a directory"
|
||||
SIZE=$(sudo du -sh /System/Volumes/Data/Volumes/photo 2>/dev/null | awk '{print $1}')
|
||||
echo " Size: $SIZE"
|
||||
|
||||
# Check if it's mounted
|
||||
MOUNTED=$(mount | grep photo || echo "NOT_MOUNTED")
|
||||
if [ "$MOUNTED" != "NOT_MOUNTED" ]; then
|
||||
echo " ⚠️ It's a MOUNTED volume:"
|
||||
echo "$MOUNTED" | sed 's/^/ /'
|
||||
echo ""
|
||||
echo " This is likely a disk image or network mount."
|
||||
echo " You can unmount it to free the space."
|
||||
else
|
||||
echo " It's a regular directory (not mounted)"
|
||||
echo " Contents:"
|
||||
ls -lah /System/Volumes/Data/Volumes/photo 2>/dev/null | head -10 | sed 's/^/ /'
|
||||
fi
|
||||
else
|
||||
echo " Not found or not accessible"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check if it's safe to remove
|
||||
echo "❓ Questions:"
|
||||
echo " 1. Do you have a 'photo' volume mounted?"
|
||||
echo " 2. Is this from an external drive or disk image?"
|
||||
echo " 3. Do you need this data?"
|
||||
echo ""
|
||||
|
||||
echo "🔧 Solutions:"
|
||||
echo ""
|
||||
echo "If it's a mounted volume you don't need:"
|
||||
echo " sudo umount /System/Volumes/Data/Volumes/photo"
|
||||
echo ""
|
||||
echo "If it's a directory with files you don't need:"
|
||||
echo " sudo rm -rf /System/Volumes/Data/Volumes/photo/*"
|
||||
echo ""
|
||||
echo "⚠️ WARNING: Make sure you don't need this data before deleting!"
|
||||
echo ""
|
||||
|
||||
read -p "Do you want to see what's inside? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo ""
|
||||
echo "📁 Contents of /System/Volumes/Data/Volumes/photo:"
|
||||
sudo ls -lah /System/Volumes/Data/Volumes/photo 2>/dev/null | head -20 | sed 's/^/ /'
|
||||
echo ""
|
||||
echo "📊 Top subdirectories:"
|
||||
sudo du -h -d 1 /System/Volumes/Data/Volumes/photo 2>/dev/null | sort -hr | head -10 | awk '{printf " %8s %s\n", $1, $2}'
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,113 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Fix QuickConnect 502 Error
|
||||
# HTTP ERROR 502 - Bad Gateway
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Fix QuickConnect 502 Error ==="
|
||||
echo ""
|
||||
echo "502 Bad Gateway means QuickConnect relay server"
|
||||
echo "can't reach your NAS or NAS is having issues."
|
||||
echo ""
|
||||
|
||||
echo "🔍 Diagnosing..."
|
||||
echo ""
|
||||
|
||||
# Check local network connectivity
|
||||
echo "1. Checking local network connection..."
|
||||
if ping -c 2 DS224plus.local &>/dev/null || ping -c 2 192.168.1.172 &>/dev/null; then
|
||||
echo " ✅ NAS is reachable on local network"
|
||||
LOCAL_REACHABLE=true
|
||||
else
|
||||
echo " ❌ NAS not reachable on local network"
|
||||
LOCAL_REACHABLE=false
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check SSH access
|
||||
echo "2. Checking SSH access..."
|
||||
if nas "uptime" &>/dev/null; then
|
||||
echo " ✅ Can connect via SSH"
|
||||
SSH_WORKING=true
|
||||
else
|
||||
echo " ❌ Cannot connect via SSH"
|
||||
SSH_WORKING=false
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check DSM web interface locally
|
||||
echo "3. Checking DSM web interface (local)..."
|
||||
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 http://192.168.1.172:5000 2>/dev/null || echo "000")
|
||||
if [ "$HTTP_STATUS" = "200" ] || [ "$HTTP_STATUS" = "302" ]; then
|
||||
echo " ✅ DSM web interface working locally"
|
||||
WEB_WORKING=true
|
||||
else
|
||||
echo " ❌ DSM web interface not responding (HTTP $HTTP_STATUS)"
|
||||
WEB_WORKING=false
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=== Solutions ==="
|
||||
echo ""
|
||||
|
||||
if [ "$LOCAL_REACHABLE" = true ] && [ "$WEB_WORKING" = true ]; then
|
||||
echo "✅ NAS is working locally!"
|
||||
echo ""
|
||||
echo "The 502 error is a QuickConnect issue, not your NAS."
|
||||
echo ""
|
||||
echo "Solution: Use local access instead:"
|
||||
echo ""
|
||||
echo " http://192.168.1.172:5000"
|
||||
echo " or"
|
||||
echo " http://DS224plus.local:5000"
|
||||
echo ""
|
||||
echo "QuickConnect issues are usually:"
|
||||
echo " - QuickConnect relay server problems (temporary)"
|
||||
echo " - QuickConnect service disabled on NAS"
|
||||
echo " - Network/firewall blocking QuickConnect"
|
||||
echo ""
|
||||
elif [ "$LOCAL_REACHABLE" = true ] && [ "$SSH_WORKING" = true ]; then
|
||||
echo "✅ NAS is reachable via SSH"
|
||||
echo ""
|
||||
echo "DSM web interface may be down. Check:"
|
||||
echo ""
|
||||
echo " 1. NAS may be restarting or updating"
|
||||
echo " 2. Web service may be stopped"
|
||||
echo ""
|
||||
echo "Via SSH, check:"
|
||||
echo " nas 'synoservice --status nginx'"
|
||||
echo " nas 'synoservice --status httpd-user'"
|
||||
echo ""
|
||||
else
|
||||
echo "⚠️ NAS may be down or unreachable"
|
||||
echo ""
|
||||
echo "Check:"
|
||||
echo " 1. Is NAS powered on? (Check power LED)"
|
||||
echo " 2. Is NAS connected to network? (Check network LED)"
|
||||
echo " 3. Try accessing directly: http://192.168.1.172:5000"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== QuickConnect 502 Error Fixes ==="
|
||||
echo ""
|
||||
echo "1. **Use Local Access Instead** (Recommended)"
|
||||
echo " http://192.168.1.172:5000"
|
||||
echo " This bypasses QuickConnect entirely"
|
||||
echo ""
|
||||
echo "2. **Check QuickConnect Settings**"
|
||||
echo " If you can access NAS locally:"
|
||||
echo " - Control Panel → External Access → QuickConnect"
|
||||
echo " - Make sure QuickConnect is enabled"
|
||||
echo " - Try disabling and re-enabling"
|
||||
echo ""
|
||||
echo "3. **Wait and Retry**"
|
||||
echo " QuickConnect 502 errors are often temporary"
|
||||
echo " Wait 5-10 minutes and try again"
|
||||
echo ""
|
||||
echo "4. **Check NAS Status**"
|
||||
echo " - Is NAS powered on?"
|
||||
echo " - Are status LEDs normal?"
|
||||
echo " - Try restarting NAS if needed"
|
||||
echo ""
|
||||
@@ -1,126 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Fix Stuck Time Machine Backup
|
||||
# When Time Machine is stuck trying to connect to NAS and consuming space
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Fix Stuck Time Machine Backup ==="
|
||||
echo ""
|
||||
|
||||
# Check Time Machine status
|
||||
TM_STATUS=$(tmutil status 2>/dev/null)
|
||||
echo "📊 Current Time Machine Status:"
|
||||
echo "$TM_STATUS" | grep -E "BackupPhase|Running" | sed 's/^/ /'
|
||||
echo ""
|
||||
|
||||
# Check if it's stuck
|
||||
if echo "$TM_STATUS" | grep -q "Running = 1"; then
|
||||
PHASE=$(echo "$TM_STATUS" | grep "BackupPhase" | sed 's/.*BackupPhase = \([^;]*\).*/\1/')
|
||||
echo "⚠️ Time Machine is RUNNING and stuck in phase: $PHASE"
|
||||
echo ""
|
||||
echo " This is why your space disappeared:"
|
||||
echo " - Time Machine created a local snapshot before backing up"
|
||||
echo " - It's trying to connect to NAS but can't"
|
||||
echo " - The snapshot is holding your deleted file space"
|
||||
echo ""
|
||||
|
||||
# Check current free space
|
||||
FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB=$(echo "scale=2; $FREE_SPACE / 1024 / 1024" | bc)
|
||||
echo " Current free space: ${FREE_SPACE_GB}GB"
|
||||
echo ""
|
||||
|
||||
read -p "Stop the stuck Time Machine backup? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo ""
|
||||
echo "🛑 Stopping Time Machine backup..."
|
||||
|
||||
# Stop the backup
|
||||
sudo tmutil stopbackup 2>/dev/null || {
|
||||
echo " ⚠️ Could not stop via tmutil, trying alternative method..."
|
||||
# Kill the backupd process (more aggressive)
|
||||
sudo killall backupd 2>/dev/null || true
|
||||
sleep 2
|
||||
}
|
||||
|
||||
echo " ✓ Backup stopped"
|
||||
echo ""
|
||||
|
||||
# Wait a moment
|
||||
echo "⏳ Waiting for processes to clean up..."
|
||||
sleep 5
|
||||
|
||||
# Check if it stopped
|
||||
NEW_STATUS=$(tmutil status 2>/dev/null | grep "Running" || echo "Running = 0")
|
||||
if echo "$NEW_STATUS" | grep -q "Running = 0"; then
|
||||
echo " ✅ Time Machine backup stopped"
|
||||
else
|
||||
echo " ⚠️ Backup may still be running, may need to restart"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Now try to delete the snapshot
|
||||
echo "🗑️ Attempting to delete local snapshot..."
|
||||
SNAPSHOTS=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$")
|
||||
if [ -n "$SNAPSHOTS" ]; then
|
||||
echo "$SNAPSHOTS" | while read snapshot; do
|
||||
if [ -n "$snapshot" ]; then
|
||||
SNAP_DATE=$(echo "$snapshot" | sed 's/.*\.\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}\)\.backup/\1/')
|
||||
if [ -n "$SNAP_DATE" ]; then
|
||||
echo " Deleting: $snapshot"
|
||||
if sudo tmutil deletelocalsnapshots "$SNAP_DATE" 2>/dev/null; then
|
||||
echo " ✅ Snapshot deleted!"
|
||||
else
|
||||
echo " ⚠️ Still stuck - may need to remove Time Machine destination first"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📊 Checking disk space..."
|
||||
sleep 3
|
||||
NEW_FREE=$(df / | tail -1 | awk '{print $4}')
|
||||
NEW_FREE_GB=$(echo "scale=2; $NEW_FREE / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $NEW_FREE_GB - $FREE_SPACE_GB" | bc)
|
||||
|
||||
echo " Before: ${FREE_SPACE_GB}GB free"
|
||||
echo " After: ${NEW_FREE_GB}GB free"
|
||||
if (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo " ✅ Freed: ${FREED_GB}GB"
|
||||
else
|
||||
echo " ⚠️ Space not freed yet"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=== Next Steps ==="
|
||||
echo ""
|
||||
echo "1. If space is still not freed, remove Time Machine destination:"
|
||||
echo " System Settings → Time Machine → Remove backup disk"
|
||||
echo " Then delete snapshot: sudo tmutil deletelocalsnapshots <date>"
|
||||
echo ""
|
||||
echo "2. Fix Time Machine connection issue:"
|
||||
echo " See: time_machine_troubleshooting.md"
|
||||
echo " Common fixes:"
|
||||
echo " - Clear credentials in Keychain Access"
|
||||
echo " - Unmount any manual mounts"
|
||||
echo " - Re-add Time Machine destination"
|
||||
echo ""
|
||||
echo "3. After fixing connection, re-add Time Machine:"
|
||||
echo " System Settings → Time Machine → Add Backup Disk"
|
||||
echo ""
|
||||
else
|
||||
echo "Cancelled."
|
||||
fi
|
||||
else
|
||||
echo "✅ Time Machine is not running"
|
||||
echo ""
|
||||
echo "If space is still missing, check for snapshots:"
|
||||
echo " tmutil listlocalsnapshots /"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,107 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Fix Stuck Time Machine Snapshot
|
||||
# When snapshots can't be deleted due to "Stale NFS file handle" error
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Fix Stuck Time Machine Snapshot ==="
|
||||
echo ""
|
||||
echo "This script fixes the 'Stale NFS file handle' error that prevents"
|
||||
echo "snapshot deletion. This happens when Time Machine has a stale"
|
||||
echo "connection to the backup destination."
|
||||
echo ""
|
||||
|
||||
# Check current situation
|
||||
echo "📊 Current Status:"
|
||||
FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB=$(echo "scale=2; $FREE_SPACE / 1024 / 1024" | bc)
|
||||
echo " Free space: ${FREE_SPACE_GB}GB"
|
||||
echo ""
|
||||
|
||||
SNAPSHOTS=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$")
|
||||
if [ -n "$SNAPSHOTS" ]; then
|
||||
echo " Stuck snapshots found:"
|
||||
echo "$SNAPSHOTS" | sed 's/^/ - /'
|
||||
else
|
||||
echo " ✓ No snapshots found"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🔧 Solution: Temporarily remove Time Machine destination, delete snapshot, then re-add"
|
||||
echo ""
|
||||
echo "⚠️ IMPORTANT: This will temporarily disconnect Time Machine from your NAS."
|
||||
echo " You'll need to re-add it after the snapshot is deleted."
|
||||
echo ""
|
||||
|
||||
read -p "Do you want to proceed? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Cancelled."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Step 1: Removing Time Machine destination..."
|
||||
echo ""
|
||||
echo " Please do this manually:"
|
||||
echo " 1. Open System Settings → General → Time Machine"
|
||||
echo " 2. Click the 'Remove' or '-' button next to your backup disk"
|
||||
echo " 3. Confirm removal"
|
||||
echo ""
|
||||
read -p " Have you removed the Time Machine destination? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo " Please remove it first, then run this script again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Step 2: Waiting for Time Machine to disconnect..."
|
||||
sleep 5
|
||||
|
||||
echo ""
|
||||
echo "Step 3: Attempting to delete stuck snapshot..."
|
||||
echo "$SNAPSHOTS" | while read snapshot; do
|
||||
if [ -n "$snapshot" ]; then
|
||||
# Extract date part
|
||||
SNAP_DATE=$(echo "$snapshot" | sed 's/.*\.\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}\)\.backup/\1/')
|
||||
if [ -n "$SNAP_DATE" ]; then
|
||||
echo " Deleting: $snapshot"
|
||||
if sudo tmutil deletelocalsnapshots "$SNAP_DATE" 2>/dev/null; then
|
||||
echo " ✅ Successfully deleted!"
|
||||
else
|
||||
echo " ⚠️ Still stuck. Try restarting your Mac."
|
||||
echo " After restart, run: sudo tmutil deletelocalsnapshots $SNAP_DATE"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Step 4: Checking disk space..."
|
||||
sleep 3
|
||||
NEW_FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
NEW_FREE_SPACE_GB=$(echo "scale=2; $NEW_FREE_SPACE / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $NEW_FREE_SPACE_GB - $FREE_SPACE_GB" | bc)
|
||||
|
||||
echo " New free space: ${NEW_FREE_SPACE_GB}GB"
|
||||
if (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo " ✅ Freed: ${FREED_GB}GB"
|
||||
else
|
||||
echo " ⚠️ Space not freed yet - may need restart"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Step 5: Re-adding Time Machine destination..."
|
||||
echo ""
|
||||
echo " Now re-add your Time Machine backup:"
|
||||
echo " 1. System Settings → General → Time Machine"
|
||||
echo " 2. Click 'Add Backup Disk...'"
|
||||
echo " 3. Select 'Time Machine Folder' on 'DS224plus.local'"
|
||||
echo " 4. Enter your credentials"
|
||||
echo ""
|
||||
echo " Or use the troubleshooting guide:"
|
||||
echo " See: time_machine_troubleshooting.md"
|
||||
echo ""
|
||||
@@ -1,161 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Fix System Data Growth When Deleting Files
|
||||
# This happens when APFS snapshots preserve deleted files
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Fix System Data Growth ==="
|
||||
echo ""
|
||||
echo "When you delete files but 'System Data' grows, it means:"
|
||||
echo " - APFS snapshots are preserving deleted files"
|
||||
echo " - Time Machine local snapshots are holding space"
|
||||
echo " - The deleted data is being kept for backup purposes"
|
||||
echo ""
|
||||
|
||||
FREE_SPACE_BEFORE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_BEFORE=$(echo "scale=2; $FREE_SPACE_BEFORE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB_BEFORE}GB"
|
||||
echo ""
|
||||
|
||||
# Check for snapshots
|
||||
echo "📸 Checking for snapshots..."
|
||||
TM_SNAPSHOTS=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$")
|
||||
SNAP_COUNT=$(echo "$TM_SNAPSHOTS" | grep -v "^$" | wc -l | tr -d ' ')
|
||||
|
||||
if [ "$SNAP_COUNT" -gt 0 ]; then
|
||||
echo " Found $SNAP_COUNT Time Machine snapshot(s):"
|
||||
echo "$TM_SNAPSHOTS" | sed 's/^/ - /'
|
||||
else
|
||||
echo " No Time Machine snapshots found"
|
||||
fi
|
||||
|
||||
APFS_SNAPS=$(diskutil apfs listSnapshots / 2>/dev/null | grep -c "Name:" || echo "0")
|
||||
echo " Found $APFS_SNAPS APFS snapshot(s)"
|
||||
echo ""
|
||||
|
||||
if [ "$SNAP_COUNT" -eq 0 ] && [ "$APFS_SNAPS" -le 1 ]; then
|
||||
echo "⚠️ No obvious snapshots, but System Data is still growing."
|
||||
echo " This may be due to:"
|
||||
echo " - Time Machine preparing for backup"
|
||||
echo " - System cache growth"
|
||||
echo " - Other system processes"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "🔧 Solution: Disable local snapshots and clean up"
|
||||
echo ""
|
||||
read -p "Proceed with cleanup? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Step 1: Stop Time Machine backup (if running)..."
|
||||
sudo tmutil stopbackup 2>/dev/null || true
|
||||
sleep 2
|
||||
echo " ✓ Stopped"
|
||||
echo ""
|
||||
|
||||
echo "Step 2: Delete all local snapshots..."
|
||||
if [ "$SNAP_COUNT" -gt 0 ]; then
|
||||
echo "$TM_SNAPSHOTS" | while read snapshot; do
|
||||
if [ -n "$snapshot" ]; then
|
||||
SNAP_DATE=$(echo "$snapshot" | sed 's/.*\.\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}\)\.backup/\1/')
|
||||
if [ -n "$SNAP_DATE" ]; then
|
||||
echo " Deleting: $snapshot"
|
||||
sudo tmutil deletelocalsnapshots "$SNAP_DATE" 2>/dev/null && \
|
||||
echo " ✅ Deleted" || \
|
||||
echo " ⚠️ Could not delete (may be in use)"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo " No snapshots to delete"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "Step 3: Aggressively thin all snapshots..."
|
||||
sudo tmutil thinlocalsnapshots / 1000000000 1 2>&1 || true
|
||||
echo " ✓ Thinned"
|
||||
echo ""
|
||||
|
||||
echo "Step 4: Disable local snapshots (prevents new ones)..."
|
||||
# Note: tmutil disablelocal doesn't exist in newer macOS, so we'll use a workaround
|
||||
# We'll remove Time Machine destination temporarily
|
||||
echo " ⚠️ To prevent snapshots, you need to:"
|
||||
echo " 1. Remove Time Machine destination in System Settings"
|
||||
echo " 2. Or wait for successful backup to clear snapshots"
|
||||
echo ""
|
||||
|
||||
echo "Step 5: Purge system memory and caches..."
|
||||
if command -v purge &> /dev/null; then
|
||||
sudo purge
|
||||
echo " ✓ Purged"
|
||||
else
|
||||
echo " ⚠️ Purge command not available"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "Step 6: Clean user caches..."
|
||||
rm -rf ~/Library/Caches/* 2>/dev/null || true
|
||||
echo " ✓ Cleaned"
|
||||
echo ""
|
||||
|
||||
echo "⏳ Waiting for system to update..."
|
||||
sleep 5
|
||||
|
||||
# Check results
|
||||
FREE_SPACE_AFTER=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_AFTER=$(echo "scale=2; $FREE_SPACE_AFTER / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $FREE_SPACE_GB_AFTER - $FREE_SPACE_GB_BEFORE" | bc)
|
||||
|
||||
echo ""
|
||||
echo "=== Results ==="
|
||||
echo " Before: ${FREE_SPACE_GB_BEFORE}GB free"
|
||||
echo " After: ${FREE_SPACE_GB_AFTER}GB free"
|
||||
if (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo " ✅ Freed: ${FREED_GB}GB"
|
||||
else
|
||||
echo " ⚠️ No space freed yet"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=== Critical Next Steps ==="
|
||||
echo ""
|
||||
echo "To STOP System Data from growing when you delete files:"
|
||||
echo ""
|
||||
echo "1. **Remove Time Machine destination temporarily**:"
|
||||
echo " System Settings → Time Machine → Remove backup disk"
|
||||
echo " This prevents new snapshots from being created"
|
||||
echo ""
|
||||
echo "2. **Wait 10-15 minutes** after deleting files before checking space"
|
||||
echo " macOS needs time to release snapshot space"
|
||||
echo ""
|
||||
echo "3. **After freeing space, fix Time Machine connection**:"
|
||||
echo " - Clear credentials in Keychain Access"
|
||||
echo " - Re-add Time Machine destination"
|
||||
echo " - Ensure it can successfully connect"
|
||||
echo ""
|
||||
echo "4. **Alternative: Use 'Optimize Storage' in System Settings**:"
|
||||
echo " Apple Menu → About This Mac → Storage → Optimize"
|
||||
echo " This can help release snapshot space"
|
||||
echo ""
|
||||
echo "5. **If System Data keeps growing**:"
|
||||
echo " - Restart your Mac (releases snapshots)"
|
||||
echo " - Or remove Time Machine until you have more free space"
|
||||
echo ""
|
||||
|
||||
if (( $(echo "$FREE_SPACE_GB_AFTER < 5" | bc -l) )); then
|
||||
echo "⚠️ Still critically low on space!"
|
||||
echo ""
|
||||
echo " You need to free more space before Time Machine can work."
|
||||
echo " Consider:"
|
||||
echo " - Moving large files to NAS"
|
||||
echo " - Removing unused applications"
|
||||
echo " - Cleaning Downloads folder"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,106 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Quick Fix: Free up space for Time Machine
|
||||
# This script performs safe cleanup operations to free disk space
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Time Machine Disk Space Fix ==="
|
||||
echo ""
|
||||
echo "This script will help free up space so Time Machine can work."
|
||||
echo ""
|
||||
|
||||
# Check current free space
|
||||
FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB=$(echo "scale=2; $FREE_SPACE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB}GB"
|
||||
echo ""
|
||||
|
||||
# Ask for confirmation
|
||||
read -p "Do you want to proceed with safe cleanup? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Cancelled."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🧹 Cleaning up..."
|
||||
|
||||
# 1. Empty Trash
|
||||
if [ -d ~/.Trash ] && [ "$(ls -A ~/.Trash 2>/dev/null)" ]; then
|
||||
TRASH_SIZE=$(du -sh ~/.Trash 2>/dev/null | awk '{print $1}')
|
||||
echo " Emptying Trash ($TRASH_SIZE)..."
|
||||
rm -rf ~/.Trash/* ~/.Trash/.* 2>/dev/null || true
|
||||
echo " ✓ Trash emptied"
|
||||
else
|
||||
echo " ✓ Trash already empty"
|
||||
fi
|
||||
|
||||
# 2. Clean Library Caches (safe - will regenerate)
|
||||
if [ -d ~/Library/Caches ]; then
|
||||
CACHES_SIZE=$(du -sh ~/Library/Caches 2>/dev/null | awk '{print $1}')
|
||||
echo " Cleaning Library/Caches ($CACHES_SIZE)..."
|
||||
# Keep some important caches
|
||||
mkdir -p ~/Library/Caches/backup_temp
|
||||
find ~/Library/Caches -mindepth 1 -maxdepth 1 ! -name "backup_temp" -exec mv {} ~/Library/Caches/backup_temp/ \; 2>/dev/null || true
|
||||
rm -rf ~/Library/Caches/backup_temp/* 2>/dev/null || true
|
||||
rmdir ~/Library/Caches/backup_temp 2>/dev/null || true
|
||||
echo " ✓ Caches cleaned"
|
||||
fi
|
||||
|
||||
# 3. Clean user cache
|
||||
if [ -d ~/.cache ]; then
|
||||
CACHE_SIZE=$(du -sh ~/.cache 2>/dev/null | awk '{print $1}')
|
||||
echo " Cleaning ~/.cache ($CACHE_SIZE)..."
|
||||
rm -rf ~/.cache/* 2>/dev/null || true
|
||||
echo " ✓ User cache cleaned"
|
||||
fi
|
||||
|
||||
# 4. Clean npm cache (if exists)
|
||||
if command -v npm &> /dev/null; then
|
||||
NPM_CACHE_SIZE=$(du -sh ~/.npm 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
if [ "$NPM_CACHE_SIZE" != "0" ] && [ -d ~/.npm ]; then
|
||||
echo " Cleaning npm cache ($NPM_CACHE_SIZE)..."
|
||||
npm cache clean --force 2>/dev/null || true
|
||||
echo " ✓ npm cache cleaned"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📊 Checking new disk space..."
|
||||
NEW_FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
NEW_FREE_SPACE_GB=$(echo "scale=2; $NEW_FREE_SPACE / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $NEW_FREE_SPACE_GB - $FREE_SPACE_GB" | bc)
|
||||
|
||||
echo ""
|
||||
echo "=== Results ==="
|
||||
echo " Before: ${FREE_SPACE_GB}GB free"
|
||||
echo " After: ${NEW_FREE_SPACE_GB}GB free"
|
||||
if (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo " Freed: ${FREED_GB}GB"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check if we have enough space now
|
||||
if (( $(echo "$NEW_FREE_SPACE_GB < 5" | bc -l) )); then
|
||||
echo "⚠️ Still low on space. Additional recommendations:"
|
||||
echo ""
|
||||
echo " 1. Review Downloads folder (19GB found):"
|
||||
echo " cd ~/Downloads && ls -lhS | head -20"
|
||||
echo ""
|
||||
echo " 2. Check Documents folder (60GB found):"
|
||||
echo " Move large files to NAS if possible"
|
||||
echo ""
|
||||
echo " 3. Review .ollama folder (17GB found):"
|
||||
echo " Consider removing unused models"
|
||||
echo ""
|
||||
echo " 4. Use macOS Storage Management:"
|
||||
echo " Apple Menu → About This Mac → Storage → Manage"
|
||||
echo ""
|
||||
else
|
||||
echo "✅ Good! You should have enough space for Time Machine now."
|
||||
echo " Try running Time Machine backup again."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,79 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Fix Synology USB Copy Issue
|
||||
# Based on diagnosis findings
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Fix Synology USB Copy ==="
|
||||
echo ""
|
||||
echo "Diagnosis found:"
|
||||
echo " - USB connection errors (cable/device issue)"
|
||||
echo " - USB device was unmounted"
|
||||
echo " - No USB device currently mounted"
|
||||
echo ""
|
||||
|
||||
echo "🔧 Solutions:"
|
||||
echo ""
|
||||
|
||||
echo "1. **Physical USB Connection Issue**"
|
||||
echo ""
|
||||
echo " The logs show: 'Cannot enable. Maybe the USB cable is bad?'"
|
||||
echo ""
|
||||
echo " Try:"
|
||||
echo " a) Unplug USB device from front port"
|
||||
echo " b) Wait 10 seconds"
|
||||
echo " c) Plug back in firmly"
|
||||
echo " d) Wait for it to be recognized (check Control Panel → External Devices)"
|
||||
echo ""
|
||||
|
||||
echo "2. **USB Device Format Issue**"
|
||||
echo ""
|
||||
echo " The device was exFAT and got unmounted due to errors."
|
||||
echo ""
|
||||
echo " Try:"
|
||||
echo " a) Format USB device on your Mac to FAT32 or exFAT"
|
||||
echo " b) Reconnect to Synology front port"
|
||||
echo " c) Wait for recognition"
|
||||
echo ""
|
||||
|
||||
echo "3. **Unmount and Remount USB Device**"
|
||||
echo ""
|
||||
echo " Via DSM:"
|
||||
echo " a) Control Panel → External Devices"
|
||||
echo " b) If USB device shows, click 'Unmount'"
|
||||
echo " c) Wait 5 seconds"
|
||||
echo " d) Click 'Mount' or reconnect device"
|
||||
echo ""
|
||||
|
||||
echo "4. **Check USB Copy Service**"
|
||||
echo ""
|
||||
echo " Via DSM:"
|
||||
echo " a) Package Center → USB Copy"
|
||||
echo " b) Make sure it's 'Started' (not stopped)"
|
||||
echo " c) If stopped, click 'Start'"
|
||||
echo ""
|
||||
|
||||
echo "5. **Check USB Copy Task Settings**"
|
||||
echo ""
|
||||
echo " Via DSM:"
|
||||
echo " a) USB Copy → Select your task"
|
||||
echo " b) Task Settings → Verify source is '[USB]'"
|
||||
echo " c) Make sure no other tasks conflict"
|
||||
echo ""
|
||||
|
||||
echo "=== Quick Fix Steps ==="
|
||||
echo ""
|
||||
echo "1. Unplug USB device from Synology"
|
||||
echo "2. Wait 10 seconds"
|
||||
echo "3. Plug USB device into FRONT USB port (not rear)"
|
||||
echo "4. Wait 30 seconds for recognition"
|
||||
echo "5. Check Control Panel → External Devices"
|
||||
echo "6. If device appears, try USB Copy again"
|
||||
echo ""
|
||||
|
||||
echo "If still not working, check:"
|
||||
echo " - USB device format (FAT32/exFAT recommended)"
|
||||
echo " - USB device not mounted as shared folder"
|
||||
echo " - USB Copy service is running"
|
||||
echo ""
|
||||
@@ -1,131 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Force Delete Stuck Snapshot - Last Resort Methods
|
||||
# When normal deletion methods fail
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Force Delete Stuck Snapshot ==="
|
||||
echo ""
|
||||
echo "This script tries aggressive methods to free stuck snapshot space."
|
||||
echo ""
|
||||
|
||||
FREE_SPACE_BEFORE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_BEFORE=$(echo "scale=2; $FREE_SPACE_BEFORE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB_BEFORE}GB"
|
||||
echo ""
|
||||
|
||||
SNAPSHOTS=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$")
|
||||
if [ -z "$SNAPSHOTS" ]; then
|
||||
echo "✅ No snapshots found!"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Found stuck snapshot(s):"
|
||||
echo "$SNAPSHOTS" | sed 's/^/ - /'
|
||||
echo ""
|
||||
|
||||
read -p "Try aggressive cleanup methods? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Method 1: Aggressive snapshot thinning..."
|
||||
sudo tmutil thinlocalsnapshots / 1000000000 1 2>&1 || true
|
||||
echo " ✓ Completed"
|
||||
echo ""
|
||||
|
||||
echo "Method 2: System purge..."
|
||||
if command -v purge &> /dev/null; then
|
||||
sudo purge
|
||||
echo " ✓ Purged"
|
||||
else
|
||||
echo " ⚠️ Purge command not available"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "Method 3: Checking APFS snapshots..."
|
||||
APFS_SNAPS=$(diskutil apfs listSnapshots / 2>/dev/null)
|
||||
if echo "$APFS_SNAPS" | grep -qi "timemachine"; then
|
||||
echo " Found Time Machine snapshot in APFS"
|
||||
# Try to get UUID and delete
|
||||
SNAP_UUID=$(echo "$APFS_SNAPS" | grep -A 2 -i "timemachine" | grep "UUID" | awk '{print $NF}' | head -1)
|
||||
if [ -n "$SNAP_UUID" ]; then
|
||||
echo " Attempting to delete APFS snapshot: $SNAP_UUID"
|
||||
sudo diskutil apfs deleteSnapshot / -uuid "$SNAP_UUID" 2>&1 || echo " ⚠️ Could not delete (may be protected)"
|
||||
fi
|
||||
else
|
||||
echo " ℹ️ Snapshot not in APFS list (ghost entry)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "Method 4: Force filesystem sync..."
|
||||
sync
|
||||
echo " ✓ Filesystem synced"
|
||||
echo ""
|
||||
|
||||
echo "Method 5: Check for Time Machine temp files..."
|
||||
TM_TEMP=$(sudo find /System/Volumes/Data/.timemachine -type f 2>/dev/null | wc -l | tr -d ' ')
|
||||
if [ "$TM_TEMP" -gt 0 ]; then
|
||||
TEMP_SIZE=$(sudo du -sh /System/Volumes/Data/.timemachine 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " Found Time Machine temp files: $TEMP_SIZE"
|
||||
read -p " Delete Time Machine temp files? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
sudo rm -rf /System/Volumes/Data/.timemachine/* 2>/dev/null || true
|
||||
echo " ✓ Cleaned"
|
||||
fi
|
||||
else
|
||||
echo " ✓ No temp files found"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "⏳ Waiting for system to update..."
|
||||
sleep 5
|
||||
|
||||
# Check results
|
||||
FREE_SPACE_AFTER=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_AFTER=$(echo "scale=2; $FREE_SPACE_AFTER / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $FREE_SPACE_GB_AFTER - $FREE_SPACE_GB_BEFORE" | bc)
|
||||
|
||||
REMAINING_SNAPS=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$" | wc -l | tr -d ' ')
|
||||
|
||||
echo ""
|
||||
echo "=== Results ==="
|
||||
echo " Free space: ${FREE_SPACE_GB_BEFORE}GB → ${FREE_SPACE_GB_AFTER}GB"
|
||||
if (( $(echo "$FREED_GB > 15" | bc -l) )); then
|
||||
echo " ✅ Successfully freed: ${FREED_GB}GB"
|
||||
elif (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo " ✅ Freed: ${FREED_GB}GB"
|
||||
else
|
||||
echo " ⚠️ No space freed yet"
|
||||
fi
|
||||
|
||||
if [ "$REMAINING_SNAPS" -gt 0 ]; then
|
||||
echo " ⚠️ Snapshot still listed (ghost entry)"
|
||||
echo ""
|
||||
echo " The snapshot entry may persist, but if space was freed,"
|
||||
echo " it's likely just a database entry and not taking space."
|
||||
else
|
||||
echo " ✅ Snapshot removed!"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
if (( $(echo "$FREED_GB < 15" | bc -l) )); then
|
||||
echo "⚠️ Space still not fully freed. Final options:"
|
||||
echo ""
|
||||
echo "1. **Restart your Mac** - This is the most reliable solution."
|
||||
echo " The snapshot will be released after restart."
|
||||
echo ""
|
||||
echo "2. Wait 10-15 minutes - macOS may still be processing"
|
||||
echo ""
|
||||
echo "3. Check if space is actually available but not showing:"
|
||||
echo " - Try creating a large file to test"
|
||||
echo " - Check Activity Monitor → Disk tab"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,143 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Force Free Space - Remove APFS and Time Machine Snapshots
|
||||
# This script removes snapshots that are holding onto deleted file space
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Force Free Space - Remove Snapshots ==="
|
||||
echo ""
|
||||
echo "This script will remove APFS and Time Machine snapshots that may be"
|
||||
echo "holding onto space from deleted files."
|
||||
echo ""
|
||||
|
||||
# Check current free space
|
||||
FREE_SPACE_BEFORE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_BEFORE=$(echo "scale=2; $FREE_SPACE_BEFORE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB_BEFORE}GB"
|
||||
echo ""
|
||||
|
||||
# List current snapshots
|
||||
echo "📸 Current Snapshots:"
|
||||
echo ""
|
||||
|
||||
echo "1. Time Machine Local Snapshots:"
|
||||
TM_SNAPSHOTS=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$")
|
||||
if [ -n "$TM_SNAPSHOTS" ]; then
|
||||
echo "$TM_SNAPSHOTS" | while read snapshot; do
|
||||
if [ -n "$snapshot" ]; then
|
||||
echo " - $snapshot"
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo " None found"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "2. APFS System Snapshots:"
|
||||
APFS_SNAPSHOTS=$(diskutil apfs listSnapshots / 2>/dev/null | grep -E "Snapshot Name|Snapshot UUID" | head -10)
|
||||
if [ -n "$APFS_SNAPSHOTS" ]; then
|
||||
echo "$APFS_SNAPSHOTS"
|
||||
else
|
||||
echo " None found (or cannot list)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Ask for confirmation
|
||||
read -p "Do you want to delete Time Machine local snapshots? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo ""
|
||||
echo "🗑️ Deleting Time Machine local snapshots..."
|
||||
|
||||
# Delete each snapshot
|
||||
echo "$TM_SNAPSHOTS" | while read snapshot; do
|
||||
if [ -n "$snapshot" ]; then
|
||||
echo " Deleting: $snapshot"
|
||||
sudo tmutil deletelocalsnapshots "$snapshot" 2>/dev/null && \
|
||||
echo " ✓ Deleted $snapshot" || \
|
||||
echo " ⚠️ Could not delete $snapshot (may be in use)"
|
||||
fi
|
||||
done
|
||||
|
||||
# Also try to delete all at once
|
||||
sudo tmutil deletelocalsnapshots / 2>/dev/null || true
|
||||
|
||||
echo " ✓ Time Machine snapshots cleanup attempted"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Force purge of purgeable space
|
||||
echo "3. Purging Purgeable Space..."
|
||||
echo " This forces macOS to actually free up space from deleted files."
|
||||
echo ""
|
||||
|
||||
read -p "Do you want to purge purgeable space? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo ""
|
||||
echo " Running purge command..."
|
||||
|
||||
# Method 1: Use purge command (if available)
|
||||
if command -v purge &> /dev/null; then
|
||||
sudo purge
|
||||
echo " ✓ Purge command executed"
|
||||
fi
|
||||
|
||||
# Method 2: Disable and re-enable local snapshots to force cleanup
|
||||
echo " Disabling local snapshots..."
|
||||
sudo tmutil disablelocal 2>/dev/null || true
|
||||
sleep 2
|
||||
echo " Re-enabling local snapshots..."
|
||||
sudo tmutil enablelocal 2>/dev/null || true
|
||||
|
||||
# Method 3: Force Time Machine to clean up
|
||||
echo " Triggering Time Machine cleanup..."
|
||||
sudo tmutil thinlocalsnapshots / 1000000000 4 2>/dev/null || true
|
||||
|
||||
echo " ✓ Purge operations completed"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Check new free space
|
||||
sleep 2
|
||||
FREE_SPACE_AFTER=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_AFTER=$(echo "scale=2; $FREE_SPACE_AFTER / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $FREE_SPACE_GB_AFTER - $FREE_SPACE_GB_BEFORE" | bc)
|
||||
|
||||
echo ""
|
||||
echo "=== Results ==="
|
||||
echo " Before: ${FREE_SPACE_GB_BEFORE}GB free"
|
||||
echo " After: ${FREE_SPACE_GB_AFTER}GB free"
|
||||
if (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo " ✅ Freed: ${FREED_GB}GB"
|
||||
else
|
||||
echo " ⚠️ No space freed yet (may need to wait or try other methods)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
if (( $(echo "$FREED_GB < 15" | bc -l) )) && (( $(echo "$FREE_SPACE_GB_AFTER < 5" | bc -l) )); then
|
||||
echo "⚠️ Still low on space. Additional steps:"
|
||||
echo ""
|
||||
echo "1. Wait a few minutes - macOS may still be processing"
|
||||
echo ""
|
||||
echo "2. Restart your Mac - this often frees up snapshot space"
|
||||
echo ""
|
||||
echo "3. Check for large files in other locations:"
|
||||
echo " ./free_disk_space.sh"
|
||||
echo ""
|
||||
echo "4. Manually delete the Time Machine snapshot:"
|
||||
SNAP=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$" | head -1)
|
||||
if [ -n "$SNAP" ]; then
|
||||
echo " sudo tmutil deletelocalsnapshots $SNAP"
|
||||
fi
|
||||
echo ""
|
||||
echo "5. Use macOS Storage Management:"
|
||||
echo " Apple Menu → About This Mac → Storage → Manage"
|
||||
echo " This tool can identify and remove large system files"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,100 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Force Purge System Data (351GB)
|
||||
# The 351GB is likely "purgeable" space that macOS won't release until forced
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Force Purge System Data (351GB) ==="
|
||||
echo ""
|
||||
echo "The 351GB in System Data is likely PURGEABLE space."
|
||||
echo "macOS shows it as 'used' but it's actually available."
|
||||
echo "We'll force macOS to release it by creating a large file."
|
||||
echo ""
|
||||
|
||||
FREE_SPACE_BEFORE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_BEFORE=$(echo "scale=2; $FREE_SPACE_BEFORE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB_BEFORE}GB"
|
||||
echo ""
|
||||
|
||||
echo "🔧 Method: Create a large file to force purge..."
|
||||
echo ""
|
||||
echo " This will:"
|
||||
echo " 1. Create a 50GB file (forces macOS to purge space)"
|
||||
echo " 2. Delete it immediately"
|
||||
echo " 3. This should release the purgeable space"
|
||||
echo ""
|
||||
|
||||
read -p "Proceed? This is safe - file will be deleted immediately. (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Cancelled."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Creating 50GB test file to force purge..."
|
||||
echo " (This may take a few minutes)"
|
||||
echo ""
|
||||
|
||||
# Create large file to force purge
|
||||
TEST_FILE="$HOME/test_force_purge_$(date +%s).tmp"
|
||||
if dd if=/dev/zero of="$TEST_FILE" bs=1g count=50 2>/dev/null; then
|
||||
echo " ✅ Created 50GB file"
|
||||
echo ""
|
||||
echo " Checking space after creation..."
|
||||
sleep 2
|
||||
FREE_DURING=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_DURING_GB=$(echo "scale=2; $FREE_DURING / 1024 / 1024" | bc)
|
||||
echo " Free space during: ${FREE_DURING_GB}GB"
|
||||
echo ""
|
||||
|
||||
echo " Deleting test file..."
|
||||
rm -f "$TEST_FILE"
|
||||
echo " ✅ Deleted"
|
||||
else
|
||||
echo " ⚠️ Could not create file (not enough space or permission issue)"
|
||||
echo " This means the purgeable space may not be available"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "⏳ Waiting for system to update..."
|
||||
sleep 10
|
||||
|
||||
# Check final results
|
||||
FREE_SPACE_AFTER=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_AFTER=$(echo "scale=2; $FREE_SPACE_AFTER / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $FREE_SPACE_GB_AFTER - $FREE_SPACE_GB_BEFORE" | bc)
|
||||
|
||||
echo ""
|
||||
echo "=== Results ==="
|
||||
echo " Before: ${FREE_SPACE_GB_BEFORE}GB free"
|
||||
echo " After: ${FREE_SPACE_GB_AFTER}GB free"
|
||||
if (( $(echo "$FREED_GB > 100" | bc -l) )); then
|
||||
echo " ✅ Successfully freed: ${FREED_GB}GB!"
|
||||
echo " The purgeable space was released!"
|
||||
elif (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo " ✅ Freed: ${FREED_GB}GB"
|
||||
else
|
||||
echo " ⚠️ No space freed"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=== Understanding System Data (351GB) ==="
|
||||
echo ""
|
||||
echo "If System Data still shows 351GB but you have free space,"
|
||||
echo "this is NORMAL macOS behavior:"
|
||||
echo ""
|
||||
echo " - System Data includes PURGEABLE space"
|
||||
echo " - Purgeable space is AVAILABLE but shown as 'used'"
|
||||
echo " - macOS will release it automatically when needed"
|
||||
echo " - The space is actually available for use"
|
||||
echo ""
|
||||
echo "To verify space is available:"
|
||||
echo " 1. Try creating a large file (you just did)"
|
||||
echo " 2. Check Activity Monitor → Disk → Purgeable"
|
||||
echo " 3. The space will be released when you actually need it"
|
||||
echo ""
|
||||
echo "The 351GB in System Data is misleading - much of it"
|
||||
echo "is purgeable and available when needed."
|
||||
echo ""
|
||||
@@ -1,96 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Free Disk Space for Time Machine
|
||||
# This script helps identify and free up space on your Mac so Time Machine can work
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Mac Disk Space Analysis ==="
|
||||
echo ""
|
||||
|
||||
# Check current disk usage
|
||||
echo "📊 Current Disk Status:"
|
||||
df -h / | tail -1 | awk '{print " Total: " $2 " | Used: " $3 " (" $5 ") | Free: " $4}'
|
||||
echo ""
|
||||
|
||||
# Check if disk is critically low
|
||||
FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB=$(echo "scale=2; $FREE_SPACE / 1024 / 1024" | bc)
|
||||
|
||||
if (( $(echo "$FREE_SPACE_GB < 5" | bc -l) )); then
|
||||
echo "⚠️ WARNING: Disk has less than 5GB free. Time Machine requires free space to work!"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "🔍 Analyzing Large Files and Folders:"
|
||||
echo ""
|
||||
|
||||
# Check Downloads folder
|
||||
if [ -d ~/Downloads ]; then
|
||||
DOWNLOADS_SIZE=$(du -sh ~/Downloads 2>/dev/null | awk '{print $1}')
|
||||
echo " 📁 Downloads: $DOWNLOADS_SIZE"
|
||||
fi
|
||||
|
||||
# Check Library Caches
|
||||
if [ -d ~/Library/Caches ]; then
|
||||
CACHES_SIZE=$(du -sh ~/Library/Caches 2>/dev/null | awk '{print $1}')
|
||||
echo " 🗑️ Library/Caches: $CACHES_SIZE (safe to clean)"
|
||||
fi
|
||||
|
||||
# Check Trash
|
||||
if [ -d ~/.Trash ]; then
|
||||
TRASH_SIZE=$(du -sh ~/.Trash 2>/dev/null | awk '{print $1}')
|
||||
echo " 🗑️ Trash: $TRASH_SIZE"
|
||||
fi
|
||||
|
||||
# Check local Time Machine snapshots
|
||||
echo ""
|
||||
echo "📸 Local Time Machine Snapshots:"
|
||||
SNAPSHOTS=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$" | wc -l | tr -d ' ')
|
||||
if [ "$SNAPSHOTS" -gt 0 ]; then
|
||||
echo " Found $SNAPSHOTS local snapshot(s)"
|
||||
tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$" | sed 's/^/ - /'
|
||||
echo ""
|
||||
echo " 💡 Tip: Local snapshots are automatically deleted when space is needed,"
|
||||
echo " but you can delete them manually if needed."
|
||||
else
|
||||
echo " No local snapshots found"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📋 Top 10 Largest Files/Directories in Home:"
|
||||
du -h -d 1 ~ 2>/dev/null | sort -hr | head -10 | awk '{printf " %8s %s\n", $1, $2}'
|
||||
|
||||
echo ""
|
||||
echo "=== Recommendations ==="
|
||||
echo ""
|
||||
echo "1. 🗑️ Empty Trash:"
|
||||
echo " rm -rf ~/.Trash/*"
|
||||
echo ""
|
||||
echo "2. 🧹 Clean System Caches (safe):"
|
||||
echo " rm -rf ~/Library/Caches/*"
|
||||
echo ""
|
||||
echo "3. 📁 Review Downloads folder (~/Downloads) - 19GB found"
|
||||
echo " Move large files to NAS or delete if not needed"
|
||||
echo ""
|
||||
echo "4. 🗑️ Delete old local snapshots (if needed):"
|
||||
echo " sudo tmutil deletelocalsnapshots <snapshot-date>"
|
||||
echo ""
|
||||
echo "5. 💾 Use Storage Management:"
|
||||
echo " Apple Menu → About This Mac → Storage → Manage"
|
||||
echo " This tool can help identify and remove large files, old backups, etc."
|
||||
echo ""
|
||||
echo "6. 📦 Check for large applications:"
|
||||
echo " Review Applications folder for unused apps"
|
||||
echo ""
|
||||
echo "=== Quick Clean Commands ==="
|
||||
echo ""
|
||||
echo "To clean caches (safe, will regenerate):"
|
||||
echo " rm -rf ~/Library/Caches/*"
|
||||
echo ""
|
||||
echo "To empty trash:"
|
||||
echo " rm -rf ~/.Trash/*"
|
||||
echo ""
|
||||
echo "To see what's taking up space:"
|
||||
echo " du -h -d 1 ~ | sort -hr | head -20"
|
||||
echo ""
|
||||
@@ -1,87 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Free Photo Cache Space
|
||||
# The photo volume is taking 179GB - likely a local cache
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Free Photo Cache Space ==="
|
||||
echo ""
|
||||
echo "Found: /System/Volumes/Data/Volumes/photo is 179GB"
|
||||
echo "This is a mounted NAS share that's being cached locally."
|
||||
echo ""
|
||||
|
||||
FREE_SPACE_BEFORE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_BEFORE=$(echo "scale=2; $FREE_SPACE_BEFORE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB_BEFORE}GB"
|
||||
echo ""
|
||||
|
||||
# Check if it's the same as /Volumes/photo
|
||||
echo "🔍 Checking mount points:"
|
||||
MOUNT_POINT=$(mount | grep photo | awk '{print $3}')
|
||||
echo " Network mount: $MOUNT_POINT"
|
||||
echo " Cache location: /System/Volumes/Data/Volumes/photo"
|
||||
echo ""
|
||||
|
||||
# Check sizes
|
||||
CACHE_SIZE=$(sudo du -sh /System/Volumes/Data/Volumes/photo 2>/dev/null | awk '{print $1}')
|
||||
MOUNT_SIZE=$(sudo du -sh "$MOUNT_POINT" 2>/dev/null | awk '{print $1}' || echo "N/A")
|
||||
echo " Cache size: $CACHE_SIZE"
|
||||
echo " Mount size: $MOUNT_SIZE"
|
||||
echo ""
|
||||
|
||||
echo "⚠️ The 179GB in /System/Volumes/Data/Volumes/photo is likely:"
|
||||
echo " - A local cache of the network share"
|
||||
echo " - Or files that were copied locally"
|
||||
echo ""
|
||||
|
||||
echo "🔧 Solution:"
|
||||
echo ""
|
||||
echo "Option 1: Unmount the network share (if not needed right now)"
|
||||
echo " diskutil unmount /Volumes/photo"
|
||||
echo " This will free the space immediately"
|
||||
echo ""
|
||||
|
||||
echo "Option 2: Clear the cache (if it's a cache)"
|
||||
echo " ⚠️ WARNING: Make sure files are on NAS first!"
|
||||
echo " sudo rm -rf /System/Volumes/Data/Volumes/photo/*"
|
||||
echo ""
|
||||
|
||||
echo "Option 3: Check if files are duplicated"
|
||||
echo " Compare /Volumes/photo vs /System/Volumes/Data/Volumes/photo"
|
||||
echo " If they're the same, you can safely remove the cache"
|
||||
echo ""
|
||||
|
||||
read -p "Do you want to unmount /Volumes/photo to free space? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo ""
|
||||
echo "Unmounting /Volumes/photo..."
|
||||
if diskutil unmount /Volumes/photo 2>/dev/null; then
|
||||
echo "✅ Successfully unmounted"
|
||||
echo ""
|
||||
echo "⏳ Waiting for space to be released..."
|
||||
sleep 5
|
||||
|
||||
FREE_SPACE_AFTER=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_AFTER=$(echo "scale=2; $FREE_SPACE_AFTER / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $FREE_SPACE_GB_AFTER - $FREE_SPACE_GB_BEFORE" | bc)
|
||||
|
||||
echo ""
|
||||
echo "=== Results ==="
|
||||
echo " Before: ${FREE_SPACE_GB_BEFORE}GB free"
|
||||
echo " After: ${FREE_SPACE_GB_AFTER}GB free"
|
||||
if (( $(echo "$FREED_GB > 150" | bc -l) )); then
|
||||
echo " ✅ Freed: ${FREED_GB}GB (179GB cache released!)"
|
||||
elif (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo " ✅ Freed: ${FREED_GB}GB"
|
||||
else
|
||||
echo " ⚠️ Space not freed yet (may need to clear cache manually)"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ Could not unmount (may be in use)"
|
||||
echo " Try: sudo umount /Volumes/photo"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,156 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Free Space Without Triggering Snapshot Growth
|
||||
# Delete files that are ALREADY in snapshots or don't trigger snapshots
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Free Space Without Snapshot Growth ==="
|
||||
echo ""
|
||||
echo "⚠️ CRITICAL: Stop deleting regular files!"
|
||||
echo " Every file you delete is preserved in the OS snapshot,"
|
||||
echo " making System Data grow."
|
||||
echo ""
|
||||
echo "Instead, delete files that DON'T trigger snapshot growth:"
|
||||
echo ""
|
||||
|
||||
FREE_SPACE_BEFORE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_BEFORE=$(echo "scale=2; $FREE_SPACE_BEFORE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB_BEFORE}GB"
|
||||
echo ""
|
||||
|
||||
echo "🔧 Safe to Delete (Won't Grow System Data):"
|
||||
echo ""
|
||||
|
||||
# 1. Caches (already cached, deleting doesn't create new snapshots)
|
||||
echo "1. Library Caches (~6GB):"
|
||||
CACHE_SIZE=$(du -sh ~/Library/Caches 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " Size: $CACHE_SIZE"
|
||||
echo " Command: rm -rf ~/Library/Caches/*"
|
||||
echo " ✅ Safe - caches are temporary"
|
||||
echo ""
|
||||
|
||||
# 2. User cache
|
||||
echo "2. User Cache (~3GB):"
|
||||
USER_CACHE=$(du -sh ~/.cache 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " Size: $USER_CACHE"
|
||||
echo " Command: rm -rf ~/.cache/*"
|
||||
echo " ✅ Safe - temporary files"
|
||||
echo ""
|
||||
|
||||
# 3. Downloads (if already backed up)
|
||||
echo "3. Downloads (~9GB):"
|
||||
DOWNLOADS_SIZE=$(du -sh ~/Downloads 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " Size: $DOWNLOADS_SIZE"
|
||||
echo " ⚠️ Only if files are already on NAS"
|
||||
echo " Command: rm -rf ~/Downloads/*"
|
||||
echo ""
|
||||
|
||||
# 4. Trash
|
||||
echo "4. Trash:"
|
||||
TRASH_SIZE=$(du -sh ~/.Trash 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " Size: $TRASH_SIZE"
|
||||
echo " Command: rm -rf ~/.Trash/*"
|
||||
echo " ✅ Safe - already deleted"
|
||||
echo ""
|
||||
|
||||
# 5. npm cache
|
||||
echo "5. npm Cache (~1GB):"
|
||||
NPM_SIZE=$(du -sh ~/.npm 2>/dev/null | awk '{print $1}' || echo "0")
|
||||
echo " Size: $NPM_SIZE"
|
||||
echo " Command: npm cache clean --force"
|
||||
echo " ✅ Safe - can be regenerated"
|
||||
echo ""
|
||||
|
||||
TOTAL_SAFE=$(echo "6 + 3 + 1" | bc)
|
||||
echo "Estimated safe space to free: ~${TOTAL_SAFE}GB"
|
||||
echo ""
|
||||
|
||||
read -p "Clean these safe items now? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo ""
|
||||
echo "🧹 Cleaning safe items..."
|
||||
|
||||
# Clean caches
|
||||
if [ -d ~/Library/Caches ]; then
|
||||
rm -rf ~/Library/Caches/* 2>/dev/null || true
|
||||
echo " ✅ Cleaned Library/Caches"
|
||||
fi
|
||||
|
||||
if [ -d ~/.cache ]; then
|
||||
rm -rf ~/.cache/* 2>/dev/null || true
|
||||
echo " ✅ Cleaned user cache"
|
||||
fi
|
||||
|
||||
# Clean trash
|
||||
if [ -d ~/.Trash ]; then
|
||||
rm -rf ~/.Trash/* 2>/dev/null || true
|
||||
echo " ✅ Emptied Trash"
|
||||
fi
|
||||
|
||||
# Clean npm
|
||||
if command -v npm &> /dev/null && [ -d ~/.npm ]; then
|
||||
npm cache clean --force 2>/dev/null || true
|
||||
echo " ✅ Cleaned npm cache"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "⏳ Waiting for system to update..."
|
||||
sleep 5
|
||||
fi
|
||||
|
||||
# Check results
|
||||
FREE_SPACE_AFTER=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_AFTER=$(echo "scale=2; $FREE_SPACE_AFTER / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $FREE_SPACE_GB_AFTER - $FREE_SPACE_GB_BEFORE" | bc)
|
||||
|
||||
echo ""
|
||||
echo "=== Results ==="
|
||||
echo " Before: ${FREE_SPACE_GB_BEFORE}GB free"
|
||||
echo " After: ${FREE_SPACE_GB_AFTER}GB free"
|
||||
if (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo " ✅ Freed: ${FREED_GB}GB"
|
||||
else
|
||||
echo " ⚠️ No space freed (may need restart)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=== CRITICAL INSTRUCTIONS ==="
|
||||
echo ""
|
||||
echo "1. ⛔ STOP DELETING REGULAR FILES"
|
||||
echo " Every file you delete makes System Data grow!"
|
||||
echo ""
|
||||
echo "2. ✅ Only delete:"
|
||||
echo " - Caches (already done above)"
|
||||
echo " - Trash (already done above)"
|
||||
echo " - Files that are already on NAS"
|
||||
echo ""
|
||||
echo "3. 🚀 Install macOS Update NOW:"
|
||||
echo " System Settings → General → Software Update"
|
||||
echo " Install macOS Tahoe 26.2"
|
||||
echo ""
|
||||
echo " The update will:"
|
||||
echo " - Clear the old snapshot"
|
||||
echo " - Free the 351GB in System Data"
|
||||
echo " - Stop the snapshot growth problem"
|
||||
echo ""
|
||||
echo "4. ⏳ If you don't have enough space for update:"
|
||||
echo " - The update needs ~3.6GB"
|
||||
echo " - Try downloading it first (may work with less space)"
|
||||
echo " - Or move files to NAS instead of deleting"
|
||||
echo ""
|
||||
|
||||
if (( $(echo "$FREE_SPACE_GB_AFTER < 4" | bc -l) )); then
|
||||
echo "⚠️ Still low on space for update."
|
||||
echo ""
|
||||
echo " Try downloading the update first:"
|
||||
echo " sudo softwareupdate --download --all"
|
||||
echo ""
|
||||
echo " Or move (don't delete) large files to NAS:"
|
||||
echo " - Documents folder (40GB)"
|
||||
echo " - .ollama models (17GB)"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,111 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Free System Data (351GB)
|
||||
# Most of this is purgeable space held by snapshots
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Free System Data (351GB) ==="
|
||||
echo ""
|
||||
echo "System Data is 351GB, but visible components only add up to ~20GB."
|
||||
echo "This means ~330GB is PURGEABLE SPACE held by snapshots."
|
||||
echo ""
|
||||
|
||||
FREE_SPACE_BEFORE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_BEFORE=$(echo "scale=2; $FREE_SPACE_BEFORE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB_BEFORE}GB"
|
||||
echo ""
|
||||
|
||||
echo "🔧 Step 1: Aggressively thin all snapshots..."
|
||||
sudo tmutil thinlocalsnapshots / 1000000000 1 2>&1
|
||||
echo " ✓ Completed"
|
||||
echo ""
|
||||
|
||||
echo "🔧 Step 2: Purge system memory and caches..."
|
||||
if command -v purge &> /dev/null; then
|
||||
sudo purge
|
||||
echo " ✓ Purged"
|
||||
else
|
||||
echo " ⚠️ Purge command not available"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "🔧 Step 3: Remove Time Machine destination (CRITICAL)"
|
||||
echo ""
|
||||
echo " ⚠️ IMPORTANT: You MUST remove Time Machine destination to"
|
||||
echo " prevent new snapshots from being created!"
|
||||
echo ""
|
||||
echo " Do this now:"
|
||||
echo " 1. System Settings → General → Time Machine"
|
||||
echo " 2. Click '-' to remove backup disk"
|
||||
echo " 3. Confirm removal"
|
||||
echo ""
|
||||
read -p " Have you removed Time Machine destination? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo " ⚠️ Please remove it first, then run this script again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🔧 Step 4: Wait for system to release purgeable space..."
|
||||
echo " This may take a few minutes..."
|
||||
sleep 10
|
||||
|
||||
echo ""
|
||||
echo "🔧 Step 5: Try to delete stuck snapshot..."
|
||||
SNAPSHOT=$(tmutil listlocalsnapshots / 2>/dev/null | grep -v "Snapshots for disk" | grep -v "^$" | head -1)
|
||||
if [ -n "$SNAPSHOT" ]; then
|
||||
SNAP_DATE=$(echo "$SNAPSHOT" | sed 's/.*\.\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}\)\.backup/\1/')
|
||||
echo " Attempting to delete: $SNAPSHOT"
|
||||
if sudo tmutil deletelocalsnapshots "$SNAP_DATE" 2>/dev/null; then
|
||||
echo " ✅ Deleted!"
|
||||
else
|
||||
echo " ⚠️ Still stuck (ghost entry - will clear on restart)"
|
||||
fi
|
||||
else
|
||||
echo " ✅ No snapshots found"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "⏳ Waiting for space to be released..."
|
||||
sleep 10
|
||||
|
||||
# Check results
|
||||
FREE_SPACE_AFTER=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB_AFTER=$(echo "scale=2; $FREE_SPACE_AFTER / 1024 / 1024" | bc)
|
||||
FREED_GB=$(echo "scale=2; $FREE_SPACE_GB_AFTER - $FREE_SPACE_GB_BEFORE" | bc)
|
||||
|
||||
echo ""
|
||||
echo "=== Results ==="
|
||||
echo " Before: ${FREE_SPACE_GB_BEFORE}GB free"
|
||||
echo " After: ${FREE_SPACE_GB_AFTER}GB free"
|
||||
if (( $(echo "$FREED_GB > 100" | bc -l) )); then
|
||||
echo " ✅ Successfully freed: ${FREED_GB}GB!"
|
||||
elif (( $(echo "$FREED_GB > 0" | bc -l) )); then
|
||||
echo " ✅ Freed: ${FREED_GB}GB"
|
||||
echo " (More space may be released over time)"
|
||||
else
|
||||
echo " ⚠️ No space freed yet"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
if (( $(echo "$FREE_SPACE_GB_AFTER < 50" | bc -l) )); then
|
||||
echo "⚠️ Still low on space. Additional steps:"
|
||||
echo ""
|
||||
echo "1. **Restart your Mac** - This is the most effective way"
|
||||
echo " to release purgeable space from snapshots."
|
||||
echo ""
|
||||
echo "2. Use macOS Storage Management:"
|
||||
echo " Apple Menu → About This Mac → Storage → Manage"
|
||||
echo " Click 'Optimize' to release purgeable space"
|
||||
echo ""
|
||||
echo "3. Wait 15-30 minutes - macOS may need time to"
|
||||
echo " release the purgeable space"
|
||||
echo ""
|
||||
echo "4. The 351GB in System Data is mostly purgeable space"
|
||||
echo " that will be released when snapshots are cleared."
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,61 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to get detailed EnConvo crash information
|
||||
|
||||
echo "=== EnConvo Crash Details Collector ==="
|
||||
echo ""
|
||||
|
||||
# 1. Check for crash reports
|
||||
echo "1. Recent Crash Reports:"
|
||||
CRASH_REPORTS=$(ls -t ~/Library/Logs/DiagnosticReports/*EnConvo* 2>/dev/null | head -3)
|
||||
if [ -z "$CRASH_REPORTS" ]; then
|
||||
echo " No crash reports found in DiagnosticReports"
|
||||
else
|
||||
echo " Found crash reports:"
|
||||
echo "$CRASH_REPORTS" | while read report; do
|
||||
echo " - $(basename "$report")"
|
||||
done
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 2. Get the most recent crash report summary
|
||||
echo "2. Most Recent Crash Report Summary:"
|
||||
LATEST_CRASH=$(ls -t ~/Library/Logs/DiagnosticReports/*EnConvo* 2>/dev/null | head -1)
|
||||
if [ -n "$LATEST_CRASH" ]; then
|
||||
echo " File: $(basename "$LATEST_CRASH")"
|
||||
echo ""
|
||||
echo " Exception Type:"
|
||||
grep -A 5 "Exception Type:" "$LATEST_CRASH" 2>/dev/null | head -6 || echo " (Not found)"
|
||||
echo ""
|
||||
echo " Crashed Thread:"
|
||||
grep -A 10 "Crashed Thread:" "$LATEST_CRASH" 2>/dev/null | head -11 || echo " (Not found)"
|
||||
echo ""
|
||||
echo " Application Specific Information:"
|
||||
grep -A 5 "Application Specific Information:" "$LATEST_CRASH" 2>/dev/null | head -6 || echo " (Not found)"
|
||||
else
|
||||
echo " No crash report found. The app may have exited without creating one."
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 3. Check Console logs
|
||||
echo "3. Recent Console Logs (last 30 seconds):"
|
||||
log show --predicate 'process == "EnConvo" AND eventMessage CONTAINS "error" OR eventMessage CONTAINS "crash" OR eventMessage CONTAINS "exception"' --last 30s --style compact 2>/dev/null | tail -10 || echo " (No relevant logs found)"
|
||||
echo ""
|
||||
|
||||
echo "=== To view full crash report, run: ==="
|
||||
if [ -n "$LATEST_CRASH" ]; then
|
||||
echo "open '$LATEST_CRASH'"
|
||||
else
|
||||
echo "# No crash report found yet"
|
||||
echo "# After the crash, run: ls -t ~/Library/Logs/DiagnosticReports/*EnConvo* | head -1 | xargs open"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install Tailscale on server2
|
||||
# This script will detect the OS and install Tailscale accordingly
|
||||
|
||||
echo "=== Installing Tailscale on server2 ==="
|
||||
echo ""
|
||||
|
||||
# Detect OS and install Tailscale
|
||||
echo "Detecting OS and installing Tailscale..."
|
||||
ssh server2 << 'EOF'
|
||||
# Detect OS
|
||||
if [ -f /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
OS=$ID
|
||||
VER=$VERSION_ID
|
||||
else
|
||||
echo "Cannot detect OS. Assuming Ubuntu/Debian."
|
||||
OS="ubuntu"
|
||||
fi
|
||||
|
||||
echo "Detected OS: $OS $VER"
|
||||
echo ""
|
||||
|
||||
# Install Tailscale based on OS
|
||||
case $OS in
|
||||
ubuntu|debian)
|
||||
echo "Installing Tailscale on Ubuntu/Debian..."
|
||||
curl -fsSL https://tailscale.com/install.sh | sh
|
||||
;;
|
||||
fedora|rhel|centos|rocky|almalinux)
|
||||
echo "Installing Tailscale on RHEL/CentOS/Fedora..."
|
||||
curl -fsSL https://tailscale.com/install.sh | sh
|
||||
;;
|
||||
arch|manjaro)
|
||||
echo "Installing Tailscale on Arch Linux..."
|
||||
curl -fsSL https://tailscale.com/install.sh | sh
|
||||
;;
|
||||
*)
|
||||
echo "Using generic Linux installation..."
|
||||
curl -fsSL https://tailscale.com/install.sh | sh
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
echo "Tailscale installation complete!"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Run: sudo tailscale up"
|
||||
echo "2. Follow the authentication link to connect this machine to your Tailscale network"
|
||||
echo ""
|
||||
echo "To check status: sudo tailscale status"
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
echo "=== Installation script completed ==="
|
||||
echo ""
|
||||
echo "To authenticate and start Tailscale, run:"
|
||||
echo " ssh server2 'sudo tailscale up'"
|
||||
echo ""
|
||||
echo "This will provide a URL to authenticate the device."
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,259 +0,0 @@
|
||||
# iPhone Mirroring Troubleshooting
|
||||
|
||||
## Issue
|
||||
iPhone Mirroring shows "Unable to Connect to iPhone" error, even though:
|
||||
- ✅ Same iPhone works on another MacBook
|
||||
- ✅ iPhone is near the Mac, powered on
|
||||
- ✅ iPhone is running iOS 18 or later
|
||||
|
||||
## Requirements Checklist
|
||||
|
||||
### iPhone Requirements
|
||||
- [ ] iOS 18.0 or later
|
||||
- [ ] Bluetooth enabled
|
||||
- [ ] Wi-Fi enabled
|
||||
- [ ] Signed in to iCloud with same Apple ID as Mac
|
||||
- [ ] iPhone is unlocked (or recently unlocked)
|
||||
- [ ] iPhone is near the Mac (within Bluetooth range)
|
||||
|
||||
### Mac Requirements
|
||||
- [ ] macOS Sequoia 15.0 or later
|
||||
- [ ] Bluetooth enabled
|
||||
- [ ] Wi-Fi enabled
|
||||
- [ ] Signed in to iCloud with same Apple ID as iPhone
|
||||
- [ ] Continuity features enabled
|
||||
|
||||
## Common Causes & Solutions
|
||||
|
||||
### 1. Different iCloud Account
|
||||
**Most Common Issue**: Mac and iPhone signed in to different iCloud accounts
|
||||
|
||||
**Check:**
|
||||
```bash
|
||||
# On Mac - check iCloud account
|
||||
defaults read MobileMeAccounts Accounts | grep AccountID
|
||||
|
||||
# Or check System Settings → Apple ID
|
||||
```
|
||||
|
||||
**Fix:**
|
||||
- System Settings → Apple ID → Sign in with same account as iPhone
|
||||
- iPhone: Settings → [Your Name] → Verify Apple ID matches
|
||||
|
||||
### 2. Continuity Features Disabled
|
||||
**Check:**
|
||||
- System Settings → General → AirDrop & Handoff
|
||||
- Ensure "Handoff" is enabled
|
||||
- Ensure "Allow Handoff between this Mac and your iCloud devices" is checked
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
# Enable Handoff via command line
|
||||
defaults write com.apple.coreservices.useractivityd.plist ActivityAdvertisingAllowed -bool true
|
||||
defaults write com.apple.coreservices.useractivityd.plist ActivityReceivingAllowed -bool true
|
||||
|
||||
# Restart the service
|
||||
killall sharingd
|
||||
```
|
||||
|
||||
### 3. Bluetooth/Wi-Fi Issues
|
||||
**Check:**
|
||||
```bash
|
||||
# Check Bluetooth status
|
||||
system_profiler SPBluetoothDataType | grep -A 5 "State"
|
||||
|
||||
# Check Wi-Fi status
|
||||
networksetup -getairportpower en0
|
||||
```
|
||||
|
||||
**Fix:**
|
||||
- Turn Bluetooth off and on: System Settings → Bluetooth
|
||||
- Turn Wi-Fi off and on: System Settings → Wi-Fi
|
||||
- Restart both devices
|
||||
|
||||
### 4. macOS Version Too Old
|
||||
**Check:**
|
||||
```bash
|
||||
sw_vers
|
||||
```
|
||||
|
||||
**Fix:**
|
||||
- iPhone Mirroring requires macOS Sequoia 15.0 or later
|
||||
- Update macOS: System Settings → General → Software Update
|
||||
|
||||
### 5. Firewall Blocking Connection
|
||||
**Check:**
|
||||
- System Settings → Network → Firewall
|
||||
- Check if Firewall is enabled
|
||||
|
||||
**Fix:**
|
||||
- Temporarily disable Firewall to test
|
||||
- If it works, add exception for "Continuity" or "Handoff"
|
||||
- Or ensure "Block all incoming connections" is NOT checked
|
||||
|
||||
### 6. Network Isolation
|
||||
**Check:**
|
||||
- Are Mac and iPhone on the same Wi-Fi network?
|
||||
- Is there a VPN active on either device?
|
||||
|
||||
**Fix:**
|
||||
- Connect both to same Wi-Fi network
|
||||
- Disable VPN temporarily to test
|
||||
- Ensure network allows device-to-device communication (not in guest/isolated mode)
|
||||
|
||||
### 7. Bluetooth Permissions
|
||||
**Check:**
|
||||
- System Settings → Privacy & Security → Bluetooth
|
||||
- Ensure apps have Bluetooth access
|
||||
|
||||
**Fix:**
|
||||
- Grant Bluetooth permissions if prompted
|
||||
- Restart Mac after granting permissions
|
||||
|
||||
### 8. Stale Continuity Cache
|
||||
**Fix:**
|
||||
```bash
|
||||
# Reset Continuity/Handoff cache
|
||||
killall sharingd
|
||||
killall bluetoothd
|
||||
|
||||
# Or restart Bluetooth daemon
|
||||
sudo launchctl stop com.apple.bluetoothd
|
||||
sudo launchctl start com.apple.bluetoothd
|
||||
```
|
||||
|
||||
### 9. Reset Network Settings (Last Resort)
|
||||
**On iPhone:**
|
||||
- Settings → General → Transfer or Reset iPhone → Reset → Reset Network Settings
|
||||
- This will reset Wi-Fi passwords but may fix connection issues
|
||||
|
||||
**On Mac:**
|
||||
```bash
|
||||
# Reset network location (less drastic)
|
||||
sudo networksetup -setairportpower en0 off
|
||||
sleep 2
|
||||
sudo networksetup -setairportpower en0 on
|
||||
```
|
||||
|
||||
## Diagnostic Commands
|
||||
|
||||
### Check Continuity Status
|
||||
```bash
|
||||
# Check Handoff status
|
||||
defaults read com.apple.coreservices.useractivityd.plist
|
||||
|
||||
# Check Bluetooth connectivity
|
||||
system_profiler SPBluetoothDataType | grep -i "connected\|paired"
|
||||
```
|
||||
|
||||
### Check System Logs
|
||||
```bash
|
||||
# Check for iPhone Mirroring errors
|
||||
log show --predicate 'eventMessage contains "iPhone Mirroring" or eventMessage contains "Continuity"' --last 1h --info
|
||||
|
||||
# Check Bluetooth errors
|
||||
log show --predicate 'subsystem == "com.apple.bluetooth"' --last 1h --info | tail -50
|
||||
```
|
||||
|
||||
### Check iCloud Account Match
|
||||
```bash
|
||||
# Mac iCloud account
|
||||
defaults read MobileMeAccounts Accounts | grep -A 5 "AccountID"
|
||||
|
||||
# Compare with iPhone (check iPhone Settings → [Your Name])
|
||||
```
|
||||
|
||||
### Test Bluetooth Connection
|
||||
```bash
|
||||
# List nearby Bluetooth devices
|
||||
system_profiler SPBluetoothDataType | grep -A 10 "iPhone"
|
||||
```
|
||||
|
||||
## Step-by-Step Troubleshooting
|
||||
|
||||
1. **Verify Requirements:**
|
||||
- Check macOS version (must be 15.0+)
|
||||
- Check iOS version (must be 18.0+)
|
||||
- Verify same iCloud account on both devices
|
||||
|
||||
2. **Restart Services:**
|
||||
```bash
|
||||
killall sharingd
|
||||
killall bluetoothd
|
||||
```
|
||||
|
||||
3. **Restart Both Devices:**
|
||||
- Restart Mac
|
||||
- Restart iPhone
|
||||
|
||||
4. **Check System Settings:**
|
||||
- System Settings → General → AirDrop & Handoff → Enable Handoff
|
||||
- System Settings → Privacy & Security → Bluetooth → Ensure enabled
|
||||
- System Settings → Network → Firewall → Check settings
|
||||
|
||||
5. **Try Again:**
|
||||
- Make sure iPhone is unlocked
|
||||
- Bring iPhone close to Mac
|
||||
- Try connecting again
|
||||
|
||||
6. **If Still Not Working:**
|
||||
- Sign out and sign back into iCloud on Mac
|
||||
- Sign out and sign back into iCloud on iPhone
|
||||
- Try again
|
||||
|
||||
## Comparison with Working MacBook
|
||||
|
||||
Since it works on another MacBook, compare:
|
||||
|
||||
1. **macOS Version:**
|
||||
```bash
|
||||
sw_vers # On both Macs
|
||||
```
|
||||
|
||||
2. **iCloud Account:**
|
||||
- Verify both Macs use same iCloud account
|
||||
- Check System Settings → Apple ID
|
||||
|
||||
3. **System Settings:**
|
||||
- Compare AirDrop & Handoff settings
|
||||
- Compare Firewall settings
|
||||
- Compare Bluetooth/Wi-Fi settings
|
||||
|
||||
4. **Network:**
|
||||
- Are both Macs on same network?
|
||||
- Any VPN differences?
|
||||
|
||||
## Quick Fix Script
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Quick fix for iPhone Mirroring issues
|
||||
|
||||
echo "Resetting Continuity services..."
|
||||
killall sharingd 2>/dev/null
|
||||
killall bluetoothd 2>/dev/null
|
||||
|
||||
echo "Restarting Bluetooth..."
|
||||
sudo launchctl stop com.apple.bluetoothd 2>/dev/null
|
||||
sudo launchctl start com.apple.bluetoothd 2>/dev/null
|
||||
|
||||
echo "Checking Handoff settings..."
|
||||
defaults read com.apple.coreservices.useractivityd.plist ActivityAdvertisingAllowed
|
||||
defaults read com.apple.coreservices.useractivityd.plist ActivityReceivingAllowed
|
||||
|
||||
echo "Done. Please restart your Mac and try again."
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- iPhone Mirroring requires **macOS Sequoia 15.0+** and **iOS 18.0+**
|
||||
- Both devices must be on same Wi-Fi network (or have Wi-Fi enabled even if using cellular)
|
||||
- Bluetooth must be enabled on both devices (used for proximity detection)
|
||||
- Same iCloud account is **required** (not just signed in, but same account)
|
||||
- Some corporate networks block device-to-device communication
|
||||
- VPNs can interfere with Continuity features
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
# iPhone Proxy Setup Guide
|
||||
|
||||
## Prerequisites
|
||||
- ✅ Tailscale installed and connected on iPhone
|
||||
- ✅ server2 proxy running at `100.70.115.1`
|
||||
|
||||
## Option 1: System-Wide Proxy (Limited Support)
|
||||
|
||||
iOS has limited system-wide proxy support. This works for some apps but not all browsers.
|
||||
|
||||
### Steps:
|
||||
1. Open **Settings** → **Wi-Fi**
|
||||
2. Tap the **ⓘ** icon next to your connected Wi-Fi network
|
||||
3. Scroll down to **HTTP Proxy**
|
||||
4. Select **Manual**
|
||||
5. Configure:
|
||||
- **Server:** `100.70.115.1`
|
||||
- **Port:** `7890` (HTTP) or `7892` (Mixed)
|
||||
- **Authentication:** Off
|
||||
6. Save
|
||||
|
||||
**Note:** This only works when connected to that specific Wi-Fi network. It won't work on cellular or other Wi-Fi networks.
|
||||
|
||||
## Option 2: Proxy App (Recommended)
|
||||
|
||||
**⚠️ Important: VPN Conflict Solution**
|
||||
|
||||
iOS only allows **one VPN connection** at a time. Since Tailscale uses VPN mode, you have two options:
|
||||
|
||||
### Solution A: Use Shadowrocket in Proxy Mode (Recommended)
|
||||
|
||||
Shadowrocket can work **WITH Tailscale** if configured correctly:
|
||||
|
||||
1. **Keep Tailscale ON** (for network access)
|
||||
2. Install **Shadowrocket** from App Store
|
||||
3. Open Shadowrocket
|
||||
4. Tap **+** (Add Server)
|
||||
5. Select **HTTP** (not VPN mode)
|
||||
6. Configure:
|
||||
- **Type:** HTTP
|
||||
- **Address:** `100.70.115.1` (Tailscale IP)
|
||||
- **Port:** `7890`
|
||||
- **Name:** server2-proxy
|
||||
7. Tap **Done**
|
||||
8. **Important:** In Shadowrocket settings:
|
||||
- Go to **Settings** → **Proxy**
|
||||
- Enable **"Use Proxy"** but **DO NOT enable VPN mode**
|
||||
- Or use **"Proxy" mode** instead of **"VPN" mode**
|
||||
9. Enable the proxy
|
||||
|
||||
**How it works:** Shadowrocket routes traffic through the proxy, but uses Tailscale's VPN connection to reach the proxy server. Both work together!
|
||||
|
||||
### Solution B: Use Shadowrocket VPN Mode (Disable Tailscale)
|
||||
|
||||
If you need Shadowrocket's VPN mode:
|
||||
1. **Disable Tailscale** temporarily
|
||||
2. Use Shadowrocket in VPN mode
|
||||
3. Shadowrocket will handle both VPN and proxy routing
|
||||
|
||||
**Note:** You'll lose direct Tailscale network access, but can still reach server2 via proxy.
|
||||
|
||||
### Surge (Paid, ~$10)
|
||||
Similar setup process - supports more advanced features.
|
||||
|
||||
### Potatso Lite (Free)
|
||||
1. Install **Potatso Lite**
|
||||
2. Add proxy with same settings
|
||||
|
||||
## Option 3: Safari Browser Extension
|
||||
|
||||
Some browsers support proxy extensions, but iOS Safari doesn't support system proxies well.
|
||||
|
||||
## Option 4: Clash Client for iOS
|
||||
|
||||
If you want to use Clash directly on iPhone:
|
||||
|
||||
### Clash Meta for iOS (Stash)
|
||||
1. Install **Stash** from App Store (or use TestFlight)
|
||||
2. Add your server2 as an HTTP proxy
|
||||
3. Configure routing rules
|
||||
|
||||
## Quick Test
|
||||
|
||||
After setup, test if proxy is working:
|
||||
|
||||
1. Open Safari or your browser
|
||||
2. Visit: https://api.ipify.org
|
||||
3. It should show server2's IP: `158.101.140.85` (not your iPhone's IP)
|
||||
|
||||
Or visit: http://100.70.115.1:9090/ui to see Clash dashboard
|
||||
|
||||
## Recommended Setup
|
||||
|
||||
**Best Solution: Use Both Together**
|
||||
- **Keep Tailscale ON** (for network connectivity)
|
||||
- Use **Shadowrocket in Proxy mode** (not VPN mode)
|
||||
- Configure HTTP proxy: `100.70.115.1:7890`
|
||||
- Shadowrocket will route through Tailscale's connection
|
||||
- Works on both Wi-Fi and cellular
|
||||
|
||||
**Alternative: Use Shadowrocket VPN Mode**
|
||||
- Disable Tailscale when using Shadowrocket VPN mode
|
||||
- Shadowrocket handles both VPN and proxy
|
||||
- You'll need to manually switch between them
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### VPN Conflict?
|
||||
- **If both Tailscale and Shadowrocket show VPN icons:** You can only have one active
|
||||
- **Solution:** Use Shadowrocket in **Proxy mode** (not VPN mode) while Tailscale is active
|
||||
- **Or:** Disable Tailscale and use Shadowrocket VPN mode
|
||||
|
||||
### Can't connect?
|
||||
1. Verify Tailscale is connected on iPhone (needed to reach `100.70.115.1`)
|
||||
2. Check Tailscale status: Open Tailscale app, verify you see "oracle-tokyo" device
|
||||
3. Test connection: Open Safari, visit `http://100.70.115.1:9090/ui`
|
||||
4. If dashboard loads, proxy is reachable via Tailscale
|
||||
|
||||
### Proxy not working?
|
||||
1. Check if proxy app is enabled/running
|
||||
2. Verify server2 is online: `ssh server2 'sudo systemctl status clash-meta'`
|
||||
3. Try different port: 7890 (HTTP), 7891 (SOCKS5), or 7892 (Mixed)
|
||||
4. Make sure Tailscale is connected (required to reach the proxy server)
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
# SSH Tunnel Workaround for iPhone Proxy
|
||||
|
||||
## The Problem
|
||||
Oracle Cloud Security List blocks proxy ports, and you don't have console access right now.
|
||||
|
||||
## Solution: SSH Tunnel via Your Mac
|
||||
|
||||
Since SSH (port 22) is already open, we can use it to tunnel proxy traffic!
|
||||
|
||||
### Step 1: Create SSH Tunnel on Your Mac
|
||||
|
||||
Open Terminal on your Mac and run:
|
||||
|
||||
```bash
|
||||
ssh -L 7890:127.0.0.1:7890 -N server2
|
||||
```
|
||||
|
||||
Or run in background:
|
||||
```bash
|
||||
ssh -f -N -L 7890:127.0.0.1:7890 server2
|
||||
```
|
||||
|
||||
This creates a tunnel: `Your Mac:7890` → `SSH` → `server2:7890`
|
||||
|
||||
### Step 2: Configure iPhone to Use Your Mac as Proxy
|
||||
|
||||
**Option A: If Mac and iPhone on Same Wi-Fi**
|
||||
|
||||
1. **On your Mac:**
|
||||
- System Settings → Network → Wi-Fi → Details → TCP/IP
|
||||
- Note your Mac's local IP (e.g., `192.168.1.100`)
|
||||
|
||||
2. **On iPhone:**
|
||||
- Settings → Wi-Fi → ⓘ (next to your Wi-Fi network)
|
||||
- Scroll to **HTTP Proxy** → **Manual**
|
||||
- **Server:** `192.168.1.100` (your Mac's IP)
|
||||
- **Port:** `7890`
|
||||
- **Authentication:** Off (SSH tunnel doesn't need it, but Clash does)
|
||||
|
||||
**Wait - this won't work because Clash needs authentication...**
|
||||
|
||||
### Better Solution: Use SOCKS Proxy Over SSH
|
||||
|
||||
Actually, SSH can create a SOCKS proxy directly!
|
||||
|
||||
### Step 3: Use SSH SOCKS Proxy (Better Method)
|
||||
|
||||
**On your Mac, run:**
|
||||
```bash
|
||||
ssh -D 1080 -N server2
|
||||
```
|
||||
|
||||
This creates a SOCKS5 proxy on your Mac at `127.0.0.1:1080`
|
||||
|
||||
**Then on iPhone (same Wi-Fi):**
|
||||
- Settings → Wi-Fi → ⓘ → HTTP Proxy → Manual
|
||||
- **Server:** `192.168.1.100` (your Mac's IP)
|
||||
- **Port:** `1080`
|
||||
- **Type:** SOCKS5 (if option available)
|
||||
|
||||
**But iOS HTTP Proxy doesn't support SOCKS5...**
|
||||
|
||||
### Best Workaround: Use a Proxy App on Mac
|
||||
|
||||
Install a local proxy server on your Mac that:
|
||||
1. Connects to server2 via SSH tunnel
|
||||
2. Provides HTTP proxy for iPhone
|
||||
|
||||
### Alternative: Use Tailscale (If Available)
|
||||
|
||||
If you can use Tailscale:
|
||||
1. Enable Tailscale VPN on iPhone
|
||||
2. Configure Shadowrocket to use: `100.70.115.1:7890`
|
||||
3. This bypasses Oracle Cloud firewall
|
||||
|
||||
### Simplest Workaround: Keep SSH Tunnel + Use Mac as Bridge
|
||||
|
||||
1. **On Mac:** Create SSH tunnel to server2's Clash
|
||||
2. **On Mac:** Run a local proxy server that iPhone can connect to
|
||||
3. **On iPhone:** Connect to Mac's proxy
|
||||
|
||||
Let me create a script for this...
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,125 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Move Small Files Test - Start with smallest files first
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Move Small Files Test ==="
|
||||
echo ""
|
||||
|
||||
NAS_PATH="/Volumes/Download/temp documents from MAc"
|
||||
DOCS_PATH="$HOME/Documents"
|
||||
|
||||
# Check NAS is mounted
|
||||
if [ ! -d "$NAS_PATH" ]; then
|
||||
echo "⚠️ NAS not mounted at: $NAS_PATH"
|
||||
echo " Please check your mount point"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check current space
|
||||
FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB=$(echo "scale=2; $FREE_SPACE / 1024 / 1024" | bc)
|
||||
echo "Current free space: ${FREE_SPACE_GB}GB"
|
||||
echo ""
|
||||
|
||||
# Create destination
|
||||
mkdir -p "$NAS_PATH/Documents"
|
||||
|
||||
echo "🔍 Finding smallest folders/files to move first..."
|
||||
echo ""
|
||||
|
||||
# Get list sorted by size (smallest first)
|
||||
du -h -d 1 "$DOCS_PATH" 2>/dev/null | sort -h | while read size item; do
|
||||
# Skip the total line
|
||||
if [ "$item" = "$DOCS_PATH" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
FOLDER_NAME=$(basename "$item")
|
||||
|
||||
# Skip if it's not a directory
|
||||
if [ ! -d "$item" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Show what we found
|
||||
echo "Found: $FOLDER_NAME ($size)"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "📦 Moving smallest items first (under 1GB)..."
|
||||
echo ""
|
||||
|
||||
MOVED_COUNT=0
|
||||
|
||||
# Move items under 1GB first
|
||||
du -h -d 1 "$DOCS_PATH" 2>/dev/null | sort -h | while read size item; do
|
||||
# Skip the total line
|
||||
if [ "$item" = "$DOCS_PATH" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Skip if not a directory
|
||||
if [ ! -d "$item" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
FOLDER_NAME=$(basename "$item")
|
||||
|
||||
# Check if size is under 1GB (look for M or K, not G)
|
||||
if echo "$size" | grep -qE "[0-9]+[MK]"; then
|
||||
echo "Moving: $FOLDER_NAME ($size)..."
|
||||
|
||||
if mv -v "$item" "$NAS_PATH/Documents/" 2>&1 | tail -3; then
|
||||
echo " ✅ Successfully moved"
|
||||
MOVED_COUNT=$((MOVED_COUNT + 1))
|
||||
|
||||
# Show progress
|
||||
REMAINING=$(du -sh "$DOCS_PATH" 2>/dev/null | awk '{print $1}')
|
||||
MOVED=$(du -sh "$NAS_PATH/Documents" 2>/dev/null | awk '{print $1}')
|
||||
FREE_NOW=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_NOW_GB=$(echo "scale=2; $FREE_NOW / 1024 / 1024" | bc)
|
||||
|
||||
echo " Progress: $MOVED on NAS, $REMAINING remaining"
|
||||
echo " Free space: ${FREE_NOW_GB}GB"
|
||||
echo ""
|
||||
|
||||
# Ask to continue after a few moves
|
||||
if [ $MOVED_COUNT -ge 3 ]; then
|
||||
read -p " Continue with more small files? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo " Stopped. Run again to continue."
|
||||
break
|
||||
fi
|
||||
MOVED_COUNT=0
|
||||
fi
|
||||
else
|
||||
echo " ⚠️ Error moving $FOLDER_NAME"
|
||||
echo " Continuing with next..."
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "📊 Summary:"
|
||||
REMAINING=$(du -sh "$DOCS_PATH" 2>/dev/null | awk '{print $1}')
|
||||
MOVED=$(du -sh "$NAS_PATH/Documents" 2>/dev/null | awk '{print $1}')
|
||||
FREE_NOW=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_NOW_GB=$(echo "scale=2; $FREE_NOW / 1024 / 1024" | bc)
|
||||
|
||||
echo " Moved to NAS: $MOVED"
|
||||
echo " Remaining: $REMAINING"
|
||||
echo " Free space now: ${FREE_NOW_GB}GB"
|
||||
echo ""
|
||||
|
||||
if [ "$REMAINING" != "0B" ] && [ -n "$REMAINING" ]; then
|
||||
echo "✅ Test successful! You can now:"
|
||||
echo " 1. Run this script again to move more small files"
|
||||
echo " 2. Or move larger files manually"
|
||||
echo " 3. Or use: ./safe_move_documents.sh for automated chunked moves"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,113 +0,0 @@
|
||||
# Oracle Cloud Console - Open Proxy Ports
|
||||
|
||||
## Step-by-Step Instructions
|
||||
|
||||
### Step 1: Find Your VCN
|
||||
From the screenshot, you have multiple VCNs. We need to find which one your server2 instance uses.
|
||||
|
||||
**Option A: Check from server2**
|
||||
```bash
|
||||
ssh server2 'ip addr show ens3 | grep "inet "'
|
||||
```
|
||||
This will show the IP (e.g., 10.0.0.100), which matches VCN CIDR 10.0.0.0/16.
|
||||
|
||||
**Option B: Check instance details**
|
||||
- Go to **Compute** → **Instances**
|
||||
- Find your server2 instance
|
||||
- Click on it
|
||||
- Check the **VCN** or **Subnet** it's attached to
|
||||
|
||||
### Step 2: Open the VCN
|
||||
1. Click on the **VCN name** (e.g., "vcn-20250609-0221") that matches your instance
|
||||
2. This opens the VCN details page
|
||||
|
||||
### Step 3: Navigate to Security Lists
|
||||
1. In the VCN details page, look for **"Security Lists"** in the left sidebar or Resources section
|
||||
2. Click on **"Security Lists"**
|
||||
3. You'll see a list of security lists (usually "Default Security List for vcn-...")
|
||||
|
||||
### Step 4: Edit the Security List
|
||||
1. Click on the **Default Security List** (or the one attached to your subnet)
|
||||
2. Click **"Edit All Rules"** or **"Add Ingress Rules"**
|
||||
|
||||
### Step 5: Add Ingress Rules
|
||||
Add these 4 rules (one for each port):
|
||||
|
||||
**Rule 1: HTTP Proxy (7890)**
|
||||
- **Source Type:** CIDR
|
||||
- **Source CIDR:** `0.0.0.0/0` (or your IP for better security)
|
||||
- **IP Protocol:** TCP
|
||||
- **Destination Port Range:** `7890`
|
||||
- **Description:** `Clash HTTP Proxy`
|
||||
|
||||
**Rule 2: SOCKS5 Proxy (7891)**
|
||||
- **Source Type:** CIDR
|
||||
- **Source CIDR:** `0.0.0.0/0`
|
||||
- **IP Protocol:** TCP
|
||||
- **Destination Port Range:** `7891`
|
||||
- **Description:** `Clash SOCKS5 Proxy`
|
||||
|
||||
**Rule 3: Mixed Proxy (7892)**
|
||||
- **Source Type:** CIDR
|
||||
- **Source CIDR:** `0.0.0.0/0`
|
||||
- **IP Protocol:** TCP
|
||||
- **Destination Port Range:** `7892`
|
||||
- **Description:** `Clash Mixed Proxy`
|
||||
|
||||
**Rule 4: Web UI (9090)**
|
||||
- **Source Type:** CIDR
|
||||
- **Source CIDR:** `0.0.0.0/0`
|
||||
- **IP Protocol:** TCP
|
||||
- **Destination Port Range:** `9090`
|
||||
- **Description:** `Clash Web UI`
|
||||
|
||||
### Step 6: Save
|
||||
1. Click **"Save Changes"** or **"Add Ingress Rules"**
|
||||
2. Wait 30-60 seconds for rules to propagate
|
||||
|
||||
### Step 7: Test
|
||||
After adding rules, test from your iPhone:
|
||||
- Open Shadowrocket
|
||||
- Add server: `158.101.140.85:7890`
|
||||
- Username: `proxy_user`
|
||||
- Password: `Cs7yBx1Rh9oK`
|
||||
- Test connection
|
||||
|
||||
## Security Note
|
||||
|
||||
Using `0.0.0.0/0` allows access from anywhere. For better security:
|
||||
- Use your home IP: `YOUR_IP/32`
|
||||
- Or use a VPN IP range
|
||||
- The proxy has authentication, so it's somewhat protected
|
||||
|
||||
## Quick Navigation Path
|
||||
|
||||
1. **Networking** → **Virtual Cloud Networks**
|
||||
2. Click your VCN (the one with 10.0.0.0/16)
|
||||
3. **Security Lists** (left sidebar or Resources)
|
||||
4. Click **Default Security List**
|
||||
5. **Add Ingress Rules**
|
||||
6. Add 4 rules (ports 7890, 7891, 7892, 9090)
|
||||
7. **Save**
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Can't find Security Lists?**
|
||||
- Make sure you're in the VCN details page
|
||||
- Look in the left sidebar under "Resources"
|
||||
- Or check the "Resources" tab in the main content area
|
||||
|
||||
**Rules not working?**
|
||||
- Wait 1-2 minutes for propagation
|
||||
- Check that you added rules to the correct Security List
|
||||
- Verify the Security List is attached to your subnet
|
||||
- Check instance's subnet assignment
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Safe Move Documents - Move in smaller chunks to avoid getting stuck
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Safe Move Documents ==="
|
||||
echo ""
|
||||
echo "Moving large folders can get stuck. This script moves in smaller chunks."
|
||||
echo ""
|
||||
|
||||
NAS_PATH="/Volumes/Download/temp documents from MAc"
|
||||
DOCS_PATH="$HOME/Documents"
|
||||
|
||||
# Check if NAS is mounted
|
||||
if [ ! -d "$NAS_PATH" ]; then
|
||||
echo "⚠️ NAS path not found: $NAS_PATH"
|
||||
echo ""
|
||||
echo "Please check your NAS mount point:"
|
||||
ls -la /Volumes/ | grep -i "download\|ds224"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📊 Current Status:"
|
||||
DOCS_SIZE=$(du -sh "$DOCS_PATH" 2>/dev/null | awk '{print $1}')
|
||||
echo " Documents size: $DOCS_SIZE"
|
||||
echo ""
|
||||
|
||||
# Check what's already moved
|
||||
if [ -d "$NAS_PATH/Documents" ]; then
|
||||
MOVED_SIZE=$(du -sh "$NAS_PATH/Documents" 2>/dev/null | awk '{print $1}')
|
||||
echo " Already on NAS: $MOVED_SIZE"
|
||||
echo ""
|
||||
echo " ⚠️ Documents folder already exists on NAS!"
|
||||
echo " The previous move may have partially completed."
|
||||
echo ""
|
||||
read -p " Continue moving remaining files? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "🔍 Analyzing Documents folder..."
|
||||
echo " Finding largest subfolders to move first..."
|
||||
du -h -d 1 "$DOCS_PATH" 2>/dev/null | sort -hr | head -10
|
||||
echo ""
|
||||
|
||||
echo "📦 Strategy: Move in smaller chunks"
|
||||
echo ""
|
||||
echo "This will:"
|
||||
echo " 1. Move largest subfolders one at a time"
|
||||
echo " 2. Show progress after each move"
|
||||
echo " 3. Allow you to stop if needed"
|
||||
echo ""
|
||||
|
||||
read -p "Proceed with chunked move? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Create destination
|
||||
mkdir -p "$NAS_PATH/Documents"
|
||||
|
||||
echo ""
|
||||
echo "🚚 Moving in chunks..."
|
||||
echo ""
|
||||
|
||||
# Get list of subfolders, sorted by size
|
||||
du -h -d 1 "$DOCS_PATH" 2>/dev/null | sort -hr | while read size folder; do
|
||||
# Skip the total line
|
||||
if [ "$folder" = "$DOCS_PATH" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
FOLDER_NAME=$(basename "$folder")
|
||||
|
||||
# Skip if it's a file (not a directory)
|
||||
if [ ! -d "$folder" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "Moving: $FOLDER_NAME ($size)..."
|
||||
|
||||
# Move with verbose output
|
||||
if mv -v "$folder" "$NAS_PATH/Documents/" 2>&1 | head -5; then
|
||||
echo " ✅ Moved successfully"
|
||||
else
|
||||
echo " ⚠️ Error moving $FOLDER_NAME"
|
||||
echo " Continuing with next folder..."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Show progress
|
||||
REMAINING=$(du -sh "$DOCS_PATH" 2>/dev/null | awk '{print $1}')
|
||||
MOVED=$(du -sh "$NAS_PATH/Documents" 2>/dev/null | awk '{print $1}')
|
||||
echo " Progress: $MOVED moved, $REMAINING remaining"
|
||||
echo ""
|
||||
|
||||
# Ask to continue after each large folder
|
||||
if echo "$size" | grep -qE "[0-9]+G"; then
|
||||
read -p " Continue? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo " Stopped. You can resume later."
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "📊 Final Status:"
|
||||
REMAINING=$(du -sh "$DOCS_PATH" 2>/dev/null | awk '{print $1}')
|
||||
MOVED=$(du -sh "$NAS_PATH/Documents" 2>/dev/null | awk '{print $1}')
|
||||
echo " Moved to NAS: $MOVED"
|
||||
echo " Remaining: $REMAINING"
|
||||
echo ""
|
||||
|
||||
if [ "$REMAINING" != "0B" ] && [ -n "$REMAINING" ]; then
|
||||
echo "⚠️ Some files remain. You can:"
|
||||
echo " 1. Run this script again to continue"
|
||||
echo " 2. Manually move remaining files"
|
||||
echo " 3. Leave them if they're small"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,222 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Setup Clash Meta proxy server on server2
|
||||
# Clash Meta is more actively maintained than original Clash
|
||||
|
||||
echo "=== Setting up Clash Meta proxy server on server2 ==="
|
||||
echo ""
|
||||
|
||||
ssh server2 << 'EOF'
|
||||
set -e
|
||||
|
||||
# Get Tailscale IP
|
||||
TAILSCALE_IP=$(tailscale ip -4)
|
||||
echo "Tailscale IP: $TAILSCALE_IP"
|
||||
echo ""
|
||||
|
||||
# Detect architecture
|
||||
ARCH=$(uname -m)
|
||||
case $ARCH in
|
||||
x86_64) CLASH_ARCH="amd64" ;;
|
||||
aarch64|arm64) CLASH_ARCH="arm64" ;;
|
||||
*) echo "Unsupported architecture: $ARCH"; exit 1 ;;
|
||||
esac
|
||||
|
||||
# Create directories
|
||||
CLASH_DIR="$HOME/clash-meta"
|
||||
mkdir -p "$CLASH_DIR"
|
||||
mkdir -p ~/.config/clash-meta
|
||||
cd "$CLASH_DIR"
|
||||
|
||||
# Download Clash Meta
|
||||
echo "Downloading Clash Meta..."
|
||||
CLASH_VERSION="v1.18.0"
|
||||
CLASH_FILE="clash.meta-linux-${CLASH_ARCH}-${CLASH_VERSION}"
|
||||
|
||||
if wget -q "https://github.com/MetaCubeX/mihomo/releases/download/${CLASH_VERSION}/${CLASH_FILE}.gz" -O clash.gz; then
|
||||
gunzip -f clash.gz
|
||||
mv "$CLASH_FILE" clash
|
||||
chmod +x clash
|
||||
echo "✓ Clash Meta downloaded"
|
||||
else
|
||||
echo "Failed to download Clash Meta. Trying alternative method..."
|
||||
# Try downloading from release page
|
||||
wget -q "https://github.com/MetaCubeX/mihomo/releases/latest/download/mihomo-linux-${CLASH_ARCH}.gz" -O clash.gz 2>/dev/null || \
|
||||
wget -q "https://github.com/MetaCubeX/mihomo/releases/download/v1.18.0/mihomo-linux-${CLASH_ARCH}.gz" -O clash.gz
|
||||
gunzip -f clash.gz
|
||||
mv mihomo-linux-${CLASH_ARCH} clash 2>/dev/null || mv mihomo clash
|
||||
chmod +x clash
|
||||
fi
|
||||
|
||||
# Verify installation
|
||||
if [ -f ./clash ]; then
|
||||
./clash -v || echo "Clash binary ready"
|
||||
else
|
||||
echo "✗ Clash binary not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create Clash configuration
|
||||
echo "Creating configuration..."
|
||||
cat > ~/.config/clash-meta/config.yaml << CONFIG
|
||||
# Clash Meta configuration for server2 proxy
|
||||
port: 7890
|
||||
socks-port: 7891
|
||||
mixed-port: 7892
|
||||
allow-lan: true
|
||||
bind-address: '*'
|
||||
mode: rule
|
||||
log-level: info
|
||||
ipv6: false
|
||||
external-controller: 0.0.0.0:9090
|
||||
external-ui: ui
|
||||
|
||||
# DNS
|
||||
dns:
|
||||
enable: true
|
||||
listen: 0.0.0.0:53
|
||||
enhanced-mode: fake-ip
|
||||
fake-ip-range: 198.18.0.1/16
|
||||
nameserver:
|
||||
- 8.8.8.8
|
||||
- 1.1.1.1
|
||||
fallback:
|
||||
- 8.8.4.4
|
||||
- 1.0.0.1
|
||||
fallback-filter:
|
||||
geoip: true
|
||||
geoip-code: CN
|
||||
ipcidr:
|
||||
- 240.0.0.0/4
|
||||
|
||||
# Proxy (direct connection)
|
||||
proxies:
|
||||
- name: "direct"
|
||||
type: direct
|
||||
|
||||
# Proxy groups
|
||||
proxy-groups:
|
||||
- name: "Proxy"
|
||||
type: select
|
||||
proxies:
|
||||
- direct
|
||||
- name: "Auto"
|
||||
type: select
|
||||
proxies:
|
||||
- direct
|
||||
|
||||
# Rules - route all traffic through direct connection
|
||||
rules:
|
||||
- MATCH,Proxy
|
||||
|
||||
# Experimental
|
||||
experimental:
|
||||
ignore-resolve-fail: true
|
||||
sniff-tls-sni: true
|
||||
CONFIG
|
||||
|
||||
# Download Clash dashboard UI
|
||||
echo "Downloading Clash UI..."
|
||||
cd ~/.config/clash-meta
|
||||
if [ ! -d ui ]; then
|
||||
wget -q https://github.com/haishanh/yacd/archive/gh-pages.zip -O ui.zip 2>/dev/null || \
|
||||
wget -q https://github.com/haishanh/yacd/releases/latest/download/yacd.tar.xz -O yacd.tar.xz 2>/dev/null
|
||||
if [ -f yacd.tar.xz ]; then
|
||||
tar -xf yacd.tar.xz
|
||||
mv public ui
|
||||
rm yacd.tar.xz
|
||||
elif [ -f ui.zip ]; then
|
||||
unzip -q ui.zip
|
||||
mv yacd-gh-pages ui
|
||||
rm ui.zip
|
||||
else
|
||||
echo "UI download failed, but Clash will work without it"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create systemd service
|
||||
echo "Creating systemd service..."
|
||||
sudo tee /etc/systemd/system/clash-meta.service > /dev/null << SERVICE
|
||||
[Unit]
|
||||
Description=Clash Meta daemon
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=always
|
||||
User=$USER
|
||||
WorkingDirectory=$CLASH_DIR
|
||||
ExecStart=$CLASH_DIR/clash -d $HOME/.config/clash-meta
|
||||
Environment="HOME=$HOME"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SERVICE
|
||||
|
||||
# Reload systemd and start Clash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable clash-meta
|
||||
sudo systemctl restart clash-meta
|
||||
|
||||
# Wait for service to start
|
||||
sleep 3
|
||||
|
||||
# Check status
|
||||
if sudo systemctl is-active --quiet clash-meta; then
|
||||
echo ""
|
||||
echo "✓ Clash Meta is running!"
|
||||
echo ""
|
||||
echo "=== Configuration Summary ==="
|
||||
echo "HTTP Proxy: $TAILSCALE_IP:7890"
|
||||
echo "SOCKS5 Proxy: $TAILSCALE_IP:7891"
|
||||
echo "Mixed Proxy (HTTP+SOCKS5): $TAILSCALE_IP:7892"
|
||||
echo "Web UI: http://$TAILSCALE_IP:9090/ui"
|
||||
echo ""
|
||||
|
||||
# Configure firewall
|
||||
echo "=== Firewall Configuration ==="
|
||||
if command -v ufw >/dev/null 2>&1 && sudo ufw status | grep -q "Status: active"; then
|
||||
echo "Configuring UFW..."
|
||||
sudo ufw allow 7890/tcp comment "Clash HTTP"
|
||||
sudo ufw allow 7891/tcp comment "Clash SOCKS5"
|
||||
sudo ufw allow 7892/tcp comment "Clash Mixed"
|
||||
sudo ufw allow 9090/tcp comment "Clash Web UI"
|
||||
sudo ufw allow 53/udp comment "Clash DNS"
|
||||
else
|
||||
echo "UFW not active. If using iptables, ensure ports 7890, 7891, 7892, 9090, 53 are open."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Client Configuration ==="
|
||||
echo "For Clash clients, configure:"
|
||||
echo " Type: HTTP"
|
||||
echo " Server: $TAILSCALE_IP"
|
||||
echo " Port: 7890"
|
||||
echo ""
|
||||
echo "Or use Mixed port (supports both HTTP and SOCKS5):"
|
||||
echo " Server: $TAILSCALE_IP"
|
||||
echo " Port: 7892"
|
||||
|
||||
else
|
||||
echo "✗ Clash Meta failed to start"
|
||||
echo "Check logs: sudo journalctl -u clash-meta -n 50"
|
||||
exit 1
|
||||
fi
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
echo "=== Setup Complete ==="
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " Status: ssh server2 'sudo systemctl status clash-meta'"
|
||||
echo " Logs: ssh server2 'sudo journalctl -u clash-meta -f'"
|
||||
echo " Restart: ssh server2 'sudo systemctl restart clash-meta'"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Setup Clash proxy server on server2
|
||||
# This will install Clash and configure it to work with Tailscale
|
||||
|
||||
echo "=== Setting up Clash proxy server on server2 ==="
|
||||
echo ""
|
||||
|
||||
ssh server2 << 'EOF'
|
||||
set -e
|
||||
|
||||
# Get Tailscale IP
|
||||
TAILSCALE_IP=$(tailscale ip -4)
|
||||
echo "Tailscale IP: $TAILSCALE_IP"
|
||||
echo ""
|
||||
|
||||
# Create clash directory
|
||||
CLASH_DIR="$HOME/clash"
|
||||
mkdir -p "$CLASH_DIR"
|
||||
cd "$CLASH_DIR"
|
||||
|
||||
# Download Clash (latest version)
|
||||
echo "Downloading Clash..."
|
||||
CLASH_VERSION="v1.20.0"
|
||||
ARCH="amd64"
|
||||
if [ "$(uname -m)" = "aarch64" ] || [ "$(uname -m)" = "arm64" ]; then
|
||||
ARCH="arm64"
|
||||
fi
|
||||
|
||||
wget -q "https://github.com/Dreamacro/clash/releases/download/${CLASH_VERSION}/clash-linux-${ARCH}-${CLASH_VERSION}.gz" -O clash.gz
|
||||
gunzip -f clash.gz
|
||||
chmod +x clash
|
||||
|
||||
# Create config directory
|
||||
mkdir -p ~/.config/clash
|
||||
|
||||
# Create Clash configuration file
|
||||
cat > ~/.config/clash/config.yaml << CONFIG
|
||||
# Clash configuration for server2 proxy
|
||||
port: 7890
|
||||
socks-port: 7891
|
||||
allow-lan: true
|
||||
bind-address: '*'
|
||||
mode: rule
|
||||
log-level: info
|
||||
external-controller: 0.0.0.0:9090
|
||||
external-ui: /root/.config/clash/ui
|
||||
|
||||
# DNS
|
||||
dns:
|
||||
enable: true
|
||||
listen: 0.0.0.0:53
|
||||
enhanced-mode: fake-ip
|
||||
nameserver:
|
||||
- 8.8.8.8
|
||||
- 1.1.1.1
|
||||
fallback:
|
||||
- 8.8.4.4
|
||||
- 1.0.0.1
|
||||
|
||||
# Proxy (direct connection - no upstream proxy needed)
|
||||
proxies:
|
||||
- name: "direct"
|
||||
type: direct
|
||||
|
||||
# Proxy groups
|
||||
proxy-groups:
|
||||
- name: "Proxy"
|
||||
type: select
|
||||
proxies:
|
||||
- direct
|
||||
- name: "Auto"
|
||||
type: select
|
||||
proxies:
|
||||
- direct
|
||||
|
||||
# Rules - route all traffic through direct connection
|
||||
rules:
|
||||
- MATCH,Proxy
|
||||
|
||||
# Experimental features
|
||||
experimental:
|
||||
ignore-resolve-fail: true
|
||||
CONFIG
|
||||
|
||||
# Download Clash dashboard UI (optional but useful)
|
||||
echo "Downloading Clash UI..."
|
||||
if [ ! -d ~/.config/clash/ui ]; then
|
||||
cd ~/.config/clash
|
||||
wget -q https://github.com/haishanh/yacd/releases/latest/download/yacd.tar.xz -O yacd.tar.xz
|
||||
tar -xf yacd.tar.xz
|
||||
mv public ui
|
||||
rm yacd.tar.xz
|
||||
fi
|
||||
|
||||
# Create systemd service
|
||||
echo "Creating systemd service..."
|
||||
sudo tee /etc/systemd/system/clash.service > /dev/null << SERVICE
|
||||
[Unit]
|
||||
Description=Clash daemon
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=always
|
||||
User=$USER
|
||||
ExecStart=$CLASH_DIR/clash -d $HOME/.config/clash
|
||||
Environment="HOME=$HOME"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SERVICE
|
||||
|
||||
# Reload systemd and start Clash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable clash
|
||||
sudo systemctl restart clash
|
||||
|
||||
# Wait a moment for service to start
|
||||
sleep 2
|
||||
|
||||
# Check status
|
||||
if sudo systemctl is-active --quiet clash; then
|
||||
echo ""
|
||||
echo "✓ Clash is running!"
|
||||
echo ""
|
||||
echo "=== Configuration Summary ==="
|
||||
echo "HTTP Proxy: $TAILSCALE_IP:7890"
|
||||
echo "SOCKS5 Proxy: $TAILSCALE_IP:7891"
|
||||
echo "Web UI: http://$TAILSCALE_IP:9090/ui"
|
||||
echo ""
|
||||
echo "=== Firewall Configuration ==="
|
||||
echo "Checking firewall rules..."
|
||||
|
||||
# Check if ufw is active
|
||||
if sudo ufw status | grep -q "Status: active"; then
|
||||
echo "UFW is active. Adding rules..."
|
||||
sudo ufw allow 7890/tcp comment "Clash HTTP"
|
||||
sudo ufw allow 7891/tcp comment "Clash SOCKS5"
|
||||
sudo ufw allow 9090/tcp comment "Clash Web UI"
|
||||
sudo ufw allow 53/udp comment "Clash DNS"
|
||||
else
|
||||
echo "UFW is not active. If using iptables, you may need to add rules manually."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Client Configuration ==="
|
||||
echo "For Clash clients, use this proxy:"
|
||||
echo " Type: HTTP"
|
||||
echo " Server: $TAILSCALE_IP"
|
||||
echo " Port: 7890"
|
||||
echo ""
|
||||
echo "Or SOCKS5:"
|
||||
echo " Type: SOCKS5"
|
||||
echo " Server: $TAILSCALE_IP"
|
||||
echo " Port: 7891"
|
||||
else
|
||||
echo "✗ Clash failed to start. Check logs with: sudo journalctl -u clash -n 50"
|
||||
exit 1
|
||||
fi
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
echo "=== Setup Complete ==="
|
||||
echo ""
|
||||
echo "To check Clash status: ssh server2 'sudo systemctl status clash'"
|
||||
echo "To view logs: ssh server2 'sudo journalctl -u clash -f'"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Setup Mac as Proxy Bridge for iPhone
|
||||
# This script sets up a local proxy on Mac that tunnels to server2
|
||||
|
||||
echo "=== Mac Proxy Bridge Setup ==="
|
||||
echo ""
|
||||
|
||||
# Check if Python is available (for simple HTTP proxy)
|
||||
if command -v python3 &> /dev/null; then
|
||||
echo "Python3 found - creating simple proxy bridge..."
|
||||
echo ""
|
||||
echo "Run this command to start the bridge:"
|
||||
echo ""
|
||||
echo "python3 -m http.server 8080 &"
|
||||
echo "ssh -L 7890:127.0.0.1:7890 -N server2 &"
|
||||
echo ""
|
||||
echo "But we need a proper HTTP proxy, not just a web server..."
|
||||
fi
|
||||
|
||||
# Better: Use socat or create a proper proxy
|
||||
if command -v socat &> /dev/null; then
|
||||
echo "socat found - can create proxy bridge"
|
||||
echo ""
|
||||
echo "Run:"
|
||||
echo "ssh -L 7890:127.0.0.1:7890 -N server2 &"
|
||||
echo "socat TCP-LISTEN:8080,fork,reuseaddr TCP:127.0.0.1:7890 &"
|
||||
else
|
||||
echo "Installing socat for proxy bridging..."
|
||||
echo "brew install socat"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Alternative: Use SSH Dynamic Port Forwarding ==="
|
||||
echo ""
|
||||
echo "Run this on your Mac:"
|
||||
echo "ssh -D 1080 -N server2"
|
||||
echo ""
|
||||
echo "This creates a SOCKS5 proxy on localhost:1080"
|
||||
echo "But iPhone HTTP Proxy doesn't support SOCKS5 directly..."
|
||||
@@ -1,110 +0,0 @@
|
||||
# Shadowrocket Setup for Cellular Data
|
||||
|
||||
## The Solution
|
||||
|
||||
Since iOS doesn't support HTTP proxy for cellular data, you need to use **Shadowrocket VPN mode**. Here's how:
|
||||
|
||||
## Setup Steps
|
||||
|
||||
### Step 1: Configure Server (Already Done ✅)
|
||||
- Clash now listens on all interfaces
|
||||
- Firewall allows Tailscale network (100.x.x.x) only
|
||||
- Proxy accessible at: `100.70.115.1:7890`
|
||||
|
||||
### Step 2: On Your iPhone
|
||||
|
||||
**Option A: Use Shadowrocket VPN Mode (Recommended for Cellular)**
|
||||
|
||||
1. **Disable Tailscale VPN:**
|
||||
- Open Tailscale app
|
||||
- Toggle VPN OFF (but keep app installed/running)
|
||||
- This frees up the VPN slot for Shadowrocket
|
||||
|
||||
2. **Configure Shadowrocket:**
|
||||
- Open Shadowrocket
|
||||
- Go to **Home** tab
|
||||
- Tap **"+"** to add server
|
||||
- Select **HTTP**
|
||||
- Enter:
|
||||
- **Address:** `100.70.115.1`
|
||||
- **Port:** `7890`
|
||||
- **Remark:** `server2-proxy`
|
||||
- Tap **Done**
|
||||
|
||||
3. **Enable Shadowrocket:**
|
||||
- Select `server2-proxy` in Home tab
|
||||
- Toggle switch **ON**
|
||||
- VPN icon should appear in status bar
|
||||
|
||||
4. **Test:**
|
||||
- Open Safari
|
||||
- Visit: https://api.ipify.org
|
||||
- Should show: `158.101.140.85` (server2's IP)
|
||||
- Works on both Wi-Fi and cellular! ✅
|
||||
|
||||
**How it works:**
|
||||
- Shadowrocket creates a VPN connection
|
||||
- It routes all traffic (Wi-Fi + cellular) through the proxy
|
||||
- Traffic goes: iPhone → Shadowrocket VPN → Tailscale network → server2 proxy → Internet
|
||||
|
||||
**Note:** You'll lose direct Tailscale network access (can't SSH to other Tailscale devices), but proxy will work on both Wi-Fi and cellular.
|
||||
|
||||
### Option B: Keep Tailscale VPN, Use System Proxy (Wi-Fi Only)
|
||||
|
||||
If you need Tailscale network access:
|
||||
|
||||
1. **Keep Tailscale VPN ON**
|
||||
2. **Don't use Shadowrocket VPN mode**
|
||||
3. Configure system proxy for Wi-Fi:
|
||||
- Settings → Wi-Fi → ⓘ → HTTP Proxy → Manual
|
||||
- Server: `100.70.115.1`
|
||||
- Port: `7890`
|
||||
4. **Cellular won't work** with this method (iOS limitation)
|
||||
|
||||
## Recommendation
|
||||
|
||||
**Use Option A (Shadowrocket VPN mode)** if you:
|
||||
- Need proxy on cellular data
|
||||
- Don't need direct Tailscale network access while using proxy
|
||||
- Want it to work everywhere
|
||||
|
||||
**Use Option B (System proxy)** if you:
|
||||
- Only need proxy on Wi-Fi
|
||||
- Need direct Tailscale network access
|
||||
- Can live without cellular proxy
|
||||
|
||||
## Switching Between Modes
|
||||
|
||||
You can easily switch:
|
||||
- **Need proxy on cellular?** → Disable Tailscale VPN, enable Shadowrocket VPN
|
||||
- **Need Tailscale network?** → Disable Shadowrocket VPN, enable Tailscale VPN
|
||||
- **Need both?** → Use system proxy on Wi-Fi (but no cellular proxy)
|
||||
|
||||
## Testing
|
||||
|
||||
After setup:
|
||||
1. Turn OFF Wi-Fi (use cellular only)
|
||||
2. Open Safari
|
||||
3. Visit: https://api.ipify.org
|
||||
4. Should show server2's IP: `158.101.140.85`
|
||||
5. If it shows your cellular IP, proxy isn't working
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Proxy not working on cellular?**
|
||||
- Make sure Shadowrocket VPN is enabled (VPN icon in status bar)
|
||||
- Check that server2 is online: `ssh server2 'sudo systemctl status clash-meta'`
|
||||
- Verify Tailscale network is reachable (even with VPN off, the network should exist)
|
||||
|
||||
**Can't reach other Tailscale devices?**
|
||||
- That's expected when Shadowrocket VPN is on
|
||||
- Disable Shadowrocket VPN and enable Tailscale VPN when you need direct access
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
# Shadowrocket Correct Setup - Working with Tailscale
|
||||
|
||||
## Understanding Shadowrocket Architecture
|
||||
|
||||
Shadowrocket works as a **local proxy server** on your iPhone:
|
||||
- Apps connect to Shadowrocket's local proxy (127.0.0.1:80)
|
||||
- Shadowrocket forwards traffic to your configured server (server2)
|
||||
- This way it doesn't need VPN mode!
|
||||
|
||||
## Step-by-Step Setup
|
||||
|
||||
### Step 1: Add Server2 as a Server (NOT in Proxy Settings)
|
||||
|
||||
1. Open Shadowrocket app
|
||||
2. Go to the **"Home"** tab (house icon at bottom)
|
||||
3. Tap the **"+"** button in the top right corner
|
||||
4. Select **"HTTP"** or **"HTTPS"**
|
||||
5. Fill in:
|
||||
- **Remark:** `server2-proxy`
|
||||
- **Address:** `100.70.115.1` (your Tailscale IP)
|
||||
- **Port:** `7890` (HTTP) or `7892` (Mixed)
|
||||
- **Username:** (leave empty)
|
||||
- **Password:** (leave empty)
|
||||
6. Tap **"Done"**
|
||||
|
||||
### Step 2: Enable the Server
|
||||
|
||||
1. Go back to **"Home"** tab
|
||||
2. You should see `server2-proxy` in the server list
|
||||
3. Tap on it to select it
|
||||
4. Toggle the switch at the top to **ON**
|
||||
|
||||
### Step 3: Configure Proxy Settings (What You Saw)
|
||||
|
||||
The "Proxy Settings" you saw (127.0.0.1:80) is Shadowrocket's **local proxy** that apps connect to. You can configure it:
|
||||
|
||||
1. Go to **"Settings"** tab (gear icon)
|
||||
2. Tap **"Proxy"**
|
||||
3. In **"Proxy Settings"** section:
|
||||
- **Proxy Type:** HTTP (or leave as is)
|
||||
- **Proxy Port:** `80` (or any port, this is local)
|
||||
- **Proxy Address:** `127.0.0.1` (localhost - this is correct)
|
||||
|
||||
**Important:** These settings are for Shadowrocket's LOCAL proxy. Your apps will connect to this, and Shadowrocket will forward to server2.
|
||||
|
||||
### Step 4: Configure Apps to Use Shadowrocket's Local Proxy
|
||||
|
||||
Now you need to tell your apps to use Shadowrocket's local proxy:
|
||||
|
||||
**Option A: System-Wide (Limited)**
|
||||
1. Settings → Wi-Fi
|
||||
2. Tap ⓘ next to your Wi-Fi
|
||||
3. Scroll to **HTTP Proxy**
|
||||
4. Select **Manual**
|
||||
5. Enter:
|
||||
- **Server:** `127.0.0.1` (or `localhost`)
|
||||
- **Port:** `80` (or whatever you set in Proxy Settings)
|
||||
6. Save
|
||||
|
||||
**Option B: Use Shadowrocket's VPN Mode (But Configured Correctly)**
|
||||
|
||||
Actually, Shadowrocket's "VPN mode" is how it intercepts traffic. Here's the trick:
|
||||
|
||||
1. In Shadowrocket **"Home"** tab
|
||||
2. Make sure your `server2-proxy` is selected
|
||||
3. Toggle the switch ON
|
||||
4. **This will create a VPN connection** BUT it's Shadowrocket's VPN, not a conflict
|
||||
5. Shadowrocket's VPN intercepts traffic and routes it through server2
|
||||
|
||||
**The key:** Shadowrocket's VPN mode is fine - it's a different VPN than Tailscale. However, iOS only allows ONE VPN at a time, so:
|
||||
|
||||
### Solution: Use Shadowrocket's VPN Mode (Disable Tailscale VPN)
|
||||
|
||||
Since iOS only allows one VPN:
|
||||
1. **Disable Tailscale's VPN mode** (but keep Tailscale app running for network access)
|
||||
2. **Enable Shadowrocket's VPN mode**
|
||||
3. Shadowrocket will route through Tailscale's network to reach server2
|
||||
|
||||
Wait - that won't work because Tailscale needs VPN mode to provide network access...
|
||||
|
||||
### Better Solution: Use Proxy Chain Feature
|
||||
|
||||
Looking at your screenshot, I see **"Proxy Chain"** option! This might be the solution:
|
||||
|
||||
1. Go to **Settings** → **Proxy Chain**
|
||||
2. Enable **"Enable Chain"** toggle
|
||||
3. Configure:
|
||||
- **Type:** HTTP
|
||||
- **Address:** `100.70.115.1`
|
||||
- **Port:** `7890`
|
||||
4. This might allow Shadowrocket to use Tailscale's network without VPN conflict
|
||||
|
||||
## Recommended Approach
|
||||
|
||||
Based on your screenshots, here's what to do:
|
||||
|
||||
### Method 1: Use Proxy Chain (Try This First)
|
||||
|
||||
1. **Keep Tailscale VPN ON**
|
||||
2. In Shadowrocket:
|
||||
- Go to **Settings** → **Proxy Chain**
|
||||
- Enable **"Enable Chain"**
|
||||
- Set Type: HTTP, Address: `100.70.115.1`, Port: `7890`
|
||||
3. In Shadowrocket **Home** tab:
|
||||
- Add a "Direct" or "Reject" server (or use existing)
|
||||
- Enable Shadowrocket
|
||||
4. Configure apps to use Shadowrocket's local proxy (127.0.0.1:80)
|
||||
|
||||
### Method 2: Use Shadowrocket VPN Mode (Disable Tailscale)
|
||||
|
||||
1. **Disable Tailscale VPN** (but app can stay installed)
|
||||
2. In Shadowrocket **Home** tab:
|
||||
- Add server2: `100.70.115.1:7890`
|
||||
- Enable Shadowrocket VPN mode
|
||||
3. Shadowrocket will handle routing
|
||||
|
||||
**Problem:** You'll lose direct Tailscale network access, but proxy will work.
|
||||
|
||||
### Method 3: Use System Proxy Settings
|
||||
|
||||
1. Keep Tailscale ON
|
||||
2. Don't use Shadowrocket VPN mode
|
||||
3. Configure system proxy:
|
||||
- Settings → Wi-Fi → ⓘ → HTTP Proxy → Manual
|
||||
- Server: `100.70.115.1`
|
||||
- Port: `7890`
|
||||
4. This works for some apps but not all
|
||||
|
||||
## Testing
|
||||
|
||||
After setup:
|
||||
1. Open Safari
|
||||
2. Visit: https://api.ipify.org
|
||||
3. Should show: `158.101.140.85` (server2's IP)
|
||||
|
||||
## Which Method Should You Use?
|
||||
|
||||
**Try Proxy Chain first** - it might allow both Tailscale and Shadowrocket to work together!
|
||||
|
||||
If that doesn't work, you'll need to choose:
|
||||
- **Tailscale VPN** = Direct network access, but no proxy
|
||||
- **Shadowrocket VPN** = Proxy works, but no direct Tailscale network
|
||||
|
||||
Let me know which method works for you!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
# Shadowrocket Proxy Mode Setup Guide
|
||||
|
||||
## Understanding Shadowrocket Modes
|
||||
|
||||
Shadowrocket has two main modes:
|
||||
1. **VPN Mode (TUN Mode)** - Creates a VPN connection (conflicts with Tailscale)
|
||||
2. **Proxy Mode** - Routes traffic through proxy without VPN (works with Tailscale) ✅ **Use This!**
|
||||
|
||||
## Reference Article
|
||||
For additional details, see: https://privateproxy.me/blog/how-to-use-proxies-with-shadowrocket/
|
||||
|
||||
## Step-by-Step: Enable Proxy Mode
|
||||
|
||||
### Step 1: Install Shadowrocket
|
||||
- Download from App Store (~$3)
|
||||
- Open the app
|
||||
|
||||
### Step 2: Add Your Proxy Server
|
||||
|
||||
1. Open Shadowrocket app
|
||||
2. Tap the **"+"** button in the top right corner
|
||||
3. You'll see different server types - select **"HTTP"** or **"HTTPS"**
|
||||
|
||||
### Step 3: Configure Proxy Settings
|
||||
|
||||
Fill in the details:
|
||||
- **Type:** HTTP (or HTTPS)
|
||||
- **Remark:** `server2-proxy` (or any name you prefer)
|
||||
- **Address:** `100.70.115.1` (your Tailscale IP)
|
||||
- **Port:** `7890` (HTTP) or `7892` (Mixed port)
|
||||
- **Username:** (leave empty)
|
||||
- **Password:** (leave empty)
|
||||
- **Method:** (leave as default)
|
||||
|
||||
4. Tap **"Done"** or **"Save"**
|
||||
|
||||
### Step 4: Enable Proxy Mode (NOT VPN Mode)
|
||||
|
||||
**This is the critical step!**
|
||||
|
||||
1. In Shadowrocket main screen, you'll see your proxy server listed
|
||||
2. Tap on your proxy server to select it
|
||||
3. **Important:** Look for these settings:
|
||||
|
||||
**Option A: Global Routing Mode**
|
||||
- Tap the three dots (⋯) or "Edit" next to your proxy
|
||||
- Look for **"Routing"** or **"Mode"** setting
|
||||
- Select **"Proxy"** or **"Global Proxy"** (NOT "VPN" or "TUN")
|
||||
|
||||
**Option B: Settings Menu**
|
||||
- Go to **Settings** (gear icon at bottom)
|
||||
- Find **"Proxy"** or **"Routing"** section
|
||||
- Enable **"Use Proxy"**
|
||||
- Make sure **"VPN" mode is OFF** or **"TUN" mode is OFF**
|
||||
- Select **"Proxy Mode"** instead
|
||||
|
||||
### Step 5: Enable the Connection
|
||||
|
||||
1. Go back to main screen
|
||||
2. Find the toggle switch at the top
|
||||
3. **Toggle it ON**
|
||||
4. You should see a checkmark next to your proxy server
|
||||
5. **Important:** You should NOT see a VPN icon in status bar (that means VPN mode is active)
|
||||
|
||||
### Step 6: Verify It's Working in Proxy Mode
|
||||
|
||||
**Check for VPN icon:**
|
||||
- ✅ **Correct:** No VPN icon in status bar = Proxy mode active
|
||||
- ❌ **Wrong:** VPN icon appears = VPN mode active (will conflict with Tailscale)
|
||||
|
||||
**Test the connection:**
|
||||
1. Open Safari
|
||||
2. Visit: https://api.ipify.org
|
||||
3. Should show: `158.101.140.85` (server2's IP)
|
||||
|
||||
## Alternative: Using Configuration File
|
||||
|
||||
If the UI is confusing, you can use a config file:
|
||||
|
||||
1. In Shadowrocket, tap **"Config"** tab at bottom
|
||||
2. Tap **"+"** to add new config
|
||||
3. Create a config with:
|
||||
|
||||
```yaml
|
||||
# Shadowrocket Config
|
||||
[Proxy]
|
||||
server2 = http, 100.70.115.1, 7890
|
||||
|
||||
[Rule]
|
||||
FINAL,server2
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Problem: VPN icon appears (conflicts with Tailscale)
|
||||
**Solution:**
|
||||
- Go to Settings → Routing
|
||||
- Disable "TUN Mode" or "VPN Mode"
|
||||
- Enable "Proxy Mode" only
|
||||
- Restart Shadowrocket
|
||||
|
||||
### Problem: Can't connect to proxy
|
||||
**Check:**
|
||||
1. Is Tailscale connected? (Required to reach 100.70.115.1)
|
||||
2. Is server2 online? `ssh server2 'sudo systemctl status clash-meta'`
|
||||
3. Try different port: 7890, 7891, or 7892
|
||||
|
||||
### Problem: Some apps don't work
|
||||
**Solution:**
|
||||
- Some iOS apps ignore system proxy
|
||||
- You may need to use Shadowrocket's VPN mode for those apps
|
||||
- But then you'll need to disable Tailscale temporarily
|
||||
|
||||
## Visual Guide Reference
|
||||
|
||||
Look for these in Shadowrocket:
|
||||
- **"Proxy"** or **"HTTP Proxy"** option (use this)
|
||||
- **"TUN"** or **"VPN"** option (avoid this when Tailscale is on)
|
||||
- **"Global Proxy"** or **"Proxy Mode"** (this is what you want)
|
||||
|
||||
## Key Differences
|
||||
|
||||
| Mode | VPN Icon? | Works with Tailscale? | Use Case |
|
||||
|------|-----------|----------------------|----------|
|
||||
| **Proxy Mode** | ❌ No | ✅ Yes | Use this! |
|
||||
| **VPN Mode** | ✅ Yes | ❌ No | Only when Tailscale is off |
|
||||
|
||||
## Quick Checklist
|
||||
|
||||
- [ ] Tailscale is ON and connected
|
||||
- [ ] Added HTTP proxy: `100.70.115.1:7890`
|
||||
- [ ] Enabled "Proxy Mode" (NOT VPN mode)
|
||||
- [ ] Toggle switch is ON
|
||||
- [ ] No VPN icon in status bar
|
||||
- [ ] Test: Visit https://api.ipify.org shows server2 IP
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
# Shadowrocket Setup with Public IP (No Tailscale VPN Needed)
|
||||
|
||||
## ✅ Solution: Proxy Now Accessible via Public IP
|
||||
|
||||
The proxy is now configured to listen on the public IP, so you can use Shadowrocket **without** Tailscale VPN!
|
||||
|
||||
## Setup Steps
|
||||
|
||||
### Step 1: Get Proxy Credentials
|
||||
|
||||
```bash
|
||||
ssh server2 'cat ~/.clash_credentials.txt'
|
||||
```
|
||||
|
||||
You'll see: `username:password`
|
||||
|
||||
### Step 2: Configure Shadowrocket on iPhone
|
||||
|
||||
1. **Disable Tailscale VPN** (Settings → Tailscale → toggle OFF)
|
||||
- This frees up the VPN slot for Shadowrocket
|
||||
|
||||
2. **Open Shadowrocket**
|
||||
- Go to **Home** tab
|
||||
- Tap **"+"** to add server
|
||||
|
||||
3. **Add HTTP Proxy with Authentication:**
|
||||
- **Type:** HTTP
|
||||
- **Address:** `158.101.140.85` (server2's public IP)
|
||||
- **Port:** `7890` (HTTP) or `7892` (Mixed)
|
||||
- **Username:** (from credentials file)
|
||||
- **Password:** (from credentials file)
|
||||
- **Remark:** `server2-proxy`
|
||||
|
||||
4. **Enable Shadowrocket:**
|
||||
- Select your proxy server
|
||||
- Toggle switch **ON**
|
||||
- VPN icon should appear in status bar
|
||||
|
||||
### Step 3: Test
|
||||
|
||||
1. Turn OFF Wi-Fi (use cellular only)
|
||||
2. Open Safari
|
||||
3. Visit: https://api.ipify.org
|
||||
4. Should show: `158.101.140.85` (server2's IP) ✅
|
||||
|
||||
## Proxy Details
|
||||
|
||||
- **Public IP:** `158.101.140.85`
|
||||
- **Ports:**
|
||||
- `7890` - HTTP
|
||||
- `7891` - SOCKS5
|
||||
- `7892` - Mixed (HTTP + SOCKS5) - **Recommended**
|
||||
- **Authentication:** Required (username/password)
|
||||
|
||||
## Security Notes
|
||||
|
||||
✅ **Protected by:**
|
||||
- Username/password authentication
|
||||
- Firewall rules (UFW active)
|
||||
- Only proxy ports exposed (not SSH or other services)
|
||||
|
||||
⚠️ **Considerations:**
|
||||
- Proxy is accessible from public internet
|
||||
- Anyone with credentials can use it
|
||||
- Monitor usage: `ssh server2 'sudo journalctl -u clash-meta -f'`
|
||||
|
||||
## Advantages
|
||||
|
||||
✅ Works on **both Wi-Fi and cellular**
|
||||
✅ **No Tailscale VPN needed** (can keep it off)
|
||||
✅ Shadowrocket VPN mode works independently
|
||||
✅ Simple setup
|
||||
|
||||
## Get Credentials
|
||||
|
||||
Run this command to get your proxy credentials:
|
||||
|
||||
```bash
|
||||
ssh server2 'cat ~/.clash_credentials.txt'
|
||||
```
|
||||
|
||||
Then use them in Shadowrocket when adding the proxy server.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Can't connect?**
|
||||
1. Check server2 is online: `ssh server2 'sudo systemctl status clash-meta'`
|
||||
2. Verify credentials are correct
|
||||
3. Try different port: 7890, 7891, or 7892
|
||||
4. Check firewall: `ssh server2 'sudo ufw status'`
|
||||
|
||||
**Proxy slow?**
|
||||
- Normal - traffic goes: iPhone → Internet → server2 → Internet
|
||||
- Depends on server2's connection speed
|
||||
|
||||
## Change Credentials
|
||||
|
||||
If you want to change the password:
|
||||
|
||||
```bash
|
||||
ssh server2 'openssl rand -base64 12'
|
||||
```
|
||||
|
||||
Then update `~/.config/clash-meta/config.yaml` and restart Clash.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
# Simple Workaround: Use Tailscale (Easiest)
|
||||
|
||||
## Quick Solution
|
||||
|
||||
Since you already have Tailscale set up, the **simplest workaround** is:
|
||||
|
||||
### Option 1: Use Tailscale + Shadowrocket (Temporarily)
|
||||
|
||||
1. **On iPhone:**
|
||||
- Enable **Tailscale VPN** (Settings → Tailscale → toggle ON)
|
||||
- Open **Shadowrocket**
|
||||
- Add server: `100.70.115.1:7890`
|
||||
- **Username:** `proxy_user`
|
||||
- **Password:** `Cs7yBx1Rh9oK`
|
||||
- Enable Shadowrocket
|
||||
|
||||
**Problem:** iOS only allows one VPN, so you can't use both...
|
||||
|
||||
### Option 2: Use Tailscale Only (No Shadowrocket)
|
||||
|
||||
1. **On iPhone:**
|
||||
- Enable **Tailscale VPN**
|
||||
- Settings → Wi-Fi → ⓘ → HTTP Proxy → Manual
|
||||
- **Server:** `100.70.115.1`
|
||||
- **Port:** `7890`
|
||||
- **Authentication:** Username/Password
|
||||
- **Username:** `proxy_user`
|
||||
- **Password:** `Cs7yBx1Rh9oK`
|
||||
|
||||
**Limitation:** Only works on Wi-Fi, not cellular (iOS limitation)
|
||||
|
||||
### Option 3: SSH Tunnel on Mac + Share with iPhone
|
||||
|
||||
**On your Mac:**
|
||||
|
||||
1. **Create SSH tunnel:**
|
||||
```bash
|
||||
ssh -L 7890:127.0.0.1:7890 -N server2
|
||||
```
|
||||
|
||||
2. **Install a local proxy bridge** (like `cow` or `polipo`):
|
||||
```bash
|
||||
# Using polipo (if installed)
|
||||
polipo proxyAddress=0.0.0.0 proxyPort=8080 parentProxy=127.0.0.1:7890
|
||||
```
|
||||
|
||||
3. **On iPhone (same Wi-Fi):**
|
||||
- Settings → Wi-Fi → ⓘ → HTTP Proxy → Manual
|
||||
- **Server:** `192.168.1.XXX` (your Mac's IP)
|
||||
- **Port:** `8080`
|
||||
|
||||
### Option 4: Use WireGuard (You Already Have It!)
|
||||
|
||||
You have `wg0` interface on server2! Use WireGuard instead:
|
||||
|
||||
1. **On iPhone:** Install WireGuard app
|
||||
2. **On server2:** Generate WireGuard config
|
||||
3. **Connect via WireGuard** to access `100.70.115.1:7890`
|
||||
|
||||
This works because WireGuard creates a VPN, and you can use Shadowrocket's proxy chain feature.
|
||||
|
||||
## Recommended: Option 2 (Tailscale + System Proxy)
|
||||
|
||||
**Easiest and works now:**
|
||||
|
||||
1. Enable Tailscale VPN on iPhone
|
||||
2. Configure system HTTP proxy:
|
||||
- Server: `100.70.115.1`
|
||||
- Port: `7890`
|
||||
- Username: `proxy_user`
|
||||
- Password: `Cs7yBx1Rh9oK`
|
||||
3. Works on Wi-Fi (cellular won't work, but it's a temporary workaround)
|
||||
|
||||
## When You Get Console Access
|
||||
|
||||
Add Security List rules for ports 7890, 7891, 7892, 9090, then you can use Shadowrocket directly with public IP.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# SSH Tunnel Workaround for Proxy Access
|
||||
# This creates an SSH tunnel to forward proxy traffic through SSH (port 22)
|
||||
|
||||
echo "=== SSH Tunnel Workaround for Clash Proxy ==="
|
||||
echo ""
|
||||
echo "Since Oracle Cloud Security List blocks proxy ports, we'll use SSH port forwarding"
|
||||
echo ""
|
||||
|
||||
# Get server details
|
||||
SERVER="server2"
|
||||
PROXY_PORT="7890"
|
||||
LOCAL_PORT="7890"
|
||||
|
||||
echo "Creating SSH tunnel..."
|
||||
echo "Local port: $LOCAL_PORT -> Remote: $SERVER:$PROXY_PORT"
|
||||
echo ""
|
||||
echo "Run this command on your Mac:"
|
||||
echo ""
|
||||
echo "ssh -L $LOCAL_PORT:127.0.0.1:$PROXY_PORT -N $SERVER"
|
||||
echo ""
|
||||
echo "Or for background:"
|
||||
echo "ssh -f -N -L $LOCAL_PORT:127.0.0.1:$PROXY_PORT $SERVER"
|
||||
echo ""
|
||||
echo "Then configure Shadowrocket to use:"
|
||||
echo " Server: 127.0.0.1 (localhost)"
|
||||
echo " Port: $LOCAL_PORT"
|
||||
echo " Username: proxy_user"
|
||||
echo " Password: Cs7yBx1Rh9oK"
|
||||
echo ""
|
||||
echo "Note: This only works when SSH tunnel is active on your Mac"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Sync projects to server2
|
||||
# Usage: ./sync-to-server.sh [project_name]
|
||||
|
||||
SERVER="server2"
|
||||
REMOTE_PATH="/home/$USER/repos"
|
||||
LOCAL_PATH="/Users/jimmyg/repos"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${YELLOW}Starting sync to $SERVER...${NC}"
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
# Sync specific project
|
||||
PROJECT="$1"
|
||||
echo -e "${GREEN}Syncing project: $PROJECT${NC}"
|
||||
rsync -avz --delete \
|
||||
--exclude='.git/' \
|
||||
--exclude='node_modules/' \
|
||||
--exclude='__pycache__/' \
|
||||
--exclude='*.pyc' \
|
||||
--exclude='.DS_Store' \
|
||||
--exclude='*.log' \
|
||||
"$LOCAL_PATH/$PROJECT/" \
|
||||
"$SERVER:$REMOTE_PATH/$PROJECT/"
|
||||
else
|
||||
# Sync all projects
|
||||
echo -e "${GREEN}Syncing all projects${NC}"
|
||||
rsync -avz --delete \
|
||||
--exclude='.git/' \
|
||||
--exclude='node_modules/' \
|
||||
--exclude='__pycache__/' \
|
||||
--exclude='*.pyc' \
|
||||
--exclude='.DS_Store' \
|
||||
--exclude='*.log' \
|
||||
"$LOCAL_PATH/" \
|
||||
"$SERVER:$REMOTE_PATH/"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Sync completed!${NC}"
|
||||
@@ -1,149 +0,0 @@
|
||||
# Synology USB Copy Troubleshooting
|
||||
|
||||
## Issue
|
||||
USB Copy shows "Unavailable" status with message:
|
||||
**"No USB/SD storage mounted to the front port or storage used for another task"**
|
||||
|
||||
## Possible Causes
|
||||
|
||||
### 1. No USB Device Connected
|
||||
- USB/SD card not plugged into the front USB port
|
||||
- USB device not properly connected
|
||||
- USB device not recognized by Synology
|
||||
|
||||
### 2. USB Device Already in Use
|
||||
- USB device mounted for another purpose (file sharing, etc.)
|
||||
- Another USB Copy task using the same device
|
||||
- USB device mounted as a shared folder
|
||||
|
||||
### 3. USB Copy Task Configuration Issue
|
||||
- Task configured but USB device not detected
|
||||
- Wrong USB port selected in task settings
|
||||
- USB device format not supported
|
||||
|
||||
## Solutions
|
||||
|
||||
### Solution 1: Check USB Device Connection
|
||||
|
||||
1. **Physically check:**
|
||||
- Ensure USB device is plugged into the **front USB port** (not rear ports)
|
||||
- Try unplugging and reconnecting
|
||||
- Try a different USB device to test
|
||||
|
||||
2. **Check in DSM:**
|
||||
- Control Panel → External Devices
|
||||
- See if USB device appears in the list
|
||||
- Check if it shows as "Mounted" or "Unmounted"
|
||||
|
||||
### Solution 2: Unmount USB Device from Other Uses
|
||||
|
||||
1. **Check if USB is mounted as shared folder:**
|
||||
- Control Panel → Shared Folder
|
||||
- Look for USB device name
|
||||
- If found, unmount it first
|
||||
|
||||
2. **Check other USB Copy tasks:**
|
||||
- USB Copy → Check all tasks
|
||||
- See if another task is using the USB device
|
||||
- Disable or delete conflicting tasks
|
||||
|
||||
3. **Unmount manually:**
|
||||
- Control Panel → External Devices
|
||||
- Select USB device → Unmount
|
||||
- Then try USB Copy again
|
||||
|
||||
### Solution 3: Check USB Copy Task Settings
|
||||
|
||||
1. **Open USB Copy task:**
|
||||
- USB Copy → Select "Copy Button" task
|
||||
- Go to "Task Settings" tab
|
||||
|
||||
2. **Verify settings:**
|
||||
- Source: Should be [USB] or specific USB device
|
||||
- Destination: Should be valid path
|
||||
- Make sure correct USB port is selected
|
||||
|
||||
3. **Check "Trigger Time" tab:**
|
||||
- Ensure trigger is properly configured
|
||||
- If using "Copy Button" trigger, ensure button is enabled
|
||||
|
||||
### Solution 4: Restart USB Copy Service
|
||||
|
||||
1. **Stop USB Copy:**
|
||||
- Package Center → USB Copy → Stop
|
||||
|
||||
2. **Unmount all USB devices:**
|
||||
- Control Panel → External Devices → Unmount all
|
||||
|
||||
3. **Restart USB Copy:**
|
||||
- Package Center → USB Copy → Start
|
||||
|
||||
4. **Reconnect USB device:**
|
||||
- Plug USB device into front port
|
||||
- Wait for it to be recognized
|
||||
- Try USB Copy again
|
||||
|
||||
### Solution 5: Check USB Device Format
|
||||
|
||||
- **Supported formats:** FAT32, NTFS, exFAT, HFS+, ext4
|
||||
- **Not supported:** Some encrypted formats, certain proprietary formats
|
||||
- Try formatting USB device to FAT32 or exFAT if needed
|
||||
|
||||
## Diagnostic Steps
|
||||
|
||||
1. **Check USB device recognition:**
|
||||
```
|
||||
SSH to NAS → Run: lsusb
|
||||
Or check: Control Panel → External Devices
|
||||
```
|
||||
|
||||
2. **Check mount status:**
|
||||
```
|
||||
SSH to NAS → Run: mount | grep usb
|
||||
Or check: Control Panel → External Devices → Status
|
||||
```
|
||||
|
||||
3. **Check USB Copy logs:**
|
||||
- USB Copy → Settings → View logs
|
||||
- Look for error messages
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: "Copy Button" Task Shows Unavailable
|
||||
- **Cause:** USB device not detected or already mounted elsewhere
|
||||
- **Fix:** Unmount USB device from other uses, then reconnect
|
||||
|
||||
### Issue: USB Device Not Detected
|
||||
- **Cause:** Wrong port, unsupported format, or hardware issue
|
||||
- **Fix:** Try front port, check format, try different USB device
|
||||
|
||||
### Issue: Task Configured But Won't Run
|
||||
- **Cause:** USB device mounted as shared folder or used by another task
|
||||
- **Fix:** Unmount from shared folders, disable other USB Copy tasks
|
||||
|
||||
## Quick Fix Checklist
|
||||
|
||||
- [ ] USB device plugged into **front USB port**
|
||||
- [ ] USB device appears in Control Panel → External Devices
|
||||
- [ ] USB device is **not** mounted as shared folder
|
||||
- [ ] No other USB Copy tasks using the same device
|
||||
- [ ] USB Copy service is running (Package Center)
|
||||
- [ ] USB device format is supported (FAT32/exFAT/NTFS)
|
||||
- [ ] Try unmounting and reconnecting USB device
|
||||
|
||||
## If Still Not Working
|
||||
|
||||
1. **Check Synology logs:**
|
||||
- Control Panel → Log Center
|
||||
- Look for USB-related errors
|
||||
|
||||
2. **Try different USB device:**
|
||||
- Test if issue is device-specific
|
||||
|
||||
3. **Check Synology model compatibility:**
|
||||
- Some older models have USB Copy limitations
|
||||
- Check Synology documentation for your model
|
||||
|
||||
4. **Contact Synology Support:**
|
||||
- If hardware issue suspected
|
||||
- Provide model number and error details
|
||||
@@ -1,82 +0,0 @@
|
||||
# Test Proxy Connection
|
||||
|
||||
## ✅ Security List Rules Added!
|
||||
|
||||
Now let's test if it works.
|
||||
|
||||
## Step 1: Wait for Rules to Propagate
|
||||
Wait 30-60 seconds for Oracle Cloud to apply the rules.
|
||||
|
||||
## Step 2: Test from Your Mac (Quick Test)
|
||||
|
||||
Run this command to test:
|
||||
```bash
|
||||
curl --proxy http://proxy_user:Cs7yBx1Rh9oK@158.101.140.85:7890 http://httpbin.org/ip
|
||||
```
|
||||
|
||||
**Expected result:** Should show `{"origin":"158.101.140.85"}`
|
||||
|
||||
If it works, the firewall is open! ✅
|
||||
|
||||
## Step 3: Configure Shadowrocket on iPhone
|
||||
|
||||
1. **Open Shadowrocket**
|
||||
2. **Add Server:**
|
||||
- Tap **"+"** button
|
||||
- Select **HTTP**
|
||||
- **Address:** `158.101.140.85`
|
||||
- **Port:** `7890` (or `7892` for Mixed)
|
||||
- **Username:** `proxy_user`
|
||||
- **Password:** `Cs7yBx1Rh9oK`
|
||||
- **Remark:** `server2-proxy`
|
||||
- Tap **Done**
|
||||
|
||||
3. **Enable Shadowrocket:**
|
||||
- Select your proxy server
|
||||
- Toggle switch **ON**
|
||||
- VPN icon should appear
|
||||
|
||||
4. **Test:**
|
||||
- Open Safari
|
||||
- Visit: https://api.ipify.org
|
||||
- Should show: `158.101.140.85` ✅
|
||||
|
||||
## Step 4: Test on Cellular
|
||||
|
||||
1. Turn OFF Wi-Fi (use cellular only)
|
||||
2. Open Safari
|
||||
3. Visit: https://api.ipify.org
|
||||
4. Should show server2's IP ✅
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Still timing out?**
|
||||
- Wait another 1-2 minutes (rules can take time to propagate)
|
||||
- Check Security List rules are saved
|
||||
- Verify ports: 7890, 7891, 7892, 9090
|
||||
- Try different port: 7892 (Mixed port)
|
||||
|
||||
**Connection works but slow?**
|
||||
- Normal - traffic goes: iPhone → Internet → server2 → Internet
|
||||
- Depends on server2's connection speed
|
||||
|
||||
**Can't connect?**
|
||||
- Check server2 is running: `ssh server2 'sudo systemctl status clash-meta'`
|
||||
- Verify credentials are correct
|
||||
- Check firewall: `ssh server2 'sudo ufw status | grep 7890'`
|
||||
|
||||
## Success Indicators
|
||||
|
||||
✅ Mac test shows server2's IP
|
||||
✅ Shadowrocket connects without timeout
|
||||
✅ Safari shows server2's IP when proxy is on
|
||||
✅ Works on both Wi-Fi and cellular
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,207 +0,0 @@
|
||||
# Time Machine NAS Connection Troubleshooting
|
||||
|
||||
## Issue
|
||||
Time Machine shows "Connecting to backup disk..." but never completes, even though:
|
||||
- ✅ NAS is accessible from Finder
|
||||
- ✅ User `zjgump` is in administrators group (has full permissions)
|
||||
- ✅ Network connectivity is fine (ping works, SMB works in Finder)
|
||||
|
||||
## Root Cause Analysis
|
||||
|
||||
### Key Finding
|
||||
**`zjgump` is in the administrators group** - This means:
|
||||
- Explicit file permissions won't apply to SMB/file protocols
|
||||
- Admin users have full access by default
|
||||
- The "Permission denied" errors are NOT about file permissions
|
||||
|
||||
### Actual Issues
|
||||
1. **Credential Cache Mismatch**: macOS has saved credentials for `DS224plus` (without .local) but Time Machine tries to use `DS224plus.local`
|
||||
2. **Stale Mounts**: Manual mounts interfere with Time Machine's automatic mounting
|
||||
3. **Time Machine Process Permissions**: Time Machine runs as a different user than your login user
|
||||
|
||||
## Solutions
|
||||
|
||||
### Solution 1: Clear Credentials and Let Time Machine Mount Itself (Recommended)
|
||||
|
||||
1. **Unmount all existing mounts:**
|
||||
```bash
|
||||
diskutil unmount "/Volumes/Time Machine Folder" 2>/dev/null
|
||||
sudo umount -f /Volumes/.timemachine/* 2>/dev/null
|
||||
```
|
||||
|
||||
2. **Clear saved credentials:**
|
||||
- Open **Keychain Access**
|
||||
- Search for `DS224plus`
|
||||
- Delete ALL entries related to DS224plus
|
||||
- Also search for `Time Machine` and delete related entries
|
||||
|
||||
3. **Remove Time Machine destination:**
|
||||
- System Settings → General → Time Machine
|
||||
- Remove the existing backup disk (click `-` button)
|
||||
|
||||
4. **Re-add Time Machine:**
|
||||
- Click "Add Backup Disk..."
|
||||
- Select "Time Machine Folder" on "DS224plus.local" (the one with `.local`)
|
||||
- When prompted, enter `zjgump` credentials
|
||||
- **Let Time Machine mount it itself** - don't mount it manually first
|
||||
|
||||
### Solution 2: Use a Dedicated Time Machine User (Best Practice)
|
||||
|
||||
Synology recommends using a **dedicated non-admin user** for Time Machine:
|
||||
|
||||
1. **On Synology DSM:**
|
||||
- Control Panel → User & Group → Create
|
||||
- Create user: `tm-backup` (or similar)
|
||||
- **Do NOT add to administrators group**
|
||||
- Set password
|
||||
|
||||
2. **Grant permissions:**
|
||||
- Control Panel → Shared Folder → Time Machine Folder → Edit → Permissions
|
||||
- Add `tm-backup` user with **Read/Write** permission
|
||||
- Check "Apply to this folder, sub-folders and files"
|
||||
|
||||
3. **Configure Time Machine on NAS:**
|
||||
- Control Panel → File Services → Time Machine
|
||||
- Select "Time Machine Folder" as the shared folder
|
||||
- Select `tm-backup` as the user (or leave blank for all users)
|
||||
|
||||
4. **On macOS:**
|
||||
- Remove existing Time Machine destination
|
||||
- Add Backup Disk → Select "Time Machine Folder – DS224plus.local"
|
||||
- When prompted, use `tm-backup` credentials (not `zjgump`)
|
||||
|
||||
### Solution 3: Fix Credential Cache for Admin User
|
||||
|
||||
If you want to keep using `zjgump` (admin user):
|
||||
|
||||
1. **Clear all DS224plus credentials:**
|
||||
```bash
|
||||
security delete-internet-password -s "DS224plus" 2>/dev/null
|
||||
security delete-internet-password -s "DS224plus.local" 2>/dev/null
|
||||
```
|
||||
|
||||
2. **Remove Time Machine destination**
|
||||
|
||||
3. **Manually connect via Finder first:**
|
||||
- Finder → ⌘K → `smb://DS224plus.local`
|
||||
- Connect as `zjgump`
|
||||
- This will save the credential properly
|
||||
|
||||
4. **Then add Time Machine:**
|
||||
- System Settings → Time Machine → Add Backup Disk
|
||||
- Select "Time Machine Folder – DS224plus.local"
|
||||
- It should use the saved credential
|
||||
|
||||
### Solution 4: Use IP Address Instead of Hostname
|
||||
|
||||
If Bonjour (.local) is causing issues:
|
||||
|
||||
1. **Find NAS IP:**
|
||||
```bash
|
||||
ping -c 1 DS224plus.local | grep PING
|
||||
# Or check your router's DHCP table
|
||||
```
|
||||
|
||||
2. **Connect via IP:**
|
||||
- System Settings → Time Machine → Add Backup Disk
|
||||
- If it doesn't show up, manually mount first:
|
||||
- Finder → ⌘K → `smb://192.168.1.172/Time Machine Folder`
|
||||
- Connect as `zjgump`
|
||||
- Then add the mounted share in Time Machine
|
||||
|
||||
## Diagnostic Commands
|
||||
|
||||
### Check Current Mounts
|
||||
```bash
|
||||
mount | grep -i "timemachine\|ds224plus"
|
||||
```
|
||||
|
||||
### Check Time Machine Logs
|
||||
```bash
|
||||
log show --predicate 'subsystem == "com.apple.TimeMachine"' --last 10m --info | tail -50
|
||||
```
|
||||
|
||||
### Check Saved Credentials
|
||||
```bash
|
||||
security find-internet-password -s "DS224plus"
|
||||
security find-internet-password -s "DS224plus.local"
|
||||
```
|
||||
|
||||
### Test SMB Connection
|
||||
```bash
|
||||
smbutil status DS224plus.local
|
||||
```
|
||||
|
||||
### Check Time Machine Configuration
|
||||
```bash
|
||||
tmutil listbackups
|
||||
defaults read /Library/Preferences/com.apple.TimeMachine
|
||||
```
|
||||
|
||||
## Common Errors and Fixes
|
||||
|
||||
### "Time Machine could not back up the disk because it is nearly full"
|
||||
- **Cause**: The **source disk** (Macintosh HD) is nearly full, NOT the destination (NAS)
|
||||
- **Symptoms**: Error says disk is "nearly full" but NAS shows plenty of space (e.g., 1.67TB available)
|
||||
- **Fix**: Free up space on your Mac's internal disk:
|
||||
1. Run the diagnostic script: `./free_disk_space.sh`
|
||||
2. Run the cleanup script: `./fix_time_machine_disk_full.sh`
|
||||
3. Or manually:
|
||||
- Empty Trash: `rm -rf ~/.Trash/*`
|
||||
- Clean caches: `rm -rf ~/Library/Caches/*`
|
||||
- Review Downloads folder (often has large files)
|
||||
- Use macOS Storage Management: Apple Menu → About This Mac → Storage → Manage
|
||||
- **Why**: Time Machine needs free space on the source disk to:
|
||||
- Create local snapshots
|
||||
- Stage files for backup
|
||||
- Maintain the backup process
|
||||
- **Minimum**: Aim for at least 5-10GB free space for Time Machine to work properly
|
||||
|
||||
### "Deleted files but space not freed" / "Stuck Time Machine snapshot"
|
||||
- **Cause**: APFS snapshots (especially Time Machine local snapshots) hold onto deleted file space
|
||||
- **Symptoms**:
|
||||
- Deleted 20GB+ of files but disk space didn't increase
|
||||
- Error: "Stale NFS file handle" when trying to delete snapshots
|
||||
- `tmutil listlocalsnapshots /` shows snapshots that can't be deleted
|
||||
- **Fix**:
|
||||
1. **Quick fix - Restart Mac**: Often the simplest solution - snapshots are released after restart
|
||||
2. **Remove Time Machine destination temporarily**:
|
||||
- System Settings → Time Machine → Remove backup disk
|
||||
- Delete snapshot: `sudo tmutil deletelocalsnapshots <date>`
|
||||
- Re-add Time Machine destination
|
||||
3. **Use the fix script**: `./fix_stuck_snapshot.sh` (guides you through the process)
|
||||
4. **Force purge**: `sudo purge` (if available)
|
||||
- **Why**: Time Machine creates local snapshots before backing up. If the backup destination (NAS) is unreachable or has a stale connection, the snapshot gets stuck and holds onto space from deleted files.
|
||||
- **Prevention**: Ensure Time Machine can reliably connect to backup destination
|
||||
|
||||
### "Permission denied" on mount point
|
||||
- **Cause**: Manual mount with wrong permissions
|
||||
- **Fix**: Unmount and let Time Machine mount it itself
|
||||
|
||||
### "Connecting to backup disk..." hangs
|
||||
- **Cause**: Credential cache mismatch or stale mount
|
||||
- **Fix**: Clear credentials, unmount all, re-add
|
||||
|
||||
### "Server may not exist or unavailable"
|
||||
- **Cause**: Using wrong hostname (DS224plus vs DS224plus.local)
|
||||
- **Fix**: Always use `.local` version or IP address
|
||||
|
||||
## Prevention
|
||||
|
||||
1. **Don't manually mount Time Machine shares** - let Time Machine do it
|
||||
2. **Use dedicated non-admin user** for Time Machine (best practice)
|
||||
3. **Keep credentials in sync** - if you change NAS password, update on Mac
|
||||
4. **Use `.local` hostname** - more reliable than IP or NetBIOS name
|
||||
|
||||
## Notes
|
||||
|
||||
- Admin users (`zjgump`) bypass file-level permissions on Synology
|
||||
- Time Machine runs as `_backup` user on macOS, not your login user
|
||||
- Bonjour (`.local`) is preferred over NetBIOS for Time Machine
|
||||
- Manual mounts can interfere with Time Machine's automatic mounting
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
# Troubleshooting Proxy Connection Timeout
|
||||
|
||||
## Issue
|
||||
Connection test timeout when connecting to proxy from iPhone/Shadowrocket.
|
||||
|
||||
## Status Check
|
||||
✅ Clash is running
|
||||
✅ Listening on ports 7890, 7891, 7892
|
||||
✅ Local connection works (tested from server2)
|
||||
✅ Authentication configured
|
||||
✅ UFW firewall allows ports
|
||||
|
||||
## Possible Causes
|
||||
|
||||
### 1. Oracle Cloud Security List / Firewall
|
||||
Oracle Cloud has a **Security List** that acts as a firewall. Even if UFW allows the ports, Oracle's firewall might be blocking them.
|
||||
|
||||
**Solution:** Check Oracle Cloud Console:
|
||||
1. Go to Oracle Cloud Console
|
||||
2. Networking → Virtual Cloud Networks
|
||||
3. Find your VCN
|
||||
4. Security Lists → Ingress Rules
|
||||
5. Add rules for ports 7890, 7891, 7892, 9090
|
||||
- Source: 0.0.0.0/0 (or your IP for security)
|
||||
- Protocol: TCP
|
||||
- Port: 7890, 7891, 7892, 9090
|
||||
|
||||
### 2. Network ACL
|
||||
Oracle Cloud also has Network ACLs that might block traffic.
|
||||
|
||||
### 3. IPv6 vs IPv4
|
||||
Clash shows as `tcp6` but `*:7890` means it listens on both IPv4 and IPv6. This should be fine.
|
||||
|
||||
### 4. Connection from iPhone
|
||||
Test from a different network to see if it's network-specific.
|
||||
|
||||
## Quick Tests
|
||||
|
||||
### Test 1: Check if port is reachable
|
||||
```bash
|
||||
# From your Mac (not iPhone)
|
||||
nc -zv 158.101.140.85 7890
|
||||
# or
|
||||
telnet 158.101.140.85 7890
|
||||
```
|
||||
|
||||
### Test 2: Test from server2 itself
|
||||
```bash
|
||||
ssh server2 'curl -v --proxy http://proxy_user:Cs7yBx1Rh9oK@127.0.0.1:7890 http://httpbin.org/ip'
|
||||
```
|
||||
|
||||
### Test 3: Check Oracle Cloud Security List
|
||||
- Log into Oracle Cloud Console
|
||||
- Check Security List rules for your instance
|
||||
|
||||
## Most Likely Issue: Oracle Cloud Security List
|
||||
|
||||
Oracle Cloud blocks all incoming traffic by default unless explicitly allowed in the Security List. UFW on the server won't help if Oracle's firewall blocks it first.
|
||||
|
||||
## Solution Steps
|
||||
|
||||
1. **Check Oracle Cloud Console:**
|
||||
- Go to your instance
|
||||
- Click on the VCN/subnet
|
||||
- Security Lists → Ingress Rules
|
||||
- Add rules for ports 7890, 7891, 7892
|
||||
|
||||
2. **Or use Oracle Cloud CLI:**
|
||||
```bash
|
||||
# Add security list rule (example - adjust for your setup)
|
||||
oci network security-list update --security-list-id <your-security-list-id> ...
|
||||
```
|
||||
|
||||
3. **Test again from iPhone after adding rules**
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Use External Drive to Free Space for Update
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Use External Drive for Update ==="
|
||||
echo ""
|
||||
echo "External drive detected! This is your solution."
|
||||
echo ""
|
||||
|
||||
# Find external drive
|
||||
EXTERNAL_VOLUMES=$(ls -d /Volumes/* 2>/dev/null | grep -v -E "Macintosh|Preboot|Recovery|VM|Download" || echo "")
|
||||
|
||||
if [ -z "$EXTERNAL_VOLUMES" ]; then
|
||||
echo "⚠️ No external volumes found mounted"
|
||||
echo ""
|
||||
echo "Please:"
|
||||
echo " 1. Connect your external USB drive"
|
||||
echo " 2. Wait for it to mount"
|
||||
echo " 3. Run this script again"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Found external volume(s):"
|
||||
echo "$EXTERNAL_VOLUMES" | while read vol; do
|
||||
SIZE=$(df -h "$vol" 2>/dev/null | tail -1 | awk '{print $2}')
|
||||
FREE=$(df -h "$vol" 2>/dev/null | tail -1 | awk '{print $4}')
|
||||
echo " - $vol ($SIZE total, $FREE free)"
|
||||
done
|
||||
echo ""
|
||||
|
||||
# Use first external volume
|
||||
EXTERNAL_VOL=$(echo "$EXTERNAL_VOLUMES" | head -1)
|
||||
echo "Using: $EXTERNAL_VOL"
|
||||
echo ""
|
||||
|
||||
FREE_SPACE=$(df / | tail -1 | awk '{print $4}')
|
||||
FREE_SPACE_GB=$(echo "scale=2; $FREE_SPACE / 1024 / 1024" | bc)
|
||||
echo "Current Mac free space: ${FREE_SPACE_GB}GB"
|
||||
echo "Need: 17.64GB"
|
||||
echo ""
|
||||
|
||||
echo "📦 Large files you can move to external drive:"
|
||||
echo ""
|
||||
echo " Downloads: 8.7GB"
|
||||
echo " .ollama: 17GB"
|
||||
echo " .local: 18GB"
|
||||
echo " Total: ~44GB"
|
||||
echo ""
|
||||
|
||||
echo "🔧 Steps:"
|
||||
echo ""
|
||||
echo "1. Move large files to external drive:"
|
||||
echo " mv ~/Downloads \"$EXTERNAL_VOL/Downloads_backup\""
|
||||
echo " mv ~/.ollama \"$EXTERNAL_VOL/ollama_backup\""
|
||||
echo " mv ~/.local \"$EXTERNAL_VOL/local_backup\""
|
||||
echo ""
|
||||
echo "2. This should free ~44GB on Mac"
|
||||
echo ""
|
||||
echo "3. Install macOS update"
|
||||
echo ""
|
||||
echo "4. After update clears snapshot, move files back"
|
||||
echo ""
|
||||
|
||||
read -p "Move Downloads, .ollama, and .local to external drive? (y/n) " -n 1 -r
|
||||
echo ""
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo ""
|
||||
echo "Moving files..."
|
||||
|
||||
# Move Downloads
|
||||
if [ -d ~/Downloads ]; then
|
||||
echo "Moving Downloads (8.7GB)..."
|
||||
mv ~/Downloads "$EXTERNAL_VOL/Downloads_backup" && \
|
||||
echo " ✅ Moved Downloads" || \
|
||||
echo " ⚠️ Error moving Downloads"
|
||||
mkdir ~/Downloads
|
||||
fi
|
||||
|
||||
# Move .ollama
|
||||
if [ -d ~/.ollama ]; then
|
||||
echo "Moving .ollama (17GB)..."
|
||||
mv ~/.ollama "$EXTERNAL_VOL/ollama_backup" && \
|
||||
echo " ✅ Moved .ollama" || \
|
||||
echo " ⚠️ Error moving .ollama"
|
||||
fi
|
||||
|
||||
# Move .local
|
||||
if [ -d ~/.local ]; then
|
||||
echo "Moving .local (18GB)..."
|
||||
mv ~/.local "$EXTERNAL_VOL/local_backup" && \
|
||||
echo " ✅ Moved .local" || \
|
||||
echo " ⚠️ Error moving .local"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "⏳ Waiting for space to update..."
|
||||
sleep 5
|
||||
|
||||
NEW_FREE=$(df / | tail -1 | awk '{print $4}')
|
||||
NEW_FREE_GB=$(echo "scale=2; $NEW_FREE / 1024 / 1024" | bc)
|
||||
|
||||
echo ""
|
||||
echo "New free space: ${NEW_FREE_GB}GB"
|
||||
echo ""
|
||||
|
||||
if (( $(echo "$NEW_FREE_GB > 17" | bc -l) )); then
|
||||
echo "✅ Enough space! Now install update:"
|
||||
echo " System Settings → General → Software Update"
|
||||
echo " OR"
|
||||
echo " sudo softwareupdate --download --all"
|
||||
else
|
||||
echo "⚠️ Still not enough. May need to move more files."
|
||||
fi
|
||||
else
|
||||
echo "Cancelled."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -1,67 +0,0 @@
|
||||
# NAS WebDAV External Access Troubleshooting
|
||||
|
||||
This repository contains diagnostic tools and guides to help troubleshoot WebDAV external access issues on NAS systems.
|
||||
|
||||
## Problem
|
||||
|
||||
WebDAV works on intranet but fails from external networks with "Connection refused" error.
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. **Run the diagnostic script on your NAS:**
|
||||
```bash
|
||||
sudo ./diagnose_webdav.sh
|
||||
```
|
||||
|
||||
2. **Check port forwarding:**
|
||||
```bash
|
||||
./check_port_forwarding.sh
|
||||
```
|
||||
|
||||
3. **Review the troubleshooting guide:**
|
||||
- See [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for detailed solutions
|
||||
|
||||
## Files
|
||||
|
||||
- `diagnose_webdav.sh` - Comprehensive diagnostic script to check service binding, firewall, and configuration
|
||||
- `check_port_forwarding.sh` - Tests port accessibility and provides port forwarding checklist
|
||||
- `TROUBLESHOOTING.md` - Detailed troubleshooting guide with common issues and solutions
|
||||
|
||||
## Most Common Issues
|
||||
|
||||
1. **Service bound to localhost only** - Service listens on `127.0.0.1:5006` instead of `0.0.0.0:5006`
|
||||
2. **Firewall blocking port** - Port 5006 not allowed in firewall rules
|
||||
3. **Router port forwarding not configured** - External port 5006 not forwarded to NAS internal IP
|
||||
4. **Router firewall blocking** - Router firewall blocking incoming connections
|
||||
|
||||
## Quick Fix
|
||||
|
||||
The most common fix is ensuring your WebDAV service is bound to all interfaces:
|
||||
|
||||
**Apache:**
|
||||
```apache
|
||||
Listen 0.0.0.0:5006
|
||||
```
|
||||
|
||||
**Nginx:**
|
||||
```nginx
|
||||
listen 0.0.0.0:5006;
|
||||
```
|
||||
|
||||
Then configure router port forwarding: External 5006 → Internal NAS IP:5006
|
||||
|
||||
## Usage
|
||||
|
||||
All scripts should be run on your NAS system:
|
||||
|
||||
```bash
|
||||
# Make scripts executable (already done)
|
||||
chmod +x *.sh
|
||||
|
||||
# Run diagnostics
|
||||
sudo ./diagnose_webdav.sh
|
||||
|
||||
# Check port forwarding
|
||||
./check_port_forwarding.sh
|
||||
```
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
# WebDAV External Access Troubleshooting Guide
|
||||
|
||||
## Problem
|
||||
WebDAV works on intranet but fails from external networks with "Connection refused" error.
|
||||
|
||||
## Common Causes and Solutions
|
||||
|
||||
### 1. Service Bound to Localhost Only
|
||||
|
||||
**Symptom:** Service only listens on `127.0.0.1` or `::1` instead of all interfaces.
|
||||
|
||||
**Solution:**
|
||||
- **Apache:** Change `Listen 127.0.0.1:5006` to `Listen 0.0.0.0:5006` or `Listen *:5006`
|
||||
- **Nginx:** Change `listen 127.0.0.1:5006;` to `listen 0.0.0.0:5006;` or `listen *:5006;`
|
||||
- **Other services:** Ensure binding to `0.0.0.0` or `*` instead of `localhost`/`127.0.0.1`
|
||||
|
||||
**Check:**
|
||||
```bash
|
||||
netstat -tuln | grep 5006
|
||||
# or
|
||||
ss -tuln | grep 5006
|
||||
```
|
||||
|
||||
If you see `127.0.0.1:5006` or `::1:5006`, the service is only accessible locally.
|
||||
|
||||
### 2. Firewall Blocking Port 5006
|
||||
|
||||
**Solution:**
|
||||
|
||||
**UFW (Ubuntu/Debian):**
|
||||
```bash
|
||||
sudo ufw allow 5006/tcp
|
||||
sudo ufw reload
|
||||
```
|
||||
|
||||
**firewalld (CentOS/RHEL):**
|
||||
```bash
|
||||
sudo firewall-cmd --permanent --add-port=5006/tcp
|
||||
sudo firewall-cmd --reload
|
||||
```
|
||||
|
||||
**iptables:**
|
||||
```bash
|
||||
sudo iptables -A INPUT -p tcp --dport 5006 -j ACCEPT
|
||||
sudo iptables-save
|
||||
```
|
||||
|
||||
### 3. Router Port Forwarding Not Configured
|
||||
|
||||
**Solution:**
|
||||
1. Access your router's admin panel
|
||||
2. Navigate to Port Forwarding / Virtual Server settings
|
||||
3. Add rule:
|
||||
- **External Port:** 5006
|
||||
- **Internal IP:** Your NAS IP address (e.g., 192.168.1.100)
|
||||
- **Internal Port:** 5006
|
||||
- **Protocol:** TCP
|
||||
4. Save and apply changes
|
||||
|
||||
### 4. Router Firewall Blocking Incoming Connections
|
||||
|
||||
**Solution:**
|
||||
- Check router firewall settings
|
||||
- Ensure port 5006 is allowed for incoming connections
|
||||
- Some routers have separate WAN firewall rules
|
||||
|
||||
### 5. ISP Blocking Port 5006
|
||||
|
||||
**Solution:**
|
||||
- Some ISPs block certain ports
|
||||
- Try a different external port (e.g., 5007, 8080)
|
||||
- Update port forwarding to use the new port
|
||||
|
||||
### 6. Service Not Running or Crashed
|
||||
|
||||
**Check service status:**
|
||||
```bash
|
||||
# For systemd services
|
||||
systemctl status webdav
|
||||
# or
|
||||
systemctl status apache2
|
||||
# or
|
||||
systemctl status nginx
|
||||
|
||||
# Check if process is running
|
||||
ps aux | grep -i webdav
|
||||
```
|
||||
|
||||
**Restart service:**
|
||||
```bash
|
||||
sudo systemctl restart webdav
|
||||
# or
|
||||
sudo systemctl restart apache2
|
||||
# or
|
||||
sudo systemctl restart nginx
|
||||
```
|
||||
|
||||
### 7. NAS-Specific Configuration
|
||||
|
||||
**Synology NAS:**
|
||||
1. Control Panel → External Access → Router Configuration
|
||||
2. Enable port forwarding for port 5006
|
||||
3. Control Panel → Security → Firewall
|
||||
4. Ensure port 5006 is allowed
|
||||
|
||||
**QNAP NAS:**
|
||||
1. Network & Virtual Switch → Port Forwarding
|
||||
2. Add rule for port 5006
|
||||
3. Security → Firewall → Allow port 5006
|
||||
|
||||
**Other NAS:**
|
||||
- Check NAS admin panel for port forwarding/firewall settings
|
||||
- Ensure WebDAV service is enabled and configured for external access
|
||||
|
||||
## Diagnostic Steps
|
||||
|
||||
1. **Run the diagnostic script:**
|
||||
```bash
|
||||
chmod +x diagnose_webdav.sh
|
||||
sudo ./diagnose_webdav.sh
|
||||
```
|
||||
|
||||
2. **Test local connection:**
|
||||
```bash
|
||||
curl -k -X PROPFIND https://localhost:5006
|
||||
# or
|
||||
curl -k -X PROPFIND https://127.0.0.1:5006
|
||||
```
|
||||
|
||||
3. **Test from internal network:**
|
||||
```bash
|
||||
curl -k -X PROPFIND https://<NAS_INTERNAL_IP>:5006
|
||||
```
|
||||
|
||||
4. **Test from external network:**
|
||||
```bash
|
||||
curl -k -X PROPFIND https://jimmygan.myds.me:5006
|
||||
```
|
||||
|
||||
5. **Check if port is reachable externally:**
|
||||
```bash
|
||||
# From external network
|
||||
telnet jimmygan.myds.me 5006
|
||||
# or
|
||||
nc -zv jimmygan.myds.me 5006
|
||||
```
|
||||
|
||||
## Quick Fix Checklist
|
||||
|
||||
- [ ] Service is bound to `0.0.0.0:5006` (not `127.0.0.1:5006`)
|
||||
- [ ] Firewall allows port 5006
|
||||
- [ ] Router port forwarding configured (External 5006 → Internal NAS IP:5006)
|
||||
- [ ] Router firewall allows incoming connections on port 5006
|
||||
- [ ] WebDAV service is running
|
||||
- [ ] Tested local connection (works)
|
||||
- [ ] Tested internal network connection (works)
|
||||
- [ ] External connection still fails → Check ISP/port blocking
|
||||
|
||||
## Additional Notes
|
||||
|
||||
- **DDNS:** Your domain `jimmygan.myds.me` appears to be a DDNS service. Ensure it's properly configured and pointing to your current external IP.
|
||||
- **HTTPS:** Since you're using HTTPS, ensure SSL certificate is valid and the service is configured for SSL/TLS.
|
||||
- **IPv6:** The error shows IPv6 connection attempts. If your router/NAS doesn't support IPv6 properly, you may need to disable IPv6 or configure it separately.
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Port Forwarding Test Script
|
||||
# Tests if port 5006 is accessible from external networks
|
||||
|
||||
echo "=========================================="
|
||||
echo "Port Forwarding Test for WebDAV (Port 5006)"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Get external IP
|
||||
echo "1. Checking external IP address..."
|
||||
EXTERNAL_IP=$(curl -s ifconfig.me 2>/dev/null || curl -s icanhazip.com 2>/dev/null)
|
||||
if [ -z "$EXTERNAL_IP" ]; then
|
||||
echo "❌ Unable to determine external IP"
|
||||
else
|
||||
echo "✅ External IP: $EXTERNAL_IP"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Get internal IP
|
||||
echo "2. Checking internal IP address..."
|
||||
if command -v ip &> /dev/null; then
|
||||
INTERNAL_IP=$(ip route get 8.8.8.8 2>/dev/null | grep -oP 'src \K\S+' | head -1)
|
||||
elif command -v hostname &> /dev/null; then
|
||||
INTERNAL_IP=$(hostname -I | awk '{print $1}')
|
||||
fi
|
||||
|
||||
if [ -z "$INTERNAL_IP" ]; then
|
||||
echo "⚠️ Unable to determine internal IP"
|
||||
else
|
||||
echo "✅ Internal IP: $INTERNAL_IP"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Test local port
|
||||
echo "3. Testing local port 5006..."
|
||||
if command -v nc &> /dev/null; then
|
||||
if timeout 2 nc -zv localhost 5006 2>&1 | grep -q "succeeded"; then
|
||||
echo "✅ Port 5006 is open locally"
|
||||
else
|
||||
echo "❌ Port 5006 is NOT open locally"
|
||||
echo " → Service may not be running or bound incorrectly"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ netcat not available, skipping local test"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Test internal network port
|
||||
if [ -n "$INTERNAL_IP" ]; then
|
||||
echo "4. Testing internal network access..."
|
||||
if command -v nc &> /dev/null; then
|
||||
if timeout 2 nc -zv "$INTERNAL_IP" 5006 2>&1 | grep -q "succeeded"; then
|
||||
echo "✅ Port 5006 accessible from internal network"
|
||||
else
|
||||
echo "❌ Port 5006 NOT accessible from internal network"
|
||||
echo " → Service may be bound to localhost only"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Test external port (if external IP service available)
|
||||
echo "5. Testing external port accessibility..."
|
||||
echo " (This requires an external service - may not work in all environments)"
|
||||
if command -v nc &> /dev/null && [ -n "$EXTERNAL_IP" ]; then
|
||||
echo " Attempting to test from external perspective..."
|
||||
echo " Note: This test may not work if your network blocks outbound connections"
|
||||
echo ""
|
||||
echo " Manual test recommended:"
|
||||
echo " From a device outside your network, run:"
|
||||
echo " telnet $EXTERNAL_IP 5006"
|
||||
echo " or"
|
||||
echo " nc -zv $EXTERNAL_IP 5006"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Port forwarding checklist
|
||||
echo "6. Port Forwarding Configuration Checklist"
|
||||
echo "-------------------------------------------"
|
||||
echo "On your router, ensure:"
|
||||
echo ""
|
||||
echo " External Port: 5006"
|
||||
echo " Internal IP: $INTERNAL_IP (your NAS IP)"
|
||||
echo " Internal Port: 5006"
|
||||
echo " Protocol: TCP"
|
||||
echo ""
|
||||
echo " Status: [ ] Configured"
|
||||
echo ""
|
||||
|
||||
# Firewall checklist
|
||||
echo "7. Firewall Configuration Checklist"
|
||||
echo "-------------------------------------------"
|
||||
echo "On your NAS/router:"
|
||||
echo " [ ] Port 5006 allowed in firewall"
|
||||
echo " [ ] Incoming connections on port 5006 allowed"
|
||||
echo " [ ] Service bound to 0.0.0.0:5006 (not 127.0.0.1:5006)"
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "Next Steps"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "If local test fails:"
|
||||
echo " 1. Check if WebDAV service is running"
|
||||
echo " 2. Check service configuration (Listen directive)"
|
||||
echo ""
|
||||
echo "If local test passes but internal fails:"
|
||||
echo " 1. Service is likely bound to localhost only"
|
||||
echo " 2. Change Listen/ServerName to 0.0.0.0:5006"
|
||||
echo ""
|
||||
echo "If internal test passes but external fails:"
|
||||
echo " 1. Check router port forwarding configuration"
|
||||
echo " 2. Check router firewall settings"
|
||||
echo " 3. Verify ISP is not blocking port 5006"
|
||||
echo ""
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# WebDAV External Access Diagnostic Script
|
||||
# This script helps diagnose why WebDAV is not accessible from external networks
|
||||
|
||||
echo "=========================================="
|
||||
echo "WebDAV External Access Diagnostic Tool"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Check if running as root (needed for some checks)
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "⚠️ Some checks may require root privileges"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# 1. Check what's listening on port 5006
|
||||
echo "1. Checking what's listening on port 5006..."
|
||||
echo "-------------------------------------------"
|
||||
if command -v netstat &> /dev/null; then
|
||||
echo "Using netstat:"
|
||||
netstat -tuln | grep 5006 || echo "❌ Nothing found listening on port 5006"
|
||||
elif command -v ss &> /dev/null; then
|
||||
echo "Using ss:"
|
||||
ss -tuln | grep 5006 || echo "❌ Nothing found listening on port 5006"
|
||||
else
|
||||
echo "⚠️ netstat or ss not available"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 2. Check if service is bound to localhost only
|
||||
echo "2. Checking if service is bound to localhost only..."
|
||||
echo "-------------------------------------------"
|
||||
if command -v netstat &> /dev/null; then
|
||||
netstat -tuln | grep 5006 | grep "127.0.0.1\|::1" && echo "❌ Service is bound to localhost only!" || echo "✅ Service is not bound to localhost only"
|
||||
elif command -v ss &> /dev/null; then
|
||||
ss -tuln | grep 5006 | grep "127.0.0.1\|::1" && echo "❌ Service is bound to localhost only!" || echo "✅ Service is not bound to localhost only"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 3. Check if port 5006 is open in firewall
|
||||
echo "3. Checking firewall status..."
|
||||
echo "-------------------------------------------"
|
||||
if command -v ufw &> /dev/null; then
|
||||
echo "UFW Status:"
|
||||
ufw status | grep 5006 || echo "⚠️ Port 5006 not found in UFW rules"
|
||||
elif command -v firewall-cmd &> /dev/null; then
|
||||
echo "firewalld Status:"
|
||||
firewall-cmd --list-ports | grep 5006 || echo "⚠️ Port 5006 not found in firewalld rules"
|
||||
elif command -v iptables &> /dev/null; then
|
||||
echo "iptables rules for port 5006:"
|
||||
iptables -L -n | grep 5006 || echo "⚠️ No iptables rules found for port 5006"
|
||||
else
|
||||
echo "⚠️ No common firewall tool detected"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 4. Check WebDAV service status (common services)
|
||||
echo "4. Checking WebDAV service status..."
|
||||
echo "-------------------------------------------"
|
||||
if systemctl list-units --type=service | grep -i webdav &> /dev/null; then
|
||||
systemctl list-units --type=service | grep -i webdav | while read service; do
|
||||
servicename=$(echo $service | awk '{print $1}')
|
||||
echo "Service: $servicename"
|
||||
systemctl status $servicename --no-pager | head -5
|
||||
done
|
||||
else
|
||||
echo "⚠️ No WebDAV systemd service found"
|
||||
echo "Checking common WebDAV processes:"
|
||||
ps aux | grep -i webdav | grep -v grep || echo "No WebDAV processes found"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 5. Test local connection
|
||||
echo "5. Testing local connection to port 5006..."
|
||||
echo "-------------------------------------------"
|
||||
if command -v nc &> /dev/null; then
|
||||
if nc -zv localhost 5006 2>&1; then
|
||||
echo "✅ Local connection successful"
|
||||
else
|
||||
echo "❌ Local connection failed"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ netcat (nc) not available for connection test"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 6. Check network interfaces
|
||||
echo "6. Network interface information..."
|
||||
echo "-------------------------------------------"
|
||||
if command -v ip &> /dev/null; then
|
||||
ip addr show | grep -E "^[0-9]+:|inet " | head -10
|
||||
elif command -v ifconfig &> /dev/null; then
|
||||
ifconfig | grep -E "^[a-z]|inet " | head -10
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 7. Check router/NAT configuration hints
|
||||
echo "7. Router/NAT Configuration Checklist..."
|
||||
echo "-------------------------------------------"
|
||||
echo "Please verify on your router/NAS:"
|
||||
echo " □ Port forwarding: External port 5006 → Internal NAS IP:5006"
|
||||
echo " □ Firewall rules allow incoming connections on port 5006"
|
||||
echo " □ NAT/UPnP is configured correctly"
|
||||
echo " □ External IP matches: $(curl -s ifconfig.me 2>/dev/null || echo 'Unable to determine')"
|
||||
echo ""
|
||||
|
||||
# 8. Common WebDAV configuration files to check
|
||||
echo "8. Common WebDAV configuration locations..."
|
||||
echo "-------------------------------------------"
|
||||
config_locations=(
|
||||
"/etc/apache2/sites-available/*webdav*"
|
||||
"/etc/apache2/conf.d/*webdav*"
|
||||
"/etc/nginx/sites-available/*webdav*"
|
||||
"/etc/nginx/conf.d/*webdav*"
|
||||
"/etc/lighttpd/lighttpd.conf"
|
||||
"/etc/httpd/conf.d/*webdav*"
|
||||
"/usr/local/etc/apache2/*webdav*"
|
||||
)
|
||||
|
||||
for pattern in "${config_locations[@]}"; do
|
||||
for file in $pattern; do
|
||||
if [ -f "$file" ]; then
|
||||
echo "Found: $file"
|
||||
echo " Checking for Listen/ServerName directives..."
|
||||
grep -E "Listen|ServerName|<VirtualHost|listen" "$file" | head -3 || true
|
||||
fi
|
||||
done
|
||||
done
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "Diagnostic Complete"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Common Issues and Solutions:"
|
||||
echo "1. If service is bound to 127.0.0.1: Change Listen directive to 0.0.0.0:5006"
|
||||
echo "2. If firewall blocks port: Open port 5006 in firewall"
|
||||
echo "3. If router blocks: Configure port forwarding for port 5006"
|
||||
echo "4. If service not running: Start the WebDAV service"
|
||||
echo ""
|
||||
|
||||
Reference in New Issue
Block a user