Skip to content

Commit

Permalink
Use Patch() instead of Update() for updating the status of network.op…
Browse files Browse the repository at this point in the history
…erator

As we don't enable status subresource in the CRD
networks.operator.openshift.io. We used to use the Update() func
to update the status of network.operator. It might mistakenly
override some content in the spec. Using Patch() to ensure
that the status_manager only updates the status field.

Signed-off-by: Peng Liu <pliu@redhat.com>
  • Loading branch information
pliurh committed Apr 16, 2024
1 parent 395a36a commit c9d3c72
Showing 1 changed file with 19 additions and 18 deletions.
37 changes: 19 additions & 18 deletions pkg/controller/statusmanager/status_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package statusmanager

import (
"context"
"encoding/json"
"fmt"
"log"
"os"
Expand Down Expand Up @@ -316,16 +317,21 @@ func (status *StatusManager) writeHypershiftStatus(operStatus *operv1.NetworkSta
// Set updates the operator and clusteroperator statuses with the provided conditions.
func (status *StatusManager) set(reachedAvailableLevel bool, conditions ...operv1.OperatorCondition) {
var operStatus *operv1.NetworkStatus
oc := &operv1.Network{ObjectMeta: metav1.ObjectMeta{Name: names.OPERATOR_CONFIG}}

// Set status on the network.operator object
err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
oc := &operv1.Network{ObjectMeta: metav1.ObjectMeta{Name: names.OPERATOR_CONFIG}}
err := status.client.ClientFor("").CRClient().Get(context.TODO(), types.NamespacedName{Name: names.OPERATOR_CONFIG}, oc)
if err != nil {
// Should never happen outside of unit tests
return err
}

return nil
})
if err != nil {
// Should never happen outside of unit tests
log.Printf("Failed to get operator: %v", err)
} else {
oldStatus := oc.Status.DeepCopy()

oc.Status.Version = os.Getenv("RELEASE_VERSION")
Expand Down Expand Up @@ -378,24 +384,19 @@ func (status *StatusManager) set(reachedAvailableLevel bool, conditions ...operv

operStatus = &oc.Status

if equality.Semantic.DeepEqual(&oc.Status, oldStatus) {
return nil
}

buf, err := yaml.Marshal(oc.Status.Conditions)
if err != nil {
buf = []byte(fmt.Sprintf("(failed to convert to YAML: %s)", err))
}
if !equality.Semantic.DeepEqual(&oc.Status, oldStatus) {
type st struct {
Status operv1.NetworkStatus `json:"status"`
}
// make sure we only update the status field
patchData, _ := json.Marshal(&st{
Status: oc.Status,
})

if err := status.client.ClientFor("").CRClient().Update(context.TODO(), oc); err != nil {
return err
if err := status.client.ClientFor("").CRClient().Patch(context.TODO(), oc, crclient.RawPatch(types.MergePatchType, patchData)); err != nil {
log.Printf("Failed to set operator status: %v", err)
}
}
log.Printf("Network operator config updated with conditions:\n%s", buf)

return nil
})
if err != nil {
log.Printf("Failed to set operator status: %v", err)
}

// Set status conditions on the network clusteroperator object.
Expand Down

0 comments on commit c9d3c72

Please sign in to comment.