Capistranoで上位タスクと同じホストを強引に処理対象とする
Capistranoのタスクは実行対象ホストのリストをホスト名やロール名で指定できる。この指定は静的なものなので、あるタスクから別のタスクを呼び出したとしても、それらの指定は引き継がれない。
以下のレシピでタスクbarには:hostsオプションがあり、これに従って同タスクはhost3とhost4に対して実行される。barから呼び出されるタスクbazにはこのような指定がないため、barでの指定によらずロールに登録されている全ホスト(host1とhost2)に対して実行される。
role :foo, 'host1', 'host2' task :bar, :hosts => %(host3 host4) do run "..." # host3とhost4でコマンド実行 baz end task :baz do run "..." # 全ロール(host1とhost2)でコマンド実行 end
このような動作をするため、タスクを部品化して再利用しようとすると、ある程度のところからはメソッド定義をしていくことになる。
ここでふと、いいかげんなオブジェクトを渡せばそのあたりの動作をコントロールできかなと考え、その思い付きのまま試みにコードを書いてみた(gist)。テストは一部だけ(しか書いていない)。
uh, ul = UpstreamSupport.create(self) role :foo, 'host1', 'host2' task :bar, :hosts => %(host3 host4) do run "..." # host3とhost4でコマンド実行 baz end task :baz, :hosts => uh do run "..." # 呼び出し元と同じホスト群でコマンド実行 end
このレシピのタスクbarを実行するとhost3とhost4でコマンド実行される。そして、そこから呼びされたタスクbazでも同様にhost3とhost4でコマンド実行される。しかし、タスクbazを直接実行すると、全ロールのホスト群、つまりhost1とhost2でコマンド実行される。さて、うまく動くかな?
ただ、あんまりふみこみすぎてもなってところでもある。