Latest Publications

サーバーの設定を自動でやるfabric

導入

sudo easy_install fabric

インストールすると、

/usr/local/bin/fab

ができる。

なぜかパスが通ってなかったので
.zshenvにパスを追加。

どこでもいいのでfabfile.pyを作成。

import os.path
from fabric.api import run, sudo, settings, abort, put, cd, env 
from fabric.contrib.console import confirm
from fabric.decorators import runs_once

# サーバー情報
env.hosts = ['xxx.xxx.xxx.xxx']
env.user = 'username'
env.port = '99999'
#env.key_filename = [os.path.expanduser('~/.ssh/secret_key')]

def hello():
 run("touch test1.txt")
 run("mv test1.txt test2.txt")

実行したら、設定ファイルの中身がサーバーで実行される。

fab hello

後は自分の設定したい内容を作りこんでいくだけ。

fabricがいるのか?

Capistrano使いの方から、
「Capistranoだけでいいじゃないか」と
disられる。

デプロイツールではあるけど
どうせCapistranoを使っているなら
サーバー設定用のプロジェクトを作っておいてそっちでやればと。

反論できず。

追記

sudo("mv test1.txt test2.txt")

というような感じでsudoを入力できるようになってて
パスワードはどうするんだろうかと思っていたら
fabの実行時にパスワードを聞かれた。なるほど。

サーバーのホスト名は安易に変更してはいけない

最近複数のサーバーにsshすることが多くなり、
今どこのサーバーにいるのかをわかりやすくするため
シェルの表示にホスト名を表示するようにしていた。

しかし、さくらVPSのホスト名はどれも似たようなものでわかりにくいため
自分がわかりやすい名前に変更してみた。

変更自体はすぐできたが、
その後にメールソフトからの送信ができなくなった。

ホスト名を変更した影響が
メール送信用に設定しているsendmailに出てしまった様子。
認証のところで止まってしまう。

色々と調べて試したがどうやっても上手く動かず
結局ホスト名を元に戻した。

シェルの表示はシェルの設定を変えてわかりやすくした。
本来はこっちだよね。

最初からホスト名を変えてから設定すれば
良かったのかもしれないが、設定が終わった後で
安易にホスト名の方はしないものだと学習。

CakePHPのmigrationのtype

cakephpのmigration pluginで
typeの指定をするところがある。

どんなtypeがあるのかがよくわからなくて調べたけど
はっきりとした情報が出ず。
関係ありそうなものはあったのでメモ。

string  => varchar
text
integer  => int
float
datetime
timestamp
time
date
binary  => blob
boolean  => tinyint

CakePHP2.3のAuthコンポーネント

色々と変わったらしいけど、とりあえず変更後に出た不具合と解決法をメモ

	public function beforeFilter() {
		parent::beforeFilter();
		//$this->Auth->allow('*');//コントローラーに対して全部のアクションを許可、というのが動かなかった
		$this->Auth->allow();
	}

vimでスニペットが使えるように設定

よく使うテキストパターンを一発で出せるようにしたいと考えて
IMEの辞書登録などを調べたけど改行に対応しておらず、
改行も含めて高度な設定ができるように思い切って作業。

準備

vimのpluginを管理するツールを入れる

% git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle

スニペットを使えるようにするプラグインを入れる

% git clone git://github.com/Shougo/neobundle.vim ~/.vim/bundle/neobundle.vim

ついでに、各言語のスニペット集を入れる

% git clone https://github.com/honza/snipmate-snippets.git ~/.vim/bundle/snipmate-snippets

.vimrcに下記を追記
最後の行にあるのがスニペットを設定しているファイルを見に行く部分。
~/.vim/mysnippets
が自分用のファイルを置く所にした。


"--------------------------------------------------------------------------
" neobundle
set nocompatible               " Be iMproved
filetype off                   " Required!

if has('vim_starting')
  set runtimepath+=~/.vim/bundle/neobundle.vim/
  endif

  call neobundle#rc(expand('~/.vim/bundle/'))

  filetype plugin indent on     " Required!

  " Installation check.
  if neobundle#exists_not_installed_bundles()
	  echomsg 'Not installed bundles : ' .
	          \ string(neobundle#get_not_installed_bundle_names())
	  echomsg 'Please execute ":NeoBundleInstall" command.'
	    "finish
endif
NeoBundle 'Shougo/neocomplcache.git'
NeoBundle 'Shougo/neosnippet.git'

" Plugin key-mappings.
imap      (neosnippet_expand_or_jump)
smap      (neosnippet_expand_or_jump)

" SuperTab like snippets behavior.
imap  neosnippet#expandable_or_jumpable() ? "\(neosnippet_expand_or_jump)" : pumvisible() ? "\" : "\"
smap  neosnippet#expandable_or_jumpable() ?"\(neosnippet_expand_or_jump)" : "\"

" For snippet_complete marker.
if has('conceal')
  set conceallevel=2 concealcursor=i
endif
" Tell Neosnippet about the other snippets
let g:neosnippet#snippets_directory='~/.vim/bundle/snipmate-snippets/snippets, ~/.vim/mysnippets'

vimを起動させて、下記のコマンドを打つことでインストールされる

:BundleInstall

自分用の設定ファイル

.vimrcで設定したディレクトリ、
ここでは
~/.vim/mysnippets
の中に設定ファイルを作る。

ここで、

拡張子名.snippets

というファイルを設定すると、その拡張子のファイルをvimで開いた時に
設定したスニペットが適用される仕組み。

例えば、

php.snippets

というファイルを作るとphpファイルに適用される。

しかし、今回実施したかったのはtxtファイルで

txt.snippets

というファイルを作ってもどうしても動作しなかった。
(誰かやり方わかる方いれば教えてください)

しかたがないので

_.snip

というファイルを作成。これは拡張子に関わらず、
全てのファイルに適用される。

スニペットの設定

あとは自分の便利なように設定する。

snippet ahaha
 1gyoume
 2gyoume
 3gyoume

と設定しておけば、vimでahahaと入力した後でCtrl+kと打つと
1gyoume
2gyoume
3gyoume
と出力される。

他にも、かなり高度なことも可能。

snippet hogef
  function hogef {
        ${1:code}
  }

などとすると、入力された上に指定場所にカーソルが合った状態で
インサートモードになっているため
すぐに中身を入力することができる。

応用

.vimrcの中身を変更することでスニペットの適用方法も変えれるみたい。
色々と使ってみながら、自分の使いやすいように設定を変更していく。

CakePHPのプロジェクトをcapistranoでデプロイ

capistranoはRuby On Rails用に作られたデプロイツールで、
設定をすればPHPのプロジェクトにも利用できる。

デプロイを自動化できるため、最初の設定さえしておけば後が楽。
ツールのインストールはデプロイをする端末だけにすれば良く、
各サーバーには特に何もする必要はなし。

複数サーバーに対して一気にデプロイすることもできるので
同じソースを複数のサービスに使っている場合などには便利。

準備

Rubyで作られているツールなので
gemでインストール。

$ gem install -y capistrano

プロジェクトごとに適用

$ cd {project_path}
$ capify .

これで
{project_path}/Capistrano
{Project_path}/config/deploy.rb
が作成される。deploy.rbが設定ファイルなので
これを自分の環境に応じて変更する。

設定ファイル

CakePHP用の設定ファイルを公開してくださっている方がいたので
それを参照させてもらいつつ自分用に修正。

CakePHPをCapistranoを使って楽々デプロイしよう!

追加分の設定

set :ssh_options, :port => "99999" # SSHのポート指定

結構つまづいた部分。
gitリポジトリを置いているサーバーとデプロイ先が同じだったので
set :repository, “file:///var/git/xxxxx.git”
などと設定したがどうしてもエラーでできず。

結局、Capistranoを動かしている自分のMacに一旦展開してから
サーバーにアップするという設定に。
SSHの鍵設定などをサーバー間でしなくてすむ反面、回線が遅いと困ることもありそう。

# set :deploy_via, :export
set :deploy_via, :copy #

delpoy:symlinkでは動かなかったので新しくなって変わったのかも。
deploy:create_symlinkに修正。
後は、CakePHP用にサーバー用の設定ファイルをsharedに置いてそこからシンボリックリンク。
また、tmp以下を.gitignoreで無視してるので必要なディレクトリを作成。

  desc "標準のシンボリック張り直し実行後に行う処理を記述する"
  # after "deploy:symlink", :roles => [:app] do
  after "deploy:create_symlink", :roles => [:app] do
    run "ln -fns #{shared_path}/system/database.php #{latest_release}/app/Config/database.php"
    run "ln -fns #{shared_path}/system/email.php #{latest_release}/app/Config/email.php"
    run "mkdir #{latest_release}/app/tmp/cache"
    run "mkdir #{latest_release}/app/tmp/cache/models"
    run "mkdir #{latest_release}/app/tmp/cache/persistent"
    run "mkdir #{latest_release}/app/tmp/cache/views"
    run "mkdir #{latest_release}/app/tmp/sessions"
    run "mkdir #{latest_release}/app/tmp/tests"
    run "chmod -R 777 #{latest_release}/app/tmp"

capistranoのコマンド

$ cap -T

と入力することで使用できるコマンドが表示される。
標準のものに加え、設定ファイルで自分が設定したものも出る。

cap deploy                 # Deploys your project.
cap deploy:check           # Test deployment dependencies.
cap deploy:cleanup         # Clean up old releases.
cap deploy:cold            # Deploys and starts a `cold' application.
cap deploy:create_symlink  # Updates the symlink to the most recently deployed version.
cap deploy:finalize_update # CakePHP用にfinalize_updateを上書きする
cap deploy:migrate         # Run the migrate rake task.
cap deploy:migrations      # Deploy and run pending migrations.
cap deploy:pending         # Displays the commits since your last deploy.
cap deploy:pending:diff    # Displays the `diff' since your last deploy.
cap deploy:rollback        # Rolls back to a previous version and restarts.
cap deploy:rollback:code   # Rolls back to the previously deployed version.
cap deploy:setup           # Prepares one or more servers for deployment.
cap deploy:start           # 標準のシンボリック張り直し実行後に行う処理を記述する
cap deploy:symlink         # Deprecated API.
cap deploy:update          # Copies your project and updates the symlink.
cap deploy:update_code     # Copies your project to the remote servers.
cap deploy:upload          # Copy files to the currently deployed version.
cap development            # Set the target stage to `development'.
cap invoke                 # Invoke a single command on the remote servers.
cap multistage:prepare     # Stub out the staging config files.
cap production             # Set the target stage to `production'.
cap shell                  # Begin an interactive Capistrano session.
cap staging                # Set the target stage to `staging'.

Some tasks were not listed, either because they have no description,
or because they are only used internally by other tasks. To see all
tasks, type `cap -vT'.

Extended help may be available for these tasks.
Type `cap -e taskname' to view it.

デプロイ先(サーバー)の準備

端末からサーバーにSSHで入れるようにしておく。

設定ファイルで指定する、プロジェクトのソースを置くための
ディレクトリは事前に作っておく。
SSHで入るユーザーがディレクトリの操作権限を持っているようにする。

その上で、下記のコマンドで必要なディレクトリを作成

cap deploy:setup

毎回のデプロイ作業

cap deploy

と入力するだけ。場合によってはjenkinsから実行させても良い。

(追記)git submoduleの管理

Plugin/Debugkit などをgit submoduleで管理していたが
git cloneしても取得されないのでエラーになっていた。

config/deploy.rb に下記を追加して解決。

set :git_enable_submodules, 1

jenkinsでのphingエラー

phingを設定したけどどうしても下記のエラーが。

FATAL: Phingの実行に失敗しました。インストールしたPhingのいずれ1つを使用してジョブを設定する必要があるかもしれません。

どうもパスが通っていないようで、
Global propertiesでパスを設定してもダメ、
Phingの高度な設定でPHING_HOMEを設定しても「Phingのディレクトリではありません。」

しかたがないのでシンボリックリンクで対応パスに入れ込んで解決。
sudo ln -s /opt/local/bin/phing /usr/bin/phing

CakePHPのコーディング規約チェックを自動で行うためにjenkinsを導入

Macに導入。

PHPのコーディング規約をチェックするPHP CodeSnifferを入れる

sudo pear install PHP_CodeSniffer

実行に必要なパスが通ってなかったのでphp.iniに追加
/opt/local/etc/php5/php.ini

include_path = ".://opt/local/lib/php"
sudo /opt/local/apache2/bin/apachectl restart

CakePHPのコーディング規約をインストール

sudo pear channel-discover pear.cakephp.org
sudo pear install cakephp/CakePHP_CodeSniffer

ちゃんと入ったかチェック

sudo phpcs -i
The installed coding standards are CakePHP, MySource, PEAR, PHPCS, PSR1, PSR2, Squiz and Zend

jenkinsはMac用のが準備されているのでインストール
Welcome to Jenkins CI! | Jenkins CI

サーバーのgitリポジトリと接続する設定をしたんだけどそこでつまづいた。
鍵をjenkins用に設置。サーバー側も対応。

/Users/Shared/Jenkins/.ssh/id_rsa

ビルドのトリガはgitにして、
変更があったら下記シェルを実行。

cd ${WORKSPACE} && phpcs '--ignore=*/Vendor/*,*/Plugin/*,*/cake.php' --report=checkstyle --report-checkstyle=${WORKSPACE}/reports/checkstyle.xml --standard=CakePHP --extensions=php,ctp ./app || id

レポートを出力する部分もつまづいて、
ファイルを出力できなかった。
ファイルが作成される方のパーミッションは設定してたんだけど
出力するファイルの設定が標準ではできていなかったのが原因。

cd /opt/local/lib/php/PHP/CodeSniffer/
sudo chmod 644 Reporting.php

google.loadでエラーが出たのを解決

JQueryやGoogle Visualization APIの呼び出しに使っていた部分が
エラーで動かなくなった。

これを

<script type="text/javascript" src="http://www.google.com/jsapi"></script>

これに変更して解決。

<script type="text/javascript" src="https://www.google.com/jsapi"></script>

httpsにするのが必須になったのか。

cakePHPのModelで別のModelデータを参照

cakePHP1.3。モデル内で別のモデルを参照する必要があった。
関連するデータは通常はアソシエーションを設定するけど、
アソシエーション関係なく呼ぶ必要もあるのでその時。

App::import('Model', 'User');
$User = new User();
$users = $User->find('all');


$User = ClassRegistry::init(‘User’);
$users = $User->find(‘all’);

など。