電気羊の執務室

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

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

棒グラフ

グラフが出ました。

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

SketchupのWebDialogで、rubyスクリプトが呼べない時

前回の続きです。
SketchUpには、WebDialogというコンポーネントがあります。
これを使うとrubyスクリプトから、フォームを作成でき,
ユーザーと対話的にスクリプトを実行できるわけです。

すごくハマったところ

今回、WebDialog経由でrubyスクリプトを実行する際に、
すごくハマったポイントをお教えします。

動作環境:
mac OS X 10.8.2
SketchUp 8.0.4810

それは・・・入力部品の種類です。
ボタンなどを押した際にjavascriptのコードが実行されるよう、
動作を設定しているのですが、
なんと、入力部品の違いによって、動作の一部が実行されません。

buttonとinput type=”button”

結論から言うと、リンクと、<input type=”button”>で生成したボタンは、
問題なく動作します。

しかし、<button>エレメントで生成したボタンは、
window.location=でリダイレクトを行う事ができません。

これができないと、javascriptからrubyコードが呼べないのです。
rubyスクリプトは、javascriptからはurlとして指定する必要があるからです。

サンプルコード

サンプルコードの使い方

まずはSketchUp上で、コードを実行します。

実行すると、こんな画面が表示されます。
ボタンが2つ、リンクが1つある画面

1番上のボタンを押すと、ダイアログボックスが1回表示されます。

javascriptのメッセージ

2番めのボタンを押すと、ダイアログボックスが2回表示されます。

javascriptのメッセージ
rubyのメッセージ

リンクをクリックしても、同様に2回表示されます。

3つとも同じ関数を実行しているのに、buttonエレメントだけは、挙動が違います。
window.locationを指定することができず、rubyのメソッドを呼べません。

ボタンの動作がうまくいかない方は、
参考にしてください。

次回は、ruby側からjavascriptの関数を呼び出す処理について書こうと思います。

VimSketchUpのすすめ

余談ですが、これを読んでいらっしゃる貴方は、どうやってサンプルコードを実行していますか?
Vim上でショートカットを入力するだけで、サンプルコードが実行できたら楽ですよね。
ちょっと心が動いた方には、VimSketchUpをおすすめします。

参考資料

Trimble SketchUp
http://www.sketchup.com/intl/en/developer/docs/ourdoc/webdialog#add_action_callback

Engineering The World
http://engineeringtheworld.wordpress.com/2010/02/16/creating-web-dialogs-in-sketchup-and-making-calls-from-and-to-sketchup/

SketchUpのWebDialogの使い方

Trimble SketchUpには、rubyで自動化できる機能があります。 今日は、rubyで画面を作る、WebDialogというコンポーネントについて お話ししたいと思います。

SketchUpには、WebDialogというコンポーネントがあります。
これを使うとrubyスクリプトから、フォームを作成でき,
ユーザーと対話的にスクリプトを実行できるわけです。

WebDialogの特長

  • htmlとCSSで、フォームを作成できる
  • rubyスクリプトから、htmlの要素にアクセスできる
  • html内のjavascript関数から、rubyスクリプトを実行できる
  • rubyスクリプトから、html内のjavascript関数を実行できる

WebDialogは、HTML+CSS+javascript

WebDialogコンポーネントは、フォームのレイアウトをHTMLで指定します。
また、入力部品の動作はjavascriptで指定します。

基本的な使い方は、公式ヘルプに載っています。
http://www.sketchup.com/intl/en/developer/docs/ourdoc/webdialog#add_action_callback

rubyスクリプトの実行方法

あらかじめ、ダイアログに、コールバックメソッドを指定しておく必要があります。 指定されたコールバックメソッドには、仮想urlが割り当てられており、 “skp:” + コールバックメソッド名のアドレスに遷移しようとすると、 コールバックメソッドが実行されます。

仮想urlへ遷移するには、以下のいずれかの方法で指定します。

  • リンクのurlとして指定
  • javascript関数内に、window.location=”skp:” + 関数名を指定し、ボタンに割り当て

macの場合はrubyコードが非同期実行

Martin Rinehartによると、 windows ではjavascriptから呼び出されたrubyスクリプトは同期実行され、 戻り値をjavasxriptで受け取る事ができるそうです。 しかし、macではrubyスクリプトは必ず非同期実行のため、 rubyの戻り値をjavascriptで利用することはできないようです。

注意してください。

サンプルコード

ほぼ最小構成のWebDialogのサンプルです。 ここでは、ボタンのクリックイベントにjavascriptのスクリプトを設定し、 リンクのurlにrubyのコールバックイベントの仮想urlを指定しています。

サンプルコードの使い方

サンプルコードを実行すると、このような画面が表示されます。

WebDialogのサンプル

ボタンを押すと、javascriptで作成されたメッセージが表示されます。

ボタンを押すと、javascriptのアラートが表示される

リンクをクリックすると、rubyで作成されたメッセージが表示されます。 コード内では、リンクのurlとして、”skp:”に続いてrubyのコールバックメソッド名が 指定されているのがわかります。

リンクをクリックすると、rubyのメッセージが表示される

参考資料

SketchUp Ruby Interface to JavaScript
http://www.martinrinehart.com/models/rubies/ruby2javascript_javascript2ruby.html

Bitnamiの仮想マシンを使うためのステップ

WordPressを使ったWebサイト作りをしようとしています。 ローカルの仮想サーバーでサイトのソースをGitに上げ、 公開用のサーバーでGitからPullすることで、デプロイする構成です。

そこで、ローカルの仮想サーバーには、 WordPressとMySQLとPHPのスタックである、 bitnamiを使ってみます。

bitnami仮想マシンのダウンロード

bitnamiを使うためには、2つの方法があります。

  1. 既存の仮想マシンに、bitnamiをインストールする
  2. bitnamiインストール済の仮想マシンを、新規にダウンロードする

今回は、2.を解説します。 公式サイトから、bitnamiがインストールされた仮想マシンをダウンロードします。

sshの導入

コマンドラインから操作するため、仮想マシンでsshを有効にします。 公開鍵の受け渡しが、最も苦労した部分です。

公開鍵の渡し方

仮想サーバーの公開鍵を、開発用マシンに渡すための方法は、 次のような選択肢があります。

  1. 仮想マシンがSmabaサーバーとなり、ホストOSのがクライアントとなってファイルを受け渡す
  2. 逆に、ホストOSの共有フォルダに、仮想マシンからアクセスしてファイルを受け渡す
  3. GitHubなど、外部ストレージを経由してファイルを受け渡す

ここでは、2.を解説します。

VMware-Toolsの導入

ホストOSの共有フォルダにゲストOSからアクセスするには、
VMware-Toolsをインストールします。

別の記事にまとめていますので、参照してください。 vmware-tools-install

ssh鍵の生成

ホストOSで、以下のコマンドを入力します。

sudo ssh-keygen

画面に従ってパスワードを入力すると、公開鍵と秘密鍵が生成されます。 id_rsa.pubファイルが公開鍵、id_rsaファイルが秘密鍵です。

公開鍵を、共有フォルダに置く

これから、いまホストOSで作った公開鍵をサーバーに渡します。

まず、id_rsa.pubファイルを、ホストOSの共有フォルダにコピーします。 オイラの環境では、Macの~/shareフォルダです。

マウスでポイっと入れればOKです。

ゲストubuntuに、ホストOSの公開鍵をインストール

共有フォルダに入れた公開鍵を、ゲストOSから見てみます。

$ ls /mnt/hgfs/share
> id_rsa.pub

ホストOSの公開鍵が見えています。 これを、ゲストOSにインストールします。

でも、いったいどこにインストールするのでしょうか?

サーバーには『この鍵をくれたマシンのアクセスには応じるよ』というファイルがあります。
authorized-keysというファイルです。 今回受け取った公開鍵を、authorized_keysファイルに追記します。

このファイルには、複数の鍵を書き込むことができます。 上書きすると、今までアクセスできたマシンがアクセスできなくなる、 という現象が起こりますよ。

cat /mnt/hgfs/share/id_rsa.pub >> /home/bitnami/.ssh/authorized_keys

>>に注目。

これで、ゲストOSに、ホストOSの公開鍵がコピーされました。

sshの設定

ゲストOSで、以下のコマンドを実行します。

$ sudo vi /etc/ssh/sshd_config

以下の行を探して、下のように変更します。

ChallengeResponseAuthentication no PasswordAuthentication no UsePAM no

sshデーモン、いでよ!

ゲストOSがアクセスを待ち構えるために、 sshデーモンを召喚します。 このデーモンが、サーバーの門番を務めてくれるわけです。

召喚の呪文は、これです。

$ sudo start ssh

これで、ゲストOS上でsshが有効になりました。

ホストOSからアクセスしてみる

ホストOS上で、sshコマンドを入力します。

ssh 192.168.100.xxx(ゲストOSのIPアドレス)-l bitnami

ゲストOSのIPアドレスは、ゲストOSでifconfigコマンドを使用すると、
表示されます。
・・・大丈夫ですよね??

あと、-l bitnamiの部分がなんなのかというと、 bitnamiユーザーでログインします、という意味です。 サーバーにはbitnamiユーザーしかいないため、 他のユーザーではログインできません。

別のユーザーを作っている場合は、 そのユーザー名を指定してください。

これを指定しない場合は、ホストOSのユーザー名でログインします。

$ ssh 192.168.100.101 -l bitnami         
> The authenticity of host '192.168.100.101 (192.168.100.101)' can't be established.
> RSA key fingerprint is 86:74:fe:6b:8b:b1:c2:64:3f:d0:80:bc:92:f3:c0:75.
> Are you sure you want to continue connecting (yes/no)? yes

何か聞かれた場合は、yesと答えて下さい。

> Warning: Permanently added '192.168.100.101' (RSA) to the list of known hosts.
> Last login: Tue Jul  3 13:10:37 2012

これで、sshログインできました。
めでたし。

ゲストubuntuから、ホスト上の共有フォルダにアクセスする

ゲストOSから、ホストOSの共有フォルダにアクセスします。

VMware 上 の Ubuntu で共有フォルダ
http://tekitobibouroku.blog42.fc2.com/blog-entry-305.html

この記事を参考にやってみたところ、だいたいこの通りにできました。感謝! 今回は、上の記事とはバージョンなど細かいところが違います。

環境

  • ホストOS: Mac OSX 10.7.4 (Lion)
  • ゲストOS: ubuntu 12.04
  • VMware: Fusion 4.1.3(730298)
  • VMware-Tools: インストール済

hgfsが見つからない

$vmware-hgfsclient
> share

hgfsclientを実行すると、共有フォルダが見えていることがわかります。

$ sudo mount -t vmhgfs .host:/ /mnt/hgfs
> Error: cannot mount filesystem: No such device

手動でマウントできません。 記事と同じです。

lsmod | grep vm

としても、hgfsの文字は

sudo gedit /var/log/syslog

参考資料

VMware 上 の Ubuntu で共有フォルダ
http://tekitobibouroku.blog42.fc2.com/blog-entry-305.html

VMWare Plyaer 3.0 ホストとの共有
http://d.hatena.ne.jp/rock_n_santa/20100430/1272584798