190 lines
5.5 KiB
Python
190 lines
5.5 KiB
Python
"""
|
|
pyserve start/stop/restart - Service management commands
|
|
"""
|
|
|
|
import asyncio
|
|
from pathlib import Path
|
|
|
|
import click
|
|
|
|
|
|
@click.command("start")
|
|
@click.argument("services", nargs=-1, required=True)
|
|
@click.option(
|
|
"--timeout",
|
|
"timeout",
|
|
default=60,
|
|
type=int,
|
|
help="Timeout in seconds for service startup",
|
|
)
|
|
@click.pass_obj
|
|
def start_cmd(ctx, services: tuple, timeout: int):
|
|
"""
|
|
Start one or more services.
|
|
|
|
\b
|
|
Examples:
|
|
pyserve start api # Start api service
|
|
pyserve start api admin # Start multiple services
|
|
"""
|
|
from ...config import Config
|
|
from .._runner import ServiceRunner
|
|
from ..output import console, print_error, print_success
|
|
from ..state import StateManager
|
|
|
|
config_path = Path(ctx.config_file)
|
|
if not config_path.exists():
|
|
print_error(f"Configuration file not found: {config_path}")
|
|
raise click.Abort()
|
|
|
|
config = Config.from_yaml(str(config_path))
|
|
state_manager = StateManager(Path(".pyserve"), ctx.project)
|
|
runner = ServiceRunner(config, state_manager)
|
|
|
|
console.print(f"[bold]Starting services: {', '.join(services)}[/bold]")
|
|
|
|
async def do_start():
|
|
results = {}
|
|
for service in services:
|
|
try:
|
|
success = await runner.start_service(service, timeout=timeout)
|
|
results[service] = success
|
|
if success:
|
|
print_success(f"Started {service}")
|
|
else:
|
|
print_error(f"Failed to start {service}")
|
|
except Exception as e:
|
|
print_error(f"Error starting {service}: {e}")
|
|
results[service] = False
|
|
return results
|
|
|
|
try:
|
|
results = asyncio.run(do_start())
|
|
if not all(results.values()):
|
|
raise click.Abort()
|
|
except Exception as e:
|
|
print_error(f"Error: {e}")
|
|
raise click.Abort()
|
|
|
|
|
|
@click.command("stop")
|
|
@click.argument("services", nargs=-1, required=True)
|
|
@click.option(
|
|
"--timeout",
|
|
"timeout",
|
|
default=30,
|
|
type=int,
|
|
help="Timeout in seconds for graceful shutdown",
|
|
)
|
|
@click.option(
|
|
"-f",
|
|
"--force",
|
|
is_flag=True,
|
|
help="Force stop (SIGKILL)",
|
|
)
|
|
@click.pass_obj
|
|
def stop_cmd(ctx, services: tuple, timeout: int, force: bool):
|
|
"""
|
|
Stop one or more services.
|
|
|
|
\b
|
|
Examples:
|
|
pyserve stop api # Stop api service
|
|
pyserve stop api admin # Stop multiple services
|
|
pyserve stop api --force # Force stop
|
|
"""
|
|
from ...config import Config
|
|
from .._runner import ServiceRunner
|
|
from ..output import console, print_error, print_success
|
|
from ..state import StateManager
|
|
|
|
config_path = Path(ctx.config_file)
|
|
config = Config.from_yaml(str(config_path)) if config_path.exists() else Config()
|
|
|
|
state_manager = StateManager(Path(".pyserve"), ctx.project)
|
|
runner = ServiceRunner(config, state_manager)
|
|
|
|
console.print(f"[bold]Stopping services: {', '.join(services)}[/bold]")
|
|
|
|
async def do_stop():
|
|
results = {}
|
|
for service in services:
|
|
try:
|
|
success = await runner.stop_service(service, timeout=timeout, force=force)
|
|
results[service] = success
|
|
if success:
|
|
print_success(f"Stopped {service}")
|
|
else:
|
|
print_error(f"Failed to stop {service}")
|
|
except Exception as e:
|
|
print_error(f"Error stopping {service}: {e}")
|
|
results[service] = False
|
|
return results
|
|
|
|
try:
|
|
results = asyncio.run(do_stop())
|
|
if not all(results.values()):
|
|
raise click.Abort()
|
|
except Exception as e:
|
|
print_error(f"Error: {e}")
|
|
raise click.Abort()
|
|
|
|
|
|
@click.command("restart")
|
|
@click.argument("services", nargs=-1, required=True)
|
|
@click.option(
|
|
"--timeout",
|
|
"timeout",
|
|
default=60,
|
|
type=int,
|
|
help="Timeout in seconds for restart",
|
|
)
|
|
@click.pass_obj
|
|
def restart_cmd(ctx, services: tuple, timeout: int):
|
|
"""
|
|
Restart one or more services.
|
|
|
|
\b
|
|
Examples:
|
|
pyserve restart api # Restart api service
|
|
pyserve restart api admin # Restart multiple services
|
|
"""
|
|
from ...config import Config
|
|
from .._runner import ServiceRunner
|
|
from ..output import console, print_error, print_success
|
|
from ..state import StateManager
|
|
|
|
config_path = Path(ctx.config_file)
|
|
if not config_path.exists():
|
|
print_error(f"Configuration file not found: {config_path}")
|
|
raise click.Abort()
|
|
|
|
config = Config.from_yaml(str(config_path))
|
|
state_manager = StateManager(Path(".pyserve"), ctx.project)
|
|
runner = ServiceRunner(config, state_manager)
|
|
|
|
console.print(f"[bold]Restarting services: {', '.join(services)}[/bold]")
|
|
|
|
async def do_restart():
|
|
results = {}
|
|
for service in services:
|
|
try:
|
|
success = await runner.restart_service(service, timeout=timeout)
|
|
results[service] = success
|
|
if success:
|
|
print_success(f"Restarted {service}")
|
|
else:
|
|
print_error(f"Failed to restart {service}")
|
|
except Exception as e:
|
|
print_error(f"Error restarting {service}: {e}")
|
|
results[service] = False
|
|
return results
|
|
|
|
try:
|
|
results = asyncio.run(do_restart())
|
|
if not all(results.values()):
|
|
raise click.Abort()
|
|
except Exception as e:
|
|
print_error(f"Error: {e}")
|
|
raise click.Abort()
|