Can I have a RPM depend on a directory? - linux

I'm creating an RPM file (with rpmbuild) whose post-install script will create a file in /etc/X11/xinit/xinitrc.d/. To make sure that the directory already exists, I'd like to specify a dependency on a package which creates it.
Is it correct in this case to add a Requires: /etc/X11/xinit/xinitrc.d line to the spec file? Or is it not allowed to depend on directories, and should I rather add a dependency on xorg-x11-xinit package (which appears to provide this directory on my system)?
The package is intended to work on CentOS (RHEL) 6.

This should work (you can Require any path), but you should be depending on the package that provides that path. There must be a reason you are not doing this?

You should use virtual packages to avoid surprises, when the required file can be provided by more than one package.
In your example, yum provides says that /etc/X11/xinit/xinitrc.d is provided by xorg-x11-xinit and qt5-qtbase-gui, so, specifying that path as a dependency could pull a package you don expect.
You should have a virtual package for each possible package that provides the file. The package my-xinit-x11 should contain:
Requires: xorg-x11-xinit
Provides: my-xinit
And your package should contain:
Requires: my-xinit
More virtual packages can be created with the same Provides, so when either is installed rpmbuild will see the dependency as satisfied

Related

Allow files from an RPM package to be overwritten by another rpm package

I have an RPM I am making and this is in a very controlled environment so let's also assume it is safe to allow another RPM package to overwrite certain files contained from the original RPM package.
I know from experience if you try to install an RPM package that overwrites another RPM packages file's you get a warning that there is a conflict and the install fails (yes you can do some command line hacking but that is not ideal for the situation).
Is there any way through the original RPM packages spec file that you can specify these files are not part of the package they can be overwritten by another RPM package or is that just strictly prohibited from ever happening?
Is there any way through the original RPM packages spec file that you can specify these files are not part of the package they can be overwritten by another RPM package or is that just strictly prohibited from ever happening?
You can use %ghost directive for this purpose.
http://ftp.rpm.org/max-rpm/s1-rpm-inside-files-list-directives.html

How to install two different versions of same rpm and make them work parallely

Currently I am trying to install a rpm secured_soft_2.0.0.rpm and i am
unable to install it as we already have secured_soft_1.3.0 installed.
Requirement is that we need to have both the versions installed.
Complexities :
These package inturn have dependent rpm's (lot of them ) and all these
interdependent rpm's also have versions
ex: secured_soft_1.3.0 works only with packages which are of version 1.3,
and secured_soft_2.0.0.rpm work only with dependecies of version 2.0 only.
So all these dependencies also need to be reinstalled and even these
dependenies should be parallely installed, without deleting old.
Finally , both these versions contain shared libraries and these shared
lib's do not have version numbers in their name.
#rpm -ivh secured_soft_2.0.0.rpm
error: Failed dependencies:
init-class >= 1.4.17.1-1 is needed by secured_soft_2.0.0.rpm
init-connection-interface >= 2.0.11.0 is needed by secured_soft_2.0.0.rpm
init-logger >= 2.0.11.0 is needed by secured_soft_2.0.0.rpm
init-security >= 2.0.11.0 is needed by secured_soft_2.0.0.rpm
As i have specified we already have secured_soft_1.3.0.rpm installed and
above dependencies are also available but of different version.
So we need the to install above dependencies and also need the old version's
of dependencies for the old rpm's to work
ex : secured_soft_2.0.0.rpm has libArt.so libSec.so and so on
which are copied to /usr/lib
Similarly secured_soft_1.3.0.rpm also has libArt.so libSec.so and so on
which are already available in /usr/lib
I tried to rename the so's but still iam not able to install.
Is it possible to change the location for these so's and get the things done
Is there any way we can do it.
At the moment, iam stuck here and would need advice on this
Appreciate any help on this.
Since the programs use the same filenames, and you need to put them on the same machine, you might be able to move the older version to another directory tree and make it work there.
You can do this with many applications which do not have compiled-in pathnames.
For instance,
install the older version (this sounds like where you are starting from)
use rpm -ql for each of the packages containing unversioned executables, libraries and associated files.
use tar to capture an archive of those files, relative to /usr (but omitting directories not owned by the packages).
create a new directory, e.g., /usr/local/myapp and untar the older version there.
update configuration files in the new location as needed
For applications such as this, I would run in a script that updates PATH (and perhaps sets LD_LIBRARY_PATH) to force the program to run from the new location. You can verify if this works using tools such as strace and lsof, i.e., by looking for the files that the program opens.
Once you have the older version working properly in the new location, you can uninstall its rpms and install the new version of the application.
Caveat: If the newer package is copied from a newer version of the operating system, however, the task is likely to be beyond your ability, whether or not you choose the alternative approach of recompiling the newer packages to fit on the existing system.
Building new/custom packages is one route to recompiling the newer version. If you have the source-RPMs for each part, that is a starting point:
extract the files from the source-RPM, e.g., using a script such as unrpm (see for example HowTo: Extract an RPM Package Files Without Installing It), and
copy those extracted files to their as-expected locations in your build-tree, e.g., $HOME/rpmbuild/SOURCES and $HOME/rpmbuild/SPECS
modify the spec-file to use the alternative location
build the new/modified package using the modified spec-file.
No, out of the box, you cannot.
I'd highly recommend looking into Docker, where you can throw each one into their own container and let them take care of all their dependency problems.

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.

Debian Package Control file Question

I am trying to create a Debian package for a Java application.
In my package there is a .jar file which is executable, a script which will run this jar file and a .so file for fmod.
I've read this tutorial.
In the control file there is a 'Depends' field which basically describes the packages that need to be installed in order to install my application. My question is, how do I find which packages are required for my application? I followed the instructions in the tutorial for one of the .so files, and got this:
$ dpkg -S libfmodex64-4.28.09.so
dpkg: *libfmodex64-4.28.09.so* not found.
Also, my application requires Java 1.5 to be installed in order for it to run. How do I specify this in my debian package?
I strongly recommend building your package from source within the Debian packaging infrastructure. Everything will be pretty much automatically taken care of if you use the Ant class in CDBS.
If you do insist on assembling a binary .deb only, equivs is much less hackish than the method described by your document.
You'll want to get the canonical name for your library:
apt-cache search libname
Take care to note the nomenclature at the end of the package. You don't want to specify a specific version in the control file, just the earliest version of the library that is suitable for your application.
You would then use canonical_libname >= major.minor , which lets the system decide if you have (or can update to) the version of the library that can support your application. If you carve this in time, i.e. specifying the full version of your current library, you'll break in the future.
For instance, if you specify libfoo-1.2.34 and future versions of Debian ship libfoo-2.3.45, your package won't install, because it thinks you have an incompatible version of libfoo.

Resources