Skip to content

Commit 358724f

Browse files
authored
feat: add helm chart (#619)
* add workflow * feat: add pgcat helm chart * fix: set the right include into configmap Signed-off-by: David ALEXANDRE <[email protected]> * update values and config * prettifying config --------- Signed-off-by: David ALEXANDRE <[email protected]>
1 parent e1e4929 commit 358724f

18 files changed

+870
-1
lines changed

.github/dependabot.yml

+4
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@ updates:
1010
commit-message:
1111
prefix: "chore(deps)"
1212
open-pull-requests-limit: 10
13+
- package-ecosystem: "github-actions"
14+
directory: "/"
15+
schedule:
16+
interval: "weekly"

.github/workflows/build-and-push.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ name: Build and Push
22

33
on:
44
push:
5-
branches:
5+
paths:
6+
- '!charts/**.md'
7+
branches:
68
- main
79
tags:
810
- v*
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Lint and Test Charts
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- charts/**
7+
- '!charts/**.md'
8+
jobs:
9+
lint-test:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout
13+
uses: actions/[email protected]
14+
with:
15+
fetch-depth: 0
16+
17+
- name: Set up Helm
18+
uses: azure/setup-helm@v3
19+
with:
20+
version: v3.8.1
21+
22+
# Python is required because `ct lint` runs Yamale (https://github.com/23andMe/Yamale) and
23+
# yamllint (https://github.com/adrienverge/yamllint) which require Python
24+
- name: Set up Python
25+
uses: actions/[email protected]
26+
with:
27+
python-version: 3.7
28+
29+
- name: Set up chart-testing
30+
uses: helm/[email protected]
31+
with:
32+
version: v3.5.1
33+
34+
- name: Run chart-testing (list-changed)
35+
id: list-changed
36+
run: |
37+
changed=$(ct list-changed --config ct.yaml)
38+
if [[ -n "$changed" ]]; then
39+
echo "changed=true" >> $GITHUB_OUTPUT
40+
fi
41+
42+
- name: Run chart-testing (lint)
43+
run: ct lint --config ct.yaml
44+
45+
- name: Create kind cluster
46+
uses: helm/[email protected]
47+
if: steps.list-changed.outputs.changed == 'true'
48+
49+
- name: Run chart-testing (install)
50+
run: ct install --config ct.yaml

.github/workflows/chart-release.yaml

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Release Charts
2+
3+
on:
4+
push:
5+
paths:
6+
- charts/**
7+
- '!**.md'
8+
branches:
9+
- main
10+
11+
jobs:
12+
release:
13+
runs-on: ubuntu-latest
14+
15+
permissions:
16+
contents: write
17+
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
21+
with:
22+
fetch-depth: 0
23+
24+
- name: Configure Git
25+
run: |
26+
git config user.name "$GITHUB_ACTOR"
27+
git config user.email "[email protected]"
28+
29+
- name: Install Helm
30+
uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3.5
31+
with:
32+
version: v3.13.0
33+
34+
- name: Run chart-releaser
35+
uses: helm/chart-releaser-action@be16258da8010256c6e82849661221415f031968 # v1.5.0
36+
with:
37+
charts_dir: charts
38+
config: cr.yaml
39+
env:
40+
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: '[CI/CD] Update README metadata'
2+
3+
on:
4+
pull_request_target:
5+
branches:
6+
- main
7+
paths:
8+
- 'charts/*/values.yaml'
9+
# Remove all permissions by default
10+
permissions: {}
11+
jobs:
12+
update-readme-metadata:
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: write
16+
steps:
17+
- name: Install readme-generator-for-helm
18+
run: npm install -g @bitnami/readme-generator-for-helm
19+
- name: Checkout
20+
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
21+
with:
22+
path: charts
23+
ref: ${{github.event.pull_request.head.ref}}
24+
repository: ${{github.event.pull_request.head.repo.full_name}}
25+
token: ${{ secrets.GITHUB_TOKEN }}
26+
- name: Execute readme-generator-for-helm
27+
env:
28+
DIFF_URL: "${{github.event.pull_request.diff_url}}"
29+
TEMP_FILE: "${{runner.temp}}/pr-${{github.event.number}}.diff"
30+
run: |
31+
# This request doesn't consume API calls.
32+
curl -Lkso $TEMP_FILE $DIFF_URL
33+
files_changed="$(sed -nr 's/[\-\+]{3} [ab]\/(.*)/\1/p' $TEMP_FILE | sort | uniq)"
34+
# Adding || true to avoid "Process exited with code 1" errors
35+
charts_dirs_changed="$(echo "$files_changed" | xargs dirname | grep -o "pgcat/[^/]*" | sort | uniq || true)"
36+
for chart in ${charts_dirs_changed}; do
37+
echo "Updating README.md for ${chart}"
38+
readme-generator --values "charts/${chart}/values.yaml" --readme "charts/${chart}/README.md" --schema "/tmp/schema.json"
39+
done
40+
- name: Push changes
41+
run: |
42+
# Push all the changes
43+
cd charts
44+
if git status -s | grep pgcat; then
45+
git config user.name "$GITHUB_ACTOR"
46+
git config user.email "[email protected]"
47+
git add . && git commit -am "Update README.md with readme-generator-for-helm" --signoff && git push
48+
fi

charts/pgcat/.helmignore

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Patterns to ignore when building packages.
2+
# This supports shell glob matching, relative path matching, and
3+
# negation (prefixed with !). Only one pattern per line.
4+
.DS_Store
5+
# Common VCS dirs
6+
.git/
7+
.gitignore
8+
.bzr/
9+
.bzrignore
10+
.hg/
11+
.hgignore
12+
.svn/
13+
# Common backup files
14+
*.swp
15+
*.bak
16+
*.tmp
17+
*.orig
18+
*~
19+
# Various IDEs
20+
.project
21+
.idea/
22+
*.tmproj
23+
.vscode/

charts/pgcat/Chart.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
apiVersion: v2
2+
name: pgcat
3+
description: A Helm chart for PgCat a PostgreSQL pooler and proxy (like PgBouncer) with support for sharding, load balancing, failover and mirroring.
4+
maintainers:
5+
- name: Wildcard
6+
7+
appVersion: "1.1.1"
8+
version: 0.1.0

charts/pgcat/templates/NOTES.txt

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
1. Get the application URL by running these commands:
2+
{{- if .Values.ingress.enabled }}
3+
{{- range $host := .Values.ingress.hosts }}
4+
{{- range .paths }}
5+
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
6+
{{- end }}
7+
{{- end }}
8+
{{- else if contains "NodePort" .Values.service.type }}
9+
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "pgcat.fullname" . }})
10+
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
11+
echo http://$NODE_IP:$NODE_PORT
12+
{{- else if contains "LoadBalancer" .Values.service.type }}
13+
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
14+
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "pgcat.fullname" . }}'
15+
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "pgcat.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
16+
echo http://$SERVICE_IP:{{ .Values.service.port }}
17+
{{- else if contains "ClusterIP" .Values.service.type }}
18+
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "pgcat.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
19+
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
20+
echo "Visit http://127.0.0.1:8080 to use your application"
21+
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
22+
{{- end }}

charts/pgcat/templates/_config.tpl

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{{/*
2+
Configuration template definition
3+
*/}}

charts/pgcat/templates/_helpers.tpl

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{{/*
2+
Expand the name of the chart.
3+
*/}}
4+
{{- define "pgcat.name" -}}
5+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
6+
{{- end }}
7+
8+
{{/*
9+
Create a default fully qualified app name.
10+
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
11+
If release name contains chart name it will be used as a full name.
12+
*/}}
13+
{{- define "pgcat.fullname" -}}
14+
{{- if .Values.fullnameOverride }}
15+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
16+
{{- else }}
17+
{{- $name := default .Chart.Name .Values.nameOverride }}
18+
{{- if contains $name .Release.Name }}
19+
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
20+
{{- else }}
21+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
22+
{{- end }}
23+
{{- end }}
24+
{{- end }}
25+
26+
{{/*
27+
Create chart name and version as used by the chart label.
28+
*/}}
29+
{{- define "pgcat.chart" -}}
30+
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
31+
{{- end }}
32+
33+
{{/*
34+
Common labels
35+
*/}}
36+
{{- define "pgcat.labels" -}}
37+
helm.sh/chart: {{ include "pgcat.chart" . }}
38+
{{ include "pgcat.selectorLabels" . }}
39+
{{- if .Chart.AppVersion }}
40+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
41+
{{- end }}
42+
app.kubernetes.io/managed-by: {{ .Release.Service }}
43+
{{- end }}
44+
45+
{{/*
46+
Selector labels
47+
*/}}
48+
{{- define "pgcat.selectorLabels" -}}
49+
app.kubernetes.io/name: {{ include "pgcat.name" . }}
50+
app.kubernetes.io/instance: {{ .Release.Name }}
51+
{{- end }}
52+
53+
{{/*
54+
Create the name of the service account to use
55+
*/}}
56+
{{- define "pgcat.serviceAccountName" -}}
57+
{{- if .Values.serviceAccount.create }}
58+
{{- default (include "pgcat.fullname" .) .Values.serviceAccount.name }}
59+
{{- else }}
60+
{{- default "default" .Values.serviceAccount.name }}
61+
{{- end }}
62+
{{- end }}
+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: {{ include "pgcat.fullname" . }}
5+
labels:
6+
{{- include "pgcat.labels" . | nindent 4 }}
7+
spec:
8+
replicas: {{ .Values.replicaCount }}
9+
selector:
10+
matchLabels:
11+
{{- include "pgcat.selectorLabels" . | nindent 6 }}
12+
template:
13+
metadata:
14+
annotations:
15+
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
16+
{{- with .Values.podAnnotations }}
17+
{{- toYaml . | nindent 8 }}
18+
{{- end }}
19+
labels:
20+
{{- include "pgcat.selectorLabels" . | nindent 8 }}
21+
spec:
22+
{{- with .Values.image.pullSecrets }}
23+
imagePullSecrets:
24+
{{- toYaml . | nindent 8 }}
25+
{{- end }}
26+
serviceAccountName: {{ include "pgcat.serviceAccountName" . }}
27+
securityContext:
28+
{{- toYaml .Values.podSecurityContext | nindent 8 }}
29+
containers:
30+
- name: {{ .Chart.Name }}
31+
securityContext:
32+
{{- toYaml .Values.containerSecurityContext | nindent 12 }}
33+
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
34+
imagePullPolicy: {{ .Values.image.pullPolicy }}
35+
ports:
36+
- name: pgcat
37+
containerPort: {{ .Values.configuration.general.port }}
38+
protocol: TCP
39+
livenessProbe:
40+
tcpSocket:
41+
port: pgcat
42+
readinessProbe:
43+
tcpSocket:
44+
port: pgcat
45+
resources:
46+
{{- toYaml .Values.resources | nindent 12 }}
47+
volumeMounts:
48+
- mountPath: /etc/pgcat
49+
name: config
50+
{{- with .Values.nodeSelector }}
51+
nodeSelector:
52+
{{- toYaml . | nindent 8 }}
53+
{{- end }}
54+
{{- with .Values.affinity }}
55+
affinity:
56+
{{- toYaml . | nindent 8 }}
57+
{{- end }}
58+
{{- with .Values.tolerations }}
59+
tolerations:
60+
{{- toYaml . | nindent 8 }}
61+
{{- end }}
62+
volumes:
63+
- secret:
64+
defaultMode: 420
65+
secretName: {{ include "pgcat.fullname" . }}
66+
name: config

0 commit comments

Comments
 (0)