Intermediate packaging step-by-step example

Photon

Photon is a Python3 application with multiple dependencies. This makes it a more interesting package than Instaloader as potentially more work is involved.

Photon Code Overview

Like before with Instaloader we will first take a look at their GitHub page to see what information we can acquire. In this case we notice the following:

Because there is no setup.py file we will have to do more work during the packaging process, and do some things differently than with Instaloader.

Setting Up Environment

We assume we have already followed our documentation on setting up a packing environment.

Let’s set up our directories now for this package:

:~$ mkdir -p ~/kali/packages/photon/ ~/kali/upstream
:~$

Downloading Tag Release

As this package has a tag release like Instaloader, we will follow the same process. We go to Photon’s GitHub’s release page and see the latest release is version 1.3.0. We then download it with the filename format of [name]_[version].orig.tar.gz:

:~$ wget https://github.com/s0md3v/photon/archive/v1.3.0.tar.gz -O ~/kali/upstream/photon_1.3.0.orig.tar.gz
:~$

Creating Package Source Code

We can now go to the working directory for the process now that the prerequisites are done:

We then can make it into an empty Git repository:

We can now import the .tar.gz we previously downloaded into the empty Git repository we just created. When prompted, we remember to accept the default values:

We remember to change the default branch, from master to kali/master (as master is for upstream development), then delete the old branch. We also run a quick git branch -v to visually see the change:

We can now generate the debian/ folder and related files. We will again go with Single for this package. We will manually specify the downloaded file (as it is not located in ../), and also the package name to use in the template:

As a quick refresher of what each of these files are for:

  • debian/changelog - tracks when the package gets an update (including why and who by). This is responsible for the package version

  • debian/control - is the metadata for the package (often seen with apt)

  • debian/copyright - what is under what license. The package can be under something different to the work we have put in to create the package

  • debian/rules - how to build the software and turn it into a package

  • debian/source/format - is the source package format

At this point, we have the base packaging files in place, and it feels like a good idea to commit before starting some real work:

We now need to edit each one to make sure the information is accurate. We can use what we found on GitHub to supply the correct info into the debian/ files:

  • License

  • Dependencies

  • Maintainers

  • Description

Collecting InformationLicense/Maintainers

This package, like Instaloader, is very straightforward and GitHub has already detected the license as GPL-3.

For GPL-3 licenses we do not have to copy the entirety as-is in the upstream license file. If we look at /usr/share/common-licenses/ we can see that there are multiple licenses in their entirety already available locally. As we can see from GPL-3’s page from Debian we can use a shortened down version of the license that will be acceptable.

Unfortunately, when we look at the license file from upstream we do not see any contact information or names. We will have to look elsewhere for it.

If we look through the README.me on Photon’s GitHub page, we can see that s0md3v appears to be the sole maintainer as his Twitter is linked however no other maintainers are seen. If we look at s0md3v’s GitHub profile page, we notice that an email is shown (if we are logged in)! With this, we have the maintainer name and email address we can use to continue.

Dependencies/Maintainers

We now need to find out what dependencies are needed for this tool to work. Fortunately, we have a requirements.txt file that we spotted earlier. Looking at this we can see four dependencies needed:

We now need to find the proper name in apt to make sure that we have everything for when we edit the debian/control file later.

From Instaloader, we already know that requests will be available with python3-requests. However, requests[socks] will not so we have to find a way to install socks. If we search for python3-requests, we can see that there is no result that includes any mention of socks:

If we broaden our search and utilize grep we are able to find what we need!

Looks like python3-socks is our second dependency. However, we can make sure that this is indeed the correct package:

  • We will first go to the PyPI page for requests to find the proper upstream source.

  • Next we can find the setup.py file and look for the line with socks. Here we can see that PySocks is the PyPI module name.

  • Again we can find the upstream source from the PyPI page for PySocks

  • We can finally compare the upstream source from PySocks to the homepage provided with python3-socks and see that they match:

Keeping this in mind, lets find urllib3 and tld:

There are the other two! We now have all four dependencies figured out (python3-requests,python3-socks,python3-urllib3 & python3-tld), and can move forward.

Maintainers

Like Instaloader, while doing the other parts we have discovered the authors and maintainers of the software, so we don’t need to do anything extra for this.

Description

Similarly to Instaloader we will pull the descriptions from the GitHub page. Remember we need two description values, a short one and a long one.

The first description we create is the short description. For this one, we will take the summary from the about section of the GitHub and expand “OSINT” to be “Open Source INTelligence” for anyone who would not know what “OSINT” means.

For the long description we will repeat the about description, and then utilize the explanation under Data Extraction from the README. The reason we do this is because the long description cannot start with the name of the package, so we will repeat the short description and modify it to provide further context. However, for now this is something to remember until we edit the debian/control file.

Editing Package Source Code

Now that we have that information copied down, we can start to populate the files in the debian/ folder we created with dh_make.

Changelog

Here we will need to alter:

  • distribution from unstable to kali-dev

    • unstable is the development distribution for Debian, kali-dev is the one we use in Kali.

  • version (from 1.3.0-1 to 1.3.0-0kali1)

    • The format is [softwareversion]-0kali[release]. We put 0kali in case this package makes it into Debian, it avoids conflicting versions and ensures proper upgrade to the Debian version.

  • The log entry - We keep it simple with Initial release

Control

Most of this we have now figured out from Instaloader, so it should make it easier to fill in. We supply the values that we found from our information gathering and get the following:

In Build-Depends now, this is a Python3 Package so we need to add in:

  • dh-python

  • python3-all

  • python3-requests

  • python3-socks

  • python3-tld

  • python3-urllib3

For this package however, as we do not have a setup.py file, we will make a small change compared to Instaloader. This change is that we do not include the build dependency of python3-setuptools. We will still include python3-all, and that is for a separate reason. We will also include all of the dependencies that are for the package. We do this to ensure that a test suite can be ran if there is one.

As stated previously, python3-all is still included. This is due to its reliance on a python module that requires compiled binary extensions. These can be found by doing the following:

This can be a bit overwhelming, and at first glance does not give too much helpful information. We can use this to learn if we are going to have any dependency that will eventually call in one of the previous files. To do this we do the following:

As we can see, python3-urllib3 suggests the python3 module cryptography, which we can tell from the previous list will have us require python3-all. This is sufficient to include python3-all.

In Depends we change ${shlibs:Depends} to ${python3:Depends} like before and add in the apt names that we found previously (python3-requests, python3-socks, python3-tld & python3-urllib3).

Copyright

We already have figured out the copyright license description we will use, and have the Upstream-Contact information, so we can easily populate this file:

Rules

This rules file will look similar to Instaloader’s, with how to install, however there is one key difference that will change significantly how the package is built. As there is no setup.py, we do not need to set the pybuild build system:

Beware that the “dh” line needs to be indented by a single tabulation character.

Watch

This watch file is easier than Instaloader’s in that we do not have to worry about version mangling. We can do a straightforward watch file like so:

.Install & Helper-Scripts

The .install and helper-script file for this package are very straightforward.

We first will create the helper-script:

We can now create the install file. For this install file, we ensure that we copy over the files that photon.py will use:

Now we can leave this package here. It is a working package, and everything appears to be correct when we build it: gbp buildpackage --git-builder=sbuild --git-export=WC

However, we want this package to be the best possible package it can be! If we take a look at the photon.py file we can see that it has the ability to update built in. This is something that we should patch out using gbp pq. Additionally, due to the helpfulness of autopkgtests we should contribute a minimal test.

Patches

Patches are occasionally used to fix an issue with the upstream tool or adhere to standards. For this tool we will be creating a patch that will remove the update functionality from photon.py, so users will update the tool from apt instead.

We will be using gbp pq to create a patch for this package:

We first will create a separate branch where we can work freely. With this command, any patches that are already created will be automatically imported and applied:

After we make our changes we will do a commit. The commit message will be the title of the patch:

We export the commits into a patch with the titles of the commits we made. We can see there are some new files made up:

Autopkgtest

Autopkgtest is a huge help to detecting issues when updating packages. For this package, we will create a simple test that may not catch more advanced errors however it is better than nothing. We first will get started with creating the directory we will create the test in:

We now have to create a control file. If we had multiple commands/tests, we would put different information into this file, however as we have only the one command/test we will be running we can work directly in this file.

For this test we will simply supply --help to photon and see if it works correctly. Because we only use photon, we only need what the tool is dependent on. For this we will use @. Finally, because it is a simple test that wont catch much, we make sure to note that this is a superficial test:

More information on runtime tests can be found on our docs which has many other helpful resources that explain in detail runtime tests.

Packing Up

We can now commit our changes and see if it all works:

Lets try and build the package!

Looks successful! We can now finish up the packaging by testing it out, committing and pushing changes, and send request for it to be added!

Last updated

Was this helpful?