Skip to content

Commit e97ca02

Browse files
committed
MINOR: improve HAProxy runtime version checks
- Add a fallback in Reload() to retry fetching the HAProxy version if the initial startup probe failed, preventing permanent gate failure. - Replace explicit struct instantiations in runtime_client.go with semver.MustParse() for cleaner and more robust version comparisons.
1 parent d4031a3 commit e97ca02

8 files changed

Lines changed: 111 additions & 189 deletions

File tree

.aspell.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ allowed:
115115
- ioutil
116116
- ipam
117117
- istanbul
118+
- instantiations
118119
- iweight
119120
- jose
120121
- json

cmd/gitlab-mr-checker/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import (
3131
"strings"
3232
"time"
3333

34-
"github.com/Masterminds/semver"
34+
"github.com/Masterminds/semver/v3"
3535
"github.com/joho/godotenv"
3636
)
3737

@@ -164,7 +164,7 @@ func main() {
164164
"backport-ee": {},
165165
}
166166
for _, version := range versions {
167-
ver := strconv.Itoa(int(version.Major())) + "." + strconv.Itoa(int(version.Minor()))
167+
ver := strconv.FormatUint(version.Major(), 10) + "." + strconv.FormatUint(version.Minor(), 10)
168168
question += "\n" + "| " + ver + " | " + "backport-" + ver + " |"
169169
backportLabels["backport-"+ver] = struct{}{}
170170
}

e2e/runtime/version/version_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ func (s *MajorVersionInRuntime) TestExample() {
3030
if err != nil {
3131
s.FailNow(err.Error())
3232
}
33-
versionStr := fmt.Sprintf("%d.%d", version.Major, version.Minor)
33+
versionStr := fmt.Sprintf("%d.%d", version.Major(), version.Minor())
3434
s.Equal(versionStr, s.haproxy_version)
3535
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/haproxytech/client-native/v6
33
go 1.25.0
44

55
require (
6-
github.com/Masterminds/semver v1.5.0
6+
github.com/Masterminds/semver/v3 v3.5.0
77
github.com/go-faker/faker/v4 v4.7.0
88
github.com/go-openapi/errors v0.22.7
99
github.com/go-openapi/strfmt v0.25.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
2-
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
1+
github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE=
2+
github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
33
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
44
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
55
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

runtime/runtime_client.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"path/filepath"
2525
"strings"
2626

27+
"github.com/Masterminds/semver/v3"
2728
native_errors "github.com/haproxytech/client-native/v6/errors"
2829
"github.com/haproxytech/client-native/v6/misc"
2930
"github.com/haproxytech/client-native/v6/models"
@@ -173,7 +174,12 @@ func (c *client) Reload() (string, error) {
173174
if c.options.MasterSocketData == nil {
174175
return "", errors.New("cannot reload: not connected to a master socket")
175176
}
176-
if !c.IsVersionBiggerOrEqual(&HAProxyVersion{Major: 2, Minor: 7}) {
177+
// Init-time version probe is fire-and-forget; retry here so a transient
178+
// startup failure doesn't permanently disable the gate.
179+
if haproxyVersion == nil {
180+
_, _ = c.GetVersion()
181+
}
182+
if !c.IsVersionBiggerOrEqual(&HAProxyVersion{Version: semver.MustParse("2.7")}) {
177183
return "", fmt.Errorf("cannot reload: requires HAProxy 2.7 or later but current version is %v", haproxyVersion)
178184
}
179185

@@ -252,7 +258,7 @@ func (c *client) AddServer(backend, name, attributes string) error {
252258
if !c.runtime.IsValid() {
253259
return errors.New("no valid runtime found")
254260
}
255-
if !c.IsVersionBiggerOrEqual(&HAProxyVersion{Major: 2, Minor: 6}) {
261+
if !c.IsVersionBiggerOrEqual(&HAProxyVersion{Version: semver.MustParse("2.6")}) {
256262
return fmt.Errorf("this operation requires HAProxy 2.6 or later but current version is %v", haproxyVersion)
257263
}
258264
err := c.runtime.AddServer(backend, name, attributes)
@@ -267,7 +273,7 @@ func (c *client) DeleteServer(backend, name string) error {
267273
if !c.runtime.IsValid() {
268274
return errors.New("no valid runtime found")
269275
}
270-
if !c.IsVersionBiggerOrEqual(&HAProxyVersion{Major: 2, Minor: 6}) {
276+
if !c.IsVersionBiggerOrEqual(&HAProxyVersion{Version: semver.MustParse("2.6")}) {
271277
return errors.New("this operation requires HAProxy 2.6 or later")
272278
}
273279
err := c.runtime.DeleteServer(backend, name)
@@ -734,7 +740,7 @@ func (c *client) AddMapPayloadVersioned(name string, entries models.MapEntries)
734740
return fmt.Errorf("%s %w", c.runtime.socketPath, err)
735741
}
736742
canAtomicUpdate := false
737-
v := HAProxyVersion{Major: 2, Minor: 4}
743+
v := HAProxyVersion{Version: semver.MustParse("2.4")}
738744
if c.IsVersionBiggerOrEqual(&v) {
739745
canAtomicUpdate = true
740746
}
@@ -976,7 +982,7 @@ func (c *client) AddACLAtomic(aclID string, entries models.ACLFilesEntries) erro
976982
if !c.runtime.IsValid() {
977983
return errors.New("no valid runtime found")
978984
}
979-
v := HAProxyVersion{Major: 2, Minor: 4}
985+
v := HAProxyVersion{Version: semver.MustParse("2.4")}
980986
if !c.IsVersionBiggerOrEqual(&v) {
981987
return fmt.Errorf("not supported for HAProxy versions lower than 2.4 %w", native_errors.ErrGeneral)
982988
}

runtime/version.go

Lines changed: 21 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -16,66 +16,42 @@
1616
package runtime
1717

1818
import (
19-
"fmt"
20-
"strconv"
2119
"strings"
20+
21+
"github.com/Masterminds/semver/v3"
2222
)
2323

2424
type HAProxyVersion struct {
25-
Commit string
26-
Version string
27-
Major int
28-
Minor int
29-
Patch int
25+
*semver.Version
26+
27+
Commit string
3028
}
3129

3230
func (v *HAProxyVersion) ParseHAProxyVersion(version string) error {
33-
v.Version = version
34-
35-
parts := strings.SplitN(version, "-", 2)
36-
data := strings.SplitN(parts[0], ".", 3)
37-
major, err := strconv.Atoi(data[0])
38-
if err == nil {
39-
v.Major = major
40-
}
41-
if len(data) > 1 {
42-
minor, err := strconv.Atoi(data[1])
43-
if err == nil {
44-
v.Minor = minor
45-
}
46-
}
47-
if len(data) > 2 {
48-
patch, err := strconv.Atoi(data[2])
49-
if err == nil {
50-
v.Patch = patch
31+
sv, err := semver.NewVersion(version)
32+
if err != nil {
33+
return err
34+
}
35+
v.Version = sv
36+
// Commit lives in the prerelease tail: "dev6-2f6f36-13" → "2f6f36",
37+
// "a42e6c-11" → "a42e6c", "34b2b10" → "34b2b10".
38+
if pre := sv.Prerelease(); pre != "" {
39+
parts := strings.Split(pre, "-")
40+
if len(parts) < 2 {
41+
v.Commit = parts[0]
42+
} else {
43+
v.Commit = parts[len(parts)-2]
5144
}
5245
}
53-
if len(parts) < 2 {
54-
return fmt.Errorf("version is not in correct format [%s]", version)
55-
}
56-
data = strings.Split(parts[1], "-")
57-
if len(data) < 2 {
58-
v.Commit = data[0]
59-
} else {
60-
v.Commit = data[len(data)-2]
61-
}
6246
return nil
6347
}
6448

6549
func IsBiggerOrEqual(minimum, current *HAProxyVersion) bool {
66-
if current == nil {
50+
if current == nil || current.Version == nil {
6751
return false
6852
}
69-
if current.Major > minimum.Major {
53+
if minimum == nil || minimum.Version == nil {
7054
return true
7155
}
72-
if current.Major == minimum.Major {
73-
switch {
74-
case current.Minor > minimum.Minor:
75-
return true
76-
case current.Minor == minimum.Minor:
77-
return current.Patch >= minimum.Patch
78-
}
79-
}
80-
return false
56+
return current.GreaterThanEqual(minimum.Version)
8157
}

0 commit comments

Comments
 (0)