Skip to content

Commit 3ec7732

Browse files
committed
chore: test fixes
1 parent 4b847fe commit 3ec7732

15 files changed

Lines changed: 515 additions & 109 deletions

File tree

cmd/main.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,16 +235,22 @@ func runAutoStart(cmd *cobra.Command, args []string) error {
235235
return fmt.Errorf("failed to run pg_tune: %w", err)
236236
}
237237
if postgres.DryRun {
238-
clicky.Infof("📄 Generated postgresql.auto.conf by pg_tune:")
238+
clicky.Infof("📄 Generated postgresql.tune.conf by pg_tune:")
239239

240240
fmt.Println(clicky.CodeBlock("properties", content).ANSI())
241241
} else {
242-
configPath := filepath.Join(opts.DataDir, "postgresql.auto.conf")
242+
configPath := filepath.Join(postgres.DataDir, "postgresql.tune.conf")
243243
if err := os.WriteFile(configPath, []byte(content), 0644); err != nil {
244-
return fmt.Errorf("failed to write postgresql.auto.conf: %w", err)
244+
return fmt.Errorf("failed to write postgresql.tune.conf: %w", err)
245245
}
246246
clicky.Infof("✅ pg_tune optimization applied and saved to %s", configPath)
247247

248+
// Ensure postgresql.conf includes the tune file
249+
postgresConfPath := filepath.Join(postgres.DataDir, "postgresql.conf")
250+
if err := config.EnsureIncludeDirective(postgresConfPath, "postgresql.tune.conf"); err != nil {
251+
return fmt.Errorf("failed to update postgresql.conf: %w", err)
252+
}
253+
clicky.Infof("✅ postgresql.conf updated to include postgresql.tune.conf")
248254
}
249255
}
250256

docker-entrypoint.sh

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ set -e
33

44
echo "PGDATA is set to: $PGDATA"
55

6+
67
# Detect current user
78
CURRENT_USER=$(id -u)
89
CURRENT_USER_NAME=$(id -un)
@@ -46,9 +47,7 @@ fi
4647
postgres-cli server status
4748

4849
# Run postgres-cli auto-start (includes permission checks)
49-
postgres-cli auto-start --upgrade-to=$PG_VERSION --data-dir "$PGDATA" $POSTGRES_CLI_ARGS
50-
51-
cat $PGDATA/pg_hba.conf
50+
postgres-cli auto-start --upgrade-to=$PG_VERSION --data-dir "$PGDATA" --report-caller $POSTGRES_CLI_ARGS
5251

5352

5453
if [ "$UPGRADE_ONLY" = "true" ]; then

go.mod

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/flanksource/postgres
33
go 1.25.1
44

55
require (
6-
github.com/flanksource/clicky v1.10.0
6+
github.com/flanksource/clicky v1.11.0
77
github.com/flanksource/commons v1.42.3
88
github.com/golang-jwt/jwt/v5 v5.3.0
99
github.com/invisionapp/go-health v2.1.0+incompatible
@@ -102,9 +102,6 @@ require (
102102
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
103103
github.com/ohler55/ojg v1.25.0 // indirect
104104
github.com/oklog/ulid/v2 v2.1.1 // indirect
105-
github.com/olekukonko/errors v1.1.0 // indirect
106-
github.com/olekukonko/ll v0.0.9 // indirect
107-
github.com/olekukonko/tablewriter v1.1.0 // indirect
108105
github.com/onsi/ginkgo v1.16.5 // indirect
109106
github.com/onsi/ginkgo/v2 v2.25.3 // indirect
110107
github.com/opencontainers/go-digest v1.0.0 // indirect

go.sum

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ github.com/f-amaral/go-async v0.3.0 h1:h4kLsX7aKfdWaHvV0lf+/EE3OIeCzyeDYJDb/vDZU
6666
github.com/f-amaral/go-async v0.3.0/go.mod h1:Hz5Qr6DAWpbTTUjytnrg1WIsDgS7NtOei5y8SipYS7U=
6767
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
6868
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
69+
github.com/flanksource/clicky v1.11.0 h1:b/gdDOuoAel5MUNMPzw0ZFgsNxPLy1hHOtrW1TeFsa8=
70+
github.com/flanksource/clicky v1.11.0/go.mod h1:Rfma4dthSRBI30HTRYYS7B6XLL5Me8saLe5lmx220z8=
6971
github.com/flanksource/commons v1.42.3 h1:53tr1A8fFywYD/56kZgYNAxUEqOdvbXAiQr+3/M2Zso=
7072
github.com/flanksource/commons v1.42.3/go.mod h1:xEBCobwaM0+EHn2SvFpqiCBJCVk1803An1kZleXFR9Y=
7173
github.com/flanksource/gomplate/v3 v3.24.60 h1:g1SjmR3m5YlXpuxyegvEj6OVbkoqP3btZbqUH0f7920=
@@ -230,12 +232,6 @@ github.com/ohler55/ojg v1.25.0 h1:sDwc4u4zex65Uz5Nm7O1QwDKTT+YRcpeZQTy1pffRkw=
230232
github.com/ohler55/ojg v1.25.0/go.mod h1:gQhDVpQLqrmnd2eqGAvJtn+NfKoYJbe/A4Sj3/Vro4o=
231233
github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s=
232234
github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
233-
github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM=
234-
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
235-
github.com/olekukonko/ll v0.0.9 h1:Y+1YqDfVkqMWuEQMclsF9HUR5+a82+dxJuL1HHSRpxI=
236-
github.com/olekukonko/ll v0.0.9/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g=
237-
github.com/olekukonko/tablewriter v1.1.0 h1:N0LHrshF4T39KvI96fn6GT8HEjXRXYNDrDjKFDB7RIY=
238-
github.com/olekukonko/tablewriter v1.1.0/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo=
239235
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
240236
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
241237
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=

pkg/config/conf.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ func (cs ConfigSetting) GetInt() (int, error) {
3838
unit := 1
3939

4040
if cs.Unit != nil {
41-
switch *cs.Unit {
41+
switch strings.ToLower(*cs.Unit) {
4242
case "8kb":
4343
unit = 8 * 1024
44-
case "kB", "KB":
44+
case "kb":
4545
unit = KB
46-
case "MB":
46+
case "mb":
4747
unit = MB
48-
case "GB":
48+
case "gb":
4949
unit = GB
5050
}
5151
}
@@ -65,8 +65,8 @@ func (cs ConfigSetting) IsBytes() bool {
6565
if cs.Unit == nil {
6666
return false
6767
}
68-
switch *cs.Unit {
69-
case "8kb", "kB", "MB", "GB", "KB":
68+
switch strings.ToLower(*cs.Unit) {
69+
case "8kb", "kb", "mb", "gb":
7070
return true
7171
}
7272
return false

pkg/config/postmaster.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package config
22

33
import (
4+
"bufio"
45
"errors"
6+
"fmt"
57
"os"
8+
"path/filepath"
69
"strings"
710
)
811

@@ -65,3 +68,70 @@ func LoadConfFile(path string) (Conf, error) {
6568
}
6669
return conf, nil
6770
}
71+
72+
// EnsureIncludeDirective ensures that postgresql.conf includes the specified file
73+
// If the include directive doesn't exist, it will be added at the end
74+
func EnsureIncludeDirective(postgresConfPath, includeFile string) error {
75+
76+
if _, err := os.Stat(postgresConfPath); os.IsNotExist(err) {
77+
if _, err := os.Stat(filepath.Dir(postgresConfPath)); err == nil {
78+
// return error with a list of files in the data directory
79+
files, _ := os.ReadDir(filepath.Dir(postgresConfPath))
80+
var fileNames []string
81+
for _, f := range files {
82+
fileNames = append(fileNames, f.Name())
83+
}
84+
return fmt.Errorf("postgresql.conf does not exist at path: %s, data directory contains: %v", postgresConfPath, fileNames)
85+
}
86+
return fmt.Errorf("postgresql.conf file does not exist at path: %s", postgresConfPath)
87+
}
88+
data, err := os.ReadFile(postgresConfPath)
89+
if err != nil {
90+
return fmt.Errorf("failed to read postgresql.conf: %w", err)
91+
}
92+
93+
lines := strings.Split(string(data), "\n")
94+
95+
// Check if include directive already exists
96+
includePattern := fmt.Sprintf("include '%s'", includeFile)
97+
includeIfExistsPattern := fmt.Sprintf("include_if_exists '%s'", includeFile)
98+
99+
for _, line := range lines {
100+
trimmed := strings.TrimSpace(line)
101+
// Skip comments
102+
if strings.HasPrefix(trimmed, "#") {
103+
continue
104+
}
105+
106+
// Check for existing include directive
107+
if strings.Contains(trimmed, includePattern) || strings.Contains(trimmed, includeIfExistsPattern) {
108+
// Include already exists
109+
return nil
110+
}
111+
}
112+
113+
// Include not found, append it
114+
file, err := os.OpenFile(postgresConfPath, os.O_APPEND|os.O_WRONLY, 0644)
115+
if err != nil {
116+
return fmt.Errorf("failed to open postgresql.conf for writing: %w", err)
117+
}
118+
defer file.Close()
119+
120+
writer := bufio.NewWriter(file)
121+
122+
// Add a newline if file doesn't end with one
123+
if len(data) > 0 && data[len(data)-1] != '\n' {
124+
writer.WriteString("\n")
125+
}
126+
127+
// Add the include directive
128+
writer.WriteString("\n")
129+
writer.WriteString("# Include pg_tune optimizations\n")
130+
writer.WriteString(fmt.Sprintf("include_if_exists '%s'\n", includeFile))
131+
132+
if err := writer.Flush(); err != nil {
133+
return fmt.Errorf("failed to write to postgresql.conf: %w", err)
134+
}
135+
136+
return nil
137+
}

pkg/config/postmaster_test.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package config
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"strings"
7+
"testing"
8+
)
9+
10+
func TestEnsureIncludeDirective(t *testing.T) {
11+
tests := []struct {
12+
name string
13+
initialContent string
14+
includeFile string
15+
expectedContent string
16+
shouldContain string
17+
}{
18+
{
19+
name: "add include to empty file",
20+
initialContent: `# PostgreSQL configuration file
21+
listen_addresses = '*'
22+
port = 5432
23+
`,
24+
includeFile: "postgresql.tune.conf",
25+
shouldContain: "include_if_exists 'postgresql.tune.conf'",
26+
},
27+
{
28+
name: "include already exists",
29+
initialContent: `# PostgreSQL configuration file
30+
listen_addresses = '*'
31+
port = 5432
32+
include_if_exists 'postgresql.tune.conf'
33+
`,
34+
includeFile: "postgresql.tune.conf",
35+
shouldContain: "include_if_exists 'postgresql.tune.conf'",
36+
},
37+
{
38+
name: "include with different syntax already exists",
39+
initialContent: `# PostgreSQL configuration file
40+
listen_addresses = '*'
41+
include 'postgresql.tune.conf'
42+
port = 5432
43+
`,
44+
includeFile: "postgresql.tune.conf",
45+
shouldContain: "include 'postgresql.tune.conf'",
46+
},
47+
{
48+
name: "commented include should add new one",
49+
initialContent: `# PostgreSQL configuration file
50+
listen_addresses = '*'
51+
# include 'postgresql.tune.conf'
52+
port = 5432
53+
`,
54+
includeFile: "postgresql.tune.conf",
55+
shouldContain: "include_if_exists 'postgresql.tune.conf'",
56+
},
57+
{
58+
name: "file without trailing newline",
59+
initialContent: `listen_addresses = '*'`,
60+
includeFile: "postgresql.tune.conf",
61+
shouldContain: "include_if_exists 'postgresql.tune.conf'",
62+
},
63+
}
64+
65+
for _, tt := range tests {
66+
t.Run(tt.name, func(t *testing.T) {
67+
tmpDir := t.TempDir()
68+
confPath := filepath.Join(tmpDir, "postgresql.conf")
69+
70+
if err := os.WriteFile(confPath, []byte(tt.initialContent), 0644); err != nil {
71+
t.Fatalf("failed to write test file: %v", err)
72+
}
73+
74+
err := EnsureIncludeDirective(confPath, tt.includeFile)
75+
if err != nil {
76+
t.Fatalf("EnsureIncludeDirective() error = %v", err)
77+
}
78+
79+
resultContent, err := os.ReadFile(confPath)
80+
if err != nil {
81+
t.Fatalf("failed to read result file: %v", err)
82+
}
83+
84+
resultStr := string(resultContent)
85+
86+
if !strings.Contains(resultStr, tt.shouldContain) {
87+
t.Errorf("Result does not contain expected string.\nExpected to contain: %s\nGot:\n%s", tt.shouldContain, resultStr)
88+
}
89+
90+
if tt.name == "include already exists" || tt.name == "include with different syntax already exists" {
91+
count := strings.Count(resultStr, "include")
92+
if count != 1 {
93+
t.Errorf("Expected exactly 1 include directive, got %d\nContent:\n%s", count, resultStr)
94+
}
95+
}
96+
})
97+
}
98+
}
99+
100+
func TestEnsureIncludeDirective_FileNotExist(t *testing.T) {
101+
tmpDir := t.TempDir()
102+
confPath := filepath.Join(tmpDir, "nonexistent.conf")
103+
104+
err := EnsureIncludeDirective(confPath, "postgresql.tune.conf")
105+
if err == nil {
106+
t.Error("Expected error for non-existent file, got nil")
107+
}
108+
}

pkg/pgtune/optimize.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type OptimizeOptions struct {
2121
SystemInfo *sysinfo.SystemInfo
2222
}
2323

24-
// OptimizeAndSave calculates optimal PostgreSQL configuration and saves to postgresql.auto.conf
24+
// OptimizeAndSave calculates optimal PostgreSQL configuration and generates content for postgresql.tune.conf
2525
func OptimizeAndSave(opts OptimizeOptions) (string, error) {
2626
// Use provided system info or detect
2727
sysInfo := opts.SystemInfo
@@ -76,15 +76,15 @@ func OptimizeAndSave(opts OptimizeOptions) (string, error) {
7676
params.MaxConnections = GetRecommendedMaxConnections(opts.DBType)
7777
}
7878

79-
// Generate postgresql.auto.conf content
79+
// Generate postgresql.tune.conf content
8080
configContent := generateAutoConf(params, sysInfo)
8181

8282
clicky.Infof("Optimized with shared_buffers: %s, cpus: %d", params.SharedBuffers, r.CPUs)
8383

8484
return configContent, nil
8585
}
8686

87-
// generateAutoConf generates postgresql.auto.conf content from tuned parameters
87+
// generateAutoConf generates postgresql.tune.conf content from tuned parameters
8888
func generateAutoConf(params *TunedParameters, sysInfo *sysinfo.SystemInfo) string {
8989
var content string
9090

0 commit comments

Comments
 (0)