-
Notifications
You must be signed in to change notification settings - Fork 193
Expand file tree
/
Copy pathAcrVersionProviderBase.cs
More file actions
101 lines (87 loc) · 3.98 KB
/
AcrVersionProviderBase.cs
File metadata and controls
101 lines (87 loc) · 3.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// --------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
// --------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Oryx.BuildScriptGenerator.Common;
namespace Microsoft.Oryx.BuildScriptGenerator
{
/// <summary>
/// Base class for ACR-based SDK version providers. Parallel to <see cref="SdkStorageVersionProviderBase"/>
/// but discovers versions via OCI Distribution API (tag listing) instead of
/// Azure Blob Storage listing with XML metadata.
/// Default versions come from local per-flavor constants rather than ACR image labels.
/// </summary>
public class AcrVersionProviderBase
{
private readonly ILogger logger;
private readonly string debianFlavor;
private readonly string repositoryPrefix;
public AcrVersionProviderBase(
IOptions<BuildScriptGeneratorOptions> commonOptions,
IHttpClientFactory httpClientFactory,
ILoggerFactory loggerFactory)
{
var options = commonOptions.Value;
this.logger = loggerFactory.CreateLogger(this.GetType());
this.debianFlavor = options.DebianFlavor;
this.repositoryPrefix = options.OryxAcrSdkRepositoryPrefix;
var registryUrl = string.IsNullOrEmpty(options.OryxAcrSdkRegistryUrl)
? SdkStorageConstants.DefaultAcrSdkRegistryUrl
: options.OryxAcrSdkRegistryUrl;
this.OciClient = new OciRegistryClient(registryUrl, httpClientFactory, loggerFactory);
}
protected OciRegistryClient OciClient { get; }
/// <summary>
/// Lists available versions for a platform from ACR tags and resolves the default
/// version from the supplied per-flavor dictionary.
/// </summary>
protected PlatformVersionInfo GetAvailableVersionsFromAcr(
string platformName,
Dictionary<string, string> defaultVersionPerFlavor)
{
var repository = SdkStorageConstants.GetSdkImageRepository(platformName, this.repositoryPrefix);
this.logger.LogDebug("Getting available versions for {platformName} from ACR repository {repository}.", platformName, repository);
var allTags = this.GetTags(repository);
var supportedVersions = this.FilterVersionTags(allTags);
string defaultVersion = null;
if (defaultVersionPerFlavor != null &&
!string.IsNullOrEmpty(this.debianFlavor) &&
defaultVersionPerFlavor.TryGetValue(this.debianFlavor, out var version))
{
defaultVersion = version;
}
this.logger.LogDebug(
"Found {count} versions for {platformName} on ACR (default: {default}).",
supportedVersions.Count,
platformName,
defaultVersion ?? "none");
return PlatformVersionInfo.CreateAvailableOnAcr(supportedVersions, defaultVersion);
}
private List<string> GetTags(string repository)
{
try
{
return this.OciClient.GetAllTagsAsync(repository).GetAwaiter().GetResult();
}
catch (Exception ex)
{
this.logger.LogError(ex, "Failed to get tags from ACR for {repository}.", repository);
throw;
}
}
private List<string> FilterVersionTags(List<string> allTags)
{
var prefix = $"{this.debianFlavor}-";
return allTags
.Where(t => t.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
.Select(t => t.Substring(prefix.Length))
.ToList();
}
}
}