OpenStack Murano でのカタログ作成手順


# 概要
murano は、OpenStack で、アプリケーションカタログ・サービスを提供します。
この機能を利用すれば、簡単にアプリケーション実行環境を使用することができます。

murano のアーキテクチャは以下の通りとなっており、内部で heat が動作する仕組みとなっています。

<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/3f694dee-4bb8-9332-3a5b-6515b082dc73.png" width=700px>
❶ Murano ダッシュボードを使用して Murano Python Client に対してリクエストを送信
❷ Murano Python Client が Murano API サーバーに対してリクエストを送信
❸ Murano API サーバが RabbitMQ に対してリクエストを送信
❹ Murano conductor がキューからメッセージを取得
❺ Murano conductor がメッセージを構文解析し、heat テンプレートを heat engine に 構成
❻ Murano conductor が実際のデプロイメント実行プランを RabbitMQ に Murano agent タスクとして送信
❼ heat がすべての IaaS レベルのインフラを様々な OpenStack サービスを介してデプロイ
❽ Murano-agent とともに OpenStack サービスのVMプロビジョニングを有効化
❾ vms Murano-agent 上で、Murano conductor によってアサインされた実行プランを取得し、特定の OS 上で、様々なスクリプトを使用して実行

# カタログ作成手順
zip アーカイブファイルの生成方法としては、以下の2通りがあります。

- 自動生成 － `murano package-create`コマンドを使用して、新規 .zip カタログパッケージを生成
- 手動生成 － 標準の murano パッケージの定義フォーマットでいくつかのファイルを手動で圧縮

zip ファイル内の構成は以下の通りです。
<font color="blue">※ [既存のアプリケーションカタログ](https://apps.openstack.org/#tab=murano-apps)をダウンロード後、解凍して参照するのも参考になるかと思います。</font>

|ディレクトリ・ファイル|必須|指定の可否<br>（自動生成）|指定の可否<br>（手動生成）|説明|
|:--|:--:|:--:|:--:|:--|
|*.yaml|必須[^1]|◯|-|HOT ファイル。自動生成の際に指定可能。|
|Classes/|必須[^1]|◯|◯|クラス定義の格納ディレクトリ。|
|┗　*.yaml|必須[^1]|〃|◯|MuranoPL(Murano Programming Language) で定義されたテンプレートファイル。|
|Resources/|(任意)|◯|◯|デプロイメント定義の格納ディレクトリ。|
|┣　*.template|(任意)|〃|◯|実行プラン・テンプレートファイル。|
|┗　scripts/|(任意)|〃|◯|デプロイメントで使用されるスクリプトファイルの格納ディレクトリ。|
|&nbsp;&nbsp;&nbsp;┗　*.sh|(任意)|〃|◯|実行プランテンプレートで記載されているセットアップ実行ファイル。<br>root ユーザーで実行される。|
|UI/|(任意)|◯|◯|動的UI定義の格納ディレクトリ。|
|┗　*.yaml|(任意)|〃|◯|UIの定義ファイル。|
|manifest.yaml|必須|◯[^2]|◯|アプリケーションのエントリポイントとしてのファイル。|
|logo.png|必須|◯[^3]|◯|アプリケーションのロゴとして使用される画像ファイル。 <br>推奨サイズは、70x70 px。|
|images.lst|(任意)|×|◯|必要となるイメージの一覧。[^4]<br>このファイルで指定したイメージは、デプロイ時にmuranoイメージとして取り込まれる。|
|LISENCE|(任意)|×|◯|ライセンスファイル。|

murano アプリケーションカタログ・パッケージ生成のステップは以下の通りとなります。

- 【Step1】必要なファイルの準備
- 【Step2】自動、または手動による murano パッケージ（zip形式）の生成
- 【Step3】murano パッケージ定義のための出力ファイル（zip アーカイブ）のアップロード
- 【Step4】murano アプリケーションのデプロイ

今回は、TensorFlow 実行環境の作成を例に、murano アプリケーションカタログの作成について、
自動生成と手動生成に分けて、順に説明してきます。

## murano アプリケーションの自動生成
最も簡単な方法は、HOT(Heat Orchestration Template) ファイル(\*.yaml) から murano アプリケーションカタログを生成する方法です。

概要で説明した通り murano は、内部で heat と連携しているため、heat テンプレート形式の定義をそのまま利用して、
murano アプリケーションカタログを作成することができます。

その場合、リソース（ネットワーク、ストレージ等）を定義する heat テンプレートを記述し、
その後、murano コマンドを使用して zip アーカイブファイルを生成します。

上述の zip ファイル内のディレクトリおよびファイルを作成し、murano コマンドの引数でそれぞれ指定することもできます。

### 【Step1】必要なファイルの準備
自動生成の場合、最小限必要なファイルは HOT テンプレートのみです。

#### HOT(Heat Orchestration Template) ファイル
環境を定義した HOT ファイルを作成します。
<font color="blue">※ 今回使用した HOT ファイルは、GitHub[^5]にアップしていますので、よろしければご活用ください。</font>

※ HOT ファイルの書き方は今回は割愛しますので、[Heat Orchestration Template (HOT) Guide](http://docs.openstack.org/developer/heat/template_guide/hot_guide.html)をご覧いただければと思います。

`heat`コマンドで事前に動作確認を使用します。

```bash
$ heat stack-create <作成するstack名> --template-file tensorflow.yaml -P key_name=<キーペア名>
+--------------------------------------+-----------------------+--------------------+---------------------+---------------------+
| id                                   | stack_name            | stack_status       | creation_time       | updated_time        |
+--------------------------------------+-----------------------+--------------------+---------------------+---------------------+
| d8a326c0-329a-4df3-bff6-27124bf088ae | tensorflow01          | CREATE_IN_PROGRESS | 2016-08-08T05:49:40 | None                |
+--------------------------------------+-----------------------+--------------------+---------------------+---------------------+
```

### 【Step2】murano パッケージの生成
`murano package-create` コマンドを使用して、murano アプリケーションカタログ(*.zip)を作成します。
<font color="red">※ 以下のコマンド例で実行する際には、事前に logo.png を準備しておく必要があります。</font>

```bash
# "--template" で HOT ファイルを指定する例
$ murano package-create \
--template murano-catalog/TensorFlowServer_HOT/tensorflow.yaml \
--logo murano-catalog/TensorFlowServer_HOT/logo.png
```

--class-dir やその他のパラメータを指定して実行することもできます。
※ 使用する各ファイルは手動生成の手順内をご参照ください。

```bash
# "--classes-dir" を指定する例
$ murano package-create \
--classes-dir murano-catalog/TensorFlowServer/Classes/ \
--resources-dir murano-catalog/TensorFlowServer/Resources/ \
--name "TensorFlow Server" \
--full-name com.example.tensorflow.TensorFlowServer \
--author "Mirantis, Inc" \
--tags "TensorFlow" "Server" "AI" "Machine Language" \
--description "TensorFlow is an open source software library for numerical computation using data flow graphs. Nodes in the graph represent mathematical operations, while the graph edges represent the multidimensional data arrays (tensors) communicated between them. The flexible architecture allows you to deploy computation to one or more CPUs or GPUs in a desktop, server, or mobile device with a single API." \
--output tensorflow.zip \
--ui murano-catalog/TensorFlowServer/UI/ui.yaml \
--type Application \
--logo murano-catalog/TensorFlowServer/logo.png
```

### 【Step3】murano パッケージ登録
horizon ダッシュボードを使用して、murano パッケージの zip アーカイブファイルをアップロードする方法は以下の通り。

・「Import Package」ボタンを押下します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/3ea6ac9f-77d0-adfb-24b0-578adc7dbb39.jpeg" width=800px>

・Murano アプリケーションカタログを選択し、「Next」ボタンを押下します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/cc1c2a6b-5614-d93e-884e-7c4d3c98a843.jpeg" width=600px>

・パッケージ名等を入力し、「Next」ボタンを押下します。
（`manifest.yaml`ファイルに定義されている情報がデフォルトで表示されます。）
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/db56fc4e-95de-4bd1-2b67-7488432a48a5.jpeg" width=600px>

・カテゴリを選択し、「Create」ボタンを押下します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/f979316a-c86a-525a-5cc7-3cfda4d5ffb9.jpeg" width=600px>

・[Manage] - [Packages] ページに先ほど登録したパッケージが表示されていることを確認します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/9f9c2419-9c42-ca31-cda6-e7fc203b18de.jpeg" width=800px>

以下の様に CLI で murano パッケージを登録することもできます。

```bash
$ murano package-import ¥
--is-public ¥
--package-version 0.0.0 ¥
--exists-action u ¥
tensorflow.zip
```

・CLI にて murano パッケージとして登録されたことを確認してみます。

```bash
$ murano package-list
Could not initialise glance client. Image creation will be unavailable.
+--------------------------------------+--------------+-------------------------------------+-----------+--------+-----------+-------------+
| ID                                   | Name         | FQN                                 | Author    | Active | Is Public | Type        |
+--------------------------------------+--------------+-------------------------------------+-----------+--------+-----------+-------------+
| a2d74fc8-2096-4a50-be79-c2b34cc968c9 | Core library | io.murano                           | murano.io | True   |           | Library     |
| dd73a18d-625a-4f10-bd89-da903597ed92 | TensorFlow   | io.murano.apps.generated.Tensorflow | admin     | True   |           | Application |
+--------------------------------------+--------------+-------------------------------------+-----------+--------+-----------+-------------+
```


### 【Step4】murano アプリケーションのデプロイ
[Catalog] > [Brouse] を開き、先ほど登録した murano パッケージが表示されているのを確認できたら、
以下の手順の通り、Quick Deploy を使用して簡単にデプロイを行っていきます。
<font color="#ff0000">注) デプロイ前に、使用する Compute Image および KeyPair を事前に登録しておく必要があります。</font>

・作成したパッケージの「Quick Deploy」ボタンを押下します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/59e9d87d-1e66-8ad5-16c4-7952f04108b5.jpeg" width=800px>

・アプリケーション名を入力し、「Next」ボタンを押下します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/6c676a6d-15eb-1e5f-274b-3e3b2f4e19ef.jpeg" width=600px>

・HOT ファイルの定義に従い、項目が表示されるので、各値を入力し、「Create」ボタンを押下します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/b65cdb3c-3668-12e6-422c-96eb29cfd1a6.jpeg" width=600px>

・自動で、Environment[^6] が作成され、先ほど作成したアプリケーションが配置されるているのを確認したら、
「Deploy This Environment」ボタンを押下して、デプロイを開始します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/a209e545-a729-8eb9-72e6-17bc380047b5.jpeg" width=800px>

・Status が `Ready`となったらデプロイ完了となります。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/139dac6f-8322-34ea-ca34-5ff7dc93e541.jpeg" width=800px>

### 【Step5】デプロイ後の確認
・CLI にて、murano アプリケーションが正常にデプロイできたことを確認してみます。

```bash
$ murano environment-list
Could not initialise glance client. Image creation will be unavailable.
+----------------------------------+-------------+--------+---------------------+---------------------+
| ID                               | Name        | Status | Created             | Updated             |
+----------------------------------+-------------+--------+---------------------+---------------------+
| 9d8534e10bfb4fa98a91da86a088ba8c | quick-env-1 | ready  | 2016-08-15T04:46:41 | 2016-08-15T04:48:05 |
+----------------------------------+-------------+--------+---------------------+---------------------+

$ murano environment-show quick-env-1
Could not initialise glance client. Image creation will be unavailable.
+-------------+-----------------------------------------------------------------------------------------+
| Property    | Value                                                                                   |
+-------------+-----------------------------------------------------------------------------------------+
| acquired_by | None                                                                                    |
| created     | 2016-08-15T04:46:41                                                                     |
| id          | 9d8534e10bfb4fa98a91da86a088ba8c                                                        |
| name        | quick-env-1                                                                             |
| services    | [                                                                                       |
|             |   {                                                                                     |
|             |     "name": "tensorflow01",                                                             |
|             |     "templateOutputs": {                                                                |
|             |       "server_private_ip": "192.168.111.17",                                            |
|             |       "server_public_ip": "{u'_attr': (u'server_floating_ip', u'floating_ip_address')}" |
|             |     },                                                                                  |
|             |     "generatedHeatStackName": null,                                                     |
|             |     "hotEnvironment": null,                                                             |
|             |     "templateParameters": {                                                             |
|             |       "server_name": "tensorflow",                                                      |
|             |       "key_name": "test",                                                               |
|             |       "image": "ubuntu-14.04-m-agent.qcow2",                                            |
|             |       "public_net_id": "admin_floating_net",                                            |
|             |       "private_net_id": "admin_internal_net",                                           |
|             |       "flavor": "m1.small",                                                             |
|             |       "private_subnet_id": "admin_internal_net__subnet"                                 |
|             |     },                                                                                  |
|             |     "?": {                                                                              |
|             |       "classVersion": "0.0.0",                                                          |
|             |       "_26411a1861294160833743e45d0eaad9": {                                            |
|             |         "name": "TensorFlow"                                                            |
|             |       },                                                                                |
|             |       "name": null,                                                                     |
|             |       "package": "io.murano.apps.generated.Tensorflow",                                 |
|             |       "_actions": {},                                                                   |
|             |       "status": "ready",                                                                |
|             |       "type": "io.murano.apps.generated.Tensorflow",                                    |
|             |       "id": "289e04ee-9e2c-41f9-ba4a-5215c3fca924"                                      |
|             |     }                                                                                   |
|             |   }                                                                                     |
|             | ]                                                                                       |
| status      | ready                                                                                   |
| tenant_id   | 01a145abf4fa48f3aed142944e59d92c                                                        |
| updated     | 2016-08-15T04:48:05                                                                     |
| version     | 1                                                                                       |
+-------------+-----------------------------------------------------------------------------------------+
```

・正常にデプロイが完了している場合、[Project] - [Compute] - [Instances] から HOTファイルで定義したインスタンスを確認することができます。
<font color="blue">※ murano の Environment を削除した場合、連動してこのインスタンスも削除されます。</font>
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/0280e330-4048-0e9d-c006-ce42b07a4b7d.jpeg" width=800px>

・作成されたインスタンスに ssh 接続し、動作確認します。

```bash
$ python test.py
Hello, TensorFlow!
```

murano パッケージのデプロイ完了後には、heat の stack が追加されていることが確認できます。

```bash
$ heat stack-list
+--------------------------------------+-------------------------------------------------+-----------------+---------------------+--------------+
| id                                   | stack_name                                      | stack_status    | creation_time       | updated_time |
+--------------------------------------+-------------------------------------------------+-----------------+---------------------+--------------+
| a82553fd-f193-4c82-97f0-5376ebd9c382 | mggewirvk6vaxm_9d8534e10bfb4fa98a91da86a088ba8c | CREATE_COMPLETE | 2016-08-15T04:47:26 | None         |
+--------------------------------------+-------------------------------------------------+-----------------+---------------------+--------------+
```



## murano アプリケーションの手動生成
### 【Step1】必要なファイルの準備
本記事作成時に使用したコードについては、GitHub[^7]にアップしておりますので、よろしければご活用ください。

#### Classes/*.yaml
MuranoPL(Murano Programming Language) で定義されたテンプレートファイル。
murano パッケージの定義をするファイル。

```yaml
<省略>
# Namespace 定義
#   com.example.<パッケージ名> - デモ用のパッケージ
#   org.openstack.projectName.<パッケージ名> - 公式の OpenStack プロジェクトのチームによって開発・保守されているパッケージ
#   com.companyname.<パッケージ名> - サードパーティによって管理されているパッケージ
#                                  （このケースでは、ドメイン名が "companyname.com"）
#   io.murano.<パッケージ名> - コアの murano チームメンバーによって、murano プロジェクトとして管理されているパッケージ
Namespaces:
  =: com.example.tensorflow
# 省略したクラス名の定義
#   ※ 以下の例では、"std:Hoge" と記述した場合、"io.murano.Hoge" として扱われる。
  std: io.murano
  res: io.murano.resources
  sys: io.murano.system

# クラス名
Name: TensorFlowServer

# 上位クラスの定義
Extends: std:Application

# プロパティの宣言
Properties:
  name:
    Contract: $.string().notNull()
  instance:
    Contract: $.class(res:Instance).notNull()

# メソッドの定義
#  <メソッド名>の子要素として、それぞれ、引数(Arguments)と順次処理の内容(Body)が定義できる。
Methods:
  initialize:
    Body:
      - $._environment: $.find(std:Environment).require()
  deploy:
    Body:
      - If: not $.getAttr(deployed, false)
        Then:
          - $._environment.reporter.report($this, 'Creating VM for TensorFlow Server.')
          - $securityGroupIngress:
            - ToPort: 65535
              FromPort: 1
              IpProtocol: tcp
              External: true
          - $._environment.securityGroupManager.addGroupIngress($securityGroupIngress)
          - $.instance.deploy()
          - $resources: new(sys:Resources)
          - $template: $resources.yaml('DeployTensorFlow.template')
          - $._environment.reporter.report($this, 'Instance is created. Deploying TensorFlow')
          - $.instance.agent.call($template, $resources)
          - $._environment.reporter.report($this, 'TensorFlow is installed.')
          - $.setAttr(deployed, true)
```

#### Resources/*.template
実行プラン・テンプレートファイル。

```yaml
FormatVersion: 2.0.0  # 実行プランで使用する構文フォーマットのバージョン
Version: 1.0.0  # 実行プランのバージョン
Name: Deploy TensorFlow  # 実行プラン名

Parameters:

Body: |
    tensorflowDeploy()
Scripts:
  tensorflowDeploy:
    Type: Application
    Version: 1.0.0
    EntryPoint: runTensorFlowDeploy.sh  # scripts ディレクトリ配下に配置するファイル名を記述
    Files: []
    Options:
      captureStdout: true
      captureStderr: true
```

#### Resources/scripts/*.sh
実行プラン・テンプレートで記載されているセットアップ実行ファイル。
root 権限で実行される。

#### UI/*.yaml
UIの定義ファイル。

```yaml
Version: 2

Application:
  ?:
    type: com.example.tensorflow.TensorFlowServer
  name: $.appConfiguration.name
  instance:
    ?:
      type: io.murano.resources.LinuxMuranoInstance
    name: generateHostname($.instanceConfiguration.unitNamingPattern, 1)
    flavor: $.instanceConfiguration.flavor
    image: $.instanceConfiguration.osImage
    keyname: $.instanceConfiguration.keyPair
    availabilityZone: $.instanceConfiguration.availabilityZone
    assignFloatingIp: $.appConfiguration.assignFloatingIP

Forms:
# UI に表示するアプリケーションカタログの設定項目
  - appConfiguration:
      fields:
        - name: license
          type: string
          description: Apache License, Version 2.0
          hidden: true
          required: false
        - name: name
          type: string
          label: Application Name
          initial: 'TensorFlowServer'
          description: >-
            Enter a desired name for the application. Just A-Z, a-z, 0-9, dash and
            underline are allowed
        - name: assignFloatingIP
          type: boolean
          label: Assign Floating IP
          description: >-
             Select to true to assign floating IP automatically
          initial: false
          required: false
          widgetMedia:
            css: {all: ['muranodashboard/css/checkbox.css']}
        - name: dcInstances
          type: integer
          hidden: true
          initial: 1

# UI に表示するインスタンスの設定項目
  - instanceConfiguration:
      fields:
        - name: title
          type: string
          required: false
          hidden: true
          description: Specify some instance parameters on which the application would be created
        - name: flavor
          type: flavor
          label: Instance flavor
          description: >-
            Select registered in Openstack flavor. Consider that application performance
            depends on this parameter.
          required: false
        - name: osImage
          type: image
          imageType: linux
          label: Instance image
          description: >-
            Select valid image for the application. Image should already be prepared and
            registered in glance.
        - name: keyPair
          type: keypair
          label: Key Pair
          description: >-
            Select the Key Pair to control access to instances. You can login to
            instances using this KeyPair after the deployment of application.
          required: false
        - name: availabilityZone
          type: azone
          label: Availability zone
          description: Select availability zone where application would be installed.
          required: false
        - name: unitNamingPattern
          type: string
          label: Instance Naming Pattern
          required: false
          maxLength: 64
          regexpValidator: '^[a-zA-z][-_\w]*$'
          errorMessages:
            invalid: Just letters, numbers, underscores and hyphens are allowed.
          helpText: Just letters, numbers, underscores and hyphens are allowed.
          description: >-
            Specify a string, that will be used in instance hostname.
            Just A-Z, a-z, 0-9, dash and underline are allowed.
```

fields に設定する type の有効な値は以下の通り。（2016年8月16日現在）

|type値|説明|
|:--|:--|
|string|一行の文字列（重複チェックは行わない）|
|boolean|boolean。入力はチェックボックス形式。|
|text|扱いは "string" と同じ。複数行の文字列入力。|
|integer|妥当性チェック伴う整数。一行のテキスト入力。|
|password|強固なパスワードチェックを伴うテキスト。入力は、２つのマスクされたテキストフォーム。（２つ目は入力確認）|
|clusterip|特殊テキスト項目。クラスタIPアドレスの入力として使用。（IPアドレス形式チェックを行う）|
|databaselist|特殊項目。カンマ区切りのデータベース名のリスト。一行のテキスト入力。|
|image|特殊項目。glance プロパティで murano 用のメタデータが付与されているイメージをフィルタリング表示として使用。|
|flavor|特殊項目。インスタンスのフレーバーのリスト選択として使用。|
|keypair|特殊項目。キーペアのリスト選択として使用。|
|azone|特殊項目。インスタンス・アベイラビリティゾーンのリスト選択として使用。|
|network|特殊項目。ユーザーが使用可能なネットワークおよびサブネットのリスト選択として使用。|

#### manifest.yaml
アプリケーションのエントリポイントとしてのファイル。
murano パッケージ作成の際に、ここで定義されている情報がデフォルトで使用される。

```yaml
# manifest で使用する構文フォーマットのバージョン
Format: 1.0

# アプリケーションのタイプ（"Application" または "Library" を指定）
Type: Application

# Murano カタログで、アプリケーション認証で使用されるユニークな名称。
FullName: com.example.tensorflow.TensorFlowServer

# 表示用のアプリケーション名
Name: TensorFlow Server

# アプリケーションに関する詳細な説明
Description: TensorFlow is an open source software library for numerical computation
  using data flow graphs. Nodes in the graph represent mathematical operations, while
  the graph edges represent the multidimensional data arrays (tensors) communicated
  between them. The flexible architecture allows you to deploy computation to one
  or more CPUs or GPUs in a desktop, server, or mobile device with a single API.

# アプリケーションパッケージを作成した個人名、または企業名
Author: Mirantis, Inc

# 検索用タグ 
Tags: [TensorFlow, Server, AI, Deep Leaning]

# MuranoPL のクラス一覧（ファイル名、クラス名を一致させること）
Classes:
 com.example.tensorflow.TensorFlowServer: TensorFlowServer.yaml
```

#### logo.png
アプリケーションのロゴとして使用される画像ファイル。
推奨サイズは、70x70 px。
このアイコンは、murano アプリケーションカタログを表示する際に使用されます。

#### images.lst
必要となるイメージの一覧。[^4]
任意作成。
このファイルで指定したイメージは、パッケージ登録時に glance イメージに登録され、murano で使用するイメージとして自動でタグ付けされます。
<font color="red">※上記のアクションは、glance イメージとして未登録の場合にのみ処理されるため、murano イメージのみ削除した場合は、デプロイ前に手動で登録しておく必要があります。（2016年8月16日現在）</font>

```yaml
Images:
- Name: 'ubuntu-14.04-m-agent.qcow2'  # イメージファイル名
  Hash: '393d4f2a7446ab9804fc96f98b3c9ba1'  # イメージファイルの hash コード
  Meta:
    title: 'Ubuntu 14.04 x64 (pre-installed murano-agent)' 
    type: 'linux'
  DiskFormat: qcow2  # イメージのディスク形式。（"ami"、"ari"、"aki"、"vhd"、"vmdk"、"raw"、"qcow2"、"vdi"、"iso" のいずれかを指定
  ContainerFormat: bare  # イメージのコンテナー形式。（"ami"、"ari"、"aki"、"docker"、"bare"、"ovf" のいずれかを指定）
```

#### LISENCE
ライセンスファイルなど含めるファイルがある場合は作成します。。

### 【Step2】murano パッケージの生成
Step1 を参考にファイルを準備した後、zip 形式で圧縮します。。

```bash
$ cd ~/murano-catalog/TensorFlowServer/
$ zip -r ~/tensorflow.zip *
```

### 【Step3】murano パッケージ登録
・Horizon、または、CLI より、Step2 で作成したパッケージの登録を行います。
<font color="blue">※ 手動生成手順と同様のため、ここでは説明を割愛します。</font>

・正常にパッケージ登録が完了すると murano のパッケージ一覧に以下のように表示されます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/9e128c17-9322-4568-3b26-f32b8f885016.jpeg" width=800px>

・`images.lst` が定義されている場合、以下のように glance イメージが登録され、murano イメージとして紐づけされます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/e5e84a27-c51d-7d07-cbf4-2d055de96cb8.jpeg" width=700px>

&nbsp;&nbsp;・glance イメージ一覧
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/8056b976-43e7-c4b8-975b-08b1f16b7515.jpeg" width=800px>

&nbsp;&nbsp;・murano イメージ一覧
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/4aee3001-739f-5931-26b4-b775e204c5a8.jpeg" width=800px>

### 【Step4】murano アプリケーションのデプロイ
デプロイ手順は、手動生成の際と同様です。
デプロイの際の UI は、UI 定義ファイルに記述した入力項目が表示されます。

・今回は、[Catalog] - [Browse] の "Quick Deploy" でインストールしていきます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/2059badf-b5a6-b3dc-26a3-61341679c3ec.jpeg" width=600px>

・ui.yaml の Forms:appConfiguration:fields で設定した項目が表示されるので、任意の値を入力し、"Next" ボタンを押下します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/947b3cee-da9a-102b-f032-83023974955b.jpeg" width=600px>

・ui.yaml の Forms:instanceConfiguration:fields で設定した項目が表示されるので、任意の値を入力し、"Next" ボタンを押下します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/6f1b1863-dd16-7220-6466-291e5e9da371.jpeg" width=600px>

・"Deploy This Environment" ボタンを押下してデプロイを開始します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/92e9248c-c13a-3376-9786-ae229dad6c30.jpeg" width=800px>

・以下のように表示されていれば、デプロイ成功です。
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/9db7d234-ec59-ee8b-a9a7-722a9a4d380b.jpeg" width=800px>




### 【Step5】デプロイ後の確認
・CLI にて、murano アプリケーションが正常にデプロイできたことを確認していきます。

```bash
$ murano environment-list


$ murano environment-show quick-env-1

```

・正常にデプロイが完了している場合、[Project] - [Compute] - [Instances] から HOTファイルで定義したインスタンスを確認することができます。
<font color="blue">※ murano の Environment を削除した場合、連動してこのインスタンスも削除されます。</font>
<img src="https://qiita-image-store.s3.amazonaws.com/0/129198/0280e330-4048-0e9d-c006-ce42b07a4b7d.jpeg" width=800px>

・作成されたインスタンスに ssh 接続し、動作確認します。

```bash
$ python test.py
Hello, TensorFlow!
```

murano パッケージのデプロイ完了後、murano アプリケーションパッケージを自動生成した場合と同様に
heat の stack が追加されていることを確認することができます。

```bash
$ heat stack-list
+--------------------------------------+-----------------------+-----------------+---------------------+---------------------+
| id                                   | stack_name            | stack_status    | creation_time       | updated_time        |
+--------------------------------------+-----------------------+-----------------+---------------------+---------------------+
| 16ac5d6c-7bc2-4f67-aed1-40194e1aa66a | murano-ulaiwirymgf8sv | UPDATE_COMPLETE | 2016-08-17T08:14:11 | 2016-08-17T08:14:44 |
+--------------------------------------+-----------------------+-----------------+---------------------+---------------------+
```

# 参考 URL
- https://wiki.openstack.org/wiki/Murano/Documentation/How_to_create_new_app_on_murano_application_catalog_automatically
- https://wiki.openstack.org/wiki/Murano/Documentation/How_to_create_application_package
- http://www.slideshare.net/opendecoy/openstack-murano-introduction

# 注釈
[^1]: 自動生成の場合、HOT テンプレート、または Classes ディレクトリのいずれかの指定が必須
[^2]: "murano package-create" コマンド実行時に自動生成される。
[^3]: 未指定の場合、自動生成される。
[^4]: [こちら](https://apps.openstack.org/#tab=glance-images)にアクセスし、murano-agnet が入っている glance イメージを指定する。
[^5]: [手動生成ソースコード（GitHub）](https://github.com/falcon39/murano-catalog/tree/master/TensorFlowServer_HOT)
[^6]: Environment は、仮想の murano アプリケーション環境です。
[^7]: [自動生成ソースコード（GitHub）](https://github.com/falcon39/murano-catalog/tree/master/TensorFlowServer)