-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for the New PowerShell Programming Model
- Loading branch information
1 parent
565ea8b
commit 887c882
Showing
6 changed files
with
235 additions
and
16 deletions.
There are no files selected for viewing
This file contains 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 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 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,59 @@ | ||
// | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
// | ||
|
||
using Microsoft.Azure.WebJobs.Script.Grpc.Messages; | ||
using Newtonsoft.Json; | ||
using Newtonsoft.Json.Linq; | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace Microsoft.Azure.Functions.PowerShellWorker.WorkerIndexing | ||
{ | ||
internal class BindingInformation | ||
{ | ||
private const string BindingNameKey = "name"; | ||
private const string BindingDirectionKey = "direction"; | ||
private const string BindingTypeKey = "type"; | ||
public enum Directions | ||
{ | ||
Unknown = -1, | ||
In = 0, | ||
Out = 1, | ||
Inout = 2 | ||
} | ||
|
||
public Directions Direction { get; set; } = Directions.Unknown; | ||
public string Type { get; set; } = ""; | ||
public string Name { get; set; } = ""; | ||
public Dictionary<string, Object> otherInformation { get; set; } = new Dictionary<string, Object>(); | ||
|
||
internal string ConvertToRpcRawBinding(out BindingInfo bindingInfo) | ||
{ | ||
string rawBinding = string.Empty; | ||
JObject rawBindingObject = new JObject(); | ||
rawBindingObject.Add(BindingNameKey, Name); | ||
BindingInfo outInfo = new BindingInfo(); | ||
|
||
|
||
if (Direction == Directions.Unknown) | ||
{ | ||
throw new Exception(string.Format(PowerShellWorkerStrings.InvalidBindingInfoDirection, Name)); | ||
} | ||
outInfo.Direction = (BindingInfo.Types.Direction)Direction; | ||
rawBindingObject.Add(BindingDirectionKey, Enum.GetName(typeof(BindingInfo.Types.Direction), outInfo.Direction).ToLower()); | ||
outInfo.Type = Type; | ||
rawBindingObject.Add(BindingTypeKey, Type); | ||
|
||
foreach (KeyValuePair<string, Object> pair in otherInformation) | ||
{ | ||
rawBindingObject.Add(pair.Key, JToken.FromObject(pair.Value)); | ||
} | ||
|
||
rawBinding = JsonConvert.SerializeObject(rawBindingObject); | ||
bindingInfo = outInfo; | ||
return rawBinding; | ||
} | ||
} | ||
} |
This file contains 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,40 @@ | ||
// | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
// | ||
|
||
using Microsoft.Azure.WebJobs.Script.Grpc.Messages; | ||
using System.Collections.Generic; | ||
|
||
namespace Microsoft.Azure.Functions.PowerShellWorker.WorkerIndexing | ||
{ | ||
internal class FunctionInformation | ||
{ | ||
private const string FunctionLanguagePowerShell = "powershell"; | ||
|
||
public string Directory { get; set; } = ""; | ||
public string ScriptFile { get; set; } = ""; | ||
public string Name { get; set; } = ""; | ||
public string EntryPoint { get; set; } = ""; | ||
public string FunctionId { get; set; } = ""; | ||
public List<BindingInformation> Bindings { get; set; } = new List<BindingInformation>(); | ||
|
||
internal RpcFunctionMetadata ConvertToRpc() | ||
{ | ||
RpcFunctionMetadata returnMetadata = new RpcFunctionMetadata(); | ||
returnMetadata.FunctionId = FunctionId; | ||
returnMetadata.Directory = Directory; | ||
returnMetadata.EntryPoint = EntryPoint; | ||
returnMetadata.Name = Name; | ||
returnMetadata.ScriptFile = ScriptFile; | ||
returnMetadata.Language = FunctionLanguagePowerShell; | ||
foreach(BindingInformation binding in Bindings) | ||
{ | ||
string rawBinding = binding.ConvertToRpcRawBinding(out BindingInfo bindingInfo); | ||
returnMetadata.Bindings.Add(binding.Name, bindingInfo); | ||
returnMetadata.RawBindings.Add(rawBinding); | ||
} | ||
return returnMetadata; | ||
} | ||
} | ||
} |
This file contains 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,71 @@ | ||
// | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
// | ||
|
||
using Microsoft.Azure.WebJobs.Script.Grpc.Messages; | ||
using Newtonsoft.Json; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Management.Automation; | ||
using System.Management.Automation.Runspaces; | ||
|
||
namespace Microsoft.Azure.Functions.PowerShellWorker.WorkerIndexing | ||
{ | ||
internal class WorkerIndexingHelper | ||
{ | ||
const string GetFunctionsMetadataCmdletName = "AzureFunctions.PowerShell.SDK\\Get-FunctionsMetadata"; | ||
internal static IEnumerable<RpcFunctionMetadata> IndexFunctions(string baseDir) | ||
{ | ||
List<RpcFunctionMetadata> indexedFunctions = new List<RpcFunctionMetadata>(); | ||
|
||
// This is not the correct way to deal with getting a runspace for the cmdlet. | ||
|
||
// Firstly, creating a runspace is expensive. If we are going to generate a runspace, it should be done on | ||
// the function load request so that it can be created while the host is processing. | ||
|
||
// Secondly, this assumes that the AzureFunctions.PowerShell.SDK module is present on the machine/VM's | ||
// PSModulePath. On an Azure instance, it will not be. What we need to do here is move the call | ||
// to SetupAppRootPathAndModulePath in RequestProcessor to the init request, and then use the | ||
// _firstPwshInstance to invoke the Get-FunctionsMetadata command. The only issue with this is that | ||
// SetupAppRootPathAndModulePath needs the initial function init request in order to know if managed | ||
// dependencies are enabled in this function app. | ||
|
||
// Proposed solutions: | ||
// 1. Pass ManagedDependencyEnabled flag in the worker init request | ||
// 2. Change the flow, so that _firstPwshInstance is initialized in worker init with the PSModulePath | ||
// assuming that managed dependencies are enabled, and then revert the PSModulePath in the first function | ||
// init request should the managed dependencies not be enabled. | ||
// 3. Continue using a new runspace for invoking Get-FunctionsMetadata, but initialize it in worker init and | ||
// point the PsModulePath to the module path bundled with the worker. | ||
|
||
|
||
InitialSessionState initial = InitialSessionState.CreateDefault(); | ||
Runspace runspace = RunspaceFactory.CreateRunspace(initial); | ||
runspace.Open(); | ||
System.Management.Automation.PowerShell _powershell = System.Management.Automation.PowerShell.Create(); | ||
_powershell.Runspace = runspace; | ||
|
||
_powershell.AddCommand(GetFunctionsMetadataCmdletName).AddArgument(baseDir); | ||
string outputString = string.Empty; | ||
foreach (PSObject rawMetadata in _powershell.Invoke()) | ||
{ | ||
if (outputString != string.Empty) | ||
{ | ||
throw new Exception(PowerShellWorkerStrings.GetFunctionsMetadataMultipleResultsError); | ||
} | ||
outputString = rawMetadata.ToString(); | ||
} | ||
_powershell.Commands.Clear(); | ||
|
||
List<FunctionInformation> functionInformations = JsonConvert.DeserializeObject<List<FunctionInformation>>(outputString); | ||
|
||
foreach(FunctionInformation fi in functionInformations) | ||
{ | ||
indexedFunctions.Add(fi.ConvertToRpc()); | ||
} | ||
|
||
return indexedFunctions; | ||
} | ||
} | ||
} |
This file contains 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