From 1955b951d106005576e3d15c54e7b436eb3a3486 Mon Sep 17 00:00:00 2001 From: Mikhail Gordeev Date: Mon, 8 Jul 2019 02:14:01 +0300 Subject: [PATCH] Test images --- cloud-build.py | 13 +++++++++ cloud_build/__init__.py | 0 cloud_build/test_images/__init__.py | 42 +++++++++++++++++++++++++++++ cloud_build/test_images/docker.py | 27 +++++++++++++++++++ cloud_build/test_images/lxd.py | 5 ++++ example-config.yaml | 4 +++ 6 files changed, 91 insertions(+) create mode 100644 cloud_build/__init__.py create mode 100644 cloud_build/test_images/__init__.py create mode 100644 cloud_build/test_images/docker.py create mode 100644 cloud_build/test_images/lxd.py diff --git a/cloud-build.py b/cloud-build.py index 12492a9..86673a4 100755 --- a/cloud-build.py +++ b/cloud-build.py @@ -15,6 +15,8 @@ import sys import yaml +from cloud_build.test_images import test_image + PROG = 'cloud-build' @@ -299,6 +301,9 @@ Dir::Etc::preferencesparts "/var/empty"; def prerequisites_by_image(self, image: str) -> List[str]: return self._images[image].get('prerequisites', []) + def tests_by_image(self, image: str) -> List[Dict]: + return self._images[image].get('tests', []) + def scripts_by_image(self, image: str) -> Dict[str, str]: scripts = {} for name, value in self._scripts.items(): @@ -473,6 +478,14 @@ Dir::Etc::preferencesparts "/var/empty"; ) image_path = self.image_path(image, branch, arch, kind) self.copy_image(tarball, image_path) + for test in self.tests_by_image(image): + if not test_image( + image=image_path, + branch=branch, + arch=arch, + **test, + ): + self.error(f'Test for {image} failed') images_in_branch.append(image_path) self.checksum_sign(images_in_branch) diff --git a/cloud_build/__init__.py b/cloud_build/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cloud_build/test_images/__init__.py b/cloud_build/test_images/__init__.py new file mode 100644 index 0000000..6629b3d --- /dev/null +++ b/cloud_build/test_images/__init__.py @@ -0,0 +1,42 @@ +import contextlib +import os +import shutil +import subprocess +import tempfile + +from .lxd import test_lxd +from .docker import test_docker + + +@contextlib.contextmanager +def pushtmpd(): + previous_dir = os.getcwd() + tmpdir = tempfile.mkdtemp() + try: + os.chdir(tmpdir) + yield tmpdir + finally: + os.chdir(previous_dir) + shutil.rmtree(tmpdir) + + +def test_image(method, image, branch, arch): + if arch not in ['x86_64', 'i586']: + return True + + with pushtmpd() as tmpdir: + image = shutil.copy(image, tmpdir) + image = os.path.basename(image) + if method == 'lxd': + commands = test_lxd(image) + elif method == 'docker': + commands = test_docker(image) + else: + raise Exception(f'Undefined test method {method}') + + for command in commands: + rc = subprocess.call(command, shell=True) + if rc: + return False + + return True diff --git a/cloud_build/test_images/docker.py b/cloud_build/test_images/docker.py new file mode 100644 index 0000000..e34acb5 --- /dev/null +++ b/cloud_build/test_images/docker.py @@ -0,0 +1,27 @@ +from typing import List + + +def test_docker(image: str) -> List[str]: + dockerfile = rf"""FROM scratch +ADD {image} / + +RUN true > /etc/security/limits.d/50-defaults.conf +RUN apt-get update && \ + apt-get install -y vim-console; \ + rm -f /var/cache/apt/archives/*.rpm \ + /var/cache/apt/*.bin \ + /var/lib/apt/lists/*.* + +CMD ["/bin/bash"]""" + + with open('Dockerfile', 'w') as f: + f.write(dockerfile) + + name = 'cloud_build_test_docker_image' + commands = [ + f'docker build --rm --tag={name} .', + f'docker run --rm {name}', + f'docker image rm {name}', + ] + + return commands diff --git a/cloud_build/test_images/lxd.py b/cloud_build/test_images/lxd.py new file mode 100644 index 0000000..f47ede1 --- /dev/null +++ b/cloud_build/test_images/lxd.py @@ -0,0 +1,5 @@ +from typing import List + + +def test_lxd(image: str) -> List[str]: + return [] diff --git a/example-config.yaml b/example-config.yaml index e5807aa..3ba6437 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -28,12 +28,16 @@ images: target: ve/docker kinds: - tar.xz + tests: + - method: docker no_scripts: - var rootfs-systemd: target: ve/systemd-base kinds: - tar.xz + tests: + - method: lxd scripts: - securetty