Hello,
I post here because I have an embarassing issue considering the yum version provided with CentOS 5.
I am trying to package an application for CentOS. So I wrote my own specfile which is composed of declaration of various packages (main application and plugins for this applications).
In that the configuration, the plugins RPM depends on the main application RPM because. Moreover, in all %postun blocks I execute a script which is provided my the main app RPM.
My issue is that when I try to remove the packages with the yum remove command, the main app RPM is erased before the plugin RPM and in that case the postun scriptlets for the plugin fails because my script is not available anymore.
As I read on the RPM and YUM doc, I used in the SPEC file the following instructions :
Requires(post): mainapp >= %{version} Requires(postun): mainapp >= %{version}
But even with this declaration, yum removes the RPM in bad order :
Erasing : mainapp 1/2 Erasing : mainapp-plugin 2/2
/var/tmp/rpm-tmp.48257: line 1: /usr/sbin/mainapp-setup: No such file or directory
As a note, I say that I use a unique specfile for all my application.
So is there a bug with yum or do I something wrong ?
For now, I use an ugly workaround which tests the availability of the script in the postun block but I don't like it.
Thanks in advance for your answers.
Regards, Olivier BONHOMME
On 05/11/11 13:22, Olivier BONHOMME wrote:
Hello,
I post here because I have an embarassing issue considering the yum version provided with CentOS 5.
I am trying to package an application for CentOS. So I wrote my own specfile which is composed of declaration of various packages (main application and plugins for this applications).
In that the configuration, the plugins RPM depends on the main application RPM because. Moreover, in all %postun blocks I execute a script which is provided my the main app RPM.
My issue is that when I try to remove the packages with the yum remove command, the main app RPM is erased before the plugin RPM and in that case the postun scriptlets for the plugin fails because my script is not available anymore.
As I read on the RPM and YUM doc, I used in the SPEC file the following instructions :
Requires(post): mainapp>= %{version} Requires(postun): mainapp>= %{version}
But even with this declaration, yum removes the RPM in bad order :
Erasing : mainapp 1/2 Erasing : mainapp-plugin 2/2
/var/tmp/rpm-tmp.48257: line 1: /usr/sbin/mainapp-setup: No such file or directory
As a note, I say that I use a unique specfile for all my application.
So is there a bug with yum or do I something wrong ?
Please post your spec file to a pastebin for us to see.
Le 05/11/2011 15:29, Ned Slider a écrit :
Please post your spec file to a pastebin for us to see.
Hello,
Here it is : http://ares.ptitoliv.net/~ptitoliv/fusiondirectory.spec
Regards, Olivier BONHOMME
On 05/11/11 14:40, Olivier BONHOMME wrote:
Le 05/11/2011 15:29, Ned Slider a écrit :
Please post your spec file to a pastebin for us to see.
Hello,
Here it is : http://ares.ptitoliv.net/~ptitoliv/fusiondirectory.spec
Rather than making the Requires specific to a package:
Requires(postun): fusiondirectory >= %{version}
try making it specific to the script that needs to be run. For example:
Requires(postun): /full/path/to/script.sh
Le 05/11/2011 16:19, Ned Slider a écrit :
On 05/11/11 14:40, Olivier BONHOMME wrote:
Le 05/11/2011 15:29, Ned Slider a écrit :
Please post your spec file to a pastebin for us to see.
Hello,
Here it is : http://ares.ptitoliv.net/~ptitoliv/fusiondirectory.spec
Rather than making the Requires specific to a package:
Requires(postun): fusiondirectory>= %{version}
try making it specific to the script that needs to be run. For example:
Requires(postun): /full/path/to/script.sh
Hello,
Thanks for you answer
Already tested and it is the same behaviour :(
After googling a little bit, I found this : https://bugzilla.redhat.com/show_bug.cgi?id=448153
Could that explaing such an issue ?
Regards, Olivier BONHOMME
On 05/11/11 15:29, Olivier BONHOMME wrote:
Le 05/11/2011 16:19, Ned Slider a écrit :
On 05/11/11 14:40, Olivier BONHOMME wrote:
Le 05/11/2011 15:29, Ned Slider a écrit :
Please post your spec file to a pastebin for us to see.
Hello,
Here it is : http://ares.ptitoliv.net/~ptitoliv/fusiondirectory.spec
Rather than making the Requires specific to a package:
Requires(postun): fusiondirectory>= %{version}
try making it specific to the script that needs to be run. For example:
Requires(postun): /full/path/to/script.sh
Hello,
Thanks for you answer
Already tested and it is the same behaviour :(
After googling a little bit, I found this : https://bugzilla.redhat.com/show_bug.cgi?id=448153
Could that explaing such an issue ?
Quite possibly, I don't know.
In which case, if such a bug does exist and is affecting you, I would place the script within %postun of each package that needs it rather than calling the script as a file that might have already been removed. This is better than simply testing the script exists before running it as if it doesn't then it doesn't get run and presumably that is not the desired outcome. There are many ways of working around such a bug.
Le 05/11/2011 17:14, Ned Slider a écrit :
Quite possibly, I don't know.
In which case, if such a bug does exist and is affecting you, I would place the script within %postun of each package that needs it rather than calling the script as a file that might have already been removed.
Hello Ned,
Sorry but I am a little bit confused. Now, it's the case : the script is in the %postun block for each RPM which needs it. But maybe, there is a misunderstanding. Are you talking about the script content ?
This is better than simply testing the script exists before running it as if it doesn't then it doesn't get run and presumably that is not the desired outcome.
In my case, it's not a big deal because, if the binary is not here, that means the main app package is not here anymore and in that case it doesn't make sense to execute the script.
There are many ways of working around such a bug.
I thought the test way the best in that case. Of course it works, but it is a bit ugly and i don't think there is pretty solution for that.
Regards, Olivier BONHOMME
On 05/11/11 16:25, Olivier BONHOMME wrote:
Le 05/11/2011 17:14, Ned Slider a écrit :
Quite possibly, I don't know.
In which case, if such a bug does exist and is affecting you, I would place the script within %postun of each package that needs it rather than calling the script as a file that might have already been removed.
Hello Ned,
Sorry but I am a little bit confused. Now, it's the case : the script is in the %postun block for each RPM which needs it. But maybe, there is a misunderstanding. Are you talking about the script content ?
Yes, the script content.
This is better than simply testing the script exists before running it as if it doesn't then it doesn't get run and presumably that is not the desired outcome.
In my case, it's not a big deal because, if the binary is not here, that means the main app package is not here anymore and in that case it doesn't make sense to execute the script.
Well that depends on what the script does I guess. In your case it may well be fine.
Le 05/11/2011 17:52, Ned Slider a écrit :
Yes, the script content.
Unfortunately, the script is a big perl script so it's difficult to integrate it. But thanks for the idea. I will note for a next time :)
This is better than simply testing the script exists before running it as if it doesn't then it doesn't get run and presumably that is not the desired outcome.
In my case, it's not a big deal because, if the binary is not here, that means the main app package is not here anymore and in that case it doesn't make sense to execute the script.
Well that depends on what the script does I guess. In your case it may well be fine.
Yes I think it's ok.
Regards, Olivier BONHOMME
Olivier,
Le 05/11/2011 16:19, Ned Slider a écrit :
On 05/11/11 14:40, Olivier BONHOMME wrote:
Rather than making the Requires specific to a package:
Requires(postun): fusiondirectory>= %{version}
try making it specific to the script that needs to be run. For example:
Requires(postun): /full/path/to/script.sh
Recently, I ran into a similar issue with package removal order, and solved it by using the method shown below. (My platform is RHEL 5.x / CentOS 5.x, using RPM version 4.4.2.3)
For each of the sub-packages, I included this in the sub-package header section:
Requires(postun): <Main-Package>
where <Main-Package> is the package name of the master. In the main package, I created a %postun section as below:
%postun exit 0
I placed a similar %postun section in the sub-packages:
%postun exit 0
These are basically "NOP" scripts, replace them with more code if your sub-package actually needs to do a post-uninstall stage. The sections do need to exist in the master and sub-packages to help RPM determine the dependencies properly.
To help debug the package removal process, use the following:
# rpm -e <Main-Package> -vv 2>&1 | tee destroy.log
This will turn on extra debugging output from rpm and capture it into a log file that you can view to see exactly how RPM is determining the order in which packages need to be removed. Look for something like this:
D: ========== tsorting packages (order, #predecessors, #succesors, tree, depth, breadth) D: 0 0 0 7 1 0 -MyPkg-util-1.0.2-2.i386 D: ========== successors only (0 bytes) D: 1 0 0 0 1 1 -MyPkg-1.0.2-2.i386 D: 2 0 0 1 1 2 -MyPkg-metro-1.0.2-2.i386 D: 3 0 0 2 1 3 -MyPkg-tomcat6-1.0.2-2.i386 D: 4 0 0 3 1 4 -MyPkg-api-1.0.2-2.i386 D: 5 0 0 4 1 5 -MyPkg-webapp-1.0.2-2.i386 D: 6 0 0 5 1 6 -MyPkg-default-1.0.2-2.i386 D: 7 0 0 6 1 7 -MyPkg-site1-1.0.2-2.i386
In my scenario, I have seven other sub-packages that depend on each other as well as the master package. As the MyPkg-site1 sub-package depends on the MyPkg, MyPkg-webapp, MyPkg-api, and MyPkg-tomcat6; I made sure to list all three of these packages in the Requires(postun): line in the MyPkg-site1 sub-package. The removal stage %preun for MyPkg-site1 depends on running a script which exists in the MyPkg master, so if the MyPkg master was removed, the MyPkg-site1 sub-package failed to properly uninstall (unless I used rpm -e --noscripts). Applying the steps above solved this and now the packages are removed in the correct order.
Refer to the RPM manual for more details on addressing package dependencies: http://www.rpm.org/max-rpm-snapshot/s1-rpm-depend-manual-dependencies.html
"RPM enforces the above dependencies _until_ the specified script has been run, not _at_ that time. In other words, it will allow erasing a dependency that was marked for eg. the %post script for an already installed package, but will not allow erasing one that is required for a %postun script for such a package."
rpm -i: %pre script runs -> installs files & dirs -> %post script runs rpm -e: %preun script runs -> removes files & dirs -> %postun script runs
Cheers!
Simba Engineering