apt upgradeとfull-upgradeで違う例

aptにはfull-upgradeなるサブコマンドがあります。説明を読んでもupgradeとどう違うのか、実際どういうケースを想定しているのか、よく分かりませんよね。

full-upgrade (apt-get(8))
full-upgrade はアップグレードの機能を実行しますが、システム全体をアップグレードするために必要とされる場合には、現在インストール済みのパッケージを削除することができます。

man apt

今回はUbuntu 22.04上で、具体例(1例だけ)を挙げて、それを検証してみました。

目的

apt upgradeapt full-upgradeで挙動の異なる状況を見つけること

背景

普段手動で実施している更新はapt upgradeなのですが、LubuntuのGUI上で使用されているMuonパッケージマネージャーが行う自動更新がどうやらfull-upgradeだったからです。何が起こるか分からないものをOKするのも気が引けるので、せめて一例だけでもと調べてみた次第です。

調査/検討

手掛かり

正直真面目に調べるつもりもないので、ソースコードまでは追いません。

手掛かりは冒頭に示したManual Pageのこれだけです。

full-upgrade (apt-get(8))
full-upgrade はアップグレードの機能を実行しますが、システム全体をアップグレードするために必要とされる場合には、現在インストール済みのパッケージを削除することができます。

man apt

考えてみる

aptはupgrade時、依存関係を壊さないように更新していきます。例えばAというパッケージがBというパッケージのバージョン1〜バージョン2に依存していた場合、たとえリポジトリ上にBのバージョン3があってもAが動かなくなると困るので、Bのバージョンを2までしか上げません(upgradeの場合)。

full-upgradeではAというパッケージを消してでもBのバージョンを3まで上げてしまうのではないか?と予想します。通常このようなケースはパッケージA側もBのバージョン3以上に対応する新しいバージョンが用意されるからです。

どのような状況ならそんなことをしたいか

ではどういう状況で消したくなるのでしょう?

答えは「ディストリビューション全体のバージョンを上げるとき」(例: 22.04LTSから22.10など)です。

Ubuntuの公式リポジトリだけで作業してる人なら問題ないのですが、他のリポジトリを使っていると、特定のソフトのために依存している公式リポジトリのライブラリのバージョンを上げられない場合もあります。すると、公式リポジトリの他の依存アプリのバージョンも上げられなくなり、公式リポジトリのソフトのバージョンを最新にできません。

公式リポジトリのソフトのバージョンを最新に上げないと、22.04LTSから22.10などのリリースバージョンを上げる際には問題が発生しやすくなります。リリースバージョンを上げる際には他のリポジトリからインストールされたソフトは全てremoveされ、リポジトリも一旦全てコメントアウトされます。なので、この状況では、全パッケージを最新にすることを最優先にして、それを阻害するパッケージを削除することは問題ないわけです。

apt dist-upgrade

実はこの機能、aptコマンドの非interactive版、apt-getコマンドでは大昔からdist-upgradeとして用意されていました。そしてmanには書いていませんが、apt-get dist-upgradeapt full-upgradeと等価だそうです。

https://askubuntu.com/questions/770135/apt-full-upgrade-versus-apt-get-dist-upgrade

検証すべき状況

  1. 特定のパッケージを1つバージョンダウンします
  2. バージョンダウンした状態のパッケージに依存するパッケージを作成してインストールします

この状況でupgradeとfull-upgradeを試せばよいでしょう。

検証

特定のパッケージを1つバージョンダウン

今回はみんな大好きVisual Studio Codeを使います。何でもいいのですが、複数のバージョンを置いているリポジトリは外部にしかなさそうなので。まずは現在のバージョンを確認。

$ apt list -a code
一覧表示...
code/stable,now 1.85.1-1702462158 amd64 [インストール済み]
code/stable 1.85.0-1701902998 amd64
code/stable 1.84.2-1699528352 amd64
code/stable 1.84.1-1699275408 amd64
code/stable 1.84.0-1698839401 amd64
...
$

そしてバージョンダウン。

sudo apt install code=1.85.0-1701902998

依存パッケージを作成してインストール

パッケージ作成

説明は面倒なので一気に作成します。

mkdir -p helloworld/DEBIAN
cat >helloworld/DEBIAN/control <<EOF
Package: helloworld
Version: 0.1
Maintainer: someone
Architecture: all
Description: hello world
Depends: code(= 1.85.0-1701902998)
EOF
mkdir -p helloworld/usr/local/bin
cat >helloworld/usr/local/bin/helloworld.sh <<EOF
#!/bin/sh
echo 'Hello, world!'
EOF
chmod 755 helloworld/usr/local/bin/helloworld.sh
dpkg-deb --build helloworld

Hello, world!するシェルスクリプトを/usr/local/binに置くだけのパッケージです。面倒なのでownerとかも変えません。すぐ消すダミーパッケージなので。

重要なのはDepends: code(= 1.85.0-1701902998)の部分です。Visual Studio codeの1.85.0だけに固定で依存しています。

インストール

sudo apt install ./helloworld.deb

試しに実行してみます。

$ helloworld.sh 
Hello, world!
$

upgradeとfull-upgradeの違い

upgrade

$ sudo apt upgrade
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了        
状態情報を読み取っています... 完了        
アップグレードパッケージを検出しています... 完了
Get more security updates through Ubuntu Pro with 'esm-apps' enabled:
...
Learn more about Ubuntu Pro at https://ubuntu.com/pro
以下のパッケージは保留されます:
  code systemd-hwe-hwdb
アップグレード: 0 個、新規インストール: 0 個、削除: 0 個、保留: 2 個。
$

(helloworldパッケージの嘘依存情報のため、)codeのパッケージが保留されてアップグレードが滞っています。

full-upgrade

$ sudo apt full-upgrade
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了        
状態情報を読み取っています... 完了        
アップグレードパッケージを検出しています... 完了
Get more security updates through Ubuntu Pro with 'esm-apps' enabled:
...
Learn more about Ubuntu Pro at https://ubuntu.com/pro
以下のパッケージは「削除」されます:
  helloworld
以下のパッケージは保留されます:
  systemd-hwe-hwdb
以下のパッケージはアップグレードされます:
  code
アップグレード: 1 個、新規インストール: 0 個、削除: 1 個、保留: 1 個。
96.0 MB のアーカイブを取得する必要があります。
この操作後に追加で 0 B のディスク容量が消費されます。
続行しますか? [Y/n]

ここまでで既に成功です。helloworldパッケージは削除されて、codeがアップグレードされるそうです。yで続行します。

続行しますか? [Y/n] y
取得:1 https://packages.microsoft.com/repos/code stable/main amd64 code amd64 1.85.1-1702462158 [96.0 MB]
96.0 MB を 11秒 で取得しました (8,979 kB/s)                                                                                                                                                 
(データベースを読み込んでいます ... 現在 310434 個のファイルとディレクトリがインストールされています。)
helloworld (0.1) を削除しています ...
dpkg: 警告: helloworld の削除中、ディレクトリ '/usr/local' が空でないため削除できませんでした
(データベースを読み込んでいます ... 現在 310433 個のファイルとディレクトリがインストールされています。)
.../code_1.85.1-1702462158_amd64.deb を展開する準備をしています ...
code (1.85.1-1702462158) で (1.85.0-1701902998 に) 上書き展開しています ...
code (1.85.1-1702462158) を設定しています ...
shared-mime-info (2.1-2) のトリガを処理しています ...
mailcap (3.70+nmu1ubuntu1) のトリガを処理しています ...
desktop-file-utils (0.26-1ubuntu3) のトリガを処理しています ...
$

なんか警告が出ていますが、適当パッケージなので見逃します(問題はない)。

まとめ

full-upgradeはパッケージを最新にするために必要なら依存パッケージを削除する、という例を検証出来ました。

未分類linux,ubuntu

Posted by first_user