harbor/tests/apitests/python/library/docker_api.py
danfengliu acc027afd7 Remove deploytment of python3.6 and set dns for docker
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>
2021-03-11 17:53:36 +08:00

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))