89 lines
2.9 KiB
Python
89 lines
2.9 KiB
Python
import asyncio
|
|
import subprocess
|
|
from typing import List
|
|
from sqlalchemy.orm import Session
|
|
from app.database import Server, WolLog
|
|
from app.models.schemas import WolLogCreate
|
|
from app.services.logging_service import LoggingService
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class WolService:
|
|
@staticmethod
|
|
async def send_wol_packet(mac_address: str) -> bool:
|
|
try:
|
|
result = subprocess.run(
|
|
["wakeonlan", mac_address],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=10
|
|
)
|
|
return result.returncode == 0
|
|
except subprocess.TimeoutExpired:
|
|
logger.error(f"WOL timeout for MAC: {mac_address}")
|
|
return False
|
|
except Exception as e:
|
|
logger.error(f"WOL error for MAC {mac_address}: {str(e)}")
|
|
return False
|
|
|
|
@staticmethod
|
|
async def ping_server(ip_address: str) -> bool:
|
|
try:
|
|
result = subprocess.run(
|
|
["ping", "-c", "1", "-W", "3", ip_address],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=5
|
|
)
|
|
return result.returncode == 0
|
|
except subprocess.TimeoutExpired:
|
|
return False
|
|
except Exception as e:
|
|
logger.error(f"Ping error for IP {ip_address}: {str(e)}")
|
|
return False
|
|
|
|
@staticmethod
|
|
async def wake_server(db: Session, server_id: int) -> bool:
|
|
server = db.query(Server).filter(Server.id == server_id).first()
|
|
if not server:
|
|
return False
|
|
|
|
success = await WolService.send_wol_packet(server.mac_address)
|
|
|
|
# Log to both WolLog (backward compatibility) and ActionLog (new unified system)
|
|
log_entry = WolLog(
|
|
server_id=server_id,
|
|
action="wake",
|
|
success=success,
|
|
message=f"WOL packet sent to {server.mac_address}" if success else "Failed to send WOL packet"
|
|
)
|
|
db.add(log_entry)
|
|
|
|
# Log to unified action log
|
|
LoggingService.log_wol_action(
|
|
db=db,
|
|
server_id=server_id,
|
|
server_name=server.name,
|
|
success=success,
|
|
message=f"WOL packet {'sent successfully' if success else 'failed'} to {server.name} ({server.mac_address})"
|
|
)
|
|
|
|
return success
|
|
|
|
@staticmethod
|
|
async def check_all_servers_status(db: Session) -> None:
|
|
servers = db.query(Server).all()
|
|
|
|
tasks = []
|
|
for server in servers:
|
|
tasks.append(WolService.ping_server(server.ip_address))
|
|
|
|
results = await asyncio.gather(*tasks)
|
|
|
|
from datetime import datetime
|
|
for server, is_online in zip(servers, results):
|
|
server.is_online = is_online
|
|
server.last_ping = datetime.utcnow()
|
|
|
|
db.commit() |