Skip to content

Commit b13a4df

Browse files
authored
feat: embedded db (#309)
* feat: Add support for embedded db * feat: support embedded database in Helm chart * fix: improve docker file * fix: templates/deployment.yaml * feat: ability to create postgresql stateful set * fix: calling db.MustInit twice on operator mode
1 parent 0fea290 commit b13a4df

File tree

13 files changed

+215
-59
lines changed

13 files changed

+215
-59
lines changed

.dockerignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.bin/
2+
.config-db/
3+
.github/
4+
.vscode/
5+
6+
build
7+
8+
chart/
9+
CONTRIBUTING.md
10+
SECURITY.md
11+
README.md
12+
PROJECT
13+
14+
cover.out
15+
.releaserc

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ GOBIN=$(shell go env GOBIN)
2020
endif
2121

2222
docker:
23-
docker build . -t ${IMG}
23+
docker build . -f build/Dockerfile -t ${IMG}
2424

2525
# Push the docker image
2626
docker-push:
Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
FROM golang:1.20@sha256:bc5f0b5e43282627279fe5262ae275fecb3d2eae3b33977a7fd200c7a760d6f1 as builder
22
WORKDIR /app
3-
COPY ./ ./
43

54
ARG VERSION
5+
66
COPY go.mod /app/go.mod
77
COPY go.sum /app/go.sum
88
RUN go mod download
9-
WORKDIR /app
10-
RUN go version
9+
10+
COPY ./ ./
1111
RUN make build
1212

1313
FROM ubuntu:jammy@sha256:0bced47fffa3361afa981854fcabcd4577cd43cebbb808cea2b1f33a3dd7f508
@@ -16,5 +16,11 @@ WORKDIR /app
1616
COPY --from=builder /app/.bin/config-db /app
1717
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
1818

19+
RUN mkdir /opt/database && groupadd --gid 1000 catalog && \
20+
useradd catalog --uid 1000 -g catalog -m -d /var/lib/catalog && \
21+
chown -R 1000:1000 /opt/database && chown -R 1000:1000 /app
22+
23+
USER catalog:catalog
24+
1925
RUN /app/config-db go-offline
20-
ENTRYPOINT ["/app/config-db"]
26+
ENTRYPOINT ["/app/config-db"]

chart/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ description: A Helm chart for config-db
44

55
type: application
66

7-
version: 0.2.0
7+
version: 0.3.0
88

99
appVersion: "0.0.5"

chart/templates/deployment.yaml

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,41 @@
1+
{{$embeddedDB := and (eq .Values.db.external.enabled false) (eq .Values.db.embedded.persist true) }}
2+
---
13
apiVersion: apps/v1
4+
{{- if $embeddedDB}}
5+
kind: StatefulSet
6+
{{- else }}
27
kind: Deployment
8+
{{- end }}
39
metadata:
410
name: {{ include "config-db.name" . }}
511
labels: {{- include "config-db.labels" . | nindent 4 }}
612
spec:
713
replicas: {{ .Values.replicas }}
814
selector:
915
matchLabels: {{- include "config-db.selectorLabels" . | nindent 6 }}
16+
{{- if $embeddedDB }}
17+
serviceName: {{ include "config-db.name" . }}
18+
volumeClaimTemplates:
19+
- metadata:
20+
name: config-db-embedded-database
21+
labels:
22+
{{- include "config-db.labels" . | nindent 10 }}
23+
spec:
24+
{{- if not (eq .Values.db.embedded.storageClass "") }}
25+
storageClassName: {{ .Values.db.embedded.storageClass }}
26+
{{- end }}
27+
accessModes: ["ReadWriteOnce"]
28+
resources:
29+
requests:
30+
storage: {{ .Values.db.embedded.storage }}
31+
{{- end }}
1032
template:
1133
metadata:
1234
labels: {{- include "config-db.selectorLabels" . | nindent 8 }}
1335
spec:
1436
serviceAccountName: {{ template "config-db.serviceAccountName" . }}
37+
securityContext:
38+
fsGroup: 1000
1539
containers:
1640
- name: {{ include "config-db.name" . }}
1741
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
@@ -42,7 +66,7 @@ spec:
4266
- --disable-postgrest={{ .Values.disablePostgrest }}
4367
- --change-retention-days={{ .Values.configChangeRetentionDays }}
4468
- --analysis-retention-days={{ .Values.configAnalysisRetentionDays }}
45-
{{- if .Values.db.enabled}}
69+
{{- if .Values.db.runMigrations}}
4670
- --db-migrations
4771
{{- end}}
4872
{{- if .Values.upstream.enabled}}
@@ -52,10 +76,14 @@ spec:
5276
{{- end}}
5377
env:
5478
- name: DB_URL
79+
{{- if .Values.db.external.enabled}}
5580
valueFrom:
5681
secretKeyRef:
57-
name: {{ .Values.db.secretKeyRef.name }}
58-
key: {{ .Values.db.secretKeyRef.key }}
82+
name: {{ .Values.db.external.secretKeyRef.name }}
83+
key: {{ .Values.db.external.secretKeyRef.key }}
84+
{{- else}}
85+
value: "embedded:///opt/database"
86+
{{- end}}
5987
- name: NAMESPACE
6088
value: {{ .Values.namespace | default .Release.Namespace }}
6189
{{- if .Values.upstream.enabled}}
@@ -66,6 +94,11 @@ spec:
6694
{{- end}}
6795
resources:
6896
{{- toYaml .Values.resources | nindent 12 }}
97+
volumeMounts:
98+
{{- if $embeddedDB}}
99+
- name: config-db-embedded-database
100+
mountPath: "/opt/database"
101+
{{- end }}
69102
{{- with .Values.extra }}
70103
{{- toYaml . | nindent 6 }}
71104
{{- end }}

chart/templates/postgres.yaml

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
{{- if eq .Values.db.enabled true }}
2-
1+
{{- if .Values.db.external.create }}
32
---
43
# PostgreSQL StatefulSet
54
apiVersion: apps/v1
@@ -25,18 +24,18 @@ spec:
2524
mountPath: /data
2625
envFrom:
2726
- secretRef:
28-
name: {{ .Values.db.secretKeyRef.name }}
27+
name: {{ .Values.db.external.secretKeyRef.name }}
2928
volumeClaimTemplates:
3029
- metadata:
3130
name: postgresql
3231
spec:
3332
accessModes: ["ReadWriteOnce"]
34-
{{- if not (eq .Values.db.storageClass "") }}
35-
storageClassName: {{ .Values.db.storageClass }}
33+
{{- if ne .Values.db.external.storageClass "" }}
34+
storageClassName: {{ .Values.db.external.storageClass }}
3635
{{- end }}
3736
resources:
3837
requests:
39-
storage: {{ .Values.db.storage }}
38+
storage: {{ .Values.db.external.storage }}
4039
---
4140
# PostgreSQL StatefulSet Service
4241
apiVersion: v1
@@ -50,11 +49,10 @@ spec:
5049
- port: 5432
5150
targetPort: 5432
5251
---
53-
{{- if .Values.db.secretKeyRef.create }}
5452
apiVersion: v1
5553
kind: Secret
5654
metadata:
57-
name: {{ .Values.db.secretKeyRef.name }}
55+
name: {{ .Values.db.external.secretKeyRef.name }}
5856
annotations:
5957
"helm.sh/resource-policy": "keep"
6058
type: Opaque
@@ -66,16 +64,12 @@ stringData:
6664
{{- $dbname := (( get $secretData "POSTGRES_DB" ) | b64dec ) | default "config_db" }}
6765
{{- $host := print (include "config-db.name" .) "-postgresql." .Release.Namespace ".svc.cluster.local:5432" }}
6866
{{- $url := print "postgresql://" $user ":" $password "@" $host }}
69-
{{- $configDbUrl := ( get $secretData .Values.db.secretKeyRef.key ) | default ( print $url "/config_db?sslmode=disable" ) }}
70-
67+
{{- $configDbUrl := ( get $secretData .Values.db.external.secretKeyRef.key ) | default ( print $url "/config_db?sslmode=disable" ) }}
7168
POSTGRES_USER: {{ $user | quote }}
7269
POSTGRES_PASSWORD: {{ $password | quote }}
7370
POSTGRES_HOST: {{ $host | quote }}
7471
POSTGRES_DB: {{ $dbname | quote }}
75-
{{ .Values.db.secretKeyRef.key }}: {{ $configDbUrl | quote }}
76-
77-
{{- end }}
78-
72+
{{ .Values.db.external.secretKeyRef.key }}: {{ $configDbUrl | quote }}
7973
---
8074

8175
{{- end }}

chart/values.yaml

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,55 @@
44
replicas: 1
55

66
# Use this only if you want to replace the default that is .Chart.Name as the name of all the objects.
7-
nameOverride: ""
7+
nameOverride: ''
88

99
# Set to true if you want to disable the postgrest service
10-
disablePostgrest: false
10+
disablePostgrest: false
1111

1212
image:
1313
repository: docker.io/flanksource/config-db
1414
pullPolicy: IfNotPresent
1515
# Overrides the image tag whose default is the chart appVersion.
16-
tag: "latest"
16+
tag: 'latest'
1717

1818
configChangeRetentionDays: 60
1919
configAnalysisRetentionDays: 60
2020

2121
# a list of configmaps to load scrape rules from, the configmap should have a single entry called "config.yaml"
2222
scrapeRuleConfigMaps:
2323
- config-db-rules
24+
2425
db:
25-
# Setting this to true will create a postgres stateful set for config-db to connect to.
26-
enabled: true
27-
secretKeyRef:
28-
create: true
29-
# The name of the secret to look for.
30-
name: config-db-postgresql
31-
# This is the key that we look for in the secret.
32-
key: DB_URL
33-
storageClass: ""
34-
storage: 20Gi
26+
runMigrations: true
27+
embedded:
28+
# If the database is embedded, setting this to true will persist the contents of the database
29+
# through a persistent volume
30+
persist: true
31+
storageClass: ''
32+
storage: 20Gi
33+
external:
34+
# Setting enabled to true will use an external postgres DB.
35+
# You can either use the embedded db or an external db.
36+
# If both is enabled, then embedded db will take precedence.
37+
enabled: false
38+
# Setting create:true will create
39+
# - a postgres stateful set
40+
# - the secret &
41+
# - the service to expose the postgres stateful set.
42+
# By default, the generated secret will use 'postgres' as the username and a randomly generated password.
43+
# If you need to set a custom username and password, you can populate a secret named 'postgres-connection' before install
44+
# with POSTGRES_USER and POSTGRES_PASSWORD
45+
#
46+
# If create:false, a prexisting secret containing the URI to an existing postgres database must be provided
47+
# The URI must be in the format 'postgresql://"$user":"$password"@"$host"/"$database"'
48+
create: false
49+
secretKeyRef:
50+
# The name of the secret to look for.
51+
name: config-db-postgresql
52+
# This is the key that we look for in the secret.
53+
key: DB_URL
54+
storageClass: ''
55+
storage: 20Gi
3556

3657
ingress:
3758
enabled: false
@@ -55,7 +76,7 @@ resources:
5576

5677
serviceAccount:
5778
create: true
58-
name: ""
79+
name: ''
5980
annotations: {}
6081

6182
upstream:

cmd/operator.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package cmd
22

33
import (
4-
"context"
54
"fmt"
65
"os"
76

@@ -39,8 +38,10 @@ func init() {
3938
}
4039

4140
func run(cmd *cobra.Command, args []string) {
42-
db.MustInit()
43-
api.DefaultContext = api.NewScrapeContext(context.Background(), db.DefaultDB(), db.Pool)
41+
ctx := cmd.Context()
42+
43+
db.MustInit(ctx)
44+
api.DefaultContext = api.NewScrapeContext(ctx, db.DefaultDB(), db.Pool)
4445

4546
zapLogger := logger.GetZapLogger()
4647
if zapLogger == nil {
@@ -64,7 +65,7 @@ func run(cmd *cobra.Command, args []string) {
6465
utilruntime.Must(configsv1.AddToScheme(scheme))
6566

6667
// Start the server
67-
go serve(args)
68+
go serve(ctx, args)
6869

6970
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
7071
Scheme: scheme,

cmd/run.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package cmd
22

33
import (
4-
"context"
54
"encoding/json"
65
"fmt"
76
"os"
@@ -23,15 +22,17 @@ var Run = &cobra.Command{
2322
Use: "run <scraper.yaml>",
2423
Short: "Run scrapers and return",
2524
Run: func(cmd *cobra.Command, configFiles []string) {
25+
ctx := cmd.Context()
26+
2627
logger.Infof("Scraping %v", configFiles)
2728
scraperConfigs, err := v1.ParseConfigs(configFiles...)
2829
if err != nil {
2930
logger.Fatalf(err.Error())
3031
}
3132

3233
if db.ConnectionString != "" {
33-
db.MustInit()
34-
api.DefaultContext = api.NewScrapeContext(context.Background(), db.DefaultDB(), db.Pool)
34+
db.MustInit(ctx)
35+
api.DefaultContext = api.NewScrapeContext(ctx, db.DefaultDB(), db.Pool)
3536
}
3637

3738
if db.ConnectionString == "" && outputDir == "" {

cmd/server.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ import (
2323
var Serve = &cobra.Command{
2424
Use: "serve",
2525
Run: func(cmd *cobra.Command, args []string) {
26-
serve(args)
26+
ctx := cmd.Context()
27+
28+
db.MustInit(ctx)
29+
serve(ctx, args)
2730
},
2831
}
2932

30-
func serve(configFiles []string) {
31-
db.MustInit()
32-
api.DefaultContext = api.NewScrapeContext(context.Background(), db.DefaultDB(), db.Pool)
33+
func serve(ctx context.Context, configFiles []string) {
34+
api.DefaultContext = api.NewScrapeContext(ctx, db.DefaultDB(), db.Pool)
3335

3436
e := echo.New()
3537
// PostgREST needs to know how it is exposed to create the correct links
@@ -60,8 +62,19 @@ func serve(configFiles []string) {
6062

6163
go jobs.ScheduleJobs()
6264

63-
if err := e.Start(fmt.Sprintf(":%d", httpPort)); err != nil {
64-
e.Logger.Fatal(err)
65+
go func() {
66+
if err := e.Start(fmt.Sprintf(":%d", httpPort)); err != nil {
67+
e.Logger.Fatal(err)
68+
}
69+
}()
70+
71+
<-ctx.Done()
72+
if err := db.StopEmbeddedPGServer(); err != nil {
73+
logger.Errorf("failed to stop server: %v", err)
74+
}
75+
76+
if err := e.Shutdown(ctx); err != nil {
77+
logger.Errorf("failed to shutdown echo HTTP server: %v", err)
6578
}
6679
}
6780

0 commit comments

Comments
 (0)