318 lines
11 KiB
Bash
318 lines
11 KiB
Bash
#!/bin/bash
|
||
|
||
# MY Network Simple Setup - без venv, прямо с системным Python
|
||
# Самый простой способ запуска
|
||
|
||
set -e
|
||
|
||
echo "🚀 MY Network Simple Setup"
|
||
echo "=========================="
|
||
echo "Пользователь: $(whoami)"
|
||
echo "Директория: $(pwd)"
|
||
echo ""
|
||
|
||
# Переход в my-uploader-bot
|
||
if [[ -d "my-uploader-bot" ]]; then
|
||
cd my-uploader-bot
|
||
echo "✅ Директория my-uploader-bot найдена"
|
||
else
|
||
echo "❌ Директория my-uploader-bot не найдена!"
|
||
echo "Содержимое текущей директории:"
|
||
ls -la
|
||
exit 1
|
||
fi
|
||
|
||
# Создание директорий
|
||
mkdir -p app/api
|
||
mkdir -p logs
|
||
|
||
# Проверка Python
|
||
echo "🐍 Проверка Python..."
|
||
python3 --version || { echo "❌ Python3 не найден"; exit 1; }
|
||
|
||
# Установка пакетов через pip --user
|
||
echo "📦 Установка Python пакетов (--user)..."
|
||
python3 -m pip install --user fastapi uvicorn requests python-dotenv
|
||
|
||
# Создание упрощенного MY Network приложения
|
||
echo "🏗️ Создание MY Network приложения..."
|
||
|
||
cat > app/main.py << 'EOF'
|
||
#!/usr/bin/env python3
|
||
"""MY Network Bootstrap Node - Simple Version"""
|
||
|
||
import os
|
||
import json
|
||
import sys
|
||
import logging
|
||
from datetime import datetime
|
||
from typing import Dict, Any
|
||
|
||
# Простой HTTP сервер без FastAPI
|
||
try:
|
||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||
from urllib.parse import urlparse, parse_qs
|
||
import socketserver
|
||
import threading
|
||
USE_SIMPLE_SERVER = True
|
||
except ImportError:
|
||
USE_SIMPLE_SERVER = True
|
||
|
||
# Настройка логирования
|
||
logging.basicConfig(
|
||
level=logging.INFO,
|
||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||
handlers=[
|
||
logging.FileHandler('logs/my-network.log'),
|
||
logging.StreamHandler()
|
||
]
|
||
)
|
||
logger = logging.getLogger("MY-Network")
|
||
|
||
NODE_ID = f"bootstrap-simple-{int(datetime.now().timestamp())}"
|
||
DOMAIN = "my-public-node-3.projscale.dev"
|
||
PORT = 15100
|
||
|
||
class MyNetworkHandler(BaseHTTPRequestHandler):
|
||
def do_GET(self):
|
||
parsed_path = urlparse(self.path)
|
||
path = parsed_path.path
|
||
|
||
# Маршруты
|
||
if path == '/':
|
||
self.send_json_response({"message": "MY Network Bootstrap Node v2.0 - Simple", "status": "active"})
|
||
elif path == '/api/my/health':
|
||
self.send_json_response({
|
||
"status": "healthy",
|
||
"node_id": NODE_ID,
|
||
"node_type": "bootstrap",
|
||
"domain": DOMAIN,
|
||
"port": PORT,
|
||
"mode": "simple",
|
||
"timestamp": datetime.utcnow().isoformat(),
|
||
"services": ["api", "monitor"],
|
||
"version": "2.0.0"
|
||
})
|
||
elif path == '/api/my/node/info':
|
||
self.send_json_response({
|
||
"node_id": NODE_ID,
|
||
"node_type": "bootstrap",
|
||
"domain": DOMAIN,
|
||
"port": PORT,
|
||
"ssl": False,
|
||
"public": True,
|
||
"region": "eu-central",
|
||
"capacity": "low",
|
||
"mode": "simple",
|
||
"services": ["api", "monitor"],
|
||
"protocol_version": "2.0",
|
||
"last_seen": datetime.utcnow().isoformat()
|
||
})
|
||
elif path == '/api/my/bootstrap/config':
|
||
config = {
|
||
"version": "2.0",
|
||
"network_id": "my-network-main",
|
||
"bootstrap_nodes": [
|
||
{
|
||
"id": NODE_ID,
|
||
"host": DOMAIN,
|
||
"port": PORT,
|
||
"ssl": False,
|
||
"public": True,
|
||
"region": "eu-central",
|
||
"capacity": "low",
|
||
"mode": "simple",
|
||
"services": ["api", "monitor"],
|
||
"last_seen": datetime.utcnow().isoformat()
|
||
}
|
||
],
|
||
"network_config": {
|
||
"protocol_version": "2.0",
|
||
"max_peers": 10,
|
||
"sync_interval": 300
|
||
},
|
||
"api_endpoints": {
|
||
"base_url": f"http://{DOMAIN}:{PORT}",
|
||
"health": "/api/my/health",
|
||
"node_info": "/api/my/node/info",
|
||
"bootstrap": "/api/my/bootstrap/config"
|
||
}
|
||
}
|
||
self.send_json_response(config)
|
||
elif path == '/api/my/monitor/' or path == '/api/my/monitor':
|
||
self.send_html_response(self.get_monitor_html())
|
||
else:
|
||
self.send_response(404)
|
||
self.end_headers()
|
||
self.wfile.write(b'Not Found')
|
||
|
||
def send_json_response(self, data: Dict[Any, Any]):
|
||
self.send_response(200)
|
||
self.send_header('Content-type', 'application/json')
|
||
self.send_header('Access-Control-Allow-Origin', '*')
|
||
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
|
||
self.send_header('Access-Control-Allow-Headers', 'Content-Type, Authorization')
|
||
self.send_header('X-MY-Network-Version', '2.0')
|
||
self.end_headers()
|
||
json_data = json.dumps(data, indent=2)
|
||
self.wfile.write(json_data.encode('utf-8'))
|
||
|
||
def send_html_response(self, html: str):
|
||
self.send_response(200)
|
||
self.send_header('Content-type', 'text/html; charset=utf-8')
|
||
self.send_header('Access-Control-Allow-Origin', '*')
|
||
self.send_header('X-MY-Network-Version', '2.0')
|
||
self.end_headers()
|
||
self.wfile.write(html.encode('utf-8'))
|
||
|
||
def get_monitor_html(self) -> str:
|
||
return f"""
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<title>MY Network Bootstrap Monitor - Simple</title>
|
||
<meta charset="utf-8">
|
||
<style>
|
||
body {{ font-family: 'Courier New', monospace; background: #000; color: #0f0; padding: 20px; }}
|
||
h1 {{ color: #ff0; text-align: center; }}
|
||
.box {{ border: 1px solid #0f0; padding: 15px; margin: 10px 0; }}
|
||
.status {{ color: #0f0; }}
|
||
.info {{ color: #00f; }}
|
||
.warning {{ color: #f80; }}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<h1>🚀 MY Network Bootstrap Node Monitor</h1>
|
||
<div class="box">
|
||
<h3 class="status">Node Status: ACTIVE (Simple Mode)</h3>
|
||
<p class="info">Node ID: {NODE_ID}</p>
|
||
<p class="info">Domain: {DOMAIN}</p>
|
||
<p class="info">Port: {PORT}</p>
|
||
<p class="info">Type: Bootstrap Primary</p>
|
||
<p class="info">Version: 2.0.0</p>
|
||
<p class="info">Mode: Simple HTTP Server</p>
|
||
<p class="info">Services: API, Monitor</p>
|
||
<p class="info">Last Update: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
|
||
</div>
|
||
<div class="box">
|
||
<h3 class="status">Network Configuration</h3>
|
||
<p class="info">Protocol Version: 2.0</p>
|
||
<p class="info">Max Peers: 10</p>
|
||
<p class="info">Public Access: Enabled</p>
|
||
<p class="warning">SSL: Disabled (Simple Mode)</p>
|
||
</div>
|
||
<div class="box">
|
||
<h3 class="warning">⚠️ Simple Mode</h3>
|
||
<p class="warning">Сервис запущен в упрощенном режиме</p>
|
||
<p class="warning">Использует встроенный HTTP сервер Python</p>
|
||
<p class="info">Доступ: http://{DOMAIN}:{PORT}</p>
|
||
</div>
|
||
<script>
|
||
setTimeout(() => location.reload(), 30000);
|
||
</script>
|
||
</body>
|
||
</html>
|
||
"""
|
||
|
||
def log_message(self, format, *args):
|
||
logger.info(f"{self.address_string()} - {format % args}")
|
||
|
||
def start_server():
|
||
logger.info(f"🚀 Starting MY Network Bootstrap Node - Simple Mode")
|
||
logger.info(f"Domain: {DOMAIN}")
|
||
logger.info(f"Port: {PORT}")
|
||
logger.info(f"Node ID: {NODE_ID}")
|
||
logger.info(f"Mode: Simple HTTP Server")
|
||
logger.info(f"Access: http://{DOMAIN}:{PORT}")
|
||
|
||
try:
|
||
with HTTPServer(("0.0.0.0", PORT), MyNetworkHandler) as httpd:
|
||
logger.info(f"✅ Server started on http://0.0.0.0:{PORT}")
|
||
httpd.serve_forever()
|
||
except Exception as e:
|
||
logger.error(f"❌ Server error: {e}")
|
||
raise
|
||
|
||
if __name__ == "__main__":
|
||
start_server()
|
||
EOF
|
||
|
||
# Создание скрипта запуска
|
||
cat > start_my_network.sh << 'EOF'
|
||
#!/bin/bash
|
||
|
||
cd /home/service/my-uploader-bot
|
||
|
||
echo "🚀 Запуск MY Network Bootstrap Node (Simple Mode)"
|
||
echo "==============================================="
|
||
echo ""
|
||
|
||
# Создание директории для логов
|
||
mkdir -p logs
|
||
|
||
# Запуск приложения
|
||
python3 app/main.py
|
||
EOF
|
||
|
||
chmod +x start_my_network.sh
|
||
|
||
# Создание скрипта для фонового запуска
|
||
cat > run_my_network.sh << 'EOF'
|
||
#!/bin/bash
|
||
|
||
# Проверка, запущен ли MY Network
|
||
if ! pgrep -f "python3 app/main.py" > /dev/null; then
|
||
echo "$(date): Запуск MY Network" >> /home/service/my-uploader-bot/logs/cron.log
|
||
cd /home/service/my-uploader-bot
|
||
nohup python3 app/main.py >> logs/app.log 2>&1 &
|
||
echo "$(date): MY Network запущен (PID: $!)" >> /home/service/my-uploader-bot/logs/cron.log
|
||
else
|
||
echo "$(date): MY Network уже запущен" >> /home/service/my-uploader-bot/logs/cron.log
|
||
fi
|
||
EOF
|
||
|
||
chmod +x run_my_network.sh
|
||
|
||
# Создание скрипта остановки
|
||
cat > stop_my_network.sh << 'EOF'
|
||
#!/bin/bash
|
||
|
||
echo "🛑 Остановка MY Network..."
|
||
if pgrep -f "python3 app/main.py" > /dev/null; then
|
||
pkill -f "python3 app/main.py"
|
||
echo "✅ MY Network остановлен"
|
||
echo "$(date): MY Network остановлен" >> /home/service/my-uploader-bot/logs/cron.log
|
||
else
|
||
echo "⚠️ MY Network не запущен"
|
||
fi
|
||
EOF
|
||
|
||
chmod +x stop_my_network.sh
|
||
|
||
# Добавление в crontab
|
||
echo "📅 Добавление в crontab..."
|
||
(crontab -l 2>/dev/null | grep -v "run_my_network.sh"; echo "*/5 * * * * /home/service/my-uploader-bot/run_my_network.sh") | crontab -
|
||
|
||
echo ""
|
||
echo "✅ MY Network Bootstrap Node установлен!"
|
||
echo "======================================="
|
||
echo ""
|
||
echo "🚀 Запуск:"
|
||
echo " cd /home/service/my-uploader-bot"
|
||
echo " ./start_my_network.sh # В терминале"
|
||
echo " ./run_my_network.sh # В фоне"
|
||
echo " ./stop_my_network.sh # Остановка"
|
||
echo ""
|
||
echo "🌐 Доступ:"
|
||
echo " http://my-public-node-3.projscale.dev:15100"
|
||
echo " http://my-public-node-3.projscale.dev:15100/api/my/health"
|
||
echo " http://my-public-node-3.projscale.dev:15100/api/my/monitor/"
|
||
echo ""
|
||
echo "📝 Логи:"
|
||
echo " tail -f logs/my-network.log"
|
||
echo " tail -f logs/app.log"
|
||
echo " tail -f logs/cron.log"
|
||
echo ""
|
||
echo "⚡ Автозапуск настроен через cron (каждые 5 минут)"
|
||
echo ""
|
||
echo "🎯 MY Network Bootstrap Node готов к работе!" |