-
Notifications
You must be signed in to change notification settings - Fork 588
Create versioned parent class for all plugins that enumerate Linux ke… #1719
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
Conversation
This will need to be merged after #1717 is merged and then this branch rebased, but otherwise will be good. |
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.
This isn't passing some of the tests at the moment.
Also I really uncertain as to the effects of inheriting from a plugin that doesn't live under an os directory. I'd really strongly advise that we only proxy methods from the class, that will allow the methods to stay shared, with minimal duplicated code and ensures we don't have to deal with any shared complexity (like a plugin inheritting from itself before it knows whether its own version passes the requirements. I can't see a compelling reason to use inheritance for the sake of run = ModuleDisplayPlugin.run
(although we'll need to think about binding of methods to make sure that works properly)...
return reqs | ||
|
||
|
||
class ModuleDisplayPlugin(plugins.PluginInterface): |
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.
This seems like the wrong place for it, and inheriting from the plugin interface means it may get listed as main plugin (our code to list plugins looks for anything that inherits from plugin). Are we sure that's what we want? I'd much prefer any plugins we have to live as a plugin in the right directory.
name="linux_utilities_modules", | ||
component=linux_utilities_modules.Modules, | ||
version=(3, 0, 0), | ||
name="linux_utilities_modules_module_display_plugin", |
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 would surely be better to define classmethod generator and run methods and then just proxy them at this point? We're really not getting anything from inheritance other than complexity?
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.
Can __init__
of each plugin just set .run
and and ._generator
to the shared function? and Where would that shared functons best live now? I was trying to avoid one plugin becoming the container (say lsmod) that the other plugins then need to import and depend on.
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.
Yeah, that should be ok, but you can just define it straight in the class I think? So
class Blah:
run = linux_utilities_modules.ModuleDisplayPlugin.run
?
Yes, the 1 test would break until I rebase with the netfilter PR you just merged. That is a really good point on inheriting to look like a plugin + re-using .run. I will adjust to that. |
f2e10da
to
1096217
Compare
…rnel modules. Convert plugins to new method.
1096217
to
f906bde
Compare
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.
Looking much better, but there's nothing to be gained by the multiple inheritance. Literally just reach into the classes and assign the methods to the new classes. It should all work (because self
is included explicitly, so it'll refer to the instantiated class, not the ModuleDisplayPlugin
class, which likely will never get instantiated ever. It's just acting as a code wrapper to keep it all nice and warm and bundled up for the plugins that actually want to use it... 5:)
_required_framework_version = (2, 0, 0) | ||
|
||
def __init__(self, *args, **kwargs): | ||
super().__init__(self.compare_kset_and_lsmod, *args, **kwargs) |
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.
I mean this is nice, but not worth it, just set a self variable in here, and pull it back in the proxied method.
name="linux_utilities_modules", | ||
component=linux_utilities_modules.Modules, | ||
version=(3, 0, 0), | ||
name="linux_utilities_modules_module_display_plugin", |
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.
Yeah, that should be ok, but you can just define it straight in the class I think? So
class Blah:
run = linux_utilities_modules.ModuleDisplayPlugin.run
?
self.implementation = implementation | ||
|
||
@classmethod | ||
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: |
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 the results of this to the individual class get_requirements.
The constructor of the plugin must call super() with the `implementation` set | ||
""" | ||
|
||
_version = (1, 0, 0) |
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.
Don't need these local variables, since they shouldn't be being inherited anyway (you can if you really want, but the plugins should be defining their own needs
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.
Sorry, I realized we version this directly, so it's important for this to have its own version! 5:S
), | ||
] | ||
|
||
def _generator(self): |
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.
This might give a ruff warning, because it's a private member, but you can actually make it public and just assign it to a private member in the new class?
_generator = modules.ModuleDisplayPlugin.generator
for example?
Nice idea! I think its sorted now. Also, if you see in the diff functions moving, its so they could be referenced from the code under them. |
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.
Looks good, let's get it landed 5:)
So I said:
To which you eventually said:
And I then merged it in, seemingly because I was getting tired of reworking it and because it was an overly large pull request. I'm sorry, I shouldn't have accepted it, I don't think I thought this through full before landing it. You sounded as though you'd fixed the inheritance that I objected to twice, but there's still inheritance being used and is now causing some headaches in a circular dependency because this extension module is actually partial plugins rather than discrete code blocks each doing their own thing (see #1773). Please can we can this refactored ASAP. No inheritance please. None. Only code blocks and version checks... |
Ok, having calmed a bit (but only a bit) and scoped out exactly what's going on, it seems we jury rigged inheritance. It's not as bad as I thought, but trying to pull in complex functions (like run and generator) removes the ability for plugin to easily be able to override settings (or for us to separate concerns when, for example, part of the dumping functionality needs to be refactored). I'm working up a PR that should improve this, but I suspect that the |
Ok, I've worked up #1801 to get this slightly more in order. |
…rnel modules. Convert plugins to new method.
Ok @ikelos I am really happy to see how this turned out. Previously each of the enumeration plugins printed different columns and used different names. This gets us to where everything is consistent with a proper name.
Furthermore, given the maturity we now have with the versioning of modules, there is no need for a particular plugin to be the "main" one that the others inherit from (like thrdscan in Windows for threads plugins), and instead we can have a fully versioned chain of classes that plugins can use for our
self.implementation
style enumeration when the outputs will be the same.You will see the in the comment I left, but this also sets us up to display Load Arguments, but jamming that into this PR would have spiraled it, so that will fill in here once merged.