Manipulate your first DEB Package
All Debian and Ubuntu OpenVZ / KVM appliances and all OpenVZ templates made with the Debian Appliance Builder use debian packages with the .deb extension. This article describes what they are, how they can be altered without having to recompile them and understand how they work.
Mainpulate a .deb package
A deb is just a common archive in an .ar format, camouflaged with another name. So, right clicking on the deb file and choosing to open it with a common compressed files manager (such as file roller in gnome and OpenGEU) will work and show you the contents of the file. Now, you can modify an already existent deb file or create one from scratch. Should you prefer the second option, don't be scared, it really is a simple task.
deb files contain two main files, viz.,:
Hence, to manipulate an existing deb, open it with an archive manager and extract those files wherever you wish.
Now, create a new dir with the name of the application being created. In reality, the name of this dir means nothing but you may still want the name to have a meaning, just for convenience. Inside this dir, create a subdir called debian. Now, enter the debian dir and create another sub-dir called DEBIAN. All of this work is case sensitive so use the right letters. The dir structure at this point should look like this:
application_name => debian => DEBIAN
Open the file control.tar.gz
Inside this file, we find some other files, Extract them into the DEBIAN dir as they are.
Open the file data.tar.gz and extract its contents into the debian dir as they are, with any contained folder and subfolder. In other words, retain the directory structure of the compressed archive unaltered.
We have now recreated the directory structure of the original deb file. Enter the DEBIAN dir, and find a file called control.
This is the main brain of the deb. It contains all of the informations regarding this package. Without this file, the entire creation of a deb package has no meaning at all. A control file looks like this (quoting the contents of the opengeu-artwork-usplash control file as an example):
Package: opengeu-artwork-usplash Version: 3.01 Section: x11 Priority: optional Architecture: all Depends: libc6 (>= 2.5-0ubuntu1), initramfs-tools (>= 0.40ubuntu30), usplash (>= 0.4-21) Installed-Size: 1010 Maintainer: darkmaster <firstname.lastname@example.org> Conflicts: geubuntu-artwork-usplash Replaces: geubuntu-artwork-usplash Description: OpenGEU usplash image The startup screen shown on OpenGEU boot, by default it is the Sunshine version, you can later change it to the Moonlight edition too using usplash-switcher.
Analysis of the important parts this file show:
- Package: you have to put here the name of the package, never use spaces, never use a version number. It is case sensitive, be warned!
- Version: of course, the version number / code. It can also be, for example, opengeu-3.0.2 or any other weird code, as long as the last part is a number. Always remember that chaning the version to a higher number triggers the system to consider that new file as an update of course!
- Priority: optional, high, low, only system or security updated should have something like high in the priority.
- Architecture: i386, amd64, all. - Specify here what platform this package is compiled for. If it is only an artowork or a metapackage, you can put all in the Architecture field.
- Depends: a list of all the packages this package depends on. A metapackage, for example, can include almost nothing but depend on a lot of other packages so that installing this metapackage automatically installs a lot of other packages! That's what happens with opengeu-desktop for example!
- Conflicts: if you know that your package can't work if another package is installed, well, you should then list that package here.
- Replaces: Here you specify that this file replaces another package, maybe an old one. Useful if you change the name of the package into something else and whant the new package to be installed INSTEAD of the package to be replaced.
- Description: put only a very short description in the first line, then enter a longer description on the second line, like it is shown in the example above.
That is almost eveything about the control file. But this is not the only file you can find in the DEBIAN dir. For example, you could find a prerm and / or postinst file. They are scripts.
The postinst script will execute any action contained in it, right after the installation of the package. Here is an example of the contents of the postinst file contained in the opengeu-artwork-usplash package:
#!/bin/sh set -e case "$1" in configure) update-alternatives -remove usplash-artwork.so /usr/lib/usplash/usplash-theme-opengeu-sunshine.so update-alternatives -install /usr/lib/usplash/usplash-artwork.so usplash-artwork.so /usr/lib/usplash/usplash-theme-opengeu-sunshine.so 55 update-alternatives -install /usr/lib/usplash/usplash-artwork.so usplash-artwork.so /usr/lib/usplash/usplash-theme-opengeu-moonlight.so 55 update-alternatives -set usplash-artwork.so /usr/lib/usplash/usplash-theme-opengeu-sunshine.so update-initramfs -u ;; esac
So, right after the installation of the package, those commands are executed, very simply!
The prerm script instead is executed right before the package is removed! Here are the contents of the prerm file contained in the opengeu-artwork-usplash package:
#! /bin/sh set -e case "$1" in remove) update-alternatives -remove usplash-artwork.so /usr/lib/usplash/usplash-theme-opengeu-sunshine.so update-initramfs -u ;; esac
If you are creating a new deb file from scratch, remember to right click on those files, change the permission tag to make them executable, or they won't work.
Keeping the folders clean
Every time you create or modify a new text / script file, some temporary files are created and we don't want them to go into the deb. So enable your file browser to see hidden files and remove the temporary files before compiling the deb!
Every file that has to be installed into the system goes into the debian folder. Let us say that this is like the heart of our deb package. Consider this folder as the "/" mount point of your system, the main system folder or whatever you call it. Basically, you have to recreate into the debian folder the structure of the folders and files you wish to be installed into the system. So, let us say that our package has to install the usplash-theme-opengeu-moonlight.so file into the /usr/lib/usplash/ folder, then, you'll have to create or edit the files and folders status to look like this:
Installing the deb file will cause the usplash-theme-opengeu-moonlight.so to be copied in the right place :)
You can of course add multiple files into the same package with multiple folder structures but remember that if you create a package containing the same files as another already installed package, and if this new package is not an upgrade to the other one, the installation will fail. apt-get will give you an error saying that the file is already contained in another package and therefore it cannot be overwritten.
Creating the real package
Now that we created the contents and the controls of the package, let us build it so that a deb file is created for us automatically. Move to the main folder of the application, in our example, it should be the package-name folder. Open a terminal here and run:
dpkg-deb -build debian
You will be asked to install some extra packages the first time you use this command, just do it and then run the command again. A debian.deb file will be created in the dir you are in, just rename it to the same name you mentioned in the control file, followed by the file version. For example: opengeu-artwork-usplash-3.0.deb and remember never to use spaces!
The file is now ready to be installed. In this way and knowing the files structure you can create any new deb from scratch or edit an existent one, no difference. Just use any control file as a template. Remember to keep your folder structure clean and that it is case sensitive and you'll soon create nice deb packages :D
Adding Checksum Hash into control file
The problem is that when you create a deb file and you make a control file for that deb file where you put all your package information, then you run dpkg-scanpackages which will create a PACKAGES file for your repo. Once you do this dpkg-scanpackages checks each and every deb file and it adds a CHECKSUM HASH into the packages file.
So for example lets say your CONTROL file looks like this when you created your deb file.
Package: com.myhost.myapp Version: 1.0 Priority: Standard Section: MyHost Packages Maintainer: MyHost <email@example.com> Architecture: iphoneos-arm Description: A pretty cool app Name: MyApp Homepage: http://www.myhost.com/
Well once you run dpkg-scanpackages it will then add checksum and size values to your package's CONTROL file like this
Package: com.myhost.myapp Version: 1.0 Priority: Standard Section: MyHost Packages Maintainer: MyHost <firstname.lastname@example.org> Architecture: iphoneos-arm Filename: ./deb/MyApp_v1.0.deb Size: 83820 MD5sum: 8a89bd4caeeef7601d5c5f27732f23e0 Description: A pretty cool app Name: MyApp Homepage: http://www.myhost.com/
So ANYTIME you modify a deb file or a you add or remove a deb file from your repo you HAVE to RE-RUN dpkg-scanpackages so that it can update your package's CONTROL file.