-
Notifications
You must be signed in to change notification settings - Fork 1.3k
fix(dataset): recreate the ThinRuntime of a reference dataset stuck in NotBound #6138
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,6 +18,7 @@ package utils | |
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| "reflect" | ||
|
|
||
| datav1alpha1 "github.com/fluid-cloudnative/fluid/api/v1alpha1" | ||
|
|
@@ -41,6 +42,29 @@ func GetRuntimeByCategory(runtimes []datav1alpha1.Runtime, category common.Categ | |
| return -1, nil | ||
| } | ||
|
|
||
| // datasetControllerOwnerReference builds the controller ownerReference which points to the given dataset. | ||
| // Kind and APIVersion come from the dataset's TypeMeta, and fall back to the well-known values of the Dataset | ||
| // CRD when it is empty, which a typed client may hand back depending on how the object was read. The owner | ||
| // based watch of the dataset controller resolves a dependent through those two fields, so they must be set. | ||
| func datasetControllerOwnerReference(dataset *datav1alpha1.Dataset) metav1.OwnerReference { | ||
| kind := dataset.GetObjectKind().GroupVersionKind().Kind | ||
| if len(kind) == 0 { | ||
| kind = datav1alpha1.Datasetkind | ||
| } | ||
| apiVersion := dataset.APIVersion | ||
| if len(apiVersion) == 0 { | ||
| apiVersion = datav1alpha1.GroupVersion.String() | ||
| } | ||
|
|
||
| return metav1.OwnerReference{ | ||
| Kind: kind, | ||
| APIVersion: apiVersion, | ||
| Name: dataset.GetName(), | ||
| UID: dataset.GetUID(), | ||
| Controller: ptr.To(true), | ||
| } | ||
| } | ||
|
|
||
| // CreateRuntimeForReferenceDatasetIfNotExist creates runtime for ReferenceDataset | ||
| func CreateRuntimeForReferenceDatasetIfNotExist(client client.Client, dataset *datav1alpha1.Dataset) (err error) { | ||
| err = retry.RetryOnConflict(retry.DefaultBackoff, func() error { | ||
|
|
@@ -49,15 +73,17 @@ func CreateRuntimeForReferenceDatasetIfNotExist(client client.Client, dataset *d | |
| dataset.GetNamespace()) | ||
| // 1. if err is null, which indicates that the runtime exists, then return | ||
| if err == nil { | ||
| // 1.1 The runtime is being deleted, it can neither be adopted nor be re-created for now. | ||
| // Return an error (not a conflict error, so retry.RetryOnConflict won't swallow it) to | ||
| // let the caller requeue until the terminating runtime is really gone. | ||
| if HasDeletionTimestamp(runtime.ObjectMeta) { | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Returning an error here makes Given the PR is about a reference dataset stuck in NotBound, I wanted to confirm this is the intended trade-off — fail loudly and back off — rather than surfacing |
||
| return fmt.Errorf("the ThinRuntime %s/%s is terminating, wait for it to be deleted before creating a new one for the reference dataset", | ||
| runtime.GetNamespace(), runtime.GetName()) | ||
| } | ||
|
|
||
| runtimeToUpdate := runtime.DeepCopy() | ||
| runtimeToUpdate.SetOwnerReferences([]metav1.OwnerReference{ | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The behaviour predates this PR, but the new The existing |
||
| { | ||
| Kind: dataset.GetObjectKind().GroupVersionKind().Kind, | ||
| APIVersion: dataset.APIVersion, | ||
| Name: dataset.GetName(), | ||
| UID: dataset.GetUID(), | ||
| Controller: ptr.To(true), | ||
| }}) | ||
| datasetControllerOwnerReference(dataset)}) | ||
| if !reflect.DeepEqual(runtimeToUpdate, runtime) { | ||
| err = client.Update(context.TODO(), runtimeToUpdate) | ||
| return err | ||
|
|
@@ -72,13 +98,7 @@ func CreateRuntimeForReferenceDatasetIfNotExist(client client.Client, dataset *d | |
| Name: dataset.Name, | ||
| Namespace: dataset.Namespace, | ||
| OwnerReferences: []metav1.OwnerReference{ | ||
| { | ||
| Kind: dataset.GetObjectKind().GroupVersionKind().Kind, | ||
| APIVersion: dataset.APIVersion, | ||
| Name: dataset.GetName(), | ||
| UID: dataset.GetUID(), | ||
| Controller: ptr.To(true), | ||
| }, | ||
| datasetControllerOwnerReference(dataset), | ||
| }, | ||
| Labels: map[string]string{ | ||
| common.LabelAnnotationDatasetId: GetDatasetId(dataset.GetNamespace(), dataset.GetName(), string(dataset.GetUID())), | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The label is read in a few places ( Separately, and out of scope for this PR: |
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#6139 adds the same kind/apiVersion fallback to
pkg/utils/transformer/owner_reference.govia a scheme lookup. Once both land there are two independent implementations of "recover the owner GVK" with different semantics: this one fills the two fields independently, while the transformer gates the whole recovery ongvk.Empty()and therefore misses partially populated TypeMeta.Worth converging on one. The per-field approach here is the more robust of the two, so folding it into the shared helper and having this call site delegate would remove the duplication without losing coverage. Not something to fix in this PR — I will open a follow-up issue.