Esempio n. 1
0
def _container_env(version: CMKVersion) -> Dict[str, str]:
    return {
        "LANG":
        "C",
        "PIPENV_PIPFILE":
        "/git/Pipfile",
        "PIPENV_VENV_IN_PROJECT":
        "true",
        "VERSION":
        version.version_spec,
        "EDITION":
        version.edition_short,
        "BRANCH":
        version.branch(),
        "RESULT_PATH":
        "/results",
        # Write to this result path by default (may be overridden e.g. by integration tests)
        "PYTEST_ADDOPTS":
        os.environ.get("PYTEST_ADDOPTS", "") +
        " --junitxml=/results/junit.xml",
    }
Esempio n. 2
0
def _create_cmk_image(client: docker.DockerClient, base_image_name: str,
                      docker_tag: str, version: CMKVersion) -> str:
    base_image_name_with_tag = "%s:%s" % (base_image_name, docker_tag)
    logger.info("Preparing base image [%s]", base_image_name_with_tag)
    base_image = _get_or_load_image(client, base_image_name_with_tag)

    # This installs the requested Checkmk Edition+Version into the new image, for this reason we add
    # these parts to the target image name. The tag is equal to the origin image.
    image_name = "%s-%s-%s" % (base_image_name, version.edition_short,
                               version.version)
    image_name_with_tag = "%s:%s" % (image_name, docker_tag)

    logger.info("Preparing image [%s]", image_name_with_tag)
    # First try to get the pre-built image from the local or remote registry
    image = _get_or_load_image(client, image_name_with_tag)
    if image:
        # We found something locally or remote and ensured it's available locally.
        #
        # Only use it when it's based on the latest available base image. Otherwise
        # skip it. The following code will re-build one based on the current base image
        if _is_based_on_current_base_image(client, image, base_image):
            return image_name_with_tag  # already found, nothing to do.

    logger.info("Build image from [%s]", base_image_name_with_tag)
    if base_image is None:
        raise Exception(
            'Image [%s] is not available locally and the registry "%s" is not reachable. It is '
            "not implemented yet to build the image locally. Terminating." %
            (base_image_name_with_tag, _DOCKER_REGISTRY_URL))

    with _start(
            client,
            image=base_image_name_with_tag,
            labels={
                "org.tribe29.build_time": "%d" % time.time(),
                "org.tribe29.build_id": base_image.short_id,
                "org.tribe29.base_image": base_image_name_with_tag,
                "org.tribe29.base_image_hash": base_image.short_id,
                "org.tribe29.cmk_edition_short": version.edition_short,
                "org.tribe29.cmk_version": version.version,
                "org.tribe29.cmk_branch": version.branch(),
            },
            command=["tail", "-f", "/dev/null"],  # keep running
            volumes=list(_image_build_volumes().keys()),
            host_config=client.api.create_host_config(
                # needed to make the overlay mounts work on the /git directory
                # Should work, but does not seem to be enough: 'cap_add=["SYS_ADMIN"]'. Using this instead:
                privileged=True,
                binds=[
                    ":".join([k, v["bind"], v["mode"]])
                    for k, v in _image_build_volumes().items()
                ],
            ),
    ) as container:

        logger.info("Building in container %s (from [%s])", container.short_id,
                    base_image_name_with_tag)

        assert _exec_run(container, ["mkdir", "-p", "/results"]) == 0

        # Ensure we can make changes to the git directory (not persisting it outside of the container)
        _prepare_git_overlay(container, "/git-lowerdir", "/git")
        _prepare_virtual_environment(container, version)
        _persist_virtual_environment(container, version)

        logger.info("Install Checkmk version")
        assert (_exec_run(
            container,
            ["scripts/run-pipenv", "run", "/git/tests/scripts/install-cmk.py"],
            workdir="/git",
            environment=_container_env(version),
            stream=True,
        ) == 0)

        logger.info("Check whether or not installation was OK")
        assert _exec_run(container, ["ls", "/omd/versions/default"],
                         workdir="/") == 0

        logger.info("Finalizing image")

        container.stop()

        image = container.commit(image_name_with_tag)
        logger.info("Commited image [%s] (%s)", image_name_with_tag,
                    image.short_id)

        try:
            logger.info("Uploading [%s] to registry (%s)", image_name_with_tag,
                        image.short_id)
            client.images.push(image_name_with_tag)
            logger.info("  Upload complete")
        except docker.errors.APIError as e:
            logger.warning("  An error occurred")
            _handle_api_error(e)

    return image_name_with_tag