OmniAICreator/Qiita-1.07M huggingface dataset:
[SoftLayer]Windows Updateが失敗した時の対応（備忘録）

このブログは、SoftLayerでWindowsUpdateが失敗した時の対応について書いた備忘録です。
対処法について以下に取りまとめます。

読むタイミングによってはバージョンなど異なるため適宜読み替えが必要です。
障害や対応方法については、必要に応じてSoftlayerのチケットを発行し対応する必要があります。この情報は個人的な見解であり所属する組織には一切関係ありません。

# １．発生した環境

　・DC　　：サンノゼ
　・OS　　：Windows Server2008R2 Standard（**無料Mcafeeをオーダー**）
　・現象　 ：WindowsUpdateで特定のパッチが導入できない。
　　　　　　 以下の4つのセキュリティ・パッチの導入（WindowsUpdate）が失敗する。

　　Security Update for Windows Server2008 R2x64 Edition(KB2984972)
　　Security Update for Windows Server2008 R2x64 Edition(KB3011780)
　　Security Update for Windows Server2008 R2x64 Edition(KB2992611)
　　Security Update for Windows Server2008 R2x64 Edition(KB3003743)


# ２．対応方法

　1.コマンドnslookupでwsus01.service.softlayer.comを確認する。
　　プライベートアドレスで、WSUSサーバーが答えることを確認する。
　　※プライベートLAN側にWSUSサーバーがあります。今回は10.0.77.53が答えた。

　　![nslookup.png](https://qiita-image-store.s3.amazonaws.com/0/59647/516369b1-4627-0e3c-ba00-0177363a503b.png)


　2.マカフィーのコンソール設定を変更する
　　常駐プログラムより「VirScanコンソール(v)」を起動する。
　　![Macfee1.png](https://qiita-image-store.s3.amazonaws.com/0/59647/19043591-ee05-3ff4-0ef4-bf8fac8d3ac0.png)



　3.VirusScanコンソールより「Acceess Protection」をDisableにします。
　　![VSコンソール.png](https://qiita-image-store.s3.amazonaws.com/0/59647/59cf648c-2400-fba3-b188-498a23c9ac4e.png)


# ３．設定変更後にWindowsUpdateを確認する

　失敗していたセキュリティ・パッチが正常に導入できることを確認する。

　　![WU_Log.png](https://qiita-image-store.s3.amazonaws.com/0/59647/fb538377-db77-71c8-9299-8a0ff867572e.png)


# ４．最後に
　・アップデートが完了したらマカフィー設定は元に戻す。

　・データーセンターによって**マカフィーのポリシー設定**に違いがあるようです。
　（すべてのDCを調べたわけではないですが・・・）
　　このような対応なく、正常にWindows Updateが行えるケースもあります。
　
　
　**参考：　KnowledgeLayer**
　http://knowledgelayer.softlayer.com/procedure/microsoft-windows-update-instructions
指定したプロセスIDのプロセスとその子孫全てを再帰的にkillするシェル関数が便利すぎる件について

超便利です，感動しました．
https://github.com/doi-t/killpstree

以下，上記のreadme.mdの引用です．

-----

killpstree
==========

指定したプロセスIDのプロセスとその子孫全てを再帰的にkillするシェル関数とそれを試すためのサンプル

## 本体のシェル関数

```sh
killpstree(){
	local children=`ps --ppid $1 --no-heading | awk '{ print $1 }'`
	for child in $children
	do
		killpstree $child
	done
	kill $1
}
```

引数にプロセスIDを渡すと、再帰的に対象のプロセスツリーの葉から根に向かってkillをして回る.

## サンプル実行

例えば、kill対象のプロセスツリーを意図的に2つ生成してそれをkillする場合．

```sh
$ bash mkpstree.bash &
$ bash mkpstree.bash &
$ ps ax --forest
$ bash killpstree.bash "mkpstree.bash"
```

サンプルスクリプトkillpstree.bash自体は、"プロセス名"を指定して、ヒットしたプロセスのIDを再帰的にkillを行うkillpstreeに渡す.

**不用意にプロセス名を指定してしまうと、思わぬプロセスまでkillされるので注意**
findByIdAndUpdateやfindAndUpdateで「Uncaught Maximum call stack size exceeded」

今日ちょっと時間を多く使ってしまったのがこのネタ。
検索しても似たような内容が引っかからなかったのでとりあえずまとめておく。

`author`はAuthorモデルのインスタンスだと思いねぇ。
対象の本を探しあてた瞬間に作者IDを入れ替える（こんなのなさそうだけどあくまで例です）。

```:coffee
Books.findByIdAndUpdate targetBook._id, {author: author}
```

で実行すると `Uncaught Maximum call stack size exceeded`が発生。
どうすれば良いかというと、単純に`_id`の抜けだった。

```:coffee
Books.findByIdAndUpdate targetBook._id, {author: author._id}
```

stack使い果たしたって出るのでそういうことが起こりそうな場所ばかり見てしまった。まさかこんなところで落とし穴があるとは。個人的にはこういうのは引数間違っている例外を出して欲しいですー。
Oracle SQLの結果をXMLで出力


# 内容
dbms_xmlgenパッケージのgetxmlファンクションを使用し、SQLの実行結果をXMLで出力する。

# 手順

"select * from v$database"の実行結果をXMLで出力する。

1. SQLの実行結果をXMLで出力するSQLファイル"xmlout.sql"を作成する。

    ``` sql:xmlout.sql
    set pages 0
    set lines 10000
    set long 10000000
    set trimspool on
    col xml for a1000
    
    spool result.xml
    select dbms_xmlgen.getxml('select * from v$database') as xml from dual;
    spool off
    
    exit
    ```

1. xmlout.sqlをsqlplusで実行する。

    ``` bash:
    sqlplus -S / as sysdba @xmlout.sql
    ```

1. 出力結果ファイル(result.xml)の内容を確認する。

    ``` xml:result.xml
    <?xml version="1.0"?>
    <ROWSET>
     <ROW>
      <DBID>12345678</DBID>
      <NAME>TEST</NAME>
      <CREATED>14-11-15</CREATED>
      <RESETLOGS_CHANGE_x0023_>1</RESETLOGS_CHANGE_x0023_>
      <RESETLOGS_TIME>14-11-15</RESETLOGS_TIME>
      <PRIOR_RESETLOGS_CHANGE_x0023_>0</PRIOR_RESETLOGS_CHANGE_x0023_>
      <LOG_MODE>ARCHIVELOG</LOG_MODE>
      …（省略）…
     </ROW>
    </ROWSET>
    ```

以上。
Sensu監視設定

以下を元に設定（※事前に、クライアント側へRubyのインストールが必要）
http://sensuapp.org/docs/0.16/adding_a_check

* Sensuインストール手順
    * [サーバ側](http://qiita.com/narvaux/items/15da8f71f7e175116d8b)
    * [クライアント側](http://qiita.com/narvaux/items/4d8d2bc59229af359c81)

## クライアント側 設定

### sensu-pluginのインストール

```
# gem install sensu-plugin --no-rdoc --no-ri
```

### 監視スクリプトのダウンロード

```
# wget -O /etc/sensu/plugins/check-procs.rb https://raw.github.com/sensu/sensu-community-plugins/master/plugins/processes/check-procs.rb
# chmod 755 /etc/sensu/plugins/check-procs.rb
```

### subscriptionsの設定

※name/addressは適宜修正すること

```
# vi /etc/sensu/conf.d/client.json
```

```diff:/etc/sensu/conf.d/client.json
{
  "client": {
    "name": "Sensu-Client",
    "address": "192.168.xxx.xxx",
-    "subscriptions": [ "all" ]
+    "subscriptions": [ "webservers" ]
  }
}
```

## サーバ側 設定

### 監視定義設定

```
# vi /etc/sensu/conf.d/check_cron.json
```

```json:/etc/sensu/conf.d/check_cron.json
{
  "checks": {
    "cron_check": {
      "handlers": ["default"],
      "command": "/etc/sensu/plugins/check-procs.rb -p crond -C 1 ",
      "interval": 60,
      "subscribers": [ "webservers" ]
    }
  }
}
```

## Sensu 再起動

### クライアント側

```
# service sensu-client restart
```

### サーバ側

```
# service sensu-server restart
# service sensu-api restart
```

## ログ確認

### クライアント側

```
# grep cron_check /var/log/sensu/sensu-client.log
{"timestamp":"2015-01-19T21:51:48.042368+0900","level":"info","message":"received check request","check":{"name":"cron_check","issued":1421671843,"command":"/etc/sensu/plugins/check-procs.rb -p crond -C 1 "}}
{"timestamp":"2015-01-19T21:51:48.129277+0900","level":"info","message":"publishing check result","payload":{"client":"Sensu-Client","check":{"name":"cron_check","issued":1421671843,"command":"/etc/sensu/plugins/check-procs.rb -p crond -C 1 ","executed":1421671908,"duration":0.086,"output":"CheckProcs OK: Found 1 matching processes; cmd /crond/\n","status":0}}}
```

### サーバ側

```
# grep cron_check /var/log/sensu/sensu-server.log
{"timestamp":"2015-01-19T21:51:43.444922+0900","level":"info","message":"publishing check request","payload":{"name":"cron_check","issued":1421671903,"command":"/etc/sensu/plugins/check-procs.rb -p crond -C 1 "},"subscribers":["webservers"]}
```

## 障害検出確認

### crondを停止してみる

```
# service crond stop
```

### Dashboard確認

http://＜Server IP＞:3000/#/events

![sensu-crond-check.png](https://qiita-image-store.s3.amazonaws.com/1163/3539/18028b06-0eee-448b-5102-ecddb92bcce8.png "sensu-crond-check.png")


### クライアント側 ログ確認

```
# grep cron_check /var/log/sensu/sensu-client.log | tail -2
{"timestamp":"2015-01-19T21:58:03.577208+0900","level":"info","message":"received check request","check":{"name":"cron_check","issued":1421672203,"command":"/etc/sensu/plugins/check-procs.rb -p crond -C 1 "}}
{"timestamp":"2015-01-19T21:58:03.663127+0900","level":"info","message":"publishing check result","payload":{"client":"Sensu-Client","check":{"name":"cron_check","issued":1421672203,"command":"/etc/sensu/plugins/check-procs.rb -p crond -C 1 ","executed":1421672283,"duration":0.086,"output":"CheckProcs CRITICAL: Found 0 matching processes; cmd /crond/\n","status":2}}}
```
Windows と IE のサポート状況

IEって結局どっから対応したらいいんだっけ？ と毎回思うのでまとめ。


**●サポート終了済み（2014.4.8.）**
Windows Xp： IE 6、7、8

**●サポート終了間近（2016.1.12.）**
Windows Vista： IE 7、8、9
Windows 7： IE 8、9、10
Windows 8： IE 10

**●まだまだサポート（2017.4.11.）**
Windows Vista： IE 9

（参照）Internet ExplorerのどのバージョンからどのHTML/CSS/JSに対応しているかの一覧｜Web制作 W3G
https://w3g.jp/blog/ie_supportlist

* * *

**●2014年12月のシェア**
（参照）Windows XPが急増 - 12月OSシェア | マイナビニュース
http://news.mynavi.jp/news/2015/01/06/203/
（参照）IE 8が急増 - 12月ブラウザシェア | マイナビニュース
http://news.mynavi.jp/news/2015/01/06/202/
> 1位：IE11（21.79%）
> 2位：IE8（19.28%）
> 3位：Chrome（12.79%）
【SoftLayer】Windowsでもプロビのときにスクリプト

#なにするの？
Softlayerを使うって人がいれば、量産プロビする人もいるでしょうから、スクリプトとかで簡単設定できればうれしいですよね。
頭では出来ると思っていても、いざUACとか管理者権限とか大丈夫かな?ってことで、Win情報もほぼ無いことから検証したものを！

#まずはじめに
私のリスペクトする伝道師さんが書いた、Linuxの手順を先に呼んでおいたほうがイメージしやすくなります。。。

http://pocketstudio.jp/log3/2014/12/09/how_to_use_softlayer_provisining_script/

あの、ようはこのURLを理解すれば、小職の書いた以下のページはおまけみたいなものです。LinuxとWinを置き換えればいいだけなんで！！


##検証してみよう

**検証環境**
・Win2012Std64
・スクリプト保管WebサーバはGithubを利用。

**検証で確認してみること**
・プロビジョニングで利用するWindowsのスクリプトがUACに影響することなく適用されることを、firewallの設定を変更することで確認する。
※powershell得意じゃないんで時間もないし、実績のあるバッチでｗ

**確認方法**
SL注文時にプロビジョングスクリプトを利用してfirewallの設定を最初から設定しちゃおってことです。あ、デフォルトではFW有効になってないんでね。あとはFWの設定は追加より変更のほうが難しそうだったんで、既存FTPのルールを変更(Allow⇒Block)してみました。

どうやってやる？
スクリプトというかバッチをね。実績のあるやつを作ってみたねｗ

んじゃどうやってスクリプト利用すんの？
スクリプトは外部の専用のサーバーたてるんです。。そんな余裕はないし、セキュリティこの時点で関係ないから、Web上から閲覧できるサーバに登録して利用していますよ。

ここサクッと準備できたらさ、
SLのポータルにこのWebサイトを登録するのさ。あとはWinサーバを注文するだけね。お金かかるよ。

ひとつだけ注意がありますよ。
必ずhttpsで登録してね。httpだとスクリプト直接実行されんのでね。


##それでは作業開始

GithubにWebにアカウント作って、SoftLayerにProvisioningScriptとして登録しました。
※あ、ここは

```
https://gist.githubusercontent.com/t-amano/2530aba09d93c029a168/raw/7d06702f45e35113e41827f236663b6a318e29d8/fwconf.bat
```

※ここのサイトたぶんいじれちゃうんで、悪意な感じで触らんといて～

```
@echo off

rem
rem Firewall enable and default rule change.
rem

netsh advfirewall set allprofiles state on
netsh advfirewall firewall set rule name="FTP - 21U" new action=block

exit

```

仮想サーバオーダーの際、このスクリプトを指定する。
![１.png](https://qiita-image-store.s3.amazonaws.com/0/66142/7a13ed60-89fe-3e71-cb24-bd27bb73b4ff.png)


プロビ完了後、サーバに始めてログイン。
結果①　Firewallが有効化されているので成功。

※あ、エビちゃん取るの忘れたごめんなさいｗ


結果②　既存ルール「FTP – 21U」をブロックしているので成功。
![4.png](https://qiita-image-store.s3.amazonaws.com/0/66142/3e453d9e-9d01-deca-f835-785a318d7642.png)



※ちなみに、このプロビジョニングスクリプトを使わないで仮想サーバを注文した結果、firewallは無効化されています。

![３.png](https://qiita-image-store.s3.amazonaws.com/0/66142/774625bc-4aaf-34aa-ee10-c07d30c3a050.png)


#強引にまとめ
問題なくWindowsでもプロビ時の設定変更をスクリプトで実施可能。
まあ、私にも出来たのでやってみてください。
まねっこまんじゅうなのは内緒ねｗ

それでは、さよならさよなら！
Mac上のPHPでエラーログの設定


MacのPHPのバージョンを[PHP for OS X as binary package](http://php-osx.liip.ch/)からアップデートしたついでにエラーログの出力を試してみたのでメモ。

アップデートしたPHPのphp.iniの設定はデフォルトで
`error_log = /var/log/apache2/php_errors.log`
となっているのでそのままターミナルから

```Bash
php -a
php > error_log('hoge');

```

と実行してもファイルに書き込まれない。

原因はエラーログファイルの権限の問題。
まずPHPのapacheプロセスのユーザを確認する。

```Bash
php -a
php > echo `whoami`;
username

```
phpinfo のEnvironment>Userでも確認可。

あとはエラーログファイルの実行権限を`chown`とかで変えてやれば無事エラーログがファイルに書き込まれるようになる。こんなことで二度とつまりたくないので備忘録残しました！
HTML5 File APIを使用しローカルファイルを読み込む簡単なサンプル

## HTML5 File APIとは
今までセキュリティ上、ローカルファイルにアクセスできなかったが、HTML5から「File API」というのを使用し、ローカルファイルを読み込むことができるようになった。

## サンプルと解説
画像ファイルを選択すると、その画像ファイルをプレビューだけするサンプル。
今まで、サーバーに画像をアップしないとできなかったことが、HTML + JavaScriptだけで完結できる。
これにより、HTML5のアプリケーションの幅が広がる。

また、SNSサイトなどでアイコン画像を、サーバーにアップする前にプレビューするときなどに使用される。
※キャンセルさせる画像は、わざわざサーバーにアップされないメリットがある

### HTML

```html
<input type="file" id="files" name="files[]">
<output></output>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
```


### JavaScript
```js
$(function(){

// --------------------------------------------------------
// 関数定義
// --------------------------------------------------------
function handleFileSelect(evt) {
    var files = evt.target.files; // inputタグからFileオブジェクトを取得

    // ファイル数分実行
    for (var i = 0, f; f = files[i]; i++) {
        if (!f.type.match('image.*')) {
            continue;
        }

        var reader = new FileReader(); // ファイル読み取り用オブジェクト作成

        // ファイルを読み時
        reader.onload = (function(theFile) {
            return function(e) {
                // サムネイル用のimgタグ
                var $html = ['<img class="photo" src="', e.target.result,'" title="', escape(theFile.name), '">'].join('');

                // サムネイルタグを生成
                $('output').append($html);
            };
        })(f);

        // データURLにエンコードした内容を格納
        reader.readAsDataURL(f);
    }
}



// --------------------------------------------------------
// Ready時実行
// --------------------------------------------------------
// File APIのサポートチェックし、ボタンを押した時に実行
if (window.File && window.FileReader && window.FileList && window.Blob) {
    $('#files').on('change', handleFileSelect);
} else {
    alert('お使いのブラウザはサポートしておりません');
}


});
```

## 補足
### Fileオブジェクトのプロパティ
- `name` : ファイルの名前
- `type` : ファイルのMIME/TYPE
- `size` : ファイルのサイズ(バイト)
- `urn` : ファイルのURN(URL)

## 参考URL
- [JavaScript で File API を使用してファイルを読み取る](http://www.html5rocks.com/ja/tutorials/file/dndfiles/)
- [File APIを使ってローカルファイルを読み込む](http://techbooster.org/html5/11063/)
「遠い世界の数式」解いてみた

# What is「遠い世界の数式」?
これ
http://nabetani.sakura.ne.jp/kanagawa.rb/evalex/

# 基本戦略
* 「あっ、これ再帰だ」と思ったので再帰でやる
* 最初の分割するところ以外では正規表現使わない（正規表現バリバリ使って解くパターンもある）
* Ruby（仕事では PHP 使ってるけど、とりあえずこういうの書きやすそうなやつでいく）

# 結果
https://github.com/pullphone/unknown_numerical_formula

## とりあえずガーッと書いたやつ
https://github.com/pullphone/unknown_numerical_formula/blob/2c2e8be9e4af1606be89987533ca9aa6ec482822/unknown_numerical_formula.rb

### 雑感
* 勤務時間中に1時間くらいで書いた
* 外部から ```input``` を渡すだけで呼び出せるように全部クラスメソッドにしといた
* ホントはコレの前に ```operators``` でまとめる前のバージョン（つまりそれぞれの演算子で別メソッドのバージョン）が有る
* 左辺と右辺を分ける処理がひどいと思う
* 最初の数式を分割する処理もいまいちしっくりこない
* エラー処理はガン無視した

## リファクタリングしたやつ
https://github.com/pullphone/unknown_numerical_formula/blob/c437c9175f507b7c4b0a2c0a2cacfc52f1ed8cad/unknown_numerical_formula.rb

### 雑感
* ちょこちょこと（勤務時間中に）直した（もちろん仕事もやりつつ）
* ```class << self``` というやつがあるのを知らなかった
* ```Array#slice``` という便利メソッドがあったことも思い出した
* ネストを1個まで（メソッドで2個以上ネストしたらメソッドに切り出す）という方針で書きなおした
* 結果、あんまし処理変わってない割にメソッドが増えたので行数が増える
* 数式分割処理の部分を関数型っぽく（？）一行で処理するようにした（が、これはちょっと微妙な気も）
* Go では（error の返却があるからだと思うけど）ほぼ必須の複数 return も Ruby ではあんまり見かけないような気も（try-catch あるし、基本クラス変数 or インスタンス変数で受け渡すっていう方針が多いからかな）
* 後置if文が便利すぎる
* Haskell とか（の関数型言語）でやったらどんな感じになるのかやってみたい気も
Ruby: state_machineがメンテされてないのでaasmに移行した

Rails4.2でActiveRecord Enumとか出ましたが、状態遷移を気持よくやろうとするとやっぱりなんかgemが欲しい。

# state_machine 生きてない..?

あんまりメンテされてないみたいです。

pluginaweek/state_machine
https://github.com/pluginaweek/state_machine

Rails4.1ぐらいまではパッチ当ててなんとか使っていたけどそろそろ無理。

# aasm いい感じよ！

機能的に100%互換ではないけど、大体syntaxが似ているし、state_machineでうまく扱えなかった継承関係もうまくやれる！

aasm/aasm
https://github.com/aasm/aasm

# 移行時に注意したこと

使い方は [README.md](https://github.com/aasm/aasm/blob/master/README.md) 読んでね。

## bangをつけないと保存されない

```state_machine.rb
job.run #=> ダメなときはfalse
job.run! #=> ダメなときはエラーが出る
```

でも保存されたんだけど、aasmはされない。値が変わるだけ。
なので、ひとつひとつbangつけた。

## `:from => :to`なsyntaxが使えないので書き換え

```state_machine.rb
transition :hoge => :hogehoge
``` 

な記法は気持ちよかったけどない。

```aasm.rb
transitions from: :hoge, to: :hogehoge
```

## `may_[state_name]?`な書き方できるのいいね

state_machineでは`can_[state_name]?`だったかな？

## `with_state`ではなくscopeへ

```state_machine.rb
class Job
  state_machine do
    state :hoge
  end
end

Job.with_state(:job)
```

```aasm.rb
class Job
  aasm do
    state :hoge
  end
end

Job.hoge
```

ActiveRecord Enumみたいな感じでscope定義してくれる。
無効にも出来るけど、直感的なのであったほうがいいかな。

## その他
 
* ## 地味に`transition`ではなく`transitions`
* `any`はないがそもそも省略できる

---

Qiita久しぶりすぎてやばい！
階層構造 if 文の Xcode のバグっぽいもの

うーん今日はこの問題に小一時間くらい悩まされました…なにより一番タチが悪いのは Playground ではちゃんと動作するということ…
簡単にどんなものかというと、以下の様な階層構造の if 文の問題です：

```swift
if test == nil {
	// Do something
	if test == nil {
		test = 1
	}
}
```

で、// Do something のところで戻り値がオプショナル変数の関数を test に代入して、一応ここでちゃんとした値が代入されますが、なぜかその次の nil 判断でも true が返され更に下の階層まで実行されたのです。

実際の動作をだいぶ略したコードは以下のようです：

```swift
import UIKit

let table: [String: Int] = ["s_hoge": 1]
var test: Any? = nil

func returnANumber(key: String) -> Int? {
	let switchKey = key.substringToIndex(key.startIndex.successor().successor())
	switch switchKey {
	case "s_":
		return table[key]
		
	default:
		return nil
	}
}

if test == nil {
	test = returnANumber("s_hoge")
	
	if test == nil {
		test = "hoge"
	}
}
```

で、このコードを Playground で実行してみた場合、test がちゃんと「1」になりますが、なぜか普通のプログラムにコンパイルして実行してみた場合「"hoge"」になっちゃいます…

んで、if 文だけ以下のように直せばちゃんと動きます：

```swift
if test == nil {
	test = returnANumber("s_hoge")
}

if test == nil {
	test = "hoge"
}
```

このようにするとちゃんと2回目の if 判断で nil じゃないって判定され test がそのまま1です。なんじゃこりゃ…ずっと returnANumber 関数の書き方が間違えたのか table 辞書の設定が間違えたのかと思って1時間以上散々テストした俺の時間を返してくださいw
（ちなみに元のソースコードでは table 辞書は超絶に長いものが4つあって returnANumber の switch 文で切り替えて使ってます…多分これも関係なくはないと思ったり思わなかったり…）

まあ時間あったら Xcode 6.2 でもテストしてみますわ…w
レプリケーションしてみた


CentOS7標準のMariaDB 5.5.40 にて実施。

# 設定

## masterの設定

```diff:/etc/my.cnf.d/my_custom.cnf
  [mysqld]
  character-set-server = utf8
  innodb_file_per_table = 1
  
  # show variables like slow;
  slow_query_log=ON
  long_query_time=1
  log-slow-queries=/var/log/mariadb/slow.log
  
+ # 一意の値を設定
+ server-id = 101
+ # binlog
+ log_bin = /srv/binlog/bin.log
+ binlog_format=MIXED
+ # 1年保管
+ expire_logs_days = 365
```


## masterにてレプリケーション用アカウント作成

```sql:
MariaDB [(none)]>
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.11.0/255.255.255.0' IDENTIFIED BY 'oida4Wezxa5OSh8V';
```

```sql:
MariaDB [(none)]> show master status;
+------------+----------+--------------+------------------+
| File       | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------+----------+--------------+------------------+
| bin.000001 |      245 |              |                  |
+------------+----------+--------------+------------------+
1 row in set (0.00 sec)
```

後でこの値を使うので覚えておく。

## masterからslaveにコピー

```bash:
mkdir /opt/{bin,relay}log
chown mysql:mysql /opt/{bin,relay}log

systemctl stop mariadb
cd /var/lib/mysql
tar cpf /tmp/db.tar .
scp /tmp/db.tar dbsrv2:

systemctl restart mariadb
```

## slaveにてmasterのbinlogのpositionを指定

```diff:/etc/my.cnf.d/my_custom.cnf
  [mysqld]
  character-set-server = utf8
  innodb_file_per_table = 1
  
  # show variables like slow;
  slow_query_log=ON
  long_query_time=1
  log-slow-queries=/var/log/mariadb/slow.log
  
+ server-id = 102
+ relay-log=/srv/relaylog/bin
+ relay-log-index=/srv/relaylog/bin
```

```bash:
mkdir /opt/{bin,relay}log
chown mysql:mysql /opt/{bin,relay}log

cd /var/lib/mysql
rm -rf *
tar xpf ~/db.tar .

systemctl restart mariadb
```

```sql:
MariaDB [(none)]> 
CHANGE MASTER TO
  MASTER_HOST = 'dbsrv1',
  MASTER_USER = 'repl',
  MASTER_PASSWORD = 'oida4Wezxa5OSh8V',
  MASTER_LOG_FILE = 'bin.000001',
  MASTER_LOG_POS = 245;
```

```sql:
MariaDB [(none)]> START SLAVE;
MariaDB [(none)]> SHOW SLAVE STATUS \G
```

# 動作確認

## masterにて実施

```sql:
MariaDB [(none)]> use test;
MariaDB [(none)]> CREATE TABLE count1(num INT);
MariaDB [(none)]> INSERT INTO count1 (num) VALUES (1);
```

## slaveにて確認

```sql:
MariaDB [(none)]> use test;
MariaDB [(none)]> show tables;
MariaDB [(none)]> select * from count1;
```

# 注意点

masterのmariadbを再起動したら、slaveのmariadbも再起動しないと
レプリケーションがされない！？
CentOS 6.6にSensuインストール（クライアント側）

以下はChef/Puppetを使わずにCentOS 6.6にインストールする手順。

* OS: CentOS 6.6
* Sensu: 0.16
* [Sensuサーバ側のインストール手順](http://qiita.com/narvaux/items/15da8f71f7e175116d8b)

下記手順をもとに進める。
http://sensuapp.org/docs/0.16/guide

## Sensuインストール

http://sensuapp.org/docs/0.16/packages

### リポジトリ設定ファイル作成

```
# vi /etc/yum.repos.d/sensu.repo
```

```/etc/yum.repos.d/sensu.repo
[sensu]
name=sensu-main
baseurl=http://repos.sensuapp.org/yum/el/$releasever/$basearch/
gpgcheck=0
enabled=1
```

### Sensuインストール

```
# yum install sensu
```

## Sensu設定

### Sensu用のSSL証明書ファイル配置ディレクトリ作成

```
# mkdir -p /etc/sensu/ssl
```

### Sensuサーバで作成済みのSSL証明書ファイルを`/etc/sensu/ssl`配下にコピー

scpなり何なりでコピーする。

```
# scp user@192.168.xxx.xxx:/etc/sensu/ssl/*.pem /etc/sensu/ssl/
```

### /etc/sensu/conf.d/rabbitmq.json作成

* user/password -> [Sensuサーバにて`Sensu用のRabbitMQユーザ作成・パーミッション付与`で設定したもの](http://qiita.com/narvaux/items/15da8f71f7e175116d8b#sensu%E7%94%A8%E3%81%AErabbitmq%E3%83%A6%E3%83%BC%E3%82%B6%E4%BD%9C%E6%88%90%E3%83%91%E3%83%BC%E3%83%9F%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E4%BB%98%E4%B8%8E)
* `host`及び`user`, `password`は適宜修正すること

```
# vi /etc/sensu/conf.d/rabbitmq.json
```

```json:/etc/sensu/conf.d/rabbitmq.json
{
  "rabbitmq": {
    "ssl": {
      "cert_chain_file": "/etc/sensu/ssl/cert.pem",
      "private_key_file": "/etc/sensu/ssl/key.pem"
    },
    "host": "192.168.xxx.xxx",
    "port": 5671,
    "vhost": "/sensu",
    "user": "sensu",
    "password": "rabbitmq-sensu-password"
  }
}
```

## Sensu clients設定

### /etc/sensu/conf.d/client.json作成

* name -> Sensuクライアントのホスト名
* address -> SensuクライアントのIPアドレス

※name/addressは適宜変更すること

```
# vi /etc/sensu/conf.d/client.json
```

```json:/etc/sensu/conf.d/client.json
{
  "client": {
    "name": "Sensu-Client",
    "address": "192.168.xxx.xxx",
    "subscriptions": [ "all" ]
  }
}
```

## Sensu Agent起動

```
# chkconfig sensu-client on
# service sensu-client start
```

## 登録確認

サーバ側に登録されていることを確認。（自動的に登録されているはず）
http://＜Server IP＞:3000/#/clients
文字列を渡すと右始まりの縦書きにレイアウトする

なんか、気付いたら書いていたのだけれど、書き終った時に、なぜ書いていたのか思い出せず、しかも、現在の作業とまるで関係ないコードだったため、お蔵入りになることが確定した。供養のために投稿しておく。



```php
<?php
$string = '私は宇宙人ですが地球人でもあります。私は宇宙人でした。私は宇宙人だったような気もします。';

echo "<< original >>\n";
echo $string . "\n";

echo "<< converted >>\n";

$result = convertVerticalLayout($string);
for ($i = 0; $i < count($result); $i++) {
    for ($j = 0; $j < count($result[$i]); $j++) {
        echo $result[$i][$j];
    }
    echo "\n";
}

function convertVerticalLayout ($string) {
    $lines = explode ('。', $string);
    unset($lines[count($lines) - 1]);
    $maxLength = 0;
    $lineCount = count($lines);
    for ($i = 0; $i < $lineCount; $i++) {
        $line = $lines[$i];
        $lines[$i] = array();
        $j = 0;
        for (; $j < mb_strlen($line, 'UTF8'); $j++) {
            $lines[$i][$j] = mb_substr($line, $j, 1, 'UTF8');
        }
        $lines[$i][$j] = '。';
        if ($maxLength < count($lines[$i])) {
            $maxLength = count($lines[$i]);
        }
    }

    $result = array();
    for ($j = 0; $j < $maxLength; $j++) {
        for ($i = 0; $i < $lineCount; $i++) {
            $result[$j][$lineCount - 1 - $i] = isset($lines[$i][$j]) ? $lines[$i][$j] : '　';
        }
    }
    return $result;
}
```
Atomのautocomplete-plusパッケージで補完確定をTabキーからEnterキーに変更



本家にそのままあった。
下のように追加したらOKだった

~~~~/.atom/packages/autocomplete-plus/keymaps/autocomplete-plus.cson
# 上はデフォのまま
'atom-text-editor:not(mini) .autocomplete-plus.autocomplete-suggestion-list':
  'tab': 'unset!'
  'enter': 'autocomplete-plus:confirm'
~~~

## [追記] .csonいじらなくても、GUIぽちぽちでできた

- [cmd] + ,でsettingを開く(メニューからPreferences...でもok)

![Screen_Shot_2015-01-20_at_10_35_35_AM.png](https://qiita-image-store.s3.amazonaws.com/0/10722/4424b635-61e2-d2a1-2208-2becc2622da1.png "Screen_Shot_2015-01-20_at_10_35_35_AM.png")

![Screen_Shot_2015-01-20_at_10_38_58_AM.png](https://qiita-image-store.s3.amazonaws.com/0/10722/bb37ea67-2dd9-b759-4e1a-b4abcb45d553.png "Screen_Shot_2015-01-20_at_10_38_58_AM.png")

- [補足] ctrl+n,pで補完候補を選択するのも下にあった


## 参考
- [autocomplete+ package](https://atom.io/packages/autocomplete-plus)
ブラックホールオブジェクトを利用して nil に妨げられないメソッドチェイン

- [tap のブロックの中で break すると戻り値を返せる](http://qiita.com/ma2saka/items/3c137d2652242417de64)

昨日こんなのを書いたのだけど、やりたいことはむしろこういうことだった。


```
class Object
  def chain?
    self
  end
end

class BlackHole < BasicObject
  def method_missing(method_name, *args)
    nil
  end
end

class NilClass
  def chain?
    BlackHole.new
  end
end
```

えー結局ブラックホールオブジェクトに行き着いてしまったのかーと自分で残念な感じ。

これで、こんな風な記述ができる。まあ、そうですねという。

```
description = Context.user.chain?.profile.chain?.description || "-"
```
Edisonで参考になったサイトとかTips



### wifiの設定で困った時
```unix
// パスとかデーモンの設定 パス設定すればsshが使えるようになる。
$ configure_edison --setup
// 簡単にwifiの設定。　接続先を変える時とか。
$ configure_edison --wifi
// 今繋いでるwifiは？
$ iwconfig 
```

### opkgでインストール出来ない時


パスが通らないエラー発生。
あるけど、ない状態。

```
$ opkg install vim
$ vim
vim : comman not find
$ opkg install vim
Package vim (version) installed in root is up to date.
```
たぶんupgradeとかした時おかしくなった気がする。
再インストールしてあげましょう。

```
$ opkg remove vim
$ opkg install vim
```


### rootの容量がたりなさすぎて困った時
[Intel Edisonのセットアップと容量不足問題](http://frisk.gizmon.com/intel-edisonnosetutoatupu/)

### expressサーバーを立てる時
http://tomowatanabe.hatenablog.com/entry/2014/10/31/152554


### インテルのIoTデバイス開発キットmraa
https://github.com/intel-iot-devkit/mraa

```
$ opkg install libmraa0
// $ opkg install mraa
```

### pipとeasy_installを入れる
http://nonnoise.github.io/Edison/python.html

```
$ wget https://bootstrap.pypa.io/ez_setup.py --no-check-certificate -O - | python
$ easy_install pip
```
CentOS6でDockerを初期化したい


ハマったのでメモ.

# dockerが壊れた

ある日突然 [docker] が動かなくなって、pullしてもErrorになる。色々試したけど直らない。
仕方ないので、 **コンテナ、Image全部消して再installしても何故か直らない** 。

# /var/lib/docker/にデータが...

↓にDockerのデータがありました。これ消さないとダメでした。

```
$ sudo rm -r /var/lib/docker/
```

"docker info"コマンドで情報でます。

```
$ docker info

Containers: 1
Images: 15
Storage Driver: devicemapper
 Pool Name: docker-253:0-1582072-pool
 Pool Blocksize: 65.54 kB
 Data file: /var/lib/docker/devicemapper/devicemapper/data
 Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata
 Data Space Used: 830.2 MB
 Data Space Total: 107.4 GB
 Metadata Space Used: 1.663 MB
 Metadata Space Total: 2.147 GB
 Library Version: 1.02.89-RHEL6 (2014-09-01)
Execution Driver: native-0.2
Kernel Version: 2.6.32-504.3.3.el6.x86_64
Operating System: <unknown>
```


# 参考元

* [archlinux]

[archlinux]:https://bbs.archlinux.org/viewtopic.php?id=179942
[docker]:https://www.docker.com/
別アカウントのS3 bucketと同期を取る

s3cmdを使って別アカウントのS3 bucketと同期を取る。

### 同期元のS3 bucket policy設定

bucket policyは以下でも作成可能。
http://awspolicygen.s3.amazonaws.com/policygen.html

1. https://console.aws.amazon.com/s3/home
1. 同期元のbucket選択
1. Properties
1. Pemissions
1. Edit bucket policy
1. Save

```
{
	"Version": "2008-10-17",
	"Id": "Policy1421378237042",
	"Statement": [
		{
			"Sid": "Stmt1421378165334",
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::＜同期先bucketアカウントのオーナーID12桁＞:root"
			},
			"Action": "s3:*",
			"Resource": [
				"arn:aws:s3:::＜同期元bucket名＞",
				"arn:aws:s3:::＜同期元bucket名＞/*"
			]
		}
	]
}
```

### s3cmdインストール

http://s3tools.org/s3cmd

**Mac**

```
$ brew install s3cmd
```

### s3cmdの設定

```
$ s3cmd --configure
Access Key: 同期先アカウントのアクセスキー
Secret Key: 同期先アカウントのシークレットキー
Encryption password:
Path to GPG program:
Use HTTPS protocol [No]:
HTTP Proxy server name:

Test access with supplied credentials? [Y/n] y
Please wait...
Success. Your access key and secret key worked fine :-)

Save settings? [y/N] y
Configuration saved to '/Users/user/.s3cfg'
```

### 同期処理実行

`s3cmd sync 同期元bucket[/OBJECT] 同期先bucket[/OBJECT]`

```
$ s3cmd sync s3://org-image.example.jp/test1 s3://new-image.example.jp
Summary: 2 source files to copy, 90 files at destination to delete
File s3://org-image.example.jp/test1/ copied to s3://new-image.example.jp/test1/
File s3://org-image.example.jp/test1/test.jpg copied to s3://new-image.example.jp/test1/test.jpg
Done. Copied 2 files in 0.2 seconds, 13.29 files/s
```

```
$ s3cmd --help
〜
  Synchronize a directory tree to S3
      s3cmd sync LOCAL_DIR s3://BUCKET[/PREFIX] or s3://BUCKET[/PREFIX] LOCAL_DIR
〜
```
fluentdで@timestampフィールドをレコードに追加する


# やりたいこと

![スクリーンショット 2015-01-19 17.56.34.png](https://qiita-image-store.s3.amazonaws.com/0/9140/f5ecfc15-ea50-144e-e7b8-525c8c3ceac3.png "スクリーンショット 2015-01-19 17.56.34.png")


上記のような構成で、[fluent-plugin-elasticsearch](https://github.com/uken/fluent-plugin-elasticsearch)を使ってログ収集する際に、web-server側のイベント時間を@timestampフィールド（fluent-plugin-elasticsearchがタイムスタンプとして利用するフィールド）としてレコードに追加したい。

# fluentdの設定

```
<match oreno.access>
  type record_reformer
  enable_ruby true
  tag oreno.access.timestamp
  <record>
    @timestamp ${time.strftime('%Y-%m-%dT%H:%M:%S%z')}
  </record>
</match>
```

[fluent-plugin-record-reformer](https://github.com/sonots/fluent-plugin-record-reformer)を利用して、こんな感じの設定をweb-serverのfluentdに追加した。（正規表現でフォーマットしないと、スペース入りのtimestampになってしまって、Elasticsearch側で正しく処理されなかった）

# 何が嬉しいのか

@timestampフィールドはデフォルトだとfluent-plugin-elasticsearchが動作しているfluentdのtimeを適用するので、アグリゲーターとして動かしているfluentdがダウンしている時間があった場合などに、再起動後からのタイムスタンプを付与してしまう。送信側でバッファしていたログがあった場合は、再起動後ではなく、ログの出力時間を基準にmetricsを構築しないと、正しいアクセス数などが集計できないため、こんな感じの設定を入れた。
Adobeのスクリプトでホストアプリケーションのパスを取得する方法(ExtendScript, jsx)

#ホストアプリケーションのパスを取得する
Adobeのソフトウェアで使用するExtendScript(jsx)で、実行中のホストアプリケーションのファイルパスの取得方法です。
IllustratorやPhotoshop、After Effectsなど、実際のソフトウェアのパスが返ってきます。

```js:hostApp.jsx
BridgeTalk.getAppPath(BridgeTalk.appName)
```
##ExtendScript Toolkit CS6での実行結果
![hostappalert.png](https://qiita-image-store.s3.amazonaws.com/0/26207/530086f8-b693-7554-1a02-e67b3808dd6b.png)

ここでのポイントは**対象のソフトウェアのバージョン違いがあるときでも、ちゃんと正しいパスを拾ってくれる**ことです。
##After Effects CC 2014での実行結果
![hostappalertae.png](https://qiita-image-store.s3.amazonaws.com/0/26207/c225460d-5845-6999-31d6-4e9dba8646a9.png)

##After Effects CCでの実行結果
![hostappalertae12.png](https://qiita-image-store.s3.amazonaws.com/0/26207/9a21c652-9bf3-4da1-b663-4c38018497d2.png)

#BridgeTalk
ここで使用している**BridgeTalk**というのはAdobeのアプリケーション間でスクリプトのやり取りを行う際に使用するオブジェクトです。
このオブジェクトを使用すれば、Adobeのソフトウェア間ならパスを指定することなく対象のアプリケーションを呼び出すことが可能です。
RDSにPostgreSQLのdumpをインポートする

現状、スナップショットを他アカウントのRDSにリストア出来ない模様。
→dumpを取得して移行してみる

以下を参考にした。
http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/PostgreSQL.Procedural.Importing.html

* DB -> PostgreSQL 9.3.5
* クライアント -> CentOS 6.6

### PostgreSQLのクライアント関係パッケージのインストール

クライアント側で必要パッケージのインストール。
http://yum.postgresql.org/rpmchart.php

```
$ wget http://yum.postgresql.org/9.3/redhat/rhel-6-i386/postgresql93-libs-9.3.5-1PGDG.rhel6.i686.rpm
$ wget http://yum.postgresql.org/9.3/redhat/rhel-6-i386/postgresql93-9.3.5-1PGDG.rhel6.i686.rpm
# yum localinstall postgresql93-libs-9.3.5-1PGDG.rhel6.i686.rpm
# rpm -ivh postgresql93-9.3.5-1PGDG.rhel6.i686.rpm
# pg_dump --version
pg_dump (PostgreSQL) 9.3.5
```

### 既存DBのdump取得

クライアント側から既存DBのdumpを取得。
https://www.postgresql.jp/document/9.3/html/app-pgdump.html

```
$ pg_dump -h xxx-org-db.xxxxxx.ap-northeast-1.rds.amazonaws.com -U app development -f /tmp/development.dump
```

### インポート先のRDSインスタンス起動

なお、以下の設定でインスタンスを作成しておくと、データのインポートが高速になる。

* バックアップの保持設定を`0`
* マルチAZを`無効`

### データベース作成

インポート先のRDSインスタンスにdumpしたデータベースと同名のデータベースを作成。

```sql
postgres=> CREATE DATABASE development LC_COLLATE 'ja_JP.UTF-8' LC_CTYPE 'ja_JP.UTF-8' ENCODING 'UTF8' TEMPLATE template0;
```

### dumpをインポートする

インポート先のRDSインスタンスにdumpをインポートする。
https://www.postgresql.jp/document/9.3/html/app-psql.html

```
$ psql -f /tmp/development.dump --host=xxx-new-db.xxxxxx.ap-northeast-1.rds.amazonaws.com 
--port=5432 --username=app --password --dbname=development  
```

### データベース名を変更する場合

https://www.postgresql.jp/document/9.3/html/sql-alterdatabase.html

```sql
postgres=> ALTER DATABASE development RENAME TO new_database_name
```
Railsで動的にエラーページを表示する

Railsでエラーページを表示する方法についてメモ。
[rexception](https://github.com/kami30k/rexception/)というGemを使う。

## 手順

まず、サンプルアプリケーションを生成する。

```
$ rails new sample
```

`rexception`を追加する。

```
$ vi Gemfile

gem 'rexception'
```

インストールする。

```
$ bundle
```

`app/views`下に`errors`ディレクトリを作成する。
その下に`application.html.erb`を作成する。

```erb:app/views/errors/application.html.erb
<h1>Application Error</h1>
```

`development`環境でエラーを確認するために以下の設定をする。

```ruby:config/environments/development.rb
config.consider_all_requests_local = false
```

WEBrickを起動する。

```
$ bin/rails s
```

存在しないURLにアクセスしてみる。

![Screen_Shot_2015-01-19_at_5_53_32_PM.png](https://qiita-image-store.s3.amazonaws.com/0/66490/40d39077-1bb5-1985-8348-709b948007ee.png)

ログは以下のようになる。

```
Processing by Rexception::ExceptionsController#not_found as HTML
  Rendered errors/application.html.erb within layouts/application (0.2ms)
Completed 404 Not Found in 22ms (Views: 21.7ms | ActiveRecord: 0.0ms)
```
CoreLocation許可ダイアログが消えてしまう


位置情報を使おうとiOS 8から新しくなった許可ダイアログを出したのですが、applicationDidBecomeActiveが呼ばれてしまい、ダイアログが一瞬出ては消えてしまう。

サンプルコード
https://github.com/nmisawa/CoreLocationActivate

CoreLocationの呼び出し部分

    CLLocationManager *lm = [[CLLocationManager alloc] init];
    if ([CLLocationManager locationServicesEnabled]) {
        lm.delegate = self;
        lm.distanceFilter = kCLDistanceFilterNone;
        lm.desiredAccuracy = kCLLocationAccuracyBest;
    }
    
    if ([lm respondsToSelector:@selector(requestAlwaysAuthorization)]) {
        [lm requestWhenInUseAuthorization];
    } else {
        [lm startUpdatingLocation];
    }

いたって普通。。
Info.plistにも
NSLocationWhenInUseUsageDescription
を追加しているし、、

はまっていたら、、、

CLLocationManagerをpropertyで宣言すれば良いというのを見つけ、、追い出してやって解決。
I
@property (strong, nonatomic) CLLocationManager *locationManager;

一体この時間は何だったんだ。。

githubにあげたソースコードも修正しました。

    lm = [[CLLocationManager alloc] init];
    if ([CLLocationManager locationServicesEnabled]) {
        lm.delegate = self;
        lm.distanceFilter = kCLDistanceFilterNone;
        lm.desiredAccuracy = kCLLocationAccuracyBest;
    }
    
    if ([lm respondsToSelector:@selector(requestAlwaysAuthorization)]) {
        [lm requestWhenInUseAuthorization];
    } else {
        [lm startUpdatingLocation];
    }
webで頑張っている元教え子ちゃんにおくるまとめ＃5　MDN


#記述の動機
専門学校でPG、Webを教え始めてもう８年。
マイナススタートの２年はあまりに短い。教えきれなかったことが多い。
頑張ってる元教え子ちゃんにむけてまとめているのですが
ついでに、公開しておきます。
そして、現役の学生諸君へ、「こんなもんやれば出来る。」
コンピュータの世界はやっただけのご褒美はある。


#MDN
Mozilla 日本語表示にしてもいいけど、英文読め！！
https://developer.mozilla.org/en-US/docs/Web/CSS

![kobito.1421655710.421022.png](https://qiita-image-store.s3.amazonaws.com/0/33317/2fc299e2-fbc2-43f3-b977-d06b99908d9b.png "kobito.1421655710.421022.png")

#日本のMDN
http://www.mdn.co.jp/di/
ここだけでもかなり学べます。

![スクリーンショット 2015-01-19 17.42.55.png](https://qiita-image-store.s3.amazonaws.com/0/33317/aece251d-ed3f-59a1-4e3c-545fd839660f.png "スクリーンショット 2015-01-19 17.42.55.png")


#やってはいけないこと
##古いコードのコピペ。
百害あって一利無し。

##メンテナンスされていない解説サイト
当時は正しい。今は非推奨。

##古すぎるテンプレート
使えません。無意味

#ジェネレーター
Naverにまとめがあったので、各種使ってみてください。
http://matome.naver.jp/odai/2132750704946539001
オブジェクトをChef Serverにアップロードする

### 差分確認

Chefサーバとのdiffを確認する。

```diff
$ knife diff roles/sample-role.json
diff --knife roles/sample-role.json roles/sample-role.json
--- roles/sample-role.json	2014-09-29 16:55:35.000000000 +0900
+++ roles/sample-role.json	2014-09-29 16:55:35.000000000 +0900
@@ -1,5 +1,6 @@
 {
   "name": "sample-role",
+  "description": "sample role",
   "run_list": [
     "recipe[sample]"
   ]
```

### Dry Runで確認

```
$ knife upload roles/sample-role.json --dry-run
Would update roles/sample-role.json
```

### Chefサーバにアップロード

```
$ knife upload roles/sample-role.json
Updated roles/sample-role.json
```

### 変更が適用されていることを確認

ここでは「description: sample role」が追加された。

```
$ knife role show sample-role
chef_type:           role
default_attributes:
description:         sample role
env_run_lists:
json_class:          Chef::Role
name:                sample-role
override_attributes:
run_list:            recipe[sample]
```
JMXからjetty-jolokia proxyを通してREST API(HTTP+json)で統計情報収集

# 背景

jolokiaをjavaアプリケーションに直接組み込めないので、jetty+jolokiaのプロクシを立ち上げる。
REST APIにより、JMXポートから情報を引っ張ってこれるようになる。
リクエストのjsonにJMXポートを開いているホストのURIを埋め込む必要がある。

# 手順

openjdkをインストールして、jetty、jolokiaをdownload

```bash
yum install java-1.7.0-openjdk
cd /tmp
wget http://download.eclipse.org/jetty/9.2.6.v20141205/dist/jetty-distribution-9.2.6.v20141205.tar.gz
wget http://labs.consol.de/maven/repository/org/jolokia/jolokia-war/1.2.3/jolokia-war-1.2.3.war
tar xfz jetty-distribution-9.2.6.v20141205.tar.gz
cp jolokia-war-1.2.3.war jetty-distribution-9.2.6.v20141205/webapps/jolokia.war
cd jetty-distribution-9.2.6.v20141205
grep -i port start.ini
java -jar start.jar
```

テスト

```bash
curl http://<jetty hsotname>:8080/jolokia/ -X POST -d '{ "type" : "read","mbean" : "java.lang:type=Memory","attribute" : "HeapMemoryUsage", "target" : { "url" : "service:jmx:rmi:///jndi/rmi://<javaアプリ hostname>:<javaアプリ jmx port>/jmxrmi" }}'
```
明細番号の振り方


* ヘッダ
* 明細

みたいな感じの普通の書類に、

ヘッダ

*  ヘッダ番号(連番インクリメント)
* 内容

明細

* ヘッダ番号
* 明細番号
* 内容

みたいなテーブルを作る。

この時の明細番号を自動で作成したい場合は、以下の様な設定を行う。


|ヘッダ番号| 明細番号|内容|カウント用|
|:-------|:-------|:--|:-------|
|リレーションで設定|集計(カウント用の値を現在まで合計、もしくはカウント、明細のヘッダ番号でソート)|内容|グローバルフィールドで数字"1"を指定|


とすると、カウント用の数字を明細番号が自動で計算、インクリメントしてくれる。

ただし、明細を削除すると、明細番号が非保存なので、自動で計算され直して、欠番が塞がれてしまうので、注意。

固有のIDなどを付ける場合は、別にID用のフィールドを用意して`&`で結合する。数字で初期値を用意したい場合も同様。

つーか、こんな基礎機能を持ってないのは、怠慢じゃないかと...。
Chef Serverからローカルのchef-repoにオブジェクトをダウンロードする

ここでは例として、rolesをダウンロードする。

### ローカルのchef-repoにcd

現時点ではroles配下に何もない。

```
$ cd ~/work/chef-repo
$ ll roles/
total 16
-rw-r--r--  1 user  staff  632  5 22 18:21 README.md
```

### knife downloadコマンドでChefサーバからオブジェクトをダウンロード

```
$ knife download roles
Created roles/base.json
Created roles/web.json
```

ダウンロードされていることを確認。

```
$ ll roles/
total 64
-rw-r--r--  1 user  staff  632  5 22 18:21 README.md
-rw-r--r--  1 user  staff  208  9 29 14:17 base.json
-rw-r--r--  1 user  staff  166  9 29 14:17 web.json

$ cat roles/base.json
```

```json:roles/base.json
{
  "name": "base",
  "description": "base role",
  "run_list": [
    "recipe[audit]",
    "recipe[users]"
  ]
}
```

### Dry Run

knife downloadに「--dry-run」オプションを付与すると、以下を事前に確認可能。

* ダウンロード対象のオブジェクト
* ローカルのChef-Repoに行われる処理

```
$ knife download roles --dry-run
Would create roles/base.json
Would create roles/web.json
```

### ダウンロード候補

以下をダウンロード/管理しておくと良い。

* data_bags
* environments
* nodes
* roles
Macのpbcopyをubuntuでも使う

Max OS では クリップボードにコピーするための pbcopy が使える

```
$ cat hoge.txt | pbcopy
```

この場合は、hoge.txtの内容がクリップボードにコピーされる

Ubuntuの場合は、xsel というものを使ってこの動きを模倣できる。
標準ではインストールされていないので、まずはインストールする必要がある。

```
$ sudo apt-get install xsel
```

出力をクリップボードにコピーするのは以下のコマンドでできる

```
$ cat hoge.txt | xsel --clipboard --input
```

いちいちこれを入力するのは面倒なので。.bashrcにエイリアスを定義しておく

```
$ alias pbcopy='xsel --clipboard --input'
```
AWSトレーニング(Developing on AWS)受講記録

[AWSトレーニング(Developing on AWS)](http://aws.amazon.com/jp/training/course-descriptions/developing/)を受講しました。
受講するかどうかの判断の助けとなるように内容を記録しておきます。

# 参加者

* 講師(ソリューションアーキテクト)：1名 
* 受講者：8名
 * AWS歴は数ヶ月〜2年
 * [Architecting on AWS](http://aws.amazon.com/jp/training/course-descriptions/architect/)も受講されていた方数人

# 受講概要

AWSでのアプリ開発のための知識習得を3日間で行いました。

### 1日目
 * AWSとは：グローバルインフラやセキュリティモデルなどのAWSの基本
 * IAM：AWSの基本であるIAMの説明
 * S3/DynamoDB：アプリのデータ保管先としてのS3とDyanamoDBの説明

### 2日目

 * SQS/SNS：主にバックエンドアプリで利用するSQSとSNSの説明
 * Application Security：AWSのセキュリティとSTSの説明

### 3日目

 * デプロイ
  * BeansTalk、OpsWorks、CloudFormationの概要と位置付けと開発向けサービスとしてのBeansTalkの説明
 * EffectiveCodingPractices：例外処理、ロギング、非同期API、カスタム認証プロバイダチェーンの説明

### ラボ

各章の終りでは演習がありました。
演習のソースはこちら。

* Java https://github.com/aws-jp-trainers/devonaws-labs-java-master-jp
* C# https://github.com/aws-jp-trainers/devonaws-labs-csharp-master

以下の演習では主にSDKを使ってAWSサービスを操作することを行いました。

* ラボ1.1 IAMユーザとグループの作成(後の演習の準備)
* ラボ1.2 IDE(Eclipse or VisualStudio)の設定
* ラボ2.1 S3をSDKで操作
* ラボ2.2 DynamoDBをSDKで操作
* ラボ3.1 SNSおよびSQSをSDKで操作
* ラボ4.1 STSのAssumeRoleで一時的な権限を取得してAWSを操作
* ラボ5.1 Elastic BeansTalkでWebアプリをデプロイしてみる

# 他のトレーニングとの比較

今まで[Architecting on AWS](http://aws.amazon.com/jp/training/course-descriptions/architect/)と[Systems Operations on AWS](http://aws.amazon.com/jp/training/course-descriptions/sysops/)を受講したことがあるのでそちらとの比較です。

* Architecting on AWSはスケジュールがぎゅうぎゅうという感じだが、Developing on AWSはSystems Operations on AWSと同じく余裕がある(お昼休み外に食べに出られる)
* 他のトレーニングではチームを作ってのディスカッションがあったがSystems Operations on AWSでは無く、各章でクイズがある時に隣の人と話すのみだった。
 * 他の参加者のAWSの実運用の話が聞ける機会がトレーニングとしてないのがちょっと残念

# 所感

* 体系的な学習とラボによって効率的にAWSでのアプリ開発の知識が得られる
 * デプロイまでやるあたりさすがAWSといった感じで実践的
* 講師の方に個別に質問することで個人的に悩んでいるAWSのことを聞ける
* ラボをやっていけば知識を効率的に得られるので良いが、もうちょっと改善されるとうれしいことがいくつかあった
 * RubyistなのでRubyも対応されるとうれしい
 * ラボ3.1ではSNSからSQSの連携が遅延する場合があるがそれが考慮されたコードになっておらず警告が表示される
 * ラボ5.1ではTomcat環境の構築など本筋でない部分でハマりやすいので構築済環境を整えるか事前に環境を構築させてほしい
* 個人的にSTSのAssumeRoleとFederationUserが完全ではないが理解できたのが特に良かった
CentOS 6.6にUchiwaをインストール

SensuのdashboardであるUchiwaをCentOS 6.6にインストールする手順。
※SensuとUchiwaは同サーバにインストールするものとする
http://sensuapp.org/docs/0.16/dashboards_uchiwa

* OS: CentOS 6.6
* Sensu: 0.16
* [Sensuのインストール手順](http://qiita.com/narvaux/items/15da8f71f7e175116d8b)

### Uchiwaインストール

```
# yum install uchiwa
```

### 設定

`/etc/sensu`ディレクトリの所有グループが`sensu`であることを確認。

```
# ll -d /etc/sensu
drwxr-xr-x 8 sensu sensu 4096  1月 16 21:29 2015 /etc/sensu
```

/etc/sensu/uchiwa.jsonを作成。
user/passは`/etc/sensu/conf.d/api.json`で設定したものを使用。

```
# vi /etc/sensu/uchiwa.json
```

```json:/etc/sensu/uchiwa.json
{
    "sensu": [
        {
            "name": "Sensu",
            "host": "127.0.0.1",
            "ssl": false,
            "port": 4567,
            "user": "admin",
            "pass": "sensu-api-admin-password",
            "path": "",
            "timeout": 5000
        }
    ],
    "uchiwa": {
        "user": "",
        "pass": "",
        "port": 3000,
        "stats": 10,
        "refresh": 10000
    }
}
```

### Uchiwa起動

```
# chkconfig uchiwa on
# service uchiwa start
```

### dashboardにアクセス

ブラウザで下記にアクセス。
http://＜Server IP＞:3000

![uchiwa-1.png](https://qiita-image-store.s3.amazonaws.com/1163/3539/3d8a5857-95f3-e4e0-4e0f-38d3b3e0ecf6.png "uchiwa-1.png")
bootstrap-datepickerを使って年月のみ取得する

jQueryのみを使っていた頃は、jQueryのDatePickerを改造した[ympicker](https://www.softel.co.jp/blogs/tech/archives/4297)を使っていたのですが、Bootstrap3を導入したらcssがうまく適用されなかったので、[bootstrap-datepicker](https://github.com/acidsound/bootstrap-datepicker)で同じようなことができないか調べてみました。

# 実はbootstrap-datepickerにはモードがある

ソースコードを読んでいけばわかるのですが、bootstrap-datepickerの設定時のオプションに、minValueModeというのがあります。

```js:bootstrap-datepicker.jsの175行目あたり
switch (o.minViewMode){
	case 1:
	case 'months':
		o.minViewMode = 1;
		break;
	case 2:
	case 'years':
		o.minViewMode = 2;
		break;
	default:
		o.minViewMode = 0;
}
```

これを設定してみましょう。

## 使ってみる

idがyear_month_start, year_month_endの要素がある場合、年月のみのdatepickerを設定してみます。

```coffeescript:coffeescript
if $('#year_month_start, #year_month_end').is '*'
  $('#year_month_start, #year_month_end').datepicker(
    format: 'yyyy/mm'
    language: 'ja'
    autoclose: true,
    minViewMode: 'months'
  )
```

すると、年月のみの表示がされました！

![スクリーンショット 2015-01-19 17.12.36.png](https://qiita-image-store.s3.amazonaws.com/0/10078/065075ff-1303-af96-abac-4aac8c93477b.png)

bootstrap-datepickerは便利ですなぁ。
vSphere 5.5で選択可能な輻輳制御アルゴリズム

# 概要

vSphere 5.5のESXiでは「輻輳制御アルゴリズム｣として、NewRenoか、CUBICを選択できる。これについて簡単に調べたが、推奨や使い分けについては理解できなかった。

# 詳細

vSphere 5.5のESXiのTCP/IP構成に、輻輳制御アルゴリズムがある。選択式のパラメータで、選択肢は以下の二つになる。

* NewReno（日本語UIでは「新規 Reno」）
* CUBIC

デフォルト値はNewRenoだったが、推奨や使い分けは不明。

この先を調べる方の、初期調査の省力化に役立つよう、確認範囲について記録しておく。なお、解説やコメントの投稿は全面的に歓迎。誤りの指摘も歓迎だが、投稿者がそれを受けて「正解にたどり着いて修正する」には能力が不足しているかもしれない。

## vSphere 5.5ドキュメントでの記述

[vSphere 5.5のドキュメント](http://www.vmware.com/jp/support/support-resources/pubs/vsphere-esxi-vcenter-server-pubs/)での記述を確認した。

* 「[vSphereのインストールとセットアップ Update 2 vSphere 5.5](http://pubs.vmware.com/vsphere-55/topic/com.vmware.ICbase/PDF/vsphere-esxi-vcenter-server-552-installation-setup-guide.pdf)」には輻輳制御についての記述なし。
* 「[vCenterServerおよびホスト管理 Update2 ESXi 5.5 vCenter Server 5.5](http://pubs.vmware.com/vsphere-55/topic/com.vmware.ICbase/PDF/vsphere-esxi-vcenter-server-552-host-management-guide.pdf)」には輻輳制御についての記述なし。
* 「[vSphereネットワーク Update 2 vSphere 5.5](http://pubs.vmware.com/vsphere-55/topic/com.vmware.ICbase/PDF/vsphere-esxi-vcenter-server-552-networking-guide.pdf)」では、4章「VMkernelネットワークの設定」で輻輳制御アルゴリズムの選択内容表示(P.69)および選択変更方法(P.70)について触れている。ただし選択肢やその内容には触れていない。

他にvSphere API Documentの「[HostNetStackInstanceCongestionControlAlgorithmType](http://pubs.vmware.com/vsphere-55/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvim.host.NetStackInstance.CongestionControlAlgorithmType.html)」で、ここに（API経由で）指定できる値を以下のように説明している。

* cubic - Cubic Algorithm. See http://tools.ietf.org/id/draft-rhee-tcp-cubic-00.txt for detail. 
* newreno - New Reno Algorithm. See http://tools.ietf.org/html/rfc3782 for detail. 

## NewRenoとCUBIC

**以下はTCP/IPをまったく理解していない本投稿者による、現時点での解釈ないし判断になる。調査の材料にはなるかもしれないが、判断の根拠にしないこと。**

NewRenoとその前身であるRenoについては「[TCP各バージョンの輻輳制御の観察](http://www.net.c.dendai.ac.jp/~yutaro/)」を参考にした。どちらもパケットの喪失（ロス）を観測して、喪失が発生していれば転送量を下げて、ネットワークの混雑緩和を図る。80年代からの方式が、改良、改善を加えられてきた、よく枯れた役立つアルゴリズムになる。

CUBICのNewRenoに対する比較については、FastSoft（[2012年にAkamaiが買収](http://www.akamai.co.jp/enja/html/about/press/releases/2012/press_091312.html)）のペーパー「[TCPの進化とその比較 どのTCPが今日のインターネットの要求に合うのか？](https://www.toyo.co.jp/file/pdf/it/fastsoft/pdf/tcp_comparison.pdf)を参考にした。以下、引用するが、おおむね上記[IETFのCUBICについてのメモ](http://tools.ietf.org/id/draft-rhee-tcp-cubic-00.txt)のIntroductionでの指摘とも内容合致していると思う。

> TCP Renoは、エンド-トゥ-エンドのボトルネック容量が大きい、転送距離が長い、パケットロスが多い場合にうまく動作しません。これはこの様な環境では、TCP Reno は利用可能な帯域を探り当てることが下手で、パケットロス発生時には極端に反応してしまいます。また、ランダムなロス（ワイヤレスコネクションのドロップの様な場合）と輻輳によるロスを区別することができません。
>
> この問題に対応するため、Windows Vista は、複合 TCP（CTCP）と呼ばれる新たな TCPの派生品を配備しました。一方 Linux2.6 カーネルは CUBIC と呼ばれる他の派生品を使っています。CUBIC はロスベースですが、“長距離・広帯域”ネットワークで Reno よりもさらにアグレッシブに動作します。

## vSphere 5.5での設定

**以下はTCP/IPをまったく理解していない本投稿者による、現時点での解釈ないし判断になる。調査の材料にはなるかもしれないが、判断の根拠にしないこと。**

現時点で、ESXiでの輻輳制御アルゴリズム選択としては、デフォルト設定となっている「NewReno」で大過ないと思われる。

背景を推測すれば、VMware社はvSphere 5.5で長距離vMotionを実用化しよう（した）としており、災害対策ソリューション（SRM:Site Recovery Manager）の一部として遠距離でのソフトウェアレプリケーションにも力を入れてきている。こうしたケースで「“長距離・広帯域”ネットワーク」に向いたCUBICを選択できるようにしてきたのかもしれない。
Kali Linuxに最新版のGitとMetasploitをいれて... さらに！！ Node.jsまでつけちゃうんです。

全部Root権限で実行。
(PostgreSQLいじるところだけ、PostgreSQL用ユーザ)

※ #だとコメントアウトになっちゃうんで、rootだけど$にしてます。
※ VirtualBoxで動かしてます。

# 事前準備

apt-getが古いので最新の状態にしてパッケージも更新

```bash
$ apt-get update && apt-get upgrade
```

Virtualbox Guest Editionを入れる。
CD ROMからだとrunがミスるので、ローカルにコピーして実行

```bash
$ apt-get install -y linux-headers-$(uname -r)
$ cd /media/cdrom/
$ cp /media/cdrom/VBoxLinuxAdditions.run /root/
$ cd
$ chmod 755 VBoxLinuxAdditions.run
$ ./VBoxLinuxAdditions.run
```

## Git

Gitを最新にする。
CurlのSSLパッケージを事前に入れておく

```bash
$ apt-get install libcurl4-openssl-dev gettext
$ wget https://www.kernel.org/pub/software/scm/git/git-2.2.1.tar.gz
$ tar zvxf git-2.2.1.tar.gz
$ cd git-2.2.1/
$ ./configure
$ make
$ make install
```

このままだとGitのバージョンがそのままなので、
一旦閉じて開き直すとバージョンが新しくなってると思います

```bash
$ git version
> git version 2.2.1
```

## Metasploit

metasploitの最新版をいれる
PostgreSQLを起動して、既存のmetasploitはデーモンを停止してから実行

```bash
$ service postgresql start
$ service metasploit stop
$ apt-get install build-essential libreadline-dev libssl-dev libpq5 libpq-dev libreadline5 libsqlite3-dev libpcap-dev openjdk-7-jre subversion git-core autoconf postgresql pgadmin3 curl zlib1g-dev libxml2-dev libxslt1-dev vncviewer libyaml-dev ruby-dev libpq-dev ruby-pcap libpcap-ruby libpcap0.8-dev
$ git clone https://github.com/rapid7/metasploit-framework.git
$ cd metasploit-framework
$ bundle install
```

初期セットアップ(1)
metasploitのデータベースとそのユーザを作る

```bash
$ su - postgres
$ createuser msfgit -P -S -R -D
# パスワードはmsfとかで
$ createdb -O msfgit msfgit
$ exit
```

初期セットアップ(2)
設定ファイルを作る

```bash
$ msfconsole
(しばらく待ちます)
msf> quit

(これで /root/.msf4ができる)

$ vi /root/.msf4/database.yml
```

```yaml:database.yml
production:
  adapter: "postgresql"
  database: "msfgit"
  username: "msfgit"
  password: "msf"
  port: 5432
  host: "localhost"
  pool: 256
  timeout: 5
```

## Node.js

node.jsを入れる

```bash
$ apt-get install python g++ make checkinstall fakeroot
$ src=$(mktemp -d) && cd $src
$ wget -N http://nodejs.org/dist/node-latest.tar.gz
$ tar xzvf node-latest.tar.gz && cd node-v*
$ ./configure
$ fakeroot checkinstall -y --install=no --pkgversion $(echo $(pwd) | sed -n -re's/.+node-v(.+)$/\1/p') make -j$(($(nproc)+1)) install
$ dpkg -i node_*
```

## 備考

あとはこれをVagrant+ansibleとかでやっちゃえば最強！
(他力本願)
PHPで値が入っていたとき、いないときの条件分岐文の書き方

値が入っていれば実行、入っていなければ(null)その他の処理を実行

ex: $Contactに値があるときとないときの分岐文

```html+php


if ($Contact) {
  <!-値が入っている時の処理 -->
　echo 'お問合せがあります';
} else {
  <!--値が入っていないとき(null)の処理 -->
}
Macローカル環境のRails4のDBをMySQLに変更する


## 概要
Macのローカル環境にて、Rails4のDBをMySQLに変更する手順のメモです。

## MySQLのインストール
Homebrewでインストールします。

```
$ brew update
$ brew install mysql
```

ここからMySQLの設定を行っていきます。
なお、この設定の仕方は```$ brew info mysql```で確認することができます。

まず、データベースを初期化します。

```
$ unset TMPDIR
$ mysql_install_db --verbose --user=`whoami` --basedir="$(brew --prefix mysql)" --datadir=/usr/local/var/mysql --tmpdir=/tmp
```

これでサーバーが起動できるはずです。
サーバーを手動で起動させてみましょう。

```
$ mysql.server start
```	

ログイン時に自動起動させたい場合は、次のように設定します。

```
$ ln -sfv /usr/local/opt/mysql/*.plist ~/Library/LaunchAgents
$ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
```

最後に、セキュリティの設定を行います。
パスワード以外の設定は、基本的に「Y」で大丈夫です。

```
$ mysql_secure_installation
```

これでインストール完了です。
以下のコマンドでMySQLにログインしてみましょう。

```
$ mysql -uroot -p
$ #{設定したパスワード}
```

## RailsからMySQLへ接続する
それではRailsからMySQLへ接続します。
```config/database.yml```に、上で設定した root ユーザのパスワードを追記します。

```config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password: [ここにパスワードを追記]
  socket: /tmp/mysql.sock
```

マイグレーションを実行します。

```
$ rake db:migrate
```

以上で完了です。

## 参考
* [Mac へ MySQL を Homebrew でインストールする手順](http://qiita.com/hkusu/items/cda3e8461e7a46ecf25d)
* [MacにHomebrewでMySQLをインストールしてみた。](http://howtohp.com/2011/08/20/homebrew-mysql/)
Ebean で (a or b) and (c or d or e) みたいなクエリを作る

たくさん or を繋ぐなら junction 使えってリファレンスに書いてあるんだけど、それを更に and で繋ぎたくなったらどうするの？って話。結論、endJunction で一旦切ればいいようです。

```java
find.where()
    .disjunction()
        .add(a)
        .add(b)
        .endJunction()
    .disjunction()
        .add(c)
        .add(d)
        .add(e)
// .findList() なりなんなり
```

a とか b とかは、実際にはこういうやつ。

```
Expr.eq("column1", somevalue) とか
Expr.lt("column2", 100) とか
```

参考にしたサイト

 - [ebean - join two expressionList with "or" or "and" - Stack Overflow](http://stackoverflow.com/questions/10995253/join-two-expressionlist-with-or-or-and)
 - [Junction (Ebean 2.6.0 API)](http://www.avaje.org/static/javadoc/pub/com/avaje/ebean/Junction.html)