2018-11-01 11:26:04 +01:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
import base
|
2020-03-01 10:57:40 +01:00
|
|
|
import subprocess
|
2020-03-28 04:29:28 +01:00
|
|
|
import json
|
2018-11-01 11:26:04 +01:00
|
|
|
|
|
|
|
try:
|
|
|
|
import docker
|
|
|
|
except ImportError:
|
|
|
|
import pip
|
|
|
|
pip.main(['install', 'docker'])
|
|
|
|
import docker
|
|
|
|
|
2020-04-22 10:44:10 +02:00
|
|
|
def docker_info_display():
|
|
|
|
command = ["docker", "info", "-f", "'{{.OSType}}/{{.Architecture}}'"]
|
2020-07-30 10:04:14 +02:00
|
|
|
print("Docker Info: ", command)
|
2020-04-22 10:44:10 +02:00
|
|
|
ret = base.run_command(command)
|
2020-07-30 10:04:14 +02:00
|
|
|
print("Command return: ", ret)
|
2020-04-22 10:44:10 +02:00
|
|
|
|
2020-09-15 12:51:40 +02:00
|
|
|
def docker_login_cmd(harbor_host, user, password, cfg_file = "./tests/apitests/python/update_docker_cfg.sh", enable_manifest = True):
|
2020-03-01 10:57:40 +01:00
|
|
|
command = ["sudo", "docker", "login", harbor_host, "-u", user, "-p", password]
|
2020-07-30 10:04:14 +02:00
|
|
|
print( "Docker Login Command: ", command)
|
2020-03-01 10:57:40 +01:00
|
|
|
base.run_command(command)
|
2020-03-07 04:15:19 +01:00
|
|
|
if enable_manifest == True:
|
|
|
|
try:
|
2020-09-15 12:51:40 +02:00
|
|
|
ret = subprocess.check_output([cfg_file], shell=False)
|
2020-07-30 10:04:14 +02:00
|
|
|
except subprocess.CalledProcessError as exc:
|
2020-03-07 04:15:19 +01:00
|
|
|
raise Exception("Failed to update docker config, error is {} {}.".format(exc.returncode, exc.output))
|
2020-03-01 10:57:40 +01:00
|
|
|
|
|
|
|
def docker_manifest_create(index, manifests):
|
2020-09-15 12:51:40 +02:00
|
|
|
command = ["sudo", "docker","manifest","create", "--amend", index]
|
2020-03-01 10:57:40 +01:00
|
|
|
command.extend(manifests)
|
2020-07-30 10:04:14 +02:00
|
|
|
print( "Docker Manifest Command: ", command)
|
2020-03-01 10:57:40 +01:00
|
|
|
base.run_command(command)
|
|
|
|
|
|
|
|
def docker_manifest_push(index):
|
|
|
|
command = ["sudo", "docker","manifest","push",index]
|
2020-07-30 10:04:14 +02:00
|
|
|
print( "Docker Manifest Command: ", command)
|
2020-03-01 10:57:40 +01:00
|
|
|
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
|
|
|
|
|
2020-09-15 12:51:40 +02:00
|
|
|
def docker_manifest_push_to_harbor(index, manifests, harbor_server, user, password, cfg_file = "./tests/apitests/python/update_docker_cfg.sh"):
|
|
|
|
docker_login_cmd(harbor_server, user, password, cfg_file=cfg_file)
|
2020-03-01 10:57:40 +01:00
|
|
|
docker_manifest_create(index, manifests)
|
|
|
|
return docker_manifest_push(index)
|
|
|
|
|
2020-03-28 04:29:28 +01:00
|
|
|
def list_repositories(harbor_host, user, password, n = None, last = None):
|
|
|
|
if n is not None and last is not None:
|
|
|
|
command = ["curl", "-s", "-u", user+":"+password, "https://"+harbor_host+"/v2/_catalog"+"?n=%d"%n+"&last="+last, "--insecure"]
|
|
|
|
elif n is not None:
|
|
|
|
command = ["curl", "-s", "-u", user+":"+password, "https://"+harbor_host+"/v2/_catalog"+"?n=%d"%n, "--insecure"]
|
|
|
|
else:
|
|
|
|
command = ["curl", "-s", "-u", user+":"+password, "https://"+harbor_host+"/v2/_catalog", "--insecure"]
|
2020-07-30 10:04:14 +02:00
|
|
|
print( "List Repositories Command: ", command)
|
2020-03-28 04:29:28 +01:00
|
|
|
ret = base.run_command(command)
|
|
|
|
repos = json.loads(ret).get("repositories","")
|
|
|
|
return repos
|
|
|
|
|
|
|
|
def list_image_tags(harbor_host, repository, user, password, n = None, last = None):
|
|
|
|
if n is not None and last is not None:
|
|
|
|
command = ["curl", "-s", "-u", user+":"+password, "https://"+harbor_host+"/v2/"+repository+"/tags/list"+"?n=%d"%n+"&last="+last, "--insecure"]
|
|
|
|
elif n is not None:
|
|
|
|
command = ["curl", "-s", "-u", user+":"+password, "https://"+harbor_host+"/v2/"+repository+"/tags/list"+"?n=%d"%n, "--insecure"]
|
|
|
|
else:
|
|
|
|
command = ["curl", "-s", "-u", user+":"+password, "https://"+harbor_host+"/v2/"+repository+"/tags/list", "--insecure"]
|
2020-07-30 10:04:14 +02:00
|
|
|
print( "List Image Tags Command: ", command)
|
2020-03-28 04:29:28 +01:00
|
|
|
ret = base.run_command(command)
|
|
|
|
tags = json.loads(ret).get("tags","")
|
|
|
|
return tags
|
|
|
|
|
2018-11-01 11:26:04 +01:00
|
|
|
class DockerAPI(object):
|
|
|
|
def __init__(self):
|
2020-01-20 04:51:03 +01:00
|
|
|
self.DCLIENT = docker.APIClient(base_url='unix://var/run/docker.sock',version='auto',timeout=30)
|
2019-09-03 09:52:41 +02:00
|
|
|
self.DCLIENT2 = docker.from_env()
|
2018-11-01 11:26:04 +01:00
|
|
|
|
2019-05-06 05:34:11 +02:00
|
|
|
def docker_login(self, registry, username, password, expected_error_message = None):
|
|
|
|
if expected_error_message is "":
|
|
|
|
expected_error_message = None
|
2018-11-01 11:26:04 +01:00
|
|
|
try:
|
|
|
|
self.DCLIENT.login(registry = registry, username=username, password=password)
|
2020-07-30 10:04:14 +02:00
|
|
|
except docker.errors.APIError as err:
|
2019-05-06 05:34:11 +02:00
|
|
|
if expected_error_message is not None:
|
2020-07-30 10:04:14 +02:00
|
|
|
print( "docker login error:", str(err))
|
2019-05-06 05:34:11 +02:00
|
|
|
if str(err).lower().find(expected_error_message.lower()) < 0:
|
|
|
|
raise Exception(r"Docker login: Return message {} is not as expected {}".format(str(err), expected_error_message))
|
|
|
|
else:
|
2020-08-11 04:34:58 +02:00
|
|
|
raise Exception(r" Docker login failed, error is [{}]".format (str(err)))
|
2018-11-01 11:26:04 +01:00
|
|
|
|
2018-11-21 05:19:28 +01:00
|
|
|
def docker_image_pull(self, image, tag = None, expected_error_message = None):
|
2018-11-01 11:26:04 +01:00
|
|
|
if tag is not None:
|
|
|
|
_tag = tag
|
2018-11-21 05:19:28 +01:00
|
|
|
else:
|
|
|
|
_tag = "latest"
|
2019-02-18 06:47:16 +01:00
|
|
|
if expected_error_message is "":
|
|
|
|
expected_error_message = None
|
|
|
|
caught_err = False
|
|
|
|
ret = ""
|
2018-11-01 11:26:04 +01:00
|
|
|
try:
|
2020-08-07 08:56:18 +02:00
|
|
|
self.DCLIENT.pull(r'{}:{}'.format(image, _tag))
|
2020-03-01 10:57:40 +01:00
|
|
|
return ret
|
2020-07-30 10:04:14 +02:00
|
|
|
except Exception as err:
|
2019-02-18 06:47:16 +01:00
|
|
|
caught_err = True
|
2018-11-21 05:19:28 +01:00
|
|
|
if expected_error_message is not None:
|
2020-07-30 10:04:14 +02:00
|
|
|
print( "docker image pull error:", str(err))
|
2018-11-21 05:19:28 +01:00
|
|
|
if str(err).lower().find(expected_error_message.lower()) < 0:
|
2019-02-18 06:47:16 +01:00
|
|
|
raise Exception(r"Pull image: Return message {} is not as expected {}".format(str(err), expected_error_message))
|
2018-11-21 05:19:28 +01:00
|
|
|
else:
|
2020-11-04 03:13:12 +01:00
|
|
|
raise Exception(r" Docker pull image {} failed, error is [{}]".format (image, str(err)))
|
2019-02-18 06:47:16 +01:00
|
|
|
if caught_err == False:
|
|
|
|
if expected_error_message is not None:
|
|
|
|
if str(ret).lower().find(expected_error_message.lower()) < 0:
|
2020-01-27 20:31:18 +01:00
|
|
|
raise Exception(r" Failed to catch error [{}] when pull image {}, return message: {}".format (expected_error_message, image, str(ret)))
|
2019-02-18 06:47:16 +01:00
|
|
|
else:
|
|
|
|
if str(ret).lower().find("error".lower()) >= 0:
|
|
|
|
raise Exception(r" It's was not suppose to catch error when pull image {}, return message is [{}]".format (image, ret))
|
2018-11-01 11:26:04 +01:00
|
|
|
|
|
|
|
def docker_image_tag(self, image, harbor_registry, tag = None):
|
|
|
|
_tag = base._random_name("tag")
|
|
|
|
if tag is not None:
|
|
|
|
_tag = tag
|
|
|
|
try:
|
2018-12-03 10:05:06 +01:00
|
|
|
self.DCLIENT.tag(image, harbor_registry, _tag, force=True)
|
2018-11-01 11:26:04 +01:00
|
|
|
return harbor_registry, _tag
|
2020-08-11 04:34:58 +02:00
|
|
|
except docker.errors.APIError as err:
|
|
|
|
raise Exception(r" Docker tag image {} failed, error is [{}]".format (image, str(err)))
|
2018-11-01 11:26:04 +01:00
|
|
|
|
2019-02-18 06:47:16 +01:00
|
|
|
def docker_image_push(self, harbor_registry, tag, expected_error_message = None):
|
2020-11-03 08:32:13 +01:00
|
|
|
ret = None
|
2019-02-18 06:47:16 +01:00
|
|
|
if expected_error_message is "":
|
|
|
|
expected_error_message = None
|
2018-11-01 11:26:04 +01:00
|
|
|
try:
|
2020-11-03 08:32:13 +01:00
|
|
|
ret = self.DCLIENT.push(harbor_registry, tag)
|
2020-07-30 10:04:14 +02:00
|
|
|
except Exception as err:
|
2019-02-18 06:47:16 +01:00
|
|
|
if expected_error_message is not None:
|
2020-07-30 10:04:14 +02:00
|
|
|
print( "docker image push error:", str(err))
|
2019-02-18 06:47:16 +01:00
|
|
|
if str(err).lower().find(expected_error_message.lower()) < 0:
|
|
|
|
raise Exception(r"Push image: Return message {} is not as expected {}".format(str(err), expected_error_message))
|
|
|
|
else:
|
2020-08-11 04:34:58 +02:00
|
|
|
raise Exception(r" Docker push image {} failed, error is [{}]".format (harbor_registry, message))
|
2020-11-03 08:32:13 +01:00
|
|
|
else:
|
2019-02-18 06:47:16 +01:00
|
|
|
if expected_error_message is not None:
|
|
|
|
if str(ret).lower().find(expected_error_message.lower()) < 0:
|
2020-01-27 20:31:18 +01:00
|
|
|
raise Exception(r" Failed to catch error [{}] when push image {}, return message: {}".
|
|
|
|
format (expected_error_message, harbor_registry, str(ret)))
|
2019-02-18 06:47:16 +01:00
|
|
|
else:
|
|
|
|
if str(ret).lower().find("errorDetail".lower()) >= 0:
|
2020-01-27 20:31:18 +01:00
|
|
|
raise Exception(r" It's was not suppose to catch error when push image {}, return message is [{}]".
|
|
|
|
format (harbor_registry, ret))
|
2019-09-03 09:52:41 +02:00
|
|
|
|
|
|
|
def docker_image_build(self, harbor_registry, tags=None, size=1, expected_error_message = None):
|
|
|
|
caught_err = False
|
|
|
|
ret = ""
|
|
|
|
try:
|
|
|
|
baseimage='busybox:latest'
|
|
|
|
if not self.DCLIENT.images(name=baseimage):
|
|
|
|
self.DCLIENT.pull(baseimage)
|
|
|
|
c=self.DCLIENT.create_container(image='busybox:latest',command='dd if=/dev/urandom of=test bs=1M count=%d' % size )
|
|
|
|
self.DCLIENT.start(c)
|
|
|
|
self.DCLIENT.wait(c)
|
|
|
|
if not tags:
|
|
|
|
tags=['latest']
|
|
|
|
firstrepo="%s:%s" % (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="%s:%s" % (harbor_registry, tag)
|
|
|
|
self.DCLIENT.tag(firstrepo, repo)
|
|
|
|
for tag in tags:
|
|
|
|
repo="%s:%s" % (harbor_registry, tag)
|
|
|
|
self.DCLIENT.push(repo)
|
|
|
|
print("build image %s with size %d" % (repo, size))
|
|
|
|
self.DCLIENT.remove_image(repo)
|
|
|
|
self.DCLIENT.remove_container(c)
|
2020-03-07 04:15:19 +01:00
|
|
|
self.DCLIENT.pull(repo)
|
|
|
|
image = self.DCLIENT2.images.get(repo)
|
|
|
|
return repo, image.id
|
2020-07-30 10:04:14 +02:00
|
|
|
except Exception as err:
|
2019-09-03 09:52:41 +02:00
|
|
|
caught_err = True
|
|
|
|
if expected_error_message is not None:
|
2020-07-30 10:04:14 +02:00
|
|
|
print( "docker image build error:", str(err))
|
2019-09-03 09:52:41 +02:00
|
|
|
if str(err).lower().find(expected_error_message.lower()) < 0:
|
|
|
|
raise Exception(r"Push image: Return message {} is not as expected {}".format(str(err), expected_error_message))
|
|
|
|
else:
|
2020-08-11 04:34:58 +02:00
|
|
|
raise Exception(r" Docker build image {} failed, error is [{}]".format (harbor_registry, str(err)))
|
2019-09-03 09:52:41 +02:00
|
|
|
if caught_err == False:
|
|
|
|
if expected_error_message is not None:
|
|
|
|
if str(ret).lower().find(expected_error_message.lower()) < 0:
|
2020-01-27 20:31:18 +01:00
|
|
|
raise Exception(r" Failed to catch error [{}] when build image {}, return message: {}".
|
|
|
|
format (expected_error_message, harbor_registry, str(ret)))
|
2019-09-03 09:52:41 +02:00
|
|
|
else:
|
|
|
|
if str(ret).lower().find("errorDetail".lower()) >= 0:
|
|
|
|
raise Exception(r" It's was not suppose to catch error when push image {}, return message is [{}]".format (harbor_registry, ret))
|