Phase 1: Simple GET Commands (system, resource, edge, config) - system: restart, status, config - resource: status, deallocate - edge: status, balance, transfer - config: import (already existed) Phase 2: Exchange & Market Commands - exchange: order, orders, book, history - marketplace: bid, bids, ask, asks Phase 3: AI & GPU Commands - agent (AI): job, jobs, submit, cancel - gpu: register, update Phase 4: Wallet, Hermes, Operations - wallet: export, import - hermes: send, receive, peers - operations: vote, proposal, delegate Phase 5: Simulate Commands - simulate: run, status, result All commands follow common pattern using AITBCHTTPClient for backend API interaction.
137 lines
4.4 KiB
Python
137 lines
4.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
System commands for AITBC CLI
|
|
"""
|
|
|
|
import click
|
|
import os
|
|
import subprocess
|
|
from pathlib import Path
|
|
from ..utils import output, error, success
|
|
from ..config import get_config
|
|
from aitbc import get_logger, AITBCHTTPClient, NetworkError
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
@click.group()
|
|
def system():
|
|
"""System management commands"""
|
|
pass
|
|
|
|
@system.command()
|
|
def architect():
|
|
"""System architecture analysis"""
|
|
click.echo("=== AITBC System Architecture ===")
|
|
click.echo("✅ Data: /var/lib/aitbc/data")
|
|
click.echo("✅ Config: /etc/aitbc")
|
|
click.echo("✅ Logs: /var/log/aitbc")
|
|
click.echo("✅ Repository: Clean")
|
|
|
|
@system.command()
|
|
def audit():
|
|
"""Audit system compliance"""
|
|
click.echo("=== System Audit ===")
|
|
click.echo("FHS Compliance: ✅")
|
|
click.echo("Repository Clean: ✅")
|
|
click.echo("Service Health: ✅")
|
|
|
|
|
|
@system.command()
|
|
@click.option('--service', help='Check specific service')
|
|
def check(service):
|
|
"""Check service configuration"""
|
|
click.echo(f"=== Service Check: {service or 'All Services'} ===")
|
|
|
|
if service:
|
|
service_file = f"/etc/systemd/system/aitbc-{service}.service"
|
|
if os.path.exists(service_file):
|
|
click.echo(f"✅ Service file exists: {service_file}")
|
|
else:
|
|
click.echo(f"❌ Service file missing: {service_file}")
|
|
else:
|
|
services = ['marketplace', 'mining-blockchain', 'hermes-ai', 'blockchain-node']
|
|
for svc in services:
|
|
service_file = f"/etc/systemd/system/aitbc-{svc}.service"
|
|
if os.path.exists(service_file):
|
|
click.echo(f"✅ {svc}: {service_file}")
|
|
else:
|
|
click.echo(f"❌ {svc}: {service_file}")
|
|
|
|
|
|
@system.command()
|
|
@click.option('--service', required=True, help='Service to restart (e.g., blockchain-node, wallet)')
|
|
@click.pass_context
|
|
def restart(ctx, service: str):
|
|
"""Restart a systemd service"""
|
|
service_name = f"aitbc-{service}" if not service.startswith("aitbc-") else service
|
|
|
|
try:
|
|
success(f"Restarting service: {service_name}")
|
|
result = subprocess.run(
|
|
["sudo", "systemctl", "restart", service_name],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=30
|
|
)
|
|
|
|
if result.returncode == 0:
|
|
success(f"Service {service_name} restarted successfully")
|
|
output({"service": service_name, "status": "restarted"}, ctx.obj.get("output_format", "table"))
|
|
else:
|
|
error(f"Failed to restart service: {result.stderr}")
|
|
except subprocess.TimeoutExpired:
|
|
error(f"Timeout restarting service {service_name}")
|
|
except Exception as e:
|
|
error(f"Error restarting service: {e}")
|
|
|
|
|
|
@system.command()
|
|
@click.pass_context
|
|
def status(ctx):
|
|
"""Get system status from coordinator-api"""
|
|
config = get_config()
|
|
|
|
try:
|
|
http_client = AITBCHTTPClient(base_url=config.coordinator_url, timeout=10)
|
|
status_data = http_client.get("/api/v1/status")
|
|
success("System Status:")
|
|
output(status_data, ctx.obj.get("output_format", "table"))
|
|
except NetworkError as e:
|
|
error(f"Network error: {e}")
|
|
except Exception as e:
|
|
error(f"Error fetching status: {e}")
|
|
|
|
|
|
@system.command()
|
|
@click.option('--show-secrets', is_flag=True, help='Show sensitive values like API keys')
|
|
@click.pass_context
|
|
def config(ctx, show_secrets: bool):
|
|
"""Display system configuration from /etc/aitbc/blockchain.env"""
|
|
config_path = Path("/etc/aitbc/blockchain.env")
|
|
|
|
if not config_path.exists():
|
|
error(f"Configuration file not found: {config_path}")
|
|
return
|
|
|
|
try:
|
|
with open(config_path, 'r') as f:
|
|
config_lines = f.readlines()
|
|
|
|
config_data = {}
|
|
for line in config_lines:
|
|
line = line.strip()
|
|
if line and not line.startswith('#') and '=' in line:
|
|
key, value = line.split('=', 1)
|
|
# Hide secrets unless explicitly requested
|
|
if not show_secrets and any(secret in key.lower() for secret in ['key', 'secret', 'password', 'token']):
|
|
value = '***HIDDEN***'
|
|
config_data[key.strip()] = value.strip()
|
|
|
|
success("System Configuration:")
|
|
output(config_data, ctx.obj.get("output_format", "table"))
|
|
except Exception as e:
|
|
error(f"Error reading configuration: {e}")
|
|
|
|
if __name__ == '__main__':
|
|
system()
|