-
Notifications
You must be signed in to change notification settings - Fork 11
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
feat(referrers): delete manifest with subject #174
base: main
Are you sure you want to change the base?
feat(referrers): delete manifest with subject #174
Conversation
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #174 +/- ##
==========================================
+ Coverage 83.25% 83.37% +0.11%
==========================================
Files 37 37
Lines 1266 1347 +81
Branches 149 162 +13
==========================================
+ Hits 1054 1123 +69
- Misses 149 156 +7
- Partials 63 68 +5 ☔ View full report in Codecov by Sentry. |
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
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 can be kept in the original directory.
@@ -29,6 +27,8 @@ internal enum ReferrersState | |||
} | |||
|
|||
internal record ReferrerChange(Descriptor Referrer, ReferrerOperation ReferrerOperation); | |||
|
|||
internal static readonly string ZeroDigest = "sha256:0000000000000000000000000000000000000000000000000000000000000000"; |
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 can be made const
.
/// IndexReferrersForDelete indexes referrers for manifests with a subject field on manifest delete. | ||
/// References: | ||
/// - Latest spec: https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#deleting-manifests | ||
/// - Compatible spec: https://github.com/opencontainers/distribution-spec/blob/v1.1.0-rc1/spec.md#deleting-manifests |
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.
nit: We don't need to mention the old spec here.
if (ReferrersState == Referrers.ReferrersState.Supported) | ||
{ | ||
return true; | ||
} | ||
|
||
if (ReferrersState == Referrers.ReferrersState.NotSupported) | ||
{ | ||
return false; | ||
} |
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.
nit: How about using a switch clause?
if (ReferrersState == Referrers.ReferrersState.Supported) | |
{ | |
return true; | |
} | |
if (ReferrersState == Referrers.ReferrersState.NotSupported) | |
{ | |
return false; | |
} | |
switch (ReferrersState) | |
{ | |
case Referrers.ReferrersState.Supported: | |
return true; | |
case Referrers.ReferrersState.NotSupported: | |
return false; | |
} |
reference.ContentReference = Referrers.ZeroDigest; | ||
var url = new UriFactory(reference, Options.PlainHttp).BuildReferrersUrl(); | ||
var request = new HttpRequestMessage(HttpMethod.Get, url); | ||
var response = Options.HttpClient.SendAsync(request, cancellationToken).ConfigureAwait(true).GetAwaiter() |
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 we await this function and make PingReferrers
async? But async calls are not allowed within the lock
statement. We can try SemaphoreSlim.
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.
The SemaphoreSlim
does not seem right either. We need to consider a lock-free version.
Signed-off-by: Patrick Pan <[email protected]>
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 curious on the reason moving this class to Exceptions
where that namespace should contain generic exception while the ResponseException
is scoped to remote server only.
using System.Text.Json.Serialization; | ||
|
||
namespace OrasProject.Oras.Registry.Remote; | ||
|
||
public class ResponseException : HttpRequestException | ||
{ | ||
{ | ||
public static readonly string ErrorCodeNameUnknown = "NAME_UNKNOWN"; |
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 it be grouped as an enum for ErrorCode
?
public Reference Clone() | ||
{ | ||
return new Reference(Registry, Repository, ContentReference); | ||
} |
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 seems not be a good pattern as it does not meet the IClonable
. You may consider about the copy constructor.
/// <param name="target">The target descriptor to delete.</param> | ||
/// <param name="cancellationToken">A cancellation token to cancel the operation if needed. Defaults to default.</param> | ||
/// <returns></returns> | ||
internal async Task DeleteWithIndexing(Descriptor target, CancellationToken cancellationToken = default) |
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 the method modifier be private
instead of internal
?
await Repository.DeleteAsync(target, true, cancellationToken).ConfigureAwait(false); | ||
return; | ||
} | ||
var manifest = await FetchAsync(target, cancellationToken).ConfigureAwait(false); |
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.
potential resource leak as the manifest is never disposed.
await Repository.DeleteAsync(target, true, cancellationToken).ConfigureAwait(false); | ||
return; | ||
} | ||
var manifest = await FetchAsync(target, cancellationToken).ConfigureAwait(false); |
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.
The manifest is not verified against the target
descriptor. It is possible that a corrupted manifest is fetched.
await Repository.DeleteAsync(target, true, cancellationToken).ConfigureAwait(false); | ||
return; | ||
} | ||
var manifest = await FetchAsync(target, cancellationToken).ConfigureAwait(false); |
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.
The download size of the manifest is not limited / well-guarded. It means it is vulnerable to excessive resource attack.
/// <returns></returns> | ||
/// <exception cref="ResponseException"></exception> | ||
/// <exception cref="Exception"></exception> | ||
internal bool PingReferrers(CancellationToken cancellationToken = default) |
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 the modifier be private
instead of internal
?
What this PR does / why we need it
The PR is to implement the feature to delete manifest with subject as per the OCI distribution spec v1.1.0.
Which issue(s) this PR resolves / fixes
Resolves / Fixes #160
Please check the following list