abra/bin/app-json.py

134 lines
4.0 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
2021-04-02 14:05:31 +00:00
# Usage: ./app-json.py
#
# Gather metadata from Co-op Cloud apps in $ABRA_DIR/apps (default
# ~/.abra/apps), and format it as JSON so that it can be hosted here:
# https://abra-apps.autonomic.zone
from json import dump
2021-04-02 14:05:31 +00:00
from os import chdir, listdir, mkdir
from os.path import exists, expanduser
from pathlib import Path
from re import findall, search
from shlex import split
from subprocess import check_output, run
from requests import get
HOME_PATH = expanduser("~/")
CLONES_PATH = Path(f"{HOME_PATH}/.abra/apps").absolute()
SCRIPT_PATH = Path(__file__).absolute().parent
def clone_apps():
if not exists(CLONES_PATH):
mkdir(CLONES_PATH)
response = get("https://git.autonomic.zone/api/v1/orgs/coop-cloud/repos")
repos = [[p["name"], p["ssh_url"]] for p in response.json()]
skips = ("organising", "cloud.autonomic.zone", "docs.cloud.autonomic.zone", "abra")
for name, url in repos:
if name in skips:
continue
try:
if not exists(f"{CLONES_PATH}/{name}"):
run(split(f"git clone {url} {CLONES_PATH}/{name}"))
chdir(f"{CLONES_PATH}/{name}")
if not int(check_output("git branch --list | wc -l", shell=True)):
run(split("git checkout main"))
except Exception:
pass
def gen_apps_json():
apps_json = {}
for app in listdir(CLONES_PATH):
app_path = f"{CLONES_PATH}/{app}"
chdir(app_path)
output = check_output("git tag --list", shell=True)
2021-04-02 14:43:43 +00:00
tags = output.decode("utf-8").strip().split()
if not tags:
continue
for tag in tags:
apps_json[app] = {
"category": "apps",
"repository": f"https://git.autonomic.zone/coop-cloud/{app}.git",
2021-04-02 14:43:43 +00:00
"features": get_app_features(app_path, tag),
"versions": get_app_versions(app_path, tag),
}
return apps_json
2021-04-02 14:43:43 +00:00
def get_app_features(app_path, tag):
print(f"Gathering features for {app_path}, tag: {tag}")
features = {}
2021-04-02 14:43:43 +00:00
chdir(app_path)
run(f"git checkout {tag}", shell=True)
with open(f"{app_path}/README.md", "r") as handle:
contents = handle.read()
for match in findall(r"\*\*.*\s\*", contents):
2021-04-01 19:40:38 +00:00
title = search(r"(?<=\*\*).*(?=\*\*)", match).group().lower()
if title == "image":
value = {
"image": search(r"(?<=`).*(?=`)", match).group(),
"url": search(r"(?<=\().*(?=\))", match).group(),
2021-04-01 19:40:38 +00:00
"rating": match.split(",")[1].strip(),
"source": match.split(",")[-1].replace("*", "").strip(),
}
else:
value = match.split(":")[-1].replace("*", "").strip()
features[title] = value
2021-04-02 14:43:43 +00:00
run(f"git checkout HEAD", shell=True)
return features
2021-04-02 14:43:43 +00:00
def get_app_versions(app_path, tag):
print(f"Gathering versions for {app_path}, tag: {tag}")
versions = []
chdir(app_path)
2021-04-02 14:43:43 +00:00
run(f"git checkout {tag}", shell=True)
2021-04-02 14:43:43 +00:00
services_command = "yq e '.services | keys | .[]' compose*.yml"
services = check_output(services_command, shell=True).decode("utf-8").split()
2021-04-02 14:43:43 +00:00
for service in services:
images_command = f"yq e '.services.{service}.image' compose*.yml"
images = check_output(images_command, shell=True).decode("utf-8").split()
2021-04-02 14:43:43 +00:00
for image in images:
if image in ("null", "---"):
continue
2021-04-02 14:43:43 +00:00
digest_command = f"skopeo inspect docker://{image} | jq '.Digest'"
output = check_output(digest_command, shell=True).decode("utf-8")
digest = output.strip().split(":")[-1][:8]
versions.append({service: {"image": image, "tag": tag, "digest": digest}})
2021-04-02 14:43:43 +00:00
run(f"git checkout HEAD", shell=True)
return versions
clone_apps()
target = f"{SCRIPT_PATH}/../deploy/abra-apps.autonomic.zone/abra-apps.json"
with open(target, "w", encoding="utf-8") as handle:
dump(gen_apps_json(), handle, ensure_ascii=False, indent=4)
print(f"Output saved to {target}")