OmniAICreator/Qiita-1.07M huggingface dataset:
CentOSでlsyncdを使ってファイルを同期する

# 環境
* CentOS 7系
* SELinux


# 準備
- [プロキシの指定方法 - Qiita](http://qiita.com/tunepolo/items/296c2639e0b750de41c6)
- Extra Packages for Enterprise Linux (EPEL) 導入
  - [Third Party Repositories | AdditionalResources/Repositories - CentOS Wiki](https://wiki.centos.org/AdditionalResources/Repositories#head-60737493141730f521521176d3cc3a4fe5d98043)
  - [EPEL/ja - FedoraProject](https://fedoraproject.org/wiki/EPEL/ja)

    ```bash
yum install epel-release
sed -i -e "s/enabled=1/enabled=0/" /etc/yum.repos.d/epel.repo
```


説明のために、同期元のディレクトリを`/tmp/original`として同期先のディレクトリを`/tmp/target`とする


# インストール

```bash
yum --enablerepo=epel install lsyncd
```

- lsyncd.conf の編集

```bash
cp -ip /etc/lsyncd.conf{,.org}
vi /etc/lsyncd.conf
```

```lua:/etc/lsyncd.conf
settings {
  logfile    = "/var/log/lsyncd/lsyncd.log",
  statusFile = "/var/log/lsyncd/lsyncd.status"
}

sync{
  default.rsync,
  source = "/tmp/origin",
  target = "/tmp/target",
  rsync = {
    archive  = true,
    compress = true
  },
  delete = false
}
```

詳しくは、作者作成の [Manual](https://axkibe.github.io/lsyncd/) を参照


## /etc/sysconfig/lsyncdの編集（任意）

lsyncdのログレベルを変更するために、起動時のオプションを変更する

```
cp -ip /etc/sysconfig/lsyncd{,.org}
vi /etc/sysconfig/lsyncd
```

```:/etc/sysconfig/lsyncd
LSYNCD_OPTIONS="-log Inotify"
```


## ログファイル用準備

```bash
mkdir -m 700 /var/log/lsyncd && chcon -R -u system_u "/var/log/lsyncd"
systemctl restart rsyslog
```


## デーモンに登録

```bash
systemctl start lsyncd
systemctl enable lsyncd
```



# トラブル対応

ログは`/var/log/lsyncd/lsyncd.log`に保存されているので、トラブルがある時は眺めてみる

## Error: Terminating since out of inotify watches.
inotifyで監視しているディレクトリ数が上限に達しているのが原因
`/etc/sysctl.conf`を修正しサービスを再起動する。`/var/log/lsyncd/lsyncd.status`にinotifyが現在監視しているディレクトリ数が出力されています。

```bash
cp -ip /etc/sysctl.conf{,.org}
vi /etc/sysctl.conf
```

```:/etc/sysctl.conf
fs.inotify.max_user_watches = 819200
```

```bash
sysctl -p
```


## SELinux関連

CentOS 6系だとSELinux関連のセキュリティ保護が働いていたので、備忘のために。

### SELinuxの設定を変更
Red Hat Enterprise Linuxの製品マニュアル[第12章 rsync](https://access.redhat.com/site/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Managing_Confined_Services/chap-Managing_Confined_Services-rsync.html)を参考にした

1. ラベルの適用

    ```bash
chcon -R -t public_content_rw_t '/tmp/target'
```

2. Booleanの変更

    ```bash
setsebool -P allow_rsync_anon_write on
```


### rsync: Permission denied (13)
rsync によるNFSおよびCIFSのエクスポートを許可する（どちらか片方で良いかも…）

- SELinuxのBooleanを変更をする

    ```bash
setsebool -P rsync_export_all_ro on
```

- rsync によるCIFSのエクスポートを許可する

    ```bash
setsebool -P rsync_use_cifs on
```



# 参考
1. [lsyncd rsyndの設定方法 | ネットワークチェンジニアとして](http://changineer.info/server/centos_basic/lsyncd_rsynd.html)
2. [lsyncd+rsyncd でサーバー間の自動同期 | ベリーキュート Blog](http://www.very-cute.net/wp/lsyncd-rsyncd/)
3. [lsyncdで上限ファイル数を超えた時の対処策 - UNIX的なアレ](http://wadap.hatenablog.com/entry/20100123/1264211202)
4. [lsyncdでミラー元のファイル変更が検知できていなかった | Oreradio.memo](http://www.oreradio.com/2011/08/26.php)
grunt-contrib-watchのlivereloadでどんなHTMLにも対応する

メモ。

HTMLへのアクセスのとき、HTMLの末尾にLiveReload用のスクリプトを勝手に追加して返す。`</html>`とかの位置を無視するのでお行儀良くないけども、まあ開発用だから良いかなーと。

```js:Gruntfile.js
module.exports = function(grunt) {
	grunt.initConfig({
		express: {
			dev: {
				options: {
					script: 'server.js'
				}
			}
		},
		watch: {
			dev: {
				files: [ 'app/**/*' ],
				options: {
					livereload: true
				}
			}
		}
	});
};
```

```js:server.js
var express = require('express');
var app = express();
app.use(livereloadHtml(__dirname+'/../app/html'));
app.use(express.static(__dirname+'/../public'));
var port = 3000;
var host = '0.0.0.0';
app.listen(port, host, function() {
	console.log('http://' + host + ':' + port);
});

// --------------------------------

function livereloadHtml(dir) {
	var fs = require('fs');
	var lrScript = '<script type="text/javascript">document.write(\'<script src="\' + (location.protocol || \'http:\') + \'//\' + (location.hostname || \'localhost\') + \':35729/livereload.js?snipver=1" type="text/javascript"><\\/script>\')</script>';

	return function(req, res, next) {
		var path = req.url;
		if (path.charAt(path.length-1) === '/') {
			path += 'index.html';
		}

		if (path.lastIndexOf('.html') === path.length-5) {
			var fname = dir + path;
			var html = fs.readFileSync(fname, { encoding:'utf8' });
			html += lrScript;
			res.send(html);
			return;
		}

		next();
	};
}
```

……え、connect-livereloadなんてあるの？
plugmanコマンドでCordovaプラグインを導入

# plugmanコマンドでCordovaプラグインを導入

## plugmanコマンドのインストール

```
$ npm install plugman -g
```

cordovaコマンドを用いずにCordovaプラグインを導入するには、plugmanコマンドを使います。

plugmanコマンドは、Cordova開発チームが提供しているCordovaプラグインを管理するためのコマンドラインツールです。

cordovaコマンドは、内部でプラグインを管理するためにこのツールを利用していますので、cordovaコマンドを用いてプロジェクトを作成した場合には、このplugmanコマンドを使う必要はありません。

逆に、既存のプロジェクトに対してCordovaプラグインを導入するためには、plugmanコマンドを使います。

## plugmanコマンドのインストール

```
$ npm install plugman -g
```

インストールの確認

```
$ plugman -v
plugman version 0.10.1
```

## plugmanコマンドで既存のプロジェクトにプラグインを導入

plugmanコマンドを用いてCordovaプラグインを導入するには、プラグインのリポジトリのURL、プラットフォームとプロジェクトのディレクトリを指定します。

```
$ plugman install --platform android --project ./MyProject --plugin （プラグインのURL）
```
[SyncStitch]TimedCSP"Wait[t]"

Timed CSPで追加定義されるプロセスを自前で作る。

```scm:Wait.ss
; Definitions
(define-event ti)

; Wait
(define-process (Wait t)
  (if (> t 0)
	  (! ti (Wait (- t 1)))
	  (! ti SKIP)))

(define-process Test (Wait 5))
```
rubygems上にあるgemの全てのバージョンを調べた上で、versionを指定してinstallする

#Summary

- rubygems上を検索

`gem list #{gem} -ra`
 or 
`gem search #{gem} -a`

 -r : --remote remoteのgemレポジトリを検索する
 -a : --all 全てのバージョンを列挙する


- version指定


`gem install #{gem} --version "=3.0.0"` #3.0.0(のみ）を指定
`gem install #{gem} --version "~>3.0.0"` #3.0.x のlatestを検索してinstall
`gem install #{gem} --version "~>3.0"` #3.xのlatest


#Tips

 - #{gem}には正規表現が使える。
    - ☓　`gem search rails -r` #=> railsを含む色んなものが引っかかってしまう。
    - ◯ `gem search ^rails$ -r`  #=> railsのみ引っ掛けられる。

#Log

```shell-session
$ gem list ^rails$ -r -a

*** REMOTE GEMS ***

rails (4.1.0, 4.0.4, 4.0.3, 4.0.2, 4.0.1, 4.0.0, 3.2.17, 3.2.16, 3.2.15, 3.2.14, 3.2.13, 3.2.12, 3.2.11, 3.2.10, 3.2.9, 3.2.8, 3.2.7, 3.2.6, 3.2.5, 3.2.4, 3.2.3, 3.2.2, 3.2.1, 3.2.0, 3.1.12, 3.1.11, 3.1.10, 3.1.9, 3.1.8, 3.1.7, 3.1.6, 3.1.5, 3.1.4, 3.1.3, 3.1.2, 3.1.1, 3.1.0, 3.0.20, 3.0.19, 3.0.18, 3.0.17, 3.0.16, 3.0.15, 3.0.14, 3.0.13, 3.0.12, 3.0.11, 3.0.10, 3.0.9, 3.0.8, 3.0.7, 3.0.6, 3.0.5, 3.0.4, 3.0.3, 3.0.2, 3.0.1, 3.0.0, 2.3.18, 2.3.17, 2.3.16, 2.3.15, 2.3.14, 2.3.12, 2.3.11, 2.3.10, 2.3.9, 2.3.8, 2.3.7, 2.3.6, 2.3.5, 2.3.4, 2.3.3, 2.3.2, 2.2.3, 2.2.2, 2.1.2, 2.1.1, 2.1.0, 2.0.5, 2.0.4, 2.0.2, 2.0.1, 2.0.0, 1.2.6, 1.2.5, 1.2.4, 1.2.3, 1.2.2, 1.2.1, 1.2.0, 1.1.6, 1.1.5, 1.1.4, 1.1.3, 1.1.2, 1.1.1, 1.1.0, 1.0.0, 0.14.4, 0.14.3, 0.14.2, 0.14.1, 0.13.1, 0.13.0, 0.12.1, 0.12.0, 0.11.1, 0.11.0, 0.10.1, 0.10.0, 0.9.5, 0.9.4.1, 0.9.4, 0.9.3, 0.9.2, 0.9.1, 0.9.0, 0.8.5, 0.8.0)
```
GenymotionでUnable to connect to your virtual device!と言われた時の対処方法

### 環境等（2014/04/17時点）
Genymotion 2.2
VirtualBox 4.3.8（4.6が出てるっぽいけど、以前VBのバージョンを上げたらGenymotionが動かなくなったので上げていません）
Mac OS X 10.9.1

## はじめに
Genymotion、使ってますかー！
開発用PCの性能によってはx86エミュレータ（HAXM）でも遅い場合があります。そんな端末でもGenymotionはさくさく動くのでおすすめ。

さて、GenymotionでVirtual Deviceを新規追加した時など、`Unable to connect to your virtual device!` というメッセージボックスが表示されてVMが起動しない時があるので、その対処方法です。
Macでの設定例ですが、Windowsでもだいたい同じかと。

![スクリーンショット 2014-04-17 15.36.59.png](https://qiita-image-store.s3.amazonaws.com/0/40758/74e7f003-fe13-8882-b267-7ce50101741e.png)

```
Unable to connect to your virtual device! Genymotion will now stop. Check your VirtualBox network configuration.

For more information refer to: https://cloud.genymotion.com/page/faq/#collapse-nostart
```

## 対処

### VirtualBoxの設定画面で設定を変更

VMのネットワークアダプタ設定が正しく設定されていないため、GenymotionがVirtualBoxと通信できないことが原因のようです。

そこで、VMのネットワークアダプタを正しく設定し直します。

#### 1.ネットワークアダプタ設定確認
![スクリーンショット 2014-04-17 15.33.40.png](https://qiita-image-store.s3.amazonaws.com/0/40758/48f2909b-8ff7-b62c-fffa-0af02357d3f5.png)
VirtualBoxを起動し、左ペインの一覧で起動しないVMを選択、その状態で画面上部の黄色い歯車アイコンをクリックします。


![スクリーンショット 2014-04-17 15.33.06.png](https://qiita-image-store.s3.amazonaws.com/0/40758/94acf1a8-25f3-2fa4-02c0-490fe607859f.png)

ネットワークタブへ移動します。
この画像はVM追加直後ですが、アダプター１が「未割り当て」になっています。

#### 2.ネットワークアダプタ設定変更

「割り当て」欄、「名前」欄で正しいアダプタ設定を選択します。
「割り当て」は通常、`ホストオンリーアダプター` を選択します。
「名前」では、 `vboxnet0` のみが選択できる場合は、`vboxnet0` を選択します。複数の選択肢が表示された場合は、以下の手順で正しい選択肢を確認します。


![スクリーンシ![スクリーンショット 2014-04-17 16.09.29.png](https://qiita-image-store.s3.amazonaws.com/0/40758/b8b46d41-ff24-4b50-c978-530034d2c67d.png)
ョット 2014-04-17 15.34.34.png](https://qiita-image-store.s3.amazonaws.com/0/40758/e6e92a6d-720e-81a8-9b25-53865f31c861.png)

メニューバー > VirtualBox > 環境設定... を選択します。

![スクリーンショット 2014-04-17 15.58.41.png](https://qiita-image-store.s3.amazonaws.com/0/40758/d6948c20-63cf-89cc-2a90-2ef3b93a1786.png)

ネットワークタブ > ホストオンリーネットワーク を選択します。
右のドライバーアイコンをクリックするとアダプタ設定画面が開きます。（下図）

![スクリーンショット 2014-04-17 15.59.04.png](https://qiita-image-store.s3.amazonaws.com/0/40758/6c4fbd1e-1393-b9b8-1649-32063052f4f0.png)

IPv4アドレスが 192.168.56.1 になっているアダプタを探します。
ここでは vboxnet1 でした。VMのネットワークアダプタ設定画面へ戻り、`ホストオンリーアダプター` `vboxnet1`を選択します。

![スクリーンショット 2014-04-17 16.09.29.png](https://qiita-image-store.s3.amazonaws.com/0/40758/a346304c-c2df-f086-3699-adb63c52b1f5.png)

これで起動するはずです。
mergetoolでgitのdiffを見やすくする

コンフリクトしたときに git diff で差分を表示するとコードが混ざってしまって、よくわからない場合があります。
そういうときは、gitの `mergetool` コマンドが便利です。
`mergetool` コマンドは差分を様々なtoolで表示してくれます。

例えば、vimdiffを使う場合

```bash 
$ git mergetool -t vimdiff
```

どのようなtoolが使えるかは `—tool-help` オプションで確認できます。

```bash
$ git mergetool --tool-help
```
git add -A と git add . と git add -u の違い

結論から言えば、git add -A は git add . と git add -u を足したものです。


git add . はワーキングツリーに新規作成された、もしくは変更されたファイルをaddします。つまり、rmコマンドなどで削除されたファイルはaddされません。

git add -u は一つ前と最新のステージを比較して、変更があった部分のみをaddします。つまり、新しく作られたファイルはaddされません。

最初にも述べたように、git add -A は git add . と git add -u を足したものですから、新規作成、修正、削除といった全てのファイルをaddします。

分かり易い例がさきのリンクに記述されているので読んでみてください。
Terminal.app で、C-oが利かない時


Terminalで、Emacsを使っていたら、C-o(open-lineにバインドされている)が利かなくて、何でかとぐぐったら、解決方法が見つかったのでメモ。

## 解決方法

```sh:
$ stty discard undef
```

と打つ。.bash_profileにも書いておけば良い。
[SyncStitch]an example of deadlock

本日はTopSEセミナーにて、PATツールを使ってCSPを勉強しています。
ということで、PATのCSPモデルをSyncStitchのモデルにコンバート。

```scm:deadlock.ss
; Definitions
(define-event setorange)
(define-event setlemon)
(define-event orange)
(define-event lemon)
(define-event tomato)

;DrinkDispenser
(define-process DD
  (alt
	(! setorange O)
	(! setlemon L)))

(define-process O
  (alt
	(! orange O)
	(! setlemon L)
	(! setorange O)
	(! tomato STOP)))

(define-process L
  (alt 
	(! lemon L)
	(! setorange O)
	(! setlemon L)))
```
ubuntuでAllowOverrideを変更しても.htaccessが有効化しなかった時の対処法


###参考 
http://www.uetyi.mydns.jp/wordpress/apache-setting/entry-570.html

###大雑把にまとめ

.htaccessファイルを有効化する上でmod_rewrite.soモジュールが必要なので確認

```command
apache2ctl -M
```

mod_rewrite.soモジュールを有効化させるため`a2enmod`コマンドを使う

```command
/usr/sbin/a2enmod rewrite
```

apache2をrestartしてくださいとか言われたらok

httpd.conf(/etc/apahce2/sites-available/default)の設定を変更

```/etc/apache2/sites-available/default
<Directory /var/www/>
	Options Indexes FollowSymLinks MultiViews
#	AllowOverride None
	AllowOverride All
	Order allow,deny
	allow from all
</Directory>
```

もう一回apacheをrestartさせておしまい
Couchbaseのbucketのquotaサイズを変更するコマンドのメモ

Couchbaseでノードのメモリを増やした等で、合わせてbucketのquotaサイズを変更したい時は、
以下のコマンドを実行すると変更できます

```
/opt/couchbase/bin/couchbase-cli cluster-init -c 127.0.0.1 \
 -u Administrator \
 -p <PASSWORD> \
 --cluster-init-ramsize=16384

```
Chefをダウングレードする（CentOS）

# Goal

```
* 2014/4上旬ごろから、Chefをデフォルトのコマンドでインストールすると、knife configureが動かないバグがあり、修正されていない
* 一度インストールしてしまったchefのバージョンを下げる対応を実行する
```

# Preparation

```bash
uname -a
  # Linux *** 2.6.32-431.3.1.el6.x86_64 #1 SMP Fri Jan 3 21:39:27 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

cat /etc/issue
  # CentOS release 6.5 (Final)
  # Kernel \r on an \m

```

# Problem

```bash
[root]

curl -L https://www.opscode.com/chef/install.sh | bash
  # gem install knife-soloが別途必要だけど省略
chef-solo --version
  # Chef: 11.12.2
knife --version
  # Chef: 11.12.2

[youruser]

## 
## knife configureを実行してインタラクティブ入力を進めようとするとプラグインがないというエラーで次に進めない
## 

knife configure
  # WARNING: No knife configuration file found
  # Where should I put the config file? [/home/nomaduser/.chef/knife.rb]
  # ERROR: Ohai::Exceptions::DependencyNotFound: Can not find a plugin for dependency os

```

# Fix

* http://www.getchef.com/chef/install/

```
* chefのバージョンを11.10系に戻す
* 上のURLから、利用OSなどを選択し、利用可能バージョンだけ確認する
* Enterprise Linuxだと、11.10.4-1が利用可能
```

```bash
[root]

curl -L https://www.opscode.com/chef/install.sh | bash -s -- -v 11.10.4-1
  # versionを指定して再度installコマンドを実行
```

## Check

```bash
[youruser]

chef-solo --version
  # Chef: 11.10.4
knife --version
  # Chef: 11.10.4

knife configure
  # Interactive settings
cat ~/.chef/knife.rb
  # Check knife configure succeeded
```

# References

* http://qiita.com/sakatuba@github/items/1548818b02735b2047ad
* http://ionrails.com/2013/04/19/downgrading-chef-client/
paiza POH ec-campaign #paizahack_01 [JavaScript]

|問題|https://paiza.jp/poh/ec-campaign|
|:--|:--|
|タイム一覧/C++|http://qiita.com/cielavenir/items/a61cfe8390eb16866ae5|
|Python/Ruby(1)|http://qiita.com/cielavenir/items/b10ff4d201150f525062|
|C#/Java/Python/Ruby|http://qiita.com/cielavenir/items/d89e85f069cf570e6786|
|Perl/PHP|http://qiita.com/cielavenir/items/1a650a4c41d7bdd31392|
|JavaScript|http://qiita.com/cielavenir/items/a85b985888fdc15c52b7|
|Go/CoffeeScript/Scala/R/Bash|http://qiita.com/cielavenir/items/79016a0afd30470f440d|
|VB/F#/D|http://qiita.com/cielavenir/items/cb6094bab56253de992c|

JavaScript (0.34s)

```js
#!/usr/bin/node
(function(){
	var T=[];
	var stdin = process.openStdin();
	stdin.setEncoding('utf8');

array_binarysearch=function(needle,haystack,size){
    var high = size-1;
    var low = 0;
    var ret = size;
    while( low <= high ){
        var probe = (high + low) / 2^0;
        var comparison = haystack[probe]-needle;
        if( comparison <= 0 ){
            low = probe+1;
        }else{
			ret=high;
            high = probe-1;
        }
    }
	return ret;
}

	var input_fragment="";
	stdin.on('data', function(input) {
		var i=0,len,ref,x=[];
		ref=(input_fragment+input).split("\n");
		input_fragment=ref.pop();
		for(len=ref.length;i<len;i++){
    		if(ref[i]=='')continue;
    		x.push(ref[i]);
		}
		T=T.concat(x);
	});

	stdin.on('end', function(z) {
		if(input_fragment){
			var i=0,len,ref,x=[];
			ref=(input_fragment+"\n").split("\n");
			input_fragment=ref.pop();
			for(len=ref.length;i<len;i++){
    			if(ref[i]=='')continue;
    			x.push(ref[i]);
			}
			T=T.concat(x);
		}

		var arg=T[0].split(' ').map(Number);
		var n=arg[0];
		var d=arg[1];
		var v=T.slice(1,1+n).map(Number).sort(function(a,b){return a-b;});

		for(var i=0;i<d;i++){
			var m=Number(T[1+n+i]);
			var idx=array_binarysearch(m-v[0],v,n);
			var r=0;
			var j=0;
			for(var k=idx-1;j<k&&v[j]+v[j+1]<=m;j++){
				for(;v[j]+v[k]>m;)k--;
				if(r<v[j]+v[k]){
					r=v[j]+v[k];
					if(r==m)break;
				}
			}
			console.log(r);
		}
	});
})();
```
gemsetを維持しつつ、rvm上で管理しているrubyのpatch levelを最新にする 

#summary
`rvm upgrade`を使う。

#step
1. `rvm get stable` rvm最新版を取ってくる 
2. `rvm reload` リロード。(* 上記のコマンドの末尾に、自動で行われるかもだが念のため。)
3. `rvm upgrade #{old} #{new}` 
 - 例:`rvm upgrade 1.9.2-pxxx 1.9.2`とか。
4. 色々聞かれる。そのまま移行したいだけなら全部Yでよい
```shell-session
Are you sure you wish to upgrade from ruby-2.0.0-p195 to ruby-2.0.0-p247? (Y/n): Y
Are you sure you wish to MOVE gems from ruby-2.0.0-p195 to ruby-2.0.0-p247?
This will overwrite existing gems in ruby-2.0.0-p247 and remove them from ruby-2.0.0-p195 (Y/n): Y
Do you wish to move over aliases? (Y/n): Y
Do you wish to move over wrappers? (Y/n): Y
Do you also wish to completely remove ruby-2.0.0-p195 (inc. archive)? (Y/n): Y
```

#background
- `rvm update`ってやろうとしてもできなかったので。
- メモるまでもなかった感

#references
- http://stackoverflow.com/questions/4574318/how-do-i-upgrade-my-ruby-1-9-2-p0-to-the-latest-patch-level-using-rvm
paiza POH paizen #paizahack_02 [JavaScript]

|問題|https://paiza.jp/poh/paizen|
|:--|:--|
|タイム一覧/Ruby/C/C++/C#/Java|http://qiita.com/cielavenir/items/17f66daa2be639fd74f3|
|Perl/PHP/Python|http://qiita.com/cielavenir/items/5b57808a28a8b4c5c7b2|
|JavaScript|http://qiita.com/cielavenir/items/9dab2bfbcfa0047b345f|
|CoffeeScript/Go/Scala/VB/F#|http://qiita.com/cielavenir/items/32591dd03376ba534d1e|

ある操作を行うことでJavaScriptによる提出が可能になります。
が、メールは来ましたがWebは500になってしまいました。
ですので、サーバーに迷惑かかるかもなんで真似しないで下さい…。

[追記・訂正]
入力が巨大なため、JavaScriptは入力に注意が必要なだけのようです。

JavaScript (0.37/0.33)

```js
#!/usr/bin/node
(function(){
	var T=[];
	var stdin = process.openStdin();
	stdin.setEncoding('utf8');

	var input_fragment="";
	stdin.on('data', function(input) {
		var i=0,len,ref,x=[];
		ref=(input_fragment+input).split("\n");
		input_fragment=ref.pop();
		for(len=ref.length;i<len;i++){
    		if(ref[i]=='')continue;
    		x.push(ref[i]);
		}
		T=T.concat(x);
	});

	stdin.on('end', function(z) {
		if(input_fragment){
			var i=0,len,ref,x=[];
			ref=(input_fragment+"\n").split("\n");
			input_fragment=ref.pop();
			for(len=ref.length;i<len;i++){
    			if(ref[i]=='')continue;
    			x.push(ref[i]);
			}
			T=T.concat(x);
		}

		var arg=T[0].split(' ').map(Number);
		var h=arg[0];
		var w=arg[1];
		var a=Array(h);
		for(var i=0;i<h;i++){
			var line=T[1+i];
			a[i]=Array(w);
			for(var j=0;j<w;j++){
				a[i][j]=Array(h);
				a[i][j][0]=line[j]^1;
			}
		}
		var accum=Array(h);
		for(var i=0;i<h;i++){
			accum[i]=Array(w+1);
			for(var j=0;j<=w;j++)accum[i][j]=0;
		}
		for(var i=0;i<h;i++){
			accum[0][a[i][0][0]]++;
			for(var j=1;j<w;j++){
				if(a[i][j][0]){
					a[i][j][0]+=a[i][j-1][0];
					accum[0][a[i][j][0]]++;
				}
			}
		}
		for(var i=1;i<h;i++)for(var j=0;j<w;j++)for(var k=1;k<=i;k++){
			a[i][j][k]=a[i-1][j][k-1];
			if(a[i][j][k]>a[i][j][k-1]){a[i][j][k]=a[i][j][k-1];}
			if(!a[i][j][k])break;
			accum[k][a[i][j][k]]++;
		}
		for(var i=0;i<h;i++)for(var j=w-1;j>=0;j--)accum[i][j]+=accum[i][j+1];
		var k=Number(T[1+h]);
		for(var i=0;i<k;i++){
			arg=T[1+h+1+i].split(' ').map(Number);
			var s=arg[0];
			var t=arg[1];
			console.log(s<=h&&t<=w?accum[s-1][t]:0);
		}
	});
})();
```
EC2でFTPサーバを起動する（セキュリティグループ設定のコツ）

EC2上にFTPサーバを起動する際のポート空けとかの設定。

# パッシブモードOFFだけの対応でよければ簡単
セキュリティグループでTCPの`20-21`を開けるだけでOK

# パッシブモードONの対応方法がちょっと面倒
セキュリティグループでTCPの`60000-60100`を追加で開ける。
更に proftpd.conf に以下の設定も追加する。

```text:proftpd.conf
MasqueradeAddress <Public IP or Hostname>
PassivePorts      60000 60100
```

## 説明
- `60000-60100`ポートはPassive Mode Onの接続で使うことにするポート。
- `PassivePorts`ではパッシブモード用のポート範囲を限定している。
- `MasqueradeAddress`でEC2インスタンスに付いている`PublicIP`の指定もしてやる必要がある。これをしておかないとパッシブの接続先として10.0.2.32とかのプライベートアドレスを伝えてしまうから繋がらない。
awakeFromNibとinitWithFrameとinitWithCoderの使い方


### initWithFrameとinitWithCoderの違い
* initWithFrameは、code上でobjectを作る時に呼ばれる
* initWithCoderは、interface builder(storyboardやnibファイルなど)からobjectを作るときに呼ばれる

### initWithCoderとawakeFromNibの違い
* initWithCoderでは、IBOutletやIBActionはロードされていない、awakeFromNibはロードされた後に呼び出される

### 使い方
* interface builder(storyboard)使ってて、なにも考えず使いたいならawakeFromNibを使うといいのでは
* initWithFrameとinitWithCorder両方呼び出す可能性があるviewの場合は、initWithCorderで書くこととawakeFromNibで書く内容を分けて書く必要がある。

```

- (void)awakeFromNib
{
    [super awakeFromNib];
}
```

```
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setup];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if ((self = [super initWithCoder:aDecoder])) {
        [self setup];
    }
    return self;
}


- (void)setup
{
}
```

### メソッドの詳細
* initWithFrameはUIView、クラス
    * https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html
* initWithCoderはNSCoding、プロトコル
    * https://developer.apple.com/library/mac/documentation/cocoa/reference/foundation/protocols/nscoding_protocol/reference/reference.html
* awakeFromNibはNSNibAwaking、プロトコル
    * 詳しくawakeFromNibが呼ばれる流れが説明されている
    * https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/Protocols/NSNibAwaking_Protocol/Reference/Reference.html

### 参考
* initWithCoderとinitWithNibName:bundle:とawakeFromNibの違いについて http://www.quora.com/Cocoa-API/What-is-the-difference-between-initWithCoder-initWithNibName-and-awakeFromNib
PHP 静的メソッドのオーバーライドと遅延静的束縛

PHPを再勉強中。

PHPでは親クラスの静的メソッドを子クラスでオーバーライドすることができます。
でもちょっと普通に期待する動作とは違うので注意が必要みたい。

### サンプル

```php:test1.php
<?php

# 親クラス
class MyParent
{
    static function foo()
    {
        return "Parent";
    }
    
    static function bar()
    {
        echo self::foo() . PHP_EOL;
    }
}

# 子クラス
class MyChild extends  MyParent
{
    # 親クラスのメソッドをオーバーライド
    static function foo()
    {
        return "Child";
    }
}

MyParent::bar();    # <= "Parent"と出力してほしい
MyChild::bar();     # <= "Child"と出力してほしい

```

親クラスの静的メソッド`foo()`を子クラスでオーバーライドしています。`foo()`は親クラスで定義された静的メソッド`bar()`から呼ばれます。静的でない通常のメソッドであれば、子クラスから`bar()`を呼び出せば、`bar()`からはオーバーライドされた子クラスの`foo()`が仮想メソッドとして呼ばれます。しかし静的メソッドに対して同様のことを実行すると、期待はずれの結果になります。

### 実行結果

> $ php test1.php
 Parent
 Parent 

子クラスでオーバーライドしたfoo()が呼ばれず、親クラスのfoo()が呼ばれています。

子クラスから親クラスの静的メソッドを呼び出した場合、そのメソッドは親クラスのコンテキスト（selfが親クラスを指す）で実行されてしまうようです。そのため、子クラスから呼び出した親クラスの静的メソッド内で子クラスでオーバーライドされたメソッドを呼び出そうとしても、仮想メソッドとしては機能せず親クラスで定義されたものが呼ばれる結果になります。

PHP(5.3移行）にはこれを回避するために、遅延静的束縛という仕組みが用意されています。

参考 ： [遅延静的束縛 (Late Static Bindings) ](http://www.php.net/manual/ja/language.oop5.late-static-bindings.php)

上のプログラムを遅延静的束縛を利用したものに書き換えてみます。

```php:test2.php
<?php

# 親クラス
class MyParent
{
    static function foo()
    {
        return "Parent";
    }
    
    static function bar()
    {
        echo static::foo() . PHP_EOL;
    }
}

# 子クラス
class MyChild extends  MyParent
{
    # 親クラスのメソッドをオーバーライド
    static function foo()
    {
        return "Child";
    }
}

MyParent::bar();    # <= "Parent"と出力してほしい
MyChild::bar();     # <= "Child"と出力してほしい
```

`bar()`内で`foo()`を呼び出すさい、静的メンバを参照するさいの`self`を`static`と書き換えただけです。（この`self`や`static`というのは定数？　構文？よく判らない）
`static::hogehoge`とすると定義されたクラスではなく呼び出されたクラスのコンテキストで`hogehoge`が探索されるようになります。これを遅延静的束縛という（らしいです）。

### 実行結果

> $ php test2.php
 Parent
 Child

期待通りの結果になりました。
phantomJS2 build on linux

# deprecated
see [PhantomJS 2 · ariya/phantomjs Wiki](https://github.com/ariya/phantomjs/wiki/PhantomJS-2)

# background
込み入ったバグが2で解決してたので2を使いたい。おまけで2にするとweb fontsがサポートされる(1.xはweb fontsサポートしないと公言されてる)

# environment
- requires 8G memory. 4G is not enough.
- CentOS

# steps
[PhantomJS 2 (Qt5) - Google Groups](https://groups.google.com/forum/#!msg/phantomjs/iYyH6hF_xoQ/LrjmP-YwKxAJ)

> Unfortunately for now if someone wants to experiment building it, then 
> you have to collect all the info (bits and pieces) from this 
> mailing-list. 


## dependencies
-develがついてないもので不必要な物もあるかもしれませんが時間がもったいないので検証してません。

```
sudo yum -y install libicu
sudo yum -y install gdb
sudo yum -y install libicu-devel
sudo yum -y install gperf
sudo yum -y install sqlite-devel
sudo yum -y install freetype
sudo yum -y install fontconfig
sudo yum -y install freetype-devel
sudo yum -y install fontconfig-devel
sudo yum -y install flex

sudo yum -y install vlgothic-fonts
```

[phantomjs screenshot font missing, boxes rendered instead - Stack Overflow](http://stackoverflow.com/questions/15029002/phantomjs-screenshot-font-missing-boxes-rendered-instead)



## build

```
git clone https://github.com/KDAB/phantomjs.git
cd phantomjs
git checkout bf655c3c9b216d19d6f292f8526bf3c66b533e4f
git submodule init
git submodule update

sh build.sh --confirm --jobs 10
```

`bin/phantomjs` が生成されます。
MavericksでCommand Line Toolsのインストール方法

MacのOSをMavericksにしたらMacportsが使えなくなってた。

Macports使ったらこんな警告でた。

```
Warning: port definitions are more than two weeks old, consider using selfupdate
```

selfupdate時にもこんなエラー。

```
DEBUG: Error installing new MacPorts base: command execution failed
    while executing
"macports::selfupdate [array get global_options] base_updated"
Error: /opt/local/bin/port: port selfupdate failed: Error installing new MacPorts base: command execution failed
```

Command Line Toolsを入れ直さないといけないみたい。
Xcodeからじゃ駄目みたいでターミナルから。

以下のコマンド入力してダイアログ出現させてインストール。

```
$ xcode-select --install
```

もろもろアップデート。

```
$ sudo port -d selfupdate
$ sudo port upgrade outdated
$ sudo port upgrade installed
```

これでなんとかなった。
JSON仕様でのスラッシュのエスケープ

[JSON 仕様](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf)で文字列リテラル中のエスケープシーケンスに [ECMAScript仕様](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf)に含まれていないスラッシュのエスケープ \/ が含まれているのはどういう意図なんだろう。
meta-tagsで悩んでたこと。


## 問題

[meta-tags](https://github.com/kpumuk/meta-tags)を使ってOpenGraphのtypeをvideoとして設定しようとしたときに、

```html:
<meta property="og:type" content="video">
<meta property="og:video" content="http://www.youtube.com/v/2ZBtPf7FOoM?version=3&amp;autohide=1">
<meta property="og:video:type" content="application/x-shockwave-flash">
<meta property="og:video:width" content="480">
<meta property="og:video:height" content="360">

```


``og:video``で指定する項目が複数あって、それをmeta-tagsを使って表現するにはどうしたらいいのか迷っていました。


## 解決策

meta-tagsの[Array](https://github.com/kpumuk/meta-tags#arrays)と[Hash](https://github.com/kpumuk/meta-tags#hashes)を組み合わせて

```ruby:
set_meta_tags og: {
      :type     => 'video',
      :video => ["http://www.youtube.com/v/2ZBtPf7FOoM?version=3&amp;autohide=1",{
        :type => 'application/x-shockwave-flash',
        :width => '480',
        :height => '360'
      }]
    }

```

と、``:video``の部分をArrayにして、``og:video``のcontentにあたる部分と、``og:video:xxx``にあたる部分はHashの形で渡すようにすると上手くいきました。
公開中アプリの Default Language を日本語→英語にしてみた。


# 前置き

* Default Language を Japanese で申請したアプリがあった。
	* もちろん、翻訳言語も Japanese のみ。
* オレ **「どーせ英語対応とかしねーだろ」**
* (数週間後………)
* ディレクター **「英語対応するから！」**
* オレ **「なん………だと…っ！？」**
* てことは非日本語圏のユーザは最低でも英語で表示されてくれなきゃ困るよね。うん。
* でも、「一回日本語で出したアプリの App Store での表示言語を英語にするの大変」って話を聞いたことあるよね。
* これは…戦いの火ぶたが切って落とされるのか…っ！！

# 先に結論

* まぁ、戦いの火ぶたは切って落とされませんでした。
* 拍子抜けするほど簡単に、非日本語圏に於ける表示言語を英語に切り替えられましたとさ。

# ちょっと前まで

* いつアップデートされたのかは調べてないが、少なくとも去年 (2013年) の前半辺りまでは、「一回設定した Default Language は変更出来ない」というのが通説だった。
* なので、一回 Default Language を Japanese で登録してしまったアプリを非日本語圏で英語表示にするためには、 **Japan 以外の全ストア分の Description 等々を英語で入力する** という非常に泥臭いコトをしなければならなかった。
	* 基本的にコピペで済むとはいえ、スクショのアップロードとかダルい作業を手動でポチポチしたりとか、心を無にしないとやってられない作業ですね。ええ。

# ところが最近は

* **Default Language の変更が出来るようになっている**
	* まぁ、初回公開時に Japanese しか登録していない場合は、勿論プルダウンには Japanese しか表示されないけどね。
* しかも申請不要。

# てことで手順

1.	該当アプリの詳細ページに入り、 App Information の横にある Edit ボタンを押下<br />
	![ScreenShot 01](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140416-01/iTunes_Connect/01.png)
1.	Default Language のプルダウンをプルッとダウンしてみると…？<br />
	![ScreenShot 02](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140416-01/iTunes_Connect/02.png)
1.	English ｷﾀ━━━━━(ﾟ∀ﾟ)━━━━━!!!!<br />
	てことで、選択して Save ボタン押下
	![ScreenShot 03](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140416-01/iTunes_Connect/03.png)
1.	はい、見事に変更されてます。めでたしめでたし。<br />
	![ScreenShot 04](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140416-01/iTunes_Connect/04.png)


# 注意点

## Ready for Sale なバージョンの言語が大事

![ScreenShot 05](http://d4dqxb4bcxr8q.cloudfront.net/img/ss/20140416-01/iTunes_Connect/05.png)

ちゃんと英語で Description とか入れてるのに、Japanese しか出てこないお…(´･ω･`) って人は、 **Current Version のストア掲載テキストに English があるかどうか** をちゃんとチェックしましょう。

上のスクショのように、翻訳言語の追加をしたバージョンのステータスが *Prepare for Upload* やら *Waiting for Review* やら *In Review* やらのように、ストアには公開されていない状態の場合、 **そのバージョンが *Ready for Sale* になるまで** は Default Language の変更はできません。(まぁ、そりゃそーだって話だが。)
Javaの検査例外の存在意義

あらゆるところで否定され続けているJavaの検査例外だが、なぜこのような仕組みが必要なのか説明しようと思う。

この投稿は [golang で複数のエラーをハンドリングする方法](http://mattn.kaoriya.net/software/lang/go/20140416212413.htm) という記事を見かけたので書いた。

いつも通り「コメントは大歓迎」です。

# 検査例外の話

検査例外の目的は **静的な分岐の強制** である。

例えばこのようなコードがあったとする。

```rb
f = File.open("dummy.txt")
f.write "Hello"
f.close
```

このようなAPIではプログラマが「ファイルを開けなかったときの処理を忘れる」ことを防ぐことができない。

一方、検査例外を使えば「開けなかったときの処理」をプログラマが忘れることができない。
忘れた場合はコンパイルエラーになり、そもそも実行できないからである。
（簡単のためRuby風なAPIにしている）

```java
try {
  File f = File.open("dummy.txt");
  f.write("Hello");
  f.close();
} catch (IOException e) { // catchしない場合コンパイルエラー
  System.out.println("ファイルを開けませんでした。");
}
```

# Maybe/Eitherの話

検査例外というのは、関数型言語における`Maybe`や`Either`の一種だと考えるのが良い。
型システムを利用して、失敗したときの処理を書き忘れるのを防ぐのが目的である。

Scala風なプログラムで、分岐を強制している例を挙げる。

```scala
val result = File.open("dummy.txt")
result match {
  case Success(f) => f.write("Hello")
  case Fail       => System.out.println("ファイルを開けませんでした。")
}
```

このように分岐後でしか `f` に触れることができず、分岐を強制させることができる。

# Kotlinの話

Kotlinでは「`null`になる可能性がある変数」かそうでないかを明確に区別する。 [参考](http://confluence.jetbrains.com/display/Kotlin/Null-safety)
最近Facebookが発表したHackにも同様の機能があるようだ。

```kotlin
val file : File? = File.open("dummy.txt") // 型は明示的に書いているだけで省略可能
file.write("Hello") // コンパイルエラー

// OKな例
val file : File? = File.open("dummy.txt")
if (file != null) {
  file.write("Hello") // ここのfileの型は<File?>ではなく<File>
} else {
  print("ファイルを開けませんでした。");
}
```

通常の言語において、変数 `file` の型はずっと変わらないが、この言語ではifチェックの前後で型が異なるように振る舞う。

# Goの話

（断わっておくが、Goのことはよく知らないので、間違いがあればコメントがほしい）

```go
if file, err := file_open("dummy.txt"); err != nil {
  print("ファイルを開けませんでした。");
} else {
  file.write("Hello");
}

// 無視する例
file, _ := file_open("dummy.txt");
file.write("Hello");
```

Goは失敗時に二値を返すという方針のようだ。
値が二つある以上、「分岐を忘れる」ことは少なくなるが、強制はできないだろう。
また、正常系でも異常系でも`file`, `err`に触れるのも問題である。

# C#の話

これはC#でも同様である。C#では例外以外には`TryXxx`を使うのが推奨されている。

```csharp
File file;
if (File.TryOpen("dummy.txt", out file)) {
  file.Write("Hello");
} else {
  Console.WriteLine("ファイルを開けませんでした。");
}

// 無視する例
File file;
File.TryOpen("dummy.txt", out file);
file.Write("Hello");
```

関数は `bool` を返すため、分岐を忘れることは少なくなるが、強制できるわけではない。

# まとめ

検査例外はそんなに悪い機能じゃない
コンパイルエラーを有効に使おう
Windows バッチファイル チートシート

それなりに多用する Windows `.bat` ファイルのチートシート。

# 乱数

```bat
REM RANDOMU NUMBER
SET _NUM_=%RANDOM%
```

# 日付

```bat
REM YYYY/MM/DD
SET _DATE_=%DATE%

REM YYYY-MM-DD
SET _DATE_=%DATE:/=-%

REM YYYYMMDD
SET _DATE_=%DATE:/=%

REM YYYY/MM
SET _DATE_=%DATE:~1,7%

REM YYYY
SET _DATE_=%DATE:~0,4%

REM YYYYMM
SET _DATE_=%DATE:~0,7%

REM MM/DD
SET _DATE_=%DATE:~5,5%

REM HH:MI:SS.MIS
SET _TIME_=%TIME%

REM HHMISS
SET _TIME_=%TIME::=%
SET _TIME_=%_TIME_:~0,6%

REM HH:MI:SS
SET _TIME_=%TIME:~0,8%

REM HH:MI
SET _TIME_=%TIME:~0,5%

REM HOUR (HH)
SET _TIME_=%TIME:~0,2%

REM MIN (MI)
SET _TIME_=%TIME:~3,2%

REM SEC (SS)
SET _TIME_=%TIME:~6,2%

```

# PC情報関連

```bat
REM current directory
ECHO %CD%

REM Control PC Domain
ECHO  %USERDOMAIN%

REM Control PC User
ECHO  %USERNAME%

REM Control PC User Home
ECHO %USERPROFILE%
ECHO %HOMEPATH% 

REM SYSTEM DRIVE
ECHO %SystemDrive%

REM HOME DRIVE
ECHO %HOMEDRIVE%

REM Program Files
ECHO %ProgramFiles%
ECHO %ProgramFiles(x86)%

```

# ファイル操作
* 重に大容量ファイルアップロード

```bat:要特権
REM fsutil file createnew <filename.ext> <file.size>

REM create 0 Byte file
fsutil file createnew filename.ext 0

REM create 1 KByte file
fsutil file createnew filename.ext 1024

REM create 1 MByte file
fsutil file createnew filename.ext 1048576

REM create 1 GByte file
fsutil file createnew filename.ext 1073741824

REM create 10 GByte file
fsutil file createnew filename.ext 10737418240

REM hard link
REM fsutil hardlink create <source.file> <hardcopy.file>
fsutil hardlink create source.file hardcopy.file

```

# ドライブの確認

```bat:要特権
REM HDD -> 固定
REM CD(DVD) -> CD-ROM
REM fsutil fsinfo drivetype <DRIVENAME>
fsutil fsinfo drivetype C:
REM C: - 固定ドライブ

fsutil fsinfo drivetype d:
REM D: - CD-ROM ドライブ

REM Dirve Info
REM fsutil volume diskfree <DRIVENAME>
fsutil volume diskfree c:
REM 空きバイト総数　　　　　　: xxxxxxxxxxxxxxx
REM バイト総数　　　　　　　　: xxxxxxxxxxxxxxx
REM 利用可能な空きバイト総数　: xxxxxxxxxxxxxxx

```
WIP Pull Request でチェックボックスを表示する


タイトルに [WIP] と書けばリストが自動的にチェックボックスになる訳ではなく，GitHub Flavored Markdown で定義されている[タスクリスト](https://github.com/blog/1375%0A-task-lists-in-gfm-issues-pulls-comments)を使う．

    - [x] Completed Task
    - [ ] Incomplete Task 1
    - [ ] Incomplete Task 2
AndroidのJUnitを利用したユニットテストでjava.lang.IllegalAccessError

# ユニットテストを実行しようとと思ったら

コンソール画面に

```

Test run failed: Instrumentation run failed due to 'java.lang.IllegalAccessError'


```

と表示されてテストが実行されなかった．

# ライブラリプロジェクトの指定がダメっぽい

## はじめはこれで指定した

![test1.png](https://qiita-image-store.s3.amazonaws.com/0/20506/20278e85-9640-c5bc-eb01-0b42351ec307.png)

これだと実行時にタイトルのエラーが発生する．

## ビルドパス画面のプロジェクト追加でいけた

![test2.png](https://qiita-image-store.s3.amazonaws.com/0/20506/095e8d11-f594-bc5c-83fb-7284e5908e85.png)

なんでコレじゃ無いとダメなんだろ…？
Espresso利用のため，Instrumentation runnerを GoogleInstrumentationTestRunner にしてるから？

```text:追記

android.test.InstrumentationTestRunner でも発生しました

```

# その他

ビルドパスの追加でテストを実行すると，Could not find **Lib.apk! っていうエラーがコンソールに表示される．
けど，まぁ単なるライブラリなのでapkが有るわけ無く，問題ない．
EC2にリバースプロキシを使ってjenkinsを構築する

EC2上にjenkinsを一から構築したのでその手順

* http://ec2-xxx.compute.amazonaws.com/jenkins/ でアクセスできるようになる
* OSはAmazon Linuxを選択

----
## jnekinsインストール
* yumでのインストールは以前書いた記事参照
 * http://qiita.com/kmats@github/items/1e2a14a95699cc95ad07
* 今回は /jenkinsでアクセスしたいので以下の変更も加える
 * http://d.hatena.ne.jp/hiranasu/20110507/1304781709

```
$ sudo cp /etc/sysconfig/jenkins{,.org}
$ sudo vi /etc/sysconfig/jenkins
```

```
$ sudo diff /etc/sysconfig/jenkins{.org,}
133c133
< JENKINS_ARGS=""
---
> JENKINS_ARGS="--prefix=/jenkins"
```

## httpdインストール
```
$ sudo yum install httpd -y
```

* 80番ポートでリクエストを受けたいので、:80/jenkinsを :8080/jenkins にプロキシするようにする
 * https://wiki.jenkins-ci.org/display/JENKINS/Running+Jenkins+behind+Apache

```
$ sudo vi /etc/httpd/conf.d/jenkins.conf
```

```
ProxyPass        /jenkins http://localhost:8080/jenkins nocanon
ProxyPassReverse /jenkins http://localhost:8080/jenkins
ProxyRequests    off
AllowEncodedSlashes NoDecode

<Proxy http://localhost:8080/jenkins*>
  Order deny,allow
  Allow from all
</Proxy>
```

## 起動
```
$ sudo /etc/init.d/jenkins start
$ sudo /etc/init.d/httpd start
```

自動起動

```
$ sudo chkconfig jenkins on
$ sudo chkconfig httpd on
```
Unix user と異なる user で git push する


端末で使用している user 名が GitHub の user 名と異なる場合，適切な秘密鍵を持っていたとしても Push 時に以下のようなエラーが表示される．

    $ git push origin develop
    Error: Permission to github-user-name/repo denied to unix-user-name.

明示的に user を指定する場合は，.ssh/config に Host を設定し，IdentitiesOnly を yes にする．

    $ vi ~/.ssh/config
    Host github.com
      HostName github.com
      User github-user-name
      IdentityFile ~/.ssh/id_rsa
      IdentitiesOnly yes
vagrantを1.5.3にアップグレードしたら動かなくなった


MacのvagrantでDockerを試したくなったので1.3.5から1.5.3にアップデートしたら次のようなメッセージが出て何にもできなくなった。

```
Vagrant failed to initialize at a very early stage:

The plugins failed to load properly. The error message given is shown below.

cannot load such file -- /Applications/Vagrant/embedded/gems/gems/vagrant-1.5.3/plugins/providers/virtualbox/action/share_folders
```

削除してから新規インストールしても、1.5.2などにしてもダメなのでいろいろ試してて、次のコマンドでプラグインをアップデートしたら動くようになった。

```
$ vagrant plugin update
Updating installed plugins...
Updated 'vagrant-omnibus' to version '1.3.1'!
Updated 'vagrant-windows' to version '1.6.0'!
```

そういえば、EC2とかWindowsとかをいろいろ試してた時にそんなプラグイン入れてたなと思いだした。
vagrantをバージョンアップしたら```vagrant plugin update```は必須くさいですね。
Python3 で Protocol Buffers のデータを読み出す

今日はいつもの統計や機械学習の話から急に趣向が変わって Python + Protocol Buffers の話です。

[Protocol Buffers](http://ja.wikipedia.org/wiki/Protocol_Buffers) は便利なシリアライゼーションフォーマットです。これを Python 3 で使おうとすると執筆時点では GitHub の最新のコードを使う必要があります。

[Python 2 のサポートが 2020 年まで伸びた](http://hg.python.org/peps/rev/76d43e52d978)ニュースは耳に新しく 2 系を使えば良いと言えばそうなのですが最新技術を追うエンジニアとしては Python 3.x 系以外は絶対に書きたくないという強い意志があるケースも多いかと思います。

## 環境構築

環境としては次のように GitHub から Protocol Buffers をクローンしてビルド、さらに Python でセットアップします。

```bash
git clone git://github.com/openx/python3-protobuf.git
cd python3-protobuf
./autogen.sh
./configure --prefix=$PREFIX # protobuf インストール先を指定
make
make check
sudo make install

cd python # Python バインディング
python setup.py build
python setup.py test
sudo python setup.py install
```

これで Python3 から Protocol Buffers を利用できるようになりました。簡単ですね。

## ファイル構造の定義と変換

Protocol Buffers では .proto という名前のファイルで構造を定義します。 JSON で言うキーは数値に変換されよりデータサイズが小さい形でやりとり可能であると言われています。

```bash
protoc -I=. --python_out=. schema.prot
```

schemaXX.py といったファイルが生成されるのでこれを利用したいスクリプトから import すれば OK です。

## Python からの利用

実際にデータを読み出すイメージとしてはこのようになります。

```py3
import schema_pb2 # 生成した Python ファイルのインポート
import base64
import json

event = schema_pb2.nb_event()
event.ParseFromString(base64.b64decode(value))
ts = event.timestamp

# 試しに JSON に変換してみる
obj = {}
obj['event_type'] = event.type
obj['seq'] = event.seq
obj['timestamp'] = event.timestamp
obj['op'] = event.op

# 一旦ディクショナリに格納したデータを JSON へ変換
json_dump = json.dumps(obj, ensure_ascii=False)
print(json_dump)
```
Dockerでイメージにファイルを追加する


## docker build

これが一番正当な方法。Dockerfileを用意して、

```
ADD <src> <dest>
```

と書いて`docker build`すれば追加される。

ベースイメージを作るのはこれで問題ないけど、ベースイメージから派生してちょっとだけ違うイメージつくりたい場合とかにいちいちDockerfile用意するの面倒なので他に方法がないか調べてみた。

## docker run + 標準入力

`docker run`で標準入力経由で追加する方法がある。

```
$ cat file | docker run -i IMAGE /bin/bash -c "cat - > /path"
```

ディレクトリの場合はtarで固めて渡せばよさげ。

```
$ tar c dir | docker run -i IMAGE /bin/bash -c "tar -xC /"
```

dokkuとかでやってた。

https://github.com/progrium/dokku/blob/9ac94abcf0c209193918a3b989cbd7a8428d8b6c/dokku#L33

## docker insert

`docker insert`というコマンドがあって

```
$ docker insert IMAGE URL PATH
```

という感じでhttp経由でイメージにファイルを追加できるんだけど、この機能は0.10.0でDeprecatedになってる。

[Deprecate 'docker insert' by shykes · Pull Request #5005 · dotcloud/docker](https://github.com/dotcloud/docker/pull/5005)

`docker build`と`ADD`使えとのこと。

ちなみにこの`docker insert`にローカルのファイルを追加できるようにするという議論や実装もあったみたいだけど、`docker insert`自体がなくなったために闇に葬り去られたようである。

* [Moving a file from the host system to a container · Issue #905 · dotcloud/docker](https://github.com/dotcloud/docker/issues/905)
* [Fix #905 : insert files by jvermillard · Pull Request #3890 · dotcloud/docker](https://github.com/dotcloud/docker/pull/3890)
Windwos7にデフォルトでインストールされているIE９をIE８に変更する方法

**(2014/04/17時点)**

・【Windwos7にデフォルトでインストールされているIE９をIE８に変更する方法】
------------------------------------------------------------------

Windwos7は標準でIE9がインストールされているが、場合によってはIE8に戻したい時ある。
方法は至って簡単で既存のIE9をアンインストールすれば良い。

作業を簡単にまとめると以下の通り。
　①コントロールパネルを開き「プログラムと機能」を選択する。
　②「インストールされた更新プログラムを表示」を選択する。
　③以下を選択し、[右クリック]-[アンインストール]を行う。
　④アンインストールが完了したら、OSを再起動する。

**■アンインストール方法**
==================================================================
①コントロールパネルを開き「 **プログラムと機能** 」を選択する。
------------------------------------------------------------------
![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/41775/fa879d17-3d9b-acda-596d-17f814e798d5.jpeg)



②「 **インストールされた更新プログラムを表示** 」を選択する。
------------------------------------------------------------------
![2.png](https://qiita-image-store.s3.amazonaws.com/0/41775/0afb4b4d-6c0a-59e0-7283-7b1b77076e67.png)


③以下を選択し、右クリック>アンインストールを行う。
------------------------------------------------------------------
　・Windows Internet Explorer9
　・Internet Explorer9 ja-JP Language Pack
![ie921.jpg](https://qiita-image-store.s3.amazonaws.com/0/41775/48dae26c-14ad-5803-b1d1-f91fda42a8c4.jpeg)


④アンインストールが完了したら、OSを再起動する。
------------------------------------------------------------------
これでIE9からIE8に変更される。
![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/41775/a64fba8c-02cc-cdb2-ac26-810e318ec62c.jpeg)



[参考：http://pc.mogeringo.com/archives/5403](http://pc.mogeringo.com/archives/5403)

参考まで。
KVOやるならFBKVOController使うべき


* シンプルで、モダンなkey value observingが行える

### メリット
* ブロックで書けるので、コードが読みやすくなる
* observerの削除のときにexceptionが起きない
* observerの削除はFBKVOControllerのdelloc時に呼ばれる

### 使い方

```
// create KVO controller with observer
FBKVOController *KVOController = [FBKVOController controllerWithObserver:self];

// observe clock date property
[KVOController observe:clock keyPath:@"date" options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew block:^(ClockView *clockView, Clock *clock, NSDictionary *change) {

  // update clock view with new value
  clockView.date = change[NSKeyValueChangeNewKey];
}];
```

* 実際にはviewやcontrollerのdelloc時に呼ぶために以下のように書く

```
// Observer with KVO controller instance variable
@implementation ClockView
{
  FBKVOController *_KVOController;
}

- (id)init
{
  ...
  // create KVO controller with observer
  FBKVOController *KVOController = [FBKVOController controllerWithObserver:self];

  // add strong reference from observer to KVO controller
  _KVOController = KVOController;
```

### インストール

```
pod 'KVOController'
```

### 参考

https://github.com/facebook/KVOController
MAMP Virtual hosts/OPcache 設定

## MAMP Downloads
MAMP & MAMP PRO - Downloads: (https://www.mamp.info/en/downloads/)


## ※既にMAMPをインストールしている場合
**/Applications/MAMP/conf/apache/httpd.conf** をデスクトップなどに保存してから
新しいMAMPをインストールしましょう。
今までの設定が全て消えてしまいます。

## Virtual hostsを許可する
ターミナルで下記ファイルを開きます。

```
$ vim /Applications/MAMP/conf/apache/httpd.conf
```

### 変更前
```apache:httpd.conf
# Virtual hosts
#Include /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf
```

### 変更後
```apache:httpd.conf
# Virtual hosts
Include /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf
```

## Virtual hostsを設定する

※既にMAMPをインストールしていた方は、先ほどデスクトップに保存した
**httpd-vhosts.conf** で上書きしましょう。

```
$ vim /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf
```

```apache:httpd-vhosts.conf
Listen 8080
<VirtualHost *:8080>
DocumentRoot "/Users/macbookpro/htdocs"
ServerName localhost
<Directory "/Users/macbookpro/htdocs">
Options Indexes FollowSymLinks +Includes
AddOutputFilter INCLUDES .html .php
AddHandler application/x-httpd-php .html .php .cgi
AllowOverride All
Order Allow,Deny
Allow From All
</Directory>
</VirtualHost>
```

## PHP 5.5/OPcache を無効にする

```
$ vim /Applications/MAMP/bin/php/php5.5.10/conf/php.ini 
```

### 変更前

```ini:php.ini
[OPcache]
;zend_extension="/Applications/MAMP/bin/php/php5.5.10/lib/php/extensions/no-debug-non-zts-20121212/opcache.so"
  opcache.memory_consumption=128
  opcache.interned_strings_buffer=8
  opcache.max_accelerated_files=4000
  opcache.revalidate_freq=60
  opcache.fast_shutdown=1
  opcache.enable_cli=1
```

### 変更後

```ini:php.ini
;zend_extension="/Applications/MAMP/bin/php/php5.5.10/lib/php/extensions/no-debug-non-zts-20121212/opcache.so"
  opcache.memory_consumption=128
  opcache.interned_strings_buffer=8
  opcache.max_accelerated_files=4000
  opcache.revalidate_freq=60
  opcache.fast_shutdown=1
  opcache.enable_cli=0
  opcache.enable=0
```
OpenVzコンテナ起動時にbind mountする

* [Bind mounts - OpenVZ Linux Containers Wiki](http://wiki.openvz.org/Bind_mounts)

```bash:/etc/vz/conf/100.mount
#!/bin/bash
. /etc/vz/vz.conf
. ${VE_CONFFILE}
SRC=/mnt/cdrom
DST=/mnt/cdrom

if [ ! -e ${VE_ROOT}${DST} ];then
  mkdir -p ${VE_ROOT}${DST};
fi
mount -n -t simfs ${SRC} ${VE_ROOT}${DST} -o ${SRC}
```

`SRC=`と`DST=`を書き換えることでよい。

コンテナを再立ち上げすると起動時にmountされることを確認。
`/etc/vz/conf/100.mount`に実行権限は不要。
NokogiriのWarningが出てつらかったので消した

* rbenv使っている
  * bundle installするとvendor/bundleにアレされるようにしてる
* rails4.1にした

そしたら、こんなのが出てた

```
WARNING: Nokogiri was built against LibXML version 2.8.0, but has dynamically loaded 2.9.1
```

or

```
WARNING: Nokogiri was built against LibXML version 2.9.1, but has dynamically loaded 2.9.0
```

色々ググッた結果、以下で解決した

```
rm vendor/bundle vendor/bin
brew update
brew uninstall libxml2
brew install libxml2 --with-xml2-config
brew link --force libxml2
 
brew install libxslt
brew link --force libxslt

brew install libiconv
brew link --force libiconv
 
bundle config build.nokogiri -- --with-xml2-dir=/usr/local --with-xslt-dir=/usr/local --with-iconv-dir=/usr/local
bundle install
```
OSXのsambaをLinuxからmountする時の注意点

`nounix,sec=ntlmssp`をつける必要がある。

```bash:ダメな例
$ sudo mount -t cifs //192.168.0.2/Downloads /mnt \
  -o username="macowner",ro
```

```bash:良い例
$ sudo mount -t cifs //192.168.0.2/Downloads /mnt \
  -o username="macowner",ro,nounix,sec=ntlmssp
```

なお、mountコマンド完了からファイル一覧が見れるようになるまで5秒くらいかかる。
`ls /mnt` をしても一覧が取得できなくてはまっていた。
Rails4 で Oracle を使い始める


**環境**
- Rails 4.0.4
- ruby-oci8 (2.1.7)
- activerecord-oracle_enhanced-adapter (1.5.4)

**前提**
- sqlplus system/oracle@127.0.0.1/xe で接続できる

**サンプル**
- https://github.com/usutani/blog_with_oracle_enhanced-adapter

-
alias g='git'
alias be='bundle exec'


```
rails _4.0.4_ new blog --skip-bundle
cd blog
```

vi Gemfile

```
gem 'ruby-oci8', '~> 2.1.0'
gem "activerecord-oracle_enhanced-adapter", "~> 1.5.0"
```
bundle install --path vendor/bundler

vi config/database.yml

```
development:
  adapter: oracle_enhanced
  database: //127.0.0.1:1521/xe
  username: blog_development
  password: oracle
```

```
$ be rake db:create
Please provide the SYSTEM password for your Oracle installation
> oracle
```

be rake db:migrate:status
be rake db:migrate

sqlplus blog_development/oracle@127.0.0.1/xe
SQL> select * from tab;
SQL> desc schema_migrations

rails g scaffold Post title body:text
be rake db:migrate
rails s

-
**ユーザーの削除**
sqlplus system/oracle@127.0.0.1/xe 
SQL> select username from all_users;
SQL> drop user USER cascade;
OS X Mavericks に Oracle Client と ruby-oci8 をインストール


**環境**
- OS X 10.9.2
- Oracle client 11.2.0.3.0
- ruby-oci8 (2.1.6)

[（参考）Setup Oracle instant client and ruby oci8 gem on Mac](https://coderwall.com/p/nvva7a)

-
**オラクルから64bit版のファイルを入手する（要OTNアカウント）**
http://www.oracle.com/technetwork/topics/intel-macsoft-096467.html

```
instantclient-basic-macos.x64-11.2.0.3.0.zip
instantclient-sqlplus-macos.x64-11.2.0.3.0.zip
instantclient-sdk-macos.x64-11.2.0.3.0.zip
```

**ファイルを解凍する**

```
unzip -qq instantclient-basic-macos.x64-11.2.0.3.0.zip
unzip -qq instantclient-sqlplus-macos.x64-11.2.0.3.0.zip
unzip -qq instantclient-sdk-macos.x64-11.2.0.3.0.zip
```

**ファイルを移動する**

```
mkdir -p /usr/local/oracle/product/instantclient_64/11.2.0.3.0/bin
mkdir -p /usr/local/oracle/product/instantclient_64/11.2.0.3.0/lib
mkdir -p /usr/local/oracle/product/instantclient_64/11.2.0.3.0/jdbc/lib
mkdir -p /usr/local/oracle/product/instantclient_64/11.2.0.3.0/rdbms/jlib
mkdir -p /usr/local/oracle/product/instantclient_64/11.2.0.3.0/sqlplus/admin

cd instantclient_11_2/

mv ojdbc* /usr/local/oracle/product/instantclient_64/11.2.0.3.0/jdbc/lib/
mv x*.jar /usr/local/oracle/product/instantclient_64/11.2.0.3.0/rdbms/jlib/
```

**glogin.sql から login.sql にファイル名を変更する**

```
mv glogin.sql /usr/local/oracle/product/instantclient_64/11.2.0.3.0/sqlplus/admin/login.sql
```

**lib と sdk を移動する**

```
mv *dylib* /usr/local/oracle/product/instantclient_64/11.2.0.3.0/lib/
mv sdk /usr/local/oracle/product/instantclient_64/11.2.0.3.0/lib/sdk

mv *README /usr/local/oracle/product/instantclient_64/11.2.0.3.0/
mv * /usr/local/oracle/product/instantclient_64/11.2.0.3.0/bin/
```

-
**TNSを設定する**

```
mkdir -p /usr/local/oracle/admin/network
vi /usr/local/oracle/admin/network/tnsnames.ora
```

```
xe=
 (description=
   (address_list=
     (address = (protocol = TCP)(host = 127.0.0.1)(port = 1521))
   )
 (connect_data =
   (service_name=xe)
 )
)
```

-
**環境変数を設定する**

```
vi ~/.oracle_client
```

```
export ORACLE_BASE=/usr/local/oracle
export ORACLE_HOME=$ORACLE_BASE/product/instantclient_64/11.2.0.3.0
export PATH=$ORACLE_HOME/bin:$PATH
export DYLD_LIBRARY_PATH=$ORACLE_HOME/lib:$DYLD_LIBRARY_PATH
export TNS_ADMIN=$ORACLE_BASE/admin/network
export SQLPATH=$ORACLE_HOME/sqlplus/admin

export NLS_LANG=Japanese_Japan.AL32UTF8
alias sqlplus='rlwrap sqlplus'
```

rlwrap をインストールすると sqlplus で履歴を使えて便利

```
brew install rlwrap
```

```
echo "source ~/.oracle_client" >> ~/.bash_profile
source ~/.bash_profile
```

-
**sqlplusで接続を確認する**

ユーザ名 system、パスワード oracle だとして・・・

```
sqlplus system/oracle@127.0.0.1/xe
```

-
**ruby-oci8 gem をインストールする**

```
cd /usr/local/oracle/product/instantclient_64/11.2.0.3.0/lib
ln -s libclntsh.dylib.11.1 libclntsh.dylib
ln -s libocci.dylib.11.1 libocci.dylib

gem install ruby-oci8
```

irbで動作を確認する

```
irb
> require 'oci8'
> o = OCI8.new('system','oracle','127.0.0.1/xe')
```
一つのIPでproxmox上の仮想OSからインターネットに出る(iptables)


## proxmox(vmbr0:0)の設定

```diff:/etc/network/interfaces
+ auto vmbr0:0
+ iface vmbr0:0 inet static
+         address 192.168.101.1
+         netmask 255.255.255.0
```

※ 2021年現在は `vmbr0:0`ではなく `vmbr0`をもう1セット書くのが良いみたい。[NetworkConfiguration - Debian Wiki](https://wiki.debian.org/NetworkConfiguration#Multiple_IP_addresses_on_one_Interface)

## proxmox上のOpenVz設定

* ip: 192.168.101.2/24

## 設定

```bash:
apt-get install -y iptables-persistent
```

```bash:POSTROUTING設定をする。
iptables -t nat -A POSTROUTING -s 192.168.101.0/24 -o vmbr0 -j MASQUERADE
```

```bash:再起動後も有効にする
/etc/init.d/iptables-persistent save
Saving rules... IPv4... IPv6...done.
```

* /etc/iptables/rules.v4 に保存される。

```bash:POSTROUTING設定を削除する場合
iptables -t nat -F
```

## 動作確認

```bash:コンテナ内からネットに出られることを確認。
# vzctl enter 100
[root@vz100 /]# ping google.co.jp
pingが通ること。
[root@vz100 /]# yum install -y nkf
インストールができること
[root@vz100 /]# exit
```

```bash:proxmoxからコンテナにsshできることを確認。
# ssh root@192.168.101.2
```

# proxmox 4 の場合

```bash:
apt-get install -y iptables-persistent
```

```bash:POSTROUTING設定をする。
iptables -t nat -A POSTROUTING -s 192.168.101.0/24 -o vmbr0 -j MASQUERADE

iptables -t nat -L
```

```bash:再起動後も有効にする
/usr/share/netfilter-persistent/plugins.d/15-ip4tables save
```