Skip to content

Commit

Permalink
fix: check if lates progressing status is for current deployment temp…
Browse files Browse the repository at this point in the history
…late
  • Loading branch information
osmman committed Aug 29, 2024
1 parent 1ee4730 commit 0d39dd9
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 6 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ jobs:
auth_file_path: /tmp/config.json

- name: Install Cluster
uses: container-tools/[email protected].1
uses: container-tools/[email protected].4
with:
version: v0.20.0
node_image: kindest/node:v1.26.6@sha256:6e2d8b28a5b601defe327b98bd1c2d1930b49e5d8c512e1895099e4504007adb
version: v0.24.0
node_image: kindest/node:v1.27.17@sha256:3fd82731af34efe19cd54ea5c25e882985bafa2c9baefe14f8deab1737d9fabe
cpu: 3
registry: false
config: ./ci/config.yaml
Expand Down
38 changes: 36 additions & 2 deletions internal/controller/common/utils/kubernetes/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@ package kubernetes

import (
"context"
"encoding/binary"
"errors"
"fmt"
"hash"
"hash/fnv"
"strings"

"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/apimachinery/pkg/util/rand"

v1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -36,11 +43,13 @@ func DeploymentIsRunning(ctx context.Context, cli client.Client, namespace strin
}

for _, d := range list.Items {
log.V(2).WithValues(
templateHash := ComputeHash(&d.Spec.Template, d.Status.CollisionCount)
log.WithValues(
"namespace", d.Namespace, "name",
d.Name, "generation", d.Generation,
"observed", d.Status.ObservedGeneration,
"conditions", d.Status.Conditions,
"templateHash", templateHash,
).Info("state")

if d.Generation != d.Status.ObservedGeneration {
Expand All @@ -53,7 +62,7 @@ func DeploymentIsRunning(ctx context.Context, cli client.Client, namespace strin
}

c = getDeploymentCondition(d.Status, v1.DeploymentProgressing)
if c == nil || c.Status != corev1.ConditionTrue || c.Reason != "NewReplicaSetAvailable" {
if c == nil || c.Status != corev1.ConditionTrue || c.Reason != "NewReplicaSetAvailable" || !strings.Contains(c.Message, templateHash) {
return false, fmt.Errorf("%w(%s): %w", ErrDeploymentNotReady, d.Name, ErrNewReplicaSetNotAvailable)
}
}
Expand All @@ -69,3 +78,28 @@ func getDeploymentCondition(status v1.DeploymentStatus, condType v1.DeploymentCo
}
return nil
}

// ComputeHash returns a hash value calculated from pod template and
// a collisionCount to avoid hash collision. The hash will be safe encoded to
// avoid bad words.
func ComputeHash(template *corev1.PodTemplateSpec, collisionCount *int32) string {
podTemplateSpecHasher := fnv.New32a()
DeepHashObject(podTemplateSpecHasher, *template)

// Add collisionCount in the hash if it exists.
if collisionCount != nil {
collisionCountBytes := make([]byte, 8)
binary.LittleEndian.PutUint32(collisionCountBytes, uint32(*collisionCount))
_, _ = podTemplateSpecHasher.Write(collisionCountBytes)
}

return rand.SafeEncodeString(fmt.Sprint(podTemplateSpecHasher.Sum32()))
}

// DeepHashObject writes specified object to hash using the spew library
// which follows pointers and prints actual values of the nested objects
// ensuring the hash does not change when a pointer changes.
func DeepHashObject(hasher hash.Hash, objectToWrite interface{}) {
hasher.Reset()
_, _ = fmt.Fprintf(hasher, "%v", dump.ForHash(objectToWrite))
}
8 changes: 7 additions & 1 deletion internal/testing/kubernetes/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package kubernetes
import (
"context"
"errors"
"fmt"

"github.com/securesign/operator/internal/controller/common/utils/kubernetes"

"github.com/securesign/operator/internal/controller/constants"
v1 "k8s.io/api/apps/v1"
Expand All @@ -15,10 +18,13 @@ func SetDeploymentToReady(ctx context.Context, cli client.Client, deployment *v1
return errors.New("nil deployment")
}

templateHash := kubernetes.ComputeHash(&deployment.Spec.Template, deployment.Status.CollisionCount)

deployment.Status.ObservedGeneration = deployment.Generation
deployment.Status.Conditions = []v1.DeploymentCondition{
{Status: corev1.ConditionTrue, Type: v1.DeploymentAvailable, Reason: constants.Ready},
{Status: corev1.ConditionTrue, Type: v1.DeploymentProgressing, Reason: "NewReplicaSetAvailable"},
{Status: corev1.ConditionTrue, Type: v1.DeploymentProgressing, Reason: "NewReplicaSetAvailable",
Message: fmt.Sprintf("ReplicaSet \"%s-%s\" has successfully progressed.", deployment.Name, templateHash)},
}
return cli.Status().Update(ctx, deployment)
}

0 comments on commit 0d39dd9

Please sign in to comment.