2013年7月30日火曜日

Vagrantドキュメントを意訳してみる Getting Started前篇

多分こんな感じなはず。(たぶん)
オリジナル: http://docs.vagrantup.com/v2/getting-started/index.html

Getting Startedガイド

Getting StartedガイドではVagrantの基本と主な機能を説明します。

初めてのVagrantプロジェクトを作成する前に、Vagrantをインストールしてください。
もし、なぜVagrantを使う必要があるのか疑問がある場合は、"Why Vagrant?"をご参照のこと。

Getting StartedガイドではVagrantを使うために、
VirtualBox(無料でなおかつメジャーなOSで利用可能なので)を使います。
ですが、VagrantはVirtualBoxだけでなくVMWareなどの
他のプロバイダーを使っても動きますのでお忘れなきよう。

ともかく動かしてみる!


$ vagrant init precise32 http://files.vagrantup.com/precise32.box
$ vagrant up

↑の2つのコマンドを実行すると、
VirtualBox上でUbuntu 12.04 LTS 32-bitをインストールしたVMが動きます!
vagrant sshコマンドでこのVMにsshログインできますし、
ひとしきり遊び終わったらvagrant destroyでVMを削除することもできます。

簡単でしょ?

Vagrantでは、vagrant upさえすれば、
プロジェクトに必要な全部の依存関係の解決やネットワークの設定やフォルダの同期などを
勝手にやってくれます。

このガイドの残りでもうちょっと詳しくVagrantの機能について説明します。


プロジェクトのセットアップ

Vagrantを使うためにはまずVagrantfileを編集する必要があります。
Vagrantfileの存在意義は2つあります。

1. Vagrantfileを置いた場所をプロジェクトのrootディレクトリとすること。
Vagrantの設定で使うパスなどはこのrootディレクトリとの相対パスとなります。

2. プロジェクトに必要なVMの設定やインストールすべきソフトウェアや
どうやってVMにアクセスするかの設定を書くこと。

rootディレクトリを初期化するためには
vagrant initコマンドを使います。
ということで、以下のコマンドを実行してみましょう。

$ mkdir vagrant_getting_started
$ cd vagrant_getting_started
$ vagrant init

これで、vagrant_getting_startedディレクトリにVagrantfileが作成されます。
Vagrantfileをちらっと見てください。コメントと実例で埋め尽くしてます。

既存のディレクトリをVagrant用にセットアップすることもできます。

プロジェクトごとにVagrantfileをバージョン管理すると便利です。
そうすると、そのプロジェクトで一緒に働いている人がみんなハッピーになりますから。

BOX

VMをスクラッチからビルドする代わりに、
VagrantはVMにお手軽に環境をcloneするために、ベースとなるイメージを使います。
ベースとなるイメージはVagrantでは"box"と呼んでいます。
Vagrantfileを作成したら、いの一番にプロジェクトで使うboxを指定しましょう。
(こうすることによって、CentOSのISOをダウンロードして、
ISOから一からインストールするというプロセスをスキップできます。)

boxをインストールする!


もし↓のコマンドをすでに打ってたら、

$ vagrant init precise32 http://files.vagrantup.com/precise32.box

もうboxはインストールされているのでもう一回インストールコマンドを打つ必要はないです。
ただ、もうちょっと詳しくboxについて知るためには、
このセクションを読んどいたほうがいいです。

boxはvagrant box addコマンドを打った時に追加されます。
boxは複数のVagrant環境が再利用できるように特定の名前をつけます。

$ vagrant box add precise32 http://files.vagrantup.com/precise32.box

↑のコマンドでboxがhttp://files.vagrantup.com/precise32.boxからダウンロードされ、
"precise32"という名前で保存されます。
(ローカルマシン内のboxファイルも同じ手順で管理することができます)

追加したboxは複数プロジェクトで再利用できます。
各プロジェクトはboxをベースイメージとして使うだけなので、
保存されたboxファイルは修正されません。
つまり、2つのプロジェクトでprecise32(さっきダウンロードしたbox)を利用していても、
お互いに全く影響がありません。

boxを使う


さてさてboxがVagrantに追加されたので、
プロジェクトがさっき追加したboxをベースイメージとするように設定します。
Vagrantfileを開いて以下の内容を編集します。

Vagrant.configure("2") do |config|
  config.vm.box = "precise32
end

"precise32"はさっき追加したbox名と一致してなければなりません。
Vagrantはこの名前にもとづいてどのboxを使うべきかを判断します。

次のセクションではVMを立ち上げて、すこし遊んでみます。

立ち上げてSSHでログインしてみる!

ではさっそくVMを立ち上げてみましょう。

$ vagrant up

1分以内にUbuntuがインストールされたVMが起動されます。
・・・とは言っても、VagrantはUIなしでVMを立ち上げるので、
何も起こってないように見えるでしょう。
実際に起動していることを確かめるため、VMにsshでログインしてみましょう!

$ vagrant ssh

このコマンドでsshログインでき、VM上で好き放題出来ます。
ただし、↓のコマンドだけは気をつけてください、

$ rm -rf /

といいますのも、VM上の/vagrantディレクトリは
ホストマシンのVagrantfileを含むディレクトリと同期しているからです。



・・・ちょっと考えてみてください。
たった一行のコンフィグファイルの修正と一つのコマンドでSSHでログイン可能なVMを作りましたよ。どうですよ?

作ったVMでひと遊びしたら、vagrant destroyコマンドをホストマシンで打ってください。
さっき作ったVMを跡形もなく削除します。

2013年7月29日月曜日

Vagrantドキュメントを意訳してみる インストール篇

多分こんな感じなはず。(たぶん)
オリジナル: http://docs.vagrantup.com/v2/installation/index.html

Vagrantのインストール!

Vagrantのインストールはとても簡単です!
ダウンロードページに行って
各OS用のインストーラーをダウンロードするだけ。
後は他のアプリのインストールとおんなじようにインストールするだけです。

インストールが終わると、ターミナルから"vagrant"コマンドが打てるはずです。
もしコマンドが打てなかったら、
一回OSからログアウトしてまたログインしたら打てるようになっているはず。
(Windowsだとたまに必要)

もし、gemでVagrant 1.0.x系をすでにインストールしてるのなら、
新しいのをインストールする前に1.0.x系をgem uninstallする必要があります。

gemインストール??
Vagrant 1.0.x系だとgemでインストールすることができますが、
あんまりオススメじゃないからやめた方がいいです。(たぶん今後のサポート無し)
代わりにここからダウンロードしてください。

後方互換性

1.0.x系との互換性

Vagrant 1.1+はpluginを使ってないVagrant 1.0.xとなら完全に互換性があります。
なので、アップグレードしても、Vagrant 1.0.x系で作った環境もそのまんま使えます。

ただし、もし1.0.x系のpluginを使ってるのなら要注意
Vagrantfileに書いてあるpluginへの参照を完全に削除する必要があります。
Vagrant 1.1+からはpluginのフォーマットが新しくして、
こういう互換性のなさを避けるようにしました。

もし、pluginを使ってない1.0.x系のVagrantfileが1.1でうまく動かなくなったら、
バグを報告してください。


1.X系との互換性

1.x系(1.0以外)の間での後方互換性は保証してません。
さらに言っておくと、Vagrantfileのsyntaxも2.0 finalまではころころ変わるかもしれない。
ただ、互換性がない部分はドキュメントに丁寧に書くつもりなのでそれを見てください。

0.x系のときも同じでしたね。
2.0 finalは1.0系と同じで完全に後方互換性を保つつもりです。

Vagrantのアップグレード!

1.0.x系からアップグレードする場合は一つ↓の項目をみてください。
ここでは1.x系(1.0系以外)間でのアップグレード方法を書くつもりです。

1.x系でのアップグレードはとてもシンプルです。
ただ新しいパッケージをダウンロードしてインストールするだけです。
後はインストーラが勝手にやってくれます。
Linuxのパッケージマネージャー(yumとかaptitude?)を使っている場合も
同じようにうまいことインストールしてくれるはず。

さっきも言いましたが、2.0系になるまでは
1.x系でのVagrantfileのSyntaxの互換性は保証してないから
それだけは要注意です。

1.0.x系からのアップグレード!

1.0.x系から1.x系へのアップグレードはとてもシンプルです。(さっきも言ったな・・・)
ただ新しいパッケージをダウンロードしてインストールするだけです。

ただ、gemで1.0.x系をインストールしてしまったときは要注意です。
その場合は、新しいのをインストールする前に、gem uninstallする必要があります。
1.x系以降は、gemでのインストールはもうサポートしてません。

Vagrantのアンインストール

Vagrantのアンインストールもこれまた簡単です。
Vagrantのバイナリかユーザーデータを削除すればOKです。
もちろん両方削除してもOKです!
↓でもう少し詳しく説明します。

Vagrantプログラムの削除

Vagrantプログラムを削除したら、
vagrantのバイナリや依存してるファイルを全部マシンから削除します。

Windows ... コンパネからプログラムの追加と削除でアンインストール
Mac OS X ... /Applications/Vagrantディレクトリと/usr/bin/vagrantを削除
Linux ... /opt/vagrantディレクトリと/usr/bin/vagrantを削除

ユーザーデータの削除

ユーザーデータを削除することは、
つまり、boxpluginやVagrantが保存した状態すべてを削除するってことです。

ユーザーデータを削除すると、
再インストールするときに、Vagrantは全く新しいインストールだと認識します。

ユーザーデータの削除時にやることは、どのOSでもやることは同じです。
~/.vagrant.dディレクトリの削除です。

Vagrantを実行すると勝手に必要なデータを作成するので、
ためらわずに削除しちゃってください。


2013年7月15日月曜日

Gitでほんとによく使うコマンド

自分はもともとsvnでバージョン管理してたので、
正直最初gitにはとっつきにくかったです。

とっつきにくかった理由は、

1. 分散管理がようわからん
2. svnと用語が微妙に違う

ってとこだと思います。

1についてはhttp://git-scm.com/book/ja
1.1と1.3をよく読めばなんとなくわかってくるかと思います。

2については反復実行して体で覚えるしかないです。

$ git clone <remote> <local>
  リモートリポジトリからローカルリポジトリとワークスペースを作成する。
$ git pull
  最新版のリモートリポジトリを取得してローカルリポジトリ、ワークスペースを更新する
$ git push <remote> <branch>
  リモートリポジトリへローカルリポジトリの変更を更新する
$ git init --bare --shared
  gitのリモートリポジトリを作成する。しかもグループで共有したい。
$ git add <file>
  修正したファイルをステージングにあげる。新しく追加したファイルをバージョン管理する。
$ git reset HEAD <file>
  ステージングに上げたファイルをステージングから下ろす。
$ git commit
  ステージングにあがっている修正をコミットする。
$ git commit -a
  git addなんてめんどくさいって時に便利。
$ git commit --amend
  やっちまった!一つ前のコミットを修正したい・・・
$ git mv  <from> <to>
  ファイルをリネームする
$ git rm <file>
  ファイルを削除し、バージョン管理からも外す
$ git branch
  ブランチを表示し、現在のブランチを知る。
$ git branch <branch>
  ブランチを作成する
$ git checkout <branch>
  ブランチを切り替えたい
$ git checkout -b <branch>
  ブランチを作成しつつ切り替える
$ git merge <branch>
  ブランチをマージする
$ git rebase <branch>
  ブランチをリベースする

リモートリポジトリ関連

リモートリポジトリの取得


社内gitや自分のgitやGitHubからプロジェクトを取得するには、
以下のコマンドを打ちます。

$ git clone <remote> <local> 

svn checkoutとたぶんほぼ同じです。
このコマンドで、<local>で指定したディレクトリに
ローカルリポジトリとワークスペースが作成されます。
また、↓のような感じで<local>を指定しないこともできます。
この場合、nerdtreeディレクトリが作成されます。

$ git clone https://github.com/scrooloose/nerdtree.git

clone以降、開発中はファイルのステータスが
"修正済み", "ステージングに上がっている", "コミット済み"を行き来するわけですが
その間リモートリポジトリとのやり取りは発生しません。

リモートリポジトリ <-> ローカルリポジトリのやり取り


$ git pull
$ git push <remote> <branch>

git pushするとリモートリポジトリを、
ローカルリポジトリと同期するのですが、
複数人で開発している場合は、
その前にgit pullをして他の人の修正を取り込まなければgit pushできません。

リモートリポジトリの作成


$ git init --bare --shared

↑のコマンドを実行すると、リモートリポジトリを作成することができます。
--sharedを忘れると、基本的には複数人で開発できなくなります。
ただし--sharedをつけても、開発者全員が同じグループに所属している必要があります。

ステージング <-> ワークスペースのやり取り

$ git add <file>

git addしたファイル(またはディレクトリ)は
コミット候補生(ステージングされた状態)となります。

なぜステージングなんて中途半端なものがあるのか ・・・
と最初はまどろっこしいわいと思ってましたが、
コミットヒストリーにためらい傷を残さないですむので
そそっかしい人にはちょうどいいです。
(他にもステージングがある理由はあると思いますが・・・)

そして、
あ、間違ってステージングに上げてしまった!って時は慌てずに、
  git reset HEAD iwaswrong.txt

を実行すればステージング前の状態に戻ります。

コミットする

ステージングにあげた修正をコミットする場合は、
$ git commit

を実行します。
実行するとコメントを求められますので、
あとで見直す自分のことを考えて、わかりやすいコメントを入力します。

ちょっとした修正なのでわざわざステージングに上げるのもめんどくさいという時には、
$ git commit -a

なんて便利なコマンドもあります。
これを使うと、ワークスペースの修正がすべてローカルリポジトリに反映されます。

前回のコミットのコメント間違った!とかファイル1個追加し忘れた!って時は、
$ git add forgottenfile.txt
$ git commit --amend

でコミットをやり直せます。

ファイルをリネームしたり削除したり・・・

遠い過去なのであまり覚えてませんが、
ファイルのリネームはsvnだと若干めんどくさかったような記憶があります。

それは置いといて、まずはバージョン管理から外す方法ですが、

$ git rm unnecessary.txt

で可能です。コマンドを実行するとunnecessary.txtはバージョン管理から外れるのみならず、
ファイル自体削除されるので要注意です。(すぐに戻せますが)

ちなみにリネームのプロセスはgitだと以下のプロセスでできます。

$ mv old.txt new.txt
$ git rm old.txt
$ git add new.txt

・・・めんどくさっ!
以下のコマンド一発で同じ事ができるのでご安心ください。

$ git mv old.txt new.txt

ブランチ関連あれこれ

ブランチを知る


$ git branch
* master

でブランチの一覧を表示します。

作成したばかりのリポジトリだとmasterブランチしかないはず。
masterの左に*がついてると思いますが、*がついているところが現在作業中のブランチです。

ブランチの作成と切り替え


例えば、devブランチを新しく作成したい場合は

$ git branch dev

を実行します。
そして、devブランチに作業ブランチを切り替えます。

$ git checkout dev

この一連の流れ(ブランチ作成しーの切り替えーの)をコマンド一発でもできます。

$ git checkout -b dev

ブランチを合併


devブランチで開発をしているさなか、
新機能Aを追加するためにfeatureAブランチを切って開発する一方で、
BUG 1が発見されたのでその解決のためにdevブランチからhotfix1ブランチを作成した。

新機能AもBUG 1も無事修正が終わり、devブランチとマージしたい。
しかし、featureAブランチはhotfix1ブランチから枝分かれしたことにしたい。
というケースを考えてみる。

$ git branch
  master
  dev
  featureA
* hotfix1                         # 現在hotfix1ブランチで作業中
$ git checkout featureA  # featureAブランチへ移動
$ git rebase  hotfix1        # BUG 1の修正をfeatureAブランチに取り込む。
$ git branch
  master
  dev
* featureA
  hotfix1
$ git checkout dev          # devブランチへ移動
$ git merge featureA       # 新機能Aをマージ

git rebaseとgit mergeをこのように使い分けると何がいいかっていうと、
git mergeだけだと、コミットヒストリーは、

--dev--featureA
    |--hotfix1

--14a2b--featureA--dev
      |--hotfix1----------|

となるところを

--dev--featureA
    |--hotfix1

--14a2b--hotfix1--featureA--dev

という綺麗なコミットヒストリーのツリーを作ることができる点です。

しかし、細かいことは忘れましたが、
git push前後でgit rebaseをすると、
とんでもないことが起こって、共同開発者に切れられるらしいので要注意です。




もっと便利にgitを弄びたいという方は、
* Pro Git: http://git-scm.com/book/ja
の1, 2, 3, 5章を読めばだいたいOKかと思われます。

もっと深くgitを知りたいという方は
↑の他の章も読むとよろしいかと思います。

なんにせよ↑の本一冊で十分じゃないかなと思います。

アルゴリズムを体で覚えてみる 二分探索

最近訳あってアルゴリズムの勉強をしてます。

いままであんまりアルゴリズムに強い関心を持ってたわけじゃないですし、
正直アルゴリズムなんて知らなくても大概のプログラムは書けると思うのですが・・・
やはりアルゴリズムは強力だなと思う今日このごろです。

超有名ですが、『二分探索』って改めてすごいなーと思ったので、
二分探索について書いてみたいと思います。

線形探索(配列の先頭から順番に調べてくあれです)と
二分探索の計算のオーダーをそれぞれ比較してみると・・・

* 線形探索 O(n)
* 二分探索 O(log n)

なのはたぶん有名だと思うのですが、
正直この凄さをあまり真面目に考えたことがなかったです。
ほんとプログラマーやっててすみませんでした。

なにがすごいって、、、
n=1,000,000の場合、
線形探索の場合、平均して500,000回の比較が必要となりますが、
二分探索の場合、最悪でもおよそ19回の比較で十分なんですよ。
いやほんとすみません・・・

ちょっとPythonで書いてみます。(バグってたらすみません)

def binsearch_rec(target, arr, l, r): 
    """ 再帰で二分探索をする関数

    target: 見つけ出したい値
    arr: targetを探索する配列
    l: arrの探索範囲の左端
    r: arrの探索範囲の右端

    前提条件: arrは昇順にソートされている必要がある
    戻り値: targetの見つかった位置。見つからなかった場合は-1
    """

    if l > r:
        # 探しに探したが見つからなかった
        return -1

    m = (l + r) / 2 # 探索範囲の真ん中のindexを計算
    if target < arr[m]:
        # 見つけたい値がarrの真ん中より小さかったら
        # mより左の範囲を再帰的に探す。
        return binsearch_rec(target, arr, l, m-1)
    elif target > arr[m]:
        # 見つけたい値がarrの真ん中より大きかったら
        # mより右の範囲を再帰的に探す。
        return binsearch_rec(target, arr, m+1, r)
    else:
        # 見つけた!
        return m


↑は再帰バージョンですが、ループを使う方法もあります。
def binsearch_loop(target, arr):
    l = 0 
    r = len(arr)-1
    while l <= r:
        m = (l + r) / 2 
        if target < arr[m]:
            r = m-1 
        elif target > arr[m]:
            l = m+1
        else:
            return m
    return -1

趣味だとは思いますが、個人的には再帰を使う方が覚えやすいです。
ですが、ループのほうが関数の呼び出し分のロスがない分、
速いという噂もあります。



正直なところ、探索が必要なときは
今まですべて線形探索してました。
というか二分探索する必要すらなかったのですが・・・
・・・にしても自己嫌悪に陥いりますわ。


2013年7月14日日曜日

VagrantとChef SoloでNode.jsの開発環境を作る

Nodeの開発環境ってどうやって準備してますか?
nvmいれてnodeを入れてnpmでパッケージインストールするだけ!
といえばそうなんですけど・・・例えば、別のマシンで環境を作りなおすとなると
少しめんどうですよね。

例えば、VirtualBoxをインストールして、Vagrantをインストールして、
コマンド一発で環境を作り直せるとしたら便利ですよね・・・

node入れるだけならそれほど便利さは実感できないと思いますが、
例えば、そこにApacheやらNginxをいれて、Rails入れたりとかしなきゃいかんとなると、
ゾッとしますね。
それにコマンド一発だとインストール漏れもないという利点も・・・

ということで、VirtualBox + Vagrant + Chef Soloで
Mac上に作ったVirtual Machineにnodeをインストールして、
さらにgruntをインストールするというレシピを作ってみます。

ChefやレシピやChef Soloについては↓でとてもわかりやすく説明されております。

* 明日から始めるChef入門
  http://www.slideshare.net/TakeshiKomiya/chef-20014957
* Chef Soloの正しい始め方
  http://tsuchikazu.net/chef_solo_start/


レシピを作る

Vagrantfileがあるディレクトリで、以下のコマンドを実行して
レシピの置き場所を作成します。
  $ knife solo init chef-repo

↑のコマンドを実行すると、
chef-repo以下にいい感じでディレクトリツリーが出来上がります。

3rdパーティーのレシピはchef-repo/cookbooksに置き、
自作レシピはchef-repo/site-cookbooksに置くそうです。


git, curlコマンドをインストールするレシピを作ってみる


nvmをインストールするためにgitとcurlコマンドが必要なので、
git, curlコマンドをインストールします。
まずは先ほど作成したchef-repoディレクトリに移動して、Cookbookの雛型を作成します。
 $ knife cookbook create base -o site-cookbooks/

↑のコマンドを実行すると、
site-cookbooks以下にbaseディレクトリ(Cookbook)が作成されます。

次に、git, curlコマンドをインストールするレシピを書いてみます。
  $ cd site-cookbooks/base/
  $ vi recipes/default.rb
    package "git"
    package "curl"

たったこれだけで、
Ubuntu (Debian系)ならapt-getコマンドが呼ばれ、
CentOS (Redhat系)ならyumコマンドが呼ばれてインストールが始まります。

nvmをインストールするレシピを作ってみる


まずは先ほどと同じく、nvmレシピの雛型を作成します。
  $ knife cookbook create nvm -o site-cookbooks/

ではではnvm & Node.js v0.10.1をインストールするレシピを書いてみます。

  $ cd site-cookbooks/nvm/
  $ vi recipes/default.rb
    git "/usr/local/nvm" do                                            # githubからnvmを/usr/local/nvmへインストール
      repository "git://github.com/creationix/nvm.git"
      notifies :run, "bash[nvm.sh]"                                 # インストールが終わったらnvm.shという名前のbashを実行
    end

    bash "nvm.sh" do                                                     # nvm.shという名前のbash。
      code <<-EOH
        . /usr/local/nvm/nvm.sh                                      # nvmコマンドの読み込み
        nvm install v0.10.1                                               # Node.js v0.10.1をインストール
      EOH
      action :nothing                                                        # git cloneが終わるまで実行したくないのでnothingを指定。
    end

    template "/etc/profile.d/nvm.sh" do                        # nvm.sh.erb (後述)を/etc/profile.d/nvm.shにコピー
      source "nvm.sh.erb"
      mode 00644
    end

最後のブロック(template)なのですが、これはなんというか・・・
基本的には、(chef-repo/site-cookbooks/nvm/)template/default/nvm.sh.erbを
指定した場所にコピーするのですが、
単にコピーするだけではなく、
nvm.sh.erb内でRubyの変数が使われている場合、
変数に適切な値を代入しつつコピーしてくれるといったものです。

ちなみに、nvm.sh.erbの中身はこんな感じです。(特にrubyの変数は使ってないです)
  $ cat template/default/nvm.sh.erb
    #!/bin/sh
    . /usr/local/nvm/nvm.sh
    nvm use v0.10.1


Gruntをインストールするレシピを作ってみる


では最後に、Gruntをインストールするレシピを作成します。
Gruntのレシピはnvm Cookbook内に作成するとします。
  $ vi recipes/grunt.rb
    bash "grunt" do
      code <<-EOH
        . /usr/local/nvm/nvm.sh
        nvm use v0.10.1
        npm install -g grunt-cli
      EOH
      action :nothing                                                                    # nvm.shの実行終了したら走らせるためnothingを指定
      subscribes :run, "bash[nvm.sh]", :delayed                          # nvm.shの実行を監視してます。
    end

VagrantとChef Soloを連携させる

VagrantfileにChef Soloとの連携部分を追記する。

  $ vi Vagrantfile
    ・・・中略 ・・・
    config.vm.provision :chef_solo do |chef|
      chef.cookbooks_path = "chef-repo/site-cookbooks"
      chef.add_recipe "base"
      chef.add_recipe "nvm"
      chef.add_recipe "nvm::grunt"
    end

VMにレシピを適用する!

  $ vagrant halt && vagrant up

でvagrant upするときにChefのレシピも実行されますが、
以下のコマンドを実行するとChefの部分のみ実行することができます。

  $ vagrant provision

2013年7月8日月曜日

Vagrantでお手軽にVMを作っては壊し作っては壊す

Mac OS上にVirtual Machineを作成して
楽しむ方法を以前 (VitrualBoxでMacにいつでも壊せるVMをサクサク作る) 書きました。

が、Vagrantというツールを使うと、
Virtual Machineと連携してもっと簡単にVMを作成出来ます!

詳しくはこちら↓↓
http://www.vagrantup.com/
http://docs.vagrantup.com/v2/installation/index.html

Vagrantのインストール

http://downloads.vagrantup.com/
からdmgをダウンロードする。

※ Gemでインストールすると、
    古いVersionのVagrantをインストールしてしまうそうなので、要注意。

Boxのダウンロード

Boxはなんていうか・・・Vagrantで使うOSイメージみたいなもんらしいです。
ISO的やつです。

ということでOSをインストールするために、まずはBoxをダウンロードします。
今回はubuntuをダウンロードします。

 $ vagrant box add ubuntu http://files.vagrantup.com/precise64.box

ダウンロードできるBoxの一覧はこちら。
http://www.vagrantbox.es/

VMの設計書を作る

次にVagrantfileを作成します。

Vagrantfileとは何かといいますとVMの設計書みたいなものを作ります。
つまり、
* 今から作成するサーバの名前はほにゃららで、
* IPアドレスはほにゃららで
* メモリはふにゃららGB使います
的なことを記述しているファイルです。

  $ vagrant init ubuntu
(ubuntuを指定することでさっきbox addしたOSをインストールしますよ、
って指定してます)
このコマンドを実行すると、Vagrantfileができます。
これがVMの設計書となります。

初期設定する

ホスト名の設定


config.vm.hostname = "HOSTNAME"

をVagrantfileに追加します。
そうするとホスト名が設定されます。

ネットワークの設定


1. NAT的設定
  config.vm.network :forwarded_port, guest: 80, host: 8080

  とVagrantfileに書くことでホストマシンの8080へのアクセスは、
  ゲストVMの80ポートへ転送されます。

2. Bridge的設定
  config.vm.network :public_network

  とVagrantfileに書くことでローカルネットワークからゲストVMを見ることができます。

3. NAT + Host Only Adapter的設定
  config.vm.network :private_network, ip: "192.168.33.10"

  とVagrantfileに書くことで、ホストマシンからのみアクセスを許可する。

メモリサイズの設定


デフォルトだとOSが推奨する最小限のメモリになるような気がします。(たぶん)
なので、ちょっと多めに割り当てたいときは、

  config.vm.provider :virtualbox do |vb|
    vb.customize ["modifyvm", :id, "--memory", "1024"]
  end

のようにVagrantfileに記述します。
この場合、メモリを1024MBに設定してます。

VMを作る

設計書ができたので、以下のコマンドで実際にVMを作成してみます。

  $ vagrant up

しばらく待ったらVMができてます。

VMにログインする

以下のコマンドをVagrantfileを置いたディレクトリで実行すると
さっき作成したVMにsshでログインします。

  $ vagrant ssh

デフォルトではvagrantユーザーで~/.vagrant.d/insecure_private_keyを使った
鍵認証でログインします。

VMを壊す

  $ vagrant destroy
をホストマシンで実行するだけで完全にVMを消し去ります。

もう一回同じ設定で作りなおすときは、
  $ vagrant up
でOK。

単にshutdownしたいだけなら、
  $ vagrant halt
で終了。

で?

まーここまでだとあんまり良さを実感できないですよね。
単にOSのインストールでいろいろ選ばなきゃダメなところを勝手にやってくれるだけ?
って感じですね。

VagrantはChefやPuppetと連携することでもっと威力を発揮します。
次回Chef Soloとの連携を書くと思います。

2013年7月7日日曜日

VitrualBoxでMacにいつでも壊せるVMをサクサク作る

ローカルマシン上にVirtual Machine (VM)を作れるといろいろと便利ですよね。

無駄にソフトウェアをインストールして失敗してはVMを作りなおしたり、
 MacにWindowsを入れてみたりできますしね。

VirtualBoxは無料でWindowsやMac、Linux上にVMを作れる Oracleが提供するサービスです。
https://www.virtualbox.org/

VMWareも同じようなものですが、
Macで無料というのはVirtualBoxだけかと思われます。

VirtualBoxのインストール

https://www.virtualbox.org/wiki/Downloads
こちらのURLからダウンロード。

ダウンロードしたdmgをダブルクリックして、
指示通りやればインストール完了。

UbuntuのVMを作ってみる

Ubuntu Serverのisoをダウンロード


まずはここから

Ubuntu Server 13.04をダウンロードする。

VMの箱だけとりあえず作ってみる


箱という呼び方が正しいかどうかわかりませんが、
とりあえずUbuntuをインストールする前準備をします。
では、インストールしたVirtualBoxを起動して、VMを作成しまーす。

1. 新規作成



2. 名前は適当でいいですがタイプはLinuxでバージョンはUbuntu (64bit)を選ぶ



3. メモリの割り当ては後で変えれるのでデフォでOK
4. 仮想ハードドライブを作成するを選ぶ。あとはVDI、可変タイプを選択。
  サイズは20GBくらい?

ネットワークの設定


あんまりネットワーク詳しくないのですが、以下の3つの方法があるかと。

1. NAT
  NATだけだと、IPがホストマシンと同じになるので、
  SSHでログインとかするときに別のポート設定しなきゃだめだし、
  サービス増えるごとにポートの設定も増えるのでなし。

2. Bridge
  Bridgeだとホストマシンとローカルネットワーク内で同列に並べることができるので、
  ホストマシン以外からも閲覧可能にしたい場合はBridgeがいい。

3. NAT + Host Only Adapter
  VM -> ホストの通信(VMからwgetしたりとか)にはNATを使い、
  VM <- ホストの通信(VMへログインしたり)にはHost Only Adapterを使う方法。

ローカルネットワークから見える必要はないので、3でやってみる。


NAT + Host Only Adapterの設定


0. 環境 -> ネットワークタブでホストオンリーネットワークを追加する。

1. 作ったVMを選択
2. 設定ボタンを押してネットワークタブを選択
3. アダプター2を選択
    * ネットワークアダプタを有効
    * ホストオンリーアダプターを選択

4. でOK


ようやくUbuntuのインストール


VirtualBoxのウィンドウ上の左側からさきほど作ったVMを選択しますね。
そしたら、↓のような画面が表示されるので、
さっきダウンロードしたUbuntuのISOを選んでインストールを開始します。
あんまり細かいことを気にしないのであれば、
基本yes的なボタンを押し続けていればインストールは完了します。

起動してみる


一応インストールが終わったはずなので起動してみます。
◯で囲んだところをダブルクリックでVMを起動。

起動したらゲストVMにログインしてネットワークの設定をします。
  $ sudo vi /etc/network/interfaces
    auto eth1
    iface eth1 inet dhcp

設定が終わったら
  $ sudo service networking restart
でネットワークを再起動してさきほどの変更内容を有効にします。

ネットワークの再起動が終わったらホストマシンからsshでログイン可能に。

ウィンドウ無しで起動する


なんというかVMのウィンドウ? (GUI)があるとなんかうっとうしいですね。
基本ターミナルからsshでログインして使いたいので、
VMのGUIを作らずにVMを起動します。
これをHeadlessというらしい (たぶん)

以下のコマンドをホストマシンで実行したらHeadlessで起動できます。
  $ VBoxManage startvm "test" --type headless