OpenSTF+Dockerで社内Android端末管理システムをMac上に構築する

## 概要

![https://raw.githubusercontent.com/openstf/stf/master/res/common/logo/exports/STF-128.png](https://raw.githubusercontent.com/openstf/stf/master/res/common/logo/exports/STF-128.png)

OpenSTFを使って社内開発用Android端末を一括管理する仕組みを構築したのでその手順を残しておきます

※本記事では開発機として持っている人が多いであろうMacをホストPCとして想定していますがOpenSTFは本来[Macはサポート外](https://qiita.com/KazaKago/items/26db0f68ba224eb094d3#os%E7%9A%84%E3%81%AA%E5%95%8F%E9%A1%8C)です。自己責任でご利用ください

## 発端

今まで手元に何台も端末を置いてアプリの開発・検証をしていましたが、どの端末にどのOSバージョンが入っているかわかりにくく、しばらく放置しているとバッテリーが切れていたり検証したいデバイスを何度も借りに行ったりと、端末の扱いにストレスを感じることが多くありました

![IMG_20180706_193905.jpg](https://qiita-image-store.s3.amazonaws.com/0/129872/5d0313c0-4f4f-e9a3-dd2a-403a758f1b11.jpeg)

（全部起動するだけで大変。。）

## OpenSTF

STFとはSmartphone Test Farmの略称で、その中でもオープンソースで知名度が高いのがOpenSTFです。
もともとはサイバーエージェントさんが作成されていました。
端末を一括で管理するためのツール群だと思ってくれればだいたい間違いないです。

ホストPCへ管理したいAndroid端末をすべてつなぎ、ブラウザ経由で端末が使えるようになります。
端末の操作はもちろん、端末の状態や貸出状況の把握、OpenSTF上の端末へビルドやデバッグ、テストを行うことも可能です

残念ながらOpenSTFではiOS端末は現在非対応なのでAndroidのみを対象としています

公式：https://openstf.io/
Github：https://github.com/openstf/stf

![https://raw.githubusercontent.com/openstf/stf/master/doc/7s_usage.gif](https://raw.githubusercontent.com/openstf/stf/master/doc/7s_usage.gif)

使い勝手は詳しく解説されている方がいらっしゃるのでそちらで雰囲気はつかめると思います（丸投げ）
https://qiita.com/tabbyz/items/5f6cec37e1d525a8e4d5

#### 検証環境

- MacOS High Sierra 10.13.5
- Docker for Mac 18.03.1-ce-mac65
- Android SDK Platform-Tools 28.0.0

#### ゴール

- ローカルネットワーク上のPCからブラウザを使って社内Android開発端末へアクセス可能な状態にすること
- Dockerを利用してPCの中身を汚さずなるべく簡単に構築できること（気軽に挑戦できること）

#### 構築手順

LinuxだとフルDockerで行けるらしいのですが、Macだとコンテナ内のadbからホスト側のUSB接続が認識できずadb周りだけはホストPCへ構築しました
Androidの開発者であれば大半のステップは済んでいると思うので適宜読み飛ばしてください

- 1. 端末をデバッグONにしてPCに挿しておく
    - 公式を参考にAndroid端末のデバッグをONにしてPCへ接続してください
    - https://developer.android.com/studio/debug/dev-options?hl=ja#enable
- 2. Docker for Macのインストール
    - Docker公式サイトからインストールして下さい
    - https://www.docker.com/docker-mac
- 3. JDKのインストール
    - Android SDKを動かすのに必要なのでインストールしてください
    - http://www.oracle.com/technetwork/java/javase/downloads/index.html
- 4. Android SDKのインストール
    - SDKに含まれるADBコマンドが使いたいのでインストールしてください。
    - Android Studioをまるっと入れてしまうのが一番てっとり早いです
    - https://developer.android.com/studio/?hl=ja
- 5. ADBコマンドのPATHを通す
    - adbコマンドを使用するためPATHを通してください
    - `$ adb version`が使えるようなればOKです
    - SDKのパスをいじっていなければ`~/.zshrc`へ以下を記述した上で`source`コマンド等で再読み込みすればいけるはずです

```shell:~/.zshrc
export PATH=$PATH:/Users/<自分のユーザー名のフォルダ>/Library/Android/sdk/tools
export PATH=$PATH:/Users/<自分のユーザー名のフォルダ>/Library/Android/sdk/platform-tools
```

```shell:shell
$ source ~/.zshrc
```

- 6. MacのローカルIP固定
    - DHCPで動的にIPが変わると別のPCからアクセスできなくなってしまうので使われなさそうな値に固定します
    - https://support.apple.com/kb/PH25448?locale=ja_JP
    - ネットワーク管理者であればルーター側で固定するのでももちろんOKです
- 7. docker-compose.ymlの書き換え
    - 以下のdocker-compose.ymlから一番下の`--public-ip`を固定したローカルIPへ書き換えて任意の場所に保存します

```yaml:docker-compose.yml
version: '2'
services:
  db:
    image: rethinkdb
    command: rethinkdb --bind all
    ports:
      - 8082:8080
    volumes:
      - db_data:/data
  stf:
    image: openstf/stf
    ports:
      - 7100:7100
      - 7110:7110
      - 7400-7700:7400-7700
    links:
      - db
    environment:
      - RETHINKDB_PORT_28015_TCP=tcp://db:28015
      - RETHINKDB_ENV_DATABASE=stf
    command: stf local --allow-remote --public-ip 172.21.34.110 --adb-host docker.for.mac.localhost
volumes:
  db_data:
```

- 8. ADBサーバーを起動する 
    - `$ adb start-server`で立ち上がるはずです
- 9. dockerコンテナの立ち上げ
    - docker-compose.ymlを配置したパスで`$ docker-compose up -d`を叩けば立ち上がるはずです 
- 10. 動作確認
    - http://<固定したIP>:7100 へウェブブラウザでアクセスして表示されればOKです
    - ログインっぽい画面が表示されますが、認証ではないのでユーザー名とメールアドレスを適当に入れれば入れます
    - Android端末をケーブルでPCに繋いで`$ docker-compose up -d`し直せば自動的に読み込まれて画面上に表示されるはずです

## 構築後やること

ここまででとりあえずOpenSTFの導入は出来ているかと思います。
ただ、実際に社内システムとして稼働させるために用意しなければならないものがいくつかあります

- **高出力のUSBハブを用意する**
    - PCのバスパワーだけだとたくさんの端末に電力を供給できないので別電力供給が出来るUSBハブが必須です
    - OpenSTFの公式でおすすめも記載されているので[README](https://github.com/openstf/stf#recommended-hardware)を参考にすると良いと思います
- **接続する端末の数だけUSBケーブルを用意する**
    - 端末によってUSB-CとMicro-USBの2種類があるので注意です
- **OpenSTFを常時稼働させるホストPCを用意する**
    - 何十台もつなぐ場合は性能のよいマシンが必要になるかもしれません
    - 5台以下であればMacbook Pro 2012年モデルでも十分実用範囲内でした
- **端末とホストPCの置き場所を確保する**
    - 当たり前ですが地味に場所をとるので上司やチームメンバーと相談してください
- **スマートフォンスタンドを用意する**
    - ケーブルが結構ごちゃつくのでそのままにしておくと画面に触れて誤タップの原因になるのでスタンドがあったほうがいいです
    - ケーブルを挿したままスタンドに置ければ割となんでもいいと思います
    - 見栄えも良くなり発熱の解消にもなります
- **他メンバーにも使ってもらえるよう布教活動を行う**
    - 非エンジニアにも使えるよう使い方ドキュメント書いたり周知する必要があるかもしれないです
    - エンジニア数人なら口頭でもいいですが、チームメンバーが増えてくると周知するのも一苦労なので根気よく説明して覚えてもらうまでが構築手順の一環です！

![IMG_20180717_152556.jpg](https://qiita-image-store.s3.amazonaws.com/0/129872/64cbecf1-f0bc-939a-9afb-36edd91e1b0e.jpeg)

実際の稼働状況はこんな感じになっています。社内にあった古いMacBook Pro（2012年モデル）上に構築しました。
開発中に端末が机にたくさん散らかったり、電池が切れてたり、MTGへ端末を持たずに臨んで席まで取りに戻ったりすることはほとんどなくなりました。

## 稼働させてみての課題

### STF上でアプリをインストールしても次使うときに消える

しばらく稼働させてみて初めて気づいたのですが、OpenSTFのデフォルト挙動では利用中にインストールしたアプリは利用解除時に削除されるとのことです。
シンクライアント風に使う分には便利なのですが、社内の限られた人のみ使う場合は残っていたほうが便利なことも多いので無効化させました。

やり方はSTF起動時に`--no-cleanup`パラメータを付与すればOKです

```
stf local --no-cleanup
```

https://github.com/openstf/stf/issues/242


### ~~OS的な問題~~

~~今回お古のMac上にOpenSTFを構築しており、Docker上だからホストOSは何でもええやろ！とか思ってたんですがどうやらUSBの接続周りで問題があり、一度ケーブルを抜くと再接続時にstfから認識されない現象に見舞われました。OpenSTF自体を再起動すれば認識されます。~~

~~どうもMacのadbにはバグがあるため公式サポートはしないというのがstfチームの結論のようでした。~~

~~https://github.com/openstf/stf#requirements~~
> ~~Note that while Mac OS can be used for development, it doesn't provide a very reliable experience in production due to (presumed) bugs in ADB's Mac OS implementation. We use CoreOS but any Linux or BSD distribution should do fine.~~

~~https://github.com/openstf/stf/issues/659~~
> ~~We do not support Macs in production. They're a pain and and a waste of
everyone's time.~~

~~なので根本的な解決策としてはLinux上に構築するかDocker on Vagrant環境を立てる必要がありそうです。~~

#### 追記

上記問題はOpenSTFのアップデートに伴い解決されました

### アクセスポイント的な懸念

先人方の記事を見ると、何十台も端末を接続して常時ネットワークに接続していると周囲のAPを専有してしまって帯域を圧迫することがあるとのことです。
稼働させた範囲では5台しかつないでいなかったため大した影響は出ませんでしたが多くの端末を購入して管理するようになった場合は専用APを設ける必要がでてくるかもしれないです

参考：「OpenSTF の導入によるゲーム開発への貢献 - GREE Engineer Blog」
http://labs.gree.jp/blog/2015/12/14951/

### セキュリティ的な懸念

OpenSTF自体には現状アクセス権限がなく、なりすましも容易なので社内の性善説に基づく運用スタイルになります。
アクセスできる人全員が使えるので、場合によっては独自に認証を入れたりネットワーク制限をするなどの対策が必要になるかもしれません。