Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 947332 - Adding Hook Support Similar to APT
Summary: Adding Hook Support Similar to APT
Status: UNCONFIRMED
Alias: None
Product: Portage Development
Classification: Unclassified
Component: Enhancement/Feature Requests (show other bugs)
Hardware: All Linux
: Normal normal
Assignee: Portage team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2025-01-01 21:21 UTC by webdevred
Modified: 2025-01-07 13:30 UTC (History)
4 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description webdevred 2025-01-01 21:21:09 UTC
This is a feature request to enhance Gentoo's Portage package manager by introducing support for pre-installation, post-installation, pre-removal, and post-removal hooks, similar to those available in APT on Debian-based systems. These hooks provide system administrators with greater flexibility and control during package management operations.
Details

Feature Description:
APT in Debian-based distributions provides a mechanism to execute custom scripts (hooks) before and after specific package management actions (e.g., installation, removal). This feature is highly useful for performing tasks like configuring services, cleaning up temporary files, or notifying users/admins of critical changes. Introducing a similar hook mechanism in Portage would make it more powerful and user-friendly.
Current Behavior

    Portage currently lacks a native hook system for executing user-defined scripts during package management operations.
    Any such tasks must be managed manually or implemented through external scripts and overlays, which is error-prone and lacks standardization.

Expected Behavior

The proposed feature would allow users to define hook scripts in designated directories (e.g., /etc/portage/hooks/) that Portage executes automatically during package operations. For example:

    Pre-installation Hooks: Tasks to execute before installing a package.
    Post-installation Hooks: Tasks to execute after successfully installing a package.
    Pre-removal Hooks: Tasks to execute before removing a package.
    Post-removal Hooks: Tasks to execute after successfully removing a package.

Proposed Implementation

    Configuration:
    Introduce a configuration option in make.conf or a similar file to enable or disable hooks globally.

    FEATURES="hooks"

    Hook Directories:
    Define standardized directories for hooks (e.g., /etc/portage/hooks/), with subdirectories for specific operations:
        /etc/portage/hooks/pre-install.d/
        /etc/portage/hooks/post-install.d/
        /etc/portage/hooks/pre-remove.d/
        /etc/portage/hooks/post-remove.d/

    Script Execution:
    During package management operations, Portage would:
        Check if hooks are enabled.
        Execute all scripts in the relevant directory, passing relevant environment variables (e.g., $PKG_NAME, $PKG_VERSION, $ACTION).

    Error Handling:
        Implement a mechanism to handle failures in hooks (e.g., configurable behavior to continue or abort package operations).

Use Cases

    Configuration Management: Automatically update configuration files or apply custom settings post-installation.
    Service Management: Start, stop, or restart services associated with packages being installed or removed.
    Custom Notifications: Send alerts or notifications to system administrators after critical updates.

Benefits

    Increased flexibility for system administrators.
    Standardized mechanism for extending package management behavior.
    Enhanced alignment with best practices in package management from other distributions.

I personally want to get into open source software development more and I do reallly  like Gentoo so in case there is anyone wanting this to be implemented, I would be happy to write the code for this.
Comment 1 Ionen Wolkens gentoo-dev 2025-01-02 00:00:18 UTC
It's not overly intuitive, but you can already do this using bashrc files.

Either using the global one at /etc/portage/bashrc, or per-package ones at e.g. /etc/portage/env/sys-apps/grep ("grep" itself here is a bashrc file, not a directory). Not to be confused with /etc/portage/package.env's files, this is different.

Not sure if we have good documentation for this somewhere (haven't looked), but in these files you can have "pre_" and "post_" functions for each ebuild phases. Such as post_pkg_postinst(), post_pkg_prerm(), and so on.

And in pkg_* phases you have unsandboxed root access and can do anything.

e.g. the aforementioned "grep" file could contain (can use all normal ebuild variables like ${PN} for the name, or ${PV} for version):

    post_pkg_install() {
        elog "successfully installed ${CATEGORY}/${PN}"
    }

And it'll print that message only after emerging sys-apps/grep.

It can of course also do things like restart services and such.
Comment 2 Ionen Wolkens gentoo-dev 2025-01-02 00:04:22 UTC
(In reply to Ionen Wolkens from comment #1)
>     post_pkg_install() {
Opps, meant post_pkg_postinst() there.
Comment 3 Zac Medico gentoo-dev 2025-01-02 02:34:50 UTC
The bashrc locations are documented here:

https://dev.gentoo.org/~zmedico/portage/doc/ch01.html#config-bashrc-locations

There is some brief documentation about phase hooks here:

https://dev.gentoo.org/~zmedico/portage/doc/ch01s02.html
Comment 4 webdevred 2025-01-02 07:52:23 UTC
(In reply to Ionen Wolkens from comment #1)
> It's not overly intuitive, but you can already do this using bashrc files.
> 
> Either using the global one at /etc/portage/bashrc, or per-package ones at
> e.g. /etc/portage/env/sys-apps/grep ("grep" itself here is a bashrc file,
> not a directory). Not to be confused with /etc/portage/package.env's files,
> this is different.
> 
> Not sure if we have good documentation for this somewhere (haven't looked),
> but in these files you can have "pre_" and "post_" functions for each ebuild
> phases. Such as post_pkg_postinst(), post_pkg_prerm(), and so on.
> 
> And in pkg_* phases you have unsandboxed root access and can do anything.
> 
> e.g. the aforementioned "grep" file could contain (can use all normal ebuild
> variables like ${PN} for the name, or ${PV} for version):
> 
>     post_pkg_install() {
>         elog "successfully installed ${CATEGORY}/${PN}"
>     }
> 
> And it'll print that message only after emerging sys-apps/grep.
> 
> It can of course also do things like restart services and such.

I already read the about the bash approach but according to my understanding it does it fit what I wanted.

Is it possible run the hook once when for example when I emerge emerge --update --deep --newuse @world? I want to run a backup command and name the backup "2025-01-02-rebuild-world-newuse-deep".
If "emerge www-servers/nginx" was run the backup "2025-01-02-install-www-servers-nginx" if the package installed with that emerge.
Comment 5 Ionen Wolkens gentoo-dev 2025-01-02 10:47:21 UTC
Well, could argue that running a command before or after emerge itself does not particularly need hooks given you can well, just run it or use a wrapper script to name your backup & run the emerge command.
Comment 6 Ionen Wolkens gentoo-dev 2025-01-02 10:52:24 UTC
(In reply to Ionen Wolkens from comment #5)
> Well, could argue that running a command before or after emerge itself does
> not particularly need hooks given you can well, just run it or use a wrapper
> script to name your backup & run the emerge command.
(not that portage does not already do something similar for emerge --sync with /etc/portage/postsync.d for convenience, can still use e.g. eix-sync over it)
Comment 7 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2025-01-03 02:32:46 UTC
I think this is probably a dupe of bug 839777.
Comment 8 Pascal Jäger 2025-01-07 13:30:23 UTC
(In reply to Ionen Wolkens from comment #5)
> Well, could argue that running a command before or after emerge itself does
> not particularly need hooks given you can well, just run it or use a wrapper
> script to name your backup & run the emerge command.

This does not really work well. You can only wrap around emerge itself, maybe check if it gets matching variables and only then invoke some action, but there is no possibility to react to what emerge outputs and does. 
E.g. maybe a user only wants to do something after emerge came up with a merge plan. (when it asks "Would you like to merge these packages?") or only when it couldn't because of some dependency conflict.