The following is a short guide to getting set up for Ubuntu development.
You must have a Launchpad ID. To get an ID:
- Go to https://launchpad.net/
- Click
Log in / Register
$ sudo apt update && \
sudo apt dist-upgrade -y && \
sudo apt install -y \
apt-cacher-ng \
autopkgtest \
build-essential \
debconf-utils \
debmake \
dh-make \
git-buildpackage \
libvirt-daemon-system \
pastebinit \
piuparts \
pkg-config \
quilt \
sbuild-launchpad-chroot \
ubuntu-dev-tools \
uvtool \
virtinst && \
sudo snap install lxd && \
sudo snap install --classic snapcraft && \
sudo snap install --classic ustriage && \
sudo snap install --classic --edge git-ubuntu && \
sudo snap install --classic --beta multipass
GnuPG is an encryption tool that helps manage your encryption keys.
-
Install and set up GPG normally.
-
List the keys and make sure you associate the email you want to use for publishing.
$ gpg --list-secret-key /home/karl/.gnupg/pubring.kbx ----------------------------- sec rsa4096 2018-08-15 [SC] 7C177302572849D84A5048349E9C224744EF2A5A uid [ultimate] Karl Stenerud <[email protected]> ssb rsa4096 2018-08-15 [E]
-
In this case, my Canonical address isn't in there, so I need to add it:
$ gpg --edit-key 7C177302572849D84A5048349E9C224744EF2A5A ... gpg> adduid Real name: Karl Stenerud Email address: [email protected] Comment: You selected this USER-ID: "Karl Stenerud <[email protected]>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
-
-
Then save and quit:
gpg> save
-
And push to the keyserver:
$ gpg --keyserver keyserver.ubuntu.com --send-keys 7C177302572849D84A5048349E9C224744EF2A5A
Make sure you note the key strength of your GPG key. In this case its rsa4096, but if you have an older key it may be a weaker 2048-bit or 1024-bit key. If so, create a new 4096-bit one and deprecate the old one in Launchpad, GitHub, etc.
Installing git-ubuntu
will modify your .gitconfig
. Make sure it got your
Launchpad username correct:
[gitubuntu]
lpuser = your-launchpad-username
You must also ensure that the [user]
section has your name and email:
[user]
name = Your Full Name
email = [email protected]
You may also want to add the following to your .gitconfig
:
[log]
decorate = short
[commit]
verbose = true
[merge]
summary = true
stat = true
[core]
whitespace = trailing-space,space-before-tab
[diff "ruby"]
funcname = "^ *\\(\\(def\\) .*\\)"
[diff "image"]
textconv = identify
[url "git+ssh://[email protected]/"]
insteadof = lp:
Quilt is a CLI used to manage patch stacks. It can take any number of patches and condense them into a single patch.
A working .quiltrc
:
d=. ; while [ ! -d $d/debian -a `readlink -e $d` != / ]; do d=$d/..; done
if [ -d $d/debian ] && [ -z $QUILT_PATCHES ]; then
# if in Debian packaging tree with unset $QUILT_PATCHES
QUILT_PATCHES="debian/patches"
QUILT_PATCH_OPTS="--reject-format=unified"
QUILT_DIFF_ARGS="-p ab --no-timestamps --no-index --color=auto"
QUILT_REFRESH_ARGS="-p ab --no-timestamps --no-index"
QUILT_COLORS="diff_hdr=1;32:diff_add=1;34:diff_rem=1;31:diff_hunk=1;33:diff_ctx=35:diff_cctx=33"
if ! [ -d $d/debian/patches ]; then mkdir $d/debian/patches; fi
fi
This configures Quilt for use with Debian packages, with default settings that conform to standard Debian practices.
DPut is the Debian Package Upload Tool. It's used to upload a software package to the Ubuntu repository, or to a personal package archive (PPA).
A working .dput.cf
:
[DEFAULT]
default_host_main = unspecified
[unspecified]
fqdn = SPECIFY.A.TARGET
incoming = /
[ppa]
fqdn = ppa.launchpad.net
method = ftp
incoming = ~%(ppa)s/ubuntu
This configures `dput`` for safety, such that if you accidentally forget to specify a destination, it'll default to doing nothing.
sbuild is a wrapper script around schroot
.
In these examples, replace my_user
with your own username.
Make mount points:
$ mkdir -p ~/schroot/build
$ mkdir -p ~/schroot/logs
Set up scratch dir:
$ mkdir -p ~/schroot/scratch
$ echo "/home/my_user/schroot/scratch /scratch none rw,bind 0 0" \
>> /etc/schroot/sbuild/fstab
Optionally, you can mount your homedir inside the container:
$ echo "/home/my_user /home/my_user none rw,bind 0 0" \
>> /etc/schroot/sbuild/fstab
In the following template (.sbuildrc
), replace the following:
$maintainer_name = 'Your Full Name <[email protected]>';
$build_dir = '/home/my_user/schroot/build';
$log_dir = "/home/my_user/schroot/logs";
Template:
# Name to use as override in .changes files for the Maintainer: field
# (optional; only uncomment if needed).
# $maintainer_name = 'Your Full Name <[email protected]>';
# Default distribution to build.
$distribution = "focal";
# Build arch-all by default.
$build_arch_all = 1;
# When to purge the build directory afterwards; possible values are 'never',
# 'successful', and 'always'. 'always' is the default. It can be helpful
# to preserve failing builds for debugging purposes. Switch these comments
# if you want to preserve even successful builds, and then use
# 'schroot -e --all-sessions' to clean them up manually.
$purge_build_directory = 'successful';
$purge_session = 'successful';
$purge_build_deps = 'successful';
# $purge_build_directory = 'never';
# $purge_session = 'never';
# $purge_build_deps = 'never';
# Directory for chroot symlinks and sbuild logs. Defaults to the
# current directory if unspecified.
$build_dir = '/home/my_user/schroot/build';
# Directory for writing build logs to
$log_dir = "/home/my_user/schroot/logs";
# don't remove this, Perl needs it:
1;
A working .mk-sbuild.rc
:
SCHROOT_CONF_SUFFIX="source-root-users=root,sbuild,admin
source-root-groups=root,sbuild,admin
preserve-environment=true"
# you will want to undo the below for stable releases, read `man mk-sbuild` for details
# during the development cycle, these pockets are not used, but will contain important
# updates after each release of Ubuntu
SKIP_UPDATES="1"
SKIP_PROPOSED="1"
# if you have e.g. apt-cacher-ng around
DEBOOTSTRAP_PROXY=http://127.0.0.1:3142/
Note: For more info, see the Ubuntu wiki page on sbuild
Having sbuild set up is only half of the solution, schroot environments for
the respective builds are also needed.
As outlined in the Ubuntu wiki page on sbuild
one can use e.g. mk-sbuild noble --arch=amd64
for that.
But many use sbuild-launchpad-chroot instead which includes two sbuild hooks
and a command line tool to setup and maintain build chroots that are as close
as possible to a standard Launchpad sbuild chroot.
$ sudo sbuild-launchpad-chroot create -n noble-amd64 -s noble -a amd64
This will create multiple schroots which allow to easily select building against different configurations like -proposed or backports.
In general schroots can get stale and there are more and more updates needed in a build. They can be updated individually using sbuild-update. The common -udcar options map to apt update, dist-upgrade, clean and autoremove.
$ sudo sbuild-update -udcar jammy-proposed-amd64
Furthermore sometimes a schroot for Debian is needed to contribute there or to compare build results. Those can be created with sbuild-createchroot that comes with the sbuild package. We usually add a few packages that help us later and refer to where to create and where to get the content. Here is an example:
$ sudo sbuild-createchroot --include=eatmydata,ccache,gnupg unstable /srv/chroot/unstable-amd64-sbuild http://deb.debian.org/debian
LXD is a powerful container system similar in concept to Docker and other container software.
Install and set up LXD using the standard installation directions.
Create some helper aliases for common LXD tasks:
$ lxc alias add ls 'list -c ns4,user.comment:comment'
$ lxc alias add login 'exec @ARGS@ \
--mode interactive -- bash -xac $@my_user - exec /bin/login -p -f '
Note that the trailing space after the -f
is important. Replace 'my_user'
with 'ubuntu' or whatever username you use in your containers.
Note: For more info, see the LXD documentation
Downloading packages can be a bottleneck, so it helps to set up a local cache:
$ echo 'Acquire::http::Proxy "http://127.0.0.1:3142";' \
| sudo tee /etc/apt/apt.conf.d/01acng
Your user should be a member of the following groups:
- adm
- libvirt
- lxd
- sbuild
- sudo
Ensure you have installed the packages listed above, which will be the trigger to create most of these groups. For group membership to be activated one usually needs to re-login. Then, one can double check group membership via:
$ groups my_user
my_user : my_user adm cdrom sudo dip plugdev lpadmin sambashare \
libvirt sbuild lxd
If any of the following groups is missing for your user you can fix it via
adduser
, like this:
$ sudo adduser my_user lxd
$ sudo adduser my_user sbuild
$ sudo adduser my_user libvirt
Your .profile
should include entries for DEBFULLNAME
and DEBEMAIL
:
export DEBFULLNAME="Your Full Name"
export [email protected]
You can also set the DEBSIGN
variables:
export DEBSIGN_PROGRAM="/usr/bin/gpg2"
export DEBSIGN_KEYID="0xMYKEYHASH"
A fix for "clear-sign failed: Inappropriate ioctl for device":
$ export GPG_TTY=$(tty)
If you're operating from a GUI, this can be useful:
$ eval `dbus-launch --sh-syntax`