@@ -6,7 +6,9 @@ package main
66
77import (
88 "context"
9+ "embed"
910 "fmt"
11+ "io/fs"
1012 "log"
1113 "math/rand"
1214 "os"
@@ -27,32 +29,44 @@ const (
2729 connIdleTimeout = 15 * time .Minute
2830 connTimeout = 5 * time .Minute
2931
30- caCertPath = "/tmp/ca.pem"
32+ caCertPath = "/tmp/ca.pem"
33+ helperFunctionsPath = "functions.sql"
34+ )
35+
36+ var (
37+ //go:embed *.sql
38+ data embed.FS
3139)
3240
3341func main () {
3442 ctx , p := provider .MustPrepare [* postgres.DatabaseIntent ]()
3543
44+ if err := run (ctx , p ); err != nil {
45+ log .Fatal (err )
46+ }
47+ }
48+
49+ func run (ctx context.Context , p * provider.Provider [* postgres.DatabaseIntent ]) error {
3650 cluster := & postgresclass.ClusterInstance {}
3751 if err := p .Resources .Unmarshal (fmt .Sprintf ("%s:cluster" , providerPkg ), cluster ); err != nil {
38- log . Fatalf ("unable to read required resource \" cluster\" : %v " , err )
52+ return fmt . Errorf ("unable to read required resource \" cluster\" : %w " , err )
3953 }
4054
4155 // TODO inject file as secret ref and propagate secret ref to server, too.
4256 if cluster .CaCert != "" {
4357 if err := os .WriteFile (caCertPath , []byte (cluster .CaCert ), 0644 ); err != nil {
44- log . Fatalf ("failed to write %q: %v " , caCertPath , err )
58+ return fmt . Errorf ("failed to write %q: %w " , caCertPath , err )
4559 }
4660
4761 if err := os .Setenv ("PGSSLROOTCERT" , caCertPath ); err != nil {
48- log . Fatalf ("failed to set PGSSLROOTCERT: %v " , err )
62+ return fmt . Errorf ("failed to set PGSSLROOTCERT: %w " , err )
4963 }
5064
5165 }
5266
5367 exists , err := ensureDatabase (ctx , cluster , p .Intent .Name )
5468 if err != nil {
55- log . Fatalf ("unable to create database %q: %v " , p .Intent .Name , err )
69+ return fmt . Errorf ("unable to create database %q: %w " , p .Intent .Name , err )
5670 }
5771
5872 instance := & postgresclass.DatabaseInstance {
@@ -72,29 +86,45 @@ func main() {
7286 MaxConnIdleTime : connIdleTimeout ,
7387 })
7488 if err != nil {
75- log . Fatalf ("unable to open connection: %v " , err )
89+ return fmt . Errorf ("unable to open connection: %w " , err )
7690 }
7791 defer func () {
7892 if err := db .Close (); err != nil {
7993 log .Printf ("unable to close database connection: %v" , err )
8094 }
8195 }()
8296
97+ if p .Intent .ProvisionHelperFunctions {
98+ content , err := fs .ReadFile (data , helperFunctionsPath )
99+ if err != nil {
100+ return fmt .Errorf ("failed to read %s: %w" , helperFunctionsPath , err )
101+ }
102+
103+ if err := applyWithRetry (ctx , db , string (content )); err != nil {
104+ return fmt .Errorf ("unable to apply helper functions: %w" , err )
105+ }
106+ }
107+
83108 for _ , schema := range p .Intent .Schema {
84- if err := backoff .Retry (func () error {
85- _ , err := db .Exec (ctx , string (schema .Contents ))
86- return err
87- }, backOff {
88- interval : 100 * time .Millisecond ,
89- deadline : time .Now ().Add (15 * time .Second ),
90- jitter : 100 * time .Millisecond ,
91- }); err != nil {
92- log .Fatalf ("unable to apply schema %q: %v" , schema .Path , err )
109+ if err := applyWithRetry (ctx , db , string (schema .Contents )); err != nil {
110+ return fmt .Errorf ("unable to apply schema %q: %w" , schema .Path , err )
93111 }
94112 }
95113 }
96114
97115 p .EmitResult (instance )
116+ return nil
117+ }
118+
119+ func applyWithRetry (ctx context.Context , db * universepg.DB , sql string ) error {
120+ return backoff .Retry (func () error {
121+ _ , err := db .Exec (ctx , sql )
122+ return err
123+ }, backOff {
124+ interval : 100 * time .Millisecond ,
125+ deadline : time .Now ().Add (15 * time .Second ),
126+ jitter : 100 * time .Millisecond ,
127+ })
98128}
99129
100130func ensureDatabase (ctx context.Context , cluster * postgresclass.ClusterInstance , name string ) (bool , error ) {
0 commit comments