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

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.

Related

debian packaging and package.rules files

I am working on changing machines from the RHEL world over to the debian/ubuntu world, and I am struggling a bit with a packaging problem. I am trying to build a package for Ubuntu 16.4.
I've got an very old pre-compiled application that can only listen through xinetd. I am creating a binary only package similar to what this person was doing: I need my Debian rules file to simply copy files to it's target. I simply need to copy pre-compiled files into directories.
I have no problem getting files in /opt and in /var/log, however I have been trying to get the dpkg to copy the needed setup file into /etc/xinetd.d/
So I have a debian/package.install file something like this:
opt/oldapplication-3.10/* opt/oldapplication-3.10/
var/log/* var/log/
etc/xinetd.d/oldapplication /etc/xinetd.d
The xinetd setup file never makes it to xinetd.d, and trying to look at the dpkg install with debug doesn't give me any hints. The file is definitely in the tarball, it just simply never gets moved.
Looking through the different dh helper applications, I can't see anything that fits, and google does nothing to illuminate the problem.
Do I have to simply move the file over in a postinst script? Is that the only way to solve this, or is there a more "debian" way to do this by creating a file in the dpkg's debian directory? Is there a more generic setup I should be doing to put files into /etc?
Thanks.

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 :)

Debian / Ubuntu package installed in root as default

Created a simple debian/ubuntu package with some library files (*.so).
Works fine except, it installs them as default in the root path "/".
Since I've recreated my Makefile to output to $DESTDIR/ instead of "the usual" directory that I provide in the Makefile, when compiling from source, how do I now set the path of where the files should be installed now? I know there are several choices when using dh_make to create the package, "s" being the default one. Still, can't seem to find anything on where to tell dpkg to put the installed files.
Secondly, a Deb Library package containing only ".so" files should still be a "Single binary" since I gather that using the Library is for development purposes? Since this is a library, I just wanna make sure that's not the cause of the files being installed in the wrong location. What I mean is .so files and header files installation?
What I've used:
dh_make -e my#email.com -f ../myfile-1.0.tar.gz
dpkg-buildpackage -rfakeroot
and some configurations set i debian/control, $DESTDIR in Makefile.
Seems that it was fairly simple, yet very confusing. This works, not sure if there is a better solution.
In my makefile I have a few variables
InstallTo = /usr/lib
install:
mkdir -p $(DESTDIR)$(InstallTo)
cp $FILE_TO_COPY $(DESTDIR)$(InstallTo)
This way it will create the directory tree inside the *.deb file. I had some trouble using /usr/local/lib instead of /usr/lib/ and rmdir complained when trying to delete it and it had no files (just directories). Not sure why, but changed it to /usr/lib instead.
Since someone voted this up, I'm guessing someone were also looking for the answer and this is my solution. Perhaps someone can provide a better one if there is one.
Just a note, $DESTDIR variable is the variable that dh_make suggest the user to use in our Makefile. It's the path to where dpkg will build the program and where it will install it so it can be included in the .deb file.

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

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.

Run time installation directory of debian package contents

I have a debian package that I built that contains a tar ball of the files, a control file, and a postinst file. Its built using dpkg-deb and it installs properly using dpkg.
The modification I would like to make is to have the installation directory of the files be determined at runtime based on an environment variable that will be set when dpkg -i is run on the deb file. I echo out the environment variable in the postinst script and I can see that its set properly.
My questions:
1) Is it possible to dynamically determine the installation directory at runtime?
2) If its possible how would I go about this? I have read about the rules file and the mypackage.install files but I don't know if either of these would allow me to accomplish this.
I could hack it by copying the files to the target location in the posinst script but I would prefer to do it the right way if possible.
Thanks in advance!
So this is what I found out about this problem over the past couple of weeks.
With prepackaged binaries you can't build a debian package with a destination directory dynamicall determined at runtime. I believe that this might be possible if installing a package that is built from source where you can set the install directory using configure. But in this case since these are embedded Ubuntu machines they don't have make so I didn't pursue such an option. I did work out a non traditional method (hack) for installing that did work. Since debian packages simply contain a tar ball relative to / simply build your package relative to a directory under /tmp. In the postinst script you can then determine where to copy the files from the archive into a permanent location.
I expected that after rebooting and the automatic deletion of the subdirectory under /tmp that dpkg might not know that the file package existed. This wasn't a problem. When I ran 'dpkg -l myapp' it showed as still installed. Updating the package using dpkg/apt-get also worked without a hitch.
What I did find is that if you attempted to remove the package using 'dpkg -r myapp' that dpkg would try and remove /tmp which wasn't good. However /tmp isn't easily removed so it never succeeded. Plus in our situation we never remove packages but instead simply upgrade them.
I eventually had to abandon the universal package due to code differences in the sources resulting in having to recompile per platform but I would have left it this way and it did work.
I tried using --instdir to change the install directory of the package and it does relocate the files but dpkg fails since the dpkg file can't be found relative to the new instdir. Using --instdir is sort of like a chroot. I also tried --admindir and --root in various combinations to see if I could use the dpkg system relative to / but install relocate the files but they didn't work. I guess rpm has a relocate option that works but not Ubuntu.
You can also write a script that runs dpkg-deb with a different environment for 6 times, generating 6 different packages. When you make a modification, you simply have to run your script, and all 6 packages gets generated and you can install them on your machines avoiding postinst hacking!
Why not install to a standard location, and simply use a postinst script to create symbolic links to the desired location? This is much cleaner, and shouldn't break anything in dpk -I.

Resources