最初から提供されているタスクのロールを変更するにはどうすればいいんだろうか。
注) 手元のCapistranoのバージョンは2.4.3です。
例えば、deploy:defaultを再定義して、":roles => :app"を指定したとします。再定義したdeploy:defaultの中で、標準定義のままのdeploy:updateを実行した場合を考えます。
deploy名前空間内の標準定義タスクは、いずれもロール未指定です("capistrano/recipes/deploy.rb"を見る限り)。特に何もせずにcapコマンドを使ってタスクを実行した場合、「定義済みロールすべて」に対して実行されます。
タスクを実行する対象となるロールは、3段階の優先度を持って決定されます。"lib/capistrano/configuration/servers.rb"の38行にその処理が書かれています。
roles = role_list_from(ENV['ROLES'] || options[:roles] || self.roles.keys)
- 環境変数ROLES
- タスク定義時に指定したoptions[:roles]
- deploy.rbなどで定義したロール
タスク定義時にロールを指定せず、「特に何もせず」にタスクを実行すれば、3番目の"self.roles.keys"からロールを取得するため、定義されているすべてのロールが対象となるわけです。
さて、ここからが本題ですが、「ロール未指定な既存タスク」のロールを環境変数ROLESを使わずに指定するにはどうすればいいのでしょうか。
暫定的な対策として、タスク実行時にタスクのオプションを書き換える方法があります。定義されたタスクはTaskDefinitionのインスタンスとして保管されます。TaskDefinitionのインスタンスは、定義時に指定した:rolesなどのオプションを、@optionsというインスタンス変数で保持します。そして、ネームスペースであるCapistrano::Configuration::Namespacesは、TaskDefinitionのインスタンスを格納する@tasksというインスタンス変数を持ちます。つまりは、タスク定義の中から"tasks[:task_name].options[:roles]"で指定ロールにアクセス可能だという事です。
と、まあ、ふとした事から気になったので追いかけてみました。本当は、どうするのが正解なんでしょうかね。
Capistranoを詳しく調査/利用したことはないので、いろんな意味で的はずれかもしれませんが、ご容赦。

