Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker plain helm chart #1035

Open
wants to merge 40 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
429158a
feat: add initial draft for helm chart (docker-plain)
segfault16 May 6, 2024
a8df74d
test: docker-plain chart test use AWS ECR busybox
gerardcl May 10, 2024
55df77c
test: update docker-plain golden tests with helm integration
gerardcl May 10, 2024
abcd6c1
feat: docker-plain remove provisioning resources creation
gerardcl May 10, 2024
8be1e7a
drop: comment on docker-plain chart name
gerardcl May 10, 2024
5fb6f7e
feat: prepare Chart.yaml for templating the componend_id
segfault16 Jul 17, 2024
3dc157b
fix: remove custom app label, prefer the labels suggested by kubernetes
segfault16 Jul 17, 2024
ed3b160
fix: remove componentId since this should be covered by the helm char…
segfault16 Jul 17, 2024
f83dba3
feat: update image section
segfault16 Jul 17, 2024
1d7229d
update devnotes
segfault16 Jul 17, 2024
543e5e2
fix TODO note regarding image Values values.yaml
gerardcl Jul 17, 2024
e48a729
feat: docker-plain ingress with default tls templating, fix imagetag …
gerardcl Jul 17, 2024
3c9e765
fix: align tabs on ingress.yaml and update devnotes todo
gerardcl Jul 17, 2024
0658683
feat: docker-plain render Helm chart Chart.yaml file
gerardcl Jul 18, 2024
0b541a8
update devnotes, remove dependencies in Chart.yml for now
segfault16 Aug 2, 2024
d6d7121
Merge branch 'master' into docker-plain-helm-chart
segfault16 Aug 2, 2024
b97f813
update changelog
segfault16 Aug 2, 2024
8b87c2c
enable chart testing and enable deploymentStrategy to be set via valu…
gerardcl Aug 21, 2024
b2452c0
avoid dependency on Jenkins lib only provided image values - enable c…
gerardcl Aug 21, 2024
6148c67
fix: add missing tpl for serviceAccount
segfault16 Aug 27, 2024
2b4a064
fix no property error
BraisVQ Sep 5, 2024
9b6e866
fix
BraisVQ Sep 5, 2024
37271df
skip SA creation on default, use chart fullname
segfault16 Sep 5, 2024
b64fd82
Change to nginxinc image
BraisVQ Sep 5, 2024
4b74140
Merge branch 'master' into docker-plain-helm-chart
BraisVQ Sep 5, 2024
6cd786f
Specify selector for Release manager pipeline
BraisVQ Sep 6, 2024
1d9ff9c
Remove value
segfault16 Sep 10, 2024
865c738
use nginx image from redhat
segfault16 Sep 17, 2024
be71448
move image name logic to _image.tpl, make registry optional
segfault16 Sep 17, 2024
f445e25
Update readme, switch to ImagePullStrategy: IfNotPresent
segfault16 Sep 17, 2024
00ceccd
Provide initial values files for environments
segfault16 Sep 17, 2024
4485450
more strict schema
segfault16 Sep 19, 2024
818e13f
update image
segfault16 Sep 20, 2024
6bf18ed
docker-plain add helm lint and helm template processing howto info in…
gerardcl Sep 20, 2024
11871d4
Update OS package by default
BraisVQ Sep 23, 2024
a4c338a
docker-plain: add HorizontalPodAutoscaler
faust2199 Nov 27, 2024
e3e6552
docker-plain: use nginx/nginx-unprivileged
faust2199 Nov 28, 2024
167397b
docker-plain: add simpleHost to chart/values.yaml
faust2199 Nov 28, 2024
fe5fa7f
docker-plain: allow additionalProperties; make use of .Values.service…
faust2199 Nov 28, 2024
6c58ed7
Revert "docker-plain: add simpleHost to chart/values.yaml"
faust2199 Nov 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- Update jdk and scala quickstarters and agents ([#1032](https://github.com/opendevstack/ods-quickstarters/issues/1032))
- Gitleaks docs fix and update ([#1028](https://github.com/opendevstack/ods-quickstarters/issues/1028))
- Enable OpenSSL vendored compilation for Rust Jenkins Agent ([#1026](https://github.com/opendevstack/ods-quickstarters/pull/1026))
- Add Helm Chart to Docker Plain Quickstarter ([#1035](https://github.com/opendevstack/ods-quickstarters/pull/1035))
- Update Streamlit Quickstarter ([#1030](https://github.com/opendevstack/ods-quickstarters/issues/1030))
- Update Golang agent ([#1031](https://github.com/opendevstack/ods-quickstarters/issues/1031))
- Update gateway/nginx Quickstarter ([#1048](https://github.com/opendevstack/ods-quickstarters/pull/1048))
Expand Down
24 changes: 24 additions & 0 deletions docker-plain/Chart.yaml.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: v2
name: @component_id@
description: A Helm chart for Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 1.0.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.0.0"
15 changes: 10 additions & 5 deletions docker-plain/Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,17 @@ odsQuickstarterPipeline(

odsQuickstarterStageCopyFiles(context)

odsQuickstarterStageCreateOpenShiftResources(
context,
[directory: 'common/ocp-config/component-environment']
)

odsQuickstarterStageRenderJenkinsfile(context)

odsQuickstarterStageRenderSonarProperties(context)

renderHelmChart(context)
}

def renderHelmChart(def context) {
def relativeSourceFilePath = "Chart.yaml.template"
def relativeDestinationFilePath = "chart/Chart.yaml"
def absoluteSourceFilePath = "${context.sourceDir}/${relativeSourceFilePath}"
def absoluteDestinationFilePath = "${context.targetDir}/${relativeDestinationFilePath}"
sh(script: "sed 's|@component_id@|${context.componentId}|g' ${absoluteSourceFilePath} > ${absoluteDestinationFilePath}", label: "Render Helm Chart.yaml file")
}
5 changes: 4 additions & 1 deletion docker-plain/Jenkinsfile.template
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ odsComponentPipeline(
*/
odsComponentStageBuildOpenShiftImage(context)
}
odsComponentStageRolloutOpenShiftDeployment(context)
odsComponentStageRolloutOpenShiftDeployment(context, [
'selector': "app.kubernetes.io/name=${context.componentId}",
'helmEnvBasedValuesFiles': ["values.env.yaml"],
])
}

def stageBuild(def context) {
Expand Down
60 changes: 59 additions & 1 deletion docker-plain/files/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,66 @@
# Plain Docker image (docker-plain)

## Purpose

This Quickstarter serves as a minimal starting point for building your own components that don't fit any of the other Quickstarters.
For demonstration purposes, a nginx webserver provides a simple 'Hello World' message.

## Folder structure and important files

- docker: All files inside this folder are available for use in building the docker container
- [docker/Dockerfile](docker/Dockerfile): Defines the container to be built.
- chart: The Helm chart used for deploying the component.
- [chart/Chart.yaml](chart/Chart.yaml): Metadata for your Helm chart.
- [chart/values.yaml](chart/values.yaml): Default values used when templating the Helm chart.
- [chart/values.dev.yaml](chart/values.dev.yaml): Values used for deployment in the 'dev' environment. Values specified in this file are overriding default values from [chart/values.yaml](chart/values.yaml).
- chart/templates:
- [chart/templates/deployment.yaml](chart/templates/deployment.yaml): Template for the [deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) resource. This is where you add additional configuration like environment variables.
- [chart/templates/service.yaml](chart/templates/service.yaml): Template for the [service](https://kubernetes.io/docs/concepts/services-networking/service/) resource.
- [chart/templates/ingress.yaml](chart/templates/ingress.yaml): Template for the [ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) resource.

## Testing locally

If you want to run this component locally for testing, this might get you started.
It also mimicks what's happening in the [Jenkinsfile](Jenkinsfile).

### Building the container

Using a local container runtime you can build the container and tag it with the current git revision:

```bash
docker build -t testing/my-component:$(git rev-parse --short=8 HEAD) docker/
```

### Helm chart linting

This quickstarter comes with a fine-tunned [values.schema.json](chart/values.schema.json) Helm chart linting file.
Validate your chart template by running, under the `chart` folder, the following command:

```bash
helm lint
```

### Helm chart template processing test

One can test the chart template processing; run, under the `chart` folder, the following command:

```bash
helm --debug template . --set image.path=testing --set image.name=my-component --set image.tag=$(git rev-parse --short=8 HEAD)
```

### Deploying the helm chart using a local k8s

Using a local kubernetes cluster (i.e.: [kind](https://kind.sigs.k8s.io/)) you can deploy the component:

```bash
kubectl create ns docker-plain
kind load docker-image testing/my-component:$(git rev-parse --short=8 HEAD)
helm upgrade --install --wait --atomic --namespace docker-plain --set image.path=testing --set image.name=my-component --set image.tag=$(git rev-parse --short=8 HEAD) docker-plain chart
```

## How to create a custom jenkins-agent out of this docker-plain component
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still needed?

- Remove `odsComponentStageRolloutOpenShiftDeployment(context)` from your `Jenkinsfile`. We only want to build a docker image, not run it outside the pipeline.
- In your `Dockerfile`, replace `FROM alpine:latest` with the ods-jenkins-agent-base image that is available in the OpenDevStack namespace of your cluster, e.g. `FROM docker-registry.default.svc:5000/ods/jenkins-agent-base:latest`.
- Add everything you need in the jenkins-agent to your `Dockerfile`, for examples see the existing agents at [github](https://github.com/opendevstack/ods-quickstarters/tree/master/common/jenkins-agents).
- Commit and push your code to git, this will trigger the pipeline and result in a docker image of your custom jenkins-agent in your cd-namespace.
- Now you can use your custom jenkins-agent by changing the imageStreamTag to `imageStreamTag: '<your_cd_namespace>/<your_custom_jenkins_agent_image_name>:latest'` in the `Jenkinsfile` of the actual application you want to build with your custom new jenkins-agent.
- Now you can use your custom jenkins-agent by changing the imageStreamTag to `imageStreamTag: '<your_cd_namespace>/<your_custom_jenkins_agent_image_name>:latest'` in the `Jenkinsfile` of the actual application you want to build with your custom new jenkins-agent.
23 changes: 23 additions & 0 deletions docker-plain/files/chart/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
26 changes: 26 additions & 0 deletions docker-plain/files/chart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# IMPORTANT: Content will be recreated from the Chart.yaml.template file by the Jenkins shared library provision job
# NOTE: The content is provided for testing purposes
apiVersion: v2
name: Your helm chart
description: A Helm chart for Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 1.0.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.0.0"
41 changes: 41 additions & 0 deletions docker-plain/files/chart/DEVNOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# TODO
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just in case we forget, this file should be removed before the PR is merged

Can we adapt NOTES.txt to display some deployed resources and other important information for release documentation? Do we need it?

- helm linting preps, hence to add values schema validation in the chart together with the values.yaml
- add a test for helm lint
- future add as a Jenkins shared lib stage
- now either we do it as an added manually in the jenkinsfiles or documented and test locally
- make use of it on the github actions when PRs on quickstarters (reuse max as possible)
- we will move to values.yaml
- [X] the probes
- [x] the affinity (missing labels now and some additions required)
- [x] the route (with timeout values and example for ACME usage)
- [x] rolling update strategy?
- [X] remove provisioning resources creation -> get rid odsQuickstarterStageCreateOpenShiftResources
- jenkinsfile with values.env.yaml ready, so we will provide all the env values too: Different replicaCount + ingress hosts
segfault16 marked this conversation as resolved.
Show resolved Hide resolved
- [X] update test-conection.yaml with better image (to not suffer dockerhub rate limiting)
- [X] golden tests do not check anymore imagetags nor deploymentconfigs
- [X] Test ingress on Openshift without hostname -> is there a generated one? NO -> host value is required but tls can be left empty now with default OpenShift TLS (See ingress.yaml and values.yaml). host value is required as ingress approach is a rules based system.
- [X] Make ingress more standard helm (e.g. list of hosts) -> Sebastian
- start defining howtos/FAQS we detect on the way (goal to keep simple the chart but to show how to improve it and have good practises) bitnami examples (more elaborated affinity, ...)


- example of chart dependency
- example of configmap and secret
- example of secret resource management in code
- add support for extra secret operator

Later
- with the common folder with tpl files we provide a more clean and fitting approach for us
- create a new pipeline step provisioning that copies over .tpl files required from common
- creation of template files folder in common, so we try to centralise the chart creation and maintenance from one place (as it is done already with openshift templates/tailor)

Decisions:
- To stay close to default helm templates: Remove the Values.componentId and use chart.fullname instead -> Otherwise breaks DEV + PREVIEW. Chart.Name should be the source for componentId. If we want to automate -> template the Chart.yaml on provisioning <- DONE

Shared library ToDo's:
- Match required labels (app)
- Review helm install command
- Release manager image checks
- Agree if helm install requires overwritting values on image (see helm notes and deployment, and values.yaml)
segfault16 marked this conversation as resolved.
Show resolved Hide resolved
- provide docs on how to test chart updates, by running `helm --debug template . ` under the chart folder to be tested
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also helm lint

10 changes: 10 additions & 0 deletions docker-plain/files/chart/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Component '{{ include "chart.fullname" . }}' on version '{{ .Values.imageTag }}' released with Helm!
{{- if .Values.ingress.enabled }}
The component is exposed via the following routes:
{{- $appUrl := .Values.appUrl -}}
{{- range .Values.ingress.hosts }}
{{ printf "https://%s" .host }}
{{- end }}
{{- else }}
The component is not exposed.
{{- end }}
51 changes: 51 additions & 0 deletions docker-plain/files/chart/templates/_affinity.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{{/*
Part of the ODS helm tpl library

Version: 1.0
*/}}


{{/*
Pod affinity/anti-affinity (soft)

Usage: Include where needed, e.g.
````
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
affinity:
podAntiAffinity: {{- include "common.affinities.pods.soft" . | nindent 10}}
gerardcl marked this conversation as resolved.
Show resolved Hide resolved
````
*/}}
{{- define "common.affinities.pods.soft" -}}
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchLabels: {{- include "common.matchLabels" . | nindent 10 }}
topologyKey: "kubernetes.io/hostname"
{{- end -}}

{{/*
Pod affinity/anti-affinity (hard)

Usage: Include where needed, e.g.
````
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
affinity:
podAntiAffinity: {{- include "common.affinities.pods.hard" . | nindent 10}}
````
*/}}
{{- define "common.affinities.pods.hard" -}}
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchLabels: {{- include "common.matchLabels" . | nindent 10 }}
topologyKey: "kubernetes.io/hostname"
{{- end -}}
62 changes: 62 additions & 0 deletions docker-plain/files/chart/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "chart.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "chart.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "chart.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "chart.labels" -}}
helm.sh/chart: {{ include "chart.chart" . }}
{{ include "chart.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "chart.selectorLabels" -}}
app.kubernetes.io/name: {{ include "chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{- define "chart.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "chart.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
19 changes: 19 additions & 0 deletions docker-plain/files/chart/templates/_image.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

{{/*
Part of the ODS helm tpl library

Version: 1.0
*/}}

{{/*
Create an image name from the registry, image path, name and tag.
.Values.registry, .Values.imageNamespace, .Values.componentId and .Values.imageTag are injected by the ODS pipeline on deployment.
If not set, values from .Values.image.registry, .Values.image.path, .Values.image.name and .Values.image.tag are used.
*/}}
{{- define "image.fullname" -}}
{{- if (or .Values.registry .Values.image.registry) }}
{{- printf "%s/%s/%s:%s" (or .Values.registry .Values.image.registry) (or .Values.imageNamespace .Values.image.path) (or .Values.componentId .Values.image.name) (or .Values.imageTag .Values.image.tag ) -}}
{{- else }}
{{- printf "%s/%s:%s" (or .Values.imageNamespace .Values.image.path) (or .Values.componentId .Values.image.name) (or .Values.imageTag .Values.image.tag ) -}}
{{- end }}
{{- end }}
11 changes: 11 additions & 0 deletions docker-plain/files/chart/templates/_labels.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{{/*
Part of the ODS helm tpl library

Version: 1.0
*/}}


{{- define "common.matchLabels" -}}
app.kubernetes.io/name: {{ include "chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
Loading