Ubuntu 26.04 講座 / Snap インストール・権限・アップデートを理解する

Ubuntu ServerのSnapは、コマンドラインでインストール済み・提供者・チャンネル・接続権限・更新状況を確認して管理します。APTのDebパッケージとは別にインストールされるため、同じプログラム名を使っても実行パス・インストール形式・データの場所を区別する必要があります。

アプリ形式と提供者から確認する

snap info アプリ名 で提供者・説明・チャンネルを読み、snap list でインストール済みの名前・バージョン・追跡チャンネルを照合します。実行パスは command -v コマンドで確認します。名前が同じだからといって、メンテナ・更新経路・設定場所まで同じだと判断しません。

Ubuntu Serverのパッケージ管理ドキュメントでAPTとSnapのインストール・管理経路を確認できます。

snap list
snap changes
snap refresh --time

snap listの実際のインストール名・バージョン・追跡チャンネルを記録します。snap changesはインストール・更新など作業履歴を表示します。aptで更新がないからといって、すべてのSnapアプリも最新状態だと結論づけません。

小さいアプリでインストールと実行を確認する

snap info hello-world
sudo snap install hello-world
hello-world

実習前に hello-world が既にインストールされているか確認し、既存のインストールであれば任意に削除したりチャンネルを変更したりしません。インストールの提案と提供者を読んだ後、実行結果を確認します。実行ファイルが PATH に見えない場合は、新しいログインセッションと /snap/bin のパスを確認します。

チャンネルと隔離レベルを理解する

チャンネルはトラック・リスク・ブランチでバージョンの流れを指定でき、stable・candidate・beta・edge が常に同じ安定性を意味するわけではありません。一般使用では提供者が推奨する安定チャンネルを優先し、チャンネルを切り替える前に現在のチャンネルとデータのバックアップを記録します。

strict・classic・devmode は隔離条件が異なります。classic インストールが要求される場合、なぜstrict の隔離で提供されないかを確認します。インストールエラーをなくすために --classic や --devmode を任意に付け足しません。

接続権限と失敗原因を確認する

権限を調査する実際のアプリ名を snap list で選び、snap connections アプリ名 で接続されているインターフェースを確認します。例えば外部メディアへのアクセス問題は、アプリの接続権限と 実際のマウント・ファイル権限を併せて確認する必要があります。すべてのインターフェースを一度に接続しません。

snap info アプリ名、snap connections アプリ名と提供者のドキュメントで必要なインターフェースを確認した後、最小限だけ接続して新しいアクセスを試します。問題解決後は、今回追加した接続だけを解除できるように元の状態を記録します。インターフェース接続だけでホストのファイル権限が変わるわけではありません。

宣言されたインターフェースを確認して新しい接続だけを復元する

既にインストールされているサーバ用Snapで実際に必要なインターフェースを提供者のドキュメントで確認します。snap connections アプリ名の Plug・Slot 列と snap interface インターフェース名の出力を照合します。以下のスクリプトには、その出力の正確な SNAP:PLUG と SLOT だけを渡します。宣言されたプラグがない場合は、練習のために新しい権限を推測して接続しません。

全部を ~/test-snap-interface.sh に保存し、bash ~/test-snap-interface.sh 実際のSNAP:PLUG 実際のSLOT で実行します。既存の接続には手を付けず、新しい接続についてだけ、別のターミナルで提供者が説明する機能を試した後、Enterで解除します。機密性の高いシステム資源へのアクセスを許可するインターフェースは、運用サーバでは単純な練習用として接続しません。

set -eu
if [ "$#" -ne 2 ]; then
    printf 'Usage: bash test-snap-interface.sh SNAP:PLUG SLOT\n' >&2; exit 2
fi
plug=$1
slot=$2
app=${plug%%:*}
case "$plug" in *:*) ;; *) printf 'Use the exact Plug from snap connections.\n' >&2; exit 2 ;; esac
case "$slot" in *:*) ;; *) printf 'Use the exact Slot from snap connections.\n' >&2; exit 2 ;; esac
snap list "$app"
connections=$(LC_ALL=C snap connections "$app")
printf '%s\n' "$connections"
previous_slot=$(printf '%s\n' "$connections" | awk -v p="$plug" '$2 == p {print $3}')
case "$previous_slot" in
    -) ;;
    '') printf 'Declared plug not found; stop.\n' >&2; exit 1 ;;
    *) printf 'Already connected to %s; preserve it.\n' "$previous_slot"; exit 0 ;;
esac
restore() {
    original_status=$?
    trap - EXIT HUP INT TERM
    if ! connections=$(LC_ALL=C snap connections "$app"); then
        printf 'Cannot inspect the connection; verify restoration manually.\n' >&2; exit 1
    fi
    current_slot=$(printf '%s\n' "$connections" | awk -v p="$plug" '$2 == p {print $3}')
    case "$current_slot" in
        "$previous_slot") ;;
        "$slot")
            if ! sudo snap disconnect "$plug" "$slot"; then
                printf 'Restoration failed; inspect the connection.\n' >&2; exit 1
            fi
            ;;
        *) printf 'Unexpected connection state; inspect before disconnecting.\n' >&2; exit 1 ;;
    esac
    if ! connections=$(LC_ALL=C snap connections "$app"); then
        printf 'Cannot verify restoration; inspect the connection.\n' >&2; exit 1
    fi
    printf '%s\n' "$connections"
    restored_slot=$(printf '%s\n' "$connections" | awk -v p="$plug" '$2 == p {print $3}')
    if [ "$restored_slot" != "$previous_slot" ]; then
        printf 'Original connection state was not restored.\n' >&2; exit 1
    fi
    exit "$original_status"
}
trap restore EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM
sudo snap connect "$plug" "$slot"
snap connections "$app"
read -r -p 'Run your documented app test in another terminal; press Enter to restore: ' answer

未接続 - が実際のスロットに変わるか確認し、終了後にsnap connectionsでアプリ名を使用して元の状態を再確認します。スクリプトは今回要求したスロットのみを解除し、元の未接続状態に戻ったかを再度確認します。解除または状態の確認が失敗した場合は0以外のコードで終了し、実習自体が失敗した場合はその終了コードも保持します。Ctrl+C・終了信号でも復元を試みますが、電源オフ・強制終了までは保証されないため、作業記録に元のプラグ・スロットと復元コマンドを残します。ホストファイルの権限およびサービスアクセスポリシーはインターフェース接続とは別に点検します。

Snapの公式使用ガイドで接続・解除コマンドを確認できます。

更新・復元・削除後のデータ確認

sudo snap refresh アプリ名で該当アプリの更新をリクエストできますが、使用中のアプリとサービスへの影響を先に確認します。以前のリビジョンに戻す機能はデータ形式の逆互換性まで保証しないため、バックアップなしで万能復元として使用しません。

新しくインストールした練習アプリだけを整理する場合は、sudo snap remove hello-worldを使用します。一般的な削除で作成される可能性のある自動データスナップショットは、snap savedで確認し、保存ポリシーを別途判断します。アプリの削除、スナップショットの保管、ホームディレクトリ内のすべてのファイル削除は同じ作業ではありません。