Collect all rpm dependencies to deploy a project - deployment

I need to deploy a software project (packaged as an rpm) from a developer machine into a server. I'm using Fedora 23, along with the dnf package manager. I have to collect all dependencies of my rpm before I deploy to the server. The server can't be connected to the internet due to internal regulation (But I can ssh onto it). Running repository mirrors, etc. is not an option. I'm afraid I just have to collect all dependencies on the developer machine, scp (or ansible) them to the server and install them on the server.
I hoped that --installroot option in dnf could be of much help, as I could retrieve all rpms that would get installed into what dnf thinks is an empty system. This however doesn't work.
mkdir foo && sudo dnf install --installroot=$PWD/foo golang
gives an error:
Failed to synchronize cache for repo 'fedora'
Why does this fail? What are my options?
I'd like to see an elegant and robust solution. I'd prefer not to install anything on the server (I'd be most happy to do a single scp followed by one or two commands over ssh). A combination of rpm + yum/dnf magic would be great, but other solutions, including apt + deb are also of interest. I'd prefer not to use docker, and I'm strongly against running any additional infrastructure (docker registry, rpm mirror, etc.)

Here is a (ad hoc, lightly tested) script (assuming you have an already installed rpm system) to generate the list of all the rpm package names needed to install a given package (the script assumes goal="bash", edit to taste).
Feed the output names to dnf/yum to install.
#!/bin/sh
goal=bash
deps=$(rpm -q --qf '[%{REQUIRENAME}\n]' $goal | egrep -v '^(rpmlib|rtld|config|/)')
goals=
while true; do
subs=$(rpm -q --qf '%{NAME}\n' --whatprovides $deps | sort -u | tr '\n' ' ')
if [ ."$subs" = ."$goals" ]; then
echo "--- packages needed"
echo "$goals" | tr ' ' '\n'
exit 0
fi
goals=$(echo $goals $subs | tr ' ' '\n' | sort -u | tr '\n' ' ')
for sub in $subs; do
subdeps=$(rpm -q --qf '[%{REQUIRENAME}\n]' $sub | egrep -v '^(rpmlib|rtld|config|/)')
deps=$(echo $deps $subdeps | sort -u)
done
done

Related

ubuntu 16 install gstreamer but gstreamer-plugins-base-1.0.pc file is not found anywhere

(Using ubuntu 16 0n my mac pro.)
To integrate gstreamer and pocketsphinx, I need three .pc files as the offical website says:
gstreamer-1.0.pc
gstreamer-base-1.0.pc
gstreamer-plugins-base-1.0.pc
I start a new empty ubuntu 18.
install the gstreamer through
$ sudo apt-get install libgstreamer1.0-dev
But only two of the three important .pc files exist after the previous command.
If I cd to /usr/ and run :
sudo find . -print | grep -i 'gstreamer-plugins-base-1.0'
the terminal returns empty( not found).
At the same time,
sudo find . -print | grep -i 'gstreamer-base-1.0'
and
sudo find . -print | grep -i 'gstreamer-1.0'
will give me correct paths.
Where is the missing gstreamer-plugins-base-1.0.pc file? Thank you.
If there are only two but not three of the .pc files, the configuration of pocketsphinx will not work.
**sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev**
helped me generate the missing gstreamer-plugins-base-1.0.pc file.
Those two are needed.

Centos-updates list item with yum

Can somebody help me? i need to get the available update list on Centos without the header information, and it shoud work on evry Centos version. How can i do that?
PS: I can't use plugins just yum command combined with AWK or anything else
check if
yum check-update -q
or
yum updateinfo -q
matches your requirements. You can use these commands to extract the data you want, like yum check-update -q | cut -d ' ' -f1 to get just a list of the package names with updates.

Which yum group(s) contain a given package?

Is there a way to ask yum which group(s) contain a given package? I know how to ask what packages are in a given group, and could write a quick script to trawl over all of the groups, but it would be nice to have a simpler mechanism than that.
If you are only looking for a 'simpler mechanism' to be used by a human and don't need it in some kind of script or so, you might get by with this one:
yum groupinfo '*' | less +/sendmail-cf
Of course, replace sendmail-cf with the package name you're interested in.
You can find a group to which the specified package belongs, by using yum-list-data plugin.
$ sudo yum -y install yum-plugin-list-data
$ yum -C list-groups ftp
Loaded plugins: fastestmirror, list-data
==================== Available Packages ====================
Console internet tools 1 (100%)
list-groups done
Or, if you are not allowed to install the plugin, please save the following script and try to run it with one argument, the name of the package you try to find:
#!/bin/sh
search_name=$1
LANG=C yum grouplist -v | grep "^ " | awk -F'(' '{print $1}' | sed -e 's/^ *//' | while read line
do
if [ "${search_name}" != "" ]; then
yum groupinfo "${line}" | grep -q "^ *${search_name}$"
if [ $? -eq 0 ]; then
echo ${line}
break
fi
fi
done
I don't know about yum, but remember that it sits on top of rpm. The rpm command you're looking for is:
rpm -q --qf %{group} yourRPM
You might want to add a \n at the end, depending on that you are up to:
[root#Niflheim ~]# rpm -q --qf %{group} setarch
System Environment/Kernel[root#Niflheim ~]# rpm -q --qf "%{group}\n" setarch
System Environment/Kernel
[root#Niflheim ~]#

How to programmatically install the latest epel-release rpm, without knowing its version number?

My first post here, but I googled around and cannot find a simple way to do this.
I have a program which automatically configures new CentOS Linux servers as they come online. As part of the process it installs the latest version of epel-release rpm.
The command I use looks like this:
$ rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-7.noarch.rpm && \
yum clean all
This works great... until they change the rpm file to epel-release-6-8.noarch, then epel-release-6-9.noarch, and so on. They seem to update the version every 3-4 months. This is a problem, because if the repository updates the epel-release version number, my scripts will fail because it has no idea what that version should be.
I failed to find a link that might redirect to the latest epel rpm file, so I have no choice but to hard-code the version into my install scripts, and change it when they fail.
Anyone know a simple (non-hard-coded) way to download the latest epel rpm without knowing the version number? I'm hoping for a way that does not involve dong a curl on the repo file list and grep'ing the url, but curious what anyone might suggest?
The following script will do the trick:
cat <<EOM >/etc/yum.repos.d/epel-bootstrap.repo
[epel]
name=Bootstrap EPEL
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=epel-\$releasever&arch=\$basearch
failovermethod=priority
enabled=0
gpgcheck=0
EOM
yum --enablerepo=epel -y install epel-release
rm -f /etc/yum.repos.d/epel-bootstrap.repo
It should work on RHEL/CentOS 5 and 6. I didn't test version 4.
The EPEL project has recently implemented "latest" symlinks for the epel-release package.
https://dl.fedoraproject.org/pub/epel/epel-release-latest-5.noarch.rpm
​https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
See https://fedorahosted.org/epel/ticket/8#comment:12
Do it right from the shell:
$ EPEL_BASEURL=http://dl.fedoraproject.org/pub/epel/$(awk '/rhel/ {print $2}' /etc/rpm/macros.dist)/$(uname -p)/
$ rpm -ivh $EPEL_BASEURL$(curl -s $EPEL_BASEURL | grep epel-release | awk -F'<|>' '{print $5}')
Retrieving http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
warning: /var/tmp/rpm-tmp.zRXE1U: Header V3 RSA/SHA256 Signature, key ID 0608b895: NOKEY
Preparing... ########################################### [100%]
1:epel-release ########################################### [100%]
I've tested this on CentOS 6.4, 6.5 and 6.6 and RHEL 6.5 and 6.6, but the contents of /etc/rpm/macros.dist and the HTML code from http://dl.fedoraproject.org should be consistent on all platforms, so this should work on all platforms.
For posterity's sake, here it is with more detail:
$ EPEL_BASEURL=http://dl.fedoraproject.org/pub/epel/$(awk '/rhel/ {print $2}' /etc/rpm/macros.dist)/$(uname -p)/
# http://dl.fedoraproject.org/pub/epel/6/x86_64/
$ EPEL_RELEASE_RPM=$(curl -s $EPEL_BASEURL | grep epel-release | awk -F'<|>' '{print $5}')
# epel-release-6-8.noarch.rpm
$ EPEL_RELEASE_RPMURL=$EPEL_BASEURL$EPEL_RELEASE_RPM
# http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
$ rpm -ivh $EPEL_RELEASE_RPMURL
Retrieving http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
warning: /var/tmp/rpm-tmp.ep6xy3: Header V3 RSA/SHA256 Signature, key ID 0608b895: NOKEY
Preparing... ########################################### [100%]
1:epel-release ########################################### [100%]

Package manager command that returns 0 or 1 in Ubuntu/Debian if a package is installed or not

I'm writing a package installer script in Perl. I need a command (probably OS command) that returns a simple 0 or 1 to the caller script if a Ubuntu/Debian package is installed or not.
I've tried
dpkg -s
It always returns 0.
dpkg -L
almost works but if the user does not
apt-get --purge remove
the packages, some files are left and always returns 0
I don't want to grep text - a simple true or false is what I need.
Any ideas?
#Andy:
aptitude remove unixodbc -y
dpkg-query -W unixodbc; echo $?
unixodbc 2.2.11-21
0
aptitude install unixodbc -y
dpkg-query -W unixodbc; echo $?
unixodbc 2.2.11-21
0
Maybe not ideal, but this works:
dpkg -s "$package" | grep '^Status:' | grep -q ' installed'
Or just
dpkg -s "$package" | grep -q '^Status:.* installed'
I think this does it:
test -n "`aptitude search '?name(^packagename$)~i'`"
Won't work on virtual packages.
If you're going to use the dpkg database, I concur with the "use grep" suggestions. Weighing the possibility that the output format of the package tools changes against the complexity of the alternative solutions, it's probably better to use grep.
That said, here are some possibilities:
use dpkg --get-selections. The exit status is always zero, but the output is very simple: <package><white space><status>. This is the "requested state" (install/hold/deinstall/purge), which can differ from the actual package state, but usually won't.
use one of the utilities in the dctrl-tools or dpkg-awk packages
implement a test that directly determines whether the dependency is present, e.g., use pkg-config, or search for a program in PATH. This has the advantage that it will allow the install to continue on systems where the dependency has been built by hand and installed without the knowledge of the package manager. This also makes your install script more portable.
you may want to look in to PackageKit