- Flagstar: program completed, all 35 awards already distributed - USDA Business Builder: TERMINATED July 15, 2025 (RFBC killed by current admin) - Updated funding-research.html with strikethrough + red badges + updated capital stack - Updated meeting agenda funding table (closures + added EASSI) - Added plane-projects/ scaffolds (Compose YAML, used API instead due to CE compat) - Added supply-checklist.csv, trailer-registry.md, README.html, kiowa-meeting-agenda.html
223 lines
7.5 KiB
Bash
223 lines
7.5 KiB
Bash
#!/bin/bash
|
|
# setup-gdrive-mount.sh — Install rclone, configure Google Drive, mount at ~/gdrive
|
|
# Run ON ws (not remotely). Requires a browser for OAuth.
|
|
# Usage: bash setup-gdrive-mount.sh
|
|
|
|
set -euo pipefail
|
|
|
|
LOG="/tmp/gdrive-setup-$(date +%Y%m%d-%H%M%S).log"
|
|
MOUNT_POINT="$HOME/gdrive"
|
|
REMOTE_NAME="gdrive"
|
|
SERVICE_FILE="$HOME/.config/systemd/user/gdrive-mount.service"
|
|
|
|
log() { echo "[$(date '+%H:%M:%S')] $*" | tee -a "$LOG"; }
|
|
err() { echo "[$(date '+%H:%M:%S')] ERROR: $*" | tee -a "$LOG" >&2; }
|
|
|
|
log "=== Google Drive Mount Setup ==="
|
|
log "Log file: $LOG"
|
|
log ""
|
|
|
|
# --- Step 1: Check/install dependencies ---
|
|
log "Step 1: Checking dependencies..."
|
|
|
|
if ! command -v fusermount &>/dev/null && ! command -v fusermount3 &>/dev/null; then
|
|
log " Installing fuse3..."
|
|
sudo apt-get update -qq && sudo apt-get install -y fuse3 >> "$LOG" 2>&1
|
|
if ! command -v fusermount3 &>/dev/null; then
|
|
err "fuse3 install failed. Cannot mount without FUSE."
|
|
exit 1
|
|
fi
|
|
log " fuse3 installed."
|
|
else
|
|
log " FUSE already installed."
|
|
fi
|
|
|
|
if command -v rclone &>/dev/null; then
|
|
CURRENT_VER=$(rclone version --check 2>/dev/null | head -1 || rclone --version | head -1)
|
|
log " rclone already installed: $CURRENT_VER"
|
|
read -rp " Reinstall/update rclone? [y/N]: " UPDATE
|
|
if [[ "${UPDATE,,}" == "y" ]]; then
|
|
log " Updating rclone..."
|
|
curl -fsSL https://rclone.org/install.sh | sudo bash >> "$LOG" 2>&1
|
|
log " Updated: $(rclone --version | head -1)"
|
|
fi
|
|
else
|
|
log " Installing rclone..."
|
|
curl -fsSL https://rclone.org/install.sh | sudo bash >> "$LOG" 2>&1
|
|
if ! command -v rclone &>/dev/null; then
|
|
err "rclone install failed."
|
|
exit 1
|
|
fi
|
|
log " Installed: $(rclone --version | head -1)"
|
|
fi
|
|
|
|
# --- Step 2: Configure remote (if not already set up) ---
|
|
log ""
|
|
log "Step 2: Configuring rclone remote '$REMOTE_NAME'..."
|
|
|
|
if rclone listremotes | grep -q "^${REMOTE_NAME}:$"; then
|
|
log " Remote '$REMOTE_NAME' already exists."
|
|
read -rp " Reconfigure it? [y/N]: " RECONFIG
|
|
if [[ "${RECONFIG,,}" == "y" ]]; then
|
|
rclone config delete "$REMOTE_NAME"
|
|
log " Deleted old config. Starting fresh..."
|
|
else
|
|
log " Keeping existing config."
|
|
fi
|
|
fi
|
|
|
|
if ! rclone listremotes | grep -q "^${REMOTE_NAME}:$"; then
|
|
log ""
|
|
log " ┌─────────────────────────────────────────────────────────┐"
|
|
log " │ An AUTH URL will be printed below. │"
|
|
log " │ Copy it, open in ANY browser, sign in with: │"
|
|
log " │ samueljamesinc@snsnetworksolutions.net │"
|
|
log " │ Authorize rclone, then come back here. │"
|
|
log " └─────────────────────────────────────────────────────────┘"
|
|
log ""
|
|
sleep 2
|
|
|
|
# Use config create with no-browser so it prints the URL to terminal
|
|
rclone config create "$REMOTE_NAME" drive \
|
|
scope=drive \
|
|
config_is_local=false 2>&1 | tee -a "$LOG"
|
|
|
|
# Verify it worked
|
|
if ! rclone listremotes | grep -q "^${REMOTE_NAME}:$"; then
|
|
err "Remote creation failed. Run 'rclone config' manually to debug."
|
|
exit 1
|
|
fi
|
|
log " Remote '$REMOTE_NAME' configured successfully."
|
|
fi
|
|
|
|
# --- Step 3: Test connectivity ---
|
|
log ""
|
|
log "Step 3: Testing connectivity..."
|
|
|
|
if rclone lsd "${REMOTE_NAME}:" --max-depth 1 >> "$LOG" 2>&1; then
|
|
log " Connected to Google Drive. Top-level folders:"
|
|
rclone lsd "${REMOTE_NAME}:" --max-depth 1 | awk '{print " " $NF}' | head -10 | tee -a "$LOG"
|
|
else
|
|
err "Cannot list Google Drive. Check OAuth token / network."
|
|
err "Try: rclone config reconnect ${REMOTE_NAME}:"
|
|
exit 1
|
|
fi
|
|
|
|
# --- Step 4: Create mount point ---
|
|
log ""
|
|
log "Step 4: Setting up mount point at $MOUNT_POINT..."
|
|
|
|
mkdir -p "$MOUNT_POINT"
|
|
|
|
# Check if already mounted
|
|
if mountpoint -q "$MOUNT_POINT" 2>/dev/null; then
|
|
log " $MOUNT_POINT is already mounted."
|
|
read -rp " Unmount and remount? [y/N]: " REMOUNT
|
|
if [[ "${REMOUNT,,}" == "y" ]]; then
|
|
fusermount -u "$MOUNT_POINT" 2>/dev/null || fusermount3 -u "$MOUNT_POINT" 2>/dev/null || true
|
|
log " Unmounted."
|
|
else
|
|
log " Leaving existing mount. Skipping to service setup."
|
|
fi
|
|
fi
|
|
|
|
# --- Step 5: Test mount (foreground, 5 seconds) ---
|
|
if ! mountpoint -q "$MOUNT_POINT" 2>/dev/null; then
|
|
log ""
|
|
log "Step 5: Test mounting (5 second check)..."
|
|
|
|
rclone mount "${REMOTE_NAME}:" "$MOUNT_POINT" \
|
|
--vfs-cache-mode full \
|
|
--vfs-cache-max-age 1h \
|
|
--dir-cache-time 30s \
|
|
--poll-interval 15s \
|
|
--allow-other \
|
|
--daemon
|
|
|
|
sleep 3
|
|
|
|
if mountpoint -q "$MOUNT_POINT" 2>/dev/null; then
|
|
log " Mount successful! Files visible at $MOUNT_POINT"
|
|
ls "$MOUNT_POINT" | head -5 | while read -r f; do log " $f"; done
|
|
# Unmount — the systemd service will handle persistent mount
|
|
fusermount -u "$MOUNT_POINT" 2>/dev/null || fusermount3 -u "$MOUNT_POINT" 2>/dev/null || true
|
|
log " Test unmounted. Setting up persistent service..."
|
|
else
|
|
err "Mount test failed. Check: 'rclone mount ${REMOTE_NAME}: $MOUNT_POINT --vfs-cache-mode full' manually."
|
|
err "Common fix: add 'user_allow_other' to /etc/fuse.conf"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# --- Step 6: Create systemd user service for auto-mount ---
|
|
log ""
|
|
log "Step 6: Creating systemd user service..."
|
|
|
|
mkdir -p "$(dirname "$SERVICE_FILE")"
|
|
|
|
cat > "$SERVICE_FILE" << EOF
|
|
[Unit]
|
|
Description=Google Drive mount via rclone (${REMOTE_NAME})
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=notify
|
|
ExecStartPre=/bin/mkdir -p ${MOUNT_POINT}
|
|
ExecStart=/usr/bin/rclone mount ${REMOTE_NAME}: ${MOUNT_POINT} \\
|
|
--vfs-cache-mode full \\
|
|
--vfs-cache-max-age 1h \\
|
|
--dir-cache-time 30s \\
|
|
--poll-interval 15s \\
|
|
--allow-other \\
|
|
--log-file=%h/.local/share/rclone-gdrive.log \\
|
|
--log-level INFO
|
|
ExecStop=/bin/fusermount -u ${MOUNT_POINT}
|
|
Restart=on-failure
|
|
RestartSec=10
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
EOF
|
|
|
|
log " Service file written: $SERVICE_FILE"
|
|
|
|
# Enable lingering so user services run without login
|
|
sudo loginctl enable-linger "$USER" 2>/dev/null || true
|
|
|
|
# Ensure user_allow_other is set in fuse.conf (needed for --allow-other)
|
|
if ! grep -q "^user_allow_other" /etc/fuse.conf 2>/dev/null; then
|
|
log " Enabling user_allow_other in /etc/fuse.conf..."
|
|
echo "user_allow_other" | sudo tee -a /etc/fuse.conf > /dev/null
|
|
fi
|
|
|
|
# Reload and start
|
|
systemctl --user daemon-reload
|
|
systemctl --user enable gdrive-mount.service
|
|
systemctl --user start gdrive-mount.service
|
|
|
|
sleep 3
|
|
|
|
if mountpoint -q "$MOUNT_POINT" 2>/dev/null; then
|
|
log " Service running. Google Drive mounted at $MOUNT_POINT"
|
|
else
|
|
err " Service started but mount not detected. Check:"
|
|
err " systemctl --user status gdrive-mount.service"
|
|
err " cat ~/.local/share/rclone-gdrive.log"
|
|
exit 1
|
|
fi
|
|
|
|
# --- Done ---
|
|
log ""
|
|
log "=== SETUP COMPLETE ==="
|
|
log ""
|
|
log " Mount point: $MOUNT_POINT"
|
|
log " Service: systemctl --user {status,stop,restart} gdrive-mount.service"
|
|
log " Logs: ~/.local/share/rclone-gdrive.log"
|
|
log " Persists: Yes (auto-starts on login, lingering enabled)"
|
|
log " Full log: $LOG"
|
|
log ""
|
|
log " Your Google Drive is at: ~/gdrive/"
|
|
log " SnS Hospitality folder: ~/gdrive/SnS Network Solutions/SnS Hospitality Group LLC/"
|
|
log ""
|