-
Notifications
You must be signed in to change notification settings - Fork 162
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
Incremental build changes #822
Comments
#806 needs to be considered here too. |
I'm +1ing here, with elaborating as to why I need this functionality: I have 2 jails building with mysql dependencies, which in turn (at the time of writing this) builds llvm90 each time of a base system update (freebsd patch level change, for example). llvm90 builds for ~25 minutes each time, with an AMD Ryzen server with 16 cores, while maxing out load. I think rebuilding llvm only to build mysql-(client|server) is totally superfluous and unnecessary, since it has no custom build options. As it is only needed for the mysql build, it would be fine just to install it from a package repository, for which I have no option now. So as you can see, the issue isn't just about 'incremental builds', because on a base system change (i.e. the aforementioned freebsd patch level change) poudriere deletes the entire built package tree and rebuilds everything. Which is fine, but llvm could be seeded into the build environment from a binary package, saving lots of time and resources. |
I have a prototype for this that I will put into the next poudriere-devel for wider testing. |
Is there progress on this? I've had to abandon poudriere entirely because I can't get it to not build the entire dependency tree when all I need it to do is build one port with non-default options, and use its testport facility on stuff I maintain. |
I'm sorry for the trouble. I feel your pain. The frustration from rebuilds and rust crashing my build system so many times is what keeps me working on this currently. I have it working locally and have been working over the past month to clean it up before pushing it out. Right now I am focused on adding more tests to capture some of the specific odd cases that the changes ran into. In particular there were no build queue, testport, options, pkgclean, distclean tests committed yet. I have some for each of those now. It's a big change and as I tested it more I found more pieces which were needing manual testing. So I've been adding more tests around those areas.
Most of that is just in the test dir:
The new build tests explicitly are checking for what is built to make sure only what is needed to rebuild is rebuilt. It's coming soon. I want it out within the next week or two. |
Really looking forward to this. Just another example: today another ca_root_nss arrived, which in turn made curl to rebuild, which in turn made rust to rebuild, which in turn made clamd rebuild. I only really use clamd. Rust builds for ~35 minutes, burning all 16 cores in my server. |
I feel with you. ca_root_nss is one of the most useless ports these days, it has been long superseded with the CA certs system in base (though a few fixes need to be done). I am look at you @kevans91 ;-) |
this makes me think that there probably are a number of dependencies out there that when bumped don't need packages depending on them to rebuild. as in: it might need verification / testing, but not a rebuild. How many people who use poudriere run a package's tests? |
Poudriere running tests will be handled in #355. Probably a lot don't get ran. Not exactly responding to what you're asking but it made realize I should brain dump this out somewhere. In general what I can think of that needs a chased rebuild (
Through testing this change over the past year I have ran into most of those. Each was very confusing to debug and they were not obviously because of this change. That's a big reason I've been moving slow on releasing this. Simple changes like a shared library package has behavior changed or docs changed but the shlib version does not change - no Some of these don't require a chased rebuild for functionality but for the sake of reproducible builds they do. When we communicate the "new" rebuild to porters we'll want the key point that anything that changes reproducibility of downstream packages will require a Committers do forget to do a chase, or are unaware that it is needed, or rely on Poudriere to do the chasing for them. Relying on Poudriere was never the right thing because for reproducibility. The only case I have special checks for are shared libraries. If a package requires shared libraries it will check that the package that provides the library still provides it. If not then it rebuilds the package assuming that the shared library has a newer version/name to use. This is non-trivial. Ports don't tell what libraries they provide in an easy way. Ports do say which they require but not what they provide. So Poudriere needs to do a lot of work to make these decisions which can lead to a NOP-build spending minutes solving which packages provide which libraries. This special case is a big reason I haven't pushed this out yet as I'm unhappy with how it is implemented. I need to make it smarter but need tests for it first. I didn't add tests initially. I could see handling some of the other special cases depending on community testing of the change. |
I have 2 more commits to add tests for. It's almost done. |
Does work in progress on this issue explain why ports such as llvm15 are sometimes queued, then not (a good thing)? |
3.4.0 (installed from latest) shipped with a change that reads amongst others:
@bdrewery, is this the change we've been waiting for? I've set this up, couldn't test it as there are no updates for my jails now (in terms of curl/rust or anything that pulls these). I've did a quick run, couple python packages updated, nothing significant that would put a real strain on my server. Merry Christmas btw. |
Well, if it is, it's not working. Even when I specified |
sometimes, rust changes underneath, due to transient dependencies, such as curl updating. if the rust in package repos is recorded with the old version of curl, your local build will, unfortunately correctly, determine that rust needs to be rebuilt. it would be nice to find ways around this, especially in cases where there was no ABI change to a library. |
@igalic You could get the lastest commit hash, that was used for the builds, from here That way, i usually don't need to build rust, gcc & llvm |
This is dealing with dependencies that have a changed PKGBASE from what the package is looking for. A specific example here is freebsd/freebsd-ports@9196671 which changed the PKGBASE for net/openldap24-client from openldap-client to openldap24-client. Packages such as php74-ldap were depending on this metadata: "openldap-client":{"origin":"net/openldap24-client"} That would cause pkg-add (during make depends) to try installing openldap-client-*.pkg. That would not be found since the openldap package was now named openldap24-client-VER.pkg, having been rebuilt for a changed PKGNAME itself. But reverse deps didn't have the logic to rebuild on changed dep pkgnames. Note that this was discovered with the PKG_NO_VERSION_FOR_DEPS feature because but the root cause is the removal of the recursive deleting of packages; default SKIP_RECURSIVE_REBUILD==1 causes this. Issue #822
I merged in the major test framework changes this depends on today. I plan to merge the feature in "soon". Subpackages became a distraction but I've decided I'll leave subpackages broken and focus on getting this in. |
This allows the job queue to have smarter dependencies for ordering jobs. This will allow things like TEST_DEPENDS, and fixes some issues with TRIM_ORPHANED_BUILD deps (which the removed XFAIL tests test for). Some job types do not do anything except provide ordering. They are trimmed from the queue at the time of running. Rework the queue to support just-in-time determination of whether a port needs to build or not. That is, on startup do not remove items from the queue that are not needed. They will be trimmed out when eligible to be ran. This incurs slight overhead but avoids a lot of problems with determining the proper dependency graph needs or optimizing it early on which can do the wrong thing. This is primarily needed to support PKG_NO_VERSION_FOR_DEPS which avoids deleting packages that do not need a rebuild (effectively defaults SKIP_RECURSIVE_REBUILD to 1. In that case we ended up in a situation where some dependencies in the middle of the graph did not need a rebuild but items further down the chain did. The trimming would incorrectly clear out the middle down, losing the needed rebuild. An example is someport -> patchutils -> bash. If patchutils did not need a rebuild, but bash did, the queue was trimming out both patchutils and bash. Determining what needed to be kept pre-build was overly complex. With this method we determine the need on visit right before build. Fixes #806 - The TRIM_ORPHANED_BUILD_DEPS problem and similar solution. Issue #822
This flag was a hack to avoid recursively rebuilding packages but a fatal flaw is that Pkg records the versions of dependencies. If that specific version is not available then Pkg breaks. The intent of this feature was to respect version bumps (and other rebuild checks) rather than forcing a rebuild of everything. That feature is coming in Issue #822. If for some reason this is needed then SKIP_RECURSIVE_REBUILD=1 can be used in poudriere.conf. Issue #806
It's happening. I had a few hundreds commits behind this work that are now merged. There's only 3 commits left to merge. I'm fixing up some shared library tracking changes and then this will be in. |
@bdrewery, not sure if this is the best place to call it out, but -S is still listed 3 times in the poudriere-bulk(8) synopsis (version poudriere-git-3.4.99.20240424).
|
@markmcb thanks, fixed. I have merged this into git. Updating the port now. Off-by-default. I will send an email to ports later today explaining how to enable, use, and debug it. |
Changes: - bulk: Major changes for incremental build with PKG_NO_VERSION_FOR_DEPS=yes o Off-by-default for now o Poudriere will no longer force rebuild all reverse dependencies when a dependency is updated. o It will now only rebuild a port if pkg-upgrade(8) would automatically reinstall it. Cases such as changed dep libraries, options, ABI. o dependencies will be generated into the .pkg files without a version. You may see "-(null)" in some places that is expected. o Remote fetching will look for both versioned and unversioned dependencies that satisfy the current port build request. o A recursive rebuild *will be done* if the involved packages in the set have versioned dependencies, until all packages involved use the new unversioned dependency. o Setting PKG_NO_VERSION_FOR_DEPS back to no will recursively rebuild all packages back to the previous behavior with versioned deps. o PORTREVISION chases are critical to do in cases like language updates (ruby,perl,python,etc) or <static> library updates. o Shared library version updates still require their port consumers to be rebuilt to link to the new shared library. Porters are not used to always PORTREVISION chasing when doing this, and it is not always practical. Because of this Poudriere will now "inspect" shared library consuming packages *during the build* before deciding if they need to be rebuilt. There is likely a lot of room for optimization here to avoid Poudriere rechecking packages every build; currently a scale of seconds per package. Some metadata tracking in Ports would help improve this too. More work needs to be done still to improve the reporting and display of this process in the queue and web interface. Currently they just get marked "ignored" after being checked. o freebsd/poudriere#822 (link to generate notification for interested people) - bulk: -S was removed. The new PKG_NO_VERSION_FOR_DEPS feature replaces it and will become default after public testing - Support MAX_EXECUTION_TIME_$pkgbase in poudriere.conf - image: Use gptboot.efi in place of loader.efi to support bootme and bootonce - image: Enable space optimisation and disable minfree on read-only firmware images - image: Set a GPT label for EFI partition - image: Generate the upgrade image too
See freebsd/freebsd-ports@eef5ff6 for summary of feature |
Changes: - bulk: Major changes for incremental build with PKG_NO_VERSION_FOR_DEPS=yes o Off-by-default for now o Poudriere will no longer force rebuild all reverse dependencies when a dependency is updated. o It will now only rebuild a port if pkg-upgrade(8) would automatically reinstall it. Cases such as changed dep libraries, options, ABI. o dependencies will be generated into the .pkg files without a version. You may see "-(null)" in some places that is expected. o Remote fetching will look for both versioned and unversioned dependencies that satisfy the current port build request. o A recursive rebuild *will be done* if the involved packages in the set have versioned dependencies, until all packages involved use the new unversioned dependency. o Setting PKG_NO_VERSION_FOR_DEPS back to no will recursively rebuild all packages back to the previous behavior with versioned deps. o PORTREVISION chases are critical to do in cases like language updates (ruby,perl,python,etc) or <static> library updates. o Shared library version updates still require their port consumers to be rebuilt to link to the new shared library. Porters are not used to always PORTREVISION chasing when doing this, and it is not always practical. Because of this Poudriere will now "inspect" shared library consuming packages *during the build* before deciding if they need to be rebuilt. There is likely a lot of room for optimization here to avoid Poudriere rechecking packages every build; currently a scale of seconds per package. Some metadata tracking in Ports would help improve this too. More work needs to be done still to improve the reporting and display of this process in the queue and web interface. Currently they just get marked "ignored" after being checked. o freebsd/poudriere#822 (link to generate notification for interested people) - bulk: -S was removed. The new PKG_NO_VERSION_FOR_DEPS feature replaces it and will become default after public testing - Support MAX_EXECUTION_TIME_$pkgbase in poudriere.conf - image: Use gptboot.efi in place of loader.efi to support bootme and bootonce - image: Enable space optimisation and disable minfree on read-only firmware images - image: Set a GPT label for EFI partition - image: Generate the upgrade image too
Hey, I started using poudriere-devel a while ago, and wanted to wait for this moment, until curl becomes updated and per the poudriere-stable branch, rust would be recompiled because of it. I was hoping that this devel version and the changes you added within would solve this issue but it didn't. Curl had a new version today, and rust will be recompiled, whereas rust is only needed for the compilation of clamd, which means a binary version of it would be totally fine for the time of the compilation. Same goes for mysql-server in another jail, that is only pulled in by teamspeak-server and isn't used.
So my question is: do you have information on how I can avoid this with poudriere-devel? Compiling rust is not only unnecessary, it takes huge resources, as it takes 36 minutes with my server sweating blood. Same with mysql-server. Thanks for your help in advance. |
@karolyi do you have I had the same update and a rust rebuild was not triggered. It’s been working as expected for me. |
@markmcb thanks for your reply. No I don't, because I wasn't sure what exactly I should have used to not have rust rebuilt. I'll try next time (I guess I can't avoid building it now), but the cleanest solution would be just to pull a rust binary for the build time, and maybe to the packages. In my case, it isn't even installed when I install the jail, since it's not a requirement. |
Hm. I made a build with -S (no Now I removed Update: yes it is rebuilding mysql-server too. |
We should make
bulk -S
the default and rely onPORTREVISION
bumps. This will greatly reduce package rebuilds.It depends on freebsd/pkg#1831 which has more details on what needs to change here and how to interact with
pkg
differently.Edit:
bulk -S
isn't exactly same behavior being discussed here. The idea that we don't force rebuild packages because a dependency is updated is what this is. A port version/revision/epoch bump would still do a rebuild.The text was updated successfully, but these errors were encountered: