Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package azure-cli-core for openSUSE:Factory checked in at 2021-09-17 23:25:42 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/azure-cli-core (Old) and /work/SRC/openSUSE:Factory/.azure-cli-core.new.1899 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "azure-cli-core" Fri Sep 17 23:25:42 2021 rev:29 rq:918721 version:2.28.1 Changes: -------- --- /work/SRC/openSUSE:Factory/azure-cli-core/azure-cli-core.changes 2021-09-10 23:40:39.386517580 +0200 +++ /work/SRC/openSUSE:Factory/.azure-cli-core.new.1899/azure-cli-core.changes 2021-09-17 23:25:58.945237832 +0200 @@ -1,0 +2,8 @@ +Fri Sep 10 09:11:43 UTC 2021 - John Paul Adrian Glaubitz <adrian.glaub...@suse.com> + +- New upstream release + + Version 2.28.1 + + For detailed information about changes see the + HISTORY.rst file provided with this package + +------------------------------------------------------------------- Old: ---- azure-cli-core-2.27.2.tar.gz New: ---- azure-cli-core-2.28.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ azure-cli-core.spec ++++++ --- /var/tmp/diff_new_pack.UEwMba/_old 2021-09-17 23:25:59.357238199 +0200 +++ /var/tmp/diff_new_pack.UEwMba/_new 2021-09-17 23:25:59.357238199 +0200 @@ -17,7 +17,7 @@ Name: azure-cli-core -Version: 2.27.2 +Version: 2.28.1 Release: 0 Summary: Microsoft Azure CLI Core Module License: MIT ++++++ azure-cli-core-2.27.2.tar.gz -> azure-cli-core-2.28.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.27.2/HISTORY.rst new/azure-cli-core-2.28.1/HISTORY.rst --- old/azure-cli-core-2.27.2/HISTORY.rst 2021-08-23 05:32:32.000000000 +0200 +++ new/azure-cli-core-2.28.1/HISTORY.rst 2021-09-09 09:00:29.000000000 +0200 @@ -3,6 +3,14 @@ Release History =============== +2.28.1 +++++++ +* No changes + +2.28.0 +++++++ +* Conditional Access: Show `--scope` for `az login` message when failed to refresh the access token (#17738) + 2.27.2 ++++++ * No changes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.27.2/PKG-INFO new/azure-cli-core-2.28.1/PKG-INFO --- old/azure-cli-core-2.27.2/PKG-INFO 2021-08-23 05:32:40.267739800 +0200 +++ new/azure-cli-core-2.28.1/PKG-INFO 2021-09-09 09:00:43.452860600 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: azure-cli-core -Version: 2.27.2 +Version: 2.28.1 Summary: Microsoft Azure Command-Line Tools Core Module Home-page: https://github.com/Azure/azure-cli Author: Microsoft Corporation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.27.2/azure/cli/core/__init__.py new/azure-cli-core-2.28.1/azure/cli/core/__init__.py --- old/azure-cli-core-2.27.2/azure/cli/core/__init__.py 2021-08-23 05:32:32.000000000 +0200 +++ new/azure-cli-core-2.28.1/azure/cli/core/__init__.py 2021-09-09 09:00:29.000000000 +0200 @@ -4,7 +4,7 @@ # -------------------------------------------------------------------------------------------- # pylint: disable=line-too-long -__version__ = "2.27.2" +__version__ = "2.28.1" import os import sys diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.27.2/azure/cli/core/_profile.py new/azure-cli-core-2.28.1/azure/cli/core/_profile.py --- old/azure-cli-core-2.27.2/azure/cli/core/_profile.py 2021-08-23 05:32:32.000000000 +0200 +++ new/azure-cli-core-2.28.1/azure/cli/core/_profile.py 2021-09-09 09:00:29.000000000 +0200 @@ -19,7 +19,7 @@ from azure.cli.core._environment import get_config_dir from azure.cli.core._session import ACCOUNT from azure.cli.core.util import get_file_json, in_cloud_console, open_page_in_browser, can_launch_browser,\ - is_windows, is_wsl, scopes_to_resource + is_windows, is_wsl, scopes_to_resource, resource_to_scopes from azure.cli.core.cloud import get_active_cloud, set_cloud_subscription logger = get_logger(__name__) @@ -574,11 +574,7 @@ "Please run `az login` with a user account or a service principal.") if identity_type is None: - def _retrieve_token(sdk_resource=None): - # When called by - # - Track 1 SDK, use `resource` specified by CLI - # - Track 2 SDK, use `sdk_resource` specified by SDK and ignore `resource` specified by CLI - token_resource = sdk_resource or resource + def _retrieve_token(token_resource): logger.debug("Retrieving token from ADAL for resource %r", token_resource) if in_cloud_console() and account[_USER_ENTITY].get(_CLOUD_SHELL_ID): @@ -591,8 +587,7 @@ account[_TENANT_ID], use_cert_sn_issuer) - def _retrieve_tokens_from_external_tenants(sdk_resource=None): - token_resource = sdk_resource or resource + def _retrieve_tokens_from_external_tenants(token_resource): logger.debug("Retrieving token from ADAL for external tenants and resource %r", token_resource) external_tokens = [] @@ -607,7 +602,8 @@ from azure.cli.core.adal_authentication import AdalAuthentication auth_object = AdalAuthentication(_retrieve_token, - _retrieve_tokens_from_external_tenants if external_tenants_info else None) + _retrieve_tokens_from_external_tenants if external_tenants_info else None, + resource=resource) else: if self._msi_creds is None: self._msi_creds = MsiAccountTypes.msi_auth_factory(identity_type, identity_id, resource) @@ -630,6 +626,19 @@ import posixpath authority = posixpath.join(self.cli_ctx.cloud.endpoints.active_directory, tenant) + # Raise error for managed identity and Cloud Shell + not_support_message = "VM SSH currently doesn't support {}." + + # managed identity + managed_identity_type, _ = Profile._try_parse_msi_account_name(account) + if managed_identity_type: + raise CLIError(not_support_message.format("managed identity")) + + # Cloud Shell + if in_cloud_console() and account[_USER_ENTITY].get(_CLOUD_SHELL_ID): + raise CLIError(not_support_message.format("Cloud Shell")) + + # user if identity_type == _USER: # Use ARM as resource to get the refresh token from ADAL token cache resource = self.cli_ctx.cloud.endpoints.active_directory_resource_id @@ -649,6 +658,7 @@ token_entry = self._login_with_authorization_code_flow(tenant, scopes_to_resource(scopes)) result = cred.acquire_token_by_refresh_token(token_entry['refreshToken'], scopes, data=data) + # service principal elif identity_type == _SERVICE_PRINCIPAL: from azure.cli.core.msal_authentication import ServicePrincipalCredential @@ -656,11 +666,12 @@ sp_credential = self._creds_cache.retrieve_cred_for_service_principal(sp_id) cred = ServicePrincipalCredential(sp_id, secret_or_certificate=sp_credential, authority=authority) result = cred.get_token(scopes=scopes, data=data) + else: - raise CLIError("Identity type {} is currently unsupported".format(identity_type)) + raise CLIError("Unknown identity type {}".format(identity_type)) if 'error' in result: - from azure.cli.core.adal_authentication import aad_error_handler + from azure.cli.core.auth.util import aad_error_handler aad_error_handler(result) return username_or_sp_id, result["access_token"] @@ -706,7 +717,7 @@ use_cert_sn_issuer) except adal.AdalError as ex: from azure.cli.core.adal_authentication import adal_error_handler - adal_error_handler(ex) + adal_error_handler(ex, scopes=resource_to_scopes(resource)) return (creds, None if tenant else str(account[_SUBSCRIPTION_ID]), str(tenant if tenant else account[_TENANT_ID])) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.27.2/azure/cli/core/adal_authentication.py new/azure-cli-core-2.28.1/azure/cli/core/adal_authentication.py --- old/azure-cli-core-2.27.2/azure/cli/core/adal_authentication.py 2021-08-23 05:32:32.000000000 +0200 +++ new/azure-cli-core-2.28.1/azure/cli/core/adal_authentication.py 2021-09-09 09:00:29.000000000 +0200 @@ -9,7 +9,7 @@ from msrest.authentication import Authentication from msrestazure.azure_active_directory import MSIAuthentication from azure.core.credentials import AccessToken -from azure.cli.core.util import in_cloud_console, scopes_to_resource +from azure.cli.core.util import in_cloud_console, scopes_to_resource, resource_to_scopes from knack.util import CLIError from knack.log import get_logger @@ -19,7 +19,7 @@ class AdalAuthentication(Authentication): # pylint: disable=too-few-public-methods - def __init__(self, token_retriever, external_tenant_token_retriever=None): + def __init__(self, token_retriever, external_tenant_token_retriever=None, resource=None): # DO NOT call _token_retriever from outside azure-cli-core. It is only available for user or # Service Principal credential (AdalAuthentication), but not for Managed Identity credential # (MSIAuthenticationWrapper). @@ -28,16 +28,23 @@ # - AdalAuthentication.get_token, which is designed for Track 2 SDKs self._token_retriever = token_retriever self._external_tenant_token_retriever = external_tenant_token_retriever + self._resource = resource def _get_token(self, sdk_resource=None): """ :param sdk_resource: `resource` converted from Track 2 SDK's `scopes` """ + + # When called by + # - Track 1 SDK, use `resource` specified by CLI + # - Track 2 SDK, use `sdk_resource` specified by SDK and ignore `resource` specified by CLI + token_resource = sdk_resource or self._resource + external_tenant_tokens = None try: - scheme, token, token_entry = self._token_retriever(sdk_resource) + scheme, token, token_entry = self._token_retriever(token_resource) if self._external_tenant_token_retriever: - external_tenant_tokens = self._external_tenant_token_retriever(sdk_resource) + external_tenant_tokens = self._external_tenant_token_retriever(token_resource) except CLIError as err: if in_cloud_console(): AdalAuthentication._log_hostname() @@ -45,7 +52,7 @@ except adal.AdalError as err: if in_cloud_console(): AdalAuthentication._log_hostname() - adal_error_handler(err) + adal_error_handler(err, scopes=resource_to_scopes(token_resource)) except requests.exceptions.SSLError as err: from .util import SSLERROR_TEMPLATE raise CLIError(SSLERROR_TEMPLATE.format(str(err))) @@ -236,24 +243,11 @@ return dt.timestamp() -def aad_error_handler(error: dict): - """ Handle the error from AAD server returned by ADAL or MSAL. """ - login_message = ("To re-authenticate, please {}. If the problem persists, " - "please contact your tenant administrator." - .format("refresh Azure Portal" if in_cloud_console() else "run `az login`")) - - # https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-aadsts-error-codes - # Search for an error code at https://login.microsoftonline.com/error - msg = error.get('error_description') - - from azure.cli.core.azclierror import AuthenticationError - raise AuthenticationError(msg, login_message) - - -def adal_error_handler(err: adal.AdalError): +def adal_error_handler(err: adal.AdalError, **kwargs): """ Handle AdalError. """ try: - aad_error_handler(err.error_response) + from azure.cli.core.auth.util import aad_error_handler + aad_error_handler(err.error_response, **kwargs) except AttributeError: # In case of AdalError created as # AdalError('More than one token matches the criteria. The result is ambiguous.') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.27.2/azure/cli/core/auth/__init__.py new/azure-cli-core-2.28.1/azure/cli/core/auth/__init__.py --- old/azure-cli-core-2.27.2/azure/cli/core/auth/__init__.py 1970-01-01 01:00:00.000000000 +0100 +++ new/azure-cli-core-2.28.1/azure/cli/core/auth/__init__.py 2021-09-09 09:00:29.000000000 +0200 @@ -0,0 +1,4 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.27.2/azure/cli/core/auth/util.py new/azure-cli-core-2.28.1/azure/cli/core/auth/util.py --- old/azure-cli-core-2.27.2/azure/cli/core/auth/util.py 1970-01-01 01:00:00.000000000 +0100 +++ new/azure-cli-core-2.28.1/azure/cli/core/auth/util.py 2021-09-09 09:00:29.000000000 +0200 @@ -0,0 +1,45 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + + +def aad_error_handler(error, **kwargs): + """ Handle the error from AAD server returned by ADAL or MSAL. """ + + # https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-aadsts-error-codes + # Search for an error code at https://login.microsoftonline.com/error + msg = error.get('error_description') + login_message = _generate_login_message(**kwargs) + + from azure.cli.core.azclierror import AuthenticationError + raise AuthenticationError(msg, recommendation=login_message) + + +def _generate_login_command(scopes=None): + login_command = ['az login'] + + if scopes: + login_command.append('--scope {}'.format(' '.join(scopes))) + + return ' '.join(login_command) + + +def _generate_login_message(**kwargs): + from azure.cli.core.util import in_cloud_console + login_command = _generate_login_command(**kwargs) + + msg = "To re-authenticate, please {}" .format( + "refresh Azure Portal." if in_cloud_console() else "run:\n{}".format(login_command)) + + return msg + + +def decode_access_token(access_token): + # Decode the access token. We can do the same with https://jwt.ms + from msal.oauth2cli.oidc import decode_part + import json + + # Access token consists of headers.claims.signature. Decode the claim part + decoded_str = decode_part(access_token.split('.')[1]) + return json.loads(decoded_str) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.27.2/azure/cli/core/extension/operations.py new/azure-cli-core-2.28.1/azure/cli/core/extension/operations.py --- old/azure-cli-core-2.27.2/azure/cli/core/extension/operations.py 2021-08-23 05:32:32.000000000 +0200 +++ new/azure-cli-core-2.28.1/azure/cli/core/extension/operations.py 2021-09-09 09:00:29.000000000 +0200 @@ -18,7 +18,7 @@ from packaging.version import parse from azure.cli.core import CommandIndex -from azure.cli.core.util import CLIError, reload_module +from azure.cli.core.util import CLIError, reload_module, rmtree_with_retry from azure.cli.core.extension import (extension_exists, build_extension_path, get_extensions, get_extension_modname, get_extension, ext_compat_with_cli, EXT_METADATA_ISPREVIEW, EXT_METADATA_ISEXPERIMENTAL, @@ -559,22 +559,3 @@ "for your distribution or change the above file accordingly.") logger.debug("Linux distro check: %s has '%s', current distro is '%s'", LIST_FILE_PATH, stored_linux_dist_name, current_linux_dist_name) - - -def rmtree_with_retry(path): - # A workaround for https://bugs.python.org/issue33240 - # Retry shutil.rmtree several times, but even if it fails after several retries, don't block the command execution. - retry_num = 3 - import time - while True: - try: - shutil.rmtree(path) - return - except OSError as err: - if retry_num > 0: - logger.warning("Failed to delete '%s': %s. Retrying ...", path, err) - retry_num -= 1 - time.sleep(1) - else: - logger.warning("Failed to delete '%s': %s. You may try to delete it manually.", path, err) - break diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.27.2/azure/cli/core/profiles/_shared.py new/azure-cli-core-2.28.1/azure/cli/core/profiles/_shared.py --- old/azure-cli-core-2.27.2/azure/cli/core/profiles/_shared.py 2021-08-23 05:32:32.000000000 +0200 +++ new/azure-cli-core-2.28.1/azure/cli/core/profiles/_shared.py 2021-09-09 09:00:29.000000000 +0200 @@ -63,7 +63,7 @@ MGMT_APPSERVICE = ('azure.mgmt.web', 'WebSiteManagementClient') MGMT_IOTCENTRAL = ('azure.mgmt.iotcentral', 'IotCentralClient') MGMT_IOTHUB = ('azure.mgmt.iothub', 'IotHubClient') - MGMT_ARO = ('azure.mgmt.redhatopenshift', 'AzureRedHatOpenShiftClient') + MGMT_ARO = ('azure.mgmt.redhatopenshift', 'AzureRedHatOpenShift4Client') MGMT_DATABOXEDGE = ('azure.mgmt.databoxedge', 'DataBoxEdgeManagementClient') MGMT_CUSTOMLOCATION = ('azure.mgmt.extendedlocation', 'CustomLocations') MGMT_CONTAINERSERVICE = ('azure.mgmt.containerservice', 'ContainerServiceClient') @@ -143,7 +143,7 @@ 'latest': { ResourceType.MGMT_STORAGE: '2021-04-01', ResourceType.MGMT_NETWORK: '2021-02-01', - ResourceType.MGMT_COMPUTE: SDKProfile('2021-03-01', { + ResourceType.MGMT_COMPUTE: SDKProfile('2021-04-01', { 'resource_skus': '2019-04-01', 'disks': '2020-12-01', 'disk_encryption_sets': '2020-12-01', @@ -153,9 +153,9 @@ 'gallery_images': '2020-09-30', 'gallery_image_versions': '2020-09-30', 'shared_galleries': '2020-09-30', - 'virtual_machine_scale_sets': '2021-03-01' + 'virtual_machine_scale_sets': '2021-04-01' }), - ResourceType.MGMT_RESOURCE_FEATURES: '2015-12-01', + ResourceType.MGMT_RESOURCE_FEATURES: '2021-07-01', ResourceType.MGMT_RESOURCE_LINKS: '2016-09-01', ResourceType.MGMT_RESOURCE_LOCKS: '2016-09-01', ResourceType.MGMT_RESOURCE_POLICY: '2020-09-01', @@ -220,12 +220,12 @@ 'subscription_diagnostic_settings': '2017-05-01-preview' }), ResourceType.MGMT_APPSERVICE: '2020-09-01', - ResourceType.MGMT_IOTHUB: '2021-03-31', + ResourceType.MGMT_IOTHUB: '2021-07-01', ResourceType.MGMT_IOTCENTRAL: '2018-09-01', ResourceType.MGMT_ARO: '2020-04-30', ResourceType.MGMT_DATABOXEDGE: '2021-02-01-preview', ResourceType.MGMT_CUSTOMLOCATION: '2021-03-15-preview', - ResourceType.MGMT_CONTAINERSERVICE: SDKProfile('2021-05-01', { + ResourceType.MGMT_CONTAINERSERVICE: SDKProfile('2021-07-01', { 'container_services': '2017-07-01', 'open_shift_managed_clusters': '2019-09-30-preview' }) @@ -245,7 +245,7 @@ 'virtual_machine_scale_sets': '2020-06-01' }), ResourceType.MGMT_KEYVAULT: '2016-10-01', - ResourceType.MGMT_RESOURCE_FEATURES: '2015-12-01', + ResourceType.MGMT_RESOURCE_FEATURES: '2021-07-01', ResourceType.MGMT_RESOURCE_LINKS: '2016-09-01', ResourceType.MGMT_RESOURCE_LOCKS: '2016-09-01', ResourceType.MGMT_RESOURCE_POLICY: '2016-12-01', @@ -253,7 +253,7 @@ ResourceType.MGMT_RESOURCE_SUBSCRIPTIONS: '2016-06-01', ResourceType.MGMT_RESOURCE_TEMPLATESPECS: '2015-01-01', ResourceType.MGMT_NETWORK_DNS: '2016-04-01', - ResourceType.MGMT_AUTHORIZATION: SDKProfile('2016-09-01', { + ResourceType.MGMT_AUTHORIZATION: SDKProfile('2015-07-01', { 'classic_administrators': '2015-06-01', 'policy_assignments': '2016-12-01', 'policy_definitions': '2016-12-01' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.27.2/azure/cli/core/style.py new/azure-cli-core-2.28.1/azure/cli/core/style.py --- old/azure-cli-core-2.27.2/azure/cli/core/style.py 2021-08-23 05:32:32.000000000 +0200 +++ new/azure-cli-core-2.28.1/azure/cli/core/style.py 2021-09-09 09:00:29.000000000 +0200 @@ -152,12 +152,15 @@ if isinstance(theme, str): theme = get_theme_dict(theme) - # Cache the value of is_legacy_powershell - if not hasattr(format_styled_text, "_is_legacy_powershell"): - from azure.cli.core.util import get_parent_proc_name - is_legacy_powershell = not is_modern_terminal() and get_parent_proc_name() == "powershell.exe" - setattr(format_styled_text, "_is_legacy_powershell", is_legacy_powershell) - is_legacy_powershell = getattr(format_styled_text, "_is_legacy_powershell") + # If style is enabled, cache the value of is_legacy_powershell. + # Otherwise if theme is None, is_legacy_powershell is meaningless. + is_legacy_powershell = None + if theme: + if not hasattr(format_styled_text, "_is_legacy_powershell"): + from azure.cli.core.util import get_parent_proc_name + is_legacy_powershell = not is_modern_terminal() and get_parent_proc_name() == "powershell.exe" + setattr(format_styled_text, "_is_legacy_powershell", is_legacy_powershell) + is_legacy_powershell = getattr(format_styled_text, "_is_legacy_powershell") # https://python-prompt-toolkit.readthedocs.io/en/stable/pages/printing_text.html#style-text-tuples formatted_parts = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.27.2/azure/cli/core/util.py new/azure-cli-core-2.28.1/azure/cli/core/util.py --- old/azure-cli-core-2.27.2/azure/cli/core/util.py 2021-08-23 05:32:32.000000000 +0200 +++ new/azure-cli-core-2.28.1/azure/cli/core/util.py 2021-09-09 09:00:29.000000000 +0200 @@ -4,17 +4,18 @@ # -------------------------------------------------------------------------------------------- # pylint: disable=too-many-lines -import sys -import json -import getpass import base64 import binascii +import getpass +import json +import logging +import os import platform -import ssl import re -import logging - +import ssl +import sys from urllib.request import urlopen + from knack.log import get_logger from knack.util import CLIError, to_snake_case @@ -271,7 +272,7 @@ def get_latest_from_github(package_path='azure-cli'): try: import requests - git_url = "https://raw.githubusercontent.com/Azure/azure-cli/master/src/{}/setup.py".format(package_path) + git_url = "https://raw.githubusercontent.com/Azure/azure-cli/main/src/{}/setup.py".format(package_path) response = requests.get(git_url, timeout=10) if response.status_code != 200: logger.info("Failed to fetch the latest version from '%s' with status code '%s' and reason '%s'", @@ -379,7 +380,6 @@ else: _print(ext.name.ljust(20) + (ext.version or 'Unknown').rjust(20)) _print() - import os _print("Python location '{}'".format(os.path.abspath(sys.executable))) _print("Extensions directory '{}'".format(EXTENSIONS_DIR)) if os.path.isdir(EXTENSIONS_SYS_DIR) and os.listdir(EXTENSIONS_SYS_DIR): @@ -522,8 +522,8 @@ "https://docs.microsoft.com/cli/azure/use-cli-effectively#quoting-issues" # Recommendation especially for PowerShell - parent_proc = get_parent_proc_name().lower() - if parent_proc in ("powershell.exe", "pwsh.exe"): + parent_proc = get_parent_proc_name() + if parent_proc and parent_proc.lower() in ("powershell.exe", "pwsh.exe"): recommendation += "\nPowerShell requires additional quoting rules. See " \ "https://github.com/Azure/azure-cli/blob/dev/doc/quoting-issues-with-powershell.md" @@ -581,7 +581,6 @@ def in_cloud_console(): - import os return os.environ.get('ACC_CLOUD', None) @@ -610,7 +609,6 @@ def should_disable_connection_verify(): - import os return bool(os.environ.get(DISABLE_VERIFY_VARIABLE_NAME)) @@ -657,7 +655,8 @@ try: # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe # Ampersand (&) should be quoted - return subprocess.Popen(['powershell.exe', '-NoProfile', '-Command', 'Start-Process "{}"'.format(url)]) + return subprocess.Popen( + ['powershell.exe', '-NoProfile', '-Command', 'Start-Process "{}"'.format(url)]).wait() except OSError: # WSL might be too old # FileNotFoundError introduced in Python 3 pass elif platform_name == 'darwin': @@ -695,7 +694,6 @@ def can_launch_browser(): - import os import webbrowser platform_name, _ = _get_platform_info() if is_wsl() or platform_name != 'linux': @@ -829,7 +827,6 @@ # Borrow AZURE_HTTP_USER_AGENT from msrest # https://github.com/Azure/msrest-for-python/blob/4cc8bc84e96036f03b34716466230fb257e27b36/msrest/pipeline/universal.py#L70 _ENV_ADDITIONAL_USER_AGENT = 'AZURE_HTTP_USER_AGENT' - import os if _ENV_ADDITIONAL_USER_AGENT in os.environ: agents.append(os.environ[_ENV_ADDITIONAL_USER_AGENT]) @@ -1097,7 +1094,6 @@ agents = ["AZURECLI/{}".format(core_version)] - import os from azure.cli.core._environment import _ENV_AZ_INSTALLER if _ENV_AZ_INSTALLER in os.environ: agents.append('({})'.format(os.environ[_ENV_AZ_INSTALLER])) @@ -1240,28 +1236,33 @@ logger.debug(ex) return None - import os - parent = psutil.Process(os.getpid()).parent() + try: + parent = psutil.Process(os.getpid()).parent() - # On Windows, when CLI is run inside a virtual env, there will be 2 python.exe. - if parent and parent.name().lower() == 'python.exe': - parent = parent.parent() - - if parent: - # On Windows, powershell.exe launches cmd.exe to launch python.exe. - grandparent = parent.parent() - if grandparent: - grandparent_name = grandparent.name().lower() - if grandparent_name in ("powershell.exe", "pwsh.exe"): - return grandparent.name() - # if powershell.exe or pwsh.exe is not the grandparent, simply return the parent's name. - return parent.name() + # On Windows, when CLI is run inside a virtual env, there will be 2 python.exe. + if parent and parent.name().lower() == 'python.exe': + parent = parent.parent() + + if parent: + # On Windows, powershell.exe launches cmd.exe to launch python.exe. + grandparent = parent.parent() + if grandparent: + grandparent_name = grandparent.name().lower() + if grandparent_name in ("powershell.exe", "pwsh.exe"): + return grandparent.name() + # if powershell.exe or pwsh.exe is not the grandparent, simply return the parent's name. + return parent.name() + except psutil.AccessDenied as ex: + # Ignore due to https://github.com/giampaolo/psutil/issues/1980 + logger.debug(ex) return None def get_parent_proc_name(): # This function wraps _get_parent_proc_name, as psutil calls are time-consuming, so use a # function-level cache to save the result. + # NOTE: The return value may be None if getting parent proc name fails, so always remember to + # check it first before calling string methods like lower(). if not hasattr(get_parent_proc_name, "return_value"): parent_proc_name = _get_parent_proc_name() setattr(get_parent_proc_name, "return_value", parent_proc_name) @@ -1272,3 +1273,23 @@ """In addition to knack.util.is_modern_terminal, detect Cloud Shell.""" import knack.util return knack.util.is_modern_terminal() or in_cloud_console() + + +def rmtree_with_retry(path): + # A workaround for https://bugs.python.org/issue33240 + # Retry shutil.rmtree several times, but even if it fails after several retries, don't block the command execution. + retry_num = 3 + import time + while True: + try: + import shutil + shutil.rmtree(path) + return + except OSError as err: + if retry_num > 0: + logger.warning("Failed to delete '%s': %s. Retrying ...", path, err) + retry_num -= 1 + time.sleep(1) + else: + logger.warning("Failed to delete '%s': %s. You may try to delete it manually.", path, err) + break diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.27.2/azure_cli_core.egg-info/PKG-INFO new/azure-cli-core-2.28.1/azure_cli_core.egg-info/PKG-INFO --- old/azure-cli-core-2.27.2/azure_cli_core.egg-info/PKG-INFO 2021-08-23 05:32:40.000000000 +0200 +++ new/azure-cli-core-2.28.1/azure_cli_core.egg-info/PKG-INFO 2021-09-09 09:00:43.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: azure-cli-core -Version: 2.27.2 +Version: 2.28.1 Summary: Microsoft Azure Command-Line Tools Core Module Home-page: https://github.com/Azure/azure-cli Author: Microsoft Corporation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.27.2/azure_cli_core.egg-info/SOURCES.txt new/azure-cli-core-2.28.1/azure_cli_core.egg-info/SOURCES.txt --- old/azure-cli-core-2.27.2/azure_cli_core.egg-info/SOURCES.txt 2021-08-23 05:32:40.000000000 +0200 +++ new/azure-cli-core-2.28.1/azure_cli_core.egg-info/SOURCES.txt 2021-09-09 09:00:43.000000000 +0200 @@ -32,6 +32,8 @@ azure/cli/core/style.py azure/cli/core/telemetry.py azure/cli/core/util.py +azure/cli/core/auth/__init__.py +azure/cli/core/auth/util.py azure/cli/core/auth_landing_pages/fail.html azure/cli/core/auth_landing_pages/ok.html azure/cli/core/commands/__init__.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-core-2.27.2/setup.py new/azure-cli-core-2.28.1/setup.py --- old/azure-cli-core-2.27.2/setup.py 2021-08-23 05:32:32.000000000 +0200 +++ new/azure-cli-core-2.28.1/setup.py 2021-09-09 09:00:29.000000000 +0200 @@ -8,7 +8,7 @@ from codecs import open from setuptools import setup, find_packages -VERSION = "2.27.2" +VERSION = "2.28.1" # If we have source, validate that our version numbers match # This should prevent uploading releases with mismatched versions.