From 11f65c6c1d3bfd6a12f8e71d778d46d635010449 Mon Sep 17 00:00:00 2001 From: Michal Arbet Date: Tue, 15 Feb 2022 13:50:59 +0100 Subject: Add mechanism for patching files in containers This patch adds a way to patch files in a Docker image built by Kolla. This is very useful for several reasons, specifically: - Custom modifications - The stable branch of some library has a fix but no pip package has been released - Eliminates the need to package your own pip packages - Eliminates the need to invent your own versioning to prevent upstream versioning - Eliminates the need to manage a pip server - In other words, it eliminates the need to get a wheel into the image and install it manually using any method not previously mentioned It is also highly desirable because, although Kolla can replace the source for a service with a custom URL for a tarball or its own Git repo, it cannot do this for dependencies pulled from pip. I would also like to point out that this is a feature with its own code path and works only if the user "inserts" a patch into the folder patches/docker-image/something.patch and creates an analogous series file for patch source code. Simply said, this code will never interfere with the upstream build process since this feature is not intended for use in upstream. It is rather meant for downstream users who know what they are doing. Now they just have an option to patch their images. Everything works on all layers of the Docker image and stores a report of applied patches which can then be seen in /etc. This mechanism is similar as debian patch quilt. Change-Id: I61d0790c5d4d070b7ea9e8c99c0a76ff5d22bf9d --- docker/base/Dockerfile.j2 | 11 +++++++--- docker/base/kolla_patch.sh | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 3 deletions(-) create mode 100755 docker/base/kolla_patch.sh (limited to 'docker/base') diff --git a/docker/base/Dockerfile.j2 b/docker/base/Dockerfile.j2 index bb61c8307..8b31e196a 100644 --- a/docker/base/Dockerfile.j2 +++ b/docker/base/Dockerfile.j2 @@ -25,7 +25,6 @@ LABEL kolla_version="{{ kolla_version }}" ENV KOLLA_BASE_DISTRO={{ base_distro }} \ KOLLA_BASE_ARCH={{ base_arch }} - #### Customize PS1 to be used with bash shell COPY kolla_bashrc /tmp/ RUN cat /tmp/kolla_bashrc >> /etc/skel/.bashrc \ @@ -192,7 +191,8 @@ RUN {{ macros.install_packages(base_centos_yum_repo_packages | customizable("cen 'tar', 'util-linux', 'util-linux-user', - 'which' + 'which', + 'patch' ] %} # Install base packages @@ -279,7 +279,8 @@ COPY apt_preferences /etc/apt/preferences.d/kolla-custom 'python3-pip', 'socat', 'sudo', - 'tgt' + 'tgt', + 'patch' ] %} {% set base_apt_keys = [ @@ -348,6 +349,7 @@ COPY start.sh /usr/local/bin/kolla_start COPY copy_cacerts.sh /usr/local/bin/kolla_copy_cacerts COPY install_projects.sh /usr/local/bin/kolla_install_projects COPY httpd_setup.sh /usr/local/bin/kolla_httpd_setup +COPY kolla_patch.sh /usr/local/bin/kolla_patch COPY sudoers /etc/sudoers {% if use_dumb_init %} @@ -368,6 +370,7 @@ RUN touch /usr/local/bin/kolla_extend_start \ /usr/local/bin/kolla_set_configs \ /usr/local/bin/kolla_copy_cacerts \ /usr/local/bin/kolla_install_projects \ + /usr/local/bin/kolla_patch \ && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_httpd_setup \ && chmod 440 /etc/sudoers \ && mkdir -p /var/log/kolla \ @@ -382,5 +385,7 @@ RUN touch /usr/local/bin/kolla_extend_start \ # ENV UPPER_CONSTRAINTS_FILE=https://releases.openstack.org/constraints/upper/{{ openstack_release }} {% endblock %} +{{ macros.kolla_patch_sources() }} + {% block base_footer %}{% endblock %} CMD ["kolla_start"] diff --git a/docker/base/kolla_patch.sh b/docker/base/kolla_patch.sh new file mode 100755 index 000000000..b17a5b61d --- /dev/null +++ b/docker/base/kolla_patch.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +# This script works as debian quilt patch. +# So, patch files included in /patches/series +# are applied and information what was applied +# is stored in /etc/kolla/patched. +# +# No more, no less :) + +cd / + +# If exist /patches/series +# let's try to apply patches +if [ -e "/patches/series" ]; then + # If there is /patches/series.applied + # then it means previous run already applied + # some patches - from another intermediate container + # + # So, let's add patches again to /patches/series + # and let's script to handle it + if [ -e "/patches/series.applied" ]; then + grep -v '^#' /patches/series.applied > /tmp/series.tmp + grep -v '^#' /patches/series >> /tmp/series.tmp + rm -f /patches/series + mv /tmp/series.tmp /patches/series + fi + touch /etc/kolla/patched + for patchfile in $(grep -v '^#' /patches/series); do + # If patch is not applied, try to apply it, otherwise + # inform user that patchfile is already applied + if ! grep -q "$patchfile" /etc/kolla/patched; then + echo "[i] Applying /patches/${patchfile}" + patch -p0 --fuzz=0 --ignore-whitespace < /patches/${i}/${patchfile} + # If apply patch was successful inform user, + # otherwise fail build process and inform user + # to check/fix patch + if [ $? -eq 0 ]; then + echo "[i] Applied /patches/${patchfile}" >> /etc/kolla/patched + else + echo "[i] Patch /patches/${patchfile} failed, please fix your patchfiles." + exit 1 + fi + else + echo "[i] /patches/${patchfile} already applied." + fi + done + # Ignore files which are commented and move + # to /patches/series.applied as /patch/series + # can be potentially replaced by another files + # from different intermediate container + grep -v '^#' /patches/series > /patches/series.applied + rm -f /patches/series +else + echo "[i] No series file found, nothing to patch." +fi -- cgit v1.2.3