page_adsence

2015年10月27日火曜日

MailCore2をSwiftプロジェクトで使う

初めてiOSアプリを作るのですが、メール周りの機能が欲しかったので、下記のライブラリを使って実装してみようと思ったのですが、
初めて過ぎて何をどうすればいいのかわからなかったのでメモしておく。
とりあえず今回の記事ではSwiftからObjective-Cを使える様にする所までやってみる。 使ったのはXcode7。

まず、Xcodeで新しいプロジェクトを作成しておく。
今回はSingleViewApplicationで作る。

適当なプロジェクト名をつける

保存場所を指定して作成ボタンをクリック

で、作成が終了したらXcodeは終了しておく。


続いて使用したかったライブラリをインストールしていく。 使いたかったライブラリはこれ。
■MailCore2
https://github.com/MailCore/mailcore2

CocoaPodsでインストール出来るので、ターミナルを起動させて、CocoaPodsをインストールする。
$ sudo gem install cocoapods
Password: ← 自分のMacのログインパスワードを入力
Fetching: nap-1.0.0.gem (100%)
Successfully installed nap-1.0.0
Fetching: cocoapods-core-0.39.0.gem (100%)
Successfully installed cocoapods-core-0.39.0
Fetching: claide-0.9.1.gem (100%)
Successfully installed claide-0.9.1
Fetching: xcodeproj-0.28.2.gem (100%)
Successfully installed xcodeproj-0.28.2
Fetching: cocoapods-downloader-0.9.3.gem (100%)
Successfully installed cocoapods-downloader-0.9.3
Fetching: cocoapods-search-0.1.0.gem (100%)
Successfully installed cocoapods-search-0.1.0
Fetching: cocoapods-stats-0.6.2.gem (100%)
Successfully installed cocoapods-stats-0.6.2
Fetching: cocoapods-try-0.5.1.gem (100%)
Successfully installed cocoapods-try-0.5.1
Fetching: cocoapods-trunk-0.6.4.gem (100%)
Successfully installed cocoapods-trunk-0.6.4
Fetching: molinillo-0.4.0.gem (100%)
Successfully installed molinillo-0.4.0
Fetching: cocoapods-0.39.0.gem (100%)
Successfully installed cocoapods-0.39.0
Parsing documentation for nap-1.0.0
Installing ri documentation for nap-1.0.0
Parsing documentation for cocoapods-core-0.39.0
Installing ri documentation for cocoapods-core-0.39.0
Parsing documentation for claide-0.9.1
Installing ri documentation for claide-0.9.1
Parsing documentation for xcodeproj-0.28.2
Installing ri documentation for xcodeproj-0.28.2
Parsing documentation for cocoapods-downloader-0.9.3
Installing ri documentation for cocoapods-downloader-0.9.3
Parsing documentation for cocoapods-search-0.1.0
Installing ri documentation for cocoapods-search-0.1.0
Parsing documentation for cocoapods-stats-0.6.2
Installing ri documentation for cocoapods-stats-0.6.2
Parsing documentation for cocoapods-try-0.5.1
Installing ri documentation for cocoapods-try-0.5.1
Parsing documentation for cocoapods-trunk-0.6.4
Installing ri documentation for cocoapods-trunk-0.6.4
Parsing documentation for molinillo-0.4.0
Installing ri documentation for molinillo-0.4.0
Parsing documentation for cocoapods-0.39.0
Installing ri documentation for cocoapods-0.39.0
11 gems installed

これでCocoaPodsが使えるようになった。
試しにpodコマンドが使えるのか確認してみる。
$ pod --version
0.39.0

きちんとバージョンが表示されたので、これでCocoaPodsのインストール作業は完了。
これからmailcore2をCocoaPods経由でインストールしていく。
まずターミナルを起動し、Xcodeで作成したプロジェクトファイル(*.xcodeproj)のおいてあるディレクトリへ移動する
自分の場合は「/Users/user_name/Documents/iPhoneApps/mailCoreTest」というプロダクトを作ったのでそこへ移動した。
$ cd /Users/user_name/Documents/iPhoneApps/mailCoreTest

対象のディレクトリへ移動したらPodfileというファイルを作成し、下記の通り記述して保存する。 PodfileはPHPでいうcomposer.jsonみたいなもの。
$ vi Podfile
platform :ios, “7.0”
pod 'mailcore2-ios', '~> 0.5.1'

で、mailcore2をインストールする。
$ pod install
Updating local specs repositories
Analyzing dependencies
Downloading dependencies
Installing mailcore2-ios (0.5.1)
Generating Pods project
Integrating client project

[!] Please close any current Xcode sessions and use `mailCoreTest.xcworkspace` for this project from now on.
Sending stats
Pod installation complete! There is 1 dependency from the Podfile and 1 total
pod installed.
以上でmailcore2を使う事前準備が完了。
mailCoreTest.xcworkspaceというファイルが出来ているので、これをXcodeで開く。

するとPodsというプロジェクトがmailCoreTestの中に出来ている。

後はSwiftプロジェクトからObjective-Cを呼べる様にXcode側で設定してやる

SwiftからObjective-Cのコードを呼ぶためには、Bridging-Header.hという特殊なヘッダファイルを用意してやる必要がある。
で、追加してみる。(Objective-Cのソースがプロジェクトに追加されると、自動で生成される。)
自分で追加する場合は下記の通り。

XcodeのFile -> New -> Fileを選択。もしくは⌘Nを押す。

Header Fileを選択。

プロジェクト名-Bridging-Headerという名前を付けて保存


作成したヘッダファイルの中に下記を追加して保存。
#import <MailCore/MailCore.h>

続いて、追加したヘッダファイルをXcodeに認識させる。
Build Settings -> Swift Compiler – Code Generation
”Install Objective-C Compatibility Header”が”Yes”
”Objective-C Bridging Header”に、”$(SRCROOT)/$(PROJECT)/$(SWIFT_MODULE_NAME)-Bridging-Header.h”と入力する。(実際にBridging-Header.hファイルがあるパスを指定する。)

以上でSwiftからObjective-Cが呼べる様になる。

2015年10月13日火曜日

ConfluenceをローカルのVMに入れてみた

会社で利用しているConfluenceなのですが、これが結構便利で他の事にも使えないかということで、調査目的でローカルのVMにインストールしてみた。

インストール方法は下記のサイトを参考にインストールしました。 Atlassian Confluence インストール ガイド (Linux OS)
インストール完了後にConfluenceのセットアップウィザードみたいなのがあるのですが、
その辺はこちらでも書いておこうと思います。

インストールしたConfluenceのバージョンは若干古めのやつ(5.6.6)を使っています。(会社で利用しているバージョンと同じバージョンにするため)

まず、事前にAtlassianのアカウントを作成する必要があります。
https://id.atlassian.com/signup
上記サイトにアクセスして、アカウントを作成しておきます。

下記のURLにアクセスして、Confluenceのセットアップ画面にいきます。
http://VMのIP:8090/
※ポート番号はインストール手順の中で変更出来ますので、変更している人は自分で指定したポート番号に読み替えて下さい。

画面右上の日本語をクリックして、表示を日本語に変換


トライアル版の使用を始めるをクリック


ライセンスキーの入力画面で、アカウントを持っており、キーを作成したいをチェック


先ほど作成したAtlassianのログイン情報を入力して、「I agree to ~」にチェックして、「サインインしてライセンスキーを作成」ボタンをクリック
クリック後に非常に時間が掛かった・・・。1時間位は放置しておく位の気持ちで挑んだ方がいいのかもしれない。


Manage users~ボタンをクリック(何故かここからは英語になってしまう・・・)


最初にシステム管理者のアカウントを作成するための情報を入力する。


初期設定完了。「Start using Confluence」をクリックしてウェルカムページへ遷移


以上でとりあえずConfluenceが利用出来る状態になる。 Confluence自体のインストール手順が書かれているサイトの一番下にインストール後の設定という項目があるので、 こちらも合わせてやっておくと良いかもしれません。 色々と試してみたいと思います。

2015年10月12日月曜日

SSL接続の仕組み

iOSアプリ開発していた時に色々と横道に逸れていったらSSL通信の仕組みに関して、ちゃんと理解してない事に気がついたので図を書いてみた。


言葉で流れを説明する前に、SSLは「共通鍵暗号方式」と「公開鍵暗号方式」の両方を使っているということを知っておく必要があります。

共通鍵暗号方式


クライアントとサーバで同じ鍵情報を持っている状態で、それぞれが送信時には暗号化し、受信時には復号化する。
クライアント、サーバ共に暗号化、復号化が可能。

公開鍵暗号方式


サーバ上で生成された秘密鍵と公開鍵のキーペアを使う。
クライアントは公開鍵を取得し、サーバ側に公開鍵を使って暗号化した情報を送る。
サーバ側では受信した情報を秘密鍵を使って復号化する。
共通鍵暗号方式との大きな違いは、公開鍵で暗号化された情報は秘密鍵でしか復号出来ないという点。
クライアントにしろ、サーバにしろ、秘密鍵を持っている方でしか復号できない。

以上の事を踏まえて、SSL通信の流れを説明してみる。

1.ユーザーがSSL化されているページにアクセス(SSL接続要求)
2.サーバ側はその接続要求に対し公開鍵を含んでいる証明書を返却
3.ユーザーは証明書から公開鍵を取り出す
4.SSL接続要求をしたサーバと暗号化通信するための共通鍵を作成
5.作成した共通鍵を公開鍵を使って暗号化して、サーバへ送信
6.サーバは受信した共通鍵を秘密鍵を使って復号化
7.処理の終了通知を送る。
8.ユーザーが入力したユーザー名やパスワードを共通鍵を使って暗号化して送信
9.共通鍵を使って復号化し、入力された情報を取り出す。
10.取り出した情報で各種処理を行う。
11.レスポンスを返却する。

以上がざっくりとした流れです。

ネットでググっていると、この辺の情報はいっぱい出てくるのですが、どれが正しいのか正直わかりません・・・。
この記事も間違っている可能性もあります・・・。
程々に参考にして下さい。

2015年7月24日金曜日

phpファイルをテキストファイルとして返却する

Web上で差分を確認するために、phpファイルを「text/plain」として返却する必要があった。
(phpファイルとして解釈されてしまうとパラメータとか諸々展開されてしまうので、正確な差分が取れない)
ただ、差分を確認するためにいちいちテキストファイルにして比較とかはしたくなかったので、
.htaccessファイルを使って、phpファイルはテキストファイルとして解釈するようにした。
その設定がこちら。
php_flag engine off
AddType text/plain php

2015年7月23日木曜日

vagrant haltやsuspendコマンドが使えない

ansible-playbookを処理途中で「Ctrl + C」した影響か、vagrant haltやsuspendコマンドを実行すると下記の様なエラーが出るようになってしまった。
ちなみに、vagrant statusやvagrant sshは普通に使えました。

$ vagrant halt
An action 'halt' was attempted on the machine 'default',
but another process is already executing an action on the machine.
Vagrant locks each machine for access by only one process at a time.
Please wait until the other Vagrant process finishes modifying this
machine, then try again.

If you believe this message is in error, please check the process
listing for any "ruby" or "vagrant" processes and kill them. Then
try again.

原因はホストマシン側(自分の場合はWindows)で動いているrubyによるものらしい。
vagrantコマンドを実行するとホストマシン上でrubyが実行されるのですが、
コマンドの処理終了のタイミングでrubyのプロセスも切れる様になっている。
しかし、このメッセージが出ている時は、rubyのプロセスが切れずに残り続けている状態になっていた。
対応としては、該当のrubyのプロセスを切ってやればいい。
タスクマネージャーを開くと、ruby.exeというプロセスが残っているはずなので、それを右クリックしてプロセス終了をクリック。
終了したら通常通りvagrant haltやsuspendなどが使えるようになりました。

2015年7月22日水曜日

vagrantのバージョンアップしてみた

同僚の人がansible-playbookがうまくいかないとの事だったので、その人と環境を揃える為にvagrantのバージョンを1.6.5から最新の1.7.3に上げてみた。
vagrant自体のバージョンアップは簡単だけど、ちょっと面倒臭い。
旧バージョンをアンインストールして再起動、新バージョンをインストールして再起動すれば完了。
作業自体は単純ですが、Windowsの再起動が遅すぎてすごく時間が掛かった。
SSDに換装してほしい・・・。

Virtualboxのバージョンアップも行ったがこちらはインストーラーを使ってインストールするだけでバージョンアップされる。
両方のバージョンアップが終わった所で、諸々確認していく。
最終的に確認する内容としては、ansible-playbookを実行して、VM上の環境がきちんと出来上がるかどうかを確認する。

まず、1.6.5の時に作ったVMは不要になったので、一度削除して作りなおす事にした。
Cygwin上から下記のコマンドを実行。
$ vagrant destroy
Vagrant is attempting to interface with the UI in a way that requires
a TTY. Most actions in Vagrant that require a TTY have configuration
switches to disable this requirement. Please do that or run Vagrant
with TTY.

今までは普通に削除出来たのに、vagrantのバージョンを上げた途端に削除出来なくなってしまった・・・。
原因はまだ調べていないが、下記の様にオプションをつけることで削除することは可能。
$ vagrant destroy --force
==> default: Destroying VM and associated drives...

Vagrantfile自体は特に変更する必要がなかったので、vagrant upした。
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'centos64-100g'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: vm-test
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 => 2231 (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2231
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection timeout. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default:
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default:
    default: Inserting generated public key within guest...
    default: Removing insecure key from the guest if it's present...
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
    default: /vagrant => C:/cygwin64/home/user_name/VirtualBoxMachines/vm-test

赤い文字の部分が多分バージョンアップ後に新しくデータメッセージで、
安全じゃない鍵があったから、より安全な新しい鍵ペアに置き換えるよというメッセージが出ていた。
今まで使っていた1.6系だと、1ユーザーに付き1個の鍵が生成されていて、複数のVMを作ってもその1つの鍵を使いまわして接続ができたが、1.7系にすると1台に付き1個の鍵が生成される(vagrant up時)。
設定を今まで通りの状態でPlaybookを実行すると、下記の様なエラーが出てしまう。

.ssh/configに書かれている鍵情報が古いバージョンの時の鍵のままになっている場合に出るエラー

$ ansible-playbook setup.yml

PLAY [vm-grp] *************************************************************

GATHERING FACTS ***************************************************************
fatal: [vm] => SSH Error: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
    while connecting to 192.168.33.10:22
It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.

TASK: [check selinux off] *****************************************************
FATAL: no hosts matched or all hosts have already failed -- aborting


PLAY RECAP ********************************************************************
           to retry, use: --limit @/home/user_name/setup.retry

vm                  : ok=0    changed=0    unreachable=1    failed=0

新しい鍵を使うために、.ssh/configを書き換える

Host vm-test
  HostName 192.168.33.10
  Port 22
  User vagrant
  #IdentityFile C:\Users\user_name\.vagrant.d\insecure_private_key <- コメントアウト
  IdentityFile /home/user_name/VirtualBoxMachine/vm1/.vagrant/machines/default/virtualbox/private_key <- 追記

ファイルのパーミッションで出るエラー

$ ansible-playbook setup.yml

PLAY [vm-grp] *************************************************************

GATHERING FACTS ***************************************************************
fatal: [vm] => SSH Error:     while connecting to 192.168.33.10:22
It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.

TASK: [check selinux off] *****************************************************
FATAL: no hosts matched or all hosts have already failed -- aborting


PLAY RECAP ********************************************************************
           to retry, use: --limit @/home/user_name/setup.retry

vm                  : ok=0    changed=0    unreachable=1    failed=0

上記の様なパーミッションのエラーになったら確認する場所としては、下記が挙げられる。
※下記のパーミッションになっていることを確認する
~/.ssh -> 700
~/.ssh/config -> 744
.vagrant/machines/default/virtualbox/private_key -> 700

上記の対応をしたらちゃんとansible-playbookが実行できた。

2015年7月7日火曜日

久しぶりのOAuth1.0にハマった

ものすごく久々にOAuth周りを触っていたのですが、色々とハマってしまったのでメモを残す。
以前のメモはあまり役に立ちませんでした・・・。
OAuthのライブラリはGoogleのOAuth.php
http://oauth.googlecode.com/svn/code/php/OAuth.php

今回ハマった内容としてはものすごく単純でした。
既存のソースでCURLOPT_POSTFIELDSに対してリクエストパラメータの配列が配列の状態のまま渡っていたため、
BaseStringとかがすごい事になっていたのですが、そうなっている原因がすぐに分からず修正に時間がかかってしまった・・・。

例)HMAC_SHA1の形式でGETリクエストの場合

<?php
include_once 'oauth.php';

$consumerKey    = 'XXXXXXXXXXXX';
$consumerSecret = 'XXXXXXXXXXXX';
$accessToken    = null;
$method         = 'GET';
$url            = 'http://XXXX/XXX.php';
$request_params = array(
    'a' => 1,
    'b' => 2
);

$OAuthConsumer        = new OAuthConsumer($consumerKey, $consumerSecret);
$OAuthSignatureMethod = new OAuthSignatureMethod_HMAC_SHA1();

$OAuthRequest = OAuthRequest::from_consumer_and_token($OAuthConsumer, $accessToken, $method, $url, $request_params);
$OAuthRequest->sign_request($OAuthSignatureMethod , $OAuthConsumer, $accessToken);

list($buf, $OAuthAuthorization) = explode(':', $OAuthRequest->to_header(''), 2);

$OAuthAuthorizationHeader  = array(
    'Authorization:'.$OAuthAuthorization,
);

$ch   = curl_init();

curl_setopt($ch, CURLOPT_URL,            $url.'?'.http_build_query($request_params));
curl_setopt($ch, CURLOPT_HEADER,         true);
curl_setopt($ch, CURLOPT_HTTPGET,        true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER,     $OAuthAuthorizationHeader);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT,        30);

$res = curl_exec($ch);

例)HMAC_SHA1の形式でPOSTリクエストの場合

<?php
$consumerKey    = 'XXXXXXXXXXXX';
$consumerSecret = 'XXXXXXXXXXXX';
$accessToken    = null;
$method         = 'POST';
$url            = 'http://XXXX/XXX.php';
$request_params = array(
    'a' => 1,
    'b' => 2
);

$OAuthConsumer        = new OAuthConsumer($consumerKey, $consumerSecret);
$OAuthSignatureMethod = new OAuthSignatureMethod_HMAC_SHA1();

$OAuthRequest = OAuthRequest::from_consumer_and_token($OAuthConsumer, $accessToken, $method, $url, $request_params);
$OAuthRequest->sign_request($OAuthSignatureMethod , $OAuthConsumer, $accessToken);

list($buf, $OAuthAuthorization) = explode(':', $OAuthRequest->to_header(''), 2);

$OAuthAuthorizationHeader  = array(
    'Authorization:'.$OAuthAuthorization,
    'Content-Type: application/x-www-form-urlencoded',
);

$ch   = curl_init();

curl_setopt($ch, CURLOPT_URL,            $url);
curl_setopt($ch, CURLOPT_HEADER,         true);
curl_setopt($ch, CURLOPT_POST,           true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER,     $OAuthAuthorizationHeader);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT,        30);
curl_setopt($ch, CURLOPT_POSTFIELDS,     http_build_query($request_params));

$res = curl_exec($ch);

署名をチェック

<?php
include_once 'oauth.php';

$OAuthConsumerKey    = 'XXXXXXXXXXXX';
$OAuthConsumerSecret = 'XXXXXXXXXXXX';

$request              = OAuthRequest::from_request();
$OAuthSignatureMethod = new OAuthSignatureMethod_HMAC_SHA1();
$consumer             = new OAuthConsumer($OAuthConsumerKey, $OAuthConsumerSecret);

if ($OAuthSignatureMethod->check_signature($request, $consumer, null, $request->get_parameter('oauth_signature'))) {
        echo 'This signature is OK.';
} else {
        echo 'This signature is NG.';
}

2015年6月30日火曜日

vagrantのbox容量を拡張する方法

Vagrantでboxファイルをダウンロードしてくると基本的に容量が少なくて困ることが多かったので、boxのサイズを拡張してみた。
とは言ったものの、サクッと出来る感じではなく、結構手順が面倒くさいです。
何故かと言うと、Vagrantで使われる仮想ディスクイメージはvmdk形式と言われるもので、一度作成したディスクのサイズを変更することが出来ない。
なので、一度変換可能な形式(vdi)に変換して、拡張してから元のvmdk形式に戻すという手順が必要になる。
また、注意点としてVirtualBoxでスナップショット等を使っていた場合、スナップショットで保存されている内容は一切移行出来ない。
(出来る方法があるのかもしれないが、現時点ではわからなかった)

VirtualBoxをインストールしたディレクトリ内に「VBoxManage.exe」というファイルがあるので、それを使って拡張する。
C:\Program Files\Oracle\VirtualBox\VBoxManage.exe

以下、拡張のための手順。

1.VirtualBoxマネージャーで拡張したいVMを選択し、設定画面を開く

拡張したいVMを選択し、右クリック押して、コンテキストメニューの中の設定をクリック。
もしくは拡張したいVMを選択した状態で、設定ボタンを押す。


2.設定画面で拡張したいvmdkファイルの場所を調べる。

ストレージ → XXXXX.vmdk → 場所にマウスカーソルを合わせる。
そうするとフルパスが出てくるので、それを確認する。場所を右クリックするとコピー出来る。
コピーした値は「C:\Users\UserName\VirtualBox VMs\jenkins-laravel\box-disk1.vmdk」とする。


3.コマンドプロンプトを立ち上げて下記のディレクトリへ移動

cd C:\Program Files\Oracle\VirtualBox\

4.VBoxManage.exeがあるか確認

C:\Program Files\Oracle\VirtualBox> dir VBoxManage.exe

5.仮想HDDのUUIDを調べる

先ほど確認したvmdkファイルのパスと、下記のリストの中のLocationが一致するものを探す。
該当のvmdkファイルのUUIDの項目をコピーする。
C:\Program Files\Oracle\VirtualBox> VBoxManage.exe list hdds

UUID:           6e50fc33-ab05-4ca5-9740-ad708e335e11 ← これをコピーする
Parent UUID:    base
State:          created
Type:           normal (base)
Location:       C:\Users\UserName\VirtualBox VMs\jenkins-laravel\box-disk1.vmdk
Storage format: VMDK
Capacity:       30720 MBytes

UUID:           acd294ea-6844-4121-b66f-85f848bcecec
Parent UUID:    base
State:          created
Type:           normal (base)
Location:       C:\Users\UserName\VirtualBox VMs\jenkins-laravel-2\box-disk1.vmdk
Storage format: VMDK
Capacity:       30720 MBytes

6.vmdk形式からvdi形式にしてコピーする

vmdkファイルと同じ内容の仮想ディスクをvdi形式で作成する。
$ VBoxManage.exe clonehd "C:\Users\UserName\VirtualBox VMs\jenkins-laravel\box-disk1.vmdk" "C:\Users\UserName\VirtualBox VMs\jenkins-laravel\clone.vdi" --format vdi

0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Clone hard disk created in format 'vdi'. UUID: 152e5d9f-e66a-4212-84d6-dbe05c1f8ceb

7.vdi形式の仮想ディスクのサイズを変更する。100GBにしたい場合は下記の通り。単位はMB

$ VBoxManage.exe modifyhd "C:\Users\UserName\VirtualBox VMs\jenkins-laravel\clone.vdi" --resize 102400
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

8.拡張したvdi形式をvmdk形式にしてコピーする

$ VBoxManage clonehd "C:\Users\UserName\VirtualBox VMs\jenkins-laravel\clone.vdi" "C:\Users\UserName\VirtualBox VMs\jenkins-laravel\box-disk1.vmdk" --format vmdk

※上書きするのが怖い場合は別名にして保存し、VirtualBox上でストレージを変更することで対応出来る。
仮想ハードディスクファイルの選択をクリックして、新しく作ったvmdkファイルを選択することで、過去のファイルを残した状態で拡張出来る。
もし拡張したvmdkファイルに何か不都合があった場合は、元の仮想ハードディスクファイルに戻せば元の状態に戻る。


9.vdiファイルをVBoxManger上の管理から外す

ここに記載しているUUIDはvdi形式のファイルのUUID。
$ VBoxManage closemedium disk 152e5d9f-e66a-4212-84d6-dbe05c1f8ceb

ここまでで、vmdkファイルのディスク拡張作業は完了。
ここからは拡張したディスクを使用できるようにする。


10.拡張したVMにログインして、現状を確認する

使用出来る容量は変わっていない事を確認。
# df -h
Filesystem            Size  Used Avail Use% マウント位置
/dev/mapper/vg_vagrantcentos64-lv_root
                       28G  1.8G   24G   7% /
tmpfs                 499M     0  499M   0% /dev/shm
/dev/sda1             485M   32M  428M   7% /boot
vagrant               459G  358G  102G  78% /vagrant

11.VMWareを立ち上げて状態を確認

ディスク容量自体が増えていることを確認する
# fdisk -l

ディスク /dev/sda: 107.4 GB, 107374182400 バイト
ヘッド 255, セクタ 63, シリンダ 13054
Units = シリンダ数 of 16065 * 512 = 8225280 バイト
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O size (minimum/optimal): 512 bytes / 512 bytes
ディスク識別子: 0x00054ab8

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sda1   *           1          64      512000   83  Linux
パーティション 1 は、シリンダ境界で終わっていません。
/dev/sda2              64        3917    30944256   8e  Linux LVM

ディスク /dev/mapper/vg_vagrantcentos64-lv_root: 29.6 GB, 29569843200 バイト
ヘッド 255, セクタ 63, シリンダ 3594
Units = シリンダ数 of 16065 * 512 = 8225280 バイト
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O size (minimum/optimal): 512 bytes / 512 bytes
ディスク識別子: 0x00000000


ディスク /dev/mapper/vg_vagrantcentos64-lv_swap: 2113 MB, 2113929216 バイト
ヘッド 255, セクタ 63, シリンダ 257
Units = シリンダ数 of 16065 * 512 = 8225280 バイト
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O size (minimum/optimal): 512 bytes / 512 bytes
ディスク識別子: 0x00000000

12.パーティションを作成する

先ほど、fdiskコマンドで出てきた「ディスク /dev/sda」と書かれているところの「/dev/sda」の部分を入れる。(青文字の部分)
# fdisk /dev/sda

警告: DOS互換モードは廃止予定です。このモード (コマンド 'c') を止めることを
      強く推奨します。 and change display units to
         sectors (command 'u').

コマンド (m でヘルプ): n
コマンドアクション
   e   拡張
   p   基本パーティション (1-4)
p
パーティション番号 (1-4): 3
最初 シリンダ (3917-13054, 初期値 3917): Enter
初期値 3917 を使います
Last シリンダ, +シリンダ数 or +size{K,M,G} (3917-13054, 初期値 13054): Enter
初期値 13054 を使います

コマンド (m でヘルプ): t
パーティション番号 (1-4): 3
16進数コード (L コマンドでコードリスト表示): 8e ← fdiskコマンドの黄文字のとこの値を入れる
領域のシステムタイプを 3 から 8e (Linux LVM) に変更しました

コマンド (m でヘルプ): wq
パーティションテーブルは変更されました!

ioctl() を呼び出してパーティションテーブルを再読込みします。

警告: パーティションテーブルの再読込みがエラー 16 で失敗しました: デバイスもしくはリソースがビジー状態です。
カーネルはまだ古いテーブルを使っています。新しいテーブルは
次回リブート時か、partprobe(8)またはkpartx(8)を実行した後に
使えるようになるでしょう
ディスクを同期しています。

13.状態を再び確認

/dev/sda3が追加され、そこに空き容量が割り当てられていることを確認する
# fdisk -l

ディスク /dev/sda: 107.4 GB, 107374182400 バイト
ヘッド 255, セクタ 63, シリンダ 13054
Units = シリンダ数 of 16065 * 512 = 8225280 バイト
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O size (minimum/optimal): 512 bytes / 512 bytes
ディスク識別子: 0x00054ab8

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sda1   *           1          64      512000   83  Linux
パーティション 1 は、シリンダ境界で終わっていません。
/dev/sda2              64        3917    30944256   8e  Linux LVM
/dev/sda3            3917       13054    73398975   8e  Linux LVM

ディスク /dev/mapper/vg_vagrantcentos64-lv_root: 29.6 GB, 29569843200 バイト
ヘッド 255, セクタ 63, シリンダ 3594
Units = シリンダ数 of 16065 * 512 = 8225280 バイト
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O size (minimum/optimal): 512 bytes / 512 bytes
ディスク識別子: 0x00000000


ディスク /dev/mapper/vg_vagrantcentos64-lv_swap: 2113 MB, 2113929216 バイト
ヘッド 255, セクタ 63, シリンダ 257
Units = シリンダ数 of 16065 * 512 = 8225280 バイト
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O size (minimum/optimal): 512 bytes / 512 bytes
ディスク識別子: 0x00000000

14.リブートもしくはpartprobeを実行する

今回はrebootで反映させる。
# reboot

15.物理ボリュームを作成する

# pvcreate /dev/sda3
Physical volume "/dev/sda3" successfully created

16.既存のボリュームグループ(VG) に新しいパーティションを追加する

# vgextend vg_vagrantcentos64 /dev/sda3
  Volume group "vg_vagrantcentos64" successfully extended

17.既存の論理ボリューム(LV) を追加したパーティションの分を拡張する

既存のLV は lvdisplay で確認。「lv_root」が既存で、LSizeが既存のディスク容量
# lvdisplay -C
  LV      VG                 Attr      LSize  Pool Origin Data%  Move Log Cpy%Sync Convert
  lv_root vg_vagrantcentos64 -wi-ao--- 27.54g
  lv_swap vg_vagrantcentos64 -wi-ao---  1.97g

18.拡張できるサイズを確認する

# vgdisplay
  --- Volume group ---
  VG Name               vg_vagrantcentos64
  System ID
  Format                lvm2
  Metadata Areas        2
  Metadata Sequence No  4
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                2
  Open LV               2
  Max PV                0
  Cur PV                2
  Act PV                2
  VG Size               99.50 GiB
  PE Size               4.00 MiB
  Total PE              25473
  Alloc PE / Size       7554 / 29.51 GiB
  Free  PE / Size       17919 / 70.00 GiB
  VG UUID               f4eZwV-24wK-49T7-oERF-da3e-cwoW-gPtAdu

19.指定したサイズにディスクを拡張する

[PE Size] * [Free PE] の値が拡張できるサイズとなるので、4MB * 17919 = 71676MiB を拡張する。
# lvextend -L +71676MiB /dev/vg_vagrantcentos64/lv_root
  Extending logical volume lv_root to 97.54 GiB
  Logical volume lv_root successfully resized

20.ファイルシステムを拡張する

ディスク容量が大容量になると時間が掛かる。
# resize2fs /dev/vg_vagrantcentos64/lv_root
resize2fs 1.41.12 (17-May-2010)
Filesystem at /dev/vg_vagrantcentos64/lv_root is mounted on /; on-line resizing required
old desc_blocks = 2, new_desc_blocks = 7
Performing an on-line resize of /dev/vg_vagrantcentos64/lv_root to 25568256 (4k) blocks.
The filesystem on /dev/vg_vagrantcentos64/lv_root is now 25568256 blocks long.
※CentOS7では「resize2fs」は利用出来ないので、「xfs_growfs」を使う。
# xfs_growfs /dev/vg_vagrantcentos64/lv_root

21.容量が増えていることを確認する

# df -h
Filesystem            Size  Used Avail Use% マウント位置
/dev/mapper/vg_vagrantcentos64-lv_root
                       97G  1.8G   90G   2% /
tmpfs                 499M     0  499M   0% /dev/shm
/dev/sda1             485M   32M  428M   7% /boot

composer update時にgithubのrate limitに引っかかる

composer updateコマンドを行ってライブラリをインストールしていたのですが、途中で下記の様なメッセージが出てきた。

$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing XXXXXXX/XXXXXX (X.X.XX
    Downloading: 100%)

  - Installing XXXXXXX/XXXXXX (X.X.XX
    Downloading: 100%)

  - Installing XXXXXXX/XXXXXX (X.X.XX
    Downloading: 100%)

  - Installing XXXXXXX/XXXXXX (X.X.XX
    Downloading: 100%)

  - Installing XXXXXXX/XXXXXX (X.X.XX
    Downloading: Connecting...
Could not fetch https://api.github.com/repos/~~~~~, please create a GitHub OAuth token to go over the API rate limit
Head to https://github.com/settings/tokens/new?scopes=repo&description=Composer+on+host_name+2015-06-30+0254
to retrieve a token. It will be stored in "/home/user_name/.composer/auth.json" for future use by Composer.
Token (hidden):

調べてみると、githubのダウンロード回数制限に引っかかったみたいです。
時間が経てば解消されるのですが、待たずに規制緩和してもらうことも出来るので、その方法で対応してみた。

1.githubにログインして、下記URLにアクセス
https://github.com/settings/tokens

2.右カラムの「Personal access tokens」の中の「Generate new token」ボタンをクリック

3.「Token description」に適当な名前を入れて、「repo」だけを選択。
 「Generate token」ボタンをクリック

4.自分が付けたdescriptionの所に新しいトークンがあるので、それをコピーし、先ほどのメッセージが出た所へペーストする。

以上で対応出来るはず。

2015年6月5日金曜日

Google Cloud SDKとGoogle App Engine SDKにハマった

Google App Engineを使ってみようかと思い、SDKをダウンロードしてきたのですが、
Google Cloud SDKでも使えると思ってダウンロードして来てインストールしてみた。
しかし、手元のWindowsマシンではうまく動かなかった・・・。
その時に諸々調べたので、比べてみた。

■ダウンロード先URL
- Google Cloud SDK
https://cloud.google.com/sdk/

- Google App Engine SDK
https://cloud.google.com/appengine/downloads

■ダウンロードファイル
- Google Cloud SDK
GoogleCloudSDKInstaller.exe

- Google App Engine SDK
GoogleAppEngine-1.9.21.msi

落としてきたファイル自体は全然違うのですが、Google Cloud SDKをインストールしてもGoogle App Engineは使用できる。
インストール先のディレクトリを見ると同じ様な内容がインストールされていた。

■ディレクトリ構成 - Google Cloud SDK
C:\Program Files\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine


- Google App Engine SDK
C:\Program Files (x86)\Google\google_appengine


比べてみるとGoogle App Engine SDKの方がファイルが少ない。
また、同じプロジェクトを実行してみても、吐かれるログも若干異なる。

- Google Cloud SDK
2015-06-05 18:31:24 Running command: "['C:\\Python27\\pythonw.exe', 'C:\\Program Files\\Google\\Cloud SDK\\google-cloud-sdk\\platform\\google_appengine\\dev_appserver.py', '--skip_sdk_update_check=yes', '--port=8080', '--admin_port=8000', 'C:\\GoogleAppEngine\\helloworld\\engineapp']"
INFO     2015-06-05 18:31:28,542 devappserver2.py:745] Skipping SDK update check.
INFO     2015-06-05 18:31:28,795 api_server.py:190] Starting API server at: http://localhost:61721
INFO     2015-06-05 18:31:28,819 dispatcher.py:192] Starting module "default" running at: http://localhost:8080
INFO     2015-06-05 18:31:28,822 admin_server.py:118] Starting admin server at: http://localhost:8000


- Google App Engine SDK
2015-06-05 18:06:43 Running command: "['C:\\Python27\\pythonw.exe', 'C:\\Program Files (x86)\\Google\\google_appengine\\dev_appserver.py', '--skip_sdk_update_check=yes', '--port=8080', '--admin_port=8000', 'C:\\GoogleAppEngine\\helloworld\\engineapp']"
INFO     2015-06-05 18:06:43,177 devappserver2.py:745] Skipping SDK update check.
INFO     2015-06-05 18:06:43,970 api_server.py:190] Starting API server at: http://localhost:61256
INFO     2015-06-05 18:06:43,996 dispatcher.py:192] Starting module "default" running at: http://localhost:8080
INFO     2015-06-05 18:06:44,013 admin_server.py:118] Starting admin server at: http://localhost:8000


ちなみに、Google Cloud SDKの方は、ファイル内を修正しないと動かなかった。
dockerが問題になるらしく、docker-pyとかインストールしてみたのですが、解決しなかったので、
とりあえずコメントアウトして対応しました。

参考URL:http://qiita.com/MiCHiLU/items/495e4c6da7a3e7f3925c

2015-06-05 18:27:00 Running command: "['C:\\Python27\\pythonw.exe', 'C:\\Program Files\\Google\\Cloud SDK\\google-cloud-sdk\\platform\\google_appengine\\dev_appserver.py', '--skip_sdk_update_check=yes', '--port=8080', '--admin_port=8000', 'C:\\GoogleAppEngine\\helloworld\\engineapp']"
Traceback (most recent call last):
  File "C:\Program Files\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\dev_appserver.py", line 83, in 
    _run_file(__file__, globals())
  File "C:\Program Files\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\dev_appserver.py", line 79, in _run_file
    execfile(_PATHS.script_file(script_name), globals_)
  File "C:\Program Files\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\google\appengine\tools\devappserver2\devappserver2.py", line 36, in 
    from google.appengine.tools.devappserver2 import dispatcher
  File "C:\Program Files\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\google\appengine\tools\devappserver2\dispatcher.py", line 29, in 
    from google.appengine.tools.devappserver2 import module
  File "C:\Program Files\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\google\appengine\tools\devappserver2\module.py", line 74, in 
    from google.appengine.tools.devappserver2 import vm_runtime_factory
  File "C:\Program Files\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\google\appengine\tools\devappserver2\vm_runtime_factory.py", line 25, in 
    from google.appengine.tools.devappserver2 import vm_runtime_proxy
  File "C:\Program Files\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\google\appengine\tools\devappserver2\vm_runtime_proxy.py", line 29, in 
    from google.appengine.tools.devappserver2 import log_manager
  File "C:\Program Files\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\google\appengine\tools\devappserver2\log_manager.py", line 34, in 
    from google.appengine.tools.docker import containers
  File "C:\Program Files\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\google\appengine\tools\docker\containers.py", line 48, in 
    from docker import docker
ImportError: cannot import name docker
2015-06-05 18:27:00 (Process exited with code 1)

どちらを起動させてもGoogle App Engine Launcherの見た目は同じですが、
初期状態ではGoogle Cloud SDKの方はエラーが出て立ち上がらず、Google App Engine SDKの方は普通に立ち上がります。
※左がGoogle App Engine SDK版、右がGoogle Cloud SDK版です。