1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-21 14:50:08 +03:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Hector Sanjuan 2012-02-28 13:10:12 +01:00
commit 4c4a34fcfd
53 changed files with 980 additions and 278 deletions

View File

@ -228,12 +228,12 @@ public:
static string version()
{
return "OpenNebula 3.2.0";
return "OpenNebula 3.3.0";
};
static string db_version()
{
return "3.2.0";
return "3.3.0";
}
void start();

View File

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands"
.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands"
.SH NAME
OpenNebula \- OpenNebula econe-describe-images
.SH SYNOPSIS

View File

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands"
.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands"
.SH NAME
OpenNebula \- OpenNebula econe-describe-instances
.SH SYNOPSIS

View File

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands"
.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands"
.SH NAME
OpenNebula \- OpenNebula econe-register
.SH SYNOPSIS

View File

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands"
.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands"
.SH NAME
OpenNebula \- OpenNebula econe-run-instances
.SH SYNOPSIS

View File

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands"
.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands"
.SH NAME
OpenNebula \- OpenNebula econe-terminate-instances
.SH SYNOPSIS

View File

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
.TH OPENNEBULA "1" "September 2011" "OpenNebula 3.2.0" "User Commands"
.TH OPENNEBULA "1" "September 2011" "OpenNebula 3.3.0" "User Commands"
.SH NAME
OpenNebula \- OpenNebula econe-upload
.SH SYNOPSIS

View File

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands"
.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands"
.SH NAME
OpenNebula \- OpenNebula occi-compute
.SH SYNOPSIS

View File

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands"
.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands"
.SH NAME
OpenNebula \- OpenNebula occi-network
.SH SYNOPSIS

View File

@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
.TH OPENNEBULA "1" "January 2012" "OpenNebula 3.2.0" "User Commands"
.TH OPENNEBULA "1" "February 2012" "OpenNebula 3.3.0" "User Commands"
.SH NAME
OpenNebula \- OpenNebula occi-storage
.SH SYNOPSIS

View File

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "ONEACL" "1" "January 2012" "" "oneacl(1) -- manages OpenNebula ACLs"
.TH "ONEACL" "1" "February 2012" "" "oneacl(1) -- manages OpenNebula ACLs"
.
.SH "NAME"
\fBoneacl\fR
@ -128,7 +128,7 @@ Comma\-separated list of OpenNebula ACL names or ids
.IP "" 0
.
.SH "LICENSE"
OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
.
.P
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

View File

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "ONEDB" "1" "January 2012" "" "onedb(1) -- OpenNebula database migration tool"
.TH "ONEDB" "1" "February 2012" "" "onedb(1) -- OpenNebula database migration tool"
.
.SH "NAME"
\fBonedb\fR

View File

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "ONEGROUP" "1" "January 2012" "" "onegroup(1) -- manages OpenNebula groups"
.TH "ONEGROUP" "1" "February 2012" "" "onegroup(1) -- manages OpenNebula groups"
.
.SH "NAME"
\fBonegroup\fR
@ -160,7 +160,7 @@ Comma\-separated list of OpenNebula GROUP names or ids
.IP "" 0
.
.SH "LICENSE"
OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
.
.P
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

View File

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "ONEHOST" "1" "January 2012" "" "onehost(1) -- manages OpenNebula hosts"
.TH "ONEHOST" "1" "February 2012" "" "onehost(1) -- manages OpenNebula hosts"
.
.SH "NAME"
\fBonehost\fR
@ -234,7 +234,7 @@ Comma\-separated list of OpenNebula HOST names or ids
.IP "" 0
.
.SH "LICENSE"
OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
.
.P
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

View File

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "ONEIMAGE" "1" "January 2012" "" "oneimage(1) -- manages OpenNebula images"
.TH "ONEIMAGE" "1" "February 2012" "" "oneimage(1) -- manages OpenNebula images"
.
.SH "NAME"
\fBoneimage\fR
@ -381,7 +381,7 @@ user IMAGE of the user identified by the username
.IP "" 0
.
.SH "LICENSE"
OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
.
.P
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

View File

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "ONETEMPLATE" "1" "January 2012" "" "onetemplate(1) -- manages OpenNebula templates"
.TH "ONETEMPLATE" "1" "February 2012" "" "onetemplate(1) -- manages OpenNebula templates"
.
.SH "NAME"
\fBonetemplate\fR
@ -13,7 +13,10 @@
.
.nf
\-n, \-\-name vm_name Name of the new Virtual Machine
\-n, \-\-name vm_name Name of the new Virtual Machine\. When instantiating
multiple VMs you can use the"%i" wildcard to produce
different names such as vm\-0, vm\-1\.\.\.
\-m, \-\-multiple x Instance multiple VMs
\-l, \-\-list x,y,z Selects columns to display with list command
\-d, \-\-delay x Sets the delay in seconds for top command
@ -327,7 +330,7 @@ user VMTEMPLATE of the user identified by the username
.IP "" 0
.
.SH "LICENSE"
OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
.
.P
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

View File

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "ONEUSER" "1" "January 2012" "" "oneuser(1) -- manages OpenNebula users"
.TH "ONEUSER" "1" "February 2012" "" "oneuser(1) -- manages OpenNebula users"
.
.SH "NAME"
\fBoneuser\fR
@ -305,7 +305,7 @@ User password
.IP "" 0
.
.SH "LICENSE"
OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
.
.P
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

View File

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "ONEVDC" "1" "January 2012" "" "onevdc(1) -- manages OpenNebula Virtual DataCenters"
.TH "ONEVDC" "1" "February 2012" "" "onevdc(1) -- manages OpenNebula Virtual DataCenters"
.
.SH "NAME"
\fBonevdc\fR
@ -171,7 +171,7 @@ VDC ID
.IP "" 0
.
.SH "LICENSE"
OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
.
.P
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

View File

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "ONEVM" "1" "January 2012" "" "onevm(1) -- manages OpenNebula virtual machines"
.TH "ONEVM" "1" "February 2012" "" "onevm(1) -- manages OpenNebula virtual machines"
.
.SH "NAME"
\fBonevm\fR
@ -526,7 +526,7 @@ user VM of the user identified by the username
.IP "" 0
.
.SH "LICENSE"
OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
.
.P
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

View File

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "ONEVNET" "1" "January 2012" "" "onevnet(1) -- manages OpenNebula networks"
.TH "ONEVNET" "1" "February 2012" "" "onevnet(1) -- manages OpenNebula networks"
.
.SH "NAME"
\fBonevnet\fR
@ -351,7 +351,7 @@ user VNET of the user identified by the username
.IP "" 0
.
.SH "LICENSE"
OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
.
.P
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

View File

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "ONEZONE" "1" "January 2012" "" "onezone(1) -- manages OpenNebula zones"
.TH "ONEZONE" "1" "February 2012" "" "onezone(1) -- manages OpenNebula zones"
.
.SH "NAME"
\fBonezone\fR
@ -43,7 +43,7 @@ show \fIzoneid\fR [\fIresource\fR]
.nf
Show information of a particular Zone
Available resources: host, vm, image, vn, template, user
Available resources: host, vm, image, vnet, vmtemplate, user
Examples:
onezone show 4
onezone show 4 host
@ -144,7 +144,7 @@ Zone ID
.IP "" 0
.
.SH "LICENSE"
OpenNebula 3\.2\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
OpenNebula 3\.3\.0 Copyright 2002\-2012, OpenNebula Project Leads (OpenNebula\.org)
.
.P
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

View File

@ -21,7 +21,7 @@ include OpenNebula
module OpenNebulaHelper
ONE_VERSION=<<-EOT
OpenNebula 3.2.0
OpenNebula 3.3.0
Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org)
Licensed under the Apache License, Version 2.0 (the "License"); you may

View File

@ -181,7 +181,7 @@ module CloudCLI
def version_text
version=<<EOT
OpenNebula 3.2.0
OpenNebula 3.3.0
Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org)
Licensed under the Apache License, Version 2.0 (the "License"); you may

View File

@ -40,7 +40,7 @@ require 'pp'
# OpenNebula Engine
##############################################################################
COLLECTIONS = ["compute", "instance_type", "network", "storage"]
COLLECTIONS = ["compute", "instance_type", "network", "storage", "user"]
# FLAG that will filter the elements retrieved from the Pools
POOL_FILTER = Pool::INFO_ALL
@ -81,10 +81,10 @@ class OCCIServer < CloudServer
############################################################################
def get_collections(request)
xml_resp = "<COLLECTIONS>\n"
xml_resp = "<COLLECTIONS>"
COLLECTIONS.each { |c|
xml_resp << "\t<#{c.upcase}_COLLECTION href=\"#{@base_url}/#{c}\">\n"
COLLECTIONS.sort.each { |c|
xml_resp << "<#{c.upcase}_COLLECTION href=\"#{@base_url}/#{c}\"/>"
}
xml_resp << "</COLLECTIONS>"
@ -92,18 +92,38 @@ class OCCIServer < CloudServer
return xml_resp, 200
end
def get_instance_types(request)
xml_resp = "<INSTANCE_TYPE_COLLECTION>\n"
@config[:instance_types].each { |k, v|
xml_resp << "\t<INSTANCE_TYPE href=\"#{@base_url}/instance_type/#{k.to_s}\">\n"
xml_resp << "\t\t<NAME>#{k.to_s}</NAME>\n"
v.each { |elem, value|
next if elem==:template
str = elem.to_s.upcase
xml_resp << "\t\t<#{str}>#{value}</#{str}>\n"
}
xml_resp << "\t</INSTANCE_TYPE>\n"
INSTANCE_TYPE = %q{
<INSTANCE_TYPE href="<%= @base_url %>/instance_type/<%=name%>" name="<%= name %>">
<ID><%= name.to_s %></ID>
<NAME><%= name.to_s %></NAME>
<% opts.sort{|k1,k2| k1[0].to_s<=>k2[0].to_s}.each { |elem, value|
next if elem==:template
str = elem.to_s.upcase %>
<<%= str %>><%= value %></<%= str %>>
<% } %>
</INSTANCE_TYPE>
}
def get_instance_types(request)
xml_resp = "<INSTANCE_TYPE_COLLECTION>"
@config[:instance_types].sort { |k1,k2|
k1[0].to_s<=>k2[0].to_s
}.each { |name, opts|
if request.params['verbose']
begin
occi_it = ERB.new(INSTANCE_TYPE)
occi_it = occi_it.result(binding)
rescue Exception => e
error = OpenNebula::Error.new(e.message)
return error, CloudServer::HTTP_ERROR_CODE[error.errno]
end
xml_resp << occi_it.gsub(/\n\s*/,'')
else
xml_resp << "<INSTANCE_TYPE href=\"#{@base_url}/instance_type/#{name.to_s}\" name=\"#{name}\"/>"
end
}
xml_resp << "</INSTANCE_TYPE_COLLECTION>"
@ -111,6 +131,24 @@ class OCCIServer < CloudServer
return xml_resp, 200
end
def get_instance_type(request, params)
name = params[:id].to_sym
unless @config[:instance_types].keys.include?(name)
error = OpenNebula::Error.new("INSTANCE_TYPE #{name} not found")
return error, 404
else
opts = @config[:instance_types][name]
begin
occi_it = ERB.new(INSTANCE_TYPE)
occi_it = occi_it.result(binding)
rescue Exception => e
error = OpenNebula::Error.new(e.message)
return error, CloudServer::HTTP_ERROR_CODE[error.errno]
end
return occi_it.gsub(/\n\s*/,''), 200
end
end
# Gets the pool representation of COMPUTES
# request:: _Hash_ hash containing the data of the request
@ -127,7 +165,7 @@ class OCCIServer < CloudServer
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
end
return to_occi_xml(vmpool, :status=>200, :verbose=>request.params['verbose'])
return to_occi_xml(vmpool, :code=>200, :verbose=>request.params['verbose'])
end
@ -147,7 +185,7 @@ class OCCIServer < CloudServer
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
end
return to_occi_xml(network_pool, :status=>200, :verbose=>request.params['verbose'])
return to_occi_xml(network_pool, :code=>200, :verbose=>request.params['verbose'])
end
# Gets the pool representation of STORAGES
@ -166,7 +204,7 @@ class OCCIServer < CloudServer
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
end
return to_occi_xml(image_pool, :status=>200, :verbose=>request.params['verbose'])
return to_occi_xml(image_pool, :code=>200, :verbose=>request.params['verbose'])
end
# Gets the pool representation of USERs
@ -183,7 +221,7 @@ class OCCIServer < CloudServer
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
end
return to_occi_xml(user_pool, :status=>200, :verbose=>request.params['verbose'])
return to_occi_xml(user_pool, :code=>200, :verbose=>request.params['verbose'])
end
############################################################################
@ -219,7 +257,7 @@ class OCCIServer < CloudServer
# --- Prepare XML Response ---
vm.info
return to_occi_xml(vm, :status=>201)
return to_occi_xml(vm, :code=>201)
end
# Get the representation of a COMPUTE resource
@ -238,7 +276,7 @@ class OCCIServer < CloudServer
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
end
return to_occi_xml(vm, :status=>200)
return to_occi_xml(vm, :code=>200)
end
# Deletes a COMPUTE resource
@ -281,7 +319,7 @@ class OCCIServer < CloudServer
return result, code
else
vm.info
return to_occi_xml(vm, :status=>code)
return to_occi_xml(vm, :code=>code)
end
end
@ -311,7 +349,7 @@ class OCCIServer < CloudServer
# --- Prepare XML Response ---
network.info
return to_occi_xml(network, :status=>201)
return to_occi_xml(network, :code=>201)
end
# Retrieves a NETWORK resource
@ -329,7 +367,7 @@ class OCCIServer < CloudServer
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
end
return to_occi_xml(network, :status=>200)
return to_occi_xml(network, :code=>200)
end
# Deletes a NETWORK resource
@ -375,7 +413,7 @@ class OCCIServer < CloudServer
# --- Prepare XML Response ---
vnet.info
return to_occi_xml(vnet, :status=>202)
return to_occi_xml(vnet, :code=>202)
end
############################################################################
@ -421,7 +459,7 @@ class OCCIServer < CloudServer
end
# --- Prepare XML Response ---
return to_occi_xml(image, :status=>201)
return to_occi_xml(image, :code=>201)
end
# Get a STORAGE resource
@ -440,7 +478,7 @@ class OCCIServer < CloudServer
end
# --- Prepare XML Response ---
return to_occi_xml(image, :status=>200)
return to_occi_xml(image, :code=>200)
end
# Deletes a STORAGE resource (Not yet implemented)
@ -494,7 +532,7 @@ class OCCIServer < CloudServer
# --- Prepare XML Response ---
image.info
return to_occi_xml(image, :status=>202)
return to_occi_xml(image, :code=>202)
end
# Get the representation of a USER
@ -513,7 +551,7 @@ class OCCIServer < CloudServer
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
end
return to_occi_xml(user, :status=>200)
return to_occi_xml(user, :code=>200)
end
############################################################################

View File

@ -305,6 +305,11 @@ get '/user/:id' do
treat_response(result,rc)
end
get '/instance_type/:id' do
result,rc = @occi_server.get_instance_type(request, params)
treat_response(result,rc)
end
##############################################
## OCCI UI (Self-Service)
##############################################

View File

@ -75,7 +75,7 @@
</div>
<div id="footer" class="ui-layout-south">
Copyright 2002-2012 &copy; OpenNebula Project Leads (<a href="http://opennebula.org" target="_blank">OpenNebula.org</a>). All Rights Reserved. OpenNebula 3.2.0
Copyright 2002-2012 &copy; OpenNebula Project Leads (<a href="http://opennebula.org" target="_blank">OpenNebula.org</a>). All Rights Reserved. OpenNebula 3.3.0
</div>

View File

@ -0,0 +1 @@
<COMPUTE_COLLECTION></COMPUTE_COLLECTION>

View File

@ -0,0 +1,20 @@
<COMPUTE href="http://localhost:4567/compute/0">
<ID>0</ID>
<USER href="http://localhost:4567/user/2" name="my_first_occi_user"/>
<GROUP>oneadmin</GROUP>
<CPU>1</CPU>
<MEMORY>1024</MEMORY>
<NAME>Compute</NAME>
<INSTANCE_TYPE href="http://localhost:4567/instance_type/small">small</INSTANCE_TYPE>
<STATE>PENDING</STATE>
<DISK id="0">
<STORAGE href="http://localhost:4567/storage/0" name="Storage"/>
<TYPE>DISK</TYPE>
<TARGET>hde</TARGET>
</DISK>
<NIC>
<NETWORK href="http://localhost:4567/network/0" name="Network"/>
<IP>192.168.1.1</IP>
<MAC>02:00:c0:a8:01:01</MAC>
</NIC>
</COMPUTE>

View File

@ -0,0 +1,20 @@
<COMPUTE href="http://localhost:4567/compute/0">
<ID>0</ID>
<USER href="http://localhost:4567/user/2" name="my_first_occi_user"/>
<GROUP>oneadmin</GROUP>
<CPU>1</CPU>
<MEMORY>1024</MEMORY>
<NAME>Compute</NAME>
<INSTANCE_TYPE href="http://localhost:4567/instance_type/small">small</INSTANCE_TYPE>
<STATE>DONE</STATE>
<DISK id="0">
<STORAGE href="http://localhost:4567/storage/0" name="Storage"/>
<TYPE>DISK</TYPE>
<TARGET>hde</TARGET>
</DISK>
<NIC>
<NETWORK href="http://localhost:4567/network/0" name="Network"/>
<IP>192.168.1.1</IP>
<MAC>02:00:c0:a8:01:01</MAC>
</NIC>
</COMPUTE>

View File

@ -0,0 +1,20 @@
<COMPUTE href="http://localhost:4567/compute/1">
<ID>1</ID>
<USER href="http://localhost:4567/user/3" name="my_second_occi_user"/>
<GROUP>users</GROUP>
<CPU>1</CPU>
<MEMORY>1024</MEMORY>
<NAME>Compute2</NAME>
<INSTANCE_TYPE href="http://localhost:4567/instance_type/small">small</INSTANCE_TYPE>
<STATE>PENDING</STATE>
<DISK id="0">
<STORAGE href="http://localhost:4567/storage/1" name="Storage2"/>
<TYPE>DISK</TYPE>
<TARGET>hde</TARGET>
</DISK>
<NIC>
<NETWORK href="http://localhost:4567/network/1" name="Network2"/>
<IP>192.168.2.1</IP>
<MAC>02:00:c0:a8:02:01</MAC>
</NIC>
</COMPUTE>

View File

@ -0,0 +1,20 @@
<COMPUTE href="http://localhost:4567/compute/1">
<ID>1</ID>
<USER href="http://localhost:4567/user/3" name="my_second_occi_user"/>
<GROUP>users</GROUP>
<CPU>1</CPU>
<MEMORY>1024</MEMORY>
<NAME>Compute2</NAME>
<INSTANCE_TYPE href="http://localhost:4567/instance_type/small">small</INSTANCE_TYPE>
<STATE>DONE</STATE>
<DISK id="0">
<STORAGE href="http://localhost:4567/storage/1" name="Storage2"/>
<TYPE>DISK</TYPE>
<TARGET>hde</TARGET>
</DISK>
<NIC>
<NETWORK href="http://localhost:4567/network/1" name="Network2"/>
<IP>192.168.2.1</IP>
<MAC>02:00:c0:a8:02:01</MAC>
</NIC>
</COMPUTE>

View File

@ -0,0 +1,20 @@
<INSTANCE_TYPE_COLLECTION>
<INSTANCE_TYPE href="http://localhost:4567/instance_type/large" name="large">
<ID>large</ID>
<NAME>large</NAME>
<CPU>8</CPU>
<MEMORY>8192</MEMORY>
</INSTANCE_TYPE>
<INSTANCE_TYPE href="http://localhost:4567/instance_type/medium" name="medium">
<ID>medium</ID>
<NAME>medium</NAME>
<CPU>4</CPU>
<MEMORY>4096</MEMORY>
</INSTANCE_TYPE>
<INSTANCE_TYPE href="http://localhost:4567/instance_type/small" name="small">
<ID>small</ID>
<NAME>small</NAME>
<CPU>1</CPU>
<MEMORY>1024</MEMORY>
</INSTANCE_TYPE>
</INSTANCE_TYPE_COLLECTION>

View File

@ -0,0 +1,5 @@
<INSTANCE_TYPE_COLLECTION>
<INSTANCE_TYPE href="http://localhost:4567/instance_type/large" name="large"/>
<INSTANCE_TYPE href="http://localhost:4567/instance_type/medium" name="medium"/>
<INSTANCE_TYPE href="http://localhost:4567/instance_type/small" name="small"/>
</INSTANCE_TYPE_COLLECTION>

View File

@ -0,0 +1 @@
<NETWORK_COLLECTION></NETWORK_COLLECTION>

View File

@ -0,0 +1,11 @@
<NETWORK href="http://localhost:4567/network/0">
<ID>0</ID>
<NAME>Network</NAME>
<USER href="http://localhost:4567/user/2" name="my_first_occi_user"/>
<GROUP>oneadmin</GROUP>
<DESCRIPTION>Network of the user my_first_occi_user</DESCRIPTION>
<ADDRESS>192.168.1.1</ADDRESS>
<SIZE>125</SIZE>
<USED_LEASES>0</USED_LEASES>
<PUBLIC>NO</PUBLIC>
</NETWORK>

View File

@ -0,0 +1,11 @@
<NETWORK href="http://localhost:4567/network/1">
<ID>1</ID>
<NAME>Network2</NAME>
<USER href="http://localhost:4567/user/3" name="my_second_occi_user"/>
<GROUP>users</GROUP>
<DESCRIPTION>Network of the user my_second_occi_user</DESCRIPTION>
<ADDRESS>192.168.2.1</ADDRESS>
<SIZE>125</SIZE>
<USED_LEASES>0</USED_LEASES>
<PUBLIC>NO</PUBLIC>
</NETWORK>

7
src/cloud/occi/test/fixtures/root.xml vendored Normal file
View File

@ -0,0 +1,7 @@
<COLLECTIONS>
<COMPUTE_COLLECTION href="http://localhost:4567/compute"/>
<INSTANCE_TYPE_COLLECTION href="http://localhost:4567/instance_type"/>
<NETWORK_COLLECTION href="http://localhost:4567/network"/>
<STORAGE_COLLECTION href="http://localhost:4567/storage"/>
<USER_COLLECTION href="http://localhost:4567/user"/>
</COLLECTIONS>

View File

@ -0,0 +1 @@
<STORAGE_COLLECTION></STORAGE_COLLECTION>

View File

@ -0,0 +1,13 @@
<STORAGE href="http://localhost:4567/storage/0">
<ID>0</ID>
<NAME>Storage</NAME>
<USER href="http://localhost:4567/user/2" name="my_first_occi_user"/>
<GROUP>oneadmin</GROUP>
<STATE>READY</STATE>
<TYPE>DATABLOCK</TYPE>
<DESCRIPTION>Storage of the user my_first_occi_user</DESCRIPTION>
<SIZE>100</SIZE>
<FSTYPE>ext3</FSTYPE>
<PUBLIC>NO</PUBLIC>
<PERSISTENT>NO</PERSISTENT>
</STORAGE>

View File

@ -0,0 +1,13 @@
<STORAGE href="http://localhost:4567/storage/1">
<ID>1</ID>
<NAME>Storage2</NAME>
<USER href="http://localhost:4567/user/3" name="my_second_occi_user"/>
<GROUP>users</GROUP>
<STATE>READY</STATE>
<TYPE>DATABLOCK</TYPE>
<DESCRIPTION>Storage of the user my_second_occi_user</DESCRIPTION>
<SIZE>100</SIZE>
<FSTYPE>ext3</FSTYPE>
<PUBLIC>NO</PUBLIC>
<PERSISTENT>NO</PERSISTENT>
</STORAGE>

View File

@ -0,0 +1,283 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.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. #
#--------------------------------------------------------------------------- #
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
# The following methods are helpers defined in spec_helper
# - compare_xml
# - get_fixture
# - network_template
# - storage_template
# - compute_template
describe 'OCCI tests' do
before(:all) do
@user_oneadmin = "my_first_occi_user"
`oneuser create #{@user_oneadmin} my_pass`.scan(/^ID: (\d+)/) { |uid|
`oneuser show #{uid.first}`.scan(/PASSWORD\s*:\s*(\w*)/) { |password|
@user_pass = password.first.strip
}
`oneuser chgrp #{uid.first} 0`
}
@user_users = "my_second_occi_user"
`oneuser create #{@user_users} my_pass2`.scan(/^ID: (\d+)/) { |uid|
`oneuser show #{uid.first}`.scan(/PASSWORD\s*:\s*(\w*)/) { |password|
@user_pass2 = password.first.strip
}
}
# Define BRIDGE attirbute in network.erb, otherwise the NETWORK creation will
`sed -i.bck "s%^#\\(BRIDGE = \\).*$%\\1 br0%" $ONE_LOCATION/etc/occi_templates/network.erb`
end
describe "with a user of the oneadmin group" do
before(:each) do
basic_authorize(@user_oneadmin, @user_pass)
end
it "should retrieve the list of collections" do
get '/'
compare_xml(last_response.body, get_fixture('/root.xml'))
last_response.status.should == 200
end
it "should retrieve the list of INSTANCE_TYPEs" do
get '/instance_type'
compare_xml(last_response.body, get_fixture('/instance_type/list.xml'))
last_response.status.should == 200
end
it "should retrieve the extended list of INSTANCE_TYPEs" do
get '/instance_type', {'verbose'=>true}
compare_xml(last_response.body, get_fixture('/instance_type/extended.xml'))
last_response.status.should == 200
end
context "for NETWORK" do
it "should retrieve the empty list" do
get '/network'
compare_xml(last_response.body, get_fixture('/network/empty.xml'))
last_response.status.should == 200
end
it "should create a new NETWORK" do
network = {
:name => "Network",
:description => "Network of the user #{@user_oneadmin}",
:address => "192.168.1.0",
:size => "100",
:pubic => "YES"
}
post '/network', network_template(network)
compare_xml(last_response.body, get_fixture('/network/first_net.xml'))
last_response.status.should == 201
end
it "should retrieve the NETWORK with ID 0" do
get '/network/0'
compare_xml(last_response.body, get_fixture('/network/first_net.xml'))
last_response.status.should == 200
end
end
context "for STORAGE" do
it "should retrieve the empty list" do
get '/storage'
compare_xml(last_response.body, get_fixture('/storage/empty.xml'))
last_response.status.should == 200
end
it "should create a new STORAGE, type DATABLOCK. This request waits until the IMAGE is ready in OpenNebula" do
storage = {
:name => "Storage",
:description => "Storage of the user #{@user_oneadmin}",
:type => "DATABLOCK",
:size => "100",
:fstype => "ext3"
}
post '/storage', {'occixml' => storage_template(storage)}
compare_xml(last_response.body, get_fixture('/storage/first_storage.xml'))
last_response.status.should == 201
end
it "should retrieve the STORAGE with ID 0" do
get '/storage/0'
compare_xml(last_response.body, get_fixture('/storage/first_storage.xml'))
last_response.status.should == 200
end
end
context "for COMPUTE" do
it "should retrieve the empty list" do
get '/compute'
compare_xml(last_response.body, get_fixture('/compute/empty.xml'))
last_response.status.should == 200
end
it "should create a new COMPUTE using the previous NETWORK (ID=0) and STORAGE(ID=0)" do
compute = {
:name => "Compute",
:instance_type => "small",
:disk => [ {:storage => '0'} ],
:nic => [ {:network => '0'} ]
}
post '/compute', compute_template(compute)
compare_xml(last_response.body, get_fixture('/compute/first_compute.xml'))
last_response.status.should == 201
end
it "should retrieve the COMPUTE with ID 0" do
get '/compute/0'
compare_xml(last_response.body, get_fixture('/compute/first_compute.xml'))
last_response.status.should == 200
end
it "should terminate (DONE) the COMPUTE with ID 0" do
compute = {
:id => "0",
:state => "DONE"
}
put '/compute/0', compute_action(compute)
compare_xml(last_response.body, get_fixture('/compute/first_compute_done.xml'))
last_response.status.should == 202
end
end
end
describe "with a user of the users group" do
before(:each) do
basic_authorize(@user_users, @user_pass2)
end
it "should retrieve the list of collections" do
get '/'
compare_xml(last_response.body, get_fixture('/root.xml'))
last_response.status.should == 200
end
it "should retrieve the list of INSTANCE_TYPEs" do
get '/instance_type'
compare_xml(last_response.body, get_fixture('/instance_type/list.xml'))
last_response.status.should == 200
end
it "should retrieve the extended list of INSTANCE_TYPEs" do
get '/instance_type', {'verbose'=>true}
compare_xml(last_response.body, get_fixture('/instance_type/extended.xml'))
last_response.status.should == 200
end
context "for NETWORK" do
it "should retrieve the empty list" do
get '/network'
compare_xml(last_response.body, get_fixture('/network/empty.xml'))
last_response.status.should == 200
end
it "should create a new NETWORK" do
network = {
:name => "Network2",
:description => "Network of the user #{@user_users}",
:address => "192.168.2.0",
:size => "100",
:pubic => "YES"
}
post '/network', network_template(network)
compare_xml(last_response.body, get_fixture('/network/second_net.xml'))
last_response.status.should == 201
end
it "should retrieve the NETWORK with ID 1" do
get '/network/1'
compare_xml(last_response.body, get_fixture('/network/second_net.xml'))
last_response.status.should == 200
end
end
context "for STORAGE" do
it "should retrieve the empty list" do
get '/storage'
compare_xml(last_response.body, get_fixture('/storage/empty.xml'))
last_response.status.should == 200
end
it "should create a new STORAGE, type DATABLOCK. This request waits until the IMAGE is ready in OpenNebula" do
storage = {
:name => "Storage2",
:description => "Storage of the user #{@user_users}",
:type => "DATABLOCK",
:size => "100",
:fstype => "ext3"
}
post '/storage', {'occixml' => storage_template(storage)}
compare_xml(last_response.body, get_fixture('/storage/second_storage.xml'))
last_response.status.should == 201
end
it "should retrieve the STORAGE with ID 1" do
get '/storage/1'
compare_xml(last_response.body, get_fixture('/storage/second_storage.xml'))
last_response.status.should == 200
end
end
context "for COMPUTE" do
it "should retrieve the empty list" do
get '/compute'
compare_xml(last_response.body, get_fixture('/compute/empty.xml'))
last_response.status.should == 200
end
it "should create a new COMPUTE using the previous NETWORK (ID=1) and STORAGE(ID=1)" do
compute = {
:name => "Compute2",
:instance_type => "small",
:disk => [ {:storage => '1'} ],
:nic => [ {:network => '1'} ]
}
post '/compute', compute_template(compute)
compare_xml(last_response.body, get_fixture('/compute/second_compute.xml'))
last_response.status.should == 201
end
it "should retrieve the COMPUTE with ID 1" do
get '/compute/1'
compare_xml(last_response.body, get_fixture('/compute/second_compute.xml'))
last_response.status.should == 200
end
it "should terminate (DONE) the COMPUTE with ID 1" do
compute = {
:id => "1",
:state => "DONE"
}
put '/compute/1', compute_action(compute)
compare_xml(last_response.body, get_fixture('/compute/second_compute_done.xml'))
last_response.status.should == 202
end
end
end
end

View File

@ -0,0 +1,4 @@
--colour
--format progress
--loadby mtime
--reverse

View File

@ -24,6 +24,8 @@ require 'rubygems'
require 'rspec'
require 'rack/test'
require 'rexml/document'
# Load the Sinatra app
require 'occi-server'
@ -39,3 +41,153 @@ set :environment, :test
def app
Sinatra::Application
end
def get_fixture(path)
File.read(FIXTURES_PATH + path).strip
end
def compare_xml(a, b)
a = REXML::Document.new(a.to_s)
b = REXML::Document.new(b.to_s)
normalized = Class.new(REXML::Formatters::Pretty) do
def write_text(node, output)
super(node.to_s.strip, output)
end
end
normalized.new(indentation=0,ie_hack=false).write(node=a, a_normalized='')
normalized.new(indentation=0,ie_hack=false).write(node=b, b_normalized='')
a_normalized.should == b_normalized
end
OCCI_NETWORK = %q{
<NETWORK>
<% if hash[:name] %>
<NAME><%= hash[:name] %></NAME>
<% end %>
<% if hash[:description] %>
<DESCRIPTION><%= hash[:description] %></DESCRIPTION>
<% end %>
<% if hash[:address] %>
<ADDRESS><%= hash[:address] %></ADDRESS>
<% end %>
<% if hash[:size] %>
<SIZE><%= hash[:size] %></SIZE>
<% end %>
<% if hash[:public] %>
<PUBLIC><%= hash[:public] %></PUBLIC>
<% end %>
</NETWORK>
}
def network_template(hash)
ERB.new(OCCI_NETWORK).result(binding)
end
OCCI_IMAGE = %q{
<STORAGE>
<% if hash[:name] %>
<NAME><%= hash[:name] %></NAME>
<% end %>
<% if hash[:type] %>
<TYPE><%= hash[:type] %></TYPE>
<% end %>
<% if hash[:description] %>
<DESCRIPTION><%= hash[:description] %></DESCRIPTION>
<% end %>
<% if hash[:size] %>
<SIZE><%= hash[:size] %></SIZE>
<% end %>
<% if hash[:fstype] %>
<FSTYPE><%= hash[:fstype] %></FSTYPE>
<% end %>
<% if hash[:public] %>
<PUBLIC><%= hash[:public] %></PUBLIC>
<% end %>
<% if hash[:persistent] %>
<PERSISTENT><%= hash[:persistent] %></PERSISTENT>
<% end %>
</STORAGE>
}
def storage_template(hash)
ERB.new(OCCI_IMAGE).result(binding)
end
OCCI_VM = %q{
<COMPUTE>
<% if hash[:name] %>
<NAME><%= hash[:name] %></NAME>
<% end %>
<% if hash[:instance_type] %>
<INSTANCE_TYPE href="http://localhost:4567/instance_type/<%= hash[:instance_type] %>"/>
<% end %>
<% if hash[:disk] %>
<% hash[:disk].each { |disk| %>
<DISK>
<% if disk[:storage] %>
<STORAGE href="http://localhost:4567/storage/<%= disk[:storage] %>"/>
<% end %>
</DISK>
<% } %>
<% end %>
<% if hash[:nic] %>
<% hash[:nic].each { |nic| %>
<NIC>
<% if nic[:network] %>
<NETWORK href="http://localhost:4567/network/<%= nic[:network] %>"/>
<% end %>
<% if nic[:ip] %>
<IP><%= nic[:ip] %></IP>
<% end %>
</NIC>
<% } %>
<% end %>
<% if hash[:context] %>
<CONTEXT>
<% hash[:context].each { |key, value| %>
<<%= key.to_s.upcase %>><%= value %></<%= key.to_s.upcase %>>
<% } %>
</CONTEXT>
<% end %>
</COMPUTE>
}
OCCI_VM_ACTION = %q{
<COMPUTE>
<% if hash[:id] %>
<ID><%= hash[:id] %></ID>
<% end %>
<% if hash[:state] %>
<STATE><%= hash[:state] %></STATE>
<% end %>
</COMPUTE>
}
def compute_template(hash)
ERB.new(OCCI_VM).result(binding)
end
def compute_action(hash)
ERB.new(OCCI_VM_ACTION).result(binding)
end

View File

@ -106,7 +106,7 @@ conf = YAML::load(File.read(CONF_FILE))
rc, data = do_action("virsh -c #{@uri} --readonly nodeinfo")
if rc == false
exit info
exit data
end
data.split(/\n/).each{|line|

View File

@ -138,7 +138,7 @@ void OpenNebulaTemplate::set_conf_default()
vvalue.insert(make_pair("BACKEND","sqlite"));
vattribute = new VectorAttribute("DB",vvalue);
conf_default.insert(make_pair(attribute->name(),vattribute));
conf_default.insert(make_pair(vattribute->name(),vattribute));
//VNC_BASE_PORT
value = "5900";

View File

@ -137,56 +137,6 @@ public class VirtualMachine extends PoolElement{
return client.call(ALLOCATE, description);
}
/**
* Allocates a new VM in OpenNebula from a registered Template.
*
* @param client XML-RPC Client.
* @param templateId The source Template's ID
* @param newName Name for the new VM, replaces the Template's one.
* Can be null.
* @return If successful the message contains the associated
* id generated for this VM.
*/
public static OneResponse allocateFromTemplate(Client client,
int templateId, String newName)
{
String template = "TEMPLATE_ID = " + templateId;
if( newName != null )
{
template += "\nNAME = " + newName;
}
return allocate(client, template);
}
/**
* Allocates a new VM in OpenNebula from a registered Template.
*
* @param client XML-RPC Client.
* @param templateId The source Template's ID
* @return If successful the message contains the associated
* id generated for this VM.
*/
public static OneResponse allocateFromTemplate(Client client,
int templateId)
{
return allocateFromTemplate(client, templateId, null);
}
/**
* Allocates a new VM in OpenNebula from a registered Template.
*
* @param client XML-RPC Client.
* @param template The source Template.
* @return If successful the message contains the associated
* id generated for this VM.
*/
public static OneResponse allocateFromTemplate(Client client,
Template template)
{
return allocateFromTemplate(client, template.id());
}
/**
* Retrieves the information of the given VM.
*

View File

@ -247,17 +247,6 @@ public class TemplateTest
assertTrue( res.isError() );
}
@Test
public void allocateFromTemplate()
{
res = template.info();
assertTrue( !res.isError() );
res = VirtualMachine.allocateFromTemplate(client, template);
assertTrue( !res.isError() );
assertTrue( res.getMessage().equals("0") );
}
@Test
public void chown()
{

View File

@ -60,7 +60,7 @@
</div>
</div>
<div id="footer" class="ui-layout-south">
Copyright 2002-2012 &copy; OpenNebula Project Leads (<a href="http://opennebula.org" target="_blank">OpenNebula.org</a>). All Rights Reserved. OpenNebula 3.2.0
Copyright 2002-2012 &copy; OpenNebula Project Leads (<a href="http://opennebula.org" target="_blank">OpenNebula.org</a>). All Rights Reserved. OpenNebula 3.3.0
</div>

View File

@ -231,7 +231,7 @@ class SunstoneServer
############################################################################
#
############################################################################
def get_monitoring(id, resource, monitor_resources, gid)
def get_monitoring(id, resource, monitor_resources, opts={})
watch_client = case resource
when "vm","VM"
OneWatchClient::VmWatchClient.new
@ -242,13 +242,16 @@ class SunstoneServer
return [200, error.to_json]
end
filter = {}
filter[:uid] = opts[:uid] if opts[:gid]!="0"
columns = monitor_resources.split(',')
columns.map!{|e| e.to_sym}
if id
rc = watch_client.resource_monitoring(id.to_i, columns)
rc = watch_client.resource_monitoring(id.to_i, columns, filter)
else
rc = watch_client.total_monitoring(columns)
rc = watch_client.total_monitoring(columns, filter)
end
if rc.nil?

View File

@ -269,7 +269,8 @@ get '/:resource/monitor' do
nil,
params[:resource],
params[:monitor_resources],
session[:user_gid])
:uid => session[:user_id],
:gid => session[:user_gid])
end
get '/:resource/:id/monitor' do
@ -277,7 +278,8 @@ get '/:resource/:id/monitor' do
params[:id],
params[:resource],
params[:monitor_resources],
session[:user_gid])
:uid => session[:user_id],
:gid => session[:user_gid])
end

View File

@ -76,7 +76,7 @@
</div>
</div>
<div id="footer" class="ui-layout-south">
Copyright 2002-2012 &copy; OpenNebula Project Leads (<a href="http://opennebula.org" target="_blank">OpenNebula.org</a>). All Rights Reserved. OpenNebula 3.2.0
Copyright 2002-2012 &copy; OpenNebula Project Leads (<a href="http://opennebula.org" target="_blank">OpenNebula.org</a>). All Rights Reserved. OpenNebula 3.3.0
</div>

View File

@ -38,9 +38,9 @@ end
$: << RUBY_LIB_LOCATION
require 'pp'
require "VirtualMachineDriver"
require "CommandManager"
require 'scripts_common'
require "rexml/document"
# The main class for the EC2 driver
@ -48,27 +48,113 @@ class EC2Driver < VirtualMachineDriver
# EC2 commands constants
EC2 = {
:run => "#{EC2_LOCATION}/bin/ec2-run-instances",
:terminate => "#{EC2_LOCATION}/bin/ec2-terminate-instances",
:describe => "#{EC2_LOCATION}/bin/ec2-describe-instances",
:associate => "#{EC2_LOCATION}/bin/ec2-associate-address",
:reboot => "#{EC2_LOCATION}/bin/ec2-reboot-instances",
:authorize => "#{EC2_LOCATION}/bin/ec2-authorize"
:run => {
:cmd => "#{EC2_LOCATION}/bin/ec2-run-instances",
:args => {
"AKI" => {
:opt => '--kernel'
},
"AMI" => {
:opt => ''
},
"BLOCKDEVICEMAPPING" => {
:opt => '-b'
},
"CLIENTTOKEN" => {
:opt => '--client-token'
},
"INSTANCETYPE" => {
:opt => '-t'
},
"KEYPAIR" => {
:opt => '-k'
},
"LICENSEPOOL" => {
:opt => '--license-pool'
},
"PLACEMENTGROUP" => {
:opt => '--placement-group'
},
"PRIVATEIP" => {
:opt => '--private-ip-address'
},
"RAMDISK" => {
:opt => '--ramdisk'
},
"SUBNETID" => {
:opt => '-s'
},
"TENANCY" => {
:opt => '--tenancy'
},
"USERDATA" => {
:opt => '-d'
},
"USERDATAFILE" => {
:opt => '-f'
},
"SECURITYGROUPS" => {
:opt => '-g',
:proc => lambda {|str| str.split(',').join(' -g ')}
}
}
},
:terminate => {
:cmd => "#{EC2_LOCATION}/bin/ec2-terminate-instances"
},
:describe => {
:cmd => "#{EC2_LOCATION}/bin/ec2-describe-instances"
},
:associate => {
:cmd => "#{EC2_LOCATION}/bin/ec2-associate-address",
:args => {
"SUBNETID" => {
:opt => '-a',
:proc => lambda {|str| ''}
},
"ELASTICIP" => {
:opt => ''
}
}
},
:authorize => {
:cmd => "#{EC2_LOCATION}/bin/ec2-authorize",
:args => {
"AUTHORIZEDPORTS" => {
:opt => '-p',
:proc => lambda {|str| str.split(',').join(' -p ')}
}
}
},
:reboot => {
:cmd => "#{EC2_LOCATION}/bin/ec2-reboot-instances"
},
:stop => {
:cmd => "#{EC2_LOCATION}/bin/ec2-stop-instances"
},
:start => {
:cmd => "#{EC2_LOCATION}/bin/ec2-start-instances"
},
:tags => {
:cmd => "#{EC2_LOCATION}/bin/ec2-create-tags",
:args => {
"TAGS" => {
:opt => '-t',
:proc => lambda {|str| str.split(',').join(' -t ')}
}
}
}
}
# EC2 constructor, loads defaults for the EC2Driver
def initialize(ec2_conf = nil)
if !EC2_JVM_CONCURRENCY
concurrency = 5
else
concurrency = EC2_JVM_CONCURRENCY.to_i
end
super('',
:concurrency => concurrency,
:threaded => true
)
super('', :concurrency => concurrency, :threaded => true)
@defaults = Hash.new
@ -83,18 +169,127 @@ class EC2Driver < VirtualMachineDriver
return if !ec2
@defaults["KEYPAIR"] = ec2_value(ec2,"KEYPAIR")
@defaults["AUTHORIZEDPORTS"] = ec2_value(ec2,"AUTHORIZEDPORTS")
@defaults["INSTANCETYPE"] = ec2_value(ec2,"INSTANCETYPE")
EC2.each {|action, hash|
if hash[:args]
hash[:args].each { |key, value|
@defaults[key] = value_from_xml(ec2, key)
}
end
}
end
end
# DEPLOY action, also sets ports and ip if needed
def deploy(id, drv_message)
ec2_info = get_deployment_info(drv_message)
return unless ec2_info
if !ec2_value(ec2_info, 'AMI')
msg = "Can not find AMI in deployment file"
send_message(ACTION[:deploy], RESULT[:failure], id, msg)
return
end
deploy_exe = exec_and_log_ec2(:run, ec2_info, id)
if deploy_exe.code != 0
msg = deploy_exe.stderr
send_message(ACTION[:deploy], RESULT[:failure], id, msg)
return
end
if !deploy_exe.stdout.match(/^INSTANCE\s*(.+?)\s/)
msg = "Could not find instance id. Check ec2-describe-instances"
send_message(ACTION[:deploy], RESULT[:failure], id, msg)
return
end
deploy_id = $1
if ec2_value(ec2_info, 'AUTHORIZEDPORTS')
exec_and_log_ec2(:authorize, ec2_info, 'default', id)
end
if ec2_value(ec2_info, 'TAGS')
exec_and_log_ec2(:tags, ec2_info, deploy_id, id)
end
if ec2_value(ec2_info, 'ELASTICIP')
exec_and_log_ec2(:associate, ec2_info, "-i #{deploy_id}", id)
end
send_message(ACTION[:deploy], RESULT[:success], id, deploy_id)
end
# Shutdown a EC2 instance
def shutdown(id, drv_message)
ec2_action(drv_message, :terminate, ACTION[:shutdown], id)
end
# Reboot a EC2 instance
def reboot(id, drv_message)
ec2_action(drv_message, :reboot, ACTION[:reboot], id)
end
# Cancel a EC2 instance
def cancel(id, drv_message)
ec2_action(drv_message, :terminate, ACTION[:cancel], id)
end
# Stop a EC2 instance
def save(id, drv_message)
ec2_action(drv_message, :stop, ACTION[:save], id)
end
# Cancel a EC2 instance
def restore(id, drv_message)
ec2_action(drv_message, :start, ACTION[:restor], id)
end
# Get info (IP, and state) for a EC2 instance
def poll(id, drv_message)
msg = decode(drv_message)
deploy_id = msg.elements["DEPLOY_ID"].text
info = "#{POLL_ATTRIBUTE[:usedmemory]}=0 " \
"#{POLL_ATTRIBUTE[:usedcpu]}=0 " \
"#{POLL_ATTRIBUTE[:nettx]}=0 " \
"#{POLL_ATTRIBUTE[:netrx]}=0"
exe = exec_and_log_ec2(:describe, nil, deploy_id, id)
if exe.code != 0
send_message(ACTION[:poll], RESULT[:failure], id, exe.stderr)
return
end
exe.stdout.match(Regexp.new("INSTANCE\\s+#{deploy_id}\\s+(.+)"))
if !$1
info << " #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:deleted]}"
else
monitor_data = $1.split(/\s+/)
case monitor_data[3]
when "pending"
info << " #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:active]}"
when "running"
info<<" #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:active]}"<<
" IP=#{monitor_data[1]}"
when "shutting-down","terminated"
info << " #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:deleted]}"
end
end
send_message(ACTION[:poll], RESULT[:success], id, info)
end
private
def get_deployment_info(drv_message)
msg = decode(drv_message)
host = msg.elements["HOST"].text
local_dfile = msg.elements["LOCAL_DEPLOYMENT_FILE"].text
if !local_dfile
@ -134,150 +329,67 @@ class EC2Driver < VirtualMachineDriver
end
end
ami = ec2_value(ec2,"AMI")
keypair = ec2_value(ec2,"KEYPAIR")
eip = ec2_value(ec2,"ELASTICIP")
ports = ec2_value(ec2,"AUTHORIZEDPORTS")
type = ec2_value(ec2,"INSTANCETYPE")
if !ami
send_message(ACTION[:deploy],RESULT[:failure],id,
"Can not find AMI in deployment file #{local_dfile}")
return
end
deploy_cmd = "#{EC2[:run]} #{ami}"
deploy_cmd << " -k #{keypair}" if keypair
deploy_cmd << " -t #{type}" if type
deploy_exe = LocalCommand.run(deploy_cmd, log_method(id))
if deploy_exe.code != 0
send_message(ACTION[:deploy],RESULT[:failure],id)
return
end
if !deploy_exe.stdout.match(/^INSTANCE\s*(.+?)\s/)
send_message(ACTION[:deploy],RESULT[:failure],id,
"Could not find instance id. Check ec2-describe-instances")
return
end
deploy_id = $1
if eip
ip_cmd = "#{EC2[:associate]} #{eip} -i #{deploy_id}"
ip_exe = LocalCommand.run(ip_cmd, log_method(id))
end
if ports
ports_cmd = "#{EC2[:authorize]} default -p #{ports}"
ports_exe = LocalCommand.run(ports_cmd, log_method(id))
end
send_message(ACTION[:deploy],RESULT[:success],id,deploy_id)
ec2
end
# Shutdown a EC2 instance
def shutdown(id, drv_message)
# Execute an EC2 command and send the SUCCESS or FAILURE signal
# +drv_message+: String, base64 encoded info sent by ONE
# +ec2_action+: Symbol, one of the keys of the EC2 hash constant (i.e :run)
# +one_action+: String, OpenNebula action
# +id+: String, action id
def ec2_action(drv_message, ec2_action, one_action, id)
msg = decode(drv_message)
host = msg.elements["HOST"].text
deploy_id = msg.elements["DEPLOY_ID"].text
ec2_terminate(ACTION[:shutdown], id, deploy_id)
end
# Reboot a EC2 instance
def reboot(id, drv_message)
cmd = "#{EC2_LOCATION}/bin/ec2-reboot-instances #{deploy_id}"
exe = LocalCommand.run(cmd, log_method(id))
exe = exec_and_log_ec2(ec2_action, nil, deploy_id, id)
if exe.code != 0
result = RESULT[:failure]
send_message(one_action, RESULT[:failure], id, exe.stderr)
else
result = RESULT[:success]
send_message(one_action, RESULT[:success], id)
end
send_message(action,result,id)
end
# Cancel a EC2 instance
def cancel(id, drv_message)
msg = decode(drv_message)
# Execute an EC2 command and log the message if error
# This function will build the command joining the :cmd value of the EC2
# hash, the extra_params string and the options built from the :args schema
# of the EC2 hash and the xml
# +action+: Symbol, one of the keys of the EC2 hash constant (i.e :run)
# +xml+: REXML Document, containing EC2 information
# +extra_params+: String, extra information to be added to the command
def exec_and_log_ec2(action, xml, extra_params="", id)
cmd = EC2[action][:cmd].clone
cmd << ' ' << extra_params << ' ' if extra_params
host = msg.elements["HOST"].text
deploy_id = msg.elements["DEPLOY_ID"].text
ec2_terminate(ACTION[:cancel], id, deploy_id)
end
# Get info (IP, and state) for a EC2 instance
def poll(id, drv_message)
msg = decode(drv_message)
host = msg.elements["HOST"].text
deploy_id = msg.elements["DEPLOY_ID"].text
info = "#{POLL_ATTRIBUTE[:usedmemory]}=0 " \
"#{POLL_ATTRIBUTE[:usedcpu]}=0 " \
"#{POLL_ATTRIBUTE[:nettx]}=0 " \
"#{POLL_ATTRIBUTE[:netrx]}=0"
cmd = "#{EC2[:describe]} #{deploy_id}"
exe = LocalCommand.run(cmd, log_method(id))
if exe.code != 0
send_message(ACTION[:poll],RESULT[:failure],id)
return
if EC2[action][:args]
cmd << EC2[action][:args].map {|k,v|
str = ec2_value(xml, k, &v[:proc])
v[:opt] + ' ' + str if str
}.join(' ')
end
exe.stdout.match(Regexp.new("INSTANCE\\s+#{deploy_id}\\s+(.+)"))
LocalCommand.run(cmd, log_method(id))
end
if !$1
info << " #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:deleted]}"
# Returns the value of the xml specified by the name or the default
# one if it does not exist
# +xml+: REXML Document, containing EC2 information
# +name+: String, xpath expression to retrieve the value
# +block+: Block, block to be applied to the value before returning it
def ec2_value(xml, name, &block)
value = value_from_xml(xml, name) || @defaults[name]
if block_given? && value
block.call(value)
else
monitor_data = $1.split(/\s+/)
case monitor_data[3]
when "pending"
info << " #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:active]}"
when "running"
info<<" #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:active]}"<<
" IP=#{monitor_data[1]}"
when "shutting-down","terminated"
info << " #{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:deleted]}"
end
value
end
send_message(ACTION[:poll], RESULT[:success], id, info)
end
private
def ec2_terminate(action, id, deploy_id)
cmd = "#{EC2_LOCATION}/bin/ec2-terminate-instances #{deploy_id}"
exe = LocalCommand.run(cmd, log_method(id))
if exe.code != 0
result = RESULT[:failure]
else
result = RESULT[:success]
def value_from_xml(xml, name)
if xml
element = xml.elements[name]
element.text.strip if element && element.text
end
send_message(action,result,id)
end
def ec2_value(xml,name)
value = nil
element = xml.elements[name]
value = element.text.strip if element && element.text
if !value
value = @defaults[name]
end
return value
end
end

View File

@ -108,8 +108,6 @@ int VirtualNetworkPool::allocate (
goto error_duplicated;
}
vn = new VirtualNetwork(uid, gid, uname, gname, vn_template);
*oid = PoolSQL::allocate(vn, error_str);
return *oid;