|
| 1 | +--- |
| 2 | +RFC: '0056' |
| 3 | +Author: Bruce Payette |
| 4 | +Status: Withdrawn |
| 5 | +SupercededBy: |
| 6 | +Version: 6.? |
| 7 | +Area: Hosting |
| 8 | +Comments Due: 01/03/2019 |
| 9 | +Plan to implement: Yes |
| 10 | +--- |
| 11 | + |
| 12 | +#PowerShell Application Mode |
| 13 | + |
| 14 | +##Motivation |
| 15 | + |
| 16 | +There is increasing need for the ability to deploy stand-alone non-interactive (embedded) PowerShell “applications”. These applications would be consumed by higher-layer services which, for various reasons, can’t run PowerShell in-process with the existing PowerShell API. |
| 17 | +Examples: |
| 18 | + |
| 19 | +- Azure Functions/AWS lambdas |
| 20 | +- Azure Stack |
| 21 | +- PowerShell language service for VSCode, etc. |
| 22 | +- Azure resource extension scripts/configurations |
| 23 | +- Puppet/Chef |
| 24 | + |
| 25 | +##Specifcation |
| 26 | + |
| 27 | +This type of PowerShell deployment differs from traditional interactive applications in a number if ways: |
| 28 | +- The functionality is likely predefined – the application is composed of a known set of scripts and modules. |
| 29 | +- This implies that only a subset of the PowerShell functionality is required. For example, the help and formatting subsystems might be unnecessary. The net result would be faster startup, reduced footprint and consequently a reduced security Surface. |
| 30 | +- Interactive debugging is not as applicable; logging is required for postmortem debugging. |
| 31 | + |
| 32 | +###Logging |
| 33 | + |
| 34 | +PowerShell provides a number of “streams” for logging style behavior however they are mostly focused on the interactive experience (verbose, error, etc.). By default, these streams are simply written to the console. Without a console, there are two things that might be done with the messages: |
| 35 | + |
| 36 | +- Embed them in the output stream. This requires the calling application to demultiples the messages (which is what the PowerShell console host does now.) Returning them in a single stream has the advantage that the messages are in the proper context. |
| 37 | +- Log the messages, with to a buffer in memory or to a file. |
| 38 | + |
| 39 | +###Packaging |
| 40 | + |
| 41 | +- Similar to ‘dotnet package’ – bundle all required resources into a directory which can be copied. |
| 42 | +- Bundle into a ‘self-installing’ exe with resources (e.g. modules) read from memory rather than disk files. (or a .zip file) |
| 43 | + |
| 44 | +###Servicing & Versioning |
| 45 | + |
| 46 | +- tbd |
| 47 | + |
| 48 | +###Security |
| 49 | + |
| 50 | +- tbd |
| 51 | + |
| 52 | +##Basic Host model (non-HTTP) |
| 53 | + |
| 54 | +- use stdin/stdout for host connection |
| 55 | +- JSON commands sent to std in, JSON objects returned from stdout. |
| 56 | +- Asynchronous “jobs” model for communication |
| 57 | +- Commands start/stop jobs or retrieve results |
| 58 | +- Results are retrieved in batches, formatted as JSON objects. |
| 59 | + |
| 60 | +An example command might look like: |
| 61 | + |
| 62 | +```JSON |
| 63 | +{ |
| 64 | + "Action" = "StartPipeline", |
| 65 | + "PipeLine" = "get-process | sort -descending | select -first 5" |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +This command, when processed by the host will immediately return a job id for the running pipeline as follows: |
| 70 | + |
| 71 | +```JSON |
| 72 | +{ |
| 73 | + "JOBID" = <id> |
| 74 | + "STATUS" = “Running” |
| 75 | +} |
| 76 | +``` |
| 77 | + To stop a running job, the parent will send a command as follows |
| 78 | + |
| 79 | +```JSON |
| 80 | +{ |
| 81 | + "Action" = "StopPipeline" |
| 82 | + "ID" = <id> |
| 83 | +} |
| 84 | +``` |
| 85 | +The host will then return a result object as follows: |
| 86 | + |
| 87 | +```JSON |
| 88 | +{ |
| 89 | + "JOBID" = <id> |
| 90 | + "STATUS" = “Succeeded” | “Failed” |
| 91 | + "ERROR" = “error string” |
| 92 | +} |
| 93 | +``` |
| 94 | +To retrieve results from a job, the parent application will send a message as follows: |
| 95 | + |
| 96 | +```JSON |
| 97 | +{ |
| 98 | + "Action" = "RecieveJob" |
| 99 | + "ID" = <id> |
| 100 | + "MaxRecords" = 500 # optional |
| 101 | +} |
| 102 | +``` |
| 103 | +If a large amount of data is expected, the parent application can specify the maximum number of records to return. Records will be buffered by the PAM host. Subsequence `ReceiveJob` calls will retrieve the next set of records from the PAM host. |
| 104 | + |
| 105 | +##Asynchronous Notification of State Changes |
| 106 | + |
| 107 | +On job state changes the PAM host will write a message to stdout |
| 108 | + |
| 109 | +```JSON |
| 110 | +{ |
| 111 | + "JOBSTATE" = “DataReady" | "Completed" | "Error" |
| 112 | + "ID" = <id> |
| 113 | +} |
| 114 | +``` |
| 115 | +##HTTP Host |
| 116 | + |
| 117 | +The HTTP host will run as a standalone HTTP application. Communication will use the same JSON messages as the basic host but over HTTP instead of stdio. |
| 118 | + |
0 commit comments