Skip to content

Commit 9705deb

Browse files
Managed Dependencies is not supported on Legion (#945) (#946)
* Error out if the user tries to install modules via Managed Dependencies on Legion * Moved logic to help figure out if we are running in Azure to a helper class * Add test case to validate that we do not throw on Legion when requirements.psd1 has no entries * Add Managed Dependencies is not supported on Legion test case
1 parent 358aa2d commit 9705deb

File tree

5 files changed

+111
-15
lines changed

5 files changed

+111
-15
lines changed

src/DependencyManagement/DependencyManager.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ internal string Initialize(ILogger logger)
105105
return null;
106106
}
107107

108+
if (WorkerEnvironment.IsLinuxConsumptionOnLegion())
109+
{
110+
throw new NotSupportedException(PowerShellWorkerStrings.ManagedDependenciesIsNotSupportedOnLegion);
111+
}
112+
108113
_currentSnapshotPath = _installedDependenciesLocator.GetPathWithAcceptableDependencyVersionsInstalled()
109114
?? _storage.CreateNewSnapshotPath();
110115

src/DependencyManagement/ManagedDependenciesPathDetector.cs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@ namespace Microsoft.Azure.Functions.PowerShellWorker.DependencyManagement
1010
{
1111
internal static class ManagedDependenciesPathDetector
1212
{
13-
// Environment variables to help figure out if we are running in Azure.
14-
private const string AzureWebsiteInstanceId = "WEBSITE_INSTANCE_ID";
15-
private const string ContainerName = "CONTAINER_NAME";
16-
1713
private const string HomeDriveName = "HOME";
1814
private const string DataFolderName = "data";
1915

@@ -31,7 +27,7 @@ internal static class ManagedDependenciesPathDetector
3127
public static string GetManagedDependenciesPath(string functionAppRootPath)
3228
{
3329
// If we are running in Azure App Service or Linux Consumption use the 'HOME\data' path.
34-
if (IsAppService() || IsLinuxConsumption())
30+
if (WorkerEnvironment.IsAppService() || WorkerEnvironment.IsLinuxConsumption())
3531
{
3632
var homeDriveVariable = Environment.GetEnvironmentVariable(HomeDriveName);
3733
if (string.IsNullOrEmpty(homeDriveVariable))
@@ -48,15 +44,5 @@ public static string GetManagedDependenciesPath(string functionAppRootPath)
4844
string appDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData, Environment.SpecialFolderOption.DoNotVerify);
4945
return Path.Combine(appDataFolder, AzureFunctionsFolderName, functionAppName, ManagedDependenciesFolderName);
5046
}
51-
52-
private static bool IsAppService()
53-
{
54-
return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable(AzureWebsiteInstanceId));
55-
}
56-
57-
private static bool IsLinuxConsumption()
58-
{
59-
return !IsAppService() && !string.IsNullOrEmpty(Environment.GetEnvironmentVariable(ContainerName));
60-
}
6147
}
6248
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace Microsoft.Azure.Functions.PowerShellWorker.DependencyManagement
8+
{
9+
/// <summary>
10+
/// Hold information about the environment.
11+
/// </summary>
12+
internal static class WorkerEnvironment
13+
{
14+
// Environment variables to help figure out if we are running in Azure.
15+
private const string AzureWebsiteInstanceId = "WEBSITE_INSTANCE_ID";
16+
private const string ContainerName = "CONTAINER_NAME";
17+
private const string LegionServiceHost = "LEGION_SERVICE_HOST";
18+
19+
public static bool IsAppService()
20+
{
21+
return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable(AzureWebsiteInstanceId));
22+
}
23+
24+
public static bool IsLinuxConsumption()
25+
{
26+
return !IsAppService() && !string.IsNullOrEmpty(Environment.GetEnvironmentVariable(ContainerName));
27+
}
28+
29+
public static bool IsLinuxConsumptionOnLegion()
30+
{
31+
return !IsAppService() &&
32+
!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(ContainerName)) &&
33+
!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(LegionServiceHost));
34+
}
35+
}
36+
}

src/resources/PowerShellWorkerStrings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,4 +376,7 @@
376376
<data name="UtilizingExternalDurableSDK" xml:space="preserve">
377377
<value>Utilizing external Durable Functions SDK: '{0}'.</value>
378378
</data>
379+
<data name="ManagedDependenciesIsNotSupportedOnLegion" xml:space="preserve">
380+
<value>Managed Dependencies is not supported in Linux Consumption on Legion. Please remove all module references from requirements.psd1 and include the function app dependencies with the function app content. For more information, please see https://aka.ms/functions-powershell-include-modules.</value>
381+
</data>
379382
</root>

test/Unit/DependencyManagement/DependencyManagerTests.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,72 @@ public void Initialize_ReturnsNewSnapshotPath_WhenNoAcceptableDependencyVersions
5050
}
5151
}
5252

53+
[Fact]
54+
public void Initialize_Throws_WhenDependenciesAreDefinedInRequirementsPsd1_OnLegion()
55+
{
56+
const string ContainerName = "CONTAINER_NAME";
57+
const string LegionServiceHost = "LEGION_SERVICE_HOST";
58+
const string AzureWebsiteInstanceId = "WEBSITE_INSTANCE_ID";
59+
60+
try
61+
{
62+
Environment.SetEnvironmentVariable(AzureWebsiteInstanceId, null);
63+
Environment.SetEnvironmentVariable(ContainerName, "MY_CONTAINER_NAME");
64+
Environment.SetEnvironmentVariable(LegionServiceHost, "MY_LEGION_SERVICE_HOST");
65+
66+
_mockStorage.Setup(_ => _.GetDependencies()).Returns(GetAnyNonEmptyDependencyManifestEntries());
67+
68+
using (var dependencyManager = CreateDependencyManagerWithMocks())
69+
{
70+
var caughtException = Assert.Throws<DependencyInstallationException>(
71+
() => dependencyManager.Initialize(_mockLogger.Object));
72+
73+
Assert.Contains("Managed Dependencies is not supported in Linux Consumption on Legion.", caughtException.Message);
74+
Assert.Contains("https://aka.ms/functions-powershell-include-modules", caughtException.Message);
75+
}
76+
}
77+
78+
finally
79+
{
80+
Environment.SetEnvironmentVariable(ContainerName, null);
81+
Environment.SetEnvironmentVariable(LegionServiceHost, null);
82+
}
83+
}
84+
85+
[Fact]
86+
public void Initialize_NoDependenciesOnRequirementsPsd1_OnLegion_DoesNotThrow()
87+
{
88+
const string ContainerName = "CONTAINER_NAME";
89+
const string LegionServiceHost = "LEGION_SERVICE_HOST";
90+
const string AzureWebsiteInstanceId = "WEBSITE_INSTANCE_ID";
91+
92+
try
93+
{
94+
Environment.SetEnvironmentVariable(AzureWebsiteInstanceId, null);
95+
Environment.SetEnvironmentVariable(ContainerName, "MY_CONTAINER_NAME");
96+
Environment.SetEnvironmentVariable(LegionServiceHost, "MY_LEGION_SERVICE_HOST");
97+
98+
_mockStorage.Setup(_ => _.GetDependencies()).Returns(new DependencyManifestEntry[0]);
99+
100+
using (var dependencyManager = CreateDependencyManagerWithMocks())
101+
{
102+
var dependenciesPath = dependencyManager.Initialize(_mockLogger.Object);
103+
104+
Assert.Null(dependenciesPath);
105+
VerifyMessageLogged(LogLevel.Warning, PowerShellWorkerStrings.FunctionAppDoesNotHaveRequiredModulesToInstall, expectedIsUserLog: true);
106+
107+
_mockBackgroundDependencySnapshotMaintainer.VerifyNoOtherCalls();
108+
_mockNewerDependencySnapshotDetector.VerifyNoOtherCalls();
109+
}
110+
}
111+
112+
finally
113+
{
114+
Environment.SetEnvironmentVariable(ContainerName, null);
115+
Environment.SetEnvironmentVariable(LegionServiceHost, null);
116+
}
117+
}
118+
53119
[Fact]
54120
public void Initialize_ReturnsExistingSnapshotPath_WhenAcceptableDependencyVersionsAlreadyInstalled()
55121
{

0 commit comments

Comments
 (0)