Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upgrade addon rollout library #212

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ require (
k8s.io/component-base v0.26.7
k8s.io/klog/v2 v2.80.1
k8s.io/utils v0.0.0-20221128185143-99ec85e7a448
open-cluster-management.io/api v0.12.0
open-cluster-management.io/api v0.12.1-0.20230925140632-bf4f47ea90d1
sigs.k8s.io/controller-runtime v0.14.4
)

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -819,8 +819,8 @@ k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+O
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4=
k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y=
k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
open-cluster-management.io/api v0.12.0 h1:sNkj4k2XyWA/GLsTiFg82bLIZ7JDZKkLLLyZjJUlJMs=
open-cluster-management.io/api v0.12.0/go.mod h1:/CZhelEH+30/pX7vXGSZOzLMX0zvjthYOkT/5ZTzVTQ=
open-cluster-management.io/api v0.12.1-0.20230925140632-bf4f47ea90d1 h1:8r0fdost7Yhvvz+xJb7xkj/tLZ4DigxiGoEJGakXhUg=
open-cluster-management.io/api v0.12.1-0.20230925140632-bf4f47ea90d1/go.mod h1:/CZhelEH+30/pX7vXGSZOzLMX0zvjthYOkT/5ZTzVTQ=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
Expand Down
78 changes: 47 additions & 31 deletions pkg/manager/controllers/addonconfiguration/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@ type addonConfigMap map[addonv1alpha1.ConfigGroupResource]addonv1alpha1.ConfigRe

// set addon rollout status
func (n *addonNode) setRolloutStatus() {
n.status = &clusterv1alpha1.ClusterRolloutStatus{ClusterName: n.mca.Namespace}

// desired configs doesn't match actual configs, set to ToApply
if len(n.mca.Status.ConfigReferences) != len(n.desiredConfigs) {
n.status = &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.ToApply}
n.status.Status = clusterv1alpha1.ToApply
return
}

Expand All @@ -66,38 +68,33 @@ func (n *addonNode) setRolloutStatus() {
if desired, ok := n.desiredConfigs[actual.ConfigGroupResource]; ok {
// desired config spec hash doesn't match actual, set to ToApply
if !equality.Semantic.DeepEqual(desired.DesiredConfig, actual.DesiredConfig) {
n.status = &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.ToApply}
n.status.Status = clusterv1alpha1.ToApply
return
// desired config spec hash matches actual, but last applied config spec hash doesn't match actual
} else if !equality.Semantic.DeepEqual(actual.LastAppliedConfig, actual.DesiredConfig) {
switch progressingCond.Reason {
case addonv1alpha1.ProgressingReasonInstallFailed, addonv1alpha1.ProgressingReasonUpgradeFailed:
n.status = &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.Failed, LastTransitionTime: &progressingCond.LastTransitionTime}
n.status.Status = clusterv1alpha1.Failed
n.status.LastTransitionTime = &progressingCond.LastTransitionTime
case addonv1alpha1.ProgressingReasonInstalling, addonv1alpha1.ProgressingReasonUpgrading:
n.status = &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.Progressing, LastTransitionTime: &progressingCond.LastTransitionTime}
n.status.Status = clusterv1alpha1.Progressing
n.status.LastTransitionTime = &progressingCond.LastTransitionTime
default:
n.status = &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.Progressing}
n.status.Status = clusterv1alpha1.Progressing
}
return
}
} else {
n.status = &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.ToApply}
n.status.Status = clusterv1alpha1.ToApply
return
}
}

// succeed
n.status.Status = clusterv1alpha1.Succeeded
if progressingCond.Reason == addonv1alpha1.ProgressingReasonInstallSucceed || progressingCond.Reason == addonv1alpha1.ProgressingReasonUpgradeSucceed {
n.status = &clusterv1alpha1.ClusterRolloutStatus{
Status: clusterv1alpha1.Succeeded,
LastTransitionTime: &progressingCond.LastTransitionTime,
}
} else {
n.status = &clusterv1alpha1.ClusterRolloutStatus{
Status: clusterv1alpha1.Succeeded,
}
n.status.LastTransitionTime = &progressingCond.LastTransitionTime
}

}

func (d addonConfigMap) copy() addonConfigMap {
Expand Down Expand Up @@ -311,20 +308,39 @@ func (n *installStrategyNode) generateRolloutResult() error {
if n.placementRef.Name == "" {
// default addons
rolloutResult := clusterv1alpha1.RolloutResult{}
rolloutResult.ClustersToRollout = map[string]clusterv1alpha1.ClusterRolloutStatus{}
for k, addon := range n.children {
rolloutResult.ClustersToRollout = []clusterv1alpha1.ClusterRolloutStatus{}
for name, addon := range n.children {
if addon.status == nil {
return fmt.Errorf("failed to get rollout status on cluster %v", name)
}
if addon.status.Status != clusterv1alpha1.Succeeded {
rolloutResult.ClustersToRollout[k] = *addon.status
rolloutResult.ClustersToRollout = append(rolloutResult.ClustersToRollout, *addon.status)
}
}
n.rolloutResult = rolloutResult
} else {
// placement addons
rolloutHandler, err := clusterv1alpha1.NewRolloutHandler(n.pdTracker)
rolloutHandler, err := clusterv1alpha1.NewRolloutHandler(n.pdTracker, getClusterRolloutStatus)
if err != nil {
return err
}
_, rolloutResult, err := rolloutHandler.GetRolloutCluster(n.rolloutStrategy, n.getUpgradeStatus)

// get existing addons
existingRolloutClusters := []clusterv1alpha1.ClusterRolloutStatus{}
for name, addon := range n.children {
clsRolloutStatus, err := getClusterRolloutStatus(name, addon)
if err != nil {
return err
}
existingRolloutClusters = append(existingRolloutClusters, clsRolloutStatus)
}

// sort by cluster name
sort.SliceStable(existingRolloutClusters, func(i, j int) bool {
return existingRolloutClusters[i].ClusterName < existingRolloutClusters[j].ClusterName
})

_, rolloutResult, err := rolloutHandler.GetRolloutCluster(n.rolloutStrategy, existingRolloutClusters)
if err != nil {
return err
}
Expand All @@ -334,23 +350,16 @@ func (n *installStrategyNode) generateRolloutResult() error {
return nil
}

func (n *installStrategyNode) getUpgradeStatus(clusterName string) clusterv1alpha1.ClusterRolloutStatus {
if node, exist := n.children[clusterName]; exist {
return *node.status
} else {
// if children not exist, return succeed status to skip
return clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.Skip}
}
}

// addonToUpdate finds the addons to be updated by placement
func (n *installStrategyNode) getAddonsToUpdate() []*addonNode {
var addons []*addonNode
var clusters []string

// get addon to update from rollout result
for c := range n.rolloutResult.ClustersToRollout {
clusters = append(clusters, c)
for _, c := range n.rolloutResult.ClustersToRollout {
if _, exist := n.children[c.ClusterName]; exist {
clusters = append(clusters, c.ClusterName)
}
}

// sort addons by name
Expand Down Expand Up @@ -385,6 +394,13 @@ func (n *installStrategyNode) countAddonTimeOut() int {
return len(n.rolloutResult.ClustersTimeOut)
}

func getClusterRolloutStatus(clusterName string, addonNode *addonNode) (clusterv1alpha1.ClusterRolloutStatus, error) {
if addonNode.status == nil {
return clusterv1alpha1.ClusterRolloutStatus{}, fmt.Errorf("failed to get rollout status on cluster %v", clusterName)
}
return *addonNode.status, nil
}

func desiredConfigsEqual(a, b addonConfigMap) bool {
if len(a) != len(b) {
return false
Expand Down
89 changes: 62 additions & 27 deletions pkg/manager/controllers/addonconfiguration/graph_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ func TestConfigurationGraph(t *testing.T) {
},
},
},
mca: addontesting.NewAddon("test", "cluster1"),
status: &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.ToApply},
mca: addontesting.NewAddon("test", "cluster1"),
status: &clusterv1alpha1.ClusterRolloutStatus{
ClusterName: "cluster1",
Status: clusterv1alpha1.ToApply},
},
{
desiredConfigs: map[addonv1alpha1.ConfigGroupResource]addonv1alpha1.ConfigReference{
Expand All @@ -77,8 +79,10 @@ func TestConfigurationGraph(t *testing.T) {
},
},
},
mca: addontesting.NewAddon("test", "cluster2"),
status: &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.ToApply},
mca: addontesting.NewAddon("test", "cluster2"),
status: &clusterv1alpha1.ClusterRolloutStatus{
ClusterName: "cluster2",
Status: clusterv1alpha1.ToApply},
},
},
},
Expand Down Expand Up @@ -146,8 +150,10 @@ func TestConfigurationGraph(t *testing.T) {
},
},
},
mca: addontesting.NewAddon("test", "cluster1"),
status: &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.ToApply},
mca: addontesting.NewAddon("test", "cluster1"),
status: &clusterv1alpha1.ClusterRolloutStatus{
ClusterName: "cluster1",
Status: clusterv1alpha1.ToApply},
},
{
desiredConfigs: map[addonv1alpha1.ConfigGroupResource]addonv1alpha1.ConfigReference{
Expand All @@ -168,8 +174,11 @@ func TestConfigurationGraph(t *testing.T) {
},
},
},
mca: addontesting.NewAddon("test", "cluster2"),
status: &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.ToApply},
mca: addontesting.NewAddon("test", "cluster2"),
status: &clusterv1alpha1.ClusterRolloutStatus{
ClusterName: "cluster2",
Status: clusterv1alpha1.ToApply,
},
},
{
desiredConfigs: map[addonv1alpha1.ConfigGroupResource]addonv1alpha1.ConfigReference{
Expand All @@ -190,8 +199,11 @@ func TestConfigurationGraph(t *testing.T) {
},
},
},
mca: addontesting.NewAddon("test", "cluster3"),
status: &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.ToApply},
mca: addontesting.NewAddon("test", "cluster3"),
status: &clusterv1alpha1.ClusterRolloutStatus{
ClusterName: "cluster3",
Status: clusterv1alpha1.ToApply,
},
},
},
},
Expand Down Expand Up @@ -306,8 +318,12 @@ func TestConfigurationGraph(t *testing.T) {
},
},
},
mca: addontesting.NewAddon("test", "cluster1"),
status: &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.Failed, LastTransitionTime: &fakeTime},
mca: addontesting.NewAddon("test", "cluster1"),
status: &clusterv1alpha1.ClusterRolloutStatus{
ClusterName: "cluster1",
Status: clusterv1alpha1.Failed,
LastTransitionTime: &fakeTime,
},
},
{
desiredConfigs: map[addonv1alpha1.ConfigGroupResource]addonv1alpha1.ConfigReference{
Expand All @@ -320,8 +336,12 @@ func TestConfigurationGraph(t *testing.T) {
},
},
},
mca: addontesting.NewAddon("test", "cluster2"),
status: &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.Progressing, LastTransitionTime: &fakeTime},
mca: addontesting.NewAddon("test", "cluster2"),
status: &clusterv1alpha1.ClusterRolloutStatus{
ClusterName: "cluster2",
Status: clusterv1alpha1.Progressing,
LastTransitionTime: &fakeTime,
},
},
{
desiredConfigs: map[addonv1alpha1.ConfigGroupResource]addonv1alpha1.ConfigReference{
Expand All @@ -334,8 +354,11 @@ func TestConfigurationGraph(t *testing.T) {
},
},
},
mca: addontesting.NewAddon("test", "cluster4"),
status: &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.ToApply},
mca: addontesting.NewAddon("test", "cluster4"),
status: &clusterv1alpha1.ClusterRolloutStatus{
ClusterName: "cluster4",
Status: clusterv1alpha1.ToApply,
},
},
},
},
Expand Down Expand Up @@ -403,8 +426,10 @@ func TestConfigurationGraph(t *testing.T) {
},
},
},
mca: addontesting.NewAddon("test", "cluster1"),
status: &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.ToApply},
mca: addontesting.NewAddon("test", "cluster1"),
status: &clusterv1alpha1.ClusterRolloutStatus{
ClusterName: "cluster1",
Status: clusterv1alpha1.ToApply},
},
{
desiredConfigs: map[addonv1alpha1.ConfigGroupResource]addonv1alpha1.ConfigReference{
Expand All @@ -425,8 +450,10 @@ func TestConfigurationGraph(t *testing.T) {
},
},
},
mca: addontesting.NewAddon("test", "cluster2"),
status: &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.ToApply},
mca: addontesting.NewAddon("test", "cluster2"),
status: &clusterv1alpha1.ClusterRolloutStatus{
ClusterName: "cluster2",
Status: clusterv1alpha1.ToApply},
},
{
desiredConfigs: map[addonv1alpha1.ConfigGroupResource]addonv1alpha1.ConfigReference{
Expand All @@ -447,8 +474,10 @@ func TestConfigurationGraph(t *testing.T) {
},
},
},
mca: addontesting.NewAddon("test", "cluster3"),
status: &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.ToApply},
mca: addontesting.NewAddon("test", "cluster3"),
status: &clusterv1alpha1.ClusterRolloutStatus{
ClusterName: "cluster3",
Status: clusterv1alpha1.ToApply},
},
},
},
Expand Down Expand Up @@ -523,7 +552,9 @@ func TestConfigurationGraph(t *testing.T) {
{ConfigGroupResource: addonv1alpha1.ConfigGroupResource{Group: "core", Resource: "Bar"},
ConfigReferent: addonv1alpha1.ConfigReferent{Name: "test1"}},
}, nil, nil),
status: &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.ToApply},
status: &clusterv1alpha1.ClusterRolloutStatus{
ClusterName: "cluster1",
Status: clusterv1alpha1.ToApply},
},
{
desiredConfigs: map[addonv1alpha1.ConfigGroupResource]addonv1alpha1.ConfigReference{
Expand All @@ -544,8 +575,10 @@ func TestConfigurationGraph(t *testing.T) {
},
},
},
mca: addontesting.NewAddon("test", "cluster2"),
status: &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.ToApply},
mca: addontesting.NewAddon("test", "cluster2"),
status: &clusterv1alpha1.ClusterRolloutStatus{
ClusterName: "cluster2",
Status: clusterv1alpha1.ToApply},
},
{
desiredConfigs: map[addonv1alpha1.ConfigGroupResource]addonv1alpha1.ConfigReference{
Expand All @@ -566,8 +599,10 @@ func TestConfigurationGraph(t *testing.T) {
},
},
},
mca: addontesting.NewAddon("test", "cluster3"),
status: &clusterv1alpha1.ClusterRolloutStatus{Status: clusterv1alpha1.ToApply},
mca: addontesting.NewAddon("test", "cluster3"),
status: &clusterv1alpha1.ClusterRolloutStatus{
ClusterName: "cluster3",
Status: clusterv1alpha1.ToApply},
},
},
},
Expand Down
2 changes: 1 addition & 1 deletion vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1226,7 +1226,7 @@ k8s.io/utils/path
k8s.io/utils/pointer
k8s.io/utils/strings/slices
k8s.io/utils/trace
# open-cluster-management.io/api v0.12.0
# open-cluster-management.io/api v0.12.1-0.20230925140632-bf4f47ea90d1
## explicit; go 1.19
open-cluster-management.io/api/addon/v1alpha1
open-cluster-management.io/api/client/addon/clientset/versioned
Expand Down
Loading
Loading