-
Notifications
You must be signed in to change notification settings - Fork 351
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
Fix quickstart bug: branch protection #6682
Conversation
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.
Some comments.
In addition:
Can we add an esti test for S3 which checks the creation of the sample repo?
pkg/graveler/graveler.go
Outdated
return g.protectedBranchesManager.GetRules(ctx, repository) | ||
} | ||
|
||
func (g *Graveler) SetBranchProtectionRules(ctx context.Context, repository *RepositoryRecord, rules *BranchProtectionRules, lastKnownChecksum *string) error { | ||
if lastKnownChecksum == nil { | ||
return g.protectedBranchesManager.SetRules(ctx, repository, rules) | ||
} | ||
return g.protectedBranchesManager.SetRulesIf(ctx, repository, rules, *lastKnownChecksum) | ||
if *lastKnownChecksum == "" { |
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.
Seem like the logic should be reversed?:
- lastKnownChecksum is nil -> SetIf
- lastKnownChecksum is "" -> Set
And of course change the logic in the invoking methods accordingly
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.
Agree that this is ugly. I argue that "" as the "skip validation checksum" is just as problematic. Added a dedicated skip-validation constant to overcome this. This will be removed once the legacy API is dropped.
pkg/graveler/graveler.go
Outdated
|
||
// SetBranchProtectionRules sets the branch protection rules for the repository. | ||
// If lastKnownChecksum doesn't match the current state, the update fails with ErrPreconditionFailed. | ||
// If lastKnownChecksum is the empty string, the update is performed only if no rules exist. |
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 be nil and not empty
@N-o-Z, added an Esti test for sample repo creation. |
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.
LGTM
setRefresh(!refresh) | ||
setDeleteButtonDisabled(false) | ||
}).catch(err => { | ||
setDeleteButtonDisabled(false) | ||
setActionError(err) |
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.
can move setDeleteButtonDisabled(false)
to finally
@@ -1003,28 +1003,19 @@ class BranchProtectionRules { | |||
} | |||
|
|||
async setRules(repoID, rules, lastKnownChecksum) { | |||
let additionalHeaders = {} | |||
if (lastKnownChecksum) { | |||
console.log(`setting branch protection rules with checksum ${lastKnownChecksum}`) |
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.
console log
@@ -1003,28 +1003,19 @@ class BranchProtectionRules { | |||
} | |||
|
|||
async setRules(repoID, rules, lastKnownChecksum) { | |||
let additionalHeaders = {} |
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.
can use const
@@ -1788,7 +1788,7 @@ func (c *Controller) GetBranchProtectionRules(w http.ResponseWriter, r *http.Req | |||
Pattern: pattern, | |||
}) | |||
} | |||
w.Header().Set("ETag", eTag) | |||
w.Header().Set("ETag", swag.StringValue(eTag)) |
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.
if etag is nil it means there is no data - so I guess we should not send empty etag, right? as it is valid value as indicator and not a value for a content that is not there.
@@ -1816,6 +1816,9 @@ func (c *Controller) SetBranchProtectionRules(w http.ResponseWriter, r *http.Req | |||
} | |||
} | |||
eTag := params.IfMatch | |||
if swag.StringValue(eTag) == "" { | |||
eTag = nil |
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.
Thought we kept the kv way:
As the client call without eTag - no check to be done.
If eTag is empty - check no previous value is set.
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 API does not allow skipping the validation.
decodedChecksum, err := base64.StdEncoding.DecodeString(lastKnownChecksum) | ||
if err != nil { | ||
return fmt.Errorf("decode checksum: %w", err) | ||
valueWithPredicate, err := m.store.Get(ctx, []byte(graveler.RepoPartition(repository)), []byte(graveler.SettingsPath(key))) |
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.
Case lastKnownChecksum
is nil we don't need to Get
the current value, we can just return from SetMsg - it will also remove the check if valueWithPredicate is nil later as successful call should return non-nil.
return graveler.ErrPreconditionFailed | ||
} | ||
err = kv.SetMsgIf(ctx, m.store, graveler.RepoPartition(repository), []byte(graveler.SettingsPath(key)), setting, currentPredicate) | ||
if err != nil && errors.Is(err, kv.ErrPredicateFailed) { |
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.
Simplify
if err != nil && errors.Is(err, kv.ErrPredicateFailed) { | |
if errors.Is(err, kv.ErrPredicateFailed) { |
var currentPredicate kv.Predicate | ||
if valueWithPredicate != nil { | ||
if valueWithPredicate.Value != nil { | ||
currentChecksum, err = computeChecksum(valueWithPredicate.Value) | ||
} | ||
if err != nil { | ||
return err | ||
} | ||
currentPredicate = valueWithPredicate.Predicate | ||
} | ||
if swag.StringValue(currentChecksum) != swag.StringValue(lastKnownChecksum) { | ||
return graveler.ErrPreconditionFailed | ||
} | ||
err = kv.SetMsgIf(ctx, m.store, graveler.RepoPartition(repository), []byte(graveler.SettingsPath(key)), setting, currentPredicate) |
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.
Main concern here is just the flow where we call SetMsgIf
while using currentPredicate
value that was not part of valueWithPredicate
.
The promise from kv is to support SetIf only with predicate that was returned from Get or explicit call with nil
to indicate that the value should not be exists.
Suggest to check if lastKnownChecksum is "" and call SetIf with nil - for all the rest we can compare the checksum as above and call SetMsgIf
func (m *Manager) GetLatest(ctx context.Context, repository *graveler.RepositoryRecord, key string, settingTemplate proto.Message) (proto.Message, string, error) { | ||
data := settingTemplate.ProtoReflect().Interface() | ||
pred, err := m.getWithPredicate(ctx, repository, key, data) | ||
func (m *Manager) GetLatest(ctx context.Context, repository *graveler.RepositoryRecord, key string, settingTemplate proto.Message) (proto.Message, *string, 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.
Accept protoreflect.ProtoMessage
as settingMsg and unmarshal the data into it instead of template+reflect+create and return.
Resolves #6674.