diff --git a/NOTICE b/NOTICE index e35b54607c..443c4c1a02 100644 --- a/NOTICE +++ b/NOTICE @@ -7,8 +7,8 @@ documentation at www.OpenNebula.org AUTHORS -- Ruben Santiago Montero (rubensm@dacya.ucm.es) -- Ignacio Martin Llorente (llorente@dacya.ucm.es) +- Ruben Santiago Montero (rsmontero@opennebula.org) +- Ignacio Martin Llorente (imllorente@opennebula.org) ACKNOWLEDGEMENTS diff --git a/install.sh b/install.sh index b5c507ac43..ec2d5b1341 100755 --- a/install.sh +++ b/install.sh @@ -40,6 +40,7 @@ usage() { echo "-d: target installation directory, if not defined it'd be root. Must be" echo " an absolute path." echo "-c: install client utilities: OpenNebula cli, occi and ec2 client files" + echo "-s: install OpenNebula Sunstone" echo "-r: remove Opennebula, only useful if -d was not specified, otherwise" echo " rm -rf \$ONE_LOCATION would do the job" echo "-l: creates symlinks instead of copying files, useful for development" @@ -47,7 +48,7 @@ usage() { } #------------------------------------------------------------------------------- -TEMP_OPT=`getopt -o hkrlcu:g:d: -n 'install.sh' -- "$@"` +TEMP_OPT=`getopt -o hkrlcsu:g:d: -n 'install.sh' -- "$@"` if [ $? != 0 ] ; then usage @@ -60,6 +61,7 @@ INSTALL_ETC="yes" UNINSTALL="no" LINK="no" CLIENT="no" +SUNSTONE="no" ONEADMIN_USER=`id -u` ONEADMIN_GROUP=`id -g` SRC_DIR=$PWD @@ -70,7 +72,8 @@ while true ; do -k) INSTALL_ETC="no" ; shift ;; -r) UNINSTALL="yes" ; shift ;; -l) LINK="yes" ; shift ;; - -c) CLIENT="yes" ; shift ;; + -c) CLIENT="yes"; INSTALL_ETC="no" ; shift ;; + -s) SUNSTONE="yes"; INSTALL_ETC="no" ; shift ;; -u) ONEADMIN_USER="$2" ; shift 2;; -g) ONEADMIN_GROUP="$2"; shift 2;; -d) ROOT="$2" ; shift 2 ;; @@ -89,6 +92,7 @@ if [ -z "$ROOT" ] ; then ETC_LOCATION="/etc/one" LOG_LOCATION="/var/log/one" VAR_LOCATION="/var/lib/one" + SUNSTONE_LOCATION="$LIB_LOCATION/sunstone" IMAGES_LOCATION="$VAR_LOCATION/images" RUN_LOCATION="/var/run/one" LOCK_LOCATION="/var/lock/one" @@ -96,7 +100,19 @@ if [ -z "$ROOT" ] ; then SHARE_LOCATION="/usr/share/one" MAN_LOCATION="/usr/share/man/man8" - if [ "$CLIENT" = "no" ]; then + if [ "$CLIENT" = "yes" ]; then + MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION" + + DELETE_DIRS="" + + CHOWN_DIRS="" + elif [ "$SUNSTONE" = "yes" ]; then + MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $VAR_LOCATION $SUNSTONE_LOCATION" + + DELETE_DIRS="$MAKE_DIRS" + + CHOWN_DIRS="" + else MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $ETC_LOCATION $VAR_LOCATION \ $INCLUDE_LOCATION $SHARE_LOCATION \ $LOG_LOCATION $RUN_LOCATION $LOCK_LOCATION \ @@ -106,12 +122,6 @@ if [ -z "$ROOT" ] ; then $RUN_LOCATION $SHARE_DIRS" CHOWN_DIRS="$LOG_LOCATION $VAR_LOCATION $RUN_LOCATION $LOCK_LOCATION" - else - MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION" - - DELETE_DIRS="" - - CHOWN_DIRS="" fi else @@ -119,12 +129,21 @@ else LIB_LOCATION="$ROOT/lib" ETC_LOCATION="$ROOT/etc" VAR_LOCATION="$ROOT/var" + SUNSTONE_LOCATION="$LIB_LOCATION/sunstone" IMAGES_LOCATION="$VAR_LOCATION/images" INCLUDE_LOCATION="$ROOT/include" SHARE_LOCATION="$ROOT/share" MAN_LOCATION="$ROOT/share/man/man8" - if [ "$CLIENT" = "no" ]; then + if [ "$CLIENT" = "yes" ]; then + MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION" + + DELETE_DIRS="$MAKE_DIRS" + elif [ "$SUNSTONE" = "yes" ]; then + MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $VAR_LOCATION $SUNSTONE_LOCATION" + + DELETE_DIRS="$MAKE_DIRS" + else MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $ETC_LOCATION $VAR_LOCATION \ $INCLUDE_LOCATION $SHARE_LOCATION $IMAGES_LOCATION \ $MAN_LOCATION" @@ -132,10 +151,6 @@ else DELETE_DIRS="$MAKE_DIRS" CHOWN_DIRS="$ROOT" - else - MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION" - - DELETE_DIRS="$MAKE_DIRS" fi CHOWN_DIRS="$ROOT" @@ -188,6 +203,16 @@ VAR_DIRS="$VAR_LOCATION/remotes \ $VAR_LOCATION/remotes/vmm/xen \ $VAR_LOCATION/remotes/vmm/kvm" +SUNSTONE_DIRS="$SUNSTONE_LOCATION/models \ + $SUNSTONE_LOCATION/models/OpenNebulaJSON \ + $SUNSTONE_LOCATION/public \ + $SUNSTONE_LOCATION/public/js \ + $SUNSTONE_LOCATION/public/js/vendor \ + $SUNSTONE_LOCATION/public/css \ + $SUNSTONE_LOCATION/public/css/vendor \ + $SUNSTONE_LOCATION/public/images \ + $SUNSTONE_LOCATION/templates" + LIB_ECO_CLIENT_DIRS="$LIB_LOCATION/ruby \ $LIB_LOCATION/ruby/OpenNebula \ $LIB_LOCATION/ruby/cloud/ \ @@ -197,14 +222,19 @@ LIB_OCCI_CLIENT_DIRS="$LIB_LOCATION/ruby \ $LIB_LOCATION/ruby/OpenNebula \ $LIB_LOCATION/ruby/cloud/occi" +LIB_OCA_CLIENT_DIRS="$LIB_LOCATION/ruby \ + $LIB_LOCATION/ruby/OpenNebula" + LIB_CLI_DIRS="$LIB_LOCATION/ruby \ $LIB_LOCATION/ruby/OpenNebula" -if [ "$CLIENT" = "no" ]; then - MAKE_DIRS="$MAKE_DIRS $SHARE_DIRS $ETC_DIRS $LIB_DIRS $VAR_DIRS" -else +if [ "$CLIENT" = "yes" ]; then MAKE_DIRS="$MAKE_DIRS $LIB_ECO_CLIENT_DIRS $LIB_OCCI_CLIENT_DIRS \ $LIB_CLI_DIRS" +elif [ "$SUNSTONE" = "yes" ]; then + MAKE_DIRS="$MAKE_DIRS $SUNSTONE_DIRS $LIB_OCA_CLIENT_DIRS" +else + MAKE_DIRS="$MAKE_DIRS $SHARE_DIRS $ETC_DIRS $LIB_DIRS $VAR_DIRS $SUNSTONE_DIRS" fi #------------------------------------------------------------------------------- @@ -267,6 +297,24 @@ INSTALL_CLIENT_FILES=( RUBY_OPENNEBULA_LIB_FILES:$LIB_LOCATION/ruby/OpenNebula ) +INSTALL_SUNSTONE_RUBY_FILES=( + SUNSTONE_RUBY_LIB_FILES:$LIB_LOCATION/ruby + RUBY_OPENNEBULA_LIB_FILES:$LIB_LOCATION/ruby/OpenNebula +) + +INSTALL_SUNSTONE_FILES=( + SUNSTONE_FILES:$SUNSTONE_LOCATION + SUNSTONE_BIN_FILES:$BIN_LOCATION + SUNSTONE_MODELS_FILES:$SUNSTONE_LOCATION/models + SUNSTONE_MODELS_JSON_FILES:$SUNSTONE_LOCATION/models/OpenNebulaJSON + SUNSTONE_TEMPLATE_FILES:$SUNSTONE_LOCATION/templates + SUNSTONE_PUBLIC_JS_FILES:$SUNSTONE_LOCATION/public/js + SUNSTONE_PUBLIC_JS_VENDOR_FILES:$SUNSTONE_LOCATION/public/js/vendor + SUNSTONE_PUBLIC_CSS_FILES:$SUNSTONE_LOCATION/public/css + SUNSTONE_PUBLIC_CSS_VENDOR_FILES:$SUNSTONE_LOCATION/public/css/vendor + SUNSTONE_PUBLIC_IMAGES_FILES:$SUNSTONE_LOCATION/public/images +) + INSTALL_ETC_FILES=( ETC_FILES:$ETC_LOCATION VMM_EC2_ETC_FILES:$ETC_LOCATION/vmm_ec2 @@ -646,6 +694,80 @@ CLI_BIN_FILES="src/cli/onevm \ src/cli/oneimage \ src/cli/onecluster" +#----------------------------------------------------------------------------- +# Sunstone files +#----------------------------------------------------------------------------- + +SUNSTONE_FILES="src/sunstone/config.ru \ + src/sunstone/sunstone-server.rb" + +SUNSTONE_BIN_FILES="src/sunstone/bin/sunstone-server" + +SUNSTONE_MODELS_FILES="src/sunstone/models/OpenNebulaJSON.rb \ + src/sunstone/models/SunstoneServer.rb" + +SUNSTONE_MODELS_JSON_FILES="src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb \ + src/sunstone/models/OpenNebulaJSON/HostJSON.rb \ + src/sunstone/models/OpenNebulaJSON/ImageJSON.rb \ + src/sunstone/models/OpenNebulaJSON/JSONUtils.rb \ + src/sunstone/models/OpenNebulaJSON/PoolJSON.rb \ + src/sunstone/models/OpenNebulaJSON/UserJSON.rb \ + src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb \ + src/sunstone/models/OpenNebulaJSON/VirtualNetworkJSON.rb" + +SUNSTONE_TEMPLATE_FILES="src/sunstone/templates/index.html \ + src/sunstone/templates/login.html" + +SUNSTONE_PUBLIC_JS_FILES="src/sunstone/public/js/layout.js \ + src/sunstone/public/js/login.js \ + src/sunstone/public/js/one-ui_views.js \ + src/sunstone/public/js/one-ui_views.templates.js \ + src/sunstone/public/js/opennebula.js" + +SUNSTONE_PUBLIC_JS_VENDOR_FILES="src/sunstone/public/js/vendor/base64.js \ + src/sunstone/public/js/vendor/jquery-1.4.4.min.js \ + src/sunstone/public/js/vendor/jquery.dataTables.min.js \ + src/sunstone/public/js/vendor/jquery.jgrowl_minimized.js \ + src/sunstone/public/js/vendor/jquery.layout.min-1.2.0.js \ + src/sunstone/public/js/vendor/jquery-ui-1.8.7.custom.min.js" + +SUNSTONE_PUBLIC_CSS_FILES="src/sunstone/public/css/application.css \ + src/sunstone/public/css/demo_table_jui.css \ + src/sunstone/public/css/jquery.jgrowl.css \ + src/sunstone/public/css/layout.css \ + src/sunstone/public/css/layout-default-latest.css \ + src/sunstone/public/css/login.css" + +SUNSTONE_PUBLIC_CSS_VENDOR_FILES="\ + src/sunstone/public/css/vendor/jquery-ui-1.8.7.custom.css \ + src/sunstone/public/css/vendor/ui-bg_flat_0_575c5b_40x100.png \ + src/sunstone/public/css/vendor/ui-bg_flat_0_8f9392_40x100.png \ + src/sunstone/public/css/vendor/ui-bg_flat_0_aaaaaa_40x100.png \ + src/sunstone/public/css/vendor/ui-bg_flat_75_ffffff_40x100.png \ + src/sunstone/public/css/vendor/ui-bg_glass_55_fbf9ee_1x400.png \ + src/sunstone/public/css/vendor/ui-bg_glass_65_ffffff_1x400.png \ + src/sunstone/public/css/vendor/ui-bg_glass_75_dadada_1x400.png \ + src/sunstone/public/css/vendor/ui-bg_glass_75_e6e6e6_1x400.png \ + src/sunstone/public/css/vendor/ui-bg_glass_95_fef1ec_1x400.png \ + src/sunstone/public/css/vendor/ui-bg_highlight-soft_75_cccccc_1x100.png \ + src/sunstone/public/css/vendor/ui-icons_222222_256x240.png \ + src/sunstone/public/css/vendor/ui-icons_2e83ff_256x240.png \ + src/sunstone/public/css/vendor/ui-icons_454545_256x240.png \ + src/sunstone/public/css/vendor/ui-icons_888888_256x240.png \ + src/sunstone/public/css/vendor/ui-icons_cd0a0a_256x240.png" + +SUNSTONE_PUBLIC_IMAGES_FILES="src/sunstone/public/images/ajax-loader.gif \ + src/sunstone/public/images/login_over.png \ + src/sunstone/public/images/login.png \ + src/sunstone/public/images/opennebula-sunstone-big.png \ + src/sunstone/public/images/opennebula-sunstone-small.png \ + src/sunstone/public/images/panel.png \ + src/sunstone/public/images/pbar.gif \ + src/sunstone/public/images/Refresh-icon.png" + +SUNSTONE_RUBY_LIB_FILES="src/mad/ruby/CommandManager.rb \ + src/oca/ruby/OpenNebula.rb" + #----------------------------------------------------------------------------- # MAN files #----------------------------------------------------------------------------- @@ -696,10 +818,12 @@ do_file() { } -if [ "$CLIENT" = "no" ]; then - INSTALL_SET=${INSTALL_FILES[@]} -else +if [ "$CLIENT" = "yes" ]; then INSTALL_SET=${INSTALL_CLIENT_FILES[@]} +elif [ "$SUNSTONE" = "yes" ]; then + INSTALL_SET="${INSTALL_SUNSTONE_RUBY_FILES[@]} ${INSTALL_SUNSTONE_FILES[@]}" +else + INSTALL_SET="${INSTALL_FILES[@]} ${INSTALL_SUNSTONE_FILES[@]}" fi for i in ${INSTALL_SET[@]}; do @@ -713,7 +837,7 @@ for i in ${INSTALL_SET[@]}; do done done -if [ "$CLIENT" = "no" -a "$INSTALL_ETC" = "yes" ] ; then +if [ "$INSTALL_ETC" = "yes" ] ; then for i in ${INSTALL_ETC_FILES[@]}; do SRC=$`echo $i | cut -d: -f1` DST=`echo $i | cut -d: -f2` diff --git a/src/sunstone/bin/sunstone-server b/src/sunstone/bin/sunstone-server new file mode 100755 index 0000000000..06efb73b8a --- /dev/null +++ b/src/sunstone/bin/sunstone-server @@ -0,0 +1,124 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# 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. # +#--------------------------------------------------------------------------- # + + +if [ -z "$ONE_LOCATION" ]; then + SUNSTONE_PID=/var/run/one/sunstone.pid + SUNSTONE_SERVER=/usr/lib/one/sunstone/config.ru + SUNSTONE_LOCK_FILE=/var/lock/one/.sunstone.lock + SUNSTONE_LOG=/var/log/one/sunstone.log +else + SUNSTONE_PID=$ONE_LOCATION/var/sunstone.pid + SUNSTONE_SERVER=$ONE_LOCATION/lib/sunstone/config.ru + SUNSTONE_LOCK_FILE=$ONE_LOCATION/var/.sunstone.lock + SUNSTONE_LOG=$ONE_LOCATION/var/sunstone.log +fi + +PORT="4567" +HOST="127.0.0.1" + +usage() { + echo + echo "Usage: sunstone-server [-H host] [-p port]" + echo + echo "-H: Host for the Sunstone server, default value: localhost" + echo "-p: Port for incoming connections, default value: 4567" +} + +setup() +{ + + if [ -f $SUNSTONE_LOCK_FILE ]; then + if [ -f $SUNSTONE_PID ]; then + SUNSTONEPID=`cat $SUNSTONE_PID` + ps $SUNSTONEPID &> /dev/null + if [ $? -eq 0 ]; then + echo "Sunstone Server is still running (PID:$SUNSTONEPID). Please try 'sunstone-server stop' first." + exit 1 + fi + fi + echo "Stale .lock detected. Erasing it." + rm $SUNSTONE_LOCK_FILE + fi +} + + +start() +{ + if [ ! -f "$SUNSTONE_SERVER" ]; then + echo "Can not find $SUNSTONE_SERVER." + exit 1 + fi + + # Start the sunstone daemon + touch $SUNSTONE_LOCK_FILE + rackup $SUNSTONE_SERVER -s thin -p $PORT -o $HOST -P $SUNSTONE_PID &> $SUNSTONE_LOG & + + LASTRC=$? + + if [ $LASTRC -ne 0 ]; then + echo "Error executing $SUNSTONE_SERVER" + exit 1 + fi + + sleep 1 + ps $LASTPID &> /dev/null + + if [ $? -ne 0 ]; then + echo "Error executing $SUNSTONE_SERVER." + exit 1 + fi + + echo "sunstone-server started" +} + +# +# Function that stops the daemon/service +# +stop() +{ + if [ ! -f $SUNSTONE_PID ]; then + echo "Couldn't find sunstone-server process pid." + exit 1 + fi + + # Kill the sunstone daemon + kill -INT `cat $SUNSTONE_PID` &> /dev/null + + # Remove pid files + rm -f $SUNSTONE_LOCK_FILE &> /dev/null + + echo "sunstone-server stopped" +} + +while getopts "p:H:" OPTION +do + case $OPTION in + p) PORT=$OPTARG;; + H) HOST=$OPTARG;; + *) usage; exit 3;; + esac +done + +shift $((OPTIND-1)) + +case "$1" in + start) setup; start;; + stop) stop;; + *) usage; exit 3;; +esac diff --git a/src/sunstone/config.ru b/src/sunstone/config.ru index a7034811d0..8b695e23af 100644 --- a/src/sunstone/config.ru +++ b/src/sunstone/config.ru @@ -19,6 +19,6 @@ # TBD Change path for intallation tree $: << File.dirname(__FILE__) -require 'one-ui.rb' +require 'sunstone-server.rb' run Sinatra::Application diff --git a/src/sunstone/models/OpenNebulaJSON.rb b/src/sunstone/models/OpenNebulaJSON.rb index 28821ef8e1..709f553a48 100644 --- a/src/sunstone/models/OpenNebulaJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON.rb @@ -14,33 +14,28 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -ONE_LOCATION = ENV["ONE_LOCATION"] +ONE_LOCATION = ENV["ONE_LOCATION"] if !ONE_LOCATION if !ONE_LOCATION RUBY_LIB_LOCATION = "/usr/lib/one/ruby" - VAR_LOCATION = "/var/lib/one" else RUBY_LIB_LOCATION = ONE_LOCATION+"/lib/ruby" - VAR_LOCATION = ONE_LOCATION+"/var" end $: << RUBY_LIB_LOCATION +$: << File.dirname(__FILE__) require 'OpenNebula' include OpenNebula -# TBD Change path for intallation tree -#require 'OpenNebulaJSON/PoolJSON' -#require 'OpenNebulaJSON/HostJSON' -#require 'OpenNebulaJSON/JSONUtils' -require 'models/OpenNebulaJSON/ClusterJSON' -require 'models/OpenNebulaJSON/HostJSON' -require 'models/OpenNebulaJSON/ImageJSON' -require 'models/OpenNebulaJSON/JSONUtils' -require 'models/OpenNebulaJSON/PoolJSON' -require 'models/OpenNebulaJSON/UserJSON' -require 'models/OpenNebulaJSON/VirtualMachineJSON' -require 'models/OpenNebulaJSON/VirtualNetworkJSON' +require 'OpenNebulaJSON/ClusterJSON' +require 'OpenNebulaJSON/HostJSON' +require 'OpenNebulaJSON/ImageJSON' +require 'OpenNebulaJSON/JSONUtils' +require 'OpenNebulaJSON/PoolJSON' +require 'OpenNebulaJSON/UserJSON' +require 'OpenNebulaJSON/VirtualMachineJSON' +require 'OpenNebulaJSON/VirtualNetworkJSON' module OpenNebula class Error diff --git a/src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb b/src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb index 9c015d0187..a8dbc44635 100644 --- a/src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb @@ -14,7 +14,7 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -require 'models/OpenNebulaJSON/JSONUtils' +require 'OpenNebulaJSON/JSONUtils' module OpenNebulaJSON class ClusterJSON < OpenNebula::Cluster diff --git a/src/sunstone/models/OpenNebulaJSON/HostJSON.rb b/src/sunstone/models/OpenNebulaJSON/HostJSON.rb index 42490d405a..33f8962f6a 100644 --- a/src/sunstone/models/OpenNebulaJSON/HostJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/HostJSON.rb @@ -14,7 +14,7 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -require 'models/OpenNebulaJSON/JSONUtils' +require 'OpenNebulaJSON/JSONUtils' module OpenNebulaJSON class HostJSON < OpenNebula::Host diff --git a/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb b/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb index 05cb041d21..36ddb98790 100644 --- a/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb @@ -14,7 +14,7 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -require 'models/OpenNebulaJSON/JSONUtils' +require 'OpenNebulaJSON/JSONUtils' module OpenNebulaJSON class ImageJSON < OpenNebula::Image diff --git a/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb b/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb index 4c4414200d..d32241c5d7 100644 --- a/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/PoolJSON.rb @@ -14,7 +14,7 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -require 'models/OpenNebulaJSON/JSONUtils' +require 'OpenNebulaJSON/JSONUtils' module OpenNebulaJSON class HostPoolJSON < OpenNebula::HostPool; include JSONUtils; end diff --git a/src/sunstone/models/OpenNebulaJSON/UserJSON.rb b/src/sunstone/models/OpenNebulaJSON/UserJSON.rb index 803903641f..1a17e93a6d 100644 --- a/src/sunstone/models/OpenNebulaJSON/UserJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/UserJSON.rb @@ -14,7 +14,7 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -require 'models/OpenNebulaJSON/JSONUtils' +require 'OpenNebulaJSON/JSONUtils' module OpenNebulaJSON class UserJSON < OpenNebula::User diff --git a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb index 932b54a97b..92d152a9e9 100644 --- a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb @@ -14,7 +14,7 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -require 'models/OpenNebulaJSON/JSONUtils' +require 'OpenNebulaJSON/JSONUtils' module OpenNebulaJSON class VirtualMachineJSON < OpenNebula::VirtualMachine @@ -45,14 +45,14 @@ module OpenNebulaJSON when "deploy" then self.deploy(action_hash['params']) when "finalize" then self.finalize when "hold" then self.hold - when "live_migrate" then self.live_migrate(action_hash['params']) + when "livemigrate" then self.live_migrate(action_hash['params']) when "migrate" then self.migrate(action_hash['params']) when "resume" then self.resume when "release" then self.release when "stop" then self.stop when "suspend" then self.suspend when "restart" then self.restart - when "save_as" then self.save_as(action_hash['params']) + when "saveas" then self.save_as(action_hash['params']) when "shutdown" then self.shutdown else error_msg = "#{action_hash['perform']} action not " << diff --git a/src/sunstone/models/OpenNebulaJSON/VirtualNetworkJSON.rb b/src/sunstone/models/OpenNebulaJSON/VirtualNetworkJSON.rb index 3170dd1607..b4e7503dbb 100644 --- a/src/sunstone/models/OpenNebulaJSON/VirtualNetworkJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/VirtualNetworkJSON.rb @@ -14,7 +14,7 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -require 'models/OpenNebulaJSON/JSONUtils' +require 'OpenNebulaJSON/JSONUtils' module OpenNebulaJSON class VirtualNetworkJSON < OpenNebula::VirtualNetwork diff --git a/src/sunstone/models/OneUI.rb b/src/sunstone/models/SunstoneServer.rb similarity index 89% rename from src/sunstone/models/OneUI.rb rename to src/sunstone/models/SunstoneServer.rb index f41200adbf..cc3c256532 100644 --- a/src/sunstone/models/OneUI.rb +++ b/src/sunstone/models/SunstoneServer.rb @@ -14,13 +14,20 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -# TBD Change path for intallation tree +ONE_LOCATION = ENV["ONE_LOCATION"] + +if !ONE_LOCATION + LOG_LOCATION = "/var/log/one" + VAR_LOCATION = "/var/lib/one" +else + VAR_LOCATION = ONE_LOCATION+"/var" + LOG_LOCATION = ONE_LOCATION+"/var" +end -#require 'OpenNebulaJSON' require 'models/OpenNebulaJSON' include OpenNebulaJSON -class OneUI +class SunstoneServer def initialize(username, password) # TBD one_client_user(name) from CloudServer @client = Client.new("dummy:dummy") @@ -53,9 +60,8 @@ class OneUI ############################################################################ # ############################################################################ - def get_pool(kind, user_id) - user_flag = user_id=="0" ? -2 : -1 - + def get_pool(kind) + user_flag = -1 pool = case kind when "cluster" then ClusterPoolJSON.new(@client) when "host" then HostPoolJSON.new(@client) @@ -150,7 +156,11 @@ class OneUI ############################################################################ # ############################################################################ - def get_configuration + def get_configuration(user_id) + if user_id != "0" + return [401, ""] + end + one_config = VAR_LOCATION + "/config" config = Hash.new @@ -178,17 +188,24 @@ class OneUI # ############################################################################ def get_vm_log(id) - id = id.to_s - vm_log_file = VAR_LOCATION + "/#{id}/vm.log" + resource = retrieve_resource("vm", id) + if OpenNebula.is_error?(resource) + return [404, nil] + else + if !ONE_LOCATION + vm_log_file = LOG_LOCATION + "/#{id}.log" + else + vm_log_file = LOG_LOCATION + "/#{id}/vm.log" + end - begin - log = File.read(vm_log_file) - rescue Exception => e - error = Error.new("Error: log for VM #{id} not available") - return [500, error.to_s] + begin + log = File.read(vm_log_file) + rescue Exception => e + return [200, "Log for VM #{id} not available"] + end + + return [200, log] end - - return [200, log] end private diff --git a/src/sunstone/public/css/application.css b/src/sunstone/public/css/application.css index 886e469918..4d2a4ad743 100644 --- a/src/sunstone/public/css/application.css +++ b/src/sunstone/public/css/application.css @@ -21,20 +21,20 @@ body { p{ margin:0 10px 10px; } -a { - color: #000C96; text-decoration: none; +a { + color: #000C96; text-decoration: none; } -a:hover { - color: #127FE4; text-decoration: none; +a:hover { + color: #127FE4; text-decoration: none; } -select, button { - padding: 2px; +select, button { + padding: 2px; } -h2 { - float:left; - font-size:20px; - margin-bottom: 5px; +h2 { + float:left; + font-size:20px; + margin-bottom: 5px; padding-bottom: 0} h3 { @@ -296,7 +296,7 @@ textarea:focus{ } .remove_button { - + } tr.odd, tr.even { @@ -480,6 +480,8 @@ tr.even:hover{ cursor: pointer; } +.ui-widget-overlay { background: #353735; opacity: .60; filter:Alpha(Opacity=60); } + .ui-tabs .ui-tabs-nav li a { /*padding: .5em 1em;*/ padding: .3em 1em; diff --git a/src/sunstone/public/css/jquery.jgrowl.css b/src/sunstone/public/css/jquery.jgrowl.css old mode 100755 new mode 100644 diff --git a/src/sunstone/public/css/layout.css b/src/sunstone/public/css/layout.css old mode 100755 new mode 100644 diff --git a/src/sunstone/public/css/smoothness/images/ui-icons_222222_256x240.png.old b/src/sunstone/public/css/smoothness/images/ui-icons_222222_256x240.png.old deleted file mode 100644 index b273ff111d..0000000000 Binary files a/src/sunstone/public/css/smoothness/images/ui-icons_222222_256x240.png.old and /dev/null differ diff --git a/src/sunstone/public/css/smoothness/jquery-ui-1.8.7.custom.css b/src/sunstone/public/css/vendor/jquery-ui-1.8.7.custom.css similarity index 94% rename from src/sunstone/public/css/smoothness/jquery-ui-1.8.7.custom.css rename to src/sunstone/public/css/vendor/jquery-ui-1.8.7.custom.css index e74edd7957..15e2706919 100644 --- a/src/sunstone/public/css/smoothness/jquery-ui-1.8.7.custom.css +++ b/src/sunstone/public/css/vendor/jquery-ui-1.8.7.custom.css @@ -59,26 +59,26 @@ /*.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } .ui-widget .ui-widget { font-size: 1em; }*/ /*.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }*/ -.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } +.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } .ui-widget-content a { color: #222222; } -.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } +.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } .ui-widget-header a { color: #222222; } /* Interaction states ----------------------------------*/ -.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; } +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; } .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; } -.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } .ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; } -.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; } .ui-widget :active { outline: none; } /* Interaction Cues ----------------------------------*/ -.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } .ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } -.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } .ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } .ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } @@ -89,14 +89,14 @@ ----------------------------------*/ /* states and images */ -.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } -.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } -.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } -.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); } -.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } -.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } -.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } -.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } +.ui-icon { width: 16px; height: 16px; background-image: url(ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(ui-icons_222222_256x240.png); } +.ui-state-default .ui-icon { background-image: url(ui-icons_888888_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(ui-icons_454545_256x240.png); } +.ui-state-active .ui-icon {background-image: url(ui-icons_454545_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(ui-icons_cd0a0a_256x240.png); } /* positioning */ .ui-icon-carat-1-n { background-position: 0 0; } @@ -291,8 +291,8 @@ .ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } /* Overlays */ -.ui-widget-overlay { background: #575c5b url(images/ui-bg_flat_0_575c5b_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } -.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* +.ui-widget-overlay { background: #575c5b url(ui-bg_flat_0_575c5b_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* * jQuery UI Resizable 1.8.7 * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) diff --git a/src/sunstone/public/css/smoothness/images/ui-bg_flat_0_575c5b_40x100.png b/src/sunstone/public/css/vendor/ui-bg_flat_0_575c5b_40x100.png similarity index 100% rename from src/sunstone/public/css/smoothness/images/ui-bg_flat_0_575c5b_40x100.png rename to src/sunstone/public/css/vendor/ui-bg_flat_0_575c5b_40x100.png diff --git a/src/sunstone/public/css/smoothness/images/ui-bg_flat_0_8f9392_40x100.png b/src/sunstone/public/css/vendor/ui-bg_flat_0_8f9392_40x100.png similarity index 100% rename from src/sunstone/public/css/smoothness/images/ui-bg_flat_0_8f9392_40x100.png rename to src/sunstone/public/css/vendor/ui-bg_flat_0_8f9392_40x100.png diff --git a/src/sunstone/public/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png b/src/sunstone/public/css/vendor/ui-bg_flat_0_aaaaaa_40x100.png similarity index 100% rename from src/sunstone/public/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png rename to src/sunstone/public/css/vendor/ui-bg_flat_0_aaaaaa_40x100.png diff --git a/src/sunstone/public/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png b/src/sunstone/public/css/vendor/ui-bg_flat_75_ffffff_40x100.png similarity index 100% rename from src/sunstone/public/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png rename to src/sunstone/public/css/vendor/ui-bg_flat_75_ffffff_40x100.png diff --git a/src/sunstone/public/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png b/src/sunstone/public/css/vendor/ui-bg_glass_55_fbf9ee_1x400.png similarity index 100% rename from src/sunstone/public/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png rename to src/sunstone/public/css/vendor/ui-bg_glass_55_fbf9ee_1x400.png diff --git a/src/sunstone/public/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png b/src/sunstone/public/css/vendor/ui-bg_glass_65_ffffff_1x400.png similarity index 100% rename from src/sunstone/public/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png rename to src/sunstone/public/css/vendor/ui-bg_glass_65_ffffff_1x400.png diff --git a/src/sunstone/public/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png b/src/sunstone/public/css/vendor/ui-bg_glass_75_dadada_1x400.png similarity index 100% rename from src/sunstone/public/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png rename to src/sunstone/public/css/vendor/ui-bg_glass_75_dadada_1x400.png diff --git a/src/sunstone/public/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png b/src/sunstone/public/css/vendor/ui-bg_glass_75_e6e6e6_1x400.png similarity index 100% rename from src/sunstone/public/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png rename to src/sunstone/public/css/vendor/ui-bg_glass_75_e6e6e6_1x400.png diff --git a/src/sunstone/public/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png b/src/sunstone/public/css/vendor/ui-bg_glass_95_fef1ec_1x400.png similarity index 100% rename from src/sunstone/public/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png rename to src/sunstone/public/css/vendor/ui-bg_glass_95_fef1ec_1x400.png diff --git a/src/sunstone/public/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/src/sunstone/public/css/vendor/ui-bg_highlight-soft_75_cccccc_1x100.png similarity index 100% rename from src/sunstone/public/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png rename to src/sunstone/public/css/vendor/ui-bg_highlight-soft_75_cccccc_1x100.png diff --git a/src/sunstone/public/css/smoothness/images/ui-icons_222222_256x240.png b/src/sunstone/public/css/vendor/ui-icons_222222_256x240.png similarity index 100% rename from src/sunstone/public/css/smoothness/images/ui-icons_222222_256x240.png rename to src/sunstone/public/css/vendor/ui-icons_222222_256x240.png diff --git a/src/sunstone/public/css/smoothness/images/ui-icons_2e83ff_256x240.png b/src/sunstone/public/css/vendor/ui-icons_2e83ff_256x240.png similarity index 100% rename from src/sunstone/public/css/smoothness/images/ui-icons_2e83ff_256x240.png rename to src/sunstone/public/css/vendor/ui-icons_2e83ff_256x240.png diff --git a/src/sunstone/public/css/smoothness/images/ui-icons_454545_256x240.png b/src/sunstone/public/css/vendor/ui-icons_454545_256x240.png similarity index 100% rename from src/sunstone/public/css/smoothness/images/ui-icons_454545_256x240.png rename to src/sunstone/public/css/vendor/ui-icons_454545_256x240.png diff --git a/src/sunstone/public/css/smoothness/images/ui-icons_888888_256x240.png b/src/sunstone/public/css/vendor/ui-icons_888888_256x240.png similarity index 100% rename from src/sunstone/public/css/smoothness/images/ui-icons_888888_256x240.png rename to src/sunstone/public/css/vendor/ui-icons_888888_256x240.png diff --git a/src/sunstone/public/css/smoothness/images/ui-icons_cd0a0a_256x240.png b/src/sunstone/public/css/vendor/ui-icons_cd0a0a_256x240.png similarity index 100% rename from src/sunstone/public/css/smoothness/images/ui-icons_cd0a0a_256x240.png rename to src/sunstone/public/css/vendor/ui-icons_cd0a0a_256x240.png diff --git a/src/sunstone/public/images/box_gradient.png b/src/sunstone/public/images/box_gradient.png deleted file mode 100644 index 4e2c718c0c..0000000000 Binary files a/src/sunstone/public/images/box_gradient.png and /dev/null differ diff --git a/src/sunstone/public/js/layout.js b/src/sunstone/public/js/layout.js old mode 100755 new mode 100644 diff --git a/src/sunstone/public/js/one-ui_views.js b/src/sunstone/public/js/one-ui_views.js index b3b5cbc7a7..22c58a3746 100644 --- a/src/sunstone/public/js/one-ui_views.js +++ b/src/sunstone/public/js/one-ui_views.js @@ -58,7 +58,15 @@ $(document).ready(function() { refreshButtonListener(); //listen to manual refresh image clicks confirmButtonListener(); //listen to buttons that require confirmation confirmWithSelectListener(); //listen to buttons requiring a selector - actionButtonListener(); //listens to all simple actions (not creates) + actionButtonListener(); //listens to all simple actions (not creates) + + hostInfoListener(); + vMachineInfoListener(); + vNetworkInfoListener(); + imageInfoListener(); + + + setupImageAttributesDialogs(); //setups the add/update/remove attr dialogs //Jquery-ui eye-candy @@ -68,6 +76,12 @@ $(document).ready(function() { preloadTables(); setupAutoRefresh(); + tableCheckboxesListener(dataTable_hosts); + tableCheckboxesListener(dataTable_vMachines); + tableCheckboxesListener(dataTable_vNetworks); + tableCheckboxesListener(dataTable_users); + tableCheckboxesListener(dataTable_images); + $(".ui-widget-overlay").live("click", function (){ $("div:ui-dialog:visible").dialog("close"); }); @@ -165,7 +179,8 @@ function initDataTables(){ "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "60px", "aTargets": [0] }, - { "sWidth": "35px", "aTargets": [1] } + { "sWidth": "35px", "aTargets": [1] }, + { "sWidth": "100px", "aTargets": [2] } ] }); @@ -176,8 +191,9 @@ function initDataTables(){ "sPaginationType": "full_numbers", "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, - { "sWidth": "60px", "aTargets": [0,5,6,7] }, - { "sWidth": "35px", "aTargets": [1] } + { "sWidth": "60px", "aTargets": [0,4,5,6,7] }, + { "sWidth": "35px", "aTargets": [1] }, + { "sWidth": "100px", "aTargets": [2] } ] }); @@ -203,7 +219,8 @@ function initDataTables(){ "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "60px", "aTargets": [0,3] }, - { "sWidth": "35px", "aTargets": [1] } + { "sWidth": "35px", "aTargets": [1] }, + { "sWidth": "100px", "aTargets": [2,3] } ] }); @@ -237,7 +254,7 @@ function initListButtons(){ $('.multi_action_slct').each(function(){ //prepare replacement buttons buttonset = $('
Previous action').button(); + button1 = $('').button(); button1.attr("disabled","disabled"); button2 = $('').button({ text:false, @@ -281,14 +298,12 @@ function initListButtons(){ prev_action_button.val($(this).val()); prev_action_button.removeClass("confirm_with_select_button"); prev_action_button.removeClass("confirm_button"); + prev_action_button.removeClass("action_button"); prev_action_button.addClass($(this).attr("class")); - confirmButtonListener(); - confirmWithSelectListener(); - actionButtonListener(); prev_action_button.button("option","label",$(this).text()); prev_action_button.button("enable"); $(this).parents('ul').hide("blind",100); - return false; + //return false; }); @@ -333,11 +348,11 @@ function refreshButtonListener(){ callback = updateHostsView; waiting_nodes(dataTable_hosts); OpenNebula.Host.list({success: callback, error: onError}); + callback = updateClustersView; + OpenNebula.Cluster.list({success: callback, error: onError}); break; case "OpenNebula.Cluster.list": - callback = updateClustersView; - waiting_nodes(dataTable_clusters); - OpenNebula.Cluster.list({success: callback, error: onError}); + //we have no cluster button for this break; case "OpenNebula.VM.list": callback = updateVMachinesView; @@ -396,8 +411,7 @@ function confirmButtonListener(){ $('div#confirm_dialog button').button(); - //add listeners - $('.confirm_button').click(function(){ + $('.confirm_button').live("click",function(){ val=$(this).val(); tip=""; //supported cases @@ -490,8 +504,8 @@ function confirmWithSelectListener(){ }); $('div#confirm_with_select_dialog button').button(); - //add listeners - $('.confirm_with_select_button').click(function(){ + + $( '.confirm_with_select_button').live("click",function(){ val=$(this).val(); tip=""; dataTable=null; @@ -512,7 +526,7 @@ function confirmWithSelectListener(){ dataTable="null"; select_var = clusters_select; callback = function (){ - OpenNebula.Host.list({success: updateClustersView,error: onError}); + OpenNebula.Cluster.list({success: updateClustersView,error: onError}); } break; case "OpenNebula.VM.deploy": @@ -608,8 +622,9 @@ function confirmWithSelectListener(){ //of the element, it sends actions to OpenNebula.js. This function //handles all the simple actions of the UI: delete, enables, disables, etc... function actionButtonListener(){ + //Listener - $('.action_button').click(function(){ + $('.action_button').live("click",function(){ dataTable=null; //Which dataTable should be updated afterwards? callback = null; //Which callback function should be used on success? @@ -727,9 +742,8 @@ function actionButtonListener(){ nodes_id.push($(this).val()); //Calling action(id,callback,error_callback) if (extra_param!=null){ //action with two parameters - data = extra_param; - data.id = $(this).val(); - (eval(action)({data: data, success: callback, error: onError})); + var data_arg = {cluster_id: extra_param, id: $(this).val()}; + (eval(action)({data: data_arg, success: callback, error: onError})); } else { //action with one parameter (eval(action)({data:{id:$(this).val()},success: callback,error: onError})); }; @@ -798,11 +812,11 @@ function setupImageAttributesDialogs(){
\ \ \ - \ + \
\
\ \ - \ + \
\
\ \ @@ -815,7 +829,7 @@ function setupImageAttributesDialogs(){ autoOpen:false, width:400, modal:true, - height:270, + height:200, resizable:false, }); @@ -1034,7 +1048,7 @@ function createClusterDialog(){ //If it's successfull we refresh the list. OpenNebula.Cluster.create({ data:cluster_json, success: function(){ - OpenNebula.Cluster.list(updateClustersView,onError)}, + OpenNebula.Cluster.list({success:updateClustersView,error:onError})}, error: onError}); $create_cluster_dialog.dialog('close'); return false; @@ -1887,10 +1901,10 @@ function createVMachineDialog(){ }); $('button#create_vm_form_manual').click(function(){ - template = $('#vm_template').val(); + template = $('#textarea_vm_template').val(); //wrap it in the "vm" object - template = {vm: {vm_raw: template}}; + template = {"vm": {"vm_raw": template}}; OpenNebula.VM.create({data: template, success: addVMachineElement, @@ -2078,7 +2092,7 @@ function createImageDialog(){ break; } obj = { "image" : img_json }; - OpenNebula.Image.create({data: obj,success: addImageElement,error: onError}); + OpenNebula.Image.register({data: obj,success: addImageElement,error: onError}); $create_image_dialog.dialog('close'); return false; @@ -2205,9 +2219,12 @@ function updateSingleElement(element,data_table,tag){ tr = $(tag).parents('tr')[0]; position = data_table.fnGetPosition(tr); data_table.fnUpdate(element,position,0); + $('input',data_table).trigger("change"); + } function tableCheckboxesListener(dataTable){ + context = dataTable.parents('form'); last_action_b = $('.last_action_button',context); $('.top_button, .list_button',context).button("disable"); @@ -2217,13 +2234,21 @@ function tableCheckboxesListener(dataTable){ $('.new_button',context).button("enable"); //listen to changes - $('input',dataTable).click(function(){ + $('input',dataTable).live("change",function(){ dataTable = $(this).parents('table').dataTable(); context = dataTable.parents('form'); last_action_b = $('.last_action_button',context); - nodes_length = $('input:checked',dataTable.fnGetNodes()).length; + nodes = dataTable.fnGetNodes(); + total_length = nodes.length; + checked_length = $('input:checked',nodes).length; - if (nodes_length){ + if (total_length == checked_length){ + $('.check_all',dataTable).attr("checked","checked"); + } else { + $('.check_all',dataTable).removeAttr("checked"); + } + + if (checked_length){ $('.top_button, .list_button',context).button("enable"); if (last_action_b.length && last_action_b.val().length){ last_action_b.button("enable"); @@ -2241,6 +2266,7 @@ function tableCheckboxesListener(dataTable){ function deleteElement(data_table,tag){ tr = $(tag).parents('tr')[0]; data_table.fnDeleteRow(tr); + $('input',data_table).trigger("change"); } function addElement(element,data_table){ @@ -2253,18 +2279,24 @@ function hostElementArray(host_json){ if (!acpu) {acpu=100}; acpu = acpu - parseInt(host.HOST_SHARE.CPU_USAGE); - total_mem = parseInt(host.HOST_SHARE.MAX_MEM); free_mem = parseInt(host.HOST_SHARE.FREE_MEM); - ratio_mem = Math.round(((total_mem - free_mem) / total_mem) * 100); + + if (total_mem == 0) { + ratio_mem = 0; + } else { + ratio_mem = Math.round(((total_mem - free_mem) / total_mem) * 100); + } total_cpu = parseInt(host.HOST_SHARE.MAX_CPU); used_cpu = Math.max(total_cpu - parseInt(host.HOST_SHARE.USED_CPU),acpu); - ratio_cpu = Math.round(((total_cpu - used_cpu) / total_cpu) * 100); - - + if (total_cpu == 0) { + ratio_cpu = 0; + } else { + ratio_cpu = Math.round(((total_cpu - used_cpu) / total_cpu) * 100); + } pb_mem = '
\ @@ -2306,7 +2338,8 @@ function hostElementArray(host_json){ //Adds a listener to show the extended info when clicking on a row function hostInfoListener(){ - $('#tbodyhosts tr').click(function(e){ + $('#tbodyhosts tr').live("click",function(e){ + //do nothing if we are clicking a checkbox! if ($(e.target).is('input')) {return true;} @@ -2327,13 +2360,17 @@ function hostInfoListener(){ //~ } function vMachineElementArray(vm_json){ - vm = vm_json.VM; + var vm = vm_json.VM; + var state = OpenNebula.Helper.resource_state("vm",vm.STATE); + if (state == "ACTIVE") { + state = OpenNebula.Helper.resource_state("vm_lcm",vm.LCM_STATE); + } return [ '', vm.ID, vm.USERNAME ? vm.USERNAME : getUserName(vm.UID), vm.NAME, - OpenNebula.Helper.resource_state("vm",vm.STATE), + state, vm.CPU, humanize_size(vm.MEMORY), vm.HISTORY ? vm.HISTORY.HOSTNAME : "--", @@ -2343,7 +2380,8 @@ function vMachineElementArray(vm_json){ //Adds a listener to show the extended info when clicking on a row function vMachineInfoListener(){ - $('#tbodyvmachines tr').click(function(e){ + + $('#tbodyvmachines tr').live("click", function(e){ if ($(e.target).is('input')) {return true;} aData = dataTable_vMachines.fnGetData(this); id = $(aData[0]).val(); @@ -2354,9 +2392,9 @@ function vMachineInfoListener(){ function vNetworkElementArray(vn_json){ network = vn_json.VNET; - if (network.TOTAL_LEASES != undefined){ + if (network.TOTAL_LEASES){ total_leases = network.TOTAL_LEASES; - }else if (network.LEASES.LEASE != undefined){ + }else if (network.LEASES && network.LEASES.LEASE){ total_leases = network.LEASES.LEASE.length ? network.LEASES.LEASE.length : "1"; } else{ total_leases = "0"; @@ -2373,7 +2411,8 @@ function vNetworkElementArray(vn_json){ } //Adds a listener to show the extended info when clicking on a row function vNetworkInfoListener(){ - $('#tbodyvnetworks tr').click(function(e){ + + $('#tbodyvnetworks tr').live("click", function(e){ if ($(e.target).is('input')) {return true;} aData = dataTable_vNetworks.fnGetData(this); id = $(aData[0]).val(); @@ -2384,10 +2423,16 @@ function vNetworkInfoListener(){ function userElementArray(user_json){ user = user_json.USER; + if (!user.NAME || user.NAME == {}){ + name = ""; + } else { + name = user.NAME; + } + return [ '', user.ID, - user.NAME + name ] } @@ -2407,8 +2452,9 @@ function imageElementArray(image_json){ ]; } -function imageInfoListener(){ - $('#tbodyimages tr').click(function(e){ +function imageInfoListener(target){ + + $('#tbodyimages tr').live("click",function(e){ if ($(e.target).is('input')) {return true;} aData = dataTable_images.fnGetData(this); id = $(aData[0]).val(); @@ -2461,7 +2507,9 @@ function updateImageSelect(image_list){ images_select=""; images_select += ""; $.each(image_list, function(){ - images_select += ""; + if ((this.IMAGE.STATE < 3) && (this.IMAGE.STATE > 0)){ + images_select += ''; + } }); //update static selectors @@ -2582,8 +2630,9 @@ function onError(request,error_json) { }; //Parse known errors: - var action_error = new RegExp("^\\[(\\w+)\\] Error trying to (\\w+) (\\w+) \\[(\\w+)\\].*Reason: (.*)\.$"); - var get_error = new RegExp("^\\[(\\w+)\\] Error getting (\\w+) \\[(\\w+)\\]\.$"); + var action_error = /^\[(\w+)\] Error trying to (\w+) (\w+) \[(\w+)\].*Reason: (.*)\.$/; + var action_error_noid = /^\[(\w+)\] Error trying to (\w+) (\w+) (.*)\.$/; + var get_error = /^\[(\w+)\] Error getting (\w+) \[(\w+)\]\.$/; var auth_error = /^\[(\w+)\] User \[.\] not authorized to perform (\w+) on (\w+) \[?(\w+)\]?\.?$/; if (m = message.match(action_error)) { @@ -2592,6 +2641,11 @@ function onError(request,error_json) { object = m[3]; id = m[4]; reason = m[5]; + } else if (m = message.match(action_error_noid)) { + method = m[1]; + action = m[2]; + object = m[3]; + reason = m[4]; } else if (m = message.match(get_error)) { method = m[1]; action = "SHOW"; @@ -2634,7 +2688,7 @@ function onError(request,error_json) { function updateHostElement(request, host_json){ id = host_json.HOST.ID; element = hostElementArray(host_json); - updateSingleElement(element,dataTable_hosts,'#host_'+id) + updateSingleElement(element,dataTable_hosts,'#host_'+id); } function deleteHostElement(req){ @@ -2642,10 +2696,9 @@ function deleteHostElement(req){ } function addHostElement(request,host_json){ + id = host_json.HOST.ID; element = hostElementArray(host_json); addElement(element,dataTable_hosts); - hostInfoListener(); - tableCheckboxesListener(dataTable_hosts); } function updateHostsView (request,host_list){ @@ -2660,10 +2713,6 @@ function updateHostsView (request,host_list){ updateView(host_list_array,dataTable_hosts); updateHostSelect(host_list); updateDashboard("hosts"); - - //We need to re-add this listener as list has been refreshed - hostInfoListener(); - tableCheckboxesListener(dataTable_hosts); } @@ -2706,12 +2755,11 @@ function deleteVMachineElement(req){ } function addVMachineElement(request,vm_json){ - notifySubmit('OpenNebula.VM.create',vm_json.VM.ID); + id = vm_json.VM.ID; + notifySubmit('OpenNebula.VM.create',id); element = vMachineElementArray(vm_json); addElement(element,dataTable_vMachines); - vMachineInfoListener(); updateVMInfo(null,vm_json); - tableCheckboxesListener(dataTable_vMachines); } function updateVMachinesView(request, vmachine_list){ @@ -2723,8 +2771,6 @@ function updateVMachinesView(request, vmachine_list){ }); updateView(vmachine_list_array,dataTable_vMachines); - vMachineInfoListener(); - tableCheckboxesListener(dataTable_vMachines); updateDashboard("vms"); } @@ -2733,17 +2779,18 @@ function updateVNetworkElement(request, vn_json){ id = vn_json.VNET.ID; element = vNetworkElementArray(vn_json); updateSingleElement(element,dataTable_vNetworks,'#vnetwork_'+id); - tableCheckboxesListener(dataTable_vNetworks); } function deleteVNetworkElement(req){ deleteElement(dataTable_vNetworks,'#vnetwork_'+req.request.data); + //How to delete vNetwork select option here? } function addVNetworkElement(request,vn_json){ element = vNetworkElementArray(vn_json); addElement(element,dataTable_vNetworks); - vNetworkInfoListener(); + vnetworks_select += ""; + $('div.vm_section#networks select#NETWORK').html(vnetworks_select); } function updateVNetworksView(request, network_list){ @@ -2756,9 +2803,7 @@ function updateVNetworksView(request, network_list){ updateView(network_list_array,dataTable_vNetworks); updateNetworkSelect(network_list); - vNetworkInfoListener(); updateDashboard("vnets"); - tableCheckboxesListener(dataTable_vNetworks); } @@ -2766,7 +2811,6 @@ function updateUserElement(request, user_json){ id = user_json.USER.ID; element = userElementArray(user_json); updateSingleElement(element,dataTable_users,'#user_'+id); - tableCheckboxesListener(dataTable_users); } function deleteUserElement(req){ @@ -2787,7 +2831,6 @@ function updateUsersView(request,users_list){ }); updateView(user_list_array,dataTable_users); updateDashboard("users"); - tableCheckboxesListener(dataTable_users); } @@ -2795,12 +2838,27 @@ function updateImageElement(request, image_json){ id = image_json.IMAGE.ID; element = imageElementArray(image_json); updateSingleElement(element,dataTable_images,'#image_'+id); - tableCheckboxesListener(dataTable_images); - imageInfoListener(); + if ((image_json.IMAGE.STATE < 3) && + (image_json.IMAGE.STATE > 0) && + ($('#img_sel_'+id,images_select).length == 0)){ + images_select += ''; + } + else { + tag = 'option#img_sel_'+id; + select = $(''); + $(tag,select).remove(); + images_select = $(select).html(); + } + $('div.vm_section#disks select#IMAGE').html(images_select); } function deleteImageElement(req){ deleteElement(dataTable_images,'#image_'+req.request.data); + tag = 'option#img_sel_'+req.request.data; + select = $(''); + $(tag,select).remove(); + images_select = $(select).html(); + $('div.vm_section#disks select#IMAGE').html(images_select); } function addImageElement(request, image_json){ @@ -2817,8 +2875,6 @@ function updateImagesView(request, images_list){ updateView(image_list_array,dataTable_images); updateImageSelect(images_list); - imageInfoListener(); - tableCheckboxesListener(dataTable_images); updateDashboard("images"); @@ -2998,7 +3054,7 @@ function updateVMInfo(request,vm){ \ \ LCM State\ - '+OpenNebula.Helper.resource_state("vm",vm_info.LCMSTATE)+'\ + '+OpenNebula.Helper.resource_state("vm_lcm",vm_info.LCM_STATE)+'\ \ \ Start time\ @@ -3006,7 +3062,7 @@ function updateVMInfo(request,vm){ \ \ Deploy ID\ - '+(vm_info.DEPLOY_ID ? vm_info.DEPLOY_ID : "-")+'\ + '+(typeof(vm_info.DEPLOY_ID) == "object" ? "-" : vm_info.DEPLOY_ID)+'\ \ \ \ @@ -3093,14 +3149,16 @@ function updateVNetworkInfo(request,vn){ \ \ \ -
Public'+(parseInt(vn_info.PUBLIC) ? "yes" : "no" )+'
\ - \ +
'; + if (vn_info.TEMPLATE.TYPE == "FIXED"){ + rendered_info += '\ \ \ '+ prettyPrintJSON(vn_info.LEASES)+ - '
Leases information
\ -
\ + ''; + } + rendered_info += '
\
\ \ '+ @@ -3144,11 +3202,11 @@ function updateImageInfo(request,img){ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ @@ -3156,7 +3214,7 @@ function updateImageInfo(request,img){ \ \ \ - \ + \ \
Virtual Network template
Public'+(img_info.PUBLIC ? "yes" : "no")+''+(parseInt(img_info.PUBLIC) ? "yes" : "no")+'
Persistent'+(img_info.PERSISTENT ? "yes" : "no")+''+(parseInt(img_info.PERSISTENT) ? "yes" : "no")+'
Source
State'+img_info.STATE+''+OpenNebula.Helper.resource_state("image",img_info.STATE)+'
\
\ diff --git a/src/sunstone/public/js/one-ui_views.templates.js b/src/sunstone/public/js/one-ui_views.templates.js index 67dbaa50b6..6a3a83873d 100644 --- a/src/sunstone/public/js/one-ui_views.templates.js +++ b/src/sunstone/public/js/one-ui_views.templates.js @@ -168,14 +168,14 @@ var hostlist_tmpl =
\
\ \ + \ \
\
\ - \ + \
\ \ \ @@ -757,7 +757,7 @@ var create_vm_tmpl = \

Write the Virtual Machine template here

\
\ - \ + \
\
\
\ @@ -895,7 +895,7 @@ var userlist_tmpl = '\
\
\ - OpenNebula.VM.list\ + OpenNebula.User.list\
\
\ \ @@ -1042,10 +1042,13 @@ var create_image_tmpl =
\
\ \ - Provide a path
\ - Provide a source
\ - Create an empty datablock\ -
Please choose path if you have a file-based image. Choose source otherwise or create an empty datablock disk.
\ + \ +
\ + \ +
\ + \ + \ +
Please choose path if you have a file-based image. Choose source otherwise or create an empty datablock disk.

\
\
\ \ diff --git a/src/sunstone/public/js/opennebula.js b/src/sunstone/public/js/opennebula.js index 74fdbe8027..310e88a7d3 100644 --- a/src/sunstone/public/js/opennebula.js +++ b/src/sunstone/public/js/opennebula.js @@ -65,6 +65,25 @@ var OpenNebula = { "DONE", "FAILED"][value]; break; + case "VM_LCM","vm_lcm": + return ["LCM_INIT", + "PROLOG", + "BOOT", + "RUNNING", + "MIGRATE", + "SAVE_STOP", + "SAVE_SUSPEND", + "SAVE_MIGRATE", + "PROLOG_MIGRATE", + "PROLOG_RESUME", + "EPILOG_STOP", + "EPILOG", + "SHUTDOWN", + "CANCEL", + "FAILURE", + "CLEANUP", + "UNKNOWN"][value]; + break; case "IMAGE","image": return ["INIT", "READY", @@ -126,7 +145,9 @@ var OpenNebula = { var p_pool = []; - pool = response[pool_name][type]; + if (response[pool_name]) { + pool = response[pool_name][type]; + } else { pull = null }; if (pool == null) { @@ -267,7 +288,7 @@ var OpenNebula = { url: "/host", type: "POST", dataType: "json", - data: data, + data: JSON.stringify(data), success: function(response) { if (callback) diff --git a/src/sunstone/public/js/base64.js b/src/sunstone/public/js/vendor/base64.js similarity index 100% rename from src/sunstone/public/js/base64.js rename to src/sunstone/public/js/vendor/base64.js diff --git a/src/sunstone/public/js/jquery-1.4.4.min.js b/src/sunstone/public/js/vendor/jquery-1.4.4.min.js similarity index 100% rename from src/sunstone/public/js/jquery-1.4.4.min.js rename to src/sunstone/public/js/vendor/jquery-1.4.4.min.js diff --git a/src/sunstone/public/js/jquery-ui-1.8.7.custom.min.js b/src/sunstone/public/js/vendor/jquery-ui-1.8.7.custom.min.js similarity index 100% rename from src/sunstone/public/js/jquery-ui-1.8.7.custom.min.js rename to src/sunstone/public/js/vendor/jquery-ui-1.8.7.custom.min.js diff --git a/src/sunstone/public/js/jquery.dataTables.min.js b/src/sunstone/public/js/vendor/jquery.dataTables.min.js similarity index 100% rename from src/sunstone/public/js/jquery.dataTables.min.js rename to src/sunstone/public/js/vendor/jquery.dataTables.min.js diff --git a/src/sunstone/public/js/jquery.jgrowl_minimized.js b/src/sunstone/public/js/vendor/jquery.jgrowl_minimized.js similarity index 100% rename from src/sunstone/public/js/jquery.jgrowl_minimized.js rename to src/sunstone/public/js/vendor/jquery.jgrowl_minimized.js diff --git a/src/sunstone/public/js/jquery.layout.min-1.2.0.js b/src/sunstone/public/js/vendor/jquery.layout.min-1.2.0.js similarity index 100% rename from src/sunstone/public/js/jquery.layout.min-1.2.0.js rename to src/sunstone/public/js/vendor/jquery.layout.min-1.2.0.js diff --git a/src/sunstone/one-ui.rb b/src/sunstone/sunstone-server.rb similarity index 87% rename from src/sunstone/one-ui.rb rename to src/sunstone/sunstone-server.rb index e8f5a4b24c..f855f3e0bc 100755 --- a/src/sunstone/one-ui.rb +++ b/src/sunstone/sunstone-server.rb @@ -16,30 +16,21 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -############################################################################## -# Environment Configuration for the Server -############################################################################## -HOST = "127.0.0.1" -PORT = "4567" - - ############################################################################## # Required libraries ############################################################################## require 'rubygems' require 'sinatra' -require 'models/OneUI' +require 'models/SunstoneServer' ############################################################################## # Sinatra Configuration ############################################################################## -set :host, HOST -set :port, PORT - use Rack::Session::Pool + ############################################################################## # Helpers ############################################################################## @@ -54,7 +45,7 @@ helpers do user = auth.credentials[0] sha1_pass = Digest::SHA1.hexdigest(auth.credentials[1]) - rc = OneUI.authorize(user, sha1_pass) + rc = SunstoneServer.authorize(user, sha1_pass) if rc[1] session["user"] = user session["user_id"] = rc[1] @@ -86,7 +77,7 @@ before do unless request.path=='/login' || request.path=='/' halt 401 unless authorized? - @OneUI = OneUI.new(session["user"], session["password"]) + @SunstoneServer = SunstoneServer.new(session["user"], session["password"]) end end @@ -132,44 +123,44 @@ end # GET Pool information ############################################################################## get '/:pool' do - @OneUI.get_pool(params[:pool], session["user_id"]) + @SunstoneServer.get_pool(params[:pool]) end ############################################################################## # GET Resource information ############################################################################## get '/:resource/:id' do - @OneUI.get_resource(params[:resource], params[:id]) + @SunstoneServer.get_resource(params[:resource], params[:id]) end ############################################################################## # Delete Resource ############################################################################## delete '/:resource/:id' do - @OneUI.delete_resource(params[:resource], params[:id]) + @SunstoneServer.delete_resource(params[:resource], params[:id]) end ############################################################################## # Create a new Resource ############################################################################## post '/:pool' do - @OneUI.create_resource(params[:pool], request.body.read) + @SunstoneServer.create_resource(params[:pool], request.body.read) end ############################################################################## # Perform an action on a Resource ############################################################################## post '/:resource/:id/action' do - @OneUI.perform_action(params[:resource], params[:id], request.body.read) + @SunstoneServer.perform_action(params[:resource], params[:id], request.body.read) end ############################################################################## # Config and Logs ############################################################################## get '/config' do - @OneUI.get_configuration + @SunstoneServer.get_configuration(session["user_id"]) end get '/vm/:id/log' do - @OneUI.get_vm_log(params[:id].to_i) + @SunstoneServer.get_vm_log(params[:id]) end diff --git a/src/sunstone/templates/index.html b/src/sunstone/templates/index.html index a6c483b362..9100ba8156 100644 --- a/src/sunstone/templates/index.html +++ b/src/sunstone/templates/index.html @@ -4,18 +4,18 @@ OpenNebula Admin Console - + - - - - - - + + + + + + @@ -27,7 +27,6 @@
-
@@ -40,7 +39,6 @@