-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathimage_tags.py
More file actions
90 lines (76 loc) · 2.33 KB
/
image_tags.py
File metadata and controls
90 lines (76 loc) · 2.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import argparse
import json
import logging
from datetime import datetime
from packaging import version
import requests
log = logging
TAGS = "https://registry.hub.docker.com/v2/repositories/{image}/tags/"
LIB_PREFIX = "library/"
TAG_STORE = {}
def api_call(url):
result = requests.get(url)
if not result.ok:
log.error(f"{result}, {result.status_code}, {result.url}")
return {}
data = result.json()
tags = {}
for entry in data["results"]:
tags[entry["name"]] = datetime.strptime(entry["last_updated"], "%Y-%m-%dT%H:%M:%S.%fZ") if entry["last_updated"] else "------"
if data['next']:
tags.update(api_call(data['next']))
return tags
def get_tags(image):
if "/" not in image:
image = LIB_PREFIX + image
if ":" in image:
image = image.split(":")[0]
url = TAGS.format(image=image)
tags = api_call(url)
if not len(tags):
raise ValueError(f"Unknown image '{image}'")
return tags
def replace(string, replacements):
for k,v in replacements:
string = string.replace(k,v)
return string
def compare(base, other, match_suffix=False, replacements=[("-","+"),]):
if match_suffix and "-" in base:
suffix = base.split("-")[-1]
if not other.endswith(suffix):
return False
base = replace(base, replacements)
other = replace(other, replacements)
v1 = version.parse(base)
v2 = version.parse(other)
result = v1 < v2
log.debug(f"{v1} < {v2}: {result}")
return result
def get_new_tags(image, match_suffix=False):
if not ":" in image:
log.warn("using implicit latest, skip")
return
image_name, current_tag = image.split(":")
if not image_name in TAG_STORE:
TAG_STORE[image_name] = get_tags(image_name)
new_tags = {}
for tag in TAG_STORE[image_name]:
log.debug("check("+str(tag)+")")
if compare(current_tag, tag, match_suffix):
log.debug("NEWER!!!")
update = TAG_STORE[image_name][tag]
new_tags[tag] = str(update)
log.debug(tag)
return new_tags
if __name__=="__main__":
parser = argparse.ArgumentParser(description="list new docker image tags")
parser.add_argument("image", nargs="+")
parser.add_argument("--list", "-l", action="store_true")
args= parser.parse_args()
for i in args.image:
log.debug(i)
if args.list:
print(json.dumps({k:str(v) for k,v in get_tags(i).items()}, indent=1))
else:
print(json.dumps(get_new_tags(i), indent=1))
# call with: `python3 image_tags.py -i alpine ubuntu:xenial debian`