aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel P. Berrangé <berrange@redhat.com>2022-03-15 17:34:48 +0000
committerDaniel P. Berrangé <berrange@redhat.com>2022-05-11 13:22:21 +0100
commita191457de96f3ea53e965fd3fe0323205ead28e0 (patch)
tree92a56174ccacec6ed82b52ac0bf8da5edc4df15d
parentb754051722b0c354880b83109da5dd13c9d2a0c8 (diff)
downloadlibvirt-ci-a191457de96f3ea53e965fd3fe0323205ead28e0.zip
libvirt-ci-a191457de96f3ea53e965fd3fe0323205ead28e0.tar.gz
libvirt-ci-a191457de96f3ea53e965fd3fe0323205ead28e0.tar.bz2
lcitool/manifest: eliminate redundant container rebuilds
Currently we rebuild containers on every pipeline that is run. We only ever keep one tag 'latest' per container in the registry, regardless of branch. This is done to avoid filling the registry for per-branch tags. The cost is that we must rebuild the container on every branch push, since the current 'latest' tag might reflect an unrelated branch. The use of a single tag also creates a race if pipelines from different branches get triggered concurrently. The cost is somewhat mitigated by using layer caching during build. Historically this was handled the same way for forks and upstream, but for upstream it is overkill. We don't make use of CI against anything except the default branch, so the content of the 'latest' tag always reflects current HEAD. Given this there are only three cases where the upstream needs to re-build containers - The Dockerfile / container-template.yml files changed - To pick up new packages published by the distro - A project member deleted a container from the registry IOW, in upstream: - Most push events don't need to rebuild the 'latest' tag, only those with relevant file paths changed. - Only certain scheduled pipelines need to trigger a container rebuild. One a week is fine. - Manually triggered pipelines may need to rebuild This patch set rules against the .container_job template to cut down on jobs in upstream. To force the container builds in a pipeline, the LIBVIRT_CI_CONTAINERS=1 variable should be set. When updating across this change, project admins will need to setup a scheduled job todo the weekly container rebuild. Since the container build jobs will not exist in certain scenarios, we now need to make the deps in the build jobs optional. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
-rw-r--r--guests/lcitool/lcitool/gitlab.py35
-rw-r--r--guests/lcitool/tests/data/manifest/out/ci/gitlab/builds.yml12
-rw-r--r--guests/lcitool/tests/data/manifest/out/ci/gitlab/container-templates.yml32
3 files changed, 70 insertions, 9 deletions
diff --git a/guests/lcitool/lcitool/gitlab.py b/guests/lcitool/lcitool/gitlab.py
index c1e098d..7a58c92 100644
--- a/guests/lcitool/lcitool/gitlab.py
+++ b/guests/lcitool/lcitool/gitlab.py
@@ -15,6 +15,18 @@ def includes(paths):
def container_template(namespace, project, cidir):
return textwrap.dedent(
f"""
+ # For upstream
+ #
+ # - Push to default branch:
+ # -> rebuild if dockerfile changed, no cache
+ # - Otherwise
+ # -> rebuild if LIBVIRT_CI_CONTAINERS=1, no cache,
+ # to pick up new published distro packages or
+ # recover from deleted tag
+ #
+ # For forks
+ # - Always rebuild, with cache
+ #
.container_job:
image: docker:stable
stage: containers
@@ -27,11 +39,27 @@ def container_template(namespace, project, cidir):
- docker info
- docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD"
script:
- - docker pull "$TAG" || docker pull "$COMMON_TAG" || true
- - docker build --cache-from "$TAG" --cache-from "$COMMON_TAG" --tag "$TAG" -f "{cidir}/containers/$NAME.Dockerfile" {cidir}/containers
+ - if test $CI_PROJECT_NAMESPACE = "{namespace}";
+ then
+ docker build --tag "$TAG" -f "{cidir}/containers/$NAME.Dockerfile" {cidir}/containers ;
+ else
+ docker pull "$TAG" || docker pull "$COMMON_TAG" || true ;
+ docker build --cache-from "$TAG" --cache-from "$COMMON_TAG" --tag "$TAG" -f "{cidir}/containers/$NAME.Dockerfile" {cidir}/containers ;
+ fi
- docker push "$TAG"
after_script:
- docker logout
+ rules:
+ - if: '$CI_PROJECT_NAMESPACE == "{namespace}" && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
+ when: on_success
+ changes:
+ - {cidir}/gitlab/container-templates.yml
+ - {cidir}/containers/$NAME.Dockerfile
+ - if: '$CI_PROJECT_NAMESPACE == "{namespace}" && $LIBVIRT_CI_CONTAINERS == "1"'
+ when: on_success
+ - if: '$CI_PROJECT_NAMESPACE == "{namespace}"'
+ when: never
+ - when: on_success
""")
@@ -224,7 +252,8 @@ def _build_job(target, arch, suffix, variables, template, allow_failure, artifac
{arch}-{target}{suffix}:
extends: {template}
needs:
- - {arch}-{target}-container
+ - job: {arch}-{target}-container
+ optional: true
allow_failure: {allow_failure}
""") + format_variables(variables) + format_artifacts(artifacts)
diff --git a/guests/lcitool/tests/data/manifest/out/ci/gitlab/builds.yml b/guests/lcitool/tests/data/manifest/out/ci/gitlab/builds.yml
index 3e1f87b..af6f84a 100644
--- a/guests/lcitool/tests/data/manifest/out/ci/gitlab/builds.yml
+++ b/guests/lcitool/tests/data/manifest/out/ci/gitlab/builds.yml
@@ -3,7 +3,8 @@
x86_64-centos-stream-9:
extends: .native_build_job
needs:
- - x86_64-centos-stream-9-container
+ - job: x86_64-centos-stream-9-container
+ optional: true
allow_failure: false
variables:
NAME: centos-stream-9
@@ -12,7 +13,8 @@ x86_64-centos-stream-9:
x86_64-fedora-rawhide-clang:
extends: .native_build_job
needs:
- - x86_64-fedora-rawhide-container
+ - job: x86_64-fedora-rawhide-container
+ optional: true
allow_failure: false
variables:
CC: clang
@@ -25,7 +27,8 @@ x86_64-fedora-rawhide-clang:
i686-debian-sid:
extends: .cross_build_job
needs:
- - i686-debian-sid-container
+ - job: i686-debian-sid-container
+ optional: true
allow_failure: false
variables:
CROSS: i686
@@ -40,7 +43,8 @@ i686-debian-sid:
mingw32-fedora-rawhide:
extends: .cross_build_job
needs:
- - mingw32-fedora-rawhide-container
+ - job: mingw32-fedora-rawhide-container
+ optional: true
allow_failure: false
variables:
CROSS: mingw32
diff --git a/guests/lcitool/tests/data/manifest/out/ci/gitlab/container-templates.yml b/guests/lcitool/tests/data/manifest/out/ci/gitlab/container-templates.yml
index 47bed1e..cc2f8ac 100644
--- a/guests/lcitool/tests/data/manifest/out/ci/gitlab/container-templates.yml
+++ b/guests/lcitool/tests/data/manifest/out/ci/gitlab/container-templates.yml
@@ -1,3 +1,15 @@
+# For upstream
+#
+# - Push to default branch:
+# -> rebuild if dockerfile changed, no cache
+# - Otherwise
+# -> rebuild if LIBVIRT_CI_CONTAINERS=1, no cache,
+# to pick up new published distro packages or
+# recover from deleted tag
+#
+# For forks
+# - Always rebuild, with cache
+#
.container_job:
image: docker:stable
stage: containers
@@ -10,8 +22,24 @@
- docker info
- docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD"
script:
- - docker pull "$TAG" || docker pull "$COMMON_TAG" || true
- - docker build --cache-from "$TAG" --cache-from "$COMMON_TAG" --tag "$TAG" -f "ci/containers/$NAME.Dockerfile" ci/containers
+ - if test $CI_PROJECT_NAMESPACE = "test-group";
+ then
+ docker build --tag "$TAG" -f "ci/containers/$NAME.Dockerfile" ci/containers ;
+ else
+ docker pull "$TAG" || docker pull "$COMMON_TAG" || true ;
+ docker build --cache-from "$TAG" --cache-from "$COMMON_TAG" --tag "$TAG" -f "ci/containers/$NAME.Dockerfile" ci/containers ;
+ fi
- docker push "$TAG"
after_script:
- docker logout
+ rules:
+ - if: '$CI_PROJECT_NAMESPACE == "test-group" && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
+ when: on_success
+ changes:
+ - ci/gitlab/container-templates.yml
+ - ci/containers/$NAME.Dockerfile
+ - if: '$CI_PROJECT_NAMESPACE == "test-group" && $LIBVIRT_CI_CONTAINERS == "1"'
+ when: on_success
+ - if: '$CI_PROJECT_NAMESPACE == "test-group"'
+ when: never
+ - when: on_success