EBSブートなAMIイメージで、インスタンスストレージを割り当てる

通常、EBS *1 からブートするAMIイメージでインスタンスを立ち上げると、インスタンスに割り当てられたストレージ(smallの場合150GB)はデバイスとしてアタッチされていません。


せっかくEBSがメインストレージなんだからそれを増やせばいいという話もありますが、僕のような貧乏性はもったいないな〜、あればなにか使えそうなのに〜と感じていました。


というわけで前置きはこのあたりにするとして、下記のようにインスタンスを立ち上げるとストレージを割り当てることができます。

$ ec2run ami-xxxxxxxx -b /dev/sdc=ephemeral0 -k user_key -g user_group


"ami-xxxxxxxx"はEBSブートなAMIイメージです。
ログオンして覗いてみます。

$ df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda1             15481840   2212052  12483356  16% /
none                    874032         0    874032   0% /dev/shm


$ mkdir /vol
$ mount /dev/sdc /vol
$ df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda1             15481840   2212056  12483352  16% /
none                    874032         0    874032   0% /dev/shm
/dev/sdc             153899044    192072 145889348   1% /vol


ちゃんと150GBのストレージが現れました♪
(ただし、通常smallのルートデバイスとなる10GBの方は割り当てることはできませんでした。)
試していませんが、largeのように複数のストレージが割り当てることができる場合には下のように-bを複数指定できるようです。

$ ec2run ami-xxxxxxxx -b /dev/sdc=ephemeral0 -b /dev/sdd=ephemeral1 -k user_key -g user_group


必要? という話はおいといても適当なテンポラリとしては十分なサイズなので、なにか使い出があるのではないでしょうか。
あとEBSはI/Oリクエストに対しても課金されます。
つまりサーバダウン等で消えちゃってもいいデータをうまく追い出すことができれば、EBSの利用料金をちょっぴりお安くすることができるかもしれません。(検証はしていませんけど)

*1:ELASTIC BLOCK STORE

mixiアプリ、正式公開

id:hidea に言われるまで気付かなかったのですが、mixiアプリが正式公開されていました。
β当初にがりがりっと作ったまま放っていましたが、新刊.netmixiアプリが利用できるようになっています。


詳しくは、以下をごらんください。

Amazon Product Advertising API

アマゾンの商品検索WEBサービスである、「Amazon Associates Web Service (A2W)」が「Amazon Product Advertising API (APA?)」に名称が変更されました。
そして、名称が変わっただけではなく、その仕様も大きく変わることに…


これまで、AWSのアカウントを持っていれば、そのIDに加えて検索条件を設定し、リクエストをするだけで結果が帰ってきていたのですが、どうもそこにもうひと手間必要になったようです。


おおまかには、上記のリクエストに、

  1. 現在時刻のタイムスタンプを追加
  2. AWSアカウントの秘密鍵を追加
  3. [2]のリクエスト文字列で、署名認証(HMAC-SHA1)を生成
  4. 秘密鍵を含まない[1]のリクエスト + 署名認証でアマゾンへリクエス

という流れ。


既に公式のサンプルは出ていますし、フォーラムを覗いたらPHPでのサンプルもありました。
PHPのサンプルは結構わかりやすいので応用しやすいかと。

Amazon® AWS HMAC signed request using PHP


まっこと面倒な話ですが、8月16日を過ぎるとこれ以外のリクエストはエラーになってしまうようです。
ECS3 → 4 の時に比べるとかなり移行期間が性急なのが気になりますが、他に選択肢が無い以上早めに実装しておいた方がいいでしょう。
アマゾンに、日本語でのFAQもありました。

Product Advertising API サービス名称変更および署名認証の開始に関する、よくあるご質問


しかしなんでまた、こんなことにするのやら…
上のFAQでは、「認証されていない不正な API の利用を防ぐ」のが目的と書かれていますが、結果的にアマゾンへ人が流れていればさして問題にしなくてもいいはず。
ということは、APIへの負荷が人の流れに見合わないほど大きくなってきているのかな?
だとすると、2chのスレで書いていた人がいましたが、遠からずS3やEC2のような他のAPIのように課金を考えているのかもしれません。

mixiアプリ、ユーザー設定

mixiアプリのユーザー毎の設定の表示で、ちょっと勘違い(というより混乱)していたのでメモ。


アプリ開始時、保存してある永続化データを取得する際に、以下のようなコードにしていたのですが、

// OWNER の永続化データを取得
var request = opensocial.newDataRequest();
request.add(request.newFetchPersonRequest(
  opensocial.IdSpec.PersonId.OWNER
), "owner");
var param = {};
param[ opensocial.IdSpec.Field.USER_ID ] = opensocial.IdSpec.PersonId.OWNER;
var idSpec = opensocial.newIdSpec(param);
request.add(request.newFetchPersonAppDataRequest(idSpec, [ "data" ]), "owner_data");
request.send(function (response) {
  if (response.hadError()) return;

  var owner = response.get("owner").getData();
  if (owner.isOwner()) {
    // 設定ボタンを表示
  }
  ...
}

他の人のプロフィール画面上でも、「設定」ボタンが表示されていて失敗。
どうも、

if (owner.isOwner()) {
  // 設定ボタンを表示
}

「観ている人がオーナーか否か?」と思っていたのは勘違いでした。
これは、「取得したデータが、オーナーのものか否か?」だったんですね。


正解は、

if (owner.isViewer()) {
  // 設定ボタンを表示
}

「取得したデータが、閲覧者のものか否か?」で、真だったらボタンを表示すると。

safari for Windows 3.2 で開発(Debug)メニュー

作った mixiアプリが、IE7safariでうまく動かないので、まずは safari上で JavaScriptデバッグをしようと思った所、デバッグコンソールが見当たらない…


ググってみたところ、

Windows 版 Safari で JavaScript Console を表示する方法

というのがあったのですが、ここに書かれている「...Safari\Preferences.plist」というファイルが見当たらないんですよね。
そこで、片っ端からそれっぽいファイルに項目を追加してみると

C:\Documents and Settings\(user)\Application Data\
Apple Computer\Safari\Preferences\com.apple.Safari.plist

というファイルに、

IncludeDebugMenu

を追加した所で「開発」というメニューが登場しました!

mixiアプリ、現時点での疑問

現在の view *1 を取得する方法。


Google Code にある OpenSocial のページを見ると、「gadgets.views」ってstaticクラスから

gadgets.views.getCurrentView().getName();

で取れるようなのですが、mixiアプリの gadgets にはそもそも views がないようです。
現時点では、ということで今後追加されるのかもしれませんが。

<Content type="html" view="profile">
<![CDATA[
]]>
</Content>
<Content type="html" view="canvas">
<![CDATA[
]]>
</Content>
<Content type="html" view="home">
<![CDATA[
]]>
</Content>

と書き分けるのではなく、内部のロジックで場合分けしたいのです。

解決

ModulePrefs に、feature を追加することで機能が有効になるようです。

<ModulePrefs title="sinkan.net today test (mixi appli)">
  <Require feature="opensocial-0.8" />
  <Require feature="views" />
  <Require feature="dynamic-height" />
</ModulePrefs>


これで、gadgets.views.getCurrentView().getName() とか、gadgets.window.adjustHeight() が使えるようになりました。

*1:profile / canvas / home

mixiアプリのテスト

ちょっと時間があったので、mixiアプリのテストをしてみました。
主な目的は、外部ファイルの読み込みです。


JavaScript自体、めったに触らないので試行錯誤して、とりあえるRSSフィードを読むことに成功。
UIとかまだ面倒なので、とりあえず「新刊.net」の固定URIを指定しました。


アプリとしては役立たずなのであまり意味はありませんが、
http://platform001.mixi.jp/view_appli.pl?id=1019
に公開してもらっています。


エントリーが3つまでしか表示されないのは、

gadgets.io.ContentType.FEED

の仕様かな?
gadgets.io.ContentType.TEXT, gadgets.io.ContentType.JSON ともにちゃんと動作してるっぽいです。


コードは以下の通りとなります。

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="rss feed test (mixi appli)">
    <Require feature="opensocial-0.8" />
  </ModulePrefs>
  <Content type="html">
  <![CDATA[
      <script type="text/javascript">
      // witten by YOD-Y,hidea/rukari.com

      function request() {
        var url = "http://sinkan.net/?action_rss=true&mode=today";
        var params = {};
        params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.FEED;
        gadgets.io.makeRequest(url, response, params);
      }

      function response(obj) {
        var html = "";

        // Feed title
        html += "<a href=\"" + obj.data.Link + "\">" + obj.data.Title + "</a>";
        html += "<hr />";

        // Entry list
        for (i in obj.data.Entry) {
          var entry = obj.data.Entry[ i ];
          html += "<a href=\"" + entry.Link + "\">" + entry.Title + "</a>";
          html += "<hr />";
        }

        // Output
        var div = document.getElementById("feed");
        div.innerHTML = html;
      }

      gadgets.util.registerOnLoadHandler(request);
    </script>

    <div id='feed'></div>
  ]]>
  </Content>

</Module>