endokのブログ

IT・プログラミングネタ

Spring Boot触ってみる その2 ーController,テンプレートエンジン(Thymeleaf)ー

Spring Boot触ってみる その1 ー環境構築・サンプルプロジェクト作成ー - endokのブログ
の続き。

Controller作成と、Thymeleafを使ったテンプレート描画部分を確認する。
Spring BootではJSPではなくThymeleafの方がベタな模様。
(他のJava製Webフレームワークではどうなんでしょう)

前回作成したサンプルプロジェクトを引き続き利用する。

続きを読む

Spring Boot触ってみる その1 ー環境構築・サンプルプロジェクト作成ー

いまJavaでWebアプリケーションを作るならSpring Boot(http://projects.spring.io/spring-boot/)らしいという話を聞き、触ってみることに。

まずは環境構築とサンプルプロジェクトの作成。

続きを読む

Vagrantで独自BOX作成してATLASで公開する

やりたいこと

  • chef/centos-6.5 をベースにyum update、yum groupinstall Development ToolsしたBOXを作る。
  • Atlas by HashiCorp で公開してVagrantfileで指定できるようにする。

環境

最終的な手順

いろいろ問題は発生したが、最終的な手順は下記となった。

※ $ 〜はホストでのコマンド。> 〜はVM内でのコマンド。

ベースにするboxを使って普通にvagrant upする

今回の場合、Vagrantfileに下記のようにベースのboxを指定し、vagrant upする。

config.vm.box = "chef/centos-6.5"

vagrant sshして変更を加える

$ vagrant ssh
> sudo yum update -y
> sudo yum groupinstall -y 'Development Tools'

vagrantユーザーのinsecure private keyを配置する

vagrantユーザーのデフォルト公開鍵があり、それを設定しておく必要があった。

https://github.com/mitchellh/vagrant/tree/master/keys
vagrant.pubをvagrantユーザーのauthorized_keysに設定する。

> wget https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub
> cat vagrant.pub >> /home/vagrant/.ssh/authorized_keys
> rm vagrant.pub

kernelをアップデートした場合はVirtualBox Guest Additionsの再セットアップする

kernelをアップデートすると、vagrant up した際に下記のようなエラーが出る。

Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` vagrant /vagrant
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` vagrant /vagrant

The error output from the last command was:

/sbin/mount.vboxsf: mounting failed with the error: No such device

vagrant-vbguestプラグインで再セットアップする。
自分の場合、通常時は使わないのでセットアップが終わったら削除しておく。

$ vagrant plugin install vagrant-vbguest
$ vagrant vbguest
$ vagrant plugin uninstall vagrant-vbguest

参考: VagrantのboxのGuest Additionsのアップデート方法 - Qiita

NICマッピングを消す

参考: Vagrant で作った仮想マシンから Box ファイルを作りなおす | CUBE SUGAR STORAGE

> sudo ln -s -f /dev/null /etc/udev/rules.d/70-persistent-net.rules

ログアウト後、Vagrantのinsecure key置き換え機能をOFFにする

VMからログアウトする。

> exit

設定したinsecure keyが置き換えられないように、Vagrantfileで機能をOFFにする。

config.ssh.insert_key = false

停止、パッケージングする

$ vagrant halt
$ vagrant package

package.boxというファイルが出来上がる。

出来上がったboxファイルを使ってみる

BOXを登録する。

$ vagrant add mycentos package.box

既存のVM破棄後、登録したBOXを起動する。

$ vagrant destroy
$ vi Vagrantfile
  config.vm.box = "mycentos"
$ vagrant up

vagrant sshして問題ないか確認する。

ATLASで公開する

  1. ATLASにログインし、Developmentページを開く
  2. "Create a Vagrant Box"のBeginボタンを押す
  3. BOX名、説明など入力し、BOX作成する
  4. "New Box Version"にバージョンと説明を入力してCreate versionボタンを押してバージョンを作成する
  5. "Providers"欄のCreate new providerボタンを押す
  6. Providerには「virtualbox」と入力し、Uploadを選択してpackage.boxをアップロードする。Providerが登録される
  7. Overviewページに戻り、バージョンのEditボタンを押す。
  8. 上の方に「This version hasn't been released.〜」と出ているので、Release versionボタンを押す

これで外部からアクセス可能になる。

Vagrantfileで

config.vm.box = "[アカウント名]/[BOX名]"

を指定すれば使える。

Dockerの公式MySQLイメージを使ってホストからアクセスするまで

Dockerわかってる人には単純な話かと思いますが、一部ハマったのでメモ。

やりたいこと

  • 公式MySQLイメージを使ってコンテナ起動する
  • ホスト側からmysqlコマンドでコンテナのmysqldに接続する。

mysql Repository | Docker Hub Registry - Repositories of Docker Images
こちらのイメージを利用する。

dockerはインストール済とする。

公式MySQLイメージをpullする

今回はバージョン5.5を利用。

$ docker pull mysql:5.5
$ docker ps
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
mysql                      5.5                 c8defdc7b8fa        6 days ago          214.7 MB

コンテナを起動する

MYSQL_ROOT_PASSWORDという環境変数でrootパスワードを設定する。
その他の環境変数は公式参照。

外部から接続するには、-p [ホスト側ポート]:[コンテナ側ポート]でポートを公開する必要があるとのこと。
今回はホストの13306でコンテナの3306ポートに接続する。

ここで問題発生。

最初、

$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=mysql -d mysql:5.5 -p 13306:3306

としていたが、これだとすぐにコンテナがエラーで終了してしまった。

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

ログを確認する。

$ docker logs mysql
...
150314 15:00:05 [ERROR] mysqld: unknown option '-p'
150314 15:00:05 [ERROR] Aborting

150314 15:00:05  InnoDB: Starting shutdown...
150314 15:00:06  InnoDB: Shutdown completed; log sequence number 1595675
150314 15:00:06 [Note] mysqld: Shutdown complete

mysqldに-pオプションが渡ってしまっている模様。
考えてみると当たり前だが、最後に-pオプションを指定していたのがまずかった。
-pオプションの場所を変更すると起動成功。

$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=mysql -d -p 13306:3306 mysql:5.5
$ docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                     NAMES
5289e9512b4e        mysql:5.5           "/entrypoint.sh mysq   47 seconds ago      Up 46 seconds       0.0.0.0:13306->3306/tcp   mysql

ホストから接続する

ホストからlocalhostの13306ポートに接続すればよい。
パスワードは上の例では"mysql"。

$ mysql -u root -p -h 127.0.0.1 -P 13306
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.42 MySQL Community Server (GPL)

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

無事接続成功。

Bootstrapでpull-leftしたアイコンを含む要素を表示/非表示するとその要素のテキスト、背景色が消える(iPhone Safariで発生)

原因よくわからないものの解決したのでとりあえずメモ。
かなり状況は限定的。

環境

Bootstrap 3.3.2
jQuery 1.11.2
iPhone6(iOS8.1.3)

現象

下記の"Button"を押すと左の"LEFT"がtoggleするようになっている。

"Button"を2回押して非表示→表示とすると、LEFTというテキスト、背景色が消える。

サンプルコードは下記。

<html lang="ja">
<head>
  <meta name="viewport" content="width=device-width">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
  <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>

  <style>
    body {
      font-size: 16px;
    }
    .left {
      background-color: skyblue;
    }
    .right {
      background-color: yellow;
    }
  </style>
</head>  
<body>
  <div class="container">
    <div class="clearfix">
      <div class="pull-left left">
        <span class="glyphicon glyphicon-search" aria-hidden="true"></span>
        LEFT
      </div>
      <div class="pull-right right">
        RIGHT  
      </div>
    </div> 
    <button id="btn">Button</button>
  </div>

  <script>
    $(function(){
      $("#btn").on("click", function(){
        $(".left").toggle();
      });
    });
  </script>
</body> 
</html>

発生条件

下記条件を満たすときに発生する(本当はもっと細かい条件があるかもしれないが調べきれていない)

  • pull-left(float: left)した要素をclearfixクラスでクリアしている。
  • pull-leftしている要素内にglyphiconがある。
  • pull-leftしている要素をjQuery.toggle()する。
  • iPhonesafariで表示したときに発生する。(PCのChromeでは発生しない)

解決方法

pull-leftする要素とtoggleする要素を分離する。

    <div class="clearfix">
      <div class="pull-left">
        <div class="left">
          <span class="glyphicon glyphicon-search" aria-hidden="true"></span>
          LEFT
        </div>
      </div>
      <div class="pull-right right">
        RIGHT  
      </div>
    </div>

rspec3でJST日付を検証する

modelのdatetime型項目を検証する。

例えば下記のmodelを考える。

class CreateTasks < ActiveRecord::Migration                                                           
  def change
    create_table :tasks do |t|
      t.string :title
      t.datetime :deadline

      t.timestamps null: false
    end
  end                                                                                                 
end

'2015/01/01'でdeadlineを初期化後に

p task.deadline

すると

Thu, 01 Jan 2015 00:00:00 JST +09:00

と表示される。

この状態で

expect(task.deadline).to eq DateTime.new(2015,1,1)

とすると

Failure/Error: expect(task.deadline).to eq DateTime.new(2015,1,1)
       expected: Thu, 01 Jan 2015 00:00:00.000000000 +0000
       got: 2015-01-01 00:00:00.000000000 +0900

と言われてしまう。
DateTimeではタイムゾーンが反映されないのが原因?の模様。
Timeを使うとタイムゾーンが反映され、比較OKとなる。

expect(task.deadline).to eq Time.new(2015,1,1)


DateTimeとTimeの扱いは下記ページが詳しい。
RubyとRailsにおけるTime, Date, DateTime, TimeWithZoneの違い - Qiita

Railsでassets/imagesの画像を差し替えるとundefined method `bytesize'が発生する

現象

railsで、app/assets/images配下に画像を配置していた。
その画像のサイズを変更しながら見栄えを確認していると、下記のような状態になった。

  • 同じファイル名で最初に配置したファイルよりもサイズの小さい画像を配置すると、 ERROR NoMethodError: undefined method `bytesize' for nil:NilClass というエラーが発生する。ブラウザ上では途中まで読み込みが行われるが、読み込み終わると画像読み込みエラーになる。
  • 同じファイル名で最初に配置したファイルよりもサイズの大きい画像を配置すると、画像の途中で読み込みが終わってしまう。
  • ファイル名を別名にしてみると、正常に表示される。

解決方法

どこかのキャッシュなんだろうと思いつつ調べていくと、サーバー側のassets情報のキャッシュが原因だった模様。

railsアプリケーションのルートフォルダから

$ rm -rf tmp/cache/assets

を実行したところ解消した。