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

[Fleet] cleanup old package assets #112644

Merged
merged 6 commits into from
Sep 27, 2021

Conversation

juliaElastic
Copy link
Contributor

@juliaElastic juliaElastic commented Sep 21, 2021

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:

  • call same logic after package update
  • do a more generic check on all outdated package assets to clean up those that are already updated

How I tested:

  1. install old version of apache e.g.

POST http://elastic:changeme@localhost:5601/julia/api/fleet/epm/packages/apache-0.3.3
kbn-xsrf: kibana

{ "force": true }

  1. click on update to get 1.0.0 installed (with policy upgrade, if there are policies)
    image

  2. the cleanup logic runs, assets of 0.3.3 are deleted, while 1.0.0 remain

image

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.

@joshdover
Copy link
Contributor

However didn't find a suitable function on server to remove old installation, as sendRemovePackage deletes the latest one, even though I call it with an older version.
Should I change the server to delete the given version?

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 removeInstallation function isn't really what we want). We can probably add a new file for this behavior in a location like x-pack/plugins/fleet/server/services/epm/packages/cleanup.ts that performs this logic. The only things we really want to remove are the epm-packages-assets Saved Objects for any older package versions than the current one. We don't want to touch any Elasticsearch assets (such as index templates, pipelines, etc.).

@juliaElastic
Copy link
Contributor Author

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

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?

@joshdover
Copy link
Contributor

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.

Comment on lines 28 to 29
// how to query if more than one page?
perPage: 100,
Copy link
Contributor

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.

Copy link
Contributor Author

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

Copy link
Contributor Author

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,
Copy link
Contributor

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.

Copy link
Contributor Author

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

Comment on lines 18 to 20
savedObjectsClient: SavedObjectsClientContract;
pkgName: string;
oldVersion: string;
Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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({
Copy link
Contributor Author

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

@juliaElastic juliaElastic added auto-backport Deprecated - use backport:version if exact versions are needed Team:Fleet Team label for Observability Data Collection Fleet team v7.16.0 v8.0.0 labels Sep 23, 2021
@juliaElastic juliaElastic marked this pull request as ready for review September 23, 2021 07:58
@juliaElastic juliaElastic requested a review from a team as a code owner September 23, 2021 07:58
@elasticmachine
Copy link
Contributor

Pinging @elastic/fleet (Team:Fleet)

@juliaElastic juliaElastic added the release_note:skip Skip the PR/issue when compiling release notes label Sep 23, 2021
Copy link
Member

@kpollich kpollich left a 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. 🚀

@juliaElastic
Copy link
Contributor Author

@elasticmachine merge upstream

@juliaElastic juliaElastic enabled auto-merge (squash) September 27, 2021 07:58
@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

✅ unchanged

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@juliaElastic juliaElastic merged commit aeaad1f into elastic:master Sep 27, 2021
kibanamachine added a commit to kibanamachine/kibana that referenced this pull request Sep 27, 2021
* cleanup on server side

* cleanup all older versions

* fixed type errors

* added unit tests

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
@kibanamachine
Copy link
Contributor

💚 Backport successful

Status Branch Result
7.x

This backport PR will be merged automatically after passing CI.

@juliaElastic juliaElastic deleted the cleanup-package branch September 27, 2021 09:54
kibanamachine added a commit that referenced this pull request Sep 27, 2021
* cleanup on server side

* cleanup all older versions

* fixed type errors

* added unit tests

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: juliaElastic <90178898+juliaElastic@users.noreply.github.com>
lykkin pushed a commit to lykkin/kibana that referenced this pull request Sep 28, 2021
* cleanup on server side

* cleanup all older versions

* fixed type errors

* added unit tests

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport Deprecated - use backport:version if exact versions are needed release_note:skip Skip the PR/issue when compiling release notes Team:Fleet Team label for Observability Data Collection Fleet team v7.16.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Fleet] Old package assets are not removed from ES storage when package is upgraded
5 participants