How to "repackage" a RPM file for example cpio2rpm without installing the RPM? - linux

I'm able to extract files from a RPM file, but how do I "rebuild" it, for example cpio2rpm?
I have extracted RPM file using following command.
rpm2cpio theFileName.rpm | cpio –idmv
I have to modify the few web application files like *.php, *.html or .js. These files don’t require any source recompilation. So I would like to replaces or change these files with modification without rebuilding rpm. Since, I need to do this for multiple platforms like Redhat Linux and SUSE, and multiple architecture like 32 and 64 bit OS.
I am expecting to do these changes on only on system and without rebuild rpm and there would not be have target system architecture dependency (like i386, 64).
I am not looking like command rpmbuild –rebuild the.src.rpm since, I don’t have source. I need to be rebuild binary .RPM file(not source .rpm)
I want to do this without source and platform or architecture independent and without using spec file if possible.
Any buddy, could you please suggest any solution or any free tools.
Thank you to all whoever spends time to read and reply to my thread.

You can use rpmrebuild to modify an actual rpm file (it doesn't need to be installed).
Most of the examples for this use complicated inline edit commands to modify known files in particular ways, but you can use a normal editor. I used this to fix a shell script in an rpm file that I didn't have the source for. Call the command as
rpmrebuild -ep theFileName.rpm
This puts you in an editor with the spec file for the RPM. The name of the file will be something like ~/.tmp/rpmrebuild.12839/work/spec.2. If you look in, in this example, ~/.tmp/rpmrebuild.12839/work, you will find all of the files used to make the RPM (in my case, the file was in root/usr/sbin within that directory). So, go to another window, cd to that directory, and edit any files you need to change.
When you have finished editing files, go back to the edit window with the spec file, make any changes you need to that file (I didn't have any, since I wasn't adding or deleting files), save the file, and say "y" to the "Do you want to continue" question. It will then build a new RPM file, and tell you where it has put it (in my case, in ~/rpmbuild/RPMS/x86_64/)

You can repackage an installed RPM (including modified files) using rpmrebuild. http://rpmrebuild.sourceforge.net/
Obviously your binaries (if any) would have to be platform/architecture independent to work on all the OS flavors you're hoping for, but it sounds like if they're just web files that shouldn't be a problem.

Principially you can pack everything you want into a RPM file. Just treat what you have as "source" and write a SPEC file which puts the data where the compiled binaries would normally go.
Concerning RPM, I consider "source" "what I have" and "binary" "what I need to run". Not very exact terminology, but it helps working with RPMs.
Your spec file looks like any other spec file, what concerns the parameters etc. But the code part is different:
[...]
%prep
# Here you either have nothing to do or you already unpack the cpio and possibly modify it.
# %build can be omitted
%install
[ "${buildroot}" != "/" ] && [ -d ${buildroot} ] && rm -rf ${buildroot};
# Here you can either unpack the cpio or copy the data unpacked in %prep.
# Be careful to put it into %{buildroot} or $RPM_BUILD_ROOT.

Related

Build debian package without .orig file

I've created packages previously by using a Makefile, the command "dh_make --createorig", then adjusting files in the debian folder generated and finally using the debuild command to generate the .deb. That workflow is simple and works for me, but I was told to adjust it a little in a way that you could build the project from the sources without requiring the orig files and I'm unsure how to do it, but according to this (https://askubuntu.com/questions/17508/how-to-have-debian-packaging-generate-two-packages-given-an-upstream-source-arch) and this structure (http://bazaar.launchpad.net/~andrewsomething/imagination/debian/files) there must be a way. In my case I would have a folder with the sources and all of that and then a debian folder (generated with dh_make) but I'm unsure on how to avoid the debuild command to ask for the .orig files or if I should be using some other command for this.
Sorry for the superlong question, I think I provided all the relevant information, but I can clarify if anything is fuzzy.
The difference is in the version number in the file debian/changelog.
If you use 1.2.3-1 it implied Debian build 1 of an upstream package 1.2.3 --- for which the build programs (dpkg-buildpackage and whichever wrappers on top) --- assume an .orig.tar.gz to exists.
But if you use 1.2.3 it will consider the package 'Debian native' and the archive is just a .tar.gz and not an .orig.tar.gz.
Now the choice should not be driven by your convenience alone. If this has an upstream source, use the first scheme. If not, the second can be fine. In the packages I maintain I have both but way more of the former.
If you want to create a Debian directory directly in the source package (ie you're packaging your own work, rather than from an upstream release) you could use the --native option to dh_make
I think the question was asked differently, it was somewhat clear that the project was upstream and it's probably not a good reason to change its format to native.
Currently I package some upstream python project, this exact same question came to my mind. Why isn't there any dh_* hook to overwrite in order to generate this origin tarball on the fly so you do not get bothered by:
This package has a Debian revision number but there does not seem to be
an appropriate original tar file or .orig directory in the parent directory;
for a start, I added a makefile to the project:
# Makefile
VERSION:=$(shell dpkg-parsechangelog -S Version | sed -rne 's,([^-\+]+)+(\+dfsg)*.*,\1,p'i)
UPSTREAM_PACKAGE:=click_${VERSION}.orig.tar.gz
dpkg:
tar cafv ../${UPSTREAM_PACKAGE} . --exclude debian --exclude .git
debuild -uc -us
clean:
rm -f ../${UPSTREAM_PACKAGE}
debuild clean
so a simple make clean dpkg was all it needed to build the package.
Now I think the question remains if someone has some bright idea how to insert the tar operation within the debian/rules so I could just call debuild -uc -us and it magically creates the orig tarball I would be awsome :)

Can I avoid exporting LD_LIBRARY_PATH by hardcoding library paths in the executable?

I'm zipping a pre-built (no source/object files) binary application for distribution. The binary application requires a couple of libraries not included by default. The only way I seem to be able to get the application to start on the end-user is by including a run.sh that sets the library path to the current directory:
export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH
./MyApp.out
However, I'd really like to allow the user to just unzip the zip and doubleclick MyApp.out (without the shell script). Can I edit MyApp.out to search the current directory for the library? I've done something similar on OSX using install_name_tool, but that tool isn't available here.
You want to set the rpath. See this answer. So link using
gcc yourobjects*.o -L/some/lib/dir/ -lsome -Wl,-rpath,.
But you might want even to use -Wl,-rpath,$PWD or perhaps -Wl,-rpath,'$ORIGIN'. See this.
You could also (and this should work for a pre-built executable) configure your /etc/ld.so.conf by adding a line there with an absolute path (of the directory containing the lib), then running ldconfig -v ... See ldconfig(8)
I would suggest adding /usr/local/lib into /etc/ld.so.conf and making a symlink from /usr/local/lib/libfoo.so to e.g. $HOME/libfoo.so etc... (then run ldconfig ...). I don't think adding a user specific directory to /etc/ld.so.conf is reasonable ...
PS. What you really want is to package your application (e.g. as a *.deb package for Debian or Ubuntu, or an *.rpm for Fedora or Redhat). Package management systems handle dependencies!

steps needed to create binary package for distribution in linux

I am little confused on how to create a complete binary package using rpmbuild from a project I just created (already compiled binary).
my current project contain similar format as this user (Packaging proprietary software for Linux)
Where I have
foo (binary)
data
libs
foo.sh
libs will contain all the shared libraries the project requires, and foo.sh is a script that sets LD_LIBRARY_PATH to include libs. Therefore, the user will execute foo.sh and the program should start.
I am looking at the tutorial from this site (rpm tutorial)
I understand to create a rpm I create a build area use rpmdev-setuptree
I can create a spec file use cd ~/rpmbuild/SPECS; rpmdev-newspec foo and if I got a good SOURCES folder I can build it with rpmbuild -ba foo.spec
But I have no idea how to setup the SOURCES directory. The tutorial stated (here) that I should create a tarball and place all my source file in it and put in SOURCE directory. What would be the source file in my case?
You are trying to create a RPM from binary files you have already? In that case, you can just leave the whole building stuff out of the SPEC file, and you need a SOURCE directory to keep the bundles you've got, the %prep step described below will take them from here.
In a binary package I built a while back from zip files, I did:
Heading, with name, version, description written by me/cribbed from the originals
Sources: The original places to download the Linux packages, official documentation, ...
%prep: Just unpack the different pieces, delete some redundant files, ...
%build: Nothing to do
%install: Create the relevant directories under $RPM_BUILD_ROOT by hand, copy files there by install, copy/create configuration files, ...
%clean: Blow away $RPM_BUILD_ROOT
%files: An exhaustive list of all files installed.
This required a few iterations to get right. Afterwards I followed the upstream package by rebuilding my RPM (conveniently I had everything packaged up in a SRPM, where the Source part was kind of a misnomer...)

Keep files generated by RPM after rerunning rpm -e

Is it possible to keep RPM content in the filesystem after the uninstallation ?
Basically, I don't want to erase the files generated by the RPM when someone runs rpm -e, but still remove the package from the list of installed RPMs. I want to uninstall my application manually from the server and I cannot find a way to do so.
Thanks in advance.
Specfile creation
From this perspective as a package creator, you can flag files as configurations. John Warbrick at Cambridge Uni has a good rundown of the different file markings you can use in an RPM specfile and how they behave during upgrade.
Files marked %config, if changed, are:
left behind on uninstall but renamed with an .rpmsave extension
untouched on update or reinstall, but the payload copy is installed with an .rpmnew extension
Warbrick does not deal with straight package removal: if a file marked %config is unchanged, erasing the package will remove the file. (Bear in mind that, according to RPM scriptlet ordering, RPM update or reinstall begins with erasing the old package, before the new files are lain down. I.e., the old unchanged config is replaced with the new config.)
It would be an abuse of RPM file classification to mark something a %config that is not really a config. This is important because sysadmins need to be able to trust the package payload. Plus, you probably don't want such a file to be renamed with an extension.
Your best hope then is to create the file during RPM %post. Files copied to the filesystem in %install are checked against the %files list and stored in the RPM database, but files created in %post are not. Again, this an abuse of the RPM spec file format, but if you mention it in the %description and any other documentation, but especially if it's logically expected behavior in the context of your package, you'll maybe get some sympathy.
Existing packages
For sysadmins wanting to remove a package without removing its payload, you use rpm --justdb. First, check the file list:
# rpm -ql $PACKAGE | tee $PACKAGE.payload
[rpm returns list of files, tee saves it in the file $PACKAGE.payload]
# rpm -e --justdb $PACKAGE
(At this stage, you may get a complaint about deps, so repeat with --nodeps if you must.)
And finally, check that the package is gone, but payload is still there:
# rpm -q $PACKAGE
package $PACKAGE is not installed
# ls -l $(<$PACKAGE.payload)
[ls queries list of files saved in $PACKAGE.payload]
(Or for a more reliable ls if filenames contain spaces, which would be unconscionable in RPM.)
# cat $PACKAGE.payload|xargs -d '\n' ls -l
Other observations
Note that for a package created using the method outlined at the top of my answer, attempting to list the files it owns with rpm -ql $PACKAGE will not show those persistent files. Another consequence of throwing down files during %post is that another package which "owns" those files could overwrite them unexpectedly - they're not listed in the RPM database, so they're not protected.
The two methods I've outlined break Best Practices for both RPM package creation and sysadmin. Please be very careful how you use this dangerous "little bit of knowledge". Maybe there's something else you could do to create the desired situation.
(Finally, I know this is a question from four year back. It wasn't answered. It needed answering. Cheers.)
rpm -e --repackage package_name will drop a re-installable copy in /var/spool/repackage. You can extract from that rpm using rpm2cpio if you need those files back individually.
One of the advantages of RPMS is exactly that: you can uninstall (remove)
all the files easily.
If you want to install the files provided by an RPM manually,
simply unpack the RPM as root, with:
cd / &&
rpm2cpio *.rpm | cpio -idmv
It's not a good idea, but you can unpack RPMS like that elsewhere (e.g. under ${HOME}),
and that's very useful. You may need to adjust some environment variables though.
You don't pollute the RPM database but still use the contents of an RPM.
Of course your application may get broken by system updates,
because it is not protected by dependencies.
Anyway this is how you "install" and RPM if you are not root.
Removal is also easy (if installation path chosen suitably).

Why does my hand created deb package fails at install with "unable to create" on files?

I made a perl script that creates a deb binary package from scratch.
I created the data, control, etc.
But when I run dpkg -i on my deb package it complains that it is unable to files from data.
Example:
unable to create '.dpkg-new'(while processing ''): No such file or directory.
I have downloaded some .deb packages to look at and they do not use the preinst script to create the directory structure.
I am thinking I am doing something wrong, I consider having to create my own directories in preinst but it does not seem right... perhaps I am missing something?
Do I have to create directories where my files from data will be copied in the preinst sh, or should dpkg do it and I am doing something wrong?
I had the same problem in a Ruby script I wrote.
I was generating a list of files to pass to tar when building the data.tar.gz archive. When I ungzip and untared the archive manually it would deflate fine, but dpkg would fail.
It turns out that the list of files must also include each directory to create as well.
Note that when I created data.tar.gz I built it with nearly the same options as dpkg-deb/build.c does in the dpkg-1.15.8.11 source.
execlp(TAR, "tar", "-cf", "-", "--format=gnu", "--null", "-T", "-", "--no-recursion", NULL);
Instead I used
IO.popen("gnutar -czf - --format=gnu -T - --no-recursion", "r+")
In addition to what #Arrowmaster said, check the http://www.debian.org/doc/debian-policy/ for some detailed explanation of the files. After you build the package itself, you can check it with lintian tool to see if there is anything obvious you might have missed.
If any one looks for a solution to the problem:
"Build a deb package from an rpm spec file."
Look here http://www.deepnet.cx/debbuild/
I have made my own perl build script much simple then the mentioned one so I can easily maintain it.
Some useful knowledge gained in the process:
0. the deb is an ar archive that contains 3 files, the order of the files is important.
1. the scripts from control.tar.gz must be made executable.
2. it is good to have a preinstall script to make directories if dirs do not exist.
3. sometimes dpkg decides to unzip your zips (this happened if the zip was the only file in the data.tar.gz) so check for that in an postinstall script.
4. when you tar.gz some files be sure to chmod to the dir that contains the directory structure for your tar.
You should not attempt to manually create a .deb binary package by hand. The Debian New Maintainers' Guide covers how to get started creating a Debian package using the correct tools.
Your hand created package may look correct to you but because it is not installing it is obviously flawed in either a minor way that you have not noticed or in a more serious way that is not visible to you (for example most people don't realize a .deb is actually an ar archive).
There are lots of reasons for this. You really need to run:
dpkg -i -D1110 mydeb.deb
And post the result to have any hope of someone being able to solve the problem.

Resources