Giter Club home page Giter Club logo

docker.registry.dotnet's Introduction

docker icon Docker.Registry.DotNet

NuGet version Build and Push to Nuget Downloads

.NET (C#) Client Library for interacting with a Docker Registry API (v2 only).

Setup

Install nuget package into your project via powershell:

PM> Install-Package Docker.Registry.DotNet

Add nuget package via dotnet CLI:

dotnet add package Docker.Registry.DotNet

Usage

var configuration = new RegistryClientConfiguration("localhost:5000");

using (var client = configuration.CreateClient())
{
    await client.System.PingAsync();
}

Changelog

v1.1.33

  • Added Basic Authentication (thanks Zguy).
  • Fixed issue with operational parameters (thanks lostllama).
  • Fixed issue with large manifest layers (thanks msvprogs).

docker.registry.dotnet's People

Contributors

dependabot[bot] avatar jaben avatar lostllama avatar rgl avatar rquackenbush avatar saber-wang avatar zguy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

docker.registry.dotnet's Issues

JSON deserialization exception when trying to get manifest of the image with big layer (several GB)

registryClient.Manifest.GetManifestAsync(imageId.Name, imageId.Tag, cancellationToken) throws this exception when trying to get manifest of image with layer size greater than int.MaxValue bytes:

Newtonsoft.Json.JsonReaderException: JSON integer 3795828966 is too large or small for an Int32. Path 'layers[13].size', line 77, position 27.
   at Newtonsoft.Json.JsonTextReader.ParseReadNumber(ReadType readType, Char firstChar, Int32 initialPosition)
   at Newtonsoft.Json.JsonTextReader.ReadNumberValue(ReadType readType)
   at Newtonsoft.Json.JsonTextReader.ReadAsInt32()
   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonConverter[] converters)
   at Docker.Registry.DotNet.Endpoints.ManifestOperations.GetManifestAsync(String name, String reference, CancellationToken cancellationToken)

It can be fixed by changing the type of Size property in ManifestLayer and Config classes to 'long'.

Remove a tag

Is it possible to remove an existing tag? The only method I can see to do with tags is ListImageTagsAsync.

Thank you!

Unable to read manifest with provenance enabled image

I noticed that recently docker (buildkit) pushed image manifests are sometimes not readable by Docker.Registry.DotNet.
Specifically, the call to IManifestOperations.GetManifestAsync() fails.

I don't know much about API specs, but I did a little research, so here's the information.

This seems to be related to the provenance option when building with docker buildx (buildkit).
Recent versions seem to default to the equivalent of --provenance true.
An image built with it will have an error getting the manifest.
Even if you use the same version of docker buildx, the image built with --provenance false can get the manifest normally.

When built with --provenance true, the MediaType in the manifest seems to be application/vnd.oci.*****.
I think it's relevant here. (But I don't fully understand what this means.)
https://docs.docker.com/build/attestations/slsa-provenance/

Failure to retrieve the manifest appears to be due to the fact that the current(v1.2.1) GetManifestAsync() does not support this MediaType.
Specifically, the server seems to be returning a 404 Not Found because the Accept header of the request does not contain application/vnd.oci.*****.

For reference, here are the materials I used when I tried it.
https://github.com/toras9000/test-docker-registry

You may have already figured it out, but I've included it for reference.

I rely on translation tools. I'm sorry if there is a strange sentence.

Cannot use basic auth to ping Azure Container Registry

string username = "xxxxtestacr";
string password = "xxxxxx";
string server = "xxxxtestacr.azurecr.io";

 var configuration = new RegistryClientConfiguration(server);
 AuthenticationProvider provider = new PasswordOAuthAuthenticationProvider(username, password);
 using var client = configuration.CreateClient(provider);
 client.System.PingAsync().Wait();

I wrote the above sample code to try to ping Azure Container Registry using basic auth.
But the result shows:

Unhandled exception. System.AggregateException: One or more errors occurred. (Docker API responded with status code=Unauthorized)
---> Docker.Registry.DotNet.Registry.UnauthorizedApiException: Docker API responded with status code=Unauthorized
at Docker.Registry.DotNet.Registry.NetworkClient.<>c.<.ctor>b__7_0(RegistryApiResponse r)
at Docker.Registry.DotNet.Registry.NetworkClient.HandleIfErrorResponse(RegistryApiResponse response)
at Docker.Registry.DotNet.Registry.NetworkClient.MakeRequestAsync(CancellationToken cancellationToken, HttpMethod method, String path, IQueryString queryString, IDictionary2 headers, Func1 content)
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at playground.Program.Main(String[] args) in C:\Users\xuycao\source\repos\playground\playground\Program.cs:line 34

May I know the reason for this failure?

[Authentication]405 Method not allowed

Due to the change of #13 , the authentication of OAuthClient is interrupted and the authentication mode of

var queryString = new QueryString();
queryString.AddIfNotEmpty("service", service);
queryString.AddIfNotEmpty("scope", scope);
var builder = new UriBuilder(new Uri(realm))
{
Query = queryString.GetQueryString()
};
var request = new HttpRequestMessage(HttpMethod.Get, builder.Uri);
if (username != null && password != null)
{
// https://gist.github.com/jlhawn/8f218e7c0b14c941c41f
var bytes = Encoding.UTF8.GetBytes($"{username}:{password}");
var parameter = Convert.ToBase64String(bytes);
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", parameter);
}
is missing

How to read full manifest, not only layers?

Hello, your program working fine, but read only a part of information. For example, I see as manifest only this info:
Registry_12312021_031448-1
However I need full information, including history, like this
Registry_12312021_031300-1
Registry_12312021_031957-1

Is this possible to read full manifest?

Unable to write own AuthenticationProvider

Trying to write Basic auth provider but it won't compile. I believe because the abstract methods are marked internal. Sample code

public class BasicAuthProvider : AuthenticationProvider
	{
		private string _user;
		private string _password;

		public BasicAuthProvider(string user, string password)
		{
			_user = user;
			_password = password;
		}

		override Task AuthenticateAsync(HttpRequestMessage request)
		{
			return Task.CompletedTask;
		}

		override Task AuthenticateAsync(HttpRequestMessage request, HttpResponseMessage response)
		{
			return Task.CompletedTask;
		}
	}

GetManifestAsync does not work with docker plugins

To install a docker plugin, one uses something like:

docker_plugin_reference="grafana/loki-docker-driver:2.2.1"
docker plugin install \
  --disable \
  --grant-all-permissions \
  --alias "$docker_plugin_reference" \
  "$docker_plugin_reference" \
    LOG_LEVEL=debug

And this is how the docker daemon contacts the docker hub registry and is able to download the image manifest:

image

And this is how this library GetManifestAsync does it but fails to download the image manifest:

image

The difference is, the docker daemon first manifest request uses a HEAD request to translate the manifest reference from the version 2.2.1 to the digest sha256:c7cf4544f8eee4e9d55e701e01f6ec5a290a807f0e75dfaf14ec463e3d973963 (which it obtained from the HEAD response docker-content-digest header), and only then, it uses a GET request to obtain the actual manifest.

I think this library should be changed to behave the same way.

What happened to DeleteManifestAsync?

Updated to 1.1.33 from 1.1.15 and the IManifestOperations.DeleteManifestAsync no longer exists and there is no mention of why in the commit? This method was marked with [PublicApi].

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.