mirror of
https://github.com/goharbor/harbor.git
synced 2024-09-01 16:59:37 +02:00
1. Fix E2E quotas issue, push the same image but with different name; 2. Add checkpoint for robot account test; 3. Upgraded docker and containerd in E2E image; 4. Package base image sample(busybox) into E2E image, so in E2E container, all local docker images can be cleaned up, once base image is needed for building image, it can be loaded locally; 5. Adapt OIDC service of supporting LDAP user, and add OIDC group user test; 6. Restart docker deamon before content trust test, both in API and UI test; 7. Add retry for keyword "Add A Tag Immutability Rule"; 8. Fix tag retention test issue, missing click angle icon, and enhance checkpoint of dry run and real run; 9. Fix schedule test issue for wrong cron string; 10. Disable quotas verification, it's not stable for script defect; Signed-off-by: danfengliu <danfengl@vmware.com>
250 lines
12 KiB
Python
250 lines
12 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import base
|
|
import subprocess
|
|
import json
|
|
from testutils import DOCKER_USER, DOCKER_PWD, BASE_IMAGE, BASE_IMAGE_ABS_PATH_NAME
|
|
|
|
try:
|
|
import docker
|
|
except ImportError:
|
|
import pip
|
|
pip.main(['install', 'docker'])
|
|
import docker
|
|
|
|
def docker_info_display():
|
|
command = ["docker", "info", "-f", "'{{.OSType}}/{{.Architecture}}'"]
|
|
print("Docker Info: ", command)
|
|
ret = base.run_command(command)
|
|
print("Command return: ", ret)
|
|
|
|
def docker_login_cmd(harbor_host, username, password, cfg_file = "./tests/apitests/python/update_docker_cfg.sh", enable_manifest = True):
|
|
if username == "" or password == "":
|
|
print("[Warnig]: No docker credential was provided.")
|
|
return
|
|
command = ["sudo", "docker", "login", harbor_host, "-u", username, "-p", password]
|
|
print( "Docker Login Command: ", command)
|
|
base.run_command(command)
|
|
if enable_manifest == True:
|
|
try:
|
|
ret = subprocess.check_output([cfg_file], shell=False)
|
|
print("docker login cmd ret:", ret)
|
|
except subprocess.CalledProcessError as exc:
|
|
raise Exception("Failed to update docker config, error is {} {}.".format(exc.returncode, exc.output))
|
|
|
|
def docker_manifest_create(index, manifests):
|
|
command = ["sudo", "docker","manifest","create", "--amend", index]
|
|
command.extend(manifests)
|
|
print( "Docker Manifest Command: ", command)
|
|
base.run_command(command)
|
|
|
|
def docker_images_all_list():
|
|
command = ["sudo", "docker","images","-a"]
|
|
base.run_command(command)
|
|
|
|
def docker_load_image(image):
|
|
command = ["sudo", "docker","load","-i", image]
|
|
base.run_command(command)
|
|
|
|
def docker_image_clean_all():
|
|
docker_images_all_list()
|
|
command = ["sudo docker rmi -f $(docker images -a -q)"]
|
|
base.run_command_with_popen(command)
|
|
command = ["sudo", "docker","system", "prune", "-a", "-f"]
|
|
base.run_command(command)
|
|
docker_images_all_list()
|
|
|
|
def docker_manifest_push(index):
|
|
command = ["sudo", "docker","manifest","push",index]
|
|
print( "Docker Manifest Command: ", command)
|
|
ret = base.run_command(command)
|
|
index_sha256=""
|
|
manifest_list=[]
|
|
for line in ret.split("\n"):
|
|
if line[:7] == "sha256:":
|
|
index_sha256 = line
|
|
if line.find('Pushed ref') == 0:
|
|
manifest_list.append(line[-71:])
|
|
return index_sha256, manifest_list
|
|
|
|
def docker_manifest_push_to_harbor(index, manifests, harbor_server, username, password, cfg_file = "./tests/apitests/python/update_docker_cfg.sh"):
|
|
docker_login_cmd(harbor_server, username, password, cfg_file=cfg_file)
|
|
docker_manifest_create(index, manifests)
|
|
return docker_manifest_push(index)
|
|
|
|
def list_repositories(harbor_host, username, password, n = None, last = None):
|
|
if n is not None and last is not None:
|
|
command = ["curl", "-s", "-u", username+":"+password, "https://"+harbor_host+"/v2/_catalog"+"?n=%d"%n+"&last="+last, "--insecure"]
|
|
elif n is not None:
|
|
command = ["curl", "-s", "-u", username+":"+password, "https://"+harbor_host+"/v2/_catalog"+"?n=%d"%n, "--insecure"]
|
|
else:
|
|
command = ["curl", "-s", "-u", username+":"+password, "https://"+harbor_host+"/v2/_catalog", "--insecure"]
|
|
print( "List Repositories Command: ", command)
|
|
ret = base.run_command(command)
|
|
repos = json.loads(ret).get("repositories","")
|
|
return repos
|
|
|
|
def list_image_tags(harbor_host, repository, username, password, n = None, last = None):
|
|
if n is not None and last is not None:
|
|
command = ["curl", "-s", "-u", username+":"+password, "https://"+harbor_host+"/v2/"+repository+"/tags/list"+"?n=%d"%n+"&last="+last, "--insecure"]
|
|
elif n is not None:
|
|
command = ["curl", "-s", "-u", username+":"+password, "https://"+harbor_host+"/v2/"+repository+"/tags/list"+"?n=%d"%n, "--insecure"]
|
|
else:
|
|
command = ["curl", "-s", "-u", username+":"+password, "https://"+harbor_host+"/v2/"+repository+"/tags/list", "--insecure"]
|
|
print( "List Image Tags Command: ", command)
|
|
ret = base.run_command(command)
|
|
tags = json.loads(ret).get("tags","")
|
|
return tags
|
|
|
|
class DockerAPI(object):
|
|
def __init__(self):
|
|
self.DCLIENT = docker.APIClient(base_url='unix://var/run/docker.sock',version='auto',timeout=30)
|
|
self.DCLIENT2 = docker.from_env()
|
|
|
|
def docker_login(self, registry, username, password, expected_error_message = None):
|
|
ret = ""
|
|
err_message = ""
|
|
if username == "" or password == "":
|
|
print("[Warnig]: No docker credential was provided.")
|
|
return
|
|
if expected_error_message == "":
|
|
expected_error_message = None
|
|
if registry == "docker":
|
|
registry = None
|
|
try:
|
|
print("Docker login: {}:{}:{}".format(registry,username,password))
|
|
ret = self.DCLIENT.login(registry = registry, username=username, password=password)
|
|
except Exception as err:
|
|
print( "Docker image pull catch exception:", str(err))
|
|
err_message = str(err)
|
|
if expected_error_message is None:
|
|
raise Exception(r" Docker pull image {} failed, error is [{}]".format (image, str(err)))
|
|
else:
|
|
print("Docker image login did not catch exception and return message is:", ret)
|
|
err_message = ret
|
|
finally:
|
|
if expected_error_message is not None:
|
|
if str(err_message).lower().find(expected_error_message.lower()) < 0:
|
|
raise Exception(r" Failed to catch error [{}] when login registry {}, return message: {}".format (expected_error_message, registry, err_message))
|
|
else:
|
|
print(r"Docker image login got expected error message:{}".format(expected_error_message))
|
|
else:
|
|
if str(err_message).lower().find("error".lower()) >= 0:
|
|
raise Exception(r" It's was not suppose to catch error when login registry {}, return message is [{}]".format (registry, err_message))
|
|
|
|
def docker_image_pull(self, image, tag = None, expected_error_message = None, is_clean_all_img = True):
|
|
ret = ""
|
|
err_message = ""
|
|
if tag is not None:
|
|
_tag = tag
|
|
else:
|
|
_tag = "latest"
|
|
if expected_error_message is "":
|
|
expected_error_message = None
|
|
try:
|
|
ret = self.DCLIENT.pull(r'{}:{}'.format(image, _tag))
|
|
except Exception as err:
|
|
print( "Docker image pull catch exception:", str(err))
|
|
err_message = str(err)
|
|
if expected_error_message is None:
|
|
raise Exception(r" Docker pull image {} failed, error is [{}]".format (image, str(err)))
|
|
else:
|
|
print("Docker image pull did not catch exception and return message is:", ret)
|
|
err_message = ret
|
|
finally:
|
|
if expected_error_message is not None:
|
|
if str(err_message).lower().find(expected_error_message.lower()) < 0:
|
|
raise Exception(r" Failed to catch error [{}] when pull image {}, return message: {}".format (expected_error_message, image, err_message))
|
|
else:
|
|
print(r"Docker image pull got expected error message:{}".format(expected_error_message))
|
|
else:
|
|
if str(err_message).lower().find("error".lower()) >= 0:
|
|
raise Exception(r" It's was not suppose to catch error when pull image {}, return message is [{}]".format (image, err_message))
|
|
if is_clean_all_img:
|
|
docker_image_clean_all()
|
|
|
|
def docker_image_tag(self, image, harbor_registry, tag = None):
|
|
_tag = base._random_name("tag")
|
|
if tag is not None:
|
|
_tag = tag
|
|
ret = ""
|
|
try:
|
|
ret = self.DCLIENT.tag(image, harbor_registry, _tag, force=True)
|
|
print("Docker image tag commond return:", ret)
|
|
return harbor_registry, _tag
|
|
except docker.errors.APIError as err:
|
|
raise Exception(r" Docker tag image {} failed, error is [{}]".format (image, str(err)))
|
|
|
|
def docker_image_push(self, harbor_registry, tag, expected_error_message = None):
|
|
ret = ""
|
|
err_message = ""
|
|
docker_images_all_list()
|
|
if expected_error_message is "":
|
|
expected_error_message = None
|
|
try:
|
|
ret = self.DCLIENT.push(harbor_registry, tag)
|
|
except Exception as err:
|
|
print( "Docker image push catch exception:", str(err))
|
|
err_message = str(err)
|
|
if expected_error_message is None:
|
|
raise Exception(r" Docker push image {} failed, error is [{}]".format (image, str(err)))
|
|
else:
|
|
print("Docker image push did not catch exception and return message is:", ret)
|
|
err_message = ret
|
|
finally:
|
|
if expected_error_message is not None:
|
|
if str(err_message).lower().find(expected_error_message.lower()) < 0:
|
|
raise Exception(r" Failed to catch error [{}] when push image {}, return message: {}".format (expected_error_message, harbor_registry, err_message))
|
|
else:
|
|
print(r"Docker image push got expected error message:{}".format(expected_error_message))
|
|
else:
|
|
if str(err_message).lower().find("error".lower()) >= 0:
|
|
raise Exception(r" It's was not suppose to catch error when push image {}, return message is [{}]".format (harbor_registry, err_message))
|
|
docker_images_all_list()
|
|
|
|
def docker_image_build(self, harbor_registry, tags=None, size=1, expected_error_message = None):
|
|
ret = ""
|
|
err_message = ""
|
|
docker_images_all_list()
|
|
try:
|
|
baseimage = BASE_IMAGE['name'] + ":" + BASE_IMAGE['tag']
|
|
if not self.DCLIENT.images(name=baseimage):
|
|
print( "Docker load is triggered when building {}".format(harbor_registry))
|
|
docker_load_image(BASE_IMAGE_ABS_PATH_NAME)
|
|
docker_images_all_list()
|
|
c = self.DCLIENT.create_container(image=baseimage,
|
|
command='dd if=/dev/urandom of=test bs=1M count={}'.format(size))
|
|
self.DCLIENT.start(c)
|
|
self.DCLIENT.wait(c)
|
|
if not tags:
|
|
tags=['latest']
|
|
firstrepo="{}:{}".format(harbor_registry, tags[0])
|
|
#self.DCLIENT.commit(c, firstrepo)
|
|
self.DCLIENT2.containers.get(c).commit(harbor_registry, tags[0])
|
|
for tag in tags[1:]:
|
|
repo="{}:{}".format(harbor_registry, tag)
|
|
self.DCLIENT.tag(firstrepo, repo)
|
|
for tag in tags:
|
|
repo="{}:{}".format(harbor_registry, tag)
|
|
ret = self.DCLIENT.push(repo)
|
|
print("docker_image_push ret:", ret)
|
|
print("build image {} with size {}".format(repo, size))
|
|
self.DCLIENT.remove_container(c)
|
|
except Exception as err:
|
|
print( "Docker image build catch exception:", str(err))
|
|
err_message = str(err)
|
|
if expected_error_message is None:
|
|
raise Exception(r" Docker push image {} failed, error is [{}]".format (harbor_registry, str(err)))
|
|
else:
|
|
print("Docker image build did not catch exception and return message is:", ret)
|
|
err_message = ret
|
|
finally:
|
|
if expected_error_message is not None:
|
|
if str(err_message).lower().find(expected_error_message.lower()) < 0:
|
|
raise Exception(r" Failed to catch error [{}] when build image {}, return message: {}".format (expected_error_message, harbor_registry, err_message))
|
|
else:
|
|
print(r"Docker image build got expected error message: {}".format(expected_error_message))
|
|
else:
|
|
if str(err_message).lower().find("error".lower()) >= 0:
|
|
raise Exception(r" It's was not suppose to catch error when build image {}, return message is [{}]".format (harbor_registry, err_message))
|
|
docker_image_clean_all() |