Ubuntu Weekly Recipe

第654回 snapパッケージング入門

この記事を読むのに必要な時間:およそ 8 分

サンプルパッケージの作成

snapcraft initコマンドを使うと,パッケージのメタデータであるsnapcraft.yamlを生成してくれます。何かパッケージを作るなら,まずはここから始めると良いでしょう。

$ mkdir snaptest && cd snaptest
$ snapcraft init
Created snap/snapcraft.yaml.
Go to https://docs.snapcraft.io/the-snapcraft-format/8337 for more information about the snapcraft.yaml format.
$ ls -R
.:
snap

./snap:
snapcraft.yaml

作られたのはsnap/snapcraft.yamlだけです。ここにパッケージングに関するすべての情報を記載していきます。現時点での内容を確認しましょう。

$ cat snap/snapcraft.yaml
name: my-snap-name # you probably want to 'snapcraft register <name>'
base: core18 # the base snap is the execution environment for this snap
version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'
summary: Single-line elevator pitch for your amazing snap # 79 char long summary
description: |
  This is my-snap's description. You have a paragraph or two to tell the
  most important story about your snap. Keep it under 100 words though,
  we live in tweetspace and your description wants to look good in the snap
  store.

grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots

parts:
  my-part:
    # See 'snapcraft plugins'
    plugin: nil

逐一コメントが入っているので,比較的把握しやすいはずです。詳細はsnapcraft formatのページを参照してください。

  • name:パッケージの名前です。ちなみに構築時に作られる仮想マシンも同じ名前になります。小文字の英数字およびハイフンのみ利用可能で,Snap Storeで配布する際は一意である必要があります。snap findでマッチするパッケージ名がないか確認しておくと良いでしょう。
  • base:後述するベースシステムになるsnapパッケージを指定します。
  • version:パッケージのバージョンです。最大32文字で,YAML的に文字列として認識させるためにシングルクオートでくくることをおすすめします。ちなみに「git」を記述するとgit describeの結果がバージョンになります。
  • summarysnap find時に表示される78文字以内の概要です。
  • descriptionsnap info時に表示されるより詳細な説明です。概要だけでなく,そのパッケージの利用方法などを説明することもよくあります。
  • grade:そのパッケージの状態を示します。完全な開発版ならdevelを,一般的に利用できる状態ならstableを記述します。
  • confinement:ホストのリソースへのアクセス権限に関する情報を記述します。strictがsnapの通常状態でリソースへのアクセスが制限され,ユーザーによる許可が必要になります。classicはホストのリソースの利用を前提としたパッケージに使われます。classicを指定するためにはSnap Store側でレビューを受けた上で特別な許可が必要です。devmodeは開発時に使うモードで,原則としてリソースへのアクセスは制限されません。devmodeではSnap Store経由の公開はできません。
  • parts:実際にパッケージをビルドする手順やコンテンツの場所などを記述します。

base snapはそのsnapパッケージが動くベースシステムを提供するsnapパッケージです。snapパッケージは依存関係を原則としてすべてパッケージに内包するシステムですが,libcのように「ほとんどすべてのsnapパッケージで必要とするコンテンツ」までsnapパッケージごとに保持するのは不経済です。そこでbase snapで必要最低限のシステムを提供し,すべてのsnapパッケージはいずれかのbase snapに依存することになっています。2021年2月時点で,次のようなbase snapが存在します。

  • core20:Ubuntu 20.04 LTSのパッケージを元に作られたbase snap
  • core18:Ubuntu 18.04 LTSのパッケージを元に作られたbase snap
  • core:Ubuntu 20.04 LTSのパッケージを元に作られたbase snap
  • bare:何も提供しないbase snap

core20は2021年2月に正式リリースされたばかりのbase snapですUbuntu Weekly Topics 2021年2月5日号⁠。新規にsnapパッケージを作るならcore20を使いたいところですが,いくつかの拡張機能はまだcore20をサポートしていないため,今の段階ではcore18を使うことをおすすめします。

bareはたとえばすべてのライブラリを静的にリンクした単一のバイナリのみを提供するようなsnapパッケージに使われます。ただ,結局のところどんなツールもなんやかんやのシステムライブラリやファイルが必要になるため,使いどころが難しいです。Go言語のようなシングルバイナリ化しやすい言語のツールをsnap化するなら使えるかもしれません。

具体的なパッケージングの情報はpartsに記載します。partsは辞書形式になっており,複数のツールを同梱する場合はその数だけ情報を記述していきます。

parts:
  my-part:
    # See 'snapcraft plugins'
    plugin: nil

今回の例だと作るのはmy-partという名前の一個のソフトウェアだけです。一般的なビルド方法はsnapcraft pluginsとして共通化しています。たとえばautotoolsに対応しているならautotoolsプラグインを,pipでインストールするタイプならpythonプラグインを使えば,snapcraft.yamlの記述が楽になります。

今回は「何も入っていない空のパッケージ」を作るため,plugin: nilとしています。

これで「必要最低限の設定」は完了しました。実用的なsnapパッケージを作る場合は,ここからsnapcraft.yamlにいろいろな情報を追記していくことになります。しかしながら,その対応は次回以降に後回しすることにして,今回はこのままパッケージをビルドしてみましょう。

サンプルパッケージのビルド

snapパッケージのビルドはシンプルで,次のコマンドを実行するだけです。

$ snapcraft --debug
Launching a VM.                                                                                                                               Launched: snapcraft-my-snap-name
(snip)
Pulling my-part
+ snapcraftctl pull
Building my-part
+ snapcraftctl build
Staging my-part
+ snapcraftctl stage
Priming my-part
+ snapcraftctl prime
Snapping |
Snapped my-snap-name_0.1_amd64.snap

Multipassをインストールしていないと,⁠Multipassをインストールするか」問い合わせがあるので「Y」と答えておきましょう。その後,次のような流れでビルドが行われます。

  1. ビルド用の仮想マシンを作成・起動する
  2. ローカルの環境を仮想マシンにsshfsでマウントする
  3. snap/snapcraft.yamlの記述に従ってビルドを実施する
  4. ビルドした成果物をひとつのSquashFSにまとめる
  5. snapパッケージの完成
  6. 仮想マシンのシャットダウン

パッケージファイルはパッケージ名_バージョン名_アーキテクチャー.snapという名前で作られます。

--debugを付けるとエラー発生時にビルド処理を行っている仮想マシンにログインしてシェルを起動します。ホスト上の端末でsnap/snapcraft.yamlを変更した上で,起動したシェルで再度snapcraftコマンドを実行したらビルドを継続してくれます。何がおかしいかをトライアンドエラーで調べたい際に便利です。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member株式会社 創夢所属。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。