add-apt-repositoryを使わないでPPAを追加する

Dockerコンテナ内で、足りないパッケージをインストールしようとしたところ、

  • apt searchでリストに出てこない
  • リポジトリを追加しようとしたが、add-apt-repositoryがインストールされてない

などの理由ではまってしまいました。add-apt-repositoryコマンドは、

> sudo apt install software-properties-common

を実行すると、インストールされます。そして、リポジトリ(例えばppa:deadsnakes/ppa)を以下のように追加してアップデートすれば、パッケージが見つかってインストールできます。通常はこれで良いのです。

> sudo add-apt-repository ppa:deadsnakes/ppa
> sudo apt update

しかし、software-properties-commonは余計なアプリが大量に含まれており相当大きなパッケージなのと、これを入れると自動的にpython3.6が依存しているためインストールされてしまいます。

実はpython3.8環境を作成しようとしていた時に、pipをインストールしようとしてハマってしまったことが発端だったのですが、余計なものはインストールしたくないです。

> curl -kL https://bootstrap.pypa.io/get-pip.py | python
:
  File "/tmp/tmpvbf3jy3a/pip.zip/pip/_internal/cli/main_parser.py", line 7, in <module>
  File "<frozen zipimport>", line 259, in load_module
  File "/tmp/tmpvbf3jy3a/pip.zip/pip/_internal/cli/cmdoptions.py", line 19, in <module>
ModuleNotFoundError: No module named 'distutils.util'

上記のエラーは、distutilsのパッケージをインストールすると解消されるが、python3.6などの古いバージョンに依存しているので、インストールすると望んでない古いPythonまでインストールされてしまう。python3.8-distutilsをインストールすればいいが、リストに表示されない。

> apt install python3-distutils

なので、software-properties-commonをインストールせずに、正規の方法でリポジトリ登録を行わないで、リポジトリを追加する方法をいろいろ調べて試したことを記録しておく。

手動でリポジトリを追加する

題材として、上記でも触れたPythonの最新の開発リポジトリを追加してみる。

何もしてない状態(python3.8はインストール済み)で、python3.8-distutilsを探してみてもリストに表示されないことがわかる。

> apt search python3.8-dist
:
python3.8/bionic-updates,now 3.8.0-3~18.04 amd64 [インストール済み]
  Interactive high-level object-oriented language (version 3.8)

python3.8-dbg/bionic-updates 3.8.0-3~18.04 amd64
  Debug Build of the Python Interpreter (version 3.8)

python3.8-dev/bionic-updates 3.8.0-3~18.04 amd64
  Header files and a static library for Python (v3.8)

python3.8-examples/bionic-updates 3.8.0-3~18.04 all
  Examples for the Python language (v3.8)

python3.8-minimal/bionic-updates,now 3.8.0-3~18.04 amd64 [インストール済み、自動]
  Minimal subset of the Python language (version 3.8)

python3.8-venv/bionic-updates 3.8.0-3~18.04 amd64
  Interactive high-level object-oriented language (pyvenv binary, version 3.8)
:

まず、https://launchpad.net/ で目的のリポジトリを検索する。

python-repo001

リポジトリのページにあるTechnical details about this PPAを選択すると、下図のようにリポジトリのURLやキーが表示される。

python-repo002a

# url
deb http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic main 
deb-src http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic main
# key
4096R/F23C5A6CF475977595C89F51BA6932366A755776
# Fingerprint
F23C5A6CF475977595C89F51BA6932366A755776

Signing keyのリンクを選択すると、キーが表示される。rsa4096/の後ろのキーが公開鍵になる。

python-repo003

公開鍵をapt-keyで登録しておく。鍵を登録しておかないと、リポジトリを追加してそこからパッケージをダウンロードしようとするとエラーになる(強制的にやることも可能だが)

> apt-key adv --keyserver keyserver.ubuntu.com --recv f23c5a6cf475977595c89f51ba6932366a755776

Executing: /tmp/apt-key-gpghome.WfzlxgCqYh/gpg.1.sh --keyserver keyserver.ubuntu.com --recv f23c5a6cf475977595c89f51ba6932366a755776
gpg: 鍵BA6932366A755776: 公開鍵"Launchpad PPA for deadsnakes"をインポートしました
gpg: 処理数の合計: 1
gpg:               インポート: 1

次にリポジトリのURLを以下のように、/etc/apt/sources.list.d/に適当なファイルで追加したあとで、apt updateで更新する

> echo "deb http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic main " > /etc/apt/sources.list.d/python.list
> echo "deb-src http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic main" >> /etc/apt/sources.list.d/python.list

> cat /etc/apt/sources.list.d/python.list
deb http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic main
deb-src http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic main

> apt update

取得:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
取得:2 http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic InRelease [15.9 kB]
ヒット:3 http://archive.ubuntu.com/ubuntu bionic InRelease
取得:4 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]
取得:5 http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic/main Sources [6,454 B]
取得:6 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]
取得:7 http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic/main amd64 Packages [36.4 kB]
311 kB を 2秒 で取得しました (129 kB/s)
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了

もう一度、検索してみると、python3.8関連のパッケージがいくつか増えており、目的のpython3.8-distutilsがインストール可能になる。

> apt search python3.8
:
python3.8-distutils/bionic 3.8.0-1+bionic2 all
  distutils package for Python (version 3.8)
:

> apt install python3.8-distutils