mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-26 06:50:09 +03:00
First commit of OpenNebula OCCI implementation
git-svn-id: http://svn.opennebula.org/one/trunk@783 3034c82b-c49b-4eb3-8279-a7acafdc01c0
This commit is contained in:
parent
fc85c54245
commit
8b717585d5
34
install.sh
34
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"
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
|
6
src/cloud/occi/OCCI.rb
Normal file
6
src/cloud/occi/OCCI.rb
Normal file
@ -0,0 +1,6 @@
|
||||
require 'lib/VirtualMachineOCCI'
|
||||
require 'lib/VirtualMachinePoolOCCI'
|
||||
require 'lib/VirtualNetworkOCCI'
|
||||
require 'lib/VirtualNetworkPoolOCCI'
|
||||
|
||||
require 'lib/OCCIConfiguration'
|
442
src/cloud/occi/OCCIServer.rb
Normal file
442
src/cloud/occi/OCCIServer.rb
Normal file
@ -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 = "<DISK><ID>" + img.uuid + "</ID>" +
|
||||
"<NAME>" + image_info['DISK']['NAME'] + "</NAME>" +
|
||||
"<SIZE>" + ((img.size/1024)/1024).to_s + "</SIZE>" +
|
||||
"<URL>" + image_info['DISK']['URL'] + "<URL>" +
|
||||
"</DISK>"
|
||||
|
||||
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 = "<STORAGE>"
|
||||
for image in images do
|
||||
image_pool += "<DISK id=\"#{image[:uuid]}\" href=\"http://#{CONFIG[:server]}/storage/#{image[:uuid]}\">"
|
||||
end
|
||||
image_pool += "</STORAGE>"
|
||||
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 = "<DISK><ID>" + image.uuid + "</ID>" +
|
||||
"<NAME>" + image.name + "</NAME>" +
|
||||
"<SIZE>" + ((image.size/1024)/1024).to_s + "</SIZE>" +
|
||||
"<URL>" + image.description + "<URL>" +
|
||||
"</DISK>"
|
||||
else
|
||||
status 404
|
||||
"Disk with id = \"" + params[:id] + "\" not found"
|
||||
end
|
||||
end
|
||||
|
||||
delete '/storage/:id' do
|
||||
protected!
|
||||
"Not yet implemented"
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
220
src/cloud/occi/commands/occi-compute
Executable file
220
src/cloud/occi/commands/occi-compute
Executable file
@ -0,0 +1,220 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# == Synopsis
|
||||
# occi-compute
|
||||
#
|
||||
# Manages compute resources
|
||||
#
|
||||
# == Usage
|
||||
#
|
||||
# occi-compute <COMMAND> [OPTIONS] [ARGUMENTS]
|
||||
#
|
||||
# COMMANDS
|
||||
#
|
||||
# create <occi xml file>
|
||||
# creates a new compute resource described by the provided
|
||||
# <occi xml file>
|
||||
#
|
||||
# list
|
||||
# lists available compute resources
|
||||
#
|
||||
# show <compute id>
|
||||
# retrieves the OCCI XML representation of the compute resource
|
||||
# identified by <compute id>
|
||||
#
|
||||
# update <occi xml file>
|
||||
# updates the representation of the compute resource represented by the
|
||||
# provided <occi xml file>
|
||||
#
|
||||
# delete <compute id>
|
||||
# deletes the compute resource idenfitied by <compute id>
|
||||
#
|
||||
#
|
||||
# OPTIONS
|
||||
#
|
||||
# -h, --help:
|
||||
# show help
|
||||
#
|
||||
# --username <id>, -U <id>:
|
||||
# The username of the user
|
||||
#
|
||||
# --password <key>, -P <key>:
|
||||
# The password of the user
|
||||
#
|
||||
# --url <url>, -U <url>:
|
||||
# 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
|
173
src/cloud/occi/commands/occi-network
Executable file
173
src/cloud/occi/commands/occi-network
Executable file
@ -0,0 +1,173 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# == Synopsis
|
||||
# occi-network
|
||||
#
|
||||
# Manages virtual networks
|
||||
#
|
||||
# == Usage
|
||||
#
|
||||
# occi-network <COMMAND> [OPTIONS] [ARGUMENTS]
|
||||
#
|
||||
# COMMANDS
|
||||
#
|
||||
# create <occi xml file>
|
||||
# creates a new virtual network described by the provided
|
||||
# <occi xml file>
|
||||
#
|
||||
# list
|
||||
# lists available virtual networks
|
||||
#
|
||||
# show <network id>
|
||||
# retrieves the OCCI XML representation of the virtual network
|
||||
# identified by <network id>
|
||||
#
|
||||
# delete <network id>
|
||||
# deletes the virtual network idenfitied by <network id>
|
||||
#
|
||||
#
|
||||
# OPTIONS
|
||||
#
|
||||
# -h, --help:
|
||||
# show help
|
||||
#
|
||||
# --username <id>, -U <id>:
|
||||
# The username of the user
|
||||
#
|
||||
# --password <key>, -P <key>:
|
||||
# The password of the user
|
||||
#
|
||||
# --url <url>, -U <url>:
|
||||
# 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
|
||||
|
||||
|
||||
|
||||
|
163
src/cloud/occi/commands/occi-storage
Executable file
163
src/cloud/occi/commands/occi-storage
Executable file
@ -0,0 +1,163 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# == Synopsis
|
||||
# occi-storage
|
||||
#
|
||||
# Manages OCCI storage resource
|
||||
#
|
||||
# == Usage
|
||||
#
|
||||
# occi-storage <COMMAND> [OPTIONS] [PARAMETERS]
|
||||
#
|
||||
# COMMANDS
|
||||
#
|
||||
# create <occi xml file>
|
||||
# creates a new storage resource described by the provided
|
||||
# <occi xml file>
|
||||
#
|
||||
# list
|
||||
# lists available storage resources
|
||||
#
|
||||
# show <storage id>
|
||||
# retrieves the OCCI XML representation of the storage resource
|
||||
# identified by <storage id>
|
||||
#
|
||||
# update <occi xml file>
|
||||
# updates the representation of the storage resource represented by the
|
||||
# provided <occi xml file>
|
||||
#
|
||||
# delete <storage id>
|
||||
# deletes the storage resource idenfitied by <storage id>
|
||||
#
|
||||
#
|
||||
# OPTIONS
|
||||
# -h, --help:
|
||||
# show help
|
||||
#
|
||||
# --username <id>, -U <id>:
|
||||
# The username of the user
|
||||
#
|
||||
# --password <key>, -P <key>:
|
||||
# The password of the user
|
||||
#
|
||||
# --url <url>, -U <url>:
|
||||
# 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
|
||||
|
||||
|
||||
|
||||
|
73
src/cloud/occi/lib/OCCIConfiguration.rb
Normal file
73
src/cloud/occi/lib/OCCIConfiguration.rb
Normal file
@ -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]<<value
|
||||
else
|
||||
conf[key]=value
|
||||
end
|
||||
end
|
||||
|
||||
def parse_conf(file)
|
||||
conf_file=File.read(file)
|
||||
|
||||
conf=Hash.new
|
||||
|
||||
conf_file.scan(SINGLE_VARIABLE_REG) {|m|
|
||||
key=m[0].strip.upcase
|
||||
value=m[1].strip
|
||||
|
||||
# hack to skip multiline VM_TYPE values
|
||||
next if %w{NAME TEMPLATE}.include? key.upcase
|
||||
|
||||
add_value(conf, key, value)
|
||||
}
|
||||
|
||||
conf_file.scan(ARRAY_VARIABLE_REG) {|m|
|
||||
master_key=m[0].strip.upcase
|
||||
|
||||
pieces=m[1].split(',')
|
||||
|
||||
vars=Hash.new
|
||||
pieces.each {|p|
|
||||
key, value=p.split('=')
|
||||
vars[key.strip.upcase]=value.strip
|
||||
}
|
||||
|
||||
add_value(conf, master_key, vars)
|
||||
}
|
||||
|
||||
conf
|
||||
end
|
||||
|
||||
def conf
|
||||
@conf
|
||||
end
|
||||
|
||||
def [](key)
|
||||
@conf[key.to_s.upcase]
|
||||
end
|
||||
end
|
||||
|
||||
if $0 == __FILE__
|
||||
|
||||
require 'pp'
|
||||
|
||||
conf=OCCIConfiguration.new('occi-server.conf')
|
||||
pp conf.conf
|
||||
|
||||
end
|
303
src/cloud/occi/lib/ONEOCCIClient.rb
Normal file
303
src/cloud/occi/lib/ONEOCCIClient.rb
Normal file
@ -0,0 +1,303 @@
|
||||
#!/usr/bin/ruby
|
||||
|
||||
require 'rubygems'
|
||||
require 'curb'
|
||||
require 'uri'
|
||||
require 'OpenNebula'
|
||||
require 'Crack'
|
||||
|
||||
module ONEOCCIClient
|
||||
#####################################################################
|
||||
#
|
||||
#
|
||||
#####################################################################
|
||||
class Client
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
#
|
||||
#######################################################################
|
||||
def initialize(endpoint_str=nil, user=nil, pass=nil, debug_flag=false)
|
||||
@debug = debug_flag
|
||||
|
||||
# Server location
|
||||
if endpoint_str
|
||||
@endpoint = endpoint_str
|
||||
elsif ENV["OCCI_URL"]
|
||||
@endpoint = ENV["OCCI_URL"]
|
||||
else
|
||||
@endpoint = "http://localhost:4567"
|
||||
end
|
||||
|
||||
# Autentication
|
||||
if user && pass
|
||||
@occiauth = user + ":" + Digest::SHA1.hexdigest(pass)
|
||||
elsif ENV["ONE_AUTH"]
|
||||
one_auth= ENV["ONE_AUTH"]
|
||||
one_auth=~/(\w+):(\w+)/
|
||||
user = $1
|
||||
pass = $2
|
||||
@occiauth = user + ":" + Digest::SHA1.hexdigest(pass)
|
||||
elsif
|
||||
raise "No authorization data present"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#######################################################################
|
||||
# Pool Resource Request Methods
|
||||
#######################################################################
|
||||
|
||||
#######################################################################
|
||||
# Post a new VM to the VM Pool
|
||||
# :instance_type
|
||||
# :xmlfile
|
||||
#######################################################################
|
||||
def post_vms(instance_type,xmlfile)
|
||||
curl=Curl::Easy.new(@endpoint+"/compute")
|
||||
curl.userpwd=@occiauth
|
||||
curl.verbose=true if @debug
|
||||
|
||||
xml=File.read(xmlfile)
|
||||
|
||||
begin
|
||||
curl.http_post(
|
||||
Curl::PostField.content('occixml', xml),
|
||||
Curl::PostField.content('InstanceType', instance_type)
|
||||
)
|
||||
rescue Exception => 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
69
src/cloud/occi/lib/VirtualMachineOCCI.rb
Normal file
69
src/cloud/occi/lib/VirtualMachineOCCI.rb
Normal file
@ -0,0 +1,69 @@
|
||||
require 'OpenNebula'
|
||||
|
||||
include OpenNebula
|
||||
|
||||
class VirtualMachineOCCI < VirtualMachine
|
||||
# Creates the VMI representation of a Virtual Machine
|
||||
def to_occi
|
||||
occi_xml = "<COMPUTE>"
|
||||
occi_xml += "<ID>" + id.to_s + "</ID>"
|
||||
occi_xml += "<NAME>" + self['NAME'] + "</NAME>"
|
||||
occi_xml += "<TYPE>" + self['OCCI_SIZE_TYPE'] + "</TYPE>" if self['OCCI_SIZE_TYPE']
|
||||
occi_xml += "<STATE>" + state_str + "</STATE>"
|
||||
|
||||
# Now let's parse the template
|
||||
template=self.to_hash("TEMPLATE")
|
||||
|
||||
template['DISK']=[template['DISK']].flatten
|
||||
|
||||
if template['DISK']
|
||||
|
||||
occi_xml += "<STORAGE>"
|
||||
|
||||
template['DISK'].each{|disk|
|
||||
case disk['TYPE']
|
||||
when "disk" then
|
||||
occi_xml += "<DISK image=\"#{disk['IMAGE_ID']}\" dev=\"#{disk['DEV']}\"/>"
|
||||
when "swap" then
|
||||
occi_xml += "<SWAP size=\"#{disk['SIZE']}\" dev=\"#{disk['DEV']}\"/>"
|
||||
when "fs" then
|
||||
occi_xml += "<FS size=\"#{disk['SIZE']}\" format=\"#{disk['FORMAT']}\" dev=\"#{disk['DEV']}\"/>"
|
||||
end
|
||||
}
|
||||
|
||||
occi_xml += "</STORAGE>"
|
||||
end
|
||||
|
||||
template['NIC']=[template['NIC']].flatten
|
||||
|
||||
if template['NIC']
|
||||
occi_xml += "<NETWORK>"
|
||||
|
||||
template['NIC'].each{|nic|
|
||||
|
||||
occi_xml += "<NIC network=\"#{nic['VNID']}\""
|
||||
if nic['IP']
|
||||
occi_xml += " ip=\"#{nic['IP']}\""
|
||||
end
|
||||
occi_xml += "/>"
|
||||
}
|
||||
|
||||
occi_xml += "</NETWORK>"
|
||||
end
|
||||
|
||||
occi_xml += "</COMPUTE>"
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
19
src/cloud/occi/lib/VirtualMachinePoolOCCI.rb
Normal file
19
src/cloud/occi/lib/VirtualMachinePoolOCCI.rb
Normal file
@ -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 = "<COMPUTES>"
|
||||
|
||||
pool_hash['VM_POOL']['VM'].each{|vm|
|
||||
occi_xml+='<COMPUTE id="' + vm['ID'].strip + '"' +
|
||||
' href="' + base_url + '/compute/' + vm['ID'].strip + '"/>'
|
||||
}
|
||||
occi_xml += "</COMPUTES>"
|
||||
end
|
||||
end
|
||||
|
28
src/cloud/occi/lib/VirtualNetworkOCCI.rb
Normal file
28
src/cloud/occi/lib/VirtualNetworkOCCI.rb
Normal file
@ -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 = "<NIC>"
|
||||
|
||||
occi_xml += "<ID>" + vn_hash['VNET']['ID'].strip + "</ID>"
|
||||
occi_xml += "<NAME>" + vn_hash['VNET']['NAME'].strip + "</NAME>"
|
||||
occi_xml += "<ADDRESS>" + vn_hash['VNET']['TEMPLATE']['NETWORK_ADDRESS'].strip + "</ADDRESS>"
|
||||
occi_xml += "<SIZE>" + vn_hash['VNET']['TEMPLATE']['NETWORK_SIZE'].strip + "</SIZE>"
|
||||
|
||||
occi_xml += "</NIC>"
|
||||
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
|
||||
|
19
src/cloud/occi/lib/VirtualNetworkPoolOCCI.rb
Normal file
19
src/cloud/occi/lib/VirtualNetworkPoolOCCI.rb
Normal file
@ -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>"
|
||||
|
||||
network_pool_hash['VNET_POOL']['VNET'].each{|network|
|
||||
occi_xml+='<NIC id="' + network['ID'].strip + '"' +
|
||||
' href="' + base_url + '/network/' + network['ID'].strip + '"/>'
|
||||
}
|
||||
|
||||
occi_xml += "</NETWORK>"
|
||||
end
|
||||
end
|
9
src/cloud/occi/occi-server
Executable file
9
src/cloud/occi/occi-server
Executable file
@ -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 &
|
||||
|
||||
|
26
src/cloud/occi/occi-server.conf
Normal file
26
src/cloud/occi/occi-server.conf
Normal file
@ -0,0 +1,26 @@
|
||||
# OpenNebula administrator user
|
||||
USER=oneadmin
|
||||
PASSWORD=<PUT HERE ONEADMIN PASS>
|
||||
|
||||
# OpenNebula server contact information
|
||||
ONE_XMLRPC=http://localhost:2633/RPC2
|
||||
|
||||
# Host and port where the occi server will run
|
||||
SERVER=<FQDN OF OCCI SERVER>
|
||||
PORT=4567
|
||||
|
||||
# Configuration for the image repository
|
||||
DATABASE=<ONELOCATION>/var/occi.db
|
||||
IMAGE_DIR=<PATH TO EXISTING IMAGE DIRECTORY>
|
||||
|
||||
# Configuration for OpenNebula's Virtual Networks
|
||||
BRIDGE=<NAME OF DEFAULT 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]
|
||||
|
45
src/cloud/occi/templates/large.erb
Normal file
45
src/cloud/occi/templates/large.erb
Normal file
@ -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 ]%>
|
||||
|
45
src/cloud/occi/templates/medium.erb
Normal file
45
src/cloud/occi/templates/medium.erb
Normal file
@ -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 ]%>
|
||||
|
45
src/cloud/occi/templates/small.erb
Normal file
45
src/cloud/occi/templates/small.erb
Normal file
@ -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 ]%>
|
||||
|
Loading…
x
Reference in New Issue
Block a user