283 lines
6.0 KiB
Python
Executable File
283 lines
6.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
"""
|
|
dcm down -v --remove-orphans
|
|
"""
|
|
|
|
import subprocess
|
|
import yaml
|
|
import pprint
|
|
import os
|
|
import re
|
|
from sys import argv, exit
|
|
from time import time, sleep
|
|
from pprint import PrettyPrinter
|
|
from operator import itemgetter
|
|
|
|
|
|
def echo(text):
|
|
print(">> " + text)
|
|
|
|
|
|
def print_list(lst):
|
|
for item in lst:
|
|
print(item)
|
|
|
|
|
|
def error(text):
|
|
print(text)
|
|
exit(1)
|
|
|
|
|
|
def system(cmd):
|
|
return subprocess.call(cmd, shell=True)
|
|
|
|
|
|
def split(text):
|
|
return re.split(r'\s+', text)
|
|
|
|
|
|
def prefix_join(prefix, array):
|
|
return " ".join([prefix + " " + item for item in array])
|
|
|
|
|
|
def join_args(args):
|
|
return " ".join(args)
|
|
|
|
|
|
def dc_files(files):
|
|
return prefix_join("-f", files)
|
|
|
|
|
|
def load_dc_file(dc_file):
|
|
with open(dc_file) as yamlFile:
|
|
dc = yaml.load(yamlFile, Loader=yaml.FullLoader)
|
|
return dc
|
|
|
|
|
|
def dc_cmd(args):
|
|
# split join
|
|
args = join_args(args)
|
|
return join_args([DOCKER_COMPOSE, DC_FILES_ARGS, args])
|
|
|
|
|
|
def dc_run(args):
|
|
cmd = dc_cmd(args)
|
|
print(cmd)
|
|
return system(cmd)
|
|
|
|
|
|
def dc_log(args):
|
|
args = ["logs", "--no-color"] + args + [r"| sed -r 's/^[^|]+\| //g'"]
|
|
dc_run(args)
|
|
|
|
|
|
def dc_services(dc_file):
|
|
dc = load_dc_file(dc_file)
|
|
return [service for service in dc["services"].keys()]
|
|
|
|
|
|
def dc_commands(args):
|
|
for key in sorted(COMMANDS.keys()):
|
|
print(key)
|
|
|
|
|
|
def dump_services(files):
|
|
services = [(filename, service) for filename in files for service in dc_services(filename)]
|
|
services = map(itemgetter(1), services)
|
|
#services = sorted(services)
|
|
print_list(services)
|
|
|
|
|
|
def deps_load(yaml_filename):
|
|
deps = {}
|
|
with open(yaml_filename) as file:
|
|
dc = yaml.load(file, Loader=yaml.FullLoader)
|
|
for (name, conf) in dc['services'].items():
|
|
depends_on = conf.get('depends_on', [])
|
|
deps[name] = depends_on
|
|
return deps
|
|
|
|
|
|
def deps_find(service, deps):
|
|
all = set([service])
|
|
if service in deps:
|
|
services = deps[service]
|
|
new = set(services) - all
|
|
if new:
|
|
new_list = " ".join(new)
|
|
print(f"{service} >> {new_list}")
|
|
all.update(services)
|
|
del deps[service]
|
|
for one in new:
|
|
all.update(deps_find(one, deps))
|
|
return all
|
|
|
|
|
|
def dc_deps(dc_files, args):
|
|
service = args[0]
|
|
pp = PrettyPrinter(indent=2)
|
|
for dc_file in dc_files:
|
|
deps = deps_load(dc_file)
|
|
if service in deps:
|
|
all = sorted(deps_find(service, deps))
|
|
print("ALL >> " + " ".join(all))
|
|
return
|
|
print(f"Service {service} not found")
|
|
|
|
|
|
def dump_files(files):
|
|
for file in files:
|
|
print(file)
|
|
|
|
|
|
def curl_check(uri):
|
|
cmd = "curl -f -s -o /dev/null " + uri
|
|
echo(cmd)
|
|
return system(cmd) == 0
|
|
|
|
|
|
def wait_for(check, delay, duration):
|
|
start = time()
|
|
while time() - start < duration:
|
|
if check():
|
|
return True
|
|
else:
|
|
echo(f"sleep for {delay} sec")
|
|
sleep(delay)
|
|
return False
|
|
|
|
|
|
def service_wait(service, check, delay = 10, duration = 120):
|
|
echo(f"WAIT FOR {service}")
|
|
started = wait_for(check, delay, duration)
|
|
if started:
|
|
echo(f"READY {service}")
|
|
else:
|
|
echo(f"BAD {service}")
|
|
|
|
|
|
def get_check(service):
|
|
checker = SERVICES.get(service, None)
|
|
if checker is None:
|
|
error(f"No checker for {service}")
|
|
else:
|
|
return checker
|
|
|
|
|
|
def dc_check(args):
|
|
for service in args:
|
|
check = get_check(service)
|
|
running = check()
|
|
if running:
|
|
print(f"{service} ON")
|
|
else:
|
|
print(f"{service} OFF")
|
|
|
|
|
|
def dc_up(services):
|
|
dc_run(["up", "-d"] + services)
|
|
|
|
|
|
def dc_wait(args):
|
|
for service in args:
|
|
check = get_check(service)
|
|
service_wait(service, check)
|
|
|
|
|
|
def dc_on(args):
|
|
for service in args:
|
|
if service == "tiger":
|
|
tiger_on()
|
|
else:
|
|
check = get_check(service)
|
|
dc_up([service])
|
|
service_wait(service, check)
|
|
|
|
|
|
def dc_build_parallel(args):
|
|
services = args
|
|
dc_run(["build", "--parallel"] + args)
|
|
|
|
|
|
def tiger_on():
|
|
dc_on(["pulsar", "postgres"])
|
|
dc_up(["redis", "jaeger", "router"])
|
|
dc_on(["result-cache", "metadata-api", "aqe", "sql-executor", "scan-model", "afm-exec-api"])
|
|
|
|
|
|
def try_load_list(name, default):
|
|
if name in os.environ:
|
|
return split(os.environ[name])
|
|
else:
|
|
return default
|
|
|
|
|
|
DOCKER_COMPOSE = "docker-compose"
|
|
|
|
DEFAULT_DCF = ["docker-compose.yaml"]
|
|
DC_FILES = try_load_list("DCF", DEFAULT_DCF)
|
|
DC_FILES_ARGS = dc_files(DC_FILES)
|
|
|
|
SERVICES = {
|
|
"pulsar":
|
|
lambda:
|
|
curl_check("http://localhost:8080/admin/v2/tenants/public"),
|
|
"postgres":
|
|
lambda:
|
|
system("/usr/bin/pg_isready") == 0,
|
|
"redis":
|
|
lambda:
|
|
system("/usr/bin/redis-cli ping") == 0,
|
|
# AQE: /opt/bin/aqe ping
|
|
"aqe":
|
|
lambda:
|
|
True,
|
|
"metadata-api":
|
|
lambda:
|
|
curl_check("http://localhost:9008/actuator/health/readiness"),
|
|
"afm-exec-api":
|
|
lambda:
|
|
curl_check("http://localhost:9001/actuator/health/readiness"),
|
|
"result-cache":
|
|
lambda:
|
|
curl_check("http://localhost:9041/actuator/health/readiness"),
|
|
"scan-model":
|
|
lambda:
|
|
curl_check("http://localhost:9061/actuator/health/readiness"),
|
|
"sql-executor":
|
|
lambda:
|
|
curl_check("http://localhost:9101/actuator/health/readiness"),
|
|
"data-loader":
|
|
None, # co chci testovat? ze ma Exit code 0
|
|
}
|
|
|
|
COMMANDS = {
|
|
"files": lambda args: dump_files(DC_FILES),
|
|
"commands": dc_commands,
|
|
"services": lambda args: dump_services(DC_FILES),
|
|
"log": dc_log,
|
|
"deps": lambda args: dc_deps(DC_FILES, args),
|
|
"check": dc_check,
|
|
"wait": dc_wait,
|
|
"on": dc_on,
|
|
"pb": dc_build_parallel,
|
|
"bp": dc_build_parallel,
|
|
}
|
|
|
|
|
|
def main():
|
|
args = argv[1:]
|
|
action = args[0] if args else None
|
|
if action in COMMANDS:
|
|
COMMANDS[action](args[1:])
|
|
else:
|
|
exit(dc_run(args))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
try:
|
|
main()
|
|
except KeyboardInterrupt:
|
|
pass
|