インタラクティブモードで依存関係をインストールする方法

このチュートリアルは、「How to Develop Function Compute」シリーズの一部です。このチュートリアルでは、対話形式で**依存関係をインストール**する方法を説明します。

#はじめに
まず、この記事で紹介されているいくつかの重要な概念について、簡単に説明します。

- Function Compute：イベントドリブンなサービスで、ユーザーはサーバーなどのインフラを管理する必要がなく、コードの作成やアップロードに集中することができます。Function Computeはコンピュートリソースを提供し、ユーザーはコードを実行する際に消費されるリソースに対して料金を支払うだけで、より弾力的にコードを実行することができます。Function Computeの詳細については、[こちら](https://www.alibabacloud.com/products/function-compute?spm=a2c65.11461447.0.0.59771221LowwyF)をご覧ください。
- Fun： Funcraftとも呼ばれ、Function Compute、API Gateway、Log Serviceなどのリソースの管理を支援するサーバーレスアプリケーション向けの開発ツールです。Funを使って、`template.yml`ファイルで指定したリソースを定義することで、リソースの開発、ビルド、デプロイを行うことができます。Funの詳細については、[こちら](https://github.com/alibaba/funcraft/blob/master/README-en.md?spm=a2c65.11461447.0.0.59771221LowwyF&file=README-en.md)をご覧ください。
注）本記事の操作は、Fun 3.0.0-beta.1以降のバージョンに適用されます。

#依存するツール
本プロジェクトの開発は、MacOSをベースにしています。しかし、関係するツールはプラットフォームに依存せず、LinuxやWindowsのOSにも適用できます。例題を進める前に、以下のツールが正しくインストールされ、最新バージョンにアップデートされ、適切に設定されていることを確認してください。

- [Docker](https://www.docker.com/?spm=a2c65.11461447.0.0.59771221LowwyF)
- [Fun](https://github.com/alibaba/funcraft/blob/master/README-en.md?spm=a2c65.11461447.0.0.59771221LowwyF&file=README-en.md)

FunはDockerをベースに、ローカル環境をシミュレートします。

MacOSユーザーは、[homebrew](https://brew.sh/?spm=a2c65.11461447.0.0.59771221LowwyF)を使ってこれらのツールをインストールすることができます。

```
brew cask install docker
brew tap vangie/formula
brew install fun
```

WindowsとLinuxのユーザーは、[この記事](https://github.com/aliyun/fun/blob/master/docs/usage/installation.md?spm=a2c65.11461447.0.0.59771221LowwyF&file=installation.md)を読んで、これらのツールをうまくインストールしてください。

インストールが完了したら、まず`fun config`コマンドを実行して設定を初期化します。

注：Funのバージョンは必ず3.0.0-beta.1またはそれ以降のバージョンを使用してください。

```
$ fun --version
3.0.0-beta.1
```

#背景
Function Computeでは、合意された成果物としてZipファイルを使用しており、通常はコードと依存関係を含んでいます。これらの依存関係は、一般的に、apt-getによってインストール・管理されるシステム依存関係と、NPMやpipなどの言語関連パッケージ・マネージャーによってインストールされる言語ランタイム依存関係です。

#システム依存性は一般的に移植性がない
システムの依存性は、通常、環境に関連しています。例えば、`brew install brotli`コマンドを実行すると、MacOSを使用する開発マシンにbrotliがインストールされ、Function Computeにパッケージ化されます。その後、ファイルを解凍するbrotliコマンドを実行するために関数を呼び出すと、関数の呼び出しに失敗します。また、Linuxを使用している開発機でも、関数の呼び出しに失敗することがあります。これは、システムが提供するパッケージ・マネージャでインストールされる実行プログラムやダイナミックリンクライブラリが、システムの種類やバージョンに強く関係しているためです。Mac、Windows、Linuxなどの異なるシステムにインストールされたプログラムやファイルは、相互に移植できません。

#言語依存は移植不可能
一般的に、言語依存関係はプラットフォームに依存しません。例えば、Node.jsの依存関係をインストールするために`npm install jszip`コマンドを実行したとします。その結果、その依存関係は異なるOSや異なるNode.jsのバージョンで動作する可能性があります。言語プラットフォームの依存関係は、通常、ポータブルです。ただし、例外がある場合もあります。例えば、npm install node-ptyは、ネイティブバインディングを用いた例です。node-ptyモジュールのインストールは、いくつかのC/C ++コードに依存しており、それらはインストールの過程でコンパイルされます。C/C++コードは異なるプラットフォーム間で移植性がありますが、コンパイル後は移植性のないコードになります。

#DSLスクリプトの限界
Fun 2.0はDSLファイル(`fun.yml`)を使って依存関係を一括してインストールすることをサポートしています。`fun install —package-type pip tensorflow`のように、日常的な開発のためのコマンドラインモードも用意されています。Fun 3.0では、新しいDSLファイル、すなわちFunfileを提供します。FunfileはDockerfileのシンタックスサブセットと考えてください。そのため、Dockerに慣れている開発者はすぐに始められるでしょう。

しかし、`fun.yml`、Funfile、コマンドラインモードのどれを使っても、開発者にとっては痛いところがあります。現在の環境が不明で、以下のような点が考えられます。

1) どんなソフトウェアがインストールされているか？
2) 特定のディレクトリにどんなファイルがあるか？
3) それぞれのファイルの内容と属性は何か？

開発者には、インタラクションを伴うサンドボックス環境が必要です。しかし、この機能はFun 2.0にはありません。その代わり、ユーザーは`fcli sbox`コマンドを実行したり、[fc-docker](https://yq.aliyun.com/go/articleRenderRedirect?spm=a2c65.11461447.0.0.59771221LowwyF&url=https%3A%2F%2Fgithub.com%2Faliyun%2Ffc-docker)で提供されるイメージを直接使用して、`docker run --rm -it -v $(pwd):/code aliyunfc/runtime-python2.7:bash`コマンドでコンテナを起動することが多いです。しかし、ユーザーはこれらの複雑なコマンドやパラメータを使用する前に、DockerとFunction Computeをよく知っている必要があります。

これらの問題を解決し、ユーザーの開発体験を向上させるために、Fun 3.0では`fun install sbox`サブコマンドを提供しています。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/f095f1cc-72c4-edbd-60a7-d6636d035958.png)

#コマンドラインパラメータ
以下のコマンドラインパラメーターを参照してください。

```
$ fun install sbox --help
Usage: fun install sbox [-f|--function <[service/]function>] [-r|--runtime <runtime>] [-i|--interactive] [-e|--env key=val ...] [-e|--cmd <cmd>]

Start a local sandbox for installation dependencies or configuration

Options:
  -f, --function <[service/]function>  Specify which function to execute installation task.
  -r, --runtime <runtime>              function runtime, avaliable choice is: nodejs6, nodejs8, nodejs10, python2.7, python3, java8, php7.2, custom
  -i, --interactive                    run as interactive mode. Keep STDIN open and allocate a pseudo-TTY when in a interactive shell. (default: false)
  -e, --env <env>                      environment variable, ex. -e PATH=/code/bin (default: [])
  -c, --cmd <cmd>                      command with arguments to execute inside the installation sandbox.
  -h, --help                           output usage information
```

#クイックスタート
[Pyzbar_example](https://github.com/alibaba/funcraft/blob/master/examples/install/pyzbar_example/index.py?spm=a2c65.11461447.0.0.59771221LowwyF&file=index.py)プロジェクトを例に説明します。`pyzbar_example`プロジェクトには以下のファイルが含まれています。

```
$  tree .             
.
©À©¤©¤ fun.yml
©À©¤©¤ index.py
©À©¤©¤ qrcode.png
©¸©¤©¤ template.yml

0 directories, 4 files
```

次のスニペットは、`template.yml`ファイルの内容を表示しています。


```
ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
 pyzbar-srv:
   Type: 'Aliyun::Serverless::Service'
   pyzbar-fun:
     Type: 'Aliyun::Serverless::Function'
     Properties:
       Handler: index.handler
       Runtime: python3
       Timeout: 60
       MemorySize: 128
       CodeUri: .
```

#インタラクティブモードでのサンドボックスの有効化

```
$ fun install sbox -f pyzbar-fun -i
using template: template.yml
root@fc-python3:/code# ls
fun.yml  index.py  qrcode.png  template.yml
root@fc-python3:/code# exit
exit
$
```

`template.yml`が存在するディレクトリで、fun install sboxコマンドを実行します。

- -f/-- function：サンドボックスを起動するための関数を指定します。この例では，関数に設定されているランタイムはPython 3です。したがって，Python 3 環境のサンドボックスが有効になります。pyzbar-fun関数に対応するCodeUriディレクトリは，サンドボックス環境内の/codeディレクトリにマウントされており，サンドボックス環境で`ls`コマンドを実行した後に返されるファイルリストで確認できます。
- -i/-- interactive：インタラクティブモードを有効にします。非対話型モードの使い方は後ほど紹介します。

`template.yml`ファイルが存在しない場合や，`template.yml`ファイル内の関数が設定されていない場合は，--runtimeパラメータを指定することで，インタラクティブ・モードが起動します。この場合，カレント・ディレクトリはサンドボックス環境の /code ディレクトリにマウントされます。

```
$ fun install sbox -r nodejs10 -i                                               
root@fc-nodejs10:/code# ls
fun.yml  index.py  qrcode.png  template.yml
root@fc-nodejs10:/code# exit
exit
$
```

上記の方法は、実験用のサンドボックスを一時的に起動する場合に適用されます。

#fun-install を使って apt と pip の依存関係をインストールする
以下のコマンドを実行して、apt と pip をインストールします。



```
$ fun install sbox -f pyzbar-fun -i          
using template: template.yml
root@fc-python3:/code# fun-install apt-get install libblas3
Task => [UNNAMED]
     => apt-get update (if need)
     => apt-get install -y -d -o=dir::cache=/code/.fun/tmp libblas3
     => bash -c 
        for f in $(ls /code/.fun/tmp/archives/*.deb); do
          dpkg -x $f /code/.fun/root; 
          mkdir -p /code/.fun/tmp/deb-control/${f%.*}; 
          dpkg -e $f /code/.fun/tmp/deb-control/${f%.*}; 

          if [ -f "/code/.fun/tmp/deb-control/${f%.*}/postinst" ]; then 
            FUN_INSTALL_LOCAL=true /code/.fun/tmp/deb-control/${f%.*}/postinst configure;
          fi; 
        done;
     => bash -c 'rm -rf /code/.fun/tmp/archives'
root@fc-python3:/code# fun-install --help
Usage: fun local [options] [command]

build function codes or install related depedencies for Function Compute

Options:
  -h, --help  output usage information

Commands:
  apt-get     install apt depencies
  pip         install pip depencies
  build       build function codes for Function Compute
  help [cmd]  display help for [cmd]
```

#非対話型モードでのサンドボックスの使用
pyzbar-fun関数のSandboxにプレインストールされたdebパッケージを表示するには、次のコマンドを実行します。



```
$ fun install sbox -f pyzbar-fun -c 'dpkg -l'
using template: template.yml
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                               Version                          Architecture Description
+++-==================================-================================-============-===============================================================================
ii  acl                                2.2.52-2                         amd64        Access control list utilities
ii  adduser                            3.113+nmu3                       all          add and remove users and groups
ii  apt                                1.0.9.8.4                        amd64        commandline package manager
ii  apt-utils                          1.0.9.8.5                        amd64        package management related utility programs
ii  autoconf                           2.69-8                           all          automatic configure script builder
ii  automake                           1:1.14.1-4+deb8u1                all          Tool for generating GNU Standards-compliant Makefiles
...(´Ë´¦Ê¡ÂÔÁËÐí¶àÐÐ)
```

また、以下のコマンドを実行すると、外部コマンドの出力をパイプライン経由で内部システムに送ることができます。

```
$  echo hello | fun install sbox -r nodejs10  -i -c 'cat -'
hello
```

注：標準入力を受け付けることを示す`-i`パラメーターを指定します。

#概要
fun install sbox コマンドは，fcli sbox コマンドの代替コマンドです。fun install sbox コマンドは、対話モードのサポートに加えて、指定されたランタイムの指定された関数を介してサンドボックスを起動します。次に、fun install sboxコマンドは、インラインコマンドやパイプラインなどの非対話型モードでも使用することができ、スクリプトの作成が容易になります。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/how-to-develop-function-compute---installing-dependencies-in-interactive-mode_596084)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*


*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*