Skip to content
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

Invoke-AzContainerInstanceCommand output #15754

Closed
janegilring opened this issue Aug 26, 2021 · 15 comments
Closed

Invoke-AzContainerInstanceCommand output #15754

janegilring opened this issue Aug 26, 2021 · 15 comments
Assignees
Labels
Breaking Change Release This PR contains breaking change Container Instances customer-reported feature-request This issue requires a new behavior in the product in order be resolved. question The issue doesn't require a change to the product in order to be resolved. Most issues start as that

Comments

@janegilring
Copy link

janegilring commented Aug 26, 2021

Description

Scenario: Execute a command within an Azure Container Instances container.

By using Azure CLI, this works as expected:

PS /> az container exec --resource-group test-rg --name test-aci-01 --container-name container-01 --exec-command "date"
Thu Aug 26 04:14:18 UTC 2021

When trying to accomplish the same using Azure PowerShell, the output is not the command output - but rather a password and a websocket URI as shown below. Could it be that the Azure CLI uses these credentials to actually gather the command output, but the PowerShell command does not? If so, it would be useful if this behaviour could be change similarly to Azure CLI.

Also, it is unclear why we in the PowerShell command need to specify -TerminalSizeCol and -TerminalSizeRow, while in the Azure CLI option we do not.

Steps to reproduce

PS /> Invoke-AzContainerInstanceCommand -ResourceGroupName test-rg -ContainerGroupName test-aci-01 -ContainerName container-01 -Command "date" -TerminalSizeCol 12 -TerminalSizeRow 12

Password                         WebSocketUri
--------                         ------------
random-string wss://abc123.norwayeast.atlas.cloudapp.azure.com:19390/execstream/sessionId/80035cbc-85e8-4fec-a0af-

Environment data

PS /> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.1.3
PSEdition                      Core
GitCommitId                    7.1.3
OS                             Linux 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Module versions

ModuleType Version    PreRelease Name                                ExportedCommands
---------- -------    ---------- ----                                ----------------
Script     2.5.2                 Az.Accounts                         {Add-AzEnvironment, Clear-AzContext, Clear-AzDefault, Connect-AzAccount…}
Script     2.1.0                 Az.ContainerInstance                {Add-AzContainerInstanceOutput, Get-AzContainerGroup, Get-AzContainerInstan

Debug output

DEBUG: 06:20:55 - GetAzureRMContextCommand end processing.
DEBUG: [CmdletBeginProcessing]: Starting command
DEBUG: CmdletBeginProcessing:
DEBUG: CmdletProcessRecordStart:
DEBUG: [CmdletProcessRecordAsyncStart]: Created new QosEvent for command 'Invoke-AzContainerInstanceCommand_ExecuteExpanded'
DEBUG: CmdletProcessRecordAsyncStart:
DEBUG: CmdletGetPipeline:
DEBUG: CmdletBeforeAPICall:
DEBUG: URLCreated: /subscriptions/1234b02e-f8fd-40bd-8b6a-ed7f52778fbd/resourceGroups/test-rg/providers/Microsoft.ContainerInstance/containerGroups/aci-01/containers/container-01/exec?api-version=2021-03-01
DEBUG: RequestCreated: /subscriptions/1234b02e-f8fd-40bd-8b6a-ed7f52778fbd/resourceGroups/test-rg/providers/Microsoft.ContainerInstance/containerGroups/aci-01/containers/container-01/exec?api-version=2021-03-01
DEBUG: HeaderParametersAdded:
DEBUG: BodyContentSet:
DEBUG: ============================ HTTP REQUEST ============================

HTTP Method:
POST

Absolute Uri:
https://management.azure.com/subscriptions/1234b02e-f8fd-40bd-8b6a-ed7f52778fbd/resourceGroups/test-rg/providers/Microsoft.ContainerInstance/containerGroups/aci-01/containers/container-01/exec?api-version=2021-03-01

Headers:
x-ms-unique-id                : 2
x-ms-client-request-id        : 410e0c1b-657c-4a36-ba9c-3eaff7d4a6a3
CommandName                   : Az.ContainerInstance.internal\Invoke-AzContainerInstanceCommand
FullCommandName               : Invoke-AzContainerInstanceCommand_ExecuteExpanded
ParameterSetName              : __AllParameterSets
User-Agent                    : AzurePowershell/Az4.0.0-preview

Body:
{
  "terminalSize": {
    "rows": 12,
    "cols": 12
  },
  "command": "date"
}


DEBUG: BeforeCall:
DEBUG: ============================ HTTP RESPONSE ============================

Status Code:
OK

Headers:
Cache-Control                 : no-cache
Pragma                        : no-cache
Vary                          : Accept-Encoding
x-ms-request-id               : norwayeast:6423ba08-f3cf-47dd-923f-e100ceab4dd5
x-ms-ratelimit-remaining-subscription-writes: 1198
x-ms-correlation-request-id   : 708d1e3d-aed9-44c7-b61c-65916bc994df
x-ms-routing-request-id       : GERMANYNORTH:20210826T042057Z:708d1e3d-aed9-44c7-b61c-65916bc994df
Strict-Transport-Security     : max-age=31536000; includeSubDomains
X-Content-Type-Options        : nosniff
Date                          : Thu, 26 Aug 2021 04:20:56 GMT

Body:
{
  "webSocketUri": "wss://randomized.norwayeast.atlas.cloudapp.azure.com:19390/execstream/sessionId/871eacb5-aa1b-4f90-8b56-7eeadc0fd603?api-version=1.0&rows=12&cols=12",
  "password": "removed"
}


DEBUG: ResponseCreated:
DEBUG: BeforeResponseDispatch:

DEBUG: Finally:
DEBUG: CmdletAfterAPICall:
DEBUG: [CmdletProcessRecordAsyncEnd]: Finish HTTP process
DEBUG: CmdletProcessRecordAsyncEnd:
DEBUG: CmdletProcessRecordEnd:
DEBUG: AzureQoSEvent: Module: Az.ContainerInstance:2.1.0.0; CommandName: Invoke-AzContainerInstanceCommand_ExecuteExpanded; PSVersion: ; IsSuccess: True; Duration: 00:00:00
DEBUG: Finish sending metric.
DEBUG: CmdletEndProcessing:

Error output

N/A
@janegilring janegilring added the needs-triage This is a new issue that needs to be triaged to the appropriate team. label Aug 26, 2021
@ghost ghost added question The issue doesn't require a change to the product in order to be resolved. Most issues start as that customer-reported labels Aug 26, 2021
@dingmeng-xue dingmeng-xue added Container Instances feature-request This issue requires a new behavior in the product in order be resolved. and removed needs-triage This is a new issue that needs to be triaged to the appropriate team. labels Aug 26, 2021
@dingmeng-xue
Copy link
Member

Thanks for reporting. The current cmdlet is following its API definition. We will consider to provide additional logic.

@dingmeng-xue dingmeng-xue added the Breaking Change Release This PR contains breaking change label Aug 27, 2021
@dingmeng-xue dingmeng-xue added this to the Sep 2021 (2021-10-05) milestone Aug 27, 2021
@janegilring
Copy link
Author

Thanks - that would have been great. Per now, the command is not useful for the regular IT Pro/PowerShell Admin the way I see it.

@BethanyZhou
Copy link
Contributor

Hi @janegilring , I'm sorry we have to postpone the onboard of additional logic since this command should not just work as Send/Receive mode, it would work as an interactive way by web socket like:

az container exec -g bez-rg --name test-cg --container-name test-container --exec-command "/bin/bash"
root@SandboxHost-637674435442429493:/# ls
bin   dev                  docker-entrypoint.sh  home  lib64       media  opt   root  sbin  sys  usr
boot  docker-entrypoint.d  etc                   lib   lost+found  mnt    proc  run   srv   tmp  var
root@SandboxHost-637674435442429493:/# dir
bin   dev                  docker-entrypoint.sh  home  lib64       media  opt   root  sbin  sys  usr
boot  docker-entrypoint.d  etc                   lib   lost+found  mnt    proc  run   srv   tmp  var
root@SandboxHost-637674435442429493:/# exit
exit

So that we needs more time to do additional investigation and we will go back to you when we find a proper solution.

@amarkwong
Copy link

Hi @BethanyZhou, could you please share how can we implementing the WebSocketUri and password to get the result? Looks like the Invoke-AzContainerInstanceCommand didn't executed any command on the container?

For example, to create a test file, we ran this line on azure cloud shell
Invoke-AzContainerInstanceCommand -ContainerGroupName alpine -ContainerName alpine -ResourceGroupName MeterData -Command "touch test.txt" -TerminalSizeCol 80 -TerminalSizeRow 80

But in the container instance, nothing happened
image

if I ran the azcli version on my local computer (with azure-cli at 2.27, 2.28 has some breaking change)
az container exec --resource-group MeterData --name alpine --container-name alpine --exec-command "touch test.txt"
image

@BethanyZhou
Copy link
Contributor

Hi @amarkwong ,

Yes, we need send password to its corresponding websocket to trigger command execution. That's why Invoke-AzContainerInstanceCommand didn't executed any command on the container.

Could you please share how can we implementing the WebSocketUri and password to get the result?

A rough code for non-interactive command is as below:

        # $response is the execution result of current Invoke-AzContainerInstanceCommand
        $socket = [System.Net.WebSockets.ClientWebSocket]::new()
        $uri = [System.Uri]::new($response.WebSocketUri)
        $cts = [System.Threading.CancellationTokenSource]::new()
        $socket.ConnectAsync($uri, $cts.Token).Wait()
        $bytesToSend = New-Object System.ArraySegment[byte] -ArgumentList @(,[System.Text.Encoding]::UTF8.GetBytes($response.Password))
        $conn = $socket.SendAsync($bytesToSend, [System.Net.WebSockets.WebSocketMessageType]::Text, $true, $cts.Token).Wait()
    
        $allBytes = New-Object System.Collections.Generic.List[byte]

        while($socket.State -eq [System.Net.WebSockets.WebSocketState]::Open)
        {
          $bytesReceived  = New-Object System.ArraySegment[byte] -ArgumentList @(, (new-object byte[] 1024))
          $result = $socket.ReceiveAsync($bytesReceived, [System.Threading.CancellationToken]::None).GetAwaiter().GetResult()
          $allBytes.AddRange($bytesReceived.Slice(0, $result.Count))
        }
        return [System.Text.Encoding]::UTF8.GetString($allBytes.ToArray(), 0, $allBytes.Count)

We are planning return command execution result in Invoke-AzContainerInstanceCommand in the future.

@dingmeng-xue
Copy link
Member

link PR #16350

@BethanyZhou
Copy link
Contributor

Close as #16518 closed.

Following new features in Invoke-AzContainerInstanceCommand will be available on 12/07/2021
- [Breaking Change] Displayed command execution result as the cmdlet output by connecting websocket in backend
- Added -PassThru to get last execution result when the command succeeds
- Set default value for TerminalSizeCol and TerminalSizeRow according to current PowerShell window size

@obayesshelton
Copy link

Hi @BethanyZhou has this been released yet? I am still having the same issue as @amarkwong

Currently the command Invoke-AzContainerInstanceCommand in Azure Automation is pretty useless.

@BethanyZhou
Copy link
Contributor

Hi @obayesshelton , this enhancement had been enabled in Az.ContainerInstance>=3.0.0. Pleas check your module version.

@otabut
Copy link

otabut commented Apr 13, 2022

Hi,

Two comments about the Invoke-AzContainerInstanceCommand cmdlet in Az.ContainerInstance>=3.0.0 :

  • the result of the command is displayed but cannot be retrieved in a Powershell variable (stream issue ?)
  • in case of command failure, error message is displayed but no Powershell error is raised

@BethanyZhou
Copy link
Contributor

Hi @otabut , Thanks for reporting.

the result of the command is displayed but cannot be retrieved in a Powershell variable (stream issue ?)

You can obtain last execution result by Invoke-AzContainerInstanceCommand -PassThru

in case of command failure, error message is displayed but no Powershell error is raised

Could you provide example for this case?

@otabut
Copy link

otabut commented Apr 13, 2022

About 1st comment :

image

About 2nd comment (command is hostname without ending e to generate error) :

image

@BethanyZhou
Copy link
Contributor

Thanks for quick response.

  • Could you please raise a new issue specific for 1st comment? We will use the new issue to track 1st problem.
  • The 2nd issue is a known limitation as we communicate with container by web socket. All messages are provided as plain text. We are unable to distinguish formal message or error message.

@BenH-Puregym
Copy link

Hi @amarkwong ,

Yes, we need send password to its corresponding websocket to trigger command execution. That's why Invoke-AzContainerInstanceCommand didn't executed any command on the container.

Could you please share how can we implementing the WebSocketUri and password to get the result?

A rough code for non-interactive command is as below:

        # $response is the execution result of current Invoke-AzContainerInstanceCommand
        $socket = [System.Net.WebSockets.ClientWebSocket]::new()
        $uri = [System.Uri]::new($response.WebSocketUri)
        $cts = [System.Threading.CancellationTokenSource]::new()
        $socket.ConnectAsync($uri, $cts.Token).Wait()
        $bytesToSend = New-Object System.ArraySegment[byte] -ArgumentList @(,[System.Text.Encoding]::UTF8.GetBytes($response.Password))
        $conn = $socket.SendAsync($bytesToSend, [System.Net.WebSockets.WebSocketMessageType]::Text, $true, $cts.Token).Wait()
    
        $allBytes = New-Object System.Collections.Generic.List[byte]

        while($socket.State -eq [System.Net.WebSockets.WebSocketState]::Open)
        {
          $bytesReceived  = New-Object System.ArraySegment[byte] -ArgumentList @(, (new-object byte[] 1024))
          $result = $socket.ReceiveAsync($bytesReceived, [System.Threading.CancellationToken]::None).GetAwaiter().GetResult()
          $allBytes.AddRange($bytesReceived.Slice(0, $result.Count))
        }
        return [System.Text.Encoding]::UTF8.GetString($allBytes.ToArray(), 0, $allBytes.Count)

We are planning return command execution result in Invoke-AzContainerInstanceCommand in the future.

I'm still only able to get this command working if i use powershell 7 and run all the code suggested by @BethanyZhou

@BethanyZhou
Copy link
Contributor

@BenH-Puregym , please upgrade Az.ContainerInstance to latest version, Invoke-AzContainerInstanceCommand returns command execution result now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Breaking Change Release This PR contains breaking change Container Instances customer-reported feature-request This issue requires a new behavior in the product in order be resolved. question The issue doesn't require a change to the product in order to be resolved. Most issues start as that
Projects
None yet
Development

No branches or pull requests

7 participants