-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
issue #6807: Retry failed create when using generateName #6830
issue #6807: Retry failed create when using generateName #6830
Conversation
8106a6e
to
9410057
Compare
Codecov Report
@@ Coverage Diff @@
## main #6830 +/- ##
==========================================
- Coverage 60.67% 60.61% -0.06%
==========================================
Files 249 250 +1
Lines 26476 26498 +22
==========================================
- Hits 16064 16063 -1
- Misses 9268 9290 +22
- Partials 1144 1145 +1
|
@@ -40,7 +42,9 @@ type DefaultServerStatusGetter struct { | |||
func (g *DefaultServerStatusGetter) GetServerStatus(kbClient kbclient.Client) (*velerov1api.ServerStatusRequest, error) { | |||
created := builder.ForServerStatusRequest(g.Namespace, "", "0").ObjectMeta(builder.WithGenerateName("velero-cli-")).Result() | |||
|
|||
if err := kbClient.Create(context.Background(), created, &kbclient.CreateOptions{}); err != nil { | |||
if err := retry.OnError(retry.DefaultRetry, apierrors.IsAlreadyExists, func() error { |
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.
I think it would make sense to check for generateName metadata before attempting to retry.
If object does not use generateName, retrying will just be redundant.
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.
I'm only adding this code in places where generateName is always set. If this were in a reusable func, then it would make sense to check that, but since the reusable func would end up just being a thin wrapper around retry.OnError
, I'm not sure it's warranted here. Also, most of these calls involve interface objects so we'd have to attempt to cast to ObjectMeta, then look for GenerateName. I'm leaning towards thinking we don't need this since every time we call OnError it's right after explicitly setting generateName.
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.
cool.
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.
Upon further reflection, I think this is a good idea, actually -- I'll move the retry logic into a util func which either does retries or a simple one-time call, depending on GenerateName/Name values.
I think it would be reasonable for velero to by default cleanup completed status CRs since we generate a lot of them. |
like here #5683 |
I think status cleanup would be a separate thing. I'd like to limit this PR to fixing the GenerateName bug. |
pkg/cmd/cli/backup/delete.go
Outdated
@@ -22,9 +22,11 @@ import ( | |||
|
|||
"github.com/pkg/errors" | |||
"github.com/spf13/cobra" | |||
apierrors "k8s.io/apimachinery/pkg/api/errors" |
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.
I would use camelCase: apierrors
-> apiErrors
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.
@mateusoliveira43 For package names (and package name aliases) the general convention is all lowercase
d3b90e9
to
3297d13
Compare
Related upstream k8s issue: kubernetes/kubernetes#115489 |
3297d13
to
21d892f
Compare
@@ -0,0 +1 @@ | |||
Retry failed create when using generateName |
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.
Retry failed create when using generateName | |
Retry create calls during restore when using generateName to resolve `the server was not able to generate a unique name for the object` errors. |
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.
@kaovilai This doesn't relate to restore. This is when Velero creates CRs with GenerateName. Anything we're restoring already has Name set, so GenerateName isn't involved.
pkg/client/retry.go~
Outdated
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.
What is this file for?
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.
@kaovilai auto-created backup file that accidentally got added to the commit. Will remove.
|
||
func CreateRetryGenerateName(client kbclient.Client, ctx context.Context, obj kbclient.Object) error { | ||
return CreateRetryGenerateNameWithFunc(obj, func() error { | ||
return client.Create(ctx, obj, &kbclient.CreateOptions{}) |
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.
Should CreateOptions be parameterized?
FieldManager could become handy in the future. Also, this maybe what we should be using to restore managedFields during create call.
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.
@kaovilai There weren't any cases in the current code that used it, so it seemed simpler to avoid it. If we need to add CreateOptions in the future, we can add it. I can add it now (and just pass in the empty CreateOptions in all cases), but my thinking was that this was easier to read/maintain without it until we needed it. I don't have a strong opinion there, though.
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.
This is fine as is, just read on the options and saw ability to add managedfields which you might be interested in
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.
@kaovilai Yes, at some point we should probably open a separate issue to investigate better ways to restore managed fields. If we can avoid the extra Patch, that would be great. In any case, none of this code is used for resource restore, since we'll never restore anything that doesn't already have a name.
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.
cool.
21d892f
to
4999e64
Compare
When creating resources with generateName, apimachinery does not guarantee uniqueness when it appends the random suffix to the generateName stub, so if it fails with already exists error, we need to retry. Signed-off-by: Scott Seago <[email protected]>
4999e64
to
09be1f7
Compare
74ed994
into
vmware-tanzu:main
When creating resources with generateName, apimachinery does not guarantee uniqueness when it appends the random suffix to the generateName stub, so if it fails with already exists error, we need to retry.
Thank you for contributing to Velero!
Please add a summary of your change
Does your change fix a particular issue?
Fixes #6807
Please indicate you've done the following:
/kind changelog-not-required
as a comment on this pull request.site/content/docs/main
.