Azure / Azure/azure-cli

The UX of az vm run-command invoke is abysmal

Open
#22,245 5 comments 7 reactions 2 assignees Claimed by @cxznmhdcxz View on GitHub
act-observability-squad Auto-Assign Compute customer-reported feature-request
Dominant language
Python
Stars
4.6k
Forks
3.5k
Avg merge
3d 2h
Merged PRs (30d)
60

Description

### Describe the bug

The UX of `az vm run-command invoke` is abysmal:
1. The output is encoded in a pointless, bad DSL
2. 640 KiB 4 KiB should be enough for anyone.
3. It is slower than 🐌

**Despite emitting JSON, the bits anyone cares about (the output of the command) is encoded is an ambiguous DSL**

Take an example run:
```
» az vm run-command invoke -g example-rg -n example-rg --command-id RunShellScript --scripts 'ls -la'
{
"value": [
{
"code": "ProvisioningState/succeeded",
"displayStatus": "Provisioning succeeded",
"level": "Info",
"message": "Enable succeeded: \n[stdout]\ntotal 12\ndrwx------ 2 root root 4096 May 2 20:37 .\ndrwx------ 36 root root 4096 May 2 20:37 ..\n-r-x------ 1 root root 7 May 2 20:37 script.sh\n-rw------- 1 root root 0 May 2 20:37 stderr\n-rw------- 1 root root 0 May 2 20:37 stdout\n\n[stderr]\n",
"time": null
}
]
}
```
The bit we care about is the output; we can ask either `az` to make that more legible, or we can run it through `| jq -r`. Either way nets one:
```
Enable succeeded:
[stdout]
total 12
drwx------ 2 root root 4096 May 2 20:37 .
drwx------ 36 root root 4096 May 2 20:37 ..
-r-x------ 1 root root 7 May 2 20:37 script.sh
-rw------- 1 root root 0 May 2 20:37 stderr
-rw------- 1 root root 0 May 2 20:37 stdout

[stderr]

```

… so here, we have three pieces of actual data: the `stdout`, the `stderr`, and … whatever the heck "Enable succeeded" is or signifies. This just came out of _JSON_, a way to represent structured data, it could have been,
```json
{
"enableSucceeded": true,
"stdout": "",
"stderr": ""
}
```
… and parsing would have been mind-bogglingly simple. One could have used the built in facilities of `az`'s `--query`, even.

But instead, what we've got (the above text blob) is some [stringly typed data](https://wiki.c2.com/?StringlyTyped); if we want to get, e.g., the output, we've got to parse that ourselves. And if you *try* this, you should also realize that the output's language is *ambiguous*: our parser cannot know whether `[stderr]` signifies the end of `stdout`, or if that string literally appeared in the output. To avoid this, you have to implement some sort of escaping mechanism in the script you pass to be run on the remote, to guarantee that output won't appear.

Now I realize there is some level of "plugins" occurring here (i.e., the arg to `--command-id`) but that's not a salient reason for the troubles here. At the worst, the `message` string could have been JSON, or whatever interface these communicate via could have just been made more powerful than a simple text message…

**640 KiB 4 KiB should be enough for anyone:** you're limited to only returning 4 paltry KiB of data. Examples of command that one might run that would exceed this? `ps -ef`, for example. `ls`. Simple stuff, but you're forced to sip through a coffee stir.

You can work around this, of course, by piping the output to a file on the remote. The response is also a JSON string, which can't handle binary, so to ensure everything gets over the write alright, `| gzip | base64` — this has the added benefits of avoiding the ambiguity problems in point 1, as base64 will never emit `[stderr]`.

Then write a script that does that for you, then transfers that output file in chucks through multiple invocations of `az vm run-command invoke`.

**It is slower than 🐌:** It takes ~30s per command. At a rate of 4KiB per command, that works out to a total bit rate of ~1,000 bps. That's *bits* per second. In the year 2022.

Add all this together, and running `ps -ef` over this channel takes, all told, ***2m 8s***.

### To Reproduce

Run the command more than once.

### Expected behavior

My sanity remains intact, and I don't have to do so much work to _get stuff done_.

### Environment summary
`brew install`. macOS. Let's be honest it's going to be equally bad no matter the environment.

### Additional context

While debugging this, I discovered a but in my terminal, too. So there's that.

Holistically, these problems are more pervasive than just `az`. The Azure "REST" APIs also having pagination limits that result in tiny transfers per request, and are slow. (E.g., some of ACR's APIs have bandwidths best measured in "baud" as well.)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.