OmniAICreator/Qiita-1.07M huggingface dataset:
Cloud9環境でWordPressサイト制作① -導入-

WordPressを手っ取り早く体験するために、cloud9を利用しようという試みです。VCCWという仮想環境もありますが、手っとりばやく体験するという点においては、かなり優秀な部類だと思われます。
※勉強しながらの執筆のため、多々至らない点があるかと思いますのでご了承ください。

1. cloud9でWordPress用のworkspaceを作成
------
まず、[cloud9](https://c9.io/)のページにアクセスし、自身のアカウントでログインする。次に「Create a new workspace」をクリックし、下図のようにworkspaceを作成する。
※WordPressに対しての攻撃が多いため、可能であれば「Private」で作成することをお勧めしたい。  
<img src=https://qiita-image-store.s3.amazonaws.com/0/91976/4df55486-14b2-e173-4c4c-24c6c3f5b9d3.png width=400px>

2. WordPressの起動準備
------
この段階でほとんど完成してはいるのだが、mysqlを使用しておきたいので下記コマンドをTerminalから入力しておくとよい（何も設定していないとWordPressのDBとしてsqliteが使用されます）

```
mysql-ctl start
```

3. Apacheの起動
------
「Run」→「Run With」→「PHP(built-in web server)」を選択し、WordPressを起動させます。すると下記のようにApacheが起動するので、
表示されているURLにアクセスします。  

```
Starting Apache httpd, serving https://wordpress-project-username.c9users.io/.
Enabled xdebug.remote_enable
Started apache2
```

<img src=https://qiita-image-store.s3.amazonaws.com/0/91976/1af568e1-cda1-986d-a4db-fc7509b0a8b9.png width=400px>

4. WordPressのインストール
------
URLにアクセスすると対話型のインストーラが起動するので、自身の好みの設定を入力してください。この例では分かりやすくするために、ユーザをadminにしていますが、実際は推測されにくいIDを入力した方がよいです。（といっても、自動のパスワードを利用していれば比較的安全ではあります。IDよりもパスワードをしっかりする方がセキュリティ面では安全なようです）
 
<img src=https://qiita-image-store.s3.amazonaws.com/0/91976/8f9730d2-49a2-7703-c7d1-fe38ee27e203.png width=250px>  
<img src=https://qiita-image-store.s3.amazonaws.com/0/91976/97a01d2f-87e6-18de-4b6c-6ae2894a68c8.png width=400px> 

5. 確認
------
インストール後、ログイン画面が出てきますのでログインして完成！
何度やっても簡単ですね！

<img src=https://qiita-image-store.s3.amazonaws.com/0/91976/f6fd5c1f-6354-cc4c-7702-26a797918b05.png width=250px>
PythonでダミーのSMTPサーバ立ててActionMailerからの送信の動作確認まで


RailsのActionMailerでの実装を動作確認するにあたってSMTPサーバが必要なんだけど、わざわざサーバ立てるのも大変なのでPythonでダミーのSMTPサーバを立ててみた。

# ダミーのSMTPサーバを立てる

参考: [Pythonでローカルでテストできる簡易SMTPサーバを立てる方法 - Qiita](http://qiita.com/vh5150/items/50d52cbcb9d7e55786b7)

上記のページを参考に以下のように起動

```起動例
$ python -m smtpd -n -c DebuggingServer localhost:8025
```

# telnetでSMTPサーバの動作を確認

とりあえず telnet でローカルのSMTPサーバに繋いで、SMTPサーバと会話してみる。

参考: [telnetでメール送信](http://ash.jp/net/telnet_smtp.htm)

接続先のホストに localhost ポート番号は先ほど立ち上げたサーバのポート番号を指定

```
$ telnet localhost 8025
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 localhost.localdomain Python SMTP proxy version 0.2
```

HELOコマンドを入力しEnter（行頭の">"は入力行を表すもので実際は入力しない）

```
>HELO localhost
250 localhost.localdomain
```

送信者(from:)を入力

```
>MAIL FROM: hoge@example.com
250 Ok
```

宛先(to:)を入力

```
>RCPT TO: hoge+recipient@example.com
250 Ok
```

DATAコマンドを入力しメール本文を入力。"."のみの行を入力すると本文の入力は終了。

```
>DATA
354 End data with <CR><LF>.<CR><LF>
>Hello world.
>.
250 Ok
```

QUITコマンドでSMTPサーバから抜ける。

```
>QUIT
221 Bye
Connection closed by foreign host.
```

上記の手順を実行して SMTP サーバを起動したターミナルの画面に送信内容のログが表示されたたら疎通OK

# Rails側からメール送信してみる

以下のように config/application.rb にActionMailerの設定を記述

```config/application.rb
config.action_mailer.smtp_settings = {
   address: "localhost",
   port: 8025,
   domain: "localhost"
}
```

app/mailer/test_mailer.rb を作って以下のようにテストメール送信メソッドを定義

```app/mailer/test_mailer.rb
class TestMailer < ActionMailer::Mailer
  default from: "hoge@example.com",
            to: "fuga@example.com"
  
  def test
    mail(subject: "test") do |format|
      format.text { render text: "This is test mail." }
    end
  end
end
```

上記の準備ができたら rails console を立ち上げ、以下のようにテストメールを送信してみる。

```
> TestMailer.test.deliver_now
```

上記の入力結果、SMTPサーバのターミナル出力を確認して"This is test mail."とメール本文が読めたらOK


# 参考

* [Pythonでローカルでテストできる簡易SMTPサーバを立てる方法 - Qiita](http://qiita.com/vh5150/items/50d52cbcb9d7e55786b7)
* [telnetでメール送信](http://ash.jp/net/telnet_smtp.htm)
* [Action Mailer Basics — Ruby on Rails Guides](http://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration)
* [RailsのActionMailerでメールを送信する（Gmail経由） - Qiita](http://qiita.com/dalaito0514/items/0907ee3312ed9d79c9e8)
c++ builder / debug > 多数のコンポーネントの名前付け確認 > 「タブ順」を開く 

```txt:動作確認
C++ Builder XE4
```

- TPanel
  - TComboBox > 5 x 3列
  - TEdit > 5 x 2列
  - TCheckBox > 5 x 1列

上記のTPanelが10セットあるとする。

コードで一括処理するためにsuffixで連番をつけて管理するが、連番をつけるフォームデザインの単調作業で失敗することがある。

きちんと名前付けしたか確認するには Name プロパティを確認することになるが、各コンポーネントのNameを確認していくと時間がかかりすぎる。

TPanelごとに「タブ順」を開けばよい。 名前付けが失敗していたらすぐにわかる。
タブの切り替え方: JQuery + CSS + html の書き方

タブの切り替える方法を実現するために、やり方のメモです。

※普通の場合、html, js, cssはそれぞれのファイルに書きますが、
実際に１つのファイルだけで、確認できるために、html + JQuery + CSS を１つのファイルまとめて書いてみました。

###■内容のポイント
1. CSS でタブの表示
2. Jqueryタブの切り替え
　参考：[誰でも出来る！プラグインを使わずにjQueryで実装するタブ切り替え機能！](http://blog.three-co.jp/web/558/)
3. htmlメソッドを利用して要素配下のHTMLソースを設定
4. htmlタグ配下のhtml内容設定、表示
　参考：[要素配下のテキストを取得／設定するには？](http://www.buildinsider.net/web/jqueryref/004)




##headerの部分

1.タブの色を変える**CSS** の設定

```lang:tabChange.html_(header/css)

<!DOCTYPE html>
<html>
<head>

<style>
.tab{overflow:hidden;}
.tab li{background:#228B22; padding:10px 25px; float:left; margin-right:1px; height:50px;}
.tab li.select{background:#9ACD32;}
.content li{background:#9ACD32; padding:20px;}
.hide {display:none;}
</style>
```

2.タブを切り替える **JQuery**の部分。
JQueryを実行できるために、script srcを設定することを忘れないように。

```lang:tabChange.html_(header/JQuery_1)
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
<script>
$(function() {
    //クリックしたときのファンクションを指定
    $('.tab li').click(function() {

        //クリックされたタブの番号がindex変数に代入
        var index = $('.tab li').index(this);

        //コンテンツを一度すべて非表示
        $('.content li').css('display','none');

        //クリックされたタブと同じindex番号のコンテンツを表示
        $('.content li').eq(index).css('display','block');

        //一度タブについているクラスselectを消し
        $('.tab li').removeClass('select');

        //クリックされたタブのみにクラスselectをつけ
        $(this).addClass('select')
    });
});
```

3.scriptで、タブ内の要素は、htmlメソッドを使ってソースを設定します。

```lang:tabChange.html_(header/JQuery_2)

$(function() {
var result1 = '';
result1 += '<div class="content1">';
result1 += 'Apple';
result1 += '</div>';
$('#content1').html(result1);

var result2 = '';
result2 += '<div class="content2">';
result2 += 'orange';
result2 += '</div>';
$('#content2').html(result2);

var result3 = '';
result3 += '<div class="content3">';
result3 += 'Spring';
result3 += '</div>';
$('#content3').html(result3);

});
</script>

</head>

```

##bodyの部分

4.実際に表示する**html** の部分です。
contentの部分で、< li id=xxx > で、scriptでhtmlメソッドで設定した番号を指定すれば、ソースを反映します。

```lang:tabChange.html_(body)

<body>

<ul class="tab">
    <li class="select">Favorite fruit</li>
    <li>Favorite Color</li>
    <li>Favorite Season</li>
</ul>

<ul class="content">
    <li class =" " id = "content1">
　　<li class ="hide" id= "content2" ></li>
    <li class ="hide" id= "content3"></li>
</ul>

</body>
</html

```


上記4つのパーツを組み合わせれば、OK～～!

***
実際に conetent をもっと複雑な内容を表現したいですが、
まず、タブの変換ができまして、満足しました... ^^"
【MySQL】autocommit

##autocommitとは

**InnoDBではデフォルトでautocommitは有効。**この状態でトランザクションを実行せずにSQLを実行すると、1つのSQLごとにcommitが行われる。もちろんrollbackは行われない。
トランザクションを実行すれば、明示的にcommitしたタイミングでcommitは行われる。rollbackも可能。


無効にした場合、SQLの実行及びトランザクションの開始でトランザクションが開始する。トランザクションが開始するので、明示的なcommitでcommitされる。

##autocommitの変更方法
5.5.8移行であれば、my.cnfに書くことで変更可能。

```
[mysqld]
autocommit = 1
```

##疑問点

autocommitを無効にするシチュエーションがいまいちよくわからない。
OracleはMySQLと逆でautocommitがデフォルトでOFFらしいので、OracleからMySQLへDBを移行した場合なのかなと。詳しい人いたら教えてください。

参考
[MySQLのAUTOCOMMIT（オートコミット）覚え書き](http://open-groove.net/mysql/autocommit/)
[MySQLのautocommitとトランザクション分離レベルのメモ](http://qiita.com/rubytomato@github/items/562a1638191aacaeb333)
[MySQL]MySQL接続エラー(mysqlnd cannot connect to MySQL 4.1+ using the old insecure authentication)

# [MySQL]MySQL接続エラー(mysqlnd cannot connect to MySQL 4.1+ using the old insecure authentication)

## 事象
- PHPから外部DBであるMySQLへの接続でエラーが発生

## 確認内容
- 接続先情報について何度も確認したが問題ない
- 別サーバからの接続テストでMySQLへ接続できることを確認

## エラー内容をもうよく一度見る

### 英文
mysqlnd cannot connect to MySQL 4.1+ using the old insecure authentication. 
Please use an administration tool to reset your password with the command SET PASSWORD = PASSWORD('your_existing_password'). 
This will store a new, and more secure, hash value in mysql.user. 
If this user is used in other scripts executed by PHP 5.2 or earlier you might need to remove the old-passwords flag from your my.cnf file


### Google翻訳
mysqlndは、古い安全でない認証を使用して、 4.1以降のMySQLに接続することはできません。
コマンドSET PASSWORD = PASSWORD （ ' your_existing_password '）を使用してパスワードをリセットするには、管理ツールを使用してください。
これはにmysql.userに新しい、より安全、ハッシュ値を格納します。
このユーザーは、 PHP 5.2で実行される他のスクリプトで使用またはそれ以前のバージョンされている場合は、あなたのmy.cnfファイルから古いパスワードフラグを削除する必要がある場合があります

### 解釈
- 今の`mysqlnd`で接続できないってことか？

## 調べた
`MySQL 4.1+ using the old insecure authentication`で検索  
色々出てきましたよ

- [PHP5.3でMYSQL接続エラー(OLD_PASSWORDS=1)](http://www.ninton.co.jp/?p=1198)
- [PHPで「mysqlnd cannot connect to MySQL 4.1+ using the old insecure authentication.」エラーが発生した](http://piyopiyocs.blog115.fc2.com/blog-entry-844.html)
- [【php】mysqlndを使うとMySQLに接続できない？](https://www.softel.co.jp/blogs/tech/archives/2225)
- [公式ドキュメント](http://php.net/manual/ja/migration53.incompatible.php)
 
## 原因
- `mysqlnd`はMySQLの古い形式のパスワードをサポートしなくなった
	- 古い形式 : ハッシュ値の長さが16バイト

## 解決方法
- 接続したいユーザーのパスワードを「41バイトハッシュ」で再作成する

### やり方
- 「my.cnf」に「old_password=1」が設定されていないMySQLに接続
- パスワードの41バイトハッシュを作る（以下コマンド）

```
SELECT PASSWORD('abcdef');
# *C2D24DCA38E9E862098B85BF0AB35CAA52803797
```
- パスワードを更新する

```
SET PASSWORD FOR testuser@'%' = '*C2D24DCA38E9E862098B85BF0AB35CAA52803797';
```
 
これで新しいパスワードがセットされた  
再度接続したところ問題なく接続できた！！

## 本当は
- 本当は「my.cnf」の「old_password=1」を「old_password=0」にする必要がある
- その後mysqlを再起動
- 次回から作成するユーザーは「41バイトハッシュ」されたパスワードになる
    - 既存のユーザーパスワードは「16バイトハッシュ」されたパスワードのまま

**だが本番稼働しているので、そんなことできない！**

なので今回のような解決方法を取りました。
以上です。
第3話 持ち物

**朝、持っていくものは確認するように！**

いろんな事件に巻き込まれる太郎と次郎は普段から十分に準備が必要と考えたことをコード化しようとしているところです。

こんな感じはどうだろう...

```php:Item.php
class Item implements JsonSerializable {
    private $properties;
    function __construct($param = []) {
        $this->properties = $param;
    }
    function __set($name, $value) {
        $this->properties[$name] = $value;
    }
    function __get($name) {
        return $this->properties[$name];
    }
        function toArray() {
        return $this->properties;
    }
    function jsonSerialize() {
        return $this->toArray();
    }
}
```
いろいろな属性を持った持ち物があるので、例えば

```php:yomple.php
$bat = new Item();
$bat->name = '金属バット';
$bat->type = 'Weapon';
$bat->attackPoint = '3d6';

$nabe = new Item();
$nabe->name = 'アルミの鍋';
$nabe->type = 'Helmet';
$nabe->defencePoint = 3;

$coke = new Item();
$coke->name = '黒い炭酸水';
$coke->type = 'Drink';
$coke->recoveryPoint = 7;
```
みたいな感じで作っておいて、データベースに格納してみる。思いつきで、属性を増やしてみたりしそうだし、この性質上、MySQL的なRDB向きではないと思われる。なのでMongoDB使ってみる（実は初めて使うｗ）

```php:mongolian_chop.php
$mongo = new MongoClient();
$db = $mongo->test;
$col = $db->item;
$col->insert($bat->toArray());
$col->insert($nabe->toArray());
$col->insert($coke->toArray());
```
※例外処理とか書いてません（見ればわかる）
ついでに、ちゃんとデータベースに登録できたかを確認してみた。

```php:yondemiru.php
abstract class UsableItem {
    protected $item;
    function __construct($item = null) {
        $this->item = $item;
    }
    function doAction() {
    }
}

class Weapon extends UsableItem {
    function doAction() {
        echo $this->item->name."を振り回して".dice($this->item->attackPoint)."のダメージを与えた<br>";
    }
}

class Helmet extends UsableItem {
    function doAction() {
        echo $this->item->name."を深くかぶり、".$this->item->defencePoint."のダメージを防いだ<br>";
    }
}

class Drink extends UsableItem {
    function doAction() {
        echo $this->item->name."を一気に飲み干して、体力が".$this->item->recoveryPoint."回復した<br>";
    }
}

$cur = $col->find();
foreach ($cur as $item) {
    $tmp = new Item($item);
    $class = $tmp->type;
    $use = new $class($tmp);
    $use->doAction();
}
```
ちゃんと登録できてた。なんか、こういうのに使えそう。
しかしながら、ぅ～ん...一意キーとかないし、もうちょっと考えたほうがいいｗ

とりあえず、アイデアをコード化（備忘メモ）したものですｗ
単体だと動くのに複数Cookbook組み合わせたら動かないときのデバッグ方法

# とりあえず、berks updateしてみる

最新版だと直っている可能性もあるので、最新版を試してみる。

```sh
$ chef exec berks update
```

それでもダメなら

# デバッグ方針

エラー文を注意深く読んで、まずはエラーが出ているRecipeを突き止める。
その後、どこまでは期待通りに動いているのか可能な限り絞り込んでいく。外部のリソースだろうがローカルに保存して書き換えるくらいの心意気が大事。

# テスト環境構築

ChefDKをサクッと入れておきます
https://downloads.chef.io/chef-dk/

これで、test-kitchenを使ってテストができます。使い方は[公式ドキュメント](http://kitchen.ci/docs/getting-started/)にお任せして割愛。

# 一部のcookbookだけ差し替える

## 差し替え方法

問題のcookbookをローカルに保存します。
git cloneしてくるも良し、berks vendorしてからmvするも良し。

そして、``Berksfile``を開き、cookbookの参照先をローカルパスに差し替えます。

```rb
# Berksfile
cookbook 'buggy_cookbook', path: '/path/to/cookbook'
```

GitHub上でForkしてgit urlをfork先のものに変える方法もありますが、ローカルで書き換えた方が圧倒的に早いので、pathで指定することをお勧めします。

念のため、再現できるか確認。

```sh
$ chef exec kitchen test
```

無事再現した場合は、思う存分デバッグコードを仕込みます。

# デバッグ方法

## Log Level Debug

ChefのログレベルをDEBUGにして、情報を増やしてみる。

```sh
$ chef exec kitchen test -l debug
```

## log

古き良きprintデバッグ。実行時の値をチェックしたいのでlazy付けます。付けないと、コンパイル時に評価されてしまいます。

```rb
# recipes/xxx.rb
log 'check variable' do
  command lazy { "Value is #{SOME_VARIABLE}" }
end
```

## remote_file -> cookbook_file

例えremote_fileだろうが、wgetしてローカルで書き換えます。filesディレクトリに保存しておけば、recipeから参照しやすくなります。

```sh
$ wget -o files/default/yyy.sh http://example.com/yyy.sh
```

remote_fileの代わりにfiles下のファイルを指定するために、cookbook_fileメソッドに書き換えます。

```sh
$ git diff
-remote_file '/usr/local/src/yyy.sh' do
-  source 'http://example.com/yyy.sh'
+cookbook_file '/usr/local/src/yyy.sh' do
+  source 'yyy.sh'
```

Shell Scriptなら、set -xでデバッグフラグ立てておくと変数の値等が見れて役立ちます。

## kitchen login

インスタンスの中に乗り込んで、現状を調査します。

```sh
$ chef exec kitchen login
```
linq.jsでlinqの勉強

#概要
linqを勉強したかったが、visualstudioを開く気力はなかった。
linq.jsをjsdo.itでホスティングした。
#fizzbuzz
http://jsdo.it/ohisama1/8Em2 
#即、実行、linq pad
http://jsdo.it/ohisama1/cCEk
#rssを操作
http://jsdo.it/ohisama1/a0Fn
#jsonを操作
http://jsdo.it/ohisama1/yk0l
個人TODOをTrelloで管理してみた

[Trello](https://trello.com/)はクラウド形のタスク管理ツールで、チーム作業の管理などによく使われるのだけど、個人のタスク管理にも威力を発揮する。Qiitaにも色々記事があるようだけど、僕自身の使い方で少しずつノウハウがたまってきたのでメモる。ただ、Trello自体柔軟な使い方のできるアプリなので、全然違うやり方もあるかもしれない。参考までに。

## 構造

### board

大分類で一つの画面。たとえば、僕なんかは、生活、電子工作、趣味、ソフトウェアみたいな感じのボードを作成している。

### list

画面上では一つの列として表示されている。僕は最初これを種類として扱っていたが、実は後ほど出てくるlabelで十分管理が出来ることがわかった。今はどのボードでも、作業中・プロジェクト・気が向いたら・完了の四つかプラスアルファで使っている。

### card

一つのリストの中に無数のcardが入る。一つのプロジェクトだったり一つのタスクだったり。ボード上ではカードはタイトルとラベルしか表示されないが、クリックすると詳細が表示される。個人的には詳細状態じゃない場合の、カードの表示のシンプルさが気に入っているポイントの一つだ。

詳細機能|内容
-------|----
members|チーム作業するなら作業者を設定する(個人で使うなら関係ない)
description|そのカードの説明。comments についつい書きそうになるが、comments は「流れてしまう」ので要注意
comments|作業のコメントを残すには少し不向き。別途Wikiなりなんなりに残す方が良い。理由はカードに対する操作(activitiy)によってコメントが流れてしまう
Labels|ラベルは、ボードごとにラベルが設定できる。色と文字列。ここに種類を書くといい
Checklist|チェックリストはTODOリストとも言える。たとえば具体的な作業内容を書いて、完了したらチェックしていくような形になる
Due Date|カレンダー機能と連動できる日付設定。アラートとか来るのかな？まぁ時々カレンダー眺めておくと幸せになれるかもしれない

## 僕の使い方

大きく分けてプロジェクトと作業の二種類に分かれる。

プロジェクトは、たとえば「ガンダムのプラモデルを作る」「自宅鯖一号くんを作る」など。

作業は大体一時間〜四時間くらいで終わる具体的にかみ砕いた作業を書く、たとえば「上半身を組み立てる」「自宅鯖一号君にNginxを入れる」など。

### プロジェクト

プロジェクトにチェックリストを作成しておおざっぱなTODOを書き連ねていく。スクラム用語で言うところのプロダクトバックログ。ここに書かれたものをそのまま作業に回せるのがベストだけど、作業工程が見えてない場合は大きい粒度でも大丈夫。とりあえず必要そうな事を書いていけば良い。

プロジェクトを書き連ねたら、たとえば優先順位で並び替えるなどしてから、優先順位の高い物や気が乗ったプロジェクトの中で、次、どういう作業をするかを考えて「作業」を書き出す

### 作業

たとえばあるプラモを作る時に上半身が大体二・三時間程度でくめるとしたらまず作業に「ガンダムの上半身を組み立てる」と書く。ラベルはきっと「プラモ」とかになるはず。この作業のチェックリストにはもっと具体的な作業を書く「腕を組み立てる」「顔を組み立てる」「胸部を組み立てる」など。それぞれ工程が進めばチェックリストを塗りつぶしていって、全体が完了したら、このカードを「完了」のリストに移動する。

僕はよくこの作業を Phase.1 とか読んだりしている。プラモ作りPhase.1で上半身を組み立てて、Phase.2で下半身を組み立てて、Phase3.で全体をくみ上げる、Phase.4で色を塗って完成みたいな。

### ポイント

- 僕は割とやりたい事が多いので、やりたい事をとにかく全部書き出して、頭をすっきりさせる。夢物語なんかも書き出す。そういうのは「気が向いたら(プロジェクト)」「夢物語(プロジェクト)」とかに入る
- 作業リストを一時間〜四時間程度にする理由は、それくらいの粒度だとさくさく進んで楽しいし、他の人の割り込みからも強い、時間が取りやすいなど。一日仕事レベルになると、何らかの理由でのびのびになってしまいがち。なるべくなら二時間程度の作業に抑えておくと良い
- 完了リストは、目に見えるご褒美。作業がそれだけ進んだという自分へのご褒美であり自尊心を満たしてハッピーになるためのもの。数が多くなってきたらarchiveする
- 見積もりのたたない作業の場合、「見積もりを立てる為の調査をする」という作業を用意するのも手。なるべく手を動かしながら見積もる為の情報を集める

現状ではこんなところかな。こういうツールではついつい抽象的な目標を書いてしまう事があるけど、そういうのはせいぜいプロジェクトまで。作業リストはとにかく具体的にする、短い時間で完了する、の二点を心がける。あんまり凝った事すると続かないので、なるべくシンプルに使うべき。
GitHub Pages のプロジェクトリポジトリにHugo製ジェネレータを用いてプロジェクトの静的ページを作成する．


## 目的
* GitHub Pagesのプロジェクトページに静的ページを配置する．
* 端的にコマンドを実行し続けるだけで生成できるようにする．

## 準備

### Hugoのインストール

```
brew install hugo
```

### Hugoを用いてサイトを生成する

下記のコマンドでsiteを一発で生成する事が出来る．
今回はtestpageという名前のsiteを生成する．

```
hugo new site testpage
cd testpage
```

### Hugoのテーマをインストール

まずはテーマ適用のためにディレクトリを作成する．
作製位置は，testpageのすぐ下になる．

```
mkdir themes
cd themes
```

次に，Installしたいテーマを決めてcloneする．
今回はhugo-base-themeというテーマを利用したため，以下のようなコマンドになる．

```
git clone https://github.com/crakjie/hugo-base-theme.git hugo-base-theme

# もし任意のテーマをインストールする場合は，
# git clone https://github.com/[username]/[userproject].git [userproject]
# と実行する事で，themesの下に [userproject]という名前のテーマのディレクトリが生成できる．
```

### Hugoのテーマを適用させる
テーマを適用させるには，

```
# testpageディレクトリに戻り
cd ..

# テーマを適用
hugo -t hugo-base-theme
```

上記のコマンドで実行可能

### サーバを建ててテーマが適用されているか確認

```
hugo server -t hugo-base-theme
```

## Github にProjectリポジトリを作成する


### Githubリポジトリを作製
これは各自でお願いします．
私は 同名のtestpageというディレクトリを生成しました．

### config.tomlを編集する
terminal内のtestpage配下に存在する`config.toml`を編集します．
以下のサイトを参考にしました．
[Hugo Part 2 - Hugo で github にブログを立ち上げる](http://blog.syati.info/post/create_hugo_2/)

```config.toml

title = "My New Hugo Site"
baseurl = "http://shopetan.github.io/testpage"
languageCode = "ja-jp"
theme = "hugo-base-theme"　# part 1 で選んだ theme を設定する
canonifyurls = true # 相対パスではなく baseurl を基点とした絶対パスにする

[params]
  description = "This is yourblog"
    author = "your name"

[taxonomies]
  category = "categories"
    tag = "tags"

```

## Git管理を開始する

Github側で何かREADME.mdファイルなどを追加していた場合は以下のようにしてgit pullしておきます．

```
git init
git remote add origin git@github.com:shopetan/testpage.git
git pull origin master
```

次に，現在存在している `public`ディレクトリは削除します．

```
rm -rf public
```

後はいつも通り

```
git add .
git commit -m "First commit"
git push origin master
```

でOKです．

## 公開準備

Github pagesで公開する為には，`gh-pages`というブランチを新たに作成し，index.htmlを含めている必要があります．

まずは`gh-pages`にブランチを切り，

```
# --prphanオプションを付ける事で，他のブランチと独立して管理
git checkout --orphan gh-pages
```

既存の管理していたファイルを除外する．

```
git rm -f --cached $(git ls-files)
```

とりあえず，適当にREADME.mdファイルを追加して反映させる．

```
echo "# testpage" >> README.md
git add README.md
git commit -m "Initial commit on gh-pages branch"
git push origin gh-pages
```

masterブランチに戻り，公開準備．
gh-pagesをsubtree化することで，masterブランチにgh-pagesで変更したpublicの内容を反映させる事ができる．

```
git checkout master
git subtree add --prefix=public git@github.com:shopetan/testpage.git gh-pages --squash
git subtree pull --prefix=public git@github.com:shopetan/testpage.git gh-pages
```

## 実際にデプロイを行う．
ここまで出来たら簡単で，後は何か変更を加えるたびに以下のコマンドを入力するだけでOKになる．

```
# testpageディレクトリから，以下のコマンドを打つだけ

hugo -t hugo-base-theme
git add .
git commit -m "Updating site"
git push origin master
git subtree push --prefix=public git@github.com:shopetan/testpage.git gh-pages
```

## 参考

* [Hugo Part 2 - Hugo で github にブログを立ち上げる](http://blog.syati.info/post/create_hugo_2/)
* [公式のDocument](http://gohugo.io/tutorials/github-pages-blog/)
* [公式を日本語訳したサイト](http://www.kotazi.com/blog/post/2015111301/)
PhantomJS で Web ページのスクリーンショットを保存する

[PhantomJS | PhantomJS](http://phantomjs.org/)


PhantomJS を利用する上では基礎中の基礎みたいな話なので簡潔に書く
環境としては、CoffeeScript で書いて `npm install` した後に `npm run start` をする
まぁ公式を見ればすぐにできることである


<a href="http://phantomjs.org/api/webpage/method/render.html">render | PhantomJS</a>


以下が、作成したもの

```js:package.json
{
  "name": "screenshots"
  "version": "1.0.0",
  "description": "Renders the web page to an image buffer and saves it as the specified filename.",
  "scripts": {
    "start": "coffee -c index.coffee && node_modules/phantomjs/bin/phantomjs index.js",
  },
  "dependencies": {
    "phantomjs": "^2.1.3"
  },
  "engines": {
    "node": "5.5.0",
    "npm": "3.3.8"
  }
}
```

```coffeescript:index.coffee
page = require('webpage').create()

page.open 'http://www.yjfx.jp/', (status) ->
  console.log 'Status: ' + status
  if status == 'success'
    page.render 'yjfx.png'
  phantom.exit()
  return
```

生成物は省略
かなり簡単に Web ページのスクリーンショットが生成できる
もっと楽にスクリーンショットが欲しいのであれば Chrome 拡張機能 を使えばいい





追記

このページをスクリーンショットする場合は `page.viewportSize` を設定すると大きいサイズで保存できます

```coffeescript:index2.coffee
page = require('webpage').create()

page.open 'http://qiita.com/makietan/items/bce761dcc9ac468cf53a', (status) ->
  console.log 'Status: ' + status
  if status = 'success'
    page.viewportSize = { width: 1920, height: 1080 }
    page.render 'qiita.png'
  phantom.exit()
  return
```

結果画像

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/30241/5aa44d14-e35d-a49a-fc97-8cc1b007cbdd.png)
さくらのクラウドのKUSANAGIを利用したときにThemeSwitcherでテーマが読み込まれなかった件の対処

# はじめに
さくらのクラウドでKUSANAGIアーカイブを利用しています。
ポイっと使うだけでKUSANAGI早いので便利です。

が、その中で一点、うまく行かない点があったので手動で修正・対処した点のメモです。

2016年10月18日(火)追記
wp-cliを使う解決方法を載せました。

# 問題
KUSANAGIプラグインに「Theme Switcher」(デバイス切替)と呼ばれる、スマホなどによってテーマを切り替える機能があります。
案件によってはレスポンシブではなくテーマを切り替える必要があったりして、その時にすごく便利な機能です。

しかしながらこの機能を使おうとした際にテーマが認識されませんでした。

![Screen Shot 2016-02-02 at 3.23.06 PM.png](https://qiita-image-store.s3.amazonaws.com/0/47327/86aba0e8-2083-0268-ebba-84b7e1aa2fba.png)

上記のように「Theme Switcher」ではデフォルトのテーマしか見えていません。
WordPressの管理画面 ＞ 外観からは追加したテーマがちゃんと見えていますので、テーマが壊れているということはなさそうです。

# 新対処
以前はソースコードを編集していましたが、構築する毎に編集するのは大変でしたのでwp-cliを利用しました。
KUSANAGIであればデフォルトでwp-cliが使えます。
WordPressがインストールされたディレクトリ( 例: /home/kusanagi/example.com/DocumentRoot )で`wp`コマンドを実行します。

```bash
$ wp transient delete avaiable_themes
Success: Transient deleted.
```

これでキャッシュをクリアすることが出来ました。簡単ですね！

# 対処
対処はソースコードを修正しました。

```php:/home/kusanagi/example/DocumentRoot/wp-content/mu-plugins/kusanagi-core/modules/theme-switcher.php
   public function get_avaiable_themes() {
-                if ( false === ( $this->avaiable_themes = get_transient( 'avaiable_themes' ) ) ) {
+                if ( true || false === ( $this->avaiable_themes = get_transient( 'avaiable_themes' ) ) ) {
                        if ( function_exists( 'wp_get_themes' ) ) {
                                $this->avaiable_themes =  wp_get_themes();
```

if文の中に `true ||` を突っ込みます。
これで出てきます。

一度設定できたら元に戻しても良いです。
または **1日待てば戻ります**。

# 原因
KUSANAGIではテーマ一覧を取得する際に`get_transient()`という一時的なキャッシュを利用しているようです。このキャッシュの期間が1日になっているため、初回の色々と設定しているときにテーマ一覧が反映されない！となるようです。
KUSANAGIは色々なインスタンス上で動くようになっていますので、他の環境では発現しないかもしれません。
KUSANAGIプラグインの元(?)の「[SiteManager](https://ja.wordpress.org/plugins/wp-sitemanager/screenshots/)」では発生しない(らしい)です。
MySQLが動かなかった時のメモ

MySQLをインストールして、いつもの設定をmy.cnfに記述したが動かなかった時のメモ。

```
#service mysqld start

MySQL Daemon failed to start.
Starting mysqld:                                           [FAILED]
```

まずはログ。

```
tail -f /var/log/mysqld.log
```

気になる一行発見。

```
mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
/usr/libexec/mysqld: Character set 'utf8mb4' is not a compiled character set and is not specified in the '/usr/share/mysql/charsets/Index.xml' file
[ERROR] Aborting
```

取り敢えずmy.cnfの'utf8mb4'を'utf8'に変更で次エラー。

```
[ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.host' doesn't exist
```

初期テーブルが作成されていないのか、データベースディレクトリがどこだかわからない状態になっているか...。

```
mysql_install_db --datadir=/var/lib/mysql --user=mysql
```

これで無事起動できました。

参考：
[MySQLをインストールしたけどなかなか起動できない](http://absg.hatenablog.com/entry/2014/08/12/160716)
[MySQLをstartしたら[ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.host' doesn't existがでたとき](http://qiita.com/840_/items/06f32fecbe57c3fdf5ec)
ボタンをクリックして非表示だった要素を表示させる

jQueyでshow,hide,toggle

メモ

■HTML

```
<p>1+1=?</p>
<button class="answer_button">解答</button>
<div id="answer" class="dis_n">
<p>正解:2</p>
</div>
```

■CSS

```
.dis_n {
 display: none;
 }
```

■JavaScript

```
$(function(){
  $(".answer_button").on('click', function(){
    if($('#answer').css('display') == 'block'){
      $("#answer").hide();
    }else{
      $("#answer").show();
    }
  });
});

または

$(function(){
　$(".answer_button").on('click', function(){
　　$("#answer").toggle();	
});
```
---
![スクリーンショット 2016-02-02 18.13.41.png](https://qiita-image-store.s3.amazonaws.com/0/109842/8c50bc63-2cf6-a6bf-aa15-edebac3c291e.png)
↓解答ボタンをクリックすると  
![スクリーンショット 2016-02-02 18.13.55.png](https://qiita-image-store.s3.amazonaws.com/0/109842/415724b2-04c7-dbe6-ae59-1ae02fd35f27.png)
--- 
 
もう一度クリックすると非表示になる
ACMでSSL証明書0円運用ができなかったはなし

# まえがき
(2016/02/02 22:50 追記)
この記事でとりあげるのは一般的なウェブシステム(LAMP)です。
[後述](#ssl証明書0円運用はできないのか)しますが全てのケースにおいてSSL証明書0円ができないわけではありません。

----

# はじめに

1/22にAWSに新機能「AWS Certificate Manager」(ACM)が追加されました。
ELBとCloudFront限定ですが無料でSSL証明書を発行できて，しかもワイルドカードにも対応しているイケてるサービスです。

残念ながら2/2現在，米国東部 (バージニア北部)でしか使えないので東京にあるELBでは使用できません。
CloudFrontはリージョン関係ないので今日から恩恵にあずかれる・・・・はずでした。

# 何が起こったか

ある日を境にhttps接続で502が返ってくるようになりましたorz

# 事の始まりは

とあるサービスのSSL証明書が有効期限をまもなく迎えようとしているとある日，ACMなるサービスが発表されました。
ちょうどいい機会だったので今まで使用していたSSL証明書は廃止してACMに全面移行しようと考えました。

その時の構成は東京リージョン内で ELB + EC2 という構成を取っていました。
残念ながらACMは未だ東京では使用できないため必然的にCFを使うことになります。

CFとACMの設定については割愛しますが，問題なく稼働していることが確認できたのでこのままSSL証明書0円運用を始めました。


# そして事件が起こる

ACMによるSSL証明書0円運用を始めて1週間ほど経った日，既存のSSL証明書の有効期限を迎えました。

CFはELBと違いオリジンの証明書の正当性を要求するため，有効期限切れのSSL証明書を使っている限りCFはオリジンと通信ができません。
そのためCFは502を返していたのです。

ドキュメントに以下のように書いてあります。

> ステップ 3 でオリジンと通信するときに HTTPS を使用するように CloudFront を構成した場合、CloudFront は確立されたサードパーティ認証局によって証明書が発行されたことを確認します。CloudFront は Mozilla と同じ認証局をサポートします。現在のリストについては、「Mozilla に付属する CA 証明書一覧」を参照してください。自己署名証明書を使用することはできません。

http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/SecureConnections.html

# どう対応したか？

今回は障害を解消するスピードを優先するためにSSL証明書を買いました。

# SSL証明書0円運用はできないのか？

結論から言うと限られた条件を満たした場合にとSSL証明書0円運用は可能です。
CFはオリジンのSSL証明書の正当性を要求するためオリジンに有効なSSL証明書がインストールされていれば良いのです。

1. オリジンとしてS3を使用する
2. オリジンへのアクセスは全てhttpとする
3. 米国東部(バージニア北部)を使用する
4. [StartSSL](https://www.startssl.com)などで無料のSSL証明書を取得する

1.のパターンは言わずもがなですね。
問題として静的なものしか配信できないです。
2.のパターンは最大の問題としてオリジンとの通信が暗号化されないです。
AWS内の通信になるはずなので盗聴は現実的でないかもしれませんが，暗号化すべきデータが暗号化されていない状態になるのは避けたいところです。
3.のパターンはELBはバックエンドのSSL証明書エラーを無視できることを利用します。
ELBでACMを使用するために米国東部 (バージニア北部)を使用する必要があります。(2/2現在）
4.のパターンは無料のSSL証明書を使用していることをエンドユーザからは隠せることがメリットですかね。
ACMも無料じゃんと突っ込まれそうですがAWSが証明してくれている安心感？があると思います。

# まとめ

ACMでSSL証明書0円運用を試みて見事に失敗しました。
実は障害を起こしたのは本番運用しているサービスでした。
CFはバックエンドのSSL証明書をチェックしないと思い込んでいたためのミスです。
これを公開することで同じ失敗が繰り返されないことを願っています。
【Github】一台电脑使用多个 Github 账户


### 账户所用 SSH 秘钥生成

```
$ cd ~/.ssh
$ ls
id_rsa id_rsa.pub

$ ssh-keygen -t rsa -c [mail] -f [filename]
```

### 将生成的 SSH 秘钥登录到 Github 账号中

登录 Github 账户，进入 https://github.com/settings/ssh 
「Add SSH Key」中，将新生成的 .pub 秘钥粘贴至输入框

### 编辑 ~/.ssh/config

对文件 ~/.ssh/config 进行编辑（如文件不存在则新建一个）：

```
Host github.com
  HostName github.com
  User git
  Port 22
  IdentityFile ~/.ssh/id_rsa  # 主账号所使用的 SSH 秘钥
  TCPKeepAlive yes
  IdentitiesOnly yes
Host github.com.sub  # (1) 副账号：可任意命名
  HostName github.com
  User git
  Port 22
  IdentityFile ~/.ssh/id_rsa_sub  # (2) 副账号所使用 SSH 秘钥路径
  TCPKeepAlive yes
  IdentitiesOnly yes
```

### 使用副账号 clone 远程仓库
正常情况下 ```git clone``` 与 ```git remote add```：

```
$ git clone git@github.com:xxx/multi-account-sample.git
$ git remote add origin git@github.com:xxx/multi-account-sample.git
```

在使用副账号时则将@之后的部分进行修改

```
$ git clone git@github.com.sub:xxx/multi-account-sample.git
$ git remote add origin git@github.com.sub:xxx/multi-account-sample.git
```

### 设置副账号的 ```user.name``` 和 ```user.email```
在副账号所管理的文件下，执行一次如下命令：

```
$ git config user.name [sub_account.user_name]
$ git config user.email [sub_account.email]
```
UnityでLive2Dの複数モーション再生

Live2Dでアイドルモーションしつつ、顔だけモーション変えたいという場合に有効な方法をメモしておきます。
やり方は簡単で、モーション管理してるクラスのMotionQueueManagerを2つ作ればできます。

# 開発環境
・Live2D_SDK_Unity_2.1.00_1_jpのMotionプロジェクト
・Unity 5.2.0

# 複数モーション再生のやり方

**１）まずは顔だけのモーションを作ります。**
SDKサンプルのモーションファイル(.mtn)を開き、顔以外のパラメーターは削除しました。
ここではざっくりやりますが、本当は尺の長さは再生するもう1つのモーションと合わせた方がいい感じになるかと思います
<img width="449" alt="スクリーンショット 0028-02-02 17.51.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/15028/0ad07a4c-d6fa-f32a-7aaa-9a39d81f0201.png">


**２）Live2D Viewerで動作確認**
モーション1を再生しつつ、顔だけモーション再生してみます

・モーション1を再生した場合
![defaultmotion.gif](https://qiita-image-store.s3.amazonaws.com/0/15028/abac9691-33b8-7c8e-241c-14537c048eee.gif)

・モーション１再生後に顔だけモーション再生した場合
![mixmotion.gif](https://qiita-image-store.s3.amazonaws.com/0/15028/f5e7181e-1859-759b-4dbd-9da3f6398cd4.gif)


**３）ソースを修正して、Inspectorにモーションファイルをアタッチ**

```csharp:SimpleModel.cs
using UnityEngine;
using System;
using System.IO;
using System.Collections;
using live2d;

[ExecuteInEditMode]
public class SimpleModel: MonoBehaviour 
{
	private Live2DModelUnity live2DModel;
    private Live2DMotion motion;
	private Live2DMotion faceMotion;			// Add
	private MotionQueueManager motionMgr;
	private MotionQueueManager faceMotionMgr;	// Add

    private Matrix4x4 live2DCanvasPos;

    public TextAsset mocFile ;
    public Texture2D[] textureFiles ;
    public TextAsset motionFile;
	public TextAsset faceMotionFile;	// Add

	void Start () 
	{
        Live2D.init();

        live2DModel = Live2DModelUnity.loadModel(mocFile.bytes);

        for (int i = 0; i < textureFiles.Length; i++)
        {
            live2DModel.setTexture(i, textureFiles[i]);
        }

        float modelWidth = live2DModel.getCanvasWidth();
        live2DCanvasPos = Matrix4x4.Ortho(0, modelWidth, modelWidth, 0, -50.0f, 50.0f);

        motionMgr = new MotionQueueManager();
		faceMotionMgr = new MotionQueueManager();	// Add
		motion = Live2DMotion.loadMotion(motionFile.bytes);
		// Add
		faceMotion = Live2DMotion.loadMotion(faceMotionFile.bytes);	
	}
	

    void Update()
    {
        if (live2DModel == null) return;
        live2DModel.setMatrix(transform.localToWorldMatrix * live2DCanvasPos);

        if (!Application.isPlaying)
        {
            live2DModel.update();
            return;
        }

        if (motionMgr.isFinished())
        {
            motionMgr.startMotion(motion);
        }
        motionMgr.updateParam(live2DModel);

		// Add
		if (faceMotionMgr.isFinished())
		{
			faceMotionMgr.startMotion(faceMotion);
		}
		
		faceMotionMgr.updateParam(live2DModel);

		live2DModel.update();
    }

	
	void OnRenderObject()
	{
        if (live2DModel == null) return;
		live2DModel.draw();
	}
}
```

これで顔のパラメータが上書きされ複数モーション再生できました
![finalmotion.gif](https://qiita-image-store.s3.amazonaws.com/0/15028/0ac09b77-28ad-2cd8-513e-570841fe6c20.gif)
ログファイルが複数あるんだけど、全部に RequestId 入れたい

# 結論
``config.log_tags = [:request_id]``
しといて、 (Rails5ではデフォルトで設定されている。 Rails4以前は `:uuid` )
``ActiveSupport::TaggedLogging.new(Logger.new('log/my_great_module.log'))``
を好きなだけ書く。

# 状況

そもそもログファイル複数ってどうなのよ一本化しろよ fluentd とかしろよ、という正論はさておき、世の中にはどうしても立ち向かわねばならない状況というものがあります。
大きなシステムのあちこちのモジュールで個別にログファイル出力してるんだけど、アクセスが集中するとタイムスタンプだけで対応を読むのは限界があり、なんかリクエスト毎に固有キーかなんかで grep 出来たらいいのになと
# そこで X-Request-ID
X-Request-ID ヘッダというのは、個々のリクエストに固有のユニークな文字列で、 nginx や apache が付けてくれたり、誰も付けなければ rails が付けたりします。誰が付与するかはこの際どうでもよくて、 rails の action が動く時点では既に付与されており、 ``request.uuid`` で取得することができます。
なので、すべてのログ出力に request.uuid をセットで吐き出すようにすれば、複数のログファイルを跨いで「このリクエストに関連する全てのログを横断的に見たい」というようなことが grep で簡単に実現できるわけです。

すべてのログ出力に request.uuid をセットで吐き出すようにすれば。。。

なんかうまいことこれをやる方法はないだろうか、というわけで検索すると

# config.log_tags = [:uuid]

これだーー！これこそ私の求めていたものださすが rails 様、我々愚民の望みなど全てお見通しなのだッッッと一瞬歓喜するわけですがいやちょっと待て。
私の rails プロジェクトではあちこちで ``Logger.new('my_great_module.log')`` みたいなことをしているのだが、 ``log_tags`` を設定するだけでこれら全てで uuid が吐き出されるようになるなんていう不思議な事はもちろん起きそうになく、実際起きない。
ところでこの log_tags ってのはどういう仕組なのだろう？と探していくと rack の塔をいくつか登って以下のコードにたどり着きます。

https://github.com/rails/rails/blob/v4.2.5/railties/lib/rails/rack/logger.rb#L20

Rails.logger が ``tagged`` メソッドを持っていればそれを呼んでくれる、とな。

この tagged というメソッドで検索をかけると ``ActiveSupport::TaggedLogging`` が見つかりまして、とりあえず、デフォルトの Rails.logger は tagged に対応している、ということと、自前で
 Logger を初期化するときには
 ``ActiveSupport::TaggedLogging.new(Logger.new("log/#{Rails.env}.log"))`` 
 といようにデコレートすれば良いということがわかります。
 
とりあえずこれで、 Rails.logger を使う限りは RequestId が自動的に付与される仕組みがわかったわけですが、じゃあこの ``Rails.logger.tagged`` を拡張して、自前の ``Logger`` インスタンス全部の tagged をコールしてくれるように改造すれば、と考え始めた所でふとあることに気づく。

https://github.com/rails/rails/blob/v4.2.5/activesupport/lib/active_support/tagged_logging.rb#L46

# こいつ、スレッドローカル変数を使っている。。。？
そうなのです。あるスレッド内のどれか1つの ActiveSupport::TaggedLogging インスタンスがタグ付けされれば、同じスレッドの全てのインスタンスは自動的にタグ付けされる仕組みになっていたのでした。
(railsはnode.jsのようなイベントドリブンモデルではないので、あるスレッドがリクエストを受け取ったら、レスポンスを返すまで他のリクエストの処理に関わることはない)
で、リクエスト毎に前述の Rack::Logger が Rails.logger に対してタグ付けを自動的にしてくれるので、Rails.logger だけは忘れずに TaggedLogging でデコレートしておき、あとは好きな場所で好きなだけ Logger インスタンスを作り、uuid つけたいログには TaggedLogging でデコレートしてやれば、その全てに自動的に RequestId を付与することが出来る、というわけでした。
さすが rails 様。

# おまけ
## RequestId長すぎ。6文字もあればいいでしょ。
``config.log_tags = [->(req){req.uuid.first(6)}]``
BeanstalkでSSHアクセス制限を行うためのconfig


Beanstalkで起動するEC2インスタンスは自動的に作られるセキュリティグループ(awseb-e-xxxxxxxxxx-stack-AWSEBSecurityGroup-XXXXXXXXXXXXXのような名前のもの)が紐付きます。

このセキュリティグループはロードバランサーのリスナーポートの設定によって変わりますが、HTTPSを受け付けるWebサーバだと例えば以下のようになっています。

|タイプ|プロトコル|ポート範囲|送信元|
|---|---|---|---|
|SSH|TCP|22|0.0.0.0/0|
|HTTPS|TCP|443|0.0.0.0/0|

HTTPSが全開放なのは問題無いですが、SSHが全開放なのはセキュリティ的によろしくありません。.ebextensionsにこの設定を変更するためのconfigを置くことでSSHアクセスのIP制限を行うことができます。

```.ebextensions/00-option-settings.config
option_settings:
  - namespace: aws:autoscaling:launchconfiguration
    option_name: SSHSourceRestriction
    value: tcp, 22, 22, 12.34.56.78/32
```

これで12.34.56.78からのみSSHアクセスを受け付けるようになります。

ちなみにAutoScalingの設定であるにもかかわらず、シングルインスタンスでもこの設定は有効でした。

参考
- [AWS Elastic Beanstalk＞環境設定＞.ebextensions＞オプション設定](http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/ebextensions-optionsettings.html)
- [AWS Elastic Beanstalk＞環境設定＞設定オプション＞汎用オプション](http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/command-options-general.html)
Mondo Rescue を使ったバックアップとリカバリ

## 0. 参考

* 本家 http://www.mondorescue.org/
* Centos7手順 http://www.maruweb.jp.net/wp/?p=1860
* Centos6.6手順 http://www.maruweb.jp.net/wp/?p=1860
* リカバリ後のネットワーク調整
  http://qiita.com/satomin/items/964182390a08b678d576


## 1. インストール

### 1.1. 環境

* CentOS 7
* CentOS 6.6

### 1.2. yumリポジトリからインストール

* リポジトリURL http://www.mondorescue.org/ftp/

#### 1.2.1 yumリポジトリを追加する。 

```
yumリポジトリディレクトリに移動
# cd /etc/yum.repos.d 

ダウンロード（CentOS7系）
# wget http://www.mondorescue.org/ftp/centos/7/x86_64/mondorescue.repo

ダウンロード（Rhel6、CebtOS6系）
# wget http://www.mondorescue.org/ftp/rhel/6/x86_64/mondorescue.repo
```

#### 1.2.2. インストール

```
リポジトリの読み込みを確認する（結果にmondoが表示される）
# yum list mondo

インストール
# yum install mondo
```

### 1.3. 関連パッケージのインストール

* lzo（高速圧縮ライブラリ）
* lzop（高速圧縮ユーティリティ）

yumリポジトリからインストール

```
# yum list lzo lzop
どちらもbaseにある

# yum install lzop
両方インストールされる
```

## 2. バックアップ

### 2.1. 手順

#### 2.1.1. SELinuxを停止する

設定ファイルを編集し、再起動する。

```
# vi /etc/selinux/config
```

```
~~
SELINUX=disabled
~~
```

```
# reboot
```

#### 2.1.2. バックアップを取得する。

* 安全にバックアップする場合はシングルユーザーモードに変更する。

```
# init 1
```

* バックアップを実行。

```
# mondoarchive -O -i -N -d /mnt -E '/mnt' -s 4480m
```

主要なオプションは以下の通り。

| option | 説明 |
|:--|:--|
| -i | ISOファイルをバックアップメディアとして使用する。 |
| -r | DVDをバックアップメディアとして使用する。（growisofsがサポートしていないためsudoが必要） |
| -O | ISOファイルを出力する。 |
| -p | 出力するISOファイル名を指定する。指定しない場合は"mondorescue"が使用される。 |
| -d | 出力先（ディレクトリやバックアップデバイス）を指定する。 |
| -E | 除外するディレクトリを指定。自動で(/mnt/floppy, /mnt/cdrom, /proc, /sys, /run, /tmp)は除外される。 |
| -N | ネットワークファイルシステム（NFS,SMBなど）を除外する。 |
| -s | 出力するISOファイルサイズを指定する。作成するファイルサイズが指定より大きくなる場合は複数に分割される。 |
| -V | 出力したISOファイルをベリファイする。 |
| -g | GUIモード。 |
| -S | 作業フォルダを指定する。 |
| -T | 一時フォルダを指定する。 |
| -D | 差分バックアップを行う。 |


### 2.2. エラー対処

* エラー: libgcc_s.so.1 must be installed for pthread_cancel to work

ライブラリをインストールして対応。

```
# yum install libgcc_s.so.1
```

## 3. リストア

リカバリするマシンのハードウェア要件は、バックアップ元と同様とする。

### 3.1. リストアの実行

1. 仮想マシン上に1つのHDDで器を作る。
1. ISOを起動時にマウントするようにセットする。
1. 仮想マシンを起動する。
1. Mondo Rescueのブート画面が表示されるので、"boot:"プロンプトでエンターキーを押しmondorescueを起動する。
1. リストアメニューが表示されるため、"Automatically"を選択する。

| メニュー | 説明 |
|:--|:--|
| Automatically | 自動的にディスクのフォーマット、リストアを実行する。（通常はこれを使う）|
| Interactively | 対話的にリストアを進める。（難しいらしい） |
| Compare only! | リストアファイルと現在のファイルシステムを比較する。 |
| Exit to shell | 終了してシェルプロンプトに戻る。 |

リカバリ終了後、シェルプロンプトに戻るため、システム再起動をする。

```
# reboot
```

### 3.2. リストア後の後片付け

1. リブート後、fsckコマンドが実行された後にシステムが起動し、リストア完了。
2. ネットワークの修正
  ネットワークの設定を修正する。
  * /etc/network/network-script/ifcfg-eth0 のMACアドレスを正しいものに合わせる。
  * /etc/udev/rules.d/70-persistent-net.rules では、複製されているので原本を消してeth*を書き直す。
【俺用メモ】gitでたまに使う程度なので忘れるコマンド

# 削除
## ローカルブランチ
```
git branch -d branch_name
```

mergeしてないブランチだったりするとerrorが起きて本当に消していいなら``-D``オプション使えよ、ってメッセージが出ます。

## リモートブランチ
git 1.7.0以降なら

```
git push --delete origin branch_name 
```
バージョンを問わない場合は

```
git push origin :branch_name
```
なんでコロンで削除になるのか？
[今さら聞けないgit pushコマンド - Shoichi Matsuda's diary](http://shoma2da.hatenablog.com/entry/2014/03/08/234523)
> 「何もないものをリモートのhogeにpushする ＝ hogeの存在を何もないものにする ＝ hogeを削除」です。

すごく参考になる…。

## merge済みリモートブランチをまとめて削除
コマンドをパイプで組み合わせてやります。

1. hogeにmerge済みのリモートブランチを表示
2. origin/の状態になっているのでorigin/をトリミング
3. ブランチ名が取り出せたのでxargsに渡して削除していく
4. 上記のコマンド群をつないで実行

```
1. git branch -r --merged hoge
2. sed -e 's% *origin/%%'
3. xargs -I{} git push --delete origin {}
-- ↓これが4
$ git branch -r --merged hoge | sed -e 's% *origin/%%' | xargs -I{} git push --delete origin {}
```

これを実運用するときに注意したいのは、手順1でマージ済み一覧を表示する際に、hogeがmasterを取り込んでいる場合にmasterにすでにmerge済みのものも出てくること。
mergeしたまま残しておきたいというブランチがいるかもしれないので目視で消していいかどうか確認する必要があった。
PHP foreach文でキーと値を取得

<?php
$test_array = array(
    "aaa" => "A", "bbb" => "B", "ccc" => "C", "ddd" => "D", "eee" => "E", 
    "fff" => "F", "ggg" => "G", "hhh" => "H", "iii" => "I", "jjj" => "J" 
);

foreach($test_array as $a => $b){
    print $a."=>".$b."<br />";
}
Auto Layout で Scroll View のスクロール方向を制限して、内容を中央揃えにする

## 概要

- Scroll View のスクロール方向を制限します
- Scroll View の中で要素を中央揃えにします

Apple のドキュメントの一部を目的に合わせて要約したものになっています。

https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithScrollViews.html

## イメージ

Content View の制約
<img width="235" alt="スクリーンショット 2016-02-02 16.15.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/31477/18d0027f-27e1-71d3-1456-24b7151b06b8.png">


##  Scroll View のスクロール方向を制限する方法

## 縦横共通

1. Scroll View の中に View を追加します (Content View と名前をつけておきます)
1. Content View に以下の制約を追加します

- `Trailing Space to: Superview`
- `Leading Space to: Superview`
- `Bottom Space to: Superview`
- `Top Space to: Superview`

### 縦方向にだけスクロールさせる

Content View に `Equal Width to: Superview` の制約を追加します

### 横方向にだけスクロールさせる

Content View に `Equal Height to: Superview` の制約を追加します

## Scroll View の中で要素を中央揃えにする

1. 前述した縦方向にだけスクロールさせる制約を追加します
1. Scroll View 内に表示したいすべての要素を Content View の中に追加します
1. それぞれに `Align Center X to: Superview` の制約を追加します 

ここで、1 の制約を追加しなかった場合、Scroll View の内容のサイズが決まらないので、中央揃えにすることができません。
nginxでリダイレクトの調整するときに使ったコマンド

# リダイレクト
リダイレクトの設定って大変ですよね。
一時代を築いたapacheのmod_rewriteでも非常に苦労しました。
nginxのリダイレクトも正規表現を使い始めると結構時間を取られたりします。
`編集 -> 再起動 -> チェック`
のサイクルを素早く回すために使ったコマンドです。
OSはCentOSです。

# 再起動
```bash
$ sudo sh -c ' nginx -t && systemctl restart nginx.service || systemctl status nginx.service -l'
```

ちょっと前までは`service`コマンドを使っていましたが、最近は`systemctl`コマンドのようですね。初めて知りました。
これで
`再起動 -> エラーがあれば横幅いっぱいに表示`
が出来るようです。

# リダイレクトのチェック

```bash
$ curl -I http://example.com/hogehoge.html  |& grep Location
Location: http://example.com/path/to/redirect/
```

これでブラウザを開かなくともコマンドベースでリダイレクトのチェックができます。
ハッカソンを初めて主催したレポート

先日、NIJIBOX主催で初めてハッカソンイベント「築地ッカソン」を
開催したときのレポートです。

**※第二回築地ッカソンが開催されることになりました！下記のURLから飛べますのでぜひご参加ください！**
http://peatix.com/event/153432

## 築地ッカソンとは？
築地を眺めながら、バカなアプリを開発するハッカソンです。
作るものはバカであればアプリでもWebでも何でもＯＫで、
テクニカルなテーマもありません。
1/23に行われた第一回は「築地」をテーマにおいて
みんなで、がやがやもくもくとバカアプリを作りました！

## 開発中の皆さんの様子
![01.jpg](https://qiita-image-store.s3.amazonaws.com/0/101501/33281fd5-2368-d834-1583-4bbcd2d89d50.jpeg)
開発中は皆さん真剣。
分からないことを相談したり、
アイデアソン的に何を作ろうか話していたりといい雰囲気。
自分は裏方だったのですが、次は参加者として何か作りたいです。

## アプリ発表会
11時～18時の開発の後(うち2時間はMonacaやCloudVisionのチュートリアル)
それぞれの成果物を発表しました。

発表した皆さんの作品に
「いいね！」と「バカだね！」を各々で好きなだけつけて評価。
作品は、画像認証と画像合成で割とガチなアプリがあったり、
Monacaを使ってJSでバカアプリを作っちゃったりと多種多様。

![02_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/101501/09b311c8-b99c-f2df-f9e1-f23b064e42d5.jpeg)
発表を見ながら、お酒とピザと寿司！
全員が何かしらの作品を発表することができました。
これって結構すごいことな気がする。

![02_2.jpg](https://qiita-image-store.s3.amazonaws.com/0/101501/de071f40-0b02-dc53-8657-e7c4e1aead30.jpeg)
寿司うめぇ。築地だかんね！


![02_3.jpg](https://qiita-image-store.s3.amazonaws.com/0/101501/59b9324f-a1f4-3c14-1bb9-3c82d3436e47.jpeg)
優勝はどんぶりに回転する具材を乗せて海鮮丼を作るアプリ！
いいねポイントもバカだねポイントも高く、面白くて完成度が高かったです。

![03.jpg](https://qiita-image-store.s3.amazonaws.com/0/101501/1caf0844-b489-a29f-1f1b-c9e70ea36b3c.jpeg)
賞品は築地で買った乾物詰め合わせです。
兵庫県産…？知らんがな。

![04.jpg](https://qiita-image-store.s3.amazonaws.com/0/101501/56494df4-59fd-b19e-a1e0-7a87d0a36f1c.jpeg)
最後はみんなで記念撮影。
この写真だけで凄く楽しかったことが伝わるだろうという自慢。


## 反省点
発表時にスマホをプロジェクタで映す手段がなかったり、
開発中の写真をあまり撮影してなかったり、
もうちょっと技術側のサポートが出来る人を準備するべきだったと反省。
次回はもっとちゃんと準備しよう。

## 終わりに
ハッカソンと言うと、
凄い技術者がくるんだろうなぁ…とか、
ちゃんとモノヅクリが出来るか不安だなぁ…とか、
そんな人でも気軽に参加できるハッカソン！みたいな位置づけで、
これからも定期的に開催していきたいなと思います。
CI ビルド URL を開く ciopen コマンド

元ネタは Quipper の CTO (@tomo) が社内向けにシェアした zsh コマンド。別途 `hub` をインストールしてください。
https://hub.github.com/

```bash
# 使い方:
# 1. 以下を .bashrc などにコピペして保存 -> 端末・シェル再起動または .bashrc 再読み込み
# 2. Git リポジトリを clone したディレクトリに移動 -> Pull Request と紐付いているブランチを checkout
# 3. $ ciopen [COMMIT]
#    $ ciopen head
#    $ ciopen head^
#    $ ciopen head~2
ciopen() {
  commit=$1
  result=$(hub ci-status -v $commit)
  if [ $? == 3 ]; then
    echo $result
  else
    open $(echo $result | awk '{print $2}')
  fi
}
```

![Untitled.gif](https://qiita-image-store.s3.amazonaws.com/0/339/4878a0e0-967f-df83-8305-fde0ea8c9d73.gif)

元ネタとの差分:

- 元ネタは zsh 用で `precmd` を使っていたが自分は bash ユーザーなので zsh 依存を無くした
- 元ネタは `git` サブコマンドを駆使して repo, branch を特定していたが `hub ci-status` コマンドを使うように変更した（その結果 `hub` に依存するようになった）
- 元ネタは https://circleci.com/gh/circleci/frontend/tree/levlaz_docker_docs のような URL を開くが `hub ci-status -v` で得られる CI ビルドの permalink を開くように変更した

どうぞご利用ください。

`hub` コマンドを使っていない方はこの機会にぜひお試しを。 `hub ci-status` 以外にも `hub browse` や [`hub compare`](http://qiita.com/kyanny/items/58516590bcafd02dbd1a) など便利なコマンドがあるのでおすすめです。
Projectを選んでAtomを起動する

皆さんは普段どうやってAtomを起動しているのでしょうか。
僕はWindows8になってからというもの、すべてのアプリを `Win + Q` で起動しているためAtomも例に漏れず `Win + Q` です。
するとどうでしょう、Atomは前回作業したProjectのパースペクティブ(?)をそのまま復元してくれるのです!
**~ 完 ~**

---
これでよいときはよいのです。
しかし、全く違うプロジェクト開きたいんだぜという場合には
project-manager でお目当てのprojectを選択し、初めのprojectのウィンドウを閉じ...
なんて作業が必要になって悶々します。(しますよね。)
この作業がわずらわしくなった僕は、
eclipseでは初めにワークスペースが尋ねられることを思い出し、それもどきを WindowsForm で作ったのでした。
https://github.com/tomoki1207/AtomProjectLauncher

### 必要なもの

* [Atom](https://atom.io/)
* [atom-project-manager(Atomパッケージ)](https://github.com/danielbrodin/atom-project-manager)
* ~~VisualStudio(>=2013)(書いてて気づいたんですがBuild環境がないと実行できませんわ)~~ ひとまずZIPで落とせるようにしてみました

### 使いかた

特にありません。
前述の通り、`Win + Q` でLauncherの方を起動してもらえれば登録済みのProjectが選べると思います。
しかし、いまのところただのファイルなので、検索ボックスに随分入力しないと検索にかかりませんね…。

### 使うかた

Windows(>=8.1)ユーザだけ。
そりゃそうですよ、どうせMacとかLinuxユーザはもっといいランチャがあるんでしょうからね!
えっ、Windowsにもあるんですか!?早く教えてくださいよ!
Rubygemsの kms-env でAWS Key Management Service (KMS)で暗号化したデータをつかう


AWS KMSを経由した暗号をRuby/Railsからしれっと使いたいので、Gemでも作るかと思ったら[kms-env](https://github.com/Fullscreen/kms-env)というのがあった。
これがなかなか利用シーンを想定した工夫がなされていたので紹介。


## 準備: 末尾に`_KMS`をつけた環境変数をセットする

たとえば`MY_TEXT1`という環境変数に目的の文字列を入れたい場合、`MY_TEXT1_KMS`という環境変数にCiphertextを入れておく。

```bash:
export MY_TEXT1_KMS="CiCIvMyU68+VaZSTfI3932heQDZdvp+5+HrByuWVyEcTRRKZAQEBAgB4iLzMlOvPlWmUk3yN/d9oXkA2Xb6fufh6wcrllchHE0UAAABwMG4GCSqGSIb3DQEHBqBhMF8CAQAwWgYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAxbSecwaBUfYce/0MQCARCALftL6ZVE9fAMgpohPz0A8hfylDx3wGg64M4J47GK2CTrI11pIylpKHnklMcIag=="
export MY_TEXT2_KMS="CiCIvMyU68+VaZSTfI3932heQDZdvp+5+HrByuWVyEcTRRKcAQEBAgB4iLzMlOvPlWmUk3yN/d9oXkA2Xb6fufh6wcrllchHE0UAAABzMHEGCSqGSIb3DQEHBqBkMGICAQAwXQYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAwgFJzQeMJU3a7NF5YCARCAMDE2ngCZllnIKUq9S5qdS9FuxWmlEW8OlmjSoE3chqmLgTuoXvwzwX7AltZg7jecmQ=="
```



## 使用: `KmsEnv::load`を実行すると、`_KMS`が取り除かれたキーでENVにセットされる

手元でやるならprofile、その他ならアクセスキーをつかう。もちろんEC2などAWS上ならロール/STSでいい。

```
export AWS_PROFILE=myprofile
export AWS_REGION=ap-northeast-1
```

動作の様子をPryで。

```ruby:pry-console
> ENV['MY_TEXT1']
=> nil  ## まだカラッポ

> require 'kms-env'
=> true


> KmsEnv.load
=> ["MY_TEXT2_KMS", "MY_TEXT1_KMS"]  # 処理対象が返される。


> puts ENV['MY_TEXT1']          # MY_TEXT1に復号されたデータがセットされた
Is this your pen?
=> nil

> puts ENV['MY_TEXT2']          # MY_TEXT2に復号されたデータがセットされた
Yes, this is my pen.
=> nil

## === ついでに既存の値は？

> ENV['MY_TEXT2'] = 'hoge'

> ENV['MY_TEXT2']          # MY_TEXT2を上書きしてからの...
=> hoge


(pry)> KmsEnv.load
=> ["MY_TEXT2_KMS", "MY_TEXT1_KMS"]  # もう一度ロードしてみる

(pry)> puts ENV['MY_TEXT2']          # またMY_TEXT2に復号されたデータがセットされた
Yes, this is my pen.
```

こいつはよい。initializeで`KmsEnv.load`した後は通常のENVとして使い放題だ。
対象(*_KMS)がなければ特に何もせず、既存の値を上書きしないのでローカルは平文、デプロイ先ではCiphertextという運用が可能なのも素敵。



## まとめ

サフィックスから自動でやるってのは考えつかなかった、副作用もすくなかろうし応用が効きそうだ。
自前でライブラリつくろうかなっと思った時はCLIで暗号化もできたらいいかもと思ったが、KMSでデータを変換するインターフェースはlamvery(encrypt/decrypt)があるからいいや。
「AdSense Management API経由の数字がウェブUIで見た数字とずれてる？」と思ったときにチェックするべき項目

AdSense Management APIはGoogle Apps Scriptで数字がとれたりして、とても便利です。
ただ、チュートリアルにあるサンプルを使っていると、タイムゾーンがデフォルト（PTZ）のままになっていて、ウェブUIで見たレポートと数字がずれていて、「？？？」となってしまうことがあります。これは、ウェブUIのタイムゾーンがJSTで、API経由のタイムゾーンがPTZだからずれている（ように見える）んですね。
そんなときは、"useTimezoneReporting"をtrueにするのを忘れないようにしましょう。そうすれば、API経由とウェブUI経由のレポートにずれがなくなります。

```
useTimezoneReporting: true
```

###参考文献
https://developers.google.com/adsense/management/timezone?hl=ja
load直後にjQueryを使ってcss属性値を取得できないことへの対処法

loadイベント発生直後には、ブラウザが各HTML要素とCSS属性を結び付けられていないらしく、css属性値を取得できないことがある。

そこで、各要素とCSSがブラウザによって関連付けられるまで待つためにsetTimeoutを使い、loadイベント発生後に200ミリ秒ほど待ってからcss属性値を取得する。

```js
var timer = false; /* グローバル変数 */
$(window).on("load resize", function() {
    if(timer !== false){
        clearTimeout(timer);
    }
    timer = setTimeout(function() {
         
        // jQueryを使ってcss属性値などを読み出す。
         
    }, 200);
});

```
Visual Studio C# サンプルコードを書く環境を構築する

# 記事を書くようの環境を構築する
　公開可能なサンプルコードを書く環境を作成したことをまとめる。

## 作成する環境
Visual Studio C# のアプリケーションを**複数**開発する
(今回はコンソールアプリのProjectを作成する)
こんなイメージ（ビンに小物が入っている感じ）
![20160202_000.png](https://qiita-image-store.s3.amazonaws.com/0/111261/0ffb9cd2-1981-b378-39b3-e4ec0f42d57f.png)
Solutionを作ってからProjectを追加した方が作成したアプリケーションが散らからないので、Solutionを作るようにしている。

## 使用ソフト
・VisualStudio 2015 Community

## 手順
1. Solutionの作成
2. Projectの作成

### 1. Solutionの作成
1. File -> New -> Project...
2. Installed -> Templates -> Othe Project Type -> Visual Studio Solutionを選択し、[Name][Location]を設定する![20160202_001.png](https://qiita-image-store.s3.amazonaws.com/0/111261/20654e23-e056-1c57-b120-5e218070fd22.png)

### 2. Projectの作成
1. File -> **add...** -> Project...  (NewではなくAddを選択)
2. Templates -> Visual C# -> Windows -> Console Applicationを選択し、[Name]を設定する![20160202_002.png](https://qiita-image-store.s3.amazonaws.com/0/111261/af26ed1c-dd7a-a20f-fac8-83871c7fae16.png)

### 完成
![20160202_003.png](https://qiita-image-store.s3.amazonaws.com/0/111261/6bb29b9b-21d1-148d-a44a-b62c8fc35f4b.png)

[ここまでの内容](https://github.com/gansaibow/qiita/tree/master/VisualStudio/SandBox)
作成したサンプルコードはこの公開リポジトリにコミット
[gansaibow/qiita](https://github.com/gansaibow/qiita)
バックアップ用途にAWSのs3を使う時の小ネタ

# はじめに
AWSのs3バケットを静的ファイルの配信サーバにする他にバックアップ用途に使っている人も多くいると思います。
僕がやっている例を紹介します。

# s3cmdをインストールと設定
* epelからインストール

入るバージョンを念のため見てみる

 ```
yum info –enablerepo=epel s3cmd
.
.
.
Name        : s3cmd
Arch        : x86_64
Version     : 1.0.0
Release     : 4.1
Size        : 296 k
```
1.0.0が入るみたい。
最新ではないっぽいけど込み入った使い方はしないのでまぁ良いか

```
yum --enablerepo epel install s3cmd
 ```
一応色々見ながら```y```を押す

configを設定

```
s3cmd --configure
Access Key: xxx
Secret Key: xxx
```

```
[root@hostname]# s3cmd ls
2015-02-13 03:26  s3://xxxxxxxx
```
s3コマンドが使えたので正常にインストールされてることを確認

# aws s3バケットの設定（非公開設定）
awsのコンソール＞s3の管理画面＞BK用のバケット＞プロパティ＞静的ウェブサイトホスティング
＞有効にしない

## 確認
* 実際にBKファイルをs3の該当バケットにupload
* awsのコンソール画面から該当のファイルのプロパティを確認
![S3 Management Console.png](https://qiita-image-store.s3.amazonaws.com/0/106937/730aed52-d24a-e516-597e-1b609430bfab.png)
* 鍵マークがあり、実際にurlにアクセスしても```AccessDenied```と出る

# バックアップ用のshellを作る
```backup.sh
#!/bin/sh

# 終了ステータスが0以外の時は処理を中断してNGを出力する
# jenkinsのjobで実行予定で異常に気づけるように
set -e
trap 'echo NG' ERR

# n世代のバックアップを保存
MAX_SAVE_CNT=7
BACKUP_NAME=`date +"%Y-%m%d-%H%M%S".sql`

# BK用途のslaveサーバからmysqldumpでバックアップを取得
# サイズが大きくなればserviceをstopしてバイナリーバックアップに切り替える
ssh backup@<slave database hostname> /usr/local/mysql/bin/mysqldump -uroot <database name> > <bk dir>$BACKUP_NAME
tar cvzf $BACKUP_NAME.tar.gz $BACKUP_NAME

# s3へ格納
s3cmd put -r $BACKUP_NAME.tar.gz s3://<BUCKET_NAME>/<BUCKET_PATH>/

file_count=`ls -1 | grep sql.tar.gz | wc -l`
if [ $file_count -gt $MAX_SAVE_CNT ]
then
　　　　# s3にある7世代以降のバックアップを削除
        s3cmd del -r s3://<BUCKET_NAME>/<BUCKET_PATH>/`ls -1 | grep sql.tar.gz | head -1`
　　　　# localのバックアップファイルも削除
        rm -rf `ls -1 | grep sql.tar.gz | head -1 | xargs rm -rf`
fi
```

* 世代バックアップ管理をできるようにしている
* jenkinsで定期実行を想定。
* 何か例外的なことが発生したら処理を中断して``` error```を出力するようにして、jenkins jobの実行失敗になるようにした。
* バックアップの実行時間はjenkinsのjobの実行時間をイコールで見るようにした
* 分散保存という意味でlocalにも世代バックアップを持っている
* リストアの確認は別途した