-
Notifications
You must be signed in to change notification settings - Fork 193
ACR-based SDK distribution #2837
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
Merged
Merged
Changes from all commits
Commits
Show all changes
87 commits
Select commit
Hold shift + click to select a range
e6e98cd
feat: Oryx SDK regional distribution — pull SDKs from ACR
43067b3
feat: Add ACR-based SDK distribution with feature flag
56e8f6d
refactor: Simplify ExternalAcrSdkProvider - let LWASv2 handle image r…
b38884d
refactor: Remove script-based ACR publish (moved to AAPT-Antares-Oryx…
faa6b2d
fix: Default ACR SDK registry to oryxacr.azurecr.io
505580f
fix: Resolve StyleCop analyzer errors in ACR SDK provider files
3a88dfe
fix: Resolve StyleCop analyzer errors in ACR SDK provider files
78c75d3
latest pull
kumaraksh1 cf20ab6
Feature/oryx sdk acr distribution sdks resolver (#2842)
kumaraksh1 962a3a3
fix build and tests (#2843)
kumaraksh1 7d8e4ea
fix to fetch from acr (#2844)
kumaraksh1 ccafe60
Update version providers (#2845)
kumaraksh1 4f0262e
Refactor version providers (#2846)
kumaraksh1 0b24751
Fix acr version info (#2848)
kumaraksh1 061b3c9
Changes for php composer (#2849)
kumaraksh1 268a682
Clean dead code (#2850)
kumaraksh1 c2e1e23
Fix priroity in sdk resolver (#2851)
kumaraksh1 dd2367f
Fix Uts and version providers (#2852)
kumaraksh1 c427f24
ACR Sdk provider refactor (#2854)
kumaraksh1 f9de4e6
registryclient improvements
sarsharma 7e429cb
Merge branch 'feature/oryx-sdk-acr-distribution' of https://github.co…
sarsharma 8ae6264
fix build issue
sarsharma bda3623
Add changes foe external ACR provider (#2855)
kumaraksh1 04e1b11
Change flag name for external acr case (#2856)
kumaraksh1 77d9f99
Handle multiplatform (#2857)
kumaraksh1 6808271
Revert "Handle multiplatform (#2857)" (#2858)
kumaraksh1 476b64f
Disable external ACR for multiplatform (#2859)
kumaraksh1 dda3a96
Fix test case (#2860)
kumaraksh1 eb2f4e8
Refactor external acr provider (#2862)
kumaraksh1 69cd61e
update externalacrsdkprovider contract
sarsharma df51c58
Align ExternalAcrSdkProvider and ExternalAcrVersionProviderBase with …
8a56014
update logic for dotnet and default versions
sarsharma 5d8b2f7
update logic for dotnet and default versions (#2864)
sarsharma aed87c7
Merge branch 'feature/oryx-sdk-acr-distribution' of https://github.co…
sarsharma 03e68ed
Refactor code for new acr way (#2863)
kumaraksh1 1516468
nit fix (#2865)
kumaraksh1 4611ff7
Refactor ACR SDK provider to return tarball path
sarsharma e10bcf5
ACR SDK distribution: Refactor direct acr sdk fetching logic (#2866)
sarsharma 1e804be
Merge branch 'feature/oryx-sdk-acr-distribution' of https://github.co…
sarsharma 693727d
Cleanup startupscriptgen and refactor ACR SDK distribution constants
sarsharma 6e2c252
ACR Sdk distribution: Cleanup startupscriptgenerator and fix image re…
sarsharma 402f206
Merge branch 'feature/oryx-sdk-acr-distribution' of https://github.co…
sarsharma 41991b1
Refactor ACR SDK provider methods to return boolean status and update…
sarsharma b7b98ee
Update version provider logic to check for external SDK provider option
sarsharma e839939
ACR Sdk distribution: Fix failure path for acr sdk fetching (#2868)
sarsharma ea20742
Update version provider fallback (#2872)
kumaraksh1 482a3d3
Update fallback logic for sdks (#2873)
kumaraksh1 0509648
Merge branch 'feature/oryx-sdk-acr-distribution' of https://github.co…
sarsharma c92c90b
version map fix
sarsharma bea56ef
fix externalacrprovider for dotnet
sarsharma f7d8970
ACR Sdk distribution: fix external ACR sdk provider for dotnet (#2874)
sarsharma 82bbdc1
Feature/oryx sdk acr distribution fix phpand composer (#2875)
kumaraksh1 cf85f1f
Enhance OciRegistryClient to support anonymous token acquisition for …
sarsharma e65ab64
add logging
sarsharma d1f430e
Merge branch 'feature/oryx-sdk-acr-distribution' of https://github.co…
sarsharma 5dffc25
Acr SDK Distribution: Add token for listing sdk images (#2876)
sarsharma 25e09ff
fix build
sarsharma 12679b1
Merge branch 'feature/oryx-sdk-acr-distribution' of https://github.co…
sarsharma 82750e0
suppress auth header from logs
sarsharma 6927662
fix socket paths
sarsharma b888008
Add a method to fetch all versions for a platform (#2877)
kumaraksh1 0ff88ac
fix fallback flow
sarsharma 37b2f4f
Merge branch 'feature/oryx-sdk-acr-distribution' of https://github.co…
sarsharma 6530647
logging fixes
sarsharma 10b4488
logging fixes (#2878)
sarsharma e8338e7
fix tar extraction and add more logging
sarsharma f652350
Merge branch 'feature/oryx-sdk-acr-distribution' of https://github.co…
sarsharma 81c204d
fix dotnet image pull
sarsharma ea1d124
handle gzip stream
sarsharma a23d473
fix php installationscript duplication
sarsharma 6a035c6
ACR Sdk dist: Enhancements for cache management (#2889)
sarsharma 1aee0e1
Feature/oryx sdk acr distribution pr review 1 (#2888)
kumaraksh1 f149c27
Fix UTs
kumaraksh1 2750adc
ACR SDK dist: Add tests, refactoring and some fixes (#2892)
sarsharma ac413ec
Fix composer logic (#2893)
kumaraksh1 f423409
fix build (#2894)
kumaraksh1 2f2b67d
Add .NET SDK versions and composerVersion to constants.yml
2847957
ACR SDK dist: Refactor version provider and bump up dependencies (#2895)
sarsharma 0bad95a
ACR SDK dist: Additional test cases (#2896)
sarsharma 73aafda
follow existing pattern for php composer, add more tests
sarsharma dd1484f
Revert "Add .NET SDK versions and composerVersion to constants.yml"
3e7b7ae
update comment
sarsharma 52bc0e2
Add VERSIONS_TO_BUILD_OVERRIDE to force-build specific SDK versions (…
CodingIsBliss bf4bb4a
resolve comments
kumaraksh1 357df9a
nit
kumaraksh1 134eb16
fix comment
sarsharma 6c24341
Merge branch 'feature/oryx-sdk-acr-distribution' of https://github.co…
sarsharma File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
src/BuildScriptGenerator.Common/SdkImageRepositoryHelper.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // -------------------------------------------------------------------------------------------- | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT license. | ||
| // -------------------------------------------------------------------------------------------- | ||
|
|
||
| namespace Microsoft.Oryx.BuildScriptGenerator.Common | ||
| { | ||
| public static class SdkImageRepositoryHelper | ||
| { | ||
| /// <summary> | ||
| /// Maps a platform name to its OCI SDK image repository path. | ||
| /// e.g. "nodejs" → "oryx/nodejs-sdk", "php" → "oryx/php-sdk". | ||
| /// Final image ref: mcr.microsoft.com/oryx/nodejs-sdk:bookworm-20.20.2 | ||
| /// </summary> | ||
| public static string GetSdkImageRepository(string platformName, string prefix = null) | ||
| { | ||
| prefix = string.IsNullOrEmpty(prefix) ? SdkStorageConstants.DefaultAcrSdkRepositoryPrefix : prefix; | ||
| return $"{prefix}/{platformName}-sdk"; | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,212 @@ | ||
| // -------------------------------------------------------------------------------------------- | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT license. | ||
| // -------------------------------------------------------------------------------------------- | ||
|
|
||
| using System; | ||
| using System.Formats.Tar; | ||
| using System.IO; | ||
| using System.IO.Compression; | ||
| using System.Threading.Tasks; | ||
| using Microsoft.Extensions.Logging; | ||
| using Microsoft.Extensions.Options; | ||
| using Microsoft.Oryx.BuildScriptGenerator.Common; | ||
|
|
||
| namespace Microsoft.Oryx.BuildScriptGenerator | ||
| { | ||
| /// <summary> | ||
| /// Fetches SDK tarballs directly from an OCI container registry. | ||
| /// SDK images are single-layer <c>FROM scratch</c> images containing a single | ||
| /// <c>.tar.gz</c> SDK file. The OCI layer blob is a tar archive of the image | ||
| /// filesystem, so this provider downloads the layer, extracts the inner SDK | ||
| /// tarball from it, and caches it locally. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// Makes direct HTTP calls to the registry (no Unix socket). | ||
| /// See <see cref="ExternalAcrSdkProvider"/> for the socket-based variant. | ||
| /// </remarks> | ||
| public class AcrSdkProvider : IAcrSdkProvider | ||
| { | ||
| private readonly ILogger<AcrSdkProvider> logger; | ||
| private readonly IStandardOutputWriter outputWriter; | ||
| private readonly BuildScriptGeneratorOptions options; | ||
| private readonly OciRegistryClient ociClient; | ||
|
|
||
| public AcrSdkProvider( | ||
| IStandardOutputWriter outputWriter, | ||
| ILogger<AcrSdkProvider> logger, | ||
| IOptions<BuildScriptGeneratorOptions> options, | ||
| OciRegistryClient ociClient) | ||
| { | ||
| this.logger = logger; | ||
| this.outputWriter = outputWriter; | ||
| this.options = options.Value; | ||
| this.ociClient = ociClient; | ||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| public async Task<bool> RequestSdkFromAcrAsync(string platformName, string version, string debianFlavor, string runtimeVersion = null) | ||
| { | ||
| if (string.IsNullOrEmpty(platformName)) | ||
| { | ||
| throw new ArgumentException("Platform name cannot be null or empty.", nameof(platformName)); | ||
| } | ||
|
|
||
| if (string.IsNullOrEmpty(version)) | ||
| { | ||
| throw new ArgumentException("Version cannot be null or empty.", nameof(version)); | ||
| } | ||
|
|
||
| if (string.IsNullOrEmpty(debianFlavor)) | ||
| { | ||
| debianFlavor = this.options.DebianFlavor ?? "bookworm"; | ||
| } | ||
|
|
||
| var repository = SdkImageRepositoryHelper.GetSdkImageRepository(platformName, this.options.OryxAcrSdkRepositoryPrefix); | ||
| var tag = string.IsNullOrEmpty(runtimeVersion) | ||
| ? $"{debianFlavor}-{version}" | ||
| : $"{debianFlavor}-{version}_{runtimeVersion}"; | ||
| var blobName = $"{platformName}-{debianFlavor}-{version}.tar.gz"; | ||
|
|
||
| this.logger.LogInformation( | ||
| "Requesting SDK from ACR: {Repository}:{Tag}", | ||
| repository, | ||
| tag); | ||
| this.outputWriter.WriteLine( | ||
| $"Requesting SDK from ACR: {repository}:{tag}"); | ||
|
|
||
| // Download to the writable dynamic install directory, NOT /var/OryxSdks (read-only external mount). | ||
| var downloadDir = Path.Combine(this.options.DynamicInstallRootDir, platformName); | ||
| var tarballPath = Path.Combine(downloadDir, blobName); | ||
| var digestPath = Path.Combine(downloadDir, $".{blobName}.digest"); | ||
|
|
||
| try | ||
| { | ||
| // Get image manifest | ||
| var remoteDigest = await this.ociClient.GetManifestDigestAsync(repository, tag); | ||
|
|
||
| // Check if cached tarball is still fresh | ||
| if (File.Exists(tarballPath) && File.Exists(digestPath) && remoteDigest != null) | ||
| { | ||
| var localDigest = File.ReadAllText(digestPath).Trim(); | ||
| if (string.Equals(localDigest, remoteDigest, StringComparison.OrdinalIgnoreCase)) | ||
| { | ||
| this.logger.LogInformation( | ||
| "SDK cache is fresh (digest match): {FilePath}", | ||
| tarballPath); | ||
| this.outputWriter.WriteLine( | ||
| $"SDK tarball already cached and fresh at {tarballPath}"); | ||
| return true; | ||
| } | ||
|
|
||
| this.logger.LogInformation( | ||
| "SDK cache is stale (digest mismatch). Re-downloading."); | ||
| } | ||
|
|
||
| // Get manifest → extract single layer digest | ||
| var manifest = await this.ociClient.GetManifestAsync(repository, tag); | ||
| var layerDigest = OciRegistryClient.GetFirstLayerDigest(manifest); | ||
|
|
||
| if (string.IsNullOrEmpty(layerDigest)) | ||
| { | ||
| this.logger.LogWarning( | ||
| "No layer found in manifest for {Repository}:{Tag}", | ||
| repository, | ||
| tag); | ||
| this.outputWriter.WriteLine($"No layer found in ACR manifest for {platformName} {version}."); | ||
| return false; | ||
| } | ||
|
|
||
| Directory.CreateDirectory(downloadDir); | ||
|
|
||
| // 2. Download the OCI layer blob to a temp file. | ||
| // The layer is a tar archive of the image filesystem (not the SDK tarball itself). | ||
| var layerTempPath = Path.Combine(downloadDir, $".layer-{Guid.NewGuid():N}.tmp"); | ||
| try | ||
| { | ||
| var downloadSuccess = await this.ociClient.DownloadLayerBlobAsync( | ||
| repository, | ||
| layerDigest, | ||
| layerTempPath); | ||
|
|
||
| if (!downloadSuccess) | ||
| { | ||
| this.logger.LogWarning( | ||
| "ACR SDK pull failed digest verification: {Repository}:{Tag}", | ||
| repository, | ||
| tag); | ||
| this.outputWriter.WriteLine( | ||
| $"Failed to pull SDK from ACR (digest mismatch): {platformName} {version}"); | ||
| return false; | ||
| } | ||
|
|
||
| // 3. Extract the inner SDK .tar.gz from the layer tar. | ||
| // The image is FROM scratch with a single COPY of the SDK tarball, | ||
| // so the layer contains the .tar.gz as a top-level entry. | ||
| this.ExtractFileFromTar(layerTempPath, tarballPath, blobName); | ||
| } | ||
| finally | ||
| { | ||
| // Always clean up the temporary layer file | ||
| if (File.Exists(layerTempPath)) | ||
| { | ||
| File.Delete(layerTempPath); | ||
| } | ||
| } | ||
|
|
||
| this.logger.LogInformation( | ||
| "Successfully pulled SDK from ACR: {Repository}:{Tag} → {FilePath}", | ||
| repository, | ||
| tag, | ||
| tarballPath); | ||
| this.outputWriter.WriteLine( | ||
| $"Successfully pulled SDK from ACR: {platformName} {version}"); | ||
|
|
||
| // Write manifest digest sidecar for future freshness checks | ||
| if (!string.IsNullOrEmpty(remoteDigest)) | ||
| { | ||
| File.WriteAllText(digestPath, remoteDigest); | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| this.logger.LogError( | ||
| ex, | ||
| "Error pulling SDK from ACR: {Repository}:{Tag}", | ||
| repository, | ||
| tag); | ||
| this.outputWriter.WriteLine( | ||
| $"Error pulling SDK from ACR: {platformName} {version}: {ex.Message}"); | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Extracts the expected SDK .tar.gz file from an OCI layer tar archive. | ||
| /// OCI layers use media type "application/vnd.docker.image.rootfs.diff.tar.gzip", | ||
| /// so the blob must be decompressed before reading tar entries. | ||
| /// </summary> | ||
| private void ExtractFileFromTar(string layerPath, string outputPath, string expectedFileName) | ||
kumaraksh1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| using (var stream = File.OpenRead(layerPath)) | ||
| using (var gzipStream = new GZipStream(stream, CompressionMode.Decompress)) | ||
| using (var tarReader = new TarReader(gzipStream)) | ||
| { | ||
| TarEntry entry; | ||
| while ((entry = tarReader.GetNextEntry()) != null) | ||
| { | ||
| var name = entry.Name.TrimStart('.', '/'); | ||
| if (entry.DataStream != null && name.Equals(expectedFileName, StringComparison.OrdinalIgnoreCase)) | ||
| { | ||
| entry.ExtractToFile(outputPath, overwrite: true); | ||
| return; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| throw new InvalidOperationException($"Expected entry '{expectedFileName}' not found in OCI layer: {layerPath}"); | ||
| } | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.