Skip to content

Commit c34fd83

Browse files
committed
Add SystemGeneration to channel version tracker
This allows us to reapply a manifest when we introduce new functionality, such as pruning. Otherwise an old version can apply the manifest, mark the manifest as applied, and we won't reapply.
1 parent 7eda9a4 commit c34fd83

File tree

6 files changed

+66
-25
lines changed

6 files changed

+66
-25
lines changed

channels/pkg/api/channel.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ type AddonSpec struct {
4646
// Manifest is the URL to the manifest that should be applied
4747
Manifest *string `json:"manifest,omitempty"`
4848

49-
// Manifesthash is the sha256 hash of our manifest
49+
// ManifestHash is the sha256 hash of our manifest
5050
ManifestHash string `json:"manifestHash,omitempty"`
5151

5252
// KubernetesVersion is a semver version range on which this version of the addon can be applied

channels/pkg/channels/addon.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func (m *AddonMenu) MergeAddons(o *AddonMenu) {
7373
if existing == nil {
7474
m.Addons[k] = v
7575
} else {
76-
if v.ChannelVersion().replaces(existing.ChannelVersion()) {
76+
if v.ChannelVersion().replaces(k, existing.ChannelVersion()) {
7777
m.Addons[k] = v
7878
}
7979
}
@@ -82,9 +82,10 @@ func (m *AddonMenu) MergeAddons(o *AddonMenu) {
8282

8383
func (a *Addon) ChannelVersion() *ChannelVersion {
8484
return &ChannelVersion{
85-
Channel: &a.ChannelName,
86-
Id: a.Spec.Id,
87-
ManifestHash: a.Spec.ManifestHash,
85+
Channel: &a.ChannelName,
86+
Id: a.Spec.Id,
87+
ManifestHash: a.Spec.ManifestHash,
88+
SystemGeneration: CurrentSystemGeneration,
8889
}
8990
}
9091

@@ -120,7 +121,7 @@ func (a *Addon) GetRequiredUpdates(ctx context.Context, k8sClient kubernetes.Int
120121
}
121122
}
122123

123-
if existingVersion != nil && !newVersion.replaces(existingVersion) {
124+
if existingVersion != nil && !newVersion.replaces(a.Name, existingVersion) {
124125
newVersion = nil
125126
}
126127

channels/pkg/channels/addons.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func (a *Addons) GetCurrent(kubernetesVersion semver.Version) (*AddonMenu, error
7474
name := addon.Name
7575

7676
existing := menu.Addons[name]
77-
if existing == nil || addon.ChannelVersion().replaces(existing.ChannelVersion()) {
77+
if existing == nil || addon.ChannelVersion().replaces(name, existing.ChannelVersion()) {
7878
menu.Addons[name] = addon
7979
}
8080
}

channels/pkg/channels/addons_test.go

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,30 +85,48 @@ func Test_Filtering(t *testing.T) {
8585
}
8686

8787
func Test_Replacement(t *testing.T) {
88+
hash1 := "3544de6578b2b582c0323b15b7b05a28c60b9430"
89+
hash2 := "ea9e79bf29adda450446487d65a8fc6b3fdf8c2b"
90+
8891
grid := []struct {
8992
Old *ChannelVersion
9093
New *ChannelVersion
9194
Replaces bool
9295
}{
9396
//Test ManifestHash Changes
9497
{
95-
Old: &ChannelVersion{Id: "a", ManifestHash: "3544de6578b2b582c0323b15b7b05a28c60b9430"},
96-
New: &ChannelVersion{Id: "a", ManifestHash: "3544de6578b2b582c0323b15b7b05a28c60b9430"},
98+
Old: &ChannelVersion{Id: "a", ManifestHash: hash1},
99+
New: &ChannelVersion{Id: "a", ManifestHash: hash1},
97100
Replaces: false,
98101
},
99102
{
100103
Old: &ChannelVersion{Id: "a", ManifestHash: ""},
101-
New: &ChannelVersion{Id: "a", ManifestHash: "3544de6578b2b582c0323b15b7b05a28c60b9430"},
104+
New: &ChannelVersion{Id: "a", ManifestHash: hash1},
102105
Replaces: true,
103106
},
104107
{
105-
Old: &ChannelVersion{Id: "a", ManifestHash: "3544de6578b2b582c0323b15b7b05a28c60b9430"},
106-
New: &ChannelVersion{Id: "a", ManifestHash: "ea9e79bf29adda450446487d65a8fc6b3fdf8c2b"},
108+
Old: &ChannelVersion{Id: "a", ManifestHash: hash1},
109+
New: &ChannelVersion{Id: "a", ManifestHash: hash2},
107110
Replaces: true,
108111
},
112+
{
113+
Old: &ChannelVersion{Id: "a", ManifestHash: hash1},
114+
New: &ChannelVersion{Id: "a", ManifestHash: hash1, SystemGeneration: 1},
115+
Replaces: true,
116+
},
117+
{
118+
Old: &ChannelVersion{Id: "a", ManifestHash: hash1, SystemGeneration: 1},
119+
New: &ChannelVersion{Id: "a", ManifestHash: hash1},
120+
Replaces: false,
121+
},
122+
{
123+
Old: &ChannelVersion{Id: "a", ManifestHash: hash1, SystemGeneration: 1},
124+
New: &ChannelVersion{Id: "a", ManifestHash: hash1, SystemGeneration: 1},
125+
Replaces: false,
126+
},
109127
}
110128
for _, g := range grid {
111-
actual := g.New.replaces(g.Old)
129+
actual := g.New.replaces(t.Name(), g.Old)
112130
if actual != g.Replaces {
113131
t.Errorf("unexpected result from %v -> %v, expect %t. actual %v", g.Old, g.New, g.Replaces, actual)
114132
}
@@ -218,7 +236,7 @@ func Test_NeedsRollingUpdate(t *testing.T) {
218236
ctx := context.Background()
219237

220238
annotations := map[string]string{
221-
"addons.k8s.io/test": "{\"manifestHash\":\"originalHash\"}",
239+
"addons.k8s.io/test": "{\"manifestHash\":\"originalHash\",\"systemGeneration\": 1}",
222240
}
223241
if len(g.originalAnnotations) > 0 {
224242
annotations = g.originalAnnotations

channels/pkg/channels/channel_version.go

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"context"
2121
"encoding/json"
2222
"fmt"
23+
"strconv"
2324
"strings"
2425

2526
certmanager "github.com/jetstack/cert-manager/pkg/client/clientset/versioned"
@@ -38,10 +39,20 @@ type Channel struct {
3839
Name string
3940
}
4041

42+
// CurrentSystemGeneration holds our current SystemGeneration value.
43+
// Version history:
44+
// 0 Pre-history (and the default value); versions prior to prune.
45+
// 1 Prune functionality introduced.
46+
const CurrentSystemGeneration = 1
47+
4148
type ChannelVersion struct {
4249
Channel *string `json:"channel,omitempty"`
4350
Id string `json:"id,omitempty"`
4451
ManifestHash string `json:"manifestHash,omitempty"`
52+
53+
// SystemGeneration holds the generation of the channels functionality.
54+
// It is used so that we reapply when we introduce new features, such as prune.
55+
SystemGeneration int `json:"systemGeneration,omitempty"`
4556
}
4657

4758
func stringValue(s *string) string {
@@ -59,6 +70,7 @@ func (c *ChannelVersion) String() string {
5970
if c.ManifestHash != "" {
6071
s += " ManifestHash=" + c.ManifestHash
6172
}
73+
s += " SystemGeneration=" + strconv.Itoa(c.SystemGeneration)
6274
return s
6375
}
6476

@@ -102,21 +114,31 @@ func (c *Channel) AnnotationName() string {
102114
return AnnotationPrefix + c.Name
103115
}
104116

105-
func (c *ChannelVersion) replaces(existing *ChannelVersion) bool {
106-
klog.V(4).Infof("Checking existing channel: %v compared to new channel: %v", existing, c)
117+
func (c *ChannelVersion) replaces(name string, existing *ChannelVersion) bool {
118+
klog.V(6).Infof("Checking existing config for %q: %v compared to new channel: %v", name, existing, c)
119+
120+
if c.Id != existing.Id {
121+
klog.V(4).Infof("cluster has different ids for %q (%q vs %q); will replace", name, c.Id, existing.Id)
122+
return true
123+
}
124+
125+
if c.ManifestHash != existing.ManifestHash {
126+
klog.V(4).Infof("cluster has different ManifestHash for %q (%q vs %q); will replace", name, c.ManifestHash, existing.ManifestHash)
127+
return true
128+
}
107129

108-
if c.Id == existing.Id {
109-
// Same id; check manifests
110-
if c.ManifestHash == existing.ManifestHash {
111-
klog.V(4).Infof("Manifest Match")
130+
if existing.SystemGeneration != c.SystemGeneration {
131+
if existing.SystemGeneration > c.SystemGeneration {
132+
klog.V(4).Infof("cluster has newer SystemGeneration for %q (%v vs %v), will not replace", name, existing.SystemGeneration, c.SystemGeneration)
112133
return false
134+
} else {
135+
klog.V(4).Infof("cluster has different SystemGeneration for %q (%v vs %v); will replace", name, existing.SystemGeneration, c.SystemGeneration)
136+
return true
113137
}
114-
klog.V(4).Infof("Channels had same ids %q, %q but different ManifestHash (%q vs %q); will replace", c.Id, c.ManifestHash, existing.ManifestHash)
115-
} else {
116-
klog.V(4).Infof("Channels had different ids (%q vs %q); will replace", c.Id, existing.Id)
117138
}
118139

119-
return true
140+
klog.V(4).Infof("manifest Match for %q: %v", name, existing)
141+
return false
120142
}
121143

122144
func (c *Channel) GetInstalledVersion(ctx context.Context, k8sClient kubernetes.Interface) (*ChannelVersion, error) {

nodeup/pkg/model/update_service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func (b *UpdateServiceBuilder) buildDebianPackage(c *fi.ModelBuilderContext) {
9292
`
9393
} else {
9494

95-
klog.Infof("Detected OS %s; installing %s package", b.Distribution, debianPackageName)
95+
klog.Infof("Detected OS %v; installing %s package", b.Distribution, debianPackageName)
9696
c.AddTask(&nodetasks.Package{Name: debianPackageName})
9797

9898
contents = `APT::Periodic::Update-Package-Lists "1";

0 commit comments

Comments
 (0)