setting error states during Linux RPM install/upgrade - linux

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

Related

restart service in rpm spec after config renamed

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.

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

How to override anaconda/kickstart package ordering?

I am building a bootable ISO to be used to install a Linux image (Oracle Linux, 5.8). This is using anaconda with a kickstart file to select the packages to be loaded. Some of these packages are failing with dependency problems in their %post section.
Eg, this is seen in /root/install.log after the installation is complete:
Installing thirdparty-tools-1.00-09.noarch
/var/tmp/rpm-tmp.97891: line 1: ln: command not found
/var/tmp/rpm-tmp.97891: line 2: ln: command not found
/var/tmp/rpm-tmp.97891: line 3: ln: command not found
/var/tmp/rpm-tmp.97891: line 4: ln: command not found
error: %post(thirdparty-tools-1.00-09.noarch) scriptlet failed, exit status 127
I'm trying to find out if it is possible to control/override the package ordering, without editing any RPMs to add dependencies. I've been looking through the anaconda / kickstart documentation (https://fedoraproject.org/wiki/Anaconda/Kickstart#Chapter_3._Package_Selection), and searching extensively elsewhere, so I think that the answer is actually 'no, you can't do this'. Which would be a shame.
The problem is that I am trying to include various third-party RPMs, which are not under my control and which have been digitally signed. These include some processing in a %post section. This processing requires some standard Linux commands, eg 'ln', 'touch', etc, which are supplied within the coreutils package. The third-party package does not currently include a dependency on the coreutils package, though obviously it should really. Anaconda uses its own partial ordering algorithm to choose what order to install these packages, and the third-party packages are being installed before the coreutils package. Obviously, the proper solution is to get these RPMs fixed by the third-party; however, this is likely to take too long.
I was hoping that their might be some hidden / un-documented option for the kickstart file, which could add in extra dependencies. Ideally, I'd like to be able to add something like this to the %packages section:
%packages
#admin-tools
#base
#core
#system-tools
thirdparty-tools
# We would like to add some magic command to indicate a missing dependency
thirdparty-tools dependson coreutils
So, my question is: Is it possible to control or override the package ordering without editing any RPMs to add dependencies?
Very many thanks for any help.
If you can't get the source RPM, you can use rpmrebuild to re-create the RPM:
rpmrebuild -e -n -d . -p thirdparty-tools-1.00-09.noarch
This will bring up a re-created spec file in your default editor, where you can make changes to the requires lines. Also, you may want to change the package name too, so that your re-built version is differentiated from the upstream vendor's version (I usually append "-local" to the package name).
Your package "thirdparty-tools" needs to specify all of its requirements. If you can get a SRPM of this package, you can modify the spec to indicate that you need coreutils, bash, etc in your package.
If you can't modify this package at all, your best option is to create a wrapper package that has the necessary requirements. Just use your favorite editor to create a file "thirdparty-tools-installer.spec" and ensure you include coreutils as a requirement as well as "thirdparty-tools". You can refer to rpm.or for more information http://www.rpm.org/max-rpm/s1-rpm-build-creating-spec-file.html
Lastly, you can just do yum -y install thirdparty-tools in the %post section of Kickstart. It's uglier for sure, but it will probably work.

Building rpm, overriding _topdir, but getting BuildRequires deps?

I have a libfoo-devel rpm that I can create, using the trick to override _topdir. Now I want to build a package "bar" which has a BuildRequires 'libfoo-devel". I can't seem to find the Right Way to get access to the contents of libfoo-devel without having to install it on the build host. How should I be doing it?
EDIT:
My build and target distros are both SuSE.
I prefer solutions that don't require mock, since I believe SuSE does not include it in its stock repo.
Subsequent EDIT:
I believe that the answer I seek is in the build package. Perhaps it's SuSE's answer to mock? Or it's the distributed version of the oBS service?
DESCRIPTION
build is a tool to build SuSE Linux
RPMs in a safe and clean way. build
will install a minimal SuSE Linux as
build system into some directory and
will chroot to this system to compile
the package. This way you don't risk
to corrupt your working system (due to
a broken spec file for example), even
if the package does not use BuildRoot.
build searches the spec file for a
BuildRequires: line; if such a line is
found, all the specified rpms are
installed. Otherwise a selection of
default packages are used. Note that
build doesn't automatically resolve
missing dependencies, so the specified
rpms have to be sufficient for the
build.
Note that if you really don't need libfoo-devel installed to build package bar the most sensible alternative would be to remove libfoo-devel from the BuildRequires directive (and maybe put the requirement where it belongs).
However, if you cannot do that for some reason, create a "development" rpm database. Basically it involves using rpm --initdb --root /path/to/fake/root. Then populate it with all of the "target packages" of your standard distro installation.
That's a lot of rpm --install --root /path/to/fake/root --justdb package-name.rpm commands, but maybe you can figure out a way to copy over your /var/lib/rpm/* database files and use those as a starting point. Once you have the alternative rpm database, you can fake the installation of the libfoo-devel package with a --justdb option. Then you'll be home free on the actual rpm build.
If neither mock nor the openSUSE Build Service are a viable choice then you will have to buckle down and install the package, either directly or in a chroot; the package provides files that the SRPM packager has decided are required to build, and hence is in the BuildRequires tag.

Building rpm

Is there an easy procedure to build an RPM.If so Please explain or provide the link.........
My requirement is very simple ..
I have two other RPMs which should be combined into one single RPM....
Please explain the process....
Thanks in advance..........
Building an RPM itself is rather easy, you just need to run
rpmbuild -ba <mypackage.spec>
The more complex task is creating the .spec file, which controls how the rpm itself is built. A good explanation is the book Maximum RPM, which is available on the rpm homepage. Creating a .spec file is handled here. From my own experience building a .spec file is something that's not easy -- but not too complicated either unless you want to make special things. The standard ./configure && make && make install is usually not too complicated.
Not sure what the problem is; if you've already got two RPMs, why do you need to make them into 1 rpm? Why not just use a shell script to install them both at the same time?
The RPM command will take multiple arguments, so for example:
rpm -ivh one.rpm two.rpm three.rpm
Will install one, followed by two, followed by three.
Otherwise, from what I know, you're going to have to build the packages first, and then build them into an RPM, at which point you will have a custom RPM that will have to be manually updated every time one of the component packages changes. Yuck.
Basic guide for RPM creation is available at:
http://fedoraproject.org/wiki/How_to_create_an_RPM_package
A very good and complete guide for RPM creation (by Fedora community) is available at link: http://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/
It is is wonderful.
BTW, for straight answer of your question, you might want to add two packages as a subpackage of another package. For that there are some specific entries in RPM spec file.
You need to create only one SPEC file for all three packages

Resources