-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Fleet] cleanup old package assets #112644
Conversation
In general, I think we should try to keep as much of this type of business logic on the server-side so that users who are using the Fleet API also get the same behavior as users of the UI. I think the appropriate place to do this cleanup would be in the package policy service during upgrades: https://github.com/elastic/kibana/blob/master/x-pack/plugins/fleet/server/services/package_policy.ts/#L541 I suspect that you'll also need to add new logic for removing assets from an existing package without deleting the entire package (as you noted, the existing |
Is it enough to clean up after package policy upgrade? What if a package is updated without any policies? Shouldn't cleanup happen after package update? |
Good point, we should probably add logic during the package upgrade as well just for that case. Either way, I think we'll need new logic for removing these asset objects without removing the entire package. |
fbb6519
to
ac9cd50
Compare
// how to query if more than one page? | ||
perPage: 100, |
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 recommend using the savedObjectsClient.createPointInTimeFinder
utility for paging which will give you a stable "cursor" of sorts that can be used in conjunction with the find
API.
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.
thanks, I'll check this
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 rewrote this to use point in time finder
const { total } = await packagePolicyService.list(savedObjectsClient, { | ||
kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${pkgName} AND ${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.version:${oldVersion}`, | ||
page: 0, | ||
perPage: 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.
Will perPage: 0
ever return a total more than 0?
Also maybe we should do this check first before paging through all the refs and deleting them. That way we can delete the refs in batches without requiring that we page through all and load them into memory before deleting.
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, I took this code from remove.ts where the same check is used, also tested and it returned > 0 if there were policies
good point about the order, will do the check first
savedObjectsClient: SavedObjectsClientContract; | ||
pkgName: string; | ||
oldVersion: string; |
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 we may want to change this API to handle the scenario where there are multiple outdated versions that haven't been cleaned up. This would help cover the case where customers have been using Fleet for a while before they upgrade to the version that has this cleanup logic. So instead, I'd expect that we pass in the currentVersion
and then do a best effort to cleanup all older assets that are not in use by a package policy.
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, I was planning to extend as a next step.
do you think we can run the same cleanup logic on package update/policy upgrade for all older versions? so we don't need two versions of cleanup.
regarding the implementation, I was thinking to use the find api to find all lower version assets and check for each version that there are no dependent policies. would that work with an aggregation to find distinct versions?
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 updated this to find all older versions and delete assets for each. Tested with multiple old versions, seems to be working fine.
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.
do you think we can run the same cleanup logic on package update/policy upgrade for all older versions? so we don't need two versions of cleanup.
I can't think of a reason it wouldn't work for both scenarios. It would be good to reuse the same logic for each.
regarding the implementation, I was thinking to use the find api to find all lower version assets and check for each version that there are no dependent policies. would that work with an aggregation to find distinct versions?
An aggregation makes total sense to me. The find API does support aggregations as well, let me know if you have any trouble, but I suspect a terms aggregation on the package_policy
field should yield what you're trying to achieve. This will give you the number of documents that match each unique version keyword.
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, I found that, it is working
@@ -267,7 +268,12 @@ async function installPackageFromRegistry({ | |||
installType, | |||
installSource: 'registry', | |||
}) | |||
.then((assets) => { | |||
.then(async (assets) => { | |||
await removeOldAssets({ |
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.
doing cleanup after installing (updating) a package as well
Pinging @elastic/fleet (Team:Fleet) |
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.
Code looks good after latest changes, and all works well. Thanks for the tests as well. 🚀
@elasticmachine merge upstream |
💚 Build Succeeded
Metrics [docs]
History
To update your PR or re-run it, just comment with: |
* cleanup on server side * cleanup all older versions * fixed type errors * added unit tests Co-authored-by: Kibana Machine <[email protected]>
💚 Backport successful
This backport PR will be merged automatically after passing CI. |
* cleanup on server side * cleanup all older versions * fixed type errors * added unit tests Co-authored-by: Kibana Machine <[email protected]> Co-authored-by: juliaElastic <[email protected]>
Summary
Resolved #94340
Added logic to cleanup old version of package assets in case there are no dependent policies.
Calling this currently after package policy upgrade.
Next steps:
How I tested:
POST http://elastic:changeme@localhost:5601/julia/api/fleet/epm/packages/apache-0.3.3
kbn-xsrf: kibana
{ "force": true }
click on update to get 1.0.0 installed (with policy upgrade, if there are policies)
the cleanup logic runs, assets of 0.3.3 are deleted, while 1.0.0 remain
Tested with multiple old versions installed: 0.3.4, 0.3.3 and update -> both old versions are being deleted
Checklist
Delete any items that are not applicable to this PR.