Skip to content

Commit

Permalink
Merge pull request #14273 from danfengliu/cherry-pick-2.2.0-fix-night…
Browse files Browse the repository at this point in the history
…ly-issues-and-upgrade-docker-and-containerd

[Cherry pick 2.2.0] fix nightly issues and upgrade docker and containerd
  • Loading branch information
danfengliu authored Feb 24, 2021
2 parents a43da2a + eee81e2 commit 21dc98a
Show file tree
Hide file tree
Showing 43 changed files with 263 additions and 130 deletions.
14 changes: 14 additions & 0 deletions tests/apitests/python/library/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,20 @@ def _get_string_from_unicode(udata):
result = result + tmp.strip('\n\r\t')
return result

def run_command_with_popen(command):
print("Command: ", subprocess.list2cmdline(command))

try:
proc = subprocess.Popen(command, universal_newlines=True, shell=True,
stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output, errors = proc.communicate()
except Exception as e:
print("Error:", e)
else:
print(proc.returncode, errors, output)
finally:
proc.stdout.close()

def run_command(command, expected_error_message = None):
print("Command: ", subprocess.list2cmdline(command))
try:
Expand Down
46 changes: 24 additions & 22 deletions tests/apitests/python/library/docker_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import base
import subprocess
import json
from testutils import DOCKER_USER, DOCKER_PWD
from testutils import DOCKER_USER, DOCKER_PWD, BASE_IMAGE, BASE_IMAGE_ABS_PATH_NAME

try:
import docker
Expand Down Expand Up @@ -40,9 +40,20 @@ def docker_manifest_create(index, manifests):

def docker_images_all_list():
command = ["sudo", "docker","images","-a"]
print( "Docker images Command: ", command)
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)
Expand Down Expand Up @@ -121,15 +132,7 @@ def docker_login(self, registry, username, password, expected_error_message = No
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_remove(self, image, tag = "latest"):
docker_images_all_list()
try:
self.DCLIENT.remove_image(image+":"+tag, force=True, noprune=False)
except Exception as err:
print( "Docker image remove catch exception:", str(err))
docker_images_all_list()

def docker_image_pull(self, image, tag = None, expected_error_message = None, is_remove_image = True):
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:
Expand Down Expand Up @@ -157,8 +160,8 @@ def docker_image_pull(self, image, tag = None, expected_error_message = None, is
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_remove_image:
self.docker_image_remove(image, _tag)
if is_clean_all_img:
docker_image_clean_all()

def docker_image_tag(self, image, harbor_registry, tag = None):
_tag = base._random_name("tag")
Expand All @@ -175,6 +178,7 @@ def docker_image_tag(self, image, harbor_registry, tag = None):
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:
Expand All @@ -196,18 +200,19 @@ def docker_image_push(self, harbor_registry, tag, expected_error_message = None)
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='busybox:latest'
self.DCLIENT.login(username=DOCKER_USER, password=DOCKER_PWD)
baseimage = BASE_IMAGE['name'] + ":" + BASE_IMAGE['tag']
if not self.DCLIENT.images(name=baseimage):
print( "Docker pull is triggered when building {}".format(harbor_registry))
self.DCLIENT.pull(baseimage)
c=self.DCLIENT.create_container(image='busybox:latest',
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)
Expand All @@ -224,10 +229,7 @@ def docker_image_build(self, harbor_registry, tags=None, size=1, expected_error_
ret = self.DCLIENT.push(repo)
print("docker_image_push ret:", ret)
print("build image {} with size {}".format(repo, size))
self.DCLIENT.remove_image(repo, force=True, noprune=False)
self.DCLIENT.remove_container(c)
#self.DCLIENT.pull(repo)
#image = self.DCLIENT2.images.get(repo)
except Exception as err:
print( "Docker image build catch exception:", str(err))
err_message = str(err)
Expand All @@ -245,4 +247,4 @@ def docker_image_build(self, harbor_registry, tags=None, size=1, expected_error_
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_images_all_list()
docker_image_clean_all()
1 change: 1 addition & 0 deletions tests/apitests/python/library/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def get_project(self, project_id, expect_status_code = 200, expect_response_body

base._assert_status_code(expect_status_code, status_code)
base._assert_status_code(200, status_code)
print("Project {} info: {}".format(project_id, data))
return data

def update_project(self, project_id, expect_status_code=200, metadata=None, cve_allowlist=None, **kwargs):
Expand Down
6 changes: 3 additions & 3 deletions tests/apitests/python/library/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import time
import base
import swagger_client
import docker_api
from docker_api import DockerAPI
from swagger_client.rest import ApiException
from testutils import DOCKER_USER, DOCKER_PWD
Expand All @@ -19,7 +20,7 @@ def push_image_to_project(project_name, registry, username, password, image, tag
print("Start to push image {}/{}/{}:{}".format(registry, project_name, image, tag) )
_docker_api = DockerAPI()
_docker_api.docker_login("docker", DOCKER_USER, DOCKER_PWD)
_docker_api.docker_image_pull(image, tag = tag, is_remove_image = False)
_docker_api.docker_image_pull(image, tag = tag, is_clean_all_img = False)
_docker_api.docker_login(registry, username, password, expected_error_message = expected_login_error_message)
time.sleep(2)
if expected_login_error_message != None:
Expand All @@ -35,8 +36,7 @@ def push_image_to_project(project_name, registry, username, password, image, tag
new_harbor_registry, new_tag = _docker_api.docker_image_tag(r'{}:{}'.format(original_name, tag), target_image, tag = tag)
time.sleep(2)
_docker_api.docker_image_push(new_harbor_registry, new_tag, expected_error_message = expected_error_message)
_docker_api.docker_image_remove(target_image, tag=tag)
_docker_api.docker_image_remove(original_name, tag=tag)
docker_api.docker_image_clean_all()
return r'{}/{}'.format(project_name, image), new_tag

def push_self_build_image_to_project(project_name, registry, username, password, image, tag, size=2, expected_login_error_message = None, expected_error_message = None):
Expand Down
19 changes: 14 additions & 5 deletions tests/apitests/python/library/robot.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ def create_access_list(self, right_map = [True] * 10):
access_list.append(robotAccountAccess)
return access_list

def create_project_robot(self, project_name, duration, robot_name = None, robot_desc = None, has_pull_right = True, has_push_right = True, has_chart_read_right = True, has_chart_create_right = True, expect_status_code = 201, **kwargs):
def create_project_robot(self, project_name, duration, robot_name = None, robot_desc = None,
has_pull_right = True, has_push_right = True, has_chart_read_right = True,
has_chart_create_right = True, expect_status_code = 201, expect_response_body = None,
**kwargs):
if robot_name is None:
robot_name = base._random_name("robot")
if robot_desc is None:
Expand Down Expand Up @@ -82,10 +85,16 @@ def create_project_robot(self, project_name, duration, robot_name = None, robot_

client = self._get_client(**kwargs)
data = []
data, status_code, header = client.create_robot_with_http_info(robotAccountCreate)
base._assert_status_code(expect_status_code, status_code)
base._assert_status_code(201, status_code)
return base._get_id_from_header(header), data
try:
data, status_code, header = client.create_robot_with_http_info(robotAccountCreate)
except ApiException as e:
base._assert_status_code(expect_status_code, e.status)
if expect_response_body is not None:
base._assert_status_body(expect_response_body, e.body)
else:
base._assert_status_code(expect_status_code, status_code)
base._assert_status_code(201, status_code)
return base._get_id_from_header(header), data

def get_robot_account_by_id(self, robot_id, **kwargs):
client = self._get_client(**kwargs)
Expand Down
10 changes: 7 additions & 3 deletions tests/apitests/python/library/sign.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
# -*- coding: utf-8 -*-
import subprocess
from testutils import notary_url
from testutils import notary_url, BASE_IMAGE_ABS_PATH_NAME
from docker_api import docker_load_image, docker_image_clean_all

def sign_image(registry_ip, project_name, image, tag):
docker_load_image(BASE_IMAGE_ABS_PATH_NAME)
try:
ret = subprocess.check_output(["./tests/apitests/python/sign_image.sh", registry_ip, project_name, image, tag, notary_url], shell=False)
print("sign_image return: ", ret)
except subprocess.CalledProcessError as exc:
raise Exception("Failed to sign image error is {} {}.".format(exc.returncode, exc.output))
except subprocess.CalledProcessError as e:
raise Exception("Failed to sign image error is {} {}.".format(e.returncode, e.output))
finally:
docker_image_clean_all()

2 changes: 1 addition & 1 deletion tests/apitests/python/test_add_sys_label_to_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def testAddSysLabelToRepo(self):
expected_project_id = TestProjects.project_add_g_lbl_id, **TestProjects.USER_add_g_lbl_CLIENT)

#5. Create a new repository(RA) and tag(TA) in project(PA) by user(UA);
TestProjects.repo_name, tag = push_self_build_image_to_project(TestProjects.project_add_g_lbl_name, harbor_server, user_add_g_lbl_name, user_001_password, "hello-world", "latest")
TestProjects.repo_name, tag = push_self_build_image_to_project(TestProjects.project_add_g_lbl_name, harbor_server, user_add_g_lbl_name, user_001_password, "test_sys_label", "latest")

#6. Create a new label(LA) in project(PA) by admin;
TestProjects.label_id, _ = self.label.create_label(**ADMIN_CLIENT)
Expand Down
2 changes: 1 addition & 1 deletion tests/apitests/python/test_assign_role_to_ldap_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def testAssignRoleToLdapGroup(self):
9. Delete project(PA);
"""
url = ADMIN_CLIENT["endpoint"]
USER_ADMIN=dict(endpoint = url, username = "admin_user", password = "zhu88jie", repo = "hello-world")
USER_ADMIN=dict(endpoint = url, username = "admin_user", password = "zhu88jie", repo = "haproxy")
USER_DEV=dict(endpoint = url, username = "dev_user", password = "zhu88jie", repo = "alpine")
USER_GUEST=dict(endpoint = url, username = "guest_user", password = "zhu88jie", repo = "busybox")
USER_TEST=dict(endpoint = url, username = "test", password = "123456")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def testRetag(self):
self.project.update_project_member_role(TestProjects.project_dst_repo_id, retag_member_id, 3, **ADMIN_CLIENT)

#5. Create a new repository(RA) in project(PA) by user(UA);
TestProjects.src_repo_name, tag_name = push_self_build_image_to_project(TestProjects.project_src_repo_name, harbor_server, 'admin', 'Harbor12345', "hello-world", pull_tag_name)
TestProjects.src_repo_name, tag_name = push_self_build_image_to_project(TestProjects.project_src_repo_name, harbor_server, 'admin', 'Harbor12345', "test_copy", pull_tag_name)

#6. Get repository in project(PA), there should be one repository which was created by user(UA);
src_repo_data = self.repo.list_repositories(TestProjects.project_src_repo_name, **TestProjects.USER_RETAG_CLIENT)
Expand Down
2 changes: 1 addition & 1 deletion tests/apitests/python/test_del_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def testDelRepo(self):
TestProjects.project_del_repo_id, TestProjects.project_del_repo_name = self.project.create_project(metadata = {"public": "false"}, **TestProjects.USER_del_repo_CLIENT)

#3. Create a new repository(RA) in project(PA) by user(UA);
repo_name, _ = push_self_build_image_to_project(TestProjects.project_del_repo_name, harbor_server, 'admin', 'Harbor12345', "hello-world", "latest")
repo_name, _ = push_self_build_image_to_project(TestProjects.project_del_repo_name, harbor_server, 'admin', 'Harbor12345', "test_del_repo", "latest")

#4. Get repository in project(PA), there should be one repository which was created by user(UA);
repo_data = self.repo.list_repositories(TestProjects.project_del_repo_name, **TestProjects.USER_del_repo_CLIENT)
Expand Down
2 changes: 1 addition & 1 deletion tests/apitests/python/test_manage_project_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def testManageProjectMember(self):
TestProjects.project_alice_id, TestProjects.project_alice_name = self.project.create_project(metadata = {"public": "false"}, **USER_ALICE_CLIENT)

#2.2 Add a repository to project(PA) by Alice
TestProjects.repo_name, _ = push_self_build_image_to_project(TestProjects.project_alice_name, harbor_server, user_alice_name, user_alice_password, "hello-world", "latest")
TestProjects.repo_name, _ = push_self_build_image_to_project(TestProjects.project_alice_name, harbor_server, user_alice_name, user_alice_password, "test_member", "latest")

#3. Bob is not a member of project(PA);
self.project.check_project_member_not_exist(TestProjects.project_alice_id, user_bob_name, **USER_ALICE_CLIENT)
Expand Down
18 changes: 11 additions & 7 deletions tests/apitests/python/test_project_level_policy_content_trust.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import absolute_import

import unittest
import time

from testutils import ADMIN_CLIENT, suppress_urllib3_warning
from testutils import harbor_server
Expand All @@ -11,6 +12,7 @@
from library.repository import Repository
from library.repository import push_self_build_image_to_project
from library.repository import pull_harbor_image
from library.docker_api import docker_image_clean_all
class TestProjects(unittest.TestCase):
@suppress_urllib3_warning
def setUp(self):
Expand All @@ -19,7 +21,7 @@ def setUp(self):
self.artifact= Artifact()
self.repo= Repository()

@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
@unittest.skipIf(TEARDOWN == True, "Test data won't be erased.")
def tearDown(self):
#1. Delete repository(RA) by user(UA);
self.repo.delete_repository(TestProjects.project_content_trust_name, TestProjects.repo_name.split('/')[1], **TestProjects.USER_CONTENT_TRUST_CLIENT)
Expand Down Expand Up @@ -48,9 +50,7 @@ def testProjectLevelPolicyContentTrust(self):
3. Delete user(UA);
"""
url = ADMIN_CLIENT["endpoint"]
image = "hello-world"
admin_name = ADMIN_CLIENT["username"]
admin_password = ADMIN_CLIENT["password"]
image = "test_content_trust"
user_content_trust_password = "Aa123456"

#1. Create a new user(UA);
Expand All @@ -62,20 +62,24 @@ def testProjectLevelPolicyContentTrust(self):
TestProjects.project_content_trust_id, TestProjects.project_content_trust_name = self.project.create_project(metadata = {"public": "false"}, **TestProjects.USER_CONTENT_TRUST_CLIENT)

#3. Push a new image(IA) in project(PA) by admin;
TestProjects.repo_name, tag = push_self_build_image_to_project(TestProjects.project_content_trust_name, harbor_server, admin_name, admin_password, image, "latest")
TestProjects.repo_name, tag = push_self_build_image_to_project(TestProjects.project_content_trust_name, harbor_server, ADMIN_CLIENT["username"], ADMIN_CLIENT["password"], image, "latest")

#4. Image(IA) should exist;
artifact = self.artifact.get_reference_info(TestProjects.project_content_trust_name, image, tag, **TestProjects.USER_CONTENT_TRUST_CLIENT)
self.assertEqual(artifact.tags[0].name, tag)

docker_image_clean_all()
#5. Pull image(IA) successfully;
pull_harbor_image(harbor_server, admin_name, admin_password, TestProjects.repo_name, tag)
pull_harbor_image(harbor_server, ADMIN_CLIENT["username"], ADMIN_CLIENT["password"], TestProjects.repo_name, tag)

self.project.get_project(TestProjects.project_content_trust_id)
#6. Enable content trust in project(PA) configuration;
self.project.update_project(TestProjects.project_content_trust_id, metadata = {"enable_content_trust": "true"}, **TestProjects.USER_CONTENT_TRUST_CLIENT)
self.project.get_project(TestProjects.project_content_trust_id)

#7. Pull image(IA) failed and the reason is "The image is not signed in Notary".
pull_harbor_image(harbor_server, admin_name, admin_password, TestProjects.repo_name, tag, expected_error_message = "The image is not signed in Notary")
time.sleep(30)
pull_harbor_image(harbor_server, ADMIN_CLIENT["username"], ADMIN_CLIENT["password"], TestProjects.repo_name, tag, expected_error_message = "The image is not signed in Notary")

if __name__ == '__main__':
unittest.main()
Expand Down
4 changes: 3 additions & 1 deletion tests/apitests/python/test_project_quota.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,23 @@ def testProjectQuota(self):
with created_project(metadata={"public": "false"}, user_id=user_id) as (project_id, project_name):
#4. Push an image to project(PA) by user(UA), then check the project quota usage; -- {"count": 1, "storage": 2791709}
image, tag = "goharbor/alpine", "3.10"
image_alias_name = "_alias"
push_image_to_project(project_name, harbor_server, user_name, user_001_password, image, tag)

#5. Get project quota
quota = self.system.get_project_quota("project", project_id, **ADMIN_CLIENT)
self.assertEqual(quota[0].used["storage"], 2789002)

#6. Push the image with another tag to project(PA) by user(UA), the check the project quota usage; -- {"count": 1, "storage": 2791709}
push_image_to_project(project_name, harbor_server, user_name, user_001_password, image, tag)
push_image_to_project(project_name, harbor_server, user_name, user_001_password, image, tag, new_image=image+image_alias_name)

#7. Get project quota
quota = self.system.get_project_quota("project", project_id, **ADMIN_CLIENT)
self.assertEqual(quota[0].used["storage"], 2789002)

#8. Delete repository(RA) by user(UA);
self.repo.delete_repository(project_name, "goharbor%2Falpine", **ADMIN_CLIENT)
self.repo.delete_repository(project_name, "goharbor%2Falpine"+image_alias_name, **ADMIN_CLIENT)

#9. Quota should be 0
quota = self.system.get_project_quota("project", project_id, **ADMIN_CLIENT)
Expand Down
Loading

0 comments on commit 21dc98a

Please sign in to comment.