From b69a217a6c08243608c1a6254f57ecaf65369776 Mon Sep 17 00:00:00 2001 From: Sisira Panchagnula Date: Mon, 30 Apr 2018 11:10:02 -0700 Subject: [PATCH] SUpport for ASP.NET FW:updating to find DOTNET version Fixing logic for version detected & created for dotnot Support for Java --- src/webapp/azext_webapp/_constants.py | 4 ++ src/webapp/azext_webapp/create_util.py | 68 +++++++++++++++++++++++--- src/webapp/azext_webapp/custom.py | 39 +++++++++------ 3 files changed, 89 insertions(+), 22 deletions(-) diff --git a/src/webapp/azext_webapp/_constants.py b/src/webapp/azext_webapp/_constants.py index f218f175fee..f3f1a1202a4 100644 --- a/src/webapp/azext_webapp/_constants.py +++ b/src/webapp/azext_webapp/_constants.py @@ -5,9 +5,13 @@ NODE_VERSION_DEFAULT = "8.9" NETCORE_VERSION_DEFAULT = "2.0" +DOTNET_VERSION_DEFAULT = "4.7" # TODO: Remove this once we have the api returning the versions NODE_VERSIONS = ['4.4', '4.5', '6.2', '6.6', '6.9', '6.11', '8.0', '8.1'] NETCORE_VERSIONS = ['1.0', '1.1', '2.0'] +DOTNET_VERSIONS = ['3.5', '4.7'] NODE_RUNTIME_NAME = "node" NETCORE_RUNTIME_NAME = "dotnetcore" +DOTNET_RUNTIME_NAME = "aspnet" +JAVA_RUNTIME_NAME = "java" OS_DEFAULT = "Windows" diff --git a/src/webapp/azext_webapp/create_util.py b/src/webapp/azext_webapp/create_util.py index 0978e3a2942..86ecc4d2bcf 100644 --- a/src/webapp/azext_webapp/create_util.py +++ b/src/webapp/azext_webapp/create_util.py @@ -13,7 +13,11 @@ NODE_VERSION_DEFAULT, NODE_VERSIONS, NETCORE_RUNTIME_NAME, - NODE_RUNTIME_NAME) + NODE_RUNTIME_NAME, + DOTNET_RUNTIME_NAME, + DOTNET_VERSION_DEFAULT, + DOTNET_VERSIONS, + JAVA_RUNTIME_NAME) def _resource_client_factory(cli_ctx, **_): @@ -53,10 +57,15 @@ def zip_contents_from_dir(dirPath, lang): def get_runtime_version_details(file_path, lang_name): version_detected = None version_to_create = None + print(lang_name.lower()) if lang_name.lower() == NETCORE_RUNTIME_NAME: # method returns list in DESC, pick the first version_detected = parse_netcore_version(file_path)[0] version_to_create = detect_netcore_version_tocreate(version_detected) + elif lang_name.lower() == DOTNET_RUNTIME_NAME: + # method returns list in DESC, pick the first + version_detected = parse_dotnet_version(file_path) + version_to_create = detect_dotnet_version_tocreate(version_detected) elif lang_name.lower() == NODE_RUNTIME_NAME: version_detected = parse_node_version(file_path)[0] version_to_create = detect_node_version_tocreate(version_detected) @@ -107,22 +116,60 @@ def check_app_exists(cmd, rg_name, app_name): def get_lang_from_content(src_path): import glob # NODE: package.json should exist in the application root dir - # NETCORE: *.csproj should exist in the application root dir + # NETCORE & DOTNET: *.csproj should exist in the application dir + # NETCORE: netcoreapp2.0 + # DOTNET: v4.5.2 runtime_details_dict = dict.fromkeys(['language', 'file_loc', 'default_sku']) package_json_file = os.path.join(src_path, 'package.json') - package_netcore_glob = glob.glob("*.csproj") + package_netlang_glob = glob.glob("**/*.csproj", recursive=True) + runtime_java_file = glob.glob("**/*.war", recursive=True) if os.path.isfile(package_json_file): runtime_details_dict['language'] = NODE_RUNTIME_NAME runtime_details_dict['file_loc'] = package_json_file runtime_details_dict['default_sku'] = 'S1' - elif package_netcore_glob: - package_netcore_file = os.path.join(src_path, package_netcore_glob[0]) - runtime_details_dict['language'] = NETCORE_RUNTIME_NAME + elif package_netlang_glob: + package_netcore_file = os.path.join(src_path, package_netlang_glob[0]) + runtime_lang = detect_dotnet_lang(package_netcore_file) + runtime_details_dict['language'] = runtime_lang runtime_details_dict['file_loc'] = package_netcore_file runtime_details_dict['default_sku'] = 'F1' + elif runtime_java_file: + runtime_details_dict['language'] = JAVA_RUNTIME_NAME + runtime_details_dict['file_loc'] = runtime_java_file + runtime_details_dict['default_sku'] = 'S1' return runtime_details_dict +def detect_dotnet_lang(csproj_path): + import xml.etree.ElementTree as ET + import re + parsed_file = ET.parse(csproj_path) + root = parsed_file.getroot() + version_lang = '' + for target_ver in root.iter('TargetFramework'): + version_lang = re.sub(r'([^a-zA-Z\s]+?)', '', target_ver.text) + if 'netcore' in version_lang.lower(): + return NETCORE_RUNTIME_NAME + else: + return DOTNET_RUNTIME_NAME + + +def parse_dotnet_version(file_path): + from xml.dom import minidom + import re + xmldoc = minidom.parse(file_path) + framework_ver= xmldoc.getElementsByTagName('TargetFrameworkVersion') + version_detected= ['4.7'] + target_ver = framework_ver[0].firstChild.data + non_decimal = re.compile(r'[^\d.]+') + # reduce the version to '5.7.4' from '5.7' + if target_ver is not None: + # remove the string from the beginning of the version value + c = non_decimal.sub('', target_ver) + version_detected = c[:3] + return version_detected + + def parse_netcore_version(file_path): import xml.etree.ElementTree as ET import re @@ -157,6 +204,15 @@ def detect_netcore_version_tocreate(detected_ver): return NETCORE_VERSION_DEFAULT +def detect_dotnet_version_tocreate(detected_ver): + min_ver = DOTNET_VERSIONS[0] + if detected_ver in DOTNET_VERSIONS: + return detected_ver + elif detected_ver < min_ver: + return min_ver + return DOTNET_VERSION_DEFAULT + + def detect_node_version_tocreate(detected_ver): if detected_ver in NODE_VERSIONS: return detected_ver diff --git a/src/webapp/azext_webapp/custom.py b/src/webapp/azext_webapp/custom.py index 1f3397c8f9e..4457ce23d3a 100644 --- a/src/webapp/azext_webapp/custom.py +++ b/src/webapp/azext_webapp/custom.py @@ -33,7 +33,7 @@ web_client_factory ) -from ._constants import (NODE_RUNTIME_NAME, OS_DEFAULT) +from ._constants import (NODE_RUNTIME_NAME, OS_DEFAULT, JAVA_RUNTIME_NAME) logger = get_logger(__name__) @@ -64,7 +64,8 @@ def create_deploy_webapp(cmd, name, location=None, dryrun=False): else: sku = lang_details.get("default_sku") language = lang_details.get("language") - os_val = "Linux" if language.lower() == NODE_RUNTIME_NAME else OS_DEFAULT + is_java = language.lower() == JAVA_RUNTIME_NAME + os_val = "Linux" if language.lower() == NODE_RUNTIME_NAME or is_java else OS_DEFAULT # detect the version data = get_runtime_version_details(lang_details.get('file_loc'), language) version_used_create = data.get('to_create') @@ -100,7 +101,6 @@ def create_deploy_webapp(cmd, name, location=None, dryrun=False): src_path = "{} {}".format(src_dir.replace("\\", "\\\\"), str_no_contents_warn) rg_str = "{} {}".format(rg_name, rg_mssg) - dry_run_str = r""" { "name" : "%s", "serverfarm" : "%s", @@ -152,32 +152,38 @@ def create_deploy_webapp(cmd, name, location=None, dryrun=False): logger.warning("App '%s' already exists", name) if do_deployment: - # setting to build after deployment - logger.warning("Updating app settings to enable build after deployment") - update_app_settings(cmd, rg_name, name, ["SCM_DO_BUILD_DURING_DEPLOYMENT=true"]) - # work around until the timeout limits issue for linux is investigated & fixed - # wakeup kudu, by making an SCM call + if not is_java: + # setting to build after deployment + logger.warning("Updating app settings to enable build after deployment") + update_app_settings(cmd, rg_name, name, ["SCM_DO_BUILD_DURING_DEPLOYMENT=true"]) + # work around until the timeout limits issue for linux is investigated & fixed + # wakeup kudu, by making an SCM call import requests # work around until the timeout limits issue for linux is investigated & fixed user_name, password = _get_site_credential(cmd.cli_ctx, rg_name, name) scm_url = _get_scm_url(cmd, rg_name, name) + import urllib3 authorization = urllib3.util.make_headers(basic_auth='{0}:{1}'.format(user_name, password)) requests.get(scm_url + '/api/settings', headers=authorization) - logger.warning("Creating zip with contents of dir %s ...", src_dir) - # zip contents & deploy - zip_file_path = zip_contents_from_dir(src_dir, language) + if is_java: + zip_file_path = src_path + '\\\\' + lang_details.get('file_loc')[0] + else: + logger.warning("Creating zip with contents of dir %s ...", src_dir) + # zip contents & deploy + zip_file_path = zip_contents_from_dir(src_dir, language) logger.warning("Deploying and building contents to app." "This operation can take some time to finish...") enable_zip_deploy(cmd, rg_name, name, zip_file_path) - # Remove the file afer deployment, handling exception if user removed the file manually - try: - os.remove(zip_file_path) - except OSError: - pass + if not is_java: + # Remove the file afer deployment, handling exception if user removed the file manually + try: + os.remove(zip_file_path) + except OSError: + pass else: logger.warning("No 'NODE' or 'DOTNETCORE' package detected, skipping zip and deploy process") create_json.update({'app_url': url}) @@ -247,3 +253,4 @@ def create_tunnel(cmd, resource_group_name, name, port, slot=None): break logger.warning('Tunnel is ready! Creating on port %s', port) tunnel_server.start_server() + \ No newline at end of file