Skip to content
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

[cli] Dynamic cli extension via plugins #1186

Merged
merged 16 commits into from
Mar 31, 2021

Conversation

stepanblyschak
Copy link
Contributor

@stepanblyschak stepanblyschak commented Oct 22, 2020

Signed-off-by: Stepan Blyschak stepanb@nvidia.com

- What I did
Added a mechanism to extend command line interface via plugins.
For every program - show, config, clear a new python package called 'plugins' is added.
This package is used as a namespace for all plugins python modules. As an example mlnx.py is moved to the plugins package.

In the future, this mechanism will be used by Application Extension infrastructure.

- How I did it

- How to verify it

- Previous command output (if the output of a command-line utility has changed)

- New command output (if the output of a command-line utility has changed)

@stepanblyschak
Copy link
Contributor Author

retest this please

1 similar comment
@stepanblyschak
Copy link
Contributor Author

retest this please

@lguohan lguohan requested a review from jleveque October 27, 2020 19:21
lguohan
lguohan previously approved these changes Oct 27, 2020
@lguohan
Copy link
Contributor

lguohan commented Oct 27, 2020

retest this please

1 similar comment
@lguohan
Copy link
Contributor

lguohan commented Oct 27, 2020

retest this please

@lgtm-com
Copy link

lgtm-com bot commented Dec 9, 2020

This pull request fixes 1 alert when merging ec778be3b6b22d0f2578f89d2d26d5a190b34a6c into d414970 - view on LGTM.com

fixed alerts:

  • 1 for Unused import

@stepanblyschak
Copy link
Contributor Author

retest this please

@lgtm-com
Copy link

lgtm-com bot commented Dec 9, 2020

This pull request fixes 1 alert when merging 4b90bb79fd95951a30671c8f650ca4bb331c23a0 into 57a0b41 - view on LGTM.com

fixed alerts:

  • 1 for Unused import

@lgtm-com
Copy link

lgtm-com bot commented Dec 10, 2020

This pull request fixes 1 alert when merging 634f4afa4e253516656c4f77255da95c7d678ecc into 57a0b41 - view on LGTM.com

fixed alerts:

  • 1 for Unused import

stepanblyschak and others added 8 commits January 5, 2021 10:20
Added a mechanism to extend command line interface via plugins.
For every program - show, config, clear a new python package
called 'plugins' is added. This package is used as a namespace
for all plugins python modules. As an example mlnx.py is moved
to the plugins package.

In the fututre, this mechanism will be used by Application Extension
infrastructure.

Signed-off-by: Stepan Blyschak <stepanb@nvidia.com>
Signed-off-by: Stepan Blyshchak <stepanb@mellanox.com>
Signed-off-by: Stepan Blyshchak <stepanb@nvidia.com>
otherwise, it maybe not displayed in show command list till the execution.
use register method as an API between CLI and plugin.

Signed-off-by: Stepan Blyshchak <stepanb@nvidia.com>
Signed-off-by: Stepan Blyshchak <stepanb@nvidia.com>
Signed-off-by: Stepan Blyshchak <stepanb@nvidia.com>
Signed-off-by: Stepan Blyshchak <stepanb@nvidia.com>
Signed-off-by: Stepan Blyshchak <stepanb@nvidia.com>
@lgtm-com
Copy link

lgtm-com bot commented Jan 5, 2021

This pull request fixes 1 alert when merging 701ffef into 22d79f3 - view on LGTM.com

fixed alerts:

  • 1 for Unused import

@jleveque
Copy link
Contributor

jleveque commented Jan 8, 2021

Retest this please

Copy link

@bandaru-viswanath bandaru-viswanath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added few comments, some of them applicable for all clear/config/show cases.
Just wanted to make a mention that there has to be a similar mechanism that needs to be evolved for all the "YANG" based UI methods, to be able to support dynamic extensions there as well.

config/main.py Outdated
# Load plugins and register them
helper = util_base.UtilHelper()
for plugin in helper.load_plugins(plugins):
plugin.register(config)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the plugins are not likely part of the "original" package, it would be nicer for the system to

  • Log the plugins being loaded
  • Check with the plugin for compatibility (leaving to plugin how it decides) and log when the plugin reports incompatibility before registering.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I've added a log message for plugin import and for plugin registration but with DEBUG log level so it will not appear by default in log otherwise it is going to be printed on every CLI command execution and may pollute the log.
  2. Thanks for suggestion. Ideally, any compatibility checks should be done on installation time - here CLI auto generation based on YANG will help a lot (phase 2), thus, if package was able to be installed it is compatible.
    There is another side of this question, if plugin happens to be incompatible and this is not reflected in version constraints in manifest the whole CLI is broken (possible because plugin will throw something like AttributeError or other kind of exception). I changed the code to catch Exception and log it as error, so the CLI will still be able to work but without new commands or changed commands. This does not catch all incompatibilities possible with this approach but better then nothing.
    Given that, a plugin developer can raise Exception with message why he thinks it is not compatible which basically should satisfy your req no 2.

helper = util_base.UtilHelper()
for plugin in helper.load_plugins(plugins):
plugin.register(config)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would there be a provision for unloading/deregistering ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need. CLI is short living process that I doubt require unregistering, unloading plugin in the middle.

for _, module_name, ispkg in iter_namespace(plugins_namespace):
if ispkg:
continue
yield importlib.import_module(module_name)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be necessary to support an "order" for loading of plugins ? Or is it the expectation for the plugin to be self contained ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be needed if plugins have cross-dependencies which is against the classical plugin system design where plugins have no cross-dependencies, they only depend on the core.
App.Ext developer is forced to not depend on other plugins here. However, we do not want the infrastructure to put restrictions about CLI design. This shows that this plugin mechanism is not an ideal choice for CLI extensions here.
Again, CLI auto-generation based on YANG modules can help a lot here, since YANG will show cross-dependencies between modules and CLI can be regenerated from scratch on installation/uninstallation/upgrade.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not have any knowledge of CLI in to a generic framework. Autogenerated from YANG is just one form of CLI. Application data model should be able to support different management models.
Consider a OC-YANG based CLI. Here, one SONIC feature may share "YANG" (or data model) with other features. Dependencies would come into play.
I would think that there should be a mechanism that allows dependencies to be checked (with in the management, not at SONIC level). You can say it is plugin's responsibility to check dependencies. But I don't see any model here for a CLI plugin to see what (other cli plugins/infra) is currently available. Can we think of some model, or Can you suggest how this can be achieved ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"But I don't see any model here for a CLI plugin to see what (other cli plugins/infra) is currently available"

In your plugin you can do this to list what plugins are available:

pkgutil.iter_modules(show.plugins.__path__, show.plugins.__name__)

Signed-off-by: Stepan Blyshchak <stepanb@nvidia.com>
@lgtm-com
Copy link

lgtm-com bot commented Jan 27, 2021

This pull request fixes 1 alert when merging 1d4da48 into 41e62c6 - view on LGTM.com

fixed alerts:

  • 1 for Unused import

Signed-off-by: Stepan Blyshchak <stepanb@nvidia.com>
@lgtm-com
Copy link

lgtm-com bot commented Jan 27, 2021

This pull request fixes 1 alert when merging d815bb7 into 41e62c6 - view on LGTM.com

fixed alerts:

  • 1 for Unused import

@lgtm-com
Copy link

lgtm-com bot commented Jan 30, 2021

This pull request fixes 1 alert when merging 591788b into a50b7a2 - view on LGTM.com

fixed alerts:

  • 1 for Unused import

@liat-grozovik
Copy link
Collaborator

retest this please

@liat-grozovik
Copy link
Collaborator

@jleveque and @bandaru-viswanath comments were addressed. can you please review and approve? once all the checkers are completed i would like to move forward and merge it (as no change effect on existing behaviour)

jleveque
jleveque previously approved these changes Feb 25, 2021
@liat-grozovik
Copy link
Collaborator

@bandaru-viswanath kindly reminder, can you please review recent changes?

@bandaru-viswanath
Copy link

bandaru-viswanath commented Mar 2, 2021 via email

Signed-off-by: Stepan Blyschak <stepanb@nvidia.com>
@lgtm-com
Copy link

lgtm-com bot commented Mar 11, 2021

This pull request fixes 1 alert when merging 8732e8c into 6ced42c - view on LGTM.com

fixed alerts:

  • 1 for Unused import

@liat-grozovik
Copy link
Collaborator

retest this please

@liat-grozovik
Copy link
Collaborator

/AzurePipelines run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

sonic_platform.

This import statement causes unit testing problems as sonic_platform
is not installed in UT environment; importing util_base.py in UT code
will fail. Since, there is no infrastructure to either mock
sonic_platform or install a mocked version of it UT environment I am
hiding the import to the method using sonic_platform in util_base.py.

Signed-off-by: Stepan Blyschak <stepanb@nvidia.com>
@stepanblyschak
Copy link
Contributor Author

retest this please

@stepanblyschak
Copy link
Contributor Author

retest this please

@lgtm-com
Copy link

lgtm-com bot commented Mar 16, 2021

This pull request fixes 1 alert when merging 1d188c5 into 0de99c3 - view on LGTM.com

fixed alerts:

  • 1 for Unused import

@stepanblyschak
Copy link
Contributor Author

retest this please

@stepanblyschak
Copy link
Contributor Author

@bandaru-viswanath Based on our last subgroup meeting, do you have any more comments or it can be merged from your point of view?

@liat-grozovik
Copy link
Collaborator

@bandaru-viswanath kindly reminder. as all tests passes and it seems that issue raised has been discussed i believe it is time to move forward and merge before the next conflict comes in :-(

@stepanblyschak
Copy link
Contributor Author

@jleveque could you please re-review and approve?

@liat-grozovik
Copy link
Collaborator

/AzurePipelines run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@liat-grozovik
Copy link
Collaborator

/AzurePipelines run

@liat-grozovik
Copy link
Collaborator

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@liat-grozovik liat-grozovik merged commit 9a2872d into sonic-net:master Mar 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants