430 lines
17 KiB
Bash
430 lines
17 KiB
Bash
#!/bin/bash
|
||
|
||
# MY Network Minimal Setup - только встроенные модули Python
|
||
# Без pip, без внешних зависимостей
|
||
|
||
set -e
|
||
|
||
echo "🚀 MY Network Minimal 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; }
|
||
|
||
# Создание минимального MY Network приложения
|
||
echo "🏗️ Создание MY Network приложения (только встроенные модули)..."
|
||
|
||
cat > app/main.py << 'EOF'
|
||
#!/usr/bin/env python3
|
||
"""MY Network Bootstrap Node - Minimal Version (только встроенные модули)"""
|
||
|
||
import os
|
||
import json
|
||
import sys
|
||
import logging
|
||
import time
|
||
from datetime import datetime
|
||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||
from urllib.parse import urlparse
|
||
import threading
|
||
|
||
# Настройка логирования
|
||
logging.basicConfig(
|
||
level=logging.INFO,
|
||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||
handlers=[
|
||
logging.FileHandler('logs/my-network.log', encoding='utf-8'),
|
||
logging.StreamHandler()
|
||
]
|
||
)
|
||
logger = logging.getLogger("MY-Network")
|
||
|
||
NODE_ID = f"bootstrap-minimal-{int(datetime.now().timestamp())}"
|
||
DOMAIN = "my-public-node-3.projscale.dev"
|
||
PORT = 15100
|
||
|
||
class MyNetworkHandler(BaseHTTPRequestHandler):
|
||
def do_GET(self):
|
||
try:
|
||
parsed_path = urlparse(self.path)
|
||
path = parsed_path.path
|
||
|
||
# Маршруты
|
||
if path == '/':
|
||
self.send_json_response({"message": "MY Network Bootstrap Node v2.0 - Minimal", "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": "minimal",
|
||
"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": "minimal",
|
||
"mode": "minimal",
|
||
"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": "minimal",
|
||
"mode": "minimal",
|
||
"services": ["api", "monitor"],
|
||
"last_seen": datetime.utcnow().isoformat()
|
||
}
|
||
],
|
||
"network_config": {
|
||
"protocol_version": "2.0",
|
||
"max_peers": 5,
|
||
"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.send_header('Content-type', 'application/json')
|
||
self.end_headers()
|
||
error_response = {"error": "Not Found", "path": path}
|
||
self.wfile.write(json.dumps(error_response).encode('utf-8'))
|
||
except Exception as e:
|
||
logger.error(f"Error handling request: {e}")
|
||
self.send_response(500)
|
||
self.end_headers()
|
||
self.wfile.write(b'Internal Server Error')
|
||
|
||
def send_json_response(self, data):
|
||
try:
|
||
self.send_response(200)
|
||
self.send_header('Content-type', 'application/json; charset=utf-8')
|
||
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.send_header('Server', 'MY-Network-Bootstrap/2.0')
|
||
self.end_headers()
|
||
json_data = json.dumps(data, indent=2, ensure_ascii=False)
|
||
self.wfile.write(json_data.encode('utf-8'))
|
||
except Exception as e:
|
||
logger.error(f"Error sending JSON response: {e}")
|
||
|
||
def send_html_response(self, html):
|
||
try:
|
||
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.send_header('Server', 'MY-Network-Bootstrap/2.0')
|
||
self.end_headers()
|
||
self.wfile.write(html.encode('utf-8'))
|
||
except Exception as e:
|
||
logger.error(f"Error sending HTML response: {e}")
|
||
|
||
def get_monitor_html(self):
|
||
uptime = int(time.time() - start_time)
|
||
uptime_str = f"{uptime // 3600}h {(uptime % 3600) // 60}m {uptime % 60}s"
|
||
|
||
return f"""<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<title>MY Network Bootstrap Monitor - Minimal</title>
|
||
<meta charset="utf-8">
|
||
<meta http-equiv="refresh" content="30">
|
||
<style>
|
||
body {{ font-family: 'Courier New', monospace; background: #000; color: #0f0; padding: 20px; margin: 0; }}
|
||
h1 {{ color: #ff0; text-align: center; text-shadow: 0 0 10px #ff0; }}
|
||
.box {{ border: 1px solid #0f0; padding: 15px; margin: 10px 0; background: rgba(0,255,0,0.1); }}
|
||
.status {{ color: #0f0; font-weight: bold; }}
|
||
.info {{ color: #00f; }}
|
||
.warning {{ color: #f80; }}
|
||
.timestamp {{ color: #fff; font-size: 0.8em; }}
|
||
.ascii-art {{ color: #0f0; font-size: 0.7em; text-align: center; }}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="ascii-art">
|
||
███╗ ███╗██╗ ██╗ ███╗ ██╗███████╗████████╗██╗ ██╗ ██████╗ ██████╗ ██╗ ██╗
|
||
████╗ ████║╚██╗ ██╔╝ ████╗ ██║██╔════╝╚══██╔══╝██║ ██║██╔═══██╗██╔══██╗██║ ██╔╝
|
||
██╔████╔██║ ╚████╔╝ ██╔██╗ ██║█████╗ ██║ ██║ █╗ ██║██║ ██║██████╔╝█████╔╝
|
||
██║╚██╔╝██║ ╚██╔╝ ██║╚██╗██║██╔══╝ ██║ ██║███╗██║██║ ██║██╔══██╗██╔═██╗
|
||
██║ ╚═╝ ██║ ██║ ██║ ╚████║███████╗ ██║ ╚███╔███╔╝╚██████╔╝██║ ██║██║ ██╗
|
||
╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═══╝╚══════╝ ╚═╝ ╚══╝╚══╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝
|
||
</div>
|
||
|
||
<h1>🚀 MY Network Bootstrap Node Monitor</h1>
|
||
|
||
<div class="box">
|
||
<h3 class="status">🟢 Node Status: ACTIVE (Minimal 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: Minimal HTTP Server</p>
|
||
<p class="info">🛠️ Services: API, Monitor</p>
|
||
<p class="info">⏱️ Uptime: {uptime_str}</p>
|
||
<p class="timestamp">🕐 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: 5</p>
|
||
<p class="info">🔓 Public Access: Enabled</p>
|
||
<p class="warning">⚠️ SSL: Disabled (Minimal Mode)</p>
|
||
<p class="info">🔄 Sync Interval: 300s</p>
|
||
</div>
|
||
|
||
<div class="box">
|
||
<h3 class="warning">⚠️ Minimal Mode</h3>
|
||
<p class="warning">🔧 Сервис запущен в минимальном режиме</p>
|
||
<p class="warning">📦 Использует только встроенные модули Python</p>
|
||
<p class="warning">🚫 Без внешних зависимостей</p>
|
||
<p class="info">🌍 Доступ: http://{DOMAIN}:{PORT}</p>
|
||
</div>
|
||
|
||
<div class="box">
|
||
<h3 class="status">🔗 API Endpoints</h3>
|
||
<p class="info">📊 Health: <a href="/api/my/health" style="color: #0ff;">/api/my/health</a></p>
|
||
<p class="info">ℹ️ Node Info: <a href="/api/my/node/info" style="color: #0ff;">/api/my/node/info</a></p>
|
||
<p class="info">🏗️ Bootstrap Config: <a href="/api/my/bootstrap/config" style="color: #0ff;">/api/my/bootstrap/config</a></p>
|
||
</div>
|
||
|
||
<div class="timestamp" style="text-align: center; margin-top: 20px;">
|
||
⏰ Автообновление каждые 30 секунд
|
||
</div>
|
||
</body>
|
||
</html>"""
|
||
|
||
def log_message(self, format, *args):
|
||
client_ip = self.address_string()
|
||
message = format % args
|
||
logger.info(f"{client_ip} - {message}")
|
||
|
||
def do_OPTIONS(self):
|
||
self.send_response(200)
|
||
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.end_headers()
|
||
|
||
# Глобальная переменная для времени запуска
|
||
start_time = time.time()
|
||
|
||
def start_server():
|
||
global start_time
|
||
start_time = time.time()
|
||
|
||
logger.info("=" * 50)
|
||
logger.info("🚀 MY Network Bootstrap Node - Minimal Mode")
|
||
logger.info("=" * 50)
|
||
logger.info(f"🌐 Domain: {DOMAIN}")
|
||
logger.info(f"🔌 Port: {PORT}")
|
||
logger.info(f"🆔 Node ID: {NODE_ID}")
|
||
logger.info(f"⚙️ Mode: Minimal HTTP Server")
|
||
logger.info(f"🌍 Access: http://0.0.0.0:{PORT}")
|
||
logger.info(f"📊 Health: http://0.0.0.0:{PORT}/api/my/health")
|
||
logger.info(f"🖥️ Monitor: http://0.0.0.0:{PORT}/api/my/monitor/")
|
||
logger.info("=" * 50)
|
||
|
||
try:
|
||
# Создание HTTP сервера
|
||
server_address = ("0.0.0.0", PORT)
|
||
httpd = HTTPServer(server_address, MyNetworkHandler)
|
||
|
||
logger.info(f"✅ Server started successfully")
|
||
logger.info(f"🎯 MY Network Bootstrap Node is ready!")
|
||
|
||
# Запуск сервера
|
||
httpd.serve_forever()
|
||
|
||
except KeyboardInterrupt:
|
||
logger.info("🛑 Server stopped by user")
|
||
except Exception as e:
|
||
logger.error(f"❌ Server error: {e}")
|
||
raise
|
||
|
||
if __name__ == "__main__":
|
||
try:
|
||
start_server()
|
||
except KeyboardInterrupt:
|
||
print("\n🛑 Stopping server...")
|
||
sys.exit(0)
|
||
except Exception as e:
|
||
print(f"❌ Fatal error: {e}")
|
||
sys.exit(1)
|
||
EOF
|
||
|
||
# Создание скрипта запуска
|
||
cat > start_my_network.sh << 'EOF'
|
||
#!/bin/bash
|
||
|
||
cd /home/service/my-uploader-bot
|
||
|
||
echo "🚀 Запуск MY Network Bootstrap Node (Minimal Mode)"
|
||
echo "==============================================="
|
||
echo ""
|
||
|
||
# Создание директории для логов
|
||
mkdir -p logs
|
||
|
||
# Запуск приложения
|
||
echo "▶️ Запуск сервера..."
|
||
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 &
|
||
PID=$!
|
||
echo "$(date): MY Network запущен (PID: $PID)" >> /home/service/my-uploader-bot/logs/cron.log
|
||
echo "MY Network запущен (PID: $PID)"
|
||
else
|
||
echo "$(date): MY Network уже запущен" >> /home/service/my-uploader-bot/logs/cron.log
|
||
echo "MY Network уже запущен"
|
||
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
|
||
|
||
# Создание скрипта проверки статуса
|
||
cat > status_my_network.sh << 'EOF'
|
||
#!/bin/bash
|
||
|
||
echo "📊 Статус MY Network Bootstrap Node"
|
||
echo "================================="
|
||
|
||
if pgrep -f "python3 app/main.py" > /dev/null; then
|
||
PID=$(pgrep -f "python3 app/main.py")
|
||
echo "✅ MY Network запущен (PID: $PID)"
|
||
echo "🌐 Доступ: http://my-public-node-3.projscale.dev:15100"
|
||
echo "📊 Health: http://my-public-node-3.projscale.dev:15100/api/my/health"
|
||
echo "🖥️ Monitor: http://my-public-node-3.projscale.dev:15100/api/my/monitor/"
|
||
|
||
echo ""
|
||
echo "📈 Процесс:"
|
||
ps aux | grep "python3 app/main.py" | grep -v grep
|
||
|
||
echo ""
|
||
echo "🔌 Порт 15100:"
|
||
netstat -tulpn 2>/dev/null | grep :15100 || echo "netstat недоступен"
|
||
else
|
||
echo "❌ MY Network не запущен"
|
||
fi
|
||
|
||
echo ""
|
||
echo "📝 Последние логи:"
|
||
if [[ -f logs/my-network.log ]]; then
|
||
tail -5 logs/my-network.log
|
||
else
|
||
echo "Лог файл не найден"
|
||
fi
|
||
EOF
|
||
|
||
chmod +x status_my_network.sh
|
||
|
||
# Добавление в crontab
|
||
echo "📅 Настройка автозапуска..."
|
||
(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 " ./status_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 # Лог cron"
|
||
echo ""
|
||
echo "⚡ Автозапуск настроен через cron (каждые 5 минут)"
|
||
echo ""
|
||
echo "🎯 MY Network Bootstrap Node готов к работе!"
|
||
echo ""
|
||
echo "▶️ Запустить сейчас? Выполните:"
|
||
echo " ./run_my_network.sh" |