mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-27 14:03:40 +03:00
Merge branch 'master' into feature-1112
This commit is contained in:
commit
4d5ea6f8a2
@ -313,12 +313,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();
|
||||
|
@ -268,6 +268,7 @@ SUNSTONE_DIRS="$SUNSTONE_LOCATION/models \
|
||||
$SUNSTONE_LOCATION/public/vendor/jQuery \
|
||||
$SUNSTONE_LOCATION/public/vendor/jGrowl \
|
||||
$SUNSTONE_LOCATION/public/vendor/flot \
|
||||
$SUNSTONE_LOCATION/public/vendor/fileuploader \
|
||||
$SUNSTONE_LOCATION/public/images \
|
||||
$SUNSTONE_LOCATION/templates \
|
||||
$SUNSTONE_LOCATION/views"
|
||||
@ -460,6 +461,7 @@ INSTALL_SUNSTONE_FILES=(
|
||||
SUNSTONE_PUBLIC_VENDOR_JQUERYUIIMAGES:$SUNSTONE_LOCATION/public/vendor/jQueryUI/images
|
||||
SUNSTONE_PUBLIC_VENDOR_JQUERYLAYOUT:$SUNSTONE_LOCATION/public/vendor/jQueryLayout
|
||||
SUNSTONE_PUBLIC_VENDOR_FLOT:$SUNSTONE_LOCATION/public/vendor/flot
|
||||
SUNSTONE_PUBLIC_VENDOR_FILEUPLOADER:$SUNSTONE_LOCATION/public/vendor/fileuploader
|
||||
SUNSTONE_PUBLIC_IMAGES_FILES:$SUNSTONE_LOCATION/public/images
|
||||
SUNSTONE_PUBLIC_LOCALE_EN_US:$SUNSTONE_LOCATION/public/locale/en_US
|
||||
SUNSTONE_PUBLIC_LOCALE_RU:$SUNSTONE_LOCATION/public/locale/ru
|
||||
@ -834,6 +836,7 @@ ONEDB_MIGRATOR_FILES="src/onedb/2.0_to_2.9.80.rb \
|
||||
src/onedb/3.1.0_to_3.1.80.rb \
|
||||
src/onedb/3.1.80_to_3.2.0.rb \
|
||||
src/onedb/3.2.0_to_3.2.1.rb \
|
||||
src/onedb/3.2.1_to_3.3.0.rb \
|
||||
src/onedb/onedb.rb \
|
||||
src/onedb/onedb_backend.rb"
|
||||
|
||||
@ -1032,7 +1035,8 @@ OCCI_LIB_FILES="src/cloud/occi/lib/OCCIServer.rb \
|
||||
src/cloud/occi/lib/UserOCCI.rb \
|
||||
src/cloud/occi/lib/UserPoolOCCI.rb \
|
||||
src/cloud/occi/lib/ImageOCCI.rb \
|
||||
src/cloud/occi/lib/ImagePoolOCCI.rb"
|
||||
src/cloud/occi/lib/ImagePoolOCCI.rb \
|
||||
src/sunstone/OpenNebulaVNC.rb"
|
||||
|
||||
OCCI_LIB_CLIENT_FILES="src/cloud/occi/lib/OCCIClient.rb"
|
||||
|
||||
@ -1102,7 +1106,8 @@ ETC_CLIENT_FILES="src/cli/etc/group.default"
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
SUNSTONE_FILES="src/sunstone/config.ru \
|
||||
src/sunstone/sunstone-server.rb"
|
||||
src/sunstone/sunstone-server.rb \
|
||||
src/sunstone/OpenNebulaVNC.rb"
|
||||
|
||||
SUNSTONE_BIN_FILES="src/sunstone/bin/sunstone-server"
|
||||
|
||||
|
@ -7,19 +7,12 @@ DEFAULT=%w{optional sunstone quota cloud ozones_server acct auth_ldap}
|
||||
if defined?(RUBY_VERSION) && RUBY_VERSION>="1.8.7"
|
||||
SQLITE='sqlite3'
|
||||
|
||||
# xmlparser gem is not compatible with ruby 1.9
|
||||
OPTIONAL=%w{nokogiri}
|
||||
|
||||
if RUBY_VERSION=='1.8.7'
|
||||
OPTIONAL << 'xmlparser'
|
||||
end
|
||||
else
|
||||
SQLITE='sqlite3-ruby --version 1.2.0'
|
||||
OPTIONAL=%w{nokogiri xmlparser}
|
||||
end
|
||||
|
||||
GROUPS={
|
||||
:optional => OPTIONAL,
|
||||
:optional => ['nokogiri'],
|
||||
:quota => [SQLITE, 'sequel'],
|
||||
:sunstone => ['json', 'rack', 'sinatra', 'thin', 'sequel', SQLITE],
|
||||
:cloud => %w{amazon-ec2 rack sinatra thin uuidtools curb json},
|
||||
|
@ -1,40 +1,56 @@
|
||||
#!/bin/bash
|
||||
|
||||
NOVNC_TMP=/tmp/one/novnc-$(date "+%Y%m%d%H%M%S")
|
||||
PROXY_PATH=noVNC/utils/websockify
|
||||
|
||||
if [ -z "$ONE_LOCATION" ]; then
|
||||
ONE_SHARE=/usr/share/one
|
||||
ONE_PUBLIC_SUNSTONE=/usr/lib/one/sunstone/public
|
||||
SUNSTONE_CONF=/etc/one/sunstone-server.conf
|
||||
ONE_PUBLIC_SELFSERVICE=/usr/lib/one/ruby/cloud/occi/ui/public
|
||||
SELFSERVICE_CONF=/etc/one/occi-server.conf
|
||||
else
|
||||
ONE_SHARE=$ONE_LOCATION/share
|
||||
ONE_PUBLIC_SUNSTONE=$ONE_LOCATION/lib/sunstone/public
|
||||
SUNSTONE_CONF=$ONE_LOCATION/etc/sunstone-server.conf
|
||||
ONE_PUBLIC_SELFSERVICE=$ONE_LOCATION/lib/ruby/cloud/occi/ui/public
|
||||
SELFSERVICE_CONF=$ONE_LOCATION/etc/occi-server.conf
|
||||
fi
|
||||
|
||||
echo "Downloading noVNC latest version..."
|
||||
mkdir -p $NOVNC_TMP
|
||||
wget -P $NOVNC_TMP --no-check-certificate http://github.com/kanaka/noVNC/tarball/master
|
||||
|
||||
cd $NOVNC_TMP
|
||||
curl -O -# -L http://github.com/kanaka/noVNC/tarball/master
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error downloading noVNC"
|
||||
echo "\nError downloading noVNC"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Extracting files to temporary folder..."
|
||||
tar=`ls -rt $NOVNC_TMP|tail -n1`
|
||||
tar -C $ONE_SHARE -mxvzf $NOVNC_TMP/$tar
|
||||
tar -C $ONE_SHARE -mxzf $NOVNC_TMP/$tar
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error untaring noVNC"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Moving files to OpenNebula $ONE_SHARE folder..."
|
||||
rm -rf $ONE_SHARE/noVNC
|
||||
dir=`ls -rt $ONE_SHARE|tail -n1`
|
||||
mv $ONE_SHARE/$dir $ONE_SHARE/noVNC
|
||||
|
||||
echo "Installing Sunstone client libraries in $ONE_PUBLIC_SUNSTONE..."
|
||||
mkdir -p $ONE_PUBLIC_SUNSTONE/vendor/noVNC
|
||||
mv $ONE_SHARE/noVNC/include/ $ONE_PUBLIC_SUNSTONE/vendor/noVNC/
|
||||
cp -r $ONE_SHARE/noVNC/include/ $ONE_PUBLIC_SUNSTONE/vendor/noVNC/
|
||||
|
||||
sed -i.bck "s%^\(:novnc_path: \).*$%\1$ONE_SHARE/noVNC%" $SUNSTONE_CONF
|
||||
echo "Installing SelfService client libraries in $ONE_PUBLIC_SELFSERVICE..."
|
||||
mkdir -p $ONE_PUBLIC_SELFSERVICE/vendor/noVNC
|
||||
cp -r $ONE_SHARE/noVNC/include/ $ONE_PUBLIC_SELFSERVICE/vendor/noVNC/
|
||||
|
||||
#Update file permissions
|
||||
chmod +x $ONE_SHARE/noVNC/utils/launch.sh
|
||||
echo "Backing up and updating $SUNSTONE_CONF with new VNC proxy path..."
|
||||
sed -i.bck "s%^\(:vnc_proxy_path:\).*$%\1 $ONE_SHARE/$PROXY_PATH%" $SUNSTONE_CONF
|
||||
echo "Backing up and updating $SELFSERVICE_CONF with new VNC proxy path..."
|
||||
sed -i.bck "s%^\(:vnc_proxy_path:\).*$%\1 $ONE_SHARE/$PROXY_PATH%" $SELFSERVICE_CONF
|
||||
|
||||
echo "Installation successful"
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -22,8 +22,8 @@
|
||||
# a given metric.
|
||||
#-------------------------------------------------------------------------------
|
||||
:defaults:
|
||||
:cpu:
|
||||
:memory:
|
||||
:num_vms:
|
||||
:storage:
|
||||
:CPU:
|
||||
:MEMORY:
|
||||
:NUM_VMS:
|
||||
:STORAGE:
|
||||
|
||||
|
@ -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
|
||||
@ -365,6 +365,15 @@ EOT
|
||||
end
|
||||
end
|
||||
|
||||
def OpenNebulaHelper.period_to_str(time)
|
||||
seconds=time.to_i
|
||||
minutes, seconds=seconds.divmod(60)
|
||||
hours, minutes=minutes.divmod(60)
|
||||
days, hours=hours.divmod(24)
|
||||
|
||||
"%4dd %02d:%02d:%02d" % [days, hours, minutes, seconds]
|
||||
end
|
||||
|
||||
BinarySufix = ["K", "M", "G", "T" ]
|
||||
|
||||
def OpenNebulaHelper.unit_to_str(value, options, unit="K")
|
||||
|
@ -92,14 +92,10 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
||||
end
|
||||
|
||||
column :TIME, "Time since the VM was submitted", :size=>11 do |d|
|
||||
stime = Time.at(d["STIME"].to_i)
|
||||
etime = d["ETIME"]=="0" ? Time.now : Time.at(d["ETIME"].to_i)
|
||||
dtime = Time.at(etime-stime).getgm
|
||||
"%02d %02d:%02d:%02d" % [
|
||||
dtime.yday-1,
|
||||
dtime.hour,
|
||||
dtime.min,
|
||||
dtime.sec]
|
||||
stime = d["STIME"].to_i
|
||||
etime = d["ETIME"]=="0" ? Time.now.to_i : d["ETIME"].to_i
|
||||
dtime = etime-stime
|
||||
OpenNebulaHelper.period_to_str(dtime)
|
||||
end
|
||||
|
||||
default :ID, :USER, :GROUP, :NAME, :STAT, :CPU, :MEM, :HOSTNAME,
|
||||
@ -201,24 +197,21 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
||||
end
|
||||
|
||||
column :TIME, "Total time in this state", :size=>11 do |d|
|
||||
stime = Time.at(d["STIME"].to_i)
|
||||
etime = d["ETIME"]=="0" ? Time.now : Time.at(d["ETIME"].to_i)
|
||||
dtime = Time.at(etime-stime).getgm
|
||||
"%02d %02d:%02d:%02d" % [dtime.yday-1, dtime.hour,
|
||||
dtime.min, dtime.sec]
|
||||
stime = d["STIME"].to_i
|
||||
etime = d["ETIME"]=="0" ? Time.now.to_i : d["ETIME"].to_i
|
||||
dtime = etime-stime
|
||||
OpenNebulaHelper.period_to_str(dtime)
|
||||
end
|
||||
|
||||
column :PTIME, "Prolog time for this state", :size=>11 do |d|
|
||||
stime = Time.at(d["PSTIME"].to_i)
|
||||
stime = d["PSTIME"].to_i
|
||||
if d["PSTIME"]=="0"
|
||||
etime=Time.at(0)
|
||||
etime=0
|
||||
else
|
||||
etime = d["PETIME"]=="0" ? Time.now :
|
||||
Time.at(d["PETIME"].to_i)
|
||||
etime = d["PETIME"]=="0" ? Time.now.to_i: d["PETIME"].to_i
|
||||
end
|
||||
dtime = Time.at(etime-stime).getgm
|
||||
"%02d %02d:%02d:%02d" % [dtime.yday-1, dtime.hour,
|
||||
dtime.min, dtime.sec]
|
||||
dtime = etime-stime
|
||||
OpenNebulaHelper.period_to_str(dtime)
|
||||
end
|
||||
|
||||
default :SEQ, :HOSTNAME, :REASON, :START, :TIME, :PTIME
|
||||
|
@ -66,18 +66,18 @@ class AcctHelper
|
||||
|
||||
column :NETRX, "Group of the User", :right, :size=>10 do |d|
|
||||
OpenNebulaHelper.unit_to_str(
|
||||
d[:network][:net_rx]/1024.0,
|
||||
d[:network][:net_rx].to_i/1024.0,
|
||||
{})
|
||||
end
|
||||
|
||||
column :NETTX, "Group of the User", :right, :size=>10 do |d|
|
||||
OpenNebulaHelper.unit_to_str(
|
||||
d[:network][:net_tx]/1024.0,
|
||||
d[:network][:net_tx].to_i/1024.0,
|
||||
{})
|
||||
end
|
||||
|
||||
column :TIME, "Group of the User", :right, :size=>15 do |d|
|
||||
OpenNebulaHelper.time_to_str(d[:time])
|
||||
OpenNebulaHelper.period_to_str(d[:time])
|
||||
end
|
||||
|
||||
default :VMID, :MEMORY, :CPU, :NETRX, :NETTX, :TIME
|
||||
|
@ -110,7 +110,8 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
number = options[:multiple] || 1
|
||||
number.times do |i|
|
||||
exit_code=helper.perform_action(args[0],options,"instantiated") do |t|
|
||||
name = options[:vm_name].gsub("%i",i.to_s)
|
||||
name = options[:vm_name]
|
||||
name = name.gsub("%i",i.to_s) if name
|
||||
res = t.instantiate(name)
|
||||
|
||||
if !OpenNebula.is_error?(res)
|
||||
|
@ -61,7 +61,7 @@ module CloudClient
|
||||
# #########################################################################
|
||||
def self.get_one_auth
|
||||
if ENV["ONE_AUTH"] and !ENV["ONE_AUTH"].empty? and
|
||||
File.file?(ENV["ONE_AUTH"])
|
||||
File.file?(ENV["ONE_AUTH"])
|
||||
one_auth=File.read(ENV["ONE_AUTH"]).strip.split(':')
|
||||
elsif File.file?(DEFAULT_AUTH_FILE)
|
||||
one_auth=File.read(DEFAULT_AUTH_FILE).strip.split(':')
|
||||
@ -91,24 +91,30 @@ module CloudClient
|
||||
end
|
||||
|
||||
begin
|
||||
http.start do |connection|
|
||||
res = http.start do |connection|
|
||||
block.call(connection)
|
||||
end
|
||||
rescue Errno::ECONNREFUSED => e
|
||||
str = "Error connecting to server (#{e.to_s}).\n"
|
||||
str << "Server: #{url.host}:#{url.port}"
|
||||
|
||||
return CloudClient::Error.new(str)
|
||||
return CloudClient::Error.new(str,"503")
|
||||
rescue Errno::ETIMEDOUT => e
|
||||
str = "Error timeout connecting to server (#{e.to_s}).\n"
|
||||
str << "Server: #{url.host}:#{url.port}"
|
||||
|
||||
return CloudClient::Error.new(str)
|
||||
return CloudClient::Error.new(str,"504")
|
||||
rescue Timeout::Error => e
|
||||
str = "Error timeout while connected to server (#{e.to_s}).\n"
|
||||
str << "Server: #{url.host}:#{url.port}"
|
||||
|
||||
return CloudClient::Error.new(str)
|
||||
return CloudClient::Error.new(str,"504")
|
||||
end
|
||||
|
||||
if res.is_a?(Net::HTTPSuccess)
|
||||
res
|
||||
else
|
||||
CloudClient::Error.new(res.body, res.code)
|
||||
end
|
||||
end
|
||||
|
||||
@ -118,10 +124,12 @@ module CloudClient
|
||||
# #########################################################################
|
||||
class Error
|
||||
attr_reader :message
|
||||
attr_reader :code
|
||||
|
||||
# +message+ a description of the error
|
||||
def initialize(message=nil)
|
||||
def initialize(message=nil, code="500")
|
||||
@message=message
|
||||
@code=code
|
||||
end
|
||||
|
||||
def to_s()
|
||||
@ -140,7 +148,7 @@ end
|
||||
|
||||
# Command line help functions
|
||||
module CloudCLI
|
||||
def print_xml(xml_text)
|
||||
def print_xml(xml_text)
|
||||
begin
|
||||
doc = REXML::Document.new(xml_text)
|
||||
rescue REXML::ParseException => e
|
||||
@ -173,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
|
||||
|
@ -70,6 +70,7 @@ module EC2QueryClient
|
||||
end
|
||||
|
||||
@uri = URI.parse(endpoint)
|
||||
path = @uri.path.empty? ? '/' : @uri.path
|
||||
|
||||
@ec2_connection = AWS::EC2::Base.new(
|
||||
:access_key_id => @access_key_id,
|
||||
@ -77,7 +78,7 @@ module EC2QueryClient
|
||||
:server => @uri.host,
|
||||
:port => @uri.port,
|
||||
:use_ssl => @uri.scheme == 'https',
|
||||
:path => @uri.path)
|
||||
:path => path)
|
||||
end
|
||||
|
||||
|
||||
|
@ -54,8 +54,8 @@ class EC2QueryServer < CloudServer
|
||||
'save' => :pending,
|
||||
'epil' => :shutdown,
|
||||
'shut' => :shutdown,
|
||||
'clea' => :shutdown,
|
||||
'fail' => :terminated,
|
||||
'dele' => :terminated,
|
||||
'unkn' => :terminated
|
||||
}
|
||||
|
||||
@ -211,7 +211,8 @@ class EC2QueryServer < CloudServer
|
||||
# Helper functions
|
||||
###########################################################################
|
||||
def render_state(vm)
|
||||
ec2_state = EC2_STATES[ONE_STATES[vm.status]]
|
||||
one_state = ONE_STATES[vm.status]
|
||||
ec2_state = EC2_STATES[one_state||:pending]
|
||||
|
||||
return "<code>#{ec2_state[:code]}</code>
|
||||
<name>#{ec2_state[:name]}</name>"
|
||||
|
@ -12,7 +12,6 @@
|
||||
</groupSet>
|
||||
<instancesSet>
|
||||
<% vmpool.each do |vm| %>
|
||||
<% vm.info %>
|
||||
<item>
|
||||
<instanceId>i-<%= vm.id %></instanceId>
|
||||
<imageId><%= vm['TEMPLATE/IMAGE_ID'] %></imageId>
|
||||
|
@ -52,5 +52,26 @@
|
||||
:cpu: 8
|
||||
:memory: 8192
|
||||
|
||||
# Default language setting for Self-Service UI
|
||||
#############################################################
|
||||
# OCCI UI Settings (SelfService)
|
||||
#############################################################
|
||||
|
||||
# Default language setting
|
||||
:lang: en_US
|
||||
|
||||
# VNC Configuration
|
||||
# vnc_enable: yes | no. Allow users to launch vnc sessions.
|
||||
# base_port: base_port + vnc_port of the VM is the port where the
|
||||
# proxy will listen for VNC session connections to that VM.
|
||||
# vnc_proxy_path: path to the websockets proxy (set by install_novnc.sh)
|
||||
# support_wss: no | yes | only. If yes or only provide path to cert and key.
|
||||
# "yes" means the proxy will accept both ws and wss connections.
|
||||
# vnc_proxy_cert: Certificate to encrypt wss connections.
|
||||
# vnc_proxy_key: Key for wss connections. Only necessary if not included in cert.
|
||||
:vnc_enable: no
|
||||
|
||||
:vnc_proxy_base_port: 33876
|
||||
:vnc_proxy_path:
|
||||
:vnc_proxy_support_wss: no
|
||||
:vnc_proxy_cert:
|
||||
:vnc_proxy_key:
|
||||
|
@ -23,6 +23,8 @@ class ImageOCCI < Image
|
||||
<STORAGE href="<%= base_url %>/storage/<%= self.id.to_s %>">
|
||||
<ID><%= self.id.to_s %></ID>
|
||||
<NAME><%= self.name %></NAME>
|
||||
<USER href="<%= base_url %>/user/<%= self['UID'] %>" name="<%= self['UNAME'] %>"/>
|
||||
<GROUP><%= self['GNAME'] %></GROUP>
|
||||
<STATE><%= self.state_str %></STATE>
|
||||
<% if self['TYPE'] != nil %>
|
||||
<TYPE><%= self.type_str %></TYPE>
|
||||
@ -82,7 +84,7 @@ class ImageOCCI < Image
|
||||
end
|
||||
|
||||
# Creates the OCCI representation of an Image
|
||||
def to_occi(base_url)
|
||||
def to_occi(base_url, verbose=false)
|
||||
begin
|
||||
occi_im = ERB.new(OCCI_IMAGE)
|
||||
occi_im_text = occi_im.result(binding)
|
||||
|
@ -14,22 +14,23 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'OpenNebula'
|
||||
|
||||
include OpenNebula
|
||||
require 'ImageOCCI'
|
||||
|
||||
class ImagePoolOCCI < ImagePool
|
||||
OCCI_IMAGE_POOL = %q{
|
||||
<STORAGE_COLLECTION>
|
||||
<% self.each{ |im| %>
|
||||
<% if verbose %>
|
||||
<%= im.to_occi(base_url) %>
|
||||
<% else %>
|
||||
<STORAGE href="<%= base_url %>/storage/<%= im.id.to_s %>" name="<%= im.name %>"/>
|
||||
<% end %>
|
||||
<% } %>
|
||||
</STORAGE_COLLECTION>
|
||||
}
|
||||
|
||||
|
||||
# Creates the OCCI representation of a Virtual Machine Pool
|
||||
def to_occi(base_url)
|
||||
def to_occi(base_url, verbose=false)
|
||||
begin
|
||||
occi = ERB.new(OCCI_IMAGE_POOL)
|
||||
occi_text = occi.result(binding)
|
||||
@ -40,5 +41,9 @@ class ImagePoolOCCI < ImagePool
|
||||
|
||||
return occi_text.gsub(/\n\s*/,'')
|
||||
end
|
||||
|
||||
def factory(element_xml)
|
||||
ImageOCCI.new(element_xml,@client)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -30,11 +30,13 @@ module OCCIClient
|
||||
#####################################################################
|
||||
class Client
|
||||
|
||||
attr_accessor :endpoint
|
||||
|
||||
######################################################################
|
||||
# Initialize client library
|
||||
######################################################################
|
||||
def initialize(endpoint_str=nil, user=nil, pass=nil,
|
||||
timeout=nil, debug_flag=true)
|
||||
timeout=nil, debug_flag=true)
|
||||
@debug = debug_flag
|
||||
@timeout = timeout
|
||||
|
||||
@ -65,50 +67,30 @@ module OCCIClient
|
||||
# Pool Resource Request Methods #
|
||||
#################################
|
||||
|
||||
def get_root
|
||||
get('/')
|
||||
end
|
||||
|
||||
######################################################################
|
||||
# Retieves the available Instance types
|
||||
######################################################################
|
||||
def get_instance_types
|
||||
get('/instance_type')
|
||||
end
|
||||
|
||||
######################################################################
|
||||
# Post a new VM to the VM Pool
|
||||
# :instance_type
|
||||
# :xmlfile
|
||||
######################################################################
|
||||
def post_vms(xmlfile)
|
||||
xml=File.read(xmlfile)
|
||||
|
||||
url = URI.parse(@endpoint+"/compute")
|
||||
|
||||
req = Net::HTTP::Post.new(url.path)
|
||||
req.body=xml
|
||||
|
||||
req.basic_auth @occiauth[0], @occiauth[1]
|
||||
|
||||
res = CloudClient::http_start(url, @timeout) do |http|
|
||||
http.request(req)
|
||||
end
|
||||
|
||||
if CloudClient::is_error?(res)
|
||||
return res
|
||||
else
|
||||
return res.body
|
||||
end
|
||||
post('/compute', xmlfile)
|
||||
end
|
||||
|
||||
######################################################################
|
||||
# Retieves the pool of Virtual Machines
|
||||
######################################################################
|
||||
def get_vms
|
||||
url = URI.parse(@endpoint+"/compute")
|
||||
req = Net::HTTP::Get.new(url.path)
|
||||
|
||||
req.basic_auth @occiauth[0], @occiauth[1]
|
||||
|
||||
res = CloudClient::http_start(url, @timeout) {|http|
|
||||
http.request(req)
|
||||
}
|
||||
|
||||
if CloudClient::is_error?(res)
|
||||
return res
|
||||
else
|
||||
return res.body
|
||||
end
|
||||
get('/compute')
|
||||
end
|
||||
|
||||
######################################################################
|
||||
@ -116,44 +98,14 @@ module OCCIClient
|
||||
# :xmlfile xml description of the Virtual Network
|
||||
######################################################################
|
||||
def post_network(xmlfile)
|
||||
xml=File.read(xmlfile)
|
||||
|
||||
url = URI.parse(@endpoint+"/network")
|
||||
|
||||
req = Net::HTTP::Post.new(url.path)
|
||||
req.body=xml
|
||||
|
||||
req.basic_auth @occiauth[0], @occiauth[1]
|
||||
|
||||
res = CloudClient::http_start(url, @timeout) do |http|
|
||||
http.request(req)
|
||||
end
|
||||
|
||||
if CloudClient::is_error?(res)
|
||||
return res
|
||||
else
|
||||
return res.body
|
||||
end
|
||||
post('/network', xmlfile)
|
||||
end
|
||||
|
||||
######################################################################
|
||||
# Retieves the pool of Virtual Networks
|
||||
######################################################################
|
||||
def get_networks
|
||||
url = URI.parse(@endpoint+"/network")
|
||||
req = Net::HTTP::Get.new(url.path)
|
||||
|
||||
req.basic_auth @occiauth[0], @occiauth[1]
|
||||
|
||||
res = CloudClient::http_start(url, @timeout) {|http|
|
||||
http.request(req)
|
||||
}
|
||||
|
||||
if CloudClient::is_error?(res)
|
||||
return res
|
||||
else
|
||||
return res.body
|
||||
end
|
||||
get('/network')
|
||||
end
|
||||
|
||||
######################################################################
|
||||
@ -251,22 +203,10 @@ module OCCIClient
|
||||
# Retieves the pool of Images owned by the user
|
||||
######################################################################
|
||||
def get_images
|
||||
url = URI.parse(@endpoint+"/storage")
|
||||
req = Net::HTTP::Get.new(url.path)
|
||||
|
||||
req.basic_auth @occiauth[0], @occiauth[1]
|
||||
|
||||
res = CloudClient::http_start(url, @timeout) {|http|
|
||||
http.request(req)
|
||||
}
|
||||
|
||||
if CloudClient::is_error?(res)
|
||||
return res
|
||||
else
|
||||
return res.body
|
||||
end
|
||||
get('/storage')
|
||||
end
|
||||
|
||||
|
||||
####################################
|
||||
# Entity Resource Request Methods #
|
||||
####################################
|
||||
@ -275,20 +215,7 @@ module OCCIClient
|
||||
# :id VM identifier
|
||||
######################################################################
|
||||
def get_vm(id)
|
||||
url = URI.parse(@endpoint+"/compute/" + id.to_s)
|
||||
req = Net::HTTP::Get.new(url.path)
|
||||
|
||||
req.basic_auth @occiauth[0], @occiauth[1]
|
||||
|
||||
res = CloudClient::http_start(url, @timeout) {|http|
|
||||
http.request(req)
|
||||
}
|
||||
|
||||
if CloudClient::is_error?(res)
|
||||
return res
|
||||
else
|
||||
return res.body
|
||||
end
|
||||
get('/compute/'+id.to_s)
|
||||
end
|
||||
|
||||
######################################################################
|
||||
@ -296,57 +223,14 @@ module OCCIClient
|
||||
# :xmlfile Compute OCCI xml representation
|
||||
######################################################################
|
||||
def put_vm(xmlfile)
|
||||
xml = File.read(xmlfile)
|
||||
|
||||
begin
|
||||
vm_info = REXML::Document.new(xml).root
|
||||
rescue Exception => e
|
||||
error = CloudClient::Error.new(e.message)
|
||||
return error
|
||||
end
|
||||
|
||||
if vm_info.elements['ID'] == nil
|
||||
return CloudClient::Error.new("Can not find COMPUTE_ID")
|
||||
end
|
||||
|
||||
vm_id = vm_info.elements['ID'].text
|
||||
|
||||
url = URI.parse(@endpoint+'/compute/' + vm_id)
|
||||
|
||||
req = Net::HTTP::Put.new(url.path)
|
||||
req.body = xml
|
||||
|
||||
req.basic_auth @occiauth[0], @occiauth[1]
|
||||
|
||||
res = CloudClient::http_start(url, @timeout) do |http|
|
||||
http.request(req)
|
||||
end
|
||||
|
||||
if CloudClient::is_error?(res)
|
||||
return res
|
||||
else
|
||||
return res.body
|
||||
end
|
||||
put('/compute/', xmlfile)
|
||||
end
|
||||
|
||||
####################################################################
|
||||
# :id Compute identifier
|
||||
####################################################################
|
||||
def delete_vm(id)
|
||||
url = URI.parse(@endpoint+"/compute/" + id.to_s)
|
||||
req = Net::HTTP::Delete.new(url.path)
|
||||
|
||||
req.basic_auth @occiauth[0], @occiauth[1]
|
||||
|
||||
res = CloudClient::http_start(url, @timeout) {|http|
|
||||
http.request(req)
|
||||
}
|
||||
|
||||
if CloudClient::is_error?(res)
|
||||
return res
|
||||
else
|
||||
return res.body
|
||||
end
|
||||
delete('/compute/'+id.to_s)
|
||||
end
|
||||
|
||||
######################################################################
|
||||
@ -354,20 +238,7 @@ module OCCIClient
|
||||
# :id Virtual Network identifier
|
||||
######################################################################
|
||||
def get_network(id)
|
||||
url = URI.parse(@endpoint+"/network/" + id.to_s)
|
||||
req = Net::HTTP::Get.new(url.path)
|
||||
|
||||
req.basic_auth @occiauth[0], @occiauth[1]
|
||||
|
||||
res = CloudClient::http_start(url, @timeout) {|http|
|
||||
http.request(req)
|
||||
}
|
||||
|
||||
if CloudClient::is_error?(res)
|
||||
return res
|
||||
else
|
||||
return res.body
|
||||
end
|
||||
get('/network/'+id.to_s)
|
||||
end
|
||||
|
||||
######################################################################
|
||||
@ -375,78 +246,22 @@ module OCCIClient
|
||||
# :xmlfile Network OCCI xml representation
|
||||
######################################################################
|
||||
def put_network(xmlfile)
|
||||
xml = File.read(xmlfile)
|
||||
|
||||
begin
|
||||
vnet_info = REXML::Document.new(xml).root
|
||||
rescue Exception => e
|
||||
error = CloudClient::Error.new(e.message)
|
||||
return error
|
||||
end
|
||||
|
||||
if vnet_info.elements['ID'] == nil
|
||||
return CloudClient::Error.new("Can not find NETWORK_ID")
|
||||
end
|
||||
|
||||
vnet_id = vnet_info.elements['ID'].text
|
||||
|
||||
url = URI.parse(@endpoint+'/network/' + vnet_id)
|
||||
|
||||
req = Net::HTTP::Put.new(url.path)
|
||||
req.body = xml
|
||||
|
||||
req.basic_auth @occiauth[0], @occiauth[1]
|
||||
|
||||
res = CloudClient::http_start(url, @timeout) do |http|
|
||||
http.request(req)
|
||||
end
|
||||
|
||||
if CloudClient::is_error?(res)
|
||||
return res
|
||||
else
|
||||
return res.body
|
||||
end
|
||||
put('/network/', xmlfile)
|
||||
end
|
||||
|
||||
######################################################################
|
||||
# :id VM identifier
|
||||
######################################################################
|
||||
def delete_network(id)
|
||||
url = URI.parse(@endpoint+"/network/" + id.to_s)
|
||||
req = Net::HTTP::Delete.new(url.path)
|
||||
|
||||
req.basic_auth @occiauth[0], @occiauth[1]
|
||||
|
||||
res = CloudClient::http_start(url, @timeout) {|http|
|
||||
http.request(req)
|
||||
}
|
||||
|
||||
if CloudClient::is_error?(res)
|
||||
return res
|
||||
else
|
||||
return res.body
|
||||
end
|
||||
delete('/network/'+id.to_s)
|
||||
end
|
||||
|
||||
#######################################################################
|
||||
#######################################################################
|
||||
# Retieves an Image
|
||||
# :image_uuid Image identifier
|
||||
######################################################################
|
||||
def get_image(image_uuid)
|
||||
url = URI.parse(@endpoint+"/storage/"+image_uuid)
|
||||
req = Net::HTTP::Get.new(url.path)
|
||||
|
||||
req.basic_auth @occiauth[0], @occiauth[1]
|
||||
|
||||
res = CloudClient::http_start(url, @timeout) {|http|
|
||||
http.request(req)
|
||||
}
|
||||
|
||||
if CloudClient::is_error?(res)
|
||||
return res
|
||||
else
|
||||
return res.body
|
||||
end
|
||||
def get_image(id)
|
||||
get('/storage/'+id.to_s)
|
||||
end
|
||||
|
||||
######################################################################
|
||||
@ -454,26 +269,67 @@ module OCCIClient
|
||||
# :xmlfile Storage OCCI xml representation
|
||||
######################################################################
|
||||
def put_image(xmlfile)
|
||||
xml = File.read(xmlfile)
|
||||
|
||||
put('/storage/', xmlfile)
|
||||
end
|
||||
|
||||
######################################################################
|
||||
# :id VM identifier
|
||||
######################################################################
|
||||
def delete_image(id)
|
||||
delete('/storage/'+id.to_s)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get(path)
|
||||
url = URI.parse(@endpoint+path)
|
||||
req = Net::HTTP::Get.new(url.path)
|
||||
|
||||
do_request(url, req)
|
||||
end
|
||||
|
||||
def post(path, xmlfile)
|
||||
url = URI.parse(@endpoint+path)
|
||||
req = Net::HTTP::Post.new(url.path)
|
||||
|
||||
req.body=File.read(xmlfile)
|
||||
|
||||
do_request(url, req)
|
||||
end
|
||||
|
||||
def delete(path, xmlfile)
|
||||
url = URI.parse(@endpoint+path)
|
||||
req = Net::HTTP::Delete.new(url.path)
|
||||
|
||||
do_request(url, req)
|
||||
end
|
||||
|
||||
def put(path, xmlfile)
|
||||
xml = File.read(xmlfile)
|
||||
|
||||
# Get ID from XML
|
||||
begin
|
||||
image_info = REXML::Document.new(xml).root
|
||||
info = REXML::Document.new(xml).root
|
||||
rescue Exception => e
|
||||
error = OpenNebula::Error.new(e.message)
|
||||
error = CloudClient::Error.new(e.message)
|
||||
return error
|
||||
end
|
||||
|
||||
if image_info.elements['ID'] == nil
|
||||
return CloudClient::Error.new("Can not find STORAGE_ID")
|
||||
|
||||
if info.elements['ID'] == nil
|
||||
return CloudClient::Error.new("Can not find RESOURCE ID")
|
||||
end
|
||||
|
||||
image_id = image_info.elements['ID'].text
|
||||
|
||||
url = URI.parse(@endpoint+'/storage/' + image_id)
|
||||
resource_id = info.elements['ID'].text
|
||||
|
||||
url = URI.parse(@endpoint+path + resource_id)
|
||||
req = Net::HTTP::Put.new(url.path)
|
||||
|
||||
req.body = xml
|
||||
|
||||
do_request(url, req)
|
||||
end
|
||||
|
||||
def do_request(url, req)
|
||||
req.basic_auth @occiauth[0], @occiauth[1]
|
||||
|
||||
res = CloudClient::http_start(url, @timeout) do |http|
|
||||
@ -486,25 +342,5 @@ module OCCIClient
|
||||
return res.body
|
||||
end
|
||||
end
|
||||
|
||||
######################################################################
|
||||
# :id VM identifier
|
||||
######################################################################
|
||||
def delete_image(id)
|
||||
url = URI.parse(@endpoint+"/storage/" + id.to_s)
|
||||
req = Net::HTTP::Delete.new(url.path)
|
||||
|
||||
req.basic_auth @occiauth[0], @occiauth[1]
|
||||
|
||||
res = CloudClient::http_start(url, @timeout) {|http|
|
||||
http.request(req)
|
||||
}
|
||||
|
||||
if CloudClient::is_error?(res)
|
||||
return res
|
||||
else
|
||||
return res.body
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -30,6 +30,8 @@ require 'ImagePoolOCCI'
|
||||
require 'UserOCCI'
|
||||
require 'UserPoolOCCI'
|
||||
|
||||
require 'OpenNebulaVNC'
|
||||
|
||||
require 'pp'
|
||||
|
||||
|
||||
@ -38,11 +40,14 @@ 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
|
||||
|
||||
# Secs to sleep between checks to see if image upload© to repo is finished
|
||||
IMAGE_POLL_SLEEP_TIME = 5
|
||||
|
||||
class OCCIServer < CloudServer
|
||||
# Server initializer
|
||||
# config_file:: _String_ path of the config file
|
||||
@ -62,11 +67,11 @@ class OCCIServer < CloudServer
|
||||
# Prepare the OCCI XML Response
|
||||
# resource:: _Pool_ or _PoolElement_ that represents a OCCI resource
|
||||
# [return] _String_,_Integer_ Resource Representation or error, status code
|
||||
def to_occi_xml(resource, code)
|
||||
xml_response = resource.to_occi(@base_url)
|
||||
def to_occi_xml(resource, opts)
|
||||
xml_response = resource.to_occi(@base_url, opts[:verbose])
|
||||
return xml_response, 500 if OpenNebula.is_error?(xml_response)
|
||||
|
||||
return xml_response, code
|
||||
return xml_response, opts[:code]
|
||||
end
|
||||
|
||||
############################################################################
|
||||
@ -87,18 +92,36 @@ class OCCIServer < CloudServer
|
||||
return xml_resp, 200
|
||||
end
|
||||
|
||||
|
||||
INSTANCE_TYPE = %q{
|
||||
<INSTANCE_TYPE href="<%= @base_url %>/instance_type/<%=name%>" name="<%= name %>">
|
||||
<ID><%= name.to_s %></ID>
|
||||
<NAME><%= name.to_s %></NAME>
|
||||
<% opts.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>\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"
|
||||
@config[:instance_types].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 << "\t<INSTANCE_TYPE href=\"#{@base_url}/instance_type/#{name.to_s}\" name=\"#{name}\">\n"
|
||||
end
|
||||
}
|
||||
|
||||
xml_resp << "</INSTANCE_TYPE_COLLECTION>"
|
||||
@ -106,6 +129,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
|
||||
@ -122,7 +163,7 @@ class OCCIServer < CloudServer
|
||||
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
|
||||
end
|
||||
|
||||
return to_occi_xml(vmpool, 200)
|
||||
return to_occi_xml(vmpool, :status=>200, :verbose=>request.params['verbose'])
|
||||
end
|
||||
|
||||
|
||||
@ -142,7 +183,7 @@ class OCCIServer < CloudServer
|
||||
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
|
||||
end
|
||||
|
||||
return to_occi_xml(network_pool, 200)
|
||||
return to_occi_xml(network_pool, :status=>200, :verbose=>request.params['verbose'])
|
||||
end
|
||||
|
||||
# Gets the pool representation of STORAGES
|
||||
@ -161,7 +202,7 @@ class OCCIServer < CloudServer
|
||||
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
|
||||
end
|
||||
|
||||
return to_occi_xml(image_pool, 200)
|
||||
return to_occi_xml(image_pool, :status=>200, :verbose=>request.params['verbose'])
|
||||
end
|
||||
|
||||
# Gets the pool representation of USERs
|
||||
@ -178,7 +219,7 @@ class OCCIServer < CloudServer
|
||||
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
|
||||
end
|
||||
|
||||
return to_occi_xml(user_pool, 200)
|
||||
return to_occi_xml(user_pool, :status=>200, :verbose=>request.params['verbose'])
|
||||
end
|
||||
|
||||
############################################################################
|
||||
@ -214,7 +255,7 @@ class OCCIServer < CloudServer
|
||||
|
||||
# --- Prepare XML Response ---
|
||||
vm.info
|
||||
return to_occi_xml(vm, 201)
|
||||
return to_occi_xml(vm, :status=>201)
|
||||
end
|
||||
|
||||
# Get the representation of a COMPUTE resource
|
||||
@ -233,10 +274,9 @@ class OCCIServer < CloudServer
|
||||
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
|
||||
end
|
||||
|
||||
return to_occi_xml(vm, 200)
|
||||
return to_occi_xml(vm, :status=>200)
|
||||
end
|
||||
|
||||
|
||||
# Deletes a COMPUTE resource
|
||||
# request:: _Hash_ hash containing the data of the request
|
||||
# [return] _String_,_Integer_ Delete confirmation msg or error,
|
||||
@ -277,7 +317,7 @@ class OCCIServer < CloudServer
|
||||
return result, code
|
||||
else
|
||||
vm.info
|
||||
return to_occi_xml(vm, code)
|
||||
return to_occi_xml(vm, :status=>code)
|
||||
end
|
||||
end
|
||||
|
||||
@ -307,7 +347,7 @@ class OCCIServer < CloudServer
|
||||
|
||||
# --- Prepare XML Response ---
|
||||
network.info
|
||||
return to_occi_xml(network, 201)
|
||||
return to_occi_xml(network, :status=>201)
|
||||
end
|
||||
|
||||
# Retrieves a NETWORK resource
|
||||
@ -325,7 +365,7 @@ class OCCIServer < CloudServer
|
||||
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
|
||||
end
|
||||
|
||||
return to_occi_xml(network, 200)
|
||||
return to_occi_xml(network, :status=>200)
|
||||
end
|
||||
|
||||
# Deletes a NETWORK resource
|
||||
@ -371,7 +411,7 @@ class OCCIServer < CloudServer
|
||||
|
||||
# --- Prepare XML Response ---
|
||||
vnet.info
|
||||
return to_occi_xml(vnet, 202)
|
||||
return to_occi_xml(vnet, :status=>202)
|
||||
end
|
||||
|
||||
############################################################################
|
||||
@ -409,9 +449,15 @@ class OCCIServer < CloudServer
|
||||
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
|
||||
end
|
||||
|
||||
# --- Prepare XML Response ---
|
||||
image.info
|
||||
return to_occi_xml(image, 201)
|
||||
#wait until image is ready to return
|
||||
while (image.state_str == 'LOCKED') && (image['RUNNING_VMS'] == '0') do
|
||||
sleep IMAGE_POLL_SLEEP_TIME
|
||||
image.info
|
||||
end
|
||||
|
||||
# --- Prepare XML Response ---
|
||||
return to_occi_xml(image, :status=>201)
|
||||
end
|
||||
|
||||
# Get a STORAGE resource
|
||||
@ -430,7 +476,7 @@ class OCCIServer < CloudServer
|
||||
end
|
||||
|
||||
# --- Prepare XML Response ---
|
||||
return to_occi_xml(image, 200)
|
||||
return to_occi_xml(image, :status=>200)
|
||||
end
|
||||
|
||||
# Deletes a STORAGE resource (Not yet implemented)
|
||||
@ -484,7 +530,7 @@ class OCCIServer < CloudServer
|
||||
|
||||
# --- Prepare XML Response ---
|
||||
image.info
|
||||
return to_occi_xml(image, 202)
|
||||
return to_occi_xml(image, :status=>202)
|
||||
end
|
||||
|
||||
# Get the representation of a USER
|
||||
@ -503,6 +549,34 @@ class OCCIServer < CloudServer
|
||||
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
|
||||
end
|
||||
|
||||
return to_occi_xml(user, 200)
|
||||
return to_occi_xml(user, :status=>200)
|
||||
end
|
||||
|
||||
############################################################################
|
||||
# VNC Methods
|
||||
############################################################################
|
||||
|
||||
def startvnc(id,config)
|
||||
vm = VirtualMachineOCCI.new(VirtualMachine.build_xml(id), @client)
|
||||
rc = vm.info
|
||||
|
||||
if OpenNebula.is_error?(rc)
|
||||
error = "Error starting VNC session, "
|
||||
error << "could not retrieve Virtual Machine"
|
||||
return [404, error]
|
||||
end
|
||||
|
||||
vnc_proxy = OpenNebulaVNC.new(config,{:json_errors => false})
|
||||
return vnc_proxy.start(vm)
|
||||
end
|
||||
|
||||
def stopvnc(pipe)
|
||||
begin
|
||||
OpenNebulaVNC.stop(pipe)
|
||||
rescue Exception => e
|
||||
return [500, e.message]
|
||||
end
|
||||
|
||||
return [200,nil]
|
||||
end
|
||||
end
|
||||
|
@ -27,6 +27,7 @@ class UserOCCI < User
|
||||
<USER href="<%= base_url %>/user/<%= self.id.to_s %>">
|
||||
<ID><%= self.id.to_s %></ID>
|
||||
<NAME><%= self.name %></NAME>
|
||||
<GROUP><%= self['GNAME'] %></GROUP>
|
||||
<QUOTA>
|
||||
<% user_quota.each { |key,value|
|
||||
key_s = key.to_s.upcase
|
||||
@ -50,7 +51,7 @@ class UserOCCI < User
|
||||
end
|
||||
|
||||
# Creates the OCCI representation of a User
|
||||
def to_occi(base_url)
|
||||
def to_occi(base_url, verbose=false)
|
||||
quota = Quota.new
|
||||
user_usage = quota.get_usage(self.id, nil, FORCE_USAGE)
|
||||
user_usage.delete(:uid)
|
||||
|
@ -14,22 +14,23 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'OpenNebula'
|
||||
|
||||
include OpenNebula
|
||||
require 'UserOCCI'
|
||||
|
||||
class UserPoolOCCI < UserPool
|
||||
OCCI_USER_POOL = %q{
|
||||
<USER_COLLECTION>
|
||||
<% self.each{ |user| %>
|
||||
<% if verbose %>
|
||||
<%= user.to_occi(base_url) %>
|
||||
<% else %>
|
||||
<USER href="<%= base_url %>/user/<%= user.id.to_s %>" name="<%= user.name %>"/>
|
||||
<% end %>
|
||||
<% } %>
|
||||
</USER_COLLECTION>
|
||||
}
|
||||
|
||||
|
||||
# Creates the OCCI representation of a User Pool
|
||||
def to_occi(base_url)
|
||||
def to_occi(base_url, verbose=false)
|
||||
begin
|
||||
occi = ERB.new(OCCI_USER_POOL)
|
||||
occi_text = occi.result(binding)
|
||||
@ -40,4 +41,8 @@ class UserPoolOCCI < UserPool
|
||||
|
||||
return occi_text.gsub(/\n\s*/,'')
|
||||
end
|
||||
|
||||
def factory(element_xml)
|
||||
UserOCCI.new(element_xml,@client)
|
||||
end
|
||||
end
|
@ -22,6 +22,8 @@ class VirtualMachineOCCI < VirtualMachine
|
||||
OCCI_VM = %q{
|
||||
<COMPUTE href="<%= base_url %>/compute/<%= self.id.to_s %>">
|
||||
<ID><%= self.id.to_s%></ID>
|
||||
<USER href="<%= base_url %>/user/<%= self['UID'] %>" name="<%= self['UNAME'] %>"/>
|
||||
<GROUP><%= self['GNAME'] %></GROUP>
|
||||
<CPU><%= self['TEMPLATE/CPU'] %></CPU>
|
||||
<MEMORY><%= self['TEMPLATE/MEMORY'] %></MEMORY>
|
||||
<NAME><%= self.name%></NAME>
|
||||
@ -120,7 +122,7 @@ class VirtualMachineOCCI < VirtualMachine
|
||||
end
|
||||
|
||||
# Creates the VMI representation of a Virtual Machine
|
||||
def to_occi(base_url)
|
||||
def to_occi(base_url, verbose=false)
|
||||
begin
|
||||
occi_vm = ERB.new(OCCI_VM)
|
||||
occi_vm_text = occi_vm.result(binding)
|
||||
|
@ -14,22 +14,24 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'OpenNebula'
|
||||
|
||||
include OpenNebula
|
||||
require 'VirtualMachineOCCI'
|
||||
|
||||
class VirtualMachinePoolOCCI < VirtualMachinePool
|
||||
OCCI_VM_POOL = %q{
|
||||
<COMPUTE_COLLECTION>
|
||||
<% self.each{ |vm| %>
|
||||
<% self.each{ |vm| %>
|
||||
<% if verbose %>
|
||||
<%= vm.to_occi(base_url) %>
|
||||
<% else %>
|
||||
<COMPUTE href="<%= base_url %>/compute/<%= vm.id.to_s %>" name="<%= vm.name %>"/>
|
||||
<% end %>
|
||||
<% } %>
|
||||
</COMPUTE_COLLECTION>
|
||||
}
|
||||
|
||||
|
||||
# Creates the OCCI representation of a Virtual Machine Pool
|
||||
def to_occi(base_url)
|
||||
def to_occi(base_url, verbose=false)
|
||||
begin
|
||||
occi = ERB.new(OCCI_VM_POOL)
|
||||
occi_text = occi.result(binding)
|
||||
@ -40,5 +42,9 @@ class VirtualMachinePoolOCCI < VirtualMachinePool
|
||||
|
||||
return occi_text.gsub(/\n\s*/,'')
|
||||
end
|
||||
|
||||
def factory(element_xml)
|
||||
VirtualMachineOCCI.new(element_xml,@client)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -24,6 +24,8 @@ class VirtualNetworkOCCI < VirtualNetwork
|
||||
<NETWORK href="<%= base_url %>/network/<%= self.id.to_s %>">
|
||||
<ID><%= self.id.to_s %></ID>
|
||||
<NAME><%= self.name %></NAME>
|
||||
<USER href="<%= base_url %>/user/<%= self['UID'] %>" name="<%= self['UNAME'] %>"/>
|
||||
<GROUP><%= self['GNAME'] %></GROUP>
|
||||
<% if self['TEMPLATE/DESCRIPTION'] != nil %>
|
||||
<DESCRIPTION><%= self['TEMPLATE/DESCRIPTION'] %></DESCRIPTION>
|
||||
<% end %>
|
||||
@ -52,7 +54,7 @@ class VirtualNetworkOCCI < VirtualNetwork
|
||||
end
|
||||
|
||||
# Creates the OCCI representation of a Virtual Network
|
||||
def to_occi(base_url)
|
||||
def to_occi(base_url, verbose=false)
|
||||
network_address = nil
|
||||
network_size = nil
|
||||
|
||||
|
@ -14,22 +14,25 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'OpenNebula'
|
||||
|
||||
include OpenNebula
|
||||
require 'VirtualNetworkOCCI'
|
||||
|
||||
class VirtualNetworkPoolOCCI < VirtualNetworkPool
|
||||
OCCI_NETWORK_POOL = %q{
|
||||
<NETWORK_COLLECTION>
|
||||
<% self.each{ |vn| %>
|
||||
<% self.each{ |vn| %>
|
||||
<% if verbose %>
|
||||
<%= vn.to_occi(base_url) %>
|
||||
<% else %>
|
||||
<NETWORK href="<%= base_url %>/network/<%= vn.id.to_s %>" name="<%= vn.name %>"/>
|
||||
<% end %>
|
||||
<% } %>
|
||||
</NETWORK_COLLECTION>
|
||||
}
|
||||
|
||||
|
||||
# Creates the OCCI representation of a Virtual Machine Pool
|
||||
def to_occi(base_url)begin
|
||||
def to_occi(base_url, verbose=false)
|
||||
begin
|
||||
occi = ERB.new(OCCI_NETWORK_POOL)
|
||||
occi_text = occi.result(binding)
|
||||
rescue Exception => e
|
||||
@ -39,4 +42,8 @@ class VirtualNetworkPoolOCCI < VirtualNetworkPool
|
||||
|
||||
return occi_text.gsub(/\n\s*/,'')
|
||||
end
|
||||
|
||||
def factory(element_xml)
|
||||
VirtualNetworkOCCI.new(element_xml,@client)
|
||||
end
|
||||
end
|
@ -305,11 +305,31 @@ 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
|
||||
|
||||
##############################################
|
||||
## UI
|
||||
## OCCI UI (Self-Service)
|
||||
##############################################
|
||||
|
||||
post '/config' do
|
||||
get '/ui/config' do
|
||||
wss = settings.config[:vnc_proxy_support_wss]
|
||||
wss = (wss == true || wss == "yes" || wss == "only" ? "yes" : "no")
|
||||
|
||||
vnc = settings.config[:vnc_enable] ? "yes" : "no"
|
||||
|
||||
config = "<UI_CONFIGURARION>"
|
||||
config << " <LANG>#{session[:lang]}</LANG>"
|
||||
config << " <WSS>#{wss}</WSS>"
|
||||
config << " <VNC>#{vnc}</VNC>"
|
||||
config << "</UI_CONFIGURARION>"
|
||||
|
||||
return [200, config]
|
||||
end
|
||||
|
||||
post '/ui/config' do
|
||||
begin
|
||||
body = JSON.parse(request.body.read)
|
||||
rescue
|
||||
@ -321,6 +341,8 @@ post '/config' do
|
||||
when "lang" then session[:lang]=value
|
||||
end
|
||||
end
|
||||
|
||||
return 200
|
||||
end
|
||||
|
||||
get '/ui/login' do
|
||||
@ -349,9 +371,60 @@ get '/ui' do
|
||||
end
|
||||
|
||||
post '/ui/upload' do
|
||||
file = Tempfile.new('uploaded_image')
|
||||
FileUtils.cp(request.env['rack.input'].path,file.path)
|
||||
request.params['file'] = file.path #so we can re-use occi post_storage()
|
||||
#so we can re-use occi post_storage()
|
||||
request.params['file'] = {:tempfile => request.env['rack.input']}
|
||||
result,rc = @occi_server.post_storage(request)
|
||||
treat_response(result,rc)
|
||||
end
|
||||
|
||||
post '/ui/startvnc/:id' do
|
||||
if !settings.config[:vnc_enable]
|
||||
return [403, "VNC sessions are disabled"]
|
||||
end
|
||||
|
||||
vm_id = params[:id]
|
||||
vnc_hash = session['vnc']
|
||||
|
||||
if !vnc_hash
|
||||
session['vnc'] = {}
|
||||
elsif vnc_hash[vm_id]
|
||||
#return existing information
|
||||
info = vnc_hash[vm_id].clone
|
||||
info.delete(:pipe)
|
||||
|
||||
return [200, info.to_json]
|
||||
end
|
||||
|
||||
rc = @occi_server.startvnc(vm_id, settings.config)
|
||||
|
||||
if rc[0] == 200
|
||||
info = rc[1]
|
||||
session['vnc'][vm_id] = info.clone
|
||||
info.delete(:pipe)
|
||||
|
||||
rc = [200, info.to_json]
|
||||
end
|
||||
|
||||
return rc
|
||||
end
|
||||
|
||||
post '/ui/stopvnc/:id' do
|
||||
if !settings.config[:vnc_enable]
|
||||
return [403, "VNC sessions are disabled"]
|
||||
end
|
||||
|
||||
vm_id = params[:id]
|
||||
vnc_hash = session['vnc']
|
||||
|
||||
if !vnc_hash || !vnc_hash[vm_id]
|
||||
return [403, "It seems there is no VNC proxy running for this machine"]
|
||||
end
|
||||
|
||||
rc = @occi_server.stopvnc(vnc_hash[vm_id][:pipe])
|
||||
|
||||
if rc[0] == 200
|
||||
session['vnc'].delete(vm_id)
|
||||
end
|
||||
|
||||
return rc
|
||||
end
|
||||
|
@ -45,7 +45,7 @@ function setLang(lang_str){
|
||||
if (('localStorage' in window) && (window['localStorage'] !== null)){
|
||||
localStorage['lang']=lang_str;
|
||||
};
|
||||
$.post('config',JSON.stringify({lang:lang_str}),function(){window.location.href = "./ui"});
|
||||
$.post('ui/config',JSON.stringify({lang:lang_str}),function(){window.location.href = "./ui"});
|
||||
};
|
||||
|
||||
$(document).ready(function(){
|
||||
|
@ -342,6 +342,31 @@ var OCCI = {
|
||||
}
|
||||
},
|
||||
|
||||
"Config": {
|
||||
"resource": "CONFIG",
|
||||
|
||||
"list": function(params){
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
|
||||
var resource = OCCI.Config.resource;
|
||||
var request = OCCI.Helper.request(resource,"list");
|
||||
|
||||
$.ajax({
|
||||
url: "ui/config",
|
||||
type: "GET",
|
||||
dataType: "xml ONEjson",
|
||||
success: function(response){
|
||||
return callback ? callback(request, response) : null;
|
||||
},
|
||||
error: function(response){
|
||||
return callback_error ?
|
||||
callback_error(request, OCCI.Error(response)) : null;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
"Network": {
|
||||
"resource": "NETWORK",
|
||||
|
||||
@ -413,7 +438,7 @@ var OCCI = {
|
||||
params.data.body = '<DISK id="'+disk_id+'"><SAVE_AS name="'+im_name+'" /></DISK>';
|
||||
OCCI.Action.update(params,OCCI.VM.resource,"saveas");
|
||||
},
|
||||
/* "vnc" : function(params,startstop){
|
||||
"vnc" : function(params,startstop){
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
@ -423,7 +448,7 @@ var OCCI = {
|
||||
var action = OCCI.Helper.action(method);
|
||||
var request = OCCI.Helper.request(resource,method, id);
|
||||
$.ajax({
|
||||
url: "vm/" + id + "/" + method,
|
||||
url: "ui/" + method + "/" + id,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
success: function(response){
|
||||
@ -440,13 +465,16 @@ var OCCI = {
|
||||
},
|
||||
"stopvnc" : function(params){
|
||||
OCCI.VM.vnc(params,"stopvnc");
|
||||
|
||||
},
|
||||
/*
|
||||
"monitor" : function(params){
|
||||
OCCI.Action.monitor(params,OCCI.VM.resource,false);
|
||||
},
|
||||
"monitor_all" : function(params){
|
||||
OCCI.Action.monitor(params,OCCI.VM.resource,true);
|
||||
}*/
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
"Image": {
|
||||
|
@ -15,16 +15,19 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/*Virtual Machines tab plugin*/
|
||||
//var INCLUDE_URI = "vendor/noVNC/include/";
|
||||
var INCLUDE_URI = "vendor/noVNC/include/";
|
||||
//var VM_HISTORY_LENGTH = 40;
|
||||
|
||||
/*
|
||||
|
||||
function loadVNC(){
|
||||
var script = '<script src="vendor/noVNC/include/vnc.js"></script>';
|
||||
document.write(script);
|
||||
}
|
||||
loadVNC();
|
||||
var vnc_enable=false;
|
||||
var use_wss=false;
|
||||
|
||||
/*
|
||||
var vm_graphs = [
|
||||
{ title : tr("CPU"),
|
||||
monitor_resources : "cpu_usage",
|
||||
@ -264,7 +267,6 @@ var vm_actions = {
|
||||
error: onError
|
||||
},
|
||||
|
||||
/*
|
||||
"VM.startvnc" : {
|
||||
type: "single",
|
||||
call: OCCI.VM.startvnc,
|
||||
@ -280,6 +282,7 @@ var vm_actions = {
|
||||
notify: true
|
||||
},
|
||||
|
||||
/*
|
||||
"VM.monitor" : {
|
||||
type: "monitor",
|
||||
call : OCCI.VM.monitor,
|
||||
@ -540,6 +543,10 @@ function updateVMInfo(request,vm){
|
||||
<td class="key_td">'+tr("Memory")+'</td>\
|
||||
<td class="value_td">'+vm_info.MEMORY+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Launch VNC session")+'</td>\
|
||||
<td class="value_td">'+vncIcon(vm_info)+'</td>\
|
||||
</tr>\
|
||||
</tbody>\
|
||||
</table>\
|
||||
<div class="form_buttons">\
|
||||
@ -940,7 +947,7 @@ function setVMAutorefresh(){
|
||||
},INTERVAL+someTime());
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
function updateVNCState(rfb, state, oldstate, msg) {
|
||||
var s, sb, cad, klass;
|
||||
s = $D('VNC_status');
|
||||
@ -1016,7 +1023,7 @@ function setupVNC(){
|
||||
Sunstone.runAction("VM.stopvnc",id);
|
||||
});
|
||||
|
||||
$('.vnc',main_tabs_context).live("click",function(){
|
||||
$('.vnc').live("click",function(){
|
||||
//Which VM is it?
|
||||
var id = $(this).attr('vm_id');
|
||||
//Set attribute to dialog
|
||||
@ -1029,7 +1036,7 @@ function setupVNC(){
|
||||
|
||||
function vncCallback(request,response){
|
||||
rfb = new RFB({'target': $D('VNC_canvas'),
|
||||
'encrypt': false,
|
||||
'encrypt': use_wss,
|
||||
'true_color': true,
|
||||
'local_cursor': true,
|
||||
'shared': true,
|
||||
@ -1049,6 +1056,20 @@ function vncCallback(request,response){
|
||||
|
||||
}
|
||||
|
||||
function vncIcon(vm){
|
||||
var gr_icon;
|
||||
if (vnc_enable){
|
||||
gr_icon = '<a class="vnc" href="#" vm_id="'+vm.ID+'">';
|
||||
gr_icon += '<img src="images/vnc_on.png" alt=\"'+tr("Open VNC Session")+'\" /></a>';
|
||||
}
|
||||
else {
|
||||
gr_icon = '<img src="images/vnc_off.png" alt=\"'+tr("VNC Disabled")+'\" />';
|
||||
}
|
||||
return gr_icon;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
function vncIcon(vm){
|
||||
var graphics = vm.TEMPLATE.GRAPHICS;
|
||||
var state = vm.STATE;
|
||||
@ -1063,6 +1084,9 @@ function vncIcon(vm){
|
||||
return gr_icon;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
function vmMonitorError(req,error_json){
|
||||
var message = error_json.error.message;
|
||||
var info = req.request.data[0].monitor;
|
||||
@ -1070,9 +1094,9 @@ function vmMonitorError(req,error_json){
|
||||
var id_suffix = labels.replace(/,/g,'_');
|
||||
var id = '#vm_monitor_'+id_suffix;
|
||||
$('#vm_monitoring_tab '+id).html('<div style="padding-left:20px;">'+message+'</div>');
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// At this point the DOM is ready and the sunstone.js ready() has been run.
|
||||
$(document).ready(function(){
|
||||
@ -1102,7 +1126,7 @@ $(document).ready(function(){
|
||||
//setupCreateVMDialog();
|
||||
setupSaveasDialog();
|
||||
setVMAutorefresh();
|
||||
//setupVNC();
|
||||
setupVNC();
|
||||
|
||||
initCheckAllBoxes(dataTable_vMachines);
|
||||
tableCheckboxesListener(dataTable_vMachines);
|
||||
|
@ -41,24 +41,46 @@ var config_tab_content =
|
||||
</tr>\
|
||||
</table></form>';
|
||||
|
||||
var config_actions = {
|
||||
"Config.list" : {
|
||||
type : 'list',
|
||||
call : OCCI.Config.list,
|
||||
callback : updateConfig,
|
||||
error : onError
|
||||
},
|
||||
};
|
||||
|
||||
var config_tab = {
|
||||
title: tr("Configuration"),
|
||||
content: config_tab_content
|
||||
}
|
||||
|
||||
Sunstone.addActions(config_actions);
|
||||
Sunstone.addMainTab('config_tab',config_tab);
|
||||
|
||||
function updateConfig(request, response){
|
||||
var config = response;
|
||||
//These two variables defined in compute.js
|
||||
vnc_enable = config['VNC'] == 'true' || config['VNC'] == 'yes' ? true : false;
|
||||
use_wss = config['WSS'] == 'true' || config['WSS'] == 'yes'? true : false;
|
||||
};
|
||||
|
||||
$(document).ready(function(){
|
||||
if (lang)
|
||||
$('table#config_table #lang_sel option[value="'+lang+'"]').attr('selected','selected');
|
||||
$('table#config_table #lang_sel').change(function(){
|
||||
setLang($(this).val());
|
||||
});
|
||||
Sunstone.runAction('Config.list');
|
||||
|
||||
$('#li_config_tab').click(function(){
|
||||
hideDialog();
|
||||
});
|
||||
|
||||
$('div#logo img').attr('src',logo_small);
|
||||
//Set lang to the right value
|
||||
if (lang)
|
||||
$('table#config_table #lang_sel option[value="'+lang+'"]').attr('selected','selected');
|
||||
|
||||
//Listen to changes in language
|
||||
$('table#config_table #lang_sel').change(function(){
|
||||
setLang($(this).val());
|
||||
});
|
||||
|
||||
//Vendor customization, change small logo
|
||||
$('div#logo img').attr('src',logo_small);
|
||||
});
|
@ -478,7 +478,7 @@ function popUpCreateImageDialog(){
|
||||
multiple: false,
|
||||
params: {},
|
||||
showMessage: function(message){
|
||||
notifyMessage(message);
|
||||
//notifyMessage(message);
|
||||
},
|
||||
onSubmit: function(id, fileName){
|
||||
var xml = json2xml(img_obj,"STORAGE");
|
||||
|
@ -75,7 +75,7 @@
|
||||
</div>
|
||||
|
||||
<div id="footer" class="ui-layout-south">
|
||||
Copyright 2002-2012 © OpenNebula Project Leads (<a href="http://opennebula.org" target="_blank">OpenNebula.org</a>). All Rights Reserved. OpenNebula 3.2.0
|
||||
Copyright 2002-2012 © OpenNebula Project Leads (<a href="http://opennebula.org" target="_blank">OpenNebula.org</a>). All Rights Reserved. OpenNebula 3.3.0
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -86,7 +86,7 @@ EOF
|
||||
#-------------------------------------------------------------------------------
|
||||
function fs_du {
|
||||
if [ -d "$1" ]; then
|
||||
SIZE=`du -s "$1" | cut -f1`
|
||||
SIZE=`du -sb "$1" | cut -f1`
|
||||
error=$?
|
||||
else
|
||||
SIZE=`stat -c %s "$1"`
|
||||
|
@ -330,7 +330,7 @@ void LifeCycleManager::deploy_failure_action(int vid)
|
||||
|
||||
vmpool->update_history(vm);
|
||||
|
||||
vm->log("LCM", Log::INFO, "Fail to life migrate VM."
|
||||
vm->log("LCM", Log::INFO, "Fail to live migrate VM."
|
||||
" Assuming that the VM is still RUNNING (will poll VM).");
|
||||
|
||||
//----------------------------------------------------
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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()
|
||||
{
|
||||
|
28
src/onedb/3.2.1_to_3.3.0.rb
Normal file
28
src/onedb/3.2.1_to_3.3.0.rb
Normal file
@ -0,0 +1,28 @@
|
||||
# -------------------------------------------------------------------------- *
|
||||
# Copyright 2002-2011, 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. *
|
||||
# -------------------------------------------------------------------------- *
|
||||
|
||||
module Migrator
|
||||
def db_version
|
||||
"3.3.0"
|
||||
end
|
||||
|
||||
def one_version
|
||||
"OpenNebula 3.3.0"
|
||||
end
|
||||
|
||||
def up
|
||||
return true
|
||||
end
|
||||
end
|
@ -60,7 +60,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" class="ui-layout-south">
|
||||
Copyright 2002-2012 © OpenNebula Project Leads (<a href="http://opennebula.org" target="_blank">OpenNebula.org</a>). All Rights Reserved. OpenNebula 3.2.0
|
||||
Copyright 2002-2012 © OpenNebula Project Leads (<a href="http://opennebula.org" target="_blank">OpenNebula.org</a>). All Rights Reserved. OpenNebula 3.3.0
|
||||
</div>
|
||||
|
||||
|
||||
|
103
src/sunstone/OpenNebulaVNC.rb
Normal file
103
src/sunstone/OpenNebulaVNC.rb
Normal file
@ -0,0 +1,103 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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 'json'
|
||||
require 'OpenNebula'
|
||||
|
||||
#
|
||||
# This class provides support for launching and stopping a websockify proxy
|
||||
#
|
||||
class OpenNebulaVNC
|
||||
def initialize(config, opt={:json_errors => true})
|
||||
@proxy_path = config[:vnc_proxy_path]
|
||||
@proxy_base_port = config[:vnc_proxy_base_port].to_i
|
||||
|
||||
@wss = config[:vnc_proxy_support_wss]
|
||||
|
||||
if (@wss == "yes") || (@wss == "only") || (@wss == true)
|
||||
@enable_wss = true
|
||||
@cert = config[:vnc_proxy_cert]
|
||||
@key = config[:vnc_proxy_key]
|
||||
else
|
||||
@enable_wss = false
|
||||
end
|
||||
|
||||
@options = opt
|
||||
end
|
||||
|
||||
# Start a VNC proxy
|
||||
def start(vm_resource)
|
||||
# Check configurations and VM attributes
|
||||
|
||||
if @proxy_path == nil || @proxy_path.empty?
|
||||
return error(403,"VNC proxy not configured")
|
||||
end
|
||||
|
||||
if vm_resource['LCM_STATE'] != "3"
|
||||
return error(403,"VM is not running")
|
||||
end
|
||||
|
||||
if vm_resource['TEMPLATE/GRAPHICS/TYPE'] != "vnc"
|
||||
return error(403,"VM has no VNC configured")
|
||||
end
|
||||
|
||||
# Proxy data
|
||||
host = vm_resource['/VM/HISTORY_RECORDS/HISTORY[last()]/HOSTNAME']
|
||||
vnc_port = vm_resource['TEMPLATE/GRAPHICS/PORT']
|
||||
|
||||
proxy_port = @proxy_base_port + vnc_port.to_i
|
||||
|
||||
proxy_options = ""
|
||||
|
||||
if @enable_wss
|
||||
proxy_options << " --cert #{@cert}"
|
||||
proxy_options << " --key #{@key}" if @key && @key.size > 0
|
||||
proxy_options << " --ssl-only" if @wss == "only"
|
||||
end
|
||||
|
||||
cmd ="#{@proxy_path} #{proxy_options} #{proxy_port} #{host}:#{vnc_port}"
|
||||
|
||||
begin
|
||||
$stderr.puts("Starting vnc proxy: #{cmd}")
|
||||
pipe = IO.popen(cmd)
|
||||
rescue Exception => e
|
||||
return [500, OpenNebula::Error.new(e.message).to_json]
|
||||
end
|
||||
|
||||
vnc_pw = vm_resource['TEMPLATE/GRAPHICS/PASSWD']
|
||||
info = {:pipe => pipe, :port => proxy_port, :password => vnc_pw}
|
||||
|
||||
return [200, info]
|
||||
end
|
||||
|
||||
# Stop a VNC proxy handle exceptions outside
|
||||
def self.stop(pipe)
|
||||
Process.kill('KILL',pipe.pid)
|
||||
pipe.close
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def error(code, msg)
|
||||
if @options[:json_errors]
|
||||
return [code,OpenNebula::Error.new(msg).to_json]
|
||||
else
|
||||
return [code,msg]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
@ -16,8 +16,20 @@
|
||||
:core_auth: cipher
|
||||
|
||||
# VNC Configuration
|
||||
# base_port: base_port + vnc_port of the VM is the port where the
|
||||
# proxy will listen for VNC session connections to that VM.
|
||||
# vnc_proxy_path: path to the websockets proxy (set by install_novnc.sh)
|
||||
# support_wss: no | yes | only. For yes and only, provide path to
|
||||
# cert and key. "yes" means both ws and wss connections will be
|
||||
# supported.
|
||||
# vnc_proxy_cert: Certificate to encrypt wss connections.
|
||||
# vnc_proxy_key: Key for wss connections. Only necessary if not included in cert.
|
||||
:vnc_proxy_base_port: 29876
|
||||
:novnc_path:
|
||||
:vnc_proxy_path:
|
||||
:vnc_proxy_support_wss: no
|
||||
:vnc_proxy_cert:
|
||||
:vnc_proxy_key:
|
||||
|
||||
|
||||
# Default language setting
|
||||
:lang: en_US
|
||||
|
@ -18,11 +18,17 @@ require 'OpenNebulaJSON'
|
||||
include OpenNebulaJSON
|
||||
|
||||
require 'acct/watch_client'
|
||||
require 'OpenNebulaVNC'
|
||||
require 'OpenNebulaJSON/JSONUtils'
|
||||
include JSONUtils
|
||||
|
||||
class SunstoneServer
|
||||
# FLAG that will filter the elements retrieved from the Pools
|
||||
POOL_FILTER = Pool::INFO_ALL
|
||||
|
||||
# Secs to sleep between checks to see if image upload to repo is finished
|
||||
IMAGE_POLL_SLEEP_TIME = 5
|
||||
|
||||
def initialize(client)
|
||||
@client = client
|
||||
end
|
||||
@ -112,6 +118,31 @@ class SunstoneServer
|
||||
end
|
||||
end
|
||||
|
||||
############################################################################
|
||||
#
|
||||
############################################################################
|
||||
def upload(template, file_path)
|
||||
image_hash = parse_json(template, 'image')
|
||||
image_hash['PATH'] = file_path
|
||||
|
||||
new_template = {:image => image_hash}.to_json
|
||||
image = ImageJSON.new(Image.build_xml, @client)
|
||||
|
||||
rc = image.create(new_template)
|
||||
|
||||
if OpenNebula.is_error?(rc)
|
||||
return [500, rc.to_json]
|
||||
end
|
||||
|
||||
image.info
|
||||
#wait until image is ready to return
|
||||
while (image.state_str == 'LOCKED') && (image['RUNNING_VMS'] == '0') do
|
||||
sleep IMAGE_POLL_SLEEP_TIME
|
||||
image.info
|
||||
end
|
||||
return [201, image.to_json]
|
||||
end
|
||||
|
||||
############################################################################
|
||||
#
|
||||
############################################################################
|
||||
@ -146,37 +177,6 @@ class SunstoneServer
|
||||
end
|
||||
end
|
||||
|
||||
############################################################################
|
||||
#
|
||||
############################################################################
|
||||
def get_configuration(user_id)
|
||||
if user_id != "0"
|
||||
return [401, ""]
|
||||
end
|
||||
|
||||
one_config = VAR_LOCATION + "/config"
|
||||
config = Hash.new
|
||||
|
||||
begin
|
||||
cfg = File.read(one_config)
|
||||
rescue Exception => e
|
||||
error = Error.new("Error reading config: #{e.inspect}")
|
||||
return [500, error.to_json]
|
||||
end
|
||||
|
||||
cfg.lines do |line|
|
||||
m=line.match(/^([^=]+)=(.*)$/)
|
||||
|
||||
if m
|
||||
name=m[1].strip.upcase
|
||||
value=m[2].strip
|
||||
config[name]=value
|
||||
end
|
||||
end
|
||||
|
||||
return [200, config.to_json]
|
||||
end
|
||||
|
||||
############################################################################
|
||||
#
|
||||
############################################################################
|
||||
@ -201,7 +201,6 @@ class SunstoneServer
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
########################################################################
|
||||
# VNC
|
||||
########################################################################
|
||||
@ -211,50 +210,16 @@ class SunstoneServer
|
||||
return [404, resource.to_json]
|
||||
end
|
||||
|
||||
if resource['LCM_STATE'] != "3"
|
||||
error = OpenNebula::Error.new("VM is not running")
|
||||
return [403, error.to_json]
|
||||
end
|
||||
|
||||
if resource['TEMPLATE/GRAPHICS/TYPE'] != "vnc"
|
||||
error = OpenNebula::Error.new("VM has no VNC configured")
|
||||
return [403, error.to_json]
|
||||
end
|
||||
|
||||
# The VM host and its VNC port
|
||||
host = resource['/VM/HISTORY_RECORDS/HISTORY[last()]/HOSTNAME']
|
||||
vnc_port = resource['TEMPLATE/GRAPHICS/PORT']
|
||||
# The noVNC proxy_port
|
||||
proxy_port = config[:vnc_proxy_base_port].to_i + vnc_port.to_i
|
||||
|
||||
begin
|
||||
novnc_cmd = "#{config[:novnc_path]}/utils/wsproxy.py"
|
||||
novnc_exec = "#{novnc_cmd} #{proxy_port} #{host}:#{vnc_port}"
|
||||
$stderr.puts("Starting vnc proxy: #{novnc_exec}")
|
||||
pipe = IO.popen(novnc_exec)
|
||||
rescue Exception => e
|
||||
error = Error.new(e.message)
|
||||
return [500, error.to_json]
|
||||
end
|
||||
|
||||
vnc_pw = resource['TEMPLATE/GRAPHICS/PASSWD']
|
||||
|
||||
info = {:pipe => pipe, :port => proxy_port, :password => vnc_pw}
|
||||
return [200, info]
|
||||
vnc_proxy = OpenNebulaVNC.new(config)
|
||||
return vnc_proxy.start(resource)
|
||||
end
|
||||
|
||||
############################################################################
|
||||
#
|
||||
############################################################################
|
||||
def stopvnc(id,pipe)
|
||||
resource = retrieve_resource("vm", id)
|
||||
if OpenNebula.is_error?(resource)
|
||||
return [404, resource.to_json]
|
||||
end
|
||||
|
||||
def stopvnc(pipe)
|
||||
begin
|
||||
Process.kill('KILL',pipe.pid)
|
||||
pipe.close
|
||||
OpenNebulaVNC.stop(pipe)
|
||||
rescue Exception => e
|
||||
error = Error.new(e.message)
|
||||
return [500, error.to_json]
|
||||
@ -266,8 +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
|
||||
@ -278,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?
|
||||
@ -295,18 +262,11 @@ class SunstoneServer
|
||||
return [200, rc.to_json]
|
||||
end
|
||||
|
||||
############################################################################
|
||||
#
|
||||
############################################################################
|
||||
|
||||
############################################################################
|
||||
#
|
||||
############################################################################
|
||||
|
||||
|
||||
|
||||
private
|
||||
|
||||
############################################################################
|
||||
#
|
||||
############################################################################
|
||||
def retrieve_resource(kind, id)
|
||||
resource = case kind
|
||||
when "group" then GroupJSON.new_with_id(id, @client)
|
||||
|
@ -33,6 +33,12 @@ var config_tab_content =
|
||||
</select>\
|
||||
</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">' + tr("Secure websockets connection") + '</td>\
|
||||
<td class="value_td">\
|
||||
<input id="wss_checkbox" type="checkbox" value="yes" />\
|
||||
</td>\
|
||||
</tr>\
|
||||
</table>\
|
||||
\
|
||||
</div>\
|
||||
@ -41,18 +47,74 @@ var config_tab_content =
|
||||
</tr>\
|
||||
</table></form>';
|
||||
|
||||
var config_actions = {
|
||||
"Config.list" : {
|
||||
type: "list",
|
||||
call: OpenNebula.Config.list,
|
||||
callback: updateConfig,
|
||||
error: onError
|
||||
},
|
||||
};
|
||||
|
||||
var config_tab = {
|
||||
title: tr("Configuration"),
|
||||
content: config_tab_content
|
||||
}
|
||||
|
||||
Sunstone.addActions(config_actions);
|
||||
Sunstone.addMainTab('config_tab',config_tab);
|
||||
|
||||
|
||||
function updateConfig(request,response){
|
||||
var config = response['user_config'];
|
||||
|
||||
//Set wss checkbox to correct value
|
||||
if (config["wss"] == "yes"){
|
||||
$('table#config_table input#wss_checkbox').attr('checked','checked');
|
||||
};
|
||||
};
|
||||
|
||||
function updateWss(){
|
||||
var user_info_req = {
|
||||
data : {
|
||||
id: uid,
|
||||
},
|
||||
success: function(req,user_json) {
|
||||
var template = user_json.USER.TEMPLATE;
|
||||
var template_str="";
|
||||
template['VNC_WSS']=
|
||||
$('#config_table #wss_checkbox').is(':checked') ? "yes" : "no";
|
||||
//convert json to ONE template format - simple conversion
|
||||
$.each(template,function(key,value){
|
||||
template_str += (key + '=' + '"' + value + '"\n');
|
||||
});
|
||||
|
||||
var request = {
|
||||
data: {
|
||||
id: uid,
|
||||
extra_param: template_str
|
||||
},
|
||||
error: onError
|
||||
};
|
||||
OpenNebula.User.update(request);
|
||||
},
|
||||
};
|
||||
OpenNebula.User.show(user_info_req);
|
||||
$.post('config',JSON.stringify({wss : ($('#config_table #wss_checkbox').is(':checked') ? "yes" : "no")}));
|
||||
};
|
||||
|
||||
$(document).ready(function(){
|
||||
Sunstone.runAction('Config.list');
|
||||
|
||||
//Set the language select to correct value
|
||||
if (lang)
|
||||
$('table#config_table #lang_sel option[value="'+lang+'"]').attr('selected','selected');
|
||||
|
||||
//Listener to change language
|
||||
$('table#config_table #lang_sel').change(function(){
|
||||
setLang($(this).val());
|
||||
});
|
||||
|
||||
//Listener to wss change
|
||||
$('table#config_table #wss_checkbox').change(updateWss);
|
||||
});
|
@ -85,11 +85,12 @@ var create_host_tmpl =
|
||||
<div class="manager clear" id="vnm_mads">\
|
||||
<label>Virtual Network Manager:</label>\
|
||||
<select id="vnm_mad" name="vn">\
|
||||
<option value="dummy">Default (dummy)</option>\
|
||||
<option value="dummy">' + tr("Default (dummy)") +'</option>\
|
||||
<option value="fw">Firewall</option>\
|
||||
<option value="802.1Q">802.1Q</option>\
|
||||
<option value="ebtables">Ebtables</option>\
|
||||
<option value="ovswitch">Open vSwitch</option>\
|
||||
<option value="vmware">VMware</option>\
|
||||
</select>\
|
||||
</div>\
|
||||
<div class="manager clear" id="tm_mads">\
|
||||
|
@ -100,14 +100,21 @@ var create_image_tmpl =
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
<div class="" id="src_path_select">\
|
||||
<label style="height:3em;">'+tr("Path vs. source")+':</label>\
|
||||
<label style="height:4em;">'+tr("Image location")+':</label>\
|
||||
\
|
||||
<input type="radio" name="src_path" id="path_img" value="path" />\
|
||||
<label style="float:none">'+tr("Provide a path")+'</label><br />\
|
||||
\
|
||||
<input type="radio" name="src_path" id="source_img" value="source" />\
|
||||
<label style="float:none">'+tr("Provide a source")+'</label><br />\
|
||||
\
|
||||
<input type="radio" name="src_path" id="upload_img" value="upload" />\
|
||||
<label style="float:none">'+tr("Upload")+'</label><br />\
|
||||
\
|
||||
<input type="radio" name="src_path" id="datablock_img" value="datablock" />\
|
||||
<label style="float:none;vertical-align:top">'+tr("Create an empty datablock")+'</label>\
|
||||
<div class="tip">'+tr("Please choose path if you have a file-based image. Choose source otherwise or create an empty datablock disk.")+'</div><br />\
|
||||
\
|
||||
</div>\
|
||||
<div class="img_param">\
|
||||
<label for="img_path">'+tr("Path")+':</label>\
|
||||
@ -129,6 +136,11 @@ var create_image_tmpl =
|
||||
<input type="text" name="img_fstype" id="img_fstype" />\
|
||||
<div class="tip">'+tr("Type of file system to be built. This can be any value understood by mkfs unix command.")+'</div>\
|
||||
</div>\
|
||||
<div class="img_param" id="upload_div">\
|
||||
<label for="file-uploader" >'+tr("Upload file")+':</label>\
|
||||
<div id="file-uploader">\
|
||||
</div><div class="clear" />\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
<div class="">\
|
||||
@ -666,6 +678,7 @@ function updateImageInfo(request,img){
|
||||
function setupCreateImageDialog(){
|
||||
dialogs_context.append('<div title="'+tr("Create Image")+'" id="create_image_dialog"></div>');
|
||||
$create_image_dialog = $('#create_image_dialog',dialogs_context);
|
||||
|
||||
var dialog = $create_image_dialog;
|
||||
dialog.html(create_image_tmpl);
|
||||
|
||||
@ -694,12 +707,12 @@ function setupCreateImageDialog(){
|
||||
default:
|
||||
$('#datablock_img',context).attr('disabled','disabled');
|
||||
$('#path_img',context).attr('checked','checked');
|
||||
$('#img_source,#img_fstype,#img_size',context).parent().hide();
|
||||
$('#img_source,#img_fstype,#img_size,#file-uploader',context).parent().hide();
|
||||
$('#img_path',context).parent().show();
|
||||
}
|
||||
});
|
||||
|
||||
$('#img_source,#img_fstype,#img_size',dialog).parent().hide();
|
||||
$('#img_source,#img_fstype,#img_size,#file-uploader',dialog).parent().hide();
|
||||
$('#path_img',dialog).attr('checked','checked');
|
||||
$('#img_path',dialog).parent().addClass("img_man");
|
||||
|
||||
@ -708,24 +721,30 @@ function setupCreateImageDialog(){
|
||||
var value = $(this).val();
|
||||
switch (value){
|
||||
case "path":
|
||||
$('#img_source,#img_fstype,#img_size',context).parent().hide();
|
||||
$('#img_source,#img_fstype,#img_size',context).parent().removeClass("img_man");
|
||||
$('#img_source,#img_fstype,#img_size,#file-uploader',context).parent().hide();
|
||||
$('#img_source,#img_fstype,#img_size,#file-uploader',context).parent().removeClass("img_man");
|
||||
$('#img_path',context).parent().show();
|
||||
$('#img_path',context).parent().addClass("img_man");
|
||||
break;
|
||||
case "source":
|
||||
$('#img_path,#img_fstype,#img_size',context).parent().hide();
|
||||
$('#img_path,#img_fstype,#img_size',context).parent().removeClass("img_man");
|
||||
$('#img_path,#img_fstype,#img_size,#file-uploader',context).parent().hide();
|
||||
$('#img_path,#img_fstype,#img_size,#file-uploader',context).parent().removeClass("img_man");
|
||||
$('#img_source',context).parent().show();
|
||||
$('#img_source',context).parent().addClass("img_man");
|
||||
break;
|
||||
case "datablock":
|
||||
$('#img_source,#img_path',context).parent().hide();
|
||||
$('#img_source,#img_path',context).parent().removeClass("img_man");
|
||||
$('#img_source,#img_path,#file-uploader',context).parent().hide();
|
||||
$('#img_source,#img_path,#file-uploader',context).parent().removeClass("img_man");
|
||||
$('#img_fstype,#img_size',context).parent().show();
|
||||
$('#img_fstype,#img_size',context).parent().addClass("img_man");
|
||||
break;
|
||||
}
|
||||
case "upload":
|
||||
$('#img_path,#img_source,#img_fstype,#img_size',context).parent().hide();
|
||||
$('#img_path,#img_source,#img_fstype,#img_size',context).parent().removeClass("img_man");
|
||||
$('#file-uploader',context).parent().show();
|
||||
$('#file-uploader',context).parent().addClass("img_man");
|
||||
break;
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@ -752,9 +771,70 @@ function setupCreateImageDialog(){
|
||||
}
|
||||
);
|
||||
|
||||
$('#upload-progress',dialog).css({
|
||||
border: "1px solid #AAAAAA",
|
||||
position: "relative",
|
||||
// bottom: "29px",
|
||||
width: "258px",
|
||||
// left: "133px",
|
||||
height: "15px",
|
||||
display: "inline-block",
|
||||
});
|
||||
$('#upload-progress div',dialog).css("border","1px solid #AAAAAA");
|
||||
|
||||
var img_obj;
|
||||
|
||||
var uploader = new qq.FileUploaderBasic({
|
||||
button: $('#file-uploader',$create_image_dialog)[0],
|
||||
action: 'upload',
|
||||
multiple: false,
|
||||
params: {},
|
||||
showMessage: function(message){
|
||||
//notifyMessage(message);
|
||||
},
|
||||
onSubmit: function(id, fileName){
|
||||
uploader.setParams({
|
||||
img : JSON.stringify(img_obj),
|
||||
file: fileName
|
||||
});
|
||||
var pos_top = $(window).height() - 120;
|
||||
var pos_left = 140;
|
||||
var pb_dialog = $('<div id="pb_dialog" title="'+
|
||||
tr("Uploading...")+'">'+
|
||||
'<div id="upload-progress"></div>'+
|
||||
'</div>').dialog({
|
||||
draggable:true,
|
||||
modal:false,
|
||||
resizable:false,
|
||||
buttons:{},
|
||||
width: 460,
|
||||
minHeight: 50,
|
||||
position: [pos_left, pos_top]
|
||||
});
|
||||
|
||||
$('#upload-progress',pb_dialog).progressbar({value:0});
|
||||
},
|
||||
onProgress: function(id, fileName, loaded, total){
|
||||
$('div#pb_dialog #upload-progress').progressbar("option","value",Math.floor(loaded*100/total));
|
||||
},
|
||||
onComplete: function(id, fileName, responseJSON){
|
||||
notifyMessage("Image uploaded correctly");
|
||||
$('div#pb_dialog').dialog('destroy');
|
||||
Sunstone.runAction("Image.list");
|
||||
return false;
|
||||
},
|
||||
onCancel: function(id, fileName){
|
||||
},
|
||||
});
|
||||
|
||||
var file_input = false;
|
||||
uploader._button._options.onChange = function(input) {
|
||||
file_input = input; return false;
|
||||
};
|
||||
|
||||
$('#create_image_form_easy',dialog).submit(function(){
|
||||
var exit = false;
|
||||
var upload = false;
|
||||
$('.img_man',this).each(function(){
|
||||
if (!$('input',this).val().length){
|
||||
notifyError(tr("There are mandatory parameters missing"));
|
||||
@ -805,6 +885,9 @@ function setupCreateImageDialog(){
|
||||
img_json["SIZE"] = size;
|
||||
img_json["FSTYPE"] = fstype;
|
||||
break;
|
||||
case "upload":
|
||||
upload=true;
|
||||
break;
|
||||
}
|
||||
|
||||
//Time to add custom attributes
|
||||
@ -815,8 +898,13 @@ function setupCreateImageDialog(){
|
||||
});
|
||||
|
||||
|
||||
var obj = { "image" : img_json };
|
||||
Sunstone.runAction("Image.create", obj);
|
||||
img_obj = { "image" : img_json };
|
||||
|
||||
if (upload){
|
||||
uploader._onInputChange(file_input);
|
||||
} else {
|
||||
Sunstone.runAction("Image.create", img_obj);
|
||||
};
|
||||
|
||||
$create_image_dialog.dialog('close');
|
||||
return false;
|
||||
@ -831,6 +919,9 @@ function setupCreateImageDialog(){
|
||||
}
|
||||
|
||||
function popUpCreateImageDialog(){
|
||||
$('#file-uploader input',$create_image_dialog).removeAttr("style");
|
||||
$('#file-uploader input',$create_image_dialog).attr('style','margin:0;width:256px!important');
|
||||
|
||||
$create_image_dialog.dialog('open');
|
||||
}
|
||||
|
||||
|
@ -1227,7 +1227,7 @@ function setupVNC(){
|
||||
|
||||
function vncCallback(request,response){
|
||||
rfb = new RFB({'target': $D('VNC_canvas'),
|
||||
'encrypt': false,
|
||||
'encrypt': $('#config_table #wss_checkbox').is(':checked'),
|
||||
'true_color': true,
|
||||
'local_cursor': true,
|
||||
'shared': true,
|
||||
|
@ -51,8 +51,25 @@ var create_vn_tmpl =
|
||||
<input type="text" name="name" id="name" /><br />\
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
<label for="network_mode">'+tr("Network mode")+':</label>\
|
||||
<select name="network_mode" id="network_mode">\
|
||||
<option value="default">'+tr("Default")+'</option>\
|
||||
<option value="802.1Q">'+tr("802.1Q")+'</option>\
|
||||
<option value="etables">'+tr("Etables")+'</option>\
|
||||
<option value="openvswitch">'+tr("Open vSwitch")+'</option>\
|
||||
<option value="vmware">'+tr("VMware")+'</option>\
|
||||
</select><br />\
|
||||
<label for="bridge">'+tr("Bridge")+':</label>\
|
||||
<input type="text" name="bridge" id="bridge" /><br />\
|
||||
<label for="phydev">'+tr("Physical device")+':</label>\
|
||||
<input type="text" name="phydev" id="phydev" />\
|
||||
<label for="vlan">'+tr("VLAN")+':</label>\
|
||||
<select name="vlan" id="vlan">\
|
||||
<option value="YES">'+tr("Yes")+'</option>\
|
||||
<option value="NO">'+tr("No")+'</option>\
|
||||
</select><br />\
|
||||
<label for="vlan_id">'+tr("VLAN ID")+':</label>\
|
||||
<input type="text" name="vlan_id" id="vlan_id" /><br />\
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
<label style="height:2em;">'+tr("Network type")+':</label>\
|
||||
@ -530,12 +547,20 @@ function updateVNetworkInfo(request,vn){
|
||||
<td class="key_td">'+tr("Group")+'</td>\
|
||||
<td class="value_td">'+vn_info.GNAME+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Bridge")+'</td>\
|
||||
<td class="value_td">'+ (typeof(vn_info.BRIDGE) == "object" ? "--": vn_info.BRIDGE) +'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("VLAN")+'</td>\
|
||||
<td class="value_td">'+ (vn_info.VLAN == "0" ? "no" : "yes") +'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Physical device")+'</td>\
|
||||
<td class="value_td">'+ (typeof(vn_info.PHYDEV) == "object" ? "--": vn_info.PHYDEV) +'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("VNET ID")+'</td>\
|
||||
<td class="key_td">'+tr("VLAN ID")+'</td>\
|
||||
<td class="value_td">'+ (typeof(vn_info.VLAN_ID) == "object" ? "--": vn_info.VLAN_ID) +'</td>\
|
||||
</tr>\
|
||||
<tr><td class="key_td">Permissions</td><td></td></tr>\
|
||||
@ -704,6 +729,36 @@ function setupCreateVNetDialog() {
|
||||
$('div#fixed',$create_vn_dialog).hide();
|
||||
$('div#ranged',$create_vn_dialog).show();
|
||||
});
|
||||
|
||||
$('#network_mode',dialog).change(function(){
|
||||
$('input,select#vlan,label[for!="network_mode"]', $(this).parent()).hide();
|
||||
$('input', $(this).parent()).val("");
|
||||
switch ($(this).val()) {
|
||||
case "default":
|
||||
$('input#bridge,label[for="bridge"]',$create_vn_dialog).show();
|
||||
$('input#phydev,label[for="phydev"]',$create_vn_dialog).show();
|
||||
break;
|
||||
case "802.1Q":
|
||||
$('input#bridge,label[for="bridge"]',$create_vn_dialog).show();
|
||||
$('input#phydev,label[for="phydev"]',$create_vn_dialog).show();
|
||||
$('select#vlan,label[for="vlan"]',$create_vn_dialog).show();
|
||||
$('input#vlan_id,label[for="vlan_id"]',$create_vn_dialog).show();
|
||||
break;
|
||||
case "etables":
|
||||
$('input#bridge,label[for="bridge"]',$create_vn_dialog).show();
|
||||
break;
|
||||
case "openvswitch":
|
||||
case "vmware":
|
||||
$('input#bridge,label[for="bridge"]',$create_vn_dialog).show();
|
||||
$('select#vlan,label[for="vlan"]',$create_vn_dialog).show();
|
||||
$('input#vlan_id,label[for="vlan_id"]',$create_vn_dialog).show();
|
||||
break;
|
||||
};
|
||||
});
|
||||
|
||||
//Initialize shown options
|
||||
$('#network_mode',dialog).trigger("change");
|
||||
|
||||
$('button',dialog).button();
|
||||
|
||||
|
||||
@ -786,12 +841,60 @@ function setupCreateVNetDialog() {
|
||||
notifyError(tr("Virtual Network name missing!"));
|
||||
return false;
|
||||
}
|
||||
var bridge = $('#bridge',this).val();
|
||||
var type = $('input:checked',this).val();
|
||||
|
||||
var network_json = {"name" : name};
|
||||
|
||||
var network_mode = $('select#network_mode',this).val();
|
||||
var bridge = $('#bridge',this).val();
|
||||
var phydev = $('#phydev',this).val();
|
||||
var vlan = $('#vlan',this).val();
|
||||
var vlan_id = $('#vlan_id',this).val();
|
||||
switch (network_mode) {
|
||||
case "default":
|
||||
if (!bridge && !phydev){
|
||||
notifyError("Bridge or physical device must be specified");
|
||||
return false;
|
||||
};
|
||||
if (bridge) network_json['bridge']=bridge;
|
||||
if (phydev) network_json['phydev']=phydev;
|
||||
break;
|
||||
case "802.1Q":
|
||||
if (!phydev){
|
||||
notifyError("Physical device must be specified");
|
||||
return false;
|
||||
};
|
||||
network_json['phydev']=phydev;
|
||||
if (bridge) network_json['bridge']=bridge;
|
||||
if (vlan_id) {
|
||||
network_json['vlan']=vlan;
|
||||
network_json['vlan_id']=vlan_id;
|
||||
};
|
||||
break;
|
||||
case "etables":
|
||||
if (!bridge){
|
||||
notifyError("Bridge must be specified");
|
||||
return false;
|
||||
};
|
||||
network_json['bridge']=bridge;
|
||||
break;
|
||||
case "openvswitch":
|
||||
case "vmware":
|
||||
if (!bridge){
|
||||
notifyError("Bridge must be specified");
|
||||
return false;
|
||||
};
|
||||
network_json['bridge']=bridge;
|
||||
if (vlan_id) {
|
||||
network_json['vlan']=vlan;
|
||||
network_json['vlan_id']=vlan_id;
|
||||
};
|
||||
break;
|
||||
};
|
||||
|
||||
var type = $('input:checked',this).val();
|
||||
network_json['type']=type;
|
||||
//TODO: Name and bridge provided?!
|
||||
|
||||
var network_json = null;
|
||||
if (type == "fixed") {
|
||||
var leases = $('#leases option', this);
|
||||
var leases_obj=[];
|
||||
@ -807,12 +910,7 @@ function setupCreateVNetDialog() {
|
||||
});
|
||||
|
||||
//and construct the final data for the request
|
||||
network_json = {
|
||||
"vnet" : {
|
||||
"type" : "FIXED",
|
||||
"leases" : leases_obj,
|
||||
"bridge" : bridge,
|
||||
"name" : name }};
|
||||
network_json["leases"] = leases_obj;
|
||||
}
|
||||
else { //type ranged
|
||||
|
||||
@ -827,25 +925,17 @@ function setupCreateVNetDialog() {
|
||||
return false;
|
||||
};
|
||||
|
||||
//we form the object for the request
|
||||
network_json = {
|
||||
"vnet" : {
|
||||
"type" : "RANGED",
|
||||
"bridge" : bridge,
|
||||
"name" : name }
|
||||
};
|
||||
|
||||
if (network_addr.length)
|
||||
network_json["vnet"]["network_address"]=network_addr;
|
||||
network_json["network_address"]=network_addr;
|
||||
|
||||
if (network_mask.length)
|
||||
network_json["vnet"]["network_mask"]=network_mask;
|
||||
network_json["network_mask"]=network_mask;
|
||||
|
||||
if (custom){
|
||||
if (ip_start.length)
|
||||
network_json["vnet"]["ip_start"] = ip_start;
|
||||
network_json["ip_start"] = ip_start;
|
||||
if (ip_end.length)
|
||||
network_json["vnet"]["ip_end"] = ip_end;
|
||||
network_json["ip_end"] = ip_end;
|
||||
};
|
||||
};
|
||||
|
||||
@ -853,11 +943,13 @@ function setupCreateVNetDialog() {
|
||||
$('#custom_var_vnet_box option',$create_vn_dialog).each(function(){
|
||||
var attr_name = $(this).attr('name');
|
||||
var attr_value = $(this).val();
|
||||
network_json["vnet"][attr_name] = attr_value;
|
||||
network_json[attr_name] = attr_value;
|
||||
});
|
||||
|
||||
//Create the VNetwork.
|
||||
|
||||
network_json = {"vnet" : network_json};
|
||||
|
||||
Sunstone.runAction("Network.create",network_json);
|
||||
$create_vn_dialog.dialog('close');
|
||||
return false;
|
||||
|
@ -39,6 +39,7 @@ SUNSTONE_ROOT_DIR = File.dirname(__FILE__)
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << RUBY_LIB_LOCATION+'/cloud'
|
||||
$: << SUNSTONE_ROOT_DIR
|
||||
$: << SUNSTONE_ROOT_DIR+'/models'
|
||||
|
||||
##############################################################################
|
||||
@ -115,12 +116,28 @@ helpers do
|
||||
session[:ip] = request.ip
|
||||
session[:remember] = params[:remember]
|
||||
|
||||
#User IU options initialization
|
||||
#Load options either from user settings or default config.
|
||||
# - LANG
|
||||
# - WSS CONECTION
|
||||
|
||||
if user['TEMPLATE/LANG']
|
||||
session[:lang] = user['TEMPLATE/LANG']
|
||||
else
|
||||
session[:lang] = settings.config[:lang]
|
||||
end
|
||||
|
||||
if user['TEMPLATE/VNC_WSS']
|
||||
session[:wss] = user['TEMPLATE/VNC_WSS']
|
||||
else
|
||||
wss = settings.config[:vnc_proxy_support_wss]
|
||||
#limit to yes,no options
|
||||
session[:wss] = (wss == true || wss == "yes" || wss == "only" ?
|
||||
"yes" : "no")
|
||||
end
|
||||
|
||||
#end user options
|
||||
|
||||
if params[:remember]
|
||||
env['rack.session.options'][:expire_after] = 30*60*60*24
|
||||
end
|
||||
@ -210,10 +227,18 @@ post '/logout' do
|
||||
end
|
||||
|
||||
##############################################################################
|
||||
# Config and Logs
|
||||
# User configuration and VM logs
|
||||
##############################################################################
|
||||
|
||||
get '/config' do
|
||||
@SunstoneServer.get_configuration(session[:user_id])
|
||||
uconf = {
|
||||
:user_config => {
|
||||
:lang => session[:lang],
|
||||
:wss => session[:wss]
|
||||
}
|
||||
}
|
||||
|
||||
[200, uconf.to_json]
|
||||
end
|
||||
|
||||
post '/config' do
|
||||
@ -225,7 +250,8 @@ post '/config' do
|
||||
|
||||
body.each do | key,value |
|
||||
case key
|
||||
when "lang" then session[:lang]=value
|
||||
when "lang" then session[:lang]= value
|
||||
when "wss" then session[:wss] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -243,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
|
||||
@ -251,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
|
||||
|
||||
|
||||
@ -282,6 +310,13 @@ delete '/:resource/:id' do
|
||||
@SunstoneServer.delete_resource(params[:resource], params[:id])
|
||||
end
|
||||
|
||||
##############################################################################
|
||||
# Upload image
|
||||
##############################################################################
|
||||
post '/upload'do
|
||||
@SunstoneServer.upload(params[:img], request.env['rack.input'].path)
|
||||
end
|
||||
|
||||
##############################################################################
|
||||
# Create a new Resource
|
||||
##############################################################################
|
||||
@ -301,7 +336,8 @@ post '/vm/:id/stopvnc' do
|
||||
return [403, OpenNebula::Error.new(msg).to_json]
|
||||
end
|
||||
|
||||
rc = @SunstoneServer.stopvnc(vm_id, vnc_hash[vm_id][:pipe])
|
||||
rc = @SunstoneServer.stopvnc(vnc_hash[vm_id][:pipe])
|
||||
|
||||
if rc[0] == 200
|
||||
session['vnc'].delete(vm_id)
|
||||
end
|
||||
@ -327,7 +363,8 @@ post '/vm/:id/startvnc' do
|
||||
return [200, info.to_json]
|
||||
end
|
||||
|
||||
rc = @SunstoneServer.startvnc(vm_id, settings.config)
|
||||
rc = @SunstoneServer.startvnc(vm_id,settings.config)
|
||||
|
||||
if rc[0] == 200
|
||||
info = rc[1]
|
||||
session['vnc'][vm_id] = info.clone
|
||||
|
@ -17,6 +17,7 @@
|
||||
<script type="text/javascript" src="vendor/jQueryLayout/jquery.layout-latest.min.js"></script>
|
||||
<script type="text/javascript" src="vendor/dataTables/jquery.dataTables.min.js"></script>
|
||||
<script language="javascript" type="text/javascript" src="vendor/flot/jquery.flot.min.js"></script>
|
||||
<script type="text/javascript" src="vendor/fileuploader/fileuploader.js"></script>
|
||||
|
||||
<!-- End Vendor Libraries -->
|
||||
|
||||
@ -75,7 +76,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer" class="ui-layout-south">
|
||||
Copyright 2002-2012 © OpenNebula Project Leads (<a href="http://opennebula.org" target="_blank">OpenNebula.org</a>). All Rights Reserved. OpenNebula 3.2.0
|
||||
Copyright 2002-2012 © OpenNebula Project Leads (<a href="http://opennebula.org" target="_blank">OpenNebula.org</a>). All Rights Reserved. OpenNebula 3.3.0
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user