This is practically a place where I put things I that aren’t mine but would hate to go and search online for,again or just things that don’t belong to me that I aquired by fair means. A collection of things I know that aren’t mine if you will. My original thoughts or things I believe are my original thoughts go in my main blog

For those who do not know me, my name is Abraham Raji. I like to make things. I design and build solutions to problems that fascinate me. I consider myself a minimalist who believes in sensible and intuitive design that is beautiful both on the outside as well as under the hood.

A few phrases that could be used to semi-accurately describe me are:

  • Free/Libre Software Enthusiast.
  • Privacy Advocate.
  • Consumer of Art.
  • Open Design Advocate.
  • An advocate of “Be excellent to everyone you see”.
  • Hardware Enthusiast.
  • Debian Contributor.
  • Mozillian.
  • Vector Designer.

Setting up Sid Development Environment for Debian Packaging

Why a sid env?

Debian packages are developed for Debian through the Unstable distribution or Unstable Branch. Debian almost always has three distributions going for it at any point of time. There is a stable branch which is currently Buster which is what users put on their production machines and is recommended by Debian for it’s users as it’s officially supported by the community and recieves regular updates that resolves bugs and provides security patches. Concurrently Debian also maintains two other Distributions: testing which currently is Bullseye and unstable which always will be Sid. The way this works is when a new release is made the Debian Developers discuss and decide what features they wish to implement in the next release. They work on these features in Sid which is used to package new packages that are uploaded to the Sid archives and once they’ve proven their usability they’re moved to the testing archives where they’re further tested and worked upon. When all the features that was decided has been implemented and the distribution contains no release critical bugs, a new version of Debian is released that is the Testing becomes the new stable and the current stable becomes old-stable. The next stable version will be current testing which is Bullseye and Buster at that point will become old-stable.

So in short in order to do packaging we need a Sid env set up somehow. You can Dual Boot, use VMs, use container tech such as Docker or LXD or create a schroot.

Why schroot?

I personally prefer schroot. Schroot is light-weight and easy to set-up and use, but the real feature that sells schroot for me is that it uses the same home folder that my base distro uses. So I can access the files that I worked from schroot without entering schroot and there’s a lot less duplicatiion of config files.

Setting a Sid env with Schroot.

If you already have a Debian stable or Debian-based distribution (Arch also has schroot package, though if you have a different distro, you need to check if it has schroot package), this option is best for you. These instructions assume you are already running a Linux Distribution (preferably Debian Stable).

sudo apt install schroot debootstrap

Create root file system: The /srv contains data served by your system, it’s a relatively new folder in Unix and not a lot of distributiions use it. We will create a folder in the /srv directory to home the root files of our Debian Sid env.

mkdir -p /srv/chroot/debian-sid

Now we will use debootstrap to pull the Debian Sid files.

debootstrap sid /srv/chroot/debian-sid

Now create a text file /etc/schroot/chroot.d/debian-sid with your favorite text editor and add the following lines in it:

[debian-sid]
description=Debian Sid for building packages suitable for uploading to debian
type=directory
directory=/srv/chroot/debian-sid
users=<your username>
root-groups=root
personality=linux
preserve-environment=true

Where <your username> is an underprivileged user on your host system.

And there you go! We have successfully set up a Debian Sid env that you can now use to package Debian packages.

Using Schroot.

To enter schroot as a superuser, enter the following from a terminal.

sudo schroot -c debian-sid

W: Failed to change to directory '/ ... is common warning and can be ignored for now.

Now that you’re in schroot play around a bit. Install your favorite applications:

apt-get update && apt-get install <some-package>

Once you’re done just type in exit and hit enter to exit the schroot.

To run schroot as normal user, type in:

schroot -c debian-sid

You will notice that your home folder in your base system is still your home folder and all the files are accessible to you and your configs such as your .bashrc will work here too.

Setting up sudo

Maybe you don’t want to exit out of your normal user and re-enter schroot as the root user everytime you want to install a dependency for a package and want sudo. You can set it up the exact same way you would in regular distro.

First, enter the schroot as root with the command given above and install sudo with

apt install sudo

Once that is done add your user to the sudo group with this command:

usermod -aG sudo <your username>

Now you can exit from the root shell and re-enter schroot as a normal user and run sudo.

How to make sure you’ve set up everything correctly?

Run the command cat /etc/debian_version and it should give you an output as shown below.

❯ cat /etc/debian_version
bullseye/sid

Using GnuPG

GNU Privacy Guard (GnuPG or GPG) is a free (as in freedom) software replacement for Symantec’s PGP cryptographic software suite, and is compliant with RFC 4880, the IETF standards-track specification of OpenPGP.

Basically a piece of software that lets you generate public-private key pairs which can then be used for things like encrypting your mail, signing commits, storing passwords and more.

Modern versions of PGP are interoperable with GnuPG and other OpenPGP-compliant systems.

So technically it doesn’t matter what system you use as long as you make sure that they’re compliant with the OpenPGP standard but GnuPG is free software and so that is what I use.

Generating a GPG key pair

You can genrate a key pair with the following command:

gpg --full-gen-key

Upon which you’ll recieve the following menu:

gpg (GnuPG) 2.2.20; Copyright (C) 2020 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
  (14) Existing key from card
Your selection?

Here GPG is asking you to choose an encryption algorithm that your key will use. I would suggest you either go with DSA or RSA, simply because both have well defined specifications, are widely used and at the time of me writing this blog equally secure. However it’s always a good idea to do some research on your own.

Once you make your choice you’ll have to make another decision, Keysize.

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072)

I usually go with 4096 because why not? It takes a few extra seconds to make but that’s an accaptable trade of for me.

Then we choose how long we want the key to be valid.

Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)

For most cases you should be fine with the key does not expire option but if you’re not like me and can handle keeping track of the key’s expiration date and is okay with generating new one when the current one is expired go ahead and set a time period for automatic expiration of the key.

Is this correct? (y/N)

Put a y.

Now to add your information to the key.

GnuPG needs to construct a user ID to identify your key.

Real name: Name
Email address: [email protected]
Comment: Comment
You selected this USER-ID:
    "Name (Comment) <[email protected]>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?

Unless your version of GPG has some weird bug this step should be go smoothly. If everything looks good type in O and hit Enter.

At this point you’ll receive a message about how your key is being generated and GPG needs entropy to create random numbers and so on. Just keep using the system as you would and depending on your algorithm and keysize the process should take anywhere between a second to a couple of seconds.

What to call my key?

Now that you have a key what do you call it? GPG is the software here. PGP is the actual system. You could say ‘GPG Key’ and that is widely used too but that wouldn’t exactly be accurate. The most accurate term would be an ‘OpenPGP key’.

Backing Up keys

To export your GPG private key, run the following command on your terminal:

gpg --export-secret-keys --armor name > /path/to/secret-key-backup.asc

As an addition, you can also backup the GPG trust database.

gpg --export-ownertrust > /path/to/trustdb-backup.txt

Now to restore the GPG Key:

gpg —-import /path/to/secret-key-backup.asc

And to restore your GPG trust database, run the following command:

gpg --import-ownertrust < /path/to/trustdb-backup.txt

Signing commits

First we need to list all the keys first:

gpg --list-secret-keys --keyid-format LONG <your_email>

This will list all your GPG keys. Copy the GPG key ID that starts with ‘sec’ and add this as the key to sign commits in git using the following commit:

git config --global user.signingkey <GPG Key ID>

Optionally you can ask git to sign commits automatically using the following command:

git config --global commit.gpgsign true

Simple Packaging Tutorial: The Long Version

This page is intended to aid the attendees of the ഡെബിയന്‍ പാക്കേജിങ്ങ് ബാലപാഠങ്ങള്‍ പഠിയ്ക്കാം (Simple Packaging Tutorial with debmake) workshop held at the Malayalam MiniConf during DebConf 20 on 28th August 08:30 PM - 10:15 PM IST.

The workshop was taken by Pirate Praveen who is a Debian Developer and myself. This page adheres to the structure of the workshop and provides additional information that is otherwise spread across multiple pages in the Debian Wiki.

You could refer Simple Packaging Tutorial (a shorter version of this) at the Debian Wiki.

Having a Debian Unstable System is a pre-requisite to this workshop. If you haven’t set one up yet, you can follow the tutorial => https://wiki.abrahamraji.in/sid-env/ to set up an unstable system on your machine using schroot.

Every command we execute in this tutorial will be done in the Unstable System.

Step 0 : Getting Organized

First, let’s get organized, let’s create a folder in our home directory dedicated for packaging. You can do so from the terminal itself by running the following command:

mkdir <directory name>

Where is pretty much anything you wish to name the folder where you’ll put all the files related to packaging. Personally I’ve named mine Debian.

Keeping things organized will help you when working with complex packages in the future. It will avoid confusion and help you stay on top of things without getting overwhelming.

Now once we’ve created the said directory let’s switch to it using the cd command

cd <directory name>

Packaging is often a straight forward ordeal. The process of packaging remains more or less the same regardless of whether it’s a JS or python or language x package. For the purpose of this tutorial we will be packaging a node module called pretty-ms.

Step 1: Acquire the source code.

To begin we need to first collect the source code of the piece of software that we intend to package, which in our case is pretty-ms. So let’s go to npmjs for pretty-ms. There on the right side of the page we can find the link to the repository and this is where we can find the source code. The source to pretty-ms is hosted here. What this package pretty, much does is convert time produced in milliseconds to more human understandable formats such as hours, minutes and seconds.

If we go through the files we can find the package.json file which contains the metadata of the node module and README.md which contains documentation for the node nodule. The main files i.e. the actual module is the index.js file and we also have the test.js file which contains tests for the module to ensure that it works properly. Then we have the LICENSE file which contains the copyright information which will be useful later on.

Now on Github we have ‘Releases’ which contains various releases of the module. This can vary from one platform to another, most developers tag their releases so that is somewhere you can be sure to find releases if the platform that you encounter does not have a straight forward place to download releases from. Here the latest version of pretty-ms is 7.0.0. Let’s download the source code in tar.gz format. Apart from tar.gz, tar.bz2 and tar.xz are also used by developers. The difference between them is the algorithm used to compress the files. When you compare bz2 and gz you will find that bz2 has smaller file sizes but require more time to compress and decompress whereas gz has comparatively larger file sizes but is very fast in compressing and decompressing the files. It’s the developer who decides which one to use.

Now, we can download from the browser itself but what’s the fun in that? Let’s copy the link and use wget to download the tar file. So let’s first install wget in out schroot env and download the file using it.

sudo apt install wget
wget https://github.com/sindresorhus/pretty-ms/archive/v7.0.0.tar.gz

Package Name

Now we have the source code in our packaging folder, that is if we ran the wget command from that folder. Debian has specifications and formats for everything asociated with a Debian package and there’s a format for the source tarball’s name too. This format is <packagename>_<version>.orig.<tarball format>.

As far as the package name goes if the piece of software we are packaging is something the users will run themselves for example Firefox, Rollup, Rails etc. we usually name the package the actual name of the package itself, if we take the above example their package names will remain firefox, rollup and rails. On the otherhand if it is a library that the users won’t necessarily run themselves, we use a different naming convention. The convention used is the system or programming language or framework the library was made for, followed by a hyphen and then the package name sometimes the system or programming language or framework comes after the name of the library (whether it comes before or after the name of the package is a convention set by the team that maintain the particular set of libraries.). If the module we intend to package is made for Node JS we add node before the package name and if the package is relevant for JS in general we as libjs before the package name. Again this is only applicable to libraries and not to be used for user facing executable programs. Since pretty-ms is a module made for Node JS, the name will be node-pretty-ms. Another important thing to note is that we do not use underscores or uppercase characters in our package names, if your package contains an underscore convert those to hyphens and the upper case characters to lowercase characters when naming your package.

Now let’s complete the name of our tarball. So first comes the package name which is node-pretty-ms, next we add an underscore followed by the version of the package which is 7.0.0 and finally .orig.tar.gz. So at the end the whole thing looks like node-pretty-ms_7.0.0.orig.tar.gz .

Step 2: Debianization

Now let’s go ahead and extract the contents of our tarball with the following command:

tar -zxvf node-pretty-ms_7.0.0.orig.tar.gz

tar is one of those commands that may seem usable at the beginning with -zxvf and everything but trust us in the long run using the command line will save you a lot of time once you get used to the command. If you guys have any doubts regarding any program in your distribution just type in man <package name> to see the various options that package provides you.

Now let’s change the name of the directory according to the above mentioned naming convention except no underscore before the version number, instead of underscore for the directory we use a hyphen. The mv command can be used to do this.

mv pretty-ms-7.0.0 node-pretty-ms-7.0.0

Now let’s change into that directory using the cd command. The contents of the folder should look something like this:

drwxr-xr-x 3 avronr avronr  4096 Apr 27 11:42 .
drwxr-xr-x 3 avronr avronr  4096 Aug 28 10:00 ..
-rw-r--r-- 1 avronr avronr   175 Apr 27 11:42 .editorconfig
-rw-r--r-- 1 avronr avronr    19 Apr 27 11:42 .gitattributes
drwxr-xr-x 2 avronr avronr  4096 Apr 27 11:42 .github
-rw-r--r-- 1 avronr avronr    23 Apr 27 11:42 .gitignore
-rw-r--r-- 1 avronr avronr  2948 Apr 27 11:42 index.d.ts
-rw-r--r-- 1 avronr avronr  3697 Apr 27 11:42 index.js
-rw-r--r-- 1 avronr avronr   833 Apr 27 11:42 index.test-d.ts
-rw-r--r-- 1 avronr avronr  1109 Apr 27 11:42 license
-rw-r--r-- 1 avronr avronr    19 Apr 27 11:42 .npmrc
-rw-r--r-- 1 avronr avronr   855 Apr 27 11:42 package.json
-rw-r--r-- 1 avronr avronr  3333 Apr 27 11:42 readme.md
-rw-r--r-- 1 avronr avronr 12608 Apr 27 11:42 test.js
-rw-r--r-- 1 avronr avronr    45 Apr 27 11:42 .travis.yml

If you’re file structure looks like this then you’re good. If not retrace your steps and find what went wrong. Next we begin the actual Debianization which is done using a tool called Debmake make the debian/ directory. so let’s install debmake using sudo apt install debmake and run debmake and see how the files structure looks after that.

node-pretty-ms-7.0.0
 ├── debian
 │   ├──  changelog
 │   ├──  compat
 │   ├──  control
 │   ├──  copyright
 │   ├──  patches
 │   ├──  README.Debian
 │   ├──  rules
 │   ├──  source
 │   └──  watch
 ├──  .editorconfig
 ├──  .gitattributes
 ├──  .github
 |     └── funding.yml
 ├──  .gitignore
 ├──  index.d.ts
 ├──  index.js
 ├──  index.test-d.ts
 ├──  license
 ├──  .npmrc
 ├──  package.json
 ├──  readme.md
 ├──  test.js
 └── .travis.yml

Step 3: Creating a source package

Next let’s create a source package using dpkg-source -b .. If you guys don’t have dpkg-source in your system you can get it by running sudo apt install build-essential. The output of which should look like this: {{< code numbered=”true” >}} ❯ dpkg-source -b . dpkg-source: info: [[[using source format ‘3.0 (quilt)’]]] dpkg-source: info: [[[building node-pretty-ms using existing ./node-pretty-ms_7.0.0.orig.tar.gz]]] dpkg-source: info: [[[building node-pretty-ms in node-pretty-ms_7.0.0-1.debian.tar.xz]]] dpkg-source: info: [[[building node-pretty-ms in node-pretty-ms_7.0.0-1.dsc]]] {{< /code >}}

  1. If you look through this log you will see dpkg-source mentioning that it is using the quilt 3.0 source format.
  2. You will also notice that is using the .orig.tar.gz file that we created earlier
  3. It has build a tar of the debian directory too. But there is also something new here, the file is named node-pretty-ms_7.0.0-1.debian.tar.xz where you can see that there is a -1 after the version number. That number is called the debian revision number. Say we packaged a piece of software and uploaded it to the Debian archves and then someone reported a bug and we made and fix and want to release the package again in the archives with the fix. Now you see we have different ‘revisions’ of the same package with the same version number. So inorder to help keep a track of this we have debian revision number which is just a count of the number of times that particular version package was released into the Debian archives. So if we have made a bug fix in node-pretty-ms and release it again to the archives it will be releases as node-pretty-ms_7.0.0-2.
  4. Lastly we have the node-pretty-ms_7.0.0-1.dsc file. This file is a security measure if you look into that file you file find information regarding the package extracted from the files in our debian directory and the check-sums of the node-pretty-ms_7.0.0.orig.tar.gz and node-pretty-ms_7.0.0-1.debian.tar.xz. This is so that others can check the integrity of these files once they have downloaded it from the archives after a Debian Developer uploads it there.

These three files together form the Debian Source Package.

The .dsc file

Let’s look at the contents of the .dsc file real quick.

Format: 3.0 (quilt)
Source: node-pretty-ms
Binary: node-pretty-ms
Architecture: any
Version: 7.0.0-1
Maintainer: Abraham Raji <[email protected]>
Homepage: <insert the upstream URL, if relevant>
Standards-Version: 4.1.4
Build-Depends: debhelper (>= 11~)
Package-List:
 node-pretty-ms deb unknown optional arch=any
Checksums-Sha1:
 28bb69ab4720c07dcdd73520b1305137ae354f90 6142 node-pretty-ms_7.0.0.orig.tar.gz
 329139a95e273617ecfdb41466325cede4fa983d 2004 node-pretty-ms_7.0.0-1.debian.tar.xz
Checksums-Sha256:
 256871d7b49dc76e33d841e46c5d36008858aceea9081d9e62c7f5760e65ea33 6142 node-pretty-ms_7.0.0.orig.tar.gz
 3e28122e5bbcb1c771c7431b9af90bc74da45c0461be3a6bc8bcadd73e930707 2004 node-pretty-ms_7.0.0-1.debian.tar.xz
Files:
 ab6e9b3155d0cd73b54d4f0ba8dd0774 6142 node-pretty-ms_7.0.0.orig.tar.gz
 1d7cf58aef1718817cece400cb978ad9 2004 node-pretty-ms_7.0.0-1.debian.tar.xz

We can see a bunch information such as the format used, which as we saw before is quilt 3.0. The next two fields are interesting, we mentioned at the beginning of this workshop about names of user facing software vs libraries, the name of the source package vs the name of the binary which the users will use to install this package and such. Next we have Architecture which states what all architectures you can install this package on, here since it’s a JS package it can be installed on all architectures and that field should actually say all, but debmake hasn’t learnt to detect that yet so it put any there, we’ll fix that later. Then we have the version followed by the information about the person working on the package (which debmake got from my .zshrc which is where I’ve put it and if you use bash you can put it in your .bashrc and Debmake will pick that up). Next we have the Homepage feild where we can put the link to the homepage of the package. Next is Standards-Version which tells us which Debian policy the package follows and set to the version number of the package debian-policy, this is also a bit outdated and we will fix it a little later. The next field is Build-Depends which specifies the packages needed to build executable files from the source. Next we have the checksums we mentioned above in three formats, Sha1, Sha256 and MD5. So that’s the DSC file.

Step 4: Building, Making Fixes and Satisfying Lintian

Building

Now that we have the source package we can build it. We need to be in the node-pretty-ms-7.0.0 folder to build it. Inside the folder we will execute the dpkg-buildpackage command which will build the package for us. The log of that command will look something like this:

❯ dpkg-buildpackage
dpkg-buildpackage: info: source package node-pretty-ms
dpkg-buildpackage: info: source version 7.0.0-1
dpkg-buildpackage: info: source distribution UNRELEASED
dpkg-buildpackage: info: source changed by Abraham Raji <[email protected]>
dpkg-buildpackage: info: host architecture amd64
 dpkg-source --before-build .
 fakeroot debian/rules clean
dh clean
   dh_clean
 dpkg-source -b .
dpkg-source: info: using source format '3.0 (quilt)'
dpkg-source: info: building node-pretty-ms using existing ./node-pretty-ms_7.0.0.orig.tar.gz
dpkg-source: info: building node-pretty-ms in node-pretty-ms_7.0.0-1.debian.tar.xz
dpkg-source: info: building node-pretty-ms in node-pretty-ms_7.0.0-1.dsc
 debian/rules build
dh build
   dh_update_autotools_config
   dh_autoreconf
   create-stamp debian/debhelper-build-stamp
 fakeroot debian/rules binary
dh binary
   dh_testroot
   dh_prep
   dh_installdocs
   dh_installchangelogs
   dh_perl
   dh_link
   dh_strip_nondeterminism
   dh_compress
   dh_fixperms
   dh_missing
   dh_strip
   dh_makeshlibs
   dh_shlibdeps
   dh_installdeb
   dh_gencontrol
dpkg-gencontrol: warning: Depends field of package node-pretty-ms: substitution variable ${shlibs:Depends} used, but is not defined
   dh_md5sums
   dh_builddeb
dpkg-deb: building package 'node-pretty-ms' in '../node-pretty-ms_7.0.0-1_amd64.deb'.
 dpkg-genbuildinfo
 dpkg-genchanges  >../node-pretty-ms_7.0.0-1_amd64.changes
dpkg-genchanges: info: including full source code in upload
 dpkg-source --after-build .
dpkg-buildpackage: info: full upload (original source is included)
dpkg-buildpackage: warning: not signing UNRELEASED build; use --force-sign to override

Since it is a simple package it will build successfully. Also, if we look at the parent directory we have a few new files:

❯ ls ..
node-pretty-ms-7.0.0                    node-pretty-ms_7.0.0-1.debian.tar.xz
node-pretty-ms_7.0.0-1_amd64.buildinfo  node-pretty-ms_7.0.0-1.dsc
node-pretty-ms_7.0.0-1_amd64.changes    node-pretty-ms_7.0.0.orig.tar.gz
node-pretty-ms_7.0.0-1_amd64.deb

Most notable of the new files are the .buildinfo, .changes and .deb files.

  • .buildinfo gives us the info regarding the packages that were in our distribution at the time of building.
  • .changes gives us a lot of information that you could also find in the .dsc file but also contents of the debian/changelog file.
  • the .deb file is something we’re all familiar with and is what we use to install the package in our system.

Now if we install the generated .deb file and run the command dpkg -L node-pretty-ms which essentially gives us all the files associated with that package in our system you will see that the important files such as the index.js or package.json was not installed. So even though we have a source package that builds and installs properly we haven’t been able to install the package to our system yet. Let’s start fixing this package.

Making fixes

  • First let’s fix the architecture which can be fixed by editing our debian/control file. In the control file has a section for Architecture which currently is set to any and we will set that to all. Let’s open a text editor of choice and make the necessary change. This is probably how it will look at first.
Source: node-pretty-ms
Section: unknown
Priority: optional
Maintainer: Abraham Raji <[email protected]>
Build-Depends: debhelper (>=11~)
Standards-Version: 4.1.4
Homepage: <insert the upstream URL, if relevant>

Package: node-pretty-ms
Architecture: any
Multi-Arch: foreign
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: auto-generated package by debmake
 This Debian binary package was auto-generated by the
 debmake(1) command provided by the debmake package.

There are a few things we can fix here, namely:

  • Section: this is a JS package so set it to javascript.
  • Standards-Version: which is also using an old version, so set it the new one which is 4.5.0
  • We could also add the homepage link
  • The Architecture of course
  • Add a description too. You can find this from the package’s homepage or README.md.

Once you’ve made these changes the file should look something like this:

 Source: node-pretty-ms
 Section: javascript
 Priority: optional
 Maintainer: Abraham Raji <[email protected]>
 Build-Depends: debhelper (>=11~)
 Standards-Version: 4.5.0
 Homepage:https://github.com/sindresorhus/pretty-ms#readme
 
 Package: node-pretty-ms
 Architecture: all
 Multi-Arch: foreign
 Depends: ${misc:Depends}, ${shlibs:Depends}
 Description: Convert milliseconds to a human readable string
  • Next let’s tell Debian what all files to install. We can do so in a file inside the debian directory called install. In this case we want to install the index.js, index.d.ts and the package.json file and in debian we install it to `/usr/share/nodejs// (one thing to note here is that we don’t use the debian name but the actual name of the package for the folder). So open the debian/install file with your favorite text editor and add the required files. Once you’ve done that the debian/install file should look something like this:
❯ cat debian/install
index.js usr/share/nodejs/pretty-ms
index.d.ts usr/share/nodejs/pretty-ms
package.json usr/share/nodejs/pretty-ms

Let’s build again using dpkg-buildpackage. If you installed the previous .deb file you should remove it before you install the new one we just generated. Now if we install the new .deb file and run the command dpkg -L node-pretty-ms, we can see that all the required files were installed properly.

  • Next let’s fix the copyright file. We can find the missing information in that file from the upstream license file. Right now it will look something like this:
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: node-pretty-ms
Source: <url://example.com>
#
# Please double check copyright with the licensecheck(1) command.

Files:     .editorconfig
           .gitattributes
           .github/funding.yml
           .gitignore
           .npmrc
           .travis.yml
           index.d.ts
           index.js
           index.test-d.ts
           package.json
           readme.md
           test.js
Copyright: __NO_COPYRIGHT_NOR_LICENSE__
License:   __NO_COPYRIGHT_NOR_LICENSE__

Files:     license
Copyright: Sindre Sorhus <[email protected]> (sindresorhus.com)
License:   Expat
 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 .
 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 .
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#----------------------------------------------------------------------------
# Files marked as NO_LICENSE_TEXT_FOUND may be covered by the following
# license/copyright files.

#----------------------------------------------------------------------------
# License file: license
 MIT License
 .
 Copyright (c) Sindre Sorhus <[email protected]> (sindresorhus.com)
 .
 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Softw
...

Make sensible changes and make a single line should not have more than 80 characters, you can achieve this using the macro functionality in your text editor. Once you’re done it should look something like this.

 Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 Upstream-Name: node-pretty-ms
 Source: https://github.com/sindresorhus/pretty-ms/releases
  
 Files:     *
 Copyright: Sindre Sorhus <[email protected]> (sindresorhus.com)
 License:   Expat
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/ or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions: .
  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.
  .
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS  IN
  THE SOFTWARE.

Satisfying Lintian

Now run the dpkg-buildpackage again so that the changes we made takes effect. As of now we have resolved all the basic issues. Lintian will help us find the ones that we missed, lintian by default will give short messages but detailed descriptions will help us solve these issues. in order to do that let’s set an alias in our shell’s rc file (~/.bashr or ~/.zshrc). So pul the following lines in your .bashrc or .zshrc

alias lintian='lintian -iIEcv --pedantic --color auto'

Now run lintian and it will throw a bunch of complaints on your face. We need to pay attention to the lines that start with E: or W:. Let’s fix an E which complains that changelog-is-dh_make-template and if you read through the description you’ll see that the issue is in the debian/changelog. Let’s take a look at the file:

node-pretty-ms (7.0.0-1) UNRELEASED; urgency=low

  * Initial release. Closes: #nnnn
    <nnnn is the bug number of your ITP>

 -- Abraham Raji <[email protected]>  Fri, 28 Aug 2020 16:05:03 +0530

The issue is that when we wish to package a new package we need to send an Intend to Package mail which is registered as an ITP Bug. This helps co-ordinate packaging work and prevent duplicate work. The bug has a unique identification number. Which we put in the changelog after the hashtag in * Initial release. Closes: #nnnn. So we need to check for existing bugs before we make a new ITP bug, we could search for existing bugs at wnpp.debian.net. Now we can solve this error by removing the line <nnnn is the bug number of your ITP> and add the ITP bug number. For the sake of this workshop we’re going to add a random number there. Once we do that the file should look something like this:

node-pretty-ms (7.0.0-1) UNRELEASED; urgency=low
 
   * Initial release. Closes: #982937
 
  -- Abraham Raji <[email protected]>  Fri, 28 Aug 2020 16:05:03 +0530

Now we still have a lot more complaints to solve but to keep the size of this page somewhat reasonable, I’m not going to include fixes to all the complaints here. Here’s an example from a package I updated a while ago. It is sort of a jackpot in the sense it has a bunch of fixes to common lintian complaints I’ve come across. Commit messages could be a little better and more creative though.

Here we did a lot of things manually like visit different sites and collect tarballs and stuff but actually we didn’t have to do that. We actually have a tool that does most of what we already did called npm2deb. We went throug all taht in this tutorial because it is important you know what’s happening under the hood.

Here’s a wiki page giving a tutorial on how to use npm2deb.

Here’s a wiki page I wrote regarding updating packages.

Updating a Debian Package

Every GNU/Linux distribution has their own package manager and package format. For Debian it’s apt and .deb. Debian packaging is quite interesting, there’s a fair bit of information that is included in a Debian source package. This page deals with updating a Debian package to a new upstream release.

Preface

When to update a package?

How frequently a package is updated varies, from package to package. It’s usually as per the discretion of the maintainer of the package. Usually there are software packages that are the main products that our users primarily interact with such as Firefox, Gitlab, Emacs etc. and then there are other pieces of software and libraries that is required for above mentioned software packages to function. These packages are called dependencies. Dependencies are usually only updated to a newer version when their dependents (the main software products we mentioned above) no longer works with the current version.

The rationale for such a system comes from Debian’s core policy of preferring stability over shiny new features. It’s more important that every software package currently in Debian works well with every other software package in Debian.

What do you need to update a Debian package?

  1. A system running Debian. It’s possible to package for Debian using Ubuntu or Mint or any Debian based distro but doing it from a Debian system in my experience has given me the least headaches.
  2. A virtual Debian Unstable env. Debian has three to fours distributions active at all times: Old-Stable (Currently Stretch), Stable (Currently Buster), Testing (Currently Bullseye) and Unstable (Always Sid).
    We do packaging on sid. Every package truly only enters Debian once it is in sid, the unstable distribution. It is here that critical bugs are found, reported and fixed. Once a packages reaches a level of maturity in sid, it’s moved to the current testing repo. At any point sid has the latest version of any package in Debian. This helps people like me (and hopefully you) who does packaging for Debian. Sid BTW is the only Debian rolling release distribution. You could compare it to Archlinux.
    This page is quite long as it is so I’m not going to make it longer by adding instructions to setup a Debian Unstable env. Here’s a Debian Wiki Page that tells you how to do that. Might add a page for this too in the future but not now. On that page I personally would go with schroot because we regularly use stuff like LXC for building in clean envs and testing.

Update: I’ve made a wiki page on how to setup a Debian Sid env here.

  1. Ability to work from a terminal. You don’t need to be unix wizard. Just know your way around a terminal or this is going to be a lot more harder.
  2. Steady internet connection.
  3. If you’re not a Debian developer you need a Debian Developer to sponsor (upload your package) your package for you.

Getting Started

  1. Get the Unstable env up.
  2. Install the required packages:
sudo apt install devscripts git git-buildpackage lintian
  1. Create an account on Salsa- Debian’s Gitlab instance.
  2. Add the following to you .bashrc or .zshrc:
export [email protected]
export DEBFULLNAME='Your Name'
alias lintian='lintian -iIEcv --pedantic --color auto'
alias git-import-dsc='git-import-dsc --author-is-committer --pristine-tar'
alias clean='fakeroot debian/rules clean'

Basic steps

I’m going to use ruby-health-check, a package I recently worked on as an example. The general steps remain same for almost all packages.

  1. First fork and clone the salsa repo using git-buildpackage i.e gbp:

gbp clone --pristine-tar [email protected]:avron/ruby-health-check.git

We use gbp for convenience purposes because it does a lot of things automatically. For example, most Debian source package has three branches: master, upstream and pristine tar. Master branch is usually where we work and build the package, upstream just has untouched upstream files and pristine-tar has instructions to pristine-tar tool to generate exact same tarball from upstream branch and tag. If we clone using git it will only clone the repo and the default branch but when we use gbp all three branches will be pulled from salsa. Essentially if we use git we would have to:

git clone [email protected]:avron/ruby-health-check.git
git checkout upstream
git checkout pristine-tar
git checkout master

if we use gbp clone we can save some effort.

  • Next cd into the directory and download new upstream release tarball using the command:

    uscan --verbose

    Sometimes when using uscan the download link would have deprecated and uscan won’t work, at that point your options are either to fix the download link which can be found at debian/watch or to manually download the tarball from the upstream releases page. I prefer to fix the link at debian/watch whenever possible and it is fixable in most cases. Here’s an example of me fixing the debian/watch file for another package. Here are the instructions to manually download upstream sources when necessary.

  • If you used uscan to download the tarballs you should see a tarball named package-name_upstream-version.orig.tar.gz in the directory you cloned the repo in. Import the orig.tar.gz using
    gbp import-orig --pristine-tar ../ruby-health-check_3.0.0.orig.tar.gz.

  • We need to tell the operating system that we have imported a new version into the repo. We do that by adding an entry in the debian/changelog file. We do so by running the following command: gbp dch -a. What this will do is add an entry to debian/changelog file that looks something like this:

ruby-health-check (3.0.0-1) UNRELEASED; urgency=medium

 * New upstream version 3.0.0

-- Abraham Raji <[email protected]>  Thu, 13 Aug 2020 16:17:14 +0000

As I mentioned above Debian takes bugs seriously and the team works constantly on improving the quality of the software, so the package maintainers often update the packages with patches, missinng tests etc., so a single version of the package can have multiple revisions that are uploaded to unstable. In order to keep track of this we add a Debian revision number to the end of the upstream version number. So how the version number looks at the end is upstream-version-debian-revision. Up above, you can see the version is 3.0.0-1, which means the upstream version of the package right now is 3.0.0 and 1 signifies that this is the first revision of the said package in Debian. To learn more about versioning checkout: semver.org.

Sometimes gbp can mess up the version number if there is an UNRELEASED entry already. In the sense it will add your entry as a new revision of the previous version. In that case you can open the file in a text editor of your choice and manually change the version number.

  • Now we build. Run:

    dpkg-buildpackge

    For minor updates, i.e. a.b.c-d => a.b.e-1 there shouldn’t be any problem. The build will complete successfully almost always. If it’s not a minor update, things may not `just work`. Sometimes you may have issues where you need a newer version of a dependency for this version of our package to work, so we may have to update that package first and come back to this one or there are patches in debian/patches made by package maintainers in case a change needs to be made and for some reason the upstream maintainer can’t make that change in the upstream, these patched may no longer work when switching from one major version to another. So we need to fix these issues and successfully build the package. When do you know you’ve successfully build it? Ironically it is when you get a warning saying something along the lines of ‘failed to sign your .dsc file’. You don’t need to worry about that since the person uploading the package will be the one to sign it.

  • Next we look for policy violations using lintian. When you successfully build a package a file named package-name_version-number_debian-revision-architecture.changes is generated in the parent directory which if you pass on as an argument to lintian will give you all the warnings and errors. Run

    lintian ../ruby-health-check_3.0.0-1_amd64.changes

    All complaints from lintian come with reasons and suggestions to fix them. If it doesn’t then you haven’t added the stuff you were suppose to add at the beginning of this page. Fix lintians complaints. Commit your changes using git and use clear commit messages. Commit everything except debian/changelog. Here’s an example from a package I updated a while ago. It is sort of a jackpot in the sense it has almost every lintian complaint I’ve come across. So you should find fixes to most lintian complaints there. Commit messages could be a little better and more creative though.

  • Now remember gbp dch -a? once you’ve satisfied Lintian run it again. Now if you look at the changelog you’ll find that all of your commit messages are listed as entries in the changelog. Check if there are any duplicate and remove them. Now change the UNRELEASEDin the header to unstable. Now your changelog should look something like this:

  ruby-health-check (3.0.0-1) unstable; urgency=medium

  * Team Upload
  * New upstream version 3.0.0
  * Bumps debhelper-compat version to 13
  * Bumps standards version to 4.5.0
  * Added Rules-Requires-Root: no

 -- Abraham Raji <[email protected]>  Thu, 13 Aug 2020 16:17:14 +0000

At this point commit your debian/changelog with the commit message Upload to Unstable.

  • Now try and build the package in a clean env. Here are the instructions to setup sbuild and building your package using sbuild.
  • If the package was a major update you also need to run autopkgtests. An easy way to do this is through the meta scripts made by Debian ruby team. Instructions to setup and use the scripts are mentioned in the README.md file.
  • If all goes well send an RFS to the mailing list of the Debian Team that maintains the packages. Node packages are maintained by Debian JS team and ruby packages by Debian Ruby Team. Join the mailing list from a seperate mail account as there’s a lot of mail that comes to those lists everyday. Then send a mail requesting for sponsorship.

Zsh with Oh My Zsh

I don’t use zsh with ohmyzsh anymore. This is what I use now. More lean and custom.

Z shell or Zsh is a unix shell that was written by Paul Falstad in 1990. The name zsh derives from the name of Yale professor Zhong Shao (then a teaching assistant at Princeton University) — Paul Falstad regarded Shao’s login-id, “zsh”, as a good name for a shell. Zsh has features like interactive Tab completion, automated file searching, regex integration, advanced shorthand for defining command scope, and a rich theme engine. Combine it with a framework like oh-my-zsh, it really could help you be more productive.

Installing Zsh

  • Debian, Ubuntu and other Debian based disros:
$ sudo apt install zsh
  • Archlinux, Manjaro and other Arch-based distros:
$ sudo apt install zsh
  • Fedora, RHEL, and CentOS:
$ sudo dnf install zsh

Setting Zsh to your default shell

Now that you have installed zsh on your machine let’s set it as the default shell for your user. Execute the following command without sudo, upon which you’ll be prompted to enter the password for your user.

chsh -s $(which zsh)

Now if you log out and log back and open a terminal it should present you with the zsh shell instead of the bash shell.

Installing Oh My Zsh

  • Using Curl
$ sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
  • Using Wget
$ sh -c "$(wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)"

At this point you might as well install a favourite powerline font. if you’re on Debian or any of it’s forks sudo apt install powerline-fonts should work for most cases.

Plugins

A lot of plugins come built in, for example plugins for distro specific commands are available in the name of the distro it’s written for, so you’ll find plugins such as debian and fedora. you can find all the plugins at ~/.oh-my-zsh/plugins. All the plugins are not enabled by default. In-order to enable a plugin you need to add the plugin nams to your plugins list in your .zshrc

One plugin that I find a lot of value in is the zsh-autosuggestions plugin. It commands based on your .zsh_history. But it is not a default plugin so we need to manually add it. We can do so by cloning the plugin repo to the ~/.oh-my-zsh/custom/plugins folder.

Here’s a list of all the plugins that I use:

  • colored-man-pages
  • debian
  • emacs
  • git
  • gnu-utils
  • lxd
  • zsh-autosuggestions
  • zsh-syntax-highlighting

Only two of the above plugins are custom, so we clone them to the custom plugins folder.

cd ~/.oh-my-zsh/custom/plugins
git clone https://github.com/zsh-users/zsh-syntax-highlighting
git clone https://github.com/zsh-users/zsh-autosuggestions

Then I add the names of the plugins to the list in my .zshrc

plugins=(colored-man-pages debian emacs git gnu-utils zsh-autosuggestions zsh-syntax-highlighting )

Theme

There are a wide variety of themes built-in to oh-my-zsh but my favourite is Powerlevel10k. You can install it by running the following command:

git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k

This theme is pretty neat and if configured properly can give you a lot of information through the prompt itself. It uses a bunch of icons which you can get through the theme’s recomended font Meslo Nerd Font. You can get these fonts by downloading the TTF files given below to your ~/.fonts/ folder Download these four ttf files:

Then set ZSH_THEME="powerlevel10k/powerlevel10k" in ~/.zshrc. After this source your ~/.zshrc or open a new terminal to run the setup process for the theme.

And there you go this is my setup.

My Laptop a.k.a My Baby

I assure you we do not have an unhealthy relationship. This is just my Baby. My first laptop. This machine has been through thick and thin. It has almost never let me down. I mean everyone messes up once or twice. This laptop is what a smartphone is to most people my age.

  • Name: Aspire F15
  • Model Number: F5-573G-7536
  • CPU: Intel i7-7500U (4) @ 3.500GHz
  • Dedicated GPU: NVIDIA GeForce 940MX
  • Integrated GPU: Intel HD Graphics 620 (Kaby Lake GT2)
  • Memory: 7846MiB
  • Storage: 1000GB
  • Screen Resolution: 1920x1080 [16:9]
  • WiFi Card: Qualcomm Atheros QCA9377 802.11ac Wireless Network Adapter
    This little bad boy needs a proprietary firmware to work
  • Ethernet Card: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller

Software I Use

This is a list of software that I use. The main purpose for the existence of this page is to keep a track of the software I use and to create a place I could refer to in case I mess my system up.

Browser

  • Primary: Firefox Specifically Firefox ESR
    • Why?:
    • Extensions:
      • Adnauseum:
        AdNauseam quietly clicks on every blocked ad, registering a visit on ad networks’ databases. As the collected data gathered shows an omnivorous click-stream, user tracking, targeting and surveillance become futile.
      • Bitwarden:
        My password manager of choice. If you don’t use one, you should because if you don’t, with the amount of software services we login to, you bet you’ll reuse password between services which is a terrible idea. The alternative is to memorize a different 16+ character string for all the services you use. Seriously, use a password manager. Bitwarden works great for my use, has many useful features and is Free Software.
      • Sharp Color Picker:
        Because I like good color combinations and I design stuff from time to time.
  • Secondary: Ungoogled Chromium: basically Chromium with all the Google bits removed.
    • Why?
      Because I develop websites and I need to make sure the websites I make properly render across various browsers.

Operating System

❯ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux bullseye/sid"
NAME="Debian GNU/Linux"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

Text Editor

Emacs

I use emacs for most of my text editing needs and more. Sometime ago I started working on an emacs distribution named Armacs that helps people get started with Emacs. Up until recently I used to for pretty much anything. Recently I started experimenting with Doom Emacs and I’ve really started liking Evil Mode might actually adopt it to Armacs.

  • Why?
    • Free Software ♥
    • You can get a lot done from just Emacs- text editing, git. ssh, Document editor and more!

Instant Messaging

Terminal Emulator

  • St
  • Gnome Terminal

Shell

  • Zsh