[Rpm-maint] Plugin ponderings
pmatilai at laiskiainen.org
Thu Nov 22 13:41:40 UTC 2012
Like said in some earlier email, there's not much hope getting the
details 100% right the first time. The best way of finding out what
works and what doesn't is to try it out, so...
I started looking into creating a syslog plugin for rpm. One could argue
that logging is fundamental enough to be in rpm core, but then having it
in a plugin allows nicely for alternatives (such as *gasp* native
systemd journal support) and is a nice and harmless way to test the
plugin system. Lets just say I ran into issues real fast. No
fingerpointing implied - I didn't catch these on review either and some
of the issues are direct consequences from my own suggestions, doh :)
For logging installs and erasures, one of the primary interests is
PLUGINHOOK_PSM_POST. As it is now, the hook doesn't get called if the
package failed to install, which is a case you'll certainly want to log:
/* Run post transaction element hook for all plugins */
if (!rc) rc = rpmpluginsCallPsmPost(ts->plugins, te);
The other problem here is that the PSM_POST hook doesn't get passed the
result code of the install (otoh it doesn't get called on failure to
begin with so...). One could get the status from rpmteFailed(), but that
element failure is set only after rpmpsmRun() returns so its not
Similar issues are present in the TSM hooks: TSM_POST doesn't get called
on some error situations (file conflicts etc) where TSM_PRE is called,
and the transaction result code is not passed to plugins.
Me thinks we seriously need to define a consistent convention for all
plugin hooks and then scrutinize the existing and future hook paths for
correctness in all possible situations.
I'd think part of the convention needs to be that whenever PRE-hooks get
called, the pairing POST hooks are guaranteed to get called too. Even if
some of the PRE-hooks returned errors: some plugin(s) might return an
error from its PRE-hook, but there could be other plugins which
succeeded in their own business and might have allocated resources they
need to free up in POST.
Then there's the issue of return codes: maybe all the POST hooks should
take an added 'rc' argument for the return code of the actual operation.
That seems simple enough in principle, but there be dragons in the details:
For example rpmpsmRun() returns RPMRC_FAIL only if the package didn't
get installed (or removed) at all. %pre and %preun scriptlets can
prevent install/erase from taking place, %post and %postun cannot (as
the operations cannot be rolled back) so RPMRC_OK is returned from
rpmpsmRun() even if they fail: basically the operation succeeded with
warnings. This semantic needs to be taken into account with plugin hook
results too, so rpmpluginsCallPsmPost() can't really cause RPMRC_FAIL to
be returned from rpmpsmRun(). Or we need to revamp the whole damn return
code system (which might well be the sanest option really, especially
since its just an internal API)
Similar quirks are present in rpmtsRun() return codes, but that's a more
difficult case as its part of the public API (which everybody loves to
hate because of the nutty and useless return codes :)
Another question is whether rpmRC codes are sufficient for the task.
It's used for a lot of things in rpm, but many of those uses are ugly
abuses in reality.
P.S. I certainly dont mean you need to do all this, I'll help combing
the call- and error paths for correctness once we figure out what
"correct" actually is.
- Panu -
More information about the Rpm-maint