
Packaging PostgreSQL extensions in Debian/Ubuntu Systems
/ 5 min read
Hi everyone,
PostgreSQL has a great extensibility in features using extensions. Any feature that a user needs which isnt there natively can be added using extensions. to distribute extensions on different systems, packaging becomes important.
This blog lists down the steps to package a PostgreSQL extension in debian/ubuntu systems. I would be packaging a simple base36 extension to list down the steps.
1. Adding the sources list
To install postgresql packages in debian, the apt.postgresql.org
apt list needs to be added.
# Reference: https://wiki.postgresql.org/wiki/Apt# Add gpg keys for verificationcurl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/nul#For downloading packagessudo echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list#To also be able to download source files of packages deb-src also needs to be addedsudo echo "deb-src http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" >> /etc/apt/sources.list.d/pgdg.list
Run apt install
to update the apt list repositry and be able to search for packages using apt command.
2. Setting up the directory
Get your extension source code in a directory. Next from the root of the extension directory, call dh_make_pgxs
to setup the boilerplate for the debian folder.
vagrant@ubuntu-focal:/vagrant/base36-0.0.1$ dh_make_pgxsUpstream (-n): base36Version (-v): 0.0.1Source: base36 (0.0.1-1)Binaries: postgresql-PGVERSION-base36 (0.0.1-1)Uploader: <vagrant@localhost>Homepage (-h): https://FIXME/base36
Press Enter to continue, ^C to abortInstalling debian/control.inInstalling debian/copyrightInstalling debian/gitlab-ci.ymlInstalling debian/pgversionsInstalling debian/rulesCreating debian/source/Installing debian/source/formatCreating debian/tests/Installing debian/tests/controlInstalling debian/tests/installcheckInstalling debian/watchUpdating debian/control from debian/control.inCreating debian/changelog
Post this a debian folder would be created. It has same structure of what dh_make
creates hence the meaning of the files can be found anywhere on the internet.
3. Updating necessary files
After updating the nexecassry parts, the folder is ready to be built(incase of procedural languages) and packaged.
4. Build the extension
PostgreSQL has a cli tool pg_buildext which is extremely helpful in building the package. A great documentation of it is available on the manpage .
5. Package the extension
The final step comes to packaging the extension. To just verify there must be a README.* file in the root of the extension.
Run the dpkg_buildpackage
if a tarball of the source code already exists and dpkg_buildpackage -b
if not. This would test the extension on the supported pg versions and then create the necessary deb files ready to be shipped.
vagrant@ubuntu-focal:/vagrant/base36-0.0.1$ dpkg-buildpackage -bdpkg-buildpackage: info: source package base36dpkg-buildpackage: info: source version 0.0.1-1dpkg-buildpackage: info: source distribution UNRELEASEDdpkg-buildpackage: info: source changed by <vagrant@localhost>dpkg-buildpackage: info: host architecture amd64 dpkg-source --before-build . debian/rules cleandh clean --with pgxs dh_auto_clean --buildsystem=pgxs pg_buildext clean build-%v postgresql-%v-base36rm -rf build-10/ build-11/ build-12/ build-13/ build-14/ build-15/rm -rf debian/postgresql-10-base36/ debian/postgresql-11-base36/ debian/postgresql-12-base36/ debian/postgresql-13-base36/ debian/postgresql-14-base36/ debian/postgresql-15-base36/ debian/postgresql-10-base36.substvars debian/postgresql-11-base36.substvars debian/postgresql-12-base36.substvars debian/postgresql-13-base36.substvars debian/postgresql-14-base36.substvars debian/postgresql-15-base36.substvarsmake[1]: Entering directory '/vagrant/base36-0.0.1'rm -rf results/ regression.diffs regression.out tmp_check/ tmp_check_iso/ log/ output_iso/make[1]: Leaving directory '/vagrant/base36-0.0.1' dh_clean pg_buildext checkcontrol debian/rules binarydh binary --with pgxs dh_update_autotools_config dh_autoreconf dh_auto_configure dh_auto_build --buildsystem=pgxs pg_buildext build build-%v---building for each postgresql version--- create-stamp debian/debhelper-build-stamp dh_testroot dh_prep dh_auto_install --buildsystem=pgxs pg_buildext install build-%v postgresql-%v-base36---installing extension for each postgresql versionmake[1]: Entering directory '/vagrant/base36-0.0.1'dh_installdocs --all README.*make[1]: Leaving directory '/vagrant/base36-0.0.1' dh_installchangelogs dh_perl dh_link dh_pgxs_test pg_buildext installcheck . build-%v postgresql-%v-base36---running tests on each version---
make[1]: Leaving directory '/vagrant/base36-0.0.1/build-15'Dropping cluster 15/regress ...### End 15 installcheck ### dh_strip_nondeterminism dh_compress dh_fixperms dh_missing dh_dwz dh_strip dh_makeshlibs dh_shlibdeps dh_installdeb dh_gencontroldpkg-gencontrol: warning: Depends field of package postgresql-13-base36: substitution variable ${shlibs:Depends} used, but is not defineddpkg-gencontrol: warning: Depends field of package postgresql-10-base36: substitution variable ${shlibs:Depends} used, but is not defineddpkg-gencontrol: warning: Depends field of package postgresql-14-base36: substitution variable ${shlibs:Depends} used, but is not defineddpkg-gencontrol: warning: Depends field of package postgresql-11-base36: substitution variable ${shlibs:Depends} used, but is not defineddpkg-gencontrol: warning: Depends field of package postgresql-15-base36: substitution variable ${shlibs:Depends} used, but is not defineddpkg-gencontrol: warning: Depends field of package postgresql-12-base36: substitution variable ${shlibs:Depends} used, but is not defined dh_md5sums dh_builddebdpkg-deb: building package 'postgresql-10-base36' in '../postgresql-10-base36_0.0.1-1_amd64.deb'.dpkg-deb: building package 'postgresql-13-base36' in '../postgresql-13-base36_0.0.1-1_amd64.deb'.dpkg-deb: building package 'postgresql-11-base36' in '../postgresql-11-base36_0.0.1-1_amd64.deb'.dpkg-deb: building package 'postgresql-14-base36' in '../postgresql-14-base36_0.0.1-1_amd64.deb'.dpkg-deb: building package 'postgresql-12-base36' in '../postgresql-12-base36_0.0.1-1_amd64.deb'.dpkg-deb: building package 'postgresql-15-base36' in '../postgresql-15-base36_0.0.1-1_amd64.deb'. dpkg-genbuildinfo --build=binary dpkg-genchanges --build=binary >../base36_0.0.1-1_amd64.changesdpkg-genchanges: info: binary-only upload (no source code included) dpkg-source --after-build .dpkg-buildpackage: info: binary-only upload (no source included)
After this the parent of the root directory would have deb of each version of the extension would be created.
vagrant@ubuntu-focal:/vagrant/base36-0.0.1$ ls -la ..drwxr-xr-x 1 vagrant vagrant 4096 Jul 1 20:21 base36-0.0.1-rw-r--r-- 1 vagrant vagrant 11760 Jul 1 18:11 base36_0.0.1-1_amd64.buildinfo-rw-r--r-- 1 vagrant vagrant 2910 Jul 1 18:11 base36_0.0.1-1_amd64.changes-rw-r--r-- 1 vagrant vagrant 820 Jul 1 12:10 base36_0.0.1.orig.tar.gz-rw-r--r-- 1 vagrant vagrant 2552 Jul 1 18:11 postgresql-10-base36_0.0.1-1_amd64.deb-rw-r--r-- 1 vagrant vagrant 2552 Jul 1 18:11 postgresql-11-base36_0.0.1-1_amd64.deb-rw-r--r-- 1 vagrant vagrant 2552 Jul 1 18:11 postgresql-12-base36_0.0.1-1_amd64.deb-rw-r--r-- 1 vagrant vagrant 2556 Jul 1 18:11 postgresql-13-base36_0.0.1-1_amd64.deb-rw-r--r-- 1 vagrant vagrant 2552 Jul 1 18:11 postgresql-14-base36_0.0.1-1_amd64.deb-rw-r--r-- 1 vagrant vagrant 2556 Jul 1 18:11 postgresql-15-base36_0.0.1-1_amd64.deb
Gotchas:
- The name of the folder of the source code of the extension should be of the form <extension_name>_
. - The debian/pgversions file should have a newline otherwise any pg_buildext would neither return any output or any error(status code 0).
- The
postgresql-all
package would be needed to build, install and test the extension on all the supported versions of PostgreSQL.
Fin.