Skip to content

Commit c11373f

Browse files
author
Shikha Jha
committed
added warm-up kudu code
1 parent 35a9996 commit c11373f

File tree

1 file changed

+83
-2
lines changed
  • src/azure-cli/azure/cli/command_modules/appservice

1 file changed

+83
-2
lines changed

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

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import threading
88
import time
99
import re
10+
import requests
1011
from xml.etree import ElementTree
1112

1213
from urllib.parse import urlparse
@@ -98,6 +99,7 @@
9899
from .aaz.latest.relay.hyco.authorization_rule.keys import List as HycoAuthoKeysList
99100
from .aaz.latest.relay.namespace import List as NamespaceList
100101

102+
101103
logger = get_logger(__name__)
102104

103105
# pylint:disable=no-member,too-many-lines,too-many-locals
@@ -791,6 +793,7 @@ def enable_zip_deploy(cmd, resource_group_name, name, src, timeout=None, slot=No
791793
from azure.cli.core.util import should_disable_connection_verify
792794
# check if the app is a linux web app
793795
app_is_linux_webapp = is_linux_webapp(app)
796+
app_is_function_app = is_functionapp(app)
794797

795798
# Read file content
796799
with open(os.path.realpath(os.path.expanduser(src)), 'rb') as fs:
@@ -799,7 +802,11 @@ def enable_zip_deploy(cmd, resource_group_name, name, src, timeout=None, slot=No
799802
if app_is_linux_webapp and track_status is not None and track_status:
800803
headers["x-ms-artifact-checksum"] = _compute_checksum(zip_content)
801804

802-
res = requests.post(zip_url, data=zip_content, headers=headers, verify=not should_disable_connection_verify())
805+
if app_is_linux_webapp and not app_is_function_app:
806+
cookie = _warmup_kudu_and_get_cookie_internal(cmd, resource_group_name, name, slot)
807+
res = requests.post(zip_url, data=zip_content, headers=headers, cookies={cookie}, verify=not should_disable_connection_verify())
808+
else:
809+
res = requests.post(zip_url, data=zip_content, headers=headers, verify=not should_disable_connection_verify())
803810
logger.warning("Deployment endpoint responded with status code %d", res.status_code)
804811

805812
# check the status of async deployment
@@ -6981,6 +6988,9 @@ def perform_onedeploy_webapp(cmd,
69816988
params.slot = slot
69826989
params.track_status = track_status
69836990

6991+
client = web_client_factory(cmd.cli_ctx)
6992+
app = client.web_apps.get(resource_group_name, name)
6993+
params.is_linux_webapp = is_linux_webapp(app)
69846994
return _perform_onedeploy_internal(params)
69856995

69866996

@@ -7002,6 +7012,7 @@ def __init__(self):
70027012
self.timeout = None
70037013
self.slot = None
70047014
self.track_status = False
7015+
self.is_linux_webapp = False
70057016
# pylint: enable=too-many-instance-attributes,too-few-public-methods
70067017

70077018

@@ -7050,6 +7061,24 @@ def _build_onedeploy_arm_url(params):
70507061
)
70517062
return params.cmd.cli_ctx.cloud.endpoints.resource_manager + base_url
70527063

7064+
def _build_get_instances_list_arm_url(params):
7065+
from azure.cli.core.commands.client_factory import get_subscription_id
7066+
client = web_client_factory(params.cmd.cli_ctx)
7067+
sub_id = get_subscription_id(params.cmd.cli_ctx)
7068+
if not params.slot:
7069+
base_url = (
7070+
f"subscriptions/{sub_id}/resourceGroups/{params.resource_group_name}/providers/Microsoft.Web/sites/"
7071+
f"{params.webapp_name}/instances?api-version={client.DEFAULT_API_VERSION}"
7072+
)
7073+
else:
7074+
base_url = (
7075+
f"subscriptions/{sub_id}/resourceGroups/{params.resource_group_name}/providers/Microsoft.Web/sites/"
7076+
f"{params.webapp_name}/slots/{params.slot}/instances"
7077+
f"?api-version={client.DEFAULT_API_VERSION}"
7078+
)
7079+
7080+
logger.info("get instances list url: %s", base_url)
7081+
return params.cmd.cli_ctx.cloud.endpoints.resource_manager + base_url
70537082

70547083
def _build_deploymentstatus_url(cmd, resource_group_name, webapp_name, slot, deployment_id):
70557084
from azure.cli.core.commands.client_factory import get_subscription_id
@@ -7143,6 +7172,52 @@ def _update_artifact_type(params):
71437172
logger.warning("Deployment type: %s. To override deployment type, please specify the --type parameter. "
71447173
"Possible values: war, jar, ear, zip, startup, script, static", params.artifact_type)
71457174

7175+
def _get_instances_list_arm_internal(params):
7176+
url = _build_get_instances_list_arm_url(params)
7177+
response = send_raw_request(params.cmd.cli_ctx, "GET", url)
7178+
if response.status_code == 200:
7179+
logger.info("Instances list retrieved successfully.")
7180+
return response.json().get("value", [])
7181+
raise CLIError("Unable to get instances list.")
7182+
7183+
def _get_instance_id_internal(param):
7184+
instances = _get_instances_list_arm_internal(param)
7185+
7186+
if not instances or len(instances) == 0:
7187+
raise CLIError("No instances found.")
7188+
7189+
logger.info("returning instance id for instance: %s", instances[0]['name'])
7190+
return instances[0]['name']
7191+
7192+
7193+
def _get_affinity_cookie_internal(param):
7194+
instance = _get_instance_id_internal(param)
7195+
logger.info("returning affinity cookie for instance: %s", instance)
7196+
cookie = {
7197+
"ARRAffinity": instance,
7198+
"ARRAffinitySameSite": instance
7199+
}
7200+
return cookie
7201+
7202+
def _warmup_kudu_and_get_cookie_internal(param):
7203+
scm_url = _get_scm_url(param.cmd, param.resource_group_name, param.webapp_name, param.slot)
7204+
cookie = _get_affinity_cookie_internal(param)
7205+
Max_Retries = 3
7206+
TimeOut = 300
7207+
SleepInterval = 60
7208+
for retry in range(Max_Retries):
7209+
if _ping_kudu_internal(scm_url, param, cookie, TimeOut):
7210+
logger.info("Kudu warmed up successfully. Retry count: %d", retry)
7211+
return cookie
7212+
time.sleep(SleepInterval)
7213+
7214+
raise CLIError("Unable to warm up Kudu.")
7215+
7216+
def _ping_kudu_internal(scm_url, param, cookie, timeout):
7217+
logger.info("Warming up Kudu.")
7218+
headers = get_scm_site_headers(param.cmd.cli_ctx, param.webapp_name, param.resource_group_name)
7219+
response = requests.get(scm_url + '/deployments', headers=headers, cookies=cookie, timeout=timeout)
7220+
return response.status_code == 200
71467221

71477222
def _make_onedeploy_request(params):
71487223
import requests
@@ -7161,7 +7236,13 @@ def _make_onedeploy_request(params):
71617236
# For that, set poll_async_deployment_for_debugging=True
71627237
logger.info("Deployment API: %s", deploy_url)
71637238
if not params.src_url: # use SCM endpoint
7164-
response = requests.post(deploy_url, data=body, headers=headers, verify=not should_disable_connection_verify())
7239+
# if linux webapp then warmup kudu and use warmed up kudu for deployment
7240+
if params.is_linux_webapp and not params.is_functionapp:
7241+
logger.info("Warming up Kudu before deployment.")
7242+
cookies = _warmup_kudu_and_get_cookie_internal(params)
7243+
response = requests.post(deploy_url, data=body, headers=headers, cookies=cookies, verify=not should_disable_connection_verify())
7244+
else:
7245+
response = requests.post(deploy_url, data=body, headers=headers, verify=not should_disable_connection_verify())
71657246
poll_async_deployment_for_debugging = True
71667247
else:
71677248
response = send_raw_request(params.cmd.cli_ctx, "PUT", deploy_url, body=body)

0 commit comments

Comments
 (0)