[serial-console] Fix garbled console output by decoding binary websocket frames#9797
[serial-console] Fix garbled console output by decoding binary websocket frames#9797muram wants to merge 5 commits intoAzure:mainfrom
Conversation
️✔️Azure CLI Extensions Breaking Change Test
|
|
Thank you for your contribution! We will review the pull request and get back to you soon. |
|
The git hooks are available for azure-cli and azure-cli-extensions repos. They could help you run required checks before creating the PR. Please sync the latest code with latest dev branch (for azure-cli) or main branch (for azure-cli-extensions). pip install azdev --upgrade
azdev setup -c <your azure-cli repo path> -r <your azure-cli-extensions repo path>
|
|
@microsoft-github-policy-service agree |
|
Please fix CI issues |
…conflicts Fix CI failure on PR Azure#9797: 1. The serial-console extension pinned `websocket-client==1.3.1`, but recent azure-cli requires `websocket-client~=1.8.0`. Installing the extension into an env that already has azure-cli triggers `pkg_resources.ContextualVersionConflict` and `azdev extension add` fails. Widen the pin to `~=1.8.0` to match azure-cli and stay within the same major series. 2. In `.github/workflows/VersionCalPRComment.yml`, `azdev setup` runs after `pip install azdev` and installs azure-cli's pinned requirements, which downgrade transitive deps that azdev itself relies on: - azure-cli-diff-tool 0.1.1 needs requests~=2.32.3 but azure-cli pins requests==2.33.0 - tox 4.53.0 needs packaging>=26 but azure-cli pins packaging==25.0 Re-pin those two packages after `azdev setup` so the environment is internally consistent before the metadata generation step runs. Also add a non-fatal `pip check` for visibility. Made-with: Cursor
|
|
Pushed a follow-up commit to fix the failing
Re-running CI now. |
|
/azp run |
|
Azure Pipelines successfully started running 2 pipeline(s). |
|
@muram thanks for this fix, life much improved for me! |
|
Please fix CI issues |
…ket frames The serial-console extension's on_message callback assumed websocket frames were always str. Newer versions of websocket-client (>= 1.0) return bytes for binary frames, which the extension passed straight into print() and got rendered as a Python bytes repr (b'...\r\n \x1b[0;32m...'). This makes the serial console unusable on recent Python/websocket-client combinations (reproduced on Python 3.13 with the vendored websocket-client 1.3.1). Decode bytes to str inside on_message so that ANSI escapes and CR/LF are interpreted by the user's terminal as intended. Bumps version to 1.0.0b4 and adds a HISTORY.rst entry. Fixes Azure#9796 Made-with: Cursor
…conflicts Fix CI failure on PR Azure#9797: 1. The serial-console extension pinned `websocket-client==1.3.1`, but recent azure-cli requires `websocket-client~=1.8.0`. Installing the extension into an env that already has azure-cli triggers `pkg_resources.ContextualVersionConflict` and `azdev extension add` fails. Widen the pin to `~=1.8.0` to match azure-cli and stay within the same major series. 2. In `.github/workflows/VersionCalPRComment.yml`, `azdev setup` runs after `pip install azdev` and installs azure-cli's pinned requirements, which downgrade transitive deps that azdev itself relies on: - azure-cli-diff-tool 0.1.1 needs requests~=2.32.3 but azure-cli pins requests==2.33.0 - tox 4.53.0 needs packaging>=26 but azure-cli pins packaging==25.0 Re-pin those two packages after `azdev setup` so the environment is internally consistent before the metadata generation step runs. Also add a non-fatal `pip check` for visibility. Made-with: Cursor
This change was bundled into 22c4dfc to silence transitive `requests` and `packaging` warnings emitted after `azdev setup` reinstalls azure-cli's pinned requirements. The actual `version-cal` ContextualVersionConflict was already resolved by the `websocket-client~=1.8.0` bump in src/serial-console/setup.py; the workflow patch only quieted log noise. A repo-wide CI workflow tweak doesn't belong in a serial-console extension PR. Reverting so this PR is scoped to the bytes-decode fix and its supporting metadata changes only.
CI Build Tests for Python 3.10–3.13 fail with VCR `Can't overwrite existing cassette` because `az vm create` / `az vmss create` now fetch the image-aliases JSON from `https://azcliprod.blob.core.windows.net/cli/vm/aliases.json` while the recorded cassettes still contain the old `https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/arm-compute/quickstart-templates/aliases.json` URL. The response body is unchanged, so swap the request URI to match the live endpoint (matches the same change already landed in the scheduled-query cassettes). Affects: - src/serial-console/azext_serialconsole/tests/latest/recordings/test_check_resource_VM.yaml - src/serial-console/azext_serialconsole/tests/latest/recordings/test_check_resource_VMSS.yaml
3116ea1 to
f7767fb
Compare
|
Pushed two follow-up commits to address the failing Azure Pipelines Build Tests (Python 3.10–3.13) and to tighten the PR scope. Branch was also rebased onto current 1. Refresh stale VCR cassettes (real fix for Build Tests failures)Both
2. Revert out-of-scope workflow changeThe previous push touched Final PR scope (vs current
|
There was a problem hiding this comment.
Pull request overview
This PR fixes az serial-console connect output corruption on newer websocket-client versions by decoding binary websocket frames (bytes/bytearray) into UTF-8 text before printing, restoring correct rendering of newlines and ANSI escape sequences.
Changes:
- Decode binary websocket frames to
strinSerialConsole.connect()’son_messagecallback before callingPC.print. - Bump the
serial-consoleextension version to1.0.0b4and updateHISTORY.rst. - Update recorded test traffic to use the current VM aliases endpoint.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/serial-console/azext_serialconsole/custom.py | Decode bytes/bytearray websocket messages to UTF-8 text before printing to the terminal. |
| src/serial-console/setup.py | Bump extension version; update websocket-client dependency constraint. |
| src/serial-console/HISTORY.rst | Add 1.0.0b4 release notes describing the console output fix and dependency bump. |
| src/serial-console/azext_serialconsole/tests/latest/recordings/test_check_resource_VM.yaml | Refresh recording URIs for VM aliases lookup. |
| src/serial-console/azext_serialconsole/tests/latest/recordings/test_check_resource_VMSS.yaml | Refresh recording URIs for VMSS aliases lookup. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Related command
az serial-console connectDescription
Fixes #9796.
The
serial-consoleextension'son_messagecallback inSerialConsole.connect()assumed websocket frames were alwaysstr. Newer versions ofwebsocket-client(>= 1.0) returnbytesfor binary frames, which the extension passed straight into Python's built-inprint()— producing abytesrepr (b'...\r\n\x1b[0;32m...') in the user's terminal instead of decoded text. This makes the serial console unusable on recent Python / websocket-client combinations (reliably reproduced on Python 3.13).Sample of the broken output before this fix:
Runtime fix
In
src/serial-console/azext_serialconsole/custom.py, decodebytes/bytearraytostr(UTF-8 witherrors="replace"for safety) before forwarding the message toPC.print. After this change, ANSI escapes and CR/LF are interpreted by the user's terminal as intended and the serial console renders normally.Dependency widening (required for clean install)
The
websocket-clientrequirement is widened from==1.3.1to~=1.8.0. Currentazure-clirequireswebsocket-client~=1.8.0(src/azure-cli/setup.py, pinned to1.8.0inrequirements.py3.Linux.txt), so the existing==1.3.1pin produces apkg_resources.ContextualVersionConflictwhen the extension is added against currentazure-cli:This blocks
version-calin CI and means published1.0.0b3is currently uninstallable on a fresh azure-cli. The runtime API used by this extension (WebSocketApp.on_message) is stable across the 1.x line, so widening to~=1.8.0is safe.Test cassette refresh
Both VCR cassettes (
test_check_resource_VM.yaml,test_check_resource_VMSS.yaml) had stalealiases.jsonrequest URIs (raw.githubusercontent.com/.../aliases.json).azure-clinow fetches that file fromazcliprod.blob.core.windows.net/cli/vm/aliases.json, so the cassette URIs were swapped to match. Response bodies and headers are unchanged. Without this,Build Tests Python3.10–3.13fail with VCRCan't overwrite existing cassette. Same change pattern already landed insrc/scheduled-query/cassettes.Versioning
serial-consolefrom1.0.0b3to1.0.0b4.HISTORY.rstentry covering the runtime fix and the dependency change.Testing
az serial-console connect --resource-group <rg> --name <vmss> --instance-id <id>shows literalb'...'blob instead of console output.__pycache__), the same command renders the cloud-init / login boot log normally with proper newlines and colors.azure-cli 2.85.0, Python 3.13.12Notes
websocket-client < 1.0would also "fix" the bytes-decode symptom but is not future-proof and conflicts withazure-cli's own pinning.