Skip to content

Commit 853c2b8

Browse files
authored
[Containerapp] Fix #28553: az containerapp exec: Fix the error of inappropriate ioctl for device (#28759)
1 parent 4ce682d commit 853c2b8

File tree

6 files changed

+8020
-341
lines changed

6 files changed

+8020
-341
lines changed

src/azure-cli/azure/cli/command_modules/containerapp/_ssh_utils.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
# --------------------------------------------------------------------------------------------
55
# pylint: disable=logging-fstring-interpolation
66

7-
import os
87
import sys
98
import time
109
import threading
@@ -151,7 +150,8 @@ def _send_stdin(connection: WebSocketConnection, getch_fn):
151150

152151

153152
def _resize_terminal(connection: WebSocketConnection):
154-
size = os.get_terminal_size()
153+
from shutil import get_terminal_size
154+
size = get_terminal_size()
155155
if connection.is_connected:
156156
connection.send(b"".join([SSH_TERM_RESIZE_PREFIX,
157157
f'{{"Width": {size.columns}, '

src/azure-cli/azure/cli/command_modules/containerapp/_validators.py

+30-7
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
import re
88
from azure.cli.core.azclierror import (ValidationError, ResourceNotFoundError, InvalidArgumentValueError,
99
MutuallyExclusiveArgumentError)
10-
from msrestazure.tools import is_valid_resource_id
10+
from msrestazure.tools import is_valid_resource_id, parse_resource_id
1111
from knack.log import get_logger
1212

13-
from ._clients import ContainerAppClient
13+
from ._clients import ContainerAppClient, ManagedEnvironmentClient
1414
from ._ssh_utils import ping_container_app
1515
from ._utils import safe_get, is_registry_msi_system
1616
from ._constants import ACR_IMAGE_SUFFIX, LOG_TYPE_SYSTEM
@@ -148,6 +148,31 @@ def validate_allow_insecure(namespace):
148148
raise ValidationError("Usage error: --allow-insecure is not supported for TCP ingress")
149149

150150

151+
def _ping_containerapp_if_need(cmd, app) -> (bool, str):
152+
# if container app has no ingress or is internal, not need to ping
153+
if safe_get(app, "properties", "configuration", "ingress") is None or safe_get(app, "properties", "configuration", "ingress", "external") is False:
154+
return False, None
155+
156+
parsed_env = parse_resource_id(safe_get(app, "properties", "environmentId"))
157+
env_name = parsed_env['name']
158+
env_rg = parsed_env['resource_group']
159+
env = ManagedEnvironmentClient.show(cmd, env_rg, env_name)
160+
# if environment is internal, not need to ping
161+
if safe_get(env, "properties", "vnetConfiguration", "internal") is True:
162+
return False, None
163+
164+
try:
165+
# ping containerapp to activate its replica
166+
ping_container_app(app) # needed to get an alive replica
167+
except Exception as ex: # pylint: disable=broad-except
168+
warning_message = f"Error encountered while attempting to ping container app.\n" \
169+
f"Error message: '{str(ex)}'\n" \
170+
f"Please ensure there is an alive replica. "
171+
return True, warning_message
172+
173+
return False, None
174+
175+
151176
def _set_ssh_defaults(cmd, namespace):
152177
app = ContainerAppClient.show(cmd, namespace.resource_group_name, namespace.name)
153178
if not app:
@@ -158,16 +183,14 @@ def _set_ssh_defaults(cmd, namespace):
158183
if not namespace.revision:
159184
raise ResourceNotFoundError("Could not find a revision")
160185
if not namespace.replica:
161-
# VVV this may not be necessary according to Anthony Chu
162-
try:
163-
ping_container_app(app) # needed to get an alive replica
164-
except Exception as e: # pylint: disable=broad-except
165-
logger.warning("Failed to ping container app with error '%s' \nPlease ensure there is an alive replica. ", str(e))
186+
failed_to_ping, warning_message = _ping_containerapp_if_need(cmd, app)
166187
replicas = ContainerAppClient.list_replicas(cmd=cmd,
167188
resource_group_name=namespace.resource_group_name,
168189
container_app_name=namespace.name,
169190
revision_name=namespace.revision)
170191
if not replicas:
192+
if failed_to_ping:
193+
logger.warning(warning_message)
171194
raise ResourceNotFoundError("Could not find a replica for this app")
172195
namespace.replica = replicas[0]["name"]
173196
if not namespace.container:

src/azure-cli/azure/cli/command_modules/containerapp/custom.py

+4
Original file line numberDiff line numberDiff line change
@@ -3429,6 +3429,10 @@ def containerapp_ssh(cmd, resource_group_name, name, container=None, revision=No
34293429

34303430
logger.warning("Use ctrl + D to exit.")
34313431
while conn.is_connected:
3432+
if not reader.is_alive() or not writer.is_alive():
3433+
logger.warning("Reader or Writer for WebSocket is not alive. Closing the connection.")
3434+
conn.disconnect()
3435+
34323436
try:
34333437
time.sleep(0.1)
34343438
except KeyboardInterrupt:

0 commit comments

Comments
 (0)