-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
plugins: improve remove
command to support multiple plugins
#17030
Conversation
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 know you are still working on some tests, had a couple suggestions in the mean time :)
Refactors based on initial review look great! |
334cb55
to
f6ea649
Compare
Removal works in a single pass by finding plugins that would have unmet dependencies if all of the specified plugins were to be removed, and proceeding with the removal only if no conflicts were created. > ~~~ > ╭─{ rye@perhaps:~/src/elastic/logstash@main (pluginmanager-remove-multiple ✘) } > ╰─● bin/logstash-plugin remove logstash-input-syslog logstash-filter-grok > Using system java: /Users/rye/.jenv/shims/java > Resolving dependencies...... > Successfully removed logstash-input-syslog > Successfully removed logstash-filter-grok > [success (00:00:05)] ~~~
f6ea649
to
3e00a74
Compare
|
💚 Build Succeeded
History
|
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.
@donoghuc I've requested re-review, and the diff isn't pretty so it's best to just look at the result of the changes in lib/pluginmanager/bundler/logstash_uninstall.rb
instead of trying to map what changed.
unsatisfied_dependency_mapping = Dsl.evaluate(gemfile_path, lockfile_path, {}).specs.each_with_object({}) do |spec, memo| | ||
next if gems_to_remove.include?(spec.name) | ||
deps = spec.runtime_dependencies.collect(&:name) | ||
deps.intersection(gems_to_remove).each do |missing_dependency| | ||
memo[missing_dependency] ||= [] | ||
memo[missing_dependency] << spec.name | ||
end | ||
end | ||
end | ||
if unsatisfied_dependency_mapping.any? | ||
unsatisfied_dependency_mapping.each { |gem_to_remove, gems_depending_on_removed| display_cant_remove_message(gem_to_remove, gems_depending_on_removed) } | ||
LogStash::PluginManager.ui.info("No plugins were removed.") | ||
return false | ||
end |
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 gave up on the pre-validation "optimistic removal" approach.
Bundler did not like being told to materialize a dependency graph that had missing dependencies (e.g., the gems we had optimistically removed), which prevented us from finding the conflicts to present them in a way consistent with how we have previously done.
Instead, this approach is a lot closer to the original. It looks at the existing dependency graph to identify which dependencies would be unmet before removing them from the gemfile.
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 think this works well. I like the optimistic approach for removal. I dont think this introduces an issue with orphaned dependencies but perhaps it creates a larger surface area for that? I see you have a PR for a clean
routine as well.
Note: I realize I seem to have conflated "optimistic" #17030 (comment) I assumed that meant doing the traversal upon validation list with the complete set of gems to be removed and only committing the change if no conflicts are detected.
@logstashmachine backport 9.0 |
@logstashmachine backport 8.x |
Removal works in a single pass by finding plugins that would have unmet dependencies if all of the specified plugins were to be removed, and proceeding with the removal only if no conflicts were created. > ~~~ > ╭─{ rye@perhaps:~/src/elastic/logstash@main (pluginmanager-remove-multiple ✘) } > ╰─● bin/logstash-plugin remove logstash-input-syslog logstash-filter-grok > Using system java: /Users/rye/.jenv/shims/java > Resolving dependencies...... > Successfully removed logstash-input-syslog > Successfully removed logstash-filter-grok > [success (00:00:05)] ~~~ (cherry picked from commit 0895588)
Removal works in a single pass by finding plugins that would have unmet dependencies if all of the specified plugins were to be removed, and proceeding with the removal only if no conflicts were created. > ~~~ > ╭─{ rye@perhaps:~/src/elastic/logstash@main (pluginmanager-remove-multiple ✘) } > ╰─● bin/logstash-plugin remove logstash-input-syslog logstash-filter-grok > Using system java: /Users/rye/.jenv/shims/java > Resolving dependencies...... > Successfully removed logstash-input-syslog > Successfully removed logstash-filter-grok > [success (00:00:05)] ~~~ (cherry picked from commit 0895588)
This commit updates the acceptance tests to expect messages in the updated format for removing plugins. See elastic#17030 for change.
#17120) Removal works in a single pass by finding plugins that would have unmet dependencies if all of the specified plugins were to be removed, and proceeding with the removal only if no conflicts were created. > ~~~ > ╭─{ rye@perhaps:~/src/elastic/logstash@main (pluginmanager-remove-multiple ✘) } > ╰─● bin/logstash-plugin remove logstash-input-syslog logstash-filter-grok > Using system java: /Users/rye/.jenv/shims/java > Resolving dependencies...... > Successfully removed logstash-input-syslog > Successfully removed logstash-filter-grok > [success (00:00:05)] ~~~ (cherry picked from commit 0895588) Co-authored-by: Ry Biesemeyer <[email protected]>
#17121) Removal works in a single pass by finding plugins that would have unmet dependencies if all of the specified plugins were to be removed, and proceeding with the removal only if no conflicts were created. > ~~~ > ╭─{ rye@perhaps:~/src/elastic/logstash@main (pluginmanager-remove-multiple ✘) } > ╰─● bin/logstash-plugin remove logstash-input-syslog logstash-filter-grok > Using system java: /Users/rye/.jenv/shims/java > Resolving dependencies...... > Successfully removed logstash-input-syslog > Successfully removed logstash-filter-grok > [success (00:00:05)] ~~~ (cherry picked from commit 0895588) Co-authored-by: Ry Biesemeyer <[email protected]>
This commit updates the acceptance tests to expect messages in the updated format for removing plugins. See elastic#17030 for change.
This commit updates the acceptance tests to expect messages in the updated format for removing plugins. See #17030 for change.
This commit updates the acceptance tests to expect messages in the updated format for removing plugins. See elastic#17030 for change.
…7129) This commit updates the acceptance tests to expect messages in the updated format for removing plugins. See #17030 for change. (cherry picked from commit e8e24a0) Co-authored-by: Cas Donoghue <[email protected]>
…7122) This commit updates the acceptance tests to expect messages in the updated format for removing plugins. See elastic#17030 for change.
…7131) This commit updates the acceptance tests to expect messages in the updated format for removing plugins. See #17030 for change. Co-authored-by: Cas Donoghue <[email protected]>
Release notes
The plugin manager
bin/logstash-plugin
'sremove
command now allows multiple plugins to be removed in a single call. This simplifies removing plugins that depend on other plugins, so that the caller no longer needs to perform the removals in dependency order.What does this PR do?
Removal works by optimistically removing all specified plugin-gems from a mutable gemspec, then validating that doing so does not leave plugin-gems with orphaned runtime dependencies, saving the result and succeeding only if no conflicts were created.
Why is it important/What is the impact to the user?
Because the plugin manager (rightly) refuses to remove plugins that are depended on by other plugins and the plugin manager has historically only allowed one plugin to be removed at a time, the caller removing many plugins has needed to be aware of dependency order.
By allowing a list of plugins to be provided, the plugin manager is able to remove the requirement for dependency-order, and is able to handle the removals in a single execution.
Checklist
[ ] I have made corresponding changes to the documentation[ ] I have made corresponding change to the default configuration files (and/or docker env variables)Author's Checklist
How to test this PR locally
Related issues
Use cases
Screenshots
Logs