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

Update to use OCI spec APIs for Container Registry #1737

Merged
merged 1 commit into from
Oct 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 36 additions & 58 deletions src/code/ContainerRegistryServerAPICalls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ internal class ContainerRegistryServerAPICalls : ServerApiCall
const string containerRegistryOAuthTokenUrlTemplate = "https://{0}/oauth2/token"; // 0 - registry
const string containerRegistryManifestUrlTemplate = "https://{0}/v2/{1}/manifests/{2}"; // 0 - registry, 1 - repo(modulename), 2 - tag(version)
const string containerRegistryBlobDownloadUrlTemplate = "https://{0}/v2/{1}/blobs/{2}"; // 0 - registry, 1 - repo(modulename), 2 - layer digest
const string containerRegistryFindImageVersionUrlTemplate = "https://{0}/acr/v1/{1}/_tags{2}"; // 0 - registry, 1 - repo(modulename), 2 - /tag(version)
const string containerRegistryFindImageVersionUrlTemplate = "https://{0}/v2/{1}/tags/list"; // 0 - registry, 1 - repo(modulename)
const string containerRegistryStartUploadTemplate = "https://{0}/v2/{1}/blobs/uploads/"; // 0 - registry, 1 - packagename
const string containerRegistryEndUploadTemplate = "https://{0}{1}&digest=sha256:{2}"; // 0 - registry, 1 - location, 2 - digest

Expand Down Expand Up @@ -413,6 +413,7 @@ internal string GetContainerRegistryAccessToken(out ErrorRecord errRecord)
else
{
_cmdletPassedIn.WriteVerbose("Repository is unauthenticated");
return null;
}
}

Expand Down Expand Up @@ -572,27 +573,19 @@ internal async Task<HttpContent> GetContainerRegistryBlobAsync(string packageNam
/// </summary>
internal JObject FindContainerRegistryImageTags(string packageName, string version, string containerRegistryAccessToken, out ErrorRecord errRecord)
{
/* response returned looks something like:
* "registry": "myregistry.azurecr.io"
* "imageName": "hello-world"
* "tags": [
* {
* ""name"": ""1.0.0"",
* ""digest"": ""sha256:92c7f9c92844bbbb5d0a101b22f7c2a7949e40f8ea90c8b3bc396879d95e899a"",
* ""createdTime"": ""2023-12-23T18:06:48.9975733Z"",
* ""lastUpdateTime"": ""2023-12-23T18:06:48.9975733Z"",
* ""signed"": false,
* ""changeableAttributes"": {
* ""deleteEnabled"": true,
* ""writeEnabled"": true,
* ""readEnabled"": true,
* ""listEnabled"": true
* }
* }]
*/
/*
{
"name": "<name>",
"tags": [
"<tag1>",
"<tag2>",
"<tag3>"
]
}
*/
_cmdletPassedIn.WriteDebug("In ContainerRegistryServerAPICalls::FindContainerRegistryImageTags()");
string resolvedVersion = string.Equals(version, "*", StringComparison.OrdinalIgnoreCase) ? null : $"/{version}";
string findImageUrl = string.Format(containerRegistryFindImageVersionUrlTemplate, Registry, packageName, resolvedVersion);
string findImageUrl = string.Format(containerRegistryFindImageVersionUrlTemplate, Registry, packageName);
var defaultHeaders = GetDefaultHeaders(containerRegistryAccessToken);
return GetHttpResponseJObjectUsingDefaultHeaders(findImageUrl, HttpMethod.Get, defaultHeaders, out errRecord);
}
Expand Down Expand Up @@ -1664,51 +1657,36 @@ private Hashtable[] FindPackagesWithVersionHelper(string packageName, VersionTyp

foreach (var pkgVersionTagInfo in allPkgVersions)
{
using (JsonDocument pkgVersionEntry = JsonDocument.Parse(pkgVersionTagInfo.ToString()))
string pkgVersionString = pkgVersionTagInfo.ToString();
// determine if the package version that is a repository tag is a valid NuGetVersion
if (!NuGetVersion.TryParse(pkgVersionString, out NuGetVersion pkgVersion))
{
JsonElement rootDom = pkgVersionEntry.RootElement;
if (!rootDom.TryGetProperty("name", out JsonElement pkgVersionElement))
{
errRecord = new ErrorRecord(
new InvalidOrEmptyResponse($"Response does not contain version element ('name') for package '{packageName}' in '{Repository.Name}'."),
"FindNameFailure",
ErrorCategory.InvalidResult,
this);

return null;
}

string pkgVersionString = pkgVersionElement.ToString();
// determine if the package version that is a repository tag is a valid NuGetVersion
if (!NuGetVersion.TryParse(pkgVersionString, out NuGetVersion pkgVersion))
{
errRecord = new ErrorRecord(
new ArgumentException($"Version {pkgVersionString} to be parsed from metadata is not a valid NuGet version."),
"FindNameFailure",
ErrorCategory.InvalidArgument,
this);
errRecord = new ErrorRecord(
new ArgumentException($"Version {pkgVersionString} to be parsed from metadata is not a valid NuGet version."),
"FindNameFailure",
ErrorCategory.InvalidArgument,
this);

return null;
}
return null;
}

_cmdletPassedIn.WriteDebug($"'{packageName}' version parsed as '{pkgVersion}'");
_cmdletPassedIn.WriteDebug($"'{packageName}' version parsed as '{pkgVersion}'");

if (isSpecificVersionSearch)
if (isSpecificVersionSearch)
{
if (pkgVersion.ToNormalizedString() == specificVersion.ToNormalizedString())
{
if (pkgVersion.ToNormalizedString() == specificVersion.ToNormalizedString())
{
// accounts for FindVersion() scenario
sortedPkgs.Add(pkgVersion, pkgVersionString);
break;
}
// accounts for FindVersion() scenario
sortedPkgs.Add(pkgVersion, pkgVersionString);
break;
}
else
}
else
{
if (versionRange.Satisfies(pkgVersion) && (!pkgVersion.IsPrerelease || includePrerelease))
{
if (versionRange.Satisfies(pkgVersion) && (!pkgVersion.IsPrerelease || includePrerelease))
{
// accounts for FindVersionGlobbing() and FindName() scenario
sortedPkgs.Add(pkgVersion, pkgVersionString);
}
// accounts for FindVersionGlobbing() and FindName() scenario
sortedPkgs.Add(pkgVersion, pkgVersionString);
}
}
}
Expand Down
Loading