Hi! I'm trying to get https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin implemented. It was approved for F40, but only a few days before the mass rebuild, so there wasn't time to do much, so it was retargeted to F41. We now have some time before the F41 mass rebuild, so I want to push all the changes required in various packages so that we have time to work out any kinks before the mass rebuild commences.
When I started looking at individual packages, I discovered that we have an old rule that packages are SUPPOSED to use "historical paths" to list their files. This rule was introduced to make the transition easier when UsrMove was implemented for F17. For example, mount.nfs was historically installed as /sbin/mount.nfs, so nfs-utils must use %files:/sbin/mount.nfs, even though /sbin is a symlink to /usr/sbin, meaning that the real path after installation is /usr/sbin/mount.nfs. And packages using a file path dependency on mount.nfs must use /sbin/mount.nfs too. To implement this rule, packages must use %buildroot/sbin during installation and use literal "/sbin/" in the files section. This idea made sense at the time, but now it seems overcomplicated and unecessary. It requires additional work from packagers who create the packages that provide the files, but also additional work from packagers that want to refer to those files. In fact, I only found three packages that implement the rule correctly: nfs-utils, glibc, and ocfs2-tools. So step 0. is to drop the packaging rule: https://pagure.io/packaging-committee/pull-request/1355 As to the actual sbin merge: Currently, we have %_bindir==/usr/bin, %_sbindir==/usr/sbin, and /sbin->/usr/sbin, /bin->/usr/sbin. In the end state, we will have %_bindir==%_sbindir==/usr/bin, and /bin,/sbin,/usr/sbin -> /usr/bin. This end state is simple: _any_ path will works for any binary. It's the transition, as we rebuild packages with the new definition, that requires some careful handling. After experimenting with a few different ways to handle this, the following approach seems to work best: 1. rpm is patched to provide %_sbindir==/usr/bin. (This affects what paths packages will list after being rebuilt.) 2. filesystem is patched to not contain /usr/sbin in %files, but instead symlink /usr/sbin -> bin in %pretrans. On fresh installations, this will succeed, so the merge is in place. On upgrades, this will fail, meaning that /usr/sbin remains a dir. There is also a %posttrans scriptlet to attempt a merge on upgrades, more about this below. In particular, since buildroots are created afresh for each build, package builds will get merged-sbin. 3. We need to handle the case where package foo had /usr/sbin/foo, but this file will be in /usr/bin/foo after rebuild. After the merge is done, /usr/sbin/foo and /usr/bin/foo will point to the same location, no problem, but during the transition, users or scripts might call /usr/sbin/foo. To make this work, filesystem rpm gets a scriptlet that will create symlinks from /usr/sbin to /usr/bin, for any files which were installed by packages in /usr/sbin. (A list was obtained using repoquery.) Initially, I wanted to put those scriptlets in individual packages, but that turns out to be a lot of duplicate work. Some packages have multiple subpackages with files (currently) in /usr/sbin, so we'd end up with a lot of churn. Doing it once in filesystem turns out to be fairly easy. 4. We also need to handle the case where other package bar has Requires:/usr/sbin/foo. Once foo has been rebuilt, it has only an automatic provides for /usr/bin/foo. We could adjust bar for the new path, but then bar would not be installable on old systems. Instead, a compat virtual Provides:/usr/sbin/foo is added to foo. We know that either /usr/sbin will be a symlink, or that filesystem will create the /usr/sbin/foo symlink. We need to ensure that the filesystem package that is installed is actually new enough so that the Provides is not a lie. filesystem.rpm gets a virtual Provides:filesystem(unmerged-sbin-symlinks)=1 which is used as Requires:filesystem(unmerged-sbin-symlinks) by foo. (An explicit Provides/Requires allows us to adjust or rescind the mechanism in the future.) 5. After this preparatory work is done, we can rebuild various packages with updated rpm and filesystem. Packages which don't use %_sbindir generally don't care. Some packages which use %_sbindir need small adjustments. There are some common failure modes: a. 'mv %buildroot/%_bindir/foo %buildroot/%_sbindir/' b. 'ln -s ../bin/foo %buildroot/%_sbindir/foo' c. Listing both %_bindir/foo and %_sbindir/foo in %files d. 'ln -sf ../bin/foo %buildroot/%_sbindir/foo.alt' e. 'ln -sf ../sbin/foo %buildroot/%_bindir/foo.alt' To make builds work both before and after the merge, a-c should be conditionalized on '%if "%{_sbindir}" != "%{_bindir}"'. d-e are fixed by using 'ln -sf --relative %{buildroot}/%_bindir/foo %buildroot/%_sbindir/foo.alt' or 'ln -sf --relative %{buildroot}/%_sbindir/foo %buildroot/%_bindir/foo.alt' I submitted / will submit a bunch of pull requests for various packages, but not all, so I'm describing this here so that packagers can use this as a hint. 6. As we rebuild packages in merged buildroots, and those packages are deployed on user systems, in completely new installations, /usr/sbin will be created as a symlink. On upgraded installations, /usr/sbin is a directory and will contain a mix of files and symlinks. filesystem.rpm also has a scriptlet to check if /usr/sbin contains symlinks only, and once that's true, it will nuke /usr/sbin and replace it by a symlink to /usr/bin. This will finalize the merge on upgraded systems. The plan: I. Merge https://pagure.io/packaging-committee/pull-request/1355. This isn't stricly necessary, but makes things simpler. II. I've been doing test rebuilds of packages and filing pull requests as described in 1–4. above. Those should be merged before the other things, changes are conditionalized on '"%{_sbindir}"=="%{_bindir}"'. Some pull requests have already been merged. If you get a pull request, please review and/or merge. https://src.fedoraproject.org/rpms/rpm/pull-request/56 https://src.fedoraproject.org/rpms/filesystem/pull-request/11 https://src.fedoraproject.org/rpms/chkconfig/pull-request/13 https://src.fedoraproject.org/rpms/coreutils/pull-request/15 https://src.fedoraproject.org/rpms/cyrus-sasl/pull-request/11 MERGED https://src.fedoraproject.org/rpms/dmidecode/pull-request/8 https://src.fedoraproject.org/rpms/exim/pull-request/16 MERGED https://src.fedoraproject.org/rpms/exim/pull-request/17 https://src.fedoraproject.org/rpms/glibc/pull-request/91 https://src.fedoraproject.org/rpms/kmod/pull-request/12 https://src.fedoraproject.org/rpms/libcap/pull-request/29 MERGED https://src.fedoraproject.org/rpms/nfs-utils/pull-request/15 https://src.fedoraproject.org/rpms/ocfs2-tools/pull-request/2 https://src.fedoraproject.org/rpms/opensmtpd/pull-request/1 https://src.fedoraproject.org/rpms/policycoreutils/pull-request/42 https://src.fedoraproject.org/rpms/procps-ng/pull-request/7 https://src.fedoraproject.org/rpms/rpcbind/pull-request/4 https://src.fedoraproject.org/rpms/shadow-utils/pull-request/22 https://src.fedoraproject.org/rpms/systemd/pull-request/131 https://src.fedoraproject.org/rpms/util-linux/pull-request/17 III. I have two coprs: https://copr.fedorainfracloud.org/coprs/zbyszek/merged-sbin/builds/ https://copr.fedorainfracloud.org/coprs/zbyszek/unmerged-sbin/builds/ The first one has rpm and filesystem with the changes, so the builds done there get %{_sbindir}==%{_bindir}. Other packages are rebuilt with the patches from pull requests. The second has old rpm and filesystem, and it serves as a check that the same srpms as from the first copr still build fine without the merge. It should be possible to install the packages from the first copr onto a system and either end up with a system with some links and files in /usr/sbin, or /usr/sbin being a symlink. I still need to do more builds in the coprs. If it all turns out to work as expected, I think we're ready to execute the merge. IV. After the pull requests for rpm and filesystem are accepted, I'll build those in a side tag so that they appear in the buildroots at the same time. (Things would be even more confusing with just one of those.) [rpm, filesystem] There is a bunch of packages which do 5c in the list above. Those will FTI until they have been rebuilt. I'll build those in the same side tag so that the buildroot is not broken and we don't get cascading build failures. [rpcbind, systemd-udev, policycoreutils] Once that's done, the side tag can be merged and packages will see the new buildroot layout as they are rebuilt. V. Other packages will need to rebuild to change the layout. I think it'll make sense to rebuild any packages which have had patches applied. There is no "flag day", but it'd be great if we rebuild most packages with files in /usr/sbin, so that we can actually test if the full transition works as expected. VI. A special case of V. is packages using usermode helper with files in /usr/bin and /usr/sbin. Here, each package is different and input from maitainers will be needed. As long as those packages are not rebuilt, they will continue to function in the old state, but as point they'll need to be fixed or retired. I looked into setuptool, and AFAICT, the package is absolete and doesn't actually work. A candidate for retirement. I'm sure that I missed some corner cases. In case something breaks, let me know, I'll try to fix or help to fix. I want to finish working on rpm, filesystem, and other packages soon (hopefully this week), and merge everything about a week later. Zbyszek -- _______________________________________________ devel mailing list -- devel@lists.fedoraproject.org To unsubscribe send an email to devel-le...@lists.fedoraproject.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org Do not reply to spam, report it: https://pagure.io/fedora-infrastructure/new_issue