feat: add Python linting support with pylint and black
This commit is contained in:
@ -12,63 +12,73 @@ from helpers.functions import printfe, println, logo
|
||||
# Base directory for Docker services $HOME/services
|
||||
SERVICES_DIR = os.path.join(os.path.expanduser("~"), "services")
|
||||
|
||||
|
||||
def get_service_path(service_name):
|
||||
"""Return the path to a service's docker-compose file"""
|
||||
service_dir = os.path.join(SERVICES_DIR, service_name)
|
||||
compose_file = os.path.join(service_dir, "docker-compose.yml")
|
||||
|
||||
|
||||
if not os.path.exists(compose_file):
|
||||
printfe("red", f"Error: Service '{service_name}' not found at {compose_file}")
|
||||
return None
|
||||
|
||||
|
||||
return compose_file
|
||||
|
||||
|
||||
def run_docker_compose(args, service_name=None, compose_file=None):
|
||||
"""Run docker compose command with provided args"""
|
||||
if service_name and not compose_file:
|
||||
compose_file = get_service_path(service_name)
|
||||
if not compose_file:
|
||||
return 1
|
||||
|
||||
|
||||
cmd = ["docker", "compose"]
|
||||
|
||||
|
||||
if compose_file:
|
||||
cmd.extend(["-f", compose_file])
|
||||
|
||||
|
||||
cmd.extend(args)
|
||||
|
||||
|
||||
printfe("blue", f"Running: {' '.join(cmd)}")
|
||||
result = subprocess.run(cmd)
|
||||
return result.returncode
|
||||
|
||||
|
||||
def cmd_start(args):
|
||||
"""Start a Docker service"""
|
||||
return run_docker_compose(["up", "-d"], service_name=args.service)
|
||||
|
||||
|
||||
def cmd_stop(args):
|
||||
"""Stop a Docker service"""
|
||||
return run_docker_compose(["down"], service_name=args.service)
|
||||
|
||||
|
||||
def cmd_restart(args):
|
||||
"""Restart a Docker service"""
|
||||
return run_docker_compose(["restart"], service_name=args.service)
|
||||
|
||||
|
||||
def get_all_running_services():
|
||||
"""Return a list of all running services"""
|
||||
if not os.path.exists(SERVICES_DIR):
|
||||
return []
|
||||
|
||||
|
||||
running_services = []
|
||||
services = [d for d in os.listdir(SERVICES_DIR)
|
||||
if os.path.isdir(os.path.join(SERVICES_DIR, d)) and
|
||||
os.path.exists(os.path.join(SERVICES_DIR, d, "docker-compose.yml"))]
|
||||
|
||||
services = [
|
||||
d
|
||||
for d in os.listdir(SERVICES_DIR)
|
||||
if os.path.isdir(os.path.join(SERVICES_DIR, d))
|
||||
and os.path.exists(os.path.join(SERVICES_DIR, d, "docker-compose.yml"))
|
||||
]
|
||||
|
||||
for service in services:
|
||||
if check_service_running(service) > 0:
|
||||
running_services.append(service)
|
||||
|
||||
|
||||
return running_services
|
||||
|
||||
|
||||
def cmd_update(args):
|
||||
"""Update a Docker service by pulling new images and recreating containers if needed"""
|
||||
if args.all:
|
||||
@ -76,24 +86,27 @@ def cmd_update(args):
|
||||
if not running_services:
|
||||
printfe("yellow", "No running services found to update")
|
||||
return 0
|
||||
|
||||
|
||||
printfe("blue", f"Updating all running services: {', '.join(running_services)}")
|
||||
|
||||
|
||||
failed_services = []
|
||||
for service in running_services:
|
||||
printfe("blue", f"\n=== Updating {service} ===")
|
||||
|
||||
|
||||
# Pull the latest images
|
||||
pull_result = run_docker_compose(["pull"], service_name=service)
|
||||
|
||||
|
||||
# Bring the service up with the latest images
|
||||
up_result = run_docker_compose(["up", "-d"], service_name=service)
|
||||
|
||||
|
||||
if pull_result != 0 or up_result != 0:
|
||||
failed_services.append(service)
|
||||
|
||||
|
||||
if failed_services:
|
||||
printfe("red", f"\nFailed to update the following services: {', '.join(failed_services)}")
|
||||
printfe(
|
||||
"red",
|
||||
f"\nFailed to update the following services: {', '.join(failed_services)}",
|
||||
)
|
||||
return 1
|
||||
else:
|
||||
printfe("green", "\nAll running services updated successfully")
|
||||
@ -104,10 +117,11 @@ def cmd_update(args):
|
||||
pull_result = run_docker_compose(["pull"], service_name=args.service)
|
||||
if pull_result != 0:
|
||||
return pull_result
|
||||
|
||||
|
||||
# Then bring the service up with the latest images
|
||||
return run_docker_compose(["up", "-d"], service_name=args.service)
|
||||
|
||||
|
||||
def cmd_ps(args):
|
||||
"""Show Docker service status"""
|
||||
if args.service:
|
||||
@ -115,107 +129,123 @@ def cmd_ps(args):
|
||||
else:
|
||||
return run_docker_compose(["ps"])
|
||||
|
||||
|
||||
def cmd_logs(args):
|
||||
"""Show Docker service logs"""
|
||||
cmd = ["logs"]
|
||||
|
||||
|
||||
if args.follow:
|
||||
cmd.append("-f")
|
||||
|
||||
|
||||
if args.tail:
|
||||
cmd.extend(["--tail", args.tail])
|
||||
|
||||
|
||||
return run_docker_compose(cmd, service_name=args.service)
|
||||
|
||||
|
||||
def check_service_running(service_name):
|
||||
"""Check if service has running containers and return the count"""
|
||||
compose_file = get_service_path(service_name)
|
||||
if not compose_file:
|
||||
return 0
|
||||
|
||||
|
||||
result = subprocess.run(
|
||||
["docker", "compose", "-f", compose_file, "ps", "--quiet"],
|
||||
capture_output=True,
|
||||
text=True
|
||||
text=True,
|
||||
)
|
||||
|
||||
|
||||
# Count non-empty lines to get container count
|
||||
containers = [line for line in result.stdout.strip().split('\n') if line]
|
||||
containers = [line for line in result.stdout.strip().split("\n") if line]
|
||||
return len(containers)
|
||||
|
||||
|
||||
def cmd_list(args):
|
||||
"""List available Docker services"""
|
||||
if not os.path.exists(SERVICES_DIR):
|
||||
printfe("red", f"Error: Services directory not found at {SERVICES_DIR}")
|
||||
return 1
|
||||
|
||||
services = [d for d in os.listdir(SERVICES_DIR)
|
||||
if os.path.isdir(os.path.join(SERVICES_DIR, d)) and
|
||||
os.path.exists(os.path.join(SERVICES_DIR, d, "docker-compose.yml"))]
|
||||
|
||||
|
||||
services = [
|
||||
d
|
||||
for d in os.listdir(SERVICES_DIR)
|
||||
if os.path.isdir(os.path.join(SERVICES_DIR, d))
|
||||
and os.path.exists(os.path.join(SERVICES_DIR, d, "docker-compose.yml"))
|
||||
]
|
||||
|
||||
if not services:
|
||||
printfe("yellow", "No Docker services found")
|
||||
return 0
|
||||
|
||||
println("Available Docker services:", 'blue')
|
||||
|
||||
println("Available Docker services:", "blue")
|
||||
for service in sorted(services):
|
||||
container_count = check_service_running(service)
|
||||
is_running = container_count > 0
|
||||
|
||||
|
||||
if is_running:
|
||||
status = f"[RUNNING - {container_count} container{'s' if container_count > 1 else ''}]"
|
||||
color = "green"
|
||||
else:
|
||||
status = "[STOPPED]"
|
||||
color = "red"
|
||||
|
||||
|
||||
printfe(color, f" - {service:<20} {status}")
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Manage Docker services")
|
||||
subparsers = parser.add_subparsers(dest="command", help="Command to run")
|
||||
|
||||
|
||||
# Start command
|
||||
start_parser = subparsers.add_parser("start", help="Start a Docker service")
|
||||
start_parser.add_argument("service", help="Service to start")
|
||||
|
||||
|
||||
# Stop command
|
||||
stop_parser = subparsers.add_parser("stop", help="Stop a Docker service")
|
||||
stop_parser.add_argument("service", help="Service to stop")
|
||||
|
||||
|
||||
# Restart command
|
||||
restart_parser = subparsers.add_parser("restart", help="Restart a Docker service")
|
||||
restart_parser.add_argument("service", help="Service to restart")
|
||||
|
||||
|
||||
# Update command
|
||||
update_parser = subparsers.add_parser("update", help="Update a Docker service (pull new images and recreate if needed)")
|
||||
update_parser = subparsers.add_parser(
|
||||
"update",
|
||||
help="Update a Docker service (pull new images and recreate if needed)",
|
||||
)
|
||||
update_parser_group = update_parser.add_mutually_exclusive_group(required=True)
|
||||
update_parser_group.add_argument("--all", action="store_true", help="Update all running services")
|
||||
update_parser_group.add_argument(
|
||||
"--all", action="store_true", help="Update all running services"
|
||||
)
|
||||
update_parser_group.add_argument("service", nargs="?", help="Service to update")
|
||||
|
||||
|
||||
# PS command
|
||||
ps_parser = subparsers.add_parser("ps", help="Show Docker service status")
|
||||
ps_parser.add_argument("service", nargs="?", help="Service to check")
|
||||
|
||||
|
||||
# Logs command
|
||||
logs_parser = subparsers.add_parser("logs", help="Show Docker service logs")
|
||||
logs_parser.add_argument("service", help="Service to show logs for")
|
||||
logs_parser.add_argument("-f", "--follow", action="store_true", help="Follow log output")
|
||||
logs_parser.add_argument("--tail", help="Number of lines to show from the end of logs")
|
||||
|
||||
logs_parser.add_argument(
|
||||
"-f", "--follow", action="store_true", help="Follow log output"
|
||||
)
|
||||
logs_parser.add_argument(
|
||||
"--tail", help="Number of lines to show from the end of logs"
|
||||
)
|
||||
|
||||
# List command and its alias
|
||||
subparsers.add_parser("list", help="List available Docker services")
|
||||
subparsers.add_parser("ls", help="List available Docker services (alias for list)")
|
||||
|
||||
|
||||
# Parse arguments
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
if not args.command:
|
||||
parser.print_help()
|
||||
return 1
|
||||
|
||||
|
||||
# Execute the appropriate command
|
||||
commands = {
|
||||
"start": cmd_start,
|
||||
@ -225,10 +255,11 @@ def main():
|
||||
"ps": cmd_ps,
|
||||
"logs": cmd_logs,
|
||||
"list": cmd_list,
|
||||
"ls": cmd_list # Alias 'ls' to the same function as 'list'
|
||||
"ls": cmd_list, # Alias 'ls' to the same function as 'list'
|
||||
}
|
||||
|
||||
|
||||
return commands[args.command](args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
Reference in New Issue
Block a user