Allow sqlite3 in memory when kind is deployment (#923)

* Allow sqlite3 in memory when kind is deployment

Signed-off-by: Daniel Schlatter <[email protected]>

* Warn on unsafe in-memory datastore combinations

Signed-off-by: Daniel Schlatter <[email protected]>

---------

Signed-off-by: Daniel Schlatter <[email protected]>
This commit is contained in:
Daniel Schlatter
2026-08-18 14:22:50 -07:00
committed by GitHub
parent e46ad1594a
commit 59bb8a774c
6 changed files with 236 additions and 4 deletions
+2 -1
View File
@@ -142,7 +142,8 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr
| `dataStore.sql.port` | If 0 (default), it will auto set to 5432 for postgres and 3306 for mysql. Only used by those databases. | `0` |
| `dataStore.sql.username` | Only used when type != "sqlite3" | `spire` |
| `dataStore.sql.password` | Only used when type != "sqlite3" | `""` |
| `dataStore.sql.file` | Data source file. Only used when type == "sqlite3" | `/run/spire/data/datastore.sqlite3` |
| `dataStore.sql.file` | Data source file. Only used when type == "sqlite3" and inMemory is false | `/run/spire/data/datastore.sqlite3` |
| `dataStore.sql.inMemory` | Hold the sqlite3 datastore in memory instead of in a file, in which case `file` is unused. The datastore starts empty on every restart, so this only suits a single replica whose registration entries are recreated at startup, for example by the controller manager writing static entries. Required to run as a deployment on sqlite3, since a deployment has no durable per-pod storage. | `false` |
| `dataStore.sql.options` | takes an array of objects of form {<key>: <value>} to use when building the database connection string | `[]` |
| `dataStore.sql.rootCAPath` | Path to Root CA bundle (MySQL only) | `""` |
| `dataStore.sql.clientCertPath` | Path to client certificate (MySQL only) | `""` |
@@ -307,8 +307,15 @@ current-context: cluster
{{- $ropw := "" }}
{{- if eq .Values.dataStore.sql.databaseType "sqlite3" }}
{{- $_ := set $config "database_type" "sqlite3" }}
{{- if .Values.dataStore.sql.inMemory }}
{{- /* cache=shared is not optional: without it every pooled connection opens its own
empty database, so the server silently loses every write it did not make itself. */}}
{{- $query := include "spire-server.config-sqlite-query" (concat (list (dict "mode" "memory") (dict "cache" "shared")) .Values.dataStore.sql.options) }}
{{- $_ := set $config "connection_string" (printf "memdb%s" $query) }}
{{- else }}
{{- $query := include "spire-server.config-sqlite-query" .Values.dataStore.sql.options }}
{{- $_ := set $config "connection_string" (printf "%s%s" .Values.dataStore.sql.file $query) }}
{{- end }}
{{- else if or (eq .Values.dataStore.sql.databaseType "mysql") (eq .Values.dataStore.sql.databaseType "aws_mysql") (eq .Values.dataStore.sql.databaseType "gcp_mysql_sa_iam") }}
{{- if eq .Values.dataStore.sql.databaseType "mysql" }}
{{- $_ := set $config "database_type" "mysql" }}
@@ -41,8 +41,14 @@
{{- if (has .Values.persistence.type (list "pvc" "hostPath")) }}
{{- fail "When running as deployment, persistence can't be set. 'persistence.type' must be [\"emptyDir\"]" }}
{{- end }}
{{- if (eq .Values.dataStore.sql.databaseType "sqlite3") }}
{{- fail "When running as deployment, sqlite3 can't be used." }}
{{- if and (eq .Values.dataStore.sql.databaseType "sqlite3") (not .Values.dataStore.sql.inMemory) }}
{{- fail "When running as deployment, sqlite3 can only be used in memory. Set 'dataStore.sql.inMemory' to true." }}
{{- end }}
{{- if and (eq .Values.dataStore.sql.databaseType "sqlite3") .Values.dataStore.sql.inMemory }}
{{- $surge := dig "rollingUpdate" "maxSurge" "" .Values.updateStrategy | toString }}
{{- if not (or (eq (dig "type" "" .Values.updateStrategy) "Recreate") (eq $surge "0") (eq $surge "0%")) }}
{{- fail "An in-memory datastore on a deployment must not surge, or two servers run with separate datastores. Set 'updateStrategy' to {type: Recreate} or {rollingUpdate: {maxSurge: 0}}." }}
{{- end }}
{{- end }}
{{- if (eq (.Values.keyManager.disk.enabled | toString) "true") }}
{{- fail "When running as deployment, disk keymanager can't be used. 'keyManager.disk.enabled' must be false." }}
+3 -1
View File
@@ -196,8 +196,10 @@ dataStore:
username: spire
## @param dataStore.sql.password Only used when type != "sqlite3"
password: ""
## @param dataStore.sql.file Data source file. Only used when type == "sqlite3"
## @param dataStore.sql.file Data source file. Only used when type == "sqlite3" and inMemory is false
file: "/run/spire/data/datastore.sqlite3"
## @param dataStore.sql.inMemory Hold the sqlite3 datastore in memory instead of in a file, in which case `file` is unused. The datastore starts empty on every restart, so this only suits a single replica whose registration entries are recreated at startup, for example by the controller manager writing static entries. Required to run as a deployment on sqlite3, since a deployment has no durable per-pod storage.
inMemory: false
## @param dataStore.sql.options [array] takes an array of objects of form {<key>: <value>} to use when building the database connection string
options: []
+18
View File
@@ -22,6 +22,24 @@ Warning: You're using an unsupported plugin. Functionality of this release and f
Warning: You're using an experimental config. Functionality of this release and future upgrades aren't guaranteed to work smoothly.
{{- end }}
{{- if (index .Values "spire-server").enabled }}
{{- $ss := index .Values "spire-server" }}
{{- if and (eq $ss.dataStore.sql.databaseType "sqlite3") $ss.dataStore.sql.inMemory }}
{{- $upstream := false }}
{{- range $name, $cfg := $ss.upstreamAuthority }}
{{- if kindIs "map" $cfg }}{{ if eq ($cfg.enabled | toString) "true" }}{{ $upstream = true }}{{ end }}{{ end }}
{{- end }}
{{- $reconciled := and $ss.controllerManager.enabled (or $ss.controllerManager.reconcile.clusterSPIFFEIDs $ss.controllerManager.reconcile.clusterStaticEntries) }}
{{- if not $reconciled }}
Warning: dataStore.sql.inMemory is set, but no controller manager reconciler is enabled. Registration entries live only in memory and nothing recreates them, so every entry is lost when the server restarts. Enable controllerManager with reconcile.clusterSPIFFEIDs or reconcile.clusterStaticEntries.
{{- end }}
{{- if and $ss.keyManager.memory.enabled (not $upstream) }}
Warning: dataStore.sql.inMemory is set with keyManager.memory and no upstreamAuthority. The server mints a new CA on every restart, so the whole trust domain has to re-attest and previously issued SVIDs stop verifying. Suitable for testing only; configure a KMS key manager or an upstream authority for anything else.
{{- end }}
{{- end }}
{{- end }}
{{- if (index .Values "spire-server").enabled }}
{{- $className := include "spire-server.controller-manager-class-name" (dict "Values" (index .Values "spire-server") "Release" .Release) }}
{{- if (index .Values "spire-server").controllerManager.enabled }}
{{- if (index .Values "spire-server").controllerManager.watchClassless }}