Skip to content

Commit

Permalink
feat(nicegui): show list of all images stored in container registry (#43
Browse files Browse the repository at this point in the history
)
  • Loading branch information
tepene committed May 15, 2024
1 parent b40e0dd commit 83f047f
Show file tree
Hide file tree
Showing 8 changed files with 417 additions and 10 deletions.
40 changes: 34 additions & 6 deletions anvil/nicegui/pages/registry.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,38 @@
import pandas
import humanize
from nicegui import ui
import os
from utils.registry import DockerRegistry


## TODO: this should be async but I currently don't know how to implement this without button press
def get_image_info() -> pandas.DataFrame:
registry = DockerRegistry()
all_image_info = registry.get_all_image_info()
if isinstance(all_image_info, list) and len(all_image_info) > 0:
data = pandas.json_normalize(
all_image_info,
record_path=["tags"],
meta=[["name"]],
meta_prefix="image_",
).assign(
size=lambda x: x["manifest.layers"].apply(
lambda layers: sum(layer["size"] for layer in layers)
)
)
data = data[["image_name", "name", "size"]].rename(
columns={"image_name": "image", "name": "tag", "size": "size"}
)
data["size"] = data["size"].apply(humanize.naturalsize)
return data
else:
ui.notify(message="No images found")
data = pandas.DataFrame(columns=["image_name", "tag", "size"])
return data


def content() -> None:
project_root = os.environ['NICEGUI_DIR']
ui.label("Work in progress...").classes("text-h6")
ui.image(project_root + "/pages/assets/work-in-progress.png").classes(
"w-[200%]"
)
with ui.row().classes("w-full"):
with ui.card().classes("w-full"):
ui.label("Image Overview").classes("text-h5")
data = get_image_info()
ui.table.from_pandas(df=data).classes("w-full")
65 changes: 65 additions & 0 deletions anvil/nicegui/utils/registry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import requests
from nicegui import ui


class DockerRegistry:

def __init__(
self,
*,
registry_url: str = "https://registry.ublue.local",
registry_root_cert: str = "/data/ublue-os_forge-root.pem",
) -> None:
"""
Docker Registry integration for ublue-os forge
"""

self.registry_url = registry_url
self.registry_root_cert = registry_root_cert

def get_repositories(self) -> list:
endpoint = f"{self.registry_url}/v2/_catalog"
response = requests.get(url=endpoint, verify=self.registry_root_cert)
if response.status_code == 200:
repositories = response.json()["repositories"]
else:
with self, ui.notify() as notify:
notify(message=f"Error: {response.text}")
return repositories

def get_image_tags(self, image_name=str) -> dict:
endpoint = f"{self.registry_url}/v2/{image_name}/tags/list"
response = requests.get(url=endpoint, verify=self.registry_root_cert)
if response.status_code == 200:
tags = response.json()["tags"]
else:
with self, ui.notify() as notify:
notify(message=f"Error: {response.text}")
return tags

def get_image_manifest(self, image_name=str, image_tag=str) -> dict:
endpoint = f"{self.registry_url}/v2/{image_name}/manifests/{image_tag}"
headers = {"accept": "application/vnd.oci.image.manifest.v1+json"}
response = requests.get(
url=endpoint, verify=self.registry_root_cert, headers=headers
)
if response.status_code == 200:
manifest = response.json()
else:
with self, ui.notify() as notify:
notify(message=f"Error: {response.text}")
return manifest

def get_all_image_info(self, image_name=str) -> list:
repositories = self.get_repositories()
all_image_info = []
for repository in repositories:
tags = self.get_image_tags(image_name=repository)
for tag in tags:
manifest = self.get_image_manifest(image_name=repository, image_tag=tag)
image_info = {
"name": repository,
"tags": [{"name": tag, "manifest": manifest}],
}
all_image_info.append(image_info)
return all_image_info
306 changes: 305 additions & 1 deletion anvil/poetry.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions anvil/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ ansible-core = "^2.16"
jmespath = "^1.0"
nicegui = "^1.4.23"
ansible-runner = "^2.3.6"
requests = "^2.31.0"
pandas = "^2.2.2"
humanize = "^4.9.0"

[tool.poetry.group.dev.dependencies]
ansible-lint = { version = "^24.2", markers = 'platform_system != "Windows"' } # https://github.com/ansible/ansible-lint/issues/2730#issuecomment-1330406601
Expand Down
Binary file added docs/assets/gui_registry.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 4 additions & 3 deletions docs/gui.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ we are [working](https://github.com/ublue-os/forge/issues/35) on it.

### Registry

Currently nothing to see here. The goal is to display some
information about the docker registry <registry.ublue.local> here.
Like a list of all available images you have uploaded etc.
Here you get an overview of all images available in
the container registry `registry.ublue.local`.

![registry](./assets/gui_registry.png)

### About

Expand Down
4 changes: 4 additions & 0 deletions forge-pod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ spec:
- name: ublue-os_forge-data-pvc
persistentVolumeClaim:
claimName: ublue-os_forge-data
hostAliases:
- ip: ${FORGE_HOST_IP_ADDRESS}
hostnames:
- registry.${FORGE_DOMAIN_NAME}
containers:
- name: ansible.${FORGE_DOMAIN_NAME}
image: anvil # will be built on pod start
Expand Down
2 changes: 2 additions & 0 deletions forge.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export FORGE_POD_NAME_PRE_AMBLE="ublue-os_forge-"
export FORGE_POD_NAME_REVERSE_PROXY=${FORGE_POD_NAME_PRE_AMBLE}rvproxy
export FORGE_POD_NAME_REGISTRY=${FORGE_POD_NAME_PRE_AMBLE}registry
export FORGE_POD_NAME_ANVIL=${FORGE_POD_NAME_PRE_AMBLE}anvil
export FORGE_HOST_IP_ADDRESS=$(hostname -I | awk '{print $1}')


# Functions
function setup {
Expand Down

0 comments on commit 83f047f

Please sign in to comment.