Snapを使用する

Posted by 雅楽斎 on Thursday, July 4, 2019

TOC

パッケージ管理のあれこれ

ディストリビューション配布のパッケージ管理のこれまでとこれから

Linuxを含むいわゆるUNIX系OSではプログラムやユーザーのデータをファイルとしてどこに置くかというセオリーがありました。これは近年Filesystem Hierarchy Standard(FHS)として標準化されていますが、それまでも暗黙の了解として大雑把に以下のような運用をされていました。

  • プログラムは/bin、/usr/bin、システム管理コマンドは/sbin、/usr/sbin1

  • 設定ファイルは/etc、ライブラリは/lib、/usr/lib

  • ログ等の可変ファイルは/var

  • NFSで別端末をマウントする場合は/export。別端末のユーザーのホームディレクトリは/export/homeで参照可能。

  • ディストリビューション配布ではないプログラム等は/usr/local配下に配置(bin、lib、etc)

  • システムワイドではなくユーザーが個人でインストールするものは~/bin、~/lib

また、Redhat(rpm、yum)やDebian(dpkg、apt)ではディストリビューションとして配布するプログラムをパッケージとしてまとめ、それぞれに依存を設定することで1コマンドで必要なライブラリやコマンドまでインストールできるようになりました。 但し、ここで新たな課題が生まれ始めます。例えばあるライブラリAが必要なプログラムB、Cがあったと仮定して、

  1. ライブラリAがAPI更新やセキュリティfixなどでライブラリA’に変更したのでパッケージ更新
  2. プログラムBはライブラリA’への対応を終わらせてパッケージを更新
  3. プログラムCはメンテナンスされていない等の理由でライブラリA’に対応できない2ので動作には相変わらずライブラリAが必要

こうなってしまうと、ディストリビューション配布のパッケージとしてはライブラリAとライブラリA’のどちらかを使用、そうでない方を自分でビルドして/usr/local/libに配置、プログラムの実行前に環境変数LD_LIBRARY_PATHを指定してライブラリを直接指定するなどの手順が必要になりますが、そうするともはや自分でメンテナンスするも同然なのでディストリビューション配布のパッケージを使わなくなる、メンテナンス情報を追えなくなる、脆弱性を孕む運用…という悪夢のスパイラルに陥ってしまいかねません。 また、これは元々rpmやdpkgがシステムワイドなパッケージ管理の運用方法であることに由来しています。

これと同様に、同種のRDBMSが基本的に1つしか同時にインストールすることができず、各利用アプリケーションから同一のRDBMSをユーザー名やテーブル名を分けて共用するため、バージョンアップ・バックアップ・リストア・メンテナンス時に共用している他のアプリケーションに影響が及ばないか確認しないといけないという課題も発生しやすいものです。

パッケージ管理の別アプローチ

そこで現在、rpmやdpkgではないパッケージ管理の方法が登場しています。主にAppImage、Flatpak、Snapの3つが知られています。これらの特徴はプログラムの実行に必要なリソース(ライブラリ、場合によっては利用するRDBMS)までまとめたものを1つのパッケージとして配布することで、システムワイドな変更に左右されなくすることが挙げられます。また、これらはディストリビューションに依存せず、同じパッケージを異なるディストリビューションで使用することができます。今回はUbuntuの開発主体であるCanonicalが推進しているSnapを導入します。

Snapを確認する

現在のUbuntu3ではsnapを動作させるためのsnapdパッケージは最初からインストールされていますのでこれといって導入手順はありません。snap listで現在インストールされているsnapパッケージを確認可能です。

$ snap list
Name                 Version                     Rev   Tracking  Publisher      Notes
anbox                4-e1ecd04                   158   beta      morphis        devmode
code                 51b0b281                    6     stable    vscode✓        classic
core                 16-2.38                     6673  stable    canonical✓     core
core18               20190409                    941   -         canonical✓     base
eclipse              2019-03                     40    -         snapcrafters   classic
gnome-3-28-1804      3.28.0-10-gaa70833.aa70833  36    stable    canonical✓     -
gtk-common-themes    0.1-16-g2287c87             1198  stable    canonical✓     -
snap-store           20190228.55a1660            60    -         canonical✓     -
software-boutique    0+git.9cc961a               39    stable/…  flexiondotorg  classic
ubuntu-mate-welcome  17.10.28-749ebc7            313   stable/…  flexiondotorg  classic

Snapパッケージのインストール方法2種類について

snapパッケージはsnapコマンドを使用してインストールしますが、かなり強烈な癖があり、個人的には一旦パッケージをダウンロードしてからインストールした方が良いかなと考えています。4

Snapパッケージは定期的に更新チェックされて自動で更新されるよ(恐怖)

こちらの2017年のフォーラムの記事によれば、現時点では自動更新を止める方法が存在しません。次回の更新タイミングはsnap refresh --timeコマンドで確認することができます。

# snap refresh --time
timer: 00:00~24:00/4
last: n/a
hold: today at 11:35 JST
next: today at 02:42 JST (but held)

とはいえ、常に安定した太い回線を利用できる訳ではないですし、無駄パケット流すのもアホくさいし、更新によって以前の方が良かったとなるのはよくある事なので、個人的にはできれば自動更新は避けたい。

とにかくチェック頻度を下げてなおかつ一番影響がない時にチェックさせる

仕様としてどうしてもチェック&更新をしなければならないならその頻度をギリギリまで減らし、影響のない時にやるべきという前提に立ってこれを実現していきます。

最低頻度としては月1回らしいので、某OSのパッチが定期的にリリースされる毎月第二火曜Patch Tuesday(日本時間水曜の早朝)に合わせます。

# snap set system refresh.timer=wed2,05:00-05:01
# snap refresh --time
timer: wed2,05:00-05:01
last: n/a
hold: today at 11:35 JST
next: today at 10:10 JST (but held)

なんかholdとnextの表示が意味不明ですが(holdは変更なし、とりあえず実行するらしく、nextはsnap setコマンドの実行時刻なので過去の日付になっている)、これで様子見。

更新チェックさせても更新対象にさせない

こちらのドキュメントによれば、

By design, non-devmode snaps installed from the store are automatically updated on a regular cadence.

「storeからインストールした開発モードでないsnapsが定期的に更新される」とのことなので、それならばstoreからインストールしてないことにすればよい。となり、どうすれば一番めんどくさくなくstore以外からインストールできるか。確実そうなのは一旦ダウンロードしてからインストールするという何ともはやな方法。

Snapパッケージを(storeから)インストールする

ここではAtomエディタをインストールします。

# snap install atom
error: This revision of snap "atom" was published using classic confinement and
       thus may perform arbitrary system confined to, which may put your system at risk.
       
       If you understand and want to proceed repeat the command including --classic.

エラーとなりますが、これはインストールするsnapパッケージからシステムリソースへのアクセスを要求する場合のエラーです。例えばAtomエディタであれば、ユーザーのディレクトリ内にあるファイルを開く必要があるなどでシステムリソースを変更するので、それを許容するのであれば–classicを付けてインストールしてね、という意味になろうかと思います。

当然のこと、アクセスする必要がないのであれば無駄にシステムリソースへアクセスさせるのは何らかの脆弱性を突かれた時にシステムへ影響を及ぼす可能性が高まりますのでない方が望ましいのは間違いないのですが、そうしてしまうとテキストエディタはほぼ何もできなくなってしまうでしょう。結局のところ、インストールする人間がインストールするパッケージをどこまで信用するかという点にかかっていると考えます。逆に言えば、–classicが不要なsnapパッケージはシステムリソースへアクセスができないため、悪さができる可能性があまりない5とも言えます。

また、–classicオプションを付けてインストールが必要になるパッケージはそれなりにあるので、各々インストール時に確認しましょう。

# snap install atom --classic

Snapパッケージをダウンロードしてからインストールする

一旦snapパッケージをダウンロードしてからインストールするとStoreからインストールされた扱いではなくなりそうです。二度手間にはなりますが、複数の端末で同じアーキテクチャの同じパッケージをインストールする場合は都度パッケージのダウンロードを避けられるため、パケットと時間の節約にもできます。6

ここではGUIでsnapパッケージを検索したりできるネイティブアプリであるSnap Storeをダウンロードしてからインストールしてみます。

# snap download snap-store
Fetching snap "snap-store"
Fetching assertions for "snap-store"
Install the snap with:
   snap ack snap-store_60.assert
   snap install snap-store_60.snap

snap downloadコマンドはインストールを伴わないので一般ユーザでも実行可能です。ダウンロードが終わると実行した場所に

  • snap-store_60.assert
  • snap-store_60.snap

の2ファイルがダウンロードされます。後者の.snapはsnapパッケージファイルそのもので、これをインストールするんですが、ローカルにあるsnapパッケージをインストールする前に前者の.assertファイルを承認する必要があります。7

では.assertファイルを承認してsnap-storeをインストールすると…

# snap ack snap-store_60.assert
# snap install snap-store_60.snap
Download snap "core18" (941) from channel "stable"             0% 23.1kB/s 40.5m

という訳で、snap-storeが依存している別のcore18というsnapパッケージをダウンロードし始めたのでこれを中断、こっちも承認、インストールしてからsnap-storeを改めてインストールします。

# snap download core18
Fetching snap "core18"
Fetching assertions for "core18"
Install the snap with:
   snap ack core18_941.assert
   snap install core18_941.snap
# snap ack core18_941.assert
# snap install core18_941.snap 
core18 20190409 from Canonical✓ installed
# snap install snap-store_60.snap

手動でsnapパッケージを更新する

# snap refresh

特定のsnapパッケージだけを更新する場合は最後にパッケージ名を指定します。

# snap refresh パッケージ名

こんなsnapパッケージがあるよ

GUI環境でsnapパッケージを検索したりする場合、snap findコマンドが使用可能ですが、もっとインタラクティブな検索をしたい場合はSnap Storeをインストールするとよいと思います。

ここではこんなパッケージがあるよという紹介をしたいと思います。

これらを比較していくと、いくつかの性質がパッケージ毎にあることがわかります。

作者の違い

snapパッケージの作者に認証済みマーク(✓)の入っている作者とそうでない作者があります。VLCのように元々の作者が配布しているものがあればそれを使うのが自然でしょう。もし元々の作者以外が配布しているパッケージしかない場合、信頼できる作者であれば利用するという運用になるのではないでしょうか。

例として挙げた中ではSnapcraftersはsnapパッケージを公開するために必要なリソースを提供するグループで、これを利用して公開されているパッケージが数多くあります。

https://forum.snapcraft.io/t/join-snapcrafters/1325

また、VS CodeのようにMicrosoftがsnapパッケージを提供しているけどもユーザービルドとしてSnapcraftersが提供するものもあります。8

アーキテクチャの違い

一覧として書いたものは基本的にamd64でパッケージがあるものですが、Snap自体はアーキテクチャの縛りがないものなので、例えば次のパッケージはarm64版も利用可能です。Syncthing、Chromium、Notepad-Plus-Plus。


  1. /usr配下と/直下の違いについては元々緊急時1のシステムメンテナンスに必要なものは/直下、そうでない一般コマンドは/usr配下に置く等の違いがありましたが、Linuxにおいてはシンボリックリンクで同じ場所を参照したりと曖昧な運用もされていました [return]
  2. 特に互換性のない変更が入ってしまうとかなり困難 [return]
  3. 18.04LTSと19.04で確認しています。 [return]
  4. インストールするパッケージのものにも依りますが。セキュリティを重視したいものは直接インストールがいいと思います。 [return]
  5. snap及びAppArmorなど依存技術の脆弱性を突かれない限りできない [return]
  6. 巨大なパッケージの場合特に [return]
  7. パッと見た感じ、パッケージの署名の様です。 [return]
  8. SnapcraftersのVS Codeの説明ではMicrosoftのビルドに誘導していますが、現在でもSnapcrafters側のgithubも更新されています。https://github.com/snapcrafters/vscode/commit/c4f909b11556eea4a9421f1161131280c2f142d0 [return]

comments powered by Disqus