OmniAICreator/Qiita-1.07M huggingface dataset:
もしかしたら僕たちはLinuxカーネルのソースを読み、勉強するべきなのかもしれない

もしかしたら、コンピュータやネットワークの基本を学びたければ、僕たちはLinuxのカーネルを読んで理解するべきなのかもしれない。
僕たちは、プログラミングの勉強といったら、とりあえずやりがちなのが、Swiftを学んでiOSアプリを作る、PHPを学んで、Webアプリを作る。ネットワークの本を読む。などである。
でも、それでいいんだろうか。それをやることは否定しないけど、SwiftやPHPはゴロゴロ変わっていって、ちゃんとした技能が残らない感じするのである。ネットワークの本は本で、一次情報じゃない。
もちろん、アプリを構築するときのノウハウは手に入る。
でも、もしかしたら、僕たちは賽の河原の石積みをやっているのかもしれない。もしかしたら、コンピュータの表層的なことを理解するのではなく、もっと根本から理解するべきなのかもしれない。
コンピュータの根本とは何か、それは、ハードウェアだったり、OSだったり、ネットワークだったり、コンパイラだったりする。
で、現時点で中身を覗くことができるネットワークOSはLinuxとFreeBSDだ。
Linuxのカーネルを理解して、仕事があるかはそういう方面のことには疎いので、知らない。儲かるという話はある。
でも、もしかしたら、SwiftやPython、PHPのような、ハードウェアから遠い高級言語は、間にヌルッとしたものが挟まっているので、コンピュータを理解することとは遠いのかもしれない。
仕事でそういう言語が必要なのはわかる。でも、もしかしたら、（特に若い人は）学ぶべきは、iOSアプリの作り方ではなく、Linuxカーネルの読み方なのかもしれない。iOSアプリから始めるのではなく、Linuxカーネルと、C言語とアセンブラから始めるべきなのかもしれない。
僕は、iOSアプリから始めたが、それは間違っていたのかもしれない。
では、それぞれの長所と短所を比べてみよう。

- Linuxカーネルを読む
    - 長所
        - コンピュータの基本がわかる
        - ネットワークやコンピュータの構造が、第一次情報としてわかる
        - 時代によってそんなに変わらない（これは正しいかどうかわからない）
        - カーネルについての解説書がいっぱいでてる　
        - ソースコード読みの訓練になる
        - 特定のベンダに縛られない
        - 儲かる（本当かな？）
    - 短所
        - 難しい
        - 時間かかる
　　　　　　
- iOSアプリを作る
    - 長所
        - 形のあるものを作れる
    - 短所
        - ゴロゴロ変わっていく
        - コンピューティングの基本はわからない
        - 人のソースコードを読むスキルは身につかない

ということで、わけわからないかもしれないけど、Linuxカーネル読んで、色々記事書きたいと思う。
実際読んでてよくわからないが、よくわからんけど面白いのがLinuxカーネルだ。
ARオブジェクトをURI化する`ActiveJob::Arguments#serialize`が色々と使えそう

# ActiveJob::Arguments#serializeとは

ActiveJobの引数にActiveRecordオブジェクトのインスタンスを渡すと、それはシリアライズされずに、Global IDというURIに変換されます。

これを実現しているのが、`ActiveJob::Arguments#serialize`と`ActiveJob::Arguments#deserialize`です。

例えば、

```rb
user = User.find(5)

SampleJob.perform_later(user)
```

とした場合、引数の`user`は、

```rb
serialized_args = ActiveJob::Arguments.serialize([user])

〜〜〜
略
〜〜〜

args = ActiveJob::Arguments.deserialize(serialized_args)
```

というような処理を挟むイメージです。

この時、上記の`serialized_args`は、

```rb
[{"_aj_globalid"=>"gid://project_name/User/5"}]
```

のように、`gid://アプリケーション名/モデル名/id`の形式で表現されます。

つまり、**ActiveRecordのインスタンスをシリアライズせずに保持できる**ということです。シリアライズする必要がないので、**容量を大きく節約する**ことができます。

# serializeをActiveJobの外で使う

最新のActiveJobでは`ActiveJob::Arguments`はプライベートな内部モジュールとなっているため、ActiveJobの外で使うには明示的に`require`する必要があります。

```rb
require 'active_job/arguments'
```

使用用途としては、**何らかのメソッドに渡す引数・渡された引数を一時的に保存する**のに使えそうです。

例えば、

```rb
def store_sample(*args)
  key = SecureRandom.hex(12)
  serialized_args = ActiveJob::Arguments.serialize(args)
  Rails.cache.fetch(key.to_s) { serialized_args }
end

store_sample(User.find(4))
```
のようにローレベルキャッシュを利用することで、CacheStoreに`store_sample`メソッドに渡したActiveRecord型オブジェクトの引数を一時保存することも可能です(容量の問題を無視すれば、通常の方法でも可能ですが・・・)。

# 使ってみた

というわけで、`ActiveJob::Arguments#serialize`の仕組みを利用した簡単なRails pluginを作ってみました。
[EastResident/step_render](https://github.com/EastResident/step_render)

主な機能としては、**部分テンプレート(partial)を遅延読み込みする**というようなものです。
Apache Solrの重み付け

## qfパラメータについて
qfとは(Query Fields)の略です。

qfパラメータの使い方は、検索する項目にboost値があります。
qfパラメーターに`field^1 field^2 field^3`とあり`field^重み`みたいな感じで実装することができます。
[Unity] Post Processing Stackを使ってUI要素にもBloomを適応する

## Unity1週間ゲームジャムにて

![summer7.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/2eeb3118-3bee-7636-7dd1-fb8c763cef92.gif)

- [unityroom](https://unityroom.com/)というUnity製のゲームの投稿サイトで月に1度、1週間ゲームジャムという1週間でゲーム開発を行うイベントが開催されています。
- 自分は第4回の開催時に [「夏の花火 彗星の夜」](https://unityroom.com/games/comet_fireworks/webgl) というゲームを製作しました。
- このゲームの感想として「文字周りのぼやける表現が良い」という話があったので、対応内容をメモ。UI用にGrowのShaderを記載する等の特殊なことはやっていないので、そこを期待してたら申し訳ない...。

## Post Processing Stack
![image.png](https://qiita-image-store.s3.amazonaws.com/0/102664/bb9406a6-41e0-8349-ce16-bf42ec4372fd.png)

- https://www.assetstore.unity3d.com/jp/#!/content/83912
- Post Processing StackはImageEffectを適応するためのアセット
- Unity公式で提供しているアセットなので無料
- 複数のエフェクトを組み合わせる場合、過去にStandardAsset/Effectsに含まれているImageEffectsよりもパフォーマンスが良いので、上記アセットの使用をオススメ
- 詳しくは以下の動画を参考
  - [【Unite 2017 Tokyo】ゲームの見た目も盛ったら変わる！！！！ヤバい！！ポストプロセス！！入門！！！！！！！！！](https://www.youtube.com/watch?v=r5mNmH68KPQ)

### ImageEffect / PostProcess
- イメージエフェクト、およびポストプロセスはレンダリングされた結果(描画領域全体)に対して、エフェクトを適応すること

## Post Processing Stackの下準備
![create_post.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/744dceec-b876-2c11-e223-30ae6dc24911.gif)

- (0) AssetStoreからPost Processing Stackをインポートする (前提)
- (1) `Project > create` から `Post-Processing Profile` を選択して Profile を作成
- (2) MainCamera (および適応したい任意のCameraがアタッチされたGameObject) に対し `Post Processing Behaviour`をアタッチ
- (3) `Profile` に対して (1) で生成した Profile を適応 (ドラッグ/ドロップ)

## Bloomの適応
![create_post2.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/8d900500-3bd4-16ab-8d23-42af6e34a24b.gif)

- Bloomを有効にすることで、明るい光源からの光が周囲の物体に漏れるように見える表現を適応することができる
- 下準備の (1) にて適応した Profile で `Bloom` の項目にチェック
- Intensity (効果の強さ) や Threshold (効果を適応する白さの閾値) などを調整して理想の効果を作る

## UI要素に対する適応
- 続いてUI要素(テキスト)を作成する

![create_post3.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/6c69a78c-388d-d801-7ecd-5ff373984dbf.gif)

- 上記のgifの時点ではBloomは適応されていない
- `Canvas` の `RenderMode` が `ScreenSpace - Overlay` になっており、MainCamera (およびHierarchy上に存在する任意のカメラ) のレンダリング処理に含まれていないためである

![create_post4.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/46ce2272-5078-3cc9-c5ce-d05a3c42bf2b.gif)

- `Canvas` の `RenderMode` を `ScreenSpace - Camera` を指定し、 `MainCamera` (およびBloomを指定した任意のCamera) を指定してあげることで、同様のエフェクトがUI要素に適応される
- (上記のケースでは建物側のColorを黒に寄せたことで影響を少し抑えている)
Goでファイル追記・存在しなかったらファイル作成したい！

私がはじめわからなかった、os.OpenFile関数のフラグについて少し書きます

#Goのファイル開閉の種類
Goにはファイル読み書きの際のファイルの開き方にいくつか方法がありますよね。
`os.Create`、`os.NewFile`、`os.Open`、`os.OpenFile`です。
そのうちOpenFileを使うと、引数にフラグを渡すことで、ファイルを開く際の大まかな設定ができます。
がっつり調べたらドキュメントに言及されてるんですが、Qiitaに記事があるとわかりやすいですよね！(そうですよね！？？)

##os.OpenFileの基本
`os.OpenFile`を使うときは第二引数に、用途に合わせてフラグを渡す必要があります

* `os.O_RDONLY` //読み込む時
* `os.O_WRONLY` //書き込む時
* `os.O_RDWR` //読み書き両方する時

なお、第二引数に複数フラグを渡す場合は | で区切って渡してあげましょう。
とりあえず最後まで読み進めてみてください。

##ファイルに追記がしたい！
基本的に何も考えずファイルを開いて書き込むと中身を全部上書きして書き込まれますよね。
追記したいときは`os.OpenFile`の第二引数に`os.O_WRONLY`及び`os.O_APPEND`をつけましょう。


```EditFile.go
import(
    "os"
)
func main() {
    //引数: ファイルのパス, フラグ, パーミッション(わからなければ0666でおっけーです)
    file, err := os.OpenFile("test.txt", os.O_WRONLY|os.O_APPEND, 0666)
    if err != nil {
        //エラー処理
        log.Fatal(err)
    }
    defer file.Close()
    fmt.Fprintln(file, "書き込み〜！") //書き込み
}
```

##ファイルが存在しなかった場合新規作成したい！

何も考えずに`os.OpenFile()`を使うと、もともとファイルが存在しなかった場合、エラーが発生します。
存在しなかった場合新規ファイルを作成する場合は`os.OpenFile`の第二引数に`os.O_CREATE`をつけましょう。

```CreateNewFile.go
func main() {
    file, err := os.OpenFile("test.txt", os.O_WRONLY|os.O_CREATE, 0666)
    if err != nil {
        //エラー処理
        log.Fatal(err)
    }
    defer file.Close()
    fmt.Fprintln(file, "書き込み〜！") //書き込み
}
```

##おさらい
では、__ファイルに追記する__、__存在しなかったら新規作成する__を両方使ってみましょう。

```osarai.go
func main() {
    //os.O_RDWRを渡しているので、同時に読み込みも可能
    file, err := os.OpenFile("test.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
    if err != nil {
        //エラー処理
        log.Fatal(err)
    }
    defer file.Close()
    fmt.Fprintln(file, "書き込み〜") //書き込み
}
```
以上です。
このほかにもコアなものがいくつかあるので、詳しくはご自分で調べて見てください〜！
参考: http://golang.jp/pkg/os
vue-cliのHot ReloadがVagrant上で動かないときの対応


## Webpackでのファイル更新を監視する

- build/dev-webpack.jsのdevMiddlewareに
watchOptionsを以下のように追加します。

```javascript:ファイル更新チェック
var devMiddleware = require('webpack-dev-middleware')(compiler, {
  publicPath: webpackConfig.output.publicPath,
  quiet: true,
  watchOptions: {
    aggregateTimeout: 300,
    poll: true
  }
})
```

ファイルが更新されたかどうかを確認するためのポーリングの設定を行うことでHot Reloadを機能させます。
アクセス修飾子まとめ～JVM言語編（Java/Groovy/Scala/Kotlin）

## はじめに
先日、「[アクセス修飾子まとめ～スマホアプリ開発編（Java/Kotlin/Objective-C/Swift/C#/F#）](http://qiita.com/himarin269/items/886e3a0e7425f94d0e33)」と題してスマホアプリで使う言語のアクセス修飾子比較をまとめましたが、今回は「JVM言語」をテーマにアクセス修飾子をまとめたいと思います。

##JVM言語とは
JVM（Java Virtual Machine）上で動く言語で、Javaのほかに多数のJava代替言語が存在します。今回はその中でもメジャーなGroovy、Scala、Kotlinを取り上げ、Javaとともに比較表にまとめます。

## 比較表
|アクセス修飾子|Java|Groovy|Scala|Kotlin|
|---|---|---|---|---|
|**public**|どこからでもアクセス可能|どこからでもアクセス可能|どこからでもアクセス可能|どこからでもアクセス可能|
|**protected**|同一パッケージ内のクラス＋派生クラスからアクセス可能|どこからでもアクセス可能|同一クラス＋派生クラスからアクセス可能|継承した同一パッケージ内のクラス＋派生クラスからアクセス可能|
|**internal**|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|同一モジュール内でアクセス可能|
|**private**|同一スコープ内でアクセス可能<br>※内部クラスのprivate変数も参照可|どこからでもアクセス可能<br>※ただし派生クラスからsuper.*でアクセスすることはできない|同一スコープ内でアクセス可能|同一スコープ内でアクセス可能|
|**protected[パッケージ名]**|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|指定したパッケージ内のクラス＋派生クラスからアクセス可能<br>※所属するパッケージのみ指定化（途中の階層も可）|<font color="Silver">（存在しない）</font>|
|**private[パッケージ名]**|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|指定したパッケージ内でアクセス可能<br>※所属するパッケージのみ指定化（途中の階層も可）|<font color="Silver">（存在しない）</font>|
|**protected[クラス名]**|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|自身または指定したクラス＋派生クラスからアクセス可能<br>※自身の外側のクラスのみ指定可|<font color="Silver">（存在しない）</font>|
|**private[クラス名]**|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|自身または指定したクラスからアクセス可能<br>※自身の外側のクラスのみ指定可|<font color="Silver">（存在しない）</font>|
|**protected[this]**|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|自インスタンス＋派生クラスからアクセス可能|<font color="Silver">（存在しない）</font>|
|**private[this]**|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|自インスタンスからのみアクセス可能|<font color="Silver">（存在しない）</font>|
|**指定しない**|同一パッケージ内でアクセス可能|publicと同じ|publicと同じ|publicと同じ|

GroovyはJavaと互換性があるため、Java同様のアクセス修飾子が使えますが、それらはうまく機能せず、なんとすべてどこからでもアクセスできてしまいます（一応省略時publicになるというのは仕様通り）。この動作はバグとして管理されていますが、すべて修正されるのはまだ先のようです（本稿作成にあたりGroovy2.4.12で検証）。
Scalaでは限定子というものがあり、きめ細かいアクセスコントロールができるのが特徴ですね。

Java以外の代替言語は、何も指定しなかったとき「public」になる動きで共通です。
「アクセスコントロールを行うキーワードを書かない」
⇒「アクセスコントロールしない」
⇒「どこからでもアクセス可能」
と考えられるので、直感的でわかりやすいと思います。

## 参考
[[GROOVY-3010] fix private field visibility - ASF JIRA](https://issues.apache.org/jira/browse/GROOVY-3010)
[[GROOVY-7246] Access modifiers behave differently in Groovy when compared to Java. - ASF JIRA](https://issues.apache.org/jira/browse/GROOVY-7246)
[Scalaクラスメモ(Hishidama's Scala class Memo)](http://www.ne.jp/asahi/hishidama/home/tech/scala/class.html#h_access_modifiers)
[クラスメンバーのアクセス修飾子 | hydroculのメモ](https://hydrocul.github.io/wiki/programming_languages_diff/class/modifier.html)
[はじめてのKotlin。Javaと比較してみた](http://qiita.com/hituziando/items/fa2dc4097b24ab78276e)
Clean Codeの初めの一歩

#はじめに
"Clean Code"って何だろう？と興味を持った人達に捧ぐ言葉たちを纏めました。
具体的な例も記載しているので、Clean Codeを始めるための第一歩としてご活用ください。

---

#クリーンコードとは
##クリーンコードって何だろう？
>*"Any fool can write code that a computer can understand. Good programmers write code that humans can understand. "
>by Robert C. Martin*

>*「コンピュータが理解できるコードを書くことは誰でもできる。優秀なプログラマーは、人間が理解できるコードを書く。」*

---

##何故クリーンコードが必要か？
>*"Indeed, the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. ...[Therefore,] making it easy to read makes it easier to write."
>by Robert C. Martin*

>*「実際、コードを読む時間と書く時間の比率は10:1を優に上回る。私たちは新しいコードを書くための努力の一環として、絶えず既存のコードを読んでいる。（中略）それゆえに、読みやすくすることは、書きやすくすることに繋がる。」*

---

##ボーイスカウトから学ぶ
>*"the Boy Scout Rule tells us we should leave the code cleaner than we found it."
>by Robert C. Martin*

>*「ボーイスカウトルールは、コードを見つけた時よりもキレイにしてからその場を去るべきであることを教えてくれる。」*

※ボーイスカウトルール・・・たとえ自分が来た時には既にキャンプ場が汚かったとしても、たとえ汚したのが自分ではなかったとしても、きれいにしてからその場を去る、というボーイスカウトの思想。

---

#具体的なTips
##コメントを書いたら負け
>*"Every time you write a comment, you should grimace and feel the failure of your ability of expression."
>by Robert C. Martin*

>*「コメントを書くたびに、自分の表現力の無さに顔をしかめなさい。」*

```java:UglyCode.java
// 運転免許を取得可能かどうかを判定
if((user.age >= 18) 
    && (user.leftVision >= 0.3 || user.rightVision >= 0.3)
    && (user.visionInBothEyes >= 0.7)
  ) {
    ...
  }
```

```java:AwesomeCode.java
if (user.canObtainDriversLicense()) {
    ...
}
```

---

##識別子は「正しく」名前を付ける
>*"A name in java, or any other language, is too long when a shorter name exists that equally conveys the behavior of the method."
>by Anonymous([stackoverflow](https://stackoverflow.com/a/2230893))*

>*「javaまたは他の言語において、その振る舞いを等しく伝えることが可能な「より短い名前」が存在する場合、それは長すぎることを意味する。」*

```java:UglyCode.java
boolean doesShorterNameExistThatEquallyConveysTheBehaviorOfTheMethod‌​(String string);
```

```java:AwesomeCode.java
boolean isTooLong​(String string);
```

---

##言いたいことを記述する
>*"Easily the most frustrating thing for another developer looking at your code is seeing a variable with a misleading name or, worse, named with a single letter."
>by [Code School blog](https://www.codeschool.com/blog/2015/09/29/10-ways-to-write-cleaner-code/)*

>*「別の開発者があなたのコードを見て一番イライラするのは、誤解を招くような名前のついた変数、さらには、一文字だけの変数を見ることだ。」*


```java:UglyCode.java
int check(int n, int max) {
    if(n < max) {
        return -1;
    }else {
        return 1;
    }
}
```
```java:AwesomeCode.java
boolean hasTakenDamage(Player player) {
    return(player.currentHealth < player.maxHealth);
}
```

---

#おわりに
>*"Keeping code consistent throughout the scope of a project will help reduce logical errors and improve readability. "
>by Joe Hewitson([SmartShift](http://www.smartshifttech.com/411-clean-code-why-you-need-it-and-how-you-get-it))*

>*プロジェクト全体にわたってコードの一貫性を保つことで、論理的なエラーが削減され、読みやすさが向上する。*

いくら自分だけがClean Codeを実践出来ていても、他のメンバが実践出来ていなければ、それはさらなる混乱を招くに過ぎません。
ぜひプロジェクト全体でClean Codeを実践してみてください。
Linuxコマンド 略語 (LPIC303)

# 主題325：暗号化
## 325.1 X.509 証明書と公開鍵の基礎
OpenSSL: Open Secure Sockets Layer
PEM: Privacy Enhanced Mail
DER: Distinguished Encoding Rules
PKCS: Public-Key Cryptography Standards
CSR: Certificate Signing Request
CRL: Certificate Revocation List
OCSP: Online Certificate Status Protocol

## 325.2 暗号化、署名および認証のX.509 証明書
SSL: Secure Sockets Layer
TLS: Transport Layer Security
SNI: Server Name Indication
HSTS: HTTP Strict Transport Security
HTTPD: Hyper Text Transfer Protocol Daemon
HTTPS: Hyper Text Transfer Protocol Secure

## 325.3 暗号化ファイルシステム
LUKS: Linux Unified Key Setup
eCryptfs: Encrypted File System
EncFS: Encrypted File System

## 325.4 DNS と暗号化
DNS: Domain Name System
DNSSEC: DNS Security Extensions
DANE: DNS-based Authentication of Named Entities
EDNS: Extension mechanisms for DNS
BIND: Berkeley Internet Name Domain
DS: Delegation Signer
RRSIG: Resource Record Digital Signature
NSEC: Next Secure
TLSA: TLS Association
DO-Bit: DNSSEC OK
AD-Bit: Authenticated Data
TSIG: Transaction Signature

rndc: remote name daemon control
dig: domain information groper
delv: Domain Entity Lookup & Validation
openssl: Open Secure Sockets Layer

# 主題326：ホストセキュリティ
## 326.1 ホストの堅牢化

## 326.2 ホストの侵入検知
AIDE: Advanced Intrusion Detection Environment
OpenSCAP: Open Security Content Automation Protocol

auditd: audit daemon
auditctl: audit control
chkrootkit: check rootkit
rkhunter: rootkit hunter
maldet: malware detect

## 326.3 ユーザの管理と認証
NSS: Network Security Services
PAM: Pluggable Authentication Modules
SSSD: System Security Services Daemon

## 326.4 FreeIPA のインストレーションとSambaの統合
FreeIPA:  Free Identity, Policy, and Audit
SSH: Secure Shell
SUID: Set User ID
SGID: Set Group ID
getfacl [setfacl]: get [set] file ACL
getfattr [setfattr]: get [set] file attribute

# 主題327：アクセス制御
## 327.1 任意アクセス制御
ACL: Access Control List

## 327.2 強制アクセス制御
TE: Type Enforcement
RBAC: Role-based Access Control
MAC: Mandatory Access Control
DAC: Discretionary Access Control
SELinux: Security-Enhanced Linux
AppArmor: Application Armor
Smack: Simplified Mandatory Access Control Kernel

getsebool: get SELinux booleans
togglesebool: toggle SELinux booleans
runcon: run command
apol: analyze policy

## 327.3 ネットワークファイルシステム
NFS: Network File System
CIFS: Common Internet File System
NTLM: NT LAN Manager
nfs4acl: NFSv4 ACL
getcifsacl: get CIFS ACL
setcifsacl: set CIFS ACL

# 主題328：ネットワークセキュリティ
## 328.1 ネットワークの堅牢化
RADIUS: Remote Authentication Dial In User Service
NDP: Neighbor Discovery Protocol

radiusd: RADIUS daemon
radmin: RADIUS administration
ndpmon: NDP monitor

## 328.2 ネットワークの侵入検知
OpenVAS: Open Vulnerability Assessment System
NVT: Network Vulnerability Tests

ntop: network table of processes
openvassd: OpenVAS Security Scanner
openvas-mkcert: make certification

## 328.3 パケットフィルタ
conntrackd: connection tracking daemon
nft: Network File Transfer
ebtables: Ethernet bridge frame table

## 328.4 仮想プライベートネットワーク (VPN)
OpenVPN: Open Virtual Private Network
IPsec: Security Architecture for Internet Protocol
RancherでLDAPとRocket.Chatを構築する (4)OpenLDAPサーバを構築する


## はじめに
[前回](http://qiita.com/gldn/items/f5168cf0e09fa8562e31)の続きです。
今回は、OpenLDAP, phpLDAPadminを構築します。

## docker image選定
現時点で、OpenLDAPはRancherのカタログにないので、
Docker HubのAUTOMATED BUILDのうち、DL数の多いイメージを選択しました。

* LDAP  
accenture/adop-ldap
* phpLDAPadmin  
  dinkel/phpldapadmin

## Docker-compose.yml作成
```bash:
$ mkdir -p /vagrant/services/ldap
$ touch /vagrant/services/ldap/docker-compose.yml
```
docker Hubの各イメージのDescriptionを参考に、docker-compose.ymlを記述します。

```yaml:docker-compose.yml
version: '2'

networks:
  bridge:
    driver: bridge

services:
  ldap:
    image: accenture/adop-ldap
    container_name: ldap
    ports:
      - "389:389"
    environment:
      - SLAPD_PASSWORD=secret_password
      - SLAPD_DOMAIN=ldap.service.local
      - SLAPD_FULL_DOMAIN=dc=ldap,dc=service,dc=local
    volumes:
      - ldap-config-data:/etc/ldap
      - ldap-app-data:/var/lib/ldap
    networks:
      - bridge
  phpldapadmin:
    image: dinkel/phpldapadmin
    container_name: phpldapadmin
    ports:
      - "8010:80"
    environment:
      - LDAP_SERVER_HOST=ldap
    links:
      - ldap
    networks:
      - bridge

volumes:
  ldap-config-data: {}
  ldap-app-data: {}
```

## LDAP & phpLDAPadminコンテナ作成＆開始

docker-composeコマンドでも起動できますが、
せっかくなのでRancherから起動します。
※コマンドの場合は、Rancher CLIからもできます。

Rancherにアクセス
http://(ホストマシンのIPアドレス):8001

「STACKS」→「Add Stack」

* Name: LDAP
* Optional:docker-compose.yml  
作成したファイルを指定するか、ファイルの内容をコピペします。

![ldapup.PNG](https://qiita-image-store.s3.amazonaws.com/0/194385/bbe78d8f-914d-89d5-9dcf-2843b11d12c2.png)

「Create」を押すと、コンテナが生成されます。

![ldap_finish.PNG](https://qiita-image-store.s3.amazonaws.com/0/194385/f04676ef-b9d1-5f6b-90b3-5947d0603c77.png)



## phpLDAPadminにログインする
ホストOSからブラウザでアクセスします。
http://localhost:8010

loginを押し、以下を入力してログインします。

* Login DN：cn=admin,dc=ldap,dc=service,dc=local
* Password：secret_password


![phpadmin.PNG](https://qiita-image-store.s3.amazonaws.com/0/194385/3d84b0ac-ed1b-a052-9d8e-bcb4e24204b7.png)


ログインできました！

## テストユーザ作成

Webアプリからのログインに使用するため、ユーザ: testを作成します。

"ou=people" → "Create a child entry" → "Default" → "Courier Mail: Account"

User ID以外は適当に入力します。
![php_register.PNG](https://qiita-image-store.s3.amazonaws.com/0/194385/38b02dad-69f2-ba0b-e8f3-a434f8ad9258.png)

「Create Object」→ 「Commit」でユーザ作成完了です。

つづき→[(5)Rocket.Chatを構築する](http://qiita.com/gldn/items/c611e2eb49c481f58a40)

## 目次: RancherでLDAPとRocket.Chatを構築する 

[(1)仮想マシン構築](http://qiita.com/gldn/items/565adc5158a3c1d57ef3)
[(2)Dockerインストール](http://qiita.com/gldn/items/813e56722c6de3119e7f)
[(3)Rancherを構築する](http://qiita.com/gldn/items/f5168cf0e09fa8562e31)
[(4)OpenLDAPサーバを構築する]
(http://qiita.com/gldn/items/19116548743a85c85ddf)
[(5)Rocket.Chatを構築する](http://qiita.com/gldn/items/c611e2eb49c481f58a40)
GitHubで公開されたハンズオンコンテンツを日本語化＆補足情報を追記する

様々な有用なハンズオンコンテンツが公開されているGitHubから、私自身の勉強のために試したものや役に立ちそうなものについて、日本語化＆補足情報を追記します。

|製品|分類 |機能|コンテンツ
|:--|:--|:--|:--|
|SQL Server|In-Database Analytics|Python|[Pythonで作成した予測モデルをSQL Serverに展開し利用する](http://qiita.com/qio9o9/items/9cb8db69b9d61a332b8f)
|SQL Server|In-Database Analytics|Python|[RevoScalePyライブラリで実装した予測モデルをSQL Server 2017 Machine Learning Servicesで実行する](http://qiita.com/qio9o9/items/f43c4cf00e56b242439e)
ニフティクラウド上のプライベートLANにスムーズにサーバを組込む

## はじめに
普段仕事でWEBサーバ＋RDB、NAS等の構成でサーバーを作ることが多いのですが、
内部の通信はセキュリティを強固にしたいため、共用ネットワークではなく、プライベートネットワーク（VLAN）を利用します。
本記事はサーバ作成時の起動時スクリプトを利用してプライベートネットワークへスムーズにサーバーを組み込むという記事です。

## 前提条件
OSはCentOS6.7（ニフティ提供版）
プライベートLANは作成済み　※今回セグメントは192.168.0.0/24とします。

![capture1.PNG](https://qiita-image-store.s3.amazonaws.com/0/23761/d25e4636-ad9e-c30a-3b6f-f3bae6a719db.png)



## 手順
1. ニフティクラウドコントロールパネルより[コンピューティング]>[サーバー作成]>[3.サーバー設定]まで進みます。

2. [3.サーバー設定]のメニューで以下設定します。その他は任意で。

- ネットワーク-プライベートを「自動割当」から作成済プライベートLANを選択
- スクリプトを「使用する」とし、下記startup_script.shを読込む

```shell:startup_script.sh
#!/bin/bash
TODAY=`date '+%F'`
STATIC_IP=192.168.0.11
NETMASK=255.255.255.0

# Set vlan static ip
## Backup
mv /etc/sysconfig/network-scripts/ifcfg-eth1 /etc/sysconfig/network-scripts/ifcfg-eth1_$TODAY
## ifcfg-eth1(local network)
cat << EOS >> /etc/sysconfig/network-scripts/ifcfg-eth1 2>&1
DEVICE=eth1
BOOTPROTO=none
ONBOOT=yes
PEERDNS=no
IPADDR=$STATIC_IP
NETMASK=$NETMASK
EOS
## Network Restart
/etc/init.d/network restart
```
※ROOT_PASSWORDとSTATIC_IP、NETMASKは適宜修正してください。

![capture2.PNG](https://qiita-image-store.s3.amazonaws.com/0/23761/7a80f767-e86f-5e95-8c75-a63a64bbe413.png)
3. このまま進めサーバを作成します。すると、こんな感じにプライベートLANに組み込めました。
![capture3.PNG](https://qiita-image-store.s3.amazonaws.com/0/23761/a442971b-993e-2e79-5766-0bdbe2ed827e.png)

![capture4.PNG](https://qiita-image-store.s3.amazonaws.com/0/23761/dcbccd0f-9574-ee2b-0f0c-4969ad420227.png)

## 最後に
初めての投稿なので不備等ございますが、ご指摘頂けると幸いです。

## 参考
http://cloud.nifty.com/service/plan.htm
Dockerを使ったMastodonを1.4.7から1.5.0にバージョンアップした

Dockerを使ったMastodonを1.4.7から1.5.0にバージョンアップしました。

#アップグレード手順

[1.3.2から1.4.3にバージョンアップしたときの手順](http://qiita.com/chanken/items/4df165ae855ff664c4cc)でアップグレードしていきます。

マイグレーション実行時の外部キーに関するエラーは出ません。

#アップグレード後のログ確認でエラー発見

アップグレード後にログの確認。
ctrl-fで中断できます。

```
docker-compose logs -f
```

下記のエラーが出ていました。

```
systemTID-gmplcyec4 WARN: Errno::EACCES: Permission denied @ dir_s_mkdir - /mastodon/public/system/accounts/avatars/000/000/502
```

#ディレクトリのアクセス権を確認

/mastodon/public/systemは下記のdocker-compose.ymlの抜粋にあるようにホストOSのディレクトリをマウントしているのでdocker-compose.ymlがあるディレクトリの./public/systemのアクセス権を確認。

```docker-compose.yml（抜粋）
  web:
    extends:
      service: app
    container_name: mstdn-web
    restart: always
    env_file: .env.production
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    depends_on:
      - db
      - redis
    volumes:
      - ./public/assets:/mastodon/public/assets
      - ./public/packs:/mastodon/public/packs
      - ./public/system:/mastodon/public/system
    networks:
      - mstdn
```

ls -lの結果（抜粋）
``` 
drwxr-xr-x 4  991  991   4096  8月  6 20:00 assets
drwxr-xr-x 6  991  991  36864  8月  6 18:02 packs
drwxr-xr-x 5  root root  4096  8月  6 22:47 system
```
「system」ディレクトリのオーナーがrootになっているので、「assets」「packs」に合わせて、mastodonの実行ユーザーの「991」にオーナーを変更。
``` 
chown -R 991.991 system
``` 
エラーが解消され、「/mastodon/public/system/accounts/avatars」以下に書き込まれていることをログで確認。

以上でバージョンアップは終了です。

#リンクが切れたDocker volumeの削除
何回かバージョンアップをするとリンクが切れたDocker volumeが増えてディスク容量を圧迫しますので、リンクが切れたDocker volumeを削除します。

``` 
docker volume ls -f "dangling=true" -q | xargs docker volume rm
```
アラートダイアログ表示で困ったこと

#きっかけ
Androidアプリ開発中にアラートダイアログを表示するためにDialog Fragment を作成してMainのActivityで呼び出そうとした時、エラーが出まくって大パニックになったので覚書しました。

### その１:DialogFragmentの2重起動を防止する
データが連想配列（HashMap）などの場合、ある条件のもとでダイアログを表示させるが、1つしか必要ないのに条件に当てはまったデータが複数あればダイアログも複数表示されるので、ダイアログが1つ表示されたらフラグを立てて、「フラグがあれば表示しない」ようにするやり方。
※変数宣言時にfalseを入れておく
`boolean noDialog = false;`

```
MyDialogFragment dialog = new MyDialogFragment();
　if(noDialog == false) {
   noDialog = true;
 　dialog.show(getSupportFragmentManager(), "dialog");
 }
```


### その2：タイマーで画面を自動更新すると結局2重で表示されてしまう。
 タイマーを使って「○秒後に画面を自動更新」などしてしまうと、結局、フラグを立てるだけでは2重起動を防止できないことがわかったのでさらに、findFragmentByTag () で Activity に存在する Fragment を取得してチェックするやり方。
指定したタグがあるかないかをチェックしてなければダイアログを表示、あればreturnする。
DialogFragmentがsupport.v4を使用しているならgetSupportFragmentManager()を使用、そうでなければ、getFragmentManager()を使用する。ここにめっちゃハマった...

```
if(getSupportFragmentManager().findFragmentByTag("dialog") == null) {
  MyDialogFragment dialog = new MyDialogFragment();
  if (noDialog == false) {
  dialog.show(getSupportFragmentManager(), "dialog");
    noDialog = true;
  } else {
    noDialog = true;
  }
}
```
これで、データが連想配列（HashMap）でもダイアログは1つしか表示されない。はず....
まだ、初心者なのでとにかく忘れないように覚書しましたが、おかしなところがあればそっと教えてください...よろしくお願いします。

#参考にしたサイト
[公式サイトDialogFragment](https://developer.android.com/reference/android/app/DialogFragment.html)
[公式サイトFragmentManager]
(https://developer.android.com/reference/android/app/FragmentManager.html)
[Android memomemo](http://androidmemomemo.blogspot.jp/2015/02/dialogfragment2.html)
夏休みFortran祭り Jupyter-fortran

https://gist.github.com/cure-honey/decf5be6d2d3a9bce9a0fa08e611ac09

![forteratos.png](https://qiita-image-store.s3.amazonaws.com/0/44522/e41f4606-f98a-2d83-69be-3917d1723d51.png)

# 夏休みFortran祭り
## Jupyter-fortran-kernel
https://github.com/ZedThree/jupyter-fortran-kernel

修正点

````
git clone git@github.com:ZedThree/jupyter-fortran-kernel.git　<-　git clone https://github.com/ZedThree/jupyter-fortran-kernel.git

pip install -e --user jupyter-fortran-kernel                  <- pip install -e jupyter-fortran-kernel --user


jupyter-kernelspec install fortran_spec/                      <- jupyter-kernelspec install fortran_spec/ --user
````
時々２回　shift+ENTER　しないと出力しません。謎

## GitHub Gist の設定
https://gist.github.com/genkuroki/81de23edcae631a995e19a2ecf946a4f


## エラトステネスのふるいによる素数求め　1000以下


```fortran
program eratos
  integer, parameter :: n = 10**3
  integer :: i, itab(n)
  integer, allocatable :: ip(:)
  itab = 0
  forall (i = 2:n) itab(i) = i
  do i = 2, int(sqrt(real(n)))
    if (itab(i) /= 0) itab(i**2::i) = 0
  end do
  ip = pack(itab, itab /= 0)
  print '(*(i5))', ip
  print *, 'number of primes', size(ip)
end program eratos
```

        2    3    5    7   11   13   17   19   23   29   31   37   41   43   47   53   59   61   67   71   73   79   83   89   97  101  103  107  109  113  127  131  137  139  149  151  157  163  167  173  179  181  191  193  197  199  211  223  227  229  233  239  241  251  257  263  269  271  277  281  283  293  307  311  313  317  331  337  347  349  353  359  367  373  379  383  389  397  401  409  419  421  431  433  439  443  449  457  461  463  467  479  487  491  499  503  509  521  523  541  547  557  563  569  571  577  587  593  599  601  607  613  617  619  631  641  643  647  653  659  661  673  677  683  691  701  709  719  727  733  739  743  751  757  761  769  773  787  797  809  811  821  823  827  829  839  853  857  859  863  877  881  883  887  907  911  919  929  937  941  947  953  967  971  977  983  991  997
     number of primes         168


## エラトステネスのふるいによる素数求め　
10^8 以下の素数の個数を求める。

ただし偶数を表から抜く。表を３から始める。[3,5,7,9,...10^8-1]



```fortran
program eratos3
  integer(8), parameter :: ip = 8
  logical(1), allocatable :: itab(:) 
  integer(8) :: i, j, np
  np = 10**ip / 2 - 1
  allocate(itab(np))
  forall(i = 1:np) itab(i) = .true.
  do i = 1, int( (sqrt(real(2*(np + 1)))  ))
    if (itab(i)) forall(j = 2*i*(i+1):np:2*i+1) itab(j)= .false.
  end do
  print *, count(itab) + 1
end program eratos3
```

         5761455
Javaプログラミング基礎の練習～for文

新人の時に作ったプログラムを、2年目になった今作ってみました。
今日はfor文。

結論
何年たってもfor文が苦手
#問題
* ソースファイル名「Check31.java」
* 10から20までの和などのように、指定した任意の2数間の和を求め出力するプログラムを作成してください
* その他の詳細は以下の実行結果を参考にしてください

```
1つめの数値を入力してください>
10
2つめの数値を入力してください>
20
10から20までの和は、165です
```

#実装
以下のように作りました。

```Check31.java
package practice;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Check31 {

	public static void main(String[] args) {
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		System.out.println("1つ目の整数を入力してください");
		String line;
		try {
			line = reader.readLine();
				int num1 = Integer.parseInt(line);

		System.out.println("2つ目の整数を入力してください");
		line = reader.readLine();
		int num2 = Integer.parseInt(line);
		int answer = calc(num1,num2);
		System.out.println(num1 + "から" + num2 + "までの和は、" + answer + "です");
		} catch (NumberFormatException e) {
			System.out.println("整数を入力してください");
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	private static int calc(int num1, int num2) {
		int sum = 0;
		for (int i = num1; i <= num2; i++) {
			sum = sum + i;
		}
		return sum;

	}

}

```

#感想
ここにいたるまでに、和が11になったり、21になったり、175になったり、22527になったり。。
for文苦手。一発でfor文を完成させられるようになりたい。。
TinkerBoardでOpenCLでMonacoinを採掘してみる

# はじめに

最近ASUS TinkerBoardで遊んでいます。
価格59ドルと最近のシングルボードコンピュータの中では安いわけではないですが、いろいろ高性能で**OpenCL経由でGPUを使うことができる**、という点で面白いデバイスだと思います。
搭載しているGPUはMali-T764で、下記リンク先によると、**81.6GFLOPS**の性能とのことです：
http://gpuflops.blogspot.jp/

あと、Raspberrypiのケースや周辺ハードウェアが使えるのも嬉しいポイントですね。

今回はこれを使ってMonacoinのマイニングをしてみます。

# セットアップ
[TinkerOS debian]をセットアップします。
手順は省略しますが、イメージ書き込み後にパーティションを拡張するのは見逃しがちです：
http://www.royalcrab.net/wpx/?p=4983

# OpenCLを使えるようにする
libOpenCL.soははじめから入っているようですので、開発用にヘッダーファイルのみ用意します：

```shell-session
sudo apt-get update
sudo apt-get install opencl-headers
```
これだけでOpenCLが使えるはずですので、適当なサンプルコードなどでOpenCLの動作チェックをしておくと良いです。

# sgminerのビルド
マイナーはsgminerを使います。ベースは
 https://github.com/djm34/sgminer 
ですが、Tinkerboardで動かすために少し修正が必要です。
とりあえずの修正済みコードはGithubで公開しました
https://github.com/stnk20/sgminer/tree/tinkerboard

ビルド手順：

```shell-session
git clone -b tinkerboard https://github.com/stnk20/sgminer.git
git submodule init
git submodule update
autoreconf -i
CFLAGS="-O2 -Wall -march=native" ./configure --disable-adl --without-curses 
make -j3

```

sgminerの使い方はこちらを参照しました：
https://blog.visvirial.com/articles/499

# 結果
セッティングや冷却の条件によりますが、手元でのハッシュレートは35-45KH/s程度です。
消費電力は測っていないですが、余裕の赤字でしょう。まあ、もとから予想してたことではありますが。
最適化コードが出回っていたりするので、それを使えばもう少しは上がるとは思います。

ちなみに最近のSnapdragonなどはすごい高性能なので、環境がある人は試してみては。

# まとめ
Tinkerboard+OpenCL面白いのでやってみよう！
Arduinoことはじめ

# Arduino開発
## IDEのダウンロード
いきなりハマったIDEのダウンロード
一見ただのラベルに見える JUST DOWNLOADの文字をクリックする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/99240/1c9db8ee-2eab-f416-a44c-79a23e0b7165.png)
## プッシュボタンを使ってLEDをコントロール
”Arduinoをはじめよう”というオライリー本のプッシュボタンを使ってＬＥＤをコントロールの章を実践
いきなり名前も聞いたことないようなパーツの名前のオンパレードで、図も適当なので困惑したが、添付の写真のように接続した、ブレッドボードはどうやらボタンと抵抗とワイアの列が揃っていればOKらしい
あとで勉強せねば・・・![IMG_3245.JPG](https://qiita-image-store.s3.amazonaws.com/0/99240/f1ac4eba-9b67-fecb-4c27-8e2cf9d3d1a0.jpeg)
SymPyにおいて関数を関数で置き換えて（≠代入）三角関数の加法定理を証明しよう


## subs と replace

SymPyの `subs` と `replace` は代入と置き換えという似て非なる関数です．


```python
from sympy import symbols, sin, cos, exp, I, sqrt, expand, init_printing
init_printing()
x = symbols('x')
f =  sin(x)+sin(x**2)
```

次の例は `sin(x)` に `cos(x)` を代入します．


```python
f.subs(sin(x), cos(x))
```




$$\sin{\left (x^{2} \right )} + \cos{\left (x \right )}$$


当たり前ですが，この場合，`sin(x**2)` は `cos(x**2)` に置き換わりません．
これは意図した仕様なのかは知りませんが，`.subs(sin, cos)` で `sin` を `cos` に置き換えられます．


```python
f.subs(sin, cos)
```




$$\cos{\left (x \right )} + \cos{\left (x^{2} \right )}$$



しかし，`.subs(sin, sqrt)` では `sin` を `sqrt` に置き換えられません．


```python
f.subs(sin, sqrt)
```




$$\sin{\left (x \right )} + \sin{\left (x^{2} \right )}$$



よくは分かりませんが，`sympy.core.function.FunctionClass` 同士だったら置き換えられる気がします．


```python
for func in [sin, cos, sqrt]:
    print(func.__class__)
```

    <class 'sympy.core.function.FunctionClass'>
    <class 'sympy.core.function.FunctionClass'>
    <class 'function'>


本来，関数を関数に置き換えるには `replace` が本来の用法だと思います．


```python
f.replace(sin, cos)
```




$$\cos{\left (x \right )} + \cos{\left (x^{2} \right )}$$




```python
f.replace(sin, sqrt)
```




$$\sqrt{x} + \sqrt{x^{2}}$$



`replace` の引数には，自作の関数やlambda式でもOK．


```python
f.replace(sin, lambda t: cos(t**2)) # sin(□) を cos(□**2) に置き換える
```




$$\cos{\left (x^{2} \right )} + \cos{\left (x^{4} \right )}$$

## オイラーの公式から

オイラーの公式
$$
e^{\theta i} = \cos\theta + i\sin\theta\tag{1}
$$
において，$\theta$ を $-\theta$ に置き換えると，$\cos(-\theta) = \cos(\theta),\ \sin(-\theta) = -\sin\theta$ より
$$
e^{-\theta i} = \cos\theta - i\sin\theta\tag{2}
$$
です．したがって，$(1)+(2)$ より
$$
e^{\theta i} + e^{-\theta i} = 2\cos\theta\ \Longleftrightarrow\ \cos\theta = \frac{e^{\theta i} + e^{-\theta i}}{2}
$$
$(1)-(2)$ より
$$
e^{\theta i} - e^{-\theta i} = 2i\sin\theta\ \Longleftrightarrow\ \sin\theta = \frac{e^{\theta i} - e^{-\theta i}}{2i}
$$
が成り立ちます．すなわち，よく知られていることですが，$\cos$ や $\sin$ は指数関数で表すことができるのです．


```python
cos2exp = lambda t: (exp(t*I) + exp(-t*I))/2
sin2exp = lambda t: (exp(t*I) - exp(-t*I))/(2*I)
(sin(x)+cos(x)).replace(cos, cos2exp).replace(sin, sin2exp)
```




$$- \frac{i}{2} \left(e^{i x} - e^{- i x}\right) + \frac{e^{i x}}{2} + \frac{1}{2} e^{- i x}$$



これを利用すれば，三角関数の種々の公式を証明（確認）できます．


```python
alpha, beta = symbols(r'\alpha \beta')
A = sin(alpha+beta)
B = sin(alpha)*cos(beta) + cos(alpha)*sin(beta)
```


```python
expand(A.replace(sin, sin2exp).replace(cos, cos2exp))
```




$$- \frac{i}{2} e^{i \alpha} e^{i \beta} + \frac{i}{2} e^{- i \alpha} e^{- i \beta}$$




```python
expand(B.replace(sin, sin2exp).replace(cos, cos2exp))
```




$$- \frac{i}{2} e^{i \alpha} e^{i \beta} + \frac{i}{2} e^{- i \alpha} e^{- i \beta}$$



これで，`A=B` すなわち
$$
\sin(\alpha+\beta) = \sin\alpha\cos\beta + \cos\alpha\sin\beta
$$
が確認できました．
Linuxコマンド 略語 (LPIC304)

# 主題 330: 仮想化
## 330.1 仮想化の概念と理論
HVM: Hardware Virtual Machine
PV: Paravirtualization
P2V: Physical to Virtual
V2V: Virtual to Virtual
IaaS: Infrastructure as a Service
PaaS: Platform as a Service
SaaS: Software as a Service

## 330.2 Xen
Xen: 禅

## 330.3 KVM
KVM: Kernel-based Virtual Machine
QEMU: Quick Emulator

## 330.4 その他の仮想化ソリューション
OpenVZ: Open Virtuozzo
LXC: Linux Containers

## 330.5 Libvirt と関連ツール
libvirtd: N/A
libvirtd: libvirt daemon
virsh: N/A
oVirt: N/A

## 330.6 クラウド管理ツール

# 主題 334: 高可用クラスタ管理
## 334.1 高可用性の概念と理論
MTBF: Mean Time Between Failure
MTTR: Mean Time To Recovery
SLA: Service Level Agreement

## 334.2 ロードバランスクラスタ
LVS: Linux Virtual Server
IPVS: IP Virtual Server
VRRP: Virtual Router Redundancy Protocol
keepalived Keep Alive Daemon
ldirectord: N/A
HAProxy: High Availability Proxy

## 334.3 フェイルオーバークラスタ
Corosync: N/A
OpenAIS: Open Application Interface Specification
CMAN: Cluster Manager
CIB: Cluster Information Base
CRMd: Cluster Resource Management Daemon
PEngine: Policy Engine
LRMd: Local Resource Management Daemon
DC: Designated Coordinator
STONITHd: Shoot the Other Node in the Head Daemon
OCF: Open Cluster Framework
LSB: Linux Standard Base
STONITH: Shoot the Other Node in the Head
Nagios: Nagios Ain't Gonna Insist On Sainthood

pcs: pacemaker/corosync configuration system
crm: cluster resource manager
crmsh: crm shell
crm_mon: crm monitor

authkey: authentication key
corosync-cfgtool: corosync config tool
corosync-cmapctl: corosync 
corosync-quorumtool: N/A

## 334.4 エンタープライズ Linux ディストリビューションにおける高可用性

# 主題 335: 高可用クラスタストレージ
## 335.1 DRBD / cLVM
DRBD: Distributed Replicated Block Device
LVM: Logical Volume Manager
cLVM: Cluster LVM

vgchange: volume group change
vgs: volume group size

## 335.2 クラスタファイルシステム
GFS2: Global File System 2
OCFS2: Oracle Cluster File System 2
O2CB: N/A
DLM: Distributed Lock Manager
CephFS: Ceph File System
GlusterFS: GNU cluster file system
AFS: Andrew File System

mkfs: make file system
fsck: file system check
tunefs: tune file system
Rustで巨大なヒープメモリを取る

4MBのヒープメモリを取ることに手こずったのでメモ。

Boxを使う方法

```Rust
fn main() {
    let buf=Box::new([0;1024*1024*4]);
    println!("addr:{:?}",buf[1]);
}
```
こんなエラーが出て死ぬ

> thread 'main' has overflowed its stack

なーんでヒープ使うのにスタックオーバーフローで死んでんだよ。
ヒープ確保してるだけじゃん、mallocだろ？？？？？？？？？？？
とか思ったけど、よくよく調べてみると次の手順で初期化しているらしい。

1. スタックに領域確保&初期化
2. 確保したヒープメモリにコピー

素直にヒープ領域を初期化しろよ
とか思ったけど、何か理由があってそうしてるんだと思う。しらんけど。

なので、Vecを使う。

```Rust
fn main() {
    let mut buf :Vec<u8>= vec![0;1024*1024*4];
    println!("Hello, world!{:?}",buf);
}
```

未初期化の領域が欲しかったら以下のように。
ただし、メモリを確保して、ベクタの管理情報を自分で登録する
というように、あまりにもC言語的なミスが発生しやすそうなので使いたくない。

ぶっちゃけ自分で0-fillするので、上の例だけで十分っぽい。

```Rust
fn main() {
    let mut buf ;
    unsafe{
        let len=1024*1024*4;
        buf=Vec::<u8>::with_capacity(len);
        buf.set_len(len);
    }
    println!("buf:{:?}",buf);
}

```

おわり
AWSCLIインストール手順


### はじめに

AWSCLIを使う際にエラーがやたらに出て、詰まったのでメモ。

#### 環境

* Mac OS Sierra

### AWS CLIのインストール
---

Pythonのパッケージ管理ツールを経由してawscliを入れるためPythonをインストールする。

```
$ brew install python

$ sudo easy_install pip

$ sudo pip install awscli

// 上記の方法で出来なかった方は以下
$ sudo pip install awscli --upgrade --ignore-installed six
```

### AWS CLIの設定
---

```
// AWSの設定を行う
$ aws configure
```

上記コマンドを入力後、AWSのアクセスキーとシークレットキーを入力あとは省略してもOKです。

### pemファイルの権限
sshで接続する際に、pemファイルの権限がないと怒られたので、同様の方は以下

```
$ chmod 600 hoge.pem
```

`hoge.pem`は任意で変更し、pemファイルまでのパスを記述すればOK

以上で完了です。
CFアプリ開発と管理#5 アプリの起動、再起動、および再ステージ


このトピックでは、Cloud Foundryでアプリケーションを起動、再起動、再ステージする方法について説明します。
*コメント: IBM Bluemix では、[Bluemix CLI](https://clis.ng.bluemix.net/ui/home.html) として提供されています。bx cf としてサブコマンドとして利用します。*

*注意事項: この記事は、Cloud Foundry Documentaion [Starting, Restarting, and Restaging Applications](http://docs.cloudfoundry.org/devguide/deploy-apps/start-restart-restage.html)(last updated: November 22, 2016)からの独自の翻訳とコメントです。 内容を保証するものではありません。*


## アプリケーションの起動

アプリケーションを起動するには、アプリケーションのルートディレクトリから次のコマンドを実行します。

~~~
$ cf push YOUR-APP
~~~



アプリケーションのデプロイの詳細については、「アプリケーションのデプロイ」を参照してください。

Cloud Foundryは、次の3つのソースのいずれかからアプリケーションの開始コマンドを決定します。

* Cloud Foundry CLI の -cコマンドラインオプション。 次の例を参照してください。

~~~
$ cf YOUR-APP -c "node YOUR-APP.js"
~~~


* アプリケーション manifestでは、 次の例を参照してください。
     command: node YOUR-APP.js

* 特定のタイプのアプリケーションに適した開始コマンドを提供するbuildpackを指定

Cloud Foundryが使用するソースは、以下に説明する要因によって異なります。


### Cloud Foundryがデフォルトの開始コマンドをどのように決定するか

初めてアプリケーションをデプロイするとき、cf pushはデフォルトでbuildpack startコマンドを使用します。 その後、cf pushは、前のプッシュに使用された開始コマンドにデフォルト設定されます。

これらのデフォルトを上書きするには、-cオプションまたはマニフェストのコマンド属性を指定します。 コマンドラインとマニフェストの両方で開始コマンドを指定すると、cf pushはマニフェストのコマンドを無視します。


### Cloud Foundry がビルドパックの開始コマンドを強制するには

Cloud Foundryが buildpack startコマンドを強制するには、startコマンドをnullに指定します。

null 開始コマンドは、次の2つの方法のいずれかで指定できます。

* cf CLIで-cコマンドラインオプションを使用する：

~~~
$ cf push YOUR-APP -c "null"
~~~

* アプリケーションのmanifestでコマンド属性を使用する

command: null


これは、コマンドラインまたはmanifestの開始コマンドでデプロイした後に役立ちます。 この時、buildpack startコマンドではなく、指定したコマンドが、デフォルトの開始コマンドになります。buildpack startを使用してデプロイする場合、nullを使用すると簡単に実行できます。


### データベースの移行時に開始コマンド

アプリケーションのデプロイメントの一部としてデータベースを移行する場合は、開始コマンドが特別な方法で使用されます。 詳細については、「[クラウド・ファウンドリでのデータベースの移行](http://docs.cloudfoundry.org/devguide/services/migrate-db.html)」を参照してください。


## アプリケーションを再起動する

アプリケーションを再起動するには、次のコマンドを実行します。

~~~
$ cf restart YOUR-APP
~~~

アプリケーションを再起動すると、アプリケーションが停止し、すでにコンパイルされたドロップレットでアプリケーションが再起動されます。 dropletは、以下を含む tarball です。

* stack
* buildpack
* application source code

Diegoセルは、コンテナにdropletを展開、コンパイル、実行します。

アプリケーションを再起動して、新しいサービスをアプリケーションにバインドする、またはアプリケーションだけが使用する環境変数を設定するなどのアクションの後に、アプリケーションの環境を更新します。 ただし、ビルドパックに、アプリケーションを加えるために、環境変数が必要となる場合は、変更を有効にするためにアプリケーションを再ステージする必要があります。


## アプリケーションを再ステージする

アプリケーションを再ステージするには、次のコマンドを実行します。

~~~
$ cf restage YOUR-APP
~~~

アプリケーションを再ステージすると、新しいdropletをコンパイルして起動することによって、アプリケーションが停止し、アプリケーションが再開されます。

ビルドパックが使用する環境変数の設定など、ステージングプロセスに影響するように環境を変更した場合は、アプリケーションを停止してください。 ステージングプロセスは環境変数にアクセスできるため、環境はdropletの内容に影響を与える可能性があります。

アプリケーションを再ステージすると、アプリケーションのソースを更新することなく、アプリケーションから新しいdropletがコンパイルされます。 アプリケーションソースを更新する必要がある場合は、上記の手順に従ってアプリケーションを再プッシュします。
KerasでOpenAI GymのFrozenLake8x8-v0を解きたかった...

FrozenLake-v0は盤面サイズが4x4でしたが，こちらは8x8．
https://gym.openai.com/envs/FrozenLake8x8-v0

4x4での解法はこちらに記載しています．
http://qiita.com/namakemono/items/989f94fe788532a335f2

盤面が大きくなるので，テーブルで持つことは難しく関数近似が必要になります．

## クリア条件

- 直近100回の試行の報酬の平均値が0.99以上.
- 報酬はクリアできたら+1,落とし穴に落ちたら0とする．

## 考察

今回のマップは

```
S.......
........
...H....
.....H..
...H....
.HH...H.
.H..H.H.
...H...G
```

- S: ゲーム開始地点
- G: クリア地点(移動できれば成功)
- H: 落とし穴(落ちると失敗)
- F: 移動できる場所(Fだと見づらいので，　"."で表示しています．)

- 開始地点(S)から右に行って，下に行くのが正解となる．
- 2/3の確率で意図した方向とは異なる方向(直角)に進む(下記リンク参照)ので，最初0.99は無理でしょと思ったが，最後の2マスは右押して移動することで，100%クリアは可能ということに気づく．
https://github.com/openai/gym/blob/master/gym/envs/toy_text/frozen_lake.py#L99
- 左下からの1/3の確率で意図した方向と違う方向に進むために，安定してゴールすることはできない．(つまり，こちらのコースは引っ掛けであることをコンピュータは学習する必要がある)

## コード

```python
# -*- coding: utf-8 -*-
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
import numpy as np
import gym
from gym import wrappers
from keras.models import Sequential
from keras.layers import Dense

def build_model(input_dim, output_dim):
    model = Sequential()
    model.add(Dense(input_dim, kernel_initializer="he_normal", activation="relu", input_shape=(input_dim, )))
    model.add(Dense(output_dim, kernel_initializer="he_normal", activation="softmax"))
    return model

def run():
    env = gym.make("FrozenLake8x8-v0")
    env = wrappers.Monitor(env, directory="/tmp/frozenlake8x8-v0", force=True)
    logger.info("Observation Space: %d, Action Space: %d" % (env.observation_space.n, env.action_space.n))
    max_episode = 100000
    Gs = [] # Revenues
    best = -1
    model = build_model(env.observation_space.n, env.action_space.n)
    model.compile(loss="categorical_crossentropy", optimizer="nadam", metrics=["mae", "mse"])
    for episode in range(max_episode):
        x = env.reset()
        X = [] # States
        A = [] # Actions
        Q = [] # Action Values
        done = False
        alpha, gamma = 0.03, 0.9
        while not done:
            v = np.zeros(env.observation_space.n)
            v[x] = 1
            q = model.predict(np.asarray([v]))[0]
            a = np.argmax(q)
            X.append(v)
            A.append(a)
            Q.append(q)
            x, r, done, info = env.step(a)
            if done:
                r = +1 if r > 0 else -1
                break
        T = len(X)
        for t in range(T-1):
            a = A[t]
            Q[t][a] = (1-alpha) * Q[t][a] + alpha * r
        model.fit(np.asarray(X), np.asarray(Q), verbose=0, batch_size=T)
        Gs.append(int(r > 0))
        avg = np.mean(Gs[-100:])
        best = max(best, avg)
        logger.info("Episode: %d, End of turn: %d, Revenue: %.2f, Average: %.2f, Best: %.2f" % (episode, len(X), r, avg, best))

if __name__ == "__main__":
    run()
```

## スコア

- 0.96±0.02
DB の準備が出来るまで Django の起動を待つコマンド作ってみた

Docker-compose 使うとき不便だったので作ってみました。

https://github.com/pistatium/dj_database_waiter

## なにこれ
Database の接続が確立するまで待ち続けるだけの Python コマンドです。


```
 dj_database_waiter myproject.settings
```

Django の設定モジュールを引数に渡してあげるだけで動きます。(厳密には止まります)

docker-compose で DB と Django 立ち上げた時、Dockerは最低限のネットワーク疎通ができるまで(?)は Django 側のコンテナの立ち上げを待ってくれますが、初期 SQL の投入だったりといった初期化まではしっかり待ってはくれません。
勝手に起動して勝手にコンテナが終了します。つらいめう
StackOverflow とかで対処法調べてもシェルスクリプトで準備するまで待つしかないみたいな事が書かれていて結構つらみがあります。
疎通確認のためだけに Python の Docker に DB Client をインストールしたくないですし…。

となると Python で疎通を確認するスクリプトを書くのがベターです。
ただプロジェクトごとにそのスクリプトをコピペしたり、Django とは別に都度接続情報を渡すのも面倒だなーと思ったのでコマンド化して pip で入るようにしてみました。

最初は Django コマンドとして admin.py から呼べるように実装したのですが、DB が立ち上がる前だとサブコマンドの起動自体失敗する事に気づいて泣く泣く普通のコマンドとして書き直しました。

## 使い道

```docker-compose.yml
version: '3'

services:
  web:
    build: .
    command: python3 myproject/manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/src
    ports:
      - 8000:8000
    depends_on:
      - db
  db:
    image: mysql
    volumes:
      - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
      - db-volume:/var/lib/mysql
volumes:
  db-volume:
```

こういう docker-compose を up したときに一回で上手く立ち上がらない時は、ビルド時に dj_database_waiter をインストールするようにして

```docker-compose.yml
    command: /bin/sh dj_database_waiter myproject.settings && python3 myproject/manage.py runserver 0.0.0.0:8000
```

みたいに command を置き換えてあげればよしなに1回で起動できるようになります。


## おまけ: NamedTuple 楽しい

`dj_database_waiter` は `from typing.NamedTuple` を使いたかったため**だけ**に Python3.6.1 以上を必要とします。あしからずご了承ください。

```dj_database_waiter/cmd.py
class DbStatus(NamedTuple):
    ok: bool
    reason: str = None


def check_status(db_group_name: str) -> DbStatus:
    try:
        ...
    except Exception as e:  # NOQA
        return DbStatus(ok=False, reason=str(e))
    return DbStatus(ok=True)
```

引数2個なので NamedTuple 使う必要性ほぼ無いのですが、こんな風にわかりやすく書けます。
Scala でいう CaseClass に近いものですね。
型の情報も書いてるので IntelliJ みたいな IDE 使って書くとバリバリ補間･エラーチェックしてくれるので精神衛生上とてもよろしいです。
(ちなみに実行時型チェックはされないので、間違った型を入れても動いてしまいます)
UnityでVR対応のどこでもドア実現を目指す その２ Oblique Near-Plane Clipping編 の補足

# 概要
[UnityでVR対応のどこでもドア実現を目指す その２ Oblique Near-Plane Clipping編](http://qiita.com/tsgcpp/items/3816e4cf188db257df19)の補足を記載します。

# Oblique Near-Plane Clipping
細かい計算式やロジックについては複雑な話になるため今回はイメージのみを記載します。
なぜ平面の方程式を渡すかは、次回あたりに説明するかもしれません。

以下の逆三角がカメラ空間の視錐台とします。本来は３次元ですが説明はxz空間の２次元で行います。

* 青領域が描画**対象内**
* 赤色が描画**対象外**
* 青と赤の境界の斜線が **Clip Plane**

![Camera Space.JPG](https://qiita-image-store.s3.amazonaws.com/0/188798/dc8fad7d-4e88-d6cb-a6b3-c7c8fd8d4153.jpeg)


そして以下が上記の視錐台を描画対象範囲であるクリップ空間に変換したものです。
![clip space.JPG](https://qiita-image-store.s3.amazonaws.com/0/188798/f6ec22af-ce7d-0926-92a8-b8cda1bfb56a.jpeg)


Oblique Near-Plane Clipping は上記の境界の斜線に伸びる矢印のように

*x,y軸の値は変更せず、z軸の値のみを操作してClip Plane上のzの値をDepth Bufferの最小値にする*

というテクニックです。

## Oblique Near-Plane Clipping の注意点
### Far-Planeが不安定になる
上記のクリップ空間の上部が画像からはみ出ていますが、これは意図的に表現しています。
というのも一度Oblique Near-Plane Clippingを設定するとFar-Planeに以下の現象が起きます。

* Far-PlaneはNear-Planeと非平行化
* UnityのCameraのFarの値は正確に作用しない
  * ただし本来のFar-Planeより手前のメッシュは描画対象のまま
  * Far-Planeより外のオブジェクトは意図しない形で描画対象となる可能性がある

イメージで一例を表すと以下のような事になります。
![Camera Space for far palen.JPG](https://qiita-image-store.s3.amazonaws.com/0/188798/cf575e03-6688-248d-6af0-e57bd05540aa.jpeg)

# UnityのCameraについて
## 一部メソッドの扱うパラメータはカメラ空間準拠
今回Unityの`Camera`クラスに渡すメソッドに触れてみて気づいたのですが、
一部は**カメラ空間**でのパラメータを扱うものが含まれています。

ドキュメントには、コアな部分を触る人には当たり前なのかメソッドによってはどの空間準拠で渡すかは明記されていません。

以下カメラ空間準拠のメソッド例です。

* `CalculateObliqueMatrix`
* `worldToCameraMatrix`
* property `projectionMatrix`

[Camera.worldToCameraMatrix](https://docs.unity3d.com/ScriptReference/Camera-worldToCameraMatrix.html) のように言及してくれているものも有ります。

自分のようにグラフィックエンジンに慣れてない人からすると困惑するポイントだと思いますので、
Cameraのメソッドに渡すオブジェクトに迷ったときは、このことを意識するといいことがあるかもしれません。

## Unityのカメラ空間は左手系
普段扱っているUnityの**Transformは右手系**ですが、**カメラ空間は左手系**(OpenGL準拠)のようです。

`Camera.worldToCameraMatrix`などを直接使用して座標変換するなら意識する必要はありませんが、
もし独自にカメラに渡すパラメータを作る場合は注意が必要です。

僕の場合、はじめ
* `Transform.InverseTransformPoint`
* `Transform.InverseTransformDirection`

Cameraインスタンスの上記メソッド(Transformのため右手系のまま)を使用して平面の方程式を計算したためうまくいかず貴重な日曜日がさよならしました(笑)。
いろいろ探っているときに`Camera.worldToCameraMatrix`の説明を見つけてなんとか解決できました。

普段はあまり使わない知識かもしれませんが参考までに。


# 今回のまとめ、雑感
補足編が遅くなってしまいごめんなさい。
実はどこでもドアの実装における描画において、かなり迷ったり、行き詰まってしまっているため遅れてしまいました。。。

でも迷っているなりに楽しく感じていますのでまだまだ頑張っていきたいです。

いつも通りご指摘やコメントなどお待ちしています。
また、知識不足もありますが質問などあれば遠慮なくコメントにてください。
答えられる範囲であれば回答させていただきます！！！
node,npmのお勉強2


## import文を使いたい

初学者としてJavaScriptを学ぶ
http://blog.satotaichi.info/learning_javascript_for_beginners/

初学者なので、大変参考になります。

babelをscriptに追加しておくとcliで叩けるのね。
ecmascriptではまだimportが使えないのね。

> 僕の気持ちとしては、Yarn、Flow、ESlint、documentation.jsあたりは必須ですと書きたい。

使ってみるかな。。

## Flowは静的型チェック

flowの始め方 - Qiita
http://qiita.com/kiida/items/ea758e4d80053663e12a

Installation | Flow
https://flow.org/en/docs/install/

flow-runtime でテスト時にランタイムの型エラーでテストを落とす - Qiita
http://qiita.com/mizchi/items/ed4c4488675f249f7679

## documentation.jsはdocbookを解析してドキュメントにしてくれるのかな

documentationjs/documentation: documentation for modern JavaScript
https://github.com/documentationjs/documentation#documentation

でも、現状の環境にあるesdocを実行してみると結構いい感じだからな。。

## avaとmocha

b-o-a を mocha から AVA にのりかえた - 15 min/d
http://bouzuya.hatenablog.com/entry/2016/03/11/235959

なるほど。。

## eslint

共有設定でらくらく ESLint - Qiita
http://qiita.com/mysticatea/items/dc35ced6bd5e782f50cd

standardは動いた。
たぶん、airbnbは、バージョン依存で引っかかったのでひとまず放置。
`warnin	g "eslint-config-airbnb@15.1.0" has incorrect peer dependency "eslint-plugin-jsx-a11y@^5.1.1".`