Hello World, OpenNebula Cloud API 编程

先报告一下我们云计算项目的进度。去年休假前订购的服务器和部件已经陆续到货了,计算节点采用的是 Dell PowerEdge M710HD 刀片服务器,特别为数据中心级虚拟应用设计,海量内存、密集 IO 吞吐等优势,特别适合云计算、虚拟机等应用。现在正在等 Dell 的售后技术人员过来安装服务器和存储阵列,有些电源和机柜问题需要解决,顺利的话下周服务器可以上线。

dell poweredge m710hd

OpenNebula 提供了 XML-RPC 的方式访问 OpenNebula Cloud Api (OCA),这样就允许不同操作系统、不同语言编写的客户端程序可以通过 XML-RPC 远程调用的方式来访问 OpenNebula 服务。下面通过两个不同语言编写的最简单例子抛砖引玉一下,来看看如何是如何与 OCA 打交道的。

OpenNebula 绝大部分是由 Ruby 编写的,其提供的 Ruby OCA API 实现当然是最丰富和完整的。先安装 Ruby OCA Bindings:

$ sudo gem install oca

用 Ruby 编写一小段代码试验一下,以下代码用来打印当前云里每个计算结点的 hostname:

#!/usr/bin/ruby

require 'rubygems'
require 'oca'

include OpenNebula

# OpenNebula credentials
CREDENTIALS = "oneadmin:vpsee"

# XML_RPC endpoint where OpenNebula is listening
ENDPOINT    = "http://localhost:2633/RPC2"

client = Client.new(CREDENTIALS, ENDPOINT)
host_pool = HostPool.new(client)
rc = host_pool.info

# Print all the hostname from the host pool
host_pool.each do |host|
     puts host.name
end

再来看看用 Python 如何编写上面类似功能的代码。安装 Python OCA Bindings:

$ sudo easy_install oca

用 Python 编写一小段代码看一下:

#!/usr/bin/python

import oca

# OpenNebula credentials
CREDENTIALS = "oneadmin:vpsee"

# XML_RPC endpoint where OpenNebula is listening
ENDPOINT    = "http://localhost:2633/RPC2"

client = oca.Client(CREDENTIALS, ENDPOINT)
host_pool = oca.HostPool(client)
host_pool.info()

# Print all the hostname from the host pool
for host in host_pool:
    print host.name

应该没人会想在这种情况下用 Java 或 C++ 吧,Programming Examples 里面提供的 Java OCA 和 C++ 例子比 Ruby, Python 复杂得多。

在 Mac OS X Snow Leopard 上安装 Ruby 和 Rails

昨天刚发布的 Rails 3.0.6 包含重要的安全更新,所以刚好在升级 Rails 的时候顺便把 Ruby 也升级一下。Mac OS X Snow Leopard 默认的 Ruby 版本是 1.8.7 的,貌似直接源代码编译升级到 1.9.2 有一些问题(网上有不少人升级到 1.9.2 的时候出问题)。最好的办法是用 RVM (Ruby Version Manager),又简单又方便,而且不会替代系统自带的 Ruby 1.8.7,以后可以随时在 1.8.7 和 1.9.2 之间切换,适合开发和移植程序,Rails 3 也支持 Ruby 1.9.2 版本。

安装必要工具

安装前确定 Mac OS X 已经安装了最新的 Xcode 开发工具,至少是 3.2.1 版本。然后安装 git 工具:

$ xcodebuild -version
Xcode 3.2.6
Component versions: DevToolsCore-1809.0; DevToolsSupport-1806.0
BuildVersion: 10M2518

$ sudo port install git

安装 RVM

安装 RVM 的方法有点不同:

$ bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )

如果有代理的话,用 -x 设置代理服务器:

$ bash < <( curl -x 192.168.0.1:3128 http://rvm.beginrescueend.com/releases/rvm-install-head )

配置 RVM:

$ vi ~/.bashrc
# This loads RVM into a shell session.
[[ -s "/Users/vpsee/.rvm/scripts/rvm" ]] && source "/Users/vpsee/.rvm/scripts/rvm"

关闭 Terminal 后重新打开以便 .bash_profile 文件生效,这个时候用下面命令可以验证 rvm 是否安装成功:

$ type rvm | head -n1
rvm is a function

安装 Ruby

安装最新的 Ruby 1.9.2-p180 稳定版本:

$ rvm install 1.9.2

系统上原来是 1.8.7 的,把系统默认的 ruby 解释器设置成 1.9.2:

$ ruby -v
ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]
$ rvm --default 1.9.2
$ ruby -v
ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-darwin10.7.0]

检查 gem 版本是 1.3.7 或以上,以及 sqlite3 版本是 3.6.12 或以上,然后使用 gem 安装 sqlite3-ruby:

$ gem -v
1.3.7

$ sqlite3 -version
3.7.5

$ gem install sqlite3-ruby
/Users/vpsee/.rvm/rubies/ruby-1.9.2-p180/bin/gem:4: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040777

$ sudo chmod go-w /usr/local/bin
$ gem install sqlite3-ruby

安装 sqlite3-ruby 的时候出现目录权限警告, 修改一下 /usr/local/bin 的权限就好了。

安装 Rails

安装 Rails 3.0.6 版本:

$ gem install rails

$ rails -v
Rails 3.0.6

升级 Ruby 和 Rails 完毕后我们就在 Snow Leopard (Mac OS X 10.6.7) 上有了一个最新的 Ruby on Rails 开发环境。

利用 Android 和 Wi-Fi 做间谍相机

现在 iPhone 和 Android 上的应用程序如此丰富不是偶然的,在 iPhone 和 Android 上开发应用实在是太简单了,开发人员很容易就能上手。VPSee 花了两天的时间完成了一个 Android 上的中、日、英文本阅读器,还包括自动识别文本编码(不用自己调编码设定),触摸放大、翻页等功能,这在 Nokia Symbian 上是不可能的(至少两天内不可能完成),如果有人也有过痛苦的 Symbian 开发经历就会明白 VPSee 在说什么。现在 Android 在 Scripting Layer for Android (SL4A) 项目的帮助下能支持 Python, Perl, JRuby, Lua, BeanShell, JavaScript, Tcl 等脚本语言,我们安装 SL4A 后可以在 Android 上直接运行这些脚本,使得 Android 能支持更多编程语言、更加强大了。

利用 Android 和 Wi-Fi 做间谍相机的想法是这样的,在 Android 上装一个 web server 并用 Ruby 写个小小的 web app,通过浏览器和 wifi 访问这个 web server 和 web app,每次访问 web app 都会拍一张照片并更新 web server 上的照片。这样我们只需要把 Android 手机藏在某个地方,然后在电脑上就可以 “看” 到 Android 拍到的照片了~~(请保留邪恶的想法:D),以下操作在 VPSee 的 HTC Desire (Android 2.1) 上测试通过:

安装 SL4A 和 JRuby

首先到 SL4A 官方网站下载 sl4a_r2.apk 安装到 Android 上,然后点击 “menu” -> “View” -> “Interpreters”,然后再点击 “menu” -> “Add” -> “JRuby-1.4” 就会安装 JRuby for Android,安装成功后打开 SL4A 就会看到 hello_world.rb 和 toggle_airplane.rb 连个例子脚本,点击 “menu” -> “Add” 就会看到多了一个 “JRuby-1.4” 选项。

Ruby web app

接下来在自己电脑上写个 web app,并把 web app 拷贝到 Android 上,用 Ruby 写 web app 当然最好是用 Ruby on Rails 了,这里的应用没那么复杂,使用另一个轻量级 Ruby web 框架 Sinatra 就可以了。在桌面上创建一个 spycam 项目、创建相关目录、安装 sinatra:

$ cd /Users/vpsee/Desktop/
$ mkdir spycam
$ cd spycam
$ mkdir public
$ mkdir vendor
$ mkdir vendor/gems

$ gem install --http-proxy http://192.168.0.1:3128 sinatra
$ gem unpack sinatra --target=vendor/gems
Unpacked gem: '/Users/vpsee/Desktop/spycam/vendor/gems/sinatra-1.0'
$ gem unpack rack --target=vendor/gems
Unpacked gem: '/Users/vpsee/Desktop/spycam/vendor/gems/rack-1.1.0'

创建一个 spycam.rb 文件,并把以下内容拷贝过去(代码来自这篇文章):

$ vi spycam.rb

APP_DIR = File.expand_path File.dirname(__FILE__)
GEM_DIR = File.join(APP_DIR, 'vendor', 'gems')
PUBLIC_DIR = File.join(APP_DIR, 'public')

Dir.entries(GEM_DIR).each do |dir|
  $LOAD_PATH << File.join(GEM_DIR, dir, 'lib')
end

require "rack"
require "sinatra/base"
require "android"
DROID = Android.new

TEMPLATE = <<HTML
<!DOCTYPE html>
<html>
<head>
<title>Spy Camera - vpsee.com</title>
</head>
<body>
<a href="/"><img src="latest.png"></a>
</body>
</html>
HTML
class SpyCam < Sinatra::Base set :public, File.join(APP_DIR, 'public') get "/" do snapshot_path = File.join PUBLIC_DIR, 'latest.png' DROID.cameraCapturePicture snapshot_path TEMPLATE end end SpyCam.run!

运行

测试一下上面的 web app 和远程 WiFi 相机是否能拍照。用电脑通过 USB 连上 Android,拷贝上面的 spycam 下的 spycam.rb, public, vendor 到 Android 下的 sl4a/scripts,然后断开 Android USB 连接,运行 SL4A 执行 spycam.rb 脚本就会自动启动 WEBrick server 和运行 spycam.rb,WEBrick 是个提供 HTTP web services 的 Ruby 库,集成在 RoR 开发环境里用来测试程序,也是一个简单的 HTTP server,成功运行后显示应该如下:

Android WEBrick

在任何一台使用相同网络的电脑上打开浏览器访问 http://192.168.1.115:4567(Android 当前使用的 IP 地址是 192.168.1.115)就可以看到 Android 拍照了,每点击一次照片就会更新。

Android Spy Camera