|
from argparse import ArgumentParser, Namespace |
|
from json import dumps, load |
|
from logging import DEBUG, Formatter, StreamHandler, getLogger |
|
from pathlib import Path |
|
from urllib import parse, request |
|
|
|
# pylint: disable=missing-class-docstring |
|
# pylint: disable=missing-function-docstring |
|
|
|
log = getLogger(name=__name__) |
|
log.setLevel(DEBUG) |
|
|
|
console = StreamHandler() |
|
console.setLevel(DEBUG) |
|
formatter = Formatter( |
|
fmt="%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s", |
|
datefmt="%a, %d %b %Y %H:%M:%S", |
|
) |
|
console.setFormatter(formatter) |
|
log.addHandler(console) |
|
|
|
|
|
class ListTags(object): |
|
def __init__(self, images) -> None: |
|
self.images = images |
|
|
|
def auth(self, image) -> str: |
|
params = parse.urlencode( |
|
{"service": "registry.docker.io", "scope": f"repository:{image}:pull"} |
|
) |
|
req = request.Request(url=f"https://auth.docker.io/token?{params}") |
|
with request.urlopen(req) as _rep: |
|
return load(_rep).get("token") |
|
|
|
def _list_tags(self, image): |
|
if len(image.split("/")) < 2: |
|
image = Path("library").joinpath(image) |
|
req = request.Request( |
|
url=f"https://registry-1.docker.io/v2/{image}/tags/list", |
|
headers={ |
|
"Content-Type": "application/json; charset=utf-8", |
|
"Authorization": f"Bearer {self.auth(image)}", |
|
}, |
|
) |
|
with request.urlopen(req) as _rep: |
|
return load(_rep) |
|
|
|
def list_tags(self) -> tuple: |
|
if isinstance(self.images, str): |
|
return (self._list_tags(self.images),) |
|
return tuple(self._list_tags(image) for image in self.images) |
|
|
|
|
|
if __name__ == "__main__": |
|
arg = ArgumentParser(description="list docker tags.") |
|
arg.add_argument( |
|
"-i", |
|
"--indent", |
|
action="store_true", |
|
help="indent or not.", |
|
) |
|
arg.add_argument("images", nargs="+", type=str) |
|
parses: Namespace = arg.parse_args() |
|
|
|
tags = ListTags(parses.images).list_tags() |
|
indent = None |
|
if parses.indent: |
|
indent = 2 |
|
for img in parses.images: |
|
log.info( |
|
"%s", |
|
dumps( |
|
[f"{img}:{tag}" for version in tags for tag in version.get("tags")], |
|
indent=indent, |
|
), |
|
) |