changemakerstudios / docker.registry.dotnet Goto Github PK
View Code? Open in Web Editor NEW.NET (C#) Client Library for Docker Registry API V2
License: Apache License 2.0
.NET (C#) Client Library for Docker Registry API V2
License: Apache License 2.0
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;
}
}
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].
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, Func
1 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?
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:
And this is how this library GetManifestAsync
does it but fails to download the image manifest:
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.
Switching to Actions allows easier modification of build and easier control since it's all on Github.
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.
https://github.com/ChangemakerStudios/Docker.Registry.DotNet/blob/master/src/Docker.Registry.DotNet/Authentication/AuthenticateParser.cs#L14 assumes that there are no commas within quoted segments of the header.
In practice the following (obfuscated) string is breaking for me:
WWW-Authenticate: Bearer realm="https://containers.bigfish.com/v2/auth",service="containers.bigfish.com",scope="repository:myorg/my-repository:pull,push"
Run the tests before publishing
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'.
see:
NetworkClient Not Dispose...
It doesn't currently function. Just need some effort to make a good sample.
Is there a reason why I can't access BlobUploads via IRegsitryClient (but can if I cast to RegistryClient) ?
Due to the change of #13 , the authentication of OAuthClient
is interrupted and the authentication mode of
Is it possible to remove an existing tag? The only method I can see to do with tags is ListImageTagsAsync.
Thank you!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.