Skip to content

Commit ba9cc4c

Browse files
committed
fix: postgres auto-start and dryrun
1 parent 99e0c30 commit ba9cc4c

18 files changed

Lines changed: 1032 additions & 827 deletions

File tree

pkg/config/conf.go

Lines changed: 124 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package config
22

33
import (
4+
"fmt"
45
"sort"
6+
"strconv"
57
"strings"
68

9+
"github.com/flanksource/clicky/api"
710
"github.com/samber/lo"
811
)
912

@@ -31,32 +34,137 @@ type ConfigSetting struct {
3134
PendingRestart bool `json:"pending_restart,omitempty"`
3235
}
3336

37+
func (cs ConfigSetting) GetInt() (int, error) {
38+
unit := 1
39+
40+
if cs.Unit != nil {
41+
switch *cs.Unit {
42+
case "8kb":
43+
unit = 8 * 1024
44+
case "kB", "KB":
45+
unit = KB
46+
case "MB":
47+
unit = MB
48+
case "GB":
49+
unit = GB
50+
}
51+
}
52+
53+
num, err := strconv.Atoi(cs.Setting)
54+
if err != nil {
55+
return 0, err
56+
}
57+
return num * unit, nil
58+
}
59+
60+
var KB = 1024
61+
var MB = 1024 * KB
62+
var GB = 1024 * MB
63+
64+
func (cs ConfigSetting) IsBytes() bool {
65+
if cs.Unit == nil {
66+
return false
67+
}
68+
switch *cs.Unit {
69+
case "8kb", "kB", "MB", "GB", "KB":
70+
return true
71+
}
72+
return false
73+
}
74+
75+
func (cs ConfigSetting) String() string {
76+
if cs.IsBytes() {
77+
val, err := cs.GetInt()
78+
if err != nil {
79+
return cs.Setting
80+
}
81+
82+
if val%GB == 0 && val >= GB {
83+
return fmt.Sprintf("%dGB", val/GB)
84+
} else if val >= MB && val%MB == 0 {
85+
return fmt.Sprintf("%dMB", val/MB)
86+
}
87+
return fmt.Sprintf("%dkB", val/KB)
88+
}
89+
90+
return cs.Setting
91+
}
92+
93+
func (cs ConfigSetting) GetBool() (bool, error) {
94+
if cs.Setting == "" {
95+
return false, nil
96+
}
97+
switch strings.ToLower(cs.Setting) {
98+
case "on", "true", "yes":
99+
return true, nil
100+
case "off", "false", "no":
101+
return false, nil
102+
}
103+
return false, fmt.Errorf("Uknown bool type: %s", cs.Setting)
104+
}
105+
34106
// ConfSettings is a map of configuration parameter names to their full settings
35107
type ConfSettings []ConfigSetting
36108

37-
// ToMap converts ConfSettings to a simple map of name->setting values
38-
func (cs ConfSettings) ToMap() Conf {
39-
result := Conf{}
109+
func (cs ConfSettings) AsMap() map[string]ConfigSetting {
110+
result := map[string]ConfigSetting{}
40111
for _, setting := range cs {
41-
result[setting.Name] = setting.Setting
112+
result[setting.Name] = setting
42113
}
43114
return result
44115
}
45116

46-
func (c Conf) AsArgs() []string {
47-
args := []string{}
48-
// sort keys for consistent output
49-
keys := lo.Keys(c)
117+
func (cs ConfSettings) Pretty() api.Text {
118+
t := api.Text{}
119+
keys := lo.Keys(cs.AsMap())
50120
sort.StringSlice(keys).Sort()
51-
for _, k := range keys {
52-
v := c[k]
121+
for _, name := range keys {
122+
setting := cs.AsMap()[name]
123+
124+
t = t.Append(setting.Name).Append("=", "text-muted").Append(setting.String(), "bold").Append(" #", "text-muted")
125+
if setting.Unit != nil {
126+
t = t.Append(setting.Setting, "text-muted").Space().Append(*setting.Unit, "text-muted")
127+
}
128+
t = t.Append("@ source: "+setting.Source, "text-muted")
129+
130+
t = t.NewLine()
131+
}
132+
return t
133+
}
134+
135+
// ToConf converts ConfSettings to a simple map of name->setting values
136+
func (cs ConfSettings) ToConf() Conf {
137+
result := Conf{}
138+
for _, setting := range cs {
139+
if setting.Setting == "" {
140+
continue
141+
}
142+
result[setting.Name] = setting.String()
143+
}
144+
return result
145+
}
146+
147+
func (c Conf) Sorted() []struct{ Key, Value string } {
148+
var result []struct{ Key, Value string }
149+
for k, v := range c {
53150
if v == "" {
54151
continue
55152
}
56-
if strings.ContainsAny(v, " ") {
57-
v = "'" + v + "'"
153+
result = append(result, struct{ Key, Value string }{Key: k, Value: v})
154+
}
155+
sort.Slice(result, func(i, j int) bool {
156+
return result[i].Key < result[j].Key
157+
})
158+
return result
159+
}
160+
161+
func (c Conf) AsArgs() []string {
162+
args := []string{}
163+
for _, e := range c.Sorted() {
164+
if strings.ContainsAny(e.Value, " ") {
165+
e.Value = "'" + e.Value + "'"
58166
}
59-
args = append(args, " --"+k+"="+v)
167+
args = append(args, " --"+e.Key+"="+e.Value)
60168
}
61169
return args
62170
}
@@ -74,8 +182,9 @@ func (c Conf) MergeFrom(other Conf) Conf {
74182

75183
func (c Conf) AsFile() string {
76184
var sb strings.Builder
77-
for k, v := range c {
78-
sb.WriteString(k + " = " + v + "\n")
185+
186+
for _, e := range c.Sorted() {
187+
sb.WriteString(e.Key + " = " + e.Value + "\n")
79188
}
80189

81190
return sb.String()

pkg/config/loader.go

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,6 @@ func DefaultPostgresConf() *pkg.PostgresConf {
3232
}
3333
}
3434

35-
func LoadFromCSV(records []map[string]any) (Conf, error) {
36-
37-
conf := Conf{}
38-
39-
for _, record := range records {
40-
name := strings.TrimSpace(fmt.Sprintf("%v", record["name"]))
41-
value := strings.TrimSpace(fmt.Sprintf("%v", record["setting"]))
42-
43-
// Skip empty values
44-
if name == "" || value == "" {
45-
continue
46-
}
47-
48-
conf[name] = value
49-
}
50-
51-
return conf, nil
52-
}
53-
5435
// LoadSettingsFromQuery parses pg_settings query results into ConfSettings
5536
func LoadSettingsFromQuery(records []map[string]any) (ConfSettings, error) {
5637
settings := ConfSettings{}

pkg/config/postmaster.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import (
66
"strings"
77
)
88

9-
// LoadPostmasterOpts loads postmaster options from a file like:"
10-
// /usr/lib/postgresql/14/bin/postgres "-D" "/var/lib/postgresql/data" "--config-file=/etc/postgresql/postgresql.conf" "--checkpoint_completion_target=0.9" "--db_user_namespace=false" "--effective_cache_size=3GB" "--effective_io_concurrency=200" "--extra_float_digits=0" "--lc_messages=C" "--listen_addresses=*" "--log_autovacuum_min_duration=10s" "--log_checkpoints=true" "--log_connections=false" "--log_destination=stderr" "--log_disconnections=false" "--log_filename=postgresql-%d.log" "--log_line_prefix=%m [%p] %q[user=%u,db=%d,app=%a] " "--log_lock_waits=true" "--log_min_duration_statement=10s" "--log_rotation_age=1d" "--log_rotation_size=100MB" "--log_temp_files=100MB" "--log_timezone=UTC" "--log_truncate_on_rotation=true" "--logging_collector=true" "--maintenance_work_mem=205MB" "--max_connections=100" "--max_parallel_workers=2" "--max_parallel_workers_per_gather=2" "--max_wal_size=3GB" "--max_worker_processes=8" "--min_wal_size=2GB" "--password_encryption=scram-sha-256" "--random_page_cost=1.1" "--shared_buffers=1GB" "--ssl=false" "--timezone=UTC" "--wal_buffers=-1" "--work_mem=10MB"
119
func LoadPostmasterOpts(path string) (Conf, error) {
1210
opts := Conf{}
1311
data, err := os.ReadFile(path)

pkg/generators/pgbouncer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func (g *PgBouncerConfigGenerator) generateHeader() string {
136136
g.SystemInfo.OSType,
137137
time.Now().Format("2006-01-02 15:04:05"),
138138
g.SystemInfo.TotalMemoryGB(),
139-
g.SystemInfo.CPUCount,
139+
g.SystemInfo.EffectiveCPUCount(),
140140
g.TunedParams.MaxConnections,
141141
)
142142
}

0 commit comments

Comments
 (0)