Add helm chart
add README
This commit is contained in:
parent
004c03962f
commit
351b5e8fed
17 changed files with 860 additions and 0 deletions
|
|
@ -71,6 +71,8 @@ Check out the [quickstart](/doc/quickstart.md) document for instructions on how
|
|||
|
||||
Thanks to the efforts of the amazing folks at [@mercedes-benz](https://github.com/mercedes-benz/), GARM can now be integrated into k8s via their operator. Check out the [GARM operator](https://github.com/mercedes-benz/garm-operator/) for more details.
|
||||
|
||||
In addition to the operator, GARM can also be deployed on Kubernetes using the provided Helm chart. For detailed instructions, please see the [Helm deployment guide](/doc/helm.md).
|
||||
|
||||
## Configuring GARM for GHES
|
||||
|
||||
GARM supports creating pools and scale sets in either GitHub itself or in your own deployment of [GitHub Enterprise Server](https://docs.github.com/en/enterprise-server@3.10/admin/overview/about-github-enterprise-server). For instructions on how to use ```GARM``` with GHE, see the [credentials](/doc/github_credentials.md) section of the documentation.
|
||||
|
|
|
|||
124
doc/helm.md
Normal file
124
doc/helm.md
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
# Deploying GARM with Helm
|
||||
|
||||
This document provides instructions on how to deploy GARM on a Kubernetes cluster using the provided Helm chart.
|
||||
|
||||
As this chart is not currently published to a public Helm repository, you will need to clone the GARM git repository to deploy it.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Kubernetes 1.19+
|
||||
- Helm 3.2.0+
|
||||
- `kubectl` configured to connect to your cluster.
|
||||
|
||||
### Admin Credentials
|
||||
|
||||
By default, the chart creates a Kubernetes secret to store the admin user\'s credentials (`username`, `password`, `email`), the JWT secret, and the database passphrase.
|
||||
|
||||
If you want to use an existing secret, you can specify its name using `garm.admin.secretName`. Ensure the secret contains the necessary keys as defined by `garm.admin.usernameKey`, `garm.admin.passwordKey`, etc.
|
||||
|
||||
### Persistence
|
||||
|
||||
The chart uses a PersistentVolumeClaim (PVC) to store the GARM database. By default, persistence is enabled. You can disable it by setting `persistence.enabled` to `false`, but this is not recommended for production environments.
|
||||
|
||||
### Providers Configuration
|
||||
|
||||
You can configure external providers by adding them to the `providers` list in your `values.yaml` file. Each provider entry requires a `name`, `description`, `executable` path, and a `config` block with the provider-specific settings.
|
||||
|
||||
Example for a GCP provider:
|
||||
|
||||
```yaml
|
||||
providers:
|
||||
- name: "gcp"
|
||||
type: "external"
|
||||
description: "GCP provider"
|
||||
executable: "/opt/garm/providers.d/garm-provider-gcp"
|
||||
config:
|
||||
project_id: "my-gcp-project"
|
||||
zone: "us-central1-a"
|
||||
```
|
||||
|
||||
### Forge Credentials (GitHub/Gitea)
|
||||
|
||||
The chart\'s initialization script can automatically configure GARM with your GitHub and/or Gitea credentials. To use this feature, you must first create Kubernetes secrets containing your forge credentials.
|
||||
|
||||
Then, configure the `forges.github.credentials` or `forges.gitea.credentials` sections in your `values.yaml`.
|
||||
|
||||
**GitHub Example:**
|
||||
|
||||
First, create a secret:
|
||||
|
||||
```bash
|
||||
kubectl create secret generic my-github-secret \
|
||||
--from-literal=token='ghp_xxxxxxxx'
|
||||
```
|
||||
|
||||
Then, configure `values.yaml`:
|
||||
|
||||
```yaml
|
||||
forges:
|
||||
github:
|
||||
credentials:
|
||||
- name: "my-github"
|
||||
secretName: "my-github-secret"
|
||||
authType: "pat"
|
||||
tokenKey: "token"
|
||||
```
|
||||
|
||||
**Gitea Example:**
|
||||
|
||||
First, create a secret:
|
||||
|
||||
```bash
|
||||
kubectl create secret generic garm-gitea-config \
|
||||
--from-literal=server-url='https://gitea.example.com' \
|
||||
--from-literal=access-token='xxxxxxxx'
|
||||
```
|
||||
|
||||
Then, configure `values.yaml`:
|
||||
|
||||
```yaml
|
||||
forges:
|
||||
gitea:
|
||||
credentials:
|
||||
- name: "my-gitea"
|
||||
secretName: "garm-gitea-config"
|
||||
urlKey: "server-url"
|
||||
tokenKey: "access-token"
|
||||
```
|
||||
|
||||
## Installation Steps
|
||||
|
||||
The `helm-chart/values.yaml` file serves as a template and is not intended for direct use, as it contains placeholder values. To properly deploy the chart, follow these steps:
|
||||
|
||||
1. **Create a custom values file:**
|
||||
Clone the repository and copy the `values.yaml` to a new file. For example, `my-values.yaml`.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/cloudbase/garm.git
|
||||
cd garm
|
||||
cp helm-chart/values.yaml my-values.yaml
|
||||
```
|
||||
|
||||
2. **Configure your deployment:**
|
||||
Edit `my-values.yaml` and modify the parameters to match your environment. At a minimum, you will likely need to configure:
|
||||
- `garm.url` (or the individual `callbackUrl`, `metadataUrl`, `webhookUrl`)
|
||||
- `ingress.host` if you are using Ingress.
|
||||
- `providers` to set up at least one compute provider.
|
||||
- `forges` to configure credentials for GitHub or Gitea.
|
||||
|
||||
3. **Install the chart:**
|
||||
Once you have configured your `my-values.yaml`, install the chart using the `-f` flag to specify your custom values file.
|
||||
|
||||
```bash
|
||||
helm install my-garm ./helm-chart -f my-values.yaml
|
||||
```
|
||||
|
||||
## Uninstallation
|
||||
|
||||
To uninstall the `my-garm` deployment:
|
||||
|
||||
```bash
|
||||
helm uninstall my-garm
|
||||
```
|
||||
|
||||
The command removes all the Kubernetes components associated with the chart and deletes the release.
|
||||
1
helm-chart/.gitignore
vendored
Normal file
1
helm-chart/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
charts
|
||||
23
helm-chart/.helmignore
Normal file
23
helm-chart/.helmignore
Normal file
|
|
@ -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/
|
||||
9
helm-chart/Chart.yaml
Normal file
9
helm-chart/Chart.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: v2
|
||||
name: garm
|
||||
description: GARM (Github/Gitea Actions Runner Manager) Helm Chart
|
||||
|
||||
type: application
|
||||
|
||||
version: 0.1.0
|
||||
|
||||
appVersion: "nightly"
|
||||
22
helm-chart/templates/NOTES.txt
Normal file
22
helm-chart/templates/NOTES.txt
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
1. Get the application URL by running these commands:
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- $protocol := "http" -}}
|
||||
{{- if .Values.ingress.tls.secretName -}}
|
||||
{{- $protocol = "https" -}}
|
||||
{{- end -}}
|
||||
echo {{ $protocol }}://{{ .Values.ingress.host }}
|
||||
{{- else if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "garm.fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "garm.fullname" . }}'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "garm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "garm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||
{{- end }}
|
||||
72
helm-chart/templates/_helpers.tpl
Normal file
72
helm-chart/templates/_helpers.tpl
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "garm.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 "garm.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 "garm.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "garm.labels" -}}
|
||||
helm.sh/chart: {{ include "garm.chart" . }}
|
||||
{{ include "garm.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "garm.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "garm.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "garm.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "garm.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
|
||||
{{- define "garm.admin-secret-name" -}}
|
||||
{{- .Values.garm.admin.secretName | default (printf "%s-admin-credentials" (include "garm.fullname" .)) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "garm.db-path" -}}
|
||||
/var/lib/garm
|
||||
{{- end -}}
|
||||
89
helm-chart/templates/configmap-init-script.yaml
Normal file
89
helm-chart/templates/configmap-init-script.yaml
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: "{{ include "garm.fullname" . }}-init-script"
|
||||
labels:
|
||||
{{- include "garm.labels" . | nindent 4 }}
|
||||
data:
|
||||
init.sh: |-
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
INIT_MARKER="{{ include "garm.db-path" . }}/.initialized"
|
||||
if [ -f "$INIT_MARKER" ]; then
|
||||
echo "GARM already initialized, skipping setup."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Start GARM in the background
|
||||
/bin/garm -config /etc/garm/config.toml &
|
||||
GARM_PID=$!
|
||||
|
||||
# Wait for the server to be ready
|
||||
sleep 5
|
||||
|
||||
# Run GARM setup
|
||||
garm-cli init \
|
||||
--name "{{ include "garm.fullname" . }}" \
|
||||
--url "http://localhost:{{ .Values.service.port }}" \
|
||||
--callback-url "{{- if .Values.garm.callbackUrl }}{{ .Values.garm.callbackUrl }}{{- else }}{{ .Values.garm.url | trimSuffix "/" }}/api/v1/callbacks{{- end }}" \
|
||||
--metadata-url "{{- if .Values.garm.metadataUrl }}{{ .Values.garm.metadataUrl }}{{- else }}{{ .Values.garm.url | trimSuffix "/" }}/api/v1/metadata{{- end }}" \
|
||||
--webhook-url "{{- if .Values.garm.webhookUrl }}{{ .Values.garm.webhookUrl }}{{- else }}{{ .Values.garm.url | trimSuffix "/" }}/webhooks{{- end }}" \
|
||||
--username "$GARM_ADMIN_USERNAME" \
|
||||
--email "$GARM_ADMIN_EMAIL" \
|
||||
--password "$GARM_ADMIN_PASSWORD"
|
||||
|
||||
{{- if .Values.forges.gitea.credentials }}
|
||||
{{- range $i, $cred := .Values.forges.gitea.credentials }}
|
||||
GITEA_URL=$(cat /gitea-secrets/{{ $cred.name }}/{{ $cred.urlKey }})
|
||||
GITEA_TOKEN=$(cat /gitea-secrets/{{ $cred.name }}/{{ $cred.tokenKey }})
|
||||
|
||||
garm-cli gitea endpoint create --api-base-url "$GITEA_URL" --base-url "$GITEA_URL" --description "{{ $cred.name }}" --name "{{ $cred.name }}"
|
||||
garm-cli gitea credentials add --endpoint "{{ $cred.name }}" --auth-type pat --pat-oauth-token "$GITEA_TOKEN" --name "{{ $cred.name }}-token" --description "{{ $cred.name }} access token"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.forges.github.credentials }}
|
||||
{{- range $cred := .Values.forges.github.credentials }}
|
||||
{{- if $cred.urlKey }}
|
||||
GITHUB_URL=$(cat /github-secrets/{{ $cred.name }}/{{ $cred.urlKey }})
|
||||
garm-cli github endpoint create \
|
||||
--api-base-url "$GITHUB_URL" \
|
||||
--base-url "$GITHUB_URL" \
|
||||
--description "{{ $cred.name }}" \
|
||||
--name "{{ $cred.name }}"
|
||||
{{- end }}
|
||||
|
||||
{{- if eq $cred.authType "pat" }}
|
||||
GITHUB_TOKEN=$(cat /github-secrets/{{ $cred.name }}/{{ $cred.tokenKey }})
|
||||
garm-cli github credentials add \
|
||||
--name "{{ $cred.name }}" \
|
||||
{{- if $cred.urlKey }}
|
||||
--endpoint "{{ $cred.name }}" \
|
||||
{{- end }}
|
||||
--auth-type pat \
|
||||
--pat-oauth-token "$GITHUB_TOKEN"
|
||||
{{- else if eq $cred.authType "app" }}
|
||||
APP_ID=$(cat /github-secrets/{{ $cred.name }}/{{ $cred.appIdKey }})
|
||||
INSTALL_ID=$(cat /github-secrets/{{ $cred.name }}/{{ $cred.appInstallationIdKey }})
|
||||
PRIVATE_KEY_PATH="/github-secrets/{{ $cred.name }}/{{ $cred.privateKeyKey }}"
|
||||
garm-cli github credentials add \
|
||||
--name "{{ $cred.name }}" \
|
||||
{{- if $cred.urlKey }}
|
||||
--endpoint "{{ $cred.name }}" \
|
||||
{{- end }}
|
||||
--auth-type app \
|
||||
--app-id "$APP_ID" \
|
||||
--app-installation-id "$INSTALL_ID" \
|
||||
--private-key-path "$PRIVATE_KEY_PATH"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
echo "GARM initialization complete."
|
||||
|
||||
# Stop the background GARM server
|
||||
kill $GARM_PID
|
||||
|
||||
# Create the marker file to indicate that initialization is done
|
||||
touch "$INIT_MARKER"
|
||||
17
helm-chart/templates/configmap-providers.yaml
Normal file
17
helm-chart/templates/configmap-providers.yaml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{{- /*
|
||||
Create a ConfigMap for each provider defined in values.yaml
|
||||
*/}}
|
||||
{{- range $provider := .Values.providers }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: "{{ include "garm.fullname" $ }}-provider-{{ .name }}"
|
||||
labels:
|
||||
{{- include "garm.labels" $ | nindent 4 }}
|
||||
data:
|
||||
garm-provider-{{ .name }}.toml: |
|
||||
{{- range $key, $value := .config }}
|
||||
{{ $key }} = {{ $value | toToml }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
47
helm-chart/templates/configmap.yaml
Normal file
47
helm-chart/templates/configmap.yaml
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: "{{ include "garm.fullname" . }}-config"
|
||||
labels:
|
||||
{{- include "garm.labels" . | nindent 4 }}
|
||||
data:
|
||||
config.toml: |-
|
||||
[default]
|
||||
enable_webhook_management = true
|
||||
|
||||
[logging]
|
||||
enable_log_streamer = true
|
||||
log_format = "text"
|
||||
log_level = "info"
|
||||
log_source = false
|
||||
|
||||
[metrics]
|
||||
enable = true
|
||||
disable_auth = false
|
||||
|
||||
[jwt_auth]
|
||||
secret = "$GARM_JWT_SECRET"
|
||||
time_to_live = "8760h"
|
||||
|
||||
[apiserver]
|
||||
bind = "0.0.0.0"
|
||||
port = {{ .Values.service.port }}
|
||||
use_tls = false
|
||||
[apiserver.webui]
|
||||
enable = {{ .Values.garm.ui.enabled }}
|
||||
|
||||
[database]
|
||||
backend = "sqlite3"
|
||||
passphrase = "$GARM_DB_PASSPHRASE"
|
||||
[database.sqlite3]
|
||||
db_file = "{{ include "garm.db-path" . }}/garm.db"
|
||||
|
||||
{{- range .Values.providers }}
|
||||
[[provider]]
|
||||
name = "{{ .name }}"
|
||||
provider_type = "{{ .type | default "external" }}"
|
||||
description = "{{ .description }}"
|
||||
[provider.external]
|
||||
provider_executable = "{{ .executable }}"
|
||||
config_file = "/etc/garm/provider-configs/garm-provider-{{ .name }}.toml"
|
||||
{{- end }}
|
||||
166
helm-chart/templates/deployment.yaml
Normal file
166
helm-chart/templates/deployment.yaml
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "garm.fullname" . }}
|
||||
labels:
|
||||
{{- include "garm.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "garm.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "garm.labels" . | nindent 8 }}
|
||||
{{- with .Values.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
serviceAccountName: {{ include "garm.serviceAccountName" . }}
|
||||
volumes:
|
||||
- name: garm-config
|
||||
emptyDir: {}
|
||||
{{- if .Values.persistence.enabled }}
|
||||
- name: garm-db
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "garm.fullname" . }}-db
|
||||
{{- end }}
|
||||
- name: config-templates
|
||||
configMap:
|
||||
name: "{{ include "garm.fullname" . }}-config"
|
||||
- name: init-script
|
||||
configMap:
|
||||
name: "{{ include "garm.fullname" . }}-init-script"
|
||||
defaultMode: 0755
|
||||
{{- range .Values.providers }}
|
||||
- name: provider-config-{{ .name }}
|
||||
configMap:
|
||||
name: {{ include "garm.fullname" $ }}-provider-{{ .name }}
|
||||
{{- end }}
|
||||
{{- if .Values.forges.gitea.credentials }}
|
||||
{{- range .Values.forges.gitea.credentials }}
|
||||
- name: gitea-secret-{{ .name }}
|
||||
secret:
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.forges.github.credentials }}
|
||||
{{- range .Values.forges.github.credentials }}
|
||||
- name: github-secret-{{ .name }}
|
||||
secret:
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.extraVolumes }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
initContainers:
|
||||
- name: substitute-config
|
||||
image: envsubst/envsubst
|
||||
command: ["/bin/sh", "-c"]
|
||||
args:
|
||||
- |
|
||||
envsubst < /config-templates/config.toml > /etc/garm/config.toml
|
||||
env:
|
||||
- name: GARM_JWT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "garm.admin-secret-name" . }}
|
||||
key: {{ .Values.garm.admin.jwtSecretKey }}
|
||||
- name: GARM_DB_PASSPHRASE
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "garm.admin-secret-name" . }}
|
||||
key: {{ .Values.garm.admin.dbPassphraseKey }}
|
||||
volumeMounts:
|
||||
- name: garm-config
|
||||
mountPath: /etc/garm
|
||||
- name: config-templates
|
||||
mountPath: /config-templates
|
||||
|
||||
- name: config-init
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
command: ["/init/init.sh"]
|
||||
env:
|
||||
- name: GARM_ADMIN_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "garm.admin-secret-name" . }}
|
||||
key: {{ .Values.garm.admin.usernameKey }}
|
||||
- name: GARM_ADMIN_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "garm.admin-secret-name" . }}
|
||||
key: {{ .Values.garm.admin.passwordKey }}
|
||||
- name: GARM_ADMIN_EMAIL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "garm.admin-secret-name" . }}
|
||||
key: {{ .Values.garm.admin.emailKey }}
|
||||
volumeMounts:
|
||||
- name: garm-config
|
||||
mountPath: /etc/garm
|
||||
{{- if .Values.persistence.enabled }}
|
||||
- name: garm-db
|
||||
mountPath: {{ include "garm.db-path" . }}
|
||||
{{- end }}
|
||||
- name: config-templates
|
||||
mountPath: /config-templates
|
||||
- name: init-script
|
||||
mountPath: /init
|
||||
{{- if .Values.forges.gitea.credentials }}
|
||||
{{- range .Values.forges.gitea.credentials }}
|
||||
- name: gitea-secret-{{ .name }}
|
||||
mountPath: /gitea-secrets/{{ .name }}
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.forges.github.credentials }}
|
||||
{{- range .Values.forges.github.credentials }}
|
||||
- name: github-secret-{{ .name }}
|
||||
mountPath: /github-secrets/{{ .name }}
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- range .Values.providers }}
|
||||
- name: provider-config-{{ .name }}
|
||||
mountPath: "/etc/garm/provider-configs/garm-provider-{{ .name }}.toml"
|
||||
subPath: "garm-provider-{{ .name }}.toml"
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- name: garm-config
|
||||
mountPath: /etc/garm
|
||||
{{- if .Values.persistence.enabled }}
|
||||
- name: garm-db
|
||||
mountPath: {{ include "garm.db-path" . }}
|
||||
{{- end }}
|
||||
{{- with .Values.extraVolumeMounts }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- range .Values.providers }}
|
||||
- name: provider-config-{{ .name }}
|
||||
mountPath: "/etc/garm/provider-configs/garm-provider-{{ .name }}.toml"
|
||||
subPath: "garm-provider-{{ .name }}.toml"
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- with .Values.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
33
helm-chart/templates/ingress.yaml
Normal file
33
helm-chart/templates/ingress.yaml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
{{- if .Values.ingress.enabled -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "garm.fullname" . }}
|
||||
labels:
|
||||
{{- include "garm.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.ingress.className }}
|
||||
ingressClassName: {{ . }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls.secretName }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ .Values.ingress.host | quote }}
|
||||
secretName: {{ .Values.ingress.tls.secretName }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- host: {{ .Values.ingress.host | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: "/"
|
||||
pathType: "Prefix"
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "garm.fullname" . }}
|
||||
port:
|
||||
number: {{ .Values.service.port }}
|
||||
{{- end }}
|
||||
23
helm-chart/templates/pvc.yaml
Normal file
23
helm-chart/templates/pvc.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{{- if .Values.persistence.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "garm.fullname" . }}-db
|
||||
labels:
|
||||
{{- include "garm.labels" . | nindent 4 }}
|
||||
{{- with .Values.persistence.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
{{- range .Values.persistence.accessModes }}
|
||||
- {{ . }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.size }}
|
||||
{{- if .Values.persistence.storageClassName }}
|
||||
storageClassName: {{ .Values.persistence.storageClassName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
31
helm-chart/templates/secret.yaml
Normal file
31
helm-chart/templates/secret.yaml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{{- if not .Values.garm.admin.secretName -}}
|
||||
{{- $secretName := include "garm.admin-secret-name" . -}}
|
||||
{{- $existingSecret := lookup "v1" "Secret" .Release.Namespace $secretName -}}
|
||||
|
||||
{{- $password := "" -}}
|
||||
{{- $jwtSecret := "" -}}
|
||||
{{- $dbPassphrase := "" -}}
|
||||
|
||||
{{- if $existingSecret -}}
|
||||
{{- $password = index $existingSecret.data .Values.garm.admin.passwordKey | b64dec -}}
|
||||
{{- $jwtSecret = index $existingSecret.data .Values.garm.admin.jwtSecretKey | b64dec -}}
|
||||
{{- $dbPassphrase = index $existingSecret.data .Values.garm.admin.dbPassphraseKey | b64dec -}}
|
||||
{{- else -}}
|
||||
{{- $password = randAlphaNum 40 -}}
|
||||
{{- $jwtSecret = randAlphaNum 64 -}}
|
||||
{{- $dbPassphrase = randAlphaNum 32 -}}
|
||||
{{- end -}}
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ $secretName }}
|
||||
labels:
|
||||
{{- include "garm.labels" . | nindent 4 }}
|
||||
stringData:
|
||||
{{ .Values.garm.admin.usernameKey }}: {{ .Values.garm.admin.defaultUsername | quote }}
|
||||
{{ .Values.garm.admin.passwordKey }}: {{ $password | quote }}
|
||||
{{ .Values.garm.admin.emailKey }}: {{ .Values.garm.admin.defaultEmail | quote }}
|
||||
{{ .Values.garm.admin.jwtSecretKey }}: {{ $jwtSecret | quote }}
|
||||
{{ .Values.garm.admin.dbPassphraseKey }}: {{ $dbPassphrase | quote }}
|
||||
{{- end -}}
|
||||
19
helm-chart/templates/service.yaml
Normal file
19
helm-chart/templates/service.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "garm.fullname" . }}
|
||||
{{- with .Values.service.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "garm.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "garm.selectorLabels" . | nindent 4 }}
|
||||
13
helm-chart/templates/serviceaccount.yaml
Normal file
13
helm-chart/templates/serviceaccount.yaml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "garm.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "garm.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
|
||||
{{- end }}
|
||||
169
helm-chart/values.yaml
Normal file
169
helm-chart/values.yaml
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
# -- GARM application configuration
|
||||
garm:
|
||||
# -- Enable the GARM web UI.
|
||||
ui:
|
||||
enabled: true
|
||||
|
||||
# -- GARM admin user credentials. These will be stored in a Kubernetes secret.
|
||||
admin:
|
||||
# -- The name of the secret containing the admin credentials.
|
||||
# -- If not set, a secret will be created with a generated password.
|
||||
secretName: ""
|
||||
# -- The default admin username to use when generating the secret.
|
||||
defaultUsername: "admin"
|
||||
# -- The default admin email address to use when generating the secret.
|
||||
defaultEmail: "admin@example.com"
|
||||
# -- The key in the secret for the admin username.
|
||||
usernameKey: "username"
|
||||
# -- The key in the secret for the admin password.
|
||||
passwordKey: "password"
|
||||
# -- The key in the secret for the admin email.
|
||||
emailKey: "email"
|
||||
# -- The key in the secret for the JWT secret.
|
||||
jwtSecretKey: "jwt-secret"
|
||||
# -- The key in the secret for the database passphrase.
|
||||
dbPassphraseKey: "db-passphrase"
|
||||
|
||||
# -- The base URL for the GARM service. This will be used in garm init process.
|
||||
# -- You can omit this variable if URLs below are set.
|
||||
url: "http://garm.example.com:9997"
|
||||
# -- Specify callback URL (with correct URI path). If empty, garm.url will be used.
|
||||
callbackUrl: ""
|
||||
# -- Specify metadata URL (with correct URI path). If empty, garm.url will be used.
|
||||
metadataUrl: ""
|
||||
# -- Specify webhook URL (with correct URI path). If empty, garm.url will be used.
|
||||
webhookUrl: ""
|
||||
|
||||
# -- Image configuration for GARM and its components.
|
||||
image:
|
||||
# -- GARM image repository.
|
||||
repository: ghcr.io/cloudbase/garm
|
||||
# -- GARM image pull policy.
|
||||
pullPolicy: Always
|
||||
# -- GARM image tag. Overrides the chart's appVersion.
|
||||
tag: ""
|
||||
|
||||
# -- Overrides for the chart name.
|
||||
nameOverride: ""
|
||||
# -- Overrides for the full chart name.
|
||||
fullnameOverride: ""
|
||||
|
||||
# -- ServiceAccount configuration.
|
||||
serviceAccount:
|
||||
# -- Specifies whether a service account should be created.
|
||||
create: true
|
||||
# -- Automatically mount a ServiceAccount's API credentials.
|
||||
automount: true
|
||||
# -- Annotations to add to the service account.
|
||||
annotations: {}
|
||||
# -- The name of the service account to use.
|
||||
# -- If not set and create is true, a name is generated using the fullname template.
|
||||
name: ""
|
||||
|
||||
# -- Annotations for the Pod.
|
||||
podAnnotations: {}
|
||||
# -- Labels for the Pod.
|
||||
podLabels: {}
|
||||
|
||||
# -- Service configuration.
|
||||
service:
|
||||
# -- Kubernetes service type.
|
||||
type: ClusterIP
|
||||
# -- The port for the GARM service.
|
||||
port: 9997
|
||||
annotations: {}
|
||||
|
||||
# -- Ingress configuration.
|
||||
ingress:
|
||||
# -- Enable or disable the Ingress resource.
|
||||
enabled: false
|
||||
# -- The public-facing host for the Ingress resource. Required if ingress.enabled is true.
|
||||
host: ""
|
||||
# -- IngressClassName for the Ingress resource.
|
||||
className: ""
|
||||
# -- Annotations for the Ingress resource.
|
||||
annotations: {}
|
||||
# -- TLS configuration for the Ingress.
|
||||
tls:
|
||||
# -- The name of the secret containing the TLS certificate.
|
||||
secretName: ""
|
||||
|
||||
# -- Resource requests and limits for the GARM container.
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
|
||||
# -- Additional volumes to mount in the Pod.
|
||||
extraVolumes: []
|
||||
# - name: foo
|
||||
# secret:
|
||||
# secretName: mysecret
|
||||
# optional: false
|
||||
|
||||
# -- Additional volume mounts for the GARM container.
|
||||
extraVolumeMounts: []
|
||||
# - name: foo
|
||||
# mountPath: "/etc/foo"
|
||||
# readOnly: true
|
||||
|
||||
# -- Persistence configuration for the GARM database.
|
||||
persistence:
|
||||
# -- Enable or disable persistence.
|
||||
enabled: true
|
||||
# -- Annotations for the PVC.
|
||||
annotations: {}
|
||||
# -- The storage class to use for the PVC.
|
||||
storageClassName: ""
|
||||
# -- The access modes for the PVC.
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
# -- The size of the PVC.
|
||||
size: 1Gi
|
||||
|
||||
# -- Configuration for different git forges.
|
||||
forges:
|
||||
# -- Gitea server configurations.
|
||||
gitea:
|
||||
# -- A list of Gitea credentials. If empty, Gitea integration is not initialized.
|
||||
credentials: []
|
||||
# - name: "my-gitea"
|
||||
# secretName: "garm-gitea-config"
|
||||
# urlKey: "server-url"
|
||||
# tokenKey: "access-token"
|
||||
|
||||
# -- GitHub server configurations.
|
||||
github:
|
||||
# -- A list of GitHub servers/credentials. If empty, GitHub integration is not initialized.
|
||||
credentials: []
|
||||
# - name: "my-github"
|
||||
# secretName: "my-github-secret"
|
||||
# -- If this field is empty, the default GitHub endpoint will be used.
|
||||
# urlKey: ""
|
||||
# -- Allowed values: 'pat' or 'app'
|
||||
# authType: "pat"
|
||||
# -- Specify this key only if authType is 'pat'
|
||||
# tokenKey: "token"
|
||||
# -- Specify values below only if authType is 'app'
|
||||
# appIdKey: "app-id"
|
||||
# appInstallationIdKey: "app-installation-id"
|
||||
# privateKeyKey: "private-key"
|
||||
|
||||
# -- Configuration for different providers.
|
||||
providers: []
|
||||
# - name: "gcp" # Unique name for this provider
|
||||
# type: "external" # Provider type
|
||||
# description: "GCP provider"
|
||||
# executable: "/opt/garm/providers.d/garm-provider-gcp" # Path to the executable
|
||||
#
|
||||
# # -- Dynamic configuration for the provider's .toml file.
|
||||
# # -- You can add any keys here, and they will be added to the ConfigMap.
|
||||
# config:
|
||||
# project_id: "my-gcp-project"
|
||||
# zone: "us-central1-a"
|
||||
# network_id: "projects/my-gcp-project/global/networks/default"
|
||||
# subnetwork_id: "projects/my-gcp-project/regions/us-central1/subnetworks/default"
|
||||
# external_ip_access: true
|
||||
Loading…
Add table
Add a link
Reference in a new issue