Hatena::ブログ(Diary)

(ひ)メモ このページをアンテナに追加 RSSフィード

2014-08-28 (Thu)

VirtualBoxのスナップショットを簡単に管理できるツールを書きました。GO言語で。

VagrantではSahara pluginを使うことで、VMの状態を以前の状態に巻き戻すことができます(sandobx mode)。

VMの中でいろいろいじっている際に変更前の状態に戻せるのはとても便利なのですが、Saharaでは戻せるチェックポイントをひとつしか作れません。

自分の場合、深遠なChefのレシピを書いている過程で、戻せるポイントを何個か置きたくなることがよくあります。


さて、VagrantのバックエンドとしてVirtualBoxを使っている人は多いかと思います。

バックエンドがVritualBoxの場合、SaharaのsandboxはVirtualBoxのsnapshotを使って実現されています。

VirtualBoxのsnapshotはひとつだけでなくいくつでも作ることができます。

CUIVirtualBoxの操作(snapshotを作ったり)をするには、vboxmanage コマンドを使えばできるのですが、VMの名前が長かったりしてちょっと使いづらいです。

そこでsnapshotに関連する操作を簡単に実行できるラッパーツールを作りました。

使い方

動作中のVMの一覧を得る
$ vboxss list
vm1                 vm1_default_1404895653615_55181
vm2                 vm2_default_1404967162355_44921

VMの正規名は右側のながーいやつですが、vboxssは左の短縮名でも受け付けます。多くの場合、短縮名はvagrant initしたディレクトリ名になると思います。

あるVMのsnapshotの一覧を得る
$ vboxss list vm1
List of the snapshots of vm1_default_1404895653615_55181
initial                           e718f597-22b4-4bef-adf6-239fff78215f
install-apps                      5337e220-0075-46a5-8aaa-901361f352df
before-apply-chef                 703071da-26c1-4504-8c81-4535de33c2f2

listの後にVM名を指定すると、そのVMのsnapshotの一覧が表示されます。VM名は短縮名でも長い正規名でもOKです。

snapshotをとる
$ vboxss take vm1 provisioned

takeの後に、VM名と、snapshotにつける名前を指定します。

snapshotを使ってVMをレストアする
$ vboxss restore vm1 before-apply-chef

vm1という名のVMの状態を、before-apply-chefという名のsnapshotの状態に戻します。

vboxss restoreを実行すると、一旦VMが停止される点に留意してください。(レストア後、自動でまた立ち上がります)

snapshotを消す
$ vboxss delete vm1 provisioned

落穂ひろい

Goをまともに書いたのはこれが初めてなので「こう書いたほうがイイヨ!!」とかあったら教えてください><


バイナリのビルドと配布は Wercker を使ってます。@ さんと @ さんのを参考にさせてもらいましたー&Werckerのboxは lestrrat/peco-build をそのまま使わせてもらってます!!

2014-07-28 (Mon)

シンボリックリンク絡みでtail -Fが追従しないケース

tail -Fしているfluent-agent-liteでハマったのでメモ。

存在しないファイルをtail -Fした後、その名前のシンボリックリンクを作った場合

$ rm -fr ~/oreno-tmp && cd ~/oreno-tmp

$ tail -F tailme &
tail: cannot open `tailme' for reading: No such file or directory

$ ln -s real-file tailme
tail: cannot watch `tailme': No such file or directory

$ date >  real-file
$ date >> real-file
$ date >> real-file
  # tail -Fから流れてこない

ちなみに、存在するファイルを指すシンボリックをtail -Fしてる場合、途中で指す実ファイルが存在しなくなっても、実ファイルができ次第、追従してくれます。

$ rm -fr ~/oreno-tmp && cd ~/oreno-tmp

$ touch real-file.yesterday
$ ln -s real-file.yesterday tailme
$ tail -F tailme &
tail: inotify cannot be used, reverting to polling

$ date >> real-file.yesterday
Mon Jul 28 21:20:59 JST 2014

$ ln -sf real-file.today tailme
tail: `tailme' has become inaccessible: No such file or directory

$ date >> real-file.today
tail: `tailme' has appeared;  following end of new file
Mon Jul 28 21:21:39 JST 2014

$ date >> real-file.today
Mon Jul 28 21:21:48 JST 2014

つまり、既に存在する日付入りファイル名の実ファイルを指すシンボリックリンクがある場合は、00:00に今日の日付の名前を持つ実ファイルにシンボリックリンクを切り替えたときに、今日の日付の名前の実ファイルはあってもなくてもよい。

が、ド新規で追加したログファイルとかで、実ファイルもシンボリックリンクもない場合はハマる。


実ファイルがシンボリックリンクに変わった場合

$ rm -fr ~/oreno-tmp && cd ~/oreno-tmp

$ date > tailme
$ tail -F tailme &
Mon Jul 28 21:07:06 JST 2014

$ date >> tailme
Mon Jul 28 21:07:54 JST 2014

$ ln -sf real-file tailme
tail: `tailme' has become inaccessible: No such file or directory
tail: cannot watch `tailme': No such file or directory
$ date >> real-file
$ date >> real-file
$ date >> real-file
  # tail -Fから流れてこない

2014-07-17 (Thu)

daemontoolsなserviceをハンドリングするための Chef::Provider::Service::Daemontools を書いてみました

Chefでdaemontools配下のサービスをハンドリングするときは、コミュニティクックブックの daemontools を使ってる人が多いと思います。

こんな感じで。

daemontools_service "tinydns-internal" do
  directory "/etc/djbdns/tinydns-internal"
  template false
  action [:enable,:start]
end

notification も送れます。

template '...' do
  ...
  notifies :restart, 'daemontools_service[tinydns-internal]'
end

自分もこれを使おうと思ったのですが、いくつか不満点がありました

  • serviceとdaemontools_serviceの両対応のレシピを書く場合、
    • service と daemontools_service とでほぼ同じ記述をしないといけない
    • notifies を送る側でも service か daemontools_service か意識しないといけない
  • action :stop で svc -p (SIGSTOP) している
    • なんで svc -d (SIGTERM) じゃないんでしょうか。。。
  • サービスのハンドリングだけしたいので、daemontools のインストールとかは別に要らない
    • 依存で ucspi-tcp もインストールされるが使ってないので要らない
    • RedHat系だと "daemontools" という名前のパッケージを入れようとするが、(内部のyum reposにある)"daemontools-toaster" を入れたい
      • attribute によるパッケージ名の変更はできない
  • run ファイルの生成機能は別に要らない(あっても使わなければいいだけだけど)

ので、service リソース (http://docs.opscode.com/resource_service.html) の provider として指定可能な Chef::Provider::Service::Daemontools を書いてみました。

gem install chef-provider-service-daemontools でインストールして、こんな感じで使えます。

require 'chef/provider/service/daemontools'

template '...' do
  ...
  notifies :restart, 'service[oreno-daemon]'
end

service 'oreno-daemon' do
  provider Chef::Provider::Service::Daemontools
  service_dir '/service'
  directory '/usr/oreno/daemon/oreno-daemon'
  supports :restart => true, :reload => true
  action [:enable, :start]
end
  • provider: 「provider Chef::Provider::Service::Daemontools」は必須です
  • service_dir: svscanが監視しているディレクトリです。この下にsymlinkが作られます。デフォルトは /service です
  • directory: symlinkが指すrunファイル等があるディレクトリです。デフォルトは /usr/oreno/daemon/#{service_name} です

notifies でも既存の service と同じように 「service[oreno-daemon]」 と指定できるのがミソです。

Special thanks!

daemontools.rb を書くにあたり、ルビーカの低い自分を @ さんと @ さんに助けていただきました! あざっっっっっっっっっっっっっす!!!

2003 | 11 | 12 |
2004 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 10 | 11 | 12 |
2005 | 01 | 02 | 03 | 05 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 12 |
2012 | 01 | 02 | 03 | 06 | 08 | 10 | 11 | 12 |
2013 | 01 | 02 | 03 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2014 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 |