Skip to content
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

Open
wants to merge 31 commits into
base: main
Choose a base branch
from

Conversation

pat-pan
Copy link
Contributor

@pat-pan pat-pan commented Jan 6, 2025

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

  • Does the affected code have corresponding tests, e.g. unit test, E2E test?
  • Does this change require a documentation update?
  • Does this introduce breaking changes that would require an announcement or bumping the major version?
  • Do all new files have an appropriate license header?

Patrick Pan added 23 commits November 18, 2024 18:16
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]>
Copy link

codecov bot commented Jan 6, 2025

Codecov Report

Attention: Patch coverage is 84.61538% with 16 lines in your changes missing coverage. Please review.

Project coverage is 83.37%. Comparing base (220d7dd) to head (b13de61).
Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/OrasProject.Oras/Registry/Remote/Repository.cs 75.75% 5 Missing and 3 partials ⚠️
.../OrasProject.Oras/Registry/Remote/ManifestStore.cs 79.41% 3 Missing and 4 partials ⚠️
...c/OrasProject.Oras/Exceptions/ResponseException.cs 95.45% 0 Missing and 1 partial ⚠️
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.
📢 Have feedback on the report? Share it here.

Patrick Pan added 4 commits January 13, 2025 15:22
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Signed-off-by: Patrick Pan <[email protected]>
Copy link
Member

@Wwwsylvia Wwwsylvia Jan 13, 2025

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";
Copy link
Member

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
Copy link
Member

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.

Comment on lines 384 to 392
if (ReferrersState == Referrers.ReferrersState.Supported)
{
return true;
}

if (ReferrersState == Referrers.ReferrersState.NotSupported)
{
return false;
}
Copy link
Member

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?

Suggested change
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()
Copy link
Member

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.

Copy link
Contributor

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]>
Copy link
Contributor

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";
Copy link
Contributor

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?

Comment on lines +204 to +207
public Reference Clone()
{
return new Reference(Registry, Repository, ContentReference);
}
Copy link
Contributor

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)
Copy link
Contributor

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);
Copy link
Contributor

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);
Copy link
Contributor

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);
Copy link
Contributor

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)
Copy link
Contributor

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Delete Manifest with subject
3 participants