電気羊の執務室

魔法を作る仕事をしています。

Chefのリポジトリ構成

chefの構成について

今回、DigitalOceanに仮想マシンを作り、 Angular.jsでサイトを作りたいです。 そのために、Vagrant+chefで構成管理をします。

毎度の事ですが、今回も失敗記です。

環境構築ふたたび

1年近く放っておいたので、Rubyアプリの常として、 バージョンは上がり、環境は崩れていました。

rbenvからの入れなおしになり、 net-sshがRuby2.0以降を指定するため、 ついでにRubyのバージョンも2.2.2に上げることに。

chefはchefDKに

こないだインストールした気もしますが、 chefDKをダウンロードして実行。

  • chefDKを入れた時のお約束 – .zprofileに、export PATH=/opt/chefdk/bin:$PATHを追加
  • berkshelfが見つからない – stackOverflowのフォーラムを見て解決。最終的に、berkshelfはchefDKの組み込みgemを使うことに。

knife soloはおさらば

Unable to activate knife-solo-0.5.1, because net-ssh-3.0.2 conflicts with net-ssh

chefDKの最新環境では、net-sshはv3.0.2必須。 2.9.4も、別途インストールはされている。 しかし、knife soloのどこかで、net-sshは2.7~3.0を指定されている。 3.0.2をアンインストールすると『knife-soloはnet-ssh3.0.2必須!』と怒られ。

Gemfileとかに器用な事を書いて切り抜けられる技量がないので、 この矛盾を解消できなかった。

よって、knife soloはあきらめました。

knife zeroで行きましょう

この時点で3日め。 knife zeroで環境構築。

chefリポジトリは、新しく作るの辛かったので、前回作りまくったchef-repoにシンボリックリンクを張り、vagrant-digitaloceanフォルダ-> chef-repoフォルダの構成に。

しかし、chefプロビジョンは、vagrantフォルダからchef-repoフォルダに移動しないとうまく行きません。 面倒だし、できれば1ノード1フォルダで完結するような管理がしたいです。

chefリポジトリは、githubから

ローカルのcookbookはコピーと割り切り、 github上のchef-repoフォルダを、各ノードのディレクトリに展開すると、 使い回しもでき、環境を濁らせないのでよいのでしょうか。

Packer_esx

Packerで、Windowsの仮想マシンをESX上に生成

以前の記事でも紹介しましたが、 PackerでWindowsゲストの仮想マシンを、VMWare ESXサーバ上に 直接生成するやり方を模索しています。

ここで作るのは実行中の仮想マシンで、boxファイルではありません。

いくつかの壁があるので、ひとつひとつ確認してみましょう。

1.output_directoryを指定してはいけない

ローカルでboxファイルを構築する場合には、 output_directoryを指定するのが常ですが、 ESXサーバー上でビルドする際には、output_directoryを指定すると、 vmxファイルが参照できなくなってしまいます。

そのため、output_directoryは指定しません。

2.仮想マシンのバージョンを指定する

使用中のESXサーバーは、無償バージョンです。 そのため、仮想マシンのバージョンは、すべて8を使用しています。

これをPackerでビルドする際、以下のように項目を指定します。

1
2
3
"vmx_data": {
  "virtualHW.version": "8"
}

サーバー上のファイアウォール設定

ESXサーバーが、ゲストマシンへのSSH接続を受け入れないと、 失敗してしまいます。

そこで、サーバーのファイアウォールを設定します。

詳細は、以下を参照。 VMWare公式記事

VNCの設定

Raspberry Piをchefでcookするまでのあれこれ

raspberry piで遊びたい

raspberry piが好きです。 計測器を付けて遊ぶほか、AirPlayのサーバーにするなど、 いろいろと遊びたい事があります。

遊ぶにあたって、chefで設定できるようにしておくと、 安心して壊すことができますね。

それでは、raspberry piにchefを導入するまでの ワークフローを紹介しましょう。

まずはこのページを参照

今回参考にしたページを紹介します。 ChefでRaspberry Piをセットアップする

やりたい事は違えど、大まかな流れは、上記のページの通りです。

  1. Vagrantで仮想環境を用意
  2. chefのセットアップ
  3. Cookbookの作成とテスト(ServerSpecを使用)
  4. 本物のRaspberryPiを環境構築

ワークフロー通りにやっていく中で、 いろいろと調べ事をしたので、その足あとを追ってゆきましょう。

1.Vagrantで仮想環境を用意

まず、Vagrantの環境構築について。
この記事執筆時点ではすでに終わっていますので、
まだの方は、仮想環境構築ツール「Vagrant」で開発環境を仮想マシン上に自動作成するなどを参考にしてください。

余談

Vagrantについて思うところ。
仮想環境は長いことVMWareでやってきたので、
仮想マシンを本番環境として使う場合は、
VMWareが慣れてて楽だなぁと思っています。

しかし、実機の本番環境の練習台としての仮想マシンは、
VirtualBoxでやるのがよさそうです。

メリットは、いくつもあります。

  • VirtualBoxなら無償
  • Saharaプラグインが使える
  • 仮想マシンからのBox構築が可能

最後はともかく、無償でしかもやり直しができるのは、
練習台としてはメリットが大きいと思います。

閑話休題

今回は、仮想環境の用意には、参照記事のおすすめに従い、 これを使いました。

1
2
3
$ git clone https://github.com/nickhutchinson/raspberry-devbox raspberry_pi
$ cd rasbperry_pi
$ vagrant up

2.chefのセットアップ

お約束通りにやりました。

1
2
3
$ vagrant ssh-config --host vm-raspberry_pi >> ~/.ssh/config
$ knife solo init chef-repo
$ knife solo prepare vm-raspberry_pi

ローカルマシン側のsshの設定を、ここでvagrantがやってくれるのって、 非常にありがたい事ですね。
実機の環境構築では、1行目にあたる部分を自分でごにょごにょします。

3.Cookbookの作成とテスト(ServerSpecを使用)

ここの基本の考えかたは、参照記事 の3. クックブックの作成とテストを参照して下さい。

引用:

書いたクックブックを実行する前にVagrantをサンドボックスモードにしておく。
こうすると、失敗したときに実行した部分だけやり直すこと(ロールバック)ができる。
サンドボックスモードにするためにはsaharaというVagrantのプラグインが必要なのでインストールしておく。

サンドボックスモードをオンにしてクックブックを実行したあと、本当に期待した通りに環境構築できたかどうかをServerspecを使ってテストする。 Serverspecにはいくつかテストを実行する方法があるようだけど、今回はSSHでログインしてテストを実行する形式を採った。 テストを通らなかった場合は、saharaを使ってロールバックしてやり直す。
テストが通った場合は、saharaを使って変更を確定させる(コミット)。

これをサイクルさせながら、どんどんクックブックを追加していく。以上をコマンドで表すとこんな感じ。

1
2
3
4
5
6
7
8
$ knife cookbook create ruby -o site-cookbooks
$ vi site-cookbooks/ruby/recipes/default.rb
$ vi nodes/vm-raspberry_pi.json
$ vi spec/vm-raspberry_pi/ruby_spec.rb
$ vagrant sandbox on
$ knife solo cook vm-raspberry_pi
$ rspec
$ vagrant sandbox commit

(引用終わり)

ここで書いたレシピの内容や困り事については、
別の記事で紹介します。

とにかく上記の流れが参考になりまくったので、 ここに記すことにしました。

4. 本物のRaspberryPiを環境構築

引用:

仮想環境での環境構築が完了したら、いよいよ本物のRaspberry Piにクックブックを適用する。
そのためにはnodes以下に本物用の設定を追加するだけでいい。

1
2
$ vi nodes/raspberry_pi.json
$ knife solo cook raspberry_pi

(引用終わり)

基本の流れは、上記の通りです。 本番環境を作る上でも、sshの設定など、多少の試行錯誤があったので、 別の記事で書きます。

仮想マシン構築自動化ツールのまとめ

はじめに

3月から、仮想マシン構築を自動化しようとして、 色々もがいてみました。 早いもので、もう3ヶ月も経つんですね。

当初、いろいろ疑問が多かった中で、 『情報が少ないので、とにかく触って掴もう』 というアプローチでやってきました。

ある程度わかってきたので、まとめていこうと思います。

DevOpsツールについて

仮想マシン構築の自動化など、コード化されたインフラを、 DevOpsと呼ぶようですね。

これをやるのに、よくおすすめされる構成が、 Vagrant+Chef+BerkshelfでVirtualBoxノードを作ろう! ですね。

参考資料: あとでまとめる

Packer,Vagrant,Chef,Berkshelfの違いは?

記事を読みながら、何がなんだかよく分からなかったのが、 各ツールの違いです。

ここでは、各ツールの違いをまとめてみます。 うまく伝わるかはわかりませんが・・・

Packer:無から仮想マシンファイルを作る

Packerは、OSイメージや既存の仮想マシンの『ファイル』から、 boxや仮想マシンノードの『ファイル』を作るアプリ。

  • 設定ファイル:
    • 入力ファイル(OSのISOファイル、仮想マシンのファイル)
    • 設定用jsonファイル(OS,バージョンごとに用意)
  • 実行対象:ローカルマシン、クラウドサービス
  • 出力:ファイル(vagrant用boxファイル、仮想マシンのファイル)

Vagrant:仮想マシンを実行・廃棄する

Vagrantは、仮想マシンのひな形(boxと呼ばれる)から、 実際に動く仮想マシン(ノードと呼ばれる)を作るアプリ。 実行した際に、マシンが動作を開始するのが特徴。

  • 設定ファイル:
    • boxファイル
    • Vagrantfile(各ノードの設定内容を記述)
  • 実行対象:ローカルマシン、クラウドサービス
  • 出力:
    • 実行中の仮想マシン
    • boxファイル(packageコマンドを使用したとき)

Chef:実行中のマシンに設定を行う

Chefは、実行中の仮想マシンや物理マシンに対し、 インストールや環境設定作業を自動化するアプリ。

Cookbookと呼ばれるパッケージを指定すると、 OSの差異をChefが吸収し、OSに適したコマンドで プロビジョン(環境設定や、アプリのインストールなど)してくれる。

設定対象のマシンは、仮想マシンでも物理マシンでもOKだし、 ローカルでもリモートでもOK。

  • 設定ファイル: *Chefリポジトリ(kitchenとも呼ばれるファイルセット)
    kitchen(ここでは一部のみ)
      |- cookbooks(各設定内容をアプリごと、ジャンルごとにまとめておく)
      |- nodes(設定対象のノードと、そのノードにどんな設定を行うかを記述) 
  • 実行対象:実行中のマシン
  • 出力:実行中のマシンに設定が完了した状態

chef-soloとknife-solo

ローカルの場合はchef solo、リモートの場合はknife soloの コマンドで設定を行う。

Berkshelf:ChefのCookbook管理を便利にする

Chefを使う際、Berkshelfを併用することで、 Cookbookの管理が便利になる(RubyのGemのようなもの)

  • 設定ファイル:Berksfile
  • 実行対象:Chefリポジトリ(=kitchen)
  • 出力:整理済のChefリポジトリ

まとめ

  • Packer
    • 仮想マシンの実行ファイルを作る
    • マシンの起動はインストール時のみ(電源OFFで終わる)
    • マシンを継続的に実行する事はできない
  • Vagrant
    • 仮想マシンの起動・終了などを制御する
    • 必ず仮想マシンのひな形(box)が必要
    • OSインストールから実行することはできない
  • Chef
    • マシンの設定を自動で行う
    • 仮想マシンに限らず設定可能
    • マシンが起動している事が条件
    • マシンの起動自体を行うことはできない

流れとしては、こんな感じです。

  1. Packerで仮想マシンを生成
  2. Vagrantで仮想マシンを実行
  3. Chefでツールのインストール、設定など

VMWare ESXiホストへ、Windows7マシンをPackerで作る

今回は、VMWare ESXiのホストマシンに、 Packerを使用してWindows7のゲストマシンを導入する方法を紹介します。

今回の構成

構成図

Packerを使う理由

ゲストマシンの立ち上げは、 ESXiから直接やるよりも、 ツール経由でやるほうが後々便利です。

Packerは、『Vagrantで扱えるVMのひな形(boxファイル)を作るツール』です。 最終的には、Vagrantなどでサーバーインスタンスを次々と 作る予定ですが、そのためには最初のひな形をどうにか作る必要があります。

Linuxなどは、boxファイルが多数公開されていて、 ダウンロードして使う事ができますが、Windowsはライセンスの関係で、 公開されているものがありません。自分で作るしかないわけです。

VirtualBox使いには、vagrant packageというコマンドで、 動いているインスタンスからひな形を作ってしまう手がありますが、 VMWare使いは、手で作らなくてはなりません。

ESXiホストに、ユーザーを追加する

作業用のmacで動くPackerで、ネットワーク上のVMWare ESXiにリモート接続します。 デフォルトでは、rootでSSHログインできません。 ここは真っ当に、別ユーザーを追加することにします。

以下の2点を確認します。 * 作業用WindowsのvSphereクライアントからESXiホストを参照し、『ローカルユーザーおよびグループ』タブから、ユーザーを追加します。 * 『権限』タブから、新規ユーザーに権限を付与します。ここでは、管理者権限を付与しました。

ESXiホストのSSHを有効化する

まず、VMWare ESXホストでSSH通信を有効化します。 ホストにログインし、コンソールから、以下のふたつの項目を選びます。

Troubleshooting Options -> - Enable ESXi Shell - Enabe SSH

ホストにSSHログインし、GuestIPHackを有効化する

SSHが有効になったら、作業用macから以下のコマンドでESXホストにログインします。 ssh (新規ユーザー)@ESXホストのアドレス

パスワードを入力し、ログインできたら、以下のコマンドを入力します。

esxcli system settings advanced set -o /Net/GuestIPHack -i 1

エラーなく完了したら、exitコマンドでSSHを抜けます。

Packer用のビルドファイルを作成

Packerを実行するためのファイルを作成します。 ここでは、先人の記述してくれたjsonファイルを、 ありがたく使わせていただく事にします。

git clone https://github.com/misheska/basebox-packer template/windows7ディレクトリから、 ここではwin7x86-pro.jsonを選択します。 インストーラのパスなどを実際のものに置き換えた後、以下のコマンドで内容を確認します。

packer validate vmware_win7.json

エラーが出なければ、以下のコマンドでビルドを行います。

packer build vmware_win7.json

1回失敗するごとに、OSインストール分の時間がかかるので、 小さな修正が一番つらい。 がんばりましょう。

Active_scaffoldが調子いい

ActiveScaffoldとは

Railsアプリでは、CRUD操作(登録・修正・表示・削除)を 一気に作ってくれる、Scaffoldという機能があります。 が、あまり実用的ではない、という定評で、 便利な機能にもかかわらず、それほど使われていません。

そこでActiveScaffoldです。 ActiveScaffoldでは、ごく少ない操作で、 かなりそれっぽい画面を自動生成してしまいます。

使い方

  1. gemで導入
  2. javascriptテンプレートにrequireを書く
  3. stylesheetテンプレートにrequireを書く
  4. 生成したいエンティティを記述する
  5. routesファイルにひとこと書く

1.gemで導入

Gemfileに、以下の通り記述します。 gem install active_scaffold

関係ないですが、僕は最近、もっぱらskip_bundleオプション付きでプロジェクトを作り、
後からプロジェクト内のvendor/bundle配下にgemをインストールするのが、
全体の環境を壊さなくていいなぁとお気に入りです。

2. javascriptテンプレートにrequireを書く

ファイルイメージ

app/assets/javascripts/application.js を開きます。 ファイルの末尾に、requireを記述したブロックがあるので、 以下の通り追記します。

//= require active_scaffold

コメントアウトした感じの見た目で構いません。 追加したイメージ

3. stylesheetテンプレートにrequireを書く

stylesheetテンプレートはこれ

app/assets/stylesheets/application.css を開きます。 ファイルの末尾に、requireを記述したブロックがあるので、 以下の通り追記します。

*= require active_scaffold

これも、コメントアウトした感じの見た目で構いません。

追加したイメージ

4.生成したいエンティティを記述する

エンティティを、ActiveScaffoldを使って、 モデルとコントローラとビューを一気に生成します。 例えば、以下のように記述します。

rails g active_scaffold work_kind name:string

5.routesファイルにひとこと書く

最後に、config/routesファイルに、以下のように書きます。 resources :work_kinds do as_routes end

これで、Railsアプリ上では、このように表示されるはずです。

画面表示

間違えるとどうなるか?

ちなみに、requireの記述を間違えると、
それぞれ特有の動作をします。

stylesheetの記述をミスると、白い背景に文字だけの、 シンプルな画面になります。

stylesheetの記述をミスった感じ

javascriptの記述をミスると、リンクをクリックしても動作しなくなります。 ajaxの非同期処理が帰ってこれなくなるのでしょうか。 『新しいウィンドウで開く』などすると、別窓では表示されるようです。

これは?と思った時は、記述を見なおしてくださいね。当たり前か。

Rvmからrbenvへ移行

rvmからrbenvへ

最近、メインのmac上でRubyの調子が悪いです。 herokuを使えばRails new できず、 やっとRailsの環境ができたと思ったら rake generateできず。

しまいにはOctopressのGenerateもできなくなってしまったので、 もう環境をなんとかするしかない感じがしてきました。

というわけで、rubyのパッケージをrvmで管理するのをやめ、 rbenvに移行しました。

TimeMachineのバックアップが遅い時は、Spotlightを確認せよ

今回は、タイトルで内容を言い尽くした感があります。

今回起こったこと

約2週間前から、TimeMachineのバックアップが成功しなくなりました。

夜寝ようとすると、『バックアップ230MB/6GB』とか表示されてるわけです。 で、InsomniaTを仕掛けてスリープしないようにし、翌朝バックアップが終わったか確認すると・・・  『バックアップ2.4GB/6GB』 とか出ているわけです。

丸一日かかる計算です。 もう仕事に持っていくし、終わんねーじゃん。 こんな事が数日続いたでしょうか・・・

Spotlightの異変

仕事中に、ふと気がついた事がありました。 Spotlightで検索できない。

ぐぐる。 OSX Daily appleのフォーラム

今回は、下のコマンドで解決できました。

sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist  

TimeMachineも解決したよ

Spotlightが解決したら、TimeMachineのバックアップもうまくいきました。 たまった差分バックアップが9時間で終わった感じですが。

めでたし。

Herokuを使ってみよう

ruby on railsのアプリを作るのに、herokuを使ってみます。 railsは前にも練習しましたが、ほとんど忘れてしまったので、 改めてやります。

Lazy_high_chartsを使ってみた

Lazy high chartsを使ってみた

railsでグラフを表示させたくて、 Lazy high chartsを使ってみました。 やった事を書いておきます。

なんでLazy high chartsなの?

Lazy high chartsを選んだ理由は、以下の通りです。

  1. 『Web グラフ』で検索したら、high chartsの評判がよかった
    webアプリ(perlやjavascript)でグラフ表示なら、Highcharts で決まりかも
  2. 『ruby high charts』で検索したら、Lazy high chartsの記事を見つけた
    Rails で Lazy high charts を使ってチャートを実装してみた

というわけで、Lazy high chartsを使ってみます。

まずはインストール

上記のサイトを参考に、Lazy high chartsのインストールを行います。

まず、Gemfile に gem 'lazy_high_charts'

を追加しました。 そして、 bundle を実行します。インストールが始まりました。
ここまでは問題ありません。

そして、

bundle exec rails g lazy_high_charts:install

を実行すると、highchart.js がダウンロードされて、assets/javascripts に配置される・・・
はずでしたが、何やらエラーが表示されました。

インストールエラー

エラーメッセージは、次のようなものでした。

% /projects/rails/lazy_chart% bundle exec rails g lazy_high_charts:install [WARNING] Could not load generator "generators/lazy_high_charts/install/install_generator". Error: uninitialized constant LazyHighCharts::Rails::Generators. /.rvm/gems/ruby-1.9.3-p0/gems/lazy_high_charts-1.4.0/lib/generators/lazy_high_charts/install/install_generator.rb:4:in `<module:LazyHighCharts>' /.rvm/gems/ruby-1.9.3-p0/gems/lazy_high_charts-1.4.0/lib/generators/lazy_high_charts/install/install_generator.rb:3:in `<top (required)>' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/generators.rb:300:in `block (2 levels) in lookup' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/generators.rb:296:in `each' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/generators.rb:296:in `block in lookup' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/generators.rb:295:in `each' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/generators.rb:295:in `lookup' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/generators.rb:152:in `find_by_namespace' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/generators.rb:169:in `invoke' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/commands/generate.rb:12:in `<top (required)>' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/commands.rb:29:in `<top (required)>' script/rails:6:in `require' script/rails:6:in `<main>' Could not find generator lazy_high_charts:install.

このエラーについて調べたところ、次の記事が見つかりました。

Problem with rails g lazy_high_charts:install
どうやら、Railsのバージョンが3.1以上の場合は、
app/assets/javascripts/application.jsに次の行を追加しないといけないようです。

//= require highcharts
//= require exporting

これで、エラーは解決したでしょうか。

% /projects/rails/lazy_chart% bundle exec rails g lazy_high_charts:install [WARNING] Could not load generator "generators/lazy_high_charts/install/install_generator". Error: uninitialized constant LazyHighCharts::Rails::Generators. /.rvm/gems/ruby-1.9.3-p0/gems/lazy_high_charts-1.4.0/lib/generators/lazy_high_charts/install/install_generator.rb:4:in `<module:LazyHighCharts>' /.rvm/gems/ruby-1.9.3-p0/gems/lazy_high_charts-1.4.0/lib/generators/lazy_high_charts/install/install_generator.rb:3:in `<top (required)>' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/generators.rb:300:in `block (2 levels) in lookup' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/generators.rb:296:in `each' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/generators.rb:296:in `block in lookup' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/generators.rb:295:in `each' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/generators.rb:295:in `lookup' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/generators.rb:152:in `find_by_namespace' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/generators.rb:169:in `invoke' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/commands/generate.rb:12:in `<top (required)>' /.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.13/lib/rails/commands.rb:29:in `<top (required)>' script/rails:6:in `require' script/rails:6:in `<main>' Could not find generator lazy_high_charts:install.

じゃん。 やっぱり出ますね。

しかし、くだんの記事によると、どうやらこれでも問題なく動作するらしいです。

では、動かしてみますか

それでは、警告を気にせず、動作させてみます。

rails s

棒グラフ

グラフが出ました。

あとは、データの取得がうまくできれば、楽しく暮らせそうです。