feat: source find
This commit is contained in:
@@ -2,51 +2,99 @@ import docker
|
|||||||
|
|
||||||
client = docker.from_env()
|
client = docker.from_env()
|
||||||
running_containers = []
|
running_containers = []
|
||||||
# sleeping_containers = []
|
|
||||||
for c in client.containers.list(all=True):
|
for c in client.containers.list(): # только запущенные контейнеры
|
||||||
info = c.attrs # словарь со всеми данными
|
info = c.attrs # словарь со всеми данными
|
||||||
image = info["Config"]["Image"] # образ
|
image = info["Config"]["Image"] # образ
|
||||||
created = info["Created"] # время создания
|
created = info["Created"] # время создания
|
||||||
labels = info["Config"].get("Labels", {}) # лейблы
|
ports = info["NetworkSettings"]["Ports"] # проброшенные порты
|
||||||
ports = info["NetworkSettings"]["Ports"] # проброшенные порты ЪЪЪ
|
|
||||||
mounts = info.get("Mounts", []) # маунты
|
mounts = info.get("Mounts", []) # маунты
|
||||||
status = c.status # статус контейнера (вкл-выкл)
|
status = c.status # статус контейнера (д.б. "running")
|
||||||
if tags := c.image.tags:
|
labels_container = info["Config"].get("Labels", {}) or {}
|
||||||
ver = c.image.tags[0].split(':')[-1] # версия
|
image_cfg = c.image.attrs.get("Config", {}) or {}
|
||||||
else: ver = None
|
image_labels = image_cfg.get("Labels", {}) or {}
|
||||||
workdir = info["Config"].get("WorkingDir") or '/' # рабочая директория
|
all_labels = {**image_labels, **labels_container}
|
||||||
|
source_url = (
|
||||||
|
all_labels.get("org.opencontainers.image.source")
|
||||||
|
or all_labels.get("org.opencontainers.image.url")
|
||||||
|
or all_labels.get("org.opencontainers.image.documentation")
|
||||||
|
or all_labels.get("org.label-schema.vcs-url")
|
||||||
|
or all_labels.get("org.label-schema.url")
|
||||||
|
)
|
||||||
|
source_revision = (
|
||||||
|
all_labels.get("org.opencontainers.image.revision")
|
||||||
|
or all_labels.get("org.label-schema.vcs-ref")
|
||||||
|
)
|
||||||
|
image_version_label = (
|
||||||
|
all_labels.get("org.opencontainers.image.version")
|
||||||
|
or all_labels.get("org.label-schema.version")
|
||||||
|
)
|
||||||
|
|
||||||
|
# Версия из тега образа
|
||||||
|
tags = c.image.tags
|
||||||
|
if tags:
|
||||||
|
ver = tags[0].split(":", 1)[-1]
|
||||||
|
else:
|
||||||
|
ver = None
|
||||||
|
|
||||||
|
# Рабочая директория
|
||||||
|
workdir = info["Config"].get("WorkingDir") or "/"
|
||||||
|
|
||||||
|
# Поиск файлов зависимостей
|
||||||
|
req_paths = []
|
||||||
|
language = None
|
||||||
|
|
||||||
req_find_cmd = (
|
req_find_cmd = (
|
||||||
f"sh -c \"cd {workdir} 2>/dev/null && "
|
f"cd {workdir} 2>/dev/null || cd /; "
|
||||||
"find . -maxdepth 3 \\( "
|
"find . -maxdepth 3 \\( "
|
||||||
"-name 'requirements*.txt' -o "
|
"-name 'requirements*.txt' -o "
|
||||||
"-name 'Pipfile' -o "
|
"-name 'Pipfile' -o "
|
||||||
"-name 'pyproject.toml' -o "
|
"-name 'pyproject.toml' -o "
|
||||||
"-name 'package.json' "
|
"-name 'package.json' -о "
|
||||||
"\\) 2>/dev/null | head -n 5\""
|
"-name 'go.mod' "
|
||||||
|
"\\) 2>/dev/null | head -n 5"
|
||||||
)
|
)
|
||||||
req = c.exec_run(req_find_cmd)[1].decode() # путь до файла с зависимостями
|
|
||||||
req_paths = [line.strip() for line in req.splitlines() if line.strip()]
|
|
||||||
|
|
||||||
language = None
|
req_res = c.exec_run(["sh", "-lc", req_find_cmd])
|
||||||
|
if req_res.exit_code == 0:
|
||||||
|
req_out = req_res.output.decode(errors="ignore")
|
||||||
|
req_paths = [line.strip() for line in req_out.splitlines() if line.strip()]
|
||||||
|
else:
|
||||||
|
req_paths = []
|
||||||
|
|
||||||
|
# Определяем язык по файлам зависимостей
|
||||||
for p in req_paths:
|
for p in req_paths:
|
||||||
if "requirements" in p.lower() or p.endswith("Pipfile") or p.endswith("pyproject.toml"):
|
lower = p.lower()
|
||||||
|
if "requirements" in lower or p.endswith("Pipfile") or p.endswith("pyproject.toml"):
|
||||||
language = "python"
|
language = "python"
|
||||||
break
|
break
|
||||||
if p.endswith("package.json"):
|
if p.endswith("package.json"):
|
||||||
language = "nodejs"
|
language = "nodejs"
|
||||||
break
|
break
|
||||||
|
if p.endswith("go.mod"):
|
||||||
|
language = "go"
|
||||||
|
break
|
||||||
|
|
||||||
|
# Поиск "главных" файлов кода
|
||||||
|
code_paths = []
|
||||||
|
|
||||||
code_find_cmd = (
|
code_find_cmd = (
|
||||||
f"cd {workdir} 2>/dev/null || cd /; "
|
f"cd {workdir} 2>/dev/null || cd /; "
|
||||||
"find . -maxdepth 4 -type f \\( "
|
"find . -maxdepth 4 -type f \\( "
|
||||||
"-name 'main.*' -o "
|
"-name 'main.*' -о "
|
||||||
"-name 'app.*' -o "
|
"-name 'app.*' -o "
|
||||||
"-name 'index.*' "
|
"-name 'index.*' "
|
||||||
"\\) 2>/dev/null | head -n 10"
|
"\\) 2>/dev/null | head -n 10"
|
||||||
)
|
)
|
||||||
code = c.exec_run(code_find_cmd)
|
|
||||||
code_paths = [line.strip() for line in code[1].decode(errors='ignore').splitlines() if line.strip()]
|
|
||||||
|
|
||||||
|
code_res = c.exec_run(["sh", "-lc", code_find_cmd])
|
||||||
|
if code_res.exit_code == 0:
|
||||||
|
code_out = code_res.output.decode(errors="ignore")
|
||||||
|
code_paths = [line.strip() for line in code_out.splitlines() if line.strip()]
|
||||||
|
else:
|
||||||
|
code_paths = []
|
||||||
|
|
||||||
|
# Если по зависимостям язык не определился — пробуем по расширениям файлов кода
|
||||||
if language is None:
|
if language is None:
|
||||||
for p in code_paths:
|
for p in code_paths:
|
||||||
p_lower = p.lower()
|
p_lower = p.lower()
|
||||||
@@ -72,16 +120,31 @@ for c in client.containers.list(all=True):
|
|||||||
language = "java"
|
language = "java"
|
||||||
break
|
break
|
||||||
|
|
||||||
container = {
|
container_data = {
|
||||||
"name": c.name,
|
"name": c.name,
|
||||||
"version": ver,
|
"version": ver,
|
||||||
"image": image,
|
"image": image,
|
||||||
"id": c.id[:12],
|
"id": c.id[:12],
|
||||||
"create_time": created,
|
"create_time": created,
|
||||||
"mounted_data": mounts,
|
"mounted_data": mounts,
|
||||||
"labels": labels
|
"labels": labels_container,
|
||||||
|
"all_labels": all_labels,
|
||||||
|
"source_url": source_url,
|
||||||
|
"source_revision": source_revision,
|
||||||
|
"image_version_label": image_version_label,
|
||||||
|
"language": language,
|
||||||
|
"dep_files": req_paths,
|
||||||
|
"code_files": code_paths,
|
||||||
}
|
}
|
||||||
if status == "running":
|
running_containers.append(container_data)
|
||||||
running_containers.append(container)
|
|
||||||
# else:
|
# Проверочный вывод
|
||||||
# sleeping_containers.append(container)
|
for c in running_containers:
|
||||||
|
print(f"{c['name']} ({c['image']})")
|
||||||
|
print(f" id: {c['id']}, created: {c['create_time']}")
|
||||||
|
print(f" tag_version: {c['version']}, label_version: {c['image_version_label']}")
|
||||||
|
print(f" language: {c['language']}")
|
||||||
|
print(f" source: {c['source_url']} rev: {c['source_revision']}")
|
||||||
|
print(f" dep_files: {c['dep_files']}")
|
||||||
|
print(f" code_files: {c['code_files']}")
|
||||||
|
print()
|
||||||
|
|||||||
Reference in New Issue
Block a user