-
Notifications
You must be signed in to change notification settings - Fork 3.3k
[Extension] Support installing extensions in a system directory #12856
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Extension] Support installing extensions in a system directory #12856
Conversation
| 'cliextensions') | ||
| DEV_EXTENSION_SOURCES = _DEV_EXTENSION_SOURCES.split(',') if _DEV_EXTENSION_SOURCES else [] | ||
| EXTENSIONS_SYS_DIR = os.path.join(get_python_lib(), 'azure-cli-extensions') if sys.platform.startswith('linux') else "" | ||
| EXTENSIONS_SYS_DIR = os.path.expanduser(_CUSTOM_EXT_SYS_DIR) if _CUSTOM_EXT_SYS_DIR else os.path.join(get_python_lib(), 'azure-cli-extensions') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to test if this also works on Windows and Mac.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On windows, users need to open the shell as administrator. I have added message when users encounter the permission error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
run as admin only required when user set customized install dir right? if yes, then less concern since no change to existing behavoir
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, not affecting default extension installation.
| extension_name = _add_whl_ext(cmd=cmd, source=source, ext_sha256=ext_sha256, | ||
| pip_extra_index_urls=pip_extra_index_urls, pip_proxy=pip_proxy) | ||
| _augment_telemetry_with_ext_info(extension_name) | ||
| pip_extra_index_urls=pip_extra_index_urls, pip_proxy=pip_proxy, system=system) | ||
| ext = get_extension(extension_name) | ||
| _augment_telemetry_with_ext_info(extension_name, ext) | ||
| try: | ||
| if extension_name and get_extension(extension_name).experimental: | ||
| if extension_name and ext.experimental: | ||
| logger.warning("The installed extension '%s' is experimental and not covered by customer support. " | ||
| "Please use with discretion.", extension_name) | ||
| elif extension_name and get_extension(extension_name).preview: | ||
| elif extension_name and ext.preview: | ||
| logger.warning("The installed extension '%s' is in preview.", extension_name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_extension calls get_extensions to load all extension, then fetch the extension with the name, we should avoid calling it mulitple times.
a40c461 to
5c6e0c3
Compare
|
add to S168 |
…zure-cli into install_system_extension
| return os.path.join(EXTENSIONS_DIR, ext_name) | ||
| ext_sys_path = os.path.join(EXTENSIONS_SYS_DIR, ext_name) | ||
| ext_path = os.path.join(EXTENSIONS_DIR, ext_name) | ||
| return ext_path if os.path.isdir(ext_path) else ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add os.path.isdir(ext_path) check here, is it because previous code may case potential bug ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previous code use get_extension_path both before install when this path does not exist and when loading extensions. I splitted it to use the below build_extension_path for building the path before install, and to use this get_extension_path only for loading extensions. So we can add the isdir check here now.
| try: | ||
| if extension_name and get_extension(extension_name).experimental: | ||
| ext = get_extension(extension_name) | ||
| _augment_telemetry_with_ext_info(extension_name, ext) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move telemetry part into the try/except, so if get_extension throw exception, it will not be executed, right ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. get_extension was also called in _augment_telemetry_with_ext_info in previous code and it will be catched inside. And I think it's the same flow.
| 'cliextensions') | ||
| DEV_EXTENSION_SOURCES = _DEV_EXTENSION_SOURCES.split(',') if _DEV_EXTENSION_SOURCES else [] | ||
| EXTENSIONS_SYS_DIR = os.path.join(get_python_lib(), 'azure-cli-extensions') if sys.platform.startswith('linux') else "" | ||
| EXTENSIONS_SYS_DIR = os.path.expanduser(_CUSTOM_EXT_SYS_DIR) if _CUSTOM_EXT_SYS_DIR else os.path.join(get_python_lib(), 'azure-cli-extensions') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
run as admin only required when user set customized install dir right? if yes, then less concern since no change to existing behavoir
| except CalledProcessError as e: | ||
| logger.debug(e.output) | ||
| logger.debug(e) | ||
| if "PermissionError: [WinError 5]" in e.output: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's default install path after the change? suppose no change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. no change for the default extension path.
| _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)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's little confusing, how about direct show as Extensions directory
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea is to have no impact on users who don't use --system to install extensions. This will only be shown when users have installed at least one extension with --system.
|
Would it be better install to inside |
I think it's more organized with the azure-cli-extensions folder. What's the benefit of installing inside |
Description of PR (Mandatory)
(Why this PR? What is changed? What is the effect? etc. A high-quality description can accelerate the review process)
Resolve #9831.
Currently users can set
AZURE_EXTENSION_DIRenv variable to install extensions in a customized path. But this has a limit to install all extensions in one directory.This PR adds an option
--systemtoaz extension add. So users can choose to install an extension in either a user path or a system path, but not able to install the same extension in both paths. az will search and load all the extensions in both paths. On Windows, users need to open the shell as Administrator to install extensions with --system.The system directory is also configurable by env var
AZURE_EXTENSION_SYS_DIR. The default is theazure-cli-extensionsfolder under the lib path of the python that az is using.On windows with MSI, the directory is:
C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\lib\site-packages\azure-cli-extensionsOn Ubuntu:
/opt/az/lib/python3.6/site-packages/azure-cli-extensionsOn CentOS:
/usr/lib/python3.6/site-packages/azure-cli-extensionsOn MacOS:
/usr/local/Cellar/azure-cli/2.3.1/libexec/lib/python3.8/site-packages/azure-cli-extensionsThis PR also reduces the invoke of
get_extensionwhen possible since it will load all extensions.Testing Guide
(Example commands with explanations)
az extension add -n extension-name --system
az extension show -n extension-name
History Notes:
(Fill in the following template if multiple notes are needed, otherwise PR title will be used for history note.)
[Extension] az extension add: Add --system to enable installing extensions in a system path
This checklist is used to make sure that common guidelines for a pull request are followed.
The PR title and description has followed the guideline in Submitting Pull Requests.
I adhere to the Command Guidelines.