restart service in rpm spec after config renamed - linux

I am writing an RPM spec file to install and update a daemon. I would like to ensure that any existing configuration files are appropriately renamed to .rpmsave .rpmnew during the update. For this I use %config(noreplace), which appears to do the renaming correctly. Also, I have a command to perform a conditional restart in the %post hook, which works correctly as well.
The problem I have, is that when the %post hook executes, it seems that the config files have not been renamed yet, and this results in my service to fail to startup.
Is there an rpm hook that runs after the renaming, if not, what other approach can I take. I have considered using rpm -V to check if config file has been edited by the user and perform the renaming myself in the %post, but I dont really want to do this as it is reproducing the behaviour of %config(noreplace).

Try the %posttrans hook https://fedoraproject.org/wiki/Packaging:Scriptlets. It should run at the end of the install.

Related

How to replace binary file during rpm upgrade without changing permissions

I need to replace the existing binary during rpm upgrade but I do not want to change the permission/ownership which is set already.
In my case, after the binary installation (not upgrade), ownership/permissions are set properly by rpm. But after the rpm installation, permissions/ownership of the file are modified by admin to allow another process to run this binary. Owner/group of the another process is different from this process. But when the rpm is upgraded it resets the permissions/ownership and another process is now not able to execute it.
Looking for a solution on how to retain the existing ownership/permissions but replace the binary only.
Any type of help/pointers are appreciated. Let me know if you have any questions.
Read the state of the file in %pre and restore it in %posttrans for more informations see https://fedoraproject.org/wiki/Packaging:Scriptlets#Saving_state_between_scriptlets

prevent rpmbuild from reading ~/.rpmmacros

Is there a way to prevent the rpmbuild command from reading the ~/.rpmmacros file? I want to add rpmbuild to a Make target and want to get a consistent build under any user account, regardless of the options somebody might have personally set in the rpmmacros file in his home directory.
How can I do this? Or, is that actually a bad idea?
If you're looking to get the a consistent build then the rpmmacros is only one part of the problem. The build may still differ simply because it's running on a machine with different things installed. Use mock to get a truly consistent build environment.
Solved this now this by setting $HOME to an empty directory while running rpmbuild:
mkdir $MY_DIST_DIR/dummyhome
HOME=$MY_DIST_DIR/dummyhome/ rpmbuild ...
rm -r $MY_DIST_DIR/dummyhome

setting error states during Linux RPM install/upgrade

I'm currently developing my first Linux RPM package for release. During the %post hook, I want to ensure that a particular file is resident on the target system. If this file is present, I'd like the install to proceed. If this file is missing, I'd like RPM to abort the install and report an error code.
Conditional logic in the .spec file works fine, but adding "return 1" in the error case causes RPM to throw an error (and, ironically, RPM does return with an error code in that case). But what is the "right" way to tell RPM that an install has failed and to exit gracefully?
Thank you!
That particular file is part of the RPM? If not, the correct place to do this check is in the %pre section. If it is, you can use the %verify for verification. When the %post run, the package is installed already, so it cannot be "failed"
Either put the check in the %pre section, or add it to the Requires field to make rpm itself check for you.
what is the "right" way to tell RPM that an install has failed and to
exit gracefully?
Best practice would say that the RPM installation should not fail if all the listed dependencies are met.
It does sound very much like the file is a dependency, in which case it should be listed as Requires:/path/to/file.
If it's a site-specific file for which you control deployment, then the RPM should deploy its own good default, which you can specify under %files with %config(noreplace). This will ensure that any existing config is not overwritten, and the default is written as /path/to/file.rpmnew.
If you want to replace an existing config, you would use %config without the (noreplace) option, which causes the existing file to be moved aside to /path/to/file.rpmsave

How to build a RPM package with custom changes

I'm working on Linux.
I have installed a ruby rpm on my system sing following command,
rpm –ivh zenith_ruby_1.8.6-1.0-2.el5.src.rpm
Now i have added some debugging statments in the source files of this rpm
and i want to rebuild this rpm with my changes in source file.
I tried using following command
rpmbuild -ba rpmbuild/SPECS/zenith_ruby-1.8.6-p369.spec
But execution of this commands leads to overwriting the source file that cause removal of by changes from source file.
Is there any way to re-build with our changes in source file?
You should make your changes a patch that gets applied during the build process.
See this tutorial for instructions
I found the solution for above problem.
We need to execute following command to build already installed RPM :
rpmbuild -bc --short-circuit rpmbuild/SPECS/zenith_ruby-1.8.6-p369.spec

Run time installation directory of debian package contents

I have a debian package that I built that contains a tar ball of the files, a control file, and a postinst file. Its built using dpkg-deb and it installs properly using dpkg.
The modification I would like to make is to have the installation directory of the files be determined at runtime based on an environment variable that will be set when dpkg -i is run on the deb file. I echo out the environment variable in the postinst script and I can see that its set properly.
My questions:
1) Is it possible to dynamically determine the installation directory at runtime?
2) If its possible how would I go about this? I have read about the rules file and the mypackage.install files but I don't know if either of these would allow me to accomplish this.
I could hack it by copying the files to the target location in the posinst script but I would prefer to do it the right way if possible.
Thanks in advance!
So this is what I found out about this problem over the past couple of weeks.
With prepackaged binaries you can't build a debian package with a destination directory dynamicall determined at runtime. I believe that this might be possible if installing a package that is built from source where you can set the install directory using configure. But in this case since these are embedded Ubuntu machines they don't have make so I didn't pursue such an option. I did work out a non traditional method (hack) for installing that did work. Since debian packages simply contain a tar ball relative to / simply build your package relative to a directory under /tmp. In the postinst script you can then determine where to copy the files from the archive into a permanent location.
I expected that after rebooting and the automatic deletion of the subdirectory under /tmp that dpkg might not know that the file package existed. This wasn't a problem. When I ran 'dpkg -l myapp' it showed as still installed. Updating the package using dpkg/apt-get also worked without a hitch.
What I did find is that if you attempted to remove the package using 'dpkg -r myapp' that dpkg would try and remove /tmp which wasn't good. However /tmp isn't easily removed so it never succeeded. Plus in our situation we never remove packages but instead simply upgrade them.
I eventually had to abandon the universal package due to code differences in the sources resulting in having to recompile per platform but I would have left it this way and it did work.
I tried using --instdir to change the install directory of the package and it does relocate the files but dpkg fails since the dpkg file can't be found relative to the new instdir. Using --instdir is sort of like a chroot. I also tried --admindir and --root in various combinations to see if I could use the dpkg system relative to / but install relocate the files but they didn't work. I guess rpm has a relocate option that works but not Ubuntu.
You can also write a script that runs dpkg-deb with a different environment for 6 times, generating 6 different packages. When you make a modification, you simply have to run your script, and all 6 packages gets generated and you can install them on your machines avoiding postinst hacking!
Why not install to a standard location, and simply use a postinst script to create symbolic links to the desired location? This is much cleaner, and shouldn't break anything in dpk -I.

Resources