init projectmycelium

This commit is contained in:
mik-tf
2025-09-01 21:37:01 -04:00
commit b41efb0e99
319 changed files with 128160 additions and 0 deletions

139
scripts/README.md Normal file
View File

@@ -0,0 +1,139 @@
# Project Mycelium Deployment Scripts
This directory contains improved deployment scripts for the Project Mycelium that handle repository and directory management robustly.
## Scripts Overview
### Development Environment
- **Script**: [`tf-marketplace-dev.sh`](tf-marketplace-dev.sh)
- **Domain**: dev.threefold.pro
- **Port**: 9998
- **Branch**: development
- **Service**: tf-marketplace-dev
### Production Environment
- **Script**: [`tf-marketplace-prod.sh`](tf-marketplace-prod.sh)
- **Domain**: threefold.pro
- **Port**: 9999
- **Branch**: main
- **Service**: tf-marketplace
## Key Improvements
### 1. Robust Directory/Repository Handling
- ✅ Creates directory structure if it doesn't exist
- ✅ Handles both fresh clones and existing repositories
- ✅ Properly updates existing repositories with `git reset --hard`
- ✅ Validates git repository integrity
- ✅ Uses correct working directories throughout
### 2. Error Handling
- ✅ Exit on error (`set -e`)
- ✅ Validates cargo availability
- ✅ Checks for Cargo.toml presence
- ✅ Proper error messages with context
### 3. Environment-Specific Configuration
- ✅ Separate scripts for dev and prod environments
- ✅ Correct ports (9998 for dev, 9999 for prod)
- ✅ Correct branches (development for dev, main for prod)
- ✅ Clear environment identification in logs
## Installation
### 1. Copy Scripts to Server
```bash
# Copy the deployment scripts with explicit naming
sudo cp tf-marketplace-dev.sh /etc/zinit/cmds/tf-marketplace-dev.sh
sudo cp tf-marketplace-prod.sh /etc/zinit/cmds/tf-marketplace-prod.sh
sudo chmod +x /etc/zinit/cmds/tf-marketplace-dev.sh
sudo chmod +x /etc/zinit/cmds/tf-marketplace-prod.sh
```
### 2. Install Zinit Service Definitions
```bash
# Copy service definitions from config directory
sudo cp ../config/zinit/tf-marketplace-dev.yaml /etc/zinit/tf-marketplace-dev.yaml
sudo cp ../config/zinit/tf-marketplace-prod.yaml /etc/zinit/tf-marketplace-prod.yaml
```
## Usage
### Development Deployment
```bash
# Start development service
zinit start tf-marketplace-dev
# Monitor development service
zinit monitor tf-marketplace-dev
# View development logs
zinit log tf-marketplace-dev
```
### Production Deployment
```bash
# Start production service
zinit start tf-marketplace
# Monitor production service
zinit monitor tf-marketplace
# View production logs
zinit log tf-marketplace
```
## Comparison with Original Script
### Original Issues Fixed
1. **Directory Check Logic**:
- ❌ Original: `[ ! -d "$DIR_NAME" ] && git clone "$REPO_URL"`
- ✅ Fixed: Proper path handling and working directory management
2. **Missing Updates**:
- ❌ Original: No git pull for existing repositories
- ✅ Fixed: `git reset --hard origin/branch` for clean updates
3. **Error Handling**:
- ❌ Original: No error checking
- ✅ Fixed: Comprehensive error handling and validation
4. **Path Consistency**:
- ❌ Original: Mixed path conventions
- ✅ Fixed: Consistent with existing deployment infrastructure
## Monitoring and Troubleshooting
### Check Service Status
```bash
zinit list | grep tf-marketplace
```
### View Real-time Logs
```bash
# Development
tail -f /var/log/zinit/tf-marketplace-dev.log
# Production
tail -f /var/log/zinit/tf-marketplace.log
```
### Manual Testing
```bash
# Test development script manually
sudo /etc/zinit/cmds/tf-marketplace-dev.sh
# Test production script manually
sudo /etc/zinit/cmds/tf-marketplace.sh
```
## Integration with Existing Infrastructure
These scripts are designed to work seamlessly with:
- Existing Makefile deployment targets ([`deploy-dev`](../Makefile:14), [`deploy-prod`](../Makefile:19))
- Current Caddy configuration
- Existing zinit service management
- Current directory structure conventions
The scripts maintain compatibility with the existing deployment workflow while providing more robust error handling and repository management.

155
scripts/deploy.sh Normal file
View File

@@ -0,0 +1,155 @@
#!/bin/bash
# Exit on error
set -e
echo "===== Project Mycelium Simplified Deployment Script ====="
echo "Date: $(date)"
echo "User: $(whoami)"
# Check required commands
for cmd in git cargo zinit caddy; do
if ! command -v $cmd &> /dev/null; then
echo "Error: Required command '$cmd' not found."
echo "Please install all prerequisites before running this script."
exit 1
fi
done
# Variables
REPO_URL="https://git.ourworld.tf/tfgrid_research/projectmycelium"
INSTALL_DIR="/root/code/github.com/tfgrid_research/projectmycelium"
SERVICE_NAME="tf-marketplace"
PORT=9999
DOMAIN="example.com" # Replace with your actual domain
# Prompt for domain name
read -p "Enter your domain name [default: $DOMAIN]: " input_domain
DOMAIN=${input_domain:-$DOMAIN}
# Generate a random secret key if not provided
if [ -z "$SECRET_KEY" ]; then
SECRET_KEY=$(openssl rand -base64 32)
echo "Generated random SECRET_KEY"
fi
echo "===== Cloning Repository ====="
mkdir -p $(dirname "$INSTALL_DIR")
if [ -d "$INSTALL_DIR" ]; then
echo "Directory already exists. Updating repository..."
cd "$INSTALL_DIR"
git checkout main
git fetch
git pull
else
echo "Cloning repository..."
git clone "$REPO_URL" "$INSTALL_DIR"
cd "$INSTALL_DIR"
git checkout main
fi
echo "===== Creating zinit Service ====="
# Create service script directory
sudo mkdir -p /etc/zinit/cmds
# Create service script
cat > /tmp/tf-marketplace.sh << EOF
#!/bin/bash
cd $INSTALL_DIR
export RUST_LOG=info
export SECRET_KEY="$SECRET_KEY"
exec /root/.cargo/bin/cargo run --release -- --port $PORT
EOF
sudo cp /tmp/tf-marketplace.sh /etc/zinit/cmds/$SERVICE_NAME.sh
sudo chmod +x /etc/zinit/cmds/$SERVICE_NAME.sh
rm /tmp/tf-marketplace.sh
# Create zinit service definition
cat > /tmp/tf-marketplace.yaml << EOF
exec: "/bin/bash -c /etc/zinit/cmds/$SERVICE_NAME.sh"
EOF
sudo cp /tmp/tf-marketplace.yaml /etc/zinit/$SERVICE_NAME.yaml
rm /tmp/tf-marketplace.yaml
echo "===== Configuring Caddy ====="
cat > /tmp/Caddyfile << EOF
$DOMAIN {
# Enable compression
encode gzip zstd
# Serve static files
handle /static/* {
root * $INSTALL_DIR/src
file_server
}
# Reverse proxy to the application
reverse_proxy localhost:$PORT {
# Customize timeouts if needed
timeout 2m
# Enable WebSocket support
header_up Connection {>Connection}
header_up Upgrade {>Upgrade}
}
# Add security headers
header {
# Enable HSTS
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# Prevent MIME type sniffing
X-Content-Type-Options "nosniff"
# Protect against clickjacking
X-Frame-Options "SAMEORIGIN"
# Enable XSS protection
X-XSS-Protection "1; mode=block"
# Control browser features
Permissions-Policy "geolocation=(), midi=(), camera=(), usb=(), magnetometer=(), accelerometer=(), gyroscope=(), payment=()"
# Remove server information
-Server
}
# Log access
log {
output file /var/log/caddy/access.log
format json
}
}
EOF
sudo mkdir -p /etc/caddy
sudo cp /tmp/Caddyfile /etc/caddy/Caddyfile
rm /tmp/Caddyfile
echo "===== Starting Services ====="
# Start the marketplace service
zinit start $SERVICE_NAME
# Restart Caddy to load new configuration
zinit restart caddy
echo "===== Configuring Firewall ====="
if command -v ufw &> /dev/null; then
sudo ufw allow http
sudo ufw allow https
echo "Firewall configured to allow HTTP and HTTPS traffic."
fi
echo "===== Deployment Complete ====="
echo "Project Mycelium has been deployed at: https://$DOMAIN"
echo
echo "You can monitor the application with:"
echo " zinit list"
echo " zinit log $SERVICE_NAME"
echo " tail -f /var/log/zinit/$SERVICE_NAME.log"
echo
echo "Caddy status and logs:"
echo " zinit status caddy"
echo " zinit log caddy"

65
scripts/dev/cargo-errors.sh Executable file
View File

@@ -0,0 +1,65 @@
#!/usr/bin/env bash
# Summarize Rust compiler errors into a clean, readable log.
# Prefers cargo JSON + jq; falls back to sed/awk parser if jq is unavailable.
# Output file: /tmp/cargo_errors_only.log (override with OUT env var)
set -euo pipefail
OUT=${OUT:-/tmp/cargo_errors_only.log}
PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo "")
if [[ -n "$PROJECT_ROOT" ]]; then
cd "$PROJECT_ROOT"
fi
# Ensure colorless output from cargo to avoid ANSI in fallback
export CARGO_TERM_COLOR=never
# Function: JSON mode (best)
run_json_mode() {
# Capture cargo's exit code from the first command in the pipeline
set +e
set +o pipefail
cargo check --message-format=json -q "$@" 2>/dev/null \
| jq -r 'select(.reason=="compiler-message" and .message.level=="error") | .message.rendered' \
| tee "$OUT"
local cargo_status=${PIPESTATUS[0]}
set -o pipefail
set -e
return "$cargo_status"
}
# Function: Fallback parser (no jq required)
run_fallback_mode() {
# We intentionally capture stderr (diagnostics) and stdout
set +e
set +o pipefail
cargo check -q "$@" 2>&1 \
| sed -r 's/\x1B\[[0-9;]*[mK]//g' \
| awk '
BEGIN{inerr=0}
/^warning:/{inerr=0; next}
/^error(\[|:)/{inerr=1}
# Drop cargo/rustc warning summaries while still inside an error block
inerr && /[0-9]+ warnings? emitted/ {next}
inerr{print}
' \
| tee "$OUT"
local cargo_status=${PIPESTATUS[0]}
set -o pipefail
set -e
return "$cargo_status"
}
status=0
if command -v jq >/dev/null 2>&1; then
if ! run_json_mode "$@"; then
status=$?
fi
else
echo "INFO: jq not found; using fallback parser (install jq for best results)." >&2
if ! run_fallback_mode "$@"; then
status=$?
fi
fi
exit "$status"

194
scripts/fix_user_data.py Normal file
View File

@@ -0,0 +1,194 @@
#!/usr/bin/env python3
"""
Industry Standard Data Validation and Repair Tool
Comprehensive fix for ThreeFold Marketplace user data files
"""
import json
import os
import sys
from pathlib import Path
def normalize_activity_type(activity_type):
"""Normalize activity type to match enum variants"""
mapping = {
"ServiceProgress": "ServiceCreated",
"AppDeployment": "Deployment",
"AppCreated": "AppPublished",
"NodeCreated": "NodeAdded",
"NodeModified": "NodeUpdated",
"WalletDeposit": "WalletTransaction",
"WalletWithdraw": "WalletTransaction",
"Payment": "WalletTransaction",
"ProfileChanged": "ProfileUpdate",
"ConfigChange": "SettingsChange",
"BrowseMarketplace": "MarketplaceView",
"SliceCreation": "SliceCreated",
"SliceAssignment": "SliceAllocated",
"SliceRemoval": "SliceReleased",
}
# Valid variants pass through unchanged
valid_variants = {
"Login", "Purchase", "Deployment", "ServiceCreated", "AppPublished",
"NodeAdded", "NodeUpdated", "WalletTransaction", "ProfileUpdate",
"SettingsChange", "MarketplaceView", "SliceCreated", "SliceAllocated",
"SliceReleased"
}
if activity_type in valid_variants:
return activity_type
return mapping.get(activity_type, "ProfileUpdate")
def infer_category_from_activity_type(activity_type):
"""Infer category from activity type"""
mapping = {
"ServiceCreated": "Service",
"AppPublished": "App",
"Deployment": "App",
"NodeAdded": "Farming",
"NodeUpdated": "Farming",
"SliceCreated": "Farming",
"SliceAllocated": "Farming",
"SliceReleased": "Farming",
"WalletTransaction": "Finance",
"Login": "Account",
"ProfileUpdate": "Account",
"SettingsChange": "Account",
"Purchase": "Marketplace",
"MarketplaceView": "Marketplace",
}
return mapping.get(activity_type, "General")
def repair_user_activities(data):
"""Repair user activities to match schema"""
if "user_activities" not in data or data["user_activities"] is None:
data["user_activities"] = []
return
for activity in data["user_activities"]:
if activity is None:
continue
# Fix activity_type
if "activity_type" in activity and activity["activity_type"] is not None:
activity["activity_type"] = normalize_activity_type(activity["activity_type"])
# Ensure category field exists
if "category" not in activity:
activity_type = activity.get("activity_type", "Service")
if activity_type is not None:
activity["category"] = infer_category_from_activity_type(activity_type)
else:
activity["category"] = "General"
def repair_farmer_settings(data):
"""Repair farmer settings to include required fields"""
if "farmer_settings" not in data or data["farmer_settings"] is None:
data["farmer_settings"] = {}
farmer_settings = data["farmer_settings"]
# Ensure minimum_deployment_duration exists
if "minimum_deployment_duration" not in farmer_settings:
farmer_settings["minimum_deployment_duration"] = 24
# Ensure preferred_regions exists
if "preferred_regions" not in farmer_settings:
farmer_settings["preferred_regions"] = ["NA", "EU"]
def ensure_required_fields(data):
"""Ensure all required top-level fields exist"""
required_fields = {
"user_email": "unknown@example.com",
"wallet_balance": "0.0",
"transactions": [],
"services": [],
"service_requests": [],
"apps": [],
"app_deployments": [],
"nodes": [],
"farmer_earnings": [],
"user_activities": [],
"pool_positions": {},
}
for field, default_value in required_fields.items():
if field not in data:
data[field] = default_value
def validate_and_repair_user_data(json_str):
"""Validate and repair user data JSON"""
try:
data = json.loads(json_str)
repair_user_activities(data)
repair_farmer_settings(data)
ensure_required_fields(data)
return json.dumps(data, indent=2, ensure_ascii=False)
except json.JSONDecodeError as e:
raise ValueError(f"Invalid JSON: {e}")
def validate_all_user_files():
"""Validate all user data files"""
user_data_dir = Path("user_data")
if not user_data_dir.exists():
raise FileNotFoundError("user_data directory not found")
results = []
for json_file in user_data_dir.glob("*.json"):
filename = json_file.name
try:
content = json_file.read_text(encoding='utf-8')
repaired_content = validate_and_repair_user_data(content)
# Write back the repaired content
json_file.write_text(repaired_content, encoding='utf-8')
results.append(f"{filename}: Successfully validated and repaired")
except Exception as e:
results.append(f"{filename}: {e}")
return results
def main():
print("🔧 ThreeFold Marketplace Data Validator")
print("========================================")
print()
try:
results = validate_all_user_files()
print("📊 Validation Results:")
print()
for result in results:
print(f" {result}")
print()
success_count = sum(1 for r in results if r.startswith(""))
error_count = sum(1 for r in results if r.startswith(""))
print("📈 Summary:")
print(f" ✅ Successfully processed: {success_count}")
print(f" ❌ Errors encountered: {error_count}")
if error_count == 0:
print()
print("🎉 All user data files are now valid and ready for use!")
return 0
else:
print()
print("⚠️ Some files had errors. Please review the output above.")
return 1
except Exception as e:
print(f"❌ Validation failed: {e}")
return 1
if __name__ == "__main__":
sys.exit(main())

10
scripts/start.sh Executable file
View File

@@ -0,0 +1,10 @@
#!/bin/bash
# Get the directory of the script and change to it
cd "$(dirname "$0")"
export SECRET_KEY=1234
export GITEA_CLIENT_ID=""
export GITEA_CLIENT_SECRET=""
export GITEA_INSTANCE_URL="https://git.ourworld.tf"
cargo run

10
scripts/start_with_gitea.sh Executable file
View File

@@ -0,0 +1,10 @@
#!/bin/bash
# Get the directory of the script and change to it
cd "$(dirname "$0")"
export GITEA_CLIENT_ID="9f409b35-6258-4ac3-8370-05adc187c1f5"
export GITEA_CLIENT_SECRET="gto_4s77ae33m5ernlf2423wx6wjyyqatqoe567rym7fcu3sqmu5azea"
export GITEA_INSTANCE_URL="https://git.ourworld.tf"
export APP_URL="http://localhost:9999"
cargo run

View File

@@ -0,0 +1,239 @@
#!/bin/bash
# Exit on error
set -e
echo "===== Project Mycelium Development Deployment ====="
echo "Environment: dev.threefold.pro"
echo "Date: $(date)"
echo "User: $(whoami)"
# Load deployment credentials for git authentication
DEPLOY_ENV="/tmp/tf-marketplace-deploy.env"
if [ -f "$DEPLOY_ENV" ]; then
echo "Loading deployment credentials from $DEPLOY_ENV"
source "$DEPLOY_ENV"
else
echo "Warning: Deployment credentials not found at $DEPLOY_ENV"
echo "Please run 'make deploy-setup' to copy deployment credentials"
fi
# Variables
BASE_DIR="/root/code/git.ourworld.tf/tfgrid_research"
INSTALL_DIR="$BASE_DIR/dev/projectmycelium"
BRANCH="development"
PORT=9998
DOMAIN="dev.threefold.pro"
# Construct authenticated Git URL if credentials are available
if [ -n "$GITEA_USER" ] && [ -n "$GITEA_TOKEN" ]; then
REPO_URL="https://${GITEA_USER}:${GITEA_TOKEN}@git.ourworld.tf/tfgrid_research/projectmycelium.git"
echo "Using authenticated Git access"
else
REPO_URL="https://git.ourworld.tf/tfgrid_research/projectmycelium.git"
echo "Warning: No Gitea credentials found, using unauthenticated access"
fi
echo "===== Setting up directory structure ====="
# Create base directory if it doesn't exist
mkdir -p "$BASE_DIR"
cd "$BASE_DIR"
echo "===== Repository management ====="
if [ -d "$INSTALL_DIR" ]; then
echo "Directory exists. Checking if it's a git repository..."
cd "$INSTALL_DIR"
# Check if it's a git repository
if [ -d ".git" ]; then
echo "Valid git repository found. Updating..."
# Clean up git state
if [ -f ".git/index.lock" ]; then
echo "Removing git lock file..."
rm -f ".git/index.lock"
fi
# Clean any uncommitted changes
git reset --hard HEAD 2>/dev/null || true
git clean -fd 2>/dev/null || true
# Update remote URL with authentication if available
if [ -n "$GITEA_USER" ] && [ -n "$GITEA_TOKEN" ]; then
git remote set-url origin "$REPO_URL"
fi
git fetch origin
git checkout "$BRANCH"
git reset --hard "origin/$BRANCH"
echo "Repository updated to latest $BRANCH branch"
else
echo "Directory exists but is not a git repository. Removing and cloning fresh..."
cd "$BASE_DIR"
rm -rf "$INSTALL_DIR"
echo "Cloning repository..."
git clone "$REPO_URL" "$INSTALL_DIR"
cd "$INSTALL_DIR"
git checkout "$BRANCH"
echo "Repository cloned and checked out to $BRANCH branch"
fi
else
echo "Cloning repository..."
git clone "$REPO_URL" "$INSTALL_DIR"
cd "$INSTALL_DIR"
git checkout "$BRANCH"
echo "Repository cloned and checked out to $BRANCH branch"
fi
echo "===== Cleaning build cache ====="
# Clean cargo cache to ensure fresh build
echo "Cleaning cargo build cache..."
"$CARGO_CMD" clean 2>/dev/null || true
echo "===== Verifying environment ====="
echo "Current PATH: $PATH"
echo "Current USER: $(whoami)"
echo "Current HOME: $HOME"
# Find cargo using multiple methods with robust detection
CARGO_CMD=""
# Method 1: Check if cargo is in PATH
echo "Checking for cargo in PATH..."
if command -v cargo &> /dev/null; then
CARGO_CMD="cargo"
echo "✓ Found cargo in PATH: $(which cargo)"
# Method 2: Check common Rust installation locations
elif [ -f "$HOME/.cargo/bin/cargo" ]; then
CARGO_CMD="$HOME/.cargo/bin/cargo"
echo "✓ Found cargo at $HOME/.cargo/bin/cargo"
# Add to PATH for this session
export PATH="$HOME/.cargo/bin:$PATH"
# Method 3: Check root cargo location
elif [ -f "/root/.cargo/bin/cargo" ]; then
CARGO_CMD="/root/.cargo/bin/cargo"
echo "✓ Found cargo at /root/.cargo/bin/cargo"
export PATH="/root/.cargo/bin:$PATH"
# Method 4: Check system-wide installation
elif [ -f "/usr/local/bin/cargo" ]; then
CARGO_CMD="/usr/local/bin/cargo"
echo "✓ Found cargo at /usr/local/bin/cargo"
elif [ -f "/usr/bin/cargo" ]; then
CARGO_CMD="/usr/bin/cargo"
echo "✓ Found cargo at /usr/bin/cargo"
# Method 5: Use whereis to find cargo
else
echo "Searching for cargo with whereis..."
CARGO_PATHS=$(whereis cargo 2>/dev/null | cut -d' ' -f2-)
echo "whereis found: $CARGO_PATHS"
for path in $CARGO_PATHS; do
if [ -f "$path" ] && [ -x "$path" ]; then
CARGO_CMD="$path"
echo "✓ Found executable cargo at $path"
break
fi
done
# Method 6: Last resort - try to find cargo anywhere
if [ -z "$CARGO_CMD" ]; then
echo "Searching for cargo with find..."
FOUND_CARGO=$(find /usr /root /home -name "cargo" -type f -executable 2>/dev/null | head -1)
if [ -n "$FOUND_CARGO" ] && [ -f "$FOUND_CARGO" ]; then
CARGO_CMD="$FOUND_CARGO"
echo "✓ Found cargo at $FOUND_CARGO"
fi
fi
fi
# Final verification
if [ -n "$CARGO_CMD" ]; then
echo "Using cargo command: $CARGO_CMD"
echo "Testing cargo command..."
if "$CARGO_CMD" --version &> /dev/null; then
echo "✓ Cargo is working: $($CARGO_CMD --version)"
else
echo "✗ Cargo command failed to execute"
CARGO_CMD=""
fi
fi
# If still no cargo found, try installation
if [ -z "$CARGO_CMD" ]; then
echo "Cargo not found anywhere. Installing Rust toolchain..."
# Install Rust using rustup
if ! command -v rustup &> /dev/null; then
echo "Installing rustup..."
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
# Source the cargo environment
if [ -f "$HOME/.cargo/env" ]; then
source "$HOME/.cargo/env"
fi
# Add to PATH
export PATH="$HOME/.cargo/bin:$PATH"
fi
# Verify installation
if command -v cargo &> /dev/null; then
CARGO_CMD="cargo"
echo "✓ Rust toolchain installed successfully"
elif [ -f "$HOME/.cargo/bin/cargo" ]; then
CARGO_CMD="$HOME/.cargo/bin/cargo"
export PATH="$HOME/.cargo/bin:$PATH"
echo "✓ Rust toolchain installed successfully"
else
echo "✗ Failed to install Rust toolchain"
echo "Please install Rust manually: https://rustup.rs/"
echo "Waiting 30 seconds before retrying..."
sleep 30
exit 1
fi
fi
# Check if we're in the right directory
if [ ! -f "Cargo.toml" ]; then
echo "Error: Cargo.toml not found. Are we in the right directory?"
pwd
exit 1
fi
echo "===== Setting up application environment ====="
# Generate SECRET_KEY if .env doesn't exist or doesn't have a valid key
if [ ! -f ".env" ] || ! grep -q "^SECRET_KEY=" .env || grep -q "your_secret_key_here" .env; then
echo "Generating SECRET_KEY for application..."
SECRET_KEY=$(openssl rand -base64 64 | tr -d '\n')
# Create .env from template if it doesn't exist
if [ ! -f ".env" ] && [ -f ".env.example" ]; then
cp .env.example .env
fi
# Update or add SECRET_KEY
if [ -f ".env" ]; then
if grep -q "^SECRET_KEY=" .env; then
sed -i "s/^SECRET_KEY=.*/SECRET_KEY=$SECRET_KEY/" .env
else
echo "SECRET_KEY=$SECRET_KEY" >> .env
fi
else
echo "SECRET_KEY=$SECRET_KEY" > .env
fi
echo "SECRET_KEY generated and saved to .env"
else
echo "Using existing SECRET_KEY from .env"
fi
echo "===== Starting application ====="
echo "Running Project Mycelium on port $PORT..."
echo "Working directory: $(pwd)"
echo "Branch: $(git branch --show-current)"
echo "Commit: $(git rev-parse --short HEAD)"
# Set environment variables
export RUST_LOG=info
# Run the application (following existing pattern)
git checkout "$BRANCH"
exec "$CARGO_CMD" run --release --bin projectmycelium -- --port "$PORT"

View File

@@ -0,0 +1,239 @@
#!/bin/bash
# Exit on error
set -e
echo "===== Project Mycelium Production Deployment ====="
echo "Environment: threefold.pro"
echo "Date: $(date)"
echo "User: $(whoami)"
# Load deployment credentials for git authentication
DEPLOY_ENV="/tmp/tf-marketplace-deploy.env"
if [ -f "$DEPLOY_ENV" ]; then
echo "Loading deployment credentials from $DEPLOY_ENV"
source "$DEPLOY_ENV"
else
echo "Warning: Deployment credentials not found at $DEPLOY_ENV"
echo "Please run 'make deploy-setup' to copy deployment credentials"
fi
# Variables
BASE_DIR="/root/code/git.ourworld.tf/tfgrid_research"
INSTALL_DIR="$BASE_DIR/prod/projectmycelium"
BRANCH="main"
PORT=9999
DOMAIN="threefold.pro"
# Construct authenticated Git URL if credentials are available
if [ -n "$GITEA_USER" ] && [ -n "$GITEA_TOKEN" ]; then
REPO_URL="https://${GITEA_USER}:${GITEA_TOKEN}@git.ourworld.tf/tfgrid_research/projectmycelium.git"
echo "Using authenticated Git access"
else
REPO_URL="https://git.ourworld.tf/tfgrid_research/projectmycelium.git"
echo "Warning: No Gitea credentials found, using unauthenticated access"
fi
echo "===== Setting up directory structure ====="
# Create base directory if it doesn't exist
mkdir -p "$BASE_DIR"
cd "$BASE_DIR"
echo "===== Repository management ====="
if [ -d "$INSTALL_DIR" ]; then
echo "Directory exists. Checking if it's a git repository..."
cd "$INSTALL_DIR"
# Check if it's a git repository
if [ -d ".git" ]; then
echo "Valid git repository found. Updating..."
# Clean up git state
if [ -f ".git/index.lock" ]; then
echo "Removing git lock file..."
rm -f ".git/index.lock"
fi
# Clean any uncommitted changes
git reset --hard HEAD 2>/dev/null || true
git clean -fd 2>/dev/null || true
# Update remote URL with authentication if available
if [ -n "$GITEA_USER" ] && [ -n "$GITEA_TOKEN" ]; then
git remote set-url origin "$REPO_URL"
fi
git fetch origin
git checkout "$BRANCH"
git reset --hard "origin/$BRANCH"
echo "Repository updated to latest $BRANCH branch"
else
echo "Directory exists but is not a git repository. Removing and cloning fresh..."
cd "$BASE_DIR"
rm -rf "$INSTALL_DIR"
echo "Cloning repository..."
git clone "$REPO_URL" "$INSTALL_DIR"
cd "$INSTALL_DIR"
git checkout "$BRANCH"
echo "Repository cloned and checked out to $BRANCH branch"
fi
else
echo "Cloning repository..."
git clone "$REPO_URL" "$INSTALL_DIR"
cd "$INSTALL_DIR"
git checkout "$BRANCH"
echo "Repository cloned and checked out to $BRANCH branch"
fi
echo "===== Cleaning build cache ====="
# Clean cargo cache to ensure fresh build
echo "Cleaning cargo build cache..."
"$CARGO_CMD" clean 2>/dev/null || true
echo "===== Verifying environment ====="
echo "Current PATH: $PATH"
echo "Current USER: $(whoami)"
echo "Current HOME: $HOME"
# Find cargo using multiple methods with robust detection
CARGO_CMD=""
# Method 1: Check if cargo is in PATH
echo "Checking for cargo in PATH..."
if command -v cargo &> /dev/null; then
CARGO_CMD="cargo"
echo "✓ Found cargo in PATH: $(which cargo)"
# Method 2: Check common Rust installation locations
elif [ -f "$HOME/.cargo/bin/cargo" ]; then
CARGO_CMD="$HOME/.cargo/bin/cargo"
echo "✓ Found cargo at $HOME/.cargo/bin/cargo"
# Add to PATH for this session
export PATH="$HOME/.cargo/bin:$PATH"
# Method 3: Check root cargo location
elif [ -f "/root/.cargo/bin/cargo" ]; then
CARGO_CMD="/root/.cargo/bin/cargo"
echo "✓ Found cargo at /root/.cargo/bin/cargo"
export PATH="/root/.cargo/bin:$PATH"
# Method 4: Check system-wide installation
elif [ -f "/usr/local/bin/cargo" ]; then
CARGO_CMD="/usr/local/bin/cargo"
echo "✓ Found cargo at /usr/local/bin/cargo"
elif [ -f "/usr/bin/cargo" ]; then
CARGO_CMD="/usr/bin/cargo"
echo "✓ Found cargo at /usr/bin/cargo"
# Method 5: Use whereis to find cargo
else
echo "Searching for cargo with whereis..."
CARGO_PATHS=$(whereis cargo 2>/dev/null | cut -d' ' -f2-)
echo "whereis found: $CARGO_PATHS"
for path in $CARGO_PATHS; do
if [ -f "$path" ] && [ -x "$path" ]; then
CARGO_CMD="$path"
echo "✓ Found executable cargo at $path"
break
fi
done
# Method 6: Last resort - try to find cargo anywhere
if [ -z "$CARGO_CMD" ]; then
echo "Searching for cargo with find..."
FOUND_CARGO=$(find /usr /root /home -name "cargo" -type f -executable 2>/dev/null | head -1)
if [ -n "$FOUND_CARGO" ] && [ -f "$FOUND_CARGO" ]; then
CARGO_CMD="$FOUND_CARGO"
echo "✓ Found cargo at $FOUND_CARGO"
fi
fi
fi
# Final verification
if [ -n "$CARGO_CMD" ]; then
echo "Using cargo command: $CARGO_CMD"
echo "Testing cargo command..."
if "$CARGO_CMD" --version &> /dev/null; then
echo "✓ Cargo is working: $($CARGO_CMD --version)"
else
echo "✗ Cargo command failed to execute"
CARGO_CMD=""
fi
fi
# If still no cargo found, try installation
if [ -z "$CARGO_CMD" ]; then
echo "Cargo not found anywhere. Installing Rust toolchain..."
# Install Rust using rustup
if ! command -v rustup &> /dev/null; then
echo "Installing rustup..."
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
# Source the cargo environment
if [ -f "$HOME/.cargo/env" ]; then
source "$HOME/.cargo/env"
fi
# Add to PATH
export PATH="$HOME/.cargo/bin:$PATH"
fi
# Verify installation
if command -v cargo &> /dev/null; then
CARGO_CMD="cargo"
echo "✓ Rust toolchain installed successfully"
elif [ -f "$HOME/.cargo/bin/cargo" ]; then
CARGO_CMD="$HOME/.cargo/bin/cargo"
export PATH="$HOME/.cargo/bin:$PATH"
echo "✓ Rust toolchain installed successfully"
else
echo "✗ Failed to install Rust toolchain"
echo "Please install Rust manually: https://rustup.rs/"
echo "Waiting 30 seconds before retrying..."
sleep 30
exit 1
fi
fi
# Check if we're in the right directory
if [ ! -f "Cargo.toml" ]; then
echo "Error: Cargo.toml not found. Are we in the right directory?"
pwd
exit 1
fi
echo "===== Setting up application environment ====="
# Generate SECRET_KEY if .env doesn't exist or doesn't have a valid key
if [ ! -f ".env" ] || ! grep -q "^SECRET_KEY=" .env || grep -q "your_secret_key_here" .env; then
echo "Generating SECRET_KEY for application..."
SECRET_KEY=$(openssl rand -base64 64 | tr -d '\n')
# Create .env from template if it doesn't exist
if [ ! -f ".env" ] && [ -f ".env.example" ]; then
cp .env.example .env
fi
# Update or add SECRET_KEY
if [ -f ".env" ]; then
if grep -q "^SECRET_KEY=" .env; then
sed -i "s/^SECRET_KEY=.*/SECRET_KEY=$SECRET_KEY/" .env
else
echo "SECRET_KEY=$SECRET_KEY" >> .env
fi
else
echo "SECRET_KEY=$SECRET_KEY" > .env
fi
echo "SECRET_KEY generated and saved to .env"
else
echo "Using existing SECRET_KEY from .env"
fi
echo "===== Starting application ====="
echo "Running Project Mycelium on port $PORT..."
echo "Working directory: $(pwd)"
echo "Branch: $(git branch --show-current)"
echo "Commit: $(git rev-parse --short HEAD)"
# Set environment variables
export RUST_LOG=info
# Run the application (following existing pattern)
git checkout "$BRANCH"
exec "$CARGO_CMD" run --release --bin projectmycelium -- --port "$PORT"