Ejemplo n.º 1
0
def main():
    add_python_paths()

    version_spec = os.environ.get("VERSION", CMKVersion.DAILY)
    edition = os.environ.get("EDITION", CMKVersion.CEE)
    branch = os.environ.get("BRANCH")
    if branch is None:
        branch = current_base_branch_name()

    logger.info("Version: %s, Edition: %s, Branch: %s", version_spec, edition, branch)
    version = CMKVersion(version_spec, edition, branch)

    if version.is_installed():
        logger.info("Version %s is already installed. Terminating.")
        return 0

    manager = ABCPackageManager.factory()
    manager.install(version.version, version.edition())

    if not version.is_installed():
        logger.error("Failed not install version")

    return 0
Ejemplo 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 and _is_based_on_current_base_image(image, base_image)
            and _is_using_current_cmk_package(image, version)):
        # 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
        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(),
                # override the base image label
                "com.tribe29.image_type": "cmk-image",
            },
            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

        # Now get the hash of the used Checkmk package from the container image and add it to the
        # image labels.
        logger.info("Get Checkmk package hash")
        exit_code, output = container.exec_run([
            "cat",
            str(
                testlib.utils.package_hash_path(version.version,
                                                version.edition()))
        ], )
        assert exit_code == 0
        hash_entry = output.decode("ascii").strip()
        logger.info("Checkmk package hash entry: %s", hash_entry)

        logger.info("Stopping build container")
        container.stop()
        tmp_image = container.commit()

        new_labels = container.labels.copy()
        new_labels["org.tribe29.cmk_hash"] = hash_entry

        logger.info("Finalizing image")
        labeled_container = client.containers.run(tmp_image,
                                                  labels=new_labels,
                                                  detach=True)
        image = labeled_container.commit(image_name_with_tag)
        labeled_container.remove(force=True)

        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