From a924938b805ffa3049aae6ee8647fd07c5bfff1d Mon Sep 17 00:00:00 2001 From: opencode-agent Date: Fri, 13 Feb 2026 09:55:39 +0000 Subject: [PATCH] fix: improve permission handling for pre-existing directories - Create rclone-sync user BEFORE creating directories - Use chown -R to handle pre-existing directories from repo clone - Add ownership verification output - Support optional PUBLIC_IP argument for connection details --- ubuntu/setup.sh | 156 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 ubuntu/setup.sh diff --git a/ubuntu/setup.sh b/ubuntu/setup.sh new file mode 100644 index 0000000..b2a1b3a --- /dev/null +++ b/ubuntu/setup.sh @@ -0,0 +1,156 @@ +#!/bin/bash +# +# JingTian rclone Server Setup Script +# Run this on the Ubuntu VM that will receive synced files +# +# Usage: sudo bash setup.sh [PUBLIC_IP] +# +# If PUBLIC_IP is provided, it will be shown in the connection details. +# Otherwise, the script will try to detect it or use the first local IP. +# + +set -e + +# Configuration +DATA_DIR="/data/jingtian/BenjaminTeam" +RCLONE_USER="rclone-sync" +SSH_KEY_NAME="jingtian_rclone" +SSH_KEY_DIR="/home/$RCLONE_USER/.ssh" +PUBLIC_IP="${1:-}" + +echo "==========================================" +echo "JingTian rclone Server Setup" +echo "==========================================" + +# Check if running as root +if [ "$EUID" -ne 0 ]; then + echo "Please run as root (sudo bash setup.sh)" + exit 1 +fi + +# Step 1: Create dedicated user for rclone sync (FIRST, so we can set ownership correctly) +echo "" +echo "[1/5] Creating dedicated sync user: $RCLONE_USER..." +if id "$RCLONE_USER" &>/dev/null; then + echo " User $RCLONE_USER already exists, skipping..." +else + useradd -m -s /bin/bash "$RCLONE_USER" + echo " Created user: $RCLONE_USER" +fi + +# Step 2: Create data directory structure with correct ownership from the start +echo "" +echo "[2/5] Creating data directory..." + +# Create parent directories with root, then hand off to rclone-sync +mkdir -p /data/jingtian +chown root:root /data +chown -R "$RCLONE_USER:$RCLONE_USER" /data/jingtian + +# Create BenjaminTeam structure as rclone-sync user +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/_LLM_Sync" + +# Create the same folder structure as client +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/Admin/E-Signature" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/Admin/General Matter" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/Admin/IPD e-filing" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/Admin/JT Logo" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/Admin/Letterhead" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/Admin/Matter Open" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/Admin/Template" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/BD&M/2025 GCP" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/BD&M/HKPC" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/BD&M/WKCDA WKProcure" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/Billing/Draft Bills" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/Billing/Invoice Templates" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/Billing/Issued Bills" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/Client" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/Free Schedules/Price List" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/Free Schedules/Emails" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/IP" +sudo -u "$RCLONE_USER" mkdir -p "$DATA_DIR/Precedent" + +echo " Created: $DATA_DIR" + +# Verify ownership +echo " Verifying ownership..." +ls -la /data/jingtian/ | head -5 + +# Step 3: Generate SSH key pair for rclone +echo "" +echo "[3/5] Generating SSH key pair..." +mkdir -p "$SSH_KEY_DIR" +chown "$RCLONE_USER:$RCLONE_USER" "$SSH_KEY_DIR" +chmod 700 "$SSH_KEY_DIR" + +SSH_KEY_PATH="$SSH_KEY_DIR/$SSH_KEY_NAME" +if [ -f "$SSH_KEY_PATH" ]; then + echo " SSH key already exists at $SSH_KEY_PATH" + echo " To regenerate, delete the key and run this script again" +else + ssh-keygen -t ed25519 -f "$SSH_KEY_PATH" -N "" -C "jingtian-rclone-sync" + chown "$RCLONE_USER:$RCLONE_USER" "$SSH_KEY_PATH" "$SSH_KEY_PATH.pub" + chmod 600 "$SSH_KEY_PATH" + chmod 644 "$SSH_KEY_PATH.pub" + echo " Generated: $SSH_KEY_PATH" +fi + +# Step 4: Add public key to authorized_keys +echo "" +echo "[4/5] Configuring SSH authorized_keys..." +AUTHORIZED_KEYS="$SSH_KEY_DIR/authorized_keys" +PUBLIC_KEY=$(cat "$SSH_KEY_PATH.pub") + +if [ -f "$AUTHORIZED_KEYS" ] && grep -q "jingtian-rclone-sync" "$AUTHORIZED_KEYS"; then + echo " Public key already in authorized_keys" +else + echo "$PUBLIC_KEY" >> "$AUTHORIZED_KEYS" + chown "$RCLONE_USER:$RCLONE_USER" "$AUTHORIZED_KEYS" + chmod 600 "$AUTHORIZED_KEYS" + echo " Added public key to authorized_keys" +fi + +# Step 5: Install rclone (optional on server, but useful for debugging) +echo "" +echo "[5/5] Installing rclone..." +if command -v rclone &> /dev/null; then + echo " rclone already installed: $(rclone version | head -1)" +else + curl -s https://rclone.org/install.sh | bash + echo " Installed: $(rclone version | head -1)" +fi + +# Determine the IP to show +if [ -z "$PUBLIC_IP" ]; then + # Try to get public IP, fall back to first local IP + PUBLIC_IP=$(curl -s --max-time 5 ifconfig.me 2>/dev/null || hostname -I | awk '{print $1}') +fi + +# Print summary +echo "" +echo "==========================================" +echo "Setup Complete!" +echo "==========================================" +echo "" +echo "Data directory: $DATA_DIR" +echo "Sync user: $RCLONE_USER" +echo "SSH key location: $SSH_KEY_PATH" +echo "" +echo "==========================================" +echo "IMPORTANT: Copy the private key below" +echo "==========================================" +echo "" +echo "--- BEGIN PRIVATE KEY ---" +cat "$SSH_KEY_PATH" +echo "" +echo "--- END PRIVATE KEY ---" +echo "" +echo "Save this key to: windows/rclone-key" +echo "It will be used by Windows clients to connect." +echo "" +echo "Connection details for Windows rclone config:" +echo " Host: $PUBLIC_IP" +echo " User: $RCLONE_USER" +echo " Path: $DATA_DIR" +echo ""