2014年3月24日月曜日

Berkshelf version3+Knife soloでnginx環境をVagrantに作ってみた話

このエントリーをはてなブックマークに追加 はてなブックマーク - Berkshelf version3+Knife soloでnginx環境をVagrantに作ってみた話

今度、仕事でChefを使いそうで、ラクをしたい!からサードパーティのクックブックを使う為にBerkshelfというツールを使ってみたのでその時の手順メモ。

いや、Ruby力があればもっとあれば。。。

なお、vagrantプラグインのBerkshelfは使っていません。(Berkshelf version3とプラグインの相性が悪いとか聞いたので)

当方RubyやChef初心者なので使い方間違ってたらごめんなさい。。。

なお、省略。

  • rbenvのインストール
  • Vagrantのインストール
  • CentOS6.4のBox取得

目次

  1. Chef、Knife-soloの準備
  2. Vagrantで仮想環境の設定
  3. Chefのリポジトリ作成
  4. 仮想環境にChefをインストールする
  5. 自分でクックブックを書いて適応してみる
  6. Berkshelfのインストール
  7. Berkshelfを使ってクックブックを取得する
  8. Berkshelfで取得したクックブックを実行してみる
  9. 感想
  10. 参考

動作環境

Workstation(Chefを実行するマシン)

  • MacOSX 10.9.2
  • ruby 2.0.0p451(rbenv利用)
  • gem 2.0.14
  • Vagrant 1.4.3

Node(Vagrantで動作するnginxをインストールする対象の仮想環境)

  • CentOS6.4

1.Chef、Knife-soloの準備

Gemを使ってChef,Kinife-soloをインストールします。 必要であればsudoを付けてコマンドを実行。 rbenvでなければrbenv rehashは必要ありません。

$gem install chef
$gem install knife-solo
$rbenv rehash

確認。

$gem list --local |grep -e chef -e knife
chef (11.10.4)
chef-zero (1.7.3)
knife-solo (0.4.1)

Knifeを使う為の設定をします。 とりあえずエンターキー連打でOK。

$knife configure

2.Vagrantで仮想環境の設定

Chefを実行する仮想環境をVagrantを利用して作成します。

適当にフォルダを作成。

$cd ~
$mkdir -p vagrant/chef
$cd vagrant/chef

Boxの確認をします。 CentOSのBoxを未取得の場合、vagrant box addコマンドを利用して予めBoxを取得してください。Vagrant関連の昔の記事はこちら。

$vagrant box list
centos6_4       (virtualbox)
my_centos       (virtualbox)
precise32       (virtualbox)
ubuntu13.10_x64 (virtualbox)

Boxを指定して初期ファイル作成します。指定するのは自分の環境のboxの名称に合わせてください。

$vagrant init centos6_4

カレントディレクトリにVagrantfileが出来ているのでこちらを編集して任意のプライベートIPでアクセス出来るようにします。

#変更前
#config.vm.network :private_network, ip: "192.168.33.10";

# 変更後
config.vm.network :private_network, ip: "192.168.33.10"

上記でホストのMacから192.168.33.10というプライベートIPでアクセス出来るようになります。

VMを起動します。

$vagrant up

IPアドレス指定のアクセスだと色々面倒なのでvagran ssh-configコマンドを利用してホスト指定します。以下の例ではホスト名をblueとしました。(何でも良いです)

$vagrant ssh-config --host blue >> ~/.ssh/config

設定がうまくいっているか確認。

$ssh blue

SSHログインが出来ればOKです。

3.Chefのリポジトリ作成

Chefのリポジトリを作成します。

$cd ~/vagrant/chef/
$knife solo init chef-repo

これでカレントディレクトリにchef-repoというディレクトリが作成されたかと思います。 その中はこんな感じの構成です。

$tree chef-repo
chef-repo/
|-- cookbooks
|-- data_bags
|-- environments
|-- nodes
|-- roles
`-- site-cookbooks

慣習としてcookbooks配下にはサードパーティのレシビを入れ、site-cookbooks配下には自分で作成したレシピを入れるようです。

4.仮想環境にChefをインストールする

VM (今回はCentOS)にChefをインストールして、後でホスト側からChefが実行できるようにしておきます。 本処理ではknife solo prepareコマンドを利用します。

$cd ~/vagrant/chef/chef-repo
$knife solo prepare blue

末尾のblueはホスト名なのでssh-configで指定したそれぞれのホスト名に置き換えてください。 結構時間が掛かりますが、しばし待ちます。

私の環境では処理が終わったら

Thank you for installing Chef!
Generating node config 'nodes/blue.json'...

みたいなメッセージが最後に出てうまくいっている事が確認できました。 nodes/blue.jsonはあとで編集します。

5.自分でクックブックを書いて適応してみる

Berkshelfでサードパーティのクックブックを使う前に、自分で作ったクックブックが反映できるか確認します。

本例ではiptablesを停止させるレシピを書いてみます。(本番環境でiptablesを停止させるのは危険ですが、今は仮想環境なので)

まずはクックブックのテンプレートを作成します。 クックブック名はstop-iptableとしました。

 $knife cookbook create stop-iptables -o site-cookbooks/

クックブックのテンプレートが出来たので実際にiptablesを停止する記述を行います。

$vi site-cookbooks/stop-iptables/recipes/default.rb

以下のように編集します。

service "iptables" do
    action [ :disable, :stop ]
end

詳細はChefの公式ページのServiceについて記載されているページを参照ください。

あと実際にどのクックブックを実行するかを決定する為に、VMにChefをインストールした時に生成されたnodes/blue.jsonを以下のように編集します。

{
  "run_list": [
  "recipe[stop-iptables]"
  ]
}

では準備できたので実行。 の前に現状確認してみます。

$ssh blue
$sudo service iptables status
$exit

色々表示されて、iptablesが実行されている事が分かります。

ではChefを実行します。 以下のコマンドをMac側で実施します。

$knife solo cook blue

実行時のログを見るとptables止めたような記述が出ますが、実際に確認します。

$ssh blue
$sudo service iptables status
iptables: Firewall is not running.
$exit

iptablesが停止している事が確認出来ました。

6.Berkshelfのインストール

サードパーティのクックブックを取得する為にBerkshelfをインストールします。 gem install でインストールするとversion2がインストールされるのですが、こちらは今後サポートしないよ、と公式サイトに記述があったのでversion3の方をbundleを利用してインストールします。

まずは、bundleをインストールします。

$gem install bundle 
$rbenv rehash
$bundle --version
Bundler version 1.5.3

Bundleで取得するGemを指定するために必要なGemfileを生成します。

$cd ~/vagrant/chef/chef-repo
$bundle init

カレントディレクトリに生成されたGemfileを編集します。

$vi Gemfile

公式の通り、以下を追記。 なお、Pluginは入れないのでberkshelfのみ指定します。

source 'https://rubygems.org'
gem "berkshelf";, github: "berkshelf/berkshelf"

インストール及びコマンドが実行出来る事を確認します。

$bundle install --path vendor/bundle
$bundle exec berks --version
3.0.0.beta7

これで本ディレクトリではberksコマンドが使えます。 なお、pathを指定しないとグローバルな環境にberksをインストールするみたいですが、実際に動作出来るかは試しておりません。

あとGitからcloneしてrakeしてーみたいなやり方もありそうですが、こちらも未確認です

7.Berkshelfを使ってクックブックを取得する

サードパーティのクックブックを取得します。 本例ではOpscodeのnginx を取得してcookbookディレクトリ配下に配置します。

$vi Berksfile

以下のように記載します。

source "https://api.berkshelf.com/" 
cookbook 'nginx'

Berksfileに基づいて実際にクックブックを取得します。 一度、cookbooksを削除してからコマンドを実行します。

$rm -rf cookbooks
$bundle exec berks vendor cookbooks

処理が終わると、依存しているものも合わせてインストールしてきています。

$tree -L 1 cookbooks
cookbooks/
|-- Berksfile.lock
|-- apt
|-- bluepill
|-- build-essential
|-- nginx
|-- ohai
|-- rsyslog
|-- runit
|-- yum
`-- yum-epel

依存関係については各クックブック配下のmetadata.jsondependenciesとして定義されているものがダウンロードされているようです。

8.Berkshelfで取得したクックブックを実行してみる

いよいよ!クックブックを実行してみます。

実行する際にどのクックブックを実行するか指定する為にblue.jsonを編集します。

$vi nodes/blue.json

レシピを追加します。

{   
  "run_list": [
    "recipe[stop-iptables]",
    "recipe[nginx]"
  ]   
}  

実行します。

$knife solo cook blue

途中、warningが出てgem install berkshelfしろと言われますが、処理は止まりませんし、bundleでインストールできているので無視します。

終わったら確認の為に、ブラウザでアクセスしてみます。nginxのデフォルトはport80なのでhttp://192.168.33.10とかでアクセスします。

EEPLリポジトリを使ってインストールしたnginxのデフォルト画面が表示されています。

9.感想

  • Ruby力がなくてBerkshelfのインストール及び実行にすごく時間が掛かってしまった
  • 多分OpsCodeのクックブックは色んなOSに対応している素晴らしいクックブックだと思うのですが、それが故か初心者としてはトラブったときに何が悪いか判断するのが難しいそうだと感じました。少なくともまだレシピをあんま書いた事ない人だと設定いじるとかも少し苦労しそうな気がしました。
  • 実際に自分が使うときには一部使うような事をしようかと思いました。yum-eeplとか汎用的だと思うし、Berfshelfのものを使いたい。でも、nginxとかはPackageリソース使って自分でクックブックを書いた方が後々メンテしやすそうかなと。
  • 書き方の参考という意味ではとても勉強になると思います。

10.参考

  • Chef

入門Chef Solo - Infrastructure as Code

ドットインストール Chef入門

  • Berkshelf関連

Berkshelf(公式)

Berkshelf 入門

ツールを使いたいだけの人のための bundler 入門 (例: vagrant + veewee)

vagrant-berkshelf を使わずに Berkshelf + knife-solo で環境作ってみた話

2014年3月21日金曜日

JenkinsのGitPluginでコメントが文字化けした時の解消方法

このエントリーをはてなブックマークに追加 はてなブックマーク - JenkinsのGitPluginでコメントが文字化けした時の解消方法

UbuntuにJenkinsをインストールしてGitPluginを入れて連携させた時にコミットコメントが文字化けしたので解消方法をメモ。

原因はJenkinsのファイルエンコーディングがUTF–8になっていないためなので、これを直す。

パッケージインストール(apt-getなど)の場合、/etc/default/jenkinsにJAVA_ARGS=“-Dfile.encoding=utf–8”を追記してJenkinsをリスタートすればOK

$sudo vi /etc/default/jenkins
JAVA_ARGS="-Dfile.encoding=utf-8"
$sudo service jenkins restart

これで直るはず。

warを利用してtomcatで動かしている場合、CATALINA_OPTSDfile.encoding=utf–8を指定した後に起動すればOK。

Tomcatユーザーで起動している場合、

$vi ~/.bashrc
CATALINA_OPTS="-Dfile.encoding=utf-8"
export CATALINA_OPTS
$source ~/.bashrc

としてtomcatを再起動すれば問題ないはず。

参考

Ubuntu 12.04にJenkinsをインストールしてApacheでポート80で動かす

CATALINA_OPTSの指定

2014年3月19日水曜日

特定のAndroid SDKをCUIでインストールする方法

このエントリーをはてなブックマークに追加 はてなブックマーク - 特定のAndroid SDKをCUIでインストールする方法

AndroidサイトにあるAndroidSDKを落としきても最新のAndroidSDK(Andorid19)のみしかなく、昔のSDKでビルドする必要がある場合、別途ダウンロードが必要である。

GUIであれば簡単だが、XWindowsがないなどの場合にCUIのみで実施する必要があり、その場合のメモ。

また、全てのパッケージをダウンロードするとめちゃくちゃ時間が掛かるので特定の奴だけダウンロードする方法を記載する。

まず、現在利用可能なパッケージは以下のコマンドで確認する。

$android list sdk
Packages available for installation or update: 45
   1- Android SDK Tools, revision 22.6.1
   2- Documentation for Android SDK, API 19, revision 2
   3- SDK Platform Android 4.3, API 18, revision 2
   4- SDK Platform Android 4.2.2, API 17, revision 2
   5- SDK Platform Android 4.1.2, API 16, revision 4
   6- SDK Platform Android 4.0.3, API 15, revision 3
   7- SDK Platform Android 4.0, API 14, revision 3
   8- SDK Platform Android 3.2, API 13, revision 1
   9- SDK Platform Android 3.1, API 12, revision 3
  10- SDK Platform Android 3.0, API 11, revision 2
  11- SDK Platform Android 2.3.3, API 10, revision 2
  12- SDK Platform Android 2.2, API 8, revision 3
  13- SDK Platform Android 2.1, API 7, revision 3
  14- SDK Platform Android 1.6, API 4, revision 3
  15- SDK Platform Android 1.5, API 3, revision 4
  16- Android Wear ARM EABI v7a System Image, Android API 19, revision 1
  17- ARM EABI v7a System Image, Android API 19, revision 2
  18- Intel x86 Atom System Image, Android API 19, revision 2
  19- Google APIs (x86 System Image), Android API 19, revision 2
  20- Google APIs (ARM System Image), Android API 19, revision 3
  21- Google APIs, Android API 18, revision 3
  22- Google APIs, Android API 17, revision 3
  23- Google APIs, Android API 16, revision 3
  24- Google APIs, Android API 15, revision 2
  25- Glass Development Kit Sneak Peek, Android API 15, revision 2
  26- Google APIs, Android API 14, revision 2
  27- Google APIs, Android API 13, revision 1
  28- Google TV Addon, Android API 13, revision 1
  29- Google APIs, Android API 12, revision 1
  30- Google APIs, Android API 11, revision 1
  31- Google APIs, Android API 10, revision 2
  32- Google APIs, Android API 8, revision 2
  33- Google APIs, Android API 7, revision 1
  34- Google APIs, Android API 4, revision 2
  35- Google APIs, Android API 3, revision 3
  36- Android Support Repository, revision 4
  37- Google Analytics App Tracking SDK, revision 3
  38- Google Play services for Froyo, revision 12
  39- Google Play services, revision 15
  40- Google Repository, revision 6
  41- Google Play APK Expansion Library, revision 3
  42- Google Play Billing Library, revision 5
  43- Google Play Licensing Library, revision 2
  44- Google Web Driver, revision 2
  45- Intel x86 Emulator Accelerator (HAXM), revision 3

上記のようにリスト表示されるので、自分のインストールしたいパッケージの番号を確認する。 上記の例だとSDK Platform Android 4.0, API 14, revision 3をインストールしたい場合には7となる。

メモが終わったら、以下のように–filterオプションを付与して、updateを実施することで特定のパッケージのみインストールできる。

$android update sdk --no-ui --filter 7

なお、–filterオプションを指定しないと全てのパッケージをダウンロードするため、かなり時間がかかる。

参考

Updating SDK from command-line

2014/6/9追記

以下のような記述でもインストール可能でした。こちらだとリストを調べなくてもよいのでより便利ですね。

$android update sdk --no-ui --filter android-10

2014年3月16日日曜日

Calabash-Androidを利用してAndroidのシナリオテストを日本語で書いてみる

このエントリーをはてなブックマークに追加 はてなブックマーク - Calabash-Androidを利用してAndroidのシナリオテストを日本語で書いてみる

Androidのシナリオ自動化テストで使えるCalabsh-Andoridを利用してみたのでその時のメモ。calabash-androidのインストールを行い、HelloWorldアプリをエミュレーターで動かし、日本語によるシナリオテストできるまでを記載します。(ググれば分かりそうな所は割愛)

calabash-android

目次

  1. Calabash-Androidとは
  2. Calabash-Androidのインストール
  3. HelloWorldアプリの作成
  4. Androidエミュレーターの作成、起動
  5. 試験(cucumber)のスケルトン作成
  6. keystoreの設定
  7. テストの実行
  8. テストを日本語化する
  9. Tips

1.Calabash-Androidとは

こちらの資料がとても分かりやすかったです。

Calabash-AndroidでBDDしようぜ!

ざっくり特徴としては

  • Androidのシナリオテストを実行するライブラリ
  • 現在も開発が続いている(2014年3月16日時点)
  • テストはCucumberで書く
  • テストで日本語が書ける

などが特徴でしょうか。 あと特に良いなと思った点としてコード書かない人でもテストが書ける事です。

# language: ja
フィーチャ: 初期画面表示確認を行う
        アプリのユーザーとして初期画面表示を行う。
        なぜならアプリ起動時に表示するからだ。

シナリオ: 初期画面を表示する
        ならば"Hello world!"と表示されていること
        ならばスクリーンショットを撮る

みたいな書き方が出来るのでテスターの人でも書けるのが特に良いなと。(他のテストライブラリについてそんなに詳しく分かりませんが) あとで見た人もとても分かりやすい。

2.Calabash-Androidのインストール

公式ドキュメントはこちら。

Calabash-AndroidはRubyのGemで提供されているので、Rubyのインストールが必要です。また、以下が必要となります。

  • Ruby(1.8.7以上)
  • Ant
  • Java
  • AndroidSDKのインストール、ANDROID_HOMEの設定

自分はMacOSXで設定しましたが、LinuxでもWindowsでも条件が揃っていれば動作可能かと思います。

各インストールの詳細は割愛。 インストール後、各コマンドのパスが通っているか確認。

$ruby -v
ruby 1.9.3p385 (2013-02-06 revision 39114) [x86_64-darwin13.1.0]

$java -version
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)

$ant -version
Apache Ant(TM) version 1.9.3 compiled on December 23 2013

$echo $ANDROID_HOME
/Applications/adt-bundle-mac-x86_64-20131030/sdk

ANDROID_HOMEはsdkの所を指定しないと駄目なようなので注意。

上記が完了したら、以下コマンドでCalabash-Androidをインストール。

$gem install calabash-android

確認。

$gem list --local |grep android
calabash-android (0.4.21)

3. HelloWolrdアプリの作成

テスト対象とするAndroidアプリを作成しましょう。とりあえず自分はHelloWorldアプリを作りました。ここも詳細は割愛。

この際の注意点としてAndroidManifest.xmlandroid.permission.INTERNET を設定しておいてください。

Calabsh-Androidではhttpを使ってテストしているっぽいのでこれをやっておかないと失敗します。

4. Androidエミュレーターの作成、起動

Androidエミュレーターを作成して起動しておいてください。詳細は割愛。 実機の場合、USB接続してadb devicesコマンドで認識できていればOK。

テストしたいアプリがインストール、起動出来る事を確認しておくと良いと思います。

また、エミュレーター起動時にUse Host GPUを使うと後述するテスト時のスクリーンショットを撮るときに黒くなってしまうので注意です。

5. cucumberのスケルトン作成

試験をする為のスケルトンファイルを作成します。テストしたいAndroidプロジェクト配下(AndroidManifest.xmlがある場所)に移動して、calabash-andorid genコマンドを実行します。

$cd workspace/[YourProjectName]
$calabash-android gen

とするとスケルトンが作成されます。

features
|_support
| |_app_installation_hooks.rb
| |_app_life_cycle_hooks.rb
| |_env.rb
|_step_definitions
| |_calabash_steps.rb
|_my_first.feature

my_first.featureが試験項目になるのですが、こちらの内容をHello world!と画面に表示されている事という内容に変更します。

Feature: Login feature

  Scenario: As a valid user I can log into my app 
    Then I see "Hello world!" 

本当はFeature,Scenarioの場所も変えた方が良いのですが、とりあえず動かしたいので無視。(日本語化に関しては後述)

6. keystoreの設定

テスト実行時にテスト対象のapkと同様の署名されたテストアプリを同時にインストールします。

上記より、どのkeystoreを使ったかを教えてあげる必要があります。

$calabash-android setup

上記コマンドを実行するとkeystoreの場所、alias、パスワードを聞いてくるので入力します。 入力が終わるとカレントディレクトリにcalabash_settingというのが出来ており、こちらに入力した情報があるのが確認出来ます。

7. テストの実行

さあ、テストを実行してみましょう!calabash-androidコマンドを実行し、引数にテストしたいapkを指定します。

$calabash-android run bin/MainActivity-debug.apk
Feature: Login feature

  Scenario: As a valid user I can log into my app # features/my_first.feature:3
1135 KB/s (556187 bytes in 0.478s)
1706 KB/s (277892 bytes in 0.159s)
    Then I see "Hello world!"                     # calabash-android-0.4.21/lib/calabash-android/steps/assert_steps.rb:5

1 scenario (1 passed)
1 step (1 passed)
0m37.799s

とすると色々文字が出て最後に成功(pass)しているのが確認できます。なお、-vオプションを付けるとverboseで詳細が表示されるのでうまく動かない時はこちらを付けるのがおすすめです。

先ほど編集したmy_first.featureのThen I see “Hello World!”の箇所をThen I see “test!!!”とするとテストが失敗する事からもテストがしっかり実行できている事が確認できます。

$calabash-android run bin/MainActivity-debug.apk
Feature: Login feature

  Scenario: As a valid user I can log into my app # features/my_first.feature:3
1907 KB/s (556187 bytes in 0.284s)
1668 KB/s (277892 bytes in 0.162s)
    Then I see "test!!!"                          # calabash-android-0.4.21/lib/calabash-android/steps/assert_steps.rb:5
      Action 'assert_text' unsuccessful: Text'test!!!' was not found (RuntimeError)
      features/my_first.feature:4:in `Then I see "test!!!"'

Failing Scenarios:
cucumber features/my_first.feature:3 # Scenario: As a valid user I can log into my app

1 scenario (1 failed)
1 step (1 failed)
0m46.468s

8.テストを日本語化する

今書いてあるテストはあくまで英語なので日本語でも出来るようにします。 まず、featureファイル(シナリオ)を日本語化します。

# language: ja
フィーチャ: 初期画面表示確認を行う
        アプリのユーザーとして初期画面表示を行う。
        なぜならアプリ起動時に表示するからだ。

シナリオ: 初期画面を表示する
        ならば"Hello world!"と表示されていること
        ならばスクリーンショットを撮る

1行目で日本語での予約語を使いますよ、という事を宣言しています。(Feature:フィーチャ、Then:ならば、などなど)

ただし、これでテストを実行しても「表示されている事」、「スクリーンショットを撮る」などの記述が何の操作に対応するか不明であるため、動きません。 そこでfeatures/step_definitions/calabash_steps.rbファイルを編集します。

# coding: utf-8
require 'calabash-android/calabash_steps'

ならば /^"(.*?)"と表示されていること$/ do |text|
  step %{I should see "#{text}"}
end

ならば /^スクリーンショットを撮る$/ do
  step %{I take a screenshot}
end

こんな感じで日本語で認識させたい文言を書き、次の行に具体的に実行する処理を記載します。 step hogeで出来る処理の一覧は以下にあります。(hoge秒待つ、fugaボタンを押すなど色々あります)

calabash-android / ruby-gem / lib / calabash-android / canned_steps.md

また、最初に紹介したslideshareを書いてくれた方がstepファイルを日本語化したものをGistにおいてくれているみたいなのでこれを使っても良いかと思います。(未検証とのことですが、かなり助かります。)

patorash / common_steps.rb

準備ができたのでテストを実行してみます。

$calabash-android run bin/MainActivity-debug.apk
# language: ja
フィーチャ: 初期画面表示確認を行う
  アプリのユーザーとして初期画面表示を行う。
  なぜならアプリ起動時に表示するからだ。

  シナリオ: 初期画面を表示する               # features/my_first.feature:6
1558 KB/s (556187 bytes in 0.348s)
1397 KB/s (277892 bytes in 0.194s)
    ならば"Hello world!"と表示されていること # features/step_definitions/calabash_steps.rb:4
    ならばスクリーンショットを撮る             # features/step_definitions/calabash_steps.rb:8

1 scenario (1 passed)
2 steps (2 passed)
0m44.955s

成功しました!結果もすごい分かりやすい!撮ったスクリーンショットはカレントディレクトリにscreenshot_0.pngとかで配置されています。

試験シナリオを増やす場合にはfeature/**.featureというファイルをシナリオ分作成していけばOKで、日本語で実施したい処理を増やしたい場合にはfeatures/step_definitions/calabash_steps.rbに記述を増やしておけばOKです。

9.Tips

  • calabash-android run bin/MainActivity-debug.apk -v --format html --out reports.htmlというような書き方で結果をHTML出力できる
  • debugビルドしたアプリをインストールした状態でreleaseビルドしたアプリをテストしようとすると証明書違うよって怒られる事があるのでその場合には一度アプリを削除するなどが必要。(基本的にはuninstallコマンドが先に走るので大丈夫なはず)
  • テスト用にインストールしているアプリはtest_servers/配下に存在する
  • adb installでアプリをインストールしているが、adb -r installにしたい場合にはfeatures/support/app_installation_hooks.rbのinstall_appという記述をupdate_appとすれば良い。(プリインアプリなどアプリが削除できない場合に有効)