Vagrantで開発環境

http://www.vagrantup.com/
ここからdmgをダウンロードしてインストールする。

.zshrcに
export PATH=/Application/vagrant/bin:$PATH
を追加しておく。

VirtualBoxは導入済み。

vagrantで使うboxのリスト。
http://www.vagrantbox.es/

適当なものをチョイス。

> vagrant box add centos_64_nocm http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box
> vagrant box list
centos_64_nocm (virtualbox)

サーバ起動の準備

> mkdir develop
> cd develop
> vagrant init centos_64_nocm

Vagrantfileを編集する。
今回は自分のmacから開発環境をつくるのが目的なのでブリッジ接続することにした。

> vi Vagrantfile
config.vm.network :public_network

固定にするなら

config.vm.network :private_network, ip: "192.168.0.124"

メモリの設定をする。

config.vm.provider :virtualbox do |vb|
  vb.customize ["modifyvm", :id, "--memory", "1024"]
end

起動する。

> vagrant up

途中で、

[default] Available bridged network interfaces:
1) en1: Ethernet 2 (AirPort)
2) en0: Ethernet 1
3) p2p0
What interface should the network bridge to? 1

と聞かれるので1を入力。

サーバに入る。

> vagrant ssh
[vagrant@localhost ~]$ pwd
/home/vagrant
[vagrant@localhost ~]$ ifconfig
eth0      Link encap:Ethernet  HWaddr 08:00:27:B1:58:9A
          inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:feb1:589a/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:569 errors:0 dropped:0 overruns:0 frame:0
          TX packets:356 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:56092 (54.7 KiB)  TX bytes:46757 (45.6 KiB)

eth1      Link encap:Ethernet  HWaddr 08:00:27:94:8D:7F
          inet addr:192.168.0.124  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fe94:8d7f/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:408 errors:0 dropped:0 overruns:0 frame:0
          TX packets:97 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:52461 (51.2 KiB)  TX bytes:13714 (13.3 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

macからsshしてみる。パスワードはユーザ名と一緒みたい。

> ssh vagrant@192.168.0.124

ここにansible-playbookで環境を流す。
vagrant pluginでansibleと連携できるみたいだけど、今回は以前つくったplaybookを流す。

(ansible-env)> ansible-playbook -i develop develop.yml -K -v

環境ができたらvagrantのboxを作成しておく。

> vagrant package

package.boxというファイルができるのでこれをdropboxかどこかで開発者に共有してもらって、

> vagrant add develop http://共有したURL/package.box

みたいな感じで環境がすぐできる。

次回はvagrantでAWSとvSphere(切実)の連携を予定。

広告

Rubymotionのアレコレ2

RubyMotionのアレコレの続き。

・app.provisioning_profileの指定
Xcode5でファイル特定ができなくなった?っぽいのでterminalから直接調べにいきます。
cd ~/Library/MobileDevice/Provisioning Profiles で移動して、head * すると、ファイルの中身に

<key>AppIDName</key>
<string>アプリ名</string>

みたいなのが出てくるので、そのファイルをapp.provisioning_profileに指定する。
ちょっとめんどくさい。

・AppStoreへのリリース時
rake archive:distributionで.ipaを作成。
Xcodeを起動して、メニューの[Xcode] > [Open Developer Tool] > [Application Loader]を起動する。
Deliver Your Appをクリックすると事前にiTunes Connectで登録した情報が出てくる(出てこない場合は何かしら情報が足りてないかAgreeしていない項目があるかも)ので、そこからアップロードする。
指定したprovisioning profileが違うとか、アイコンファイルが足りないとか色々でるので頑張って用意する。
あとはレビューを経てReady For Saleになるまで待つ。

nginx + spdy + pagespeed + passenger + ruby2.0 + rails4 + varnish

という構成のログ。

nginxのconfigure –hlepとpassenger-install-nginx-mobule –helpをみるとこんな感じ。

passenger-install-nginx-module --help
Usage: passenger-install-nginx-module [options]

Options:
        --auto                       Automatically confirm 'Press ENTER to
                                     continue' prompts.
        --prefix=DIR                 Use the given Nginx install prefix instead
                                     of asking for it interactively.
        --auto-download              Download and install Nginx automatically,
                                     instead of asking interactively whether to
                                     download+install or to use an existing
                                     Nginx source directory.
        --nginx-source-dir=DIR       Compile and install Nginx using the given
                                     Nginx source directory, instead of
                                     interactively asking to download+install
                                     or to use an existing Nginx source
                                     directory. Conflicts with --auto-download.
        --extra-configure-flags=STRING
                                     Pass these extra flags to Nginx's
                                     'configure' script, instead of asking for
                                     it interactively. Specify 'none' if you
                                     do not want to pass additional flags but do
                                     not want this installer to ask
                                     interactively either.
./configure --help

  --help                             print this message

  --prefix=PATH                      set installation prefix
  --sbin-path=PATH                   set nginx binary pathname
  --conf-path=PATH                   set nginx.conf pathname
  --error-log-path=PATH              set error log pathname
  --pid-path=PATH                    set nginx.pid pathname
  --lock-path=PATH                   set nginx.lock pathname

  --user=USER                        set non-privileged user for
                                     worker processes
  --group=GROUP                      set non-privileged group for
                                     worker processes

  --builddir=DIR                     set build directory

  --with-rtsig_module                enable rtsig module
  --with-select_module               enable select module
  --without-select_module            disable select module
  --with-poll_module                 enable poll module
  --without-poll_module              disable poll module

  --with-file-aio                    enable file AIO support
  --with-ipv6                        enable IPv6 support

  --with-http_ssl_module             enable ngx_http_ssl_module
  --with-http_spdy_module            enable ngx_http_spdy_module
  --with-http_realip_module          enable ngx_http_realip_module
  --with-http_addition_module        enable ngx_http_addition_module
  --with-http_xslt_module            enable ngx_http_xslt_module
  --with-http_image_filter_module    enable ngx_http_image_filter_module
  --with-http_geoip_module           enable ngx_http_geoip_module
  --with-http_sub_module             enable ngx_http_sub_module
  --with-http_dav_module             enable ngx_http_dav_module
  --with-http_flv_module             enable ngx_http_flv_module
  --with-http_mp4_module             enable ngx_http_mp4_module
  --with-http_gunzip_module          enable ngx_http_gunzip_module
  --with-http_gzip_static_module     enable ngx_http_gzip_static_module
  --with-http_random_index_module    enable ngx_http_random_index_module
  --with-http_secure_link_module     enable ngx_http_secure_link_module
  --with-http_degradation_module     enable ngx_http_degradation_module
  --with-http_stub_status_module     enable ngx_http_stub_status_module

  --without-http_charset_module      disable ngx_http_charset_module
  --without-http_gzip_module         disable ngx_http_gzip_module
  --without-http_ssi_module          disable ngx_http_ssi_module
  --without-http_userid_module       disable ngx_http_userid_module
  --without-http_access_module       disable ngx_http_access_module
  --without-http_auth_basic_module   disable ngx_http_auth_basic_module
  --without-http_autoindex_module    disable ngx_http_autoindex_module
  --without-http_geo_module          disable ngx_http_geo_module
  --without-http_map_module          disable ngx_http_map_module
  --without-http_split_clients_module disable ngx_http_split_clients_module
  --without-http_referer_module      disable ngx_http_referer_module
  --without-http_rewrite_module      disable ngx_http_rewrite_module
  --without-http_proxy_module        disable ngx_http_proxy_module
  --without-http_fastcgi_module      disable ngx_http_fastcgi_module
  --without-http_uwsgi_module        disable ngx_http_uwsgi_module
  --without-http_scgi_module         disable ngx_http_scgi_module
  --without-http_memcached_module    disable ngx_http_memcached_module
  --without-http_limit_conn_module   disable ngx_http_limit_conn_module
  --without-http_limit_req_module    disable ngx_http_limit_req_module
  --without-http_empty_gif_module    disable ngx_http_empty_gif_module
  --without-http_browser_module      disable ngx_http_browser_module
  --without-http_upstream_ip_hash_module
                                     disable ngx_http_upstream_ip_hash_module
  --without-http_upstream_least_conn_module
                                     disable ngx_http_upstream_least_conn_module
  --without-http_upstream_keepalive_module
                                     disable ngx_http_upstream_keepalive_module

  --with-http_perl_module            enable ngx_http_perl_module
  --with-perl_modules_path=PATH      set Perl modules path
  --with-perl=PATH                   set perl binary pathname

  --http-log-path=PATH               set http access log pathname
  --http-client-body-temp-path=PATH  set path to store
                                     http client request body temporary files
  --http-proxy-temp-path=PATH        set path to store
                                     http proxy temporary files
  --http-fastcgi-temp-path=PATH      set path to store
                                     http fastcgi temporary files
  --http-uwsgi-temp-path=PATH        set path to store
                                     http uwsgi temporary files
  --http-scgi-temp-path=PATH         set path to store
                                     http scgi temporary files

  --without-http                     disable HTTP server
  --without-http-cache               disable HTTP cache

  --with-mail                        enable POP3/IMAP4/SMTP proxy module
  --with-mail_ssl_module             enable ngx_mail_ssl_module
  --without-mail_pop3_module         disable ngx_mail_pop3_module
  --without-mail_imap_module         disable ngx_mail_imap_module
  --without-mail_smtp_module         disable ngx_mail_smtp_module

  --with-google_perftools_module     enable ngx_google_perftools_module
  --with-cpp_test_module             enable ngx_cpp_test_module

  --add-module=PATH                  enable an external module

  --with-cc=PATH                     set C compiler pathname
  --with-cpp=PATH                    set C preprocessor pathname
  --with-cc-opt=OPTIONS              set additional C compiler options
  --with-ld-opt=OPTIONS              set additional linker options
  --with-cpu-opt=CPU                 build for the specified CPU, valid values:
                                     pentium, pentiumpro, pentium3, pentium4,
                                     athlon, opteron, sparc32, sparc64, ppc64

  --without-pcre                     disable PCRE library usage
  --with-pcre                        force PCRE library usage
  --with-pcre=DIR                    set path to PCRE library sources
  --with-pcre-opt=OPTIONS            set additional build options for PCRE
  --with-pcre-jit                    build PCRE with JIT compilation support

  --with-md5=DIR                     set path to md5 library sources
  --with-md5-opt=OPTIONS             set additional build options for md5
  --with-md5-asm                     use md5 assembler sources

  --with-sha1=DIR                    set path to sha1 library sources
  --with-sha1-opt=OPTIONS            set additional build options for sha1
  --with-sha1-asm                    use sha1 assembler sources

  --with-zlib=DIR                    set path to zlib library sources
  --with-zlib-opt=OPTIONS            set additional build options for zlib
  --with-zlib-asm=CPU                use zlib assembler sources optimized
                                     for the specified CPU, valid values:
                                     pentium, pentiumpro

  --with-libatomic                   force libatomic_ops library usage
  --with-libatomic=DIR               set path to libatomic_ops library sources

  --with-openssl=DIR                 set path to OpenSSL library sources
  --with-openssl-opt=OPTIONS         set additional build options for OpenSSL

  --with-debug                       enable debug logging

で以下ログ。002_pagespeed.shと005_nginx_passenger.shがちょっと詰まりそうなところ。

varnishがちょっと宙ぶらりん。

Ansible on OSX

Chefがゴツいというか大げさな感じがしてきたので、Ansibleにしようかなと。
ドキュメントは以下。
http://www.ansibleworks.com/docs/

感覚的にはcapistranoでシェルスクリプトとかコマンドをリモートに実行させたり、レシピを書いてゴニョゴニョできる感じなのかな。
そういうのわりとすき。

コマンドラインではなくブラウザからできそうな、AnsibleWorks AWXというのもある。
http://www.ansibleworks.com/ansibleworks-awx/

コマンドラインからやってみよう。

https://weluse.de/blog/installing-ansible-on-os-x.html
大体上記に書いてあるやり方でOSXに設定できるのですが、うまくいかないことがあるので以下。

pythonのバージョンは、ansibleを実行するOSX上は2.7
サーバー側は2.6以上でないとそのまま実行できないっぽい。
centos5とかだと2.4なので、以下をインストールしておく

remote$ yum install python-simplejson

sshの鍵認証でログインできるようにしておく。
別にパスワードでもいいみたいだけど、あまりないかな。

osxで作業。

> python --version
Python 2.7.5

> easy_install virtualenv
> virtualenv ansible-env
> source ansible-env/bin/activate
(ansible-env)> easy_install pip
(ansible-env)> pip install paramiko PyYAML jinja2
(ansible-env)> pip install ansible
(ansible-env)> export ANSIBLE_HOSTS=~/.ansible/hosts

準備完了。hostsを作成して実行先を書く。centosとかなら/etc/ansible/hostsでいいみたい。

(ansible-env)> vim ~/.ansible/hosts
localhost

[testserver]
192.168.100.5
192.168.100.6:22222
192.168.100.7:22222

[hoge]
hoge.runeleaf.jp

sshのポートが22以外ならそれも書く。
.ssh/configの設定をみてくれてると思ったのだけれど、微妙に見ていないところがある?
サーバーの実行ユーザーは、ansibleコマンドを実行するユーザーと合わせておくとよいかも。
ユーザーの指定もできる。

(ansible-env)> ansible
Usage: ansible <host-pattern> [options]

Options:
  -a MODULE_ARGS, --args=MODULE_ARGS
                        module arguments
  -k, --ask-pass        ask for SSH password
  -K, --ask-sudo-pass   ask for sudo password
  -B SECONDS, --background=SECONDS
                        run asynchronously, failing after X seconds
                        (default=N/A)
  -C, --check           don't make any changes, instead try to predict some of
                        the changes that may occur
  -c CONNECTION, --connection=CONNECTION
                        connection type to use (default=smart)
  -f FORKS, --forks=FORKS
                        specify number of parallel processes to use
                        (default=5)
  -h, --help            show this help message and exit
  -i INVENTORY, --inventory-file=INVENTORY
                        specify inventory host file
                        (default=/Users/kawashima/.ansible/hosts)
  -l SUBSET, --limit=SUBSET
                        further limit selected hosts to an additional pattern
  --list-hosts          dump out a list of hosts matching input pattern, does
                        not execute any modules!
  -m MODULE_NAME, --module-name=MODULE_NAME
                        module name to execute (default=command)
  -M MODULE_PATH, --module-path=MODULE_PATH
                        specify path(s) to module library
                        (default=/Users/kawashima/works/srv/ansible-
                        env/bin/../share/ansible/)
  -o, --one-line        condense output
  -P POLL_INTERVAL, --poll=POLL_INTERVAL
                        set the poll interval if using -B (default=15)
  --private-key=PRIVATE_KEY_FILE
                        use this file to authenticate the connection
  -s, --sudo            run operations with sudo (nopasswd)
  -U SUDO_USER, --sudo-user=SUDO_USER
                        desired sudo user (default=root)
  -T TIMEOUT, --timeout=TIMEOUT
                        override the SSH timeout in seconds (default=10)
  -t TREE, --tree=TREE  log output to this directory
  -u REMOTE_USER, --user=REMOTE_USER
                        connect as this user (default=kawashima)
  -v, --verbose         verbose mode (-vvv for more)
  --version             show program's version number and exit

pingモジュールを実行してみる。

(ansible-env)> ansible testserver -m ping
192.168.100.5 | success >> {
    "changed": false,
    "ping": "pong"
}

192.168.100.6 | success >> {
    "changed": false,
    "ping": "pong"
}

192.168.100.7 | success >> {
    "changed": false,
    "ping": "pong"
}

コマンド送ってみる。

(ansible-env)> ansible testserver -a "uptime"
192.168.100.5 | success | rc=0 >>
 14:07:20 up 35 days,  8:08,  1 user,  load average: 0.00, 0.00, 0.00

192.168.100.6 | success | rc=0 >>
 14:07:20 up 35 days,  8:48,  2 users,  load average: 0.00, 0.00, 0.00

192.168.100.7 | success | rc=0 >>
 14:06:50 up 141 days,  3:54,  1 user,  load average: 0.08, 0.08, 0.08

yum install vimしてみる。

(ansible-env)> ansible testserver -m yum -a "name=vim-enhanced state=installed"
192.168.100.5 | FAILED >> {
    "changed": true,
    "msg": "You need to be root to perform this command.\n",
    "rc": 1,
    "results": [
        ""
    ]
}

192.168.100.6 | success >> {
    "changed": false,
    "msg": "",
    "rc": 0,
    "results": [
        "vim-enhanced-2:7.2.411-1.8.el6.x86_64 providing vim is already installed"
    ]
}

192.168.100.7 | success >> {
    "changed": false,
    "msg": "",
    "rc": 0,
    "results": [
        "vim-enhanced-2:7.2.411-1.8.el6.x86_64 providing vim is already installed"
    ]
}

.6と.7にはインストールされてたみたいですが、.5にはなくてrootで実行しろ的な。

(ansible-env)> ansible testserver -m yum -a "name=vim-enhanced state=installed" -K
192.168.100.5 | success >> {
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [
        "\n================================================================================\n Package              Arch         Version                   Repository    Size\n================================================================================\nInstalling:\n vim-enhanced         i386         2:7.0.109-7.2.el5         base         1.2 M\n\nTransaction Summary\n================================================================================\nInstall       1 Package(s)\nUpgrade       0 Package(s)\n\nTotal download size: 1.2 M\n\nInstalled:\n  vim-enhanced.i386 2:7.0.109-7.2.el5                                           \n\n"
    ]
}

192.168.100.6 | success >> {
    "changed": false,
    "msg": "",
    "rc": 0,
    "results": [
        "vim-enhanced-2:7.2.411-1.8.el6.x86_64 providing vim is already installed"
    ]
}

192.168.100.7 | success >> {
    "changed": false,
    "msg": "",
    "rc": 0,
    "results": [
        "vim-enhanced-2:7.2.411-1.8.el6.x86_64 providing vim is already installed"
    ]
}

1台だけ実行したければ、testserverの部分を192.168.100.5にすればOK。
デフォルトで並列実行が5のようなので、もっと台数があるなら-fで指定する。

これら一連の作業を自動的に構成するのがplaybookと。
ヘルプはansible-playbook -hで、各モジュールのヘルプはansible-doc yumとかansible-doc commandとかで確認できる。

実行する。

(ansible-env)> ansible-playbook develop.yml -K -v

make && make installみたいにコンパイルしているところはモジュールにしてしまうのがいいのかな。

playbookの中身はこんな感じ。

Infrastructure as Code!

[追記]
Best Practicesみてちょっと変えてみたり。
https://github.com/runeleaf/ansible-playbook

dotCloudでRails3.2.9とpostgresqlを動かす

therubyracerがアレすぎですが、herokuよりはやりやすかった。sshできるのが大きいです。
gemfileにtwitter-bootstrapとかless-railsとか積んでると面倒かも。

自分のPCで

> pybrew use Python-2.7.3
> pip install dotcloud
> cd APP_ROOT
> dotcloud create [appname]
> vi dotcloud.yml
www:
  type: ruby
db:
  type: postgresql
> git add .
> git ci -m 'add yml'

dotcloudにアプリをアップ

> dotcloud push

dotcloudにデータベースを作成

> dotcloud run db
# createdb [dbname]
# exit

アップされたrailsアプリを動くように色々作業

> dotcloud run www
$ cd current
$ rm -rf vendor/bundle # 自分のPCではvendor/bundleにbundle installしているので削除
$ rm .bundle # 設定も削除
$ vim Gemfile
gem 'therubyracer', '0.11.0beta8', :platforms => :ruby # therubyracerが0.11.0beta8じゃないとbundle installが失敗する
$ bundle install

データベースの設定を記述

$ cat ../environment.yml
$ vi config/database.yml # productionを編集

具体的には、

<% 
require 'json'
env = JSON.parse(File.read('/home/dotcloud/environment.json'))
%>
production:
  adapter: postgresql
  encoding: unicode
  database: [dbname]
  pool: 5
  username: <%= env['DOTCLOUD_DB_SQL_LOGIN'] %>
  password: <%= env['DOTCLOUD_DB_SQL_PASSWORD'] %>
  host: <%= env['DOTCLOUD_DB_SQL_HOST'] %>
  port: <%= env['DOTCLOUD_DB_SQL_PORT'] %>

ここに書いてある
http://docs.dotcloud.com/0.9/guides/environment/

rake db:migrateの実行

$ rake db:migrate RAILS_ENV=production
$ exit

自分のPCに戻って、dotcloud open

これだとdotcloud pushしたときに設定が全部上書きされてしまうので、作業側のコードも編集しておき、rbenvあたりでgem管理しておけばいいかも。

RhodesでAndroidとiPhoneのアプリを、と思ったけれど…

たぶん使わないと思うので足早に。

インストール

> mkdir rhodes_projects
> cd rhodes_projects
> rbenv gemset create 1.9.3-p194 rhodes
> echo rhodes > .rbenv-gemsets
> gem install rhodes
> rbenv rehash
> rhodes-setup
We will ask you a few questions below about your dev environment.

JDK path (required) (/Library/Java/Home): 
Android SDK path (blank to skip) (): /usr/local/Cellar/android-sdk/r20.0.1
Android NDK path (blank to skip) (): /usr/local/Cellar/android-ndk/r8b
Windows Mobile 6 SDK CabWiz (blank to skip) (): 
BlackBerry JDE 4.6 (blank to skip) (): 
BlackBerry JDE 4.6 MDS (blank to skip) (): 
BlackBerry JDE 4.2 (blank to skip) (): 
BlackBerry JDE 4.2 MDS (blank to skip) ():

プロジェクト作成

> rhogen app basestation
> cd basestation
> vi build.yml
android:
  version: 4.1

scaffold的ななにか。

> rhodes model cbase id
Generating with model generator:
     [ADDED]  app/Cbase/index.erb
     [ADDED]  app/Cbase/edit.erb
     [ADDED]  app/Cbase/new.erb
     [ADDED]  app/Cbase/show.erb
     [ADDED]  app/Cbase/index.bb.erb
     [ADDED]  app/Cbase/edit.bb.erb
     [ADDED]  app/Cbase/new.bb.erb
     [ADDED]  app/Cbase/show.bb.erb
     [ADDED]  app/Cbase/cbase_controller.rb
     [ADDED]  app/Cbase/cbase.rb
     [ADDED]  app/test/cbase_spec.rb

ビルド
> rake -T
> rake run:android

rakeながいよ

run:iphoneするならXcodeのPreferencesからiOS 5.0 Simulatorをinstallしておく。

> rake run:iphone

ながいー

うーん、Rubyでマルチプラットフォームは魅力なんだけど、うーん。。

Androidアプリをscalaで作りたい

homebrewでsbtとscalaは入れてある前提。

> brew install android-sdk
> android

SDKマネージャーが立ち上がるので適当なバージョンをインストール

> android list targets
Available Android targets:
----------
id: 1 or "android-16"
     Name: Android 4.1
     Type: Platform
     API level: 16
     Revision: 2
     Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
     ABIs : armeabi-v7a
----------
id: 2 or "Google Inc.:Google APIs:16"
     Name: Google APIs
     Type: Add-On
     Vendor: Google Inc.
     Revision: 2
     Description: Android + Google APIs
     Based on Android 4.1 (API level 16)
     Libraries:
      * com.google.android.media.effects (effects.jar)
          Collection of video effects
      * com.android.future.usb.accessory (usb.jar)
          API for USB Accessories
      * com.google.android.maps (maps.jar)
          API for Google Maps
     Skins: WVGA854, WQVGA400, WSVGA, WXGA800-7in, WXGA720, HVGA, WQVGA432, WVGA800 (default), QVGA, WXGA800
     ABIs : armeabi-v7a

> android create avd -n android_test -t 1
Auto-selecting single ABI armeabi-v7a
Android 4.1 is a basic Android platform.
Do you wish to create a custom hardware profile [no]
Created AVD 'android_test' based on Android 4.1, ARM (armeabi-v7a) processor,
with the following hardware config:
hw.lcd.density=240
vm.heapSize=48
hw.ramSize=512

プロジェクト作成

> android create project -t 1 -k com.example.testapps -a HelloTest -p hello_test

ビルド

> ant debug

リリース用ならant releaseなのかな。

エミュレータ転送

> adb install bin/HelloTest-debug.apk

ここからscalaで開発するための準備。

> curl https://raw.github.com/n8han/conscript/master/setup.sh | sh
> cs n8han/giter8

$HOME/binにファイルがある

> mkdir scala-test
> cd scala-test
> g8 jberkel/android-app
api_level [10]: 16

androidコマンドで起動するSDKマネージャーでインストールしているものが
Android 4.1 (API 16)
だったので16を指定した。

> git clone git://github.com/jberkel/android-plugin.git
> cd android-plugin
> sbt update
> sbt publish-local

0.6.3-SNAPSHOTだった

> cd test-scala #g8でつくったプロジェクトのディレクトリ
> vi projects/plugins.sbt

0.6.3-SNAPSHOTに書き換える。

> sbt
> compile

OutOfMemoryErrorが出る時がある。が何度かやればいける。*1

デバッグ

> android:package-debug

エミュレータ起動してデプロイ

> android:emulator-start scala_android_test
> PANIC: Could not open: /usr/local/Cellar/android-sdk/r20.0.1/.android/avd/scala_android_test.ini

ここからPANIC: 部分の修正ログ。

> export ANDROID_SDK_HOME=/usr/local/Cellar/android-sdk/r20.0.1

してから

> android create avd -n scala_android_test -t 1

> sbt
> android:package-debug
> android:emulator-start scala_android_test
[error] Expected 'scala_android_test'
[error] android:emulator-start scala_android_test

~/.androidと$ANDROID_SDK_HOMEの両方にavdがあって、ごちゃってきたのでシンボリックリンクすることにした(強引)

> cd /usr/local/Cellar/android-sdk/r20.0.1
> ln -s ~/.android .android

> sbt
> android:emulator-start scala_android_test
> android:start-emulator

android:emulator-start scala_android_testでエミュレータが起動した時に画面にロックがかかっていたらandroid:start-emulatorする前にロックを外してホーム画面にしておく。

android:install-emulatorでもいい。
実機なら、
android:install-device
android:start-device

スクリーンショットも取れた。

> android:screenshot-emulator

sbtでandroid:のあとにタブ打てば色々とコマンドがでます。

[追記]
*1
sbtのファイルをみてみたら、

> cat /usr/local/bin/sbt
#!/bin/sh
test -f ~/.sbtconfig && . ~/.sbtconfig
exec java -Xmx512M ${SBT_OPTS} -jar /usr/local/Cellar/sbt/0.12.0/libexec/sbt-launch.jar "$@"

となっているので、

vi ~/.sbtconfig
SBT_OPTS=-Xmx1024M

としてみたらとりあえずOutOfMemoryErrorが出なくなった(いまのところ)
psみたら、
/usr/bin/java -Xmx512M -Xmx1024M -jar /usr/local/Cellar/sbt/0.12.0/libexec/sbt-launch.jar
いいのかな。。