Backup installed RPM packages with tar - linux

I would like to have a back-up of all RPMs installed in the system that have the keyword kernel.
So far, this is what I have:
RPMS=$(rpm -qa | grep kernel-firmware)
echo "$RPMS" | xargs -I '{}' rpm -ql '{}' | xargs tar cfz "$RPMS".tgz
This is for just one package, which works well. When I grep for kernel, things do not work as expected.
I wish to have each archive with the original package's name.
EDIT
I haven't been clear enough. I'm trying to back-up packages which are already installed. I do not have the RPM src files nor the original packages. I wish to do this to be able to rollback some old machines after kernel updates, or just simply be able to move the packages on another machine.
I know this is not the proper way to do it, and once they are extracted like this, they are no longer packages, but simple tarballs. However, this should suffice for what I wish to accomplish.
As can been seen from the above commands, I'm using rpm -qa | grep kernel to query the RPM DB for all of the packages which have kernel in their name. I then wish to use rpm -ql pacakge-name to to list all of the files on the system and pass them to tar to be able to easily move them to another machine.

Related

Removing paths from .so files so that RPM check-buildroot succeeds

I am packaging some Python libraries as RPMs. Some of the libraries are only available as source distributions (no wheels).
In my RPM spec I do:
pip install --root=%{buildroot} --prefix=/x/y tornado
When rpmbuild finishes up it runs check-buildroot, and the build fails with errors like:
Binary file /a/b/c/BUILDROOT/my-rpm-1.0.0-1.el7.x86_64/x/y/lib64/python2.7/site-packages/tornado/speedups.so matches
I see the %{buildroot} path listed if I run strings tornado.so | grep BUILDROOT.
How can I sanitize the .so files? Or more generally, how can I make check-buildroot pass?
I figured out how to remove the paths from the SO files.
I determined that the paths were embedded debug information using this command:
readelf --debug-dump=line speedups.so | less
The strip command can remove debug information from SO files, so I added this to my RPM spec:
BuildRequires: binutils
set +e
find "%{buildroot}{%_prefix}/lib64/python2.7/site-packages" -type f -name "*.so" | while read so_file
do
strip --strip-debug "$so_file"
done
set -e
Note: strip segfaults on some SO files, and it's not clear why. I disabled immediate exits with set +e so that the build ignores them.

How find file in RPM file

I was looking for a file with a gpg extension, and when I do grep gpg */*, it looks like it's in the rpm file. I'm trying to locate it, but I'm not finding it.
I tried rpm -qpl Directory/filename.rpm, but it's not listing the gpg file. It must be in a subdirectory so it's not turning up.
Does anyone know a good way to get it to list the subdirs out in the rpm, so I can find the gpg file?
you can list all files in a rpm with:
rpm -qlp mypackage.rpm
If you need to extract the rpm:
rpm2cpio mypackage.rpm | cpio -idv

Moving .ghc and .cabal to a different user

How can I move the GHC and cabal installed packages to a different user? I've copied the directories but I'm getting error messages like:
ConfigParser.hs:15:8:
Could not find module `Data.ByteString.Char8'
There are files missing in the `bytestring-0.10.2.0' package,
try running 'ghc-pkg check'.
Use -v to see a list of the files searched for.
ghc-pkg check shows that any file for any package is missing. How can I resolve this?
Note: This question intentionally does not show research effort, because it was answered Q&A-style.
First, you obviously need to copy .ghc and .cabal. These contain the binary files and configurations.
For simplicity, we will assume moving from user foo to user bar. Note that moving between architectures is not possible, as the binaries produced by GHC are not platform-independent.
After copying the aforementioned directories, there are paths like /home/foo remaining in different locations. We will use sed to replace those (run this as bar):
sed -i -e "s/foo/bar/g" ~/.cabal/config
sed -i -e "s/foo/bar/g" ~/.ghc/*-*/package.conf.d/*.conf
However, the file ~/.ghc/*-*/package.conf.d/package.cache still contains file references containing the username. We can't simply use sed to replace, however, because it's a binary file and it might destroy the package cache.
You can use ghc-pkg recache --user to re-cache all packages.
After performing these steps, you should be able to use the cabal packages as expected.

Retrieving current architecture for RPM

I'm automating RPM package building with rpmbuild. The files end up in the architecture subdirectory under RPMS.
Question - how do I retrieve, from a shell script, the architecture name of the host that RPM is using? It's not the same as arch command.
It looks like
rpm --eval '%{_arch}'
does the trick:
$ rpm --eval '%{_arch}'
x86_64
$ rpm --target 'SPARC64' --eval '%{_arch}'
sparc64
There's /usr/lib/rpm/rpmrc that translates known OS-level architecture names into canonical RPM architecture names. The following shell script does the job for me:
ARCH=`arch`
# OS-level architecture name, like 'i686'
ARCH=`cat /usr/lib/rpm/rpmrc | grep "buildarchtranslate: $ARCH" | cut -c21-`
# returns the translate line as "arch-from: arch-to"
ARCH=${ARCH/#*: /}
# strips the prefix up to colon and following space, returns arch-to.
# Assumes just one space after colon. If not, more regex magic is needed.
You're doing it wrong. Redefine %_build_name_fmt in ~/.rpmmacros.

What's the best way to move a directory into place in a Makefile install?

I'm currently using the usual technique in my Makefile to install individual files:
install:
install -D executable ${BIN_DIR}
But I just ran across a situation where I need to move a whole directory and all files underneath it into place.
Is cp -r the best way or is there a more linux-y/unix-y way to do this?
Yeah, it's hard to think of a more unix-ish way that cp -r, although the -r is a relatively late addition to cp. I can tell you the way we used to do it, and that works neatly across filesystems and such:
Let src be the source directory you want to move, and /path/to/target be an absolute path to the target. Then you can use:
$ tar cf - src | (cd /path/to/target; tar xf -)
My version of install(1) (Debian) has:
-d, --directory
treat all arguments as directory names; create all components of the specified directories
-t, --target-directory=DIRECTORY
copy all SOURCE arguments into DIRECTORY
So if you wanted to use install(1) consistently throughout your Makefile you could do:
install -d destdir
install srcdir/* -t destdir
-t isn't recursive however - if srcdir contains directories, then they won't get copied.
Linking is another viable alternative. That would allow you to keep multiple directories (representing different versions) accessible.

Resources