Initial support for FoundationDB operator

Signed-off-by: Isaiah Olson <isaiah@olson-network.com>
This commit is contained in:
Isaiah Olson
2025-09-07 05:14:23 -05:00
parent 65a734bb65
commit 5654ac4e3d
30 changed files with 10134 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
#!/usr/bin/env bats
@test "Create DB FoundationDB" {
name='test'
kubectl apply -f - <<EOF
apiVersion: apps.cozystack.io/v1alpha1
kind: FoundationDB
metadata:
name: $name
namespace: tenant-test
spec:
replicas: 3
cluster:
version: "7.4.1"
processCounts:
storage: 3
stateless: -1
cluster_controller: 1
faultDomain:
key: "foundationdb.org/none"
valueFrom: "\$FDB_ZONE_ID"
storage:
size: "8Gi"
storageClass: ""
resources:
preset: "nano"
backup:
enabled: false
s3:
bucket: "s3.example.org/fdb-backups"
endpoint: ""
region: "us-east-1"
credentials:
accessKeyId: "oobaiRus9pah8PhohL1ThaeTa4UVa7gu"
secretAccessKey: "ju3eum4dekeich9ahM1te8waeGai0oog"
retentionPolicy: "7d"
monitoring:
enabled: true
advanced:
customParameters:
- "knob_disable_posix_kernel_aio=1"
imageType: "split"
automaticReplacements: true
EOF
sleep 10
# Wait for HelmRelease to be ready
kubectl -n tenant-test wait hr foundationdb-\$name --timeout=180s --for=condition=ready
# Wait for FoundationDBCluster to be created
timeout 120 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org \$name; do sleep 10; done"
# Wait for cluster to become available (this may take some time)
timeout 300 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org \$name -o jsonpath='{.status.databaseConfiguration.usable_regions}' | grep -q '1'; do sleep 15; done"
# Check that storage processes are running
timeout 180 sh -ec "until [ \$(kubectl -n tenant-test get pods -l app=\$name,foundationdb.org/fdb-process-class=storage --field-selector=status.phase=Running --no-headers | wc -l) -eq 3 ]; do sleep 10; done"
# Check that stateless processes are running
timeout 180 sh -ec "until [ \$(kubectl -n tenant-test get pods -l app=\$name,foundationdb.org/fdb-process-class=stateless --field-selector=status.phase=Running --no-headers | wc -l) -ge 1 ]; do sleep 10; done"
# Check that cluster controller is running
timeout 180 sh -ec "until [ \$(kubectl -n tenant-test get pods -l app=\$name,foundationdb.org/fdb-process-class=cluster_controller --field-selector=status.phase=Running --no-headers | wc -l) -eq 1 ]; do sleep 10; done"
# Check WorkloadMonitor is created and configured
kubectl -n tenant-test get workloadmonitor \$name
timeout 60 sh -ec "until kubectl -n tenant-test get workloadmonitor \$name -o jsonpath='{.spec.replicas}' | grep -q '3'; do sleep 5; done"
# Check dashboard resource map is created
kubectl -n tenant-test get configmap \$name-resourcemap
# Verify cluster is healthy (check cluster status)
timeout 120 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org \$name -o jsonpath='{.status.health.available}' | grep -q 'true'; do sleep 10; done"
# Clean up
kubectl -n tenant-test delete foundationdb \$name
# Wait for cleanup to complete
timeout 60 sh -ec "while kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org \$name 2>/dev/null; do sleep 5; done"
}

View File

@@ -0,0 +1 @@
Makefile

View File

@@ -0,0 +1,25 @@
apiVersion: v2
name: foundationdb
description: Managed FoundationDB service
icon: /logos/foundationdb.svg
# 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: 0.1.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: "7.4.1"

View File

@@ -0,0 +1,4 @@
include ../../../scripts/package.mk
generate:
cozyvalues-gen -v values.yaml -s values.schema.json -r README.md

View File

@@ -0,0 +1,136 @@
# FoundationDB
A managed FoundationDB service for Cozystack.
## Overview
FoundationDB is a distributed database designed to handle large volumes of structured data across clusters of commodity servers. It organizes data as an ordered key-value store and employs ACID transactions for all operations.
This package provides a managed FoundationDB cluster deployment using the FoundationDB Kubernetes Operator.
## Features
- **High Availability**: Multi-instance deployment with automatic failover
- **ACID Transactions**: Full ACID transaction support across the cluster
- **Scalable**: Easily scale storage and compute resources
- **Backup Integration**: Optional S3-compatible backup storage
- **Monitoring**: Built-in monitoring and alerting through WorkloadMonitor
- **Flexible Configuration**: Support for custom FoundationDB parameters
## Configuration
### Basic Configuration
```yaml
# Number of total instances
replicas: 3
# Cluster process configuration
cluster:
version: "7.4.1"
processCounts:
storage: 3 # Storage processes
stateless: -1 # Automatically calculated
cluster_controller: 1
```
### Storage
```yaml
storage:
size: "16Gi" # Storage size per instance
storageClass: "" # Storage class (optional)
```
### Resources
```yaml
resources:
preset: "medium" # small, medium, large, xlarge
# Custom overrides
limits:
cpu: "2000m"
memory: "4Gi"
requests:
cpu: "1000m"
memory: "2Gi"
```
### Backup (Optional)
```yaml
backup:
enabled: true
s3:
bucket: "my-fdb-backups"
endpoint: "https://s3.amazonaws.com"
region: "us-east-1"
credentials:
accessKeyId: "AKIA..."
secretAccessKey: "..."
retentionPolicy: "7d"
```
### Advanced Configuration
```yaml
advanced:
# Custom FoundationDB parameters
customParameters:
- "knob_disable_posix_kernel_aio=1"
# Image type (split recommended for production)
imageType: "split"
# Enable automatic pod replacements
automaticReplacements: true
```
## Prerequisites
- FoundationDB Operator must be installed in the cluster
- Sufficient storage and compute resources
- For backups: S3-compatible storage credentials
## Deployment
1. Install the FoundationDB operator (system package)
2. Deploy this application package with your desired configuration
3. The cluster will be automatically provisioned and configured
## Monitoring
This package includes WorkloadMonitor integration for cluster health monitoring and resource tracking. Monitoring can be disabled by setting:
```yaml
monitoring:
enabled: false
```
## Security
- All containers run with restricted security contexts
- No privilege escalation allowed
- Read-only root filesystem where possible
- Custom security context configurations supported
## Fault Tolerance
FoundationDB is designed for high availability:
- Automatic failure detection and recovery
- Data replication across instances
- Configurable fault domains for rack/zone awareness
- Transaction log redundancy
## Performance Considerations
- Use SSD storage for better performance
- Consider dedicating nodes for storage processes
- Monitor cluster metrics for optimization opportunities
- Scale storage and stateless processes based on workload
## Support
For issues related to FoundationDB itself, refer to the [FoundationDB documentation](https://apple.github.io/foundationdb/).
For Cozystack-specific issues, consult the Cozystack documentation or support channels.

View File

@@ -0,0 +1 @@
../../../library/cozy-lib

View File

@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="144"
height="144"
viewBox="0 0 144 144"
fill="none"
version="1.1"
id="svg4"
sodipodi:docname="foundationdb.svg"
inkscape:version="1.4.2 (unknown)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="6.0902778"
inkscape:cx="72"
inkscape:cy="72.492588"
inkscape:window-width="1920"
inkscape:window-height="1128"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<rect
width="144"
height="144"
rx="24"
fill="url(#paint0_linear_fdb)"
id="rect1"
style="fill:#ffffff" />
<!-- FoundationDB Icon (scaled and positioned) -->
<!-- FoundationDB Text -->
<defs
id="defs4">
<linearGradient
id="paint0_linear_fdb"
x1="140"
y1="130.5"
x2="4"
y2="9.49999"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#047BFE"
id="stop3" />
<stop
offset="1"
stop-color="#3F9AFB"
id="stop4" />
</linearGradient>
</defs>
<g
id="g1134"
transform="matrix(3.132791,0,0,3.132791,-115.98385,6.9294227)">
<g
transform="matrix(0.08541251,0,0,0.08541251,8.7615159,9.5962543)"
id="g10">
<polygon
style="fill:#3f9afb"
class="st0"
points="457.2,150.5 457.2,98.6 561.4,124 561.6,164.8 666.6,150.9 666.3,98.7 845.8,143 846.4,189.9 667.4,165.8 560.6,177.3 457.1,165.4 354.2,177.6 354.1,165.7 "
id="polygon4" />
<path
style="fill:#0b70e0"
inkscape:connector-curvature="0"
class="st1"
d="m 666.6,183.2 179.6,18.6 v 46 H 353.8 l -0.5,-12.2 h 103.5 c 0,0 0,-34.2 0,-52.3 34.8,3.4 103.8,10.2 103.8,10.2 v 40.9 h 106 z"
id="path6" />
<path
style="fill:#9eccfd"
inkscape:connector-curvature="0"
class="st2"
d="m 561.4,109.1 -0.3,-12.6 c 0,0 68.1,-20.4 103.3,-30.8 0,-16.9 0,-33.2 0,-52.9 61.8,24.8 121.2,48.8 181.2,72.9 0,15 0,29.4 0,45.4 -61.5,-16.9 -121.7,-33.5 -180.2,-49.6 -35.6,9.5 -104,27.6 -104,27.6 z"
id="path8" />
</g>
<polygon
transform="matrix(0.08541251,0,0,0.08541251,8.7795597,9.6869671)"
style="fill:#3f9afb"
class="st0"
points="666.6,150.9 666.3,98.7 845.8,143 846.4,189.9 667.4,165.8 560.6,177.3 457.1,165.4 354.2,177.6 354.1,165.7 457.2,150.5 457.2,98.6 561.4,124 561.6,164.8 "
id="polygon856" />
<path
style="fill:#0b70e0;stroke-width:0.0854125"
inkscape:connector-curvature="0"
class="st1"
d="m 65.715539,25.334539 15.340087,1.588673 v 3.928975 h -42.05712 l -0.04271,-1.042033 h 8.840195 c 0,0 0,-2.921107 0,-4.467074 2.972356,0.290403 8.865819,0.871208 8.865819,0.871208 v 3.493371 h 9.053726 z"
id="path858" />
<path
style="fill:#9eccfd;stroke-width:0.0854125"
inkscape:connector-curvature="0"
class="st2"
d="m 56.730143,19.005472 -0.02562,-1.076198 c 0,0 5.816592,-1.742415 8.823112,-2.630705 0,-1.443471 0,-2.835695 0,-4.518322 5.278493,2.11823 10.351997,4.168131 15.476747,6.226572 0,1.281188 0,2.511128 0,3.877728 -5.252869,-1.443471 -10.394702,-2.861319 -15.391334,-4.23646 -3.040686,0.811419 -8.882901,2.357385 -8.882901,2.357385 z"
id="path860" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1,33 @@
{{/*
Common resource definitions
*/}}
{{- define "foundationdb.resources" -}}
{{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resources.preset .Values.resources $) }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "foundationdb.labels" -}}
helm.sh/chart: {{ include "foundationdb.chart" . }}
{{ include "foundationdb.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "foundationdb.selectorLabels" -}}
app.kubernetes.io/name: foundationdb
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Chart name and version
*/}}
{{- define "foundationdb.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

View File

@@ -0,0 +1,65 @@
{{- if .Values.backup.enabled }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-s3-creds
labels:
app.kubernetes.io/name: foundationdb
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
type: Opaque
data:
AWS_ACCESS_KEY_ID: {{ .Values.backup.s3.credentials.accessKeyId | b64enc }}
AWS_SECRET_ACCESS_KEY: {{ .Values.backup.s3.credentials.secretAccessKey | b64enc }}
---
apiVersion: apps.foundationdb.org/v1beta2
kind: FoundationDBBackup
metadata:
name: {{ .Release.Name }}-backup
labels:
app.kubernetes.io/name: foundationdb
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
clusterName: {{ .Release.Name }}
backupState: Running
backupDeploymentSpec:
podTemplateSpec:
spec:
containers:
- name: foundationdb
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
securityContext:
runAsUser: 0
customParameters:
- backup_agent_snapshot_mode=0
snapshotPeriodSeconds: 3600
blobStoreConfiguration:
accountName: {{ .Values.backup.s3.bucket }}
bucket: {{ .Values.backup.s3.bucket }}
{{- if .Values.backup.s3.endpoint }}
endpoint: {{ .Values.backup.s3.endpoint }}
{{- end }}
credentials:
AWS_ACCESS_KEY_ID:
secretKeyRef:
name: {{ .Release.Name }}-s3-creds
key: AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY:
secretKeyRef:
name: {{ .Release.Name }}-s3-creds
key: AWS_SECRET_ACCESS_KEY
{{- end }}

View File

@@ -0,0 +1,86 @@
---
apiVersion: apps.foundationdb.org/v1beta2
kind: FoundationDBCluster
metadata:
name: {{ .Release.Name }}
labels:
app.kubernetes.io/name: foundationdb
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
version: {{ .Values.cluster.version | quote }}
processCounts:
{{- toYaml .Values.cluster.processCounts | nindent 4 }}
automationOptions:
replacements:
enabled: {{ .Values.advanced.automaticReplacements }}
faultDomain:
key: {{ .Values.cluster.faultDomain.key }}
{{- if .Values.cluster.faultDomain.valueFrom }}
valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
{{- end }}
imageType: {{ .Values.advanced.imageType }}
labels:
filterOnOwnerReference: false
matchLabels:
foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
processClassLabels:
- foundationdb.org/fdb-process-class
processGroupIDLabels:
- foundationdb.org/fdb-process-group-id
minimumUptimeSecondsForBounce: 60
processes:
general:
{{- if .Values.advanced.customParameters }}
customParameters:
{{- range .Values.advanced.customParameters }}
- {{ . }}
{{- end }}
{{- end }}
podTemplate:
spec:
containers:
- name: foundationdb
resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resources.preset .Values.resources $) | nindent 16 }}
securityContext:
{{- toYaml .Values.advanced.securityContext | nindent 16 }}
- name: foundationdb-kubernetes-sidecar
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
securityContext:
{{- toYaml .Values.advanced.securityContext | nindent 16 }}
initContainers:
- name: foundationdb-kubernetes-init
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
securityContext:
{{- toYaml .Values.advanced.securityContext | nindent 16 }}
volumeClaimTemplate:
spec:
{{- if .Values.storage.storageClass }}
storageClassName: {{ .Values.storage.storageClass }}
{{- end }}
resources:
requests:
storage: {{ .Values.storage.size }}
routing:
defineDNSLocalityFields: true
sidecarContainer:
enableLivenessProbe: true
enableReadinessProbe: true

View File

@@ -0,0 +1,22 @@
{{- if .Values.monitoring.enabled }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-resourcemap
labels:
app.kubernetes.io/name: foundationdb
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.cozystack.io/type: dashboard-resourcemap
data:
resources: |
- apiVersion: apps.foundationdb.org/v1beta2
kind: FoundationDBCluster
name: {{ .Release.Name }}
{{- if .Values.backup.enabled }}
- apiVersion: apps.foundationdb.org/v1beta2
kind: FoundationDBBackup
name: {{ .Release.Name }}-backup
{{- end }}
{{- end }}

View File

@@ -0,0 +1,20 @@
{{- if .Values.monitoring.enabled }}
---
apiVersion: cozystack.io/v1alpha1
kind: WorkloadMonitor
metadata:
name: {{ .Release.Name }}
labels:
app.kubernetes.io/name: foundationdb
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
replicas: {{ .Values.replicas }}
minReplicas: 1
kind: foundationdb
type: foundationdb
selector:
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/name: foundationdb
version: {{ .Chart.Version }}
{{- end }}

View File

@@ -0,0 +1,203 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"replicas": {
"type": "integer",
"minimum": 1,
"default": 3,
"title": "Number of replicas",
"description": "Total number of FoundationDB instances"
},
"cluster": {
"type": "object",
"title": "Cluster Configuration",
"properties": {
"processCounts": {
"type": "object",
"title": "Process Counts",
"properties": {
"stateless": {
"type": "integer",
"default": -1,
"title": "Stateless processes",
"description": "Number of stateless processes (-1 for automatic)"
},
"storage": {
"type": "integer",
"minimum": 1,
"default": 3,
"title": "Storage processes",
"description": "Number of storage processes"
},
"cluster_controller": {
"type": "integer",
"minimum": 1,
"default": 1,
"title": "Cluster controllers",
"description": "Number of cluster controller processes"
}
}
},
"version": {
"type": "string",
"default": "7.4.1",
"title": "FoundationDB Version",
"description": "Version of FoundationDB to deploy"
},
"faultDomain": {
"type": "object",
"title": "Fault Domain",
"properties": {
"key": {
"type": "string",
"default": "foundationdb.org/none",
"title": "Fault domain key"
},
"valueFrom": {
"type": "string",
"default": "$FDB_ZONE_ID",
"title": "Fault domain value source"
}
}
}
}
},
"storage": {
"type": "object",
"title": "Storage Configuration",
"properties": {
"size": {
"type": "string",
"default": "16Gi",
"title": "Storage size",
"description": "Size of persistent volumes for each instance"
},
"storageClass": {
"type": "string",
"title": "Storage class",
"description": "Kubernetes storage class to use (optional)"
}
}
},
"resources": {
"type": "object",
"title": "Resource Configuration",
"properties": {
"preset": {
"type": "string",
"enum": ["small", "medium", "large", "xlarge"],
"default": "medium",
"title": "Resource preset",
"description": "Predefined resource configuration"
},
"limits": {
"type": "object",
"title": "Resource limits",
"properties": {
"cpu": {"type": "string"},
"memory": {"type": "string"}
}
},
"requests": {
"type": "object",
"title": "Resource requests",
"properties": {
"cpu": {"type": "string"},
"memory": {"type": "string"}
}
}
}
},
"backup": {
"type": "object",
"title": "Backup Configuration",
"properties": {
"enabled": {
"type": "boolean",
"default": false,
"title": "Enable backups",
"description": "Enable automatic backups to S3"
},
"s3": {
"type": "object",
"title": "S3 Configuration",
"properties": {
"bucket": {
"type": "string",
"title": "S3 bucket name"
},
"endpoint": {
"type": "string",
"title": "S3 endpoint URL"
},
"region": {
"type": "string",
"default": "us-east-1",
"title": "S3 region"
},
"credentials": {
"type": "object",
"title": "S3 credentials",
"properties": {
"accessKeyId": {
"type": "string",
"title": "Access key ID"
},
"secretAccessKey": {
"type": "string",
"title": "Secret access key"
}
}
}
}
},
"retentionPolicy": {
"type": "string",
"default": "7d",
"title": "Retention policy",
"description": "How long to keep backups"
}
}
},
"monitoring": {
"type": "object",
"title": "Monitoring",
"properties": {
"enabled": {
"type": "boolean",
"default": true,
"title": "Enable monitoring",
"description": "Enable WorkloadMonitor integration"
}
}
},
"advanced": {
"type": "object",
"title": "Advanced Configuration",
"properties": {
"customParameters": {
"type": "array",
"title": "Custom parameters",
"description": "Custom FoundationDB parameters",
"items": {
"type": "string"
}
},
"imageType": {
"type": "string",
"enum": ["unified", "split"],
"default": "split",
"title": "Image type",
"description": "Container image deployment type"
},
"automaticReplacements": {
"type": "boolean",
"default": true,
"title": "Automatic replacements",
"description": "Enable automatic pod replacements"
}
}
}
}
}

View File

@@ -0,0 +1,73 @@
# Default values for foundationdb.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
# Number of replicas (total instances)
replicas: 3
# Cluster configuration
cluster:
# Process counts for different roles
processCounts:
stateless: -1 # Automatically calculated
storage: 3 # Storage processes
cluster_controller: 1
# Version of FoundationDB to use
version: "7.4.1"
# Fault domain configuration
faultDomain:
key: "foundationdb.org/none"
valueFrom: "$FDB_ZONE_ID"
# Storage configuration
storage:
# Size of persistent volumes
size: "16Gi"
# Storage class (if not set, uses cluster default)
storageClass: ""
# Resource configuration
resources:
# Resource preset (will be used by cozy-lib)
preset: "medium"
# Custom resource overrides
limits: {}
requests: {}
# Backup configuration
backup:
enabled: false
# S3 configuration for backups
s3:
bucket: ""
endpoint: ""
region: "us-east-1"
credentials:
accessKeyId: ""
secretAccessKey: ""
# Retention policy for backups
retentionPolicy: "7d"
# Monitoring
monitoring:
enabled: true
# Advanced configuration
advanced:
# Custom parameters to pass to FoundationDB
customParameters: []
# Example:
# - knob_disable_posix_kernel_aio=1
# Image type (split recommended for production)
imageType: "split"
# Security context for containers
securityContext:
runAsUser: 0
runAsGroup: 0
# Enable automatic replacements
automaticReplacements: true

View File

@@ -33,6 +33,7 @@ ferretdb 0.7.1 4369b031
ferretdb 0.8.0 08cb7c0f
ferretdb 1.0.0 c02a3818
ferretdb 1.1.0 HEAD
foundationdb 0.1.0 HEAD
http-cache 0.1.0 263e47be
http-cache 0.2.0 53f2365e
http-cache 0.3.0 6c5cf5bf

View File

@@ -0,0 +1 @@
Makefile

View File

@@ -0,0 +1,3 @@
apiVersion: v2
name: cozy-foundationdb-operator
version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process

View File

@@ -0,0 +1,19 @@
export NAME=foundationdb-operator
export NAMESPACE=cozy-$(NAME)
include ../../../scripts/package.mk
update:
rm -rf charts
git clone --depth 1 --branch v2.13.0 https://github.com/FoundationDB/fdb-kubernetes-operator.git tmp-repo
mkdir -p charts
cp -r tmp-repo/charts/fdb-operator charts/
# Remove symlinked CRDs and replace with actual files
rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbbackups.yaml
rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbclusters.yaml
rm -f charts/fdb-operator/crds/apps.foundationdb.org_foundationdbrestores.yaml
cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbbackups.yaml charts/fdb-operator/crds/
cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbclusters.yaml charts/fdb-operator/crds/
cp tmp-repo/config/crd/bases/apps.foundationdb.org_foundationdbrestores.yaml charts/fdb-operator/crds/
rm -rf tmp-repo
rm -rf charts/fdb-operator/charts

View File

@@ -0,0 +1,23 @@
apiVersion: v2
name: fdb-operator
description: A Helm chart for foundationDB operator
home: https://www.foundationdb.org/
sources:
- https://github.com/FoundationDB/fdb-kubernetes-operator/tree/main/charts/fdb-operator
# 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.
version: 0.2.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.
appVersion: v2.13.0
maintainers:
- name: "foundationdb-ci"

View File

@@ -0,0 +1,100 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.18.0
foundationdb.org/release: v2.13.0
name: foundationdbrestores.apps.foundationdb.org
spec:
group: apps.foundationdb.org
names:
kind: FoundationDBRestore
listKind: FoundationDBRestoreList
plural: foundationdbrestores
shortNames:
- fdbrestore
singular: foundationdbrestore
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .status.state
name: State
type: string
name: v1beta2
schema:
openAPIV3Schema:
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
spec:
properties:
blobStoreConfiguration:
properties:
accountName:
maxLength: 100
type: string
backupName:
maxLength: 1024
type: string
bucket:
maxLength: 63
minLength: 3
type: string
urlParameters:
items:
maxLength: 1024
type: string
maxItems: 100
type: array
required:
- accountName
type: object
customParameters:
items:
maxLength: 100
type: string
maxItems: 100
type: array
destinationClusterName:
type: string
encryptionKeyPath:
maxLength: 4096
type: string
keyRanges:
items:
properties:
end:
pattern: ^[A-Za-z0-9\/\\-]+$
type: string
start:
pattern: ^[A-Za-z0-9\/\\-]+$
type: string
required:
- end
- start
type: object
type: array
required:
- destinationClusterName
type: object
status:
properties:
running:
type: boolean
state:
maxLength: 50
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@@ -0,0 +1,6 @@
FoundationDB operator has been installed successfully.
To see the logs of the operator you can use below command
kubectl logs deployment/{{ include "fdb-operator.fullname" . }} -n {{ .Release.Namespace }} -f
Thanks for trying out FoundationDB helm chart.

View File

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

View File

@@ -0,0 +1,117 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "fdb-operator.fullname" . }}
labels:
{{- include "fdb-operator.labels" . | nindent 4 }}
{{- with .Values.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.replicas }}
replicas: {{ . }}
{{- end }}
selector:
matchLabels:
{{- include "fdb-operator.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "fdb-operator.selectorLabels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
serviceAccountName: {{ include "fdb-operator.serviceAccountName" . }}
{{- with .Values.priorityClassName }}
priorityClassName: {{ . }}
{{- end }}
securityContext:
{{- toYaml .Values.securityContext | nindent 8 }}
terminationGracePeriodSeconds: 10
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
initContainers:
{{- range $version, $params := .Values.initContainers }}
- name: foundationdb-kubernetes-init-{{ $version | replace "." "-" }}
image: {{ $params.image.repository }}:{{ $params.image.tag }}
imagePullPolicy: {{ $params.image.pullPolicy }}
args:
- "--copy-library"
- "{{ $version }}"
- "--copy-binary"
- "fdbcli"
- "--copy-binary"
- "fdbbackup"
- "--copy-binary"
- "fdbrestore"
- "--output-dir"
- "/var/output-files"
- "--mode"
- "init"
volumeMounts:
- name: fdb-binaries
mountPath: /var/output-files
resources:
{{- toYaml $.Values.initContainersResources | nindent 10 }}
securityContext:
{{- toYaml $.Values.initContainerSecurityContext | nindent 10 }}
{{- end }}
containers:
- name: manager
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
command:
- /manager
{{- if not .Values.globalMode.enabled }}
env:
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
{{- end }}
ports:
- containerPort: 8080
name: metrics
volumeMounts:
- name: tmp
mountPath: /tmp
- name: logs
mountPath: /var/log/fdb
- name: fdb-binaries
mountPath: /usr/bin/fdb
securityContext:
{{- toYaml .Values.containerSecurityContext | nindent 10 }}
livenessProbe:
httpGet:
path: /metrics
port: metrics
resources:
{{- toYaml .Values.resources | nindent 10 }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
volumes:
- name: tmp
emptyDir: {}
- name: logs
emptyDir: {}
- name: fdb-binaries
emptyDir: {}

View File

@@ -0,0 +1,131 @@
---
apiVersion: rbac.authorization.k8s.io/v1
{{- if .Values.globalMode.enabled }}
kind: ClusterRole
{{- else }}
kind: Role
{{- end }}
metadata:
name: {{ include "fdb-operator.fullname" . }}
labels:
{{- include "fdb-operator.labels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- pods
- configmaps
- persistentvolumeclaims
- events
verbs:
- get
- watch
- list
- create
- update
- patch
- delete
- apiGroups:
- apps.foundationdb.org
resources:
- foundationdbclusters
- foundationdbbackups
- foundationdbrestores
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- apps.foundationdb.org
resources:
- foundationdbclusters/status
- foundationdbbackups/status
- foundationdbrestores/status
verbs:
- get
- update
- patch
- apiGroups:
- admissionregistration.k8s.io
resources:
- mutatingwebhookconfigurations
- validatingwebhookconfigurations
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- apps
resources:
- deployments
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
{{- if .Values.nodeReadClusterRole }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "fdb-operator.fullname" . }}-clusterrole
labels:
{{- include "fdb-operator.labels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- watch
- list
{{- end }}

View File

@@ -0,0 +1,44 @@
---
apiVersion: rbac.authorization.k8s.io/v1
{{- if .Values.globalMode.enabled }}
kind: ClusterRoleBinding
{{- else }}
kind: RoleBinding
{{- end }}
metadata:
name: {{ include "fdb-operator.fullname" . }}
labels:
{{- include "fdb-operator.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
{{- if .Values.globalMode.enabled }}
kind: ClusterRole
{{- else }}
kind: Role
{{- end }}
name: {{ include "fdb-operator.fullname" . }}
subjects:
- kind: ServiceAccount
name: {{ include "fdb-operator.serviceAccountName" . }}
{{- if .Values.globalMode.enabled }}
namespace: {{ .Release.Namespace }}
{{- end }}
{{- if .Values.nodeReadClusterRole }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "fdb-operator.fullname" . }}-clusterrolebinding
labels:
{{- include "fdb-operator.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "fdb-operator.fullname" . }}-clusterrole
subjects:
- kind: ServiceAccount
name: {{ include "fdb-operator.serviceAccountName" . }}
{{- if .Values.globalMode.enabled }}
namespace: {{ .Release.Namespace }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,17 @@
---
{{- if .Values.serviceAccount.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "fdb-operator.serviceAccountName" . }}
labels:
{{- include "fdb-operator.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.serviceAccount.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,70 @@
---
image:
repository: foundationdb/fdb-kubernetes-operator
tag: v2.13.0
pullPolicy: IfNotPresent
initContainers:
7.1:
image:
repository: foundationdb/fdb-kubernetes-monitor
tag: 7.1.67
pullPolicy: IfNotPresent
7.3:
image:
repository: foundationdb/fdb-kubernetes-monitor
tag: 7.3.63
pullPolicy: IfNotPresent
7.4:
image:
repository: foundationdb/fdb-kubernetes-monitor
tag: 7.4.1
pullPolicy: IfNotPresent
globalMode:
enabled: false
replicas: null
imagePullSecrets: []
annotations: {}
podAnnotations: {}
podLabels: {}
serviceAccount:
create: true
name: null
imagePullSecrets: []
annotations: {}
priorityClassName: null
securityContext:
runAsUser: 4059
runAsGroup: 4059
fsGroup: 4059
containerSecurityContext:
allowPrivilegeEscalation: false
privileged: false
capabilities:
drop:
- all
readOnlyRootFilesystem: true
nodeSelector: {}
affinity: {}
tolerations: {}
resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 500m
memory: 256Mi
initContainersResources:
limits:
cpu: 10m
memory: 50Mi
requests:
cpu: 10m
memory: 50Mi
initContainerSecurityContext:
allowPrivilegeEscalation: false
privileged: false
capabilities:
drop:
- all
readOnlyRootFilesystem: true
nodeReadClusterRole: true

View File

@@ -0,0 +1,4 @@
fdb-operator:
globalMode:
enabled: true
nodeReadClusterRole: true