IDCFクラウドのCoreOSにAPIから設置できるcloud-config.ymlのサイズ問題


（ここに書かれている内容は2015年2月13日時点のものです）

IDCFクラウドはCloudStackなので、EC2と同じくAPI経由で操作できます。

CloudStackのAPIはRESTっぽい感じなんですが、引数の形が手で書くのはつらいので、IDCFさんが提供しているcloudstack-apiというコマンドラインクライアントを使います。

CoreOSのcloud-config.ymlを指定してインスタンスの起動とかもできます。

[IDCFクラウド公式ブログ記事](http://www.idcf.jp/blog/cloud/coreos/)の「3-2. CloudStackのUser Data機能を使ったcloud-init」というところに説明があります。

>
CloudStackのUser Dataについて、いくつか注意点があります。
>
* APIに引数として渡すデータはBase64エンコードし、改行を削除した文字列である必要がある
* cloudstack-apiコマンド等HTTP GETリクエストで送信できるUser DataはBase64エンコード後で2KBまで対応
* HTTP POSTリクエスト（User Data自体はPOSTのBody部分に記載）を使うと32KBまで対応
* Base64エンコード前のデータのバイト数が3の倍数ではない場合、正常に認識できない
>
最後の点があるため、上記の例では改行などを削除して合計546バイトにしています。
>
APIを実行する端末上で上記の内容のcloud-config.ymlを作成した後、Base64エンコードした文字列を取得します。
>
```
$ base64 cloud-config.yml | tr -d "\n" ;echo ""
I2Nsb3VkLWNvbmZpZwp1c2VyczoKICAtIG5hbWU6IGlkY2YKICAgIGdyb3VwczoKICAgICAgLSBzdWRvCiAgICBzc2gtYXV0aG9yaXplZC1rZXlzOgogICAgICAtIHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQURBUUFCQUFBQkFRREJYa1VheHdSWVBIamNjaUkwMHVPOEFCMXRnSUs3aDBLQVJZWTVKUzZKbGFIYUhSLzN5eDAySGJCdjVsRVBEc3o2eERWYjd2SE9USnBpTVhJVVV2SjRaNDgwQTZFRjB3SXdUQjB4VnZFbElSL0F6NnlzNEZrTzFBK2pvNnVkZXZvTG9iMVBPNFZ3d1pqcUZZK1lUTHRrR0JidHZycmJmUU5KVE1hZ1pUZjRaMk5ObVE0c0hJNmI0Z2U1d0UrQ0QrZkNFMXdTaDlJVStIaldwNndrS2FLUVhTZHZ6eEZGZjVsZjBOMFVpWkh6UnlFOTl2SzN0V3c5YStqeU5NWmIwNjdXWVBWL2FYR0IxRG9rbzN2OXgwemtsS0ZVeDRuSkczaUlRMDlmUUlYUVFVTU5WOGY1RnlwSnViell1K3V2eDgvelhRazk4Sng0dkk5alBWSlM2UzdkCmNvcmVvczoKICAgIHVuaXRzOgogICAgICAtIG5hbWU6IGRvY2tlci5zZXJ2aWNlCiAgICAgICAgY29tbWFuZDogc3RhcnQK
```
>
上記文字列を使って、先ほど作成した仮想マシンにUser Dataを設定します。
>
```
$ cloudstack-api listVirtualMachines -t id,name,group,state
+--------------------------------------+--------+-------+---------+
|                  id                  |  name  | group |  state  |
+--------------------------------------+--------+-------+---------+
| 3583dc29-5860-47aa-bc13-9fbb7ce50d46 | coreos | test  | Running |
+--------------------------------------+--------+-------+---------+
$ cloudstack-api updateVirtualMachine --id 3583dc29-5860-47aa-bc13-9fbb7ce50d46 \
  --userdata I2Nsb3VkLWNvbmZpZwp1c2VyczoKICAtIG5hbWU6IGlkY2YKICAgIGdyb3VwczoKICAgICAgLSBzdWRvCiAgICBzc2gtYXV0aG9yaXplZC1rZXlzOgogICAgICAtIHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQURBUUFCQUFBQkFRREJYa1VheHdSWVBIamNjaUkwMHVPOEFCMXRnSUs3aDBLQVJZWTVKUzZKbGFIYUhSLzN5eDAySGJCdjVsRVBEc3o2eERWYjd2SE9USnBpTVhJVVV2SjRaNDgwQTZFRjB3SXdUQjB4VnZFbElSL0F6NnlzNEZrTzFBK2pvNnVkZXZvTG9iMVBPNFZ3d1pqcUZZK1lUTHRrR0JidHZycmJmUU5KVE1hZ1pUZjRaMk5ObVE0c0hJNmI0Z2U1d0UrQ0QrZkNFMXdTaDlJVStIaldwNndrS2FLUVhTZHZ6eEZGZjVsZjBOMFVpWkh6UnlFOTl2SzN0V3c5YStqeU5NWmIwNjdXWVBWL2FYR0IxRG9rbzN2OXgwemtsS0ZVeDRuSkczaUlRMDlmUUlYUVFVTU5WOGY1RnlwSnViell1K3V2eDgvelhRazk4Sng0dkk5alBWSlM2UzdkCmNvcmVvczoKICAgIHVuaXRzOgogICAgICAtIG5hbWU6IGRvY2tlci5zZXJ2aWNlCiAgICAgICAgY29tbWFuZDogc3RhcnQK
```

↓この部分がよくわからないですね。

>
* cloudstack-apiコマンド等HTTP GETリクエストで送信できるUser DataはBase64エンコード後で2KBまで対応
* HTTP POSTリクエスト（User Data自体はPOSTのBody部分に記載）を使うと32KBまで対応

実際に試してみると、cloud-config.ymlが一定サイズを超えると、401というエラーコードの入ったJSONが返ってくるようになります。おそらく送信するデータが2KBを超えたタイミングでしょう。

IDCFクラウドの提供しているcloudstack-apiコマンドのコードを見ると、どうやらPOSTリクエストには対応していなさそう。

https://github.com/idcf/cloudstack-api/blob/master/cloudstack/compute/stack.py

これを無理やりPOSTも遅れるように書き換えてみても、`unable to verify user credentials and/or request signature`というエラーが返ってきました。

CloudStack自体のコードを読んでみると、この↓あたりから`login`というAPIを先に叩いてJSESSIONIDというのをもらわなければPOSTリクエストを使うことはできないようでした。

https://github.com/apache/cloudstack/blob/master/server/src/com/cloud/api/ApiServlet.java#L277-L299
https://github.com/apache/cloudstack/blob/master/server/src/com/cloud/api/ApiServer.java#L785-L804

困りました。IDCFクラウドではCloudStackのlogin APIは提供されていません。

http://docs.idcf.jp/cloud/api/

そんなわけで、現時点ではAPI経由で大きめのcloud-config.ymlを使う方法は無さそうです。