OmniAICreator/Qiita-1.07M huggingface dataset:
[実践] はじめてのPull Requestをやってみよう

#はじめに
Pull Requestをするために、誰かのコードを見て何か物申すのも面倒ってことで、手軽にPull Requestをする方法を考えました。
ぜひ、最後まで見てPull Requestをやってみてください。
(※今回はサンプルとしてhtmlを使いますが、htmlの知識は必要ではないです。)
5~10分程度でできるのでやったことがない人はさくっとやってみてください！！

※実践編なので、細かい言葉の定義などはここでは取り扱いません。

##対象ユーザ
- gitを始めてばかりの人
- はじめてPull Requestをする/したい人
- 仕事やインターンでする必要が出た人
- その他、gitを使っている人など

#準備
Githubのアカウントがなければできないので[こちら](https://github.com)から作成してください。
gitの導入などは他サイトを参照してください。

##Forkする
今回はForkという機能を使ってPull Requestをします。

まず、こちらの[サイト](https://github.com/wataryooou/pull_request)に飛びます。
サイトの右上にあるこのForkボタンを押して、自分のリポジトリにコピーします。
<img width="97" alt="Screen Shot 2016-09-27 at 21.27.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/104635/1763b5b9-ef56-411c-4ee2-65eac8aca0f4.png">

Forkをしたら自分のリポジトリに「自分のユーザ名/pull_request」というリポジトリができたと思います。
そのリポジトリをcloneしましょう。
<img width="156" alt="Screen Shot 2016-09-27 at 21.28.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/104635/1a303879-3d3d-8065-1ebb-bc426e2d20a3.png">
`$ git clone [cloneで表示されたurl]`
`$ cd [cloneしたもの]`

##ブランチを作成する
まず、ブランチを作成します。
`$ git checkout -b mywork master`

次にブランチが**mywork**に切り替わっていることを確認します。
`$ git branch -a`

それでは、cloneしたディレクトリ内のファイルを見ましょう。
`$ ls
index.html README.md
`

今回はindex.htmlを編集します。

##ファイルを編集する
ファイルをエディタ等で開きます。
htmlのコードの一部にこのような記述があります。
<img width="317" alt="Screen Shot 2016-09-27 at 21.36.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/104635/4435f47f-3c9f-6e4b-1e05-9a480dca4346.png">

`<!-- ↑この上にコメントを入れてください↑ -->`と書いてあるので**必ず**以下のようにこの行の上に似たようなコメントを追記してください。(※**1行でお願いします。**)

<img width="307" alt="Screen Shot 2016-09-27 at 21.36.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/104635/1b01a696-8340-c1da-14a2-c4a865172e2f.png">
コードは以下のような形で記述してください。
`<li>{n+1}th Pull Request</li>`
`n`は一つ上の数字です。一つ上の数字が10であれば`<li>11th Pull Request</li>`と追加しましょう。
編集ができたら保存しましょう。

##ファイルを追加する
ファイルを変更したらgit diffコマンドで修正が正しく行われているか、見てみましょう。
`$ git diff`

うまく変更できていたら手元のリポジトリにコミットします。
`$ git add index.html`
`$ git commit -m "はじめてのプルリクエスト"`

## リモートブランチの作成
GithubからPull Requestを送る前に、Github側に修正を加えたブランチがある必要があるため、ブランチを作成します。
`$ git push origin mywork`

#Pull Requestをする
では、Github上にあるこのボタンを押します。
<img width="138" alt="Screen Shot 2016-09-28 at 15.50.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/104635/a5a07d22-0551-f84f-972e-7db2c0759d0d.png">
出てきたmywork(自分の作ったリモートブランチ)を押してブランチを自分が作ったブランチに変更します。

ブランチを変更したら、右上に以下のようなボタンが出るのでクリックします。
これは自分のブランチをmasterブランチにプルリクエストを送るためのボタンです。
<img width="202" alt="Screen Shot 2016-09-28 at 15.55.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/104635/9bf73a14-6510-cbe7-2277-c64d82d1e8b6.png">

押すと以下のような画面が出てきます。
<img width="782" alt="Screen Shot 2016-09-28 at 15.56.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/104635/ecf585ae-0d17-b04a-49d7-178f592dc5eb.png">

わかりやすいコメントを入れてCreate pull requestを押しましょう。
(実際に押していただいて大丈夫です。私の方でmergeします。)

これでPull Requestができました。

# おわりに
Pull Requestではforkを使う場合と使わない場合がありますが、今回は使う場合で説明しました。
少しでもみなさんのお力になれれば光栄です。
また、Pull Requestされたものに関しては、たまにMergeしていきます！
自分のコードが反映されるかを見るのも面白いと思うので、まだ終わってない方はぜひ最後までやってみてください。
何か改善点などあればコメントにてご教授お願いします！
君はAZERTYキーボードを知っているか？　日本人の知らないキーボードの世界


今回は、キーボードを扱うプログラミングをする際に日本人が（正確には、フランス人以外が）気を付けるべきポイントについてまとめてみました。

# 事の起こり
　私は、[PoderosaというSSHクライアント+ターミナルエミュレータ](https://ja.poderosa-terminal.com/)を開発・公開しております。ユーザは世界各国にいるのですが、ある日突然１本のメールがきまして、

**「Poderosaはなかなかよくできているが、ワイのフランス語キーボードではいくつかの記号が打てんのや！　なんとかせい」**

という問合せが来たのです。（もちろん原文は英語です）

　フランス語だけ特殊な要因ってあるのかなと思って調べたところ、これはちょっとネットで調べて解決するようなシロモノではなく、フランス語キーボードの現物を繋いで何がおきているかを見るしかなさそうな雰囲気です。
　ちょうどその問合せを受けた日には別件で秋葉原に行く用事があったのでヨドバシに立ち寄ったところ扱いはなく（当然か）、日本のAmazonでもダメ。しかたなくUSのAmazonに注文して待つこと２週間、送料込み45ドル払ってやっとキーボードを入手しました！

# これがフランス語キーボードだ！
　遠くから見るとふつうのキーボードですが、よく見るといろいろおかしなところが。

![FrenchKB1](http://poderosa.s3-website-ap-northeast-1.amazonaws.com/french_kb_2.jpg)

　ふつうはQWERTYですが、コイツは**AZERTY**です。でもアルファベットについてはAZQWとMのほかはまあ普通で、それほど根本的に違うわけではありません。

　次にキーボードの左下エリアを見てみましょう。
![FrenchKB2](http://poderosa.s3-website-ap-northeast-1.amazonaws.com/french_kb_7.jpg)
　これはまあ普通にCtrl,Shft,Altが並んでいます。違和感があるのは**Shift+>で<**、ですね。

![FrenchKB3](http://poderosa.s3-website-ap-northeast-1.amazonaws.com/french_kb_6.jpg)
　ところが右下エリアを見ると、**Alt Gr** という変なキーが。いったいなんだこれはと思いますが、重要なキーなのです。


![FrenchKB4](http://poderosa.s3-website-ap-northeast-1.amazonaws.com/french_kb_3.jpg)
　たとえばこの**０のキーのところに３つ文字**がありますが、

 - そのまま押す -> **à**
 - Shift押しながら -> **0**
 - AltGr押しながら -> **@**

　となります。0なんてプログラミングでは **à の1000倍使用頻度が高い**と思いますが、これをいちいちShiftが必要というのが泣けてきます。@も à よりは出てきますよね。他にも、**バックスラッシュや {} ,  [] を打つのにAltGrが必要**なので、プログラミングやシェル操作には必須のAltGrです。逆にフランス人は、**Pokémon**の**é**の入力に各国の人が苦労しているのを全く想像できないでしょう。(éは数字の7のキーに割り当てられています)

# ここから技術的な話
　さて問題はAltGrをプログラミングでどう扱うかです。例えばMSDNのこのページを見ても、Modifier Keyには**Ctrl, Shift, Alt**しかなく、どこにも**AltGr**なんて書いてありません。
　[ModifierKeys 列挙体(MSDN)](https://msdn.microsoft.com/ja-jp/library/system.windows.input.modifierkeys(v=vs.110).aspx)

　Windowsプログラミング歴20年の筆者も、これ以外にModifier Keyが存在するとは今回初めて知りました。

　そこで、このキーボードを繋いで実際にキーを打ったところ、**AltGrはAlt+Ctrlとして解釈されている**ことがわかりました。@のような普通のASCII文字にもModifierが２つ必要というのは違和感たっぷりですが、しかたありません。
　逆にいえば、日本語キーボードを接続した状態でキーボードマッピングをフランス語にしたならば、**0を押せばàが、Alt+Ctrl+0で@が入力される**ということです。

　以上の情報から、キーボードを扱うプログラミングで気を付けるべき点がいくつか浮かび上がってきます。なおこれはWindowsでの話であり、他のOSでは全く事情が違ってきます。もし情報を寄せてくれればこの記事に書き溜めていきます。

## CtrlやAltが押されているからといってキーボードショートカットを意図しているとは限らない
　**日本語・英語キーボードでは、ShiftさえあればAlt/Ctrlがなくても普通のASCII文字はすべて打つことができる**ので、CtrlやAltが押されていたらアプリケーションの機能のショートカットキーに結びつけてしまって普通の文字入力ではないと判断して問題ありません。
　しかしフランス語キーボードではそうはいかず、**AltGrの可能性を考慮する必要があります**。
　CtrlかAltが押されていたらショートカットキー、と単純に判断するロジックのアプリはフランス語キーボードでは正しく動作しなくなります。世界にユーザがいるようなアプリでは気を付けないといけません。

## IMEを使わなくても非ASCII文字の入力はできる
　Pokémonのéもですが、通常のキーでU+0080以上の文字が簡単に入力できてしまいます。さらには、¨(U+00A8)のような、日本語フォントだと全角表示になるような文字も通常のキーで打ててしまいます。アプリ側で変に決め打ちをしていると予期しない動作になるかもしれません。

　なお、フランス語はこんなにトリッキーですが、ドイツ語キーボードはいたってまともです。身近なデバイスでも、知らないことはいろいろあるんですね。中国語やロシア語も怪しそうですが、ここまで記号の入力の手間がかかる例は珍しいと思います。
　[Poderosa](https://ja.poderosa-terminal.com/)はこういう問題に取り組みながら徐々に強化させていきます。
3D モデルにボーンを入れて Unity で踊らせてみた

先日 TechShop Japan で [doob](http://jp.doob-3d.com/) が展示されており、3D データを作ることができた。今回はそのデータにボーンを入れて Unity 上で踊らせてみる。

## 必要な作業

以下の作業が必要だった。1 と 2 の作業は今回は mixamo という Web ツールを使う。自分がやった範囲だと無料で全てできた。

説明のためにスクショを貼りまくるため、それぞれページを分けて説明する。

1. [リギング](http://monopocket.net/blog/unity/mixamo-rigging/)
2. [アニメーションを追加](http://monopocket.net/blog/unity/mixamo-animations/)
3. [Unity 上でアニメーション設定](http://monopocket.net/blog/unity/mixamo-animation/)

動画の貼り方がわからないので続きは元記事で：[3D モデルにボーンを入れて Unity で踊らせてみた](http://monopocket.net/blog/unity/3d-model-dance/)
df -iでinodeが足りないときにチェックすること

# ディスクフルになった原因がinodeだったときの特定方法

## サーバーでcronを動かしている

* 標準出力が垂れ流されている場合、postfixのメールが溜まっているので/var/spool/postfix/maildropをチェックし、相当量たまっているのなら削除する
YAMLのValueにJSONを書く時(k8s manifestに記載するPodに注入する環境変数にJSONをセットしたい)

## これは何？

YAMLのValueにJSON文字列を書く際、文字列やクオートの扱いを忘れがちなのでメモ。

稼働中のシステムをk8sに移植する際に、PodへJSONな値を持った環境変数を注入したいケースがありました。
環境変数をk8s manifestのyamlファイルに記載する際のメモです。

## 1. 正しいJSONを書く

Json Parser Online
http://json.parser.online.fr/

ここでエラーのない状態になっているか確認しましょう。

## 2. YAML記載例

前後をシングルクォートで囲ってあげます。

こんな感じ。

```bash
        env:
        - name: HOGE
          value: '{"uris":["www.yahoo.com"]}'
```
知っている人には常識なのかもしれないが

使用言語ruby

EC2インスタンス上(Amazon linux)で
S3にあがってるgzファイル(展開後10Gくらい)をDLしてきて展開、

File.open('ファイル名').do |f|
  いちぎょうずつしょり
end

ってやったら、openにブロック渡すと閉じたときに勝手にcloseしてくれるはずなのに
プロセス終了後もtopで見たときのuse memoryが10G食いっぱなしだった。

ローカルでrubyでやっても再現せず。

なのでシェルで10Gほどのファイルを生成するスクリプト組んで試してみたら、
やはりプロセス終了後もmemory食いっぱなし。

なおどちらの場合もファイルを消すとmemory復活する。

~~ファイルはいったん全部メモリにもってどっかのタイミングで実体作って解放、みたいなことやってる？~~

プロセスが終了してもページキャッシュが保持されているだけだった。
~~amazon linuxのpdflushのタイミングがcentosデフォルトのやつと違うだけかひょっとして。~~

~~ほぼ一緒だった。と、するとなぜだ…？~~
語弊があった

dirty_backgroud_ratio
dirty_ratio
dirty_expire_centisecs
dirty_writeback_centisecs
min-free-kbytes

このあたりの設定値がほぼ変わりなかったというだけ

echo 1 > /proc/sys/vm/drop_caches

でメモリが解放される以上、ページキャッシュではあろう。

■2016/12/28 追記
通常、ストレージと同期が取れた時点で(vmstat -a のinact領域)「捨てて良い」メモリとなって、
別の何かからメモリの要求が来れば勝手に解放してくれるはず。
なのにうまくいってないのはinactになるのが遅いとかそういうのか？
iOSのプッシュ通知送信時にトークン認証が使えるようになったので調べてみた


iOSのプッシュ通知送信時のAPNs接続の認証に、今までは証明書を使っていましたが、代わりにトークン認証を利用することができるようになったので軽く調べてみました。

## メリット
今までの証明書をサーバーに置く方式では証明書の期限が切れたら更新する必要がありましたが、トークン方式では期限が無いため更新が不要です。なのでうっかり更新を忘れていてプッシュ通知が送れなくなっているということが無くなります。
また、期限が切れる度に新しい証明書に入れ替える手間も省けます。

## トークン認証利用に必要な手順

1. Apple Developerの証明書の作成画面に `Apple Push Notification Authentication Key (Sandbox & Production) ` という選択肢が増えているので、それを選択して秘密鍵を作成
2. プッシュ通知送信時に、この秘密鍵を使って署名したトークンを `authorization` ヘッダに乗せ、 `apns-topic` ヘッダで送信先Appの `BundleId` を指定して  `POST`
（その他のヘッダ内容、通知内容(payload)を入れるbodyは従来と変わらないのでドキュメント参照。）

※2015/12に公開された新しいAPNs Provider APIでのみトークン認証に対応しているようです。
APNs Provider APIについてはこちらが参考になりました
http://qiita.com/itosho/items/2402df4de85b360d5bd9

※トークン認証では秘密鍵生成時にAppIDを指定しないため、`apns-topic` ヘッダでの送信先Appの指定が必須になっています。
つまり従来の証明書利用時のようにAppIDごとに作成をしなくても良くなりますが、どのように運用するかは検討が必要かもしれません。

※秘密鍵は再ダウンロードすることはできないので、バックアップ必須です。

実際に送信まで試したわけではないので、間違いがあればご指摘いただけると助かります。

## トークンの生成
トークンとしてJSON Web Token(JWT)を生成して利用します。

JSON Web Tokenについてはこちらが参考になりました。
http://qiita.com/kaiinui/items/21ec7cc8a1130a1a103a

では、どのようなJSONフォーマットのデータに署名すればよいかというと、ドキュメントによるとこんな感じでした。

```
{
    "alg": "ES256",
    "kid": "ABC123DEFG"
}
{
    "iss": "DEF123GHIJ",
    "iat": 1437179036
}
```

`alg` - 署名アルゴリズム。ES256のみ対応。詳細はドキュメントに。
`kid` - Apple Developerの証明書管理画面で作成した秘密鍵のID。同画面から確認可能。（Key ID）
`iss` - デベロッパのチームID（Apple Developer管理画面から確認可能）
`iat` - トークンが生成された時刻（Unixtimestamp）

※`iat` のタイムスタンプが過去1時間以内でない場合はエラーになるため、定期的にトークンを生成することを推奨しているようです。

## その他
* 基本的に生成した秘密鍵は無期限なので一度作成したらずっと使えるが、盗まれた可能性がある場合などは管理画面からRevokeできます。

##参考

* Apple Developer Guide - Local and Remote Notification Programming Guide
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/APNsProviderAPI.html#//apple_ref/doc/uid/TP40008194-CH101-SW1
SwiftのRealmでインクリメントされた変数をデータベースに順次記録し永続化させる

```swift:ViewController.swift

import UIKit
import RealmSwift


class ViewController: UIViewController {
    
    var tapCount:Int = 0
    //数字を格納する変数を定義する

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
    }
    
 
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    @IBAction func count(sender: AnyObject) {
        //ストーリーボードからUIボタンを作る

        self.tapCount += 1
         //selfで自分を呼び出してtapCount += 1でタップされるたびに変数の値をインクリメントさせる

        print(tapCount)
        // printで変数の値がインクリメントされるかデバック

        
        
        let number = CountNumber()
        //定数numberにモデルクラスであるclass CountNumberを代入してインスタンス化
        
        
        number.num = tapCount
        //定数numberのメソッドnumに、変数tapCountを代入してドット技法でnumberへアクセス

        
        // Realmのインスタンスを取得してデータベスを召喚（おまじない的な）
        let realm = try! Realm()
        
        let numData = realm.objects(CountNumber)
        //ドット技法を使いrealmにオブジェクトobjectsに引数で変数(CountNumber)を指定して定数numDataに代入

        print(numData
　　　　　　　　　　　　　　　　　//定数numDataに、データベースは取れているか、取得したデータベースに値は入っているかをデバック

        // データを永続化
        try! realm.write {
            realm.add(number)
　　　　　　　　　　　　　　　　　//writeメソッドを使って定数number、つまり定義したデータベースのテーブルclass CountNumbeの値に値を保存
        }
    }
}

class CountNumber: Object {
//モデルクラスであるCountNumberを作る。これがデータベースのテーブルになる
    
    dynamic var num = 0
　　　　　　　//プロパティはデータベースの値となり、従来のデータベースでいうカラムになる

}
    
```

#やったこと

-ボタンを作りタップされるごとに数字がインクリメントされていく処理を作る
-Realmを使い変数をデータベースに飛ばす
-インクリメントされた数字がタップされるごとにデータベスに保存されていく
-結果1,2,3,4,5,...etc という風にデータベースにデータが増えて行く



#詰まったところ



トランザクション(IBAction)のところに記述しなければエラーを弾くコードがあったり、class `CountNumber: Object`はトップ階層に作らないといけなかったり

コードを書く"場所"に気をつける必要があった。例えば` class ViewController`の中に`class CountNumber: Object`を書くと、

`Cannot convert value of type 'ViewController.countNumber' to expected argument type 'Object.Type'`というエラーが出てかなり困った。


慣れれば&想像力が豊かであれば「こうだから動かないのかな？」と当たりを見つけることもできるかもしれないが、難し買った結構。

#感想


やっぱり、難しかったのは、記述の仕方やロジックにミスはないのに、細かい言語上のルールによって、プログラムが動かないこと。なのに吐き出すエラーは難解な言葉ばかり。

プログラミングにかかわらず、実生活でもそうかもしれないけれど「何が問題点なのか分からない」っていうのは非常に厄介なものでして、それって問題を解くことよりも難しいこともあって

問題が定義された瞬間に、その先には答えが必ずあるものでして、知ってしまえばなんてことないんだけど、もっと想像力を働かせて問題を発見できるようになりたい。
ツールボックスの一覧を表示する

課　題：会社や大学の環境で，どんなツールボックスが使えるのかを確認したいとき

解決法：`ver`コマンド

方　法：コマンドウィンドウに，そのまま

```matlab:.m
>> ver
```

と打つだけ．

参　考：http://jp.mathworks.com/matlabcentral/answers/93813-toolbox
MPICH > MPID_Init(177).....................: channel initialization failed > /etc/hosts記載ミス

```txt:動作環境
CentOS 6.8
```

Open MPIとMPICHを試した。

## code

```sample.c
#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {
    // Initialize the MPI environment
    MPI_Init(NULL, NULL);

    // Get the number of processes
    int world_size;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    // Get the rank of the process
    int world_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);

    // Get the name of the processor
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    int name_len;
    MPI_Get_processor_name(processor_name, &name_len);

    // Print off a hello world message
    printf("Hello world from processor %s, rank %d"
           " out of %d processors\n",
           processor_name, world_rank, world_size);

    // Finalize the MPI environment.
    MPI_Finalize();
}
```

### 実行

上記のコードについてmpiccでコンパイルして`mpirun -np 6 ./a.out`を実行した。

Open MPIの方では特にエラーにならなかった。

MPICHでは以下のようなエラーが出た。

```
Fatal error in PMPI_Init_thread: Other MPI error, error stack:
MPIR_Init_thread(467)..............: 
MPID_Init(177).....................: channel initialization failed
MPIDI_CH3_Init(70).................: 
...
```

http://stackoverflow.com/questions/23112515/mpich2-gethostbyname-failed
によるとホスト名の解決がされてなかった。

/etc/hostsを編集してからはOpen MPIと同じように正常終了した。
Zabbix agent だけインストールするときの手順


クライアントのRHEL系Linuxに、zabbix agentだけインストールする手順。



# yum updateをかける

```
yum update 
```

# zabbixのリポジトリをいれる

- Family 2.2

```
rpm -ivh http://repo.zabbix.com/zabbix/2.2/rhel/7/x86_64/zabbix-release-2.2-1.el7.noarch.rpm
```

- Family 2.4

```
rpm -ivh http://repo.zabbix.com/zabbix/2.4/rhel/7/x86_64/zabbix-release-2.4-1.el7.noarch.rpm
```

- Family 3.0

```
rpm -ivh http://repo.zabbix.com/zabbix/3.0/rhel/7/x86_64/zabbix-release-3.0-1.el7.noarch.rpm
```

- Family 3.1

zabbix-release-3.1-1.el7.noarch.rpm なし

- Family 3.2

```
rpm -ivh http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/zabbix-agent-3.2.11-1.el7.x86_64.rpm
```

- 3.4

```
rpm -ivh http://repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-agent-3.4.9-1.el7.x86_64.rpm 
```

- 3.5
rcなので省略

- 4.0

```
rpm -ivh http://repo.zabbix.com/zabbix/4.0/rhel/7/x86_64/zabbix-agent-4.0.14-1.el7.x86_64.rpm 
```

- 4.２

```
rpm -ivh http://repo.zabbix.com/zabbix/4.2/rhel/7/x86_64/
```
- 4.3

```
rpm -ivh http://repo.zabbix.com/zabbix/4.3/rhel/7/x86_64/
```

- 4.4

```
rpm -ivh http://repo.zabbix.com/zabbix/4.4/rhel/7/x86_64/
```

# agentのインストール 

```
yum -y install zabbix-agent
```

# config ファイルを編集する
Host name, server, Host Meta data あたりの編集

```
vi /etc/zabbix/zabbix_agentd.conf
```



# Firewallの設定
注意：
Agentをインストールするクライアントでは、tcp 10050 をあける。

```
firewall-cmd --zone=xx(任意のzoneで) --permanent --add-port=10050/tcp
firewall-cmd --reload
```

# サービスの起動と自動起動設定

```
systemctl start zabbix-agent
systemctl enable zabbix-agent
```
mackerelでworking以外のステータスのホストをslackに通知させる

# 概要
* mackerelでworking以外のステータスになってるやつを見逃すことあるよね
* なのでmkrで定期的にslackに通知させましょう
* でも意図的にstandbyにするやつは除外ルールに書いちゃいます

# 内容
### ①必要なgemのインストール
```bash
$ gem install slack-notifier
```

### ②slackに通知させるプログラム
```bash
$ vim /tmp/check_mackerel_status.rb
```

```rb
# -*- coding:utf-8 -*-
# need:
# $ gem install slack-notifier
#
# $ vim /tmp/exclude_hosts.rb
# $un_watch = [
#   ['server1', '10月上旬に削除します'],
#   ['server2', '10月上旬に削除します']
# ]
#
# $ crontab -e
# 0 10 * * 1-5 ruby /tmp/check_mackerel_status.rb


require 'json'
require 'slack-notifier'
require '/tmp/exclude_hosts'

exclude_host = []
host_list = []
message = ''
message_exclude = ''
webhook_url = 'https://hooks.slack.com/services/xxxxxxxxxxxxxxxxxxxxxxxx'

# mackerelからデータを取得
cmd = `mkr hosts`
JSON.load(cmd).each do |t|
  host_list.push(t) if t['status'] != 'working'
end

# 意図的に監視してるホスト一覧
$un_watch.each do |t|
   exclude_host.push(t[0])
   message_exclude += "#{t[0]}: #{t[1]}\n"
end

# 意図しないworkingステータス以外のホストを取得
host_list.each do |t|
  unless exclude_host.include?(t['name'])
    message += "#{t['status']} : #{t['name']}\n"
  end
end

unless message.empty?
  notifier = Slack::Notifier.new webhook_url, channel: '#infra-channel', username: 'botname'
  notifier.ping "```\nmackerelでworking以外のサーバ一覧です\n#{message}```\n"
end
```

### ③除外するホストを格納する部分
```bash
$ vim /tmp/exclude_hosts.rb
```
```rb
# mackerel上のホスト名と理由を書いてます
$un_watch = [
  ['server1', '10月上旬に削除します'],
  ['server2', '10月上旬に削除します']
]
```

### ④あとはcronで動かしてね！
```bash
$ crontab -e
0 10 * * 1-5 ruby /tmp/check_mackerel_status.rb
```
Kubernetes+s3+RDSを使ったファイルの分散処理の仕組みを作ってみた[概要編]

#概要
友達からファイルの分散処理を頼まれたので作りました。

イメージ的にはファイルの処理要求を書き込むと複数のPodが適当にタスクを分割しファイル処理を自動でやってくれるものです。

今回はs3上に保存されているファイルをダウンロードし、Kubernetes上の計算用Podでファイル処理（今回はハッシュ値計算）を行い、その結果をRDS上のmysqlサーバーに保存します。

![myfile_1.png](https://qiita-image-store.s3.amazonaws.com/0/140084/ed0daaf9-703b-548a-f056-afdf002c6cc0.png)

計算用PodはKubernetesを用いて複数配置し分散処理をさせたいため、etcdサーバーに設定を書き込み、各Podがタスクの内容を取得し処理するようにしました。

etcdサーバーに分割するPod数をもたせ、処理するファイル名の範囲を分割し処理します。

※ファイル名の範囲の分割をかんたんにするためファイル名は16進数を文字列化したものと仮定します。

なお、各ノードにetcdサーバーを配置[(記事はこちら)](http://qiita.com/mmitti/private/406e17861df61f5224be)していることが前提となります。

#計算用Podの中身

計算用Podの中は3コンテナで構成されています。
なお、全コンテナは同じフォルダーをマウントしています。

![myfile_2.png](https://qiita-image-store.s3.amazonaws.com/0/140084/ceeefeba-dfed-0bc0-37f9-20e169750af5.png)

###コンテナについて

- init-pod  
  etcdサーバーから処理内容やs3のキーなどを取得し全コンテナ共用で利用するファイルを初期化します。    
  また、etcdサーバーのパラメーターからs3の処理するファイル名の範囲を決定します。      
  本当はKubernetesのinit containersという機能を使う予定でしたがうまく動かなかったので他のコンテナの処理が終わるまでsleepします  
  他のコンテナの処理が終わった後etcdサーバーに終了を示すデータを書き込み新たな処理内容を取得します。
- s3-fetch-tool2  
  init-podが設定ファイルを生成した後s3からファイルをダウンロードします。  
  指定された共用フォルダーに上限10個ファイルが溜まるまでダウンロードします。  
  init-podで指定された範囲のファイルを全てダウンロードしたら完了を示すファイル(s3fin)を生成して他のコンテナが終了するまで待機します。
- file-hasher2  
  s3-fetch-tool2がダウンロードしたファイルのハッシュ値を求めRDS上のmysqlにハッシュ値を保存します。  
  ハッシュ値の計算アルゴリズムはetcd側で指定されたもので行います（後述）  
  s3-fetch-tool2が保存したファイルを全て保存したら完了を示すファイル(hashfin)を生成してinit-podの終了処理を待ちます。

###ファイルについて
3コンテナが共通してマウントしているディレクトリ内では3つのファイルと1フォルダーが生成されます。

 - conf.json  
 etcdから取得したハッシュ値のアルゴリズムやs3のパス、mysqlのホスト名やユーザー名などが格納されています。
 - filesフォルダー  
  s3-fetch-tool2がダウンロードしたファイルを一時的に保存するフォルダーです。
 - s3fin
  全ファイルのダウンロードが完了したときにs3-fetch-tool2が生成します。    
  全処理完了後init-podコンテナがこのファイルを削除します。
 - hashfin  
  全ファイルのハッシュ値計算が完了したときにfile-hasher2が生成します。  
  全処理完了後init-podコンテナがこのファイルを削除します。

#etcdに保存するデータ
etcdにはs3やmysqlサーバーに接続するためのIDやパスの他、ファイルを処理する要求情報を保存します。
各Podは処理中の情報や完了情報を保存します。

ちょっと複雑ですが以下のような構成になります。（もしかしたらetcdの使い方として間違っているかもしれません。）

設定関係

 - /conf/mysql_host　mysqlのホスト名（例:db.rds.amazonaws.com）
 - /conf/mysql_name　dbの名前です
 - /conf/mysql_pass　mysqlのパスワード
 - /conf/mysql_user　mysqlのユーザー名
 - /conf/s3_bucket　s3のバケット名
 - /conf/s3_key　s3のアクセスキーID
 - /conf/s3_secret　s3のシークレットアクセスキー

タスクの要求

 - /req/\<requestID\>/root  
 処理するs3のフォルダー名
 - /req/\<requestID\>/job  
タスクの分割数（処理をかんたんにするため後どれだけの数で分割するかとします）
 - /req/\<requestID\>/method  
ハッシュ値の計算アルゴリズム（MD5, SHA1, SHA224, SHA256, SHA384, SHA512)

タスクの割当情報（自動生成）

 - /wip/\<requestID\>/\<jobID\>/host  
処理しているPodのホスト名
 - /wip/\<requestID\>/\<jobID\>/range/start  
処理対処のファイル名の範囲の開始値
 - /wip/\<requestID\>/\<jobID\>/range/end  
処理対処のファイル名の範囲の終了値

タスクの完了情報（自動生成）

 - /done/\<requestID\>/\<jobID\>/host  
処理が完了したPodのホスト名

#データベースの構造
mysqlには以下のテーブル名と構造で保存します。

|カラム名|ID|HostName|FileName|HashMethod|Hash|Date|
|:----|:----|:----|:----|:----|:----|:----|
|型|int(11)<BR>auto_increment<BR>primary key|text|varchar(256)|char(10)|text|datetime|
|説明|ID|計算したPodのホスト名|計算したファイル名|ハッシュ値の計算アルゴリズム|ハッシュ値|書き込み日時|

#参考
実際に配置してテストする方は[配置編](http://qiita.com/mmitti/private/31e90a524955ba497b75)を、各コンテナの詳細については[詳細編](http://qiita.com/mmitti/private/5591610d8958bfd609a4)を御覧ください。
jqを使って、jsonのarrayに要素追加/削除

##0.　ファイル
- 対象ファイル(external-scripts.json)


```json
[
  "hubot-diagnostics",
  "hubot-help",
  "hubot-heroku-keepalive",
  "hubot-google-images",
  "hubot-google-translate",
  "hubot-pugme",
  "hubot-maps",
  "hubot-redis-brain",
  "hubot-rules",
  "hubot-shipit"
]

```

##1. 追加

- 配列の最後尾に要素追加
- 配列の要素数もjqで取得して使う

```bash
 cat external-scripts.json | jq ".[$(cat external-scripts.json | jq '. | length')]|= .+\"hoge\""
[
  "hubot-diagnostics",
  "hubot-help",
  "hubot-heroku-keepalive",
  "hubot-google-images",
  "hubot-google-translate",
  "hubot-pugme",
  "hubot-maps",
  "hubot-redis-brain",
  "hubot-rules",
  "hubot-shipit",
  "hoge"　　　　　　　　　　# <= 最後にhogeが追加された
]

# 追記: これでもできますが後からためしてみると、もっと簡単にできそうです
jq '.+["hohe"]' external-scripts.json　　# とか
cat external-scripts.json | jq '.|=.+["hoge"]'　# とか
```

##2. 削除

- `hubot-heroku-keepalive`を配列から削除して表示してみる

```bash
 cat external-scripts.json | jq ' .-["hubot-heroku-keepalive"]' 
[
  "hubot-diagnostics",
  "hubot-help",
  "hubot-google-images",
  "hubot-google-translate",
  "hubot-pugme",
  "hubot-maps",
  "hubot-redis-brain",
  "hubot-rules",
  "hubot-shipit",　　　　　
]
```

- `hubot-shipit`と`hubot-pugme`を配列から削除して表示してみる

```bash
 cat external-scripts.json | jq ' .-["hubot-pugme","hubot-shipit"]' 
[
  "hubot-diagnostics",
  "hubot-help",　　　　　　　　
  "hubot-google-images",
  "hubot-google-translate",
  "hubot-maps",
  "hubot-redis-brain",
  "hubot-rules"　　　　　
]
```
bash > 環境変数OLDPATHが定義されていたらxxxする > [ ! -z "$OLDPATH" ] && echo $OLDPATH  > openmpiとmpichの切替

```txt:動作環境
ブラウザ動作のbash
http://qiita.com/7of9/items/600815f9ab461fe0d36d
```

環境変数OLDPATHが「定義されていたら」xxxしたい。

### 参考

参考 http://stackoverflow.com/questions/11686208/check-if-environment-variable-is-already-set
> answered Jul 27 '12 at 10:48
Igor Chubin

```
[ -z "$VARIABLE" ] && VARIABLE="abc"
```

### 実装

上記を参考に以下とした。

```txt:準備
$ export OLDPATH=TEST
```

```txt:実行
$ [ ! -z "$OLDPATH" ] && echo $OLDPATH                                                                                         
TEST
```

上記を使って何をしようかというと、OLDPATHという定義をしている時にPATHをOLDPATHに書き換える。

```
$ [ ! -z "$OLDPATH" ] && export PATH=$OLDPATH
```

OpenMPIとMPICHの切替でPATHを変更しようかと考えている。

exportされているかどうかのチェックは自分の用途では不要。

### .bashrcと切替用ファイル (use_mpich / use_openmpi)

```txt:.bashrc
...中略...
OLDPATH=$PATH
```

```txt:use_mpich
[ ! -z "$OLDPATH" ] && PATH=$OLDPATH
export MPICH=/usr/lib64/mpich/bin
export PATH=${MPICH}:$PATH
```

```txt:use_openmpi
[ ! -z "$OLDPATH" ] && PATH=$OLDPATH
export OPENMPI=/usr/lib64/openmpi/bin
export PATH=${OPENMPI}:$PATH
```

以下のように使う

```
$ source use_mpich
$ mpirun -h | tail
...
Please see the intructions provided at
http://wiki.mpich.org/mpich/index.php/Using_the_Hydra_Process_Manager
for further details
```

```
$ source use_openmpi
$ mpirun -h | tail
...
Report bugs to http://www.open-mpi.org/community/help/
```

module loadはそれぞれ対応するものだけロードして使った。
AWSで構築されたサイトをSSL化しようとしたらリダイレクトループではまった

タイトルの通りですが、意外とハマったのでメモです.
## やりたいこと
- http(80)できたらhttps(443)でリダイレクトさせたい

## 原因となった箇所
筆者の場合原因は
1. ロードバランサーの設定.
2. .htaccessの設定
の二箇所.

- ロードバランサーのポートの設定(わかる方はここ見た瞬間にお察しかと思います笑)
    - 80->80
    - 443->80

## 失敗例
今回CakePHPだったのでwebroot内の.htaccessに↓のように記述しました.

```htaccess:.htaccess
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/sample/$1 [R=301,L]
```

これにhttpで指定のurlにアクセスすると想定通りにはいかず, ブラウザから「リダイレクトループ含まれてるよおおおおおお」って怒られる.

## 原因
- 上記ロードバランサーのポート設定で443が80に書き換わってしまうわけです.

つまり
1. http(80)でアクセスします.
2. ELBが80をEC2に80で渡して
3. EC2の.htaccessが「80を443でリダイレクトするぞ！」ってなる
4. ブラウザは443でアクセス
5. ELBは設定を守って「443を80で流すぞ！」となって443をEC2に80で渡す

すると3に戻るわけですね.
あとは3~5を無限ループ.

## 解決
.htaccess を↓のようにしましょう.

```htaccess:htaccess
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !=https // ここでリダイレクト指定
RewriteRule ^(.*)$ https://%{HTTP_HOST}/sample/$1 [R=301,L]
```

ELBのようなリバースプロキシで https してるときは X-Forwarded-Proto ヘッダを見るようですね.
ちなみに %{HTTPS} は mod_ssl の判定で使うようです.
こうするとELBへの接続プロトコルを判別して「httpsじゃない場合はhttpsでリダイレクトしてこいよ」という意図した実装になるわけですね.

すごく簡単なことかも知れないですが, ELBの存在をうっかり忘れるとしばらくはまる可能性があるのでお気をつけください.
CakePHPでログの出力形式をカスタマイズしたい

※「≈≈≈」は省略を表す

# バージョン

```
$ cat lib/Cake/VERSION.txt
≈≈≈
2.4.5
```

# CustomFileLog.phpの作成

```
$ cp -p lib/Cake/Log/Engine/FileLog.php app/Lib/Log/Engine/CustomFileLog.php
$ vi app/Lib/Log/Engine/CustomFileLog.php
```

1. 既存のApp::usesを削除して、以下を追加

    ```
App::uses('FileLog', 'Log/Engine');
```

2. 「```class FileLog extends BaseLog {```」を削除して、以下を追加

    ```
class CustomFileLog extends FileLog {
```

3. 「```public function write($type, $message)```」以外の関数は全て削除
4. 「```public function write($type, $message)```」内の「```$output = date('Y-m-d H:i:s') . ' ' . ucfirst($type) . ': ' . $message . "\n";```」を削除して、好きなフォーマットに変更
    例） シンプルにメッセージだけを出力したい場合

    ```
$output = $message . "\n";
```

5. bootstrap.phpを編集

    ```
$ cat app/Config/bootstrap.php
≈≈≈
/**
 * Configures default file logging options
 */
App::uses('CakeLog', 'Log');
App::uses('CustomFileLog', 'Log/Engine'); // 追加
CakeLog::config('debug', array(
	'engine' => 'File',
	'types' => array('notice', 'info', 'debug'),
	'file' => 'debug',
));
CakeLog::config('error', array(
	'engine' => 'File',
	'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
	'file' => 'error',
));
// 今回は、custom.logだけ、出力形式がカスタマイズしたいので、以下を追加
CakeLog::config('custom', array(
	'engine' => 'CustomFile', // ここでCustomFileLogクラスを見るように指定している
	'types' => array('custom'),
	'file' => 'custom'
));

config('const');
```
サーバ作業でミスしないための Bash プロンプト設定

サーバ内で作業する際のミスを防ぐ最良の手段は「サーバ内で作業しない(自動化する)こと」だが、どうしてもサーバ内で作業しなければいけないことはある。

複数のサーバで作業していたりすると、いまどのサーバにいてどういう状態なのかがわかりにくくなってしまう。そういうときにやっておくとミスを防げるかもしれない Bash プロンプトの設定について。

## 概要
こういうの感じのプロンプトになる。

![](https://qiita-image-store.s3.amazonaws.com/0/16369/fdc81cb1-4dc6-1d79-2e38-3e350aa4442c.png)

- ホスト名が表示される
- カレントディレクトリが表示される
- Git リポジトリ内の場合
    - ブランチ名が表示される
    - コミットされていない変更や追加されていないファイルがあるかどうかを表示する
- root ユーザかどうかを表示する
    - root (uid=0) であれば `#`
    - それ以外は `$`
- 直前のコマンドでエラーがあったかどうかを色で表示する
    - 終了ステータスが 0 なら緑
    - それ以外は赤

## ホスト名を変える
プロンプトを変える前にまずはこれ。
Amazon EC2 とかだと初期状態は IP アドレスから自動生成されたホスト名になっていてわかりづらい。わかりやすいホスト名を付けておくことで「違うサーバで作業してた」というような間違いを防げる。

### Ubuntu
``` :/etc/hostname
xxxxx.com
```

### Amazon Linux 1
``` :/etc/sysconfig/network
HOSTNAME=xxxxx.com
```

### Amazon Linux 2
```
# hostnamectl set-hostname xxxxx.com
```

## git-prompt.sh を落としてくる
プロンプトに Git リポジトリに関する情報を表示するための Git 公式便利ツールを入れる。

```
$ curl -L https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh -o ~/.git-prompt.sh
```

## bashrc に追記する
``` bash:~/.bashrc
GIT_PS1_SHOWDIRTYSTATE=1
GIT_PS1_SHOWUNTRACKEDFILES=1
GIT_PS1_SHOWCOLORHINTS=1
source ~/.git-prompt.sh
PS1='\[\e[1;30m\]\H:\W$(__git_ps1 "(%s)")\[\e[0;31m\]$([ $? == 0 ] && echo "\[\e[0;32m\]")$\[\e[0m\] '
```

- ホスト名を短い版 (`hostname -s`) を表示したければ `\H` を `\h` にする
- カレントディレクトリをフルパスで表示したければ `\W` を `\w` にする
- ユーザーを切り替えることが多いサーバであればユーザー名 `\u` を表示してもいいかもしれない

## Bash の設定を再読み込み
ログインし直すか `source ~/.bashrc`

## [追記]: 文字が真っ黒になってしまう場合
ターミナルの設定によっては文字が真っ黒になってしまうことがあるらしい。

![](https://qiita-image-store.s3.amazonaws.com/0/16369/f4c9cce4-30cb-1433-bbba-6e5d31aa0d8e.png)

`\e[1;30m` は「明るい(1)黒(30) = Dark Gray」という意図で使っていたのだが、ANSI カラーシーケンスの Text Attribute の `1` はもともと `Bold on` という意味なので[^1]、これに従って「太字の(1)黒(30)」と解釈するターミナルだとこの現象が発生してしまう。

これを回避するには、素直に文字を白 `\e[0;37m` に変えるか、ターミナルの設定で Text Attribute の `1` を「太文字」ではなく「明るい文字」として解釈するように設定する。

![](https://qiita-image-store.s3.amazonaws.com/0/16369/6070d5b4-a1bd-c207-0530-cfa1676cc4ea.png)

[^1]: [RubyでANSIカラーシーケンスを学ぼう！](http://melborne.github.io/2010/11/07/Ruby-ANSI/)
RANCIDでCiscoのコンフィグ取得時にTimestampが出力されるのを防ぐ方法

#はじめに
Catalyst等で vtyに`exec prompt timestamp`を入れておくと、コマンドを叩いた時間が表示されるという便利機能があるが
この部分が日時バックアップ時に差分として記録されてしまっていたので、実際にコンフィグを変更した日付がわかり辛くなっていた。

- コマンド実行時にタイムスタンプを残す設定例

```
line vty 0 4
 exec prompt timestamp
```

コマンドを叩くたびに日付と時間、CPU使用率等が変化するため、差分として記録されてしまう。

```
!Flash: Load for five secs: 36%/0%; one minute: 31%; five minutes: 31%		
!Flash: Time source is NTP, 23:01:08.558 JST Tue Sep 27 2016
```

#RANCID 2.3.8の場合
`/usr/local/rancid/bin/rancid`内に次のような変更を加える

```vim:/usr/local/rancid/bin/rancid
  # dummy function
> #sub DoNothing {print STDOUT;}
> sub DoNothing {
>     print STDERR "    In DoNothing: $_" if ($debug);
>     while (<INPUT>) {
> 	tr/\015//d;
> 	last if (/^$prompt/);
> 	next if (/^(\s*|\s*$cmd\s*)$/);
>     }
>     return 0;
> }
  # Main
  @commandtable = (
> 	{'terminal no exec prompt timestamp' => 'DoNothing'},
  	{'show version'			=> 'ShowVersion'},
```

#RANCID 3.4.1の場合
ファイル構成が変わっているが、やることは同じ。

```vim:/usr/loca/rancid/lib/rancid/ios.pm 
> # clear exec timestamps 
> sub DoNothing {
>     my($INPUT, $OUTPUT, $cmd) = @_;
>     print STDERR "    In DoNothing: $_" if ($debug);
> 
>     while (<INPUT>) {
>       tr/\015//d;
>       if (/^$prompt/) { $found_version = 1; last};
>       next if (/^(\s*|\s*$cmd\s*)$/);
>       next if (/^\s+\^$/);
>     }
>     return 0;
> }
>


# This routine parses "show version"
sub ShowVersion {
```

```vim:/usr/loca/rancid/etc/rancid.types.base
  # Cisco IOS device & Allied Telesis AW+
  cisco;script;rancid -t cisco
  cisco;login;clogin
  cisco;module;ios
  cisco;inloop;ios::inloop
> cisco;command;ios::DoNothing;terminal no exec prompt timestamp
  cisco;command;ios::ShowVersion;show version
```


#関連リソース
- https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=555705;msg=5
grpcを入れたらubuntuのunityが壊れた話

#### 現象
gRPCをコンパイルしたらubuntuのデスクトップが崩壊した．

#### 解決策
gRPCを入れる際にthird_party内のprotobufをインストールしたのが問題だったらしい．
unityのcompizがprotobufを利用していて，バージョンの違いなのか起動できなくなっていた．

grpc/pthird_party/protobufで

```bash
sudo make uninstall
```
で削除した後

```bash
sudo apt-get install --reinstall libprotobuf-dev libprotobuf8 libprotobuf-lite8
```
で再起動したら元のデスクトップに戻っていた．
OpenFOAMのバグトラッカに報告された改善内容をGitHubで確認する方法

この記事では，OpenFOAM のバグトラッキングシステム( http://bugs.openfoam.org/ )において修正が報告されたコードの内容を，GitHub上で確認する方法をメモします．

報告されたバグに対して対策が施された場合，開発者から，次のようなコメントが書き込まれます。（例 http://bugs.openfoam.org/view.php?id=1727 ）この例では，製品バージョンは 2.4.0 です。

```
Resolved by commit 1c58abec87ad0251ece3266f83802f1fad32d1d6
```

　製品バージョンに対応する開発版（上記例では，2.4.x ）のコードに対して，修正が適用されているはずです。

　修正された内容を確認するには，GitHub へアクセスします。バージョンとコミット番号を指定したアドレスにアクセスすることで，その内容が表示されます。例えば，次のリンク先です。

https://github.com/OpenFOAM/OpenFOAM-2.4.x/commit/1c58abec87ad0251ece3266f83802f1fad32d1d6

これは，GitHubの ”OpenFOAM”というユーザが開いた "OpenFOAM-2.4.x"リポジトリのcommit番号 "1c58abec87ad0251ece3266f83802f1fad32d1d6" へのリンクを表します。

　別の例を示します。

　開発バージョンが dev ，コミット番号が c6b3632c856a0f40b38973bfc546cc07520612a6 の場合（http://bugs.openfoam.org/view.php?id=2268 ）には，次のリンクとなります。

 https://github.com/OpenFOAM/OpenFOAM-dev/commit/c6b3632c856a0f40b38973bfc546cc07520612a6
Unity Asset「Easy Movie Texture」のVideoCopyTextureをiOSで動かすと動画表示が反転する

#開発環境
* Unity Pro 4.7.2
* Easy Movie Texture 3.40

#問題点
１つの動画再生を複数のテクスチャに表示できるVideoCopyTextureという便利な機能がある。
Androidだと問題ないが、iOSで動かすと表示が反転してしまう。

#再現手順
1. New Sceneを作成する。
2. Hierarchyに、EasyMovieTexture > Prefab > VideoManagerを追加する。
3. Hierarchyに、EasyMovieTexture > Prefab > VideoPlaneを追加する。
4. Hierarchyに追加したVideoPlaneに、EasyMovieTexture > Scripts > VideoCopyTexture.csを追加する。
4. VideoPlaneのInspectorを開き、Video Copy TextureのプロパティSrc Videoに、HierarchyのVideoManagerを入れる。
5. このシーンをiOSで実行すると、VideoPlaneの表示が反転している。(VideoManagerの表示は正しい)

#解決方法
HierarchyのVideoPlaneのTransform > Scale > Xの値をマイナスにする。（例えばXのスケール値が0.5のときは、-0.5にする）
ただしこれだとAndroidで表示が反転してしまうので、実行環境に応じて対処する必要がある。
ローカル IP が枯渇して VPN 接続ができなかった時の話


## 症状
なんか VPN が使えない。

## 原因
DHCP がリース可能なローカル IP アドレスがなかった。

## ルータの設定
* DHCP がリースできる IP は18個
* IP アドレスのリース期間は3日
* VPN での接続時にクライアントは DHCP からローカル IP の割り当てを受ける

## 対策
* DHCP のリースアドレスを増やした
* リース期間を24時間にした
* モバイル端末などの Wifi アクセスを受けるルータを1台追加し、セグメントを分離した

ルータ追加はコストがかかるが、今回は業務上必要だったので行った。
セグメントの切り分けや中継の設定方法はそれぞれのルータの説明を確認。

## 実際の調査
思いつくことはいくつかあるけれども、とりあえず現状は把握しておかないとならない。

### 前提
* クライアントに MacBook を使用
* クライアントでは VPN の設定が完了している
* クライアントは対象のルータに接続していない
* 対象のルータに接続済みの端末があり、ルータの管理画面を開いている
* ルータのメーカーは YAMAHA

### VPN 接続時のログを詳細に吐くようにする
1. りんごマーク＞システム環境設定＞ネットワーク＞該当の VPN ＞詳細＞詳細なログを作成にチェック
2. ターミナルを開く
3. 次のコマンドを叩く
`tail -f  /var/log/system.log`
4. 該当の VPN に接続する

これで接続した瞬間だらだらログがでるはず。
ログ表示を止めるときは `control + C` を押す。

### ログを調べてたら
`PPTP connection established.` となっているので、ルータも生きているし、 VPN の初期フェーズは突破している。
だがそのあとで `PPTP disconnected` となってしまう。
問題はその間のログにあるはず。
でも実際に書いてあったのは以下。

	ppp0: is now delegating en0 (type 0x6, family 2, sub-family 3)
	Connect: ppp0 <--> socket[34:17]
	LCP: timeout sending Config-Requests
	Connection terminated.
	PPTP disconnecting...
	
詳細ログとは一体。

### わかんねーときは比較だ
ということで、他の VPN に接続してそのログを見てみる（一部省略）。

	PPTP connection established.	ppp0: is now delegating en0 (type 0x6, family 2, sub-family 3)
	Connect: ppp0 <--> socket[34:17]
	local  IP address 192.168.xxx.x
	remote IP address 192.168.xxx.1

local IP address とな？

### ルータの状態を見てみる
DHCP のリース帯を確認 -> 18個
現在リース中のアドレス数 -> 18個
**こ　れ　だ**

## よく考えると
VPN だろうがローカル IP を割り当てる必要があるのは当たり前で、割り当てには DHCP サーバが担当するのもわかりきったことだった。
しかし VPN が繋がらないと言ったら、普通他の原因を探ると思うんだ。
そもそも設定がおかしいとか、認証方法やパスワードを間違えてるとか、ルータが死にかけてるとか。
そりゃネットを調べてみても、解決策がなかなか出てこないわけだよ。
VPN 自体の障害じゃないもん。

## 蛇足
今回は対応としてモバイル端末の Wifi を切り離したが、ルータによっては VPN 接続してきた端末のセグメントを分離することができる。
その場合はローカル資源にアクセスできるように、両方のセグメント間で通信ができるように設定する必要がある。
CakePHP3.xでLoginActionに値を渡すと弾かれる対策

CakePHPでAuthコンポーネントを使用した認証を作成する際、
ログインページのURLに値を持たせてログイン処理を制御しようとしたらはまったのでメモ。

(例) /users/login   // ok
    /users/login/1  // ng

ログインに使用するアクションの判定はURLで行っているらしく、
余計な値を持たせると別ページと判断されてしまうみたい。

対象コントローラのinitialize()で、
<code>$this->Auth->allow(['login']);</code>
と書きloginアクションを認証の対象外にすることで対処できた。
Outlook APIによるメール送信

Outlookから定期的にメールを送信する必要がありAPIを調べた。


簡単な例が以下

```
  var app = new Outlook.Application();
  Outlook.MailItem mail = app.CreateItem(Outlook.OlItemType.olMailItem) as Outlook.MailItem;
  mail.Subject = "タイトル";
  Outlook.AddressEntry currentUser = app.Session.CurrentUser.AddressEntry;
  mail.Body = "本文";
  mail.Recipients.Add("宛先@xx.com");
  mail.Recipients.ResolveAll();
  mail.Send(); 
```

Application.CreateItem メソッド
https://msdn.microsoft.com/ja-jp/library/office/ff869635.aspx

Outlook.MailItemメソッド
https://msdn.microsoft.com/ja-jp/library/office/ff861252.aspx

利用時はアセンブリを追加
Microsoft.Office.Core

----

Outlook関係なく送る方法

```
  MailMessage msg = new MailMessage();
  msg.From = new MailAddress("FROM");
  msg.To.Add(new MailAddress("TO"));
  msg.Subject = "件名";
  msg.Body = "本文";
  System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient();
  smtp.Host = "ホスト名";//SMTPサーバーを指定
  smtp.Port = 25;//（既定値は25）
  smtp.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
  smtp.Send(msg); 
  msg.Dispose();
  smtp.Dispose();//（.NET Framework 4.0以降）
```

http://c-sharp-guide.com/?p=434
【Java8】関数インターフェースでメソッドチェーン

どこにあったかは忘れたけど別言語で関数インターフェースを使ってメソッドチェーンを組む方法が紹介されていたのでそれをJavaに起こしてみた。

```java:
import java.util.function.Consumer;

public class Hoge
{
    public void method1() { /* 何らかの処理 */ }
    public void method2( final int value ) { /* 何らかの処理 */ }
    public void method3() { /* 何らかの処理 */ }

    public Hoge chain( final Consumer<Hoge> call )
    {
        call.accept( this );
        return this;
    }
}
```

呼び出し元

```java:
final Hoge hoge = new Hoge();
hoge.chain( o -> o.method1() )
    .chain( o -> o.method2( 5 ) )
    .chain( o -> o.method3() );
```

メソッドチェーンでHogeクラス内のメソッドを繋げて呼ぶことができる。
けど素直にvoidを自クラスにしてthisで返した方がいいような気もするけどメモとして。

### 追記

interfaceで実装してみてはどうか、というコメントを頂いたので抜き出してみました。

```java:ChainInterface.java
import java.util.function.Consumer;

public interface ChainInterface
{
    @SuppressWarnings( "unchecked" )
    public default <T extends ChainInterface> T chain( final Consumer<T> call )
    {
        call.accept( (T) this );
        return (T) this;
    }
}
```

使う時はHogeクラスに「implements ChainInterface」を付ける。

```java:Hoge.java
public class Hoge implements ChainInterface
{
    public void method1() { /* 何らかの処理 */ }
    public void method2( final int value ) { /* 何らかの処理 */ }
    public void method3() { /* 何らかの処理 */ }
}
```

呼び出し元

```java:
final Hoge hoge = new Hoge();
hoge.chain( (Hoge o) -> o.method1() )
    .chain( (Hoge o) -> o.method2( 5 ) )
    .chain( (Hoge o) -> o.method3() );
```

「(Hoge o)」のようにしないといけないけどこれを省略できる方法があるのかな。
[Swift] NavigationControllerのshow(push)で画面がフリーズ（leftBarButtonItemをカスタマイズした弊害でした）

NavigationController
└ ViewController
　└　TableView

このような構成で、TableViewのCellをタップしたら、次のViewControllerをshowするアプリで、スワイプ気味でTableViewCellを操作すると、まれに画面がフリーズすることが起きた。
さまざまな検証をしたが、なぜこのようなことが起きるのか原因がわからない。ただ再現性を検証してみるかぎり、何度かNavigationController内で行き来を繰り返していると発生するらしい。

この[StackOverflow](http://stackoverflow.com/questions/26674279/app-freeze-on-ios-8-when-push-or-pop)の通り、以下のようなinteractivePopGestureRecognizerの有効無効を制御することで解消できた。

```swift
class ViewController: UIViewController, UINavigationControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationController?.delegate = self
    }

    func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) {
        if self.navigationController!.respondsToSelector(Selector("interactivePopGestureRecognizer")) {
            if self.navigationController!.viewControllers.count > 1 {
                self.navigationController!.interactivePopGestureRecognizer?.enabled = true
            }else{
                self.navigationController!.interactivePopGestureRecognizer?.enabled = false
            }
        }
    }
}
```

かなりはまったし、再現も難しい。
全く意味わからないけど、誰かの役に立つことを願って。


**追記**：原因が分かりました。

[leftBarButtonItemをカスタマイズしたらエッジスワイプが無効になった](http://qiita.com/takashings/items/fef19c4b19dcf788e42e)
この記事にある通り、遷移先でleftBarButtonItemを変更していた。その為以下のコードをviewDidLoadにいれていた

```swift
self.navigationController.interactivePopGestureRecognizer.delegate = self
```

それが影響していた。よって以下の記事の通りにviewWillDisappearで元のdelegateを戻してあげる必要があった。

[UINavigationBarの戻るボタンをカスタムしてスワイプで戻る挙動も有効にする](http://qiita.com/katsuhisaishii/items/9e382d9dc2db8a43001a)

いやーはまった、はまった。


**さらに追記：**
問題の箇所はわかったので、viewWillDisappearで元のdelegateを戻す事で基本解決するが、viewWillDisappearを経由してくれない遷移があった。TabBarを使っていて、最初のページに戻る時。

よって、結局一番最初に書いた「interactivePopGestureRecognizerの有効無効を制御」を実装して対応した。
scipy Voronoi

ボロノイ分割をしたかったので `scipy.spatial.Voronoi` を使ったのだけれど、用語や配列の意味に混乱したので、整理してみた。

[ドキュメント](http://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.Voronoi.html)にあるように、処理自体はすぐにできる。

```py
import numpy
import scipy.spatial
v = scipy.spatial.Voronoi(numpy.array([[0,0],[0,1],[1,1]]))
```

まず point, region, ridge, vertice の意味。2 次元だとこんな絵になる。2 次元だと ridge は線だけれども、3 次元だと ridge は面になる。

![IMG_1585[1].JPG](https://qiita-image-store.s3.amazonaws.com/0/41883/d11b253d-ea98-67fe-8aeb-e7d96259dc44.jpeg)

それぞれのデータは `Voronoi` object の属性に対応表の形で入っている。インデックス番号で対応表は表現されている。図にするとこんな感じで辿るようになっている。少し凝ったことをすると、たくさん辿らないといけないので、迷子にならないように丁寧に追いかけないといけない。

![IMG_1584[1].JPG](https://qiita-image-store.s3.amazonaws.com/0/41883/8e51c022-3f01-0fb0-3b80-6c55ac0cc79c.jpeg)

閉じた領域で `Polygon` を作る時は、例えば次のようなコードになる。

```py
import geopandas as gpd
from shapely.geometry import Polygon
va = gpd.GeoDataFrame([dict(geometry=Polygon([v.vertices[vt] for vt in v.regions[r]]), pti=pti)
	for pti,r in enumerate(v.point_region) if -1 not in v.regions[r]])
```
CentOS 6.8 > link > IPv6を無効にする

```txt:動作環境
CentOS6.8
```

dmesg | tailした時に`eth0 : no IPv6 routers present`という表示が見つかった。

以下を参考にIPv6を無効にした。
http://smilemark.net/blog/archives/2011/08/disable-ipv6-centos6.php

3つとも変更しないといけないかは未消化。

### 本家の情報

@hkatoさんに本家の情報を教えていただきました。[コメント](http://qiita.com/7of9/items/c3c1b13aebc441e14cc8#comment-8bc350d36ac358e1d787)

情報感謝です。
paper_trail 5.0 未満 使ってると raise_in_transactional_callbacks の warning が出続ける

1. paper_trail 使ってると rails 4.2 以降で `config/application.rb` へ `config.active_record.raise_in_transactional_callbacks = true` 入れてても warning 出続ける。
2. というのが https://github.com/airblade/paper_trail/issues/584#issuecomment-130795342 で
3. https://github.com/airblade/paper_trail/pull/725 で直ったっぽい。
4. Changelog 的 には paper_trail 5.0 からリリースに入っている https://github.com/airblade/paper_trail/blob/d324bdf86ae20abb6888b3e508c943b4da8c3094/CHANGELOG.md#500-2016-05-02
VSCodeで連番を入力できる拡張機能を作りました

## 作りました、というよりは
AtomにあったパッケージをVSCode版にしてみました。
[vscode-input-sequence](https://marketplace.visualstudio.com/items/tomoki1207.vscode-input-sequence)

tsuyoshiwadaさんによるAtom版はこちらです。
[sequential-number](https://atom.io/packages/sequential-number)

ソースを見るまでもないですが、CoffeeScript → JavaScript をしただけです。

## 使い方
![screenshot.gif](https://qiita-image-store.s3.amazonaws.com/0/111100/052f62c2-3ab2-dd25-160a-2549b65b3491.gif)

構文などはすべてAtom版と同様です。(のはずです)
VSCodeだとパレットのラベルを動的に変えられなかったので、プレビューの代わりにリアルタイムで結果を反映させるようにしました。
`Enter`で結果が確定され、`Esc`でキャンセルされます。

IssueやPRお待ちしてます。

## 参考
[Atomでマルチカーソルの連番入力をするパッケージ「sequential-number」をリリースしました](http://webdesign-dackel.com/2015/11/22/atom-sequential-number/)
[Visual Studio Codeの拡張機能を公開する方法](http://toach.click/vscode-blade-runner/)
Rubyで配列内に要素があるか検索

`include?`を使って配列内に要素があるかどうかを判定する
`対象の配列.include?(配列内に存在するか確かめたい値)`

念のため例をしたに出しておきます。

```
@hoge = 'bird','dog','cat'
// 以下でtrueが返ってきます。
@hoge.include?('cat')
win10 > Windows update 2016年9月28日 > 進まない / Windows Updateカタログから取得して適用する

```txt:動作環境
Windows 10 Anniversary Update適用PC 二台
```

更新プログラムを確認しています、から進まない。

- KB3193494
- KB3176936

Windows UpdateカタログにIEから接続し手動取得して適用した。

その後、更新プログラムの確認は早くなった。

上記を適用後、イベントログででていた以下のエラーがなくなった。

> 障害が発生しているアプリケーション名: svchost.exe_wuauserv、バージョン: 10.0.14393.0、タイム スタンプ: 0x57899b1c

vmwareのCentOSから外部物理サーバ(CentOS)へのssh -X接続の速度改善は見られず。

- 「予期しないエラーが発生しました」というエラーが出なくなったような気がする
- エクスプローラが固まる現象が出なくなったような気がする
- イベントログの表示などの処理の応答が早くなった気がする


参考 http://www.vwnet.jp/Windows/w10/2016091401/KB3189866.htm
> この問題は、Microsoft Update カタログ(要 IE)から更新プログラム(KB3189866)をダウンロードし、手動でインストールすれば解消します。

KB3189866というのはカタログにはもはや存在せず、上記の2つのファイル(KB3193494とKB3176936)を取得した。
packagistを使わないcomposerのgitリポジトリの作成

プロジェクト内の一部のソースをcomposerのライブラリに切り出して、クローズドなgitリポジトリを作ったのでメモ。

ハマったポイントと、わかったことを記載します。

## 発端

composerのライブラリの作成ってだいたいGitHub+packagistなんで、参考になる記事が少なかった。

特に、今回はGitLabを使っているので余計に少ないのと、自分自身、GitHubもろくに使っていないしcomposerライブラリの作成経験もなかったのでそこそこ苦労した。

## 先に結論

1. 新しくライブラリ用のGitリポジトリを作る
2. `composer init`などでcomposer.jsonを作成する。内容はググれば山ほど出てくる
3. pushする
4. 使う側のcomposer.jsonの`repositories`に上記リポジトリを追加する
5. `require(-dev)`で、2で作ったパッケージ名(name)を指定する

必要なのはこれだけ。
あとは[接続用にSSHの公開鍵なんかを準備](http://qiita.com/redamoon/items/4b25fd2b2b9947f738fa)したらそれで完了。

## わからなかったことなど

### どうすればcomposerからインストールが可能なリポジトリとなるのか

使う側は、composer.jsonにrepositoriesを追加すれば、packagistに登録しない（できない）状態でもそのリポジトリをcomposerは検索してくれる

```json
{
    "repositories": [
        {
            "type": "vcs",
            "url": "git@gitlab.example.com:foo/bar.git"
        }
    ],
}
```

通常、composerは"require", "require-dev"に記載したパッケージをpackagistに検索しに行くが、
"repositories"に追加されたリポジトリがある場合、そのリポジトリにも探しに行く。

**この際、リポジトリのディレクトリにcomposer.jsonが存在し"name"が設定されている場合、composerはライブラリとして認識する。**

> 全てのプロジェクトはパッケージである
> composer.jsonをディレクトリに配置した時点で、そのディレクトリはパッケージとなります。
> 
> [公式ドキュメント（翻訳）](https://kohkimakimoto.github.io/getcomposer.org_doc_jp/doc/02-libraries.html)

### packagistを使わない場合、composer/satisを使う必要があるの？

[packagistを使わない場合に、composer/satisを使うと良いみたいな記事](http://ngyuki.hatenablog.com/entry/2012/11/06/210638)を見たので、最初satisを使う必要があるのかと思い迷走したが、satisは自作のpackagistを作るようなものなので、単に"repositories"にリポジトリを追加する形でライブラリを作成する場合は必要ない。

当然、packages.jsonなんかも必要ない。

逆に、あまりにクローズドのライブラリが増えて、"repositories"に追加するのが大変になったりしたら、satisを使ったほうが楽。

[あと、packagistのミラーを作ったりもできるみたい。](https://code.tutsplus.com/tutorials/setting-up-a-local-mirror-for-composer-packages-with-satis--net-36726) たのしそう。

### そんなパッケージが無いとエラーがでる

そもそも、上記のようにsatisが必要なんじゃないかまで迷走したのは、
composer.jsonを設置したリポジトリを準備しても、そんなパッケージ無いよとエラーが出ていたからだった。

```
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - The requested package foo/bae could not be found in any version, there may be a typo in the package name.
```

原因はtypoでした…。

接続エラーがでていないなら、パッケージ名をよく確認しましょう…。
尚、`composer.json`がない場合は、パッケージが無いじゃなくて以下のようになります。

```
  [Composer\Repository\InvalidRepositoryException]                                                                                                    
  No valid composer.json was found in any branch or tag of git@gitlab.example.com:foo/bar.git, could not load a package from it.
```

### GitLabへのhttp+BASIC認証の接続がうまくいかない

恐らく、type:vcs(git)の場合、httpで接続するのは得策ではない。

* [.netrcにユーザー名・パスワードを記載する方法](http://qiita.com/r-tamura/items/c6e49a3eb7f7f8aafb9d)はうまく動作しなかった。環境によるものか、composerからやった場合にうまくいかないのかは未検証
* `auth.json`を使う方法も、何故か動作しなかった。httpだったから？これも未検証
* そもそも、公式には以下のように書いている

> Exactly the same solution allows you to work with your private repositories at GitHub and BitBucket:
> The only requirement is the installation of SSH keys for a git client.
> 
> [https://getcomposer.org/doc/05-repositories.md#using-private-repositories](https://getcomposer.org/doc/05-repositories.md#using-private-repositories
)

**git client用にSSH keysを準備することだけが要件だよ！**
…なんて書いてるくらいなので、もうおとなしくSSHにしたほうがいいと思う。
AWS fluentdでelbのログをElasticSearch Service のkibanaで可視化

ログサーバーを立ててkibanaで可視化したのでメモです。


前準備
・elasticsearch serviceの作成
・IAMユーザーとポリシー作成（ESへのアクセス、S3へのアクセス）
・ELBのログをs3に保存（自分は１時間ごとにs3に保存にしました。）


#fluentd 設定

fluentdと使用するプラグイン　インストール

```
#curl -L http://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sudo sh
#td-agent-gem install fluent-plugin-elasticsearch
#td-agent-gem install fluent-plugin-elb-log
#vi /etc/td-agent/td-agent.conf
```

[]の中は例です。

```text:td-agent.conf

<source>
  type elb_log
  region ap-northeast-1
  s3_bucketname [buket name] #elbのログが保存されているバケット指定
  s3_prefix [logs/elb-log] #ディレクトリを指定
  timestamp_file /tmp/elb_last_at.dat
  buf_file /tmp/fluentd-elblog.tmpfile
  refresh_interval  [3600] #ELBのログが入るのが1時間なので1時間ごとに更新する。
  tag elb.access.log
  access_key_id [XXXXXXXXXXXXXXXXXXXXX] #IAMユーザーのアクセスキー
  secret_access_key [XXXXXXXXXXXXXXXXXXXXXXX] #IAMユーザーのシークレットキー
</source>

<match elb.access.log>
    type elasticsearch
    hosts https://search-[domain].ap-northeast-1.es.amazonaws.com/
    type_name elb-access
    logstash_format true
    logstash_prefix elb-access-log
    flush_interval 10
</match>
```

権限を変更して起動

```
#touch /tmp/elb_last_at.dat
#chown td-agent:td-agent /tmp/elb_last_at.dat
#touch /tmp/fluentd-elblog.tmpfile
#chown td-agent:td-agent /tmp/fluentd-elblog.tmpfile
#/etc/init.d/td-agent start
```
kibanaを開いてindex patternに「elb-access-log*」でindexを作成する

#問題
・古いelbログが削除されないのでたまっていくばかり。ttlというやらでローテートできるらしい。
ひとまずは、`#curl -XDELETE https://search-[domain].ap-northeast-1.es.amazonaws.com/[index]`
でログを削除できる。
その前にcurlコマンドで操作する場合にはaws configureコマンドでIAMをインスタンスに登録する必要あり。

・/var/log/td-agent/td-agent.logに「S3 Client error occurred: Access Denied」とエラー
IAMユーザーにはS3にアクセスできるように設定してあるし、ELBのログをS3からとってきているあたりアクセスできているかと…
Unity Asset「Easy Movie Texture」をiOSで動かすとハングアップする

#開発環境
* Unity Pro 4.7.2
* Easy Movie Texture 3.40

#問題点１
Easy Movie TextureのDemoシーンをiOSで動かすとアプリ起動直後にハングアップする。

##解決方法
EasyMovieTexture > Unity463_Patch_iOS > Unity463_Patch_iOS.unitypackageをインポートする。

#問題点２
動画をループ再生すると、ループ時にハングアップする。

##解決方法
動画のループ時にonPlayerDidFinishPlayingVideo関数内でハングアップする。
原因は変数m_videoURLが未初期化のためと思われるので、loadVideo関数で初期するようにした。

Plugins > iOS > VideoPlayerPlugin.mmを修正する。

修正前

``` Objective-C:VideoPlayerPlugin.mm
- (void)loadVideo:(NSURL *)videoURL {
    m_bFinish = false;
    [player loadVideo:videoURL];
}
```
修正後

``` Objective-C:VideoPlayerPlugin.mm
- (void)loadVideo:(NSURL *)videoURL {
    m_bFinish = false;
    m_videoURL = videoURL;
    [player loadVideo:videoURL];
}
```
Homebrewで全Fomulaをアップグレード&古いFomula削除する方法


## コマンド

```bash
brew update && brew outdated && brew upgrade && brew cleanup
```

## カンタンな解説

- `brew update`: リストの更新
- `brew outdated`: 新しいバージョンがでているFomula一覧を表示
- `brew upgrade`: インストールされているFomula全てをアップグレード
- `brew cleanup`: 古いFomulaを削除
【AWS】awsコマンドでのELBのProtocolProxyの設定メモ


~~下書きが埋まってきたので~~ 諸事情により、情報少ないですがアップします。

## ポリシーの確認

```shell-session:shell
$ aws elb describe-load-balancers --load-balancer-name [ELB-name]
```

```shell-session:
"LoadBalancerDescriptions": [{
  * * *
    "BackendServerDescriptions": [
        < 設定したものはここに入る >
    ],
  * * *
}]

```

## ProxyProtocol有効化ポリシーの追加

```shell-session:shell
$ aws elb create-load-balancer-policy --load-balancer-name [ELB-name] --policy-name [Policy-name] --policy-type-name ProxyProtocolPolicyType --policy-attributes AttributeName=ProxyProtocol,AttributeValue=True
```

## 有効化

`aws elb set-load-balancer-policies-for-backend-server --load-balancer-name [ELB-name] --instance-port [send-port] --policy-names [Policy-name]`

## 無効化

`aws elb set-load-balancer-policies-for-backend-server --load-balancer-name [ELB-name] --instance-port 80 --policy-names []`