mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-02 00:29:50 +01:00
acc027afd7
1. Docker v20 is the default version for git action, dns should be set manually. Python v3.8 is the default version for git action, so remove deployment for python v3.6. 2. Some of API tests would be affect by docker v20, like manifest get message will not be triggered if there is one locally, to avoid this impact, API tests will be tested with docker E2E image, in this image, docker v19 is enabled. Signed-off-by: danfengliu <danfengl@vmware.com>
237 lines
12 KiB
Python
237 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_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):
|
|
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))
|
|
|
|
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 = ""
|
|
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)
|
|
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)) |