diff --git a/install.sh b/install.sh
index b64f8643b7..70cb297a9e 100755
--- a/install.sh
+++ b/install.sh
@@ -128,12 +128,14 @@ ETC_DIRS="$ETC_LOCATION/im_kvm \
$ETC_LOCATION/tm_ssh \
$ETC_LOCATION/tm_dummy \
$ETC_LOCATION/hm \
- $ETC_LOCATION/ec2query_templates"
+ $ETC_LOCATION/ec2query_templates \
+ $ETC_LOCATION/occi_templates"
LIB_DIRS="$LIB_LOCATION/im_probes \
$LIB_LOCATION/ruby \
$LIB_LOCATION/ruby/OpenNebula \
$LIB_LOCATION/ruby/econe \
+ $LIB_LOCATION/ruby/occi \
$LIB_LOCATION/tm_commands \
$LIB_LOCATION/tm_commands/nfs \
$LIB_LOCATION/tm_commands/ssh \
@@ -163,6 +165,8 @@ INSTALL_FILES[11]="TM_EXAMPLE_SHARE_FILES:$SHARE_LOCATION/examples/tm"
INSTALL_FILES[12]="HOOK_SHARE_FILES:$SHARE_LOCATION/hooks"
INSTALL_FILES[13]="ECO_LIB_FILES:$LIB_LOCATION/ruby/econe"
INSTALL_FILES[14]="ECO_BIN_FILES:$BIN_LOCATION"
+INSTALL_FILES[15]="OCCI_LIB_FILES:$LIB_LOCATION/ruby/occi"
+INSTALL_FILES[16]="OCCI_BIN_FILES:$BIN_LOCATION"
INSTALL_ETC_FILES[0]="ETC_FILES:$ETC_LOCATION"
INSTALL_ETC_FILES[1]="VMM_XEN_ETC_FILES:$ETC_LOCATION/vmm_xen"
@@ -179,6 +183,8 @@ INSTALL_ETC_FILES[11]="TM_DUMMY_ETC_FILES:$ETC_LOCATION/tm_dummy"
INSTALL_ETC_FILES[12]="HM_ETC_FILES:$ETC_LOCATION/hm"
INSTALL_ETC_FILES[13]="ECO_ETC_FILES:$ETC_LOCATION"
INSTALL_ETC_FILES[14]="ECO_TEMPLATE_FILES:$ETC_LOCATION/ec2query_templates"
+INSTALL_ETC_FILES[15]="OCCI_ETC_FILES:$ETC_LOCATION"
+INSTALL_ETC_FILES[16]="OCCI_TEMPLATE_FILES:$ETC_LOCATION/occi_templates"
#-------------------------------------------------------------------------------
# Binary files, to be installed under $BIN_LOCATION
@@ -405,6 +411,32 @@ ECO_ETC_FILES="src/cloud/ec2/econe.conf"
ECO_TEMPLATE_FILES="src/cloud/ec2/templates/m1.small.erb"
+#-------------------------------------------------------------------------------
+# OCCI files
+#-------------------------------------------------------------------------------
+
+OCCI_LIB_FILES="src/cloud/occi/OCCI.rb \
+ src/cloud/occi/OCCIServer.rb \
+ src/cloud/occi/lib/OCCIConfiguration.rb \
+ src/cloud/occi/lib/ONEOCCIClient.rb \
+ src/cloud/occi/lib/VirtualMachineOCCI.rb \
+ src/cloud/occi/lib/VirtualMachinePoolOCCI.rb \
+ src/cloud/occi/lib/VirtualNetworkOCCI.rb \
+ src/cloud/occi/lib/VirtualNetworkPoolOCCI.rb"
+
+
+
+OCCI_BIN_FILES="src/cloud/occi/occi-server \
+ src/cloud/occi/commands/occi-compute \
+ src/cloud/occi/commands/occi-network \
+ src/cloud/occi/commands/occi-storage"
+
+OCCI_ETC_FILES="src/cloud/occi/occi-server.conf"
+
+OCCI_TEMPLATE_FILES="src/cloud/occi/templates/small.erb \
+ src/cloud/occi/templates/medium.erb \
+ src/cloud/occi/templates/large.erb"
+
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
diff --git a/src/cloud/occi/OCCI.rb b/src/cloud/occi/OCCI.rb
new file mode 100644
index 0000000000..f303615f74
--- /dev/null
+++ b/src/cloud/occi/OCCI.rb
@@ -0,0 +1,6 @@
+require 'lib/VirtualMachineOCCI'
+require 'lib/VirtualMachinePoolOCCI'
+require 'lib/VirtualNetworkOCCI'
+require 'lib/VirtualNetworkPoolOCCI'
+
+require 'lib/OCCIConfiguration'
diff --git a/src/cloud/occi/OCCIServer.rb b/src/cloud/occi/OCCIServer.rb
new file mode 100644
index 0000000000..1fd615e4f5
--- /dev/null
+++ b/src/cloud/occi/OCCIServer.rb
@@ -0,0 +1,442 @@
+################################################
+# Find out where the needed ruby libraries are
+################################################
+ONE_LOCATION=ENV["ONE_LOCATION"]
+
+if !ONE_LOCATION
+ RUBY_LIB_LOCATION="/usr/lib/one/ruby"
+else
+ RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
+ TEMPLATES_LOCATION=ONE_LOCATION+"/etc/occi_templates"
+ CONF_LOCATION=ONE_LOCATION+"/etc"
+end
+
+$: << RUBY_LIB_LOCATION
+$: << RUBY_LIB_LOCATION+"/occiserver"
+$: << RUBY_LIB_LOCATION+"/econe" # For the Repository Manager
+
+################################################
+# Required libraries
+################################################
+require 'rubygems'
+require 'sinatra'
+require 'time'
+require 'pp'
+
+require 'OpenNebula'
+require 'OCCI'
+
+
+include OpenNebula
+
+CONFIG=OCCIConfiguration.new(CONF_LOCATION+'/occi-server.conf')
+AUTH="#{CONFIG[:user]}:#{CONFIG[:password]}"
+ONE_RM_DATABASE=CONFIG[:database]
+
+# Load Repository Manager here to use ONE_RM_DATABASE from the configuration file
+require 'repo_manager'
+Image.image_dir=CONFIG[:image_dir]
+
+INSTANCE_TYPES=Hash.new
+
+puts "######################################"
+puts " OCCI Server configuration "
+puts "######################################"
+puts "---------8<---------------------"
+pp CONFIG
+puts "------>8------------------------"
+
+if CONFIG[:vm_type].kind_of?(Array)
+ # Multiple instance types
+ CONFIG[:vm_type].each {|type|
+ INSTANCE_TYPES[type['NAME']]=type
+ }
+else
+ # When only one instance type is defined
+ INSTANCE_TYPES[CONFIG[:vm_type]['NAME']]=CONFIG[:vm_type]
+end
+
+puts "######################################"
+puts " OCCI Available Instances Types "
+puts "######################################"
+puts "---------8<---------------------"
+pp INSTANCE_TYPES
+puts "------>8------------------------"
+
+set :host, CONFIG[:server]
+set :port, CONFIG[:port]
+
+# Start repository manager
+$repoman=RepoManager.new
+
+################################################
+# Client builders for ONE communication
+################################################
+
+def get_one_client
+ Client.new(AUTH)
+end
+
+def get_one_client_user(user_name)
+ user=get_user(user_name)
+
+
+ auth="#{user[:name]}:#{user[:password]}"
+
+ client=Client.new("dummy:dummy")
+ client.one_auth=auth
+ client
+end
+
+def get_user(name)
+ user=nil
+
+ user_pool=UserPool.new(get_one_client)
+ user_pool.info
+ user_pool.each{|u|
+ if u.name==name
+ user=Hash.new
+ user[:id]=u.id
+ user[:name]=u.name
+ user[:password]=u[:password]
+ end
+ }
+
+ user
+end
+
+###################################################
+# Helpers to manage authentication & authorization
+###################################################
+
+
+helpers do
+
+ def protected!
+ response['WWW-Authenticate'] = %(Basic realm="Testing HTTP Auth") and \
+ throw(:halt, [401, "Not authorized\n"]) and \
+ return unless authorized?
+ end
+
+ def authorized?
+
+ @auth ||= Rack::Auth::Basic::Request.new(request.env)
+
+ if !(@auth.provided? && @auth.basic? && @auth.credentials)
+ return false
+ end
+
+ user = get_user(@auth.credentials.first)
+
+ if user
+ if user[:password] == @auth.credentials[1]
+ return true
+ end
+ else
+ return false
+ end
+ end
+
+end
+
+###################################################
+# Helper functions
+###################################################
+
+
+def submit_vm(params)
+
+ if params['occixml']
+ @vm_info=Crack::XML.parse(params['occixml'])
+ else
+ halt 400, "OCCI XML representation of VM not present"
+ end
+
+ @vm_info=@vm_info['COMPUTE']
+
+ if @vm_info['STORAGE'].class==Array
+ disks=@vm_info['STORAGE']
+ else
+ disks=[@vm_info['STORAGE']]
+ end
+
+ disks.each{|disk|
+ next if disk['DISK']==nil
+ image=$repoman.get(disk['DISK']['image'])
+ disk['DISK']['source']=image.path
+ }
+
+ @vm_info['STORAGE']=disks[0]
+
+
+ if @vm_info['NETWORK']['NIC'].class==Array
+ nics=@vm_info['NETWORK']['NIC']
+ else
+ nics=[@vm_info['NETWORK']['NIC']]
+ end
+
+ nics.each{|nic|
+ vn=VirtualNetwork.new(VirtualNetwork.build_xml(nic['network']), get_one_client)
+ vn.info
+ vn_xml=Crack::XML.parse(vn.to_xml)
+ nic['network_id']=nic['network']
+ nic['network']=vn_xml['VNET']['NAME'].strip
+ }
+
+ @vm_info['NETWORK']['NIC']=nics
+
+ instance_type_name=params['InstanceType']
+ instance_type=INSTANCE_TYPES[instance_type_name]
+
+ halt 400, "Bad instance type" if !instance_type
+
+ @vm_info[:instance_type]=instance_type_name
+
+ template=ERB.new(File.read(
+ TEMPLATES_LOCATION+"/#{instance_type['TEMPLATE']}"))
+ template_text=template.result(binding)
+
+ vm=VirtualMachineOCCI.new(
+ VirtualMachine.build_xml, get_one_client_user(@auth.credentials[0]))
+ response=vm.allocate(template_text)
+
+ if OpenNebula.is_error?(response)
+ status 400
+ response.to_str
+ else
+ vm.info
+ vm.to_occi
+ end
+end
+
+def change_state(params)
+ if params['occixml']
+ vm_info=Crack::XML.parse(params['occixml'])
+ else
+ halt 400, "OCCI XML representation of VM not present"
+ end
+
+ vm=VirtualMachineOCCI.new(
+ VirtualMachine.build_xml(params[:id]), get_one_client_user(@auth.credentials[0]))
+
+ halt 400, "State not defined in the OCCI XML, cannot change state" if !vm_info['COMPUTE']['STATE']
+
+ case vm_info['COMPUTE']['STATE']
+ when "stopped"
+ rc = vm.stop
+ when "suspended"
+ rc = vm.suspend
+ when "resume"
+ rc = vm.resume
+ when "cancel"
+ rc = vm.cancel
+ when "done"
+ rc = vm.finalize
+ else
+ halt 400, "Invalid state"
+ end
+
+ if OpenNebula.is_error?(rc)
+ status 400
+ response.to_str
+ else
+ status 202
+ response_text = "Changing state of VM " + params[:id] + " to " + vm_info['COMPUTE']['STATE']
+ end
+end
+
+###################################################
+# Pool Resources methods
+###################################################
+
+post '/compute' do
+ # Auth check
+ protected!
+
+ submit_vm(params)
+end
+
+get '/compute' do
+ # Auth check
+ protected!
+ # Info retrieval
+ vmpool = VirtualMachinePoolOCCI.new(get_one_client)
+ vmpool.info
+ # OCCI conversion
+ begin
+ vmpool.to_occi(CONFIG[:server])
+ rescue Exception => e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+end
+
+post '/network' do
+ # Auth check
+ protected!
+ # Info retrieval from post params
+ if params['occixml']
+ network_info=Crack::XML.parse(params['occixml'])
+ else
+ halt 400, "OCCI XML representation of Virtual Network not present in the request"
+ end
+ # Allocate the VirtualNetwork
+ network = VirtualNetworkOCCI.new(
+ VirtualNetwork.build_xml,
+ get_one_client_user(@auth.credentials[0]))
+
+ vntemplate = network.to_one_template(network_info['NIC'],CONFIG[:bridge])
+ rc = network.allocate(vntemplate)
+
+ # Return status 201 XML if correct, status 500 otherwise
+ if rc
+ halt 500, "Error creating the Virtual Network: " + rc
+ else
+ network.info
+ status 201
+ network.to_occi
+ end
+end
+
+get '/network' do
+ # Auth check
+ protected!
+ # Info retrieval
+ network_pool = VirtualNetworkPoolOCCI.new(get_one_client)
+ network_pool.info
+ # OCCI conversion
+ begin
+ network_pool.to_occi(CONFIG[:server])
+ rescue Exception => e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+end
+
+post '/storage' do
+ # Auth check
+ protected!
+ # Info retrieval from post params
+ if params['occixml']
+ image_info=Crack::XML.parse(params['occixml'])
+ else
+ halt 400, "OCCI XML representation of Image not present in the request"
+ end
+
+ if params['file']
+ file=params["file"]
+ else
+ halt 400, "File not present in the request"
+ end
+
+ user = get_user(@auth.credentials[0])
+
+ # tmpfile where the file is stored
+ f_tmp=file[:tempfile]
+ img=$repoman.add(user[:id], f_tmp.path)
+ f_tmp.unlink
+
+ img.get_image_info
+ img.change_metadata(:name=>image_info['DISK']['NAME'])
+ img.change_metadata(:description=>image_info['DISK']['URL'])
+
+ xml_response = "" + img.uuid + "" +
+ "" + image_info['DISK']['NAME'] + "" +
+ "" + ((img.size/1024)/1024).to_s + "" +
+ "" + image_info['DISK']['URL'] + "" +
+ ""
+
+ status 201
+ xml_response
+end
+
+get '/storage' do
+ # Auth check
+ protected!
+ # Retrieve images owned by this user
+ user = get_user(@auth.credentials[0])
+ images=Image.filter(:owner => user[:id])
+
+ image_pool = ""
+ for image in images do
+ image_pool += ""
+ end
+ image_pool += ""
+ image_pool
+end
+
+###################################################
+# Entity Resources Methods
+###################################################
+
+get '/compute/:id' do
+ protected!
+ vm = VirtualMachineOCCI.new(VirtualMachine.build_xml(params[:id]),get_one_client_user(@auth.credentials[0]))
+ vm.info
+ begin
+ vm.to_occi()
+ rescue Exception => e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+end
+
+delete '/compute/:id' do
+ protected!
+ vm = VirtualMachineOCCI.new(VirtualMachine.build_xml(params[:id]),get_one_client_user(@auth.credentials[0]))
+ vm.finalize
+ "The Compute resource has been successfully deleted"
+end
+
+post '/compute/:id' do
+ protected!
+
+ change_state(params)
+end
+
+get '/network/:id' do
+ protected!
+ vn = VirtualNetworkOCCI.new(VirtualNetwork.build_xml(params[:id]),get_one_client_user(@auth.credentials[0]))
+ vn.info
+ begin
+ vn.to_occi()
+ rescue Exception => e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+end
+
+delete '/network/:id' do
+ protected!
+ vn = VirtualNetworkOCCI.new(VirtualNetwork.build_xml(params[:id]),get_one_client_user(@auth.credentials[0]))
+ vn.delete
+ "The Virtual Network has been successfully deleted"
+end
+
+get '/storage/:id' do
+ protected!
+ image=$repoman.get(params[:id])
+
+ image.get_image_info
+
+ if image
+ xml_response = "" + image.uuid + "" +
+ "" + image.name + "" +
+ "" + ((image.size/1024)/1024).to_s + "" +
+ "" + image.description + "" +
+ ""
+ else
+ status 404
+ "Disk with id = \"" + params[:id] + "\" not found"
+ end
+end
+
+delete '/storage/:id' do
+ protected!
+ "Not yet implemented"
+end
+
+
+
+
+
diff --git a/src/cloud/occi/commands/occi-compute b/src/cloud/occi/commands/occi-compute
new file mode 100755
index 0000000000..83e57be60e
--- /dev/null
+++ b/src/cloud/occi/commands/occi-compute
@@ -0,0 +1,220 @@
+#!/usr/bin/env ruby
+
+# == Synopsis
+# occi-compute
+#
+# Manages compute resources
+#
+# == Usage
+#
+# occi-compute [OPTIONS] [ARGUMENTS]
+#
+# COMMANDS
+#
+# create
+# creates a new compute resource described by the provided
+#
+#
+# list
+# lists available compute resources
+#
+# show
+# retrieves the OCCI XML representation of the compute resource
+# identified by
+#
+# update
+# updates the representation of the compute resource represented by the
+# provided
+#
+# delete
+# deletes the compute resource idenfitied by
+#
+#
+# OPTIONS
+#
+# -h, --help:
+# show help
+#
+# --username , -U :
+# The username of the user
+#
+# --password , -P :
+# The password of the user
+#
+# --url , -U :
+# Set url as the web service url to use
+#
+# --debug, -D
+# Enables verbosity
+#
+# --instance-type, -T
+# Specifies the type of compute resource we want (compulsory for create)
+#
+
+# -------------------------------------------------------------------------- #
+# Copyright 2002-2009, Distributed Systems Architecture Group, Universidad #
+# Complutense de Madrid (dsa-research.org) #
+# #
+# Licensed under the Apache License, Version 2.0 (the "License"); you may #
+# not use this file except in compliance with the License. You may obtain #
+# a copy of the License at #
+# #
+# http://www.apache.org/licenses/LICENSE-2.0 #
+# #
+# Unless required by applicable law or agreed to in writing, software #
+# distributed under the License is distributed on an "AS IS" BASIS, #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
+# See the License for the specific language governing permissions and #
+# limitations under the License. #
+#--------------------------------------------------------------------------- #
+
+ONE_LOCATION=ENV["ONE_LOCATION"]
+
+if !ONE_LOCATION
+ RUBY_LIB_LOCATION="/usr/lib/one/ruby"
+else
+ RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
+ TEMPLATES_LOCATION=ONE_LOCATION+"/etc/occi_templates"
+ CONF_LOCATION=ONE_LOCATION+"/etc"
+end
+
+$: << RUBY_LIB_LOCATION
+$: << RUBY_LIB_LOCATION+"/occi"
+
+require 'ONEOCCIClient'
+require 'getoptlong'
+require 'rdoc/usage'
+require 'pp'
+
+opts = GetoptLong.new(
+ ['--help', '-h',GetoptLong::NO_ARGUMENT],
+ ['--username', '-U',GetoptLong::REQUIRED_ARGUMENT],
+ ['--password', '-P',GetoptLong::REQUIRED_ARGUMENT],
+ ['--url', '-R',GetoptLong::REQUIRED_ARGUMENT],
+ ['--instance-type','-T',GetoptLong::REQUIRED_ARGUMENT],
+ ['--debug', '-D',GetoptLong::NO_ARGUMENT]
+ )
+
+url = nil
+username = nil
+password = nil
+auth = nil
+type = nil
+debug = false
+
+begin
+ opts.each do |opt, arg|
+ case opt
+ when '--help'
+ RDoc::usage
+ when '--username'
+ username = arg
+ when '--password'
+ password = arg
+ when '--url'
+ url = arg
+ when '--instance-type'
+ type = arg
+ when '--debug'
+ debug = true
+ end
+ end
+rescue Exception => e
+ exit -1
+end
+
+begin
+ occi_client = ONEOCCIClient::Client.new(url,username,password,debug)
+rescue Exception => e
+ puts "#{$0}: #{e.message}"
+ exit -1
+end
+
+if !ARGV[0]
+ puts "#{$0}: [COMMAND] not present"
+ puts "#{$0}: Execute #{$0} -h for help."
+ exit -1
+end
+
+case ARGV[0].downcase
+when 'list'
+ occi_client.get_vms
+
+when 'create'
+ if !type
+ puts "#{$0}: missing compulsory instance type"
+ exit -1
+ end
+
+ vm_xml = ARGV[1]
+
+ if !vm_xml || !File.exists?(vm_xml)
+ puts "#{$0} create: missing OCCI-XML parameter or file not found"
+ exit -1
+ end
+
+ begin
+ occi_client = ONEOCCIClient::Client.new(url,username,password,debug)
+ rescue Exception => e
+ puts "#{$0} create: #{e.message}"
+ exit -1
+ end
+
+ occi_client.post_vms(type, vm_xml)
+
+when 'show'
+ vm_id = ARGV[1]
+
+ if !vm_id
+ puts "#{$0} show: missing VM-ID parameter"
+ exit -1
+ end
+
+ begin
+ occi_client = ONEOCCIClient::Client.new(url,username,password,debug)
+ rescue Exception => e
+ puts "#{$0} show: #{e.message}"
+ exit -1
+ end
+
+ occi_client.get_vm(vm_id)
+
+when 'update'
+ vm_xml = ARGV[1]
+
+ if !vm_xml || !File.exists?(vm_xml)
+ puts "#{$0} update: missing OCCI-XML parameter or file not found"
+ exit -1
+ end
+
+ begin
+ occi_client = ONEOCCIClient::Client.new(url,username,password,debug)
+ rescue Exception => e
+ puts "#{$0} update: #{e.message}"
+ exit -1
+ end
+
+ occi_client.put_vm(vm_xml)
+
+when 'delete'
+ vm_id = ARGV[1]
+
+ if !vm_id
+ puts "#{$0} delete: missing VM-ID parameter"
+ exit -1
+ end
+
+ begin
+ occi_client = ONEOCCIClient::Client.new(url,username,password,debug)
+ rescue Exception => e
+ puts "#{$0} delete: #{e.message}"
+ exit -1
+ end
+
+ occi_client.delete_vm(vm_id)
+
+else
+ puts "Command #{ARGV[0]} not valid."
+ exit -1
+
+end
diff --git a/src/cloud/occi/commands/occi-network b/src/cloud/occi/commands/occi-network
new file mode 100755
index 0000000000..c1b888c5e2
--- /dev/null
+++ b/src/cloud/occi/commands/occi-network
@@ -0,0 +1,173 @@
+#!/usr/bin/env ruby
+
+# == Synopsis
+# occi-network
+#
+# Manages virtual networks
+#
+# == Usage
+#
+# occi-network [OPTIONS] [ARGUMENTS]
+#
+# COMMANDS
+#
+# create
+# creates a new virtual network described by the provided
+#
+#
+# list
+# lists available virtual networks
+#
+# show
+# retrieves the OCCI XML representation of the virtual network
+# identified by
+#
+# delete
+# deletes the virtual network idenfitied by
+#
+#
+# OPTIONS
+#
+# -h, --help:
+# show help
+#
+# --username , -U :
+# The username of the user
+#
+# --password , -P :
+# The password of the user
+#
+# --url , -U :
+# Set url as the web service url to use
+#
+# --debug, -D
+# Enables verbosity
+#
+
+# -------------------------------------------------------------------------- #
+# Copyright 2002-2009, Distributed Systems Architecture Group, Universidad #
+# Complutense de Madrid (dsa-research.org) #
+# #
+# Licensed under the Apache License, Version 2.0 (the "License"); you may #
+# not use this file except in compliance with the License. You may obtain #
+# a copy of the License at #
+# #
+# http://www.apache.org/licenses/LICENSE-2.0 #
+# #
+# Unless required by applicable law or agreed to in writing, software #
+# distributed under the License is distributed on an "AS IS" BASIS, #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
+# See the License for the specific language governing permissions and #
+# limitations under the License. #
+#--------------------------------------------------------------------------- #
+
+ONE_LOCATION=ENV["ONE_LOCATION"]
+
+if !ONE_LOCATION
+ RUBY_LIB_LOCATION="/usr/lib/one/ruby"
+else
+ RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
+ TEMPLATES_LOCATION=ONE_LOCATION+"/etc/occi_templates"
+ CONF_LOCATION=ONE_LOCATION+"/etc"
+end
+
+$: << RUBY_LIB_LOCATION
+$: << RUBY_LIB_LOCATION+"/occi"
+
+require 'ONEOCCIClient'
+require 'getoptlong'
+require 'rdoc/usage'
+require 'pp'
+
+
+opts = GetoptLong.new(
+ ['--help', '-h',GetoptLong::NO_ARGUMENT],
+ ['--username', '-U',GetoptLong::REQUIRED_ARGUMENT],
+ ['--password', '-P',GetoptLong::REQUIRED_ARGUMENT],
+ ['--url', '-R',GetoptLong::REQUIRED_ARGUMENT],
+ ['--debug', '-D',GetoptLong::NO_ARGUMENT]
+ )
+
+url = nil
+username = nil
+password = nil
+auth = nil
+debug = false
+
+begin
+ opts.each do |opt, arg|
+ case opt
+ when '--help'
+ RDoc::usage
+ when '--username'
+ username = arg
+ when '--password'
+ password = arg
+ when '--url'
+ url = arg
+ when '--debug'
+ debug = true
+ end
+ end
+rescue Exception => e
+ exit -1
+end
+
+
+begin
+ occi_client = ONEOCCIClient::Client.new(url,username,password,debug)
+rescue Exception => e
+ puts "#{$0}: #{e.message}"
+ exit -1
+end
+
+if !ARGV[0]
+ puts "#{$0}: [COMMAND] not present"
+ puts "#{$0}: Execute #{$0} -h for help."
+ exit -1
+end
+
+
+case ARGV[0].downcase
+when 'create'
+ network_xml = ARGV[1]
+
+ if !network_xml || !File.exists?(network_xml)
+ puts "#{$0} create: missing OCCI-XML parameter or file not found"
+ exit -1
+ end
+
+ occi_client.post_network(network_xml)
+
+when 'list'
+ occi_client.get_networks
+
+when 'show'
+ network_id = ARGV[1]
+
+ if !network_id
+ puts "#{$0} show: missing NETWORK-ID parameter or file not found"
+ exit -1
+ end
+
+ occi_client.get_network(network_id)
+
+when 'delete'
+ network_id = ARGV[1]
+
+ if !network_id
+ puts "#{$0} delete: missing NETWORK-ID parameter"
+ exit -1
+ end
+
+ occi_client.delete_network(network_id)
+
+else
+ puts "Command #{ARGV[0]} not valid."
+ exit -1
+
+end
+
+
+
+
diff --git a/src/cloud/occi/commands/occi-storage b/src/cloud/occi/commands/occi-storage
new file mode 100755
index 0000000000..782c05a123
--- /dev/null
+++ b/src/cloud/occi/commands/occi-storage
@@ -0,0 +1,163 @@
+#!/usr/bin/env ruby
+
+# == Synopsis
+# occi-storage
+#
+# Manages OCCI storage resource
+#
+# == Usage
+#
+# occi-storage [OPTIONS] [PARAMETERS]
+#
+# COMMANDS
+#
+# create
+# creates a new storage resource described by the provided
+#
+#
+# list
+# lists available storage resources
+#
+# show
+# retrieves the OCCI XML representation of the storage resource
+# identified by
+#
+# update
+# updates the representation of the storage resource represented by the
+# provided
+#
+# delete
+# deletes the storage resource idenfitied by
+#
+#
+# OPTIONS
+# -h, --help:
+# show help
+#
+# --username , -U :
+# The username of the user
+#
+# --password , -P :
+# The password of the user
+#
+# --url , -U :
+# Set url as the web service url to use
+#
+# --debug, -D
+# Enables verbosity
+#
+
+# -------------------------------------------------------------------------- #
+# Copyright 2002-2009, Distributed Systems Architecture Group, Universidad #
+# Complutense de Madrid (dsa-research.org) #
+# #
+# Licensed under the Apache License, Version 2.0 (the "License"); you may #
+# not use this file except in compliance with the License. You may obtain #
+# a copy of the License at #
+# #
+# http://www.apache.org/licenses/LICENSE-2.0 #
+# #
+# Unless required by applicable law or agreed to in writing, software #
+# distributed under the License is distributed on an "AS IS" BASIS, #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
+# See the License for the specific language governing permissions and #
+# limitations under the License. #
+#--------------------------------------------------------------------------- #
+
+ONE_LOCATION=ENV["ONE_LOCATION"]
+
+if !ONE_LOCATION
+ RUBY_LIB_LOCATION="/usr/lib/one/ruby"
+else
+ RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
+ TEMPLATES_LOCATION=ONE_LOCATION+"/etc/occi_templates"
+ CONF_LOCATION=ONE_LOCATION+"/etc"
+end
+
+$: << RUBY_LIB_LOCATION
+$: << RUBY_LIB_LOCATION+"/occi"
+
+require 'ONEOCCIClient'
+require 'getoptlong'
+require 'rdoc/usage'
+require 'pp'
+
+
+opts = GetoptLong.new(
+ ['--help', '-h',GetoptLong::NO_ARGUMENT],
+ ['--username', '-U',GetoptLong::REQUIRED_ARGUMENT],
+ ['--password', '-P',GetoptLong::REQUIRED_ARGUMENT],
+ ['--url', '-R',GetoptLong::REQUIRED_ARGUMENT],
+ ['--debug', '-D',GetoptLong::NO_ARGUMENT]
+ )
+
+url = nil
+username = nil
+password = nil
+auth = nil
+debug = false
+
+begin
+ opts.each do |opt, arg|
+ case opt
+ when '--help'
+ RDoc::usage
+ when '--username'
+ username = arg
+ when '--password'
+ password = arg
+ when '--url'
+ url = arg
+ when '--debug'
+ debug = true
+ end
+ end
+rescue Exception => e
+ exit -1
+end
+
+
+begin
+ occi_client = ONEOCCIClient::Client.new(url,username,password,debug)
+rescue Exception => e
+ puts "#{$0}: #{e.message}"
+ exit -1
+end
+
+case ARGV[0].downcase
+when 'create'
+ image_xml = ARGV[1]
+
+ if !image_xml || !File.exists?(image_xml)
+ puts "#{$0} create: missing occi xml parameter or file not found"
+ exit -1
+ end
+
+ occi_client.post_image(image_xml)
+
+when 'list'
+ occi_client.get_images
+
+when 'show'
+ image_id = ARGV[1]
+
+ if !image_id
+ puts "#{$0} show: missing storage id parameter or file not found"
+ exit -1
+ end
+
+ occi_client.get_image(image_id)
+
+when 'delete'
+ puts 'Delete still not implemented'
+ exit -1
+
+else
+ puts "Command #{ARGV[0]} not valid."
+ exit -1
+
+end
+
+
+
+
diff --git a/src/cloud/occi/lib/OCCIConfiguration.rb b/src/cloud/occi/lib/OCCIConfiguration.rb
new file mode 100644
index 0000000000..453743ba72
--- /dev/null
+++ b/src/cloud/occi/lib/OCCIConfiguration.rb
@@ -0,0 +1,73 @@
+
+class OCCIConfiguration
+
+ NAME_REG=/[\w\d_-]+/
+ VARIABLE_REG=/\s*(#{NAME_REG})\s*=\s*/
+ SIMPLE_VARIABLE_REG=/#{VARIABLE_REG}([^\[]+?)(#.*)?/
+ SINGLE_VARIABLE_REG=/^#{SIMPLE_VARIABLE_REG}$/
+ ARRAY_VARIABLE_REG=/^#{VARIABLE_REG}\[(.*?)\]/m
+
+ def initialize(file)
+ @conf=parse_conf(file)
+ end
+
+ def add_value(conf, key, value)
+ if conf[key]
+ if !conf[key].kind_of?(Array)
+ conf[key]=[conf[key]]
+ end
+ conf[key]< e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+
+ puts curl.body_str
+ end
+
+ #######################################################################
+ # Retieves the pool of Virtual Machines
+ #######################################################################
+ def get_vms
+ curl=Curl::Easy.new(@endpoint+"/compute")
+ curl.userpwd=@occiauth
+ curl.verbose=true if @debug
+
+ begin
+ curl.http_get
+ rescue Exception => e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+ puts curl.body_str
+ end
+
+ #######################################################################
+ # Post a new Network to the VN Pool
+ # :xmlfile xml description of the Virtual Network
+ #######################################################################
+ def post_network(xmlfile)
+ curl=Curl::Easy.new(@endpoint+"/network")
+ curl.userpwd=@occiauth
+ curl.verbose=true if @debug
+
+ xml=File.read(xmlfile)
+
+ begin
+ curl.http_post(
+ Curl::PostField.content('occixml', xml)
+ )
+ rescue Exception => e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+
+ puts curl.body_str
+ end
+
+ #######################################################################
+ # Retieves the pool of Virtual Networks
+ #######################################################################
+ def get_networks
+ curl=Curl::Easy.new(@endpoint+"/network")
+ curl.userpwd=@occiauth
+ curl.verbose=true if @debug
+
+ begin
+ curl.http_get
+ rescue Exception => e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+ puts curl.body_str
+ end
+
+ #######################################################################
+ # Post a new Image to the Image Pool
+ # :xmlfile
+ #######################################################################
+ def post_image(xmlfile)
+ xml=File.read(xmlfile)
+ image_info=Crack::XML.parse(xml)
+
+ curl=Curl::Easy.new(@endpoint+"/storage")
+ curl.userpwd=@occiauth
+ curl.verbose=true if @debug
+ curl.multipart_form_post = true
+
+ file_path = image_info['DISK']['URL']
+
+ m=file_path.match(/^\w+:\/\/(.*)$/)
+
+ if m
+ file_path="/"+m[1]
+ end
+
+ begin
+ curl.http_post(
+ Curl::PostField.content('occixml', xml),
+ Curl::PostField.file('file', file_path)
+ )
+ rescue Exception => e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+
+ puts curl.body_str
+ end
+
+ #######################################################################
+ # Retieves the pool of Images owned by the user
+ #######################################################################
+ def get_images
+ curl=Curl::Easy.new(@endpoint+"/storage")
+ curl.userpwd=@occiauth
+ curl.verbose=true if @debug
+
+ begin
+ curl.http_get
+ rescue Exception => e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+ puts curl.body_str
+ end
+
+ #######################################################################
+ # Entity Resource Request Methods
+ #######################################################################
+
+ #######################################################################
+ # :id VM identifier
+ #######################################################################
+ def get_vm(id)
+ curl=Curl::Easy.new(@endpoint+"/compute/" + id.to_s)
+ curl.userpwd=@occiauth
+ curl.verbose=true if @debug
+
+ begin
+ curl.http_get
+ rescue Exception => e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+ puts curl.body_str
+ end
+
+ #######################################################################
+ # Puts a new Compute representation in order to change its state
+ # :xmlfile Compute OCCI xml representation
+ #######################################################################
+ def put_vm(xmlfile)
+ xml=File.read(xmlfile)
+ vm_info=Crack::XML.parse(xml)
+
+ curl=Curl::Easy.new(@endpoint+"/compute/"+vm_info['ID'])
+ curl.userpwd=@occiauth
+ curl.verbose=true if @debug
+
+ begin
+ curl.http_post(Curl::PostField.content('occixml', xml))
+ rescue Exception => e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+
+ puts curl.body_str
+ end
+
+ #######################################################################
+ # :id Compute identifier
+ #######################################################################
+ def delete_vm(id)
+ curl=Curl::Easy.new(@endpoint+"/compute/" + id.to_s)
+ curl.userpwd=@occiauth
+ curl.verbose=true if @debug
+
+ begin
+ curl.http_delete
+ rescue Exception => e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+ puts curl.body_str
+ end
+
+ #######################################################################
+ # Retrieves a Virtual Network
+ # :id Virtual Network identifier
+ #######################################################################
+ def get_network(id)
+ curl=Curl::Easy.new(@endpoint+"/network/" + id.to_s)
+ curl.userpwd=@occiauth
+ curl.verbose=true if @debug
+
+ begin
+ curl.http_get
+ rescue Exception => e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+ puts curl.body_str
+ end
+
+ #######################################################################
+ # :id VM identifier
+ #######################################################################
+ def delete_network(id)
+ curl=Curl::Easy.new(@endpoint+"/network/" + id.to_s)
+ curl.userpwd=@occiauth
+ curl.verbose=true if @debug
+
+ begin
+ curl.http_delete
+ rescue Exception => e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+ puts curl.body_str
+ end
+
+ #######################################################################
+ # Retieves an Image
+ # :image_uuid Image identifier
+ #######################################################################
+ def get_image(image_uuid)
+ curl=Curl::Easy.new(@endpoint+"/storage/"+image_uuid)
+ curl.userpwd=@occiauth
+ curl.verbose=true if @debug
+
+ begin
+ curl.http_get
+ rescue Exception => e
+ error = OpenNebula::Error.new(e.message)
+ return error
+ end
+ puts curl.body_str
+ end
+ end
+end
+
+
+
+
+
+
diff --git a/src/cloud/occi/lib/VirtualMachineOCCI.rb b/src/cloud/occi/lib/VirtualMachineOCCI.rb
new file mode 100644
index 0000000000..71ea297046
--- /dev/null
+++ b/src/cloud/occi/lib/VirtualMachineOCCI.rb
@@ -0,0 +1,69 @@
+require 'OpenNebula'
+
+include OpenNebula
+
+class VirtualMachineOCCI < VirtualMachine
+ # Creates the VMI representation of a Virtual Machine
+ def to_occi
+ occi_xml = ""
+ occi_xml += "" + id.to_s + ""
+ occi_xml += "" + self['NAME'] + ""
+ occi_xml += "" + self['OCCI_SIZE_TYPE'] + "" if self['OCCI_SIZE_TYPE']
+ occi_xml += "" + state_str + ""
+
+ # Now let's parse the template
+ template=self.to_hash("TEMPLATE")
+
+ template['DISK']=[template['DISK']].flatten
+
+ if template['DISK']
+
+ occi_xml += ""
+
+ template['DISK'].each{|disk|
+ case disk['TYPE']
+ when "disk" then
+ occi_xml += ""
+ when "swap" then
+ occi_xml += ""
+ when "fs" then
+ occi_xml += ""
+ end
+ }
+
+ occi_xml += ""
+ end
+
+ template['NIC']=[template['NIC']].flatten
+
+ if template['NIC']
+ occi_xml += ""
+
+ template['NIC'].each{|nic|
+
+ occi_xml += ""
+ }
+
+ occi_xml += ""
+ end
+
+ occi_xml += ""
+
+ return occi_xml
+
+ end
+end
+
+if $0 == __FILE__
+ t=VirtualMachineOCCI.new(VirtualMachine.build_xml(6),Client.new("tinova:opennebula"))
+ # t=VirtualMachineOCCI.new(VirtualMachine.build_xml,nil)
+ t.info
+ puts t.to_occi
+end
+
+
+
diff --git a/src/cloud/occi/lib/VirtualMachinePoolOCCI.rb b/src/cloud/occi/lib/VirtualMachinePoolOCCI.rb
new file mode 100644
index 0000000000..cad56d8a8f
--- /dev/null
+++ b/src/cloud/occi/lib/VirtualMachinePoolOCCI.rb
@@ -0,0 +1,19 @@
+require 'OpenNebula'
+require 'Crack'
+
+include OpenNebula
+
+class VirtualMachinePoolOCCI < VirtualMachinePool
+ # Creates the OCCI representation of a Virtual Machine Pool
+ def to_occi(base_url)
+ pool_hash=Crack::XML.parse(to_xml)
+ occi_xml = ""
+
+ pool_hash['VM_POOL']['VM'].each{|vm|
+ occi_xml+=''
+ }
+ occi_xml += ""
+ end
+end
+
diff --git a/src/cloud/occi/lib/VirtualNetworkOCCI.rb b/src/cloud/occi/lib/VirtualNetworkOCCI.rb
new file mode 100644
index 0000000000..f8170070df
--- /dev/null
+++ b/src/cloud/occi/lib/VirtualNetworkOCCI.rb
@@ -0,0 +1,28 @@
+require 'OpenNebula'
+require 'Crack'
+
+include OpenNebula
+
+class VirtualNetworkOCCI < VirtualNetwork
+ # Creates the OCCI representation of a Virtual Network
+ def to_occi()
+ vn_hash=Crack::XML.parse(to_xml)
+ occi_xml = ""
+
+ occi_xml += "" + vn_hash['VNET']['ID'].strip + ""
+ occi_xml += "" + vn_hash['VNET']['NAME'].strip + ""
+ occi_xml += "" + vn_hash['VNET']['TEMPLATE']['NETWORK_ADDRESS'].strip + ""
+ occi_xml += "" + vn_hash['VNET']['TEMPLATE']['NETWORK_SIZE'].strip + ""
+
+ occi_xml += ""
+ end
+
+ def to_one_template(network_hash, bridge)
+ one_template = "NAME=" + network_hash['NAME'] + "\n"
+ one_template += "TYPE=RANGED\n"
+ one_template += "BRIDGE=" + bridge + "\n"
+ one_template += "NETWORK_ADDRESS=" + network_hash['ADDRESS'] + "\n"
+ one_template += "NETWORK_SIZE=" + network_hash['SIZE'] + "\n"
+ end
+end
+
diff --git a/src/cloud/occi/lib/VirtualNetworkPoolOCCI.rb b/src/cloud/occi/lib/VirtualNetworkPoolOCCI.rb
new file mode 100644
index 0000000000..c1ba20b16d
--- /dev/null
+++ b/src/cloud/occi/lib/VirtualNetworkPoolOCCI.rb
@@ -0,0 +1,19 @@
+require 'OpenNebula'
+require 'Crack'
+
+include OpenNebula
+
+class VirtualNetworkPoolOCCI < VirtualNetworkPool
+ # Creates the VMI representation of a Virtual Network
+ def to_occi(base_url)
+ network_pool_hash=Crack::XML.parse(to_xml)
+ occi_xml = ""
+
+ network_pool_hash['VNET_POOL']['VNET'].each{|network|
+ occi_xml+=''
+ }
+
+ occi_xml += ""
+ end
+end
\ No newline at end of file
diff --git a/src/cloud/occi/occi-server b/src/cloud/occi/occi-server
new file mode 100755
index 0000000000..ce2922944d
--- /dev/null
+++ b/src/cloud/occi/occi-server
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+eval `grep ^IMAGE_DIR= $ONE_LOCATION/etc/occi-server.conf `
+export TMPDIR=$IMAGE_DIR/tmp
+mkdir -p $TMPDIR
+
+nohup ruby $ONE_LOCATION/lib/ruby/occi/OCCIServer.rb >> $ONE_LOCATION/var/occi-server.log &
+
+
diff --git a/src/cloud/occi/occi-server.conf b/src/cloud/occi/occi-server.conf
new file mode 100644
index 0000000000..20dc160e7a
--- /dev/null
+++ b/src/cloud/occi/occi-server.conf
@@ -0,0 +1,26 @@
+# OpenNebula administrator user
+USER=oneadmin
+PASSWORD=
+
+# OpenNebula server contact information
+ONE_XMLRPC=http://localhost:2633/RPC2
+
+# Host and port where the occi server will run
+SERVER=
+PORT=4567
+
+# Configuration for the image repository
+DATABASE=/var/occi.db
+IMAGE_DIR=
+
+# Configuration for OpenNebula's Virtual Networks
+BRIDGE=
+
+# Default format for FS
+FS_FORMAT=ext3
+
+# VM types allowed and its template file (inside templates directory)
+VM_TYPE=[NAME=small, TEMPLATE=small.erb]
+VM_TYPE=[NAME=medium, TEMPLATE=medium.erb]
+VM_TYPE=[NAME=large, TEMPLATE=large.erb]
+
diff --git a/src/cloud/occi/templates/large.erb b/src/cloud/occi/templates/large.erb
new file mode 100644
index 0000000000..44b60c6d9e
--- /dev/null
+++ b/src/cloud/occi/templates/large.erb
@@ -0,0 +1,45 @@
+NAME = <%= @vm_info['NAME']%>
+
+CPU = 8
+MEMORY = 8192
+
+OS = [ kernel = /vmlinuz,
+ initrd = /initrd.img,
+ root = sda1,
+ kernel_cmd = "ro xencons=tty console=tty1"]
+<% @vm_info['STORAGE'].each do |key, image|
+
+case key
+
+ when "SWAP"
+%>
+DISK = [ type = "swap",
+ size=<%= image['size']%>,
+ dev=<%= image['dev']%> ]
+<%
+ when "DISK"
+%>
+DISK = [ type = "disk",
+ dev=<%= image['dev']%>,
+ source=<%= image['source']%>,
+ image_id=<%= image['image']%> ]
+<%
+ when "FS"
+%>
+DISK = [ type = "fs",
+ dev=<%= image['dev']%>,
+ size=<%= image['size']%>,
+ format=<%= CONFIG[:fs_format]||"ext3"%> ]
+<% end %>
+<% end %>
+<% @vm_info['NETWORK']['NIC'].each do |nic| %>
+NIC = [
+<% if nic['ip'] %>
+ IP=<%= nic['ip'] %>,
+<% end %>
+ NETWORK=<%= nic['network']%>,
+ NETWORK_ID=<%= nic['network_id'] %>
+]
+<% end %>
+OCCI_SIZE_TYPE = <%= @vm_info[:instance_type ]%>
+
diff --git a/src/cloud/occi/templates/medium.erb b/src/cloud/occi/templates/medium.erb
new file mode 100644
index 0000000000..eb8ba528e1
--- /dev/null
+++ b/src/cloud/occi/templates/medium.erb
@@ -0,0 +1,45 @@
+NAME = <%= @vm_info['NAME']%>
+
+CPU = 4
+MEMORY = 4096
+
+OS = [ kernel = /vmlinuz,
+ initrd = /initrd.img,
+ root = sda1,
+ kernel_cmd = "ro xencons=tty console=tty1"]
+<% @vm_info['STORAGE'].each do |key, image|
+
+case key
+
+ when "SWAP"
+%>
+DISK = [ type = "swap",
+ size=<%= image['size']%>,
+ dev=<%= image['dev']%> ]
+<%
+ when "DISK"
+%>
+DISK = [ type = "disk",
+ dev=<%= image['dev']%>,
+ source=<%= image['source']%>,
+ image_id=<%= image['image']%> ]
+<%
+ when "FS"
+%>
+DISK = [ type = "fs",
+ dev=<%= image['dev']%>,
+ size=<%= image['size']%>,
+ format=<%= CONFIG[:fs_format]||"ext3"%> ]
+<% end %>
+<% end %>
+<% @vm_info['NETWORK']['NIC'].each do |nic| %>
+NIC = [
+<% if nic['ip'] %>
+ IP=<%= nic['ip'] %>,
+<% end %>
+ NETWORK=<%= nic['network']%>,
+ NETWORK_ID=<%= nic['network_id'] %>
+]
+<% end %>
+OCCI_SIZE_TYPE = <%= @vm_info[:instance_type ]%>
+
diff --git a/src/cloud/occi/templates/small.erb b/src/cloud/occi/templates/small.erb
new file mode 100644
index 0000000000..c3157aefe0
--- /dev/null
+++ b/src/cloud/occi/templates/small.erb
@@ -0,0 +1,45 @@
+NAME = <%= @vm_info['NAME']%>
+
+CPU = 1
+MEMORY = 1024
+
+OS = [ kernel = /vmlinuz,
+ initrd = /initrd.img,
+ root = sda1,
+ kernel_cmd = "ro xencons=tty console=tty1"]
+<% @vm_info['STORAGE'].each do |key, image|
+
+case key
+
+ when "SWAP"
+%>
+DISK = [ type = "swap",
+ size=<%= image['size']%>,
+ dev=<%= image['dev']%> ]
+<%
+ when "DISK"
+%>
+DISK = [ type = "disk",
+ dev=<%= image['dev']%>,
+ source=<%= image['source']%>,
+ image_id=<%= image['image']%> ]
+<%
+ when "FS"
+%>
+DISK = [ type = "fs",
+ dev=<%= image['dev']%>,
+ size=<%= image['size']%>,
+ format=<%= CONFIG[:fs_format]||"ext3"%> ]
+<% end %>
+<% end %>
+<% @vm_info['NETWORK']['NIC'].each do |nic| %>
+NIC = [
+<% if nic['ip'] %>
+ IP=<%= nic['ip'] %>,
+<% end %>
+ NETWORK=<%= nic['network']%>,
+ NETWORK_ID=<%= nic['network_id'] %>
+]
+<% end %>
+OCCI_SIZE_TYPE = <%= @vm_info[:instance_type ]%>
+