OmniAICreator/Qiita-1.07M huggingface dataset:
【初心者向け】PHPマスター講座 vol.3（代数演算子を学ぼう）

みなさんこんにちは！けいです

今回は「代数演算子」について解説します！！

#【PHPマスター講座】演算子とは

===========================

▶︎演算子（えんざんし）とは何か🐼？

>ひとつ以上の値 (あるいはプログラミング用語における「式」) から別の値 (制御構造が式になるように) を生み出すもの(引用先：PHPマニュアル)

見てもらうとわかるように…

マニュアルは「これでもか！」ってくらい
簡単な内容を複雑に書く天才なので

今回は演算子の中でも
初心者が一番初めに学んでおくべき

【代数演算子】について
一つずつ丁寧に解説していきます！

---------------------------------

###▶︎【代数演算子の「6つの種類」】🐼
・「+」:「足し算」
・「-」:「引き算」
・「*」:「掛け算」
・「/」:「割り算」
・「%」:「剰余算」
・「***」:「累乗」

---------------------------------

代数演算子って言葉は難しそうですが
基本的には上記「6つの種類」しかありません！

なんだかホッと、安心できますよね〜

===========================

###▶︎代数演算子を実践で学ぼう🐼（基礎編）

`<?php`

`//足し算(「+」を使います)
echo 100+50;
echo "<br>";`

`//引き算(「-」を使います)
echo 100-50;;
echo "<br>";`

`//掛け算(「*」を使います)
echo 100*50;;
echo "<br>";`

`//割り算(「/」を使います)
echo 100/50;;
echo "<br>";`

`//剰余算(「%」を使います)
echo 100%50;;
echo "<br>";`

`//累乗(「**」を使います)
echo 10**2;
echo "<br>";`

`?>`

===========================

###▶︎【表示結果】
150  //【足し算】（100+50）
50   //【引き算】（100-50）
5000 //【掛け算】（100*50）
2    //【割り算】（100/50）
50   //【剰余算】（100%50）
100   //【累乗】 （10**2）`

===========================

###💡ポイント💡

・掛け算について
**▶︎プログラミングだと
「×」の代わりに「*」を使います！**

・引数（パラメーター）の書き方について
**▶︎print(1+1);と書くと、表示結果は「2」**
**▶︎print('1+1');と書くと、表示結果は「1+1」**

※引数の両端にクオテーション（''）がないと
**「計算式」**として扱われます！

※引数の両端にクオテーション（''）があると
**「文字列」**として扱われます！

===========================

###▶︎代数演算子を実践で学ぼう🐼（応用編）

【補足】
前回執筆したVol.2の「[変数を学ぼう](https://qiita.com/life_is/items/4576e89f2a495050117a)」をベースに「変数」を使って実践的に学んでいきましょう！

※「変数」の理解がまだ不安な人は、リンク先に飛んで確認お願いします！

`<?php`

//変数を「3種類」セット（x,y,z）
`$x = 2;`
`$y = 3;`
`$z = 4;`

`//足し算と変数のセット
echo $x + $y; 
echo "<br>";`

`//引き算と変数のセット
echo $z - $x;
echo "<br>";`

`//掛け算・足し算と変数のセット
echo $x *($y+$z);
echo "<br>";`

`//割り算・引き算と変数のセット
echo $x /($y-$z);
echo "<br>";`

`//掛け算・剰余算と変数のセット
echo $x *($y%$z);
echo "<br>";`

`//累乗・足し算と変数のセット
echo $x **($x+$y);
echo "<br>";`
`?>`

===========================

###▶︎【表示結果】
`//足し算と変数のセット(2+3)
5`

`//引き算と変数のセット(4-2)
2`

`//掛け算・足し算と変数のセット(4+3)*2
14`

`//割り算・引き算と変数のセット(4-3)/2
-2`

`//掛け算・剰余算と変数のセット(3%4)*2
6`

`//累乗・足し算と変数のセット(2+3)**2
32`

===========================

さて、今回のPHPマスター講座 vol3（代数演算子を学ぼう）はここまでとなります！

少しでもあなたのPHP学習のお役に立てれば幸いです😌
Amazon Linux2でkubelet、kubeadm、kubectlのインストール可能なバージョンを調べる方法

Amazon Linux2

# 準備

```sh
sudo sh -c "cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=0
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
"
```
# バージョン確認

```
# kubeletのインストール可能バージョン確認
# 対象バージョンだけで確認する場合は末尾に
#「 | grep x.xx」」(x.xxはバージョン)を指定
yum --disableexcludes kubernetes --showduplicates list kubelet

# kubeadmのインストール可能バージョン確認
# 対象バージョンだけで確認する場合は末尾に
#「 | grep x.xx」」(x.xxはバージョン)を指定
yum --disableexcludes kubernetes --showduplicates list kubeadm

# kubectlのインストール可能バージョン確認
# 対象バージョンだけで確認する場合は末尾に
#「 | grep x.xx」」(x.xxはバージョン)を指定
yum --disableexcludes kubernetes --showduplicates list kubectl
```

# kubelet、kubeadm、kubectl インストール

```
# kubelet 1.18.0、kubeadm 1.18.0、kubectl 1.18.0を
# インストールする場合
sudo yum install -y kubelet-1.18.0-0.x86_64 kubeadm-1.18.0-0.x86_64 kubectl-1.18.0-0.x86_64 --disableexcludes=kubernetes
```
Ubuntu18.04のGPUマシンでCOVID-19に立ち向かう方法(Folding@home)

# はじめに
本日(3月30日)、新型コロナウイルスによる症状悪化のため、タレントの志村けんさんが亡くなられました。ご冥福をお祈りいたします。

この件を受けて、現在の私に何かできることはないかと思い、つい3日ほど前から行っているあるプロジェクトへの参加方法についてメモ書きでもいいから共有すべきだと考え、現在執筆をしている所であります。参加しているプロジェクトというのはFolding@homeというもので、元々はタンパク質構造解析のための分散コンピューティングプロジェクトです。ここで得られた成果はがんやアルツハイマー病などの様々な治療に役立てることを目的としていて、現在はCOVID-19のための解析プロジェクトが行われています。

もし、お手元に少しでも余裕のあるPCをお持ちでしたらぜひご参加いただきたいのですが、この参加方法自体はとても簡単です。今回はUbuntu18.04のGPUマシンなどに対象を絞って説明させていただきます。また、SNSを利用している方でしたらぜひ周りのご友人や知人の方にご紹介いただけたら幸いです。

# Folding@homeの導入方法
ここからは早速インストール方法に入っていきます。ここでやることは主に2つです。
* 公式サイトから3つのインストールファイルをダウンロードする。
* ターミナルでダウンロードした3つのファイルを使ってインストールする。

## PCスペック
どんな方のPCでも動かすことはできますが、一応私の環境について載せておきます。詳しい対応環境については公式に問い合わせるのが一番早いと思います。

* OS : Ubuntu 18.04 64-bit
* CPU : intel Xeon E5-1650 v4
* GPU : GTX 1080ti x2
* RAM : 64 GB

## Folding@homeのダウンロード
まず公式サイトのダウンロードページに行きます。
ページリンクは↓
[Folding@home](https://foldingathome.org/alternative-downloads/)

そしたら、サイト中央あたりの`Debian / Mint / Ubuntu`と書かれている項目の下にある

    fahclient_7.5.1_amd64.deb
    fahcontrol_7.5.1-1_all.deb
    fahviewer_7.5.1_amd64.deb

の３つをそれぞれクリックしてダウンロードしてください。バージョン名はその時ごとに変わると思いますので、合うものを選んでください。

## Folding@homeのインストール
ターミナルを開き、ダウンロードしたファイルがあるディレクトリに飛んでから、

    $ sudo dpkg -i fahclient_7.5.1_amd64.deb
    $ sudo dpkg -i fahcontrol_7.5.1-1_all.deb
    $ sudo dpkg -i fahviewer_7.5.1_amd64.deb

を打ち込んでインストールします。途中でIDとチーム名、passkeyを入力する所がありますが、IDは匿名でも自分のSNSの名前でも構いません。チーム所属ももちろん無所属でも構いませんが、日本人が多く集まっているコミュニティとしてASRockManiaさんというPCパーツ屋さんであるASRockが開いているチームがあります。自分もそこに所属していますが、もし入りたい方はチームの項目に`252872`と入力してください。passkeyの設定は未設定のままで大丈夫です。ここはあとから設定し直すこともできるので飛ばしても全然大丈夫です。

ここまででもう既にFolding@homeへの参加は出来ています。あとはうまく動かないという人向けの設定方法を書いていきます

## Folding@homeの設定(FAHControlの設定)
さて、インストールが無事に済んだらあとはコントロールウインドウを開いて設定するだけです。インストールが済んだ時点で既に動いているものもあるとは思いますが、ここでproxyやGPUの設定が必要な人が多いと思います。それについて書いていきます。

まず、ターミナルを開いて

    $ FAHControl

と打ち込んでFAHControlを開きます。すると、現在の実行環境が表示されます。この画面の右上にある`Configure`を開くと設定画面が出てきます。

### GPUスロットの追加
まず、初期状態ではCPUのみがスロットに登録されているため、GPUなどはこの設定画面で追加する必要があります。設定画面の`Slots`タブを開いてFolding slotsの枠の下部にある追加を押します。すると、追加でCPUとGPUを追加できる画面が出てきますので、この画面のGPU側のチェックボタンを押して、あとはいじらずにOKを押してください。GPUが2枚の人はもう一度追加を押して同じようにGPUを追加してください。
設定が終わったら保存を押してください。

### Proxyの設定
もし、ファイアウォールなどのセキュリティがある環境下の人ではプロキシを通さないといけないという場合では設定画面の`Proxy`タブを開いてチェックボタンを押してチェックを付け、IPアドレスとポート番号をこちらに入力してください。
こちらも設定が終わったら保存を押してください。

### アカウントのパスワードの設定
ここまでの設定が行われていれば既にうまく実行ができていると思いますが、それでもうまくつながらないということが起きた場合には設定画面の`Connection`タブにあるPasswordの設定をしないといけないかもしれません。ここのパスワードには今使っているUbuntuアカウントのログインパスワードを入力してください。あとは保存を押して画面を閉じます。

## Folding@homeの再起動
ここまで色んな設定をしているので一度Folding@homeを再起動して設定が反映されているかどうかを確認してみてください。再起動は下記の

```
$ sudo /etc/init.d/FAHClient stop
$ sudo /etc/init.d/FAHClient start
```

を打って実行すれば行えます。

# おわりに
Folding@homeの導入方法について書いてきました。基本的にFolding@homeは起動しておいてあとは勝手にやってくれるため、自分から特に触るものがなくとても簡単に参加ができます。参加者が多くなればそのぶん計算できる量が増えて、多くの人を救うために必要な時間も短縮できます。冒頭でも伝えましたが、もしご友人の方でPCをお持ちの方がいればUbuntu以外でもFolding@homeへの参加は可能なので、情報の共有の程よろしくお願い致します。何か追加情報が欲しい、あるいは間違っている部分がある場合はご指摘などをコメントでくださると幸いです。

新型コロナウイルスによる感染者を一人でも多く救われますよう心から願っています。
【ACE】Billing 

# こんにちは
このガイドにはグーグルサービスを利用金額計算の主な設定を紹介します。
1. 予算と予算アラートを設定します
2. 金額データをエクスポートします

# 予算と予算アラートを設定します
:information_desk_person_tone1: [ここに](https://console.cloud.google.com/billing/)クリックしてBillingページを開きます
Billingページ > *Budgets& alerts* > **Create Budget**

**Scope**

|Property|Value|
|:--|:--|
|Name|My budget alerts|
|Projects|[YOUR_CHOISE_PROJECT_NAME] *(1以上)*|
|Products|[YOUR_CHOISE_PRODUCTS_NAME] *(1以上)*|
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581348/9b1fad73-85f6-8d4c-75d8-f6c9e0a7b9cc.png)

**Amount**
*Last month'spend* 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581348/c6ee832d-2206-809e-6b6b-58819db16cc8.png)
これを選んだと**月末**に利用した金額を通知します。そうすると予算が出来ませんから、ほとんど *Specified amount* を選びます

*Specified amount*
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581348/022f02d7-3b35-740f-0f92-a8c51cafe3d2.png)
*Target amount*：月次の最大金額

**Actions**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581348/5249085d-90b7-622a-bed2-a7e6eb1d7b07.png)
デフォルトは"50%, 90%, 100%" の金額をすごすと通知します。他の値を設定するば *add threshold* をクリックして設定します
*ADD THRESHOLD*
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581348/ebb3c2fa-6c36-0210-f9f6-c219f5375634.png)

*FINISH* ボタンをクリックして作成を完了します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581348/44555549-d1f8-a621-5b5b-48c5356a3442.png)



:information_desk_person_tone1: 詳しくは[ここに](https://cloud.google.com/billing/docs/how-to/budgets)ご参考下さい

# 金額データをエクスポートします
分析する為、金額データをクリックします。コンソルを開いてクスポートしてみます。

Billingページ > Billing export
以下のようにエクスポートができます。
## [ビッククエリへのエクスポート](https://cloud.google.com/billing/docs/how-to/export-data-bigquery)
**BIGQUERY EXPORT**

|Property|Value|
|:--|:--|
|Projects|[YOUR_CHOISE_PROJECT_NAME]|
|Billing export dataset *|[YOUR_BIGQUERY_DATASET_NAME]|

*EDIT SETTINGS* ボタンをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581348/8854e692-aba8-50ed-38fb-3a64209ce137.png)

## [ファイルへのエクスポート](https://cloud.google.com/billing/docs/how-to/export-data-file)
**FILE EXPORT**
*EDIT SETTINGS* ボタンをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581348/79817deb-f08c-983f-c7b8-6e5bf56d46be.png)

|Property|Value|
|:--|:--|
|Bucket name *|[YOUR_BUCKET_NAME]|
|Report prefix *|[YOUR_EXPORT_FILE_NAME]|

*SAVE* ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581348/f210753b-f75f-634b-5d1e-eb344b1bcd32.png)

*注: Cloud Billing のエクスポートを有効にすると、Google が所有するサービス アカウントにバケットへの書き込みアクセス権が自動的に付与されます。*

# 模擬試験
**Question 1**
:japanese_goblin: プロジェクトに対し、会社から月次予算が割り当てられているとします。そこで、プロジェクトの課金が上限に近づいてきたときに対策を取れるように、課金について自動通知を受け取りたいと考えています。どのように対応しますか。
A. 予算と同額の月次利用上限額であるクレジット カードを利用する。
B. 合計月次予算の 50%、90%、100% に達したときに通知する予算アラートを作成する。
C. App Engine の設定で、月次予算の 1/30 の割合で日次予算を設定する。
D. GCP Console で、BigQuery への請求のエクスポートを構成する。合計課金額のクエリを行う保存済みビューを作成する。

:information_desk_person_tone2: Reference
https://cloud.google.com/appengine/pricing#spending_limit 
https://cloud.google.com/billing/docs/how-to/budgets
has_secure_passwordについて

#はじめに
パスワードを実装してみたのでメモ
userモデルにパスワードを実装していきます
##1.has_secure_password
userモデルに

```ruby:user.rb
class User < ApplicationRecord
has_secure_password
end
```
と追加することで
(1).セキュアにハッシュ化したパスワードを、データベース内の`password_digest`という属性に保存できるようになる。（**条件あり**）
(2).2つのペアの仮想的な属性 (`password`と`password_confirmation`) が使えるようになる。また、存在性と値が一致するかどうかのバリデーションも追加される。
(3).`authenticate`メソッドが使えるようになる (引数の文字列がパスワードと一致するとUserオブジェクトを、間違っているとfalseを返すメソッド) 。
この3つの機能が使えるようになります。順番に解説していきます。
###(1)
ここでいうセキュアとは安全という意味です。設定したパスワードを暗号化（ハッシュ化）させて、`password_dijest`というカラムに保存できるようにします。すなわち、**Userモデルに`password_dijest`カラムを追加する**必要があります（先ほどの条件とはこのこと）。

```ruby:console
rails generate migration add_password_digest_to_users password_digest:string

rails db:migrate
```
また、パスワードを暗号化するためのgemとして、`bcrypt`(最新ので大丈夫です)というgemを`gemfail`に追加して`bundle install`する必要があります。
###(2)
`password`と`password_confirmation`のセットというのはパスワードとパスワード（確認用）ということです。ちなみに、`has_secure_password`をUserモデルに追加したことで自動的にこの二つのバリデーションが追加されるようになっていますが、これは更新時には適用されないので

```ruby:user.rb
validates :password, presence: true
```
と追加しておきましょう。パスワードの長さを制限したいときは

```ruby:user.rb
validates :password, presence: true, length: {minimum:5}
```
とすれば5文字以上のパスワードに制限することができます。
###(3)
authenticateメソッドではその説明の通り、引数の文字列がパスワードと一致しているか確認してくれます。

```ruby:console
User.create(name: "saber",email: "saber@seihai.com",password: "shirou",password_confirmation: "shirou")
user = User.find_by(name:"saber")
user.authenticate("kotomine") => false
user.authenticate("kiritugu") => false
user.authenticate("shirou") => true
```
といった感じでそのユーザーのパスワードの正誤を確認してくれます。
`autuenticate`では引数のパスワードをそのままデータベースの値と参照するわけではなく、一度ハッシュ化（暗号化）してからその値をデータベースにある値と参照してくれます。

##最後に
`has_secure_password`を自分なりにかみくだいてみました。参考になれば幸いです。
#Rails + ActiveModelSerializers で API の JSON を自由に組み立てたいけど  Controller の render で扱いづらいので、直接 each serializer で組み立てる例

# やりたいこと

たとえばこんなふうに 

- JSON 全体はオブジェクト
- オブジェクトの特定のキーが配列を持つ
- キーの名前は任意につけたい

というような場合があるのだけど

```rb
{
  "all_users" : [
    {
      "id": 1,
      "name": "Alice"
    },
    {
      "id": 2,
      "name": "Bob"
    }
  ]
}
```

# やってみた

- 良いやり方はどうかは分からない
- ActiveModelSerializers + Rails Controller の組み合わせは、自由なJSONを組み立てるのには、それほど向いていないような気もしている
- render メソッドで勝手に model インスタンスを Serialize してくれる挙動は捨てて、ある程度、自分の実装で Serialize していく必要があるのかもしれない。


```rb
class UserController < ApplicationController
  def index
    render json: { all_users: index_json }
  end

  def index_json
    ActiveModel::SerializableResource.new(
      User.all,
      each_serializer: UserSerializer
    )
  end
end
```

```rb
class UserSerializer < ActiveModel::Serializer
  attributes :id,
             :name
end
```


# Adapter を指定する

- `adapter: :json` を指定すると JSON を Serializer の名前でネストして囲ってくれるみたいだ ( この場合は `"users": [] `)
- `"all_users": []` などという好きなキー名にするには Serializer 自体を AllUserSerializer とかいう名前にする必要がありそう？
- なんか挙動が暗黙的すぎて、いままで触っていたコードではよく分かっていなかった


```rb
    render json: User.all, each_serializer: UserSerializer, adapter: :json
```

[active_model_serializers/serializers.md at v0.10.6 · rails-api/active_model_serializers](https://github.com/rails-api/active_model_serializers/blob/v0.10.6/docs/general/serializers.md)

# ルートのキーを指定する

`root: "all_users"` などと書けば 好きなキーも指定できるみたいだ。

```rb
    render json: User.all, root: "all_users", each_serializer: UserSerializer, adapter: :json
```

[active_model_serializers/rendering.md at v0.10.6 · rails-api/active_model_serializers](https://github.com/rails-api/active_model_serializers/blob/v0.10.6/docs/general/rendering.md#overriding-the-root-key)

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/3052








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Google Apps ScriptでLINE BOTのおうむ返し&スプレッドシートに自動入力

[YouTubeで公開した動画](https://youtu.be/9K_EKn2QQUQ)と[Qiita記事](https://qiita.com/njn0te/items/2c08c936661a9febb3b0)の続きです。

# YouTubeを観て実際に作ってみた人から、こんな質問がありました

例えば、

```console
田中
ご飯
味噌汁
生卵
```

と入力したら、botが

```
田中
ご飯
味噌汁
生卵

を食べました。
```
と返す方法はありませんかね？

## コード

```コード.js
// LINE developersのメッセージ送受信設定に記載のアクセストークン
const LINE_TOKEN = 'アクセストークン'; // Messaging API設定の一番下で発行できるLINE Botのアクセストークン（Channel Secretはいらないみたいです。）
const LINE_URL = 'https://api.line.me/v2/bot/message/reply';

// postリクエストを受取ったときに発火する関数
function doPost(e) {

  // 応答用Tokenを取得
  const replyToken = JSON.parse(e.postData.contents).events[0].replyToken;
  // メッセージを取得
  const userMessage = JSON.parse(e.postData.contents).events[0].message.text;
  // メッセージを改行ごとに分割
  const all_msg = userMessage.split("\n");
  // 入力データの数を取得
  const msg_num = all_msg.length;

  // 返答用メッセージを作成
  const messages = [
    {
      'type': 'text',
      'text':  `${userMessage}\n\nを食べました。`,
    }
  ]

  // ***************************
  // スプレットシートからデータを抽出
  // ***************************
  // 1. 今開いている（紐付いている）スプレッドシートを定義
  const sheet     = SpreadsheetApp.getActiveSpreadsheet();
  // 2. ここでは、デフォルトの「シート1」の名前が書かれているシートを呼び出し
  const listSheet = sheet.getSheetByName("シート1");
  // 3. 最終列の列番号を取得
  const numColumn = listSheet.getLastColumn();
  // 4. 最終行の行番号を取得
  const numRow    = listSheet.getLastRow()-1;
  // 5. 範囲を指定（上、左、右、下）
  const topRange  = listSheet.getRange(1, 1, 1, numColumn);      // 一番上のオレンジ色の部分の範囲を指定
  const dataRange = listSheet.getRange(2, 1, numRow, numColumn); // データの部分の範囲を指定
  // 6. 値を取得
  const topData   = topRange.getValues();  // 一番上のオレンジ色の部分の範囲の値を取得
  const data      = dataRange.getValues(); // データの部分の範囲の値を取得
  const dataNum   = data.length +2;        // 新しくデータを入れたいセルの列の番号を取得

  // ***************************
  // スプレッドシートにデータを入力
  // ***************************
  // 最終列の番号まで、順番にスプレッドシートの左からデータを新しく入力
  for (let i = 0; i < msg_num; i++) {
    SpreadsheetApp.getActiveSheet().getRange(dataNum, i+1).setValue(all_msg[i]);
  }

  const after_msg = {
    'type': 'text',
    'text': "保存完了。明日もしっかり食べよう！",
  }
  messages.push(after_msg);

  // lineで返答する
  UrlFetchApp.fetch(LINE_URL, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': `Bearer ${LINE_TOKEN}`,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': replyToken,
      'messages': messages,
    }),
  });

  ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);

}
```

## 解説
入力データは ```userMessage```に入っているので、そのまま最初の返答に使っています。
基本的にJavaScriptの知識で自由にカスタマイズできるので、やってみてください！
CNCFが考えるクラウドネイティブ化への道

# クラウドネイティブ化への道

クラウドネイティブ化を進めるにあたってどんなツール・サービスを活用すれば良いのか？どのような手順で進めれば良いのか？CNCFが情報を公開しているので共有します。

## CNCFとは何か？


> Cloud Native Computing Foundation(CNCF)はLinux Foundationのプロジェクトで、コンテナ技術の発展と、その進化に関連するテクノロジ業界の連携を支援するために2015年に創設された。
> 創立メンバーには、Google、CoreOS、Mesosphere、Red Hat、Twitter、ファーウェイ、Intel、Cisco、Docker、Univa、VMwareなどが名を連ねる。
> https://ja.wikipedia.org/wiki/Cloud_Native_Computing_Foundation

## クラウドネイティブ化とは何か？

CNCFはCloud Nativeの定義を各言語で定義しており、日本語では以下のような定義となっています。

> クラウドネイティブ技術は、パブリッククラウド、プライベートクラウド、ハイブリッドクラウドなどの近代的でダイナミックな環境において、**スケーラブルなアプリケーションを構築および実行**するための能力を組織にもたらします。 このアプローチの代表例に、**コンテナ、サービスメッシュ、マイクロサービス、イミュータブルインフラストラクチャ、および宣言型API**があります。
>
> これらの手法により、**回復性、管理力、および可観測性のある疎結合システムが実現**します。 これらを堅牢な**自動化**と組み合わせることで、エンジニアはインパクトのある**変更を最小限の労力で頻繁かつ予測どおり**に行うことができます。
>
> Cloud Native Computing Foundationは、オープンソースで**ベンダー中立**プロジェクトのエコシステムを育成・維持して、このパラダイムの採用を促進したいと考えてます。 私たちは最先端のパターンを民主化し、これらのイノベーションを誰もが利用できるようにします。

https://github.com/cncf/toc/blob/master/DEFINITION.md

## LandscapeとTrail Map

CNCFはクラウドネイティブ化までのステップを表したTrailMapと、Cloud Native化を実現するOSSやサービス一覧の情報を公開している。

- [Cloud Native Trail Map](https://github.com/cncf/landscape/blob/master/README.md#cloud-native-landscape)
  - クラウドネイティブ化までのステップを示したもの
- [Cloud Native Landscape](https://landscape.cncf.io/)
  - Cloud Nativeなサービス一覧
  - Serverlessは別項目で定義

## TrailMap

**クラウドネイティブ化実現のステップ**

クラウドネイティブ化の実現のために次のステップで進めると良いとしている。

1. コンテナ化
2. CI/CD
3. オーケストレーション＆アプリケーション定義
4. 可観測性と分析
5. サービスプロキシ、ディスカバリ＆メッシュ
6. ネットワーク＆ポリシー
7. 分散データベース/分散ストレージ
8. ストリーミング＆メッセージング
9. コンテナレジストリ＆ランタイム
10. ソフトウェアディストリビューション

![TrailMap](https://raw.githubusercontent.com/cncf/trailmap/master/CNCF_TrailMap_latest.png)

https://github.com/cncf/trailmap

**必ずしもTrailMapを辿る必要はない。**

> アプリケーションや会社の規模に左右されると思います。とても小規模でシンプルなアプリケーションに、豪華な可観測性やサービスメッシュは不要です。この点、セキュリティは特に顕著で、あまり担保しなくていい事業に、ガチガチなセキュリティは要らないのではないかなと。
> サイバーエージェント、青山氏
> https://www.atmarkit.co.jp/ait/articles/1911/12/news006_2.html

## Landscape

- アプリケーション定義と開発
  - データベース
  - ストリーミング＆メッセージング
  - アプリケーション定義とイメージビルド
  - CI/CD
- オーケストレーションと管理
  - スケジュールとオーケストレーション
  - コーディネーションとサービスディスカバリ
  - RPC
  - サービスプロキシ
  - API Gateway
  - サービスメッシュ
- ランタイム
  - Cloud Nativeストレージ
  - コンテナランタイム
  - Cloud Nativeネットワーク
- プロビジョニング
  - 自動化と構成管理
  - コンテナレジストリ
  - セキュリティとコンプライアンス
  - キー管理
- プラットフォーム
  - CloudFoundry
  - OpenShift
  - RANCHER
- 可観測性と分析
  - モニタリング：Prometheus等
  - ロギング：fluentd等
  - トレーシング：JAEGER
  - カオスエンジニアリング：Gremlin等

![スクリーンショット_2020-03-30_11_43_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100776/3c88ab4b-e637-a2f8-74cc-ef2db6a32bd4.png)

https://landscape.cncf.io/
6.4 ネットワークの運用ツールを利用するには？

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudの情報は [IBM Cloud Docs](https://cloud.ibm.com/docs) や [IBM Cloud アップデート情報](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/) 、[柔らか層本](https://ibm.ent.box.com/v/ibmcloud-yawaraka)をご参照ください。）

概要
SoftLayerではサーバーにログインしなくてもサーバーやネットワークとの通信状態やドメイン名の情報をカスタマーポータル内で調べられるネットワーク・ツールが提供されています。 
http://lg.softlayer.com/
ここでは、ネットワーク・ツールの概要と、実行結果の見方をご紹介します。
 

ネットワーク運用ツールとは
一般的なネットワーク調査用のコマンドをカスタマーポータル上で実行することができます。 提供されている機能は「Ping」、「Traceroute」、「NSlookup」、「Whois」、「Check DNS」です。 サーバーを準備しなくてもブラウザから確認できるので、手軽に情報を確認したいときに役に立ちます。 これらはSoftLayerのネットワークから実行されているため、パブリック・ネットワークだけでなく、プライベート・ネットワークに対しても調査できます。 ネットワーク・ツールを使うには、カスタマーポータルのメニューバーの「Network」->「Tools」をクリックします。 以降では、利用可能なツールについて詳しく解説します。
 

Ping
サーバーとの疎通や応答速度を調査するためのツールです。 入力フォームにIPアドレスかホスト名を入力して、「Ping」ボタンをクリックすると、ダラス・データセンターから対象サーバーに対してpingを実行します。 次の画面はSoftLayer上に構築したサーバーのIPアドレスに対して実行した結果です。 対象サーバーから応答があり、パケットの往復時間に179ミリ秒かかったということが分ります。


Traceroute
サーバーまでのネットワーク経路と応答速度を調査するためのツールです。 入力フォームにIPアドレスかホスト名を入力して、「Traceroute」ボタンをクリックして実行します。 次の画面はwww.softlayer.comに対して実行した結果です。 「Traceroute」の実行元のダラス・データセンターからwww.softlayer.comまでのネットワーク経路と応答速度が表示されていることが分ります。


NSlookup
ホスト名からIPアドレスを調べたり（正引き）、IPアドレスからホスト名を調べたり（逆引き）することができるツールです。 正しくDNSが設定されているかを調べるときなどに使用します。 入力フォームにホスト名を入力して「NSlookup」ボタンをクリックすると正引き情報を表示します。 次の画面はwww.softlayer.comに対して正引きを行った結果で、IPアドレスは66.228.118.51と分ります。

入力フォームにIPアドレスを入力して「NSlookup」ボタンをクリックすると逆引き情報を表示します。 次の画面は66.228.118.51に対して逆引きを行った結果で、ホスト名はwww.softlayer.comと分ります。


 

Whois
ドメイン名やIPアドレスの所有者情報が管理されているデータベースに情報を問い合わせるツールです。 入力フォームにドメイン名かIPアドレスを入力して、「Whois」ボタンをクリックするとデータベースへ問い合わせが実行され、その結果が表示されます。 次の画面は、softlayer.comに対して実行した結果です。 softlayer.comを管理している組織や登録年月日、連絡先などが確認できます。 ドメイン名が利用しているDNSサーバーの情報も得られるので、ドメイン名の移転を行った際の確認にも使用します。


Check DNS
対象ドメイン名のDNSレコードを変更した際にどのくらいの期間で古い設定情報がインターネット上のDNSサーバーから削除されるかを調べることができるツールです。 左の入力フォームにホスト名、右の入力フォームにドメイン名を入力して、「Check DNS」ボタンをクリックすると、結果が表示されます。 次の画面は、ns1.softlayer.comに対して実行した結果です。 現在の設定では古い設定情報がすべて消えるまで約1日かかるということが分ります。


DNSレコードのTTLを変更することで、古い設定情報が消えるまでの時間を調整することができます。 ただしプロバイダによっては、TTLの値に関係なく一定時間古い設定情報を保持する場合がありますので、注意してください。

以上のようにカスタマーポータルからサーバーやネットワーク、ドメイン名などの状態を簡単に調査することができます。
dockerでカラムの変更ができないエラー

docker-composeで自作アプリのテーブルをいじっていたらこんなエラーに遭遇しました。

```
$ docker-compose exec app rails g migration rename_star_column_to_topics
Starting sakelog_db_1 ... done
Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: \"rails\": executable file not found in $PATH": unknown
```




再起動してみたり、appをdbに書き換えてみたり、色々試しましたが解決できず。


でも解決法は意外と単純でした。




```
$ docker-compose exec app bundle exec rails g migration rename_star_column_to_topics
Starting sakelog_db_1 ... done
      invoke  active_record
      create    db/migrate/20200330013557_rename_star_column_to_topics.rb
```

railsの前に bundle execを付け足したらよかったんですね。

今までよくわからずに放置して使ってたbundle exec。
今回のエラーを経て改めて検索し直したら、
bundle execをつけずに実行すると、グローバルにインストールされているgemが動くのに対し、
bundle execをつけて実行するとプロジェクト内にあるgemが動くんだそうで。

なんとなくって怖いですね。適宜知識を増やしていかないと。
MySQLのgroup_concatを使えば複数レコードの値を一気に取得できる

こんな便利な機能があるのを知らなかったなんて情弱でした。


記事とカテゴリーをマッピングしたテーブルとして以下のようなものがあるとします。よくある多対多のテーブルです。

posts_categoriesテーブル

|  post_id  |  category_id|
| ---- | ---- |
|  1  |   1 |
|  1  |  3  |
|  1  |   5 |
|  2  |  2  |
|  2  |  3  |
|  2  |  4  |
|  2  |  5  |
|  3  |  2  |

これに以下のSQLを実行すると

```sql
select post_id, group_concat(distinct category_id separator \',\') as result from posts_categories group by post_id;
```

このような結果が得られます。

|  post_id  |  result|
| ---- | ---- |
|  1  |   1,3,5 |
|  2  |  2,3,4,5  |
|  3  |  2  |

PHP等の言語からMySQLを呼び出す場合など、これでデータを取得して`explode(',', $result);`とするだけで、category_idの配列を取得することが出来て便利です。
JavaScript で絵文字の文字数をカウントしたかった

JavaScript での絵文字を含む String の文字数カウントは結構ハードだった話。

## 問題の事象

😇 は直感的には1文字カウントされてほしいが、 `length` プロパティを参照すると以下のような結果になる。

```javascript
'hoge'.length  // 4
'ほげ'.length  // 2
'😇'.length  // 2 ...!?
```

## なぜ？

`length` は単に文字数を返している**わけではない**。
JavaScript の内部では文字列を UTF-16 形式で保持しており、 `lentgh` はこの単位のコード数を返している。
ASCII やひらがなは1つの 16 bit で表されるが、絵文字の多くは [サロゲートペア](https://ja.wikipedia.org/wiki/Unicode#%E3%82%B5%E3%83%AD%E3%82%B2%E3%83%BC%E3%83%88%E3%83%9A%E3%82%A2) を使って2つの 16 bit で表現される。

前述の例は UTF-16 で以下のように表現される。

```javascript
String.fromCharCode('0x0068', '0x006F', '0x0067', '0x0065')  // hoge
String.fromCharCode('0x307B', '0x3052')  // ほげ
String.fromCharCode('0xD83D', '0xDE07')  // 😇
```

見ての通り 😇 はコード2つ分なので、 `length` プロパティの値は2となる。

## `'😇'.length` を1文字としてカウントするには

[スプレッド構文](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax) を使って Array に変換した上で `length` を取れば1文字（1要素）扱いされる。

```javascript
[...'😇'].length  // 1
```

## これで解決？

文字コードの世界は広かった。
[man shrugging](https://unicode.org/emoji/charts/full-emoji-list.html#1f937_200d_2642_fe0f) と呼ばれる以下の絵文字は次のようにカウントされる。

```javascript
'🤷‍♂️'.length  // 5 ...!?
[...'🤷‍♂️'].length  // 4 ...!?
```

この絵文字は 🤷 （ `0xD83E` `0xDD37` ）と ♂ （ `0x2642` ）の組み合わせであり、内部的には以下のように表現される。

```javascript
String.fromCharCode('0xD83E', '0xDD37', '0x200D', '0x2642', '0xFE0F')
```

`0x200D` は絵文字の結合用のコード、 `0xFE0F` は[絵文字バリエーション・シーケンス](https://moji-memo.hatenablog.jp/entry/20120802/1343876603)と呼ばれるプレーン文字と絵文字を識別するためのコードらしい。
🤷 は1文字として判定されるものの、後続のコードがそれぞれ1文字判定され、結果4となる。

これらの文字に関しては[ライブラリを使って対応できるよう](https://flaviocopes.com/javascript-unicode/#get-the-proper-length-of-a-string)だが、現状ではシンプルな対応方法はなさそう...。
【phpbb】javascriptファイルをテンプレートごとに読み込む

##javascriptファイルを特定のテンプレートで読み込みたい#
phpbb3.2.5を使用しています。
ソースを見ると`</body>`の直前でjqueryが読み込まれています。
該当ファイルは`./styles/prosilver/template/overall_footer.html`です。
このファイルは基本的にすべてのページのフッター部分で使われています。

で、そのファイルの下の方に`{$SCRIPTS}`という記述があります。

```./styles/prosilver/template/overall_footer.html

<!-- EVENT overall_footer_after -->

<!-- IF S_PLUPLOAD --><!-- INCLUDE plupload.html --><!-- ENDIF -->
{$SCRIPTS}

<!-- EVENT overall_footer_body_after -->

</body>
</html>
```

テンプレートごとにjavascriptファイルを読み込む場合にここで表示されます。

テンプレート側の記述は以下のような感じで、`<!-- INCLUDEJS -->`タグ内にjavascriptファイルを記述します。

```./styles/prosilver/template/sample.html
<!-- INCLUDEJS {PATH}/javascript/sample.js -->
```

そうすると実際に生成されるhtmlは以下のような感じになります。

```sample.html
<script type="text/javascript" src="./../assets/javascript/jquery.min.js"></script> 
<script type="text/javascript" src="./../assets/javascript/core.js?assets_version=55"></script>
<script src="./../assets/javascript/sample.js?assets_version=55"></script>/* ←今回追加した部分 */
```
6.2 フローティングIPを取得するには？

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[IBM Cloud アップデート情報](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/) や [柔らか層本](https://ibm.ent.box.com/v/ibmcloud-yawaraka)をご参照ください。）

概要
フローティングIPとは、データセンターやサブネットにかかわらず移動できるIPアドレスのことを指し、SoftLayerではGlobal IPアドレスとして提供されています。 これは、SoftLayerの任意のデータセンターのユーザーに割り当てられたパブリックIPに紐づけることができるIPアドレスです。 ここではGlobal IPアドレスの取得方法と使い方をご紹介します。 本章では例として、メルボルンの仮想サーバーにGlobal IPアドレスを割り当てた後、シンガポールの仮想サーバーに移動する手順をみていきます。 あらかじめ各データセンターの仮想サーバーでウェブ・サーバーを動作させるものとします。
 

Global IPアドレスのサーバーへの割り当て方法
Global IPアドレスは、カスタマーポータル上で注文します。 「Network」->「IP Management」->「Global IP」をクリックし、表示された画面右上の「Order IP Addresses」をクリックします。

IPアドレスの注文画面では、「Global IPv4」をプルダウンメニューから選択し、「Select Option」の「Global IPv4」をクリックしたあと「Continue」をクリックします。

次の確認画面で料金を確認し、「I have read the Master Service Agreement and agree to the terms therein.」にチェックを入れ、「Place Order」をクリックすると、注文が完了します。

注文後は、カスタマーポータル上から「Network」->「IP Management」->「Global IP」をクリックし、追加されたGlobal IPをクリックします。 次の画面では「Routes to:」にメルボルンの仮想サーバーのIPアドレス「119.81.194.102」を選び、「Update」ボタンをクリックします。 これで、Global IPアドレスで、仮想サーバーにアクセスができます。 ただし、完全に反映されるまでに、数分かかりますので、少し待っていただく必要があります。

注意事項として、「Routes to:」の一覧に、実際に利用するIPアドレス表示されない場合には直接IPアドレスを入力する必要があります。
 

サーバーOSでの設定
起動時に付与されているIPアドレスに加えて、Global IPアドレスを設定します。 ここでは、注文したGlobal IPアドレス「108.168.254.219」を、メルボルンの仮想サーバー「119.81.194.102」と、シンガポールの仮想サーバー「168.1.80.68」で有効にします。 こうすることで、Global IPアドレスが紐づけられた際にサーバーが応答することができます。
6.1 ソフトレイヤーネットワーク入門

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[IBM Cloud アップデート情報](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/) や [柔らか層本](https://ibm.ent.box.com/v/ibmcloud-yawaraka)をご参照ください。）


概要
サーバーを注文するとパブリック・ネットワークとプライベート・ネットワークに対して、自動的にVLANとIPアドレスが割り当てられます。（ただし、プライベートオンリーとして注文した場合は、プライベート・ネットワークのみとなります。）ここでは、VLANとサブネットの関係や、VLAN画面でサブネットの割り当て状況を確認する方法、サブネットを追加注文する方法をみていきます。

サブネットとVLANの関係
SoftLayerのサーバーには、パブリック、プライベート、マネジメントの3つのネットワークが接続されています。 下の図のように物理サーバー(Bare Metal Server)や、仮想サーバー(Virtual Server)は、パブリック・ネットワークとプライベート・ネットワークの間に挟まるような形で配置されます。 これらの、パブリック、プライベートのネットワークはサブネットとして、アカウントごとに専用のVLANに割り当てられます。

ネットワーク・アドレスは、細かくネットマスクが設定されたサブネットであり、サーバー注文時に自動的に割り振られるもの（プライマリIPアドレス）と、必要な時に追加できるもの（スタティックIPアドレス、ポータブルIPアドレスなど）があります。 サブネットにはパブリックとプライベートがあり、パブリック側のVLANにはパブリック・アドレスのサブネット、プライベート側のVLANには、プライベート・アドレスのサブネットが割り当てられます。
 

VLANに結びつくサブネットの確認方法
カスタマーポータルでVLANに含まれているサブネットやサーバー等のデバイスの情報を見ることができます。 この画面に行くには、カスタマーポータルの「Network」->「IP Management」->「VLANs」をクリックし、 表示されたVLAN一覧画面内の「VLAN Number」をクリックし確認します。 そうすると、このVLANに所属するサブネット、サーバーを見ることができます。


VLANの詳細画面では、サーバーだけでなく、FortiGateや、NetScalerといったネットワーク・アプライアンスの情報やIPアドレスも確認することができるので、「Devices」と表記されています。 VLANに所属する全てのサブネット情報が確認でき、サーバー注文時に割り当てられるプライマリ・サブネットのほか、追加IPアドレスに対するサブネットの情報も表示されます。 IPv6のサブネットをVLANにアサインして、ここでIPv4と同じように見ることができます。

接続先サブネット毎にサーバー管理者の接続先を制限し、セキュリティを高めることができます。このサブネットの制限方法は、2.8 VPN接続のアクセス先を制限するには？にあります。

次の詳細画面で、サーバー注文時に自動的に割り当てられるプライマリ・サブネットと、ユーザーが自由に割り当てられるスタティック・サブネットとポータブル・サブネットが確認できます。

上の図のそれぞれサブネットの違いは以下の通りです。
 

 プライマリ・サブネット： サーバーの注文時に自動的に割り当てられます。
 スタティック・サブネット：特定のサーバーで複数のパブリックIPアドレスを割り当てるときのサブネットです。
 ポータブル・サブネット： ユーザーがVLANと紐づけることができるサブネットで、パブリックとプライベートを選択できます。

プライマリ・サブネットは、サーバー追加時に自動的に割り当てられますが、プライマリIPアドレスが不足したとき、自動的に新しいプライマリ・サブネットが同じVLAN上に追加されます。 そのため、サブネットが違っていたとしても同じVLAN内であれば相互に通信できるようになっていますが、サーバーに割り当てられているため他のVLANに移すことはできません。 他のVLANに移せるIPアドレスを使いたい場合は、サーバーに割り当てられないポータブル・サブネットを注文します。 ポータブル・サブネットのVLAN移動は、移動したいポータブル・サブネットと、移動先VLAN情報を記載し、チケットにて依頼します。ポータブル・サブネットの主な利用用途としては、IPエイリアスを追加したい場合や、ユーザーがベアメタル上で管理するハイパーバイザーにおける仮想マシン用のIPアドレスが挙げられます。ポータブル・サブネットとプライマリ・サブネットを疎通させたい場合は、VLANスパニングを「ON」にする必要があります。（手順は6.9 グローバル通信を有効にするには？と同様です。）

 

サブネットを追加注文するには？
サブネットの注文は、カスタマーポータル上から「Network」->「IP Management」->「Subnets」をクリックします。 画面右上の「Order IP Addresses」をクリックすると、注文画面が表示されますので、どの種類のIPアドレスを注文するか選びます。 ポータブル・サブネットを注文したいときは、次の画像のように「Portable Public」か「Portable Private」を選択し、注文を開始します。

以降の具体的な手順は、4.2 サーバーを替えても同じIPアドレスを継続するには？にあります。 カスタマーポータルで注文したあとは、サーバーのOS上でIPアドレスを追加する必要があります。

上図の「Global IPv4」、「Global IPv6」の詳細は、6.2 フローティングIPアドレスを取得するには？にあります。
6. ネットワーク編

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[IBM Cloud アップデート情報](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/) や [柔らか層本](https://ibm.ent.box.com/v/ibmcloud-yawaraka)をご参照ください。）


6.1 ソフトレイヤーネットワーク入門
6.2 フローティングIPを取得するには？
6.3 スピードテストの方法は？
6.4 ネットワークの運用ツールを利用するには？
6.5 オフィスLANをSoftLayerへ延長するには
6.6 自社とSoftLayerをダイレクトに接続するには？
6.7 ネットワークのゾーニングを構築するには？
6.8 NetScalerを2重化するには？
6.9 グローバル通信を有効にするには？
6.10 VLANだけを注文するには？
Goでインターネット上のものではなくローカルのパッケージを使う

# 背景
Goで開発をしていて、依存ライブラリの挙動を確認するために色々仕込みたかったのでローカルにソースコードを持ってきたのですが、参照先をそっちに切り替えるのに少々ハマったので備忘録的に書きます。

# やったこと
go.modファイルを書き換えました。

以下が元々のgo.modファイル。
https://github.com/mura123yasu/cloudevents-go-helloworld/blob/master/go.mod

```go
module github.com/mura123yasu/cloudevents-go-helloworld

go 1.14

require (
	github.com/cloudevents/sdk-go v1.1.2
	github.com/kelseyhightower/envconfig v1.4.0
)
```

sdkの挙動を確かめたくてローカルを参照するように変更したかったのですが、必要なのは `replace` の記載でした。

```go
module github.com/mura123yasu/cloudevents-go-helloworld

go 1.14

require (
	github.com/cloudevents/sdk-go v1.1.2
	github.com/kelseyhightower/envconfig v1.4.0
)

replace github.com/cloudevents/sdk-go v1.1.2 => <PATH to YOUR LOCAL DIR>/github.com/cloudevents/sdk-go
```

これで無事にローカルでsdkをいじって挙動確認しつつ開発を進めることができました。
正規表現まとめ

## 正規表現チェックツール
[regular expression101(PHP, JS, Python, Golang)](https://regex101.com/)
[Regexper(正規表現の可視化)](https://regexper.com/)

## 正規表現早見表
<img width="1054" alt="スクリーンショット 2020-03-30 9.44.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181094/a28273fc-672b-2a62-2dcb-b355ec88ae41.png">


## [初心者歓迎！手と目で覚える正規表現入門・その１「さまざまな形式の電話番号を検索しよう」](https://qiita.com/jnchito/items/893c887fbf19e17d3ff9)

### まとめ
- `\d` は「半角数字1文字」を表す
- `{n,m}` は「直前の文字が n 文字以上、m 文字以下」であることを表す
- `{n}` は「直前の文字がちょうど n 文字」であることを表す
- `[AB]` は「AまたはBが1文字」であることを表す
- `[a-z]` と `[-az]` ではハイフンの意味が異なる
- 正規表現の正確さと複雑さはトレードオフになることが多い

## [初心者歓迎！手と目で覚える正規表現入門・その２「微妙な違いを許容しつつ置換しよう」](https://qiita.com/jnchito/items/64c3fdc53766ac6f2008)

### まとめ
- `?` は「直前の文字が1個、または無し」を表す
- `.` は「任意の1文字」を表す
- `+` は「直前の文字が1個以上」を表す
- `*` は「直前の文字が0個以上」を表す
- `( )` はマッチする部分をキャプチャ（捕捉）する
- キャプチャした部分は置換するときに `$1` や `\1` で参照できる
- `\w` は「英単語を構成する文字（半角英数字とアンダースコア）」を表す
- `[^AB]` は「AでもなくBでもない任意の1文字」を表す
- 正規表現中の特別な文字は `\` でエスケープする
- `( )` はキャプチャだけでなく、グループ化にも使われる
- `(ABC)?` は「文字列 ABC があり、または無し」を表す
- `(?: )` はキャプチャ無しでグループ化する場合に使う
- `*` と `+` は「貪欲」で最長マッチを返すため、使い方を誤ると思いがけない結果が返る
- `*?` や `+?` にすると、最短マッチを返す
- テキストエディタで重要なテキストを置換する際は、ひとつずつ確認しながら置換する

## [初心者歓迎！手と目で覚える正規表現入門・その３「空白文字を自由自在に操ろう」](https://qiita.com/jnchito/items/6f0c885c1c4929092578)

### まとめ

- `^` は行頭を表す
- `$` は行末を表す
- `\t` はタブ文字を表す
- `\n` は改行文字を表す
- `\s` は空白文字（スペース、タブ文字、改行文字等）を表す
- `ABC|DEF` は「文字列ABCまたは文字列DEF」のOR条件を表す
- 改行コードは環境によって異なる場合がある
- `^` は行頭の意味になったり、`[^ ]` で否定の文字クラスの意味になったりする


## [初心者歓迎！手と目で覚える正規表現入門・その４（最終回）「中級者テクニックをマスターしよう」](https://qiita.com/jnchito/items/b0839f4f4651c29da408)

### まとめ
- `\b` は単語の境界を表す
- `(?=abc)` は「abcという文字列の直前の位置」を表す（先読み）
- `(?<=abc)` 「abcという文字列の直後の位置」を表す（後読み）
- `(?!abc)` は「abcという文字列以外の直前の位置」を表す（否定の先読み）
- `(?<!abc)` 「abcという文字列以外の直後の位置」を表す（否定の後読み）
- キャプチャした文字列は正規表現内でも `\1` や `\2` といった連番で参照できる（後方参照）
- `?` や `*`、`+` といった量指定子は `( )` の後ろに付けることもできる
- `|` を使ったOR条件では、各条件内でもメタ文字が使える
- 書き方によっては、とんでもなく遅い正規表現ができあがることもある
- メタ文字はバックスラッシュ（`\`）でエスケープする
- `[ ]` 内ではメタ文字の種類や使われる位置によって各文字の働きが異なる
- `{n,}` や `{,n}` はそれぞれ「直前の文字がn個以上」「n個以下」の意味になる
- `\W`、`\S`、`\D`、`\B` はそれぞれ `\w`、`\s`、`\d`、`\b` の逆の意味になる


## REF
- [初心者歓迎！手と目で覚える正規表現入門・その１「さまざまな形式の電話番号を検索しよう」](https://qiita.com/jnchito/items/893c887fbf19e17d3ff9)
- [初心者歓迎！手と目で覚える正規表現入門・その２「微妙な違いを許容しつつ置換しよう」](https://qiita.com/jnchito/items/64c3fdc53766ac6f2008)
- [初心者歓迎！手と目で覚える正規表現入門・その３「空白文字を自由自在に操ろう」](https://qiita.com/jnchito/items/6f0c885c1c4929092578)
- [初心者歓迎！手と目で覚える正規表現入門・その４（最終回）「中級者テクニックをマスターしよう」](https://qiita.com/jnchito/items/b0839f4f4651c29da408)
4.6 EVaultからリストアするには？

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[IBM Cloud アップデート情報](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/) や [柔らか層本](https://ibm.ent.box.com/v/ibmcloud-yawaraka)をご参照ください。）

概要
EVaultバックアップは、EVaultの管理コンソール(WebCC)から、バックアップ一覧を表示し、バックアップのバージョンを指定してリストアを実行できます。 ここでは、過去に取得されたEVaultバックアップからのリストア方法をご紹介します。
 

リストアの想定シナリオ
今回は、バックアップ元のサーバー上でオペレーション・ミスが起きてファイルを削除してしまった場合を想定し、リストアを実行してみます。 前提として、バックアップ・ジョブは、次のように運営しています。
 

バックアップ先は、ローカルである。
バックアップ対象は、特定のフォルダーを対象にしている。
バックアップ・ジョブは、毎日0時30分にEVaultによって自動実行される。
 

事前準備
事前準備として、サーバーでオペレーション・ミスが起きた状況を再現しておきます。 次のように画像が41件ありましたがすべて消えてしまった、というシナリオです。
 
```
# ls /mnt/san1/data/Evault-baukup*.jpg | wc -l
41
# rm -f /mnt/san1/data/Evault-baukup*.jpg
# ls /mnt/san1/data/Evault-baukup*.jpg | wc -l
ls: cannot access /mnt/san1/data/Evault-baukup*.jpg: No such file or directory
0
```

EVault管理コンソールの表示
EVaultのリストア作業は、カスタマーポータルからEVaultの管理コンソール(WebCC)に接続して実行します。 EVaultの管理コンソールは、プライベート・ネットワーク上にあります。 VPN接続をしてから管理コンソールに接続できます。 VPN接続については、2.7 パブリックIPからのログインを禁止して、保守するには？を参照してください。

VPN接続のあと、カスタマーポータルから、「Storage」->「Backup」でEVaultバックアップのデバイス一覧を表示し、左端の「三角マーク」をクリックしてEvaultの詳細情報から、EVaultの管理コンソール(WebCC)へのリンクをクリックします。 特にログイン画面は表示されません。


どのジョブを使うのか
EVaultでは、バックアップ・ジョブを複数運用することもあります。 まず、対象のファイルをバックアップしているジョブを判別して選択します。 それからリストアの実行は、「Run Retore」をクリックして進みます。


いつの時点まで戻すのか
今回のリストアは、ファイルの誤削除ですから、該当のファイルを戻すだけの作業になります。 ここでは朝、業務開始直後に誤削除が起きて直ぐ報告が上がって来たとします。 このようなケースでは、前日のバックアップで対応できるはずです。 リストア対象のバックアップが決まったら次に進みます。




どのファイルを戻すのか
EVaultのリストアにおける最大の強みは、状況に応じてバックアップをすべてリストアすることもできれば、フォルダー単位やファイル単位に選択してリストアすることもできることです。 もちろん、フォルダーやファイル名称でリストア対象をフィルターすることも可能です。

今回は、削除してしまったファイルのみをピンポイントで指定し、リストアを実行します。


リストア先およびファイル書き込みのオプション指定
EVaultのリストアでは、元の場所に戻すことも、異なる場所に戻すことも可能です。 今回は、リストア先を元の場所にします。 さらに、リストアの実行時に同名のファイルが存在する場合の動作に関するオプションを指定します。 特に、元の場所にリストアする場合、このオプションの選択は要注意です。 間違えると更なる惨事に繋がる可能性があります。

ここでは同名のファイルが存在する場合はスキップにします。 実際の運用では、関係者への確認が必要な場面です。


リストア終了の確認
リストアが終了したら、下図のようレポートが表示されます。 Statusをみると、Restore complatedとなっており、リストアの成功が一目で確認できます。

最後の締めくくりとしてサーバー上でリストア状況を確認してみます。 ご覧のとおり、誤削除してしまった41個のファイルがピンポイントでリストアできています。
 
```
# ls /mnt/san1/data/Evault-baukup*.jpg | wc -l
41
```
Raspberry Pi Zero WのUART(物理結線によるシリアル)通信

# 0.概要
これまでRaspberryPi同士を通信させたい時はインフラストラクチャーもしくはアドホックによるワイヤレス通信によって行うことが多かった。
しかし、無線が使えない環境では物理結線で通信させるしかない。この時、最も簡単であろうUARTによる通信の方法を説明したい。

#1. UART機能を使う
RaspberryPiではシリアル通信が1チャンネルのためUART通信を使う場合、
ターミナル用に用いていたUSBシリアルをつぶす必要がある。

まず`sudo vi /boot/config.txt`でファイルを開き以下を追記

``` bash:/boot/config.txt
...
enable_uart=1
```

次にUSBシリアルを無効化

```
$ sudo systemctl disable serial-getty@ttyS0.service
```

起動時にONにならないよう設定

```
$ sudo vim /boot/cmdline.txt
-> 削除: console=serial0,115200
```

ここで一度再起動

```
$ sudo reboot
```

これを2台のRaspberryPiで設定する

# 2. 通信テスト
RaspberryPiのヘッダを以下の組み合わせでジャンパで接続する


 - TX-RX
 - RX-TX
 - GND-GND

![RaspPiZero.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/7f4576d2-2760-2505-9cc9-d642d23ee210.png)

次に通信ソフトウェアをインストール

``` bash 
$ sudo apt-get install minicom -y
```

以下で通信

``` bash
$ minicom -b 115200 -o -D /dev/ttyS0
```
MySQL8　root パスワード リセット変更 

#経緯
MySQLでrootパスワードを紛失したり、またはパスワードが行方不明になったりしたとき、MySQLへの接続が出来なくなった....そんなときに

このようなエラーを見かけます...

```
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
```

#セーフモード（mysqld_safe）で起動
```
1.サーバーストップ
$ mysql.server stop

2.セーフモードでの起動、
$ mysqld_safe --skip-grant-tables &

3.パスワードなしでログインできる
$ mysql -u root
```

##パスワードを空にする

```
mysql > UPDATE mysql.user SET authentication_string=null WHERE User='root';
```

#ではrootパスワードを変更します
今まで通りこのようなコマンドで変更しようとしたところ、

```
//失敗例１
mysql > update mysql.user set password=password('hogehoge') where user = 'root';

//失敗例２
mysql > SET PASSWORD FOR root@localhost=PASSWORD('hoge');

//結果
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'PASSWORD('root')' at line 1
```


このように文法エラーという結果が帰ってきます。


#PASSWORD() 関数は、MySQL version 5.67 までで廃止
MySQL 8 においては、そもそも関数が存在しないようです。

＊下記のコマンドでパスワードを変更

```
1. MySQL再起動（非セーフモード）
$ mysql.server restart

2. 空のパスワードでログイン
$ mysql -u root -p 
enterでパスなしでログイできる

3.パスワード変更
mysql > USE mysql;
mysql > ALTER USER 'root'@'localhost' identified BY '自分の決めるパスワード';

Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0C
```

変更できました。

参考サイト
http://www-creators.com/archives/5574
4.4 古くなったサーバーを更改するには？

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[IBM Cloud アップデート情報](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/) や [柔らか層本](https://ibm.ent.box.com/v/ibmcloud-yawaraka)をご参照ください。）

概要
サーバーのスペックが古くなったり、OSのサポートが終了する場合には、サーバーの移行を検討する必要があります。 ここではデータ領域の移行を例に、サーバーのOSイメージや共有ディスクを使ってデータを移行する方法と、サービスの切り替え方をご紹介します。

サーバを運用していると、仮想サーバー・物理サーバーを問わずサーバーの移行は避けて通れない課題です。 具体的には、物理サーバーのCPUスペックが低くなり、新しいスペックに入れ替えたい場合や、OSやミドルウェアのサポートが終了し、新しいサーバー環境にデータを移行したい場合が考えられます。

運用中のサーバーを移転するには、単純なサーバーの入れ替えと違い、データの移行方法を考える必要があります。 ここでは、次の図のように、データ領域を新しい環境に移行する場合を想定し、詳しい移行手順を見ていきます。 前提として、アプリサーバーからDBサーバーへは、DNSを使ったホスト名で接続するものとします。 これは、今回のような移行作業において、アプリ側に手を加えることなくスムーズに切り替えるためです。 また切り替えが完了するまで並行稼働させておき、問題が発生しても環境を切り戻せるようにしておきます。


サーバーの移行
仮想サーバーのOSのバージョンを上げるには、新しい仮想サーバーを別途立ちあげておいて、データ移行用のディスクを使うかデータを転送して切り替えていきます。

物理サーバーの場合は、OSのバージョンアップを行いたいケースと、物理サーバーのスペックをあげたいというケースがあります。 このうちOSのバージョンを上げたい場合は仮想サーバーと同じ方法になります。 物理サーバーのスペックを上げたい場合は、フレックス・イメージをとって、新しいスペックの高いサーバーにリストアする方法になります。
 

データ領域の移行
稼働しているアプリに影響を与えずDBサーバーのデータを移行するには、オブジェクト・ストレージを使う方法や移行用のワークディスクを使う方法が考えられます。

オブジェクト・ストレージをCloudFuse ( https://github.com/redbo/cloudfuse ) でマウントしてデータをエクスポートする方法がとれます。 オブジェクト・ストレージは従量課金のため、前もって大きなディスク容量を確保する必要がないので、もっとも安価な方法と言えます。 しかし、オブジェクト・ストレージは1つのファイルが5GB以上の容量を扱えることができないため考慮が必要となります。

もう1つは、移行用のワークディスクとしてNASやiSCSIを使う方法があります。 これらのネットワーク経由でアクセスするストレージは、サーバーの再起動なしで使えます。 あらかじめ必要なディスク容量を確保するため、オブジェクト・ストレージよりも割高になることがあります。

お金のかからない手軽な方法として、移行先のサーバーでNFSサーバーを立ちあげて旧サーバーからマウントする方法もあります。 Linuxの知識があれば無料で実現できる、お手軽な方法です。 ただし、NFSはそれほどパフォーマンスが良くないので、ファイル転送の方が処理が速いことがあるので考慮が必要です。
 

DNSを使ったサービスの切り替え
アプリサーバーからは古いDBサーバーをホスト名で参照しているので、DNS設定を切り替え、新しいサーバーを参照させるようにします。 プライベート・ネットワーク内のAレコードが古いサーバーへ向いていますので、これを新しいサーバーのIPアドレスに変更をお願いします。 アプリ側がホスト名でDBサーバーに接続していれば、サービス切り替えにあたりアプリやアプリ側サーバーの変更を行う必要はありません。

SoftLayerのDNSサービスを使えば、自分でDNSサービスを構築する必要がなく、無料で使えるのでおすすめです。 DNSの設定方法については4.3 SoftLayerのDNSを利用するには？を参照してください。

参考情報として、今回のようにDNSを使わずに、同じIPアドレスのままサーバーを移行する方法もあります。 事前にサーバーにIPアドレスを割り振る必要がありますが、IPアドレスは常に同一のものが使えます。 詳しくは「4.2 サーバーを替えても同じIPアドレスを継続するには？」を参照してください。

サーバーの移行作業が完了したあとは、古いサーバーを停止・解約します。 作業用ワークディスクも不要であれば、アンマウント・デタッチしてから、解約をお願いします。
同じ行に中央寄せと右寄せを混在させたい…！(CSS)

# はじめに
エンジニアならHTMLとCSSは出来て当たり前だと言われてますが、意外と奥が深く、調べないと分からない場面って結構ありますよね！
今回は、私が先日遭遇した、調べないと分からなかったCSSについてご紹介します！
# 今回やりたかった事
<a href="https://gyazo.com/7fdb320aa5770a33e9f7d0754f27b803"><img src="https://i.gyazo.com/7fdb320aa5770a33e9f7d0754f27b803.png" alt="Image from Gyazo" width="464"/></a>
こんな感じで、ヘッダー内にロゴを中央寄せ、メニューアイコンを右寄せに配置しようとしました。

flexbox を使えば、
<a href="https://gyazo.com/3fc07006331e02ae6718de2f27755019"><img src="https://i.gyazo.com/3fc07006331e02ae6718de2f27755019.png" alt="Image from Gyazo" width="464"/></a>
<a href="https://gyazo.com/36c6a37f344c828a4dbb985acd10c0e2"><img src="https://i.gyazo.com/36c6a37f344c828a4dbb985acd10c0e2.png" alt="Image from Gyazo" width="460"/></a>
２つの要素を片側に寄せたりとか、端と端に寄せたりとかは簡単なのですが、

１つを中央、もう１つを右端（もしくは左端）に配置したい場合は、どうしたら良いのでしょか？

さっそく見ていきましょう！

# 方法
今回は、以下の状態から説明スタートです。
<a href="https://gyazo.com/07741057ef922d0309e7420f31b7a4f3"><img src="https://i.gyazo.com/07741057ef922d0309e7420f31b7a4f3.png" alt="Image from Gyazo" width="462"/></a>

```html
<div class="header-item">
  <h3>Goutfit</h3>
  <i class="fas fa-bars"></i>
</div>
```

```css
.header-item {
  display: flex;
}

h3 {
  margin: 0;
  line-height: 50px;
}

i {
  line-height: 50px;
  font-size: 20px;
}
```

line-heightとかサイズとか調整して、display flex で横並びにしてある状態です。

上記のCSSにjustify-contentを追加します。

```css
.header-item {
  display: flex;
  justify-content: center;  // 追記
}

h3 {
  margin: 0;
  line-height: 50px;
}

i {
  line-height: 50px;
  font-size: 20px;
}
```
<a href="https://gyazo.com/6601730b38e3bfe385dc00be891c50fb"><img src="https://i.gyazo.com/6601730b38e3bfe385dc00be891c50fb.png" alt="Image from Gyazo" width="466"/></a>
justify-content: center; で、取り敢えず要素を中央寄せにしました。

ここから、さらにアイコンだけを動かしていきます！

```css
.header-item {
  display: flex;
  justify-content: center;
  position: relative;   // 追記
}

h3 {
  margin: 0;
  line-height: 50px;
}

i {
  line-height: 50px;
  font-size: 20px;
  position: absolute;  // 追記
  right: 0;          // 追記
}
```
親要素に position: relative; を追加。
アイコンに position: absolute; を追加し、
親要素を起点に right: 0; とします。

すると、
<a href="https://gyazo.com/7fdb320aa5770a33e9f7d0754f27b803"><img src="https://i.gyazo.com/7fdb320aa5770a33e9f7d0754f27b803.png" alt="Image from Gyazo" width="464"/></a>

求めていた配置にする事ができました！！

# まとめ
flexbox だけでは出来なかった配置も、
position を組み合わせる事で可能となります！

今回の記事が少しでも参考になれば嬉しいです！
4.1 保守作業中に案内ページを表示するには？

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[IBM Cloud アップデート情報](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/) や [柔らか層本](https://ibm.ent.box.com/v/ibmcloud-yawaraka)をご参照ください。）

概要
ローカル・ロードバランサー(以下LLB)を利用して、保守作業中のお詫び画面を表示する方法を紹介します。
 

Sorryサーバーのイメージ・テンプレート
メンテナンス時などに案内画面を表示するSorryサーバーのような一時利用のサーバーは、事前に作業中である旨のウェブページを含むイメージ・テンプレートを作成しておいて、必要な時にだけサーバーを注文して利用すると便利です。イメージ・テンプレートを利用したサーバーの作成方法は、1.5.2 仮想サーバーのOSリストア方法は？にあります。
 

メンテナンス中の案内表示
メンテナンス中は、通常運用のサーバーへのロードバランシングを無効にし、Sorryサーバーへのロードバランシングを有効にします。 こうすることで外部からのリクエストは、すべてSorryサーバーに振り分けられます。次の図は、保守作業中であることを案内する画面を表示する状態を表しています。 LLBの利用方法は、3.3.1 ローカル・ロードバランサーを使うには？にあります。


Sorryサーバーの追加
通常運用の例として、LLBに2台のウェブ・サーバーを登録していたとします。

  ウェブ・サーバー1号機(WebServer1:50.23.120.50)
  ウェブ・サーバー2号機(WebServer2:50.23.120.51)

これに加えて作業中の案内ページを応答するSorryサーバーを追加する方法を見ていきます。

  Sorryサーバー(Maintenance-info:50.23.120.52)

カスタマーポータルから「Network」->「Load Balancing」->「Local」をクリックし、「Details-Local Load Balancer」画面を表示します。 「Details-Local Load Balancer」の右上にある「Add Service」をクリックすると下図の「Add Service」ウィンドが表示されます。

 

のウィンドでSorryサーバーを追加します。 この時、「Enabled」のチェックは外すようにお願いします。 チェックを入れたまま登録すると、LLBがリクエストを割り振ってしまいます。

サーバーの登録作業が終了すると、次のようにLLBに登録されているサーバーのリストが確認できます。 「Enabled」を見ると、通常サーバーは「Yes」、Sorryサーバーは「No」となっています。 これでSorryサーバーへの切り替え準備ができました。
 

メンテナンス中への切り替え設定
メンテナンス作業の案内画面に切り替えるには、次のようにLLBの振り分けサービスを切り替えます。

Sorryサーバーへの振り分けを有効にします。 「Actions」->「Edit Service」をクリックします。 「Edit Service」画面の「Enabled」にチェックを入れます。

通常運用サーバーへの振り分けを無効にします。 「Actions」->「Edit Service」をクリックします。 「Edit Service」画面の「Enabled」のチェックを外します。

次の図は、LLBの振り分け設定済みの状態です。 Sorryサーバーのみ、「Enabled」が「Yes」になっています。 これでユーザーへの影響無くメンテナンスを実施する状況が整いました。


LLB設定を通常の状態に戻す
メンテナンス作業が完了し、LLBを通常運用の状態に戻す時は、次のような手順で切り替え作業を行います。

1. 通常運用サーバーへの振り分けを有効にします。
2. Sorryサーバーへの振り分けを無効にします。
3. 「Actions」->「Delete Service」をクリックし、SorryサーバーをLLBから削除します。
4. 不要になったSorryサーバーは、キャンセルします。
 

補足：NetScalerの場合
NetScalyerで同様に保守中の案内画面を表示する方法は、3.3.2 専用ロードバランサー(NetScaler)を使うには？ の「応用編：メンテナンス・ページを表示するには？」にあります。
4. 運用保守性編

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[IBM Cloud アップデート情報](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/) や [柔らか層本](https://ibm.ent.box.com/v/ibmcloud-yawaraka)をご参照ください。）

4.1 保守作業中に案内ページを表示するには？
4.2 サーバーを替えても同じIPアドレスを継続するには？
4.3 SoftLayerのDNSを利用するには？
4.4 古くなったサーバーを更改するには？
4.5 EVaultでバックアップするには？
4.6 EVaultからリストアするには？
4.7 EValutで異なるサーバーに戻す方法は？
4.8 監視の閾値を設定するには？
4.9 コマンドでサーバーをオーダーするには？
4.10 カスタマーポータルのユーザー管理法は？
Laravel6 Eloquent で複数代入を使用したupdate()の書き方と注意点

初投稿です。
なんか公式のドキュメントに書いていない気がするので書きました。
バージョンはLaravel6で確認してまいすが、5.1～7.*は多分同じ。

# 複数代入とは
こうじゃなくて。

```
$flight = App\Flight::find(1);
$flight->name = 'New Flight Name';
$flight->hoge = 'New Flight Hoge';
$flight->save();
```
こうするやつ。

```
App\Flight::find(1)->update([
    'name' => 'New Flight Name',
    'hoge' => 'New Flight Hoge',
]);
```
`update()`を使います。
[$fillableか$guarded](https://readouble.com/laravel/6.x/ja/eloquent.html#mass-assignment)をModelに定義していないとエラーになります。
更新したくない値がリクエストに含まれていても、とりあえずは安心です。

呼ばれてるのはこれ。実は`fill()`して`save()`してるだけ。

```\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php
    /**
     * Update the model in the database.
     *
     * @param  array  $attributes
     * @param  array  $options
     * @return bool
     */
    public function update(array $attributes = [], array $options = [])
    {
        if (! $this->exists) {
            return false;
        }

        return $this->fill($attributes)->save($options);
    }
```



## 実は二種類あるupdate()
ここが注意点です。
こんな風に書いてしまった場合

```
App\Flight::where(['id' => 1])->update([
    'name' => 'New Flight Name',
    'hoge' => 'New Flight Hoge',
]);
```
`where()`はBuilderを返すので、Builderの`update()`が呼ばれます。

```\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Builder.php
    /**
     * Update a record in the database.
     *
     * @param  array  $values
     * @return int
     */
    public function update(array $values)
    {
        return $this->toBase()->update($this->addUpdatedAtColumn($values));
    }
```
こちらは戻り値が「変更された行」ですので、`updated_at`がないテーブルとかだと、普通に`0`が返ってきます。（ifで悲しいことになるやつ）
ついでに`$fillable`も`$guarded`も効きません。
[ここ](https://readouble.com/laravel/6.x/ja/eloquent.html#updates)に書いてる通り、Modelとか関係ないやつです。

# まとめ
EloquentはModelだったりBuilderだったりCollectionだったりするので注意が必要です。
shoulda-matchersが便利すぎる

## はじめに
RSpecを書くときに、`shoulda-matchers`というGemを使うと非常に便利でした。

## shoulda-matchersとは

> Shoulda Matchers provides RSpec- and Minitest-compatible one-liners to test common Rails functionality that, if written by hand, would be much longer, more complex, and error-prone.

`Shoulda Matchers`は、手書きで書くと長くて、複雑で、エラーが起きやすいRailsのテストをワンライナーにします。(意訳)</br>
ワンライナーって1行ってことでいいのでしょうか...

## 使用方法
このような`userモデル`に対し、

```rb:user.rb
class User < ApplicationRecord
  validates :name, presence: true
  has_many :topics
end
```

`shoulda-matchers`を使うとこのようなRSpecを書くことができます！

```rb:user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  it { is_expected.to validate_presence_of(:name) }
  it { is_expected.to have_many(:topics) }
end
```

バリデーションやアソシエーションのテストを一行で書けるのは便利すぎますね。</br>
普通のRSpecの書き方で書いて、テストケースに抜けや漏れが出てしまうなんてことを防げます。

上記の例では`presence`と`has_many`を取り上げましたが、他にも使えそうな書き方がたくさんあるので追記していきたいと思います。

参考：[Shoulda-MatchersのREADME](http://matchers.shoulda.io/docs/v4.3.0/)
3.4 アクティブ・スタンバイのクラスタを構成するには？

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[IBM Cloud アップデート情報](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/) や [柔らか層本](https://ibm.ent.box.com/v/ibmcloud-yawaraka)をご参照ください。）

概要
豊富なLinuxのソフトウェアを使って、高可用性の構成を組むことができます。 ここでは、よく利用されているハートビート(Heartbeat)、キープアライブ(Keepalived)という2つのソフトウェアを使った例をご紹介します。
 

ハートビート(Heartbeat)とは？
ハートビートは、クラスタを構成するために、通信とサーバー間のメンバーシップなどの基盤機能を提供するデーモン（プロセス）です。 これは他サーバー上のプロセスの存在や消滅を監視します。 そして、ハートビート・デーモンは、クラスタリソースマネージャ(CRM)と組み合わせて利用する必要があります。 このCRMは代表IPアドレスやサービスの開始と停止を担当して高可用化を実現します。 ペースメーカー(Pacemaker)は、ハートビートのためのCRMです。 (ご参考: http://www.linux-ha.org/wiki/Heartbeat ) このハートビートは、Linux-HAが提供するオープンソースの高可用化ソフトウェアです。 そして、ペースメーカーは、プロジェクトとして分離され、そのウェブサイトから情報提供されています。 (ご参考: http://clusterlabs.org/)
 

キープアライブ(Keepalived)とは？
キープアライブは、C言語で書かれたルーティング・ソフトウェアです。 このソフトウェアは、Linuxのためのロードバランシングと高可用性の単純で堅牢な基盤を提供します。 ロードバランシングの基本機能は、Linux Virtual Server(LVS)のカーネル・モジュールのレイヤ4ロードバランシングの上に成り立っています。 一方、高可用性は、VRRPプロトコルによって実現されています。 このVRRPは、ルーターを2重化した時のゲートウェア・アドレスを引き継ぐ場合に使われるものです。 キープアライブは、フリーソフトウェアです。 (ご参考: http://www.keepalived.org/)
 

アクティブ・スタンバイの構成例
この方式の異なる二つの高可用性を実現するためのソフトウェアは、それぞれ適用するサービスが異なっています。 どちらもアクティブ・スタンバイを構成しますが、ハートビートは、NFSサーバーやデータベース・サーバーなど、サーバーの上で動作するサービスが適用対象となります。 そして、キープアライブは、LinuxのロードバランサーであるLVSをアクティブ・スタンバイの構成にするものです。

それぞれの具体的な注文方法と設定方法は、以下のリンク先で、サンプル構成を例にご紹介していきます。
 

3.4.1 ハートビートを用いたNFSのHA構成
3.4.2 キープアライブを用いたLVSのHA構成