ククログ

株式会社クリアコード > ククログ > macOSのインストーラーを作成するには

macOSのインストーラーを作成するには

はじめに

クリアコードはFluentdの開発に参加しています。

Fluentdプロジェクトではtd-agentという名前でパッケージやインストーラーを提供しています。 td-agentはtd-agent 3からmacOS向けのインストーラーが試験的に提供されています。 macOS用のtd-agentのインストーラーについてはmacOSでのtd-agentのユーザーが少ないということもあり提供が滞っていました。

この記事では筆者畑ケがmacOSのインストーラー作成に関する事項をtd-agent4の事例を元に解説します。

macOSのインストーラー

macOSではインストーラーと呼ばれるものには形式がいくつかあります。

  1. distribution形式の.pkg単体での配布物

  2. distribution形式の.pkgをさらに同梱したディスクイメージ

  3. macOSのアプリケーション形式(.app)のアプリケーションを同梱したディスクイメージ

これらにはアンインストール機能はありません。 1 この記事ではアンインストールの機能に関しては詳述しないことにします。

この記事では2.のdistribution形式のpkgを同梱したディスクイメージを作成する方法を解説します。

macOS向けのインストーラーを作成する

以下の手順はmacOS環境を前提とします。

2.の形式のインストーラーを選ぶ理由

この記事では2.の形式のインストーラーの作り方を解説することにします。 td-agent4では以下の理由があったためです。

  • launchctlでサービス化を行いたい

    • 3.の形式では要件を満たせない。launchctlで探索するパスにサービス定義を含めることが出来ない。 2
  • インストーラーの設定を柔軟に行いたい

    • 1.のdistribution形式のpkgでは背景画像を設定したり、見栄えをよくしたり、最初にpkgの他にREADMEを提示したりするカスタマイズ性が弱い

    • macOSの暗黙的な慣習ではdistribution形式のpkg単体で配布するよりも、distribution形式のpkgをディスクイメージにさらに同梱して配布することが好まれる

同様のニーズを持つプロジェクトでは2.のdistribution形式のpkgを同梱したディスクイメージをインストーラー形式として採用することをお勧めします。

インストーラー作成の手順

ここからは手順の説明をします。 手順は以下の三段階です。

  1. flat pkgの定義を作成

  2. flat pkgを作成

  3. distribution pkgの定義を作成

  4. distribution pkgを作成

  5. ディスクイメージ(.dmg)を作成する

1. flat pkgの定義を作成

インストーラーの機能のみを持つflat pkgの定義ファイル(.plist)を作成します。 一般的に定義を作成するpkgbuildコマンドは以下のように使用します。

$ pkgbuild --analyze --root /path/to/staging-path sample.plist

これを実行するとsample.plistという定義ファイルが作成されます。 sample.plistはflat pkgの動作を変える場合、編集する必要があります。この記事では編集の手順は省略します。

td-agent4のインストーラー作成では以下の通りにしています。

$ pkgbuild --analyze --root td-agent/staging td-agent.plist
pkgbuild: Inferring bundle components from contents of td-agent/staging
pkgbuild: Writing new component property list to td-agent.plist

このケースではtd-agent/stagingというディレクトリに必要なファイルが入っており、 plistの編集が必要がないためtd-agent4ではこの定義ファイルはそのまま使用しています。

2. flat pkgを作成

pkgbuildコマンドに与えるコマンドライン引数を変えてもう一度実行し、 構成ファイルをインストールする機能のみを持つインストーラーを作成します。 このコマンドは一般的には以下のように使用します。

$ pkgbuild --root /path/to/rootDir --component-plist /path/to/sample.plist --scripts /path/to/scriptDir --identifier com.distributor.app.identifier --version version --install-location location PackageName.pkg

これで、構成ファイル群をflat pkg形式のPackageName.pkgに固めることができます。

td-agent4のインストーラー作成では以下の通りにしています。

$ pkgbuild --root td-agent/staging --component-plist td-agent.plist --identifier com.treasuredata.tdagent --version 4.0.1 --install-location / td-agent.pkg [--scripts /path/to/installation-scripts-dir]
pkgbuild: Reading components from td-agent.plist
pkgbuild: Wrote package to td-agent.pkg

インストール時に作成することが必要なディレクトリがあるため、実際のtd-agent4のflat pkgには--scriptsにはpostinstallが入ったディレクトリを指定しています。 --scripts引数の指定がない場合にはインストーラーを実行した際にインストールスクリプトの実行する候補がありません。この時にはインストールスクリプトは実行されません。

3. distribution pkgの定義を作成

前段で、flat pkgを作成しました。このインストーラーは、背景画像や、welcomeテキストや、使用許諾表示をユーザー指定のものに任意に差し替える機能がありません。 distribution pkgはこれらの機能を備えている形式のインストーラーです。また、この形式のインストーラーは複数のflat pkgを内包できます。

前段で作成したflat pkgを用いてdistribution pkgの定義の雛形を作成します。 一般的に定義を作成するproductbuildコマンドは以下のように使用します。

$ productbuild --synthesize --package /path/to/PackageName.pkg Distribution.xml

作成されたDistribution.xmlは以下のような内容になっています。

<?xml version="1.0" encoding="utf-8"?>
<installer-gui-script minSpecVersion="1">
    <!-- 中略 -->
</installer-gui-script>

Distribution.xmlを必要に応じて編集します。 例えば以下の要領です。

<?xml version="1.0" encoding="utf-8"?>
<installer-gui-script minSpecVersion="1">
    <!-- 中略 -->
    <title>Distribution pkgを実行した時のタイトル</title>
    <background file="背景画像.png" alignment="bottomleft" mime-type="image/png"/>
    <license file="使用許諾.rtf" mime-type="text/html"/>
    <welcome file="welcomeテキスト.html" mime-type="text/html"/>
</installer-gui-script>

この記事ではDistribution.xmlの編集手順は詳述しません。

td-agent4のインストーラー作成では以下の通りにしています。

$ productbuild --synthesize --package td-agent.pkg Distribution.xml 
productbuild: Wrote synthesized distribution to Distribution.xml

これにてproductbuildコマンドで使用する定義ファイルのDistribution.xmlが作成できました。 td-agent4の場合、作成されたファイルの内容は以下の通りです。

<?xml version="1.0" encoding="utf-8"?>
<installer-gui-script minSpecVersion="1">
    <pkg-ref id="com.treasuredata.tdagent"/>
    <options customize="never" require-scripts="false"/>
    <choices-outline>
        <line choice="default">
            <line choice="com.treasuredata.tdagent"/>
        </line>
    </choices-outline>
    <choice id="default"/>
    <choice id="com.treasuredata.tdagent" visible="false">
        <pkg-ref id="com.treasuredata.tdagent"/>
    </choice>
    <pkg-ref id="com.treasuredata.tdagent" version="4.0.1" onConclusion="none">td-agent.pkg</pkg-ref>
</installer-gui-script>
4. distribution pkgを作成

続いて、productbuildコマンドを実行します。 このコマンドは一般的には以下のように実行します。

$ productbuild  --distribution "Distribution.xml" --package-path /path/to/PackageName-0.0.0.pkg --resources "/path/to/resourceDir" PackageName.pkg

td-agent4のインストーラー作成では以下の通りにしています。

$ productbuild --distribution Distribution.xml --package-path td-agent.pkg [--resources /path/to/resources such as welcome.html and license.html etc.] td-agent-4.0.1.pkg
productbuild: Wrote product to td-agent-4.0.1.pkg

これで、distribution pkgが作成できました。

5. ディスクイメージ(.dmg)を作成する

macOSでは、distribution pkgを更にディスクイメージ(.dmg)に包んで配布することが多く見かけられます。

ディスクイメージを作成するには、ディスクイメージへ格納したいファイルを配置するディレクトリを作成し、そこにファイルをコピーします。

$ mkdir dmg
$ cp /path/to/PackageName-0.0.0.pkg dmg
$ hdiutil create -srcfolder dmg -fs HFS+ -format UDZO -volname SamplePackage PackageName-0.0.0.dmg
.......................................................................................................................................................
created: /path/to/PackageName-0.0.0.dmg

td-agent4のインストーラー作成に当てはめると以下のコマンドになります。 (ただし、実際にはディスクイメージのカスタマイズを行うため追加の手順があります。)

$ mkdir dmg
$ cp td-agent-4.0.1.pkg dmg
$ hdiutil create -srcfolder dmg -fs HFS+ -format UDZO -volname Td-Agent td-agent-4.0.1.dmg
.......................................................................................................................................................
created: ~/GitHub/td-agent-builder/td-agent-4.0.1.dmg

これにて2.の形式のdistribution形式のpkgを同梱したディスクイメージが作成できました。

ディスクイメージを更にカスタマイズしたい場合

ここまでの手順ではディスクイメージをhdiutil create -fs HFS+ -format UDZO ...で作成していますが、これで作成されるディスクイメージは読み込みのみ可能なディスクイメージです。

td-agent4では書き込みと読み込み可能な一時ディスクイメージを作成してディスクイメージの見た目とFinderで開いた時のサイズ調整を行っています。 td-agent4におけるmacOS向けのインストーラーを作成する作業は fluent-plugins-nursery/td-agent-builder#192 にて実施しました。この記事では解説されなかった細かな箇所に関してはリンク先のpull requestをご覧ください。

まとめ

以上、macOS向けのインストーラーの作成のやりかたを解説しました。

筆者は別の案件でdistribution形式のmacOSのインストーラーの作成を実施したことがありました。 td-agent4の前のバージョンのtd-agent3ではインストーラーを更にディスクイメージに格納しているやりかたでインストーラーを作成していました。td-agent3でのmacOSのインストーラーと形式が大きく異ならないように調整や調査をしながらtd-agent4でのmacOSインストーラーを作成する作業を実施しました。

読み込みと書き込みが可能なディスクイメージの作成が必要ということに中々気付けず、ディスクイメージのカスタマイズに難航しました。また、ディスクイメージのカスタマイズは基本的にGUI経由で行われる操作です。macOSはGUI Scripting環境(AppleScript)も提供しており、CI環境でもディスクイメージのカスタマイズを実施することができました。

当社では、お客さまからの技術的なご質問・ご依頼に有償にて対応するFluentdサポートサービスを提供しています。Fluentd/Fluent Bitをエンタープライズ環境において導入/運用されるSIer様、サービス提供事業者様は、お問い合わせフォームよりお問い合わせください。

  1. ユーザー自身がこのコマンドを使用してmacOSのインストーラー形式である.pkgがインストールしたファイルをシェルスクリプトなどの手段で削除できます。インストールされたファイルはpkgutil --files <com.distributor.app.identifier>の形式でインストーラーが登録している識別子に紐づいているファイルを取得できます。

  2. macOSではlaunchctl/launchdを用いてサービスの起動・終了を行うことが推奨されます。macOSではlaunchctlでサービスを扱いますが/Application配下の.app内のlaunchctl用のサービス定義は読み込んでくれないからです。launchctl向けのサービス定義は.plistと言う拡張子で、/Library/LaunchDaemons配下に置くことが推奨されます。