IBM Cloud Functions で bash を動かす

IBM Cloud Functions で bash スクリプト の稼働を確認しました。


#### IBM Cloud Funcitions とは

参考：[IBM Cloud Functins 入門](https://cloud.ibm.com/docs/openwhisk?topic=openwhisk-getting-started)

> IBM Cloud™ Functions では、任意のプログラミング言語を使用して、スケーラブルな方法で、アプリのロジックを実行する軽量のコードを作成することができます。アプリケーションからの HTTP ベースの API 要求によってオンデマンドでコードを実行したり、IBM Cloud サービスやサード・パーティーのイベントへの応答としてコードを実行したりできます。 この Function-as-a-Service (FaaS) プログラミング・プラットフォームは、オープン・ソース・プロジェクトである Apache OpenWhisk を基盤としています。


#### IBM Cloud Functions の Runtime 
IBM Cloud Functions がサポートしている Runtime は以下の通りです。

- JavaScript (Node.js)
- Python
- Swift
- PHP 
- Docker
- その他のランタイム・サポート: Go, Java, Ruby, .Net Core, 

参考：[Runtime](https://cloud.ibm.com/docs/openwhisk?topic=openwhisk-runtimes)


* この記事では、Dockerランタイムを使用して bash のシェル・スクリプトを実施します。

----

#### 前提環境

・Local PC : Mac OS を使用
　　ibmcloud コマンド導入済み
　　ibmcloud functions plugin 導入済み
　　参考：[CLI とプラグインのインストール](https://cloud.ibm.com/docs/openwhisk?topic=openwhisk-cli_install&locale=ja)

・IBM Cloud アカウントを保持している

・IBM Cloud Functions を操作する権限がある

・IBM Cloud Functions 環境が設定済みである

----


#### 手順

#### 1. 準備

~~1-1) 実行したいスクリプトを `exec` という名前に置き換えます。~~ * 実施不要

* 必ずしも exec, exec.zip を作成しなくても良いことがコメントを頂いてわかりましたので修正します。

1-1) 実行したい bash スクリプトを準備します

以前の記事 "[IBM Cloud の File Storage 使用率を確認するスクリプト] (https://qiita.com/c_u/items/f9505dcd2da696d261d7) " で作成した "filestorage.sh (curlコマンドでslack postする後方のスクリプト)" を使用します。


注意：スクリプト・ファイルに 実行権限があること。
　　　実行権限がない場合は変更する。

```
# chmod 755 filestorage.sh

# ls -l
-rwxr-xr-x@ 1 user01  staff  1698 Jul 17 13:08 filestorage.sh
```

~~ファイルのリネームを実行~~  * 実施不要
~~1-2) `exec` を zip に圧縮します~~  * 実施不要


#### 2. IBM Cloud ログイン

2-1) IBM Cloud にログインします。

コマンド例： 

```
# ibmcloud login --apikey < apikey > -r < region > -g < resource group >
```


||項目|内容             |
|:-------:|:---------|:-------------------------------------------------------|
|1| < apikey > |IBM Cloud アカウントに紐づく Functions 操作ができるAPI key。実行する際は対象のAPI key に置き換える|
|2| < region > |実行する際は対象リージョンに置き換える|
|3| < resource group > |実行する際は対象リソースグループに置き換える|


参考:[ ibmcloud login](https://cloud.ibm.com/docs/cli?topic=cli-ibmcloud_cli&locale=ja#ibmcloud_login)

2-2) functions のターゲット・ネームスペースを指定します。

コマンド例

```
# ibmcloud target --cf-api https://api.us-south.cf.cloud.ibm.com -o < Organization > -s < space >
```

||項目|内容             |
|:-------:|:---------|:-------------------------------------------------------|
|1| --cf-api https://xxxxxx.xx.xx | IBM Cloud Functions の エンドポイントを指定 |
|2| -o < Organization > | 実行する際は対象組織に置き換える |
|3| -s "< Space > | 実行する際は対象スペースに置き換える |



または、`ibmcloud target --cf` コマンドで対話的に設定ができます。

参考：[ibmcloud target](https://cloud.ibm.com/docs/cli?topic=cli-ibmcloud_cli&locale=ja#ibmcloud_target)

```
$ ibmcloud target --cf
Targeted Cloud Foundry (https://api.us-south.cf.cloud.ibm.com)


Select an organization (or press enter to skip):
1. AAAAAAA
2. BBBBBBB
Enter a number> 1
Targeted org AAAAAAA


Select a space (or press enter to skip):
1. dev
2. prod
Enter a number> 1
Targeted space prod

API endpoint:      https://cloud.ibm.com
Region:            us-south
User:              xxxx@xx.xxx.xxx
Account:           xxxxx <-> xxxxx
Resource group:    default
CF API endpoint:   https://api.us-south.cf.cloud.ibm.com (API version: 2.148.0)
Org:               AAAAAAA
Space:             dev
```



---

#### 3. アクションの作成

3-1) 環境確認


`ibmcloud fn package list` コマンドでパッケージを確認します。

```
# ibmcloud fn package list
packages
/AAAAAAA_dev/Alert                                                 private
/AAAAAAA_dev/Test                                                  private
```

参考：[ibmcloud fn package list](https://cloud.ibm.com/docs/openwhisk?topic=cloud-functions-cli-plugin-functions-cli#cli_pkg_list)

3-2) Action の作成

対象パッケージ、アクション名を指定して `ibmcloud fn action create <package name>/"<Action name>" exec.zip --native` コマンドを実行します。

**Point** :  --native をつけることで、docker native モードのアクションとして作成されます。

参考：[Docker スケルトン](https://cloud.ibm.com/docs/openwhisk?topic=openwhisk-runtimes&locale=ja#docker-)
> openwhisk/dockerskeleton イメージを使用してアクションをデプロイできます。 --docker openwhisk/dockerskeleton の省略表現として、--native 引数が使用できます。 この引数を使用すると、標準的な Docker アクション SDK 内で実行される実行可能ファイルを作成してデプロイできます。

コマンド実行：

```
# ibmcloud fn action create Test/"test action" filestorage.sh --native
ok: created action Test/test action
```

参考：[ibmcloud fn action create](https://cloud.ibm.com/docs/openwhisk?topic=cloud-functions-cli-plugin-functions-cli#cli_action_create)

確認：
アクションが作成されていることを `ibmcloud fn action get` コマンドで確認します。

参考：[ibmcloud fn action get](https://cloud.ibm.com/docs/openwhisk?topic=cloud-functions-cli-plugin-functions-cli#cli_action_get)

```
# ibmcloud fn action get Test/"test action"
ok: got action Test/test action
{
    "namespace": "AAAAAAA_dev/Test",
    "name": "test action",
    "version": "0.0.1",
    "exec": {
        "kind": "blackbox",
        "image": "openwhisk/dockerskeleton",
        "binary": true
    },
    "annotations": [
        {
            "key": "exec",
            "value": "blackbox"
        }
    ],
    "limits": {
        "timeout": 60000,
        "memory": 256,
        "logs": 10,
        "concurrency": 1
    },
    "publish": false,
    "updated": 1594963158986
}
```

Docker イメージには、[openwhisk/dockerskeleton] (https://hub.docker.com/r/openwhisk/dockerskeleton) が使用されていることがわかります。

参考：
・ apache/openwhisk-runtime-docker:  https://github.com/apache/openwhisk-runtime-docker


#### 4. Action の実行

4-1) Actionの実行

対象パッケージ、アクション名を指定して、`ibmcloud fn action invoke <package>/"action name" --result` コマンドを実施します。

参考：[ibmcloud fn action invoke](https://cloud.ibm.com/docs/openwhisk?topic=cloud-functions-cli-plugin-functions-cli#cli_action_invoke) 

```
# ibmcloud fn action invoke Test/"test action" --result
{
    "error": "The action did not return a dictionary."
}
```
return が dictionary 形式である必要があるようです。

4-2) 実行確認

期待していた実行結果が Slack に出力されました。

---
Action 実行による Slack への出力
![filestoragecheck.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/3e537b38-e6d3-778a-62dc-8613b05d126e.jpeg)

----


#####追記:

以下のような 内容をスクリプトの最後に実行すると、エラーなく functions を終えることができました。

```
echo "{\"exec\": 0,  \"messages\": \"Script End\"}"
```

また、このアクションで Periodic 実行を設定しようと思います。



以上です。