Compare commits

..

2 Commits

Author SHA1 Message Date
Morten Olsen
b49e273b89 fix pg db 2025-08-11 14:35:15 +02:00
Morten Olsen
47cf43b44e Added storage provisioner 2025-08-11 12:07:36 +02:00
6 changed files with 54 additions and 18 deletions

View File

@@ -33,6 +33,14 @@ spec:
imagePullPolicy: {{ .Values.image.pullPolicy }} imagePullPolicy: {{ .Values.image.pullPolicy }}
resources: resources:
{{- toYaml .Values.resources | nindent 12 }} {{- toYaml .Values.resources | nindent 12 }}
volumeMounts:
- name: data-volumes
mountPath: {{ .Values.storage.path }}
volumes:
- name: data-volumes
hostPath:
path: {{ .Values.storage.path }}
type: DirectoryOrCreate
{{- with .Values.nodeSelector }} {{- with .Values.nodeSelector }}
nodeSelector: nodeSelector:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}

View File

@@ -9,8 +9,11 @@ image:
tag: main tag: main
imagePullSecrets: [] imagePullSecrets: []
nameOverride: "" nameOverride: ''
fullnameOverride: "" fullnameOverride: ''
storage:
path: /data/volumes
serviceAccount: serviceAccount:
# Specifies whether a service account should be created # Specifies whether a service account should be created
@@ -19,7 +22,7 @@ serviceAccount:
annotations: {} annotations: {}
# The name of the service account to use. # The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template # If not set and create is true, a name is generated using the fullname template
name: "" name: ''
podAnnotations: {} podAnnotations: {}

15
scripts/list-manifests.ts Executable file
View File

@@ -0,0 +1,15 @@
#!/usr/bin/env node
import { K8sService } from '../src/services/k8s/k8s.ts';
import { Services } from '../src/utils/service.ts';
const services = new Services();
const k8s = services.get(K8sService);
const manifests = await k8s.extensionsApi.listCustomResourceDefinition();
for (const manifest of manifests.items) {
for (const version of manifest.spec.versions) {
console.log(`group: ${manifest.spec.group}, plural: ${manifest.spec.names.plural}, version: ${version.name}`);
}
}

View File

@@ -37,8 +37,8 @@ class GenerateSecretResource extends CustomResource<typeof generateSecretSpecSch
const current = decodeSecret(this.#secretResource.data) || {}; const current = decodeSecret(this.#secretResource.data) || {};
const expected = { const expected = {
...current,
...secrets, ...secrets,
...current,
}; };
if (!isDeepSubset(current, expected)) { if (!isDeepSubset(current, expected)) {

View File

@@ -95,6 +95,7 @@ class PostgresDatabaseResource extends CustomResource<typeof postgresDatabaseSpe
port: serverSecretData.data.port, port: serverSecretData.data.port,
user: this.#userName, user: this.#userName,
database: this.#dbName, database: this.#dbName,
...databaseSecretData.data,
}; };
if (!isDeepSubset(databaseSecretData.data, expectedSecret)) { if (!isDeepSubset(databaseSecretData.data, expectedSecret)) {
@@ -132,7 +133,7 @@ class PostgresDatabaseResource extends CustomResource<typeof postgresDatabaseSpe
}; };
} }
const secretData = postgresDatabaseConnectionSecretSchema.safeParse(decodeSecret(this.#serverSecret.current?.data)); const secretData = postgresDatabaseConnectionSecretSchema.safeParse(decodeSecret(this.#databaseSecret.data));
if (!secretData.success || !secretData.data) { if (!secretData.success || !secretData.data) {
return { return {
ready: false, ready: false,

View File

@@ -7,7 +7,6 @@ import type { Services } from '../utils/service.ts';
import { ResourceService, type Resource } from '../services/resources/resources.ts'; import { ResourceService, type Resource } from '../services/resources/resources.ts';
const PROVISIONER = 'reuse-local-path-provisioner'; const PROVISIONER = 'reuse-local-path-provisioner';
const LABEL_SELECTOR = `provisioner=${PROVISIONER}`;
class StorageProvider { class StorageProvider {
#watcher: Watcher<V1PersistentVolumeClaim>; #watcher: Watcher<V1PersistentVolumeClaim>;
@@ -17,26 +16,36 @@ class StorageProvider {
this.#services = services; this.#services = services;
const watchService = this.#services.get(WatcherService); const watchService = this.#services.get(WatcherService);
this.#watcher = watchService.create({ this.#watcher = watchService.create({
path: '/api/v1/persistantvolumeclaims', path: '/api/v1/persistentvolumeclaims',
list: (k8s) => transform: (manifest) => ({
k8s.api.listPersistentVolumeClaimForAllNamespaces({ apiVersion: 'v1',
labelSelector: LABEL_SELECTOR, kind: 'PersistentVolumeClaim',
...manifest,
}), }),
list: async (k8s) => {
const current = await k8s.api.listPersistentVolumeClaimForAllNamespaces();
return current;
},
verbs: ['add', 'update', 'delete'], verbs: ['add', 'update', 'delete'],
selector: LABEL_SELECTOR,
}); });
this.#watcher.on('changed', this.#handleChange); this.#watcher.on('changed', this.#handleChange);
} }
#handleChange = async (pvc: Resource<V1PersistentVolumeClaim>) => { #handleChange = async (pvc: Resource<V1PersistentVolumeClaim>) => {
if (pvc.metadata?.annotations?.['volume.kubernetes.io/storage-provisioner'] !== PROVISIONER) {
return;
}
const target = `/data/volumes/${pvc.namespace}/${pvc.name}`; const target = `/data/volumes/${pvc.namespace}/${pvc.name}`;
try {
await mkdir(target, { recursive: true }); await mkdir(target, { recursive: true });
} catch (err) {
console.error(err);
}
const resourceService = this.#services.get(ResourceService); const resourceService = this.#services.get(ResourceService);
const pv = resourceService.get<V1PersistentVolume>({ const pv = resourceService.get<V1PersistentVolume>({
apiVersion: 'v1', apiVersion: 'v1',
kind: 'PersistantVolume', kind: 'PersistentVolume',
name: pvc.name, name: `${pvc.namespace}-${pvc.name}`,
namespace: pvc.namespace,
}); });
await pv.load(); await pv.load();
await pv.patch({ await pv.patch({
@@ -50,7 +59,7 @@ class StorageProvider {
path: target, path: target,
}, },
capacity: { capacity: {
storage: pvc.spec?.resources?.requests?.storage ?? '1GB', storage: pvc.spec?.resources?.requests?.storage ?? '1Gi',
}, },
persistentVolumeReclaimPolicy: 'Retain', persistentVolumeReclaimPolicy: 'Retain',
accessModes: pvc.spec?.accessModes, accessModes: pvc.spec?.accessModes,