Esempio n. 1
0
def list_available_extensions(index_url=None, show_details=False):
    index_data = get_index_extensions(index_url=index_url)
    if show_details:
        return index_data
    installed_extensions = get_extensions()
    installed_extension_names = [e.name for e in installed_extensions]
    results = []
    for name, items in OrderedDict(sorted(index_data.items())).items():
        # exclude extensions/versions incompatible with current CLI version
        items = [item for item in items if ext_compat_with_cli(item['metadata'])[0]]
        if not items:
            continue

        latest = max(items, key=lambda c: parse_version(c['metadata']['version']))
        installed = False
        if name in installed_extension_names:
            installed = True
            ext_version = get_extension(name).version
            if ext_version and parse_version(latest['metadata']['version']) > parse_version(ext_version):
                installed = str(True) + ' (upgrade available)'
        results.append({
            'name': name,
            'version': latest['metadata']['version'],
            'summary': latest['metadata']['summary'],
            'preview': latest['metadata'].get(EXT_METADATA_ISPREVIEW, False),
            'installed': installed
        })
    return results
Esempio n. 2
0
def get_az_version_string():
    import platform
    from azure.cli.core.extension import get_extensions, EXTENSIONS_DIR, DEV_EXTENSION_SOURCES

    output = six.StringIO()
    installed_dists = get_installed_cli_distributions()

    cli_info = None
    for dist in installed_dists:
        if dist.key == CLI_PACKAGE_NAME:
            cli_info = {'name': dist.key, 'version': dist.version}
            break

    def _print(val=''):
        print(val, file=output)

    if cli_info:
        _print('{} ({})'.format(cli_info['name'], cli_info['version']))

    component_version_info = sorted([{'name': dist.key.replace(COMPONENT_PREFIX, ''),
                                      'version': dist.version}
                                     for dist in installed_dists
                                     if dist.key.startswith(COMPONENT_PREFIX)],
                                    key=lambda x: x['name'])
    _print()
    _print('\n'.join(['{} ({})'.format(c['name'], c['version']) for c in component_version_info]))
    _print()
    extensions = get_extensions()
    if extensions:
        _print('Extensions:')
        for ext in extensions:
            if ext.ext_type == 'dev':
                _print('{} ({}) [{}]'.format(ext.name, ext.version, ext.path))
            else:
                _print('{} ({})'.format(ext.name, ext.version))
        _print()
    _print("Python location '{}'".format(sys.executable))
    _print("Extensions directory '{}'".format(EXTENSIONS_DIR))
    if DEV_EXTENSION_SOURCES:
        _print("Development extension sources:")
        for source in DEV_EXTENSION_SOURCES:
            _print('    {}'.format(source))
    _print()
    _print('Python ({}) {}'.format(platform.system(), sys.version))
    _print()
    _print('Legal docs and information: aka.ms/AzureCliLegal')
    _print()
    version_string = output.getvalue()
    return version_string
Esempio n. 3
0
        def _update_command_table_from_extensions(ext_suppressions):

            def _handle_extension_suppressions(extensions):
                filtered_extensions = []
                for ext in extensions:
                    should_include = True
                    for suppression in ext_suppressions:
                        if should_include and suppression.handle_suppress(ext):
                            should_include = False
                    if should_include:
                        filtered_extensions.append(ext)
                return filtered_extensions

            extensions = get_extensions()
            if extensions:
                logger.debug("Found %s extensions: %s", len(extensions), [e.name for e in extensions])
                allowed_extensions = _handle_extension_suppressions(extensions)
                module_commands = set(self.command_table.keys())
                for ext in allowed_extensions:
                    ext_name = ext.name
                    ext_dir = ext.path or get_extension_path(ext_name)
                    sys.path.append(ext_dir)
                    try:
                        ext_mod = get_extension_modname(ext_name, ext_dir=ext_dir)
                        # Add to the map. This needs to happen before we load commands as registering a command
                        # from an extension requires this map to be up-to-date.
                        # self._mod_to_ext_map[ext_mod] = ext_name
                        start_time = timeit.default_timer()
                        extension_command_table, extension_group_table = \
                            _load_extension_command_loader(self, args, ext_mod)

                        for cmd_name, cmd in extension_command_table.items():
                            cmd.command_source = ExtensionCommandSource(
                                extension_name=ext_name,
                                overrides_command=cmd_name in module_commands,
                                preview=ext.preview)

                        self.command_table.update(extension_command_table)
                        self.command_group_table.update(extension_group_table)
                        elapsed_time = timeit.default_timer() - start_time
                        logger.debug("Loaded extension '%s' in %.3f seconds.", ext_name, elapsed_time)
                    except Exception:  # pylint: disable=broad-except
                        self.cli_ctx.raise_event(EVENT_FAILED_EXTENSION_LOAD, extension_name=ext_name)
                        logger.warning("Unable to load extension '%s'. Use --debug for more information.", ext_name)
                        logger.debug(traceback.format_exc())
Esempio n. 4
0
def get_extension_modules():
    from importlib import import_module
    import pkgutil
    from azure.cli.core.extension import get_extensions, get_extension_path, get_extension_modname
    extension_whls = get_extensions()
    ext_modules = []
    if extension_whls:
        for ext_name in [e.name for e in extension_whls]:
            ext_dir = get_extension_path(ext_name)
            sys.path.append(ext_dir)
            try:
                ext_mod = get_extension_modname(ext_name, ext_dir=ext_dir)
                module = import_module(ext_mod)
                setattr(module, 'path', module.__path__[0])
                ext_modules.append((module, ext_mod))
            except Exception as ex:
                display("Error importing '{}' extension: {}".format(ext_mod, ex))
    return ext_modules
Esempio n. 5
0
def get_az_version_string():
    import platform
    from azure.cli.core.extension import get_extensions, EXTENSIONS_DIR

    output = six.StringIO()
    installed_dists = get_installed_cli_distributions()

    cli_info = None
    for dist in installed_dists:
        if dist.key == CLI_PACKAGE_NAME:
            cli_info = {'name': dist.key, 'version': dist.version}
            break

    if cli_info:
        print('{} ({})'.format(cli_info['name'], cli_info['version']), file=output)

    component_version_info = sorted([{'name': dist.key.replace(COMPONENT_PREFIX, ''),
                                      'version': dist.version}
                                     for dist in installed_dists
                                     if dist.key.startswith(COMPONENT_PREFIX)],
                                    key=lambda x: x['name'])
    print(file=output)
    print('\n'.join(['{} ({})'.format(c['name'], c['version']) for c in component_version_info]),
          file=output)
    print(file=output)
    extensions = get_extensions()
    if extensions:
        print('Extensions:', file=output)
        print('\n'.join(['{} ({})'.format(c.name, c.version) for c in extensions]),
              file=output)
        print(file=output)
    print("Python location '{}'".format(sys.executable), file=output)
    print("Extensions directory '{}'".format(EXTENSIONS_DIR), file=output)
    print(file=output)
    print('Python ({}) {}'.format(platform.system(), sys.version), file=output)
    print(file=output)
    print('Legal docs and information: aka.ms/AzureCliLegal', file=output)
    print(file=output)
    version_string = output.getvalue()
    return version_string
Esempio n. 6
0
def list_available_extensions(index_url=None, show_details=False):
    index_data = get_index_extensions(index_url=index_url)
    if show_details:
        return index_data
    installed_extensions = get_extensions()
    installed_extension_names = [e.name for e in installed_extensions]
    results = []
    for name, items in OrderedDict(sorted(index_data.items())).items():
        latest = sorted(items, key=lambda c: parse_version(c['metadata']['version']), reverse=True)[0]
        installed = False
        if name in installed_extension_names:
            installed = True
            ext_version = get_extension(name).version
            if ext_version and parse_version(latest['metadata']['version']) > parse_version(ext_version):
                installed = str(True) + ' (upgrade available)'
        results.append({
            'name': name,
            'version': latest['metadata']['version'],
            'summary': latest['metadata']['summary'],
            'preview': latest['metadata'].get(EXT_METADATA_ISPREVIEW, False),
            'installed': installed
        })
    return results
Esempio n. 7
0
def get_az_version_string():
    from azure.cli.core.extension import get_extensions, EXTENSIONS_DIR, DEV_EXTENSION_SOURCES

    output = six.StringIO()
    versions = {}

    # get locally installed versions
    for dist in get_installed_cli_distributions():
        if dist.key == CLI_PACKAGE_NAME:
            versions[CLI_PACKAGE_NAME] = {'local': dist.version}
        elif dist.key.startswith(COMPONENT_PREFIX):
            comp_name = dist.key.replace(COMPONENT_PREFIX, '')
            versions[comp_name] = {'local': dist.version}

    # get the versions from pypi
    versions, success = _update_latest_from_pypi(versions)
    updates_available = 0

    def _print(val=''):
        print(val, file=output)

    def _get_version_string(name, version_dict):
        from distutils.version import LooseVersion  # pylint: disable=import-error,no-name-in-module
        local = version_dict['local']
        pypi = version_dict.get('pypi', None)
        if pypi and LooseVersion(pypi) > LooseVersion(local):
            return name.ljust(25) + local.rjust(15) + ' *'
        return name.ljust(25) + local.rjust(15)

    ver_string = _get_version_string(CLI_PACKAGE_NAME,
                                     versions.pop(CLI_PACKAGE_NAME))
    if '*' in ver_string:
        updates_available += 1
    _print(ver_string)
    _print()
    for name in sorted(versions.keys()):
        ver_string = _get_version_string(name, versions.pop(name))
        if '*' in ver_string:
            updates_available += 1
        _print(ver_string)
    _print()
    extensions = get_extensions()
    if extensions:
        _print('Extensions:')
        for ext in extensions:
            if ext.ext_type == 'dev':
                _print(
                    ext.name.ljust(20) + ext.version.rjust(20) + ' (dev) ' +
                    ext.path)
            else:
                _print(
                    ext.name.ljust(20) + (ext.version or 'Unknown').rjust(20))
        _print()
    _print("Python location '{}'".format(sys.executable))
    _print("Extensions directory '{}'".format(EXTENSIONS_DIR))
    if DEV_EXTENSION_SOURCES:
        _print("Development extension sources:")
        for source in DEV_EXTENSION_SOURCES:
            _print('    {}'.format(source))
    _print()
    _print('Python ({}) {}'.format(platform.system(), sys.version))
    _print()
    _print('Legal docs and information: aka.ms/AzureCliLegal')
    _print()
    version_string = output.getvalue()

    # if unable to query PyPI, use sentinel value to flag that
    # we couldn't check for updates
    if not success:
        updates_available = -1
    return version_string, updates_available
Esempio n. 8
0
def list_extensions():
    return [{OUT_KEY_NAME: ext.name, OUT_KEY_VERSION: ext.version, OUT_KEY_TYPE: ext.ext_type}
            for ext in get_extensions()]
Esempio n. 9
0
def get_az_version_string():
    import platform
    from azure.cli.core.extension import get_extensions, EXTENSIONS_DIR, DEV_EXTENSION_SOURCES

    output = six.StringIO()
    versions = {}

    # get locally installed versions
    for dist in get_installed_cli_distributions():
        if dist.key == CLI_PACKAGE_NAME:
            versions[CLI_PACKAGE_NAME] = {'local': dist.version}
        elif dist.key.startswith(COMPONENT_PREFIX):
            comp_name = dist.key.replace(COMPONENT_PREFIX, '')
            versions[comp_name] = {'local': dist.version}

    # get the versions from pypi
    versions, success = _update_latest_from_pypi(versions)
    updates_available = 0

    def _print(val=''):
        print(val, file=output)

    def _get_version_string(name, version_dict):
        from distutils.version import LooseVersion  # pylint: disable=import-error,no-name-in-module
        local = version_dict['local']
        pypi = version_dict.get('pypi', None)
        if pypi and LooseVersion(pypi) > LooseVersion(local):
            return name.ljust(20) + local.rjust(20) + ' *'
        return name.ljust(20) + local.rjust(20)

    ver_string = _get_version_string(CLI_PACKAGE_NAME, versions.pop(CLI_PACKAGE_NAME))
    if '*' in ver_string:
        updates_available += 1
    _print(ver_string)
    _print()
    for name in sorted(versions.keys()):
        ver_string = _get_version_string(name, versions.pop(name))
        if '*' in ver_string:
            updates_available += 1
        _print(ver_string)
    _print()
    extensions = get_extensions()
    if extensions:
        _print('Extensions:')
        for ext in extensions:
            if ext.ext_type == 'dev':
                _print(ext.name.ljust(20) + ext.version.rjust(20) + ' (dev) ' + ext.path)
            else:
                _print(ext.name.ljust(20) + (ext.version or 'Unknown').rjust(20))
        _print()
    _print("Python location '{}'".format(sys.executable))
    _print("Extensions directory '{}'".format(EXTENSIONS_DIR))
    if DEV_EXTENSION_SOURCES:
        _print("Development extension sources:")
        for source in DEV_EXTENSION_SOURCES:
            _print('    {}'.format(source))
    _print()
    _print('Python ({}) {}'.format(platform.system(), sys.version))
    _print()
    _print('Legal docs and information: aka.ms/AzureCliLegal')
    _print()
    version_string = output.getvalue()

    # if unable to query PyPI, use sentinel value to flag that
    # we couldn't check for updates
    if not success:
        updates_available = -1
    return version_string, updates_available
Esempio n. 10
0
 def test_extension_list(self):
     _install_test_extension1()
     actual = get_extensions()
     self.assertEqual(len(actual), 1)
Esempio n. 11
0
 def test_other_files_in_extensions_dir(self):
     tempfile.mkstemp(dir=self.ext_dir)
     actual = get_extensions()
     self.assertEqual(len(actual), 0)
Esempio n. 12
0
 def test_no_extensions_in_dir(self):
     """ Directory exists but there are no extensions """
     actual = get_extensions()
     self.assertEqual(len(actual), 0)
Esempio n. 13
0
 def test_no_extensions_dir(self):
     """ Extensions directory doesn't exist """
     shutil.rmtree(self.ext_dir)
     actual = get_extensions()
     self.assertEqual(len(actual), 0)
Esempio n. 14
0
        def _update_command_table_from_extensions(ext_suppressions):

            from azure.cli.core.extension.operations import check_version_compatibility

            def _handle_extension_suppressions(extensions):
                filtered_extensions = []
                for ext in extensions:
                    should_include = True
                    for suppression in ext_suppressions:
                        if should_include and suppression.handle_suppress(ext):
                            should_include = False
                    if should_include:
                        filtered_extensions.append(ext)
                return filtered_extensions

            extensions = get_extensions()
            if extensions:
                logger.debug("Found %s extensions: %s", len(extensions),
                             [e.name for e in extensions])
                allowed_extensions = _handle_extension_suppressions(extensions)
                module_commands = set(self.command_table.keys())
                for ext in allowed_extensions:
                    try:
                        check_version_compatibility(ext.get_metadata())
                    except CLIError as ex:
                        # issue warning and skip loading extensions that aren't compatible with the CLI core
                        logger.warning(ex)
                        continue
                    ext_name = ext.name
                    ext_dir = ext.path or get_extension_path(ext_name)
                    logger.debug("Extensions directory: '%s'", ext_dir)
                    sys.path.append(ext_dir)
                    try:
                        ext_mod = get_extension_modname(ext_name,
                                                        ext_dir=ext_dir)
                        # Add to the map. This needs to happen before we load commands as registering a command
                        # from an extension requires this map to be up-to-date.
                        # self._mod_to_ext_map[ext_mod] = ext_name
                        start_time = timeit.default_timer()
                        extension_command_table, extension_group_table = \
                            _load_extension_command_loader(self, args, ext_mod)

                        for cmd_name, cmd in extension_command_table.items():
                            cmd.command_source = ExtensionCommandSource(
                                extension_name=ext_name,
                                overrides_command=cmd_name in module_commands,
                                preview=ext.preview,
                                experimental=ext.experimental)

                        self.command_table.update(extension_command_table)
                        self.command_group_table.update(extension_group_table)
                        elapsed_time = timeit.default_timer() - start_time
                        logger.debug("Loaded extension '%s' in %.3f seconds.",
                                     ext_name, elapsed_time)
                    except Exception as ex:  # pylint: disable=broad-except
                        self.cli_ctx.raise_event(EVENT_FAILED_EXTENSION_LOAD,
                                                 extension_name=ext_name)
                        logger.warning(
                            "Unable to load extension '%s: %s'. Use --debug for more information.",
                            ext_name, ex)
                        logger.debug(traceback.format_exc())
Esempio n. 15
0
        def _update_command_table_from_extensions(ext_suppressions, extension_modname=None):
            """Loads command tables from extensions and merge into the main command table.

            :param ext_suppressions: Extension suppression information.
            :param extension_modname: Command modules to load, in the format like ['azext_timeseriesinsights'].
             If None, will do extension discovery and load all extensions.
             If [], only ALWAYS_LOADED_EXTENSIONS will be loaded.
             Otherwise, the list will be extended using ALWAYS_LOADED_EXTENSIONS.
             If the extensions in the list are not installed, it will be skipped.
            """
            def _handle_extension_suppressions(extensions):
                filtered_extensions = []
                for ext in extensions:
                    should_include = True
                    for suppression in ext_suppressions:
                        if should_include and suppression.handle_suppress(ext):
                            should_include = False
                    if should_include:
                        filtered_extensions.append(ext)
                return filtered_extensions

            def _filter_modname(extensions):
                # Extension's name may not be the same as its modname. eg. name: virtual-wan, modname: azext_vwan
                filtered_extensions = []
                for ext in extensions:
                    ext_mod = get_extension_modname(ext.name, ext.path)
                    # Filter the extensions according to the index
                    if ext_mod in extension_modname:
                        filtered_extensions.append(ext)
                        extension_modname.remove(ext_mod)
                if extension_modname:
                    logger.debug("These extensions are not installed and will be skipped: %s", extension_modname)
                return filtered_extensions

            extensions = get_extensions()
            if extensions:
                if extension_modname is not None:
                    extension_modname.extend(ALWAYS_LOADED_EXTENSIONS)
                    extensions = _filter_modname(extensions)
                allowed_extensions = _handle_extension_suppressions(extensions)
                module_commands = set(self.command_table.keys())

                count = 0
                cumulative_elapsed_time = 0
                cumulative_group_count = 0
                cumulative_command_count = 0
                logger.debug("Loading extensions:")
                logger.debug(self.header_ext)

                for ext in allowed_extensions:
                    try:
                        # Import in the `for` loop because `allowed_extensions` can be []. In such case we
                        # don't need to import `check_version_compatibility` at all.
                        from azure.cli.core.extension.operations import check_version_compatibility
                        check_version_compatibility(ext.get_metadata())
                    except CLIError as ex:
                        # issue warning and skip loading extensions that aren't compatible with the CLI core
                        logger.warning(ex)
                        continue
                    ext_name = ext.name
                    ext_dir = ext.path or get_extension_path(ext_name)
                    sys.path.append(ext_dir)
                    try:
                        ext_mod = get_extension_modname(ext_name, ext_dir=ext_dir)
                        # Add to the map. This needs to happen before we load commands as registering a command
                        # from an extension requires this map to be up-to-date.
                        # self._mod_to_ext_map[ext_mod] = ext_name
                        start_time = timeit.default_timer()
                        extension_command_table, extension_group_table = \
                            _load_extension_command_loader(self, args, ext_mod)

                        for cmd_name, cmd in extension_command_table.items():
                            cmd.command_source = ExtensionCommandSource(
                                extension_name=ext_name,
                                overrides_command=cmd_name in module_commands,
                                preview=ext.preview,
                                experimental=ext.experimental)

                        self.command_table.update(extension_command_table)
                        self.command_group_table.update(extension_group_table)

                        elapsed_time = timeit.default_timer() - start_time
                        logger.debug(self.item_ext_format_string, ext_name, elapsed_time,
                                     len(extension_group_table), len(extension_command_table),
                                     ext_dir)
                        count += 1
                        cumulative_elapsed_time += elapsed_time
                        cumulative_group_count += len(extension_group_table)
                        cumulative_command_count += len(extension_command_table)
                    except Exception as ex:  # pylint: disable=broad-except
                        self.cli_ctx.raise_event(EVENT_FAILED_EXTENSION_LOAD, extension_name=ext_name)
                        logger.warning("Unable to load extension '%s: %s'. Use --debug for more information.",
                                       ext_name, ex)
                        logger.debug(traceback.format_exc())
                # Summary line
                logger.debug(self.item_ext_format_string,
                             "Total ({})".format(count), cumulative_elapsed_time,
                             cumulative_group_count, cumulative_command_count, "")
Esempio n. 16
0
def upgrade_version(cmd, update_all=None, yes=None):  # pylint: disable=too-many-locals, too-many-statements, too-many-branches, no-member, unused-argument
    import os
    import platform
    import sys
    import subprocess
    import azure.cli.core.telemetry as telemetry
    from azure.cli.core import __version__ as local_version
    from azure.cli.core._environment import _ENV_AZ_INSTALLER
    from azure.cli.core.extension import get_extensions, WheelExtension
    from distutils.version import LooseVersion
    from knack.util import CLIError

    update_cli = True
    from azure.cli.core.util import get_latest_from_github
    try:
        latest_version = get_latest_from_github()
        if latest_version and LooseVersion(latest_version) <= LooseVersion(
                local_version):
            logger.warning("You already have the latest azure-cli version: %s",
                           local_version)
            update_cli = False
            if not update_all:
                return
    except Exception as ex:  # pylint: disable=broad-except
        logger.debug("Failed to get the latest version. %s", str(ex))
    exts = [ext.name for ext in get_extensions(
        ext_type=WheelExtension)] if update_all else []

    exit_code = 0
    installer = os.getenv(_ENV_AZ_INSTALLER) or ''
    installer = installer.upper()
    if update_cli:
        latest_version_msg = 'It will be updated to {}.'.format(latest_version) if yes \
            else 'Latest version available is {}.'.format(latest_version)
        logger.warning("Your current Azure CLI version is %s. %s",
                       local_version, latest_version_msg)
        from knack.prompting import prompt_y_n, NoTTYException
        if not yes:
            logger.warning(
                "Please check the release notes first: https://docs.microsoft.com/"
                "cli/azure/release-notes-azure-cli")
            try:
                confirmation = prompt_y_n("Do you want to continue?",
                                          default='y')
            except NoTTYException:
                from azure.cli.core.azclierror import UnclassifiedUserFault
                raise UnclassifiedUserFault("No tty available.",
                                            "Please run command with --yes.")

            if not confirmation:
                telemetry.set_success("Upgrade stopped by user")
                return

        if installer == 'DEB':
            from azure.cli.core.util import in_cloud_console
            if in_cloud_console():
                raise CLIError("az upgrade is not supported in Cloud Shell.")
            apt_update_cmd = 'apt-get update'.split()
            az_update_cmd = 'apt-get install --only-upgrade -y azure-cli'.split(
            )
            if os.geteuid() != 0:  # pylint: disable=no-member
                apt_update_cmd.insert(0, 'sudo')
                az_update_cmd.insert(0, 'sudo')
            exit_code = subprocess.call(apt_update_cmd)
            if exit_code == 0:
                logger.debug("Update azure cli with '%s'",
                             " ".join(apt_update_cmd))
                exit_code = subprocess.call(az_update_cmd)
        elif installer == 'RPM':
            from azure.cli.core.util import get_linux_distro
            distname, _ = get_linux_distro()
            if not distname:
                logger.warning(UPGRADE_MSG)
            else:
                distname = distname.lower().strip()
                if any(x in distname
                       for x in ['centos', 'rhel', 'red hat', 'fedora']):
                    update_cmd = 'yum update -y azure-cli'.split()
                    if os.geteuid() != 0:  # pylint: disable=no-member
                        update_cmd.insert(0, 'sudo')
                    logger.debug("Update azure cli with '%s'",
                                 " ".join(update_cmd))
                    exit_code = subprocess.call(update_cmd)
                elif any(x in distname for x in ['opensuse', 'suse', 'sles']):
                    zypper_refresh_cmd = ['zypper', 'refresh']
                    az_update_cmd = 'zypper update -y azure-cli'.split()
                    if os.geteuid() != 0:  # pylint: disable=no-member
                        zypper_refresh_cmd.insert(0, 'sudo')
                        az_update_cmd.insert(0, 'sudo')
                    exit_code = subprocess.call(zypper_refresh_cmd)
                    if exit_code == 0:
                        logger.debug("Update azure cli with '%s'",
                                     " ".join(az_update_cmd))
                        exit_code = subprocess.call(az_update_cmd)
                else:
                    logger.warning(UPGRADE_MSG)
        elif installer == 'HOMEBREW':
            logger.debug("Update homebrew formulae")
            exit_code = subprocess.call(['brew', 'update'])
            if exit_code == 0:
                update_cmd = ['brew', 'upgrade', 'azure-cli']
                logger.debug("Update azure cli with '%s'",
                             " ".join(update_cmd))
                exit_code = subprocess.call(update_cmd)
        elif installer == 'PIP':
            pip_args = [
                sys.executable, '-m', 'pip', 'install', '--upgrade',
                'azure-cli', '-vv', '--disable-pip-version-check',
                '--no-cache-dir'
            ]
            logger.debug("Update azure cli with '%s'", " ".join(pip_args))
            exit_code = subprocess.call(pip_args,
                                        shell=platform.system() == 'Windows')
        elif installer == 'DOCKER':
            logger.warning(
                "Exit the container to pull latest image with 'docker pull mcr.microsoft.com/azure-cli' "
                "or run 'pip install --upgrade azure-cli' in this container")
        elif installer == 'MSI':
            logger.debug(
                "Update azure cli with MSI from https://aka.ms/installazurecliwindows"
            )
            exit_code = subprocess.call(['powershell.exe', '-NoProfile', "Start-Process msiexec.exe -Wait -ArgumentList '/i https://aka.ms/installazurecliwindows'"])  # pylint: disable=line-too-long
        else:
            logger.warning(UPGRADE_MSG)
    if exit_code:
        err_msg = "CLI upgrade failed."
        logger.warning(err_msg)
        telemetry.set_failure(err_msg)
        sys.exit(exit_code)

    import azure.cli.core
    import importlib
    importlib.reload(azure.cli.core)
    new_version = azure.cli.core.__version__

    if update_cli and new_version == local_version:
        err_msg = "CLI upgrade failed or aborted."
        logger.warning(err_msg)
        telemetry.set_failure(err_msg)
        sys.exit(1)

    # Python is reinstalled in another versioned directory with Homebrew, subprocess needs to be reloaded
    if installer == 'HOMEBREW' and exts:
        importlib.reload(subprocess)

    if exts:
        logger.warning("Upgrading extensions")
    for ext_name in exts:
        try:
            logger.warning("Checking update for %s", ext_name)
            subprocess.call(['az', 'extension', 'update', '-n', ext_name],
                            shell=platform.system() == 'Windows')
        except Exception as ex:  # pylint: disable=broad-except
            msg = "Extension {} update failed during az upgrade. {}".format(
                ext_name, str(ex))
            raise CLIError(msg)
    auto_upgrade_msg = "You can enable auto-upgrade with 'az config set auto-upgrade.enable=yes'. " \
        "More details in https://docs.microsoft.com/cli/azure/update-azure-cli#automatic-update"
    logger.warning(
        "Upgrade finished.%s", "" if cmd.cli_ctx.config.getboolean(
            'auto-upgrade', 'enable', False) else auto_upgrade_msg)
Esempio n. 17
0
 def test_extension_list(self):
     _install_test_extension1()
     actual = get_extensions(ext_type=WheelExtension)
     self.assertEqual(len(actual), 1)
Esempio n. 18
0
def get_az_version_string(use_cache=False):  # pylint: disable=too-many-statements
    from azure.cli.core.extension import get_extensions, EXTENSIONS_DIR, DEV_EXTENSION_SOURCES, EXTENSIONS_SYS_DIR

    output = six.StringIO()
    versions = _get_local_versions()

    # get the versions from pypi
    versions, success = get_cached_latest_versions(versions) if use_cache else _update_latest_from_pypi(versions)
    updates_available = 0

    def _print(val=''):
        print(val, file=output)

    def _get_version_string(name, version_dict):
        from distutils.version import LooseVersion  # pylint: disable=import-error,no-name-in-module
        local = version_dict['local']
        pypi = version_dict.get('pypi', None)
        if pypi and LooseVersion(pypi) > LooseVersion(local):
            return name.ljust(25) + local.rjust(15) + ' *'
        return name.ljust(25) + local.rjust(15)

    ver_string = _get_version_string(CLI_PACKAGE_NAME, versions.pop(CLI_PACKAGE_NAME))
    if '*' in ver_string:
        updates_available += 1
    _print(ver_string)
    _print()
    for name in sorted(versions.keys()):
        ver_string = _get_version_string(name, versions.pop(name))
        if '*' in ver_string:
            updates_available += 1
        _print(ver_string)
    _print()
    extensions = get_extensions()
    if extensions:
        _print('Extensions:')
        for ext in extensions:
            if ext.ext_type == 'dev':
                _print(ext.name.ljust(20) + (ext.version or 'Unknown').rjust(20) + ' (dev) ' + ext.path)
            else:
                _print(ext.name.ljust(20) + (ext.version or 'Unknown').rjust(20))
        _print()
    _print("Python location '{}'".format(sys.executable))
    _print("Extensions directory '{}'".format(EXTENSIONS_DIR))
    import os
    if os.path.isdir(EXTENSIONS_SYS_DIR) and os.listdir(EXTENSIONS_SYS_DIR):
        _print("Extensions system directory '{}'".format(EXTENSIONS_SYS_DIR))
    if DEV_EXTENSION_SOURCES:
        _print("Development extension sources:")
        for source in DEV_EXTENSION_SOURCES:
            _print('    {}'.format(source))
    _print()
    _print('Python ({}) {}'.format(platform.system(), sys.version))
    _print()
    _print('Legal docs and information: aka.ms/AzureCliLegal')
    _print()
    version_string = output.getvalue()

    # if unable to query PyPI, use sentinel value to flag that
    # we couldn't check for updates
    if not success:
        updates_available = -1
    return version_string, updates_available
Esempio n. 19
0
def list_extensions():
    return [{
        OUT_KEY_NAME: ext.name,
        OUT_KEY_VERSION: ext.version,
        OUT_KEY_TYPE: ext.ext_type
    } for ext in get_extensions()]