Skip to content
This repository was archived by the owner on Jul 6, 2021. It is now read-only.

Commit 067e899

Browse files
committed
Merge branch 'dmius-a00x-concl-recom' into 'master'
A002, A008 conclusions and recommendations See merge request postgres-ai/postgres-checkup!297
2 parents ed82ade + cf1aa74 commit 067e899

23 files changed

+1386
-633
lines changed

.gitlab-ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ variables:
1313
stage: test
1414
before_script:
1515
- apt-get update
16-
- apt-get install -y jq curl wget git s3cmd sudo golang-1.9-go
16+
- apt-get install -y jq curl wget git s3cmd sudo golang-1.9-go git
1717
- wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
1818
- echo "deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main $PG_SERVER_VERSION" > /etc/apt/sources.list.d/pgdg.list
1919
- apt-get update
@@ -121,7 +121,7 @@ test-pghrep:
121121
stage: test
122122
extends: ".prepare"
123123
script:
124-
- cd pghrep && make test
124+
- cd pghrep && make install && make test
125125

126126
test-check-9.6:
127127
extends: ".test-check"

checkup

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ build_pghrep() {
634634
dbg "building pghrep..."
635635
local save_pwd="${PWD}"
636636
cd "${SCRIPT_DIR}/pghrep"
637-
make buildplugins main >/dev/null
637+
make install buildplugins main >/dev/null
638638
cd "${save_pwd}"
639639
export PGHREP_BIN="${SCRIPT_DIR}/pghrep/bin/pghrep"
640640
dbg "done building pghrep"

pghrep/Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ LDFLAGS = -ldflags "-s -w \
2323
PLUGINS_SRC := $(wildcard plugins/*.go)
2424

2525
# Build the project
26-
all: clean vet buildplugins main
26+
all: clean install vet buildplugins main
27+
28+
install:
29+
go get golang.org/x/net/html
30+
go get github.com/dustin/go-humanize
2731

2832
buildplugins:
2933
@for f in $(basename $(patsubst plugins/%.go,%,$(PLUGINS_SRC))); do \
@@ -36,6 +40,7 @@ main:
3640
test:
3741
go test ./src/
3842
go test ./src/fmtutils/
43+
go test ./src/checkup/*/
3944

4045
vet:
4146
# Command go vet examine all go files in a single scope, which isn't suitable for plugins.

pghrep/plugins/H001.go

Lines changed: 0 additions & 60 deletions
This file was deleted.

pghrep/plugins/H002.go

Lines changed: 0 additions & 40 deletions
This file was deleted.

pghrep/src/checkup/a002/a002.go

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
package a002
2+
3+
import (
4+
"encoding/json"
5+
"io/ioutil"
6+
"net/http"
7+
"sort"
8+
"strconv"
9+
"strings"
10+
"time"
11+
12+
checkup ".."
13+
"../../log"
14+
"../../pyraconv"
15+
"github.com/dustin/go-humanize/english"
16+
"golang.org/x/net/html"
17+
)
18+
19+
type SupportedVersion struct {
20+
FirstRelease string
21+
FinalRelease string
22+
MinorVersions []int
23+
}
24+
25+
var SUPPORTED_VERSIONS map[string]SupportedVersion = map[string]SupportedVersion{
26+
"11": SupportedVersion{
27+
FirstRelease: "2018-10-18",
28+
FinalRelease: "2023-11-09",
29+
MinorVersions: []int{3},
30+
},
31+
"10": SupportedVersion{
32+
FirstRelease: "2017-10-05",
33+
FinalRelease: "2022-11-10",
34+
MinorVersions: []int{8},
35+
},
36+
"9.6": SupportedVersion{
37+
FirstRelease: "2016-09-29",
38+
FinalRelease: "2021-11-11",
39+
MinorVersions: []int{13},
40+
},
41+
"9.5": SupportedVersion{
42+
FirstRelease: "2016-01-07",
43+
FinalRelease: "2021-02-11",
44+
MinorVersions: []int{17},
45+
},
46+
"9.4": SupportedVersion{
47+
FirstRelease: "2014-12-18",
48+
FinalRelease: "2020-02-13",
49+
MinorVersions: []int{22},
50+
},
51+
}
52+
53+
func A002PrepareVersionInfo() {
54+
url := VERSION_SOURCE_URL
55+
log.Dbg("HTML code of %s ...\n", url)
56+
resp, err := http.Get(url)
57+
if err != nil {
58+
return
59+
}
60+
defer resp.Body.Close()
61+
htmlCode, err := ioutil.ReadAll(resp.Body)
62+
if err != nil {
63+
return
64+
}
65+
domDocTest := html.NewTokenizer(strings.NewReader(string(htmlCode)))
66+
for tokenType := domDocTest.Next(); tokenType != html.ErrorToken; {
67+
if tokenType != html.TextToken {
68+
tokenType = domDocTest.Next()
69+
continue
70+
}
71+
rel := strings.TrimSpace(html.UnescapeString(string(domDocTest.Text())))
72+
if len(rel) > 3 && rel[0:3] == "REL" {
73+
if strings.Contains(rel, "BETA") || strings.Contains(rel, "RC") ||
74+
strings.Contains(rel, "ALPHA") {
75+
continue
76+
}
77+
ver := strings.Split(rel, "_")
78+
if len(ver) > 2 {
79+
majorVersion := strings.Replace(ver[0], "REL", "", 1)
80+
if majorVersion != "" {
81+
majorVersion = majorVersion + "."
82+
}
83+
majorVersion = majorVersion + ver[1]
84+
minorVersion := ver[2]
85+
ver, ok := SUPPORTED_VERSIONS[majorVersion]
86+
if ok {
87+
mVer, _ := strconv.Atoi(minorVersion)
88+
ver.MinorVersions = append(ver.MinorVersions, mVer)
89+
SUPPORTED_VERSIONS[majorVersion] = ver
90+
}
91+
}
92+
}
93+
tokenType = domDocTest.Next()
94+
}
95+
}
96+
97+
func A002CheckAllVersionsIsSame(report A002Report,
98+
result checkup.ReportOutcome) checkup.ReportOutcome {
99+
var version string
100+
var hosts []string
101+
var vers []string
102+
diff := false
103+
for host, hostData := range report.Results {
104+
if version == "" {
105+
version = hostData.Data.ServerMajorVer + "." + hostData.Data.ServerMinorVer
106+
}
107+
if version != (hostData.Data.ServerMajorVer + "." + hostData.Data.ServerMinorVer) {
108+
diff = true
109+
}
110+
hosts = append(hosts, host)
111+
vers = append(vers, hostData.Data.ServerMajorVer+"."+hostData.Data.ServerMinorVer)
112+
}
113+
if diff && len(hosts) > 1 {
114+
result.AppendConclusion(english.PluralWord(len(hosts),
115+
MSG_NOT_ALL_VERSIONS_SAME_CONCLUSION_1, MSG_NOT_ALL_VERSIONS_SAME_CONCLUSION_N),
116+
strings.Join(hosts, ", "), strings.Join(vers, ", "))
117+
result.AppendRecommendation(MSG_NOT_ALL_VERSIONS_SAME_RECOMMENDATION)
118+
result.P2 = true
119+
} else {
120+
result.AppendConclusion(MSG_ALL_VERSIONS_SAME_CONCLUSION, version)
121+
}
122+
return result
123+
}
124+
125+
func A002CheckMajorVersions(report A002Report, result checkup.ReportOutcome) checkup.ReportOutcome {
126+
var processed map[string]bool = map[string]bool{}
127+
for host, hostData := range report.Results {
128+
if _, vok := processed[hostData.Data.ServerMajorVer]; vok {
129+
// version already checked
130+
continue
131+
}
132+
ver, ok := SUPPORTED_VERSIONS[hostData.Data.ServerMajorVer]
133+
if !ok {
134+
result.AppendConclusion(MSG_WRONG_VERSION_CONCLUSION, hostData.Data.Version, host)
135+
result.AppendRecommendation(MSG_WRONG_VERSION_RECOMMENDATION, host)
136+
result.P1 = true
137+
continue
138+
}
139+
from, _ := time.Parse("2006-01-02", ver.FirstRelease)
140+
to, _ := time.Parse("2006-01-02", ver.FinalRelease)
141+
yearBeforeFinal := to.AddDate(-1, 0, 0)
142+
today := time.Now()
143+
if today.After(to) {
144+
// already not supported versions
145+
result.AppendConclusion(MSG_NOT_SUPPORTED_VERSION_CONCLUSION, hostData.Data.ServerMajorVer, ver.FinalRelease)
146+
result.AppendRecommendation(MSG_NOT_SUPPORTED_VERSION_RECOMMENDATION, hostData.Data.ServerMajorVer)
147+
result.P1 = true
148+
}
149+
if today.After(yearBeforeFinal) && today.Before(to) {
150+
// supported last year
151+
result.AppendConclusion(MSG_LAST_YEAR_SUPPORTED_VERSION_CONCLUSION, hostData.Data.ServerMajorVer, ver.FinalRelease)
152+
result.P2 = true
153+
}
154+
if today.After(from) && today.After(to) {
155+
// ok
156+
result.AppendConclusion(MSG_SUPPORTED_VERSION_CONCLUSION, hostData.Data.ServerMajorVer, ver.FinalRelease)
157+
}
158+
processed[hostData.Data.ServerMajorVer] = true
159+
}
160+
return result
161+
}
162+
163+
func A002CheckMinorVersions(report A002Report, result checkup.ReportOutcome) checkup.ReportOutcome {
164+
var updateHosts []string
165+
var curVersions []string
166+
var updateVersions []string
167+
var processed map[string]bool = map[string]bool{}
168+
for host, hostData := range report.Results {
169+
if _, vok := processed[hostData.Data.ServerMinorVer]; vok {
170+
// version already checked
171+
continue
172+
}
173+
ver, ok := SUPPORTED_VERSIONS[hostData.Data.ServerMajorVer]
174+
if !ok {
175+
result.AppendConclusion(MSG_NOT_SUPPORTED_VERSION_CONCLUSION, hostData.Data.ServerMajorVer, ver.FinalRelease)
176+
result.AppendRecommendation(MSG_NOT_SUPPORTED_VERSION_RECOMMENDATION, hostData.Data.ServerMajorVer)
177+
result.P1 = true
178+
continue
179+
}
180+
sort.Ints(ver.MinorVersions)
181+
lastVersion := ver.MinorVersions[len(ver.MinorVersions)-1]
182+
minorVersion, _ := strconv.Atoi(hostData.Data.ServerMinorVer)
183+
if minorVersion >= lastVersion {
184+
result.AppendConclusion(MSG_LAST_MINOR_VERSION_CONCLUSION,
185+
hostData.Data.ServerMajorVer+"."+hostData.Data.ServerMinorVer, hostData.Data.ServerMajorVer)
186+
processed[hostData.Data.ServerMinorVer] = true
187+
} else {
188+
updateHosts = append(updateHosts, host)
189+
curVersions = append(curVersions, hostData.Data.ServerMajorVer+"."+hostData.Data.ServerMinorVer)
190+
updateVersions = append(updateVersions, hostData.Data.ServerMajorVer+"."+strconv.Itoa(lastVersion))
191+
}
192+
}
193+
if len(updateHosts) > 0 {
194+
result.AppendConclusion(english.PluralWord(len(updateHosts),
195+
MSG_NOT_LAST_MINOR_VERSION_CONCLUSION_1, MSG_NOT_LAST_MINOR_VERSION_CONCLUSION_N),
196+
strings.Join(updateHosts, ", "), strings.Join(curVersions, ", "), updateVersions[0])
197+
result.AppendRecommendation(MSG_NOT_LAST_MINOR_VERSION_RECOMMENDATION, updateVersions[0])
198+
result.P2 = true
199+
}
200+
return result
201+
}
202+
203+
func A002Process(report A002Report) checkup.ReportOutcome {
204+
var result checkup.ReportOutcome
205+
A002PrepareVersionInfo()
206+
result = A002CheckAllVersionsIsSame(report, result)
207+
result = A002CheckMajorVersions(report, result)
208+
result = A002CheckMinorVersions(report, result)
209+
return result
210+
}
211+
212+
func A002PreprocessReportData(data map[string]interface{}) {
213+
filePath := pyraconv.ToString(data["source_path_full"])
214+
jsonRaw := checkup.LoadRawJsonReport(filePath)
215+
var report A002Report
216+
err := json.Unmarshal(jsonRaw, &report)
217+
if err != nil {
218+
log.Err("Can't load json report to process")
219+
return
220+
}
221+
result := A002Process(report)
222+
if len(result.Recommendations) == 0 {
223+
result.AppendRecommendation(MSG_NO_RECOMMENDATION)
224+
} else {
225+
result.AppendRecommendation(MSG_GENERAL_RECOMMENDATION)
226+
}
227+
// update data and file
228+
checkup.SaveConclusionsRecommendations(data, result)
229+
}

0 commit comments

Comments
 (0)