From e3c78b735887f60dbd80c25c79181eccf71c80f2 Mon Sep 17 00:00:00 2001 From: Jon Huhn Date: Fri, 18 Aug 2023 10:39:10 -0500 Subject: [PATCH] :seedling: check resource blocking clusterctl move during discovery --- cmd/clusterctl/client/cluster/mover.go | 13 +++++++++++- cmd/clusterctl/client/cluster/mover_test.go | 21 ++++++++++++++++++++ cmd/clusterctl/client/cluster/objectgraph.go | 6 ++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/cmd/clusterctl/client/cluster/mover.go b/cmd/clusterctl/client/cluster/mover.go index 0246c9fe4a5a..870687999d49 100644 --- a/cmd/clusterctl/client/cluster/mover.go +++ b/cmd/clusterctl/client/cluster/mover.go @@ -623,6 +623,18 @@ func waitReadyForMove(ctx context.Context, proxy Proxy, nodes []*node, dryRun bo } for _, n := range nodes { + log := log.WithValues( + "apiVersion", n.identity.GroupVersionKind(), + "resource", klog.ObjectRef{ + Name: n.identity.Name, + Namespace: n.identity.Namespace, + }, + ) + if !n.blockingMove { + log.V(5).Info("Resource not blocking move") + continue + } + obj := &metav1.PartialObjectMetadata{ ObjectMeta: metav1.ObjectMeta{ Name: n.identity.Name, @@ -634,7 +646,6 @@ func waitReadyForMove(ctx context.Context, proxy Proxy, nodes []*node, dryRun bo }, } key := client.ObjectKeyFromObject(obj) - log := log.WithValues("apiVersion", obj.GroupVersionKind(), "resource", klog.KObj(obj)) blockLogged := false if err := retryWithExponentialBackoff(backoff, func() error { diff --git a/cmd/clusterctl/client/cluster/mover_test.go b/cmd/clusterctl/client/cluster/mover_test.go index 1f8653119245..08481760a9be 100644 --- a/cmd/clusterctl/client/cluster/mover_test.go +++ b/cmd/clusterctl/client/cluster/mover_test.go @@ -2325,6 +2325,7 @@ func TestWaitReadyForMove(t *testing.T) { tests := []struct { name string moveBlocked bool + doUnblock bool wantErr bool }{ { @@ -2337,6 +2338,12 @@ func TestWaitReadyForMove(t *testing.T) { moveBlocked: false, wantErr: false, }, + { + name: "moving blocked cluster that is eventually unblocked should succeed", + moveBlocked: true, + doUnblock: true, + wantErr: false, + }, } for _, tt := range tests { @@ -2367,6 +2374,14 @@ func TestWaitReadyForMove(t *testing.T) { cluster.SetAnnotations(anns) g.Expect(c.Update(ctx, cluster)).To(Succeed()) + + if tt.doUnblock { + go func() { + time.Sleep(50 * time.Millisecond) + delete(cluster.Annotations, clusterctlv1.BlockMoveAnnotation) + g.Expect(c.Update(ctx, cluster)).To(Succeed()) + }() + } } // Get all the types to be considered for discovery @@ -2378,6 +2393,12 @@ func TestWaitReadyForMove(t *testing.T) { backoff := wait.Backoff{ Steps: 1, } + if tt.doUnblock { + backoff = wait.Backoff{ + Duration: 20 * time.Millisecond, + Steps: 10, + } + } err := waitReadyForMove(ctx, graph.proxy, graph.getMoveNodes(), false, backoff) if tt.wantErr { g.Expect(err).To(HaveOccurred()) diff --git a/cmd/clusterctl/client/cluster/objectgraph.go b/cmd/clusterctl/client/cluster/objectgraph.go index 2bfd157f423e..d72a69ae900f 100644 --- a/cmd/clusterctl/client/cluster/objectgraph.go +++ b/cmd/clusterctl/client/cluster/objectgraph.go @@ -92,6 +92,10 @@ type node struct { // E.g. for the cluster object we capture information to see if the cluster uses a manged topology // and the cluster class used. additionalInfo map[string]interface{} + + // blockingMove is true when the object should prevent a move operation from proceeding as indicated by + // the presence of the block-move annotation. + blockingMove bool } type discoveryTypeInfo struct { @@ -320,6 +324,8 @@ func (o *objectGraph) objMetaToNode(obj *unstructured.Unstructured, n *node) { n.isGlobal = true } } + + _, n.blockingMove = obj.GetAnnotations()[clusterctlv1.BlockMoveAnnotation] } // getDiscoveryTypes returns the list of TypeMeta to be considered for the move discovery phase.