added tests, made few changes in registry.py

This commit is contained in:
Andrey Pohilko
2017-02-10 19:46:11 +06:00
parent 5e0b82c5c3
commit 2c632c9086
4 changed files with 298 additions and 38 deletions

View File

@@ -34,31 +34,41 @@ import argparse
# number of image versions to keep
CONST_KEEP_LAST_VERSIONS = 10
# this class is created for testing
class Requests:
def request(self, method, url, **kwargs):
return requests.request(method, url, **kwargs)
# class to manipulate registry
class Registry:
username = ""
password = ""
hostname = ""
no_validate_ssl = False;
# this is required for proper digest processing
HEADERS = {"Accept":
"application/vnd.docker.distribution.manifest.v2+json"}
# store last error if any
__error = None
def __init__(self):
self.username = None
self.password = None
self.hostname = None
self.no_validate_ssl = False
self.http = None
self.last_error = None
def __init__(self, host, login, no_validate_ssl):
@staticmethod
def create(host, login, no_validate_ssl):
r = Registry
if login != None:
if not ':' in login:
print "Please provide -l in the form USER:PASSWORD"
r.last_error = "Please provide -l in the form USER:PASSWORD"
print(r.last_error)
exit(1)
(r.username, r.password) = login.split(':')
(self.username, self.password) = login.split(':')
r.hostname = host
r.no_validate_ssl = no_validate_ssl
r.http = Requests
return r
self.hostname = host
self.no_validate_ssl = no_validate_ssl
@staticmethod
def __atoi(text):
@@ -73,25 +83,26 @@ class Registry:
'''
return [ Registry.__atoi(c) for c in re.split('(\d+)', text) ]
def send(self, path, method="GET"):
try:
result = requests.request(
method, "{0}{1}".format(self.hostname, path),
headers = self.HEADERS,
auth=(None if self.username == ""
else (self.username, self.password)),
verify = not self.no_validate_ssl)
except Exception as error:
print "cannot connect to {0}\nerror {1}".format(
self.hostname,
error)
exit(1)
def send(self, path, method="GET"):
# try:
result = self.http.request(
method, "{0}{1}".format(self.hostname, path),
headers = self.HEADERS,
auth=(None if self.username == ""
else (self.username, self.password)),
verify = not self.no_validate_ssl)
# except Exception as error:
# print("cannot connect to {0}\nerror {1}".format(
# self.hostname,
# error))
# exit(1)
if str(result.status_code)[0] == '2':
self.__error = None
self.last_error = None
return result
self.__error=result.status_code
self.last_error=result.status_code
return None
def list_images(self):
@@ -106,7 +117,11 @@ class Registry:
if result == None:
return []
tags_list = json.loads(result.text)['tags']
try:
tags_list = json.loads(result.text)['tags']
except ValueError:
self.last_error = "list_tags: invalid json response"
return []
if tags_list != None:
tags_list.sort(key=Registry.natural_keys)
@@ -118,8 +133,7 @@ class Registry:
image_name, tag), method="HEAD")
if image_headers == None:
print " tag digest not found: {0}".format(self.__error)
print(" tag digest not found: {0}".format(self.last_error))
return None
tag_digest = image_headers.headers['Docker-Content-Digest']
@@ -144,7 +158,7 @@ class Registry:
image_name, tag_digest), method="DELETE")
if delete_result == None:
print "failed, error: {0}".format(self.__error)
print "failed, error: {0}".format(self.last_error)
return False
tag_digests_to_ignore.append(tag_digest)
@@ -163,7 +177,7 @@ class Registry:
image_name, layer_digest), method='DELETE')
if delete_result == None:
print "failed, error: {0}".format(self.__error)
print "failed, error: {0}".format(self.last_error)
return False
print "done"
@@ -175,17 +189,18 @@ class Registry:
image_name, tag))
if layers_result == None:
print "error {0}".format(self.__error)
print "error {0}".format(self.last_error)
return []
if json.loads(layers_result.text)['schemaVersion'] == 1:
layers = json.loads(layers_result.text)['fsLayers']
json_result = json.loads(layers_result.text)
if json_result['schemaVersion'] == 1:
layers = json_result['fsLayers']
else:
layers = json.loads(layers_result.text)['layers']
layers = json_result['layers']
return layers
def parse_args():
def parse_args(args = None):
parser = argparse.ArgumentParser(
description="List or delete images from Docker registry",
formatter_class=argparse.RawDescriptionHelpFormatter,
@@ -290,7 +305,7 @@ for more detail on garbage collection read here:
const=True)
return parser.parse_args()
return parser.parse_args(args)
def delete_tags(
@@ -335,7 +350,7 @@ def main_loop(args):
if args.no_validate_ssl:
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
registry = Registry(args.host, args.login, args.no_validate_ssl)
registry = Registry.create(args.host, args.login, args.no_validate_ssl)
if args.delete:
print "Will delete all but {0} last tags".format(keep_last_versions)