--metadata の怪


Nova のインスタンスや Cinder のボリュームには、メタデータを付ける事ができます。

メタデータって何?

メタデータはキー・バリュー形式の情報です。Python の辞書型データに似ていますが、OpenStack のメタデータはキー・値共に 255 文字の文字列です。

メタデータって何に使うの?

メタデータは課金等への活用が想定されているようですが、現時点では Nova インスタンスのライブマイグレーション程度しか使われていません。使い方は利用者次第です。

メタデータの使い方

例として、cinder コマンドのボリューム作成のヘルプを見てみましょう。

ubuntu@naio:~$ cinder help create
usage: cinder create [--snapshot-id <snapshot-id>] [--image-id <image-id>]
                     [--display-name <display-name>]
                     [--display-description <display-description>]
                     [--volume-type <volume-type>]
                     [--availability-zone <availability-zone>]
                     [--metadata [<key=value> [<key=value> ...]]]
                     <size>
Add a new volume.

Positional arguments:
  <size>                Size of volume in GB

Optional arguments:
  --snapshot-id <snapshot-id>
                        Create volume from snapshot id (Optional,
                        Default=None)
  --image-id <image-id>
                        Create volume from image id (Optional, Default=None)
  --display-name <display-name>
                        Volume name (Optional, Default=None)
  --display-description <display-description>
                        Volume description (Optional, Default=None)
  --volume-type <volume-type>
                        Volume type (Optional, Default=None)
  --availability-zone <availability-zone>
                        Availability zone for volume (Optional, Default=None)
  --metadata [<key=value> [<key=value> ...]]
                        Metadata key=value pairs (Optional, Default=None)

つまり、--metadata key=value key2=valu2 ... とすれば良い事になります。
実際に使ってみましょう。

ubuntu@naio:~$ cinder create --metadata key1=value1 1
usage: cinder create [--snapshot-id <snapshot-id>] [--image-id <image-id>]
                     [--display-name <display-name>]
                     [--display-description <display-description>]
                     [--volume-type <volume-type>]
                     [--availability-zone <availability-zone>]
                     [--metadata [<key=value> [<key=value> ...]]]
                     <size>
error: too few arguments
Try 'cinder help create' for more information.

エラーになりました。文法は合っている筈ですが、何故…?

実は、cinder コマンドのコマンドラインオプションは argparse モジュールによってパースされています。
argparse モジュールは 1 つのコマンドラインオプションを複数指定する方法が複数あります(排他利用)。

  • 「--option <値 > 」全体を列挙する(action='append')
  • 「--option <値 > <値 > ...」と値のみ列挙する(nargs='*')

cinder では --metadata オプションのパースに後者の方法を採用していますが、この方法には 1 つ問題があります。つまり、最後に指定するボリュームのサイズまで --metadata オプションの値と解釈してしまうのです。

この問題の解決策は幾つかあります。

  • --metadata オプションの前にサイズを指定する
    例:cinder create 1 --metadata key=value 
  • --metadata オプションの後に別の -- が付くオプションを使用する
    例:cinder create --metadata key=value --description hoge 1 
  • cinder コマンドを改造して、「--metadata <キー >=<値 >」全体を列挙するようにする

ただ、一番簡単な解決策は↓と思います。

  • --metadata オプション後のボリュームサイズの前に、「--」だけのオプションを付ける
    例:cinder create --metadata key=value -- 1