Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/containerapp/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ upcoming
* 'az containerapp function keys': Update minimum replica check
* 'az containerapp list': Add `--kind` parameter to filter container apps by kind
* 'az containerapp function invocations': Fix issue when cloud role name is set
* 'az containerapp sessionpool update': Fix --no-wait issue and extend timeout to 7200s
* 'az containerapp sessionpool update': Fix clean identity issue when not providing identity parameters

1.3.0b1
++++++
Expand Down
81 changes: 57 additions & 24 deletions src/containerapp/azext_containerapp/_clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,25 @@
# pylint: disable=line-too-long, no-else-return, useless-return, broad-except, no-else-raise

import json
import time
import os
import requests

from azure.cli.core.azclierror import ResourceNotFoundError, CLIError
from azure.cli.core.azclierror import CLIError, AzureResponseError
from azure.cli.core.util import send_raw_request
from azure.cli.core.commands.client_factory import get_subscription_id
from azure.cli.command_modules.containerapp._clients import (
poll_status,
poll_results,
_extract_delay,
AuthClient,
GitHubActionClient,
ContainerAppClient,
ContainerAppsJobClient,
DaprComponentClient,
ManagedEnvironmentClient,
StorageClient)
StorageClient,
PollingAnimation)

from knack.log import get_logger

Expand All @@ -29,6 +32,7 @@
PREVIEW_API_VERSION = "2025-10-02-preview"
POLLING_TIMEOUT = 1500 # how many seconds before exiting
POLLING_SECONDS = 2 # how many seconds between requests
POLLING_TIMEOUT_FOR_SESSION_POOL = 7200 # 2 hours for timeout
POLLING_TIMEOUT_FOR_MANAGED_CERTIFICATE = 1500 # how many seconds before exiting
POLLING_INTERVAL_FOR_MANAGED_CERTIFICATE = 4 # how many seconds between requests
HEADER_AZURE_ASYNC_OPERATION = "azure-asyncoperation"
Expand All @@ -37,6 +41,28 @@
MAINTENANCE_CONFIG_DEFAULT_NAME = "default"


def poll_results_with_timeout(cmd, request_url, polling_timeout_in_sec=POLLING_TIMEOUT): # pylint: disable=inconsistent-return-statements
if not request_url:
raise AzureResponseError(f"Http response lack of necessary header: '{HEADER_LOCATION}'")

start = time.time()
end = time.time() + polling_timeout_in_sec
animation = PollingAnimation()

animation.tick()
r = send_raw_request(cmd.cli_ctx, "GET", request_url)

while r.status_code in [202] and start < end:
time.sleep(_extract_delay(r))
animation.tick()
r = send_raw_request(cmd.cli_ctx, "GET", request_url)
start = time.time()

animation.flush()
if r.text:
return json.loads(r.text)


class GitHubActionPreviewClient(GitHubActionClient):
api_version = PREVIEW_API_VERSION

Expand Down Expand Up @@ -235,9 +261,10 @@ def update(cls, cmd, resource_group_name, name, container_app_name, container_ap
operation_url = r.headers.get(HEADER_LOCATION)
response = poll_results(cmd, operation_url)
if response is None:
raise ResourceNotFoundError("Could not find the app resiliency policy")
else:
return response
logger.debug("poll_results returned empty body. operation_url=%s", operation_url)
raise CLIError("Timed out waiting for the app resiliency policy update operation to complete. Please try again or use --no-wait.")

return response

return r.json()

Expand Down Expand Up @@ -588,9 +615,10 @@ def update(cls, cmd, resource_group_name, name, managed_environment_envelope, no
operation_url = r.headers.get(HEADER_LOCATION)
response = poll_results(cmd, operation_url)
if response is None:
raise ResourceNotFoundError("Could not find a container app")
else:
return response
logger.debug("poll_results returned empty body. operation_url=%s", operation_url)
raise CLIError("Timed out waiting for the managed environment update operation to complete. Please try again or use --no-wait.")

return response

return r.json()

Expand Down Expand Up @@ -748,9 +776,10 @@ def update(cls, cmd, resource_group_name, name, managed_environment_envelope, no
operation_url = r.headers.get(HEADER_LOCATION)
response = poll_results(cmd, operation_url)
if response is None:
raise ResourceNotFoundError("Could not find a connected environment")
else:
return response
logger.debug("poll_results returned empty body. operation_url=%s", operation_url)
raise CLIError("Timed out waiting for the connected environment update operation to complete. Please try again or use --no-wait.")

return response

return r.json()

Expand Down Expand Up @@ -1317,9 +1346,10 @@ def update(cls, cmd, resource_group_name, environment_name, name, java_component
operation_url = r.headers.get(HEADER_LOCATION)
response = poll_results(cmd, operation_url)
if response is None:
raise ResourceNotFoundError("Could not find the Java component")
else:
return response
logger.debug("poll_results returned empty body. operation_url=%s", operation_url)
raise CLIError("Timed out waiting for the Java component update operation to complete. Please try again or use --no-wait.")

return response

return r.json()

Expand Down Expand Up @@ -1430,11 +1460,12 @@ def update(cls, cmd, resource_group_name, name, session_pool_envelope, no_wait=F
return
elif r.status_code == 202:
operation_url = r.headers.get(HEADER_LOCATION)
response = poll_results(cmd, operation_url)
response = poll_results_with_timeout(cmd, operation_url, POLLING_TIMEOUT_FOR_SESSION_POOL)
if response is None:
raise ResourceNotFoundError("Could not find the Session Pool")
else:
return response
logger.debug("poll_results returned empty body. operation_url=%s", operation_url)
raise CLIError("Timed out waiting for the session pool update operation to complete. Please try again or use --no-wait.")

return response

return r.json()

Expand Down Expand Up @@ -1733,9 +1764,10 @@ def update(cls, cmd, resource_group_name, environment_name, name, dotnet_compone
operation_url = r.headers.get(HEADER_LOCATION)
response = poll_results(cmd, operation_url)
if response is None:
raise ResourceNotFoundError("Could not find the DotNet component")
else:
return response
logger.debug("poll_results returned empty body. operation_url=%s", operation_url)
raise CLIError("Timed out waiting for the .NET component update operation to complete. Please try again or use --no-wait.")

return response

return r.json()

Expand Down Expand Up @@ -1845,9 +1877,10 @@ def create_or_update(cls, cmd, resource_group_name, environment_name, maintenanc
operation_url = r.headers.get(HEADER_LOCATION)
response = poll_results(cmd, operation_url)
if response is None:
raise ResourceNotFoundError("Could not find the maintenance config")
else:
return response
logger.debug("poll_results returned empty body. operation_url=%s", operation_url)
raise CLIError("Timed out waiting for the maintenance configuration operation to complete. Please try again or use --no-wait.")

return response

return r.json()

Expand Down
5 changes: 3 additions & 2 deletions src/containerapp/azext_containerapp/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -3173,8 +3173,9 @@ def update_session_pool(cmd,
registry_user=None,
mi_user_assigned=None,
registry_identity=None,
mi_system_assigned=False,
probe_yaml=None):
mi_system_assigned=None,
probe_yaml=None,
no_wait=False):
raw_parameters = locals()
session_pool_decorator = SessionPoolUpdateDecorator(
cmd=cmd,
Expand Down
Loading