OmniAICreator/Qiita-1.07M huggingface dataset:
HTML&CSS 重なり順を指定する

# **はじめに**
CSSのz-indexを使って、
「例えばパワポの最前面に移動、前面に移動」のように簡単に重なり順を指定する方法をまとめました。

また、前回の「rgbaを使って背景画像を暗くする」の記事の続きになっています。
https://qiita.com/szaizen/items/3ab28c03a76e08bb5581

# **z-index**
z-indexは要素の重なり順を決めることのできるプロパティです。

```CSS:
test {
  z-index: 数字;
}
```

数字で指定した値が大きい要素ほど上に表示されます。
これを使うだけで簡単に重なり順が指定できる、、、はず。
次、実践してみます。

# **実践例**

<img width="1014" alt="スクリーンショット 2018-04-10 20.59.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/240803/c20b870c-7db2-4a3d-2db2-a90c887a71d1.png">


```html:html
<body>
<div class="back">
  <h1 class="title">パソコン教室</h1>
  <p>Learn together!</p>
</div>
</body>
```
```css:css
body{
  height: 100%;
  margin: 0;
}
.back{
  /* 画面いっぱいに背景画像を貼り付ける */
  background: url(http://simplemodern-interior.jp/knowledge/wp-content/uplads/2014/07/pc.png) no-repeat center;
  background-size: cover;
  position: relative;
  height:100%;
}
.back::before{
  /* 透過した黒を上から重ねるイメージ */
  background-color: rgba(0,0,0,0.4);
  /* 自由に位置指定 */
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  content: ' ';
}
```

前回、rgbaを使って背景画像を暗くしました。
しかし、文字まで暗くなって見にくいので、最前面に出したいと思います。

# **position: absolute;**
<img width="875" alt="スクリーンショット 2018-04-10 21.32.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/240803/af863913-d678-66ac-1430-d7a99283c7e0.png">

```css:css
.title{
    position: absolute;
    width: 100%;
    text-align: center;
}
```
このように記述します。
この場合順番通りなのでうまく前面に表示されますが、HTMLが以下のような場合は背景画像に回り込んで表示されなくなってしまいます。

```html:html
<body>
<h1 class="title">パソコン教室</h1>
<div class="back">
    <p>Learn together!</p>
</div>
</body>
```

# **z-indexで重なり順を指定する**
そこで登場するのがz-indexさん。
ちなみにpositionがデフォルトのstaticだと適用されません。

なのでz-indexを追加すると、、

```css:css
.title{
    position: absolute;
    width: 100%;
    text-align: center;
    /* 重なり順を指定*/
    z-index: 1;
}
```

ちゃんと表示できました！！！！

# **参考サイト**
- z-indexの使い方：CSSで重なり順を指定する - サルワカ<br>
https://saruwakakun.com/html-css/basic/z-index
await 挙動の違い: JavaScript v.s. Python

# TL;DR
- JavaScript では Promise を new した瞬間に処理がトリガされる
- Python ではawait した瞬間に処理がトリガされる（ように私には見える）

特に、Python 使う場合は注意。思ったとおりの並列処理ができてないかもしれないかもよ。

# サンプルコード

- 1つめの Promise/コルーチン を作成し
- CPU主体処理(というかブロッキングな処理)を実施し
- 2つめの Promise/コルーチン を作成し
- 両方の Promise/コルーチン が終わるのを待つ

なんと上記のロジックをそのまま書くと Python と JavaScript で処理時間が異なってしまう。

JavaScript では以下の処理は 6秒で終わる。

```await.js
const asleep = async (val) => {
  await new Promise(r => setTimeout(() => r(), val*1000));
  return val;
}

const doCPUIntensiveProcess = (val) => {
  const endTime = Date.now() + val * 1000;
  for (;;) {
    {hello: 'world'};
    if (Date.now() > endTime)
      break;
  }
  return 1
}

const main = async () => {
  const start = Date.now()
  const p1 = asleep(3); // sleep 3sec
  const result = doCPUIntensiveProcess(5); // work 5sec, returns 1
  const p2 = asleep(result); // sleep 1sec
  console.log(await Promise.all([p1, p2]), result);
  console.log(`${((Date.now()-start)/1000).toFixed(0)}secs passed`)
};

main();
```

Python では以下の処理は 8秒 かかってしまう。

```await.py
import asyncio
import time

async def asleep(val):
    await asyncio.sleep(val)
    return val

def doCPUIntensiveProcess(val):
    end_time = time.time() + val
    while True:
        {'hello': 'world'}
        if time.time() > end_time:
            break
    return 1

async def main():
    start = time.time()
    t1 = asleep(3)
    result = doCPUIntensiveProcess(5)
    t2 = asleep(result)
    print(await asyncio.gather(t1,t2), result)
    print('{:.0f}secs passed'.format(time.time()-start))

asyncio.get_event_loop().run_until_complete(main())
```

なぜ違いがでるかというと、以下のとおりだからだ。

- JavaScript では Promise を new した瞬間に処理がトリガされる
- Python ではawait した瞬間に処理がトリガされる（ように私には見える）



# 改版
Python で JavaScript と同様の並列性を持たせるにはどうすればいいのだろうか？ await して非同期関数をトリガさせる前に、`doCPUIntensiveProcess`が走ってしまうのが原因なので、こいつの評価を遅らせればよさそうだ。ということで、以下のように変更すれば、処理時間が6秒で済む。

```await2.py
import asyncio
import time

async def asleep(val):
    await asyncio.sleep(val)
    return val

def doCPUIntensiveProcess(val):
    end_time = time.time() + val
    while True:
        {'hello': 'world'}
        if time.time() > end_time:
            break
    return 1

async def to_coroutine(f, args):
    return f(*args)

async def main(loop):
    start = time.time()
    t1 = loop.create_task(asleep(3))
    result = await loop.create_task(to_coroutine(doCPUIntensiveProcess, [5]))
    t2 = asleep(result)
    print (await asyncio.gather(t1,t2) , result)
    print('{:.0f}secs passed'.format(time.time()-start))

loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
```

# さいごに
python は Promise じゃなくて コルーチンだから、この挙動の方が正しいんだろうなあ。同じキーワード await を使っているから混乱するだけで。promise に対応するのは task/future であるよっと。
DockerCEインストール for Windows10pro

# Hyper-Vの有効化
Windows ボタンを右クリックし、[アプリと機能] を選択。
[Windows の機能の有効化または無効化] を選択。
[Hyper-V] を選択して、[OK] をクリック。
![a](https://docs.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/quick-start/media/enable_role_upd.png)

# インストール
以下からインストーラダウンロード
https://download.docker.com/win/stable/Docker%20for%20Windows%20Installer.exe
実行してそのまま手順通りに進める


# 参考
[Install Docker for Windows](https://docs.docker.com/docker-for-windows/install/)
[Windows 10 上に Hyper-V をインストールする](https://docs.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v)
issetを見直した

今更過ぎるのかもしれませんが最近知ったのでメモ。
[isset](http://php.net/manual/ja/function.isset.php)は可変長引数だったということと、便利だったということです。

> 複数のパラメータを渡した場合は、isset() はそれらすべてがセットされている場合にのみ TRUE を返します。 左から順に評価を行い、セットされていない変数があった時点で処理を終了します。


```php
$test_list = [];
$test_list2 = [];

if (isset($test_list['test']) && isset($test_list2[$test_list['test']]))
{
    // 処理
}
```

これは以下のように記載できるのであった。

```php
$test_list = [];
$test_list2 = [];

if (isset($test_list['test'], $test_list2[$test_list['test']]))
{
    // 処理
}
```

**補足**

以下ではNotice

```php
$test_list = [];
$test_list2 = [];

if (isset($test_list2[$test_list['test']]))// Undefined index: test
{
    // 処理
}
```

```php
if (isset($test_list2[$test_list['test']]))// Undefined variable: test_list
{
    // 処理
}
```
JavaScript タイマー関数

# JavaScriptのタイマー関数について
ドットインストールで良いのがあったのでメモ。
[ドットインストールのJavaScript入門](https://dotinstall.com/lessons/basic_javascript_v2/26715)

## setTimeout()について

- setTimeout()は、指定した時間停止した後に実行する。また、停止している時間は、非同期のコールバックの関数なので時間が来るまで他の処理をしてくれる優れもの。
- タイマーとして使う時は、再帰する関数の中に入れてループさせて使用する。
- setTimeout()は、idを発行するので、そのidを使用することでsetTimeout()を停止することもできる。

## サンプルソースコード

```sample.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Sample test</title>
</head>
<body>

    <script>
        var time = 0;
        function show() {
            console.log(time++);
            var sid = setTimeout(function () {
                show();
            }, 1000);
            if ( time > 10 ) {
                clearTimeout(sid);
            }
        }
        show();
    </script>
</body>
</html>
```
HTML&CSS rgbaを使って背景画像を暗くする

#  **はじめに**

背景画像が明るくて文字が見にくい、もう少し落ち着いたWebサイトにしたい、といったときに透過度を使った要素を作り、上に重ねて暗くする方法があります。
少し苦戦したのでここにまとめます。

#  **rgbaを使って背景画像を暗くする**

<img width="1014" alt="スクリーンショット 2018-04-10 20.59.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/240803/c20b870c-7db2-4a3d-2db2-a90c887a71d1.png">


```html:html
<body>
<div class="back">
  <div>
    <h1>パソコン教室</h1>
    <p>Learn together!</p>
  </div>
</div>
</body>
```
```css:css
body{
  height: 100%;
  margin: 0;
}
.back{
  /* 画面いっぱいに背景画像を貼り付ける */
  background: url(http://simplemodern-interior.jp/knowledge/wp-content/uplads/2014/07/pc.png) no-repeat center;
  background-size: cover;
  position: relative;
  height:100%;
}
.back::before{
  /* 透過した黒を上から重ねるイメージ */
  background-color: rgba(0,0,0,0.4);
  /* 自由に位置指定 */
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  content: ' ';
}
```

このように背景画像を適用させたdivの擬似要素に、薄めた黒の背景色を適用させ、背景画像に重ねて暗くする方法です。
**background-color: rgba(0,0,0,0.4);**
の部分は、以下の記述方法でもできます。

```css:
.back::before{
  background-color: black;
  opacity: 0.4;
}
```

また、擬似要素を使う場合、contentを使わないと中身がないとみなされて何も表示されないようです。

#  **文字のみ暗くせずに見やすくする**
こちらは次回の記事を参照
「HTML&CSS 重なり順を指定する」
https://qiita.com/szaizen/items/16a01ccfa05280cf8853

# **参考サイト**
- 画像を暗くしてみる<br>
http://pilgrim-guild.com/background-darken/
- CSSだけで背景写真のみを暗くする<br>
http://glatchdesign.com/blog/web/css/532
average reduce

```js
let ary=[1,9,2,8,3,7,4,6,5,5,6,4,7,3,8,2,9,1,0,10]; //av5
let av=ary.reduce((a,b,i,me)=>{return (i===me.length-1)?(a+b)/me.length:a+b})
console.log(av)
console.log(ary.reduce((a,b)=>a+b),ary.length)//check
```
Laravelのスケジューラでの排他制御（withoutOverlapping）について

# 問題
ある日、アクセス集中によりサーバーがダウンする事態に見舞われた。
その後、サーバーを再起動してもバッチ処理が正しく実行されない問題が発生した。
バッチ処理はLaravelのスケジューラにより定期実行している。

# 原因

吐かれていたログは、
> No scheduled commands are ready to run.

そういえばスケジューラで
[多重起動の防止](https://readouble.com/laravel/5.5/ja/scheduling.html#preventing-task-overlaps)の設定をしていた。（withoutOverlapping()の指定。）

```php
// 例
$schedule->command('emails:send')->withoutOverlapping();
```

どうやら、処理が正常に終了しなかったため、ロックファイルが残り続けており、その後の処理がスキップされてしまっていたようだった :cry:

# 対策

/storage/framework配下にロック用のファイル（schedule-XXXXXXXX）が生成されていたので、削除した。まぁ、それだけ。

その後、バッチは元気に仕事を再開してくれました :thumbsup_tone2:

補足：ロック用のファイルのファイル名

```php
    /**
     * Get the mutex name for the scheduled command.
     *
     * @return string
     */
    public function mutexName()
    {
        return 'framework/schedule-'.sha1($this->description);
    }
```
Excel VBA でオートフィルタされたセルを扱う

VBA でオートフィルタをかけられたセルをマウスで選択して処理をしようとしてもうまく行かなかったので備忘録。

```vb
Dim cell As Variant
For Each cell In Selection
    ' 何かの処理
Next
```

みたいにループを回して処理をしようとしても、オートフィルタで隠されているセルまで処理されてしまいます。
こんなときは、以下のようにしてみてください。

```vb
Dim cell As Variant
For Each cell In Selection.SpecialCells(xlCellTypeVisible)
    ' 何かの処理
Next
```

要は、オートフィルタをかけて「見えてるセルだけ」処理しろということなのですけどね。


## 2018年4月24日追記

オートフィルタをかけて、1つだけセルを選択したときの挙動がおかしいです。
Excel 2013で確認しましたが、Excel のバクでしょうか。
仕方がないので、セルの高さをチェックするようにしました。

```vb
Dim cell As Variant
For Each cell In Selection
    If cell.Height = 0 Then
        GoTo CONTINUE
    End If

    ' 何かの処理

CONTINUE:
Next
```
ReactNativeアプリでMicrosoft Azure AppCenterを使ってみる①

# AppCenterとは
AppCenterとは、Microsoft　Azure Visual Studioのサービスの一つ。
クラウド上でアプリのビルド、テスト、配布、リリースができる。


# 目的
React NativeアプリをAppCenterを使って開発・運用したい。


# AppCenterのアカウントを作る
AppCenterのアカウントの作成はこちらのサイトから。
https://appcenter.ms/

基本的に、「Get Start」から案内に従えば作成ができます。
無事作成されると下記のような画面が表示されます。
デフォルトではapptestというアプリが作成されているようです。

![スクリーンショット 2018-04-10 20.33.49.png](https://qiita-image-store.s3.amazonaws.com/0/223429/4c054d0f-feb7-9e91-ce53-ae1d64ca4dbf.png)


上記のアイコンをクリックすると、個別のアプリに対するメニューが左側に表示され、色々操作を行えるようになります。

![スクリーンショット 2018-04-10 20.18.45.png](https://qiita-image-store.s3.amazonaws.com/0/223429/738021dc-fabe-ebfc-d097-17cfe615863f.png)


できた。

# アプリを追加する
アプリを追加するには、右上の「Add new」ボタンから行います。
ここで、新規作成するアプリの初期設定をしていきます。

![スクリーンショット 2018-04-10 20.16.53.png](https://qiita-image-store.s3.amazonaws.com/0/223429/d7e75da0-0474-8ff1-b358-cfd61b964298.png)

入力が終わったら「Add new app」を押します。

![スクリーンショット 2018-04-10 20.15.37.png](https://qiita-image-store.s3.amazonaws.com/0/223429/1672dd2b-6648-1940-ad40-572ff7af58ee.png)

すると、先程作成したReactNativeSampleProjectが追加されました！

ここからアプリをビルドしたり運用していきます。


# CLI

appcenterコマンドがインストールされている場合は、consoleからコマンドをたたくことでログインしているアカウントのアプリをリストで表示することもできます。

コマンドがインストールされていない場合は、

```
$ npm install -g appcenter-cli
```

などでインストールしてください。

```
$ appcenter apps list
  username/apptest
  username/ReactNativeSampleProject
```

ブラウザで表示されているものと同じものがconsole上でも確認できるはずです。
Fortigate 60Eを買った

SSL-VPNが必要となり、ついでにいろいろ制御もしたくなったのでFortigateを購入した。
50Eと60Eで大分迷ったが、50Eで困っている人も見かけたので60Eを購入。
50Eだと全部CPU処理だと見受けられたというのも60Eにした理由。

お決まりのHW情報を取得、SOC3にNP6Liteの機能が含まれているようでよかった。

```
# get hardware status 
Model name: FortiGate-60E
ASIC version: SOC3
ASIC SRAM: 64M
CPU: ARMv7
Number of CPUs: 4
RAM: 1866 MB
EMMC: 3662 MB(MLC) /dev/mmcblk0
Hard disk: not available
USB Flash: not available
Network Card chipset: FortiASIC NP6LITE Adapter (rev.)

# get hardware cpu
Processor       : ARMv7 Processor rev 1 (v7l)
processor       : 0
BogoMIPS        : 2007.04

processor       : 1
BogoMIPS        : 2007.04

processor       : 2
BogoMIPS        : 2007.04

processor       : 3
BogoMIPS        : 2007.04

Features        : swp half thumb fastmult vfp edsp thumbee vfpv3 vfpv3d16 tls 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x4
CPU part        : 0xc09
CPU revision    : 1

Hardware        : FSoC3_ASIC
Revision        : 0000
Serial          : 0000000000000000

```
まだ代理店からユーザー登録完了連絡が来てないからここまで。
KubernetesのQuality of Service(QoS)クラスについて

# Pod QoSクラスとは

Resource LimitはNodeのCapacityを超えて指定することができる。
もし、pod AがNodeのメモリ90%を使用していて、pod Bがメモリ50%を使用しようとした場合、どっちのコンテナをkillすべきだろうか？ メモリを確保できないからpod Bをkillすべきか？それともpod Aをkillしてpod Bを動かせるようにすべきか？
それは言うまでもなく状況による。

Kubernetesにはどのpodをkillするかを判断するために、Podに優先度をつける仕組みがあり、`Quality of Service(QoS)`クラスと呼ばれる。
優先度が低いQoSクラスをもったpodからkillされる。

Kubernetesは3つのQoSクラスを提供する。QoSはpodに対して自動的に付与される(人が手動で指定するものではない)。

* BestEffort (優先度が一番低い)
* Burstable
* Guaranteed (優先度が一番高い)

どのQoSクラスがpodに付与されるかは`Resource Requests`と`Resource Limits`の2つから決定される。

## どういった条件でQoSクラスが決まるか

### BestEffortが設定される条件

* pod内のどのコンテナにもCPU Resource RequestsとCPU Resource Limitsが設定されていなく、かつMemory Resource RequestsとMemory Resource Limitsが設定されていない。

### Guaranteed (the highest)が設定される条件

* pod内のどのコンテナにもCPU Resource RequestsとCPU Resource Limitsが設定されていて、かつMemory Resource RequestsとMemory Resource Limitsが設定されている。
* そして **Resource RequestsとResource Limitsの値がそれぞれ同じであること。(CPU,Memory両方)**

### Burstableが設定される条件

* BestEffortもGuaranteedも設定されていない場合。
    * つまり例えばResource Requestsしか設定されていない場合や、Resource RequestsとResource Limitsの両方が指定されているがそれぞれの値が異なっている場合にはBurstableが設定される。
    * またたとえCPU Resource RequestsとCPU Resource Limitsが設定されていて値が同じであってもMemory Resource RequestsとMemory Resource Limitsの値が同じでなければBurstableが設定される。


## pod内に複数のコンテナが存在する場合、どうやってpodのQoSが決まるか

まず各コンテナに上記のルールに従ってQoSを割り当てる。
全てのコンテナがBestEffortならpodのQoSはBestEffortになる。
全てのコンテナがGuaranteedならpodのQoSはGuaranteedになる。
それ以外の場合はpodのQoSはBurstableになる。

ちなみにpodのQoSは`kubectl describe pod -o yaml|json `したときに、`status.qosClass` fieldに表示される。

## nodeのメモリ上限に達した場合、どういった判断でプロセスがkillされるか

**QoSクラスに従ってどのコンテナがkillされるか決まる。**
最初にkillされるのはBestEffort。次にBurstable。最後にGuaranteed(ただしsystem processがメモリを必要とした場合のみkillされる)。

## 同じQoSクラスだった場合、どうやってどのコンテナがkillされるかを決めているか

どの実行中プロセスもOutOfMemory (OOM) scoreを持っている。[参考:Linux のオーバーコミットについて調べてみた](http://passingloop.tumblr.com/post/11957331420/overcommit-and-oom-killer)
システムはOutOfMemory (OOM) scoreをもとにどのプロセスをkillするかを決めている。


## 参考

* [Kubernetes in Action](http://amzn.asia/80rSDOx) (最高に分かりやすく書かれているのでぜひ買いましょう)
* [Configure Quality of Service for Pods](https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/)
* [Resource Quality of Service in Kubernetes](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/resource-qos.md)
Laravel + Vue.js 気をつけるべきところ

<h1>bladeに、app.jsで定義した変数を使うとき</h1>

```app.js

var example1 = new Vue({
  el: '#example-1',
  data: {
    counter: 0
  }
});

```

<h2><だめな例></h2>

```hoge.blade.php
  <div id="app">
      <hello></hello>
      <hello name="Laravel"></hello>
      <hello name="Vue.js"></hello>
      <div id="example-1">
  <button v-on:click="counter += 1">Add 1</button>
  <p>The button above has been clicked {{ counter }} times.</p>

</div>

```

<h2><良い例></h2>

```hoge.blade.php

<div id="app">
      <hello></hello>
      <hello name="Laravel"></hello>
      <hello name="Vue.js"></hello>
      <div id="example-1">
  <button v-on:click="counter += 1">Add 1</button>
  <p>The button above has been clicked @{{ counter }} times.</p>

</div>
```

{{ counter }}の前に,<string>@</string>を忘れるな！
configure: error: Cannot find OpenSSL's <evp.h>

村上氏がご対応

```
configure: error: Cannot find OpenSSL's <evp.h>
```
になった場合

```
PHP_BUILD_CONFIGURE_OPTS="--with-openssl=$(brew --prefix openssl) --with-libxml-dir=$(brew --prefix libxml2)" PHP_BUILD_EXTRA_MAKE_ARGUMENTS=-j4 phpenv install 7.1.0
```

これでOK
performance.measure .mark

### 計測用の関数がある。
https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure

```js
 performance.mark(name+st+slug) //start
 Array.from({length:1000}).reverse();//calc target
 performance.mark(name+end+slug) //end
 performance.measure(
  name+slug
  ,name+st+slug
  ,name+end+slug
 );
```
### 登録したものは performance.getEntries()で取る。フィルターは随意。
```js
 let ret=performance.getEntries().filter(d=>d.entryType==='measure');
```
### clear
```js
 //performance.clearMarks();
 //performance.clearMeasures();
```

### 全部
```js
let fn={};
fn.jptime=(timestamp=Date.now())=>{return new Date(timestamp+1000*60*60*9)
    .toISOString().replace(/-/g,'/').replace('T',' ').slice(0,'YYYY/MM/DD hh:mm:ss'.length)
}
fn.rhash=()=>{return Math.random().toString(36).slice(-8)}
;
let limit=20,c=0
,f=function(){
 let name =fn.jptime(),slug='-'+fn.rhash(8),st='-s',end='-e'
 performance.mark(name+st+slug) //start
 Array.from({length:1000}).reverse();//calc target
 performance.mark(name+end+slug) //end
 performance.measure(
  name+slug
  ,name+st+slug
  ,name+end+slug
 );
}
,fin=function(){
 let ret=performance.getEntries().filter(d=>d.entryType==='measure');
 console.log(ret.length)
 document.body.style.whiteSpace='pre'
 document.body.textContent = JSON.stringify(ret,null,2)
 //performance.clearMarks();
 //performance.clearMeasures();
}
let a=setInterval(()=>{if(c<limit){f();c++;}else{clearInterval(a);fin()} },300)
```

### 追記 関数が長すぎるので短く
```js
,pk=(d)=>{return performance.mark(d)}
,pm=(a,b,c)=>{return performance.measure(a,b,c)}
,pg=()=>{return performance.getEntries()}
```
Azure BLOB Storageで前方一致検索を行う方法（を考慮したコンテナ名・ファイル名の設計）

### こんな人に向けた記事
Azure BLOB Storageを使ってファイルを扱いたいけど検索って出来るの？やったことないので分かりやすいサンプルがあると助かるなーって思っていた人。

### 前提
C#er。Azure SDKがインストールされていること。

## Storageの前方一致検索
### C#メソッド例
```C#
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;
using System;

public static void GetList(string containerName, string prefix)
{
    var _accountName = "your_storage_account_name";
    var _accountKey = "your_storage_account_key";

    var externalStorageCredentials = new StorageCredentials(_accountName, _accountKey);
    var account = new CloudStorageAccount(externalStorageCredentials, true);
    var client = account.CreateCloudBlobClient();
    var container = client.GetContainerReference(containerName);
    container.CreateIfNotExists();

    var blobList = container.ListBlobs(prefix, true);
    foreach (var sourceBlob in blobList)
    {
        // このループ内で好きに処理してください。下記の例はコンソールにファイル名を出力しています。
        if (sourceBlob.GetType() == typeof(CloudBlockBlob))
        {
            CloudBlockBlob blob = (CloudBlockBlob)sourceBlob;
            var filename = blob.Name;

            Console.WriteLine(filename);
        }
    }
}
```

### メソッド呼び出し例
```C#
var containerName = "container1";
var prefix = "folder1/folder2/samp";    //ファイル名の中間一致
//var prefix = "folder1/fol";           //フォルダ名の中間一致でもOK

GetList(containerName, prefix);
```
container1というコンテナに
folder1/folder2/sample1.txt
folder1/folder2/sample2.txt
というファイル名が存在していた場合、この２ファイルの名称が取得できます。

## コンテナ名・ファイル名の設計
本題はこちらのつもりです。先に示した前方一致の検索がある前提を理解しないと、ここからの内容が役に立ちませんので先に実装方式を記載しました。

### コンテナ名を決める
コンテナ名を決めるための理由は、大きく分けて以下があります。

* 一括で消したい場合はコンテナ単位が速い
 * 一定期間で消す必要があるならコンテナ名は年月日で分けるとメリットがある

* パーティションはコンテナ単位
 * 永続的に消さない場合、投入される（若しくは取り出したい）データがばらつくようなIDの場合にメリットがある。IoTであればGatewayId、DeviceId、SensorId等。

ということで、一番ダメな例は「SeonsorData」などの、上記２つのメリットのどちらも享受できない命名となります。

### ファイル名を決める
ファイル名には/が使えますので子フォルダがあるように見えますが、実際は/も文字列として使えるだけのファイル名になります。
先の例で "folder1/folder2/sample1.txt" というファイル名を検索する場合に "folder1/folder2/samp" , "folder1/fol" のどちらでもこのファイルは検索されました。この挙動を踏まえてファイル名を決めます。

* コンテナ名以外で優先される属性がある場合、その属性を利用優先の高い順に並べる

年月日/DeviceId/dataname
DeviceId/年月日時分秒/dataname

など、取得する場合に有利な方を選ぶと良いでしょう。
選択を誤った場合でもParallel.ForEachなどで取ってきてゴニョゴニョすればなんとかなるでしょう。とはいえ処理効率が高くなるように設計段階で考えておくに越したことはありません。
例えばDBも併用しつつ、DB使わなくてもそこそこ検索性能悪くないように作る努力をしましょう。

### まずは試しましょう
サンプルコード書いて、入れたり出したりしつつ、実データがどう格納されたかをAzureポータルから覗いてみましょう。
TypeScript でオブジェクトの 1 プロパティだけを書き換える型安全な関数を定義する

こんな感じ。
[Index Types](http://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types) を使うのがミソ。

```ts
interface User {
    first_name: string;
    last_name: string;
    first_name_kana: string;
    last_name_kana: string;
    birth_year: number;
    birth_month: number;
    birth_day: number;
}

function updateUserProperty<P extends keyof User>(user: User, propName: P, value: User[P]): User {
    return {
        ...user,
        [propName]: value,
    }
}
```

すると、この関数にこんなパラメータを渡すと、型エラーになる。


```ts
const user: User = {
    first_name: '雄也',
    last_name: '竹山',
    first_name_kana: 'Yuya',
    last_name_kana: 'Takeyama',
    birth_year: 1987,
    birth_month: 3,
    birth_day: 19,
};

const updatedUser = updateUserProperty(user, 'birth_year', '1984');
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/208/b18a88e1-8ede-4f34-a00e-a5fb7a84c36b.png)

まぁこれ自体はあまり役に立たないですが、汎用的な Redux Action Creator とかを定義するときに応用できるかも。

## さらなる一般化を試みる、が...

こんな感じにしてみたのですが、

```ts
function updateObjectProperty<T, P extends keyof T>(obj: T, propName: P, value: T[P]): T {
    return {
        ...obj,
        [propName]: value,
    }
}
```

`...obj` のところがエラーになってしまいます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/208/a6e4a5ee-d8a8-f166-e7bb-47acd40d44ab.png)

`T extends object` とかしても解決しないようです。
解決方法わかる方いたら教えてください。
【Kotlin】緯度経度変換器

#はじめに
Exifで取得した緯度経度をGoogleMapApiとかで使いたい時に変換調べるの面倒なのでまとめておきます。

`['35/1', '48/1', '986/100']` みたいな文字列型を `(35 / 1) + (48 / 1 / 60) + (986 / 100 / 3600)` してDouble型で返します。

参考： [画像ファイルのEXIFタグから撮影日時と位置情報を取得する際のTips](https://qiita.com/k-holy/items/b8ca56d8026413dd1878)

#サンプル
```kotlin

fun LngLatConverter(origin:String):Double{
        val origins=origin.split(Regex(","),0)
        val freq=origins[0]
        val freqs=freq.split(Regex("/"),0)
        val min=origins[1]
        val mins=min.split(Regex("/"),0)
        val sec=origins[2]
        val secs=sec.split(Regex("/"),0)

        val reFreq=freqs[0].toDouble()/freqs[1].toDouble()
        val reMin=mins[0].toDouble()/mins[1].toDouble()/60
        val reSec=secs[0].toDouble()/secs[1].toDouble()/3600

        return reFreq+reMin+reSec
    }

```
Vagrant 事始め 01 - Vagrant をインストールする

# Vagrant をダウンロードする前に

Vagrant は Oracle Virtualbox や VMWare 等の仮想環境の構築と共有を簡単に行うためのツールですので、これらのソフトウェアを事前にインストールしておく必要があります。

* [Oracle Virtualbox](http://www.oracle.com/technetwork/server-storage/virtualbox/downloads/)
* [VMware Workstation Player](https://www.vmware.com/jp.html)

# Vagrant をダウンロードする
- [Vagrant 公式サイト (Hashi Corp.)](https://www.vagrantup.com/)
- [Vagrant ダウンロード](https://www.vagrantup.com/downloads.html)

Vagrant は仮想環境を構築・管理するソフトウェアです。
# Vagrant をインストールする
インストーラーから Vagrant をインストールできます。インストール時の設定でインストール先を指定するだけなので、初期設定のままでインストールを進めます。

![2018-04-10_11h52_10.png](https://qiita-image-store.s3.amazonaws.com/0/248967/432c4d2d-f154-cb0f-c25f-660949e1f02a.png)

インストールが完了をしたら、vagrant コマンドを使ってバージョンの確認をしてみます。

```
> vagrant version
Installed Version: 2.0.2
```
- [](https://qiita.com/centipede/items/8ac81accd014d21b83bf)
AI ノウハウ

# GPU
・AWS情報
https://qiita.com/KoronHM/items/24d7f79ea6417ab78621
https://aws.amazon.com/jp/ec2/instance-types/p2/
https://aws.amazon.com/jp/blogs/news/new-p2-instance-type-for-amazon-ec2-up-to-16-gpus/
http://www.nvidia.co.jp/object/tesla-k80-jp.html

# 単語
・K80：すごいGPU
http://www.elsa-jp.co.jp/products/products-top/gpu_computing/tesla_server/tesla_k/tesla_k80/

・TensorFlow（テンソルフロー）：Googleが開発しオープンソースで公開している、機械学習に用いるためのソフトウェアライブラリである。ディープラーニングに対応しており、Googleの各種サービスなどでも広く活用されている。 2017年2月15日に TensorFlow 1.0 がリリースされた。対応プログラミング言語はC言語、C++、Python、Java、Go。 対応OSは64ビットのLinux（ただしバイナリ配布はUbuntu用）、macOS、Windows。ハードウェアは CPU[7]、NVIDIA GPU[7]、Google TPU[8]、Snapdragon Hexagon DSP[9] などに対応していて、Android Neural Networks API 経由で Android 端末のハードウェアアクセラレータも使用できる[10]。



・Keras：Pythonで書かれたオープンソースニューラルネットワークライブラリである

・PyTorch is an open source machine learning library for Python, based on Torch,[1][2][3] used for applications such as natural language processing

・Chainer (チェイナー) :ニューラルネットワークの計算および学習を行うためのオープンソースソフトウェアライブラリである。
Chainerで始めるニューラルネットワーク：
https://qiita.com/icoxfog417/items/96ecaff323434c8d677b
Qiitaの記事がSlackで展開されない理由

Qiitaの記事URLをslackに貼ると、概要を自動で取得してプレビューを表示してくれます。
技術情報を共有する際に便利な機能ですが、中には展開されない記事もあるようです。
同じサイトなのになぜ？と思い、原因を調べてみました。

# 例

以下の記事は展開されます。

https://qiita.com/harunbu/items/8b746e589b7689ce0eb7

![slack_展開.png](https://qiita-image-store.s3.amazonaws.com/0/68159/23aef808-5343-e4b5-3a89-77f56f8d9160.png)

以下の記事は展開されません。

https://qiita.com/harunbu/items/ea0da7b4e4dc294cfaa0

![slack_展開されず.png](https://qiita-image-store.s3.amazonaws.com/0/68159/e60da51a-0254-85d9-0cec-3ec25e174ec2.png)

# 原因（推測）

結論から言うと、**記事の冒頭にHTMLタグが含まれている**と、展開してくれない仕様(バグ？)のようです。

slackにURLを含んだメッセージ送信すると、[HTMLに含まれるmetaタグからOpenGraph情報を取得し](https://get.slack.help/hc/ja/articles/204399343-Slack-%E3%81%A7%E3%83%AA%E3%83%B3%E3%82%AF%E3%82%92%E5%85%B1%E6%9C%89%E3%81%99%E3%82%8B-#%E3%83%AA%E3%83%B3%E3%82%AF%E3%81%8C%E5%B1%95%E9%96%8B%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84%E5%A0%B4%E5%90%88)、プレビューとして表示してくれます。

Qiitaの記事の場合は、

* `<meta content="..." property="og:title">`
* `<meta content="..." property="og:description">`

このへんの内容が展開表示の内容に使われています。

## 展開される記事の`og:description`
```html
<meta content="Laravelにおいて、あるルートはAjaxの場合のみ通したい、
さらにphpunitでAjaxのルートもテストしたい、という状況が発生したため、
その方法を考えてみました。
（確認環境：Laravel5.4）

# Ajaxのみ許可..." property="og:description">
```

markdownとプレーンテキストのみ含まれます。

## 展開されない記事の`og:description`
```html
<meta content="[AmazonSNS](https://aws.amazon.com/jp/sns/)とは、<b>Amazon</b>が提供するPUSH型通知サービスです。

多数のユーザーに対してメールやPUSH通知を送る以外に、
他のAWSサービ..." property="og:description">
```

`<b>`がcontentに含まれています。

## `<meta content="..." property="og:description">`に採用される内容

Qiitaの投稿ページから概要を直接編集することはできません。
では何が概要として採用されるのでしょうか。
以下の記事によれば、
**本文の先頭117文字**が、概要として採用されるとのことでした。
https://qiita.com/suin/items/c2cdf9d51198bfb714b2

# 対策

というわけで、自動展開される記事にするには、
**冒頭117文字にはHTMLタグを使わないようにする**必要がありそうです。

どうしても装飾をしたい場合は、markdownを使いましょう。

続き：[URLがSlackで展開されない理由](https://qiita.com/harunbu/items/be15779f33581d53f74c)
repoを使ってCloud9上にサクッとOpenGrokを立てる。

自分用めも。

## 経緯

[OpenGrok+Dockerで、使い捨てソース検索エンジンをつくる](https://qiita.com/YusukeIwaki/items/3f855202e9c00247d5c7) はDockerで便利〜♪
だったんだけど、Macのストレージが逼迫してしまうので、Cloud9に・・・ってなった結果。

## 用意するもの

* Cloud9環境
* repoのURL (下のcmd例の `https://gist.github.com/d7b049db19fb0286d0ace905a608d562.git` の部分)

## cmd

```
apt-get update
apt-get install -y ant exuberant-ctags tomcat7 unzip || true
mkdir /tmp/opengrok
wget https://github.com/OpenGrok/OpenGrok/files/467358/opengrok-0.12.1.6.tar.gz.zip -O /tmp/opengrok.tar.gz.zip
wget http://jflex.de/release/jflex-1.6.1.tar.gz -O /tmp/jflex.tar.gz
unzip /tmp/opengrok.tar.gz.zip -d /tmp/
tar xzvf /tmp/opengrok-0.12.1.6.tar.gz -C /tmp/opengrok
tar xzvf /tmp/jflex.tar.gz -C /tmp/opengrok
cp /tmp/opengrok/jflex-1.6.1/lib/jflex-1.6.1.jar /tmp/opengrok/opengrok-0.12.1.6/lib/
cp -Rap /tmp/opengrok/opengrok-0.12.1.6/bin /usr/local/
cp -Rap /tmp/opengrok/opengrok-0.12.1.6/lib /usr/local/
mkdir /var/opengrok
mkdir /var/opengrok/etc
mkdir /var/opengrok/data
mkdir /var/opengrok/src
OpenGrok deploy
/etc/init.d/tomcat7 restart || true
wget https://storage.googleapis.com/git-repo-downloads/repo -O /usr/local/bin/repo
chmod 755 /usr/local/bin/repo
git config --global user.name DockerOpenGrok
git config --global user.email docker.opengrok@example.com
wget https://raw.githubusercontent.com/YusukeIwaki/docker-opengrok-repo/master/update_repo.sh -O /usr/local/bin/update_repo
chmod 755 /usr/local/bin/update_repo
REPO_INIT_URL=https://gist.github.com/d7b049db19fb0286d0ace905a608d562.git update_repo
/etc/init.d/tomcat7 restart
```

をrootで実行。

## 注意点

Cloud9ってアクセス制限かけられるとはいえ、わりとみんな見れちゃうので、秘密のソースはおかないように
Laravel@nginxをシンボリックリンク貼りつつサブディレクトリで動かす


# 環境等
試したのはLaravel5.6、nginx1.12
(CentOS7,PHP7.2)

サブディレクトリで動かすのには、多分以下の感じで書けば動くっぽいが、いっぱい書きたくないなー、もっとスマートに書けないのか？というさぼりの気持ちで。
https://qiita.com/saba1024/items/2d50fb8284d699924360

# ディレクトリ構成

メインの処理は/var/www/htmlに置くけど、piyo以下を/home/moge/piyopiyoにあるlaravelを使いたいという場合

```
/var/www/html/
  ├index.html
  ├hoge/
  ├fuga/
  │  └index.html
  └piyo -> /home/moge/piyopiyo/public（シンボリックリンク）

/home/moge/piyopiyo/
  ├public
  │  └index.php
  ├app
  ├config
  ....
```

index.phpから\_\_DIR\_\_とかで上位ディレクトリのファイルを参照しますが、本来の/home/moge/piyopiyo/の方に基づいたパスで動きます。

# nginxのconfを修正

/etc/nginx/conf.d/XXXX.confに記載
追加部分は以下

```nginx
        location /piyo/ {
            try_files /piyo/$uri /piyo/$uri/ /piyo/index.php?q=$uri&$args;
        }
```

全体だとこんな感じ

```nginx
server {
        listen  80;

        server_name miyawa-tarou.com
        root   /var/www/html;
        index  index.html index.php;

        access_log  /var/log/nginx/access.log main;
        error_log   /var/log/nginx/error.log;

        location /piyo/ {
            try_files /piyo/$uri /piyo/$uri/ /piyo/index.php?q=$uri&$args;
        }

        location ~ \.php$ {
            fastcgi_pass unix:/var/run/php-fpm/www.sock;
            include     fastcgi_params;
            fastcgi_index   index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        }
}
```
crowiを引っ越しして切れたリンクをMongoDBから全置換するJavascript

# はじめに
IP 192.168.1.1 で立てたCrowiを、新規に立てた IP 192.168.1.2 にまるっとお引越しした。
引越し後、ページをあれこれ見てみると、Crowi内の記事に飛べないことがある。

どうやらURLを `http://192.168.1.1...` と直接書いているところがいっぱいある。。。Oh...

# やりたいこと
Crowiの記事データが保存されているMongoDBにつなぎ、問題の文字列を全部置換したい。

| 前提 | 今回の対象 |
| --- | --- |
| CrowiDB名 | crowidb |
| 置換元 | 192.168.1.1 |
| 置換先 | 192.168.1.2 |
|対象コレクション|revisions|
|対象フィールド|body|

環境によって読み替えてください。
バックアップなどは自己責任でお願いします。

まとめると、、、
crowidbの記事が入っているコレクション(revisions)の本文要素(body)の対象文字列を全て置換します。

処理は以下の通り

```js:replace_crowi_db.js
// MongoDBのcrowidb中、IPを全置換する

var obj = {};
var rgExp = /192.168.1.1/g;
var replaceText = "192.168.1.2";

db.revisions.find({body:rgExp}).forEach(
function(e){
    if (e.body != null) {
        obj.body = e.body.replace(rgExp, replaceText);
        writeResult = db.revisions.update({"_id":e._id}, { $set : obj } );
        if (writeResult.hasWriteError() || writeResult.hasWriteConcernError()) {
            // 更新エラー
            print("Replace faild : _id = " + e._id );
        }
    }
});
print("置換完了");
```

実行

```bash:Terminal
mongo crowidb --quiet replace_crowi_db.js 
```

# 参考にした記事
- [MongoDBのフィールドの値を一括変換するJavaScript(Qiita)](https://qiita.com/daichi_teranishi/items/dc35e5c7ac1f3946e277)
- [MongoDBのデータ構造な簡単な操作など(Qiita)](https://qiita.com/yuji0602/items/c55e2cb75376fd565b4e)
Docker-composeのキーの意味

docker-composeの書き方を学んでいるところです。
links: containerA　みたいな記述の意味をメモとしてまとめておこうと思います。

- image:
    - イメージ名。そのまんま
- build: 
    - ビルドの際に使うDockerfileのパス
- env_file:
    - 環境変数などを書いておくファイルのパス
- expose:
    - 他のコンテナに開放しておくポート番号
- links:
    - コンテナAの設定に　links: container_B　と書けば、container_Bが立ち上がるのを待ってからcontainer_Aを起動する
    - さらに、container_Bのホスト一覧にcontainer_Aを登録する。俺の名を刻め！ということである
- volumes
    - ホスト側のディレクトリをコンテナ内にマウントする際の設定
- command
    - コンテナが起動してから実行するコマンド
- restart
    - コンテナが停止しているときの再起動設定　restart: alwaysとかけばdocker-machineが立ち上がった時勝手にコンテナを起動してくれる
- volumes_from:
    - volumes_from: container_B　とすれば、container_Bのマウント設定を読み込む
finallyオペレータを含むObservableのテストを書く

# やりたいこと

こんな感じのコードがあった。

```javascript:wantToDo.js
// DB操作を伴うとかそういう系のイメージ

const Observable = require("rxjs/Rx").Observable;
const { map, finalize, catchError } = require("rxjs/operators");

function foo (val) {
  console.log("foo!");
  return val;
}

// connection closeは常にしたいとか
function teardown () {
  console.log("teardown!");
}

// エラーが起きたときだけrollbackしたいだとか
function whenError(err) {
  console.log("some process...");
  throw err;
}

function wantToDo () {
  return Observable.from([1, 2, 3]).pipe(
    finalize(() => teardown()),
    map((val) => foo(val)),
    catchError((err) => whenError(err)),
  );
}

module.exports = { 
  wantToDo,
  foo,
  teardown,
  whenError,
};

```

```javascript:index.js
wantToDo().subscribe((val) => console.log("some logic..."));
```

wantTodo()関数に対してこんな項目をテストしたくなった。

* 正常系で、最後にteardownが呼ばれたか。
* 異常系でも、最後にteardownが呼ばれたか。
* 異常系のときは、whenErrorも呼ばれたか。

# とりあえずテスト書いてみる。

こんなん書きました。

```javascript:spec.js
it("should call teardown", () => {
  // arrange
  sinon.spy(teardown); // 多分これじゃ動かないけど、teardownをスパイしたとして。

  // act & assert
  wantToDo().subscribe(
    (val) => {},
    (err) => expect.fail(),
    () => expect(teardown.called).to.be.true,  // コケる...
  );
});
```

ハマりました。
rxjs/operatorsのfinalizeについて説明を見ると、こう書いてました。

> Returns an Observable that mirrors the source Observable, but will call a specified function when the source terminates on complete or error.
> ([RxJS API Document](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-finalize))

finalizeに書いたものは、Subscriptionが**completeもしくはerrorで閉じた後**に実行されるんですね。

# 書き直し。

これでちゃんとテストできました。

```javascript:spec.js
it("should call teardown", () => {
  // ...

  // act & assert
  wantToDo().subscribe(
    (val) => {},
    (err) => expect.fail(),
  ).add(() => expect(teardown.called).to.be.true);
```

Subscription.add()に書いたteardownメソッドは、finalizeに書いたものよりも後に実行されるようです。

# でも問題もあって…。

テストが成功している間は大丈夫でした。
問題はコードを修正してテストが失敗したとき。

`mocha -r -w`とかで起動してさぁ修正…と思ったら。
テストに失敗したときにmochaのプロセスが落ちることがあるんですよね。
テスト起動し直すのめんどくせ…ってなりつつ、まだ解決策が見つかってません。
もし知ってる方がいれば教えてください。
SVN「database disk image is malformed」エラーの対処法

svn update したときに

```bash
svn: E200030: sqlite[S11]: database disk image is malformed
svn: E200042: Additional errors:
svn: E200030: sqlite[S11]: database disk image is malformed
```

というエラーが出たとき。
wc.dbというデータベースファイルが破損しているので、修復する。

```bash
$ cd .svn
$ file wc.db

wc.db: SQLite 3.x database, user version 31
```

user versionをメモしておく。

```bash
$ cp wc.db wc.db.org
$ sqlite3 wc.db .dump | sqlite3 wc_new.db
$ sqlite3 wc_new.db

sqlite> PRAGMA user_version = 31;
sqlite> PRAGMA user_version;
31
sqlite> .exit

$ mv wc_new.db wc.db
```

これで修復される。
user_versionをセットしないとsvn upで今度は「assertion failed (format >= 1)」というエラーが出るようになるので注意。
rundeckのhttps化

## 概要
httpで稼働していたrundeckをhttps化した際のメモを残します。

## 環境
* Rundeck 2.9.2-1
* Client -> ALB(443) -> rundeck(4440)
* rundeckはec2で稼働
* 証明書はACMで取得


## 変更内容
### /etc/rundeck/rundeck-config.propertiesの修正
http → httpsに修正

```
# before
grails.serverURL= http://rundeck.hogehoge.jp
```

```
# after
grails.serverURL= https://rundeck.hogehoge.jp
```
### /etc/rundeck/profileの修正
`-Drundeck.jetty.connector.forwarded=true`を追加

```
# before
RDECK_JVM="-Djava.security.auth.login.config=$JAAS_CONF \
           -Dloginmodule.name=$LOGIN_MODULE \
           -Drdeck.config=$RDECK_CONFIG \
           -Drundeck.server.configDir=$RDECK_SERVER_CONFIG \
           -Dserver.datastore.path=$RDECK_SERVER_DATA/rundeck \
           -Drundeck.server.serverDir=$RDECK_INSTALL \
           -Drdeck.projects=$RDECK_PROJECTS \
           -Drdeck.runlogs=$RUNDECK_LOGDIR \
           -Drundeck.config.location=$RDECK_CONFIG_FILE \
           -Djava.io.tmpdir=$RUNDECK_TEMPDIR \
           -Drundeck.server.workDir=$RUNDECK_WORKDIR \
           -Dserver.http.port=$RDECK_HTTP_PORT"
```

```
# after
RDECK_JVM="-Djava.security.auth.login.config=$JAAS_CONF \
           -Dloginmodule.name=$LOGIN_MODULE \
           -Drdeck.config=$RDECK_CONFIG \
           -Drundeck.server.configDir=$RDECK_SERVER_CONFIG \
           -Dserver.datastore.path=$RDECK_SERVER_DATA/rundeck \
           -Drundeck.server.serverDir=$RDECK_INSTALL \
           -Drdeck.projects=$RDECK_PROJECTS \
           -Drdeck.runlogs=$RUNDECK_LOGDIR \
           -Drundeck.config.location=$RDECK_CONFIG_FILE \
           -Djava.io.tmpdir=$RUNDECK_TEMPDIR \
           -Drundeck.server.workDir=$RUNDECK_WORKDIR \
           -Dserver.http.port=$RDECK_HTTP_PORT \
           -Drundeck.jetty.connector.forwarded=true"
```

## 参考情報
https://github.com/rundeck/rundeck/wiki/FAQ#can-i-do-ssl-offloading
NutanixのPower Systems版でVM準備

前回 [NutanixのPower版をさわってみた](https://qiita.com/tom_m_m/items/8fcf0b20c62924e513af) では、NutanixのPower版 CS821をPrismで操作してみました。

早速、Nutanix上で仮想マシンを作成したいところですが、その前の準備を行います。

#NutanixにVM作成･･･の前に
- ISOイメージの登録
- ネットワークの設定
- ストレージコンテナの設定
この3つの作業が必要です。

##ISOイメージの登録
LinuxをVMにインストールするためには、ISOイメージが必要です。
そのイメージをマシン上に置かなければいけません。

Prismの上部に歯車アイコンがあるため、そこをクリック。
メニューの中に "イメージ管理" という項目があるのでクリック。
![スクリーンショット 2018-03-23 12.51.00のコピー.png](https://qiita-image-store.s3.amazonaws.com/0/242652/bdd17e24-4755-c28b-cf45-b94b6e0b0223.png)

イメージ管理用のポップアップが表示されます。
![スクリーンショット 2018-03-23 12.48.57.png](https://qiita-image-store.s3.amazonaws.com/0/242652/9ad1d45d-7dc0-d77e-b8a9-0349a6115386.png)
名前を入力し、ISOを置くコンテナを選びます。

イメージのアップロードは、URLによる指定かローカルからのアップロードが選択できます。
URLを入力するだけで、自動でダウンロードしてくれます。
ものすごく楽ですね。
USBに書き込んだりしなくて良いんです、コマンドで登録することもないんです。

##ネットワークの設定
次に、ネットワーク設定を行います。
スクリーンショットでは、IPアドレスを"192.168.10.0"とし、サブネットマスクを"255.255.255.0"として設定しています。
![スクリーンショット 2018-03-23 13.03.14.png](https://qiita-image-store.s3.amazonaws.com/0/242652/ba603409-f705-59c0-e273-6cd6c34fca49.png)

ネットワーク設定用のポップアップは、スクロールすると下のような画面が表示されます。
![スクリーンショット 2018-03-23 13.03.47.png](https://qiita-image-store.s3.amazonaws.com/0/242652/2951ee83-7ac6-1669-eeab-bff26e5fcbfa.png)
各自の環境に合わせて、DNSサーバーや、IP Address poolsの設定を行います。

IP Address poolsを設定しておくと、VMを複数作成する際に便利です。

##ストレージコンテナの作成
最後に、ストレージコンテナを作成します。
ストレージコンテナは、ストレージ設定画面の右上に配置されているボタンから作成できます。
![スクリーンショット 2018-03-14 10.06.17.png](https://qiita-image-store.s3.amazonaws.com/0/242652/49ae34e1-85d0-c581-5eea-bd6ae6fb2527.png)

この画像の青枠で囲われた部分です。
このボタンをクリックすると下のようなポップアップが表示されます。

![スクリーンショット 2018-03-23 14.29.40.png](https://qiita-image-store.s3.amazonaws.com/0/242652/ae168b33-989c-6cc9-e4ee-dff6cf6a97b4.png)

コンテナは、ポップアップ上でコンテナ名を入力するだけで作成できます。
Advanced Settingsから、容量の予約や圧縮などの設定も行うことができます。

![スクリーンショット 2018-03-23 14.30.10.png](https://qiita-image-store.s3.amazonaws.com/0/242652/18a9daeb-e81d-8af3-56d0-8293b9819d3b.png)

![スクリーンショット 2018-03-23 14.30.39.png](https://qiita-image-store.s3.amazonaws.com/0/242652/544c27ce-b1ea-3571-2dbd-fddffaffcf07.png)

Nutanixの特徴である、Replication Factor(RF)もここで変更できます。

- ISOの準備
- ネットワークの設定
- ストレージコンテナの作成
この3つが完了すると、VMを作成する準備が整います。

#次回
今回は、VM作成までの準備を行いましたので、次回はVMの作成から起動までを書きます。
terraform-provider-awsでTERRAFORM CRASH

# 概要
それは突然やってきた。

```
!!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!!

Terraform crashed! This is always indicative of a bug within Terraform.
A crash log has been placed at "crash.log" relative to your current
working directory. It would be immensely helpful if you could please
report the crash with Terraform[1] so that we can fix this.

When reporting bugs, please include your terraform version. That
information is available on the first line of crash.log. You can also
get it by running 'terraform --version' on the command line.

[1]: https://github.com/hashicorp/terraform/issues

!!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!!
```

半日ほど時間をかけてようやく解決したのでシェア。

# 環境
* `terraform-provider-aws 1.9.0`

# 対策
* `terrform init`を使用して`terraform-provider-aws`を`1.13.0`以降にupdateで解消します。

# 注意
当たり前ですが、以下のようにバージョニングを固定しているアップデートされないので注意

```
provider "aws" {
  version = "~> 1.9.0"	
  region  = "ap-northeast-1"
}
```

# 参考
https://github.com/terraform-providers/terraform-provider-aws/blob/master/CHANGELOG.md#1130-march-28-2018
https://github.com/terraform-providers/terraform-provider-aws/pull/3954
ElectronでMacのデスクトップアプリ作成


Webの知識は少しあるので，ElectronでWebのコードからMac用のアプリを作成します．

手始めにこんな感じのものを作ります．

![electron.png](https://qiita-image-store.s3.amazonaws.com/0/152224/ee410b9b-a3a1-26b2-40da-8afd5de0cd70.png "electron.png")


# 環境構築
## Node.js
Electronのバックエンド処理にはNode.jsが使われています．

この辺りを参考にしてください．

Windows:　[Node.js / npmをインストールする(for Windows)](https://qiita.com/taiponrock/items/9001ae194571feb63a5e)  
Mac:　[Macにnode.jsをインストールする手順](https://qiita.com/akakuro43/items/600e7e4695588ab2958d)  
Ubuntu: [Ubuntuに最新のNode.jsを難なくインストールする](https://qiita.com/seibe/items/36cef7df85fe2cefa3ea)  


# アプリ作成
## プロジェクト作成
Electronのアプリプロジェクトを作成します．  
最初のディレクトリ構成は以下のように

```ディレクトリ構成
PythonApp
┠- src/  (ソースコードを置くディレクトリ)
```

## プロジェクトの初期化
npmによってプロジェクトの初期化を行います．  
`package.json`が生成されます

```Command
$ cd PythonApp
$ npm init
$ npm i -D electron
```

```ディレクトリ構成
PythonApp
┠- src/  (ソースコードを置くディレクトリ)
|    ┠- package.json (プロジェクト情報)
┠- package.json (プロジェクト情報)
┠- package-lock.json (プロジェクトのLockファイル)
┠- node_modules/ (npmでインストールしたライブラリ群)
```

## アプリケーションの実装
`src/`内にアプリケーションのソースを置きます．  
必要なのは，以下の3つ
* package.json
* index.js
* index.html

### package.json
必要なファイルです．`main`のファイルはエントリーポイントになるファイル名を指定しています．

```jsonjs
{
  "name": "src",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```

### index.js
エントリーポイントとなるJSファイル．  
アプリの処理はここから，実行される．  

```js
// Electronの読み込み
var electron = require('electron');
var app = electron.app;
var BrowserWindow = electron.BrowserWindow;

// mainWindow変数の初期化
var mainWindow = null;

// MacOS(darwin)でない場合にはアプリを終了する
app.on('window-all-closed', function() {
  if(process.platform != 'darwin')
  app.quit();
});

// 画面を表示．index.htmlを読み込む
// Close処理を行う
app.on('ready', function() {
  // 画面表示
  mainWindow = new BrowserWindow({width: 800, height: 600});
  mainWindow.loadURL('file://' + __dirname + '/index.html');

  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});
```

### index.html
メインウィンドウとして動くHTMLファイル  

```html
<!DOCTYPE html>
<html lang="ja" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Electron Read us</title>
  </head>
  <body>
    <h1>Hello, electron!</h1>
  </body>
</html>
```

アプリケーションは以上です．  
ディレクトリ構成の確認です．

```ディレクトリ構成
PythonApp
┠- src/  (ソースコードを置くディレクトリ)
|    ┠- package.json (プロジェクト情報)
|    ┠- index.html (メインウィンドウ)
|    ┠- index.js (エントリーポイント)
|    
┠- package.json (プロジェクト情報)
┠- package-lock.json (プロジェクトのLockファイル)
┠- node_modules/ (npmでインストールしたライブラリ群)
```

# アプリケーションの実行
プロジェクトディレクトリ(`PythonApp`)で以下のコマンドを実行すると，アプリが実行できる

```bash
$ npx electron src
```

# アプリケーションのパッケージ化
今はソースコードなので，アプリケーションとしてパッケージ化します  

## Mac

```bash
npx electron-packager src PythonApp --platform=darwin --arch=x64 --overwrite
```

## Windows

```bash
npx electron-packager src PythonApp --platform=win32 --arch=x64 --overwrite
```

# Source Code
https://github.com/sasayabaku/electron_training/tree/master/PythonApp

# 参考文献
[最新版で学ぶElectron入門 - HTML5でPCアプリを開発する利点と手順 - ICS MEDIA](https://ics.media/entry/7298)
EclipseにTomcatプラグインをインストールする

Eclipseの設定が壊れて作り直したときに積んだのでメモ。
Tomcatプラグインをインストールする方法が変わったのか、自分の環境のせいなのか知らないけどググった情報が当てにならなかったので書いておきます。

### 一応環境
- OS X 10.11.6
- Eclipse Oxygen (4.7.3)

---


会社にあった手順書とネットの情報を見ても、「https://sourceforge.net/projects/tomcatplugin/files/
からプラグインをダウンロードして.zipを選択」
って書いてあるのにダウンロードできるのがzipじゃない。zipに圧縮してもインストールできない。

で、色々調べてたら上記リンクからダウンロードではなくて、
<strong>
1. Eclipseの Help を開く
2. Eclipse Marketplace 選択
3. Find に"tomcat"と入れて検索
4. Eclipse Tomcat Plugin [バージョン] をインストール
</strong>
これでできました。

そのあとEclipseを再起動するとEclipse > 環境設定 にTomcatの項目が追加されます。
バージョンは3.3から9.xまで入っていたのでこれで大抵の場合は問題ないかと思われます。

しょーもないことなんだけど、毎回この手順でググって積んでいる気がする……。
Cognos Analyticsのバージョンアップ時、preserver.txtに記載のない自作ファイルは削除されるので注意が必要

#はじめに
Cognos Analytics 11.0.6 からバージョンアップする前にpreserver.txtにファイルを追記しておくことで、カスタムファイルや自作ファイルを引き継ぐことができるようになっています。

※下記記事にもまとまっています。
[Cognos Analyticsのバージョンアップ時のカスタムファイルの扱い](https://qiita.com/shinyama/items/192bb868889106f1d663)


で、Cognos Analyticsは上書きインストールなので、サーバーモジュールに含まれない自作ファイルや日付入りのバックアップファイルなんかはどうせ残るだろうと思っている方がおられましたら要注意です。
実際にはpreserver.txtに記載の無い自作ファイルに関しても問答無用で削除される動きとなることをご紹介します。

#実機での動作

##事前確認
今回の注目ファイルは事前に手動でバックアップを取得しておいた「xqe.diagnosticlogging.xml.20171021」になります。



![001.jpg](https://qiita-image-store.s3.amazonaws.com/0/146283/749c4cc3-44fe-5107-73ef-4cc528c310f2.jpeg)


##事前準備
バージョンアップ前にpreserver.txtの編集をします。
ここでは、編集済みの「xqe.diagnosticlogging.xml」のみを追記しています。

![002.jpg](https://qiita-image-store.s3.amazonaws.com/0/146283/734e22fe-696b-bff8-b6e3-2c8095f29179.jpeg)

##バージョンアップ実施
Cognos Analyticsのバージョンアップを実施します
この環境では、「CA 11.0.6」 → 「CA11.0.9」にバージョンアップしました

##バージョンアップ後確認
バージョンアップ完了後の「<CA_instdir>/configutation」フォルダの状態が下図になります。
preserver.txtに記載したファイルは古いタイムスタンプでファイルが保持されているのが確認できますが、
事前にバックアップとして取得していたファイルがものの見事に消えています。
サーバーモジュールに含まれるはずのない日付入りのファイルなのにです。。
![003.jpg](https://qiita-image-store.s3.amazonaws.com/0/146283/c340b89f-cf73-ff07-39b5-3360e2660665.jpeg)



#最後に
バージョンアップの際の上書きインストールと言っていますが、
単純に今あるフォルダに対してファイルを上書きするようなインストールではなさそうです。
preserver.txtに記載のあるファイルを一時フォルダに退避した後、ディレクトリごと削除 → 新バージョンをインストール → 退避ファイルの復元、と言った処理をしているように見られます。

くれぐれも自作ファイル、カスタムファイルがある環境でバージョンアップを実施する際は十分気をつけましょう。
Vagrant+CentOS7.4 httpd自動起動に失敗する

httpdのドキュメントルートを共有フォルダ(synced_folder)に設定していると、httpdの起動時にフォルダが存在しなくて、Vagrant起動時にhttpdの起動に失敗する時があります

そんな時は、こんなエラーが出でます
（/vagrant/wwwがドキュメントルート）

```
# sudo systemctl status httpd.service
... 省略 ...
Apr 10 02:33:55 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
Apr 10 02:33:56 localhost.localdomain httpd[915]: AH00526: Syntax error on line 120 of /etc/httpd/conf/httpd.conf:
Apr 10 02:33:56 localhost.localdomain httpd[915]: DocumentRoot '/vagrant/www' is not a directory, or is not readable
Apr 10 02:33:56 localhost.localdomain systemd[1]: httpd.service: main process exited, code=exited, status=1/FAILURE
... 省略 ...
```

# 解決法

httpdの自動起動を止めて、vagrant up時にhttpd起動コマンドを実行します

## httpdの自動起動を停止
```
# sudo systemctl disable httpd.service
```

## vagrant up時にhttpdを起動
Vagrantfileの最後のendの前に、起動用のスクリプトを追加

```:Vagrantfile
  config.vm.provision "shell", run: "always", :inline => <<-COMMAND
     sudo systemctl start httpd.service
  COMMAND

end # ファイル最後のend
```

余談：
複数コマンドを実行したい場合などは、シェルファイルを実行すると便利

```:Vagrantfile
  config.vm.provision "shell", run: "always", :path => "./startup.sh"

end # ファイル最後のend
```

```../startup.sh
sudo systemctl start httpd.service
```
OpenPose - コマンド一覧

## **主なオプション**
- `--help`: 全てのコマンドオプションを表示
- `--face`: 顔検出を有効にする
- `--hand`: 手検出を有効にする
- `--video input.mp4`: 動画の読み込み
- `--camera 3`: Webカメラ番号を指定(複数カメラがある場合)
- `--image_dir path_to_images\`: 静止画像フォルダを指定
- `--ip_camera http://iris.not.iac.es/axis-cgi/mjpg/video.cgi?resolution=320x240?x.mjpeg`: IPカメラを使用
- `--write_video path.avi`: 動画出力
- `--write_images folder_path`: 静止画出力
- `--write_keypoint path\`: JSON, XML or YMLファイル出力
- `--write_json path\`: JSON形式でファイル出力
- `--part_candidates`: JSON形式のフォーマットをパーツ番号とともに出力する
- `--process_real_time`: 動画像ファイルのリアルタイム処理
- `--disable_blending`: keypoint skeltonsまたはheatmapのみを表示
- `--part_to_show`: 指定したパーツのみ表示 [パーツ]()
- `--display 0`: 結果表示しない(若干速度向上)
- `--num_gpu 2 --num_gpu_start 1`: GPU数の指定(デフォルトは全部使用)
- `--model_pose MPI`: 使用するモデルを指定
- `--logging_level 3`: Debug用ログ出力(0:全部, 1-4:レベル, 255:なし)

## **レイテンシ/ラグを低減したい**
- `--output_resolution`: 解像度を落とすとFPS向上，精度は低下．
- `--net_resolution`: 解像度を落とすとFPS向上，精度は低下．
- `--face_net_resolution`: 解像度を落とすとFPS向上，精度は低下．
- `--hand_net_resolution`: 解像度を落とすとFPS向上，精度は低下．
- `--disable_multi_thread`: 有効にするとレイテンシは低下，速度も低下 (bodyにのみ効果あり)

## **データ出力したい(JSON形式)**
- `--write_json`を指定
- `output\`のようにoutputフォルダを指定
- `--part_candidates`: JSON形式のフォーマットをパーツ番号とともに出力する
- `--display 0`を指定すると表示なし
- `--render_pose 0`を指定を指定すると表示なし
Angularの開発用ローカルサーバーにスマホでアクセスする

メモがてら、方法だけ書いておきます。

#他のデバイスからアクセス可能なローカルサーバーを立ち上げる

ターミナルから

```
ng serve --open
```

とする代わりに、

```
ng serve --host 0.0.0.0
```

とすると、同じネットワーク内の他のデバイスからアクセス可能なローカルサーバーが立ち上がります。

この時、

```
open your browser on http://localhost:4200/
```

のような表示がでるので、この`4200`というポート番号を覚えておきます。

#ローカルIPを調べる

Macなら、Network Utilityを開き、infoタブに移動し、プルダウンからWi-Fiを選べば、IP Adressという項目があります。

(Wi-Fi以外の方法でネットワークに繋いでいるなら、適宜それを選ぶ)

またはターミナルからifconfigを使ってもわかりますが、正直読みにくいです。

Windowsならコマンドプロンプトからipconfigですかね。

#スマホからアクセスする

スマホを、ローカルサーバーを立ち上げてるPCと同じネットワークに繋ぎます。

Wi-Fiなら同じWi-Fiに繋げば良いです。

ブラウザを開き、アドレスバーに、

先ほど調べたIPアドレスの後ろに、`:`を挟んでポート番号をつけて

```
http://192.168.11.1:4200
```

のような感じで入力すれば、アクセスできます。


`localhost`と書いてあった部分を、IPアドレスで置き換えたわけです。

最近のスマホのブラウザなら、`http://`は省略していいと思います。


以上です。

#参考リンク

https://stackoverflow.com/questions/39069742/how-to-test-an-app-created-with-angular-cli-ng-serve-from-another-device

https://github.com/angular/angular-cli/pull/1475#issuecomment-235986121