1
0
mirror of https://github.com/hegerdes/gitlab-actions.git synced 2025-10-06 05:36:52 +02:00

feat: add container image manifest merge template

This commit is contained in:
Henrik Gerdes
2024-10-13 21:07:50 +00:00
parent 187feb69d7
commit 3c7404a93d
8 changed files with 151 additions and 6 deletions

View File

@@ -2,6 +2,7 @@
stages:
- test
- build
- package
- scan
- deploy
- release
@@ -18,10 +19,16 @@ include:
inputs:
context: $CI_PROJECT_DIR/tests
dockerfile: $CI_PROJECT_DIR/tests/Dockerfile
add_image_arch_postfix: true
- component: $CI_SERVER_HOST/$CI_PROJECT_PATH/buildah-build@$CI_COMMIT_SHA
inputs:
context: $CI_PROJECT_DIR/tests
dockerfile: $CI_PROJECT_DIR/tests/Dockerfile
- component: $CI_SERVER_HOST/$CI_PROJECT_PATH/container-manifest-merge@$CI_COMMIT_SHA
inputs:
stage: package
image_tags:
- $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
- component: $CI_SERVER_HOST/$CI_PROJECT_PATH/pre-commit@$CI_COMMIT_SHA
inputs:
autofix: true
@@ -34,9 +41,9 @@ include:
release_name: nginx-ingress
helm_extra_args: --atomic --wait --create-namespace --namespace test --dry-run --kube-apiserver https://kubernetes:6443 --kube-token $KUBE_TOKEN --kube-insecure-skip-tls-verify
chart: tests/charts/demo
# Alternative:
# chart: ingress-nginx
# repo: https://kubernetes.github.io/ingress-nginx/
# Alternative:
# chart: ingress-nginx
# repo: https://kubernetes.github.io/ingress-nginx/
# The above is all you need. But for testing the pipelines are run for amd64 and arm64.
# So we override the jobs to use a matrix build. Again not needed by default.
@@ -117,6 +124,14 @@ KANIKO:build:
- RUNNER: hegerdes-linux-arm64
TRIVY:container-scan:
tags: [$RUNNER]
allow_failure: true
parallel:
matrix:
- RUNNER: saas-linux-small-amd64
- RUNNER: hegerdes-linux-arm64
merge-image-manifests:
tags: [$RUNNER]
parallel:
matrix:

View File

@@ -10,6 +10,7 @@ Currently supported components are:
* [Security: Trivy container scan](https://gitlab.com/hegerdes/gitlab-actions/-/tree/main/templates/trivy-container-scan.md)
* [Container Build: Kaniko](https://gitlab.com/hegerdes/gitlab-actions/-/tree/main/templates/kaniko-build.md)
* [Container Build: Buildah](https://gitlab.com/hegerdes/gitlab-actions/-/tree/main/templates/buildash-build.md)
* [Container Build: Merge-Manifests](https://gitlab.com/hegerdes/gitlab-actions/-/tree/main/templates/container-manifest-merge.md)
* [Deployment: Helm install/upgrade](https://gitlab.com/hegerdes/gitlab-actions/-/tree/main/templates/helm-install.md)
Currently supported snippets are:

View File

@@ -28,6 +28,7 @@ The template should work without modifications but you can customize the templat
| `image_tags` | [`$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG`] | Array of the image tags to build. |
| `context` | `$CI_PROJECT_DIR` | The kaniko/docker build context. |
| `dockerfile` | `$CI_PROJECT_DIR/Dockerfile` | The path to the Dockerfile. |
| `add_image_arch_postfix` | `false` | If the container image arch should be postfixed to the image tag. |
| `authors` | `$CI_COMMIT_AUTHOR` | For OCI image label: Name of the image author(s). |
| `source_url` | `$CI_PROJECT_URL` | For OCI image label: Url of the source code. |
| `project_url` | `$CI_PROJECT_URL` | For OCI image label: Url of the project. |
@@ -36,6 +37,7 @@ The template should work without modifications but you can customize the templat
| `description` | `$CI_PROJECT_DESCRIPTION` | For OCI image label: Description. |
| `vendor` | `UNKNOWN` | For OCI image label: Vendor name. |
| `license` | `UNKNOWN` | For OCI image label: License. |
| `rules` | *Default MR rules + Tags* | The rules when the job runs |
### Variables

View File

@@ -25,6 +25,9 @@ spec:
dockerfile:
type: string
default: $CI_PROJECT_DIR/Dockerfile
add_image_arch_postfix:
type: boolean
default: false
authors:
type: string
default: $CI_COMMIT_AUTHOR
@@ -99,6 +102,16 @@ $[[ inputs.as_job ]]:
IFS=","
for IMAGE_TAG in ${IMAGE_TAGS}; do
if [ "$[[ inputs.add_image_arch_postfix ]]" = "true" ]; then
if [ "$(uname -m)" = "x86_64" ]; then
ARCH=amd64
elif [ "$(uname -m)" = "aarch64" ]; then
ARCH=arm64
else
echo "Unknown system arch. Default to $(uname -m)"
fi
IMAGE_TAG="${IMAGE_TAG}-$ARCH"
fi
# Ensure to strip any whitespace and send a curl request to each URL
CONTAINER_BUILD_IAMGE_TAGS="${CONTAINER_BUILD_IAMGE_TAGS}-t $(echo $IMAGE_TAG | xargs) "
done

View File

@@ -0,0 +1,37 @@
## Container Build: Merge-Manifests
### Usage
Use this component to merge container image manifest in your project without the need of a privileged Docker runner. It uses the [manifest-tool](https://github.com/estesp/manifest-tool) project to allow safe image operations. It is helpful if you have images which include the arch as a tag but you want to combine them to one general image manifest.
You should add this component to an existing `.gitlab-ci.yml` file by using the `include:`
keyword.
```yaml
include:
- component: gitlab.com/hegerdes/gitlab-actions/container-manifest-merge@<VERSION>
```
where `<VERSION>` is the latest released tag or `main`. This will add a `container_build` job to the pipeline.
*NOTE:* By default the latest version of manifest-tool is used. For a more predictable outcome you should pin the version to a specific tag via the `image` input.
You can customize the template settings.
### Inputs
| Input | Default value | Description |
| --------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `as_job` | `merge-image-manifests` | The name of the job that gets imported. Use ".my_job" to include as template |
| `stage` | `release` | The stage where you want the job to be added |
| `image` | `mplatform/manifest-tool:alpine` | The Docker image of kaniko |
| `image_tags` | [`$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG`] | Array of the image tags manifests to push. |
| `image_platforms` | `linux/amd64,linux/arm64` | It supports linux/amd64,linux/arm64,linux/arm/v5,linux/arm/v7,linux/s390x. |
| `image_name_template` | `"$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-ARCH"` | The template that matches the existing image tags. The `ARCH` is a placeholder and will be replaced. For more see [here](https://github.com/estesp/manifest-tool?tab=readme-ov-file#createpush). |
| `rules` | *Default MR rules + Tags* | The rules when the job runs |
### Variables
| Variable | Description |
| ----------------------------- | -------------------------------------------- |
| `GIT_STRATEGY` | Default to `fetch`. |
| `DOCKER_AUTH_CONFIG ` | GitLab variable containing registry secrets. |
| `CONTAINER_BUILD_EXTRA_ARGS ` | Extra args for the build engine. |

View File

@@ -0,0 +1,62 @@
spec:
inputs:
as_job:
type: string
default: merge-image-manifests
stage:
type: string
default: release
image:
type: string
default: mplatform/manifest-tool:alpine
image_name_template:
type: string
default: "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-ARCH"
image_tags:
type: array
default:
- "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"
image_platforms:
type: string
default: "linux/amd64,linux/arm64"
rules:
type: array
default:
# Add the job to merge request pipelines if there's an open merge request.
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# Don't add it to a *branch* pipeline if it's already in a merge request pipeline.
- if: $CI_OPEN_MERGE_REQUESTS
when: never
# Add the job to main branch pipelines.
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_TAG
---
$[[ inputs.as_job ]]:
stage: $[[ inputs.stage ]]
image:
name: "$[[ inputs.image ]]"
entrypoint: [""]
script:
- |
export IMAGE_TAGS="$[[ inputs.image_tags ]]"
IMAGE_TAGS="${IMAGE_TAGS#[}"
IMAGE_TAGS="${IMAGE_TAGS%]}"
if [ -z ${IMAGE_TOOL_USERNAME+x} ]; then
export IMAGE_TOOL_USERNAME=$CI_REGISTRY_USER
fi
if [ -z ${IMAGE_TOOL_PASSWORD+x} ]; then
export IMAGE_TOOL_PASSWORD=$CI_REGISTRY_PASSWORD
fi
# Read the cleaned-up string into an array, splitting by commas
IFS=","
for IMAGE_TAG in ${IMAGE_TAGS}; do
# Ensure to strip any whitespace and send a curl request to each URL
echo "Pushing manifest for ${IMAGE_TAG}"
manifest-tool --username=${IMAGE_TOOL_USERNAME} --password=${CI_REGISTRY_PASSWORD} push from-args \
--platforms $[[ inputs.image_platforms ]] \
--template $[[ inputs.image_name_template ]] \
--target ${IMAGE_TAG}
done
rules: $[[ inputs.rules ]]

View File

@@ -29,6 +29,7 @@ The template should work without modifications but you can customize the templat
| `image_tags` | [`$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG`] | Array of the image tags to build. |
| `context` | `$CI_PROJECT_DIR` | The kaniko/docker build context. |
| `dockerfile` | `$CI_PROJECT_DIR/Dockerfile` | The path to the Dockerfile. |
| `add_image_arch_postfix` | `false` | If the container image arch should be postfixed to the image tag. |
| `authors` | `$CI_COMMIT_AUTHOR` | For OCI image label: Name of the image author(s). |
| `source_url` | `$CI_PROJECT_URL` | For OCI image label: Url of the source code. |
| `project_url` | `$CI_PROJECT_URL` | For OCI image label: Url of the project. |
@@ -37,6 +38,7 @@ The template should work without modifications but you can customize the templat
| `description` | `$CI_PROJECT_DESCRIPTION` | For OCI image label: Description. |
| `vendor` | `UNKNOWN` | For OCI image label: Vendor name. |
| `license` | `UNKNOWN` | For OCI image label: License. |
| `rules` | *Default MR rules + Tags* | The rules when the job runs |
### Variables

View File

@@ -25,6 +25,9 @@ spec:
dockerfile:
type: string
default: $CI_PROJECT_DIR/Dockerfile
add_image_arch_postfix:
type: boolean
default: false
authors:
type: string
default: $CI_COMMIT_AUTHOR
@@ -100,9 +103,19 @@ $[[ inputs.as_job ]]:
# Read the cleaned-up string into an array, splitting by commas
IFS=","
for IMAGE_TAG in ${IMAGE_TAGS}; do
# Ensure to strip any whitespace and send a curl request to each URL
echo $IMAGE_TAG
CONTAINER_BUILD_IAMGE_TAGS="${CONTAINER_BUILD_IAMGE_TAGS}--destination $(echo $IMAGE_TAG | xargs) "
if [ "$[[ inputs.add_image_arch_postfix ]]" = "true" ]; then
if [ "$(uname -m)" = "x86_64" ]; then
ARCH=amd64
elif [ "$(uname -m)" = "aarch64" ]; then
ARCH=arm64
else
echo "Unknown system arch. Default to $(uname -m)"
fi
IMAGE_TAG="${IMAGE_TAG}-$ARCH"
fi
# Ensure to strip any whitespace and send a curl request to each URL
echo $IMAGE_TAG
CONTAINER_BUILD_IAMGE_TAGS="${CONTAINER_BUILD_IAMGE_TAGS}--destination $(echo $IMAGE_TAG | xargs) "
done
# Extract the base image name from the Dockerfile