Sunzi: Server provisioning utility for minimalists

"The supreme art of war is to subdue the enemy without fighting." - Sunzi

いわゆるchefのようなサーバープロビジョニングツール。

特徴

  • レシピはshell script
  • 冪等性?犬にくれてやれ!
  • root前提
  • デフォルト設定との差分だけを設定する
  • サーバー側に入れなきゃいけないソフトは無し(shell scriptだから)

ミニマリスト向けツールに見えますが意外と高機能で、基本的にknife-soloのようにクライアントからサーバーに対して使うの前提だし、berkshelfのようにリモートのrecipeを取り込む機能があるし、erbのテンプレートやweb, dbみたいなrole機能もあります。

そもそも俺はdebian(今だったらwheezy)しか使わないし、冪等性とか要らないし、VPSをサクッと設定したいだけなのでちょうどハマりました。

recipes/ruby.sh:

apt-get install -y ruby1.9.3

例えばrubyのrecipeはこんな感じ(少しだけ賢いsunzi.installの方がおすすめですが)。shell scriptなので他人のrecipeがいきなり読めるのがおっさんエンジニアには嬉しい。ちょっとした設定書き換えをsedでやってるの見るとホッとします。

これだったらちょこっと設定してcapistranoでrailsアプリデプロイするとこまで道筋がすごく見えやすいです。

vagrantでsandbox rollbackしながらrecipeを書いてくのが快適です。

疑問

仕事に使おうとしてるんですがいくつか疑問点が。

  • 鍵認証のrootユーザー、sshはデフォルトの22番で運用するのが普通?
  • capistranoでdeploy(=appサーバーの実行者)もrootユーザーでやるの?
  • ソフトのバージョンアップとかはどういう感じでやるの?

$ gem install icalendar
requre 'icalendar'

calendar = Icalendar::Calendar.new                                                                                 
event = Icalendar::Event.new                                                                                       
event.start = Date.new(2013, 7, 1)
event.end = Date.new(2013, 7, 8)
event.summary = "Foo Festival"
event.description = "Greatest event in the world."
event.location = "Hatsudai Tokyo Japan"
calendar.add_event(event)

puts calendar.to_ical

railsでリンクをクリックしたらiCalファイルダウンロード → iCal起動+登録ってやりたい場合。

class FooController < ApplicationController
  def calendar
    calendar = Icalendar::Calendar.new

    # implementation...

    headers['Content-Type'] = 'text/calendar; charset=UTF-8'
    render :inline, layout: false, text: calendar.to_ical
  end
end
$ heroku labs:enable user-env-compile

これすると行ける。理由はわからん・・・。

怖話(こわばな)でラジオにCMを出しました。

怖話が山口敏太郎のラジオ番組に進出!ラジオCMになりました! - 怖話からのお知らせ

世界最大の怖い話サイト「怖話」がラジオに進出!

オカルト評論家 山口敏太郎のラジオ番組内でラジオCMが放送されます!

以前発表いたしました「怖い話グランプリ」の期待の高まるなか、タッグを組んでいる山口敏太郎のラジオ番組「日本大好き」に怖話のラジオCMが流れることになりました!

音源は@machidaさんが知り合いに声も録音して作ってくれました。

@machidaさんはWebデザインよりDTM歴の方が圧倒的に長いのでメインで使われてるBGMも自作です。PS版弟切草のCMのイメージで作ったと言ってました。

ハマりポイント。

VMを壊す例として$ sudo rm -rf / --no-preserve-rootすると/vagrantにマウントされてるMac上のディレクトリまでVagrantfileごと消えるのでおすすめできない。

vagrantのplugin、saharaを使う

saharaを入れる。

% vagrant plugin install sahara

sandboxモードに入る。

% vagrant sandbox on

壊す。

% vagrant ssh
$ sudo rm -rf /usr
$ ls /usr
ls: cannot access /usr: No such file or directory
$ exit

戻す。

% vagrant sandbox rollback
% vagrant ssh
$ ls /usr/
bin  games  include  lib  local  sbin  share  src

ワオ、戻ってる!

昨日、隣の仙川でねじり鉢巻した建設関係っぽい軽トラのおっさんが、前にいるチャリンコのおっさんに対して、

「道の真ん中でフラフラと走ってんじゃねーよ!」

と非常に大きな声でスムーズに文句言ってた。

「ったく、道の真ん中でフラフラしてんじゃねーよ!」

あ、二回言った。

ものすごく怒ってるという感じではなくて、単に思ってることを一番気持ちいい声量で発声してる感じ。

あんな風に思ってることを微塵の遠慮もなく表明できたらストレス溜まらないだろうなあ。

現状渡しされてパスワードがわからない時。

mysql> update wp_users set user_pass = '$P$BQ6n8cNLFJBJyxYYoPK3bDWymBXILO.' where user_login = 'admin';

これでadminユーザーのパスワードがfooになります。

置いておきます。

https://dl.dropboxusercontent.com/u/188423/wheezy.box

VirtualBoxでVM作成

OS
Linux
バージョン
Debian
メモリ
512MB
オーディオ
無効
USB
無効
ストレージ
VMDK 32GB

Debian wheezyをインストール

rootパスワード: vagrant

vagrantパスワード: vagrant

VirtualBox Guest Additionのインストール

# apt-get install build-essential module-assistant sudo ssh ca-certificates zerofree
# m-a prepare
# reboot

Virtualboxのメニュー > Device > Install Guest Additions

# mount /media/cdrom
# sh /media/cdrom/VBoxLinuxAdditions.run

その他色々

# visudo
%sudo ALL=(ALL) NOPASSWD:ALL
# gpasswd -a vagrant sudo
# mkdir /home/vagrant/.ssh
# cd /home/vagrant/.ssh
# wget https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub
# mv vagrant.pub authorized_keys
# chmod 700 /home/vagrant/.ssh
# chown -R vagrant:vagrant /home/vagrant/.ssh
# echo 'UseDNS no' >> /etc/ssh/sshd_config

イメージサイズ縮小

# apt-get clean
# rm -rf /usr/src/vboxguest*
# rm -rf /usr/share/doc
# find /var/cache -type f -exec rm -rf {} \;
# rm -rf /usr/share/locale/{af,am,ar,as,ast,az,bal,be,bg,bn,bn_IN,br,bs,byn,ca,cr,cs,csb,cy,da,de,de_AT,dz,el,en_AU,en_CA,eo,es,et,et_EE,eu,fa,fi,fo,fr,fur,ga,gez,gl,gu,haw,he,hi,hr,hu,hy,id,is,it,ja,ka,kk,km,kn,ko,kok,ku,ky,lg,lt,lv,mg,mi,mk,ml,mn,mr,ms,mt,nb,ne,nl,nn,no,nso,oc,or,pa,pl,ps,pt,pt_BR,qu,ro,ru,rw,si,sk,sl,so,sq,sr,sr*latin,sv,sw,ta,te,th,ti,tig,tk,tl,tr,tt,ur,urd,ve,vi,wa,wal,wo,xh,zh,zh_HK,zh_CN,zh_TW,zu}
# init 1
# mount -o remount,ro /dev/sda1
# zerofree /dev/sda1
# halt

box作成

Macで。

% vagrant package --base wheezy

ハマリポイント

  • 古いvagrantを削除する。
  • VirtualBoxを新しくし過ぎない。(ちょっと古いやつを使う)
  • VirtualBox系でハマったらMacを再起動する。
  • ruby2.xではchef-solo動かない。
  • chefは公式サイトからcurlで入れる。
  • knife-soloはgithubから入れる。
  • knife-soloをbundle exec rake installする時ちゃんとruby1.9.3に入るようにする。

古いvagrantのアンインストール

% gem uninstall vagrant
% rm -rf ~/.vagrant.d

vagrantのインストール

http://downloads.vagrantup.com/tags/v1.2.2

debian wheezy64のvm作成

断固debian。

% vagrant box add wheezy64 http://dl.dropbox.com/u/937870/VMs/wheezy64.box
% mkdir wheezy64
% cd wheezy64
% vagrant init wheezy64
% vagrant up

下記でいい感じの設定を履いてくれる。(便利)

% vagrant ssh-config --host wheezy64 >> ~/.ssh/config
% ssh wheezy64

で入れるようになってる。

chef-soloのインストール

% curl -L https://www.opscode.com/chef/install.sh | sudo bash
% chef-solo -v
Chef: 11.4.4

ちゃんと動くか確認。

knife-soloのインストール

gem版は0.2.0だったのでgithubから入れる。

% git clone git@github.com:matschaffer/knife-solo.git
% cd knife-solo
% git submodule init
% git submodule update
% bundle
% bundle exec rake install

rubyが2.xだと動かないので注意!

chef-soloをwheezy64にインストール

% knife solo prepare wheezy64

これで入るChefが0.10.8なのが気になる・・・。

自分のcookbookのリポジトリ作成

% knife solo init chef-cookbook
% cd chef-cookbook
% git init .
% git commit -m'First commit'
% hub create

nginxをインストールするrecipeを書く

% knife cookbook create nginx -o site-cookbooks
% vi site-cookbooks/nginx/recipes/default.rb
package 'nginx' do
  action :install
end
% vi nodes/wheezy64.json 
{
  "run_list":[
    "nginx"
  ]
}

実行。

% knife solo cook wheezy64   
Running Chef on wheezy64...
Checking Chef version...
Uploading the kitchen...
Generating solo config...
Running Chef...
[Wed, 26 Jun 2013 08:35:26 +0200] INFO: *** Chef 0.10.8 ***
[Wed, 26 Jun 2013 08:35:26 +0200] INFO: Setting the run_list to ["nginx"] from JSON
[Wed, 26 Jun 2013 08:35:26 +0200] INFO: Run List is [recipe[nginx]]
[Wed, 26 Jun 2013 08:35:26 +0200] INFO: Run List expands to [nginx]
[Wed, 26 Jun 2013 08:35:26 +0200] INFO: Starting Chef Run for vagrant-debian-wheezy-64.vagrantup.com
[Wed, 26 Jun 2013 08:35:26 +0200] INFO: Running start handlers
[Wed, 26 Jun 2013 08:35:26 +0200] INFO: Start handlers complete.
[Wed, 26 Jun 2013 08:35:26 +0200] FATAL: No cookbook found in ["/home/vagrant/chef-solo/cookbooks-1", "/home/vagrant/chef-solo/cookbooks-2", "/home/vagrant/chef-solo/cookbooks-3"], make sure cookbook_path is set correctly.
[Wed, 26 Jun 2013 08:35:26 +0200] INFO: Processing package[nginx] action install (nginx::default line 9)
[Wed, 26 Jun 2013 08:35:26 +0200] INFO: Chef Run complete in 0.267082 seconds
[Wed, 26 Jun 2013 08:35:26 +0200] INFO: Running report handlers
[Wed, 26 Jun 2013 08:35:26 +0200] INFO: Report handlers complete

一応入ったけどFATALがきになる・・・。

scpとかtestとかちょっと長い処理があるとTwitterを見ちゃって戻ってきてまたちょこっと作業して長い処理があるとまたTwitter見ちゃう。

なのでTerminalで長い処理がある時は終わったら通知を出してすぐに作業に戻りたい。

$ gem install terminal-notifier
$ terminal-notifier-notify -message Finished!

terminal-notifier-notifyというコマンドが入って通知してくれる。

テストが成功でも失敗でも終わったら通知する。

$ rake; terminal-notifier-notify -message Finished!

ちょっと長いのでshellを書く。

~% cat ~/bin/finished 
#!/bin/sh
terminal-notifier-notify -message Finished!
$ rake;finished

testの場合はguard使えばいいけど手元にちょっとあると便利かもしれない。