From 47fb15c26feff94c06fec7a14204af54b3461327 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Jul 30 2019 11:53:09 +0000 Subject: Add devel documentation about container images rebuild. --- diff --git a/docs/conf.py b/docs/conf.py index b6669c2..7c4901e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -52,7 +52,7 @@ master_doc = 'index' # General information about the project. project = 'Freshmaker' -copyright = '2017, Red Hat, Inc. and others' +copyright = '2019, Red Hat, Inc. and others' author = 'Red Hat, Inc. and others' # The version info for the project you're documenting, acts as replacement for diff --git a/docs/images_rebuild.rst b/docs/images_rebuild.rst new file mode 100644 index 0000000..5f5311a --- /dev/null +++ b/docs/images_rebuild.rst @@ -0,0 +1,118 @@ +=========================================== +Rebuilding container images affected by CVE +=========================================== + +This document is intended for Freshmaker developers to understand the general algorithm used by Freshmaker to find out the container images which will be rebuild as result of release of RPM fixing the CVE. + +It describes the ``Lightblue.find_images_to_rebuild`` method from high-level perspective. + + +Images stored in Lightblue database +=================================== + +There are two main objects in the Lightblue which are interesting for Freshmaker: + +- ``ContainerImage`` - Stores metadata about particular container image build. +- ``ContainerRepository`` - Groups multiple images together and also contains metadata about the container repository itself. + +Important facts about ``ContainerImage``: + +- There is one ``ContainerImage`` record for each architecture on which the image has been built. +- If the image is published, it is "squashed", so it is not possible to find out its direct parent once it is published. +- If the image is published, extra ``ContainerImage`` record is created with ``published: True`` in metadata. + +Important facts about ``ContainerRepository``: + +- The ``ContainerImage`` records are tagged in ``ContainerRepository`` with tags. By default, latest built image has ``latest`` tag, but there might be multiple tags, for example per container images major release. +- The ``ContainerRepository`` contains ``auto_rebuild_tags`` list which defines which tags within the ``ContainerRepository`` are enabled to be handled by Freshmaker. + + +Resolving container images +========================== + +The metadata stored in ``ContainerImage`` in Lightblue are not enough to rebuild the container image. + +Freshmaker for example need following additional metadata, for example: + +- The git repository, branch name and commit hash from which the image have been built, so we can resubmit the exactl same commit. +- The name of Koji target in which the image has been built. +- The list of architectures the image has been built for. + +The process of getting these data is called ``resolving the image`` and happens in ``ContainerImage.resolve`` method. + + +Finding published affected images +================================= + +The ``Lightblue.find_images_to_rebuild`` has two important input values: + +- ``srpm_nvrs`` - The list of NVRs of SRPMs from which the packages fixing the CVE(s) are built. +- ``content_sets`` - The list of content sets (basically pointers to particular products) in which the RPMs are released. + +The main goal is to find out all the container images which **contains some RPM comming from srpm_nvrs with older version and was installing this RPM from one of the content_sets**. + +Freshmaker only cares about published container images, so at first Freshmaker needs to find out all the published container images affected by the CVE. This is done in ``Lightblue.find_images_with_packages_from_content_set`` method. + +At first, this method finds all the available container repositories which are enabled to be handled by Freshmaker (``Lightblue.find_all_container_repositories``). + +With that knowledge, it generates the Lightblue query (``Lightblue.find_images_with_included_srpms``) to find images which: + +- includes some RPM comming from SRPM from ``srpm_nvrs``. +- has one of the ``content_sets`` enabled. +- is tagged by one of the ``auto_rebuild_tags`` in one of the allowed container repositories. + +The images returned by Lightblue are ``resolved`` and goes to next step. Let's call this list of images ``published affected images``. + + +Finding unpublished affected images +=================================== + +Every image in ``published affected images`` squashed in a way that we cannot find its direct parent. Freshmaker therefore needs to find out unpublished versions of those images. Let's call this list ``unpublished affected images``. + +This is done in multiple threads which call ``Lightblue.find_unpublished_image_for_build`` method. + + +Finding affected parent images +============================== + +Freshmaker now has the list of ``unpublished affected images``. Freshmaker knows that the every image in this list is affected by the CVE, because it contains the RPM in older version than the one which fixes the CVE and this RPM comes from one of the ``content_sets``. + +The issue is, that this RPM might have been (and in most cases it is) inherited from some parent image which ``yum install`` it. + +Freshmaker therefore needs to go up in the image inheritance tree and find out the first parent image which contains this RPM. This parent image is responsible for installation of affected RPM and therefore all the parent images of particular ``unpublished affected image`` up to the first parent image which installed the RPM must be rebuilt. + +When determining the parent of the last affected parent image, Freshmaker tries to use the latest published parent. If it fails to find such image, it just uses the original parent image of this last affected parent image. + +The ``Lightblue.find_parent_images_with_package`` is called in a multiple threads for every ``unpublished affected image``. It extends the single ``unpublished affected image`` with all its affected parents which need to be rebuild. + +This data is stored in so-called ``rebuild_list`` in ``[unpublished_affected_image, affected_parent, affected_grandparent, ...]`` format. + + +Deduplicating multiple rebuild lists +==================================== + +Two ``unpublished affected images`` can easily share the same parent or grandparent image, but in different version or release. + +Freshmaker however needs to rebuild each container image in particular major version only once, otherwise it wouldn't be possible to release such images. Let's take following ``rebuild_lists`` as example: + +- ``[foo-1-1, parent-1-1]`` +- ``[bar-1-1, parent-1-3]`` + +In this case, Freshmaker can simply upgrade the ``foo-1-1`` to ``parent-1-3`` parent image and do not rebuild ``parent-1-1`` at all. + +The deduplication code respects following rules: + +- The parent image is always kept in the same ``version``. +- The parent image is updated to latest published ``release``. +- If the parent image is unpublished, it is kept in the same ``release``. +- If there are multiple child images with completely different parent images, the child images are grouped by the parent image and are updated individually. For example, if ``foo-1-1`` depends on ``bar-1-1`` and ``foo-1-2`` depend on ``parent-1-1``, then ``foo-1-1`` is not updated to ``foo-1-2`` to not break the compatibility. + +The deduplication method returns the changed ``rebuild_lists``. + + +Creating the build batches +========================== + +Freshmaker needs to know the order of images, so batches are created from the ``rebuild_lists`` in a way that the leaf images are in the last batch, their parent images in the first batch, their grandparent images in the second batch, ... + +This is the result of the ``LightBlue`` code and is handled later by other parts of ``Freshmaker``. diff --git a/docs/index.rst b/docs/index.rst index 34db17a..416b86c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -16,6 +16,7 @@ compose (mainly the RPM repository) with packages from Koji using the REST API. about api + images_rebuild Indices and tables ==================