Itamae | resource plugin で 板前によるトイレ操作機能を追加する #devops #itamae

# Itamae | resource plugin で 板前によるトイレ操作機能を追加する #devops #itamae

## 概要
プロビジョニングツール Itamae

resource plugin で 板前へのトイレ操作をプラグイン化します。

※toilet コマンドについては下記リンク参照
http://www.tecmint.com/20-funny-commands-of-linux-or-linux-is-fun-in-terminal/

## resource plugin
公式 Wiki による Resource Plugins の説明
https://github.com/ryotarai/itamae/wiki/Resource-Plugins

### Itamae の resource は gem で管理
Itamae では resource の管理は gem で行います。
Ruby の一般的なライブラリの管理と同じ方法で行うことができるため手軽です。

### 命名規則
Itamae の resource plugin を作成する場合、 gem 名は

***itamae-plugin-resource-somename***

のフォーマットにします。

recipe plugin とは異なり、この名前がルールであるか、Wikiには記載されていませんが、
現状作成されているリソースをみると同じ命名規則にしているようです。

例えば、 tree を扱うするリソースなら。

***itamae-plugin-resource-tree***

のようにします。

クラス名は ::Itamae::Plugin::Resource::FooBar にする必要がある。
利用時は foo_bar で利用することになる。
大抵は、::Itamae::Resource::Base を継承する。

実装内容は既存のリソースを見て確認。
https://github.com/ryotarai/itamae/tree/master/lib/itamae/resource

### 課題とその解決策
基本的には recipe plugin と同じ話。
[課題](http://qiita.com/tbpgr/items/10e48679e6535cd1adf8#%E8%AA%B2%E9%A1%8C)
[解決策](http://qiita.com/tbpgr/items/10e48679e6535cd1adf8#%E4%B8%8A%E8%A8%98%E3%81%AE%E7%82%B9%E3%82%92%E5%8A%A0%E5%91%B3%E3%81%97%E3%81%9F%E8%A7%A3%E6%B1%BA%E7%AD%96)

## 試行
### 仕様
* toilet を操作する resource plugin を作成

### itamae-plugin-resource-toilet

~~~bash
# bundle gem で gem のひな型を生成
$ bundle gem itamae-plugin-resource-toilet
~~~

* itamae-plugin-resource-upgrade/lib/itamae/plugin/resource/toilet.rb を編集

~~~ruby
require 'itamae'

module Itamae
  module Plugin
    module Resource
      module Toilet < Itamae::Resource::Base
        COMMAND = 'toilet'
        define_attribute :action, default: :run
        define_attribute :text, type: String, default_name: true
        # Filters
        # "crop": crop unused blanks
        # "gay": add a rainbow colour effect
        # "metal": add a metallic colour effect
        # "flip": flip horizontally
        # "flop": flip vertically
        # "180": rotate 180 degrees
        # "left": rotate 90 degrees counterclockwise
        # "right": rotate 90 degrees clockwise
        # "border": surround text with a border
        define_attribute :filters, type: Array, default: []

        def set_current_attributes
          super
          ensure_toilet_available

          filters_exist = filters.empty?
        end

        def action_run(options)
          if filters.empty?
            run_command([COMMAND, attributes.text])
          else
            filter_options = filters.each_with_object([]) do |e, memo|
              memo += ['--filter', e]
            end
            run_command([COMMAND] + filter_options + [attributes.text])
          end
        end

        private

        def ensure_toilet_available
          return if run_command('which toilet', error: false).exit_status == 0
          fail '`toilet` command is not available. Please install toilet.'
        end
      end
    end
  end
end
~~~

* その他のファイルの編集内容は省略（通常の gem 作成時と同じ）

### resource plugin を install
今回は Private な Gemサーバーに公開し、そちらからインストールします。
gem server は geminabox を利用します。

詳しくはこちらの記事を参照。
[Ruby | RubyKaigi2014の知見。geminabox gem で Private な Gem Server を構築 #rubykaigi](http://qiita.com/tbpgr/items/53794bfb2a7c0d7247eb)

~~~bash
$ tree -L 2
.
┗ itamae-plugin-resource-toilet
    ┣ Gemfile
    ┣ itamae-plugin-resource-toilet.gemspec
    ┣ lib
    ┣ LICENSE.txt
    ┣ Rakefile
    ┗ README.md

# 各 recipe を実装

$ cd itamae-plugin-resource-toilet
$ rake build
# geminabox で作成したサーバーに gem を公開
$ gem inabox ./pkg/itamae-plugin-resource-toilet-0.0.1.gem
~~~

![itamae-plugin-resource-toilet.png](https://qiita-image-store.s3.amazonaws.com/0/43480/0a044bcb-baae-13e0-17d2-c8d339cb2d34.png)

### レシピを作成

~~~ruby
require 'itamae/plugin/resource/toilet'

toilet 'hoge' do
end

toilet 'hige' do
  filters ['gay']
end

toilet 'hage' do
  filters ['gay', 'flip']
end

toilet 'トイレ' do
  filters ['gay', 'border']
end
~~~

### Gemfile を作成

~~~ruby
source 'http://your_gem_server:your_port/'

gem 'itamae'
gem 'itamae-plugin-resource-toilet'
~~~

~~~bash
# geminabox（private gem server） から install
$ bundle install
$ gem list | grep itamae
itamae (1.0.1)
itamae-plugin-resource-toilet (0.0.1)
~~~

### 実行

※実行前に toilet はインストール済みとする

~~~
$ tree -L 1
.
┣ Gemfile
┣ Gemfile.lock
┣ recipe.rb
┗ Vagrantfile

$ sudo bundle exec itamae local recipe.rb

~~~

![toilet_resource.png](https://qiita-image-store.s3.amazonaws.com/0/43480/3d1f5c21-4437-f970-138d-3c3f4bdcb702.png)

## 参照
* [Itamae GitHub](https://github.com/ryotarai/itamae)
* [vagrant-itamae GitHub](https://github.com/chiastolite/vagrant-itamae)
* [軽量・高速版 Chef 「Itamae」。 プロビジョニングツールの学習コスト低下。Berkshelfからの解放。Chef Solo から Chef Zero への移行からの解放 #devops #itamae](http://qiita.com/tbpgr/items/3b6796c1cfc3c3e5521f)