The Ubuntu packaging doc and Gert van Dijk's tutorial are better than this, but I found them hard to follow the first few times, so I documented one run through the process, warts and all.
$ lxc launch ubuntu:18.04 ppa-ubu1804 $ lxc exec ppa-ubu1804 bash # apt update # apt dist-upgrade # su ubuntu $ gpg --gen-key ... gpg: agent_genkey failed: Inappropriate ioctl for device : D'oh! gpg is confused by the virtual environment. Give it a hint. $ export GPG_TTY=$(tty) $ gpg --gen-key .. gpg: agent_genkey failed: No such file or directory : D'oh! gpg is confused by lack of an agent. Set one up. $ cat > .gnupg/gpg.conf <<_EOF_ use-agent pinentry-mode loopback _EOF_ $ cat > ~/.gnupg/gpg-agent.conf <<_EOF_ allow-loopback-pinentry _EOF_ $ echo RELOADAGENT | gpg-connect-agent OK $ gpg --gen-key ... Real name: Dan Kegel Email address: dank@kegel.com ... Enter passphrase: ... public and secret key created and signed pub rsa3072 2019-03-23 [SC] [expires: 2021-03-22] 841D18F50B873C06B7690B6F50A93FF65680EA47 ... $ gpg -a --export-secret-keys > myprivatekeys.asc $ gpg --export-ownertrust > otrust.txt $ gpg --send-keys --keyserver keyserver.ubuntu.com 841D18F50B873C06B7690B6F50A93FF65680EA47 : Not sure if following line works right away, but it's way faster then : visiting the web site to check. $ gpg --keyserver hkp://keyserver.ubuntu.com --search-key dank@kegel.com gpg: data source: http://91.189.89.49:11371 (1) Dan Kegel <dank@kegel.com> 3072 bit RSA key 50A93FF65680EA47, created: 2019-03-23, expires: 2021-03-22 ...Once gpg --search-key can find your key on the keyserver, you're ready to move on to the next step. But first save myprivatekeys.asc and otrust.txt somewhere safe and permanent (like google drive?), and save the passphrase in your master password file! In a month you'll need that passphrase again, and if you're like me, you'll have forgotten it utterly. e.g. on the host system:
$ mkdir my-gpg-key-backup $ lxc file pull ppa-ubu1804/home/ubuntu/myprivatekeys.asc my-gpg-key-backup $ lxc file pull ppa-ubu1804/home/ubuntu/otrust.txt my-gpg-key-backup
Next, register your GPG key with your launchpad.net account as described in the Ubuntu packaging doc. It will send you an email with an encrypted block; copy that block with your mouse and paste it into a file, then decrypt it (on a system with the GPG key you created) using gpg --decrypt. That will tell you how to complete the registration.
Finally, copy the ~/.ssh/id_rsa you registered with Launchpad to the ubuntu user's ~/.ssh directory, e.g.
$ lxc file push .ssh/id_rsa ppa-ubu1804/home/ubuntu/.ssh/
$ sudo apt-get install ubuntu-dev-tools apt-file $ echo DSCVERIFY_KEYRINGS="/etc/apt/trusted.gpg:/usr/share/keyrings/debian-maintainers.gpg:~/.gnupg/pubring.gpg" > ~/.devscripts $ echo 'export DEBEMAIL="dank@kegel.com"' >> ~/.profile $ echo 'export DEBFULLNAME="Dan Kegel"' >> ~/.profile $ . ~/.profile $ cat > ~/.dput.cf <<_EOF_ [python-fixes] fqdn = ppa.launchpad.net incoming = ~dank/ubuntu/python-fixes/ method = sftp login = dank ssh_config_options = IdentityFile ~/.ssh/id_rsa_launchpad _EOF_
$ sudo sed -i 's/^# deb-src/deb-src/' /etc/apt/sources.list $ sudo apt update $ sudo apt build-dep python-pip $ apt source python-pip $ wget https://github.com/pypa/pip/commit/018f03aab448231462b6c013a65d60a35e06e65a.patch $ cd python-pip-9.0.1 $ cd pip : Note: first hunk won't apply, that's ok $ patch -p4 < ~/018*patch $ cd .. : dch: Edit debian/changelog $ dch -i : dpkg-source: adds the code change as a patch in debian/patches : Be sure to trim unrelated crud from the patch $ dpkg-source --commit dpkg-source: info: local changes detected, the modified files are: python-pip-9.0.1/pip/wheel.py Enter the desired patch name: pypa-pip-issue-5366-crash.patch : Back up the source directory, as debuild is sometimes destructive $ cp -a . ../python-pip-9.0.1.bak $ debuildVerify that the built package works, then do a source-only build, and upload the changes file to your PPA. e.g.
$ cd .. $ sudo dpkg -i python-pip*.deb $ ... $ mv python-pip-9.0.1 python-pip-9.0.1.dirty $ cp -a python-pip-9.0.1.bak python-pip-9.0.1 $ cd python-pip-9.0.1 $ debuild -S $ dput ppa:dank/python-fixes python-pip_9.0.1-2.3~ubuntu2_amd64.changes
After a few uploads, if you're lucky, the upload will be accepted, and the build should show up in your ppa page (e.g. https://launchpad.net/~dank/+archive/ubuntu/python-fixes).
Starting from the outer host again, here's the one-time setup:
$ lxc launch ubuntu:16.04 ppa-ubu1604 $ lxc file push my-gpg-key-backup/myprivatekeys.asc ppa-ubu1604/home/ubuntu/myprivatekeys.asc $ lxc file push my-gpg-key-backup/otrust.txt ppa-ubu1604/home/ubuntu/otrust.txt $ lxc file push .ssh/id_rsa ppa-ubu1604/home/ubuntu/.ssh/id_rsa $ lxc exec ppa-ubu1604 bash # apt update # apt dist-upgrade # su ubuntu $ gpg --import myprivatekeys.asc $ gpg --import-ownertrust otrust.txt $ sudo apt-get install ubuntu-dev-tools apt-file $ echo DSCVERIFY_KEYRINGS="/etc/apt/trusted.gpg:/usr/share/keyrings/debian-maintainers.gpg:~/.gnupg/pubring.gpg" > ~/.devscripts $ echo 'export DEBEMAIL="dank@kegel.com"' >> ~/.profile $ echo 'export DEBFULLNAME="Dan Kegel"' >> ~/.profile $ . ~/.profile $ cat > ~/.dput.cf <<_EOF_ [python-fixes] fqdn = ppa.launchpad.net incoming = ~dank/ubuntu/python-fixes/ login = dank ssh_config_options = IdentityFile ~/.ssh/id_rsa_launchpad _EOF_ $ sudo sed -i 's/^# deb-src/deb-src/' /etc/apt/sources.list $ sudo apt updateAnd here's fixing the package of interest:
$ sudo apt build-dep python-pip $ apt source python-pip $ wget https://github.com/pypa/pip/commit/018f03aab448231462b6c013a65d60a35e06e65a.patch $ cd python-pip-8.1.1 $ cd pip $ patch -p4 < ~/018*patch $ cd .. : dch: Edit debian/changelog $ dch -i : dpkg-source: adds the code change as a patch in debian/patches : Be sure to trim unrelated crud from the patch $ dpkg-source --commit $ cp -a . ../python-pip-8.1.1.bak $ debuild $ cd .. $ ... test it ... $ mv python-pip-8.1.1 python-pip-8.1.1.dirty $ cp -a python-pip-8.1.1.bak python-pip-8.1.1 $ cd python-pip-8.1.1 $ debuild -S $ cd .. $ dput ppa:dank/python-fixes python-pip_8.1.1-2ubuntu0.5_source.changes