63
67

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Chefのレシピでsed的な事を実施

Last updated at Posted at 2013-08-19

この記事は最終更新から1年以上経過しています。 気をつけてね。

Infrastructure as Codeに感化されていざChefを使うとなった時、ちょっと既存のファイルを弄りたいだけなのにcookbookfileとかtemplateとかメンドクセって思うじゃないですか。

『ほなexecuteリソースでちょっとsedコマンドしたら…』と思う前にちょっとChef::Utilを検討しませんか。

対象ファイルとレシピ

サンプルとしてこんな2行で出来たファイルを2つ用意しました。

tmp1,tmp2
hogehoge
mogemoge

では 'tmp1'に一致した行の置換、'tmp2'では文字列の置換を実施してみます。

apply.rb
file './tmp1' do
  _file = Chef::Util::FileEdit.new(path)
  _file.search_file_replace_line('^hoge', "piyopiyo\n")
  content _file.send(:contents).join
end

file './tmp2' do
  _file = Chef::Util::FileEdit.new(path)
  _file.search_file_replace('ge', "ga")
  content _file.send(:contents).join
end

追記中:Chef-Clientが11.12以降では FileEditの@contentsがなくなり、@editor.linesに変更。

apply2.rb
## 11.12.0以降のクライアント
file './tmp1' do
  _file = Chef::Util::FileEdit.new(path)
  _file.search_file_replace_line('^hoge', "piyopiyo\n")
  content _file.send(:editor).lines.join
end

file './tmp2' do
  _file = Chef::Util::FileEdit.new(path)
  _file.search_file_replace('ge', "ga")
  content _file.send(:editor).lines.join
end

Chef::Util::FileEdit.new(path)pathについて。
レシピのリソース定義内では自分(self)のattributesを利用することができるので、path(※省略時はnameと同じ)を使いまわしてChef::Util::FileEdit読み込み対象にしてるんですね。

参考:file — Chef Docs

#contentsがprivate_methodなのでちょっと:sendしましたがまあいいっしょ。

Result

:dry_runです、きっと目論見通りですね。

chef-apply(dry_run)
$ chef-apply appry.rb -w
Recipe: (chef-apply cookbook)::(chef-apply recipe)
  * file[./tmp1] action create
    - Would update content in file ./tmp1 from 639ed8 to 55d5ca
        --- ./tmp1	2013-08-20 00:45:11.000000000 +0900
        +++ /var/folders/s9/kwcs_8ln0d32v_n4hdfb7td00000gn/T/.tmp120130820-24879-gemfn5	2013-08-20 00:45:19.000000000 +0900
        @@ -1,2 +1,2 @@
        -hogehoge
        +piyopiyo
         mogemoge
  * file[./tmp2] action create
    - Would update content in file ./tmp2 from 639ed8 to 93260c
        --- ./tmp2	2013-08-20 00:45:03.000000000 +0900
        +++ /var/folders/s9/kwcs_8ln0d32v_n4hdfb7td00000gn/T/.tmp220130820-24879-ieq0kc	2013-08-20 00:45:19.000000000 +0900
        @@ -1,2 +1,2 @@
        -hogehoge
        -mogemoge
        +hogahoga
        +mogamoga

実施します、まあ:dry_runと変わらず。

chef-apply(conversion)
$ chef-apply appry.rb 
Recipe: (chef-apply cookbook)::(chef-apply recipe)
  * file[./tmp1] action create
    - update content in file ./tmp1 from 639ed8 to 55d5ca
        --- ./tmp1	2013-08-20 00:45:11.000000000 +0900
        +++ /var/folders/s9/kwcs_8ln0d32v_n4hdfb7td00000gn/T/.tmp120130820-24938-1bwvf6g	2013-08-20 00:45:41.000000000 +0900
        @@ -1,2 +1,2 @@
        -hogehoge
        +piyopiyo
         mogemoge
  * file[./tmp2] action create
    - update content in file ./tmp2 from 639ed8 to 93260c
        --- ./tmp2	2013-08-20 00:45:03.000000000 +0900
        +++ /var/folders/s9/kwcs_8ln0d32v_n4hdfb7td00000gn/T/.tmp220130820-24938-h5bq4k	2013-08-20 00:45:41.000000000 +0900
        @@ -1,2 +1,2 @@
        -hogehoge
        -mogemoge
        +hogahoga
        +mogamoga

続いてchef-apply実施、もうファイルに対して残す変更はありません。

chef-apply(up_to_date)
$ chef-apply appry.rb 
Recipe: (chef-apply cookbook)::(chef-apply recipe)
  * file[./tmp1] action create (up to date)
  * file[./tmp2] action create (up to date)

よし、本日も冪等である。

その他FileEditのメソッド

その他sedでよく使うマッチ行の次に挿入や、sedでやるのは多分面倒くさい'無かったら追記'がメソッドとして用意されています。

Chef::Util::FileEdit.instance_methods(false)
pry(main)> Chef::Util::FileEdit.instance_methods(false)
=> [:search_file_replace_line,
 :search_file_replace,
 :search_file_delete_line,
 :search_file_delete,
 :insert_line_after_match,
 :insert_line_if_no_match,
 :write_file]

Chef::UtilのあたりChefの中でもかなり古いコードです、初期はファイルをちょろっといじるようなツールだったのでしょうかね。


追記:
念のため書いておくとChef::Util::FileEdit本来の使い方は#write_fileで、Chef::Util::Backupなどと組み合わせて主にLibraryやLWRP方面で利用します。
ただレシピ内でやるのは芸が無いと思うのです。

追記2:

普通の使い方のサンプルも引用しておきます。

timezone cookbook(fork版)より。

  clock = Chef::Util::FileEdit.new("/etc/sysconfig/clock")
  clock.search_file_replace_line(/^ZONE=.*$/, "ZONE=\"#{node[:tz]}\"")
  clock.write_file
63
67
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
63
67

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?