CentOS 7 - how to install dependency using wget in an RPM spec file - centos

I'm trying to write a spec RPM file to build an RPM package.
Here is in essence my spec file:
[...]
Requires: nodejs java-1.8.0-openjdk java-1.8.0-openjdk-devel log4j
%define _rpmdir ../
%define _rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
%define _unpackaged_files_terminate_build 0
%pre
[Some script]
%post
[Some script]
%preun
[Some script]
%postun
[Some script]
%install
[...]
%files
[...]
I've managed to install the package dependencies with the preamble Requires expect one that doesn't exist as a yum package (tomcat8). I found on the internet that the way to install it on centOS is:
wget https://harbottle.gitlab.io/harbottle-main/7/x86_64/00853071-tomcat8/tomcat8-8.5.37-2.el7.harbottle.x86_64.rpm
rpm -ivh tomcat8-8.5.37-2.el7.harbottle.x86_64.rpm
But where should I put it in the spec file? I tried to put it in the %pre script, but there is a lock on rpm that prevent its use. I tried to put it in the %install part, but it didn't seem right. Can you please help me to fix this problem? Is there a way to still put it in the Requires preamble?
Thanks!

this is not the way you should manage those dependencies. You should search for a way to make this rpm available in you repositories. I see multiple options:
add the harbottle repository:yum-config-manager --add-repo https://harbottle.gitlab.io/harbottle-main/7/x86_64/. Now your yum will be able to find the tomcat8 rpm by itself
If you want to make sure the package remains available; better copy the tomcat8.rpm inside your own repository besides your other rpms.

Related

rpmbuild unable to find the custom installed package

There are plenty of perl packages missing in Centos 8 and Rocky Linux. So, I try to get the rpm spec by cpanspec and build rpm by myself. But, it seems like that rpmbuild could not find the rpm I built.
This is the script for me to build rpm.
cd /root/rpmbuild
cpanspec --packer 'Example <example#example.com>' <Perl-Package-Name>
mkdir SOURCES
cp <Perl-Package-Name>.tar.gz SOURCES
rpmbuild -ba perl-<Package-Name>.spec
Let's say we have two package A and B. A is needed by B.
I try to build both of the packages through the script above. I build A first, switch into /root/rpmbuild/RPMS/noarch and install A.rpm. Then, I try to build package B.
I got
error: Failed build dependencies:
perl(A) is needed by perl-<B>
I try to check the existence of package A.
yum list installed | grep A
and
perldoc -l A
Both of the commands show that A exists.
Did I miss something?
update 2022/06/07
I just gave up and commented the BuildRequires: A in B package. This is not a good approach but it works.

Download all dependencies recursively from a rpm file

I know that I can retrieve all dependencies recursively using yumdownloader --downloadonly. But is there a way that I can do it by passing the an rpm file instead of the package name? like yum install ./google-chrome-stable_current_x86_64.rpm --downloadonly --downloaddir=xx with some option to download dependencies of chrome's dependencies.
Why dont you pull the NEVRA from the RPM file and pass it to yumdownloader
yumdownloader --resolve $(rpm -qp ./<RPMPACKAGE>.rpm --queryformat="%{nevra}")

yum local install to install a package with its dependency

I have downloaded a package with it's dependency and want to install a package with dependency. Even though i have download in local folder it's checking for online.
sudo yum -y --disablerepo=* localinstall autoconf-2.69-11.el7.noarch.rpm
I am trying above command but failed to load it's dependency that is there in same folder.
Thanks,
Hare
Inside the local directory where you have all the downloaded RPMs, do this:
sudo yum --disablerepo=* localinstall *.rpm
OR
sudo yum --disablerepo=* localinstall foo.rpm bar.rpm baz.rpm
Since you have downloaded all the dependencies to a single directory, you can also use rpm to install those:
sudo rpm -Uvvh *.rpm --test
--test does a dry-run. Remove it to install on disk.
Even if the solution provide by iamauser is very great (and I am using it all the time), I wish to give you an other way to do it.
It exists yum-downloader command which doing basically the same thing for you.
# yumdownloader <package> --resolve
You just have to download it first :
# yum install yum-utils
Overall, I suggest you to read this article from Red Hat company site's which details everything about those two methods :
https://access.redhat.com/solutions/10154

How do I set up my Dockerfile to use cpanm to install a specific version of a Perl module?

Within my Dockerfile, I am setting up the Perl modules that will be installed when run, like so:
RUN ["cpanm", "Carp", "Carp::Heavy", "Class::Data::Inheritable"]
However, for one module, I need a specific version of a module, not the latest one. How can I specify that version in the above line?
I've been searching online for hours, and haven't turned up anything useful yet.
Instead of specifying a module name, specify a URL. Eg, instead of Class::Data::Inheritable, use https://cpan.metacpan.org/authors/id/T/TM/TMTM/Class-Data-Inheritable-0.06.tar.gz
You can find the applicable URL by going to the module page on metacpan, selecting the version you want, and copying the download link.
PS: You might want to also set PERL_CPANM_OPT=--from https://cpan.metacpan.org/ in the environment so cpanm only downloads using HTTPS.
For anyone who's searching for this same answer in the future, another option can be found here in the documentation for cpanm:
cpanm Plack#0.9990
If you have a long list of modules, consider feeding a cpanfile into cpanm rather than listing them all in the Dockerfile.
The easiest way to specify a particular version number for a module in a cpanfile is like this:
requires 'Text::ParseWords', '==3.1';
The syntax for requesting the latest version of a module is this:
requires 'Text::ParseWords';
Requesting a minimum version: (note the lack of '==')
requires 'Text::ParseWords', '3.1';
The syntax for requesting specific versions in other ways is fairly well-documented here.
Another great write-up of the use of cpanm and a cpanfile can be found
in Installation of cpan modules by cpanm and cpanfile.
To have CPAN install a specific version of a module, you need to provide the full module distribution filename including the author. For example to install the module Set::Object version 1.28, at the command line type:
cpan SAMV/Set-Object-1.28.tar.gz
Same thing apply with Docker, just add
RUN cpan SAMV/Set-Object-1.28.tar.gz
To specify target module version you can use
cpanm MIYAGAWA/Plack-0.99_05.tar.gz # full distribution path
cpanm http://example.org/LDS/CGI.pm-3.20.tar.gz # install from URL
cpanm ~/dists/MyCompany-Enterprise-1.00.tar.gz # install from a local file
See official documentation: https://metacpan.org/dist/App-cpanminus/view/bin/cpanm
But better, to my mind, would be to use cpanfile. See --cpanfile option https://metacpan.org/dist/App-cpanminus/view/bin/cpanm#-cpanfile and format of this file https://metacpan.org/pod/cpanfile
But if you have many modules (like me), I recommend to use cpm. It installs modules in parallel very fast. Also with help of docker we could cache builds, thus rebuilds will takes seconds. Here is my Dockerfile:
## Modules
WORKDIR ${APP_ROOT}
# install modules outside of WORKDIR, so it will not interfere when we do COPY . .
RUN mkdir -p ../modules
RUN ln -s ../modules local
RUN cpanm -n -L ./local App::cpm Carton::Snapshot && rm -rf /root/.cpanm
COPY cpanfile ./
COPY cpanfile.snapshot ./
RUN \
--mount=type=cache,target=/root/.perl-cpm \
cpm install -w 16 --no-test -L ./local \
--with-develop
# regenerate cpanfile.snapshot
# https://github.com/miyagawa/Carmel#cpm
# cpm doesn't have the ability to manage cpanfile.snapshot file on its own.
RUN carton install
# You can copy snapshot from container by running:
# docker cp <container_name>:${APP_ROOT}/cpanfile.snapshot.latest ./cpanfile.snapshot

How do I find which rpm package supplies a file I'm looking for?

As an example, I am looking for a mod_files.sh file which presumably would come with the php-devel package. I guessed that yum would install the mod_files.sh file with the php-devel x86_64 5.1.6-23.2.el5_3 package, but the file appears to not to be installed on my filesystem.
How do I find out which package installs a specific file? I'm looking for where I have not necessarily already locally downloaded the package which may include the file that I'm looking for.
I'm using CentOS 5.
This is an old question, but the current answers are incorrect :)
Use yum whatprovides, with the absolute path to the file you want (which may be wildcarded). For example:
yum whatprovides '*bin/grep'
Returns
grep-2.5.1-55.el5.x86_64 : The GNU versions of grep pattern matching utilities.
Repo : base
Matched from:
Filename : /bin/grep
You may prefer the output and speed of the repoquery tool, available in the yum-utils package.
sudo yum install yum-utils
repoquery --whatprovides '*bin/grep'
grep-0:2.5.1-55.el5.x86_64
grep-0:2.5.1-55.el5.x86_64
repoquery can do other queries such as listing package contents, dependencies, reverse-dependencies, etc.
To know the package owning (or providing) an already installed file:
rpm -qf myfilename
The most popular answer is incomplete:
Since this search will generally be performed only for files from installed packages, yum whatprovides is made blisteringly fast by disabling all external repos (the implicit "installed" repo can't be disabled).
yum --disablerepo=* whatprovides <file>
You go to http://www.rpmfind.net and search for the file.
You'll get results for a lot of different distros and versions, but quite likely Fedora and/or CentOS will pop up too and you'll know the package name to install with yum
Well finding the package when you are connected to internet (repository) is easy however when you only have access to RPM packages inside Redhat or Centos DVD (this happens frequently to me when I have to recover a server and I need an application) I recommend using the commands below which is completely independent of internet and repositories. (supposably you have lots of uninstalled packages in a DVD).
Let's say you have mounted Package folder in ~/cent_os_dvd and you are looking for a package that provides "semanage" then you can run:
for file in `find ~/cent_os_dvd/ -iname '*.rpm'`; do rpm -qlp $file |grep '.*bin/semanage'; if [ $? -eq 0 ]; then echo "is in";echo $file ; fi; done
Using only the rpm utility, this should work in any OS that has rpm:
rpm -q --whatprovides [file name]
Ref. https://www.thegeekdiary.com/how-to-find-which-rpm-package-provides-a-specific-file-or-library-in-rhel-centos/
You can do this alike here but with your package. In my case, it was lsb_release
Run: yum whatprovides lsb_release
Response:
redhat-lsb-core-4.1-24.el7.i686 : LSB Core module support
Repo : rhel-7-server-rpms
Matched from:
Filename : /usr/bin/lsb_release
redhat-lsb-core-4.1-24.el7.x86_64 : LSB Core module support
Repo : rhel-7-server-rpms
Matched from:
Filename : /usr/bin/lsb_release
redhat-lsb-core-4.1-27.el7.i686 : LSB Core module support
Repo : rhel-7-server-rpms
Matched from:
Filename : /usr/bin/lsb_release
redhat-lsb-core-4.1-27.el7.x86_64 : LSB Core module support
Repo : rhel-7-server-rpms
Matched from:
Filename : /usr/bin/lsb_release`
Run to install: yum install redhat-lsb-core
The package name SHOULD be without number and system type so yum packager can choose what is best for him.