How building works - accetto/ubuntu-vnc-xfce-g3 GitHub Wiki

How building works

Version: G3v2

Updated: 2022-11-04


Introduction

This page describes the actual implementation of the second version (G3v2) of the building pipeline.

Before reading this page it can be helpful to read the pages Concepts of Dockerfiles, Concepts of building, Concepts of README files and Building stages first.

The building pipeline originally began as a mirror of the standard Docker Hub auto-building pipeline as it is described on the page Advanced automated builds. However, it has evolved a little bit since then.

The Docker Hub has removed the auto-building feature from the free plan and therefore the building on the Docker Hub stage has been abandoned.

The local stage is the default place for building the images now. Also a CI/CD building in a local GitLab installation in a Docker container on a Linux machine has already been tested.

It should be noticed, that the version G3v2 of the building pipeline offers a significantly higher performance by building sets of images or by repeated builds. It's achieved by utilizing the local g3-cache, which is described separately.

Building pipeline

The complete building pipeline consists of

  • hook scripts
  • source files
  • helper scripts

They are all stored in the folder docker/hooks/.

Also the Dockerfiles stored in the docker/ folder are part of the pipeline.

The docker/ folder itself is also referred as a docker building context or simply a building context.

The hook scripts pre_build, build, push and post_push make the actual building pipeline.

The source files are the helper files that contain additional source code, that is sourced by the hook scripts.

The helper scripts are used as external utilities.

The pipeline file structure looks like this:

  • docker/
    • hooks/
      • build
      • cache
      • env.rc
      • post_push
      • pre_build
      • push
      • release_of
      • util.rc
    • Dockerfile.xfce

It should be noted that some of the hook scripts use, or even require, some specific environment variables to be set.

Hook script arguments

The building pipeline can be executed completely or per parts.

All hook scripts require the following two inputs arguments

  • branch
  • blend

These are explained on the page Concepts of building (section Other building concepts).

The hook scripts pre_build and build can take also additional Docker CLI arguments (e.g --no-cache), that will be passed to the docker build command used internally.

The common usage pattern:

<hook-script> <branch> <blend> [[--no-cache] [<other-docker-cli-options>]]

Additionally to the input arguments, also some environment variables play a role in the building process. Those are described on the page Building stages.

Source files

The source files contain additional source code, that is sourced by the hook scripts.

Source file env.rc

This file prepares the building environment and is conceptually close to a configuration file. This file is source by all hook scripts.

The code in env.rc processes the input arguments branch and blend and sets all the variables, that are necessary for building a particular image.

The best description is probably an example of a possible source code. Note that this is not the actual code, but an illustration of the concept.

case "${_branch}" in

    # default (master), developer (dev, dev-*) and release (v*) builds
    master | dev | dev-* | v* )

        # feature blends in this building branch
        case "${_blend}" in
            vnc )
                DOCKERFILE_PATH="${_build_context}/Dockerfile.xfce"
                _deploy_repo="${_owner}/ubuntu-vnc-xfce-g3"
                _deploy_tags=( "vnc" )
                _readme_context="docker/xfce"
                ;;
            latest | vnc-novnc )
                FEATURES_NOVNC=1
                DOCKERFILE_PATH="${_build_context}/Dockerfile.xfce"
                _deploy_repo="${_owner}/ubuntu-vnc-xfce-g3"
                _deploy_tags=( "latest" "vnc-novnc" )
                _readme_context="docker/xfce"
                ;;
            vnc-fugo )
                FEATURES_USER_GROUP_OVERRIDE=1
                DOCKERFILE_PATH="${_build_context}/Dockerfile.xfce"
                _deploy_repo="${_owner}/ubuntu-vnc-xfce-g3"
                _deploy_tags=( "vnc-fugo" )
                _readme_context="docker/xfce"
                ;;
            vnc-chromium )
                DOCKERFILE_PATH="${_build_context}/Dockerfile.xfce.chromium"
                _deploy_repo="${_owner}/ubuntu-vnc-xfce-chromium-g3"
                _deploy_tags=( "vnc" )
                _readme_context="docker/xfce-chromium"
                CHROMIUM_VERSION=$( "${_mydir}"/release_of 'chromium-browser' )
                ;;
            *)
                echo "Unsupported blend '${_blend}'"
                exit 1
                ;;
        esac
        ;;

    # experimental builds
    experimental | exp-* )

        # feature blends in the experimental branch
        case "${_blend}" in
            rdp )
                # set some variables here
                ;;
            nomachine )
                # set some variables here
                ;;
            *)
                echo "Unsupported blend '${_blend}'"
                exit 1
                ;;
        esac
        ;;

    *)
        echo "Unsupported branch '${_branch}'"
        exit 1
        ;;
esac

Source file util.rc

This file contains some utility procedures and is also sourced by all hook scripts.

Examples of the utility procedures:

  • get_gist_file()
  • update_gist()

Source file secrets.rc (optional)

This file is used for setting the environment variables.

If the source file env.rc finds the file secrets.rc in the folder docker/hooks/, then it sources it automatically, so you don't need to do it manually.

You can use the provided file example-secrets.rc as a template.

Be careful to exclude the file from your public commits, because it probably contains the real secrets. Adjust the .gitignore file correctly.

Helper scripts

The helper scripts are used as external utilities.

Helper script release_of

This helper script returns the current release versions of the products, that are installed explicitly by their versions (e.g. Chromium Browser).

Helper script cache

This helper script refreshes the local g3-cache, which must be always located inside the docker building context.

Note that this helper script is often referenced also as a hook script.

It is always executed by the pre_build and build hook scripts. However, it can be used also stand-alone. For example for checking, if there are newer versions of the packages that are normally downloaded from the external sources.

The g3-cache and the rules for its refreshing are described separately.

Hook scripts

The hook scripts would override the default auto-building handlers on the Docker Hub stage, as it is described on the page Advanced automated builds.

However, since the version G3v2 the local stage took the role of the default building stage. Nevertheless, the original naming of the hook scripts has not been changed.

Hook script pre_build

This script builds a temporary helper image, gets the current verbose version sticker value of it and stores the value into the temporary helper file scrap-version_sticker-verbose_current.tmp.

Then it gets the verbose version sticker value of the previous image release from the GitHub Gist belonging to the builder repository and stores the value into the temporary helper file scrap-version_sticker-verbose_previous.tmp.

The contents of the both helper files are then compared and if they are the same, then an another temporary helper file named scrap-demand-stop-building is created. The file is actually empty, but its sheer presence has the meaning of a demand building stop command.

The comparison itself can be overridden and the image re-building can be forced by setting the environment variable FORCE_BUILDING=1. The environment variable PROHIBIT_BUILDING=1 has the opposite effect.

If the building process should continue, then the short version sticker value is got using the helper image. The value is stored into the temporary helper file scrap-version_sticker_current.tmp.

After that the temporary helper image is not needed any more and it is deleted.

Executing the pre_build hook script is not necessary in all scenarios.

It is required only if the up-to-date version sticker values are needed. This is usually the case when the images are to be published to the Docker Hub.

As it can be seen from the actual source code, the pre_build hook script can process also additional Docker CLI arguments, that will be passed to the internally used docker build command (notice the part docker build $@). Probably the most usual case is for refreshing the Docker builder cache:

./docker/hooks/pre_build dev vnc --no-cache

The Docker builder cache should not be confused with the local g3-cache, which is described separately.

The pre_build hook script always refreshes the local g3-cache before it starts building the temporary helper image. It uses the helper script cache for that.

It should be noticed, that the temporary helper image name has the name and the tag of the builder repository. Additionally, its name gets the suffix _helper by default.

TIP: The pre_build hook script is the only script you need to execute, if you only want to check, if the image needs a refresh.

Hook script build

This script builds the persistent final image and it also sets its created and version-sticker labels to the up-to-date values.

The docker build command gets a number of arguments that are partially dependent on the feature variables set by the env.rc source file.

Before building the image, the build hook script refreshes the local g3-cache by executing the cache helper script and checks if the temporary helper file scrap-demand-stop-building with the meaning of a demand building stop command is present. If the file is found, then the script does not continue and it exits gracefully.

Similar to the previously described pre_build hook script, the build hook script can also get additional Docker CLI arguments (e.g. --no-cache), that will be passed to the internally used docker build command.

It should be noticed, that the final image has the name and the tag of the builder repository.

TIP: The build hook script is the only script you have to execute, if you want to build an image only for a local use and you are not interested in the up-to-date values of the image's labels.

Hook script push

This script pushes the persistent final image into its target deployment repository on the Docker Hub.

The image gets the name and the tag of the deployment repository.

The same final image can be pushed several times into the same deployment repository, each time with a different deployment tag.

Before building the image, the script checks, if the temporary helper file scrap-demand-stop-building with the meaning of a demand building stop command is present. If it is found, the script does not continue and it exits gracefully.

You don't need to execute this script in all scenarios. Only if you want to push the image to its deployment repository on the Docker Hub.

It should be noticed, that if the target repository has the reserved name void, then the push will be skipped.

Hook script post_push

This script first checks, if the temporary helper file scrap-demand-stop-building with the meaning of a demand building stop command is present. If it is found, then the script does nothing and it exits gracefully.

In its normal course the post_push hook script begins with getting the values of the labels created and version-sticker (the short version sticker) from the persistent final image. The current value of the verbose version sticker is got from the temporary helper file created by the pre_build hook script.

All three values are then published to the GitHub Gist belonging to the builder repository.

Then the same three values are published also to the GitHub Gist belonging to the deployment repository. This is done for each deployment tag.

The other published data include the JSON endpoints for the badges that are embedded in the README files.

At the end this hook script removes the temporary helper files, unless the environment variable KEEP_HELPER_FILES is not set to 1.

You don't need to execute this script in all scenarios. Only if you want to update the GitHub Gists.

It should be noticed, that since the version G3v2 this hook script does not publish the README file to the Docker Hub. It has to be done separately as it is described bellow.

Remarks

Builder scripts

If you want to execute the complete building pipeline, then you don't need to execute the hook scripts individually.

Since the version G3v2 you can use the provided helper scripts builder.sh and ci-builder.sh that can build the individual images or also sets of images. They are described on the page How CI works.

The scripts also create the log files scrap_builder.log and scrap_ci-builder.log in the project's root directory.

Publishing README files

The automatic publishing of the README files to the Docker Hub had to be removed, because it was not working properly any more.

However, the README files for the Docker Hub can still be prepared with the provided utility util-readme.sh.

The content of the generated file scrap-readme.md can then be copy-and-pasted to the Docker Hub manually.

The Wiki page "Utility util-readme.sh" describes how to use the utility.


⚠️ **GitHub.com Fallback** ⚠️