almosther isolating soleprint
This commit is contained in:
157
mainroom/soleprint/ctrl/README.md
Normal file
157
mainroom/soleprint/ctrl/README.md
Normal file
@@ -0,0 +1,157 @@
|
||||
# Pawprint Control Scripts
|
||||
|
||||
Control scripts for managing pawprint services via systemd (alternative to Docker deployment).
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
ctrl/
|
||||
├── .env.pawprint # Shared configuration
|
||||
├── local/ # Scripts run from developer machine
|
||||
│ ├── commit.sh # Commit changes across all repos
|
||||
│ ├── deploy.sh # Full deployment workflow
|
||||
│ ├── init.sh # Initial sync to server
|
||||
│ ├── push.sh # Deploy to server (all by default)
|
||||
│ └── status.sh # Git status of all repos
|
||||
└── server/ # Scripts run on server
|
||||
├── install-deps.sh # Install Python deps (all by default)
|
||||
├── restart.sh # Restart services (all by default)
|
||||
├── setup-cert.sh # Setup SSL certificate
|
||||
├── setup-nginx.sh # Create nginx config
|
||||
└── setup-service.sh # Create systemd service
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Edit `.env.pawprint` to configure:
|
||||
|
||||
```bash
|
||||
# Deployment
|
||||
DEPLOY_SERVER=mariano@mcrn.ar
|
||||
DEPLOY_REMOTE_PATH=~/pawprint
|
||||
|
||||
# Local paths
|
||||
PAWPRINT_BARE_PATH=/home/mariano/pawprint
|
||||
|
||||
# Server paths
|
||||
SERVER_USER=mariano
|
||||
SERVER_PAWPRINT_PATH=/home/mariano/pawprint
|
||||
SERVER_VENV_BASE=/home/mariano/venvs
|
||||
```
|
||||
|
||||
## Design Principle
|
||||
|
||||
**All services are the default.** No flags needed for common operations.
|
||||
|
||||
```bash
|
||||
./push.sh # Deploys all (default)
|
||||
./push.sh artery # Deploy only artery (when needed)
|
||||
```
|
||||
|
||||
See `DESIGN_PAWPRINT.md` for detailed philosophy.
|
||||
|
||||
## Local Scripts
|
||||
|
||||
### commit.sh
|
||||
```bash
|
||||
./local/commit.sh "Your commit message"
|
||||
```
|
||||
|
||||
### status.sh
|
||||
```bash
|
||||
./local/status.sh
|
||||
```
|
||||
|
||||
### push.sh
|
||||
```bash
|
||||
./local/push.sh # Push all services (default)
|
||||
./local/push.sh artery # Push only artery
|
||||
```
|
||||
|
||||
### deploy.sh
|
||||
```bash
|
||||
./local/deploy.sh
|
||||
# Then restart on server:
|
||||
# ssh mariano@mcrn.ar 'bash ~/pawprint/ctrl/server/restart.sh'
|
||||
```
|
||||
|
||||
### init.sh
|
||||
```bash
|
||||
./local/init.sh # Initial full sync (run once)
|
||||
```
|
||||
|
||||
## Server Scripts
|
||||
|
||||
### restart.sh
|
||||
```bash
|
||||
sudo ./server/restart.sh # Restart all (default)
|
||||
sudo ./server/restart.sh artery # Restart only artery
|
||||
```
|
||||
|
||||
### install-deps.sh
|
||||
```bash
|
||||
./server/install-deps.sh # Install all (default)
|
||||
./server/install-deps.sh artery # Install only artery
|
||||
```
|
||||
|
||||
### setup-service.sh
|
||||
```bash
|
||||
sudo ./server/setup-service.sh pawprint 12000 main:app
|
||||
sudo ./server/setup-service.sh artery 12001 main:app
|
||||
```
|
||||
|
||||
### setup-nginx.sh
|
||||
```bash
|
||||
sudo ./server/setup-nginx.sh artery artery.mcrn.ar 12001
|
||||
```
|
||||
|
||||
### setup-cert.sh
|
||||
```bash
|
||||
sudo ./server/setup-cert.sh artery.mcrn.ar
|
||||
```
|
||||
|
||||
## Deployment Workflow
|
||||
|
||||
### Initial Setup (once)
|
||||
|
||||
Local:
|
||||
```bash
|
||||
cd ctrl/local
|
||||
./init.sh
|
||||
```
|
||||
|
||||
Server:
|
||||
```bash
|
||||
cd ~/pawprint/ctrl/server
|
||||
./install-deps.sh
|
||||
sudo ./setup-service.sh pawprint 12000 main:app
|
||||
sudo ./setup-service.sh artery 12001 main:app
|
||||
sudo ./setup-service.sh album 12002 main:app
|
||||
sudo ./setup-service.sh ward 12003 main:app
|
||||
sudo ./setup-nginx.sh pawprint pawprint.mcrn.ar 12000
|
||||
sudo ./setup-nginx.sh artery artery.mcrn.ar 12001
|
||||
sudo ./setup-nginx.sh album album.mcrn.ar 12002
|
||||
sudo ./setup-nginx.sh ward ward.mcrn.ar 12003
|
||||
```
|
||||
|
||||
### Regular Updates
|
||||
|
||||
Local:
|
||||
```bash
|
||||
cd ctrl/local
|
||||
./commit.sh "Update feature X"
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
Server:
|
||||
```bash
|
||||
sudo ~/pawprint/ctrl/server/restart.sh
|
||||
```
|
||||
|
||||
## Nest vs Pawprint Control
|
||||
|
||||
- **core_nest/ctrl/** - Manages full nest (amar + pawprint) via Docker
|
||||
- **pawprint/ctrl/** - Manages pawprint services via systemd
|
||||
|
||||
This directory provides systemd-based deployment as an alternative to Docker.
|
||||
For full nest orchestration with Docker, use `core_nest/ctrl/`.
|
||||
34
mainroom/soleprint/ctrl/local/commit.sh
Executable file
34
mainroom/soleprint/ctrl/local/commit.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
# Commit changes across all repos with the same message
|
||||
# Usage: ./commit.sh "commit message"
|
||||
|
||||
set -e
|
||||
|
||||
MSG="${1:?Usage: $0 \"commit message\"}"
|
||||
|
||||
# Find pawprint bare metal directory from PAWPRINT_BARE_PATH or default
|
||||
PAWPRINT_DIR="${PAWPRINT_BARE_PATH:-/home/mariano/pawprint}"
|
||||
REPOS=("$PAWPRINT_DIR" "$PAWPRINT_DIR/artery" "$PAWPRINT_DIR/album" "$PAWPRINT_DIR/ward")
|
||||
|
||||
for repo in "${REPOS[@]}"; do
|
||||
name=$(basename "$repo")
|
||||
[ "$repo" = "$PAWPRINT_DIR" ] && name="pawprint"
|
||||
|
||||
if [ ! -d "$repo/.git" ]; then
|
||||
echo "=== $name: not a git repo, skipping ==="
|
||||
continue
|
||||
fi
|
||||
|
||||
cd "$repo"
|
||||
|
||||
if git diff --quiet && git diff --cached --quiet && [ -z "$(git ls-files --others --exclude-standard)" ]; then
|
||||
echo "=== $name: nothing to commit ==="
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "=== $name ==="
|
||||
git add -A
|
||||
git commit -m "$MSG"
|
||||
done
|
||||
|
||||
echo "Done!"
|
||||
24
mainroom/soleprint/ctrl/local/deploy.sh
Executable file
24
mainroom/soleprint/ctrl/local/deploy.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
# Push all to server (run locally)
|
||||
# Usage: ./deploy.sh
|
||||
# Then run restart on server as admin
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
CTRL_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
|
||||
# Load configuration
|
||||
source "$CTRL_DIR/.env.soleprint" 2>/dev/null || true
|
||||
REMOTE="${DEPLOY_SERVER:-mariano@mcrn.ar}"
|
||||
|
||||
echo "=== Pushing all ==="
|
||||
"$SCRIPT_DIR/push.sh"
|
||||
|
||||
echo ""
|
||||
echo "=== Push complete ==="
|
||||
echo "Now restart services on server:"
|
||||
echo " ssh $REMOTE 'sudo systemctl restart soleprint artery atlas station'"
|
||||
echo ""
|
||||
echo "# Or restart specific service:"
|
||||
echo "# ssh $REMOTE 'sudo systemctl restart artery'"
|
||||
28
mainroom/soleprint/ctrl/local/init.sh
Executable file
28
mainroom/soleprint/ctrl/local/init.sh
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
# Initial full sync of pawprint to server
|
||||
# Run once to setup, then use push.sh for updates
|
||||
|
||||
set -e
|
||||
|
||||
# Load configuration
|
||||
CTRL_DIR="$(cd "$(dirname "$0")/../.." SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" pwd)"
|
||||
source "$CTRL_DIR/.env.pawprint" 2>/dev/null || true
|
||||
|
||||
PAWPRINT_DIR="${PAWPRINT_BARE_PATH:-/home/mariano/pawprint}"
|
||||
REMOTE="${DEPLOY_SERVER:-mariano@mcrn.ar}"
|
||||
REMOTE_DIR="${DEPLOY_REMOTE_PATH:-~/pawprint}"
|
||||
|
||||
echo "=== Initial sync of pawprint ==="
|
||||
echo "From: $PAWPRINT_DIR"
|
||||
echo "To: $REMOTE:$REMOTE_DIR"
|
||||
|
||||
rsync -avz \
|
||||
--filter=':- .gitignore' \
|
||||
--exclude '.git' \
|
||||
--exclude '.env' \
|
||||
"$PAWPRINT_DIR/" "$REMOTE:$REMOTE_DIR/"
|
||||
|
||||
echo ""
|
||||
echo "Done! Now on server run:"
|
||||
echo " cd ~/pawprint"
|
||||
echo " # Use core_nest/pawprint/tools/server/setup-*.sh scripts for initial setup"
|
||||
66
mainroom/soleprint/ctrl/local/push.sh
Executable file
66
mainroom/soleprint/ctrl/local/push.sh
Executable file
@@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
# Deploy repos via rsync
|
||||
# Usage: ./push.sh [target]
|
||||
# Example: ./push.sh (deploys all: soleprint, artery, atlas, station)
|
||||
# ./push.sh artery (deploys only artery)
|
||||
# ./push.sh soleprint (deploys only soleprint root, no sub-repos)
|
||||
|
||||
set -e
|
||||
|
||||
TARGET="${1:-all}"
|
||||
|
||||
# Load configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
CTRL_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
source "$CTRL_DIR/.env.soleprint" 2>/dev/null || true
|
||||
|
||||
SOLEPRINT_DIR="${SOLEPRINT_BARE_PATH:-/home/mariano/wdir/spr/gen}"
|
||||
REMOTE="${DEPLOY_SERVER:-mariano@mcrn.ar}"
|
||||
REMOTE_BASE="${DEPLOY_REMOTE_PATH:-~/soleprint}"
|
||||
|
||||
# Handle all (default)
|
||||
if [ "$TARGET" = "all" ]; then
|
||||
echo "=== Deploying all services ==="
|
||||
for target in soleprint artery atlas station; do
|
||||
"$0" "$target"
|
||||
echo ""
|
||||
done
|
||||
echo "=== All done ==="
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$TARGET" = "soleprint" ]; then
|
||||
# Push only root files (no sub-repos)
|
||||
echo "=== Deploying soleprint (root only) ==="
|
||||
rsync -avz \
|
||||
--filter=':- .gitignore' \
|
||||
--exclude '.git' \
|
||||
--exclude '.env' \
|
||||
--exclude '.venv' \
|
||||
--exclude 'artery/' \
|
||||
--exclude 'atlas/' \
|
||||
--exclude 'station/' \
|
||||
"$SOLEPRINT_DIR/" "$REMOTE:$REMOTE_BASE/"
|
||||
echo "Done!"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
LOCAL_DIR="$SOLEPRINT_DIR/$TARGET"
|
||||
REMOTE_DIR="$REMOTE_BASE/$TARGET"
|
||||
|
||||
if [ ! -d "$LOCAL_DIR" ]; then
|
||||
echo "Error: $LOCAL_DIR does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Deploying $TARGET ==="
|
||||
echo "From: $LOCAL_DIR"
|
||||
echo "To: $REMOTE:$REMOTE_DIR"
|
||||
|
||||
rsync -avz \
|
||||
--filter=':- .gitignore' \
|
||||
--exclude '.git' \
|
||||
--exclude '.env' \
|
||||
"$LOCAL_DIR/" "$REMOTE:$REMOTE_DIR/"
|
||||
|
||||
echo "Done!"
|
||||
33
mainroom/soleprint/ctrl/local/status.sh
Executable file
33
mainroom/soleprint/ctrl/local/status.sh
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
# Show git status of all repos
|
||||
# Usage: ./status.sh
|
||||
|
||||
# Find pawprint bare metal directory from PAWPRINT_BARE_PATH or default
|
||||
PAWPRINT_DIR="${PAWPRINT_BARE_PATH:-/home/mariano/pawprint}"
|
||||
REPOS=("$PAWPRINT_DIR" "$PAWPRINT_DIR/artery" "$PAWPRINT_DIR/album" "$PAWPRINT_DIR/ward")
|
||||
|
||||
for repo in "${REPOS[@]}"; do
|
||||
name=$(basename "$repo")
|
||||
[ "$repo" = "$PAWPRINT_DIR" ] && name="pawprint"
|
||||
|
||||
if [ ! -d "$repo/.git" ]; then
|
||||
echo "=== $name: not a git repo ==="
|
||||
continue
|
||||
fi
|
||||
|
||||
cd "$repo"
|
||||
branch=$(git branch --show-current)
|
||||
|
||||
# Check for changes
|
||||
staged=$(git diff --cached --numstat | wc -l)
|
||||
unstaged=$(git diff --numstat | wc -l)
|
||||
untracked=$(git ls-files --others --exclude-standard | wc -l)
|
||||
|
||||
if [ "$staged" -eq 0 ] && [ "$unstaged" -eq 0 ] && [ "$untracked" -eq 0 ]; then
|
||||
echo "=== $name ($branch): clean ==="
|
||||
else
|
||||
echo "=== $name ($branch): +$staged staged, ~$unstaged modified, ?$untracked untracked ==="
|
||||
git status --short
|
||||
fi
|
||||
echo
|
||||
done
|
||||
55
mainroom/soleprint/ctrl/server/install-deps.sh
Executable file
55
mainroom/soleprint/ctrl/server/install-deps.sh
Executable file
@@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
# Install/update dependencies for apps
|
||||
# Usage: ./install-deps.sh [app-name]
|
||||
# Example: ./install-deps.sh (installs deps for all services)
|
||||
# ./install-deps.sh artery (installs deps for artery only)
|
||||
|
||||
set -e
|
||||
|
||||
APP_NAME="${1:-all}"
|
||||
|
||||
# Load configuration
|
||||
CTRL_DIR="$(cd "$(dirname "$0")/../.." SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" pwd)"
|
||||
source "$CTRL_DIR/.env.pawprint" 2>/dev/null || true
|
||||
|
||||
APP_USER="${SERVER_USER:-mariano}"
|
||||
PAWPRINT_PATH="${SERVER_PAWPRINT_PATH:-/home/mariano/pawprint}"
|
||||
VENV_BASE="${SERVER_VENV_BASE:-/home/mariano/venvs}"
|
||||
|
||||
# Handle all (default)
|
||||
if [ "$APP_NAME" = "all" ]; then
|
||||
echo "=== Installing deps for all services ==="
|
||||
for app in pawprint artery album ward; do
|
||||
echo ""
|
||||
echo "--- $app ---"
|
||||
"$0" "$app"
|
||||
done
|
||||
echo ""
|
||||
echo "=== All done ==="
|
||||
exit 0
|
||||
fi
|
||||
|
||||
VENV_DIR="$VENV_BASE/$APP_NAME"
|
||||
|
||||
if [ "$APP_NAME" = "pawprint" ]; then
|
||||
REQ_FILE="$PAWPRINT_PATH/requirements.txt"
|
||||
else
|
||||
REQ_FILE="$PAWPRINT_PATH/$APP_NAME/requirements.txt"
|
||||
fi
|
||||
|
||||
if [ ! -f "$REQ_FILE" ]; then
|
||||
echo "Error: $REQ_FILE not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$VENV_DIR" ]; then
|
||||
echo "Creating venv: $VENV_DIR"
|
||||
python3 -m venv "$VENV_DIR"
|
||||
fi
|
||||
|
||||
echo "Installing deps from $REQ_FILE"
|
||||
source "$VENV_DIR/bin/activate"
|
||||
pip install -r "$REQ_FILE"
|
||||
deactivate
|
||||
|
||||
echo "Done!"
|
||||
24
mainroom/soleprint/ctrl/server/restart.sh
Executable file
24
mainroom/soleprint/ctrl/server/restart.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
# Restart pawprint services
|
||||
# Usage: ./restart.sh [service]
|
||||
# Example: ./restart.sh (restarts all services)
|
||||
# ./restart.sh artery (restarts only artery)
|
||||
|
||||
set -e
|
||||
|
||||
TARGET="${1:-all}"
|
||||
|
||||
# Handle all (default)
|
||||
if [ "$TARGET" = "all" ]; then
|
||||
echo "Restarting all services..."
|
||||
systemctl restart pawprint artery album ward
|
||||
echo "Status:"
|
||||
systemctl status pawprint artery album ward --no-pager | grep -E "●|Active:"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Restarting $TARGET..."
|
||||
systemctl restart "$TARGET"
|
||||
|
||||
echo "Status:"
|
||||
systemctl status "$TARGET" --no-pager | grep -E "●|Active:"
|
||||
24
mainroom/soleprint/ctrl/server/setup-cert.sh
Executable file
24
mainroom/soleprint/ctrl/server/setup-cert.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
# Install/update SSL certificate for a subdomain
|
||||
# Usage: ./setup-cert.sh <subdomain>
|
||||
# Example: ./setup-cert.sh pawprint.mcrn.ar
|
||||
|
||||
set -e
|
||||
|
||||
SUBDOMAIN="${1:?Usage: $0 <subdomain>}"
|
||||
|
||||
echo "=== Setting up SSL cert for $SUBDOMAIN ==="
|
||||
|
||||
# Check if certbot is installed
|
||||
if ! command -v certbot &> /dev/null; then
|
||||
echo "Installing certbot..."
|
||||
apt update
|
||||
apt install -y certbot python3-certbot-nginx
|
||||
fi
|
||||
|
||||
# Get/renew certificate
|
||||
certbot --nginx -d "$SUBDOMAIN" --non-interactive --agree-tos --register-unsafely-without-email
|
||||
|
||||
echo ""
|
||||
echo "Done! Certificate installed for $SUBDOMAIN"
|
||||
echo "Auto-renewal is enabled via systemd timer"
|
||||
54
mainroom/soleprint/ctrl/server/setup-nginx.sh
Executable file
54
mainroom/soleprint/ctrl/server/setup-nginx.sh
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/bash
|
||||
# Creates nginx config for FastAPI app
|
||||
# Usage: ./setup-nginx.sh <app-name> <subdomain> <port>
|
||||
# Example: ./setup-nginx.sh artery artery.mcrn.ar 12001
|
||||
|
||||
set -e
|
||||
|
||||
APP_NAME="${1:?Usage: $0 <app-name> <subdomain> <port>}"
|
||||
SUBDOMAIN="${2:?Usage: $0 <app-name> <subdomain> <port>}"
|
||||
PORT="${3:?Usage: $0 <app-name> <subdomain> <port>}"
|
||||
|
||||
NGINX_CONF="/etc/nginx/sites-available/$APP_NAME"
|
||||
|
||||
echo "Creating nginx config: $NGINX_CONF"
|
||||
|
||||
sudo tee "$NGINX_CONF" > /dev/null << EOF
|
||||
server {
|
||||
listen 80;
|
||||
server_name $SUBDOMAIN;
|
||||
return 301 https://\$host\$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name $SUBDOMAIN;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/mcrn.ar/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/mcrn.ar/privkey.pem;
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:$PORT;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
proxy_read_timeout 300;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "Enabling site..."
|
||||
sudo ln -sf "$NGINX_CONF" /etc/nginx/sites-enabled/
|
||||
|
||||
echo "Testing nginx config..."
|
||||
sudo nginx -t
|
||||
|
||||
echo "Reloading nginx..."
|
||||
sudo systemctl reload nginx
|
||||
|
||||
echo ""
|
||||
echo "Done! Site available at https://$SUBDOMAIN"
|
||||
echo "Note: Make sure DNS points $SUBDOMAIN to this server"
|
||||
54
mainroom/soleprint/ctrl/server/setup-service.sh
Executable file
54
mainroom/soleprint/ctrl/server/setup-service.sh
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/bash
|
||||
# Creates systemd service for FastAPI app
|
||||
# Usage: ./setup-service.sh <app-name> <port> <app-module>
|
||||
# Example: ./setup-service.sh artery 12001 main:app
|
||||
|
||||
set -e
|
||||
|
||||
APP_NAME="${1:?Usage: $0 <app-name> <port> <app-module>}"
|
||||
PORT="${2:?Usage: $0 <app-name> <port> <app-module>}"
|
||||
APP_MODULE="${3:-main:app}"
|
||||
|
||||
APP_USER="mariano"
|
||||
VENV_DIR="/home/$APP_USER/venvs/$APP_NAME"
|
||||
|
||||
# pawprint root is special case
|
||||
if [ "$APP_NAME" = "pawprint" ]; then
|
||||
WORK_DIR="/home/$APP_USER/pawprint"
|
||||
else
|
||||
WORK_DIR="/home/$APP_USER/pawprint/$APP_NAME"
|
||||
fi
|
||||
SERVICE_FILE="/etc/systemd/system/${APP_NAME}.service"
|
||||
|
||||
echo "Creating systemd service: $SERVICE_FILE"
|
||||
|
||||
sudo tee "$SERVICE_FILE" > /dev/null << EOF
|
||||
[Unit]
|
||||
Description=$APP_NAME FastAPI service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=$APP_USER
|
||||
Group=$APP_USER
|
||||
WorkingDirectory=$WORK_DIR
|
||||
Environment="PATH=$VENV_DIR/bin"
|
||||
EnvironmentFile=$PAWPRINT_PATH/.env
|
||||
ExecStart=$VENV_DIR/bin/uvicorn $APP_MODULE --host 127.0.0.1 --port $PORT
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
echo "Reloading systemd..."
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
echo "Enabling service..."
|
||||
sudo systemctl enable "$APP_NAME"
|
||||
|
||||
echo ""
|
||||
echo "Done! Service commands:"
|
||||
echo " sudo systemctl start $APP_NAME"
|
||||
echo " sudo systemctl status $APP_NAME"
|
||||
echo " sudo journalctl -u $APP_NAME -f"
|
||||
82
mainroom/soleprint/ctrl/sync-tests.sh
Executable file
82
mainroom/soleprint/ctrl/sync-tests.sh
Executable file
@@ -0,0 +1,82 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Sync contract tests from amar_django_back_contracts to ward/tools/tester
|
||||
#
|
||||
# Usage: ./sync-tests.sh
|
||||
|
||||
set -e
|
||||
|
||||
# Paths
|
||||
SOURCE_REPO="/home/mariano/wdir/ama/amar_django_back_contracts"
|
||||
DEST_DIR="/home/mariano/wdir/ama/pawprint/ward/tools/tester/tests"
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}=== Syncing Contract Tests ===${NC}"
|
||||
echo "Source: $SOURCE_REPO/tests/contracts"
|
||||
echo "Dest: $DEST_DIR"
|
||||
echo
|
||||
|
||||
# Check source exists
|
||||
if [ ! -d "$SOURCE_REPO/tests/contracts" ]; then
|
||||
echo "Error: Source directory not found: $SOURCE_REPO/tests/contracts"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create destination if it doesn't exist
|
||||
mkdir -p "$DEST_DIR"
|
||||
|
||||
# Sync test files (preserve structure)
|
||||
echo -e "${BLUE}Copying test files...${NC}"
|
||||
|
||||
# Copy the contract test structure
|
||||
rsync -av --delete \
|
||||
--include="*/" \
|
||||
--include="test_*.py" \
|
||||
--include="__init__.py" \
|
||||
--include="base*.py" \
|
||||
--include="conftest.py" \
|
||||
--include="endpoints.py" \
|
||||
--include="helpers.py" \
|
||||
--exclude="*" \
|
||||
"$SOURCE_REPO/tests/contracts/" \
|
||||
"$DEST_DIR/"
|
||||
|
||||
# Remove base_api.py and base_live.py (we only need pure HTTP base.py)
|
||||
rm -f "$DEST_DIR/base_api.py" "$DEST_DIR/base_live.py"
|
||||
|
||||
# Create a simple base.py that uses tester's base class
|
||||
cat > "$DEST_DIR/base.py" << 'EOF'
|
||||
"""
|
||||
Contract Tests - Base Class
|
||||
|
||||
Uses tester's HTTP base class for framework-agnostic testing.
|
||||
"""
|
||||
|
||||
# Import from tester's base
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add tester to path if needed
|
||||
tester_path = Path(__file__).parent.parent
|
||||
if str(tester_path) not in sys.path:
|
||||
sys.path.insert(0, str(tester_path))
|
||||
|
||||
from base import ContractTestCase
|
||||
|
||||
__all__ = ["ContractTestCase"]
|
||||
EOF
|
||||
|
||||
echo
|
||||
echo -e "${GREEN}✓ Tests synced successfully${NC}"
|
||||
echo
|
||||
echo "Test structure:"
|
||||
find "$DEST_DIR" -name "test_*.py" -type f | sed 's|'"$DEST_DIR"'||' | sort
|
||||
|
||||
echo
|
||||
echo -e "${BLUE}Next steps:${NC}"
|
||||
echo "1. Run tester locally: cd /home/mariano/wdir/ama/pawprint/ward && python -m tools.tester"
|
||||
echo "2. Deploy to server: cd /home/mariano/wdir/ama/pawprint/deploy && ./deploy.sh"
|
||||
Reference in New Issue
Block a user