Skip to content

Commit a201701

Browse files
committed
mention v7.0 in message
1 parent dfd6641 commit a201701

File tree

1 file changed

+276
-0
lines changed

1 file changed

+276
-0
lines changed

internal/version/version.go

Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
package version
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
"runtime"
8+
9+
"go.mongodb.org/mongo-driver/bson"
10+
"go.mongodb.org/mongo-driver/mongo"
11+
"golang.org/x/mod/semver"
12+
13+
"github.com/percona/percona-backup-mongodb/internal/defs"
14+
"github.com/percona/percona-backup-mongodb/internal/errors"
15+
)
16+
17+
// current PBM version
18+
const version = "2.3.0-next"
19+
20+
var (
21+
platform string
22+
gitCommit string
23+
gitBranch string
24+
buildTime string
25+
)
26+
27+
type Info struct { //nolint:musttag
28+
Version string
29+
Platform string
30+
GitCommit string
31+
GitBranch string
32+
BuildTime string
33+
GoVersion string
34+
}
35+
36+
const plain = `Version: %s
37+
Platform: %s
38+
GitCommit: %s
39+
GitBranch: %s
40+
BuildTime: %s
41+
GoVersion: %s`
42+
43+
func Current() Info {
44+
v := Info{
45+
Version: version,
46+
Platform: platform,
47+
GitCommit: gitCommit,
48+
GitBranch: gitBranch,
49+
BuildTime: buildTime,
50+
GoVersion: runtime.Version(),
51+
}
52+
if v.Platform == "" {
53+
v.Platform = fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
54+
}
55+
56+
return v
57+
}
58+
59+
func (i Info) String() string {
60+
return fmt.Sprintf(plain,
61+
i.Version,
62+
i.Platform,
63+
i.GitCommit,
64+
i.GitBranch,
65+
i.BuildTime,
66+
i.GoVersion,
67+
)
68+
}
69+
70+
func (i Info) Short() string {
71+
return i.Version
72+
}
73+
74+
func (i Info) All(format string) string {
75+
switch format {
76+
case "":
77+
return fmt.Sprintf(plain,
78+
i.Version,
79+
i.Platform,
80+
i.GitCommit,
81+
i.GitBranch,
82+
i.BuildTime,
83+
i.GoVersion,
84+
)
85+
case "json":
86+
v, _ := json.MarshalIndent(i, "", " ") //nolint:errchkjson
87+
return string(v)
88+
default:
89+
return fmt.Sprintf("%#v", i)
90+
}
91+
}
92+
93+
// CompatibleWith checks if a given version is compatible the current one. It
94+
// is not compatible if the current is crossed the breaking ponit
95+
// (version >= breakingVersion) and the given isn't (v < breakingVersion)
96+
func CompatibleWith(v string, breakingv []string) bool {
97+
return compatible(version, v, breakingv)
98+
}
99+
100+
func compatible(v1, v2 string, breakingv []string) bool {
101+
if len(breakingv) == 0 {
102+
return true
103+
}
104+
105+
v1 = majmin(v1)
106+
v2 = majmin(v2)
107+
108+
c := semver.Compare(v2, v1)
109+
if c == 0 {
110+
return true
111+
}
112+
113+
hV, lV := v1, v2
114+
if c == 1 {
115+
hV, lV = lV, hV
116+
}
117+
118+
for i := len(breakingv) - 1; i >= 0; i-- {
119+
cb := majmin(breakingv[i])
120+
if semver.Compare(hV, cb) >= 0 {
121+
return semver.Compare(lV, cb) >= 0
122+
}
123+
}
124+
125+
return true
126+
}
127+
128+
func majmin(v string) string {
129+
if len(v) == 0 {
130+
return v
131+
}
132+
133+
if v[0] != 'v' {
134+
v = "v" + v
135+
}
136+
137+
return semver.MajorMinor(v)
138+
}
139+
140+
func IsLegacyArchive(ver string) bool {
141+
return semver.Compare(majmin(ver), "v2.0") == -1
142+
}
143+
144+
// BreakingChangesMap map of versions introduced breaking changes to respective
145+
// backup defs.
146+
// !!! Versions should be sorted in the ascending order.
147+
var BreakingChangesMap = map[defs.BackupType][]string{
148+
defs.LogicalBackup: {"1.5.0"},
149+
defs.IncrementalBackup: {"2.1.0"},
150+
defs.PhysicalBackup: {},
151+
}
152+
153+
type MongoVersion struct {
154+
PSMDBVersion string `bson:"psmdbVersion,omitempty"`
155+
VersionString string `bson:"version"`
156+
Version []int `bson:"versionArray"`
157+
}
158+
159+
func (v MongoVersion) Major() int {
160+
if len(v.Version) == 0 {
161+
return 0
162+
}
163+
164+
return v.Version[0]
165+
}
166+
167+
func GetMongoVersion(ctx context.Context, m *mongo.Client) (MongoVersion, error) {
168+
res := m.Database("admin").RunCommand(ctx, bson.D{{"buildInfo", 1}})
169+
if err := res.Err(); err != nil {
170+
return MongoVersion{}, err
171+
}
172+
173+
var ver MongoVersion
174+
if err := res.Decode(&ver); err != nil {
175+
return MongoVersion{}, err
176+
}
177+
178+
return ver, nil
179+
}
180+
181+
type FeatureSupport MongoVersion
182+
183+
func (f FeatureSupport) PBMSupport() error {
184+
v := MongoVersion(f)
185+
186+
if v.Version[0] == 4 && v.Version[1] == 4 {
187+
return nil
188+
}
189+
190+
if (v.Version[0] == 5 || v.Version[0] == 6) && v.Version[1] == 0 {
191+
return nil
192+
}
193+
194+
return errors.New("Unsupported MongoDB version. PBM works with v4.4, v5.0, v6.0, v7.0")
195+
}
196+
197+
func (f FeatureSupport) FullPhysicalBackup() bool {
198+
// PSMDB 4.2.15, 4.4.6
199+
v := MongoVersion(f)
200+
if v.PSMDBVersion == "" {
201+
return false
202+
}
203+
204+
switch {
205+
case v.Version[0] == 4 && v.Version[1] == 2 && v.Version[2] >= 15:
206+
fallthrough
207+
case v.Version[0] == 4 && v.Version[1] == 4 && v.Version[2] >= 6:
208+
fallthrough
209+
case v.Version[0] >= 5:
210+
return true
211+
}
212+
213+
return false
214+
}
215+
216+
func (f FeatureSupport) IncrementalPhysicalBackup() bool {
217+
// PSMDB 4.2.24, 4.4.18, 5.0.14, 6.0.3
218+
v := MongoVersion(f)
219+
if v.PSMDBVersion == "" {
220+
return false
221+
}
222+
223+
switch {
224+
case v.Version[0] == 4 && v.Version[1] == 2 && v.Version[2] >= 24:
225+
fallthrough
226+
case v.Version[0] == 4 && v.Version[1] == 4 && v.Version[2] >= 18:
227+
fallthrough
228+
case v.Version[0] == 5 && v.Version[1] == 0 && v.Version[2] >= 14:
229+
fallthrough
230+
case v.Version[0] == 6 && v.Version[1] == 0 && v.Version[2] >= 3:
231+
fallthrough
232+
case v.Version[0] >= 7:
233+
return true
234+
}
235+
236+
return false
237+
}
238+
239+
func (f FeatureSupport) BackupType(t defs.BackupType) error {
240+
switch t {
241+
case defs.PhysicalBackup:
242+
if !f.FullPhysicalBackup() {
243+
return errors.New("full physical backup works since " +
244+
"Percona Server for MongoDB 4.2.15, 4.4.6")
245+
}
246+
case defs.IncrementalBackup:
247+
if !f.IncrementalPhysicalBackup() {
248+
return errors.New("incremental physical backup works since " +
249+
"Percona Server for MongoDB 4.2.24, 4.4.18, 5.0.14, 6.0.3")
250+
}
251+
case defs.ExternalBackup:
252+
if !f.FullPhysicalBackup() {
253+
return errors.New("external backup works since " +
254+
"Percona Server for MongoDB 4.2.15, 4.4.6")
255+
}
256+
}
257+
258+
return nil
259+
}
260+
261+
func GetFCV(ctx context.Context, m *mongo.Client) (string, error) {
262+
res := m.Database("admin").RunCommand(ctx, bson.D{
263+
{"getParameter", 1},
264+
{"featureCompatibilityVersion", 1},
265+
})
266+
if err := res.Err(); err != nil {
267+
return "", errors.Wrap(err, "query")
268+
}
269+
270+
var ver struct{ FeatureCompatibilityVersion struct{ Version string } }
271+
if err := res.Decode(&ver); err != nil {
272+
return "", errors.Wrap(err, "decode")
273+
}
274+
275+
return ver.FeatureCompatibilityVersion.Version, nil
276+
}

0 commit comments

Comments
 (0)