watermint.org - Takayuki Okazaki's note

Dropbox用ユーティリティ toolbox

Dropbox APIを使ったプログラムを昨年から幾つか作っています。いまこぢんまりと作っているのがtoolboxというプログラムで今回はこれについて少し紹介させてください。

toolboxはGoで書いているプログラムで、ファイルの操作やDropbox Businessチーム管理などの機能をコマンドラインから実行できるようにしたい。というものです。 Dropbox APIのようなAPIを直接呼び出すのは面倒でも、コマンドラインになっていればシェルスクリプトなどからコマンドを組み合わせて簡単に使えるからです。

このtoolboxには類似のプロジェクトとしてdbxcliというものがあります。これも、コマンドラインからファイル管理やDropbox Businessチーム管理を実現するようなものです。

車輪の再発明的ですが解決しようとしている問題がすこし違うのでその点について紹介できればと思っています。

toolboxのねらい

ファイルの移動やコピー操作などはエクスプローラーやFinderなどでやれば簡単ですが、大量のファイルとなるとそうはいかないことが多いです。たとえば4TBのハードディスクから、4TB空きのあるNASへコピーするというのは意外とやっかいです。ネットワーク接続が切れて途中で失敗したり、パソコンがフリーズしたり、何かとトラブルにぶつかります。

NASからDropboxへ移行したり、前職で大量のファイルやサーバを管理していた経験から、こういったときにはrsyncなどのように信頼がおけ、帯域制御、再実行などもよく考えられたコマンドを利用するようにしています。

toolboxは単にコマンドラインで簡単に実行できるようにするというよりは、実運用において信頼性のおけるコマンドになることを目指しています。

大量ファイル・フォルダへの対応

Dropboxへアップロードしたファイル数が増加してくると、場合によってはパフォーマンスに影響がでると言われています。Dropbox で保存可能なファイル件数によれば30万件を超えるとパフォーマンスが低下してくるそうです。

実際に、自分のアカウントにNASから移行した70〜80万ファイルを置いていたときには、同期処理完了までの時間が気になることがありました。これらのファイルを別のフォルダに移動したり、保存しているフォルダ名を変更するとかなりの時間がかかってしまいます。

処理が遅いだけでいずれは終了するのですがもう少し早く解決できないかということで大量のファイル向けの処理をコマンドラインから実行できるようにしました。

利用方法

現在の実装では移動とコピーを実装しています。(まだちゃんと自動テストなど整備できていませんし、動作を保証するものではありませんのでご利用の際には自己責任で)

バイナリはGoでコンパイルしたものでWindows版(32bit)、Linux版(32bit)、macOS版(64bit)を用意しています。下図はmacOSでの実行例ですがコマンドラインから展開したファイルのうち、OSや環境に合わせたものを実行してもらうと利用方法が出力されます。macOS版はdarwinと名前のついたものです。

% ./tbx-32.1.0.0-darwin-10.6-amd64

Usage: ./tbx-32.1.0.0-darwin-10.6-amd64 COMMAND

Available commands:
  file       File operation


Run './tbx-32.1.0.0-darwin-10.6-amd64 COMMAND' for more information on a command.

please specify sub command

プログラムの引数にコマンド、サブコマンド、パラメータなどを指定していきます。ファイルを移動する場合には次のように実行します。

% ./tbx-32.1.0.0-darwin-10.6-amd64 file move /移動もとパス /移動先のパス

実行すると初回は認証のためのURLが表示されるので、Dropboxにログインしているブラウザに貼り付けて認可して、トークンをコピペします。このトークンは$HOME/.tbx以下に保存しているので2度目以降は聞かれません。

トークンを保存しているファイルの権限は他者に読み取られないよう設定していますが、それでも様々な攻撃方法があるかと思うので、ある程度コマンドの体裁が整ってきたら、トークンを保存しないように仕様変更しようかと思っています。

toolboxの設計

最初はひさしぶりにDDDなんかでモデリングして作ろうかと考えましたが、あきらめてほとんどコマンドをべた書きしています。いずれリファクタリングするかもしれません。

というのも「ファイルを移動する」という簡単なユースケースでも実際には様々な要件があったり、エラー対応が必要となります。そういったエラー処理をすべて抽象化しながら書いていくにはかなり手間がかかりますし、「ファイルを移動する」で使えていた経験が「ファイルをコピーする」では通用しないといった場合もありますので抽象化に時間をかけるよりは、ソースコードコピペは許容しつつ、自動テストに力を入れようと考えています。

いまのところ、まだ自動テストのカバレッジもほとんどなくて寂しい限りですが、コマンドがある程度揃ってきたらブラックボックステストを幾つか最初に追加する予定です。

動作仕様

最終的にはrsyncや、mv/cp/rmなどUNIXライクOSで見かけるコマンドと同じような操作感になるよう仕上げたいと思っているので仕様はまだころころ変えていく予定です。あしからずご了承ください。

また野望としてはwebサーバを立ち上げてWebベースのGUIてきなツールも提供できればと考えていますが、セキュリティーをどう担保するかと言った課題もありますし、まだ大分先になりそうです。