tanacasinoのメモ

what are you waiting for ?

Eucalyptus meets Scala !? Scala meets Eucalytpus!?

この記事は Eucalyptus Advent Calendar 2014 3日目の記事です。

昨日は、@giraffeforestg さんの「Eucalyptus 4を楽しんでみる」でした。私もちゃんと読んでインストールしなおします。。。

Eucalyptus 4 を 楽しんでみる (Eucalyptus Advent Calendar 2014) - きりんメモ@GIFU


本題

EucalyptusScalaから操作する。

Midonetで話題のそうScala

全人類にとってまるで夢のような組み合わせ。

誰もが憧れる迷品。

そう、eucalyptuscala だよ!

tanacasino/eucalyptuscala · GitHub

使い方

事前にJRE 1.7 or laterを準備してください。OpenJDKでも大丈夫です。(多分ね!)

# Eucalyptusでおなじみの eucarc を source して環境変数をセットしましょう!
$ source eucarc

# eucalyptuscala をクローンしてきましょう!
$ git clone https://github.com/tanacasino/eucalyptuscala.git
$ cd eucalyptuscala

# REPL 開始
$ ./bin/sbt console
# 以下をimportするだけで使えます!
scala> import com.github.tanacasino.eucalyptuscala._
import com.github.tanacasino.eucalyptuscala._

# クライアント用インスタンスを生成するのもこんなに簡単!
scala> implicit val euca = Eucalyptus()
euca: awscala.ec2.EC2 = com.github.tanacasino.eucalyptuscala.Eucalyptus@36240cb7

# インスタンスの一覧をサクッと取得!
scala> euca.instances
res0: Seq[awscala.ec2.Instance] = ArrayBuffer()

# Scalaのコレクション操作による流れるような処理も可能!
scala> euca.instances.filter(_.name.startsWith("euca-")).map(_.instanceId)
res1: Seq[String] = ArrayBuffer()

# Walrus(S3 API)にも対応!
scala> implicit val walrus = Walrus()
walrus: awscala.s3.S3 = com.github.tanacasino.eucalyptuscala.Walrus@542d8f6d

scala> val mybucket = walrus.createBucket("mybucket")
mybucket: awscala.s3.Bucket = S3Bucket [name=mybucket, creationDate=null, owner=null]

scala> mybucket.keys
res3: Seq[String] = Stream()

# TAB で保管も効きます!
scala> mybucket.put
put   putAsPublicRead   putAsPublicReadWrite   putObject   putObjectAsPublicRead   putObjectAsPublicReadWrite

scala> mybucket.putObject

def putObject(key: String, bytes: Array[Byte], metadata: com.amazonaws.services.s3.model.ObjectMetadata)(implicit s3: S3): PutObjectResult
def putObject(key: String, file: java.io.File)(implicit s3: S3): PutObjectResult

# もちろんその場でアップロードもできる!
scala> val obj = mybucket.putObject("hoge.txt", new java.io.File("/home/tanacasino/hoge.txt"))
obj: awscala.s3.PutObjectResult = PutObjectResult(S3Bucket [name=mybucket, creationDate=null, owner=null],hoge.txt,null,4a3b564e9d8e78ac0cca5e6e0c0b3258,SjtWTp2OeKwMyl5uDAsyWA==,2014-11-24T21:35:23.180+09:00,null,null)

scala> walrus.buckets.foreach(println)
S3Bucket [name=loadbalancer-v1, creationDate=Mon Nov 24 15:44:02 JST 2014, owner=S3Owner [name=eucalyptus,id=351c014a473cb1b3c3d10364c35c3d3e39241e1f41535a2639391c5b20552c19]]
S3Bucket [name=mybucket, creationDate=Mon Nov 24 21:18:41 JST 2014, owner=S3Owner [name=eucalyptus,id=351c014a473cb1b3c3d10364c35c3d3e39241e1f41535a2639391c5b20552c19]]
S3Bucket [name=test001, creationDate=Mon Nov 24 20:57:32 JST 2014, owner=S3Owner [name=eucalyptus,id=351c014a473cb1b3c3d10364c35c3d3e39241e1f41535a2639391c5b20552c19]]

f:id:tanacasino:20141203003441p:plain

実体はScala + sbt + AWScala + aws-sdk-javaなので、本体コードとしては・・・ 環境変数からちょっと読みこむのとEucalyptus用のEndpointに設定しているだけです。

あと残念ながらEucalyptusの環境がなかった(インストールに失敗した)ので、インスタンス起動は試してません笑

keypairだけ作れたよ!まあ認証通ってるのであとはEucalyptusちゃんのAPI互換性を信じるだけです。

Eucalyptus環境をお持ちの方々動かしてね!人柱デバッグ報告お待ちしてますー!

Read Or Die !!! See you next Eucalyptus!!!

homebrew にて GitHubの API rate limit にかかって怒られた場合の対処方法

MacBook Proを新調したのでいろいろとセットアップ中です。 homebrewの検索 brew search をしまくっていたら、以下のエラーを見たのでとりあえず対策したのでメモ。

ちなみにエラーに書いてあるとおり待てば時間が解決してくれるエラーなので無理して設定する必要はないです。

$ brew search java
app-engine-java-sdk   javarepl              jslint4java           libreadline-java
Error: GitHub API rate limit exceeded for 121.108.126.210. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)
Try again in 46 minutes 16 seconds, or create an API token:
  https://github.com/settings/applications
and then set HOMEBREW_GITHUB_API_TOKEN.

まあエラーに書いてあるとおり対策はというと環境変数 HOMEBREW_GITHUB_API_TOKENGitHubAPI Tokenを設定せよ!ということですね。

GitHubAPI Tokenは以下の手順で作成できます。

  1. GitHubにログインする
  2. 右上の Settings アイコンをクリックして設定ページに移動する
  3. 左側のメニューから Application を選択して移動する
  4. Generate new tokenをクリックする

    f:id:tanacasino:20141103204957p:plain

  5. public_repoのみ選択した状態にして Generate token

    f:id:tanacasino:20141103205026p:plain

  6. めでたくtokenという名の文字列が表示されるので控えておく(もう二度と参照できないので、忘れたら作りなおす必要がある)

    f:id:tanacasino:20141103205045p:plain

GitHub API Tokenをめでたくゲットしたら、シェルの設定ファイルにでも環境変数をセットすればおしまいです。

例えば、$HOME/.bashrc あたりに以下を追記してリロード or 再度ログイン等すれば、homebrewから怒られなくなります。

export HOMEBREW_GITHUB_API_TOKEN="さっきゲットしたtoken文字列"

ちなみに前は public_repoへのアクセスのみのAPI権限なんて何に使うんや?と思ってたけどIPで制限かかってたんですね。。。 皆さん ちゃんとその時の用途にあわせて必要最小限の権限を与えたtokenを作りましょう!

GitBucketのAPI Tokenもいつか実装していつか権限設定も細かく・・・

node.js AWS SDK for JavaScript で http proxy経由のリクエストを発行する方法

忘れそうなのでメモしておく。忘れても良さそうな気はしているけれど。

意外とググっても見つからない。グーグル力が足りない。

概要

AWS SDK for JavaScriptnpm install aws-sdkでインストールできる。 社内LAN等のhttp proxyを経由させる場合は、tunnelライブラリを用いて aws-sdkagentに仕込みを入れればOK。

セットアップ

事前準備は以下のとおり。実施済みであること。

  1. node.jsインストールされていること
  2. node, npmコマンドが実行できること

準備できたら以下のように aws-sdktunnelをインストールした環境を作る

# 適当にワーキングディレクトリ作ってください
$ mkdir node-aws-example
$ cd node-aws-example
$ npm install tunnel aws-sdk

コード例

AWSのconfigに httpOptions.agentを仕込む。 仕込むためのagentは、tunnelさんの力を借りる。 proxyAuthユーザ名:パスワード は、不要な場合はなくてもよい。

var AWS = require('aws-sdk')
   ,tunnel = require('tunnel');

AWS.config.loadFromPath('./config.json');

var tunAgent = tunnel.httpsOverHttp({
  proxy: {  // your proxy server infomation
    host: "localhost",
    port: 8888,
    proxyAuth: "user:password"
  }
})

AWS.config.update({httpOptions: { agent: tunAgent }})

var s3 = new AWS.S3();

s3.listBuckets(function(err, data) {
    if (err) {
      console.log(err, err.stack);
    } else {
      console.log(data);
    }
});

まとめ

サンプルコードは以下にまとめた。

Git で親が3つ以上あるコミットを作ってみたよ

Git の Commit Objectの parent は存在する。これはGitな人には常識でしょう。 親の事考えないとamendやらrebaseやらが理解不能でしょうから。 Git のコミットオブジェクトの親は 3個以上もあるとかは考えたことあまりないと思います。

例えば親が1つのSingleコミットはこんな内容で一番多いと思う。

$ git cat-file -p 34d5217584ee4722d0c0b07ed6c8f1f01ad157c3
tree 2afc851b60064ef8ef899cb6909a3a1fd0eb3003
parent 12188a82990da099e2f3cf3d37aa4e0362122478
author Junio C Hamano <gitster@pobox.com> 1401317422 -0700
committer Junio C Hamano <gitster@pobox.com> 1401470021 -0700

Git 1.9.4

This is expected to be the final maintenance release for 1.9 series,
merging the remaining fixes that are relevant and are already in 2.0.

Signed-off-by: Junio C Hamano <gitster@pobox.com>

マージコミットの場合は大体のコミットが parent が2つあると思う。

$ git cat-file -p bce14aa132e0064d9a9b1c7ad98e71e22c6e0272
tree bc979e2a998e84450747c2c6f4010cf6c87adaa7
parent d7172825321369cb951dd7bbfc0c12dc4ecbe518
parent 34d5217584ee4722d0c0b07ed6c8f1f01ad157c3
author Junio C Hamano <gitster@pobox.com> 1401472672 -0700
committer Junio C Hamano <gitster@pobox.com> 1401472672 -0700

Sync with 1.9.4

マージコミットは親2つあると聞いてすごいわかりやすいなぁと思っていたら、親が3つ以上もGitでは存在することを知りました・・・・

そんなコミット見たことないし作るタイミングわかんねーよと思っていたら、git本家のリポジトリ内にかのHamanoさんが作っていたので、Gitのユースケース的には当たり前の存在なのであった・・・

$ git cat-file -p 1a8b76912e6ccef6bec3531eec30a0693bc25ae7
tree 0a94b441b8a3d174ce42c100cda67cab42288db0
parent 4bc708347e2b94564d9ec5e0e3a2ab0e3d6b2fd9
parent 88961ef2589433044365213fab98de081a1ce70f
parent 59c8e2cb2aee2e4eb75007602b264bc4e7928bc0
author Junio C Hamano <junkio@cox.net> 1180836294 -0700
committer Junio C Hamano <junkio@cox.net> 1180836294 -0700

Merge branches 'lh/submodules' and 'pb/am'

* lh/submodules:
  Add basic test-script for git-submodule
  Add git-submodule command

* pb/am:
  Remove git-applypatch
  git-applymbox: Remove command

Merge branches 'lh/submodules' and 'pb/am' · 1a8b769 · git/git · GitHub

さて、どうやったらparent が3個以上のマージコミットを作れるのか?

$ git merge br1 br2 br3
$ git cat-file -p c31ba16d5ab4fe530672716f7da668e99cfe9ad7
tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
parent e2da3bb525113a5fec5733b521a7acac6ce7d0f8
parent a6fee63e5b2bb1c0c832e0a906777ebdef582faf
parent f7e4c97f1a2f6909a2168b214b5629211ca25b26
author Tomofumi Tanaka <tanacasino@gmail.com> 1410529022 +0900
committer Tomofumi Tanaka <tanacasino@gmail.com> 1410529022 +0900

Merge branches 'br1', 'br2' and 'br3'

めっちゃ簡単。。。複数のブランチをマージする時ですね。(いやまあ普通に考えてそうなんですが) 必要なタイミングがなくて使ったことがないだけってかんじですね。

GitBucketに親の数が2つとかで条件文書いてしまったコードがある気がするので見なおせねばならぬ。