-
Notifications
You must be signed in to change notification settings - Fork 6.3k
Clean up old dashboard files on upgrade of local builds and static builds. #21370
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
base: master
Are you sure you want to change the base?
Conversation
This will be used to clean up old files from the web/v3 directory after an update/reinstall for a static build or local build.
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.
No issues found across 3 files
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.
Pull request overview
This PR adds a manifest file (.MANIFEST) to track installed dashboard files and automatically removes obsolete files during upgrades for both static builds and local builds.
Key changes:
- CMake generates a
.MANIFESTfile listing all installed dashboard files - Install scripts use the manifest to identify and remove old dashboard files that are no longer part of the current version
- Cleanup occurs after new files are installed to ensure only truly obsolete files are removed
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 10 comments.
| File | Description |
|---|---|
packaging/cmake/Modules/NetdataDashboard.cmake |
Generates .MANIFEST file containing list of dashboard files to be installed; adds manifest to CMake install rules |
packaging/makeself/install-or-update.sh |
Implements cleanup logic for static builds using the manifest to remove old dashboard files |
netdata-installer.sh |
Implements cleanup logic for local builds using the manifest to remove old dashboard files |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| file(GLOB files | ||
| LIST_DIRECTORIES FALSE | ||
| RELATIVE "${dashboard_src_prefix}" | ||
| "${dashboard_src_prefix}/${dir}/*") |
Copilot
AI
Dec 2, 2025
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.
Both the install rules and manifest generation only handle one level of files within subdirectories (using ${dashboard_src_prefix}/${dir}/*). If the dashboard contains nested subdirectories (e.g., static/css/fonts/), those nested files won't be installed or tracked in the manifest.
This appears to be a limitation of the current implementation. If the dashboard structure is guaranteed to be flat (no nested subdirectories), this is fine. Otherwise, both the install rules and manifest generation should use GLOB_RECURSE or handle nested directories explicitly.
Verify that the dashboard structure doesn't contain nested subdirectories, or update the code:
file(GLOB_RECURSE files
LIST_DIRECTORIES FALSE
RELATIVE "${dashboard_src_prefix}"
"${dashboard_src_prefix}/${dir}/**")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.
@Ferroin, we still have this suggestion.
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 is a known tradeoff taken based on discussion with the frontend team. Actually recursively listing all the files while still making CMake’s install directives work correctly is absurdly complicated to do right, and we have a general guarantee from the frontend team that the dashboard file layout is not going to change significantly from what is currently.
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.
nested
e.g. static/css/fonts/
This actually happened with GIF files (added and removed). I don't remember the exact directory, but there was some nesting.
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.
Correction to my earlier statement, Copilot is wrong here, and I forgot about the specifics of how the subdirlist() function that’s being used to generate the list of directories to process works (it has been more than a year since I wrote this code...).
That function generates a recursive list of all subdirectories of the specified base directory, so it does in fact pick up everything under ${dashboard_src_prefix}.
See https://github.com/netdata/netdata/blob/master/packaging/cmake/Modules/NetdataUtil.cmake#L202 for the actual code.
The strange looking split of processing all the directories one by one instead of doing a recursive glob is because CMake‘s install() command does not preserve the relative paths of the files listed for it (so install(foo/bar DESTINATION baz) will install the file bar directly into the directory baz without creating a directory baz/foo to install it into) and does not take directory trees (each file has to be listed for installation).
|
|
||
| message(STATUS " Generating manifest for dashboard code") | ||
| list(APPEND manifest | ||
| .MANIFEST |
Copilot
AI
Dec 2, 2025
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.
The manifest includes .MANIFEST itself on line 85, but this creates a potential issue: the manifest file won't exist in the source directory when it's being generated, so it shouldn't be listed as a file to preserve.
While self-referencing prevents the manifest from being deleted during cleanup, it's semantically incorrect since the manifest describes the installed dashboard files, not itself. The cleanup logic already reads the manifest file, so it's implicitly protected.
Consider removing .MANIFEST from the manifest list.
| .MANIFEST |
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.
@Ferroin, we also have 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.
The cleanup logic already reads the manifest file, so it's implicitly protected.
This is blatantly wrong, there’s no special protections given to the manifest file by virtue of it being read by the cleanup logic.
thiagoftsm
left a comment
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.
PR ran as expected after local building and generation of static installer to install on CentOS 7. LGTM!
If this version has known "tradeoffs"... why don't we make the logic easier and just remove the
It does contain. We added and removed 500 MB of gifs. This PR will not remove them, right? |
What do you mean by that? What did you test? |
Because the approach I’m taking here works pretty much independently of how the user chooses to update things (the only case it doesn’t work in is building by hand without netdata-installer.sh). The static build can’t run things before the files are extracted and put in place, so we need to track what files are installed and remove only those that aren’t part of the current version.
The logic is that anything not in the manifest for the newly installed version gets removed, so yes, it will remove them. That said, if they got installed in the first place, they would be in the manifest for the versions that they were installed in. The logic being used to generate the list of files for the manifest is literally identical to that used to generate the installation directives for the dashboard files. |
|
Converting to draft to make it non-measurable - I found some issues while testing, give me some time. |
|
@Ferroin, the original cleanup logic was functionally broken. I don't know what @thiagoftsm was testing 🤷♂️. @thiagoftsm, if you don't understand the change, please ask or don't review/approve. Two issues caused
As a result, This change replaces the pipeline with a correct, POSIX-safe loop that:
The cleanup now works as intended and handles all filenames safely. |
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.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Handles all current filenames. There’s a reason this was using null terminated records instead of newline terminated records, that’s the only character that is guaranteed to not be in a filename on all systems. Separately, there are a shit ton of files being processed here, which is exactly why I structured this as one pipeline instead of a long form loop that invokes multiple commands for every single file. |
|
Oh the irony, Copilot pointing out exactly what I was as I was writing my comment... |
de2d1eb to
0c54177
Compare
|
Force pushed to fix the code properly without wasting resources and correctly accounting for the fact that a newline is actually a valid character in filenames on most UNIX-like systems. |
Consider testing your changes before marking them ready for review. |
|
|
||
| if [ -r "${NETDATA_WEB_DIR}/.MANIFEST" ]; then | ||
| old_pwd="$(pwd)" | ||
| cd "${NETDATA_WEB_DIR}" && remove_files="$(find "." -type f -print0 | grep -vzF "" | grep -vzFf "${NETDATA_WEB_DIR}/.MANIFEST")" |
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.
grep -vzF ""
This filters everything because every string contains the empty string. What are you trying to do here? Can you please test before pushing commits?
Summary
This adds a manifest file to the root of the web directory to keep track of what files were installed by the current version of the Netdata Agent. On upgrade, static builds and local builds will remove any files in that directory that are not in the manifest file.
Test Plan
Requires manual testing to ensure that only files that are supposed to be removed are removed.
Additional Information
Fixes: #21327