Vagrantを触ってみた

きっかけ

Web開発にまつわる開発環境を「モダンないい感じ」にしたい!!!

「モダンないい感じ」にはいろいろ含まれますが、階層的に下の方から。

devops界隈も盛り上がっていることですし、お近づきになりたい!

1.前提情報

2.インストール

Oracle VM VirtualBox からインストール

  • Vagrant
> gem install vagrant
> vagrant -v
Vagrant version 1.0.7

3.VM(CentOS 6.4)の作成、起動

利用可能なboxは A list of base boxes for Vagrant - Vagrantbox.es にある。

とりあえず

を利用する。

3.1.boxを追加
> vagrant box add centos http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20130309.box
[vagrant] Downloading with Vagrant::Downloaders::HTTP...
[vagrant] Downloading box: http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20130309.box
[vagrant] Extracting box...1597339 / 491722240)[vagrant]
[vagrant] Verifying box...
[vagrant] Cleaning up downloaded box...
3.2.VMを作成
> vagrant init centos
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

起動したディレクトリに「Vagrantfile」という設定ファイルができます。
とりあえずはそのままで。

3.3.起動
> vagrant up
[default] Importing base box 'centos'...
[default] Matching MAC address for NAT networking...
[default] Clearing any previously set forwarded ports...
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] Creating shared folders metadata...
[default] Clearing any previously set network interfaces...
[default] Booting VM...
[default] Waiting for VM to boot. This can take a few minutes.
[default] VM booted and ready for use!
[default] The guest additions on this VM do not match the install version of
VirtualBox! This may cause things such as forwarded ports, shared
folders, and more to not work properly. If any of those things fail on
this machine, please update the guest additions and repackage the
box.

Guest Additions Version: 4.2.8
VirtualBox Version: 4.2.10
[default] Mounting shared folders...
[default] -- v-root: /vagrant

バージョンがどうのこうの言っているが、とりあえず気にしない・・・。

4.接続

SSH接続しようとすると、Windowsではムリ!!とごねられる。

> vagrant ssh
`vagrant ssh` isn't available on the Windows platform. You are still able
to SSH into the virtual machine if you get a Windows SSH client (such as
PuTTY). The authentication information is shown below:
4.1.あきらめません

たしか、GitHub for Windows をインストールした際に主要なUNIXコマンドが一緒にインストールされたはず・・・。

>where ssh
C:\Users\zzzzz\AppData\Local\GitHub\PortableGit_xxxxxxx\bin\ssh.exe

>ssh
usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]
           [-D [bind_address:]port] [-e escape_char] [-F configfile]
           [-i identity_file] [-L [bind_address:]port:host:hostport]
           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
           [-R [bind_address:]port:host:hostport] [-S ctl_path]
           [-w local_tun[:remote_tun]] [user@]hostname [command]

あるじゃない。パスも通っているのになぜだ。

4.2.デバッグモードで調査
> set VAGLANT_LOG=debug

とすることで、デバッグモードになるとのことなので、やってみる。

ERROR vagrant: C:/Ruby193/lib/ruby/gems/1.9.1/gems/vagrant-1.0.7/lib/vagrant/ssh.rb:59:in `exec'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/vagrant-1.0.7/lib/vagrant/command/ssh.rb:86:in `ssh_connect'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/vagrant-1.0.7/lib/vagrant/command/ssh.rb:53:in `block in execute'

ほほぅ。「ssh.rb」。。。おまえか。

4.3.勝利

ソースを確認してみると、

if Util::Platform.windows?
  raise Errors::SSHUnavailableWindows, :host => ssh_info[:host],
                                       :port => ssh_info[:port],
                                       :username => ssh_info[:username],
                                       :key_path => ssh_info[:private_key_path]
end

raise Errors::SSHUnavailable if !Kernel.system("which ssh > /dev/null 2>&1")
  • windowsだと、有無を言わさずエラー
  • whichコマンドでsshが見つからくてもエラー

となるようですね。これをコメントアウトしちまえば・・・乱暴だけど・・・。

C:\Users\nishi\VirtualBox VMs\centos>vagrant ssh
Last login: Tue Apr  2 07:52:13 2013 from 10.0.2.2
Welcome to your Vagrant-built virtual machine.
[vagrant@localhost ~]$

イケたでござる!!!

5.その他雑多なこと

5.1.停止、再起動
  • 停止
    • vagrant halt
  • 再起動
    • vagrant reload
5.2.rootユーザーのパス

デフォルトは「vagrant」

5.3.ホストとの共有ディレクトリ

「Vagrantfile」のある場所が、/vagrantにマウントされる

v-root on /vagrant type vboxsf (uid=501,gid=501,rw)
5.4.ブリッジ接続

デフォルトではホストオンリーになっています、社内NW上に公開する場合が多いので。
Vagrantファイルの以下の設定をコメントアウトすればOK。

config.vm.network :bridged

!! 注意 !!
ただし、ブリッジ接続にすると、再起動時に

ERROR vagrant: The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

/sbin/ifup eth1 2> /dev/null

のエラーでこけます。いろいろ調べましたが、根本的な解決策が見つかっていません。

/etc/sysconfig/network-scripts/ifcfg-eth1

ONBOOT=yes

を「no」にしてやることで回避できます。

6.まとめ

  • vagrantすげー
  • chefと組み合わせるともっとおいしいらしい

7.最後に、、、ありがとうございます!

jqueryを使い、ajaxでscriptタグを含む部分HTMLを取得すると、IEのみでエラーとなる

手元の再現環境

前提

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>test</title>
  </head>
  <body>
    <div id="contents"></div>
  </body>
</html>

というHTMLがあり、#contentsの中身は以下のスクリプトによって非同期に取得する。

$(document).ready(function() {
    $.ajax({
        url: "/get_contents",
        type: "GET",
        success: function(data) {
            $("#contents").html(data);
        }
    });
});

エラーなる条件

ajaxのレスポンス(/get_contetsのレスポンス)に、

  • scriptタグが含まれており、
  • jsコードがコメントされている

場合にエラーとなる。

<div>
Lorem ipsum dolor sit amet...
<div>
<script type="text/javascript">
<!--
some_function();
//-->
</script>

のようなレスポンスである。

ちなみにエラー詳細を見ても、行番号やエラー内容など、意味不明。

解決方法

コメントを取る。

<div>
Lorem ipsum dolor sit amet...
<div>
<script type="text/javascript">
some_function();
</script>

【ニコニコカレンダー for Redmine 2.X】 本家のPlugins Directoryに登録してみた

【ニコニコカレンダー for Redmine 2.X】 公開!

公開しました。

piccagliani/redmine_nikoniko_calendar2 · GitHub

Redmineバージョン1系のプラグインを作られた方は、プラグイン自体の設定だったり、データの保持期間の設定だったり、いろいろ考えられて作ってらっしゃいますが、そこらへんは今後に期待、ということで。。。。

【ニコニコカレンダー for Redmine 2.X】 5日目

うわぁ、本業が忙しい。

さて、しばらく離れていた間に、なんと、このブログを呟いてくださっている方がいらっしゃいました!!

大変有り難いことです。

f:id:piccagliani:20130312194533p:plain

亀のようにのろいペースですが、

  • 月の切り替えできるようにしないと!
  • メンバーのロールによって絞り込めた方が便利?

に対応しました。

自社内のredmineにはちょっと前から組み込んで使ってますが、うん、いったん公開しちまおうか。

しかし、公開にあたっては

  • README整備しなきゃ・・・
  • 国際化が・・・

とかいろいろあるなぁ、と思いまして。。。

とりあえずいろいろ不揃いだけれども、えいや、で行く図太さは必要でしょうか。

はじめてRailsアプリをHerokuにデプロイしたときに大きくつまった2点

そんな暇あったら、ニコニコカレンダーを進めろよ、と思うのですが、
せっかくなので、Railsの勉強もしたい!!

Windows環境で、Railsアプリを作って、Herokuにデプロイするところまで、

Learn Web Development with the Ruby on Rails Tutorial

を教科書にして行ってみました。

内容はチュートリアルを参照、ということし、ここでは、
大きくふん詰まった2点を書き留めておきます。

誰かのお役に立ちますように・・・。


1.jsonがインストールできぬ

これは調べるとすぐに出てくるDevKitないよエラー。

ERROR:  Error installing rails:
        The 'json' native gem requires installed build tools.

Please update your PATH to include build tools or download the DevKit
from 'http://rubyinstaller.org/downloads' and follow the instructions
at 'http://github.com/oneclick/rubyinstaller/wiki/Development-Kit'

メッセージにあるようにDevelopment-Kitを入れましょう。

と、ここまではよかった。

rubyinstaller.orgには

  • DevKit-tdm-32-4.5.2-20111229-1559-sfx.exe
  • DevKit-mingw64-32-4.7.2-20130224-1151-sfx.exe
  • DevKit-mingw64-64-4.7.2-20130224-1432-sfx.exe

の3種類があります。

Windows7の64bitだったので、一番下を選択しました。
(そもそもこの判断がダメ???)

ところが、どこをどうしても、

Temporarily enhancing PATH to include DevKit...
Building native extensions.  This could take a while...
ERROR:  Error installing rdiscount:
    ERROR: Failed to build gem native extension.

のエラーから抜け出せぬ。

Google先生にお伺いをたてまくり、あーーーでもない、こーーーでもない、していると、

結城大先生のブログに行き着く。

プラットホームが64bitなことに起因してるのかなと予想したが、深追いするのはやめた。

http://d.hatena.ne.jp/hyuki/20121113/heroku/

とのこと。

エラーの内容が似ていたため、もしや、と思い、

  • DevKit-tdm-32-4.5.2-20111229-1559-sfx.exe

を入れなおす。

すると、すんなりインストールできました。泣。


2.herokuにpushできぬ

これは私の環境だけかもしれませんが、、、

C:\path\to\first_app>git push heroku master
Warning: Permanently added 'heroku.com,50.19.85.132' (RSA) to the list of known hosts.
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

公開鍵ちゃんとアップロードしてあるのに、、、


Google先生にお伺いをたてると、

  • keys:refreshしてkeys:addし直してみなさいな
  • C:\Users\%USER%\.ssh\config 作りなさいな
  • git\.sshにC:\Users\%USER%\.sshの中身をコピーしなさいな
  • ssh-keygenで鍵ファイル作り直してみなさいな

等いろいろ出てきましたが、どれもダメ。


ぐぬぬと試行錯誤しているうちに、

  • herokuは鍵ファイルを正しく見つけている
    • だってkeys:addできるもん
  • git pushで実行されているsshが鍵ファイルを見つけられない
    • ひょっとしてユーザーのホームディレクトリがわからない?

という状況なのではないかと推測しました。


んでコマンドプロンプトから、

set HOME=C:\Users\%USER%

としてみたところ、ちゃんとpushされました。泣。


うむ。これで、先に進める。

sphinxでtsv-tableできなかった!(後編)

sphinxでtsv-tableできなかった!(前編) - think it over

で、csv-tableと同等の機能を持つtsv-tableの作成までできました。
後編では断念するまでの経緯をまとめておこうかと。

csv-tableの実装を確認

前編でも触れましたが、

/usr/lib/python2.7/site-packages/docutils-0.10-py2.7.egg/docutils/parsers/rst/directives/tables.py

のソースを確認すると、

「parse_csv_data_into_rows」

というわかりやすい名前の関数があります。

    def parse_csv_data_into_rows(self, csv_data, dialect, source):
        # csv.py doesn't do Unicode; encode temporarily as UTF-8
        csv_reader = csv.reader([self.encode_for_csv(line + '\n')
                                 for line in csv_data],
                                dialect=dialect)
        rows = []
        max_cols = 0
        for row in csv_reader:
            row_data = []
            for cell in row:
                # decode UTF-8 back to Unicode
                cell_text = self.decode_from_csv(cell)
                cell_data = (0, 0, 0, statemachine.StringList(
                    cell_text.splitlines(), source=source))
                row_data.append(cell_data)
            rows.append(row_data)
            max_cols = max(max_cols, len(row))
        return rows, max_cols

実際にCSV形式のコンテンツの読み込みを行っているのは「csv.reader」であることがわかります。

csvっていいながらも区切り文字を指定できるんでしょ、と調べると以下に辿り着く。
13.1. csv — CSV ファイルの読み書き — Python 2.7ja1 documentation

そこに記述されている、「短い利用例」を引用すると、

>>> import csv
>>> spamReader = csv.reader(open('eggs.csv', 'rb'), delimiter=' ', quotechar='|')
>>> for row in spamReader:
...     print ', '.join(row)
Spam, Spam, Spam, Spam, Spam, Baked Beans
Spam, Lovely Spam, Wonderful Spam

おお!やはり「delimiter」なるものが!!!

タブ区切りに♪

早速、parse_csv_data_into_rowsをtsv-tableでオーバーライドする。
delimiterに「\t」を指定して、rstをタブ区切りにして、make html!

 ERROR: "tsv-table" widths do not match the number of columns in table (1).

あちゃー。

もともと「タブ区切りは外部ファイルに定義しなきゃだめよ」という制約があったので、
そんな単純に行く訳ないかと反省し、処理を追いはじめる。

タブがスペースに?誰が?

まずは、parse_csv_data_into_rowsに渡されている、csv_dataの中身を確認してみると、
なんと、タブがない。スペースに置き換わっている??


parse_csv_data_into_rowsを起点にして呼出し元を

さかのぼり、
さかのぼり、、
さかのぼり、、、


行き着いた先は、、、、

/usr/lib/python2.7/site-packages/docutils-0.10-py2.7.egg/docutils/parsers/rst/__init__.py

貴様か、Parser

__init__.pyの中にParserというクラスが定義されており、parse関数の中身を見ると、こんな処理が。

        inputlines = docutils.statemachine.string2lines(
              inputstring, tab_width=document.settings.tab_width,
              convert_whitespace=True)

convert_whitespace。ほーーう。

特定のために前後にデバッグプリントを埋め込む

        print inputstring.split("\n")
        inputlines = docutils.statemachine.string2lines(
              inputstring, tab_width=document.settings.tab_width,
              convert_whitespace=True)
        print inputlines

結果、

[u'.. tsv-table::', u'   :header: "\u958b\u59cb"\t"\u7d42\u4e86"\t"\u6642\u9593"\t"\u5185\u5bb9"', u'   :widths: 10, 10, 10, 200', u'', u'   09:00\t09:10\t00:10\t\u30c6\u30b9\u30c8', u'']
[u'.. tsv-table::', u'   :header: "\u958b\u59cb"        "\u7d42\u4e86"    "\u6642\u9593"    "\u5185\u5bb9"', u'   :widths: 10, 10, 10, 200', u'', u'   09:00        09:10   00:10   \u30c6\u30b9\u30c8']

おお、、、、こいつだ。。。

挑戦は続けます

Parser.parse関数を書き換えてしまうのは影響範囲が計り知れない、そして時間の都合で今回はここで断念。。。

いつか近いうちにリベンジします。