Why?
Because I use the
net-fs/cifs-utils
package to provide mount.cifs
and I'd like scripts run by an unprivileged user to be able to mount and dismount entries in /etc/fstab. I'd also like user-space tools like the Dolphin file manager to be able to mount these points.At some point, there was an suid USE flag for
net-fs/cifs-utils
but it was decided that the USE flag be removed due to security concerns. Which is probably a good decision to have as a default, but it's a little annoying when my script to sync media to my media player fails because it can't (re-)mount the samba share after net-fs/cifs-utils
was updated.I had a hunch that there would be a way to hook into the emerge process -- and Gentoo (or rather, Portage) didn't let me down. After finding https://dev.gentoo.org/~zmedico/portage/doc/portage.html#config-bashrc-ebuild-phase-hooks (which alluded to creating bash functions in a special file) and https://wiki.gentoo.org/wiki/Handbook:X86/Portage/Advanced#Using_.2Fetc.2Fportage.2Fenv which hinted at where to do such magic, and after a little play-testing, I finally got to adding the following function to the (new) file /etc/portage/bashrc:
function post_pkg_postinst() {
if test "$CATEGORY/$PN" = "net-fs/cifs-utils"; then
TARGET=/sbin/mount.cifs
echo -e "\n\n\e[01;31m >>> Post-install hook: setting $TARGET SUID <<<\e[00m\n\n"
chmod +s $TARGET
fi
}
Which automatically sets the SUID bit and gives me a giant red warning that it did so.
https://wiki.gentoo.org/wiki/Handbook:X86/Portage/Advanced#Using_.2Fetc.2Fportage.2Fenv seemed to suggest that I could create the hook in
/etc/portage/env/net-fs/cifs-utils/bashrc
, but that didn't work out for me (EDIT: putting stuff under there is a very bad idea unless you're only setting environment variables -- I initially put my hooks under there and found that subsequent emerges installed under /etc/portage/env !!) . The above did and was (reasonably) simple to implement, after a few install attempts and dumping the environment that the script runs in with the env
command.Refactoring time: I'd like to be able to write individual scripts for packages (if I ever do this again), like I do with USE flags, where I store all flags pertinent to the installation of a higher-order package in /etc/portage/package.use/higher-order-package so I know where lower-down USE flags come from, for example my
/etc/portage/package.use/chromium
file contains:
www-client/chromium -cups -hangouts
>=dev-libs/libxml2-2.9.4 icu
>=media-libs/libvpx-1.5.0 svc cpu_flags_x86_sse4_1 postproc
Wherein I can always reminisce about how I had to set the
icu
flag on libxml2
to successfully install chromium
(https://wiki.gentoo.org/wiki/Qt/FAQ#qtwebkit_vs_chromium_block_caused_by_icu)Similarly, it would be nice if I could just create code snippets under /etc/portage/env/${CATEGORY}/${PN}, perhaps even have category-wide scripts (which an individual package could override)... hm. Ok, so first, we move the script above to
/etc/portage/env/net-fs/cifs-utils/post-install
. Then we create a new /etc/portage/bashrc
with these contents:
PORTAGE_HOOKS_PREFIX=/etc/portage/hooks
PACKAGE_HOOKS_DIR="$PORTAGE_HOOKS_PREFIX/$CATEGORY/$PN"
CATEGORY_HOOKS_DIR="$PORTAGE_HOOKS_PREFIX/$CATEGORY"
function source_all() {
if test -d "$1"; then
for f in $1/*; do
if test -f "$f"; then
source "$f"
fi
done
fi
}
source_all "$CATEGORY_HOOKS_DIR"
source_all "$PACKAGE_HOOKS_DIR"
Which, as suggested above, loads all scripts from the category folder (if it exists) then overlays with scripts from the package folder (if that exists). So now it's trivial to add hooks for any of the emerge phases outlined in https://dev.gentoo.org/~zmedico/portage/doc/portage.html#config-bashrc-ebuild-phase-hooks
Side-note: since the scripts above can change any environment variable involved in the build, it's quite important to use nice, long, specific variable names. One of my first attempts used
PREFIX
instead of PORTAGE_HOOKS_PREFIX
and that just ended up installing all new packages under the /etc/portage/hooks
directory because, of course, $PREFIX
is an environment variable respected by most build scripts... *facepalm*.Once again, this becomes a testament to how Gentoo provides an operating system which is totally yours. You have the control to deal with all of it, its state is as a result of your actions and choices. Once again, I wish I'd switched years ago.
Thank you very much for this blog post. I know it has been a while around, but quite now your post saved my day! :-)
ReplyDeleteCheers
Sven
For those who found this via google, it is actually already built into portage, you just need to use the correct file names. Reference here:
ReplyDeletehttps://wiki.gentoo.org/wiki//etc/portage/package.env
So set your scripts in the file:
/etc/portage/env/category/pn
or for specific package version only:
/etc/portage/env/category/pn-version
This file roughly behaves like bashrc, but is only included for that one package (or package-version)
I originally tried something along that line and it b0rk3d (read about 1/3 of the way in). Perhaps things are different now :D
Delete