def create_deploy_webapp(cmd, name, location=None, dryrun=False): import os client = web_client_factory(cmd.cli_ctx) # the code to deploy is expected to be the current directory the command is running from src_dir = os.getcwd() # if dir is empty, show a message in dry run do_deployment = False if os.listdir(src_dir) == [] else True # determine the details for app to be created from src contents lang_details = get_lang_from_content(src_dir) # we support E2E create and deploy for Node & dotnetcore, any other stack, set defaults for os & runtime # and skip deployment if lang_details['language'] is None: do_deployment = False sku = 'F1' os_val = OS_DEFAULT detected_version = '-' runtime_version = '-' else: sku = lang_details.get("default_sku") language = lang_details.get("language") is_skip_build = language.lower() == STATIC_RUNTIME_NAME os_val = "Linux" if language.lower( ) == NODE_RUNTIME_NAME else OS_DEFAULT # detect the version data = get_runtime_version_details(lang_details.get('file_loc'), language) version_used_create = data.get('to_create') detected_version = data.get('detected') runtime_version = "{}|{}".format(language, version_used_create) if \ version_used_create != "-" else version_used_create if location is None: locs = client.list_geo_regions(sku, True) available_locs = [] for loc in locs: available_locs.append(loc.geo_region_name) location = available_locs[0] # Remove spaces from the location string, incase the GeoRegion string is used loc_name = location.replace(" ", "") full_sku = get_sku_name(sku) is_linux = True if os_val == 'Linux' else False asp = "appsvc_asp_{}_{}".format(os_val, loc_name) rg_name = "appsvc_rg_{}_{}".format(os_val, loc_name) str_no_contents_warn = "" if not do_deployment: str_no_contents_warn = "[Empty directory, no deployment will be triggered]" # Resource group: check if default RG is set default_rg = cmd.cli_ctx.config.get('defaults', 'group', fallback=None) if default_rg and check_resource_group_exists(cmd, default_rg) and \ check_resource_group_supports_os(cmd, default_rg, location, is_linux): rg_name = default_rg rg_mssg = "[Using default Resource group]" else: rg_mssg = "" 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", "resourcegroup" : "%s", "sku": "%s", "os": "%s", "location" : "%s", "src_path" : "%s", "version_detected": "%s", "version_to_create": "%s" } """ % (name, asp, rg_str, full_sku, os_val, location, src_path, detected_version, runtime_version) create_json = json.loads(dry_run_str) if dryrun: logger.warning( "Web app will be created with the below configuration,re-run command " "without the --dryrun flag to create & deploy a new app") return create_json # create RG if the RG doesn't already exist if not check_resource_group_exists(cmd, rg_name): logger.warning("Creating Resource group '%s' ...", rg_name) create_resource_group(cmd, rg_name, location) logger.warning("Resource group creation complete") else: logger.warning("Resource group '%s' already exists.", rg_name) # create asp if not check_if_asp_exists(cmd, rg_name, asp): logger.warning("Creating App service plan '%s' ...", asp) sku_def = SkuDescription(tier=full_sku, name=sku, capacity=(1 if is_linux else None)) plan_def = AppServicePlan(loc_name, app_service_plan_name=asp, sku=sku_def, reserved=(is_linux or None)) client.app_service_plans.create_or_update(rg_name, asp, plan_def) logger.warning("App service plan creation complete") else: logger.warning("App service plan '%s' already exists.", asp) # create the app if not check_app_exists(cmd, rg_name, name): logger.warning("Creating app '%s' ....", name) create_webapp(cmd, rg_name, name, asp, runtime_version if is_linux else None) logger.warning("Webapp creation complete") else: logger.warning("App '%s' already exists", name) # update create_json to include the app_url url = _get_app_url( cmd, rg_name, name) # picks the custom domain URL incase a domain is assigned if do_deployment: if not is_skip_build: # 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 _ping_scm_site(cmd, rg_name, name) 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("Preparing to deploy %s contents to app.", '' if is_skip_build else 'and build') 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 else: logger.warning( 'No known package (Node, ASP.NET, .NETCORE, or Static Html) ' 'found skipping zip and deploy process') create_json.update({'app_url': url}) logger.warning("All done.") return create_json
def create_deploy_container_app(cmd, name, source_location=None, docker_custom_image_name=None, dryrun=False, registry_rg=None, registry_name=None): # pylint: disable=too-many-statements import os import json if not source_location: # the dockerfile is expected to be in the current directory the command is running from source_location = os.getcwd() client = web_client_factory(cmd.cli_ctx) _create_new_rg = True _create_new_asp = True _create_new_app = True _create_acr_img = True if docker_custom_image_name: logger.warning('Image will be pulled from DockerHub') img_name = docker_custom_image_name _create_acr_img = False else: logger.warning( 'Source code will be uploaded and built in Azure Container Registry' ) if not registry_name: raise CLIError("--registry-name not specified") if not registry_rg: raise CLIError("--registry-rg not specified") img_name = generate_img_name(source_location) sku = 'P1V2' full_sku = get_sku_name(sku) location = 'Central US' loc_name = 'centralus' asp = "appsvc_asp_linux_{}".format(loc_name) rg_name = "appsvc_rg_linux_{}".format(loc_name) # Resource group: check if default RG is set _create_new_rg = should_create_new_rg(cmd, rg_name, True) rg_str = "{}".format(rg_name) dry_run_str = r""" { "name" : "%s", "serverfarm" : "%s", "resourcegroup" : "%s", "sku": "%s", "location" : "%s" } """ % (name, asp, rg_str, full_sku, location) create_json = json.loads(dry_run_str) if dryrun: logger.warning( "Web app will be created with the below configuration,re-run command " "without the --dryrun flag to create & deploy a new app") return create_json if _create_acr_img: logger.warning("Starting ACR build") queue_acr_build(cmd, registry_rg, registry_name, img_name, source_location) logger.warning("ACR build done. Deploying web app.") # create RG if the RG doesn't already exist if _create_new_rg: logger.warning("Creating Resource group '%s' ...", rg_name) create_resource_group(cmd, rg_name, location) logger.warning("Resource group creation complete") _create_new_asp = True else: logger.warning("Resource group '%s' already exists.", rg_name) _create_new_asp = _should_create_new_asp(cmd, rg_name, asp, location) # create new ASP if an existing one cannot be used if _create_new_asp: logger.warning("Creating App service plan '%s' ...", asp) sku_def = SkuDescription(tier=full_sku, name=sku, capacity=1) plan_def = AppServicePlan(location=loc_name, app_service_plan_name=asp, sku=sku_def, reserved=True) client.app_service_plans.create_or_update(rg_name, asp, plan_def) logger.warning("App service plan creation complete") _create_new_app = True else: logger.warning("App service plan '%s' already exists.", asp) _create_new_app = should_create_new_app(cmd, rg_name, name) # create the app if _create_new_app: logger.warning("Creating app '%s' ....", name) # TODO: Deploy without container params and update separately instead? # deployment_container_image_name=docker_custom_image_name) create_webapp(cmd, rg_name, name, asp, deployment_container_image_name=img_name) logger.warning("Webapp creation complete") else: logger.warning("App '%s' already exists", name) # Set up the container if _create_acr_img: logger.warning("Configuring ACR container settings.") registry_url = 'https://' + registry_name + '.azurecr.io' acr_img_name = registry_name + '.azurecr.io/' + img_name update_container_settings(cmd, rg_name, name, registry_url, acr_img_name) logger.warning("All done.") return create_json