Skip to content

Commit 021ffac

Browse files
Nikolas De Giorgischatton
andauthored
Changed FCV handling when upgrading (#412)
Co-authored-by: Cian Hatton <cianhatton@gmail.com>
1 parent 57e37ba commit 021ffac

File tree

9 files changed

+86
-52
lines changed

9 files changed

+86
-52
lines changed

api/v1/mongodbcommunity_types.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -483,18 +483,6 @@ func (m MongoDBCommunity) GetAgentScramCredentialsNamespacedName() types.Namespa
483483
return types.NamespacedName{Name: fmt.Sprintf("%s-agent-scram-credentials", m.Name), Namespace: m.Namespace}
484484
}
485485

486-
// GetFCV returns the feature compatibility version. If no FeatureCompatibilityVersion is specified.
487-
// It uses the major and minor version for whichever version of MongoDB is configured.
488-
func (m MongoDBCommunity) GetFCV() string {
489-
versionToSplit := m.Spec.FeatureCompatibilityVersion
490-
if versionToSplit == "" {
491-
versionToSplit = m.Spec.Version
492-
}
493-
minorIndex := 1
494-
parts := strings.Split(versionToSplit, ".")
495-
return strings.Join(parts[:minorIndex+1], ".")
496-
}
497-
498486
func (m MongoDBCommunity) DesiredReplicas() int {
499487
return m.Spec.Members
500488
}

api/v1/mongodbcommunity_types_test.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,6 @@ func TestMongoDB_MongoURI(t *testing.T) {
1616
assert.Equal(t, mdb.MongoURI(), "mongodb://my-big-rs-0.my-big-rs-svc.my-big-namespace.svc.cluster.local:27017,my-big-rs-1.my-big-rs-svc.my-big-namespace.svc.cluster.local:27017,my-big-rs-2.my-big-rs-svc.my-big-namespace.svc.cluster.local:27017,my-big-rs-3.my-big-rs-svc.my-big-namespace.svc.cluster.local:27017,my-big-rs-4.my-big-rs-svc.my-big-namespace.svc.cluster.local:27017")
1717
}
1818

19-
func TestGetFCV(t *testing.T) {
20-
mdb := newReplicaSet(3, "my-rs", "my-ns")
21-
mdb.Spec.Version = "4.2.0"
22-
assert.Equal(t, "4.2", mdb.GetFCV())
23-
24-
mdb.Spec.FeatureCompatibilityVersion = "4.0"
25-
assert.Equal(t, "4.0", mdb.GetFCV())
26-
27-
mdb.Spec.FeatureCompatibilityVersion = ""
28-
assert.Equal(t, "4.2", mdb.GetFCV())
29-
}
30-
3119
func TestGetScramCredentialsSecretName(t *testing.T) {
3220
testusers := []struct {
3321
in MongoDBUser

controllers/replica_set_controller.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,6 @@ func buildAutomationConfig(mdb mdbv1.MongoDBCommunity, auth automationconfig.Aut
413413
domain := getDomain(mdb.ServiceName(), mdb.Namespace, os.Getenv(clusterDNSName))
414414
zap.S().Debugw("AutomationConfigMembersThisReconciliation", "mdb.AutomationConfigMembersThisReconciliation()", mdb.AutomationConfigMembersThisReconciliation())
415415

416-
fcv := mdb.GetFCV()
417416
return automationconfig.NewBuilder().
418417
SetTopology(automationconfig.ReplicaSetTopology).
419418
SetName(mdb.Name).
@@ -422,7 +421,7 @@ func buildAutomationConfig(mdb mdbv1.MongoDBCommunity, auth automationconfig.Aut
422421
SetReplicaSetHorizons(mdb.Spec.ReplicaSetHorizons).
423422
SetPreviousAutomationConfig(currentAc).
424423
SetMongoDBVersion(mdb.Spec.Version).
425-
SetFCV(&fcv).
424+
SetFCV(mdb.Spec.FeatureCompatibilityVersion).
426425
SetOptions(automationconfig.Options{DownloadBase: "/var/lib/mongodb-mms-automation"}).
427426
SetAuth(auth).
428427
AddModifications(getMongodConfigModification(mdb)).

controllers/replicaset_controller_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,32 @@ func TestAutomationConfig_versionIsNotBumpedWithNoChanges(t *testing.T) {
306306
assert.Equal(t, currentAc.Version, 1)
307307
}
308308

309+
func TestAutomationConfigFCVIsNotIncreasedWhenUpgradingMinorVersion(t *testing.T) {
310+
mdb := newTestReplicaSet()
311+
mgr := client.NewManager(&mdb)
312+
r := NewReconciler(mgr)
313+
res, err := r.Reconcile(context.TODO(), reconcile.Request{NamespacedName: types.NamespacedName{Namespace: mdb.Namespace, Name: mdb.Name}})
314+
assertReconciliationSuccessful(t, res, err)
315+
316+
currentAc, err := automationconfig.ReadFromSecret(mgr.Client, types.NamespacedName{Name: mdb.AutomationConfigSecretName(), Namespace: mdb.Namespace})
317+
assert.NoError(t, err)
318+
assert.Len(t, currentAc.Processes, 3)
319+
assert.Equal(t, currentAc.Processes[0].FeatureCompatibilityVersion, "4.2")
320+
321+
// Upgrading minor version does not change the FCV on the automationConfig
322+
mdbRef := &mdb
323+
mdbRef.Spec.Version = "4.4.0"
324+
_ = mgr.Client.Update(context.TODO(), mdbRef)
325+
res, err = r.Reconcile(context.TODO(), reconcile.Request{NamespacedName: types.NamespacedName{Namespace: mdb.Namespace, Name: mdb.Name}})
326+
assertReconciliationSuccessful(t, res, err)
327+
328+
currentAc, err = automationconfig.ReadFromSecret(mgr.Client, types.NamespacedName{Name: mdb.AutomationConfigSecretName(), Namespace: mdb.Namespace})
329+
assert.NoError(t, err)
330+
assert.Len(t, currentAc.Processes, 3)
331+
assert.Equal(t, currentAc.Processes[0].FeatureCompatibilityVersion, "4.2")
332+
333+
}
334+
309335
func TestAutomationConfig_CustomMongodConfig(t *testing.T) {
310336
mdb := newTestReplicaSet()
311337

dev_notes/RELEASE_NOTES.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
*(Please use the [release template](release-notes-template.md) as the template for this document)*
22
<!-- Next release -->
3+
# MongoDB Kubernetes Operator 0.5.3
4+
## Kubernetes Operator
5+
* Bug fixes
6+
* Fixes an issue that prevented the agents from reaching goal state when upgrading minor version of MongoDB.
37

8+
<!-- Past Releases -->
49
# MongoDB Kubernetes Operator 0.5.2
510
## Kubernetes Operator
611
* Changes
712
* Readiness probe has been moved into an init container from the Agent image.
8-
* Security context is now added when the `MANAGED_SECURITY_CONTEXT` environment variable is not set.
13+
* Security context is now added when the `MANAGED_SECURITY_CONTEXT` environment variable is not set.
914
* Bug fixes
1015
* Removed unnecessary environment variable configuration in the openshift samples.
1116
* Fixed an issue where the operator would perform unnecessary reconcilliations when Secrets were modified.
@@ -15,18 +20,16 @@
1520

1621
## MongoDBCommunity Resource
1722
* Changes
18-
* Added `spec.security.authentication.ignoreUnknownUsers` field. This value defaults to `true`. When enabled,
23+
* Added `spec.security.authentication.ignoreUnknownUsers` field. This value defaults to `true`. When enabled,
1924
any MongoDB users added through external sources will not be removed.
20-
21-
25+
26+
2227
## Miscellaneous
2328
* Changes
2429
* Internal code refactorings to allow libraries to be imported into other projects.
25-
26-
30+
31+
2732
## Updated Image Tags
2833
* mongodb-kubernetes-operator:0.5.2
2934
* mongodb-agent:10.27.0.6772-1
3035
* mongodb-kubernetes-readinessprobe:1.0.1 [new image]
31-
32-
<!-- Past Releases -->

pkg/automationconfig/automation_config_builder.go

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"path"
66

7+
"github.com/blang/semver"
78
"github.com/pkg/errors"
89

910
"github.com/mongodb/mongodb-kubernetes-operator/pkg/util/versions"
@@ -29,7 +30,7 @@ type Builder struct {
2930
members int
3031
domain string
3132
name string
32-
fcv *string
33+
fcv string
3334
topology Topology
3435
mongodbVersion string
3536
previousAC AutomationConfig
@@ -100,7 +101,7 @@ func (b *Builder) SetName(name string) *Builder {
100101
return b
101102
}
102103

103-
func (b *Builder) SetFCV(fcv *string) *Builder {
104+
func (b *Builder) SetFCV(fcv string) *Builder {
104105
b.fcv = fcv
105106
return b
106107
}
@@ -155,6 +156,33 @@ func (b *Builder) AddModifications(mod ...Modification) *Builder {
155156
return b
156157
}
157158

159+
func (b *Builder) setFeatureCompatibilityVersionIfUpgradeIsHappening() error {
160+
// If we are upgrading, we can't increase featureCompatibilityVersion
161+
// as that will make the agent never reach goal state
162+
if len(b.previousAC.Processes) > 0 && b.fcv == "" {
163+
164+
// Create a x.y.0 version from FCV x.y
165+
previousFCV := b.previousAC.Processes[0].FeatureCompatibilityVersion
166+
previousFCVsemver, err := semver.Make(fmt.Sprintf("%s.0", previousFCV))
167+
if err != nil {
168+
return errors.Errorf("can't compute semver version from previous FeatureCompatibilityVersion %s", previousFCV)
169+
}
170+
171+
currentVersionSemver, err := semver.Make(b.mongodbVersion)
172+
if err != nil {
173+
return errors.Errorf("current MongoDB version is not a valid semver version: %s", b.mongodbVersion)
174+
}
175+
176+
// We would increase FCV here.
177+
// Note: in theory this will also catch upgrade like 4.2.0 -> 4.2.1 but we don't care about those
178+
// as they would not change the FCV
179+
if currentVersionSemver.GT(previousFCVsemver) {
180+
b.fcv = previousFCV
181+
}
182+
}
183+
return nil
184+
}
185+
158186
func (b *Builder) Build() (AutomationConfig, error) {
159187
hostnames := make([]string, b.members)
160188
for i := 0; i < b.members; i++ {
@@ -163,6 +191,10 @@ func (b *Builder) Build() (AutomationConfig, error) {
163191

164192
members := make([]ReplicaSetMember, b.members)
165193
processes := make([]Process, b.members)
194+
195+
if err := b.setFeatureCompatibilityVersionIfUpgradeIsHappening(); err != nil {
196+
return AutomationConfig{}, errors.Errorf("can't build the automation config: %s", err)
197+
}
166198
for i, h := range hostnames {
167199

168200
process := &Process{
@@ -178,8 +210,8 @@ func (b *Builder) Build() (AutomationConfig, error) {
178210
Path: path.Join(DefaultAgentLogPath, "/mongodb.log"),
179211
})
180212

181-
if b.fcv != nil {
182-
process.FeatureCompatibilityVersion = *b.fcv
213+
if b.fcv != "" {
214+
process.FeatureCompatibilityVersion = b.fcv
183215
}
184216

185217
process.SetPort(27017)

pkg/automationconfig/automation_config_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,12 @@ func defaultMongoDbVersion(version string) MongoDbVersionConfig {
2525
}
2626

2727
func TestBuildAutomationConfig(t *testing.T) {
28-
fcv := "4.0"
2928
ac, err := NewBuilder().
3029
SetName("my-rs").
3130
SetDomain("my-ns.svc.cluster.local").
3231
SetMongoDBVersion("4.2.0").
3332
SetMembers(3).
34-
SetFCV(&fcv).
33+
SetFCV("4.0").
3534
Build()
3635

3736
assert.NoError(t, err)

test/e2e/e2eutil.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,9 @@ func NewTestMongoDB(name string, namespace string) (mdbv1.MongoDBCommunity, mdbv
153153
Namespace: mongodbNamespace,
154154
},
155155
Spec: mdbv1.MongoDBCommunitySpec{
156-
Members: 3,
157-
Type: "ReplicaSet",
158-
Version: "4.4.0",
159-
FeatureCompatibilityVersion: "4.4",
156+
Members: 3,
157+
Type: "ReplicaSet",
158+
Version: "4.4.0",
160159
Security: mdbv1.Security{
161160
Authentication: mdbv1.Authentication{
162161
Modes: []mdbv1.AuthMode{"SCRAM"},

test/e2e/replica_set_change_version/replica_set_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func TestReplicaSetUpgradeVersion(t *testing.T) {
3232
}
3333

3434
mdb, user := e2eutil.NewTestMongoDB("mdb0", "")
35-
mdb.Spec.Version = "4.4.0"
35+
mdb.Spec.Version = "4.2.0"
3636

3737
_, err := setup.GeneratePasswordForUser(user, ctx, "")
3838
if err != nil {
@@ -50,23 +50,23 @@ func TestReplicaSetUpgradeVersion(t *testing.T) {
5050
t.Run("AutomationConfig has the correct version", mongodbtests.AutomationConfigVersionHasTheExpectedVersion(&mdb, 1))
5151
t.Run("Ensure Authentication", tester.EnsureAuthenticationIsConfigured(3))
5252

53-
// Upgrade version to 4.4.1
54-
t.Run("MongoDB is reachable while version is upgraded", func(t *testing.T) {
53+
// Upgrade minor version to 4.4.0
54+
t.Run("MongoDB is reachable while minor version is upgraded", func(t *testing.T) {
5555
defer tester.StartBackgroundConnectivityTest(t, time.Second*10)()
56-
t.Run("Test Version can be upgraded", mongodbtests.ChangeVersion(&mdb, "4.4.1"))
56+
t.Run("Test Minor Version can be upgraded", mongodbtests.ChangeVersion(&mdb, "4.4.0"))
5757
t.Run("StatefulSet has OnDelete update strategy", mongodbtests.StatefulSetHasUpdateStrategy(&mdb, appsv1.OnDeleteStatefulSetStrategyType))
5858
t.Run("Stateful Set Reaches Ready State, after Upgrading", mongodbtests.StatefulSetBecomesReady(&mdb))
5959
t.Run("AutomationConfig's version has been increased", mongodbtests.AutomationConfigVersionHasTheExpectedVersion(&mdb, 2))
6060
})
6161

6262
t.Run("StatefulSet has RollingUpgrade restart strategy", mongodbtests.StatefulSetHasUpdateStrategy(&mdb, appsv1.RollingUpdateStatefulSetStrategyType))
6363

64-
// Downgrade version back to 4.4.0
65-
t.Run("MongoDB is reachable while version is downgraded", func(t *testing.T) {
64+
// Upgrade patch version to 4.4.1
65+
t.Run("MongoDB is reachable while patch version is upgraded", func(t *testing.T) {
6666
defer tester.StartBackgroundConnectivityTest(t, time.Second*10)()
67-
t.Run("Test Version can be downgraded", mongodbtests.ChangeVersion(&mdb, "4.4.0"))
67+
t.Run("Test Patch Version can be upgraded", mongodbtests.ChangeVersion(&mdb, "4.4.1"))
6868
t.Run("StatefulSet has OnDelete restart strategy", mongodbtests.StatefulSetHasUpdateStrategy(&mdb, appsv1.OnDeleteStatefulSetStrategyType))
69-
t.Run("Stateful Set Reaches Ready State, after downgrading", mongodbtests.StatefulSetBecomesReady(&mdb))
69+
t.Run("Stateful Set Reaches Ready State, after upgrading", mongodbtests.StatefulSetBecomesReady(&mdb))
7070
t.Run("AutomationConfig's version has been increased", mongodbtests.AutomationConfigVersionHasTheExpectedVersion(&mdb, 3))
7171
})
7272
t.Run("StatefulSet has RollingUpgrade restart strategy", mongodbtests.StatefulSetHasUpdateStrategy(&mdb, appsv1.RollingUpdateStatefulSetStrategyType))

0 commit comments

Comments
 (0)