init
All checks were successful
docker-build / Build image (push) Successful in 9s

This commit is contained in:
2025-12-07 20:18:17 +07:00
commit 489db3b8a6
68 changed files with 4723 additions and 0 deletions

View 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/

View File

@@ -0,0 +1,17 @@
apiVersion: v2
name: gitlab-job-runner
description: Kubernetes operator for executing code from GitLab repositories as Jobs or CronJobs
type: application
version: 0.1.0
appVersion: "0.1.0"
keywords:
- gitlab
- job
- cronjob
- operator
- automation
maintainers:
- name: RML Team
home: https://git.realmanual.ru/realmanual/gitlab-job-runner.git
sources:
- https://git.realmanual.ru/realmanual/gitlab-job-runner.git

View File

@@ -0,0 +1,26 @@
# GitLab Job Runner
Kubernetes operator for executing code from GitLab repositories as Jobs or CronJobs.
## Quick Start
```bash
# Install with Helm
helm install gitlab-job-runner ./helm/gitlab-job-runner \
--namespace gitlab-job-runner-system \
--create-namespace
# Create GitLab credentials
kubectl create secret generic gitlab-credentials \
--from-literal=GITLAB_URL=https://gitlab.example.com \
--from-literal=GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx
# Deploy example job
kubectl apply -f config/samples/batch_v1alpha1_gitlabjobrunner.yaml
```
## Documentation
- [Full Documentation](README.md)
- [Helm Chart Documentation](helm/gitlab-job-runner/README.md)
- [Examples](examples/)

View File

@@ -0,0 +1,151 @@
# GitLab Job Runner Helm Chart
Kubernetes operator for executing code from GitLab repositories as Jobs or CronJobs.
## Installation
### Add Helm Repository
```bash
helm repo add gitlab-job-runner https://your-repo-url
helm repo update
```
### Install Chart
```bash
helm install gitlab-job-runner gitlab-job-runner/gitlab-job-runner \
--namespace gitlab-job-runner-system \
--create-namespace
```
### Install from Local
```bash
helm install gitlab-job-runner ./helm/gitlab-job-runner \
--namespace gitlab-job-runner-system \
--create-namespace
```
## Configuration
### Basic Configuration
```yaml
# values.yaml
replicaCount: 1
image:
repository: your-registry/gitlab-job-runner
tag: "0.1.0"
pullPolicy: IfNotPresent
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 10m
memory: 64Mi
```
### Enable Leader Election
For high availability with multiple replicas:
```yaml
replicaCount: 3
leaderElection:
enabled: true
```
### Metrics Configuration
```yaml
metrics:
enabled: true
port: 8443
secure: true
```
### RBAC Configuration
```yaml
rbac:
create: true
serviceAccount:
create: true
name: ""
annotations: {}
```
## Parameters
| Parameter | Description | Default |
|-----------------------------|-------------------------|----------------|
| `replicaCount` | Number of replicas | `1` |
| `image.repository` | Image repository | `controller` |
| `image.tag` | Image tag | `latest` |
| `image.pullPolicy` | Image pull policy | `IfNotPresent` |
| `serviceAccount.create` | Create service account | `true` |
| `serviceAccount.name` | Service account name | `""` |
| `rbac.create` | Create RBAC resources | `true` |
| `leaderElection.enabled` | Enable leader election | `false` |
| `metrics.enabled` | Enable metrics | `true` |
| `metrics.port` | Metrics port | `8443` |
| `metrics.secure` | Secure metrics endpoint | `true` |
| `healthProbe.port` | Health probe port | `8081` |
| `resources.limits.cpu` | CPU limit | `500m` |
| `resources.limits.memory` | Memory limit | `128Mi` |
| `resources.requests.cpu` | CPU request | `10m` |
| `resources.requests.memory` | Memory request | `64Mi` |
## Usage
After installation, create GitLab credentials and GitlabJobRunner resources:
### Create GitLab Secret
```bash
kubectl create secret generic gitlab-credentials \
--from-literal=GITLAB_URL=https://gitlab.example.com \
--from-literal=GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx \
-n default
```
### Create GitlabJobRunner
```yaml
apiVersion: batch.rml.ru/v1alpha1
kind: GitlabJobRunner
metadata:
name: example-job
spec:
gitlabSecretRef: gitlab-credentials
repositoryURL: mygroup/myrepo
branch: main
scriptPath: scripts/deploy.sh
```
## Upgrade
```bash
helm upgrade gitlab-job-runner gitlab-job-runner/gitlab-job-runner \
--namespace gitlab-job-runner-system
```
## Uninstall
```bash
helm uninstall gitlab-job-runner \
--namespace gitlab-job-runner-system
```
## Testing
```bash
helm test gitlab-job-runner \
--namespace gitlab-job-runner-system
```

View File

@@ -0,0 +1,42 @@
NOTES:
Thank you for installing {{ .Chart.Name }}.
Your release is named {{ .Release.Name }}.
To learn more about the release, try:
$ helm status {{ .Release.Name }} -n {{ .Release.Namespace }}
$ helm get all {{ .Release.Name }} -n {{ .Release.Namespace }}
The GitLab Job Runner operator has been deployed successfully!
Controller manager deployment: {{ include "gitlab-job-runner.fullname" . }}-controller-manager
Next steps:
1. Create a Secret with GitLab credentials:
kubectl create secret generic gitlab-credentials \
--from-literal=GITLAB_URL=https://gitlab.example.com \
--from-literal=GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx
2. Create a GitlabJobRunner resource:
cat <<EOF | kubectl apply -f -
apiVersion: batch.rml.ru/v1alpha1
kind: GitlabJobRunner
metadata:
name: example-job
spec:
gitlabSecretRef: gitlab-credentials
repositoryURL: mygroup/myrepo
branch: main
scriptPath: scripts/deploy.sh
EOF
3. Check the status:
kubectl get gitlabjobrunner
kubectl describe gitlabjobrunner example-job
For more information, visit: https://github.com/rml/gitlab-job-runner

View File

@@ -0,0 +1,60 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "gitlab-job-runner.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
*/}}
{{- define "gitlab-job-runner.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 "gitlab-job-runner.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "gitlab-job-runner.labels" -}}
helm.sh/chart: {{ include "gitlab-job-runner.chart" . }}
{{ include "gitlab-job-runner.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "gitlab-job-runner.selectorLabels" -}}
app.kubernetes.io/name: {{ include "gitlab-job-runner.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "gitlab-job-runner.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "gitlab-job-runner.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,157 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.19.0
name: gitlabjobrunners.batch.rml.ru
spec:
group: batch.rml.ru
names:
kind: GitlabJobRunner
listKind: GitlabJobRunnerList
plural: gitlabjobrunners
singular: gitlabjobrunner
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: GitlabJobRunner is the Schema for the gitlabjobrunners API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: spec defines the desired state of GitlabJobRunner
properties:
branch:
description: branch to checkout, defaults to "main"
type: string
concurrencyPolicy:
default: Forbid
description: concurrencyPolicy defines how to handle concurrent executions
type: string
gitlabSecretRef:
description: |-
gitlabSecretRef references a Secret containing GitLab credentials
Expected keys: GITLAB_URL, GITLAB_TOKEN
type: string
image:
description: image is the container image to use for execution
type: string
repositoryURL:
description: repositoryURL is the GitLab repository to clone
type: string
schedule:
description: schedule in Cron format for recurring execution. If empty,
runs as one-time Job
type: string
scriptPath:
description: scriptPath is the relative path to the script in the
repository
type: string
serviceAccountName:
description: serviceAccountName to use for the Job/CronJob pods
type: string
suspend:
description: suspend pauses scheduled execution (only for CronJobs)
type: boolean
required:
- gitlabSecretRef
- repositoryURL
- scriptPath
type: object
status:
description: status defines the observed state of GitlabJobRunner
properties:
activeJobName:
description: activeJobName is the name of the currently running Job
type: string
conditions:
description: conditions represent the current state of the GitlabJobRunner
resource.
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
lastScheduleTime:
description: lastScheduleTime is the last time a Job was scheduled
format: date-time
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}

View File

@@ -0,0 +1,79 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "gitlab-job-runner.fullname" . }}-controller-manager
namespace: {{ .Release.Namespace }}
labels:
{{- include "gitlab-job-runner.labels" . | nindent 4 }}
control-plane: controller-manager
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "gitlab-job-runner.selectorLabels" . | nindent 6 }}
control-plane: controller-manager
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "gitlab-job-runner.selectorLabels" . | nindent 8 }}
control-plane: controller-manager
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "gitlab-job-runner.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: manager
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
command:
- /manager
args:
{{- if .Values.leaderElection.enabled }}
- --leader-elect
{{- end }}
{{- if .Values.metrics.enabled }}
- --metrics-bind-address=:{{ .Values.metrics.port }}
{{- if .Values.metrics.secure }}
- --metrics-secure=true
{{- end }}
{{- else }}
- --metrics-bind-address=0
{{- end }}
- --health-probe-bind-address=:{{ .Values.healthProbe.port }}
livenessProbe:
httpGet:
path: /healthz
port: {{ .Values.healthProbe.port }}
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /readyz
port: {{ .Values.healthProbe.port }}
initialDelaySeconds: 5
periodSeconds: 10
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
terminationGracePeriodSeconds: 10

View File

@@ -0,0 +1,57 @@
{{- if .Values.leaderElection.enabled -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "gitlab-job-runner.fullname" . }}-leader-election-role
namespace: {{ .Release.Namespace }}
labels:
{{- include "gitlab-job-runner.labels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "gitlab-job-runner.fullname" . }}-leader-election-rolebinding
namespace: {{ .Release.Namespace }}
labels:
{{- include "gitlab-job-runner.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "gitlab-job-runner.fullname" . }}-leader-election-role
subjects:
- kind: ServiceAccount
name: {{ include "gitlab-job-runner.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
{{- end }}

View File

@@ -0,0 +1,20 @@
{{- if .Values.metrics.enabled -}}
apiVersion: v1
kind: Service
metadata:
name: {{ include "gitlab-job-runner.fullname" . }}-metrics
namespace: {{ .Release.Namespace }}
labels:
{{- include "gitlab-job-runner.labels" . | nindent 4 }}
control-plane: controller-manager
spec:
type: ClusterIP
selector:
{{- include "gitlab-job-runner.selectorLabels" . | nindent 4 }}
control-plane: controller-manager
ports:
- name: https
port: {{ .Values.metrics.port }}
protocol: TCP
targetPort: {{ .Values.metrics.port }}
{{- end }}

View File

@@ -0,0 +1,56 @@
{{- if .Values.rbac.create -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "gitlab-job-runner.fullname" . }}-manager-role
labels:
{{- include "gitlab-job-runner.labels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- batch
resources:
- cronjobs
- jobs
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- batch.rml.ru
resources:
- gitlabjobrunners
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- batch.rml.ru
resources:
- gitlabjobrunners/finalizers
verbs:
- update
- apiGroups:
- batch.rml.ru
resources:
- gitlabjobrunners/status
verbs:
- get
- patch
- update
{{- end }}

View File

@@ -0,0 +1,16 @@
{{- if .Values.rbac.create -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "gitlab-job-runner.fullname" . }}-manager-rolebinding
labels:
{{- include "gitlab-job-runner.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "gitlab-job-runner.fullname" . }}-manager-role
subjects:
- kind: ServiceAccount
name: {{ include "gitlab-job-runner.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
{{- end }}

View File

@@ -0,0 +1,13 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "gitlab-job-runner.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "gitlab-job-runner.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "gitlab-job-runner.fullname" . }}-test
namespace: {{ .Release.Namespace }}
annotations:
"helm.sh/hook": test
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
data:
run.sh: |-
#!/bin/sh
set -e
kubectl get crd gitlabjobrunners.batch.rml.ru
kubectl get deployment {{ include "gitlab-job-runner.fullname" . }}-controller-manager -n {{ .Release.Namespace }}
echo "GitLab Job Runner operator is deployed successfully!"

View File

@@ -0,0 +1,56 @@
replicaCount: 1
image:
repository: controller
pullPolicy: IfNotPresent
tag: "latest"
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
create: true
annotations: {}
name: ""
podAnnotations: {}
podSecurityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 10m
memory: 64Mi
nodeSelector: {}
tolerations: []
affinity: {}
metrics:
enabled: true
port: 8443
secure: true
healthProbe:
port: 8081
leaderElection:
enabled: false
rbac:
create: true