diff --git a/include/DispatchManager.h b/include/DispatchManager.h index b9d5e94cdd..0bbc488f1d 100644 --- a/include/DispatchManager.h +++ b/include/DispatchManager.h @@ -210,6 +210,15 @@ public: int resubmit( int vid); + /** + * Reboots a VM preserving any resource and RUNNING state + * @param vid VirtualMachine identification + * @return 0 on success, -1 if the VM does not exits or -2 if the VM is + * in a wrong a state + */ + int reboot( + int vid); + private: /** * Thread id for the Dispatch Manager diff --git a/include/LifeCycleManager.h b/include/LifeCycleManager.h index 4ad0986836..4206bbd51c 100644 --- a/include/LifeCycleManager.h +++ b/include/LifeCycleManager.h @@ -67,6 +67,7 @@ public: LIVE_MIGRATE, /**< Sent by the DM to live-migrate a VM */ SHUTDOWN, /**< Sent by the DM to shutdown a running VM */ RESTART, /**< Sent by the DM to restart a deployed VM */ + REBOOT, /**< Sent by the DM to reboot a running VM */ DELETE, /**< Sent by the DM to delete a VM */ CLEAN, /**< Sent by the DM to cleanup a VM for resubmission*/ FINALIZE @@ -194,6 +195,8 @@ private: void restart_action(int vid); + void reboot_action(int vid); + void delete_action(int vid); void clean_action(int vid); diff --git a/include/Nebula.h b/include/Nebula.h index ef6575cff6..41718f0f59 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -407,7 +407,7 @@ private: // Configuration // --------------------------------------------------------------- - NebulaTemplate * nebula_configuration; + OpenNebulaTemplate * nebula_configuration; // --------------------------------------------------------------- // Nebula Pools diff --git a/include/NebulaTemplate.h b/include/NebulaTemplate.h index 06357214df..fe213e89fa 100644 --- a/include/NebulaTemplate.h +++ b/include/NebulaTemplate.h @@ -20,16 +20,25 @@ #include "Template.h" #include +/** + * This class provides the basic abstraction for OpenNebula configuration files + */ class NebulaTemplate : public Template -{ +{ public: + // ----------------------------------------------------------------------- + // ----------------------------------------------------------------------- - NebulaTemplate(string& etc_location, string& var_location); + NebulaTemplate(const string& etc_location, const char * _conf_name) + { + conf_file = etc_location + _conf_name; + } - ~NebulaTemplate(){}; + virtual ~NebulaTemplate(){}; + + // ----------------------------------------------------------------------- + // ----------------------------------------------------------------------- - static const char * conf_name; - int get(const char * name, vector& values) const { string _name(name); @@ -50,41 +59,95 @@ public: Template::get(_name,values); }; + + void get(const char *name, unsigned int& values) const + { + int ival; + + NebulaTemplate::get(name, ival); + + values = static_cast(ival); + }; void get(const char * name, time_t& values) const { - const SingleAttribute * sattr; - vector attr; + const SingleAttribute * sattr; + vector attr; - string _name(name); + string _name(name); if ( Template::get(_name,attr) == 0 ) { - values = 0; - return; + values = 0; + return; } sattr = dynamic_cast(attr[0]); if ( sattr != 0 ) { - istringstream is; - - is.str(sattr->value()); - is >> values; + istringstream is; + + is.str(sattr->value()); + is >> values; } else - values = 0; + values = 0; }; -private: - friend class Nebula; - + // ----------------------------------------------------------------------- + // ----------------------------------------------------------------------- + + /** + * Parse and loads the configuration in the template + */ + int load_configuration(); + +protected: + /** + * Full path to the configuration file + */ string conf_file; + /** + * Defaults for the configuration file + */ map conf_default; + + /** + * Sets the defaults value for the template + */ + virtual void set_conf_default() = 0; +}; + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- + +class OpenNebulaTemplate : public NebulaTemplate +{ +public: + + OpenNebulaTemplate(const string& etc_location, const string& _var_location): + NebulaTemplate(etc_location, conf_name), var_location(_var_location) + {}; - int load_configuration(); + ~OpenNebulaTemplate(){}; + +private: + /** + * Name for the configuration file, oned.conf + */ + static const char * conf_name; + + /** + * Path for the var directory, for defaults + */ + string var_location; + + /** + * Sets the defaults value for the template + */ + void set_conf_default(); }; diff --git a/include/VirtualMachineManager.h b/include/VirtualMachineManager.h index cab1799800..8f481973d6 100644 --- a/include/VirtualMachineManager.h +++ b/include/VirtualMachineManager.h @@ -51,6 +51,7 @@ public: CANCEL_PREVIOUS, MIGRATE, RESTORE, + REBOOT, POLL, TIMER, DRIVER_CANCEL, @@ -262,6 +263,13 @@ private: void restore_action( int vid); + /** + * Reboots a running VM. + * @param vid the id of the VM. + */ + void reboot_action( + int vid); + /** * Polls a VM. * @param vid the id of the VM. diff --git a/include/VirtualMachineManagerDriver.h b/include/VirtualMachineManagerDriver.h index 2d75485ed4..c37c63e28e 100644 --- a/include/VirtualMachineManagerDriver.h +++ b/include/VirtualMachineManagerDriver.h @@ -127,6 +127,15 @@ private: const int oid, const string& drv_msg) const; + /** + * Sends a reboot request to the MAD: "REBOOT ID XML_DRV_MSG" + * @param oid the virtual machine id. + * @param drv_msg xml data for the mad operation + */ + void reboot ( + const int oid, + const string& drv_msg) const; + /** * Sends a cancel request to the MAD: "CANCEL ID XML_DRV_MSG" * @param oid the virtual machine id. diff --git a/install.sh b/install.sh index cf822b82a8..fc82f1377b 100755 --- a/install.sh +++ b/install.sh @@ -253,6 +253,9 @@ SUNSTONE_DIRS="$SUNSTONE_LOCATION/models \ $SUNSTONE_LOCATION/public/js/plugins \ $SUNSTONE_LOCATION/public/js/user-plugins \ $SUNSTONE_LOCATION/public/css \ + $SUNSTONE_LOCATION/public/locale \ + $SUNSTONE_LOCATION/public/locale/en_US \ + $SUNSTONE_LOCATION/public/locale/ru \ $SUNSTONE_LOCATION/public/vendor \ $SUNSTONE_LOCATION/public/vendor/jQueryLayout \ $SUNSTONE_LOCATION/public/vendor/dataTables \ @@ -282,6 +285,31 @@ OZONES_DIRS="$OZONES_LOCATION/lib \ $OZONES_LOCATION/public/images \ $OZONES_LOCATION/public/css" +SELF_SERVICE_DIRS="\ + $LIB_LOCATION/ruby/cloud/occi/ui \ + $LIB_LOCATION/ruby/cloud/occi/ui/templates \ + $LIB_LOCATION/ruby/cloud/occi/ui/views \ + $LIB_LOCATION/ruby/cloud/occi/ui/public \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/css \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/customize \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/images \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/js \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/js/plugins \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/locale \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/locale/en_US \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/locale/es_ES \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/vendor \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/jQueryLayout \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/dataTables \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/jQueryUI \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/jQueryUI/images \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/jQuery \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/jGrowl \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/flot \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/crypto-js \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/fileuploader \ + $LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/xml2json" + OZONES_CLIENT_DIRS="$LIB_LOCATION/ruby \ $LIB_LOCATION/ruby/OpenNebula \ $LIB_LOCATION/ruby/cli \ @@ -308,14 +336,14 @@ CONF_CLI_DIRS="$ETC_LOCATION/cli" if [ "$CLIENT" = "yes" ]; then MAKE_DIRS="$MAKE_DIRS $LIB_ECO_CLIENT_DIRS $LIB_OCCI_CLIENT_DIRS \ $LIB_OCA_CLIENT_DIRS $LIB_CLI_CLIENT_DIRS $CONF_CLI_DIRS \ - $ETC_LOCATION $OZONES_CLIENT_DIRS" + $ETC_LOCATION $OZONES_CLIENT_DIRS $SELF_SERVICE_DIRS" elif [ "$SUNSTONE" = "yes" ]; then MAKE_DIRS="$MAKE_DIRS $SUNSTONE_DIRS $LIB_OCA_CLIENT_DIRS" elif [ "$OZONES" = "yes" ]; then MAKE_DIRS="$MAKE_DIRS $OZONES_DIRS $OZONES_CLIENT_DIRS $LIB_OCA_CLIENT_DIRS" else MAKE_DIRS="$MAKE_DIRS $SHARE_DIRS $ETC_DIRS $LIB_DIRS $VAR_DIRS \ - $OZONES_DIRS $OZONES_CLIENT_DIRS $SUNSTONE_DIRS" + $OZONES_DIRS $OZONES_CLIENT_DIRS $SUNSTONE_DIRS $SELF_SERVICE_DIRS" fi #------------------------------------------------------------------------------- @@ -426,6 +454,8 @@ INSTALL_SUNSTONE_FILES=( SUNSTONE_PUBLIC_VENDOR_JQUERYLAYOUT:$SUNSTONE_LOCATION/public/vendor/jQueryLayout SUNSTONE_PUBLIC_VENDOR_FLOT:$SUNSTONE_LOCATION/public/vendor/flot 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 ) INSTALL_SUNSTONE_ETC_FILES=( @@ -465,6 +495,28 @@ INSTALL_OZONES_ETC_FILES=( OZONES_ETC_FILES:$ETC_LOCATION ) +INSTALL_SELF_SERVICE_FILES=( + SELF_SERVICE_TEMPLATE_FILES:$LIB_LOCATION/ruby/cloud/occi/ui/templates + SELF_SERVICE_VIEWS_FILES:$LIB_LOCATION/ruby/cloud/occi/ui/views + SELF_SERVICE_PUBLIC_JS_FILES:$LIB_LOCATION/ruby/cloud/occi/ui/public/js + SELF_SERVICE_PUBLIC_JS_PLUGINS_FILES:$LIB_LOCATION/ruby/cloud/occi/ui/public/js/plugins + SELF_SERVICE_PUBLIC_CSS_FILES:$LIB_LOCATION/ruby/cloud/occi/ui/public/css + SELF_SERVICE_PUBLIC_CUSTOMIZE_FILES:$LIB_LOCATION/ruby/cloud/occi/ui/public/customize + SELF_SERVICE_PUBLIC_VENDOR_DATATABLES:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/dataTables + SELF_SERVICE_PUBLIC_VENDOR_JGROWL:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/jGrowl + SELF_SERVICE_PUBLIC_VENDOR_JQUERY:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/jQuery + SELF_SERVICE_PUBLIC_VENDOR_JQUERYUI:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/jQueryUI + SELF_SERVICE_PUBLIC_VENDOR_JQUERYUIIMAGES:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/jQueryUI/images + SELF_SERVICE_PUBLIC_VENDOR_JQUERYLAYOUT:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/jQueryLayout + SELF_SERVICE_PUBLIC_VENDOR_FLOT:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/flot + SELF_SERVICE_PUBLIC_VENDOR_CRYPTOJS:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/crypto-js + SELF_SERVICE_PUBLIC_VENDOR_FILEUPLOADER:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/fileuploader + SELF_SERVICE_PUBLIC_VENDOR_XML2JSON:$LIB_LOCATION/ruby/cloud/occi/ui/public/vendor/xml2json + SELF_SERVICE_PUBLIC_IMAGES_FILES:$LIB_LOCATION/ruby/cloud/occi/ui/public/images + SELF_SERVICE_PUBLIC_LOCALE_EN_US:$LIB_LOCATION/ruby/cloud/occi/ui/public/locale/en_US + SELF_SERVICE_PUBLIC_LOCALE_ES_ES:$LIB_LOCATION/ruby/cloud/occi/ui/public/locale/es_ES +) + INSTALL_ETC_FILES=( ETC_FILES:$ETC_LOCATION VMWARE_ETC_FILES:$ETC_LOCATION @@ -528,7 +580,6 @@ RUBY_LIB_FILES="src/mad/ruby/ActionManager.rb \ src/mad/ruby/ssh_stream.rb \ src/vnm_mad/one_vnm.rb \ src/mad/ruby/Ganglia.rb \ - src/mad/ruby/vmwarelib.rb \ src/oca/ruby/OpenNebula.rb \ src/tm_mad/TMScript.rb \ src/authm_mad/remotes/ssh/ssh_auth.rb \ @@ -587,6 +638,7 @@ VMM_EXEC_KVM_SCRIPTS="src/vmm_mad/remotes/kvm/cancel \ src/vmm_mad/remotes/kvm/migrate \ src/vmm_mad/remotes/kvm/migrate_local \ src/vmm_mad/remotes/kvm/restore \ + src/vmm_mad/remotes/kvm/reboot \ src/vmm_mad/remotes/kvm/save \ src/vmm_mad/remotes/kvm/poll \ src/vmm_mad/remotes/kvm/poll_ganglia \ @@ -601,6 +653,7 @@ VMM_EXEC_XEN_SCRIPTS="src/vmm_mad/remotes/xen/cancel \ src/vmm_mad/remotes/xen/xenrc \ src/vmm_mad/remotes/xen/migrate \ src/vmm_mad/remotes/xen/restore \ + src/vmm_mad/remotes/xen/reboot \ src/vmm_mad/remotes/xen/save \ src/vmm_mad/remotes/xen/poll \ src/vmm_mad/remotes/xen/poll_ganglia \ @@ -614,10 +667,12 @@ VMM_EXEC_VMWARE_SCRIPTS="src/vmm_mad/remotes/vmware/cancel \ src/vmm_mad/remotes/vmware/deploy \ src/vmm_mad/remotes/vmware/migrate \ src/vmm_mad/remotes/vmware/restore \ + src/vmm_mad/remotes/vmware/reboot \ src/vmm_mad/remotes/vmware/save \ src/vmm_mad/remotes/vmware/poll \ src/vmm_mad/remotes/vmware/checkpoint \ - src/vmm_mad/remotes/vmware/shutdown" + src/vmm_mad/remotes/vmware/shutdown \ + src/vmm_mad/remotes/vmware/vmware_driver.rb" #------------------------------------------------------------------------------- # Information Manager Probes, to be installed under $REMOTES_LOCATION/im @@ -727,7 +782,9 @@ LVM_TM_COMMANDS_LIB_FILES="src/tm_mad/lvm/tm_clone.sh \ VMWARE_TM_COMMANDS_LIB_FILES="src/tm_mad/vmware/tm_clone.sh \ src/tm_mad/vmware/tm_ln.sh \ - src/tm_mad/vmware/tm_mv.sh" + src/tm_mad/vmware/tm_mv.sh \ + src/tm_mad/vmware/functions.sh \ + src/tm_mad/vmware/tm_context.sh" #------------------------------------------------------------------------------- # Image Repository drivers, to be installed under $REMOTES_LOCATION/image @@ -761,6 +818,7 @@ ONEDB_MIGRATOR_FILES="src/onedb/2.0_to_2.9.80.rb \ ETC_FILES="share/etc/oned.conf \ share/etc/defaultrc \ + src/scheduler/etc/sched.conf \ src/cli/etc/group.default" VMWARE_ETC_FILES="src/vmm_mad/remotes/vmware/vmwarerc" @@ -1040,7 +1098,8 @@ SUNSTONE_PUBLIC_JS_FILES="src/sunstone/public/js/layout.js \ src/sunstone/public/js/login.js \ src/sunstone/public/js/sunstone.js \ src/sunstone/public/js/sunstone-util.js \ - src/sunstone/public/js/opennebula.js" + src/sunstone/public/js/opennebula.js \ + src/sunstone/public/js/locale.js" SUNSTONE_PUBLIC_JS_PLUGINS_FILES="\ src/sunstone/public/js/plugins/dashboard-tab.js \ @@ -1052,7 +1111,8 @@ SUNSTONE_PUBLIC_JS_PLUGINS_FILES="\ src/sunstone/public/js/plugins/users-tab.js \ src/sunstone/public/js/plugins/vms-tab.js \ src/sunstone/public/js/plugins/acls-tab.js \ - src/sunstone/public/js/plugins/vnets-tab.js" + src/sunstone/public/js/plugins/vnets-tab.js \ + src/sunstone/public/js/plugins/config-tab.js" SUNSTONE_PUBLIC_CSS_FILES="src/sunstone/public/css/application.css \ src/sunstone/public/css/layout.css \ @@ -1109,6 +1169,19 @@ src/sunstone/public/vendor/flot/LICENSE.txt \ src/sunstone/public/vendor/flot/NOTICE \ src/sunstone/public/vendor/flot/README.txt" +SUNSTONE_PUBLIC_VENDOR_CRYPTOJS="\ +src/sunstone/public/vendor/crypto-js/NOTICE \ +src/sunstone/public/vendor/crypto-js/2.3.0-crypto-sha1.js \ +src/sunstone/public/vendor/crypto-js/NEW-BSD-LICENSE.txt" + +SUNSTONE_PUBLIC_VENDOR_FILEUPLOADER="\ +src/sunstone/public/vendor/fileuploader/NOTICE \ +src/sunstone/public/vendor/fileuploader/fileuploader.js" + +SUNSTONE_PUBLIC_VENDOR_XML2JSON="\ +src/sunstone/public/vendor/xml2json/NOTICE \ +src/sunstone/public/vendor/xml2json/jquery.xml2json.pack.js" + SUNSTONE_PUBLIC_IMAGES_FILES="src/sunstone/public/images/ajax-loader.gif \ src/sunstone/public/images/login_over.png \ src/sunstone/public/images/login.png \ @@ -1123,6 +1196,16 @@ SUNSTONE_PUBLIC_IMAGES_FILES="src/sunstone/public/images/ajax-loader.gif \ src/sunstone/public/images/green_bullet.png \ src/sunstone/public/images/vnc_off.png \ src/sunstone/public/images/vnc_on.png" + +SUNSTONE_PUBLIC_LOCALE_EN_US="\ +src/sunstone/public/locale/en_US/en_US.js \ +" + +SUNSTONE_PUBLIC_LOCALE_RU=" +src/sunstone/public/locale/ru/ru.js \ +src/sunstone/public/locale/ru/ru_datatable.txt" + + #----------------------------------------------------------------------------- # Ozones files @@ -1183,8 +1266,9 @@ OZONES_PUBLIC_JS_FILES="src/ozones/Server/public/js/ozones.js \ src/ozones/Server/public/js/ozones-util.js \ src/sunstone/public/js/layout.js \ src/sunstone/public/js/sunstone.js \ - src/sunstone/public/js/sunstone-util.js" - + src/sunstone/public/js/sunstone-util.js \ + src/sunstone/public/js/locale.js" + OZONES_PUBLIC_CSS_FILES="src/ozones/Server/public/css/application.css \ src/ozones/Server/public/css/layout.css \ src/ozones/Server/public/css/login.css" @@ -1214,6 +1298,71 @@ OZONES_BIN_CLIENT_FILES="src/ozones/Client/bin/onevdc \ OZONES_RUBY_LIB_FILES="src/oca/ruby/OpenNebula.rb" +#----------------------------------------------------------------------------- +# Self-Service files +#----------------------------------------------------------------------------- + +SELF_SERVICE_TEMPLATE_FILES="src/cloud/occi/lib/ui/templates/login.html" +SELF_SERVICE_VIEWS_FILES="src/cloud/occi/lib/ui/views/index.erb" +SELF_SERVICE_PUBLIC_JS_FILES="src/cloud/occi/lib/ui/public/js/layout.js \ + src/cloud/occi/lib/ui/public/js/occi.js \ + src/cloud/occi/lib/ui/public/js/locale.js \ + src/cloud/occi/lib/ui/public/js/login.js \ + src/sunstone/public/js/sunstone.js \ + src/sunstone/public/js/sunstone-util.js" + +SELF_SERVICE_PUBLIC_JS_PLUGINS_FILES="src/cloud/occi/lib/ui/public/js/plugins/compute.js \ + src/cloud/occi/lib/ui/public/js/plugins/configuration.js \ + src/cloud/occi/lib/ui/public/js/plugins/dashboard.js \ + src/cloud/occi/lib/ui/public/js/plugins/network.js \ + src/cloud/occi/lib/ui/public/js/plugins/storage.js" + + +SELF_SERVICE_PUBLIC_CSS_FILES="src/cloud/occi/lib/ui/public/css/application.css \ + src/cloud/occi/lib/ui/public/css/layout.css \ + src/cloud/occi/lib/ui/public/css/login.css" + +SELF_SERVICE_PUBLIC_CUSTOMIZE_FILES="src/cloud/occi/lib/ui/public/customize/custom.js" + + +SELF_SERVICE_PUBLIC_VENDOR_DATATABLES=$SUNSTONE_PUBLIC_VENDOR_DATATABLES +SELF_SERVICE_PUBLIC_VENDOR_JGROWL=$SUNSTONE_PUBLIC_VENDOR_JGROWL +SELF_SERVICE_PUBLIC_VENDOR_JQUERY=$SUNSTONE_PUBLIC_VENDOR_JQUERY +SELF_SERVICE_PUBLIC_VENDOR_JQUERYUI=$SUNSTONE_PUBLIC_VENDOR_JQUERYUI +SELF_SERVICE_PUBLIC_VENDOR_JQUERYUIIMAGES=$SUNSTONE_PUBLIC_VENDOR_JQUERYUIIMAGES +SELF_SERVICE_PUBLIC_VENDOR_JQUERYLAYOUT=$SUNSTONE_PUBLIC_VENDOR_JQUERYLAYOUT +SELF_SERVICE_PUBLIC_VENDOR_FLOT=$SUNSTONE_PUBLIC_VENDOR_FLOT +SELF_SERVICE_PUBLIC_VENDOR_CRYPTOJS=$SUNSTONE_PUBLIC_VENDOR_CRYPTOJS +SELF_SERVICE_PUBLIC_VENDOR_FILEUPLOADER=$SUNSTONE_PUBLIC_VENDOR_FILEUPLOADER +SELF_SERVICE_PUBLIC_VENDOR_XML2JSON=$SUNSTONE_PUBLIC_VENDOR_XML2JSON + +SELF_SERVICE_PUBLIC_IMAGES_FILES="\ +src/cloud/occi/lib/ui/public/images/ajax-loader.gif \ +src/cloud/occi/lib/ui/public/images/green_bullet.png \ +src/cloud/occi/lib/ui/public/images/login_over.png \ +src/cloud/occi/lib/ui/public/images/login.png \ +src/cloud/occi/lib/ui/public/images/network_icon.png \ +src/cloud/occi/lib/ui/public/images/one-compute.png \ +src/cloud/occi/lib/ui/public/images/one-network.png \ +src/cloud/occi/lib/ui/public/images/one-storage.png \ +src/cloud/occi/lib/ui/public/images/opennebula-selfservice-big.png \ +src/cloud/occi/lib/ui/public/images/opennebula-selfservice-icon.png \ +src/cloud/occi/lib/ui/public/images/opennebula-selfservice-small.png \ +src/cloud/occi/lib/ui/public/images/panel.png \ +src/cloud/occi/lib/ui/public/images/panel_short.png \ +src/cloud/occi/lib/ui/public/images/pbar.gif \ +src/cloud/occi/lib/ui/public/images/red_bullet.png \ +src/cloud/occi/lib/ui/public/images/Refresh-icon.png \ +src/cloud/occi/lib/ui/public/images/server_icon.png \ +src/cloud/occi/lib/ui/public/images/storage_icon.png \ +src/cloud/occi/lib/ui/public/images/vnc_off.png \ +src/cloud/occi/lib/ui/public/images/vnc_on.png \ +src/cloud/occi/lib/ui/public/images/yellow_bullet.png" + +SELF_SERVICE_PUBLIC_LOCALE_EN_US="src/cloud/occi/lib/ui/public/locale/en_US/en_US.js" +SELF_SERVICE_PUBLIC_LOCALE_ES_ES="src/cloud/occi/lib/ui/public/locale/es_ES/es_ES.js \ + src/cloud/occi/lib/ui/public/locale/es_ES/es_datatable.txt" + #----------------------------------------------------------------------------- # ACCT files #----------------------------------------------------------------------------- @@ -1292,7 +1441,7 @@ elif [ "$OZONES" = "yes" ]; then INSTALL_SET="${INSTALL_OZONES_RUBY_FILES[@]} ${INSTALL_OZONES_FILES[@]}" else INSTALL_SET="${INSTALL_FILES[@]} ${INSTALL_OZONES_FILES[@]} \ - ${INSTALL_SUNSTONE_FILES[@]}" + ${INSTALL_SUNSTONE_FILES[@]} ${INSTALL_SELF_SERVICE_FILES[@]}" fi for i in ${INSTALL_SET[@]}; do diff --git a/share/scripts/one b/share/scripts/one index b54de174b8..c72e1f5826 100755 --- a/share/scripts/one +++ b/share/scripts/one @@ -43,18 +43,10 @@ fi KILL_9_SECONDS=5 #------------------------------------------------------------------------------ -# Function that checks for running daemons and gets PORT from conf +# Function that checks for running daemons #------------------------------------------------------------------------------ setup() { - PORT=$(sed -n '/^[ \t]*PORT/s/^.*PORT\s*=\s*\([0-9]\+\)\s*.*$/\1/p' \ - $ONE_CONF) - - if [ $? -ne 0 ]; then - echo "Can not find PORT in $ONE_CONF." - exit 1 - fi - if [ -f $LOCK_FILE ]; then if [ -f $ONE_PID ]; then ONEPID=`cat $ONE_PID` @@ -150,17 +142,7 @@ start() fi # Start the scheduler - # The following command line arguments are supported by mm_shed: - # [-p port] to connect to oned - default: 2633 - # [-t timer] seconds between two scheduling actions - default: 30 - # [-m machines limit] max number of VMs managed in each scheduling action - # - default: 300 - # [-d dispatch limit] max number of VMs dispatched in each scheduling action - # - default: 30 - # [-h host dispatch] max number of VMs dispatched to a given host in each - # scheduling action - default: 1 - - $ONE_SCHEDULER -p $PORT -t 30 -m 300 -d 30 -h 1& + $ONE_SCHEDULER& LASTRC=$? LASTPID=$! diff --git a/src/cli/onevm b/src/cli/onevm index 3cd90e80ec..d94455657e 100755 --- a/src/cli/onevm +++ b/src/cli/onevm @@ -182,6 +182,19 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end + reboot_desc = <<-EOT.unindent + Reboots the given VM, this is equivalent to execute the reboot command + from the VM console. + + States: RUNNING + EOT + + command :reboot, reboot_desc, [:range,:vmid_list] do + helper.perform_actions(args[0],options,"rebooting") do |vm| + vm.reboot + end + end + deploy_desc = <<-EOT.unindent Deploys the given VM in the specified Host. This command forces the deployment, in a standard installation the Scheduler is in charge diff --git a/src/cloud/occi/etc/occi-server.conf b/src/cloud/occi/etc/occi-server.conf index e803e49788..ca272a763d 100644 --- a/src/cloud/occi/etc/occi-server.conf +++ b/src/cloud/occi/etc/occi-server.conf @@ -34,6 +34,9 @@ # x509, for x509 certificate encryption of tokens :core_auth: cipher +# Life-time in seconds for token renewal (that used to handle OpenNebula auths) +:token_expiration_delta: 1800 + # VM types allowed and its template file (inside templates directory) :instance_types: :small: @@ -48,3 +51,6 @@ :template: large.erb :cpu: 8 :memory: 8192 + +# Default language setting for Self-Service UI +:lang: en_US diff --git a/src/cloud/occi/lib/occi-server.rb b/src/cloud/occi/lib/occi-server.rb index f4f78a92cc..3c184f73be 100755 --- a/src/cloud/occi/lib/occi-server.rb +++ b/src/cloud/occi/lib/occi-server.rb @@ -48,6 +48,9 @@ $: << RUBY_LIB_LOCATION+"/cloud" # For the Repository Manager require 'rubygems' require 'sinatra' require 'yaml' +require 'erb' +require 'tempfile' +require 'json' require 'OCCIServer' require 'CloudAuth' @@ -71,6 +74,9 @@ CloudServer.print_configuration(conf) ############################################################################## # Sinatra Configuration ############################################################################## +use Rack::Session::Pool, :key => 'occi' +set :public, Proc.new { File.join(root, "ui/public") } +set :views, settings.root + '/ui/views' set :config, conf if CloudServer.is_port_open?(settings.config[:server], @@ -98,22 +104,89 @@ set :cloud_auth, cloud_auth ############################################################################## before do - begin - username = settings.cloud_auth.auth(request.env, params) - rescue Exception => e - error 500, e.message - end + unless request.path=='/ui/login' || request.path=='/ui' + if !authorized? + begin + username = settings.cloud_auth.auth(request.env, params) + rescue Exception => e + error 500, e.message + end + else + username = session[:user] + end - if username.nil? - error 401, "" - else - client = settings.cloud_auth.client(username) - @occi_server = OCCIServer.new(client, settings.config) + if username.nil? #unable to authenticate + error 401, "" + else + client = settings.cloud_auth.client(username) + @occi_server = OCCIServer.new(client, settings.config) + end + end +end + +after do + unless request.path=='/ui/login' || request.path=='/ui' + unless session[:remember] + if params[:timeout] == true + env['rack.session.options'][:defer] = true + else + env['rack.session.options'][:expire_after] = 60*10 + end + end end end # Response treatment helpers do + def authorized? + session[:ip] && session[:ip]==request.ip ? true : false + end + + def build_session + begin + username = settings.cloud_auth.auth(request.env, params) + rescue Exception => e + error 500, e.message + end + + if username.nil? + error 401, "" + else + client = settings.cloud_auth.client(username) + @occi_server = OCCIServer.new(client, settings.config) + + user_id = OpenNebula::User::SELF + user = OpenNebula::User.new_with_id(user_id, client) + rc = user.info + if OpenNebula.is_error?(rc) + # Add a log message + return [500, ""] + end + + session[:ip] = request.ip + session[:user] = username + session[:remember] = params[:remember] + + if params[:remember] + env['rack.session.options'][:expire_after] = 30*60*60*24 + end + + if params[:lang] + session[:lang] = params[:lang] + else + session[:lang] = settings.config[:lang] + end + + return [204, ""] + end + end + + def destroy_session + session.clear + return [204, ""] + end + + def treat_response(result,rc) if OpenNebula::is_error?(result) halt rc, result.message @@ -234,3 +307,55 @@ get '/user/:id' do result,rc = @occi_server.get_user(request, params) treat_response(result,rc) end + +############################################## +## UI +############################################## + +post '/config' do + begin + body = JSON.parse(request.body.read) + rescue + [500, "POST Config: Error parsing configuration JSON"] + end + + body.each do | key,value | + case key + when "lang" then session[:lang]=value + end + end +end + +get '/ui/login' do + File.read(File.dirname(__FILE__)+'/ui/templates/login.html') +end + +post '/ui/login' do + build_session +end + +post '/ui/logout' do + destroy_session +end + +get '/ui' do + if !authorized? + return File.read(File.dirname(__FILE__)+'/ui/templates/login.html') + end + + time = Time.now + 60 + response.set_cookie("occi-user", + :value=>"#{session[:user]}", + :expires=>time) + + erb :index +end + +post '/ui/upload' do + file = Tempfile.new('uploaded_image') + request.params['file'] = file.path #so we can re-use occi post_storage() + file.write(request.env['rack.input'].read) + #file.close # this would allow that file is garbage-collected + result,rc = @occi_server.post_storage(request) + treat_response(result,rc) +end diff --git a/src/cloud/occi/lib/ui/public/css/application.css b/src/cloud/occi/lib/ui/public/css/application.css new file mode 100644 index 0000000000..a122bbdf1a --- /dev/null +++ b/src/cloud/occi/lib/ui/public/css/application.css @@ -0,0 +1,589 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +body { + font: 9pt Arial, Verdana, Geneva, Helvetica, sans-serif; +} + +p { + margin:0 10px 10px; +} +a { + color: #000C96; text-decoration: none; +} +a:hover { + color: #127FE4; text-decoration: none; +} +select, button { + padding: 2px; +} + +h2 { + float:left; + font-size:20px; + margin-bottom: 5px; + padding-bottom: 0} + +h3 { + border-bottom: 1px solid #CCCCCC; + color: #353735; + font-size: 14px; + font-weight: normal; + padding: 5px 8px; + margin: 0 0; +} + +table#dashboard_table{ + width:100%; + margin: 0; +} + +table#dashboard_table tr { + vertical-align: top; +} + +table#dashboard_table > tbody > tr > td{ + width:50%; +} + +div.panel { + background-color: #ffffff; + padding:0; + margin: 10px; + border: 1px #ddd solid; + min-height: 50px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -moz-box-shadow: 5px 5px 5px #888; + -webkit-box-shadow: 5px 5px 5px #888; + box-shadow: 5px 5px 5px #888; +} + +div.panel h3 { + border: 0; + padding:5px 10px 5px 10px; + margin: 0; + color: white; + font-weight: bold; + background-color: #353735; + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; +} + +div.panel .new-resource { + float: right; +} + +div.panel h3 a { + color: white; + font-weight: bold; +} + +div.panel_info { + padding: 5px; +} + +div.panel_info table.info_table { + background: none; + width: 100%; + margin:0; +} + +div.panel_info table.info_table tr { + border: 0; + border-bottom: 1px dotted #ccc; +} +div.panel_info table.info_table > tbody > tr > td { + border: 0; + width: 100%!important; +} + +div.panel_info table.info_table td.value_td { + text-align: right; +} + +.green { + color: green!important; +} + +.red { + color: #B81515!important; +} + + +ul.multi_action_menu { list-style: none; position: absolute; text-align: left; padding:0; border: 1px solid #D3D3D3; background-color: #F0EDED;} +ul.multi_action_menu li { cursor: pointer; padding: 2px 5px;} +ul.multi_action_menu li:hover { background-color: #D3D3D3;} + + +div.action_block { + display:inline; + margin-right: 5px; + border-right: 1px solid #D3D3D3; +} + +div.action_blocks { + margin-bottom: 0.5em; + text-align: right; + margin-top: 0.5em; +} + +input, textarea, select { + border: 0; + border: 1px #bbbbbb solid; +} + +input, textarea { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; +} + +form.create_form{ + margin:0; + padding:0;} + +fieldset{ + margin:0 0; + border:none; + border-top:1px solid #ccc; + padding: 10px 5px;} + +fieldset div{ + margin-bottom:.5em; + padding:0; + display:block; +} + + +fieldset input, +fieldset textarea{ + width:140px; + /*border-top:1px solid #555; + border-left:1px solid #555; + border-bottom:1px solid #ccc; + border-right:1px solid #ccc;*/ + padding:1px;color:#333; + vertical-align: top; + margin: 0 2px; + margin-bottom: 4px; +} + +fieldset select{ + width:144px; + /*border-top:1px solid #555; + border-left:1px solid #555; + border-bottom:1px solid #ccc; + border-right:1px solid #ccc;*/ + padding:1px; + color:#333; + vertical-align: top; + margin: 0 2px; + margin-bottom: 4px; +} + +/*Chrome hack*/ +input[type="radio"],input[type="checkbox"] { + width:20px; +} + +legend{ + margin-top:0; + margin-bottom: 5px; + padding:0 .5em; + color:#036; + background:transparent; + font-size:1.0em; + font-weight:bold; +} + +label{ + float: left; + width:100px; + padding:0 1em; + text-align:left; +} + +.dataTables_wrapper label { + float: none; + width: auto; + padding: 0 0; + text-align:right; +} + + +div.tip { + display: inline-block; + padding-left: 5px; + vertical-align: middle; + float:none; +} + +div.tip span.ui-icon{ + display:inline-block; +} + +div.tip span.man_icon { + display:none; +} +.img_man .man_icon { + display:inline-block!important; +} + +span.tipspan,div.full_info { + position: fixed; + display:block; + padding:4px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + border: 1px solid #353735; + margin-left:2px; + margin-right:5px; + background-color: white; + color: #353735; + font-size:10px; +} +.vm_section input { + float:none; +} + +.vm_section legend{ + display:none!important; +} +.vm_section fieldset { + border:none!important; +} + +div.show_hide { + float:none; + clear:both; +} + +.vm_param label{ + float:left; +} + +fieldset div.vm_section { + margin-top:-8px; + margin-bottom:0px; +} + + +input:focus, +textarea:focus{ + background:#efefef; + color:#000; +} + +.form_buttons { + margin-top:6px; + text-align:left; + margin-bottom:20px; +} + +.add_remove_button { + font-size:0.8em !important; + height:25px !important; + margin-bottom:4px; +} + +.add_button { + margin-left:148px; + width:58px !important; +} + +.remove_button { + +} + +tr.odd, tr.even { + background-color: #ffffff; + border: 1px #e9e9e9 solid; + height:30px!important; +} + +tr.odd td, tr.even td{ + border-left: 1px #e9e9e9 solid; +} + +tr.odd:hover{ + background-color: #0098C3 !important; + color: white; +} + +tr.even:hover{ + color: white; + background-color: #0098C3 !important; +} + +.show_hide label{ + width: 100%; +} + +.clear { + clear: both; +} + +/* Create dialogs */ +/* host: */ +#create_host_form fieldset label { + width: 200px; +} + +.action_block_info{ + width: 235px; + margin: auto; +} + +.icon_right { + display: inline-block; + margin-left: 20px; + position: relative; + top: 2px; +} +.icon_left { + float: left; + margin-right: 20px; + position: relative; + top: 0px; +/*border:1px solid;*/ +} + + + +.info_table{ + background: none repeat scroll 0 0 #FFFFFF; + border-collapse: collapse; + margin: 20px; + text-align: left; + display: inline-block; + width:85%; + vertical-align:top; + overflow:auto; +} + +.info_table > thead th,h3 { + border-bottom: 2px solid #353735; + color: #353735; + font-size: 14px; + font-weight: normal; + padding: 10px 8px; +} + + +.info_table > tbody > tr > td{ + border-bottom: 1px solid #CCCCCC; + color: #353735; + padding-top: 6px; + padding-bottom: 6px; + padding-left: 8px; + padding-right: 8px; +} + +/*.info_table > tbody, .info_table > thead, info_table > tbody > tr { + width: 100%; + }*/ + +.info_table td.key_td{ + min-width: 150px; + text-align:left; + font-weight:bold; +} + +.info_table td.graph_td{ + padding-top:0px!important; + padding-bottom:0px!important; + vertical-align:middle!important; +} + +.info_table td.value_td{ + text-align:left; + width:100%; +} + +#dialog > div > div { + margin: 0; + padding: 0; +} + +.loading_img { + vertical-align:middle; + display:inline; + overflow:hide; + +} + +.top_button { + font-size: 0.8em!important; + height: 25px; + margin: 3px 2px; + vertical-align: middle; +/*width: 89px;*/ +} +.top_button button { + font-size: 0.9em; + height: 25px; + vertical-align: middle; +} + +.image_button { + font-size: 0.8em; + margin: 3px 2px; + vertical-align: middle; + border:0; +} + +/* + .multi_action_slct{ + font-size: 0.7em; + vertical-align:middle; + margin:3px 0; + height: 25px; + }*/ + +.ui-icon-refresh{ + position:relative!important; + top:14px!important; +} + +#vm_log { + padding: 0 20px 0 20px !important; +} + +#vm_log h3 { + border-bottom: 2px solid #353735; +} + +#vm_log pre { + font-size: 0.9em; +} + +#vm_log .vm_log_error { + color: red; + font-weight: bold; +} + +/* Growl */ +.jGrowl-notification h1 { + font-size: 1.2em; +} + +.jGrowl-notification, .jGrowl-notify-submit { + border: 2px #444444 solid; + background-color: #F3F3F3!important; + color: #666666; +} + +.jGrowl-notify-error { + border: 2px #660000 solid; + background-color: #F39999!important; + color: #660000; +} + +.jGrowl-notify-error table td.key_error { + text-transform: capitalize; + width: 100%; + font-weight: bold; +} + +.jGrowl-notify-error table td.key_error:after { + content:":"; +} + +.refresh_image { + position: relative; + top: 8px; + 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; +} + +ul.action_list{ + + /*background: #EDEDED;*/ + border: 1px solid #525252; + background-image: -webkit-gradient( + linear, + left bottom, + left top, + color-stop(0.25, #E9E9E9), + color-stop(0.63, #F5F5F5) + ); + background-image: -moz-linear-gradient( + center bottom, + #E9E9E9 25%, + #F5F5F5 63% + ); + position:absolute; + z-index:1; + list-style-type:none; + text-align:left; + padding:5px 5px; + -webkit-border-radius:4px; + -webkit-border-bottom-right-radius:5px; + -webkit-border-bottom-left-radius:5px; + -moz-border-radius:4px; + -moz-border-radius-bottomright:5px; + -moz-border-radius-bottomleft:5px; + border-radius:4px; + border-bottom-right-radius:5px; + border-bottom-left-radius:5px; +} + +ul.action_list li a{ + font-size: 0.8em; + color:#575C5B; + +} +ul.action_list li a:hover{ + color:#0098C3; + +} + +.progress_bar{ + height:10px; + background: #8F9392; +} + +.ui-widget{ + font: 10pt Arial, Verdana, Geneva, Helvetica, sans-serif; +} + +.ui-layout-resizer-open-hover, /* hover-color to 'resize' */ +.ui-layout-resizer-dragging { + background: #EEE; +} + +.dashboard_p { + color: #353735; + text-align:justify; +} + +.dashboard_p p{ + padding-top:5px; +} + +.dashboard_p img { + padding-left:10px; + padding-right: 10px; + border:0; +} + diff --git a/src/cloud/occi/lib/ui/public/css/layout.css b/src/cloud/occi/lib/ui/public/css/layout.css new file mode 100644 index 0000000000..283bf1e7a6 --- /dev/null +++ b/src/cloud/occi/lib/ui/public/css/layout.css @@ -0,0 +1,183 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +body { + background: #f5f5f5; +} + +.outer-center, .inner-center { + padding: 0; +} + +.outer-center { + border: 0; +} + +.inner-south { + padding: 0; +} + +#dialog div { + border: 0; +} + +.tab { + padding: 5px 10px 0 10px; +} + +body { + font-family: Arial, Verdana, Geneva, Helvetica, sans-serif; + font-size: 13px; +} + +#header { + padding: 0 10px 0 10px; + background-color: #353735; + border:0; +} + +#footer { + padding-top: 9px; + font-size: 0.8em; + color: white; + text-align: center; + background-color: #353735; + border:0; + +} + +#footer a { + color: white; + text-decoration: underline; +} + + + +#logo { + padding-top: 6px; + font-weight: bold; + color: white; + float:left; +} + +#login-info { + padding-top: 4px; + float: right; + padding-right: 5px; +} + +#links { + padding-top: 4px; + margin-right: 40px; + float: right; +} + +#login-info, #login-info a, #links, #links a { + color: white; +} + +#login-info, #login-info a { + font-weight: bold; +} +.sunstone-color { + color: #0098C3; +} + +#logo-wrapper { + float: right; + margin-top: 0px; + margin-right: 20px; +} + +#menu { + padding-right: 0; + padding-left: 0; + border:0; + border-right: 1px solid #353735; + background-image: -webkit-gradient( + linear, + left top, + right top, + color-stop(0.95, rgb(99,102,99)), + color-stop(1, rgb(53,55,53)) +); +background-image: -moz-linear-gradient( + left center, + rgb(99,102,99) 95%, + rgb(53,55,53) 100% +); +} +#navigation { + list-style: none; + padding: 0; +} + +#navigation li { + line-height: 2em; + text-align: right; + padding-right: 10px; +} + +#navigation li a { + color: #ffffff; +} + +#navigation li:hover, .navigation-active-li { + background-image: -webkit-gradient( + linear, + left top, + right top, + color-stop(0.95, #0098C3), + color-stop(1, rgb(53,55,53)) +); +background-image: -moz-linear-gradient( + left center, + #0098C3 95%, + rgb(53,55,53) 100% +); + /* + background-image: -webkit-gradient( + linear, + right top, + left top, + color-stop(0, rgb(0,152,192)), + color-stop(1, rgb(255,255,255)) + ); + background-image: -moz-linear-gradient( + right center, + rgb(0,152,192) 0%, + rgb(255,255,255) 100% + ); + */ +} +.navigation-active-li-a { + font-weight: bold; +} +#navigation li:hover a, .navigation-active-li-a { + color: #ffffff !important; +} + +#language { + float:right; + margin-top:2px; + margin-right:25px; + width: 100px; +} + +#language select { + width: 100px; + height: 22px; +} diff --git a/src/cloud/occi/lib/ui/public/css/login.css b/src/cloud/occi/lib/ui/public/css/login.css new file mode 100644 index 0000000000..e086897b3f --- /dev/null +++ b/src/cloud/occi/lib/ui/public/css/login.css @@ -0,0 +1,162 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +body { + background: #FAFAFA; + margin: 0px; + +} + + +#header { + height: 30px; + background-color: #353735; + padding: 0 10px 0 10px; +} + + +#logo { + padding-top: 6px; + font-size: 1.1em; + font-weight: bold; + color: white; + font-family: Arial, Verdana, Geneva, Helvetica, sans-serif; + font-size: 13px; +} + +#wrapper{ + margin-left: auto; + margin-right: auto; + width: 900px; + text-align: center; +} + + +div#logo_sunstone { + position: relative; + height: 100px; + width: 600px; + top: 80px; + margin-left: auto; + margin-right: auto; + background: url(../images/opennebula-selfservice-big.png) no-repeat center; + vertical-align: center; +} + +div#login { + width: 400px; + height: 300px; + position: relative; + + margin-left: auto; + margin-right: auto; + top: 90px; + padding-left: 80px; + padding-right: 80px; + background: url(../images/panel.png) no-repeat center ; + + vertical-align: center; +} + + +.box { + font-size:0.8em; + width: 300px; + height: 25px; + background: #FFFFFF; + margin-left: auto; + margin-right: auto; + margin-bottom: 10px; + border-bottom-color: gray; + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; + border-bottom-style: solid; + border-bottom-width: 1px; + border-left-color: gray; + border-left-style: solid; + border-left-width: 1px; + border-right-color: gray; + border-right-style: solid; + border-right-width: 1px; + border-top-color: gray; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + border-top-style: solid; + border-top-width: 1px; + -moz-border-radius: 5px; + -moz-border-radius-topleft: 5px; + -moz-border-radius-topright: 5px; + -moz-border-radius-bottomright: 5px; + -moz-border-radius-bottomleft: 5px; +} + + + +div#login input#login_btn { + width: 130px; + height: 45px; + cursor: pointer; + margin-left: auto; + margin-right: 43px; + margin-top: 20px; + background-color: transparent; + border:0; + float: right; + background: url(../images/login.png) no-repeat center ; +} + +div#login input#login_btn:hover { + width: 130px; + height: 45px; + cursor: pointer; + margin-left: auto; + margin-right: 43px; + margin-top: 20px; + background-color: transparent; + border:0; + float: right; + background: url(../images/login_over.png) no-repeat center ; +} + +.error_message { + display: none; + position: relative; + top: 80px; + font-family: Arial, Helvetica, sans-serif; + color:red; + font-size:1.6em; +} + +#label_remember { + color:#353735; + font-size:0.4em; + font-family: Arial, Helvetica, sans-serif; +} + +.content { + padding-top:40px; + font-size:1.8em; + margin-bottom:0px; + margin-left:50px; + text-align:left; + font-family: Arial, Helvetica, sans-serif; +} + +#check_remember { + + margin-top: 35px; + margin-left:0px; +} \ No newline at end of file diff --git a/src/cloud/occi/lib/ui/public/customize/custom.js b/src/cloud/occi/lib/ui/public/customize/custom.js new file mode 100644 index 0000000000..e26e24fecc --- /dev/null +++ b/src/cloud/occi/lib/ui/public/customize/custom.js @@ -0,0 +1,105 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +//OpenNebula Self-Service customization file. +//Use tr("String") to enable text translation. +//You can use HTML and the following variables. +var $vm_count = ''; +var $storage_count = ''; +var $network_count = ''; + + + +//Login logo 591x43px - not implemented +var logo_big = "images/opennebula-selfservice-big.png"; +//Top left logo 179x14px - not implemented +var logo_small = "images/opennebula-selfservice-small.png"; + + +//////////////////////////////////////////////////////////////// +// Dashboard tab customization +//////////////////////////////////////////////////////////////// + +//// +//Dashboard Welcome box +//// +var dashboard_welcome_title = tr("Welcome to OpenNebula Self-Service"); +var dashboard_welcome_image = "images/opennebula-selfservice-icon.png" +var dashboard_welcome_html = '

'+tr("OpenNebula Self-Service is a simplified user interface to manage OpenNebula compute, storage and network resources. It is focused on easiness and usability and features a limited set of operations directed towards end-users.")+'

\ +

'+tr("Additionally, OpenNebula Self-Service allows easy customization of the interface (e.g. this text) and brings multi-language support.")+'

\ +

'+tr("Have a cloudy experience!")+'

'; + +//// +//Dashboard useful links box +//Array of { href: "address", text: "text" },... +//// +var dashboard_links = [ + { href: "http://opennebula.org/documentation:documentation", + text: tr("Documentation") + }, + { href: "http://opennebula.org/support:support", + text: tr("Support") + }, + { href: "http://opennebula.org/community:community", + text: tr("Community") + } +]; + +//// +//Dashboard right-side boxes +//// +var compute_box_title = tr("Compute"); +var compute_box_image = "images/server_icon.png"; //scaled to 100px width +var compute_box_html = '

'+tr("Compute resources are Virtual Machines attached to storage and network resources. OpenNebula Self-Service allows you to easily create, remove and manage them, including the possibility of pausing a Virtual Machine or taking a snapshot of one of their disks.")+'

'; + +var storage_box_title = tr("Storage"); +var storage_box_image = "images/storage_icon.png"; //scaled to 100px width +var storage_box_html = '

'+tr("Storage pool is formed by several images. These images can contain from full operating systems to be used as base for compute resources, to simple data. OpenNebula Self-Service offers you the possibility to create or upload your own images.")+'

'; + +var network_box_title = tr("Network"); +var network_box_image = "images/network_icon.png"; +var network_box_html = '

'+tr("Your compute resources connectivity is performed using pre-defined virtual networks. You can create and manage these networks using OpenNebula Self-Service.")+'

'; + + +/////////////////////////////////////////////////////////// +//Compute tab +/////////////////////////////////////////////////////////// +var compute_dashboard_image = "images/one-compute.png"; +var compute_dashboard_html = '

' + tr("This is a list of your current compute resources. Virtual Machines use previously defined images and networks. You can easily create a new compute element by cliking \'new\' and filling-in an easy wizard.")+'

\ +

'+tr("You can also manage compute resources and perform actions such as stop, resume, shutdown or cancel.")+'

\ +

'+tr("Additionally, you can take a \'snapshot\' of the storage attached to these resources. They will be saved as new resources, visible from the Storage view and re-usable.")+'

\ +

'+tr("There are currently")+' '+$vm_count+' '+ + tr("virtual machines")+'.

'; + +/////////////////////////////////////////////////////////// +//Storage tab +/////////////////////////////////////////////////////////// +var storage_dashboard_image = "images/one-storage.png"; +var storage_dashboard_html = '

'+tr("The Storage view offers you an overview of your current images. Storage elements are attached to compute resources at creation time. They can also be extracted from running virtual machines by taking an snapshot.")+'

\ +

'+tr("You can add new storages by clicking \'new\'. Image files will be uploaded to OpenNebula and set ready to be used.")+'

\ +

'+tr("Additionally, you can run several operations on defined storages, such as defining their persistance. Persistent images can only be used by 1 virtual machine, and the changes made by it have effect on the base image. Non-persistent images are cloned before being used in a Virtual Machine, therefore changes are lost unless a snapshot is taken prior to Virtual Machine shutdown.")+'

\ +

'+tr("There are currently")+' '+$storage_count+' '+ + tr("images")+'.

'; + +/////////////////////////////////////////////////////////// +//Network tab +/////////////////////////////////////////////////////////// +var network_dashboard_image = "image/one-network.png"; +var network_dashboard_html = '

'+tr("In this view you can easily manage OpenNebula Network resources. You can add or remove virtual networks.")+'

\ +

'+tr("Compute resources can be attached to these networks at creation time. Virtual machines will be provided with an IP and the correct parameters to ensure connectivity.")+'

\ +

'+ + tr("There are currently")+' '+$network_count+' '+ + tr("networks")+'.

'; \ No newline at end of file diff --git a/src/cloud/occi/lib/ui/public/images/Refresh-icon.png b/src/cloud/occi/lib/ui/public/images/Refresh-icon.png new file mode 100644 index 0000000000..a9207d2653 Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/Refresh-icon.png differ diff --git a/src/cloud/occi/lib/ui/public/images/ajax-loader.gif b/src/cloud/occi/lib/ui/public/images/ajax-loader.gif new file mode 100644 index 0000000000..cf69d7879b Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/ajax-loader.gif differ diff --git a/src/cloud/occi/lib/ui/public/images/green_bullet.png b/src/cloud/occi/lib/ui/public/images/green_bullet.png new file mode 100644 index 0000000000..6e1be22202 Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/green_bullet.png differ diff --git a/src/cloud/occi/lib/ui/public/images/login.png b/src/cloud/occi/lib/ui/public/images/login.png new file mode 100644 index 0000000000..f87e0033a9 Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/login.png differ diff --git a/src/cloud/occi/lib/ui/public/images/login_over.png b/src/cloud/occi/lib/ui/public/images/login_over.png new file mode 100644 index 0000000000..dc5f102c7a Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/login_over.png differ diff --git a/src/cloud/occi/lib/ui/public/images/network_icon.png b/src/cloud/occi/lib/ui/public/images/network_icon.png new file mode 100644 index 0000000000..3f234ac4b9 Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/network_icon.png differ diff --git a/src/cloud/occi/lib/ui/public/images/one-compute.png b/src/cloud/occi/lib/ui/public/images/one-compute.png new file mode 100644 index 0000000000..f635680693 Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/one-compute.png differ diff --git a/src/cloud/occi/lib/ui/public/images/one-network.png b/src/cloud/occi/lib/ui/public/images/one-network.png new file mode 100644 index 0000000000..9d8be0d340 Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/one-network.png differ diff --git a/src/cloud/occi/lib/ui/public/images/one-storage.png b/src/cloud/occi/lib/ui/public/images/one-storage.png new file mode 100644 index 0000000000..1a1c4975bc Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/one-storage.png differ diff --git a/src/cloud/occi/lib/ui/public/images/opennebula-selfservice-big.png b/src/cloud/occi/lib/ui/public/images/opennebula-selfservice-big.png new file mode 100644 index 0000000000..add8ed9d26 Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/opennebula-selfservice-big.png differ diff --git a/src/cloud/occi/lib/ui/public/images/opennebula-selfservice-icon.png b/src/cloud/occi/lib/ui/public/images/opennebula-selfservice-icon.png new file mode 100644 index 0000000000..798da03b07 Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/opennebula-selfservice-icon.png differ diff --git a/src/cloud/occi/lib/ui/public/images/opennebula-selfservice-small.png b/src/cloud/occi/lib/ui/public/images/opennebula-selfservice-small.png new file mode 100644 index 0000000000..d2fa63708f Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/opennebula-selfservice-small.png differ diff --git a/src/cloud/occi/lib/ui/public/images/panel.png b/src/cloud/occi/lib/ui/public/images/panel.png new file mode 100644 index 0000000000..815baddff9 Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/panel.png differ diff --git a/src/cloud/occi/lib/ui/public/images/panel_short.png b/src/cloud/occi/lib/ui/public/images/panel_short.png new file mode 100644 index 0000000000..2eb300fe1f Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/panel_short.png differ diff --git a/src/cloud/occi/lib/ui/public/images/pbar.gif b/src/cloud/occi/lib/ui/public/images/pbar.gif new file mode 100644 index 0000000000..a36f520314 Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/pbar.gif differ diff --git a/src/cloud/occi/lib/ui/public/images/red_bullet.png b/src/cloud/occi/lib/ui/public/images/red_bullet.png new file mode 100644 index 0000000000..dd95b8e35d Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/red_bullet.png differ diff --git a/src/cloud/occi/lib/ui/public/images/server_icon.png b/src/cloud/occi/lib/ui/public/images/server_icon.png new file mode 100644 index 0000000000..265b10e594 Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/server_icon.png differ diff --git a/src/cloud/occi/lib/ui/public/images/storage_icon.png b/src/cloud/occi/lib/ui/public/images/storage_icon.png new file mode 100644 index 0000000000..fac14fd912 Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/storage_icon.png differ diff --git a/src/cloud/occi/lib/ui/public/images/vnc_off.png b/src/cloud/occi/lib/ui/public/images/vnc_off.png new file mode 100644 index 0000000000..1ef79716a0 Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/vnc_off.png differ diff --git a/src/cloud/occi/lib/ui/public/images/vnc_on.png b/src/cloud/occi/lib/ui/public/images/vnc_on.png new file mode 100644 index 0000000000..3386dcc01c Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/vnc_on.png differ diff --git a/src/cloud/occi/lib/ui/public/images/yellow_bullet.png b/src/cloud/occi/lib/ui/public/images/yellow_bullet.png new file mode 100644 index 0000000000..ca0138a1e3 Binary files /dev/null and b/src/cloud/occi/lib/ui/public/images/yellow_bullet.png differ diff --git a/src/cloud/occi/lib/ui/public/js/layout.js b/src/cloud/occi/lib/ui/public/js/layout.js new file mode 100644 index 0000000000..71b0098548 --- /dev/null +++ b/src/cloud/occi/lib/ui/public/js/layout.js @@ -0,0 +1,110 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +var activeTab; +var outerLayout, innerLayout; + +function hideDialog(){ + innerLayout.close("east"); +} + +function popDialog(content){ + $("#dialog").html(content); + innerLayout.open("east"); +} + +function popDialogLoading(){ + var loading = '
loading...
'; + popDialog(loading); +} + +function showTab(tabname){ + activeTab = tabname; + + //clean selected menu + $("#navigation li").removeClass("navigation-active-li"); + $("#navigation li a").removeClass("navigation-active-li-a"); + + //select menu + var li = $("#navigation li:has(a[href='"+activeTab+"'])") + var li_a = $("#navigation li a[href='"+activeTab+"']") + li.addClass("navigation-active-li"); + li_a.addClass("navigation-active-li-a"); + + //show tab + $(".tab").hide(); + $(activeTab).show(); + //~ if (activeTab == '#dashboard') { + //~ emptyDashboard(); + //~ preloadTables(); + //~ } + innerLayout.close("south"); +} + +$(document).ready(function () { + $(".tab").hide(); + + $(".outer-west ul li.subTab a").live("click",function(){ + var tab = $(this).attr('href'); + showTab(tab); + return false; + }); + + $(".outer-west ul li.topTab a").live("click",function(){ + var tab = $(this).attr('href'); + //toggle subtabs trick + $('li.'+tab.substr(1)).toggle(); + showTab(tab); + return false; + }); + + outerLayout = $('body').layout({ + applyDefaultStyles: false + , center__paneSelector: ".outer-center" + , west__paneSelector: ".outer-west" + , west__size: 133 + , north__size: 26 + , south__size: 26 + , spacing_open: 0 // ALL panes + , spacing_closed: 0 // ALL panes + //, north__spacing_open: 0 + //, south__spacing_open: 0 + , north__maxSize: 200 + , south__maxSize: 200 + , south__closable: false + , north__closable: false + , west__closable: false + , south__resizable: false + , north__resizable: false + , west__resizable: false + }); + + var factor = 0.45; + var dialog_height = Math.floor($(".outer-center").width()*factor); + + innerLayout = $('div.outer-center').layout({ + fxName: "slide" + , initClosed: true + , center__paneSelector: ".inner-center" + , east__paneSelector: ".inner-east" + , east__size: dialog_height + , east__minSize: 400 + , spacing_open: 5 // ALL panes + , spacing_closed: 5 // ALL panes + }); + +}); + diff --git a/src/cloud/occi/lib/ui/public/js/locale.js b/src/cloud/occi/lib/ui/public/js/locale.js new file mode 100644 index 0000000000..bfec7d8f4e --- /dev/null +++ b/src/cloud/occi/lib/ui/public/js/locale.js @@ -0,0 +1,56 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +var lang="" +var locale = {}; +var datatable_lang = ""; + +function tr(str){ + var tmp = locale[str]; + if ( tmp == null || tmp == "" ) { + //console.debug("Missing translation: "+str); + tmp = str; + } + return tmp; +}; + +//Pops up loading new language dialog. Retrieves the user template, updates the LANG variable. +//Updates template and session configuration and reloads the view. +function setLang(lang_str){ + var dialog = $('
'+tr("Loading new language... please wait")+' '+spinner+'
').dialog({ + draggable:false, + modal:true, + resizable:false, + buttons:{}, + width: 460, + minHeight: 50 + + }); + + if (('localStorage' in window) && (window['localStorage'] !== null)){ + localStorage['lang']=lang_str; + }; + $.post('config',JSON.stringify({lang:lang_str}),function(){window.location.href = "./ui"}); +}; + +$(document).ready(function(){ + //Update static translations + $('#doc_link').text(tr("Documentation")); + $('#support_link').text(tr("Support")); + $('#community_link').text(tr("Community")); + $('#welcome').text(tr("Welcome")); + $('#logout').text(tr("Sign out")); +}); \ No newline at end of file diff --git a/src/cloud/occi/lib/ui/public/js/login.js b/src/cloud/occi/lib/ui/public/js/login.js new file mode 100644 index 0000000000..13eff1f619 --- /dev/null +++ b/src/cloud/occi/lib/ui/public/js/login.js @@ -0,0 +1,71 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +function auth_success(req, response){ + window.location.href = "./ui"; +} + +function auth_error(req, error){ + + var status = error.error.http_status; + + switch (status){ + case 401: + $("#one_error").hide(); + $("#auth_error").fadeIn("slow"); + break; + case 500: + $("#auth_error").hide(); + $("#one_error").fadeIn("slow"); + break; + }; +} + +function authenticate(){ + var username = $("#username").val(); + var password = $("#password").val(); + password = Crypto.SHA1(password); + var remember = $("#check_remember").is(":checked"); + + var obj = { data: {username: username, + password: password}, + remember: remember, + success: auth_success, + error: auth_error + }; + + if (('localStorage' in window) && (window['localStorage'] !== null) && (localStorage['lang'])){ + obj['lang'] = localStorage['lang']; + }; + + OCCI.Auth.login(obj); +} + +$(document).ready(function(){ + $("#login_form").submit(function (){ + authenticate(); + return false; + }); + + //compact login elements according to screen height + if (screen.height <= 600){ + $('div#logo_sunstone').css("top","15px"); + $('div#login').css("top","10px"); + $('.error_message').css("top","10px"); + }; + + $("input#username.box").focus(); +}); diff --git a/src/cloud/occi/lib/ui/public/js/occi.js b/src/cloud/occi/lib/ui/public/js/occi.js new file mode 100644 index 0000000000..4e28a5138b --- /dev/null +++ b/src/cloud/occi/lib/ui/public/js/occi.js @@ -0,0 +1,623 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +//Convert json into the XML that OCCI server can understand +function json2xml(element,root_key) { + var xml = ""; + if (!root_key) root_key="ROOT"; + + if (typeof element == "object") { //Its an object + $.each(element, function(key,value){ + if (value.constructor == Array){ + for (var i = 0; i < value.length; i++){ + xml += json2xml(value[i],key); + }; + //do not wrap arrays in root_key + return xml; + + } else + xml += json2xml(value,key); + }); + } else { //its a simple value. Base condition + xml += element.toString(); + }; + return "<" + root_key.toUpperCase() + ">" + xml + ""; +}; + + +$.ajaxSetup({ + converters: { + "xml ONEjson": function(xml){ + return $.xml2json(xml); + }, + } +}); + +var OCCI = { + + "Error": function(resp) + { + var error = { + error : { + message: resp.responseText, + http_status : resp.status} + }; + return error; + }, + + "is_error": function(obj) + { + return obj.error ? true : false; + }, + + "Helper": { + "resource_state": function(type, value) + { + switch(type) + { + case "HOST","host": + return ["INIT", + "MONITORING", + "MONITORED", + "ERROR", + "DISABLED"][value]; + break; + case "HOST_SIMPLE","host_simple": + return ["ON", + "ON", + "ON", + "ERROR", + "OFF"][value]; + break; + case "VM","vm": + return ["INIT", + "PENDING", + "HOLD", + "ACTIVE", + "STOPPED", + "SUSPENDED", + "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", + "USED", + "DISABLED", + "LOCKED", + "ERROR"][value]; + break; + default: + return; + } + }, + + "image_type": function(value) + { + return ["OS", "CDROM", "DATABLOCK"][value]; + }, + + "action": function(action, params) + { + obj = { + "action": { + "perform": action + } + } + if (params) + { + obj.action.params = params; + } + return obj; + }, + + "request": function(resource, method, data) { + var r = { + "request": { + "resource" : resource, + "method" : method + } + } + if (data) + { + if (typeof(data) != "array") + { + data = [data]; + } + r.request.data = data; + } + return r; + }, + + "pool": function(resource, response) + { + var pool_name = resource + "_COLLECTION"; + var type = resource; + var pool; + + if (typeof(pool_name) == "undefined") + { + return Error('Incorrect Pool'); + } + + var p_pool = []; + + if (response[pool_name]) { + pool = response[pool_name][type]; + } else { pull = null }; + + if (pool == null) + { + return p_pool; + } + else if (pool.length) + { + for (i=0;i'; + OCCI.Action.update(params,OCCI.VM.resource,"saveas"); + }, +/* "vnc" : function(params,startstop){ + var callback = params.success; + var callback_error = params.error; + var id = params.data.id; + var resource = OCCI.VM.resource; + + var method = startstop; + var action = OCCI.Helper.action(method); + var request = OCCI.Helper.request(resource,method, id); + $.ajax({ + url: "vm/" + id + "/" + method, + type: "POST", + dataType: "json", + success: function(response){ + return callback ? callback(request, response) : null; + }, + error: function(response){ + return callback_error ? + callback_error(request, OCCI.Error(response)) : null; + } + }); + }, + "startvnc" : function(params){ + OCCI.VM.vnc(params,"startvnc"); + }, + "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": { + "resource": "STORAGE", + + "create": function(params){ + var callback = params.success; + var callback_error = params.error; + var data = {occixml : json2xml(params.data,OCCI.Image.resource)}; + var request = OCCI.Helper.request(OCCI.Image.resource,"create", data); + + $.ajax({ + type: 'POST', + url: "storage", + data: data, + dataType: "xml ONEjson", + success: function(response){ + var res = {}; + res["STORAGE"] = response; + return callback ? callback(request, res) : null; + }, + error: function(response){ + return callback_error ? + callback_error(request, OCCI.Error(response)) : null; + } + }); + }, + "delete": function(params){ + OCCI.Action.delete(params,OCCI.Image.resource); + }, + "list": function(params){ + OCCI.Action.list(params,OCCI.Image.resource); + }, + "show": function(params){ + OCCI.Action.show(params,OCCI.Image.resource); + }, + "publish": function(params){ + params.data.body = { "PUBLIC":"YES" }; + OCCI.Action.update(params,OCCI.Image.resource,"publish"); + }, + "unpublish": function(params){ + params.data.body = { "PUBLIC":"NO" }; + OCCI.Action.update(params,OCCI.Image.resource,"unpublish"); + }, + "persistent": function(params){ + params.data.body = { "PERSISTENT":"YES" }; + OCCI.Action.update(params,OCCI.Image.resource,"persistent"); + }, + "nonpersistent": function(params){ + params.data.body = { "PERSISTENT":"NO" }; + OCCI.Action.update(params,OCCI.Image.resource,"nonpersistent"); + }, + }, + + "Template" : { + "resource" : "VMTEMPLATE", + + "create" : function(params){ + OCCI.Action.create(params,OCCI.Template.resource); + }, + "delete" : function(params){ + OCCI.Action.delete(params,OCCI.Template.resource); + }, + "list" : function(params){ + OCCI.Action.list(params,OCCI.Template.resource); + }, + "show" : function(params){ + OCCI.Action.show(params,OCCI.Template.resource); + }, + "chown" : function(params){ + OCCI.Action.chown(params,OCCI.Template.resource); + }, + "chgrp" : function(params){ + OCCI.Action.chgrp(params,OCCI.Template.resource); + }, + "update" : function(params){ + var action_obj = {"template_raw" : params.data.extra_param }; + OCCI.Action.simple_action(params, + OCCI.Template.resource, + "update", + action_obj); + }, + "fetch_template" : function(params){ + OCCI.Action.show(params,OCCI.Template.resource,"template"); + }, + "publish" : function(params){ + OCCI.Action.simple_action(params,OCCI.Template.resource,"publish"); + }, + "unpublish" : function(params){ + OCCI.Action.simple_action(params,OCCI.Template.resource,"unpublish"); + }, + + "instantiate" : function(params) { + var vm_name = params.data.extra_param ? params.data.extra_param : ""; + var action_obj = { "vm_name" : vm_name }; + OCCI.Action.simple_action(params,OCCI.Template.resource, + "instantiate",action_obj); + } + }, + + "Instance_type" : { + "resource" : "INSTANCE_TYPE", + "list" : function(params){ + OCCI.Action.list(params,OCCI.Instance_type.resource); + }, + }, + +} diff --git a/src/cloud/occi/lib/ui/public/js/plugins/compute.js b/src/cloud/occi/lib/ui/public/js/plugins/compute.js new file mode 100644 index 0000000000..aeb9a3ad4a --- /dev/null +++ b/src/cloud/occi/lib/ui/public/js/plugins/compute.js @@ -0,0 +1,1098 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +/*Virtual Machines tab plugin*/ +//var INCLUDE_URI = "vendor/noVNC/include/"; +//var VM_HISTORY_LENGTH = 40; + +/* +function loadVNC(){ + var script = ''; + document.write(script); +} +loadVNC(); + +var vm_graphs = [ + { title : tr("CPU"), + monitor_resources : "cpu_usage", + humanize_figures : false, + history_length : VM_HISTORY_LENGTH + }, + { title : tr("Memory"), + monitor_resources : "mem_usage", + humanize_figures : true, + history_length : VM_HISTORY_LENGTH + }, + { title : tr("Network transmission"), + monitor_resources : "net_tx", + humanize_figures : true, + history_length : VM_HISTORY_LENGTH + }, + { title : tr("Network reception"), + monitor_resources : "net_rx", + humanize_figures : true, + history_length : VM_HISTORY_LENGTH + } +]; +*/ + + +var vms_tab_content = +'
\ +
\ +
\ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
'+tr("All")+''+tr("ID")+''+tr("Name")+' / '+tr("State")+'
\ +
'; + +var create_vm_tmpl ='
\ +
\ + \ +
\ +
\ +
\ + \ +
\ +
\ +
\ + \ + \ +
\ +
\ + \ + \ +
\ +
\ + \ + \ +
\ +
\ +
\ + \ +
'; + +var vm_dashboard = '
\ +one-compute' ++ compute_dashboard_html + +'
'; + + +var dataTable_vMachines; +var $create_vm_dialog; +var $saveas_vm_dialog; +var $vnc_dialog; +var rfb; + +var vm_actions = { + "VM.create" : { + type: "create", + call: OCCI.VM.create, + callback: addVMachineElement, + error: onError, + notify: true + }, + + "VM.create_dialog" : { + type: "custom", + call: popUpCreateVMDialog, + }, + + "VM.list" : { + type: "list", + call: OCCI.VM.list, + callback: updateVMachinesView, + error: onError + }, + + "VM.show" : { + type: "single", + call: OCCI.VM.show, + callback: updateVMachineElement, + error: onError + }, + + "VM.showinfo" : { + type: "single", + call: OCCI.VM.show, + callback: updateVMInfo, + error: onError + }, + + "VM.showstate" : { + type: "single", + call: OCCI.VM.show, + callback: updateVMStateCB, + error: onError + }, + + "VM.refresh" : { + type: "custom", + call : function (){ + waitingNodes(dataTable_vMachines); + Sunstone.runAction("VM.list"); + }, + }, + + "VM.autorefresh" : { + type: "custom", + call : function() { + OCCI.VM.list({timeout: true, success: updateVMachinesView,error: onError}); + }, + }, + + "VM.suspend" : { + type: "multiple", + call: OCCI.VM.suspend, + callback: updateVMStateCB, + elements: vmElements, + error: onError, + notify: true + }, + + "VM.resume" : { + type: "multiple", + call: OCCI.VM.resume, + callback: updateVMStateCB, + elements: vmElements, + error: onError, + notify: true + }, + + "VM.stop" : { + type: "multiple", + call: OCCI.VM.stop, + callback: updateVMStateCB, + elements: vmElements, + error: onError, + notify: true + }, + + "VM.done" : { + type: "multiple", + call: OCCI.VM.done, + callback: deleteVMachineElement, + elements: vmElements, + error: onError, + notify: true + }, + + "VM.shutdown" : { + type: "multiple", + call: OCCI.VM.shutdown, + callback: updateVMStateCB, + elements: vmElements, + error: onError, + notify: true + }, + + "VM.cancel" : { + type: "multiple", + call: OCCI.VM.cancel, + callback: updateVMStateCB, + elements: vmElements, + error: onError, + notify: true + }, + + "VM.saveasmultiple" : { + type: "custom", + call: function(){ + var elems = vmElements(); + popUpSaveasDialog(elems); + } + }, + + "VM.saveas" : { + type: "single", + call: OCCI.VM.saveas, + callback: updateVMStateCB, + error:onError + }, + + "VM.saveas_disks" : { + type: "single", + call: OCCI.VM.show, + callback: saveasDisksCallback, + error: onError + }, + "VM.getInstanceTypes" : { + type: "list", + call: OCCI.Instance_type.list, + callback: function(request,response){ + if (response.constructor != Array){ + response = [response]; + }; + var options = ""; + for (var i = 0; i'+type+''; + }; + $('#dialog select#instance_type').html(options); + }, + error: onError + }, + + /* + "VM.startvnc" : { + type: "single", + call: OCCI.VM.startvnc, + callback: vncCallback, + error: onError, + notify: true + }, + + "VM.stopvnc" : { + type: "single", + call: OCCI.VM.stopvnc, + error: onError, + notify: true + }, + + "VM.monitor" : { + type: "monitor", + call : OCCI.VM.monitor, + callback: function(req,response) { + var info = req.request.data[0].monitor; + plot_graph(response,'#vm_monitoring_tab', + 'vm_monitor_',info); + }, + error: vmMonitorError + }, + "VM.monitor_all" : { + type: "monitor_global", + call: OCCI.VM.monitor_all, + callback: function(req,response) { + var info = req.request.data[0].monitor; + plot_global_graph(response,info); + }, + error: onError + }, + */ +} + +var vm_buttons = { + "VM.refresh" : { + type: "image", + text: tr("Refresh list"), + img: "images/Refresh-icon.png" + }, + + "VM.create_dialog" : { + type: "action", + text: tr("+ New"), + alwaysActive: true + }, + + "VM.shutdown" : { + type: "confirm", + text: tr("Shutdown"), + tip: tr("This will shutdown the selected VMs") + }, + + "action_list" : { + type: "select", + actions: { + "VM.suspend" : { + type: "confirm", + text: tr("Suspend"), + tip: tr("This will suspend the selected VMs") + }, + "VM.resume" : { + type: "confirm", + text: tr("Resume"), + tip: tr("This will resume the selected VMs in stopped or suspended states") + }, + "VM.stop" : { + type: "confirm", + text: tr("Stop"), + tip: "This will stop selected VMs" + }, + "VM.cancel" : { + type: "confirm", + text: tr("Cancel"), + tip: tr("This will cancel selected VMs") + }, + "VM.saveasmultiple" : { + type: "action", + text: tr("Take snapshot") + } + } + }, + + "VM.done" : { + type: "confirm", + text: tr("Delete"), + tip: tr("This will delete the selected VMs from the database") + } +} + +var vm_info_panel = { + "vm_info_tab" : { + title: tr("Compute resource"), + content: "" + }, + "vm_disks_tab" : { + title: tr("Disks"), + content: "" + }, + "vm_networks_tab" : { + title: tr("Networks"), + content: "" + }, +} + +var vm_create_panel = { + "vm_create_panel" : { + title: tr("Create Virtual Machine"), + content: create_vm_tmpl + }, +}; + +var vms_tab = { + title: tr("Compute"), + content: vms_tab_content, + buttons: vm_buttons +} + +Sunstone.addActions(vm_actions); +Sunstone.addMainTab('vms_tab',vms_tab); +Sunstone.addInfoPanel('vm_info_panel',vm_info_panel); +Sunstone.addInfoPanel('vm_create_panel',vm_create_panel); + + +function vmElements() { + return getSelectedNodes(dataTable_vMachines); +} + +// Returns a human readable running time for a VM +function str_start_time(vm){ + return pretty_time(vm.STIME); +} + +// Returns an array formed by the information contained in the vm_json +// and ready to be introduced in a dataTable +function vMachineElementArray(vm_json){ + var vm = vm_json.COMPUTE; + var id,name; + + if (vm.name){ + id = vm.href.split("/"); + id = id[id.length-1]; + name = vm.name; + } + else { + id = vm.ID; + name = vm.NAME; + }; + + return [ + '', + id, + name + ]; +} + + +//Creates a listener for the TDs of the VM table +function vMachineInfoListener(){ + + $('#tbodyvmachines tr',dataTable_vMachines).live("click", function(e){ + if ($(e.target).is('input') || $(e.target).is('a img')) {return true;} + popDialogLoading(); + var aData = dataTable_vMachines.fnGetData(this); + var id = $(aData[0]).val(); + Sunstone.runAction("VM.showinfo",id); + return false; + }); +} + +// Callback to refresh a single element from the list +function updateVMachineElement(request, vm_json){ + var id = vm_json.COMPUTE.ID; + var element = vMachineElementArray(vm_json); + updateSingleElement(element,dataTable_vMachines,'#vm_'+id) +} + +// Callback to delete a single element from the list +function deleteVMachineElement(request){ + deleteElement(dataTable_vMachines,'#vm_'+request.request.data); +} + +// Callback to add an element to the list +function addVMachineElement(request,vm_json){ + var id = vm_json.COMPUTE.ID; + var element = vMachineElementArray(vm_json); + addElement(element,dataTable_vMachines); + Sunstone.runAction("VM.showstate",id); +} + + +// Callback to refresh the list of Virtual Machines +function updateVMachinesView(request, vmachine_list){ + var vmachine_list_array = []; + var el_array; + + $.each(vmachine_list,function(){ + el_array = vMachineElementArray(this); + vmachine_list_array.push(el_array); + Sunstone.runAction("VM.showstate",el_array[1]); + }); + + updateView(vmachine_list_array,dataTable_vMachines); + updateDashboard("vms",vmachine_list); +}; + +function updateVMStateCB(request,vm){ + var vm_state = vm.COMPUTE.STATE; + var state_html = vm_state; + switch (vm_state) { + case "INIT": + case "PENDING": + case "HOLD": + case "STOPPED": + case "SUSPENDED": + state_html = ''+vm_state+''; + break; + case "ACTIVE": + case "DONE": + state_html = ''+vm_state+''; + break; + case "FAILED": + state_html = ''+vm_state+''; + break; + }; + + var tag = 'input#vm_'+vm.COMPUTE.ID; + var array = vMachineElementArray(vm); + array[2] = state_html + array[2]; + updateSingleElement(array,dataTable_vMachines,tag); +}; + + +// Refreshes the information panel for a VM +function updateVMInfo(request,vm){ + var vm_info = vm.COMPUTE; + + var info_tab = { + title : tr("VM information"), + content: + '\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
'+tr("Virtual Machine information")+' - '+vm_info.NAME+'
'+tr("ID")+''+vm_info.ID+'
'+tr("Name")+''+vm_info.NAME+'
'+tr("Instance type")+''+vm_info.INSTANCE_TYPE+'
'+tr("State")+''+tr(vm_info.STATE)+'
'+tr("CPU")+''+vm_info.CPU+'
'+tr("Memory")+''+vm_info.MEMORY+'
\ +
\ +
' + }; + + var disks_str = '\ +\ +\ +'; + + var disks = vm_info.DISK; + if (disks){ + if (disks.constructor != Array) // 1lease + disks = [disks]; + + for (var i=0;i\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +'; + }; + + } else { + disks_str += ''; + }; + + disks_str += '
'+tr("Disks information")+'
'+disks[i].id+'
'+tr("Name")+''+disks[i].STORAGE.name+'
'+tr("Target")+''+disks[i].TARGET+'
'+tr("Type")+''+disks[i].TYPE+'
'+ + tr("No disks defined")+'
\ +
\ +
'; + + var disks_tab = { + title : tr("Disks"), + content : disks_str + }; + + var networks_str = '\ +\ +\ +'; + + var networks = vm_info.NIC; + if (networks){ + if (networks.constructor != Array) // 1lease + networks = [networks]; + + for (var i=0;i\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +\ +'; + }; + + } else { + networks_str += ''; + }; + + networks_str += '
'+tr("Networks information")+'
'+net_id+'
'+tr("Name")+''+networks[i].NETWORK.name+'
'+tr("IP")+''+networks[i].IP+'
'+tr("MAC")+''+networks[i].MAC+'
'+ + tr("No networks defined")+'
\ +
\ +
'; + + var networks_tab = { + title : tr("Networks"), + content : networks_str + }; + + /* + var monitoring_tab = { + title: tr("Monitoring information"), + content: generateMonitoringDivs(vm_graphs,"vm_monitor_") + } + */ + + Sunstone.updateInfoPanelTab("vm_info_panel","vm_info_tab",info_tab); + Sunstone.updateInfoPanelTab("vm_info_panel","vm_disks_tab",disks_tab); + Sunstone.updateInfoPanelTab("vm_info_panel","vm_networks_tab",networks_tab); + //Sunstone.updateInfoPanelTab("vm_info_panel","vm_monitoring_tab",monitoring_tab); + + //Pop up the info panel and asynchronously get vm_log and stats + Sunstone.popUpInfoPanel("vm_info_panel"); + $('#dialog .vm_close_dialog_link').button({ + text:false, + icons: { primary: "ui-icon-closethick" } + }); + +// Sunstone.runAction("VM.log",vm_info.ID); +// for (var i=0; i'); + }); + }; + + var nets = $('#network_box option[clicked="clicked"]'); + + if (nets.length){ + vm["NIC"] = []; + + nets.each(function(){ + var value = $(this).val(); + vm["NIC"].push(''); + }); + }; + + if (n_times.length){ + n_times_int=parseInt(n_times,10); + } + + if (n_times_int>1){ + if (!vm_name.length){ + vm_name = $('#template_id option:selected',this).text(); + } + for (var i=0; i< n_times_int; i++){ + Sunstone.runAction("VM.create",vm); + }; + } else { + Sunstone.runAction("VM.create",vm); + }; + + popUpVMDashboard(); + return false; + }); +} + + +//Prepares a dialog to saveas a VM +function setupSaveasDialog(){ + //Append to DOM + dialogs_context.append('
'); + $saveas_vm_dialog = $('#saveas_vm_dialog',dialogs_context); + var dialog = $saveas_vm_dialog; + + //Put HTML in place + dialog.html('\ +
\ +
\ +
\ +
\ + \ + \ +
\ + \ +
'); + + dialog.dialog({ + autoOpen:false, + width:600, + modal:true, + height:350, + resizable:true, + }); + + $('#saveas_vm_form',dialog).submit(function(){ + var elems = $('#saveas_tabs div.saveas_tab',this); + var args = []; + $.each(elems,function(){ + var id = $('#vm_id',this).text(); + var disk_id = $('#vm_disk_id',this).val(); + var image_name = $('#image_name',this).val(); + + if (!id.length || !disk_id.length || !image_name.length) { + notifyError(tr("Skipping VM ")+id+". "+ + tr("No disk id or image name specified")); + } + else { + var obj = { + disk_id : disk_id, + image_name : image_name, + }; + args.push(id); + Sunstone.runAction("VM.saveas",id,obj); + } + }); + if (args.length > 0){ + notifySubmit("VM.saveas",args); + } + + $saveas_vm_dialog.dialog('close'); + return false; + }); + + $('#vm_saveas_cancel',dialog).click(function(){ + $saveas_vm_dialog.dialog('close'); + return false; + }); + +} + +function popUpSaveasDialog(elems){ + var dialog = $saveas_vm_dialog; + $('#saveas_tabs',dialog).tabs('destroy'); + $('#saveas_tabs',dialog).empty(); + $('#saveas_tabs',dialog).html('
    '); + + $.each(elems,function(){ + var li = '
  • VM '+this+'
  • ' + $('#saveas_tabs ul',dialog).append(li); + var tab = '
    \ +
    '+tr("Saveas for VM with ID")+' '+this+'
    \ +
    \ +
    \ + \ + \ +
    \ +
    \ + \ + \ +
    \ +
    \ +
    '; + $('#saveas_tabs',dialog).append(tab); + Sunstone.runAction("VM.saveas_disks",this); + }); + $('#saveas_tabs',dialog).tabs(); + $('button',dialog).button(); + dialog.dialog('open'); +} + +function saveasDisksCallback(req,response){ + var vm_info = response.COMPUTE; + var id=vm_info.ID; + var select=""; + + var gen_option = function(id, name, source){ + if (name){ + return ''; + } + else { + return ''; + } + } + + var disks = vm_info.DISK; + if (!disks) { select = '';} + else if (disks.constructor == Array) //several disks + { + for (var i=0;i'); + $vnc_dialog = $('#vnc_dialog',dialogs_context); + var dialog = $vnc_dialog; + + dialog.html('\ +
    \ + \ + \ + \ +
    '+tr("Loading")+'
    \ + \ +
    \ +
    \ + \ + '+tr("Canvas not supported.")+'\ + \ +'); + + dialog.dialog({ + autoOpen:false, + width:700, + modal:true, + height:500, + resizable:true, + }); + + $('#sendCtrlAltDelButton',dialog).click(function(){ + rfb.sendCtrlAltDel(); + return false; + }); + + dialog.bind( "dialogclose", function(event, ui) { + var id = $vnc_dialog.attr('vm_id'); + rfb.disconnect(); + Sunstone.runAction("VM.stopvnc",id); + }); + + $('.vnc',main_tabs_context).live("click",function(){ + //Which VM is it? + var id = $(this).attr('vm_id'); + //Set attribute to dialog + $vnc_dialog.attr('vm_id',id); + //Request proxy server start + Sunstone.runAction("VM.startvnc",id); + return false; + }); +} + +function vncCallback(request,response){ + rfb = new RFB({'target': $D('VNC_canvas'), + 'encrypt': false, + 'true_color': true, + 'local_cursor': true, + 'shared': true, + 'updateState': updateVNCState}); + //fetch things from clicked element host - port - password + vnc_port = response["port"]; + + //Hopefully this is returning sunstone server address, where + //the proxy is running + vnc_host = window.location.hostname; + vnc_pw = response["password"]; + + setTimeout(function(){ + rfb.connect(vnc_host, vnc_port, vnc_pw); + $vnc_dialog.dialog('open'); + },4000); + +} + +function vncIcon(vm){ + var graphics = vm.TEMPLATE.GRAPHICS; + var state = OCCI.Helper.resource_state("vm_lcm",vm.LCM_STATE); + var gr_icon; + if (graphics && graphics.TYPE == "vnc" && state == "RUNNING"){ + gr_icon = ''; + gr_icon += '\"'+tr("Open'; + } + else { + gr_icon = '\"'+tr("VNC'; + } + return gr_icon; +} + +function vmMonitorError(req,error_json){ + var message = error_json.error.message; + var info = req.request.data[0].monitor; + var labels = info.monitor_resources; + var id_suffix = labels.replace(/,/g,'_'); + var id = '#vm_monitor_'+id_suffix; + $('#vm_monitoring_tab '+id).html('
    '+message+'
    '); +} + +*/ + +// At this point the DOM is ready and the sunstone.js ready() has been run. +$(document).ready(function(){ + + dataTable_vMachines = $("#datatable_vmachines",main_tabs_context).dataTable({ + "bJQueryUI": true, + "bSortClasses": false, + "sPaginationType": "full_numbers", + "bAutoWidth":false, + "aoColumnDefs": [ + { "bSortable": false, "aTargets": ["check"] }, + { "sWidth": "60px", "aTargets": [0] }, + { "sWidth": "35px", "aTargets": [1] }, + ], + "oLanguage": (datatable_lang != "") ? + { + sUrl: "locale/"+lang+"/"+datatable_lang + } : "" + }); + + dataTable_vMachines.fnClearTable(); + addElement([ + spinner, + '',''],dataTable_vMachines); + Sunstone.runAction("VM.list"); + + //setupCreateVMDialog(); + setupSaveasDialog(); + setVMAutorefresh(); + //setupVNC(); + + initCheckAllBoxes(dataTable_vMachines); + tableCheckboxesListener(dataTable_vMachines); + vMachineInfoListener(); + + $('#li_vms_tab a').click(function(){ + popUpVMDashboard(); + }); + + $('.vm_close_dialog_link').live("click",function(){ + popUpVMDashboard(); + return false; + }); +}) \ No newline at end of file diff --git a/src/cloud/occi/lib/ui/public/js/plugins/configuration.js b/src/cloud/occi/lib/ui/public/js/plugins/configuration.js new file mode 100644 index 0000000000..97c5803b1c --- /dev/null +++ b/src/cloud/occi/lib/ui/public/js/plugins/configuration.js @@ -0,0 +1,62 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +var config_tab_content = +'
    \ +\ + \ + \ + \ +
    \ +
    \ +

    ' + tr("Self-Service UI Configuration") + '

    \ +
    \ +\ + \ + \ + \ + \ + \ +
    ' + tr("Language") + '\ + \ +
    \ +\ +
    \ +
    \ +
    '; + +var config_tab = { + title: tr("Configuration"), + content: config_tab_content +} + +Sunstone.addMainTab('config_tab',config_tab); + +$(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()); + }); + + $('#li_config_tab a').click(function(){ + hideDialog(); + }); + +}); \ No newline at end of file diff --git a/src/cloud/occi/lib/ui/public/js/plugins/dashboard.js b/src/cloud/occi/lib/ui/public/js/plugins/dashboard.js new file mode 100644 index 0000000000..f73b25e709 --- /dev/null +++ b/src/cloud/occi/lib/ui/public/js/plugins/dashboard.js @@ -0,0 +1,200 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +var dashboard_tab_content = +'\ +\ +\ +\ +
    \ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
    \ +
    \ +

    ' + dashboard_welcome_title + '

    \ +
    \ +'+ + dashboard_welcome_html+'\ +
    \ +
    \ +
    \ +
    \ +

    ' + tr("Current resources") + '

    \ +
    \ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
    '+tr("Compute")+''+$vm_count+'
    ' + tr("Storage") + ''+$storage_count+'
    ' + tr("Network") + ''+$network_count+'
    \ +\ +
    \ +
    \ +
    \ +
    \ +

    ' + tr("Useful links") + '

    \ +
    '+ + generateDashboardLinks() +'\ +
    \ +
    \ +
    \ +
    \ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
    \ +
    \ +

    ' + compute_box_title + '

    \ +
    \ +'+ + compute_box_html + + '

    '+tr("Create new compute resource")+'
    \ +'+tr("See more")+'

    \ +
    \ +
    \ +
    \ +
    \ +

    ' + storage_box_title + '

    \ +
    \ +' + + storage_box_html + + '

    '+tr("Create new storage resource")+'
    \ +'+tr("See more")+'

    \ +
    \ +
    \ +
    \ +
    \ +

    ' + network_box_title + '

    \ +
    \ +

    ' + + network_box_html + + '

    '+tr("Create new network resource")+'
    \ +'+tr("See more")+'

    \ +
    \ +
    \ +
    \ +
    '; + +var dashboard_tab = { + title: tr("Dashboard"), + content: dashboard_tab_content +} + +Sunstone.addMainTab('dashboard_tab',dashboard_tab); + +function quickstart_setup(){ + + $('#dashboard_table #quickstart_form input',main_tabs_context).click(function(){ + Sunstone.runAction($(this).val()); + }); +}; + +function generateDashboardLinks(){ + var links="
      "; + for (var i=0; i'+dashboard_links[i].text+''; + }; + links+="
    "; + return links; +}; + + +$(document).ready(function(){ + //Dashboard link listener + $("#dashboard_table h3 a",main_tabs_context).live("click", function (){ + var tab = $(this).attr('href'); + showTab(tab); + return false; + }); + + $('.tab_link').click(function(){ + var to= $(this).attr('href'); + $('.outer-west ul li.topTab a[href="'+to+'"]').trigger("click"); + return false; + }); + + $('.action_link').click(function(){ + var to= $(this).attr('href'); + $('.outer-west ul li.topTab a[href="'+to+'"]').trigger("click"); + var action = $(this).attr('action'); + Sunstone.runAction(action); + + //var to= $(this).attr('href'); + //$('.outer-west ul li.topTab a[href="'+to+'"]').trigger("click"); + return false; + }); + + emptyDashboard(); + + quickstart_setup(); + + $('#li_dashboard_tab a').click(function(){ + hideDialog(); + }); + +}); + +//puts the dashboard values into "retrieving" +function emptyDashboard(){ + $("#dashboard_tab .value_td span",main_tabs_context).html(spinner); +} + + +function updateDashboard(what,json_info){ + var db = $('#dashboard_tab',main_tabs_context); + switch (what){ + case "vms": + var total_vms=json_info.length; + $('.vm_count',db).html(total_vms); + break; + case "vnets": + var total_vnets=json_info.length; + $('.network_count',db).html(total_vnets); + break; + case "images": + var total_images=json_info.length; + $('.storage_count',db).html(total_images); + break; + } +} diff --git a/src/cloud/occi/lib/ui/public/js/plugins/network.js b/src/cloud/occi/lib/ui/public/js/plugins/network.js new file mode 100644 index 0000000000..b4146411ae --- /dev/null +++ b/src/cloud/occi/lib/ui/public/js/plugins/network.js @@ -0,0 +1,436 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +/*Virtual networks tab plugin*/ + +var vnets_tab_content = +'
    \ +
    \ +
    \ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
    '+tr("All")+''+tr("ID")+''+tr("Name")+'
    \ +
    '; + +var create_vn_tmpl = +'
    \ +
    \ +
    \ +
    \ + \ +
    \ +
    \ +
    \ +
    \ +
    \ + \ +
    \ + \ +
    \ +
    \ +
    \ +
    \ + \ +
    \ +
    \ +
    \ +
    \ +
    '; + + +var vnet_dashboard = '
    \ +one-network' + +network_dashboard_html + +'
    '; + +var dataTable_vNetworks; +var $create_vn_dialog; + +//Setup actions + +var vnet_actions = { + "Network.create" : { + type: "create", + call: OCCI.Network.create, + callback: addVNetworkElement, + error: onError, + notify: true + }, + + "Network.create_dialog" : { + type: "custom", + call: popUpCreateVnetDialog + }, + + "Network.list" : { + type: "list", + call: OCCI.Network.list, + callback: updateVNetworksView, + error: onError + }, + + "Network.show" : { + type: "single", + call: OCCI.Network.show, + callback: updateVNetworkElement, + error: onError + }, + + "Network.showinfo" : { + type: "single", + call: OCCI.Network.show, + callback: updateVNetworkInfo, + error: onError + + }, + + "Network.refresh" : { + type: "custom", + call: function(){ + waitingNodes(dataTable_vNetworks); + Sunstone.runAction("Network.list"); + } + }, + + "Network.autorefresh" : { + type: "custom", + call: function() { + OCCI.Network.list({timeout: true, success: updateVNetworksView, error: onError}); + } + }, + + // "Network.publish" : { + // type: "multiple", + // call: OCCI.Network.publish, + // //callback: vnShow, + // elements: vnElements, + // error: onError, + // notify: true + // }, + + // "Network.unpublish" : { + // type: "multiple", + // call: OCCI.Network.unpublish, + // //callback: vnShow, + // elements: vnElements, + // error: onError, + // notify: true + // }, + + "Network.delete" : { + type: "multiple", + call: OCCI.Network.delete, + callback: deleteVNetworkElement, + elements: vnElements, + error: onError, + notify: true + }, +}; + + +var vnet_buttons = { + "Network.refresh" : { + type: "image", + text: tr("Refresh list"), + img: "images/Refresh-icon.png" + }, + + "Network.create_dialog" : { + type: "create_dialog", + text: tr("+ New") + }, + + // "Network.publish" : { + // type: "action", + // text: tr("Publish") + // }, + + // "Network.unpublish" : { + // type: "action", + // text: tr("Unpublish") + // }, + + "Network.delete" : { + type: "action", + text: tr("Delete") + } +} + +var vnet_info_panel = { + "vnet_info_tab" : { + title: tr("Network information"), + content: "" + }, +} + + +var vnet_create_panel = { + "vnet_create_panel" : { + title: tr("Create network"), + content: create_vn_tmpl + }, +} + +var vnets_tab = { + title: tr("Networks"), + content: vnets_tab_content, + buttons: vnet_buttons +} + +Sunstone.addActions(vnet_actions); +Sunstone.addMainTab('vnets_tab',vnets_tab); +Sunstone.addInfoPanel('vnet_info_panel',vnet_info_panel); +Sunstone.addInfoPanel('vnet_create_panel',vnet_create_panel); + + +function vnElements(){ + return getSelectedNodes(dataTable_vNetworks); +} + +//returns an array with the VNET information fetched from the JSON object +function vNetworkElementArray(vn_json){ + var network = vn_json.NETWORK; + + if (network.name){ + id = network.href.split("/"); + id = id[id.length-1]; + name = network.name; + } + else { + id = network.ID; + name = network.NAME; + }; + + return [ + '', + id, + name + ]; +}; + + +//Adds a listener to show the extended info when clicking on a row +function vNetworkInfoListener(){ + + $('#tbodyvnetworks tr',dataTable_vNetworks).live("click", function(e){ + if ($(e.target).is('input')) {return true;} + popDialogLoading(); + var aData = dataTable_vNetworks.fnGetData(this); + var id = $(aData[0]).val(); + Sunstone.runAction("Network.showinfo",id); + return false; + }); +} + +//Callback to update a vnet element after an action on it +function updateVNetworkElement(request, vn_json){ + id = vn_json.NETWORK.ID; + element = vNetworkElementArray(vn_json); + updateSingleElement(element,dataTable_vNetworks,'#vnetwork_'+id); +} + +//Callback to delete a vnet element from the table +function deleteVNetworkElement(req){ + deleteElement(dataTable_vNetworks,'#vnetwork_'+req.request.data); +} + +//Callback to add a new element +function addVNetworkElement(request,vn_json){ + var element = vNetworkElementArray(vn_json); + addElement(element,dataTable_vNetworks); +} + +//updates the list of virtual networks +function updateVNetworksView(request, network_list){ + var network_list_array = []; + + $.each(network_list,function(){ + network_list_array.push(vNetworkElementArray(this)); + }); + + updateView(network_list_array,dataTable_vNetworks); + //dependency with dashboard + updateDashboard("vnets",network_list); + +} + +//updates the information panel tabs and pops the panel up +function updateVNetworkInfo(request,vn){ + var vn_info = vn.NETWORK; + var info_tab_content = + '\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
    '+tr("Virtual Network")+' '+vn_info.ID+' '+ + tr("information")+'
    '+tr("ID")+''+vn_info.ID+'
    '+tr("Name")+''+vn_info.NAME+'
    \ +
    \ +
    '; + + var info_tab = { + title: tr("Virtual Network information"), + content: info_tab_content + }; + + Sunstone.updateInfoPanelTab("vnet_info_panel","vnet_info_tab",info_tab); + + Sunstone.popUpInfoPanel("vnet_info_panel"); + $('#dialog .vnet_close_dialog_link').button({ + text:false, + icons: { primary: "ui-icon-closethick" } + }); + +} + +function popUpCreateVnetDialog() { + //$create_vn_dialog.dialog('open'); + //Handle submission of the easy mode + Sunstone.popUpInfoPanel("vnet_create_panel"); + var dialog=$('#dialog'); + $create_vn_dialog = dialog; + + $('#create_vn',dialog).button({ + icons: { + primary: "ui-icon-check" + }, + text: false + }); + $('#reset_vn',dialog).button({ + icons: { + primary: "ui-icon-scissors" + }, + text: false + }); + $('.vnet_close_dialog_link',dialog).button({ + icons: { + primary: "ui-icon-closethick" + }, + text: false + }); + + $('#create_vn_form_easy',dialog).submit(function(){ + //Fetch values + var name = $('#name',this).val(); + if (!name.length){ + notifyError(tr("Virtual Network name missing!")); + return false; + } + var bridge = $('#bridge',this).val(); + + //TODO: Name and bridge provided?! + + var network_json = null; + var network_addr = $('#net_address',this).val(); + var network_size = $('#net_size',this).val(); + + if (!network_addr.length){ + notifyError(tr("Please provide a network address")); + return false; + }; + + //we form the object for the request + network_json = { + "SIZE" : network_size, + "ADDRESS" : network_addr, + "NAME" : name + }; + + Sunstone.runAction("Network.create",network_json); + popUpVNetDashboard(); + return false; + }); + +} + +function popUpVNetDashboard(){ + var count = dataTable_vNetworks.fnGetNodes().length; + popDialog(vnet_dashboard); + $('#dialog .network_count').text(count); +} + +function setVNetAutorefresh() { + setInterval(function(){ + var checked = $('input.check_item:checked',dataTable_vNetworks); + var filter = $("#datatable_vnetworks_filter input", + dataTable_vNetworks.parents("#datatable_vnetworks_wrapper")).attr('value'); + if (!checked.length && !filter.length){ + Sunstone.runAction("Network.autorefresh"); + } + },INTERVAL+someTime()); +}; + +//The DOM is ready and the ready() from sunstone.js +//has been executed at this point. +$(document).ready(function(){ + + dataTable_vNetworks = $("#datatable_vnetworks",main_tabs_context).dataTable({ + "bJQueryUI": true, + "bSortClasses": false, + "bAutoWidth":false, + "sPaginationType": "full_numbers", + "aoColumnDefs": [ + { "bSortable": false, "aTargets": ["check"] }, + { "sWidth": "60px", "aTargets": [0] }, + { "sWidth": "35px", "aTargets": [1] }, + ], + "oLanguage": (datatable_lang != "") ? + { + sUrl: "locale/"+lang+"/"+datatable_lang + } : "" + }); + + dataTable_vNetworks.fnClearTable(); + addElement([ + spinner, + '',''],dataTable_vNetworks); + Sunstone.runAction("Network.list"); + + setVNetAutorefresh(); + + initCheckAllBoxes(dataTable_vNetworks); + tableCheckboxesListener(dataTable_vNetworks); + vNetworkInfoListener(); + + $('#li_vnets_tab a').click(function(){ + popUpVNetDashboard(); + //return false; + }); + + $('.vnet_close_dialog_link').live("click",function(){ + popUpVNetDashboard(); + return false; + }); + +}); diff --git a/src/cloud/occi/lib/ui/public/js/plugins/storage.js b/src/cloud/occi/lib/ui/public/js/plugins/storage.js new file mode 100644 index 0000000000..131c824f24 --- /dev/null +++ b/src/cloud/occi/lib/ui/public/js/plugins/storage.js @@ -0,0 +1,640 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2011, OpenNebula Project Leads (OCCI.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. */ +/* -------------------------------------------------------------------------- */ + +/*Images tab plugin*/ + +var images_tab_content = +'
    \ +
    \ +
    \ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
    '+tr("All")+''+tr("ID")+''+tr("Name")+'
    \ +
    '; + +var create_image_tmpl = +'
    \ +
    \ +
    \ +

    '+ + tr("Fields marked with")+' '+ + tr("are mandatory")+'
    \ +

    \ +
    \ + \ + \ +
    '+tr("Name that the Image will get.")+'
    \ +
    \ +
    \ + \ + \ +
    '+tr("Human readable description of the image.")+'
    \ +
    \ +
    \ +
    \ +
    \ + \ + \ +
    '+tr("Type of the image")+'
    \ +
    \ +
    \ + \ + \ +
    '+tr("Size of the datablock in MB.")+'
    \ +
    \ +
    \ + \ + \ +
    '+tr("Type of file system to be built. This can be any value understood by mkfs unix command.")+'
    \ +
    \ +
    \ + \ +
    \ +
    \ + \ +
    \ +
    \ +\ +
    \ +
    \ + \ +
    \ +
    '; + +var image_dashboard = '
    \ +one-storage'+ + storage_dashboard_html + + '
    '; + +var dataTable_images; +var $create_image_dialog; + +var image_actions = { + + "Image.create" : { + type: "create", + call: OCCI.Image.create, + callback: addImageElement, + error: onError, + notify:true + }, + + "Image.create_dialog" : { + type: "custom", + call: popUpCreateImageDialog + }, + + "Image.list" : { + type: "list", + call: OCCI.Image.list, + callback: updateImagesView, + error: onError + }, + + "Image.show" : { + type : "single", + call: OCCI.Image.show, + callback: updateImageElement, + error: onError + }, + + "Image.showinfo" : { + type: "single", + call: OCCI.Image.show, + callback: updateImageInfo, + error: onError + }, + + "Image.refresh" : { + type: "custom", + call: function () { + waitingNodes(dataTable_images); + Sunstone.runAction("Image.list"); + }, + }, + + "Image.autorefresh" : { + type: "custom", + call: function() { + OCCI.Image.list({timeout: true, success: updateImagesView, error: onError}); + } + }, + + "Image.persistent" : { + type: "multiple", + call: OCCI.Image.persistent, + elements: imageElements, + error: onError, + notify: true + }, + + "Image.nonpersistent" : { + type: "multiple", + call: OCCI.Image.nonpersistent, + elements: imageElements, + error: onError, + notify: true + }, + + // "Image.publish" : { + // type: "multiple", + // call: OCCI.Image.publish, + // callback: function (req) { + // //Sunstone.runAction("Image.show",req.request.data[0]); + // }, + // elements: imageElements, + // error: onError, + // notify: true + // }, + + // "Image.unpublish" : { + // type: "multiple", + // call: OCCI.Image.unpublish, + // callback: function (req) { + // //Sunstone.runAction("Image.show",req.request.data[0]); + // }, + // elements: imageElements, + // error: onError, + // notify: true + // }, + + "Image.delete" : { + type: "multiple", + call: OCCI.Image.delete, + callback: deleteImageElement, + elements: imageElements, + error: onError, + notify: true + }, +} + + +var image_buttons = { + "Image.refresh" : { + type: "image", + text: tr("Refresh list"), + img: "images/Refresh-icon.png" + }, + "Image.create_dialog" : { + type: "create_dialog", + text: tr('+ New') + }, + "Image.persistent" : { + type: "action", + text: tr("Make persistent") + }, + "Image.nonpersistent" : { + type: "action", + text: tr("Make non persistent") + }, + // "action_list" : { + // type: "select", + // actions: { + // "Image.publish" : { + // type: "action", + // text: tr("Publish") + // }, + // "Image.unpublish" : { + // type: "action", + // text: tr("Unpublish") + // }, + // } + // }, + "Image.delete" : { + type: "action", + text: tr("Delete") + } +} + +var image_info_panel = { + "image_info_tab" : { + title: tr("Image information"), + content: "" + }, + +}; + +var image_create_panel = { + "image_create_panel" : { + title: tr("Add storage"), + content: create_image_tmpl + }, +}; + +var images_tab = { + title: tr("Storage"), + content: images_tab_content, + buttons: image_buttons +} + +Sunstone.addActions(image_actions); +Sunstone.addMainTab('images_tab',images_tab); +Sunstone.addInfoPanel('image_info_panel',image_info_panel); +Sunstone.addInfoPanel('image_create_panel',image_create_panel); + + +function imageElements() { + return getSelectedNodes(dataTable_images); +} + +// Returns an array containing the values of the image_json and ready +// to be inserted in the dataTable +function imageElementArray(image_json){ + //Changing this? It may affect to the is_public() and is_persistent() functions. + var image = image_json.STORAGE; + var id,name; + + if (image.name){ + id = image.href.split("/"); + id = id[id.length-1]; + name = image.name; + } + else { + id = image.ID; + name = image.NAME; + }; + + return [ + '', + id, + name + ]; +} + +// Set up the listener on the table TDs to show the info panel +function imageInfoListener(){ + $('#tbodyimages tr',dataTable_images).live("click",function(e){ + var target = $(e.target); + + if (target.is('input') || target.is('select') || target.is('option')) + return true; + + popDialogLoading(); + var aData = dataTable_images.fnGetData(this); + var id = $(aData[0]).val(); + Sunstone.runAction("Image.showinfo",id); + return false; + }); +} + +// Callback to update an element in the dataTable +function updateImageElement(request, image_json){ + var id = image_json.STORAGE.ID; + var element = imageElementArray(image_json); + updateSingleElement(element,dataTable_images,'#image_'+id); +} + +// Callback to remove an element from the dataTable +function deleteImageElement(req){ + deleteElement(dataTable_images,'#image_'+req.request.data); +} + +// Callback to add an image element +function addImageElement(request, image_json){ + var element = imageElementArray(image_json); + addElement(element,dataTable_images); +} + +// Callback to refresh the list of images +function updateImagesView(request, images_list){ + var image_list_array = []; + + $.each(images_list,function(){ + image_list_array.push(imageElementArray(this)); + }); + + updateView(image_list_array,dataTable_images); + updateDashboard("images",images_list); +} + +// Callback to update the information panel tabs and pop it up +function updateImageInfo(request,img){ + var img_info = img.STORAGE; + var info_tab = { + title: tr("Image information"), + content: + '
    \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
    '+tr("Image")+' "'+img_info.NAME+'" '+ + tr("information")+'
    '+tr("ID")+''+img_info.ID+'
    '+tr("Name")+''+img_info.NAME+'
    '+tr("Name")+''+img_info.DESCRIPTION+'
    '+tr("Type")+''+OCCI.Helper.image_type(img_info.TYPE)+'
    '+tr("Persistent")+'
    '+tr("Filesystem type")+''+(typeof img_info.FSTYPE === "string" ? img_info.FSTYPE : "--")+'
    '+tr("Size (Mb)")+''+img_info.SIZE+'
    \ +
    \ +
    ' + }; + + Sunstone.updateInfoPanelTab("image_info_panel","image_info_tab",info_tab); + Sunstone.popUpInfoPanel("image_info_panel"); + $('#dialog .image_close_dialog_link').button({ + text:false, + icons: { primary: "ui-icon-closethick" } + }); + $('#dialog input').click(function(){ + if ($(this).is(':checked')) + Sunstone.runAction("Image.persistent",[img_info.ID]) + else + Sunstone.runAction("Image.nonpersistent",[img_info.ID]) + }); +} + +function popUpCreateImageDialog(){ + Sunstone.popUpInfoPanel("image_create_panel"); + var dialog = $('#dialog'); + $create_image_dialog = dialog; + + $('#create_image',dialog).button({ + icons: { + primary: "ui-icon-check" + }, + text: false + }); + $('#reset_image',dialog).button({ + icons: { + primary: "ui-icon-scissors" + }, + text: false + }); + $('.image_close_dialog_link',dialog).button({ + icons: { + primary: "ui-icon-closethick" + }, + text: false + }); + + setupTips(dialog); + + $('#img_fstype',dialog).parents('div.img_param').hide(); + $('#img_size',dialog).parents('div.img_param').hide(); + +/* + $('#img_public',dialog).click(function(){ + $('#img_persistent',$create_image_dialog).removeAttr('checked'); + }); + + $('#img_persistent',dialog).click(function(){ + $('#img_public',$create_image_dialog).removeAttr('checked'); + }); +*/ + $('#img_type',dialog).change(function(){ + if ($(this).val() == "DATABLOCK"){ + $('#img_fstype',$create_image_dialog).parents('div.img_param').show(); + $('#img_size',$create_image_dialog).parents('div.img_param').show(); + $('#upload_div',$create_image_dialog).hide(); + } else { + $('#img_fstype',$create_image_dialog).parents('div.img_param').hide(); + $('#img_size',$create_image_dialog).parents('div.img_param').hide(); + $('#upload_div',$create_image_dialog).show(); + }; + }); + + $('#upload-progress',dialog).progressbar({value:0}); + $('#upload-progress',dialog).css({ + border: "1px solid #AAAAAA", + position: "relative", +// bottom: "29px", + width: "210px", +// 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: 'ui/upload', + multiple: false, + params: {}, + showMessage: function(message){ + notifyMessage(message); + }, + onSubmit: function(id, fileName){ + var xml = json2xml(img_obj,"STORAGE"); + + uploader.setParams({ + occixml : xml, + file: fileName + }); + + $('#upload-progress',dialog).show(); + }, + onProgress: function(id, fileName, loaded, total){ + $('#upload-progress',dialog).progressbar("option","value",Math.floor(loaded*100/total)); + }, + onComplete: function(id, fileName, responseJSON){ + popUpImageDashboard(); + notifyMessage("Image uploaded correctly"); + 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; + }; + + $('#file-uploader input').removeAttr("style"); + + var processCreateImageForm = function(){ + var dialog = $create_image_dialog; + + var img_json = {}; + + var name = $('#img_name',dialog).val(); + if (!name){ + notifyError(tr("You must specify a name")); + return false; + }; + img_json["NAME"] = name; + + + var desc = $('#img_desc',dialog).val(); + if (desc){ + img_json["DESCRIPTION"] = desc; + } + + var type = $('#img_type',dialog).val(); + img_json["TYPE"]= type; + + if (type == "DATABLOCK"){ + var fstype = $('#img_fstype',dialog).val(); + var im_size = $('#img_size',dialog).val(); + if (!fstype || !im_size){ + notifyError(tr("You must specify size and FS type")); + return false; + }; + img_json["FSTYPE"] = fstype; + img_json["SIZE"] = im_size; + } else { + if (!$('#file-uploader input').val()){ + notifyError(tr("You must select a file to upload")); + return false; + }; + } + + + //img_json["PUBLIC"] = $('#img_public:checked',this).length ? "YES" : "NO"; + + //img_json["PERSISTENT"] = $('#img_persistent:checked',this).length ? "YES" : "NO"; + + return img_json; + }; + + $('#create_image_form_easy',dialog).submit(function(){ + var type = $('#img_type',dialog).val(); + img_obj = processCreateImageForm(); + if (!img_obj) return false; + if (type == "DATABLOCK"){ + Sunstone.runAction("Image.create",img_obj); + popUpImageDashboard(); + } else { + uploader._onInputChange(file_input); + }; + return false; + }); +} + +function popUpImageDashboard(){ + var count = dataTable_images.fnGetNodes().length; + popDialog(image_dashboard); + $('#dialog .storage_count').text(count); +}; + +// Set the autorefresh interval for the datatable +function setImageAutorefresh() { + setInterval(function(){ + var checked = $('input.check_item:checked',dataTable_images); + var filter = $("#datatable_images_filter input", + dataTable_images.parents("#datatable_images_wrapper")).attr('value'); + if (!checked.length && !filter.length){ + Sunstone.runAction("Image.autorefresh"); + } + },INTERVAL+someTime()); +}; + +/* +function is_public_image(id){ + var data = getElementData(id,"#image",dataTable_images)[7]; + return $(data).attr('checked'); +}; + +function is_persistent_image(id){ + var data = getElementData(id,"#image",dataTable_images)[8]; + return $(data).attr('checked'); +}; +*/ + +//The DOM is ready at this point +$(document).ready(function(){ + + dataTable_images = $("#datatable_images",main_tabs_context).dataTable({ + "bJQueryUI": true, + "bSortClasses": false, + "bAutoWidth":false, + "sPaginationType": "full_numbers", + "aoColumnDefs": [ + { "bSortable": false, "aTargets": ["check"] }, + { "sWidth": "60px", "aTargets": [0] }, + { "sWidth": "35px", "aTargets": [1] }, + ], + "oLanguage": (datatable_lang != "") ? + { + sUrl: "locale/"+lang+"/"+datatable_lang + } : "" + }); + + dataTable_images.fnClearTable(); + addElement([ + spinner, + '',''],dataTable_images); + Sunstone.runAction("Image.list"); + + setImageAutorefresh(); + + initCheckAllBoxes(dataTable_images); + tableCheckboxesListener(dataTable_images); + imageInfoListener(); + + $('#li_images_tab a').click(function(){ + popUpImageDashboard(); + //return false; + }); + + $('.image_close_dialog_link').live("click",function(){ + popUpImageDashboard(); + return false; + }); + +}) diff --git a/src/cloud/occi/lib/ui/public/locale/en_US/en_US.js b/src/cloud/occi/lib/ui/public/locale/en_US/en_US.js new file mode 100644 index 0000000000..1d13154a89 --- /dev/null +++ b/src/cloud/occi/lib/ui/public/locale/en_US/en_US.js @@ -0,0 +1,157 @@ +//Translated by +lang="en_US" +datatable_lang="" +locale={ + "Additionally, OpenNebula Self-Service allows easy customization of the interface (e.g. this text) and brings multi-language support.":"", + "Additionally, you can run several operations on defined storages, such as defining their persistance. Persistent images can only be used by 1 virtual machine, and the changes made by it have effect on the base image. Non-persistent images are cloned before being used in a Virtual Machine, therefore changes are lost unless a snapshot is taken prior to Virtual Machine shutdown.":"", + "Additionally, you can take a \'snapshot\' of the storage attached to these resources. They will be saved as new resources, visible from the Storage view and re-usable.":"", + "Add storage":"", + "All":"", + "are mandatory":"", + "Cancel":"", + "Cannot contact server: is it running and reachable?":"", + "Canvas not supported.":"", + "CD-ROM":"", + "Changing language":"", + "Community":"", + "Compute":"", + "Compute resource":"", + "Compute resources are Virtual Machines attached to storage and network resources. OpenNebula Self-Service allows you to easily create, remove and manage them, including the possibility of pausing a Virtual Machine or taking a snapshot of one of their disks.":"", + "Compute resources can be attached to these networks at creation time. Virtual machines will be provided with an IP and the correct parameters to ensure connectivity.":"", + "Configuration":"", + "Confirmation of action":"", + "CPU":"", + "Create network":"", + "Create new compute resource":"", + "Create new network resource":"", + "Create new storage resource":"", + "Create Virtual Machine":"", + "Create # VMs":"", + "Current resources":"", + "Dashboard":"", + "Datablock":"", + "Delete":"", + "Description":"", + "disk id":"", + "Disks":"", + "Disks information":"", + "Documentation":"", + "Do you want to proceed?":"", + "English":"", + "Error":"", + "Fields marked with":"", + "Filesystem type":"", + "FS type":"", + "Have a cloudy experience!":"", + "Human readable description of the image.":"", + "ID":"", + "Image":"", + "Image information":"", + "Image name":"", + "images":"", + "Images":"", + "Info":"", + "information":"", + "Instance type":"", + "In this view you can easily manage OpenNebula Network resources. You can add or remove virtual networks.":"", + "IP":"", + "Language":"", + "Loading":"", + "MAC":"", + "Make non persistent":"", + "Make persistent":"", + "Memory":"", + "Monitoring information":"", + "Name":"", + "Name that the Image will get.":"", + "Network":"", + "Network Address":"", + "Network information":"", + "Network is unreachable: is OpenNebula running?":"", + "Network reception":"", + "networks":"", + "Networks":"", + "Networks information":"", + "Network Size":"", + "Network transmission":"", + "+ New":"", + "No disk id or image name specified":"", + "No disks defined":"", + "No networks defined":"", + "OK":"", + "OpenNebula Self-Service is a simplified user interface to manage OpenNebula compute, storage and network resources. It is focused on easiness and usability and features a limited set of operations directed towards end-users.":"", + "Open VNC Session":"", + "OS":"", + "Persistence of the image":"", + "Persistent":"", + "Please, choose and modify the template you want to update":"", + "Please provide a network address":"", + "Please select":"", + "Previous action":"", + "Public":"", + "Public scope of the image":"", + "Publish":"", + "Refresh list":"", + "Resume":"", + "Retrieving":"", + "Saveas for VM with ID":"", + "See more":"", + "Select a template":"", + "Select disk":"", + "Self-Service UI Configuration":"", + "Shutdown":"", + "Sign out":"", + "Size":"", + "Size (Mb)":"", + "Size of the datablock in MB.":"", + "Skipping VM ":"", + "Spanish":"", + "State":"", + "Stop":"", + "Storage":"", + "Storage pool is formed by several images. These images can contain from full operating systems to be used as base for compute resources, to simple data. OpenNebula Self-Service offers you the possibility to create or upload your own images.":"", + "String":"", + "style":"", + "Submitted":"", + "Support":"", + "Suspend":"", + "Take snapshot":"", + "Target":"", + "There are currently":"", + "The Storage view offers you an overview of your current images. Storage elements are attached to compute resources at creation time. They can also be extracted from running virtual machines by taking an snapshot.":"", + "This is a list of your current compute resources. Virtual Machines use previously defined images and networks. You can easily create a new compute element by cliking \'new\' and filling-in an easy wizard.":"", + "This will cancel selected VMs":"", + "This will delete the selected VMs from the database":"", + "This will resume the selected VMs in stopped or suspended states":"", + "This will shutdown the selected VMs":"", + "This will suspend the selected VMs":"", + "Type":"", + "Type of file system to be built. This can be any value understood by mkfs unix command.":"", + "Type of the image":"", + "Unauthorized":"", + "Unpublish":"", + "Update":"", + "Update template":"", + "Upload image":"", + "Upload progress":"", + "Useful links":"", + "Virtual Machine information":"", + "virtual machines":"", + "Virtual Network":"", + "Virtual Network information":"", + "Virtual Network name missing!":"", + "VM information":"", + "VM Name":"", + "VNC connection":"", + "VNC Disabled":"", + "Welcome":"", + "Welcome to OpenNebula Self-Service":"", + "You can add new storages by clicking \'new\'. Image files will be uploaded to OpenNebula and set ready to be used.":"", + "You can also manage compute resources and perform actions such as stop, resume, shutdown or cancel.":"", + "You have to confirm this action.":"", + "You must select a file to upload":"", + "You must specify a name":"", + "You must specify size and FS type":"", + "You need to select something.":"", + "Your compute resources connectivity is performed using pre-defined virtual networks. You can create and manage these networks using OpenNebula Self-Service.":"", +}; diff --git a/src/cloud/occi/lib/ui/public/locale/es_ES/es_ES.js b/src/cloud/occi/lib/ui/public/locale/es_ES/es_ES.js new file mode 100644 index 0000000000..96d30e7769 --- /dev/null +++ b/src/cloud/occi/lib/ui/public/locale/es_ES/es_ES.js @@ -0,0 +1,157 @@ +//Translated by +lang="es_ES" +datatable_lang="es_datatable.txt" +locale={ + "Additionally, OpenNebula Self-Service allows easy customization of the interface (e.g. this text) and brings multi-language support.":"Además, OpenNebula Self-Service permite una fácil personalización de la interfaz (por ejemplo, de este mismo texto) y viene con soporte para múltiples lenguajes.", + "Additionally, you can run several operations on defined storages, such as defining their persistance. Persistent images can only be used by 1 virtual machine, and the changes made by it have effect on the base image. Non-persistent images are cloned before being used in a Virtual Machine, therefore changes are lost unless a snapshot is taken prior to Virtual Machine shutdown.":"Además, puede ejecutar varias operaciones en los almacenamientos presentes, como definir su persistencia. Las imágenes persistentes sólo pueden ser usadas por 1 máquina virtual, y los cambios realizados por ella tiene efecto en la imágen base. Las imágenes no persistentes son clonadas antes de ser utilizadas en una máquina virtual, por tanto los cambios se pierden a menos que se tome una instantánea antes de apagar la máquina virtual.", + "Additionally, you can take a 'snapshot' of the storage attached to these resources. They will be saved as new resources, visible from the Storage view and re-usable.":"Además, puede tomar una 'instantánea' de los almacenamientos asociado a estos recursos. Ésta será salvaguardada como un nuevo recurso, visible y reutilizable desde la vista de almacenamientos.", + "Add storage":"Añadir almacenamiento", + "All":"Todos", + "are mandatory":"son obligatorios", + "Cancel":"Cancelar", + "Cannot contact server: is it running and reachable?":"No se puede contactar con el servidor: ¿está funcionando y es alcanzable?", + "Canvas not supported.":"Canvas no soportado", + "CD-ROM":"CD-ROM", + "Changing language":"Cambiando el lenguaje", + "Community":"Comunidad", + "Compute":"Máquinas Virtuales", + "Compute resource":"máquina virtual", + "Compute resources are Virtual Machines attached to storage and network resources. OpenNebula Self-Service allows you to easily create, remove and manage them, including the possibility of pausing a Virtual Machine or taking a snapshot of one of their disks.":"Las máquinas virtuales están asociadas a recursos de almacenamiento y de red. OpenNebula Self-Service le permite crearlos, borrarlos y administrarlos fácilmente, incluyendo la posibilidad de pausar una máquina virtual o de tomar una instantánea de alguno de sus discos.", + "Compute resources can be attached to these networks at creation time. Virtual machines will be provided with an IP and the correct parameters to ensure connectivity.":"Las máquinas virtuales pueden asociarse a estas redes en el momento de su creación. Las máquinas virtuales serán provistas de una IP y de los parámetros correctos para asegurar conectividad.", + "Configuration":"Configuración", + "Confirmation of action":"Confirmar operación", + "CPU":"CPU", + "Create network":"Crear red", + "Create new compute resource":"Crear nueva máquina virtual", + "Create new network resource":"Crear nueva red", + "Create new storage resource":"Crear nuevo almacenamiento", + "Create Virtual Machine":"Crear máquina virtual", + "Create # VMs":"Crear # MVs", + "Current resources":"Recursos actuales", + "Dashboard":"Portada", + "Datablock":"Datablock", + "Delete":"Borrar", + "Description":"Descripción", + "disk id":"id del disco", + "Disks":"Discos", + "Disks information":"Información de discos", + "Documentation":"Documentación", + "Do you want to proceed?":"¿Desea continuar?", + "English":"Inglés", + "Error":"Error", + "Fields marked with":"Campos marcados con", + "Filesystem type":"Sistema de ficheros", + "FS type":"tipo de FS", + "Have a cloudy experience!":"¡Nos vemos en las nubes!", + "Human readable description of the image.":"Descripción de la imagen.", + "ID":"ID", + "Image":"Imagen", + "Image information":"Información de la imagen", + "Image name":"Nombre de la imagen", + "images":"imágenes", + "Images":"Imágenes", + "Info":"Información", + "information":"Información", + "Instance type":"Tipo de instancia", + "In this view you can easily manage OpenNebula Network resources. You can add or remove virtual networks.":"En esta vista puede gestionar fácilmente los recursos de red de OpenNebula. Puede añadir o borrar redes virtuales.", + "IP":"IP", + "Language":"Lenguaje", + "Loading":"Cargando", + "MAC":"MAC", + "Make non persistent":"Hacer no persistente", + "Make persistent":"Hacer persistente", + "Memory":"Memoria", + "Monitoring information":"Información de monitorización", + "Name":"Nombre", + "Name that the Image will get.":"Nombre para la imagen.", + "Network":"Red", + "Network Address":"Dirección de red", + "Network information":"Información de red", + "Network is unreachable: is OpenNebula running?":"No se puede alcanzar la red: ¿está OpenNebula funcionando?", + "Network reception":"Recepción de red", + "networks":"redes", + "Networks":"Redes", + "Networks information":"Información de redes", + "Network Size":"Tamaño de red", + "Network transmission":"Transmisión de red", + "+ New":"+ Nuevo", + "No disk id or image name specified":"No se ha especificado ID de disco o nombre de la imagen", + "No disks defined":"No hay discos definidos", + "No networks defined":"No hay redes definidas", + "OK":"OK", + "OpenNebula Self-Service is a simplified user interface to manage OpenNebula compute, storage and network resources. It is focused on easiness and usability and features a limited set of operations directed towards end-users.":"OpenNebula Self-Service es una interfaz de usuario simplificada para administrar máquinas virtuales, almacenamiento y red de OpenNebula. Está basada en la facilidad de uso y cuenta con un número limitado de operaciones dirigidas a los usuarios finales.", + "Open VNC Session":"Abrir sesión VNC", + "OS":"OS", + "Persistence of the image":"Persistencia de la imagen", + "Persistent":"Persistente", + "Please, choose and modify the template you want to update":"Por favor, escoja y modifique la plantilla que desea actualizar", + "Please provide a network address":"Por favor, proporcione una dirección de red", + "Please select":"Por favor escoja", + "Previous action":"Acción anterior", + "Public":"Público", + "Public scope of the image":"", + "Publish":"Publicar", + "Refresh list":"Refrescar lista", + "Resume":"Reanudar", + "Retrieving":"Cargando", + "Saveas for VM with ID":"Instantánea a MV con ID", + "See more":"Ver más", + "Select a template":"Seleccione una plantilla", + "Select disk":"Seleccione un disco", + "Self-Service UI Configuration":"Configuración de la interfaz Self-Service", + "Shutdown":"Apagar", + "Sign out":"Desconectar", + "Size":"Tamaño", + "Size (Mb)":"Tamaño (Mb)", + "Size of the datablock in MB.":"Tamaño del datablcok en MB", + "Skipping VM ":"Saltando MV", + "Spanish":"Español", + "State":"Estado", + "Stop":"Detener", + "Storage":"Almacenamiento", + "Storage pool is formed by several images. These images can contain from full operating systems to be used as base for compute resources, to simple data. OpenNebula Self-Service offers you the possibility to create or upload your own images.":"La lista de almacenamiento está formada por varias imágenes. Estas imágenes pueden contener desde sistemas operativos completos para ser usados como base en máquinas virtuales, hasta simples datos. OpenNebula Self-Service ofrece la posibilidad de crear o subir sus propias imágenes.", + "String":"String", + "style":"estilo", + "Submitted":"Hecho", + "Support":"Soporte", + "Suspend":"Suspender", + "Take snapshot":"Tomar instantánea", + "Target":"Target", + "There are currently":"Actualmente hay", + "The Storage view offers you an overview of your current images. Storage elements are attached to compute resources at creation time. They can also be extracted from running virtual machines by taking an snapshot.":"La vista de almacenamiento le ofrece la visión general de sus imágenes. Los elementos de almacenamiento se asocian a máquinas virtuales en el momento de la creación. También pueden ser extraídos de una máquina virtual en ejecución tomando una instantánea", + "This is a list of your current compute resources. Virtual Machines use previously defined images and networks. You can easily create a new compute element by cliking 'new' and filling-in an easy wizard.":"Esta es una lista de sus máquinas virtuales actuales. Las máquinas virtuales utilizan imagenes y redes definidas previamente. Puede crear fácilmente una nueva máquina virtual haciendo click en 'New' y rellenado un sencillo formulario.", + "This will cancel selected VMs":"Esto cancelará las MVs seleccionadas", + "This will delete the selected VMs from the database":"Esto borrará las MVs seleccionadas de la base de datos", + "This will resume the selected VMs in stopped or suspended states":"Esto reanudará las MVs seleccionadas paradas o suspendidas", + "This will shutdown the selected VMs":"Esto apagará las MVs seleccionadas", + "This will suspend the selected VMs":"Esto suspenderá las MVs seleccionadas", + "Type":"Tipo", + "Type of file system to be built. This can be any value understood by mkfs unix command.":"Tipo de sistema de archivos a generar. Es válido cualquier valor entendido por el comando mkfs", + "Type of the image":"Tipo de la imagen", + "Unauthorized":"No autorizado", + "Unpublish":"Despublicar", + "Update":"Actualizar", + "Update template":"Actualizar plantilla", + "Upload image":"Subir imagen", + "Upload progress":"Progreso se subida", + "Useful links":"Enlances útiles", + "Virtual Machine information":"Información de máquina virtual", + "virtual machines":"máquinas virtuales", + "Virtual Network":"Red virtual", + "Virtual Network information":"Información de red virtual", + "Virtual Network name missing!":"¡Falta el nombre de la red!", + "VM information":"Información de MV", + "VM Name":"Nombre", + "VNC connection":"Conexión VNC", + "VNC Disabled":"VNC Desabilitado", + "Welcome":"Bienvenid@", + "Welcome to OpenNebula Self-Service":"Bienvenid@ a OpenNebula Self-Service", + "You can add new storages by clicking 'new'. Image files will be uploaded to OpenNebula and set ready to be used.":"Puede añadir nuevos almacenamientos haciendo click en 'new'. Los ficheros de imagen pueden ser subidos a OpenNebula y preparados para ser usado.", + "You can also manage compute resources and perform actions such as stop, resume, shutdown or cancel.":"También puede administrar las máquinas virtuales y realizar acciones como detener, reanudar, apagar o cancelar.", + "You have to confirm this action.":"Necesita confirmar esta acción", + "You must select a file to upload":"Debe seleccionar un fichero para subir", + "You must specify a name":"Debe especificar un nombre", + "You must specify size and FS type":"Debe especificar un tamaño y un tipo de FS", + "You need to select something.":"Debe seleccionar algo", + "Your compute resources connectivity is performed using pre-defined virtual networks. You can create and manage these networks using OpenNebula Self-Service.":"La conectividad de sus máquinas virtuales se realiza usando redes virtuales pre-definidas. Puede crear y administrar estas redes usando OpenNebula Self-Service.", +}; diff --git a/src/cloud/occi/lib/ui/public/locale/es_ES/es_datatable.txt b/src/cloud/occi/lib/ui/public/locale/es_ES/es_datatable.txt new file mode 100644 index 0000000000..fb48fd561b --- /dev/null +++ b/src/cloud/occi/lib/ui/public/locale/es_ES/es_datatable.txt @@ -0,0 +1,17 @@ +{ + "sProcessing": "Procesando...", + "sLengthMenu": "Número de elementos", + "sZeroRecords": "No hay elementos", + "sInfo": "Mostrando del _START_ al _END_ de _TOTAL_", + "sInfoEmpty": "No hay elementos", + "sInfoFiltered": "(filtado de un total de _MAX_)", + "sInfoPostFix": "", + "sSearch": "Buscar:", + "sUrl": "", + "oPaginate": { + "sFirst": "Primero", + "sPrevious": "Anterior", + "sNext": "Siguiente", + "sLast": "Último" + } +} diff --git a/src/cloud/occi/lib/ui/public/locale/generate_translation_template.rb b/src/cloud/occi/lib/ui/public/locale/generate_translation_template.rb new file mode 100755 index 0000000000..e6adde7429 --- /dev/null +++ b/src/cloud/occi/lib/ui/public/locale/generate_translation_template.rb @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby +# -*- coding: utf-8 -*- + +# -------------------------------------------------------------------------- # +# 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. # +#--------------------------------------------------------------------------- # + +tr_strings = `grep -h -o -R -e 'tr("[[:print:]]*")' ../js/* ../customize/* | cut -d'"' -f 2 | sort -u` + +puts "//Translated by" +puts 'lang="en_US"' +puts 'datatable_lang=""' +puts "locale={" + +tr_strings.each_line do | line | + puts " \"#{line.chomp}\":\"\"," +end + +puts "};" diff --git a/src/cloud/occi/lib/ui/public/locale/upgrade_translation.js b/src/cloud/occi/lib/ui/public/locale/upgrade_translation.js new file mode 100755 index 0000000000..11da65b55d --- /dev/null +++ b/src/cloud/occi/lib/ui/public/locale/upgrade_translation.js @@ -0,0 +1,52 @@ +#!/usr/bin/js +/* -------------------------------------------------------------------------- */ +/* 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 (!arguments[0] || !arguments[1]){ + print("Usage: upgrade_translation.js > "); + quit(); +}; + +var from = arguments[0]; +var to = arguments[1]; + +load(from); +var tr=""; +var locale_old= {}; +for (tr in locale){ + locale_old[tr] = locale[tr]; +}; + +var lang_old = lang; +var dt_lang_old = datatable_lang + +load(to); +for (tr in locale){ + if (locale_old[tr]){ + locale[tr] = locale_old[tr] + }; +}; + +print("//Translated by"); +print('lang="'+lang_old+'"'); +print('datatable_lang="'+dt_lang_old+'"'); +print("locale={"); + +for (tr in locale){ + print(' "'+tr+'":"'+locale[tr]+'",'); +}; + +print("};"); \ No newline at end of file diff --git a/src/cloud/occi/lib/ui/templates/login.html b/src/cloud/occi/lib/ui/templates/login.html new file mode 100644 index 0000000000..a0bf676c1a --- /dev/null +++ b/src/cloud/occi/lib/ui/templates/login.html @@ -0,0 +1,53 @@ + + + + OpenNebula Self-Service Login + + + + + + + + + + + + + + + + +
    +
    +
    + +
    + Invalid username or password +
    +
    + OpenNebula is not running +
    + +
    +
    +
    + Username + + Password + +
    + + + + +
    +
    +
    +
    + + diff --git a/src/cloud/occi/lib/ui/views/index.erb b/src/cloud/occi/lib/ui/views/index.erb new file mode 100644 index 0000000000..e004a7e443 --- /dev/null +++ b/src/cloud/occi/lib/ui/views/index.erb @@ -0,0 +1,90 @@ + + + + OpenNebula Self-Service + + + + + + + + + + + + + + + + + + + + +<%if session[:lang]%> + +<%end%> + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    + + + + + + + + +
    + +
    +
    + +
    +
    + + diff --git a/src/dm/DispatchManagerActions.cc b/src/dm/DispatchManagerActions.cc index 37189b4a81..b728bd0e06 100644 --- a/src/dm/DispatchManagerActions.cc +++ b/src/dm/DispatchManagerActions.cc @@ -539,6 +539,50 @@ error: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int DispatchManager::reboot(int vid) +{ + VirtualMachine * vm; + ostringstream oss; + + vm = vmpool->get(vid,true); + + if ( vm == 0 ) + { + return -1; + } + + oss << "Rebooting VM " << vid; + NebulaLog::log("DiM",Log::DEBUG,oss); + + if (vm->get_state() == VirtualMachine::ACTIVE && + vm->get_lcm_state() == VirtualMachine::RUNNING ) + { + Nebula& nd = Nebula::instance(); + LifeCycleManager * lcm = nd.get_lcm(); + + lcm->trigger(LifeCycleManager::REBOOT,vid); + } + else + { + goto error; + } + + vm->unlock(); + + return 0; + +error: + oss.str(""); + oss << "Could not reboot VM " << vid << ", wrong state."; + NebulaLog::log("DiM",Log::ERROR,oss); + + vm->unlock(); + + return -2; +} +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int DispatchManager::finalize( int vid) { diff --git a/src/im_mad/remotes/vmware.d/vmware.rb b/src/im_mad/remotes/vmware.d/vmware.rb index 5552818cf3..b4c061656c 100755 --- a/src/im_mad/remotes/vmware.d/vmware.rb +++ b/src/im_mad/remotes/vmware.d/vmware.rb @@ -16,18 +16,31 @@ # limitations under the License. # # ---------------------------------------------------------------------------- # -ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION) +ONE_LOCATION=ENV["ONE_LOCATION"] if !ONE_LOCATION - ETC_LOCATION = "/etc/one" if !defined?(ETC_LOCATION) - RUBY_LIB_LOCATION = "/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION) + BIN_LOCATION = "/usr/bin" + LIB_LOCATION = "/usr/lib/one" + ETC_LOCATION = "/etc/one/" + VAR_LOCATION = "/var/lib/one" + RUBY_LIB_LOCATION = "/usr/lib/one/ruby" else - ETC_LOCATION = ONE_LOCATION+"/etc" if !defined?(ETC_LOCATION) - RUBY_LIB_LOCATION = ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION) + LIB_LOCATION = ONE_LOCATION + "/lib" + BIN_LOCATION = ONE_LOCATION + "/bin" + ETC_LOCATION = ONE_LOCATION + "/etc/" + VAR_LOCATION = ONE_LOCATION + "/var/" + RUBY_LIB_LOCATION = ONE_LOCATION+"/lib/ruby" end $: << RUBY_LIB_LOCATION +CONF_FILE = ETC_LOCATION + "/vmwarerc" + +ENV['LANG'] = 'C' + +require "scripts_common" +require 'yaml' +require "CommandManager" require 'OpenNebula' include OpenNebula @@ -38,6 +51,30 @@ rescue Exception => e exit(-1) end +# ######################################################################## # +# DRIVER HELPER FUNCTIONS # +# ######################################################################## # + +#Generates an ESX command using ttyexpect +def esx_cmd(command) + cmd = "#{BIN_LOCATION}/tty_expect -u #{@user} -p #{@pass} #{command}" +end + +#Performs a action usgin libvirt +def do_action(cmd) + rc = LocalCommand.run(esx_cmd(cmd)) + + if rc.code == 0 + return [true, rc.stdout] + else + err = "Error executing: #{cmd} err: #{rc.stderr} out: #{rc.stdout}" + OpenNebula.log_error(err) + return [false, rc.code] + end +end + +@result_str = "" + def add_info(name, value) value = "0" if value.nil? or value.to_s.empty? @result_str << "#{name}=#{value} " @@ -47,23 +84,31 @@ def print_info puts @result_str end -@result_str = "" +# ######################################################################## # +# Main Procedure # +# ######################################################################## # -@host = ARGV[2] +host = ARGV[2] -if !@host +if !host exit -1 end -load ETC_LOCATION + "/vmwarerc" +conf = YAML::load(File.read(CONF_FILE)) -if USERNAME.class!=String || PASSWORD.class!=String - warn "Bad ESX credentials, aborting" - exit -1 +@uri = conf[:libvirt_uri].gsub!('@HOST@', host) + +@user = conf[:username] +@pass = conf[:password] + +# Poll the VMware hypervisor + +rc, data = do_action("virsh -c #{@uri} --readonly nodeinfo") + +if rc == false + exit info end -data = perform_action("virsh -c #{LIBVIRT_URI} --readonly nodeinfo") - data.split(/\n/).each{|line| if line.match('^CPU\(s\)') $total_cpu = line.split(":")[1].strip.to_i * 100 diff --git a/src/image_mad/remotes/fs/cp b/src/image_mad/remotes/fs/cp index bbb2a67783..f1a557eb63 100755 --- a/src/image_mad/remotes/fs/cp +++ b/src/image_mad/remotes/fs/cp @@ -61,6 +61,11 @@ vmware://*) exec_and_log "cp -rf $SRC $DST" \ "Error copying $SRC to $DST" + + BASE_DISK_FILE=`ls $DST | grep -v '.*-s[0-9]*\.vmdk'` + + exec_and_log "mv -f $DST/$BASE_DISK_FILE $DST/disk.vmdk" \ + "Error renaming disk file $BASE_DISK_FILE to disk.vmdk" exec_and_log "chmod 0770 $DST" ;; @@ -86,4 +91,4 @@ esac SIZE=`fs_du $DST` -echo "$DST $SIZE" \ No newline at end of file +echo "$DST $SIZE" diff --git a/src/image_mad/remotes/fs/fsrc b/src/image_mad/remotes/fs/fsrc index 8cec0f0b05..4df7a005a3 100644 --- a/src/image_mad/remotes/fs/fsrc +++ b/src/image_mad/remotes/fs/fsrc @@ -92,12 +92,3 @@ function check_restricted { echo 0 } - -# Change the permissions of all the files inside directoriers (= VMware disks) -function fix_owner_perms { - find $IMAGE_REPOSITORY_PATH -type d \ - -mindepth 1 \ - -maxdepth 1 \ - -execdir chown \ - -R $SUDO_USER '{}' \; -} \ No newline at end of file diff --git a/src/image_mad/remotes/fs/mv b/src/image_mad/remotes/fs/mv index 84c845803e..02290af989 100755 --- a/src/image_mad/remotes/fs/mv +++ b/src/image_mad/remotes/fs/mv @@ -53,7 +53,9 @@ http://*) *) log "Moving local image $SRC to the image repository" - if [ \( -L $SRC \) -a \( "`$READLINK $SRC`" = "$DST" \) ] ; then + + if [ \( -L $SRC \) -a \ + \( "`$READLINK -f $SRC`" = "`$READLINK -f $DST`" \) ] ; then log "Not moving files to image repo, they are the same" else exec_and_log "mv -f $SRC $DST" "Could not move $SRC to $DST" @@ -63,7 +65,6 @@ esac if [ -d $DST ]; then exec_and_log "chmod 0770 $DST" - fix_owner_perms else exec_and_log "chmod 0660 $DST" fi diff --git a/src/lcm/LifeCycleActions.cc b/src/lcm/LifeCycleActions.cc index c415692bed..0366f5fa5b 100644 --- a/src/lcm/LifeCycleActions.cc +++ b/src/lcm/LifeCycleActions.cc @@ -427,6 +427,37 @@ void LifeCycleManager::cancel_action(int vid) return; } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void LifeCycleManager::reboot_action(int vid) +{ + VirtualMachine * vm; + + vm = vmpool->get(vid,true); + + if ( vm == 0 ) + { + return; + } + + if (vm->get_state() == VirtualMachine::ACTIVE && + vm->get_lcm_state() == VirtualMachine::RUNNING) + { + Nebula& nd = Nebula::instance(); + VirtualMachineManager * vmm = nd.get_vmm(); + + vmm->trigger(VirtualMachineManager::REBOOT,vid); + } + else + { + vm->log("LCM", Log::ERROR, "reboot_action, VM in a wrong state."); + } + + vm->unlock(); + + return; +} /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/lcm/LifeCycleManager.cc b/src/lcm/LifeCycleManager.cc index cd8c4c5f12..8e6e3018ea 100644 --- a/src/lcm/LifeCycleManager.cc +++ b/src/lcm/LifeCycleManager.cc @@ -165,6 +165,10 @@ void LifeCycleManager::trigger(Actions action, int _vid) aname = "RESTART"; break; + case REBOOT: + aname = "REBOOT"; + break; + case DELETE: aname = "DELETE"; break; @@ -298,6 +302,10 @@ void LifeCycleManager::do_action(const string &action, void * arg) { restart_action(vid); } + else if (action == "REBOOT") + { + reboot_action(vid); + } else if (action == "DELETE") { delete_action(vid); diff --git a/src/mad/ruby/OpenNebulaDriver.rb b/src/mad/ruby/OpenNebulaDriver.rb index 18561f1fc7..eaaa3051fb 100644 --- a/src/mad/ruby/OpenNebulaDriver.rb +++ b/src/mad/ruby/OpenNebulaDriver.rb @@ -87,7 +87,7 @@ class OpenNebulaDriver < ActionManager :ssh_stream => nil }.merge(ops) - params = parameters+" #{id} #{host}" + params = parameters + " #{id} #{host}" command = action_command_line(aname, params, options[:script_name]) if action_is_local?(aname) diff --git a/src/mad/ruby/VirtualMachineDriver.rb b/src/mad/ruby/VirtualMachineDriver.rb index f9f5fc1c21..11a419baee 100644 --- a/src/mad/ruby/VirtualMachineDriver.rb +++ b/src/mad/ruby/VirtualMachineDriver.rb @@ -36,6 +36,7 @@ class VirtualMachineDriver < OpenNebulaDriver ACTION = { :deploy => "DEPLOY", :shutdown => "SHUTDOWN", + :reboot => "REBOOT", :cancel => "CANCEL", :save => "SAVE", :restore => "RESTORE", @@ -80,6 +81,7 @@ class VirtualMachineDriver < OpenNebulaDriver register_action(ACTION[:deploy].to_sym, method("deploy")) register_action(ACTION[:shutdown].to_sym, method("shutdown")) + register_action(ACTION[:reboot].to_sym, method("reboot")) register_action(ACTION[:cancel].to_sym, method("cancel")) register_action(ACTION[:save].to_sym, method("save")) register_action(ACTION[:restore].to_sym, method("restore")) @@ -119,6 +121,11 @@ class VirtualMachineDriver < OpenNebulaDriver send_message(ACTION[:shutdown],RESULT[:failure],id,error) end + def reboot(id, drv_message) + error = "Action not implemented by driver #{self.class}" + send_message(ACTION[:reboot],RESULT[:failure],id,error) + end + def cancel(id, drv_message) error = "Action not implemented by driver #{self.class}" send_message(ACTION[:cancel],RESULT[:failure],id,error) diff --git a/src/mad/ruby/scripts_common.rb b/src/mad/ruby/scripts_common.rb index 8251ae48ff..8ded7d72cb 100644 --- a/src/mad/ruby/scripts_common.rb +++ b/src/mad/ruby/scripts_common.rb @@ -46,7 +46,7 @@ module OpenNebula STDERR.puts format_error_message(message) end - #This function formats an error message for OpenNebula Copyright e + #This function formats an error message for OpenNebula def self.format_error_message(message) error_str = "ERROR MESSAGE --8<------\n" error_str << message diff --git a/src/mad/ruby/vmwarelib.rb b/src/mad/ruby/vmwarelib.rb deleted file mode 100644 index a763e7f660..0000000000 --- a/src/mad/ruby/vmwarelib.rb +++ /dev/null @@ -1,60 +0,0 @@ -# ---------------------------------------------------------------------------- # -# Copyright 2010-2011, C12G Labs S.L # -# # -# 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. # -# ---------------------------------------------------------------------------- # - -# ---------------------------------------------------------------------------- # -# Set up the environment for the driver # -# ---------------------------------------------------------------------------- # - -ONE_LOCATION = ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION) - -if !ONE_LOCATION - BIN_LOCATION = "/usr/bin" if !defined?(BIN_LOCATION) - ETC_LOCATION = "/etc/one/" if !defined?(ETC_LOCATION) - RUBY_LIB_LOCATION = "/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION) -else - BIN_LOCATION = ONE_LOCATION + "/bin" if !defined?(BIN_LOCATION) - ETC_LOCATION = ONE_LOCATION + "/etc/" if !defined?(ETC_LOCATION) - if !defined?(RUBY_LIB_LOCATION) - RUBY_LIB_LOCATION = ONE_LOCATION + "/lib/ruby" - end -end - -$: << RUBY_LIB_LOCATION - -require "OpenNebulaDriver" -require "CommandManager" - -# Do host sustitution in the libvirt URI -LIBVIRT_URI.gsub!('@HOST@', @host) - -# Common functions -def perform_action(command) - command = BIN_LOCATION + "/tty_expect -u " + USERNAME + " -p " + PASSWORD + " " + command - - action_result = LocalCommand.run(command) - - if action_result.code == 0 - return action_result.stdout - else - log(command, action_result.stderr, action_result.stdout) - return action_result.code - end -end - -def log(cmd, stdout, stderr) - STDERR.puts "[VMWARE] cmd failed [" + cmd + - "]. Stderr: " + stderr + ". Stdout: " + stdout -end diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index b5267e9265..61d0b0870d 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -56,7 +56,7 @@ void Nebula::start() // Configuration // ----------------------------------------------------------- - nebula_configuration = new NebulaTemplate(etc_location, var_location); + nebula_configuration = new OpenNebulaTemplate(etc_location, var_location); rc = nebula_configuration->load_configuration(); diff --git a/src/nebula/NebulaTemplate.cc b/src/nebula/NebulaTemplate.cc index 1d7b6272cd..e0d2c590c8 100644 --- a/src/nebula/NebulaTemplate.cc +++ b/src/nebula/NebulaTemplate.cc @@ -15,33 +15,75 @@ /* -------------------------------------------------------------------------- */ #include "NebulaTemplate.h" -#include "Nebula.h" using namespace std; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -const char * NebulaTemplate::conf_name="oned.conf"; - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -NebulaTemplate::NebulaTemplate(string& etc_location, string& var_location) +int NebulaTemplate::load_configuration() +{ + char * error = 0; + int rc; + + string aname; + Attribute * attr; + + map::iterator iter, j; + + set_conf_default(); + + rc = parse(conf_file.c_str(), &error); + + if ( rc != 0 && error != 0) + { + cout << "\nError while parsing configuration file:\n" << error << endl; + + free(error); + + return -1; + } + + for(iter=conf_default.begin();iter!=conf_default.end();) + { + aname = iter->first; + attr = iter->second; + + j = attributes.find(aname); + + if ( j == attributes.end() ) + { + attributes.insert(make_pair(aname,attr)); + iter++; + } + else + { + delete iter->second; + conf_default.erase(iter++); + } + } + + return 0; +} +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +const char * OpenNebulaTemplate::conf_name="oned.conf"; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void OpenNebulaTemplate::set_conf_default() { - ostringstream os; SingleAttribute * attribute; VectorAttribute * vattribute; string value; - conf_file = etc_location + conf_name; - // MANAGER_TIMER value = "15"; attribute = new SingleAttribute("MANAGER_TIMER",value); conf_default.insert(make_pair(attribute->name(),attribute)); - /* #******************************************************************************* # Daemon configuration attributes @@ -170,49 +212,3 @@ NebulaTemplate::NebulaTemplate(string& etc_location, string& var_location) conf_default.insert(make_pair(attribute->name(),attribute)); } -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - - -int NebulaTemplate::load_configuration() -{ - char * error = 0; - map::iterator iter, j; - int rc; - - string aname; - Attribute * attr; - - rc = parse(conf_file.c_str(), &error); - - if ( rc != 0 && error != 0) - { - - cout << "\nError while parsing configuration file:\n" << error << endl; - - free(error); - - return -1; - } - - for(iter=conf_default.begin();iter!=conf_default.end();) - { - aname = iter->first; - attr = iter->second; - - j = attributes.find(aname); - - if ( j == attributes.end() ) - { - attributes.insert(make_pair(aname,attr)); - iter++; - } - else - { - delete iter->second; - conf_default.erase(iter++); - } - } - - return 0; -} diff --git a/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java b/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java index ccb89f254d..2660b4d9ac 100644 --- a/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java +++ b/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java @@ -248,6 +248,7 @@ public class VirtualMachine extends PoolElement{ * It is recommended to use the helper methods instead: *
      *
    • {@link VirtualMachine#shutdown()}
    • + *
    • {@link VirtualMachine#reboot()}
    • *
    • {@link VirtualMachine#cancel()}
    • *
    • {@link VirtualMachine#hold()}
    • *
    • {@link VirtualMachine#release()}
    • @@ -259,7 +260,7 @@ public class VirtualMachine extends PoolElement{ *
    * * @param action The action name to be performed, can be:
    - * "shutdown", "hold", "release", "stop", "cancel", "suspend", + * "shutdown", "reboot", "hold", "release", "stop", "cancel", "suspend", * "resume", "restart", "finalize". * @return If an error occurs the error message contains the reason. */ @@ -357,6 +358,15 @@ public class VirtualMachine extends PoolElement{ return action("shutdown"); } + /** + * Reboots a running VM. + * @return If an error occurs the error message contains the reason. + */ + public OneResponse reboot() + { + return action("reboot"); + } + /** * Cancels the running VM. * @return If an error occurs the error message contains the reason. diff --git a/src/oca/ruby/OpenNebula/VirtualMachine.rb b/src/oca/ruby/OpenNebula/VirtualMachine.rb index 8e708ff9ff..1690e210c1 100644 --- a/src/oca/ruby/OpenNebula/VirtualMachine.rb +++ b/src/oca/ruby/OpenNebula/VirtualMachine.rb @@ -143,6 +143,11 @@ module OpenNebula action('shutdown') end + # Shutdowns an already deployed VM + def reboot + action('reboot') + end + # Cancels a running VM def cancel action('cancel') diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 75d92a5fb1..8898695724 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -229,6 +229,10 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList, { rc = dm->resubmit(id); } + else if (action == "reboot") + { + rc = dm->reboot(id); + } switch (rc) { diff --git a/src/scheduler/etc/sched.conf b/src/scheduler/etc/sched.conf new file mode 100644 index 0000000000..b72f48dd37 --- /dev/null +++ b/src/scheduler/etc/sched.conf @@ -0,0 +1,51 @@ +#******************************************************************************* +# OpenNebula Configuration file +#******************************************************************************* + +#******************************************************************************* +# Daemon configuration attributes +#------------------------------------------------------------------------------- +# ONED_PORT: Port to connect to the OpenNebula daemon (oned) +# +# SCHED_INTERVAL: Seconds between two scheduling actions +# +# MAX_VM: Maximum number of Virtual Machines scheduled in each scheduling +# action +# +# MAX_DISPATCH: Maximum number of Virtual Machines actually dispatched to a +# host in each scheduling action +# +# MAX_HOST: Maximum number of Virtual Machines dispatched to a given host in +# each scheduling action +# +# DEFAULT_SCHED: Definition of the default scheduling algorithm +# - policy: +# 0 = Packing. Heuristic that minimizes the number of hosts in use by +# packing the VMs in the hosts to reduce VM fragmentation +# 1 = Striping. Heuristic that tries to maximize resources available for +# the VMs by spreading the VMs in the hosts +# 2 = Load-aware. Heuristic that tries to maximize resources available for +# the VMs by usingthose nodes with less load +# 3 = Custom. +# - rank: Custom arithmetic exprission to rank suitable hosts based in their +# attributes +#******************************************************************************* + +ONED_PORT = 2633 + +SCHED_INTERVAL = 30 + +MAX_VM = 300 + +MAX_DISPATCH = 30 + +MAX_HOST = 1 + +DEFAULT_SCHED = [ + policy = 1 +] + +#DEFAULT_SCHED = [ +# policy = 3, +# rank = "- (RUNNING_VMS * 50 + FREE_CPU)" +#] diff --git a/src/scheduler/include/RankPolicy.h b/src/scheduler/include/RankPolicy.h index 628a51c717..b6c337bf1e 100644 --- a/src/scheduler/include/RankPolicy.h +++ b/src/scheduler/include/RankPolicy.h @@ -29,12 +29,16 @@ public: RankPolicy( VirtualMachinePoolXML * vmpool, HostPoolXML * hpool, - float w=1.0):SchedulerHostPolicy(vmpool,hpool,w){}; + const string& dr, + float w = 1.0) + :SchedulerHostPolicy(vmpool,hpool,w), default_rank(dr){}; ~RankPolicy(){}; private: + string default_rank; + void policy( VirtualMachineXML * vm) { @@ -53,10 +57,10 @@ private: srank = vm->get_rank(); - if (srank == "") + if (srank.empty()) { - NebulaLog::log("RANK",Log::WARNING,"No rank defined for VM"); - } + srank = default_rank; + } for (i=0;i #include "Scheduler.h" +#include "SchedulerTemplate.h" #include "RankPolicy.h" #include "NebulaLog.h" #include "PoolObjectAuth.h" @@ -65,33 +66,44 @@ extern "C" void * scheduler_action_loop(void *arg) void Scheduler::start() { int rc; - ifstream file; + + ifstream file; + ostringstream oss; + + string etc_path; + int oned_port; pthread_attr_t pattr; // ----------------------------------------------------------- - // Log system + // Log system & Configuration File // ----------------------------------------------------------- try { - ostringstream oss; + string log_file; const char * nl = getenv("ONE_LOCATION"); if (nl == 0) //OpenNebula installed under root directory { - oss << "/var/log/one/"; + log_file = "/var/log/one/sched.log"; + etc_path = "/etc/one/"; } else { - oss << nl << "/var/"; - } + oss << nl << "/var/sched.log"; - oss << "sched.log"; + log_file = oss.str(); + + oss.str(""); + oss << nl << "/etc/"; + + etc_path = oss.str(); + } NebulaLog::init_log_system(NebulaLog::FILE, Log::DEBUG, - oss.str().c_str()); + log_file.c_str()); NebulaLog::log("SCHED", Log::INFO, "Init Scheduler Log system"); } @@ -100,6 +112,42 @@ void Scheduler::start() throw; } + // ----------------------------------------------------------- + // Configuration File + // ----------------------------------------------------------- + + SchedulerTemplate conf(etc_path); + + if ( conf.load_configuration() != 0 ) + { + throw runtime_error("Error reading configuration file."); + } + + conf.get("ONED_PORT", oned_port); + + oss.str(""); + oss << "http://localhost:" << oned_port << "/RPC2"; + url = oss.str(); + + conf.get("SCHED_INTERVAL", timer); + + conf.get("MAX_VM", machines_limit); + + conf.get("MAX_DISPATCH", dispatch_limit); + + conf.get("MAX_HOST", host_dispatch_limit); + + oss.str(""); + + oss << "Starting Scheduler Daemon" << endl; + oss << "----------------------------------------\n"; + oss << " Scheduler Configuration File \n"; + oss << "----------------------------------------\n"; + oss << conf; + oss << "----------------------------------------"; + + NebulaLog::log("SCHED", Log::INFO, oss); + // ----------------------------------------------------------- // XML-RPC Client // ----------------------------------------------------------- @@ -129,7 +177,7 @@ void Scheduler::start() // Load scheduler policies // ----------------------------------------------------------- - register_policies(); + register_policies(conf); // ----------------------------------------------------------- // Close stds, we no longer need them diff --git a/src/scheduler/src/sched/SchedulerTemplate.cc b/src/scheduler/src/sched/SchedulerTemplate.cc new file mode 100644 index 0000000000..43ffbd897f --- /dev/null +++ b/src/scheduler/src/sched/SchedulerTemplate.cc @@ -0,0 +1,126 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +#include "SchedulerTemplate.h" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +const char * SchedulerTemplate::conf_name="sched.conf"; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void SchedulerTemplate::set_conf_default() +{ + SingleAttribute * attribute; + VectorAttribute * vattribute; + string value; + +/* +#******************************************************************************* +# Daemon configuration attributes +#------------------------------------------------------------------------------- +# ONED_PORT +# SCHED_INTERVAL +# MAX_VM +# MAX_DISPATCH +# MAX_HOST +# DEFAULT_SCHED +#------------------------------------------------------------------------------- +*/ + // ONED_PORT + value = "2633"; + + attribute = new SingleAttribute("ONED_PORT",value); + conf_default.insert(make_pair(attribute->name(),attribute)); + + // SCHED_INTERVAL + value = "30"; + + attribute = new SingleAttribute("SCHED_INTERVAL",value); + conf_default.insert(make_pair(attribute->name(),attribute)); + + // MAX_VM + value = "300"; + + attribute = new SingleAttribute("MAX_VM",value); + conf_default.insert(make_pair(attribute->name(),attribute)); + + // MAX_DISPATCH + value = "30"; + + attribute = new SingleAttribute("MAX_DISPATCH",value); + conf_default.insert(make_pair(attribute->name(),attribute)); + + //MAX_HOST + value = "1"; + + attribute = new SingleAttribute("MAX_HOST",value); + conf_default.insert(make_pair(attribute->name(),attribute)); + + //DEFAULT_SCHED + map vvalue; + vvalue.insert(make_pair("POLICY","1")); + + vattribute = new VectorAttribute("DEFAULT_SCHED",vvalue); + conf_default.insert(make_pair(attribute->name(),vattribute)); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +string SchedulerTemplate::get_policy() const +{ + int policy; + string rank; + + istringstream iss; + + vector vsched; + const VectorAttribute * sched; + + get("DEFAULT_SCHED", vsched); + + sched = static_cast (vsched[0]); + + iss.str(sched->vector_value("POLICY")); + iss >> policy; + + switch (policy) + { + case 0: //Packing + rank = "RUNNING_VMS"; + break; + + case 1: //Striping + rank = "- RUNNING_VMS"; + break; + + case 2: //Load-aware + rank = "FREE_CPU"; + break; + + case 3: //Custom + rank = sched->vector_value("RANK"); + break; + + default: + rank = ""; + } + + return rank; +} \ No newline at end of file diff --git a/src/scheduler/src/sched/mm_sched.cc b/src/scheduler/src/sched/mm_sched.cc index 01e667f1b3..9e5104e6c1 100644 --- a/src/scheduler/src/sched/mm_sched.cc +++ b/src/scheduler/src/sched/mm_sched.cc @@ -15,6 +15,7 @@ /* -------------------------------------------------------------------------- */ #include "Scheduler.h" +#include "SchedulerTemplate.h" #include "RankPolicy.h" #include #include @@ -31,16 +32,7 @@ class RankScheduler : public Scheduler { public: - RankScheduler(string url, - time_t timer, - unsigned int machines_limit, - unsigned int dispatch_limit, - unsigned int host_dispatch_limit - ):Scheduler(url, - timer, - machines_limit, - dispatch_limit, - host_dispatch_limit),rp(0){}; + RankScheduler():Scheduler(),rp(0){}; ~RankScheduler() { @@ -50,9 +42,9 @@ public: } }; - void register_policies() + void register_policies(const SchedulerTemplate& conf) { - rp = new RankPolicy(vmpool,hpool,1.0); + rp = new RankPolicy(vmpool, hpool, conf.get_policy(), 1.0); add_host_policy(rp); }; @@ -64,56 +56,11 @@ private: int main(int argc, char **argv) { - RankScheduler * ss; - int port = 2633; - time_t timer= 30; - unsigned int machines_limit = 300; - unsigned int dispatch_limit = 30; - unsigned int host_dispatch_limit = 1; - char opt; - - ostringstream oss; - - while((opt = getopt(argc,argv,"p:t:m:d:h:")) != -1) - { - switch(opt) - { - case 'p': - port = atoi(optarg); - break; - case 't': - timer = atoi(optarg); - break; - case 'm': - machines_limit = atoi(optarg); - break; - case 'd': - dispatch_limit = atoi(optarg); - break; - case 'h': - host_dispatch_limit = atoi(optarg); - break; - default: - cerr << "usage: " << argv[0] << " [-p port] [-t timer] "; - cerr << "[-m machines limit] [-d dispatch limit] [-h host_dispatch_limit]\n"; - exit(-1); - break; - } - }; - - /* ---------------------------------------------------------------------- */ - - oss << "http://localhost:" << port << "/RPC2"; - - ss = new RankScheduler(oss.str(), - timer, - machines_limit, - dispatch_limit, - host_dispatch_limit); + RankScheduler ss; try { - ss->start(); + ss.start(); } catch (exception &e) { @@ -122,7 +69,5 @@ int main(int argc, char **argv) return -1; } - delete ss; - return 0; } diff --git a/src/sunstone/etc/sunstone-plugins.yaml b/src/sunstone/etc/sunstone-plugins.yaml index 38228d404e..ce33cfff64 100644 --- a/src/sunstone/etc/sunstone-plugins.yaml +++ b/src/sunstone/etc/sunstone-plugins.yaml @@ -45,3 +45,7 @@ :user: :group: oneadmin: true +- plugins/config-tab.js: + :ALL: true + :user: + :group: diff --git a/src/sunstone/etc/sunstone-server.conf b/src/sunstone/etc/sunstone-server.conf index 4391ca8a5f..1927bfb949 100644 --- a/src/sunstone/etc/sunstone-server.conf +++ b/src/sunstone/etc/sunstone-server.conf @@ -17,4 +17,7 @@ # VNC Configuration :vnc_proxy_base_port: 29876 -:novnc_path: +:novnc_path: + +# Default language setting +:lang: en_US diff --git a/src/sunstone/models/OpenNebulaJSON/UserJSON.rb b/src/sunstone/models/OpenNebulaJSON/UserJSON.rb index 726845d23c..a2d89476a4 100644 --- a/src/sunstone/models/OpenNebulaJSON/UserJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/UserJSON.rb @@ -64,7 +64,7 @@ module OpenNebulaJSON end def update(params=Hash.new) - super(params['raw_template']) + super(params['template_raw']) end def addgroup(params=Hash.new) diff --git a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb index d00c0efc32..3da1ca9f9a 100644 --- a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb @@ -62,6 +62,7 @@ module OpenNebulaJSON when "restart" then self.restart when "saveas" then self.save_as(action_hash['params']) when "shutdown" then self.shutdown + when "reboot" then self.reboot when "resubmit" then self.resubmit when "chown" then self.chown(action_hash['params']) else diff --git a/src/sunstone/public/images/green_bullet.png b/src/sunstone/public/images/green_bullet.png index d64f9dbf9d..6e1be22202 100644 Binary files a/src/sunstone/public/images/green_bullet.png and b/src/sunstone/public/images/green_bullet.png differ diff --git a/src/sunstone/public/images/red_bullet.png b/src/sunstone/public/images/red_bullet.png index b8317a77cf..dd95b8e35d 100644 Binary files a/src/sunstone/public/images/red_bullet.png and b/src/sunstone/public/images/red_bullet.png differ diff --git a/src/sunstone/public/images/yellow_bullet.png b/src/sunstone/public/images/yellow_bullet.png index 7d2e3a1911..ca0138a1e3 100644 Binary files a/src/sunstone/public/images/yellow_bullet.png and b/src/sunstone/public/images/yellow_bullet.png differ diff --git a/src/sunstone/public/js/locale.js b/src/sunstone/public/js/locale.js new file mode 100644 index 0000000000..d5b1e970c5 --- /dev/null +++ b/src/sunstone/public/js/locale.js @@ -0,0 +1,88 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +var lang="" +var locale = {}; +var datatable_lang = ""; + +function tr(str){ + var tmp = locale[str]; + if ( tmp == null || tmp == "" ) { + //console.debug("Missing translation: "+str); + tmp = str; + } + return tmp; +}; + +//Pops up loading new language dialog. Retrieves the user template, updates the LANG variable. +//Updates template and session configuration and reloads the view. +function setLang(lang_str){ + var lang_tmp=""; + var dialog = $('
    '+tr("Loading new language... please wait")+' '+spinner+'
    ').dialog({ + draggable:false, + modal:true, + resizable:false, + buttons:{}, + width: 460, + minHeight: 50 + + }); + + var updateUserTemplate = function(request,user_json){ + var template = user_json.USER.TEMPLATE; + var template_str=""; + template["LANG"] = lang_tmp; + + //convert json to ONE template format - simple conversion + $.each(template,function(key,value){ + template_str += (key + '=' + '"' + value + '"\n'); + }); + + var obj = { + data: { + id: uid, + extra_param: template_str + }, + error: onError + }; + OpenNebula.User.update(obj); + $.post('config',JSON.stringify({lang:lang_tmp}),function(){window.location.href = "."}); + + }; + + lang_tmp = lang_str; + + if (whichUI() == "sunstone"){ + var obj = { + data : { + id: uid, + }, + success: updateUserTemplate + }; + OpenNebula.User.show(obj); + } else { + dialog.dialog('close'); + }; +}; + +$(document).ready(function(){ + //Update static translations + $('#doc_link').text(tr("Documentation")); + $('#support_link').text(tr("Support")); + $('#community_link').text(tr("Community")); + $('#welcome').text(tr("Welcome")); + $('#logout').text(tr("Sign out")); +}); \ No newline at end of file diff --git a/src/sunstone/public/js/plugins/acls-tab.js b/src/sunstone/public/js/plugins/acls-tab.js index ad94ffd2b6..f0515f0bcb 100644 --- a/src/sunstone/public/js/plugins/acls-tab.js +++ b/src/sunstone/public/js/plugins/acls-tab.js @@ -25,12 +25,12 @@ var acls_tab_content = \ \ \ - \ - \ - \ - \ - \ - \ + \ + \ + \ + \ + \ + \ \ \ \ @@ -42,48 +42,48 @@ var create_acl_tmpl = '\
    \
    \ - \ + \ \
    \ - \ - Hosts
    \ - Virtual Machines
    \ - Virtual Networks
    \ - Images
    \ - Templates
    \ - Users
    \ - Groups
    \ + \ + '+tr("Hosts")+'
    \ + '+tr("Virtual Machines")+'
    \ + '+tr("Virtual Networks")+'
    \ + '+tr("Images")+'
    \ + '+tr("Templates")+'
    \ + '+tr("Users")+'
    \ + '+tr("Groups")+'
    \
    \ - \ - All
    \ - Specific ID
    \ - Owned by group
    \ + \ + '+tr("All")+'
    \ + '+tr("Specific ID")+'
    \ + '+tr("Owned by group")+'
    \
    \ - \ + \ \
    \ - \ + \ \
    \ - \ - Create
    \ - Delete
    \ - Use
    \ - Manage
    \ - Get Information
    \ - Get Pool of resources
    \ - Get Pool of my/group\'s resources
    \ - Change owner
    \ - Deploy
    \ + \ + '+tr("Create")+'
    \ + '+tr("Delete")+'
    \ + '+tr("Use")+'
    \ + '+tr("Manage")+'
    \ + '+tr("Get Information")+'
    \ + '+tr("Get Pool of resources")+'
    \ + '+tr("Get Pool of my/group\'s resources")+'
    \ + '+tr("Change owner")+'
    \ + '+tr("Deploy")+'
    \
    \ - \ + \ \
    \
    \
    \
    \ - \ - \ + \ + \
    \
    \ '; @@ -143,21 +143,21 @@ var acl_actions = { var acl_buttons = { "Acl.refresh" : { type: "image", - text: "Refresh list", + text: tr("Refresh list"), img: "images/Refresh-icon.png" }, "Acl.create_dialog" : { type: "create_dialog", - text: "+ New" + text: tr("+ New") }, "Acl.delete" : { type: "action", - text: "Delete" + text: tr("Delete") } } var acls_tab = { - title: "ACLs", + title: tr("ACLs"), content: acls_tab_content, buttons: acl_buttons } @@ -179,14 +179,14 @@ function aclElements(){ function parseUserAcl(user){ var user_str=""; if (user[0] == '*'){ - user_str = "All"; + user_str = tr("All"); } else { if (user[0] == '#'){ - user_str="User "; + user_str=tr("User")+" "; user_str+= getUserName(user.substring(1)); } else if (user[0] == '@'){ - user_str="Group "; + user_str=tr("Group "); user_str+= getGroupName(user.substring(1)); }; }; @@ -197,14 +197,14 @@ function parseUserAcl(user){ function parseResourceAcl(user){ var user_str=""; if (user[0] == '*'){ - user_str = "All"; + user_str = tr("All"); } else { if (user[0] == '#'){ - user_str="ID "; + user_str=tr("ID")+" "; user_str+= user.substring(1); } else if (user[0] == '@'){ - user_str="Group "; + user_str=tr("Group")+" "; user_str+= getGroupName(user.substring(1)); }; }; @@ -232,25 +232,25 @@ function parseAclString(string) { for (var i=0; i'); + dialogs_context.append('
    '); $create_acl_dialog = $('#create_acl_dialog',dialogs_context); var dialog = $create_acl_dialog; dialog.html(create_acl_tmpl); @@ -316,9 +316,9 @@ function setupCreateAclDialog(){ height: height }); - $('#res_subgroup_all',dialog).attr("checked","checked"); - $('#res_id',dialog).attr("disabled","disabled"); - $('#belonging_to',dialog).attr("disabled","disabled"); + $('#res_subgroup_all',dialog).attr('checked','checked'); + $('#res_id',dialog).attr('disabled','disabled'); + $('#belonging_to',dialog).attr('disabled','disabled'); $('button',dialog).button(); @@ -327,16 +327,16 @@ function setupCreateAclDialog(){ var context = $(this).parent(); switch (value) { case "*": - $('#res_id',context).attr("disabled","disabled"); - $('#belonging_to',context).attr("disabled","disabled"); + $('#res_id',context).attr('disabled','disabled'); + $('#belonging_to',context).attr('disabled','disabled'); break; case "res_id": - $('#res_id',context).removeAttr("disabled"); - $('#belonging_to').attr("disabled","disabled"); + $('#res_id',context).removeAttr('disabled'); + $('#belonging_to').attr('disabled','disabled'); break; case "belonging_to": - $('#res_id',context).attr("disabled","disabled"); - $('#belonging_to',context).removeAttr("disabled"); + $('#res_id',context).attr('disabled','disabled'); + $('#belonging_to',context).removeAttr('disabled'); break; }; }); @@ -391,13 +391,13 @@ function setupCreateAclDialog(){ $('#create_acl_form',dialog).submit(function(){ var user = $('#applies',this).val(); if (!user.length) { - notifyError("Please specify to who this ACL applies"); + notifyError(tr("Please specify to who this ACL applies")); return false; }; var resources = $('.resource_cb:checked',this).length; if (!resources) { - notifyError("Please select at least one resource"); + notifyError(tr("Please select at least one resource")); return false; } @@ -406,7 +406,7 @@ function setupCreateAclDialog(){ case "res_id": var l=$('#res_id',this).val().length; if (!l){ - notifyError("Please provide a resource ID for the resource(s) in this rule"); + notifyError(tr("Please provide a resource ID for the resource(s) in this rule")); return false; } break; @@ -441,15 +441,15 @@ function popUpCreateAclDialog(){ var users = $(''); $('.empty_value',users).remove(); $('option',users).addClass("user"); - users.prepend(''); + users.prepend(''); var groups = $(''); $('.empty_value',groups).remove(); $('option',groups).addClass("group"); - groups.prepend(''); + groups.prepend(''); var dialog = $create_acl_dialog; - $('#applies',dialog).html(''+ + $('#applies',dialog).html(''+ users.html()+groups.html()); $('#belonging_to',dialog).html(groups_select); @@ -461,7 +461,7 @@ function popUpCreateAclDialog(){ function setAclAutorefresh(){ setInterval(function(){ var checked = $('input.check_item:checked',dataTable_acls); - var filter = $("#datatable_acls_filter input",dataTable_acls.parents("#datatable_acls_wrapper")).attr("value"); + var filter = $("#datatable_acls_filter input",dataTable_acls.parents("#datatable_acls_wrapper")).attr('value'); if (!checked.length && !filter.length){ Sunstone.runAction("Acl.autorefresh"); } @@ -480,7 +480,11 @@ $(document).ready(function(){ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "60px", "aTargets": [0] }, { "sWidth": "35px", "aTargets": [1] } - ] + ], + "oLanguage": (datatable_lang != "") ? + { + sUrl: "locale/"+lang+"/"+datatable_lang + } : "" }); dataTable_acls.fnClearTable(); addElement([ diff --git a/src/sunstone/public/js/plugins/config-tab.js b/src/sunstone/public/js/plugins/config-tab.js new file mode 100644 index 0000000000..cba0c032ca --- /dev/null +++ b/src/sunstone/public/js/plugins/config-tab.js @@ -0,0 +1,58 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +var config_tab_content = +'
    \ +
    AllIDApplies toAffected resourcesResource ID / Owned byAllowed operations'+tr("All")+''+tr("ID")+''+tr("Applies to")+''+tr("Affected resources")+''+tr("Resource ID / Owned by")+''+tr("Allowed operations")+'
    \ + \ + \ + \ +
    \ +
    \ +

    ' + tr("Sunstone UI Configuration") + '

    \ +
    \ +\ + \ + \ + \ + \ + \ +
    ' + tr("Language") + '\ + \ +
    \ +\ +
    \ +
    \ +
    '; + +var config_tab = { + title: tr("Configuration"), + content: config_tab_content +} + +Sunstone.addMainTab('config_tab',config_tab); + +$(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()); + }); + +}); \ No newline at end of file diff --git a/src/sunstone/public/js/plugins/dashboard-tab.js b/src/sunstone/public/js/plugins/dashboard-tab.js index 92a38ba49c..20061c8232 100644 --- a/src/sunstone/public/js/plugins/dashboard-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-tab.js @@ -50,40 +50,44 @@ var dashboard_tab_content = \ \
    \ -

    Summary of resources

    \ +

    ' + tr("Summary of resources") + '

    \
    \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \
    Hosts (total/active)' + tr("Hosts (total/active)") + '
    Groups' + tr("Groups") + '
    VM Templates (total/public)' + tr("VM Templates (total/public)") + '
    VM Instances (total/running/failed)' + + tr("VM Instances")+ ' (' + + tr("total") + '/' + + tr("running") + '/' + + tr("failed") + ')
    Virtual Networks (total/public)' + tr("Virtual Networks (total/public)") + '
    Images (total/public)' + tr("Images (total/public)") + '
    Users' + tr("Users")+'
    ACL Rules' + tr("ACL Rules") + '
    \ @@ -95,18 +99,18 @@ var dashboard_tab_content = \ \
    \ -

    Quickstart

    \ +

    ' + tr("Quickstart") + '

    \
    \
    \ - \ - Host
    \ - VM Instance
    \ - VM Template
    \ - Virtual Network
    \ - Image
    \ - User
    \ - Group
    \ - Acl
    \ +\ + ' + tr("Host") + '
    \ + ' + tr("VM Instance") + '
    \ + ' + tr("VM Template") + '
    \ + ' + tr("Virtual Network") + '
    \ + ' + tr("Image") + '
    \ + ' + tr("User") + '
    \ + ' + tr("Group") + '
    \ + ' + tr("Acl") + '
    \
    \
    \ \ @@ -118,19 +122,19 @@ var dashboard_tab_content = \ \
    \ -

    Historical monitoring information

    \ +

    ' + tr("Historical monitoring information") + '

    \
    \ \ - \ + \ \ \ - \ + \ \ \ - \ + \ \ \ - \ + \ \ \
    Hosts CPU
    ' + tr("Hosts CPU") + '
    '+spinner+'
    Hosts memory
    ' + tr("Hosts memory") + '
    '+spinner+'
    Total VM count
    ' + tr("Total VM count") + '
    '+spinner+'
    VM Network stats
    ' + tr("VM Network stats") + '
    '+spinner+'
    \ @@ -143,7 +147,7 @@ var dashboard_tab_content = '; var dashboard_tab = { - title: 'Dashboard', + title: tr("Dashboard"), content: dashboard_tab_content } @@ -163,7 +167,7 @@ function plot_global_graph(data,info){ for (var i=0; i\ \
    \ -

    Summary of resources

    \ +

    '+tr("Summary of resources")+'

    \
    \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \
    VM Templates (total/public)'+tr("VM Templates (total/public)")+'
    VM Instances (total/running/failed)'+tr("VM Instances")+' ('+ + tr("total")+'/'+ + tr("running")+'/'+ + tr("failed")+')
    Virtual Networks (total/public)'+tr("Virtual Networks (total/public)")+'
    Images (total/public)'+tr("Images (total/public)")+'
    \ @@ -79,14 +82,14 @@ var dashboard_tab_content = \ \
    \ -

    Quickstart

    \ +

    '+tr("Quickstart")+'

    \
    \
    \ \ - VM Template
    \ - VM Instance
    \ - Virtual Network
    \ - Image
    \ + '+tr("VM Template")+'
    \ + '+tr("VM Instance")+'
    \ + '+tr("Virtual Network")+'
    \ + '+tr("Image")+'
    \
    \
    \ \ @@ -98,19 +101,19 @@ var dashboard_tab_content = \ \
    \ -

    Historical monitoring information

    \ +

    '+tr("Historical monitoring information")+'

    \
    \ \ - \ + \ \ \ - \ + \ \ \ - \ + \ \ \ - \ + \ \ \
    Total VM count
    '+tr("Total VM count")+'
    '+spinner+'
    Total VM CPU
    '+tr("Total VM CPU")+'
    '+spinner+'
    Total VM Memory
    '+tr("Total VM Memory")+'
    '+spinner+'
    VM Network stats
    '+tr("VM Network stats")+'
    '+spinner+'
    \ @@ -123,7 +126,7 @@ var dashboard_tab_content = '; var dashboard_tab = { - title: 'Dashboard', + title: tr("Dashboard"), content: dashboard_tab_content } diff --git a/src/sunstone/public/js/plugins/groups-tab.js b/src/sunstone/public/js/plugins/groups-tab.js index 0f1b39a5c9..1a31960052 100644 --- a/src/sunstone/public/js/plugins/groups-tab.js +++ b/src/sunstone/public/js/plugins/groups-tab.js @@ -25,10 +25,10 @@ var groups_tab_content = \ \ \ - \ - \ - \ - \ + \ + \ + \ + \ \ \ \ @@ -40,14 +40,14 @@ var create_group_tmpl = '\
    \
    \ - \ + \
    \
    \
    \
    \
    \ - \ - \ + \ + \
    \
    \ '; @@ -118,12 +118,12 @@ var group_actions = { var group_buttons = { "Group.refresh" : { type: "image", - text: "Refresh list", + text: tr("Refresh list"), img: "images/Refresh-icon.png" }, "Group.create_dialog" : { type: "create_dialog", - text: "+ New Group" + text: tr("+ New Group") }, // "Group.chown" : { // type: "confirm_with_select", @@ -135,12 +135,12 @@ var group_buttons = { "Group.delete" : { type: "action", - text: "Delete" + text: tr("Delete") } }; var groups_tab = { - title: 'Groups', + title: tr("Groups"), content: groups_tab_content, buttons: group_buttons } @@ -228,7 +228,7 @@ function updateGroupsView(request, group_list){ //Prepares the dialog to create function setupCreateGroupDialog(){ - dialogs_context.append('
    '); + dialogs_context.append('
    '); $create_group_dialog = $('#create_group_dialog',dialogs_context); var dialog = $create_group_dialog; @@ -259,7 +259,7 @@ function popUpCreateGroupDialog(){ function setGroupAutorefresh(){ setInterval(function(){ var checked = $('input.check_item:checked',dataTable_groups); - var filter = $("#datatable_groups_filter input",dataTable_groups.parents("#datatable_groups_wrapper")).attr("value"); + var filter = $("#datatable_groups_filter input",dataTable_groups.parents("#datatable_groups_wrapper")).attr('value'); if (!checked.length && !filter.length){ Sunstone.runAction("Group.autorefresh"); } @@ -276,7 +276,11 @@ $(document).ready(function(){ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "60px", "aTargets": [0] }, { "sWidth": "35px", "aTargets": [1] } - ] + ], + "oLanguage": (datatable_lang != "") ? + { + sUrl: "locale/"+lang+"/"+datatable_lang + } : "" }); dataTable_groups.fnClearTable(); diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 76e0a9591d..48c6802dcf 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -19,13 +19,13 @@ var HOST_HISTORY_LENGTH = 40; var host_graphs = [ { - title : "CPU Monitoring information", + title : tr("CPU Monitoring information"), monitor_resources : "cpu_usage,used_cpu,max_cpu", humanize_figures : false, history_length : HOST_HISTORY_LENGTH }, { - title: "Memory monitoring information", + title: tr("Memory monitoring information"), monitor_resources : "mem_usage,used_mem,max_mem", humanize_figures : true, history_length : HOST_HISTORY_LENGTH @@ -40,13 +40,13 @@ var hosts_tab_content =
    AllIDNameUsers'+tr("All")+''+tr("ID")+''+tr("Name")+''+tr("Users")+'
    \ \ \ - \ - \ - \ - \ - \ - \ - \ + \ + \ + \ + \ + \ + \ + \ \ \ \ @@ -57,27 +57,27 @@ var hosts_tab_content = var create_host_tmpl = '
    \
    \ - Host parameters\ - \ + ' + tr("Host parameters") + '\ + \
    \ -

    Drivers

    \ +

    ' + tr("Drivers") + '

    \
    \
    \ - \ + \ \
    \
    \ - \ + \ \
    \
    \ @@ -91,18 +91,18 @@ var create_host_tmpl = \
    \
    \ - \ + \ \
    \
    \
    \
    \ -
    \ -
    \ +
    \ +
    \
    \
    \
    '; @@ -243,7 +243,7 @@ var host_actions = { type: "single", call: OpenNebula.Host.update, callback: function() { - notifyMessage("Template updated correctly"); + notifyMessage(tr("Template updated correctly")); }, error: onError } @@ -252,51 +252,51 @@ var host_actions = { var host_buttons = { "Host.refresh" : { type: "image", - text: "Refresh list", + text: tr("Refresh list"), img: "images/Refresh-icon.png" }, "Host.create_dialog" : { type: "create_dialog", - text: "+ New" + text: tr("+ New") }, "Host.update_dialog" : { type: "action", - text: "Update a template", + text: tr("Update a template"), alwaysActive: true }, "Host.enable" : { type: "action", - text: "Enable" + text: tr("Enable") }, "Host.disable" : { type: "action", - text: "Disable" + text: tr("Disable") }, "Host.delete" : { type: "action", - text: "Delete host" + text: tr("Delete host") } }; var host_info_panel = { "host_info_tab" : { - title: "Host information", + title: tr("Host information"), content:"" }, "host_template_tab" : { - title: "Host template", + title: tr("Host template"), content: "" }, "host_monitoring_tab": { - title: "Monitoring information", + title: tr("Monitoring information"), content: "" } }; var hosts_tab = { - title: 'Hosts', + title: tr("Hosts"), content: hosts_tab_content, buttons: host_buttons } @@ -430,66 +430,66 @@ function updateHostInfo(request,host){ //Information tab var info_tab = { - title : "Host information", + title : tr("Host information"), content : '
    AllIDNameRunning VMsCPU UseMemory useStatus' + tr("All") + '' + tr("id") + '' + tr("Name") + '' + tr("Running VMs") + '' + tr("CPU Use") + '' + tr("Memory use") + '' + tr("Status") + '
    \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ - \ + \ + \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \
    Host information - '+host_info.NAME+'
    ' + tr("Host information") + ' - '+host_info.NAME+'
    ID' + tr("id") + ''+host_info.ID+'
    State'+OpenNebula.Helper.resource_state("host",host_info.STATE)+'' + tr("State") + ''+tr(OpenNebula.Helper.resource_state("host",host_info.STATE))+'
    IM MAD' + tr("IM MAD") + ''+host_info.IM_MAD+'
    VM MAD' + tr("VM MAD") + ''+host_info.VM_MAD+'
    VN MAD'+ tr("VN MAD") +''+host_info.VN_MAD+'
    TM MAD'+ tr("TM MAD") +''+host_info.TM_MAD+'
    \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ @@ -498,16 +498,16 @@ function updateHostInfo(request,host){ //Template tab var template_tab = { - title : "Host template", + title : tr("Host template"), content : '
    Host shares
    ' + tr("Host shares") + '
    Max Mem' + tr("Max Mem") + ''+humanize_size(host_info.HOST_SHARE.MAX_MEM)+'
    Used Mem (real)' + tr("Used Mem (real)") + ''+humanize_size(host_info.HOST_SHARE.USED_MEM)+'
    Used Mem (allocated)' + tr("Used Mem (allocated)") + ''+humanize_size(host_info.HOST_SHARE.MAX_USAGE)+'
    Used CPU (real)' + tr("Used CPU (real)") + ''+host_info.HOST_SHARE.USED_CPU+'
    Used CPU (allocated)' + tr("Used CPU (allocated)") + ''+host_info.HOST_SHARE.CPU_USAGE+'
    Running VMs' + tr("Running VMs") + ''+host_info.HOST_SHARE.RUNNING_VMS+'
    \ - '+ + '+ prettyPrintJSON(host_info.TEMPLATE)+ '
    Host template
    ' + tr("Host template") + '
    ' } var monitor_tab = { - title: "Monitoring information", + title: tr("Monitoring information"), content : generateMonitoringDivs(host_graphs,"host_monitor_") } @@ -527,7 +527,7 @@ function updateHostInfo(request,host){ //Prepares the host creation dialog function setupCreateHostDialog(){ - dialogs_context.append('
    '); + dialogs_context.append('
    '); $create_host_dialog = $('div#create_host_dialog'); var dialog = $create_host_dialog; @@ -543,7 +543,7 @@ function setupCreateHostDialog(){ //Handle the form submission $('#create_host_form',dialog).submit(function(){ if (!($('#name',this).val().length)){ - notifyError("Host name missing!"); + notifyError(tr("Host name missing!")); return false; } var host_json = { @@ -574,7 +574,7 @@ function popUpCreateHostDialog(){ function setHostAutorefresh() { setInterval(function(){ var checked = $('input.check_item:checked',dataTable_hosts); - var filter = $("#datatable_hosts_filter input",dataTable_hosts.parents('#datatable_hosts_wrapper')).attr("value"); + var filter = $("#datatable_hosts_filter input",dataTable_hosts.parents('#datatable_hosts_wrapper')).attr('value'); if (!checked.length && !filter.length){ Sunstone.runAction("Host.autorefresh"); } @@ -611,7 +611,11 @@ $(document).ready(function(){ { "sWidth": "35px", "aTargets": [1] }, { "sWidth": "100px", "aTargets": [6] }, { "sWidth": "200px", "aTargets": [4,5] } - ] + ], + "oLanguage": (datatable_lang != "") ? + { + sUrl: "locale/"+lang+"/"+datatable_lang + } : "" }); //preload it diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index ce879dee85..4a1583ce3a 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -23,18 +23,18 @@ var images_tab_content = \ \ \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ \ \ \ @@ -44,114 +44,116 @@ var images_tab_content = var create_image_tmpl = '
    \ -
    • Wizard
    • \ -
    • Advanced mode
    • \ + \
      \
      \ -

      Fields marked with are mandatory
      \ +

      '+ + tr("Fields marked with")+' '+ + tr("are mandatory")+'
      \

      \
      \ - \ + \ \ -
      Name that the Image will get. Every image must have a unique name.
      \ +
      '+tr("Name that the Image will get. Every image must have a unique name.")+'
      \
      \
      \ - \ + \ \ -
      Human readable description of the image for other users.
      \ +
      '+tr("Human readable description of the image for other users.")+'
      \
      \
      \
      \
      \ - \ + \ \ -
      Type of the image, explained in detail in the following section. If omitted, the default value is the one defined in oned.conf (install default is OS).
      \ +
      '+tr("Type of the image, explained in detail in the following section. If omitted, the default value is the one defined in oned.conf (install default is OS).")+'
      \
      \
      \ - \ + \ \ -
      Public scope of the image
      \ +
      '+tr("Public scope of the image")+'
      \
      \
      \ - \ + \ \ -
      Persistence of the image
      \ +
      '+tr("Persistence of the image")+'
      \
      \
      \ - \ + \ \ -
      Prefix for the emulated device this image will be mounted at. For instance, “hd”, “sd”. If omitted, the default value is the one defined in oned.conf (installation default is “hd”).
      \ +
      '+tr("Prefix for the emulated device this image will be mounted at. For instance, “hd”, “sd”. If omitted, the default value is the one defined in oned.conf (installation default is “hd”).")+'
      \
      \
      \ - \ + \ \ -
      Type of disk device to emulate.
      \ +
      '+tr("Type of disk device to emulate.")+'
      \
      \
      \ - \ + \ \ -
      Specific image mapping driver. KVM: raw, qcow2 and Xen:tap:aio:, file:
      \ +
      '+tr("Specific image mapping driver. KVM: raw, qcow2. XEN: tap:aio, file:")+'
      \
      \
      \
      \
      \ - \ + \ \ -
      \ +
      \ \ -
      \ +
      \ \ - \ -
      Please choose path if you have a file-based image. Choose source otherwise or create an empty datablock disk.

      \ + \ +
      '+tr("Please choose path if you have a file-based image. Choose source otherwise or create an empty datablock disk.")+'

      \
      \
      \ - \ + \ \ -
      Path to the original file that will be copied to the image repository. If not specified for a DATABLOCK type image, an empty image will be created.
      \ +
      '+tr("Path to the original file that will be copied to the image repository. If not specified for a DATABLOCK type image, an empty image will be created.")+'
      \
      \
      \ - \ + \ \ -
      Source to be used in the DISK attribute. Useful for not file-based images.
      \ +
      '+tr("Source to be used in the DISK attribute. Useful for not file-based images.")+'
      \
      \
      \ - \ + \ \ -
      Size of the datablock in MB.
      \ +
      '+tr("Size of the datablock in MB.")+'
      \
      \
      \ - \ + \ \ -
      Type of file system to be built. This can be any value understood by mkfs unix command.
      \ +
      '+tr("Type of file system to be built. This can be any value understood by mkfs unix command.")+'
      \
      \
      \
      \
      \ - \ + \ \ - \ + \ \ - \ - \ + \ + \
      \ - \ + \ \
      \
      \
      \
      \ - \ - \ + \ + \
      \
      \ \ @@ -159,16 +161,16 @@ var create_image_tmpl =
      \
      \
      \ -

      Write the image template here

      \ +

      '+tr("Write the image template here")+'

      \ \
      \
      \
      \ \ - \ + \
      \
      \ \ @@ -177,27 +179,26 @@ var create_image_tmpl = var update_image_tmpl = '
      \ -

      Please, choose and modify the image you want to update:

      \ +

      '+tr("Please, choose and modify the image you want to update")+':

      \
      \ - \ + \ \
      \
      \ - \ + \ \
      \
      \ - \ + \ \
      \ - \ + \
      \ \
      \
      \
      \ - \
      \
      \ @@ -277,7 +278,7 @@ var image_actions = { type: "single", call: OpenNebula.Image.update, callback: function() { - notifyMessage("Template updated correctly"); + notifyMessage(tr("Template updated correctly")); }, error: onError }, @@ -396,30 +397,30 @@ var image_actions = { var image_buttons = { "Image.refresh" : { type: "image", - text: "Refresh list", + text: tr("Refresh list"), img: "images/Refresh-icon.png" }, "Image.create_dialog" : { type: "create_dialog", - text: "+ New" + text: tr('+ New') }, "Image.update_dialog" : { type: "action", - text: "Update a template", + text: tr("Update a template"), alwaysActive: true }, "Image.chown" : { type: "confirm_with_select", - text: "Change owner", + text: tr("Change owner"), select: users_sel, - tip: "Select the new owner:", + tip: tr("Select the new owner")+":", condition: mustBeAdmin }, "Image.chgrp" : { type: "confirm_with_select", - text: "Change group", + text: tr("Change group"), select: groups_sel, - tip: "Select the new group:", + tip: tr("Select the new group")+":", condition: mustBeAdmin }, "action_list" : { @@ -427,51 +428,51 @@ var image_buttons = { actions: { "Image.enable" : { type: "action", - text: "Enable" + text: tr("Enable") }, "Image.disable" : { type: "action", - text: "Disable" + text: tr("Disable") }, "Image.publish" : { type: "action", - text: "Publish" + text: tr("Publish") }, "Image.unpublish" : { type: "action", - text: "Unpublish" + text: tr("Unpublish") }, "Image.persistent" : { type: "action", - text: "Make persistent" + text: tr("Make persistent") }, "Image.nonpersistent" : { type: "action", - text: "Make non persistent" + text: tr("Make non persistent") } } }, "Image.delete" : { type: "action", - text: "Delete" + text: tr("Delete") } } var image_info_panel = { "image_info_tab" : { - title: "Image information", + title: tr("Image information"), content: "" }, "image_template_tab" : { - title: "Image template", + title: tr("Image template"), content: "" } } var images_tab = { - title: "Images", + title: tr("Images"), content: images_tab_content, buttons: image_buttons } @@ -492,13 +493,13 @@ function imageElementArray(image_json){ var image = image_json.IMAGE; var type = $(''); var value = OpenNebula.Helper.image_type(image.TYPE); - $('option[value="'+value+'"]',type).replaceWith(''); + $('option[value="'+value+'"]',type).replaceWith(''); @@ -570,75 +571,76 @@ function updateImagesView(request, images_list){ function updateImageInfo(request,img){ var img_info = img.IMAGE; var info_tab = { - title: "Image information", + title: tr("Image information"), content: '
    AllIDOwnerGroupNameSizeTypeRegistration timePublicPersistentStatus#VMS'+tr("All")+''+tr("ID")+''+tr("Owner")+''+tr("Group")+''+tr("Name")+''+tr("Size")+''+tr("Type")+''+tr("Registration time")+''+tr("Public")+''+tr("Persistent")+''+tr("Status")+''+tr("#VMS")+'
    \ \ - \ + \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ - \ + \ + \ \ \ - \ - \ + \ + \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \
    Image "'+img_info.NAME+'" information
    '+tr("Image")+' "'+img_info.NAME+'" '+ + tr("information")+'
    ID'+tr("ID")+''+img_info.ID+'
    Name'+tr("Name")+''+img_info.NAME+'
    Owner'+tr("Owner")+''+img_info.UNAME+'
    Group'+tr("Group")+''+img_info.GNAME+'
    Type'+tr("Type")+''+OpenNebula.Helper.image_type(img_info.TYPE)+'
    Register time'+tr("Register time")+''+pretty_time(img_info.REGTIME)+'
    Public'+(parseInt(img_info.PUBLIC) ? "yes" : "no")+''+tr("Public")+''+(parseInt(img_info.PUBLIC) ? tr("yes") : tr("no"))+'
    Persistent'+(parseInt(img_info.PERSISTENT) ? "yes" : "no")+''+tr("Persistent")+''+(parseInt(img_info.PERSISTENT) ? tr("yes") : tr("no"))+'
    Source'+tr("Source")+''+(typeof img_info.SOURCE === "string" ? img_info.SOURCE : "--")+'
    Path'+tr("Path")+''+(typeof img_info.PATH === "string" ? img_info.PATH : "--")+'
    Filesystem type'+tr("Filesystem type")+''+(typeof img_info.FSTYPE === "string" ? img_info.FSTYPE : "--")+'
    Size (Mb)'+tr("Size (Mb)")+''+img_info.SIZE+'
    State'+tr("State")+''+OpenNebula.Helper.resource_state("image",img_info.STATE)+'
    Running #VMS'+tr("Running #VMS")+''+img_info.RUNNING_VMS+'
    ' } var template_tab = { - title: "Image template", + title: tr("Image template"), content: '\ - '+ + '+ prettyPrintJSON(img_info.TEMPLATE)+ '
    Image template
    '+tr("Image template")+'
    ' } @@ -652,7 +654,7 @@ function updateImageInfo(request,img){ // Prepare the image creation dialog function setupCreateImageDialog(){ - dialogs_context.append('
    '); + dialogs_context.append('
    '); $create_image_dialog = $('#create_image_dialog',dialogs_context); var dialog = $create_image_dialog; dialog.html(create_image_tmpl); @@ -669,8 +671,8 @@ function setupCreateImageDialog(){ $('#img_tabs',dialog).tabs(); $('button',dialog).button(); - $('#img_type option',dialog).first().attr("selected","selected"); - $('#datablock_img',dialog).attr("disabled","disabled"); + $('#img_type option',dialog).first().attr('selected','selected'); + $('#datablock_img',dialog).attr('disabled','disabled'); $('select#img_type',dialog).change(function(){ var value = $(this).val(); @@ -680,23 +682,23 @@ function setupCreateImageDialog(){ $('#datablock_img',context).removeAttr("disabled"); break; default: - $('#datablock_img',context).attr("disabled","disabled"); - $('#path_img',context).attr("checked","checked"); + $('#datablock_img',context).attr('disabled','disabled'); + $('#path_img',context).attr('checked','checked'); $('#img_source,#img_fstype,#img_size',context).parent().hide(); $('#img_path',context).parent().show(); } }); $('#img_source,#img_fstype,#img_size',dialog).parent().hide(); - $('#path_img',dialog).attr("checked","checked"); + $('#path_img',dialog).attr('checked','checked'); $('#img_path',dialog).parent().addClass("img_man"); $('#img_public',dialog).click(function(){ - $('#img_persistent',$create_image_dialog).removeAttr("checked"); + $('#img_persistent',$create_image_dialog).removeAttr('checked'); }); $('#img_persistent',dialog).click(function(){ - $('#img_public',$create_image_dialog).removeAttr("checked"); + $('#img_public',$create_image_dialog).removeAttr('checked'); }); @@ -732,7 +734,7 @@ function setupCreateImageDialog(){ var name = $('#custom_var_image_name',$create_image_dialog).val(); var value = $('#custom_var_image_value',$create_image_dialog).val(); if (!name.length || !value.length) { - notifyError("Custom attribute name and value must be filled in"); + notifyError(tr("Custom attribute name and value must be filled in")); return false; } option= '' : ""; + var new_select= sel_elems.length > 1? '' : ""; $('option','').each(function(){ var val = $(this).val(); if ($.inArray(val,sel_elems) >= 0){ @@ -942,7 +945,7 @@ function popUpImageTemplateUpdateDialog(){ }); $('#image_template_update_select',dialog).html(new_select); if (sel_elems.length == 1) { - $('#image_template_update_select option',dialog).attr("selected","selected"); + $('#image_template_update_select option',dialog).attr('selected','selected'); $('#image_template_update_select',dialog).trigger("change"); } @@ -958,7 +961,7 @@ function setImageAutorefresh() { setInterval(function(){ var checked = $('input.check_item:checked',dataTable_images); var filter = $("#datatable_images_filter input", - dataTable_images.parents("#datatable_images_wrapper")).attr("value"); + dataTable_images.parents("#datatable_images_wrapper")).attr('value'); if (!checked.length && !filter.length){ Sunstone.runAction("Image.autorefresh"); } @@ -967,23 +970,23 @@ function setImageAutorefresh() { function is_public_image(id){ var data = getElementData(id,"#image",dataTable_images)[7]; - return $(data).attr("checked"); + return $(data).attr('checked'); }; function is_persistent_image(id){ var data = getElementData(id,"#image",dataTable_images)[8]; - return $(data).attr("checked"); + return $(data).attr('checked'); }; function setupImageActionCheckboxes(){ $('input.action_cb#cb_public_image',dataTable_images).live("click",function(){ var $this = $(this) - var id=$this.attr("elem_id"); - if ($this.attr("checked")){ + var id=$this.attr('elem_id'); + if ($this.attr('checked')){ if (!is_persistent_image(id)) Sunstone.runAction("Image.publish",id); else { - notifyError("Image cannot be public and persistent"); + notifyError(tr("Image cannot be public and persistent")); return false; }; } else Sunstone.runAction("Image.unpublish",id); @@ -993,12 +996,12 @@ function setupImageActionCheckboxes(){ $('input.action_cb#cb_persistent_image',dataTable_images).live("click",function(){ var $this = $(this) - var id=$this.attr("elem_id"); - if ($this.attr("checked")){ + var id=$this.attr('elem_id'); + if ($this.attr('checked')){ if (!is_public_image(id)) Sunstone.runAction("Image.persistent",id); else { - notifyError("Image cannot be public and persistent"); + notifyError(tr("Image cannot be public and persistent")); return false; }; } else Sunstone.runAction("Image.nonpersistent",id); @@ -1009,7 +1012,7 @@ function setupImageActionCheckboxes(){ $('select.action_cb#select_chtype_image', dataTable_images).live("change",function(){ var $this = $(this); var value = $this.val(); - var id = $this.attr("elem_id"); + var id = $this.attr('elem_id'); Sunstone.runAction("Image.chtype", id, value); }); @@ -1030,7 +1033,11 @@ $(document).ready(function(){ { "sWidth": "35px", "aTargets": [1,5,11] }, { "sWidth": "100px", "aTargets": [6] }, { "sWidth": "150px", "aTargets": [7] } - ] + ], + "oLanguage": (datatable_lang != "") ? + { + sUrl: "locale/"+lang+"/"+datatable_lang + } : "" }); dataTable_images.fnClearTable(); @@ -1048,4 +1055,6 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_images); tableCheckboxesListener(dataTable_images); imageInfoListener(); + + }) diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index 18c185f64a..f1d8f97d9c 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -23,13 +23,13 @@ var templates_tab_content = \ \ \ - \ - \ - \ - \ - \ - \ - \ + \ + \ + \ + \ + \ + \ + \ \ \ \ @@ -39,10 +39,10 @@ var templates_tab_content = var create_template_tmpl = '
    \ \
    \ \ @@ -54,35 +54,37 @@ var create_template_tmpl = '
    \ XEN\
    \ -->\ -

    Fields marked with are mandatory
    \ - Fold / Unfold all sections

    \ +

    '+ + tr("Fields marked with")+''+ + tr("are mandatory")+'
    \ + '+tr("Fold / Unfold all sections")+'

    \
    \ \ \
    \
    \ -

    Capacity options

    \ +

    '+tr("Capacity options")+'

    \
    \ -
    Capacity\ +
    '+tr("Capacity")+'\
    \ - \ + \ \ -
    Name that the VM will get for description purposes. If NAME is not supplied a name generated by one will be in the form of one-<VID>.
    \ +
    '+tr("Name that the VM will get for description purposes. If NAME is not supplied a name generated by one will be in the form of one-<VID>.")+'
    \
    \
    \ - \ + \ \ -
    Amount of RAM required for the VM, in Megabytes.
    \ +
    '+tr("Amount of RAM required for the VM, in Megabytes.")+'
    \
    \
    \ - \ + \ \ -
    Percentage of CPU divided by 100 required for the Virtual Machine. Half a processor is written 0.5.
    \ +
    '+tr("Percentage of CPU divided by 100 required for the Virtual Machine. Half a processor is written 0.5.")+'
    \
    \
    \ - \ + \ \ -
    Number of virtual cpus. This value is optional, the default hypervisor behavior is used, usually one virtual CPU.
    \ +
    '+tr("Number of virtual cpus. This value is optional, the default hypervisor behavior is used, usually one virtual CPU.")+'
    \
    \
    \
    \ @@ -91,58 +93,58 @@ var create_template_tmpl = '
    \ -->\
    \
    \ -

    Boot/OS options

    \ +

    '+tr("Boot/OS options")+'

    \
    \ -
    OS and Boot options\ +
    '+tr("OS and Boot options")+'\
    \ - \ + \ \ -
    CPU architecture to virtualization
    \ +
    '+tr("CPU architecture to virtualization")+'
    \
    \ \
    \ - \ + \ \ -
    Select boot method
    \ +
    '+tr("Select boot method")+'
    \
    \
    \ - \ + \ \ -
    Path to the OS kernel to boot the image
    \ +
    '+tr("Path to the OS kernel to boot the image")+'
    \
    \
    \ - \ + \ \ -
    Path to the initrd image
    \ +
    '+tr("Path to the initrd image")+'
    \
    \
    \ - \ + \ \ -
    Device to be mounted as root
    \ +
    '+tr("Device to be mounted as root")+'
    \
    \
    \ - \ + \ \ -
    Arguments for the booting kernel
    \ +
    '+tr("Arguments for the booting kernel")+'
    \
    \
    \ - \ + \ \ -
    Path to the bootloader executable
    \ +
    '+tr("Path to the bootloader executable")+'
    \
    \
    \ - \ + \ \ -
    Boot device type
    \ +
    '+tr("Boot device type")+'
    \
    \
    \
    \ @@ -151,26 +153,26 @@ var create_template_tmpl = '
    \ \
    \
    \ -

    Features

    \ +

    '+tr("Features")+'

    \
    \ -
    Features\ +
    '+tr("Features")+'\
    \ - \ + \ \ -
    Physical address extension mode allows 32-bit guests to address more than 4 GB of memory
    \ +
    '+tr("Physical address extension mode allows 32-bit guests to address more than 4 GB of memory")+'
    \
    \
    \ - \ + \ \ -
    Useful for power management, for example, normally required for graceful shutdown to work
    \ +
    '+tr("Useful for power management, for example, normally required for graceful shutdown to work")+'
    \
    \
    \
    \ @@ -182,92 +184,92 @@ var create_template_tmpl = '
    \ readonly SEVERAL DISKS-->\
    \
    \ -

    Add disks/images

    \ -
    \ -
    Disks\ +

    '+tr("Add disks/images")+'

    \ +
    \ +
    '+tr("Disks")+'\
    \ - \ - Disk\ + \ + '+tr("Disk")+'\ \ - Image\ + '+tr("Image")+'\ \
    \
    \
    \ - \ + \ \ -
    Name of the image to use
    \ +
    '+tr("Name of the image to use")+'
    \ \
    \
    \ - \ + \ \ -
    Type of disk device to emulate: ide, scsi
    \ +
    '+tr("Type of disk device to emulate: ide, scsi")+'
    \
    \
    \ - \ + \ \ -
    Device to map image disk. If set, it will overwrite the default device mapping
    \ +
    '+tr("Device to map image disk. If set, it will overwrite the default device mapping")+'
    \
    \
    \ - \ + \ \ -
    Specific image mapping driver. KVM: raw, qcow2. Xen:tap:aio:, file:. VMware unsupported
    \ +
    '+tr("Specific image mapping driver. KVM: raw, qcow2. Xen:tap:aio:, file:. VMware unsupported")+'
    \
    \
    \ - \ + \ \ -
    Disk type
    \ +
    '+tr("Disk type")+'
    \
    \
    \ - \ + \ \ -
    Disk file location path or URL
    \ +
    '+tr("Disk file location path or URL")+'
    \
    \
    \ \ - \ + \ \ -
    Size in MB
    \ +
    '+tr("Size in MB")+'
    \
    \
    \ \ - \ + \ \ -
    Filesystem type for the fs images
    \ +
    '+tr("Filesystem type for the fs images")+'
    \
    \
    \ - \ + \ \ -
    Clone this image
    \ +
    '+tr("Clone this image")+'
    \
    \
    \ - \ + \ \ -
    Save this image after shutting down the VM
    \ +
    '+tr("Save this image after shutting down the VM")+'
    \
    \
    \ - \ + \ \ -
    Mount image as read-only
    \ +
    '+tr("Mount image as read-only")+'
    \
    \
    \ - \ - \ + \ + \
    \ - \ + \ \
    \ @@ -279,107 +281,107 @@ var create_template_tmpl = '
    \ bridge, target, script, model -->\
    \
    \ -

    Setup Networks

    \ +

    '+tr("Setup Networks")+'

    \
    \ -
    Network\ +
    '+tr("Network")+'\
    \ - \ - Predefined\ + \ + '+tr("Predefined")+'\ \ - Manual\ + '+tr("Manual")+'\ \ \
    \
    \
    \ - \ + \ \ -
    Name of the network to attach this device
    \ +
    '+tr("Name of the network to attach this device")+'
    \ \
    \
    \ - \ + \ \ -
    Request an specific IP from the Network
    \ +
    '+tr("Request an specific IP from the Network")+'
    \
    \
    \ - \ + \ \ -
    HW address associated with the network interface
    \ +
    '+tr("HW address associated with the network interface")+'
    \
    \
    \ - \ + \ \ -
    Name of the bridge the network device is going to be attached to
    \ +
    '+tr("Name of the bridge the network device is going to be attached to")+'
    \
    \
    \ - \ + \ \ -
    Name for the tun device created for the VM
    \ +
    '+tr("Name for the tun device created for the VM")+'
    \
    \
    \ - \ + \ \ -
    Name of a shell script to be executed after creating the tun device for the VM
    \ +
    '+tr("Name of a shell script to be executed after creating the tun device for the VM")+'
    \
    \
    \ - \ + \ \ -
    Hardware that will emulate this network interface. With Xen this is the type attribute of the vif.
    \ +
    '+tr("Hardware that will emulate this network interface. With Xen this is the type attribute of the vif.")+'
    \
    \
    \ - \ + \ \
    \
    \
    \ - \ + \ \ -
    Permits access to the VM only through the specified ports in the TCP protocol
    \ +
    '+tr("Permits access to the VM only through the specified ports in the TCP protocol")+'
    \
    \
    \ - \ + \ \ -
    Disallow access to the VM through the specified ports in the TCP protocol
    \ +
    '+tr("Disallow access to the VM through the specified ports in the TCP protocol")+'
    \
    \
    \ - \ + \ \
    \
    \
    \ - \ + \ \ -
    Permits access to the VM only through the specified ports in the UDP protocol
    \ +
    '+tr("Permits access to the VM only through the specified ports in the UDP protocol")+'
    \
    \
    \ - \ + \ \ -
    Disallow access to the VM through the specified ports in the UDP protocol
    \ +
    '+tr("Disallow access to the VM through the specified ports in the UDP protocol")+'
    \
    \
    \ - \ + \ \ -
    ICMP policy
    \ +
    '+tr("ICMP policy")+'
    \
    \
    \
    \ - \ - \ + \ + \
    \ - \ + \ \
    \ @@ -390,31 +392,31 @@ var create_template_tmpl = '
    \ \
    \
    \ -

    Add inputs

    \ +

    '+tr("Add inputs")+'

    \
    \ -
    Inputs\ +
    '+tr("Inputs")+'\
    \ - \ + \ \
    \
    \
    \ - \ + \ \
    \
    \
    \ - \ - \ + \ + \
    \ - \ + \ \
    \ @@ -425,37 +427,37 @@ var create_template_tmpl = '
    \ \
    \
    \ -

    Add Graphics

    \ +

    '+tr("Add Graphics")+'

    \
    \ -
    Graphics\ +
    '+tr("Graphics")+'\
    \ - \ + \ \
    \
    \
    \ - \ + \ \ -
    IP to listen on
    \ +
    '+tr("IP to listen on")+'
    \
    \
    \ - \ + \ \ -
    Port for the VNC server
    \ +
    '+tr("Port for the VNC server")+'
    \
    \
    \ - \ + \ \ -
    Password for the VNC server
    \ +
    '+tr("Password for the VNC server")+'
    \
    \
    \ - \ + \ \ -
    Keyboard configuration locale to use in the VNC display
    \ +
    '+tr("Keyboard configuration locale to use in the VNC display")+'
    \
    \
    \
    \ @@ -464,24 +466,24 @@ var create_template_tmpl = '
    \ \
    \
    \ -

    Add context variables

    \ +

    '+tr("Add context variables")+'

    \
    \ -
    Context\ +
    '+tr("Context")+'\
    \ - \ + \ \ -
    Name for the context variable
    \ +
    '+tr("Name for the context variable")+'
    \
    \
    \ - \ + \ \ -
    Value of the context variable
    \ +
    '+tr("Value of the context variable")+'
    \
    \
    \ - \ - \ + \ + \
    \ - \ + \ \
    \ @@ -492,18 +494,18 @@ var create_template_tmpl = '
    \ \
    \
    \ -

    Add placement options

    \ +

    '+tr("Add placement options")+'

    \
    \ -
    Placement\ +
    '+tr("Placement")+'\
    \ - \ + \ \ -
    Boolean expression that rules out provisioning hosts from list of machines suitable to run this VM
    \ +
    '+tr("Boolean expression that rules out provisioning hosts from list of machines suitable to run this VM")+'
    \
    \
    \ - \ + \ \ -
    This field sets which attribute will be used to sort the suitable hosts for this VM. Basically, it defines which hosts are more suitable than others
    \ +
    '+tr("This field sets which attribute will be used to sort the suitable hosts for this VM. Basically, it defines which hosts are more suitable than others")+'
    \
    \
    \
    \ @@ -512,15 +514,15 @@ var create_template_tmpl = '
    \ \
    \
    \ -

    Add Hypervisor raw options

    \ +

    '+tr("Add Hypervisor raw options")+'

    \
    \ -
    Raw\ +
    '+tr("Raw")+'\ \
    \ - \ + \ \ \ -
    Raw data to be passed directly to the hypervisor
    \ +
    '+tr("Raw data to be passed directly to the hypervisor")+'
    \
    \
    \
    \ @@ -529,24 +531,24 @@ var create_template_tmpl = '
    \ \
    \
    \ -

    Add custom variables

    \ +

    '+tr("Add custom variables")+'

    \
    \ -
    Custom variables\ +
    '+tr("Custom variables")+'\
    \ - \ + \ \ -
    Name for the custom variable
    \ +
    '+tr("Name for the custom variable")+'
    \
    \
    \ - \ + \ \ -
    Value of the custom variable
    \ +
    '+tr("Value of the custom variable")+'
    \
    \
    \ - \ - \ + \ + \
    \ - \ + \ \
    \ @@ -556,16 +558,16 @@ var create_template_tmpl = '
    \
    \
    \ \ - \ + \
    \
    \ \
    \
    \
    \ -

    Write the Virtual Machine template here

    \ +

    '+tr("Write the Virtual Machine template here")+'

    \
    \ \
    \ @@ -573,9 +575,9 @@ var create_template_tmpl = '
    \
    \
    \ \ - \ + \
    \
    \ \ @@ -584,16 +586,16 @@ var create_template_tmpl = '
    \ var update_template_tmpl = '
    \ -

    Please, choose and modify the template you want to update:

    \ +

    '+tr("Please, choose and modify the template you want to update")+':

    \
    \ - \ + \ \
    \
    \ - \ + \ \
    \ - \ + \
    \ \
    \ @@ -606,7 +608,6 @@ var update_template_tmpl =
    \ '; -var templates_select = ""; var dataTable_templates; var $create_template_dialog; @@ -672,7 +673,7 @@ var template_actions = { type: "single", call: OpenNebula.Template.update, callback: function() { - notifyMessage("Template updated correctly"); + notifyMessage(tr("Template updated correctly")); }, error: onError }, @@ -751,34 +752,34 @@ var template_actions = { var template_buttons = { "Template.refresh" : { type: "image", - text: "Refresh list", + text: tr("Refresh list"), img: "images/Refresh-icon.png" }, "Template.create_dialog" : { type: "create_dialog", - text: "+ New" + text: tr("+ New") }, "Template.update_dialog" : { type: "action", - text: "Update a template", + text: tr("Update a template"), alwaysActive: true }, "Template.instantiate_vms" : { type: "action", - text: "Instantiate" + text: tr("Instantiate") }, "Template.chown" : { type: "confirm_with_select", - text: "Change owner", + text: tr("Change owner"), select: users_sel, - tip: "Select the new owner:", + tip: tr("Select the new owner")+":", condition: mustBeAdmin }, "Template.chgrp" : { type: "confirm_with_select", - text: "Change group", + text: tr("Change group"), select: groups_sel, - tip: "Select the new group:", + tip: tr("Select the new group")+":", condition: mustBeAdmin }, "action_list" : { @@ -786,29 +787,29 @@ var template_buttons = { actions: { "Template.publish" : { type: "action", - text: "Publish" + text: tr("Publish") }, "Template.unpublish" : { type: "action", - text: "Unpublish" + text: tr("Unpublish") }, } }, "Template.delete" : { type: "action", - text: "Delete" + text: tr("Delete") } } var template_info_panel = { "template_info_tab" : { - title: "Template information", + title: tr("Template information"), content: "" } } var templates_tab = { - title: "Templates", + title: tr("Templates"), content: templates_tab_content, buttons: template_buttons } @@ -857,12 +858,12 @@ function templateInfoListener(){ //Updates the select input field with an option for each template function updateTemplateSelect(){ - templates_select = + var templates_select = makeSelectOptions(dataTable_templates, 1,//id_col 4,//name_col - [7],//enabled_col - ["no"]//bad status col + [],//status_cols + []//bad status values ); //update static selectors: @@ -908,42 +909,43 @@ function updateTemplatesView(request, templates_list){ function updateTemplateInfo(request,template){ var template_info = template.VMTEMPLATE; var info_tab = { - title: "Information", + title: tr("Information"), content: '
    AllIDOwnerGroupNameRegistration timePublic'+tr("All")+''+tr("ID")+''+tr("Owner")+''+tr("Group")+''+tr("Name")+''+tr("Registration time")+''+tr("Public")+'
    \ \ - \ + \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ + \ \ \ \ - \ - \ + \ + \ \
    Template "'+template_info.NAME+'" information
    '+tr("Template")+' \"'+template_info.NAME+'\" '+ + tr("information")+'
    ID'+tr("ID")+''+template_info.ID+'
    Name'+tr("Name")+''+template_info.NAME+'
    Owner'+tr("Owner")+''+template_info.UNAME+'
    Group'+tr("Group")+''+template_info.GNAME+'
    Register time'+tr("Register time")+''+pretty_time(template_info.REGTIME)+'
    Public'+(parseInt(template_info.PUBLIC) ? "yes" : "no")+''+tr("Public")+''+(parseInt(template_info.PUBLIC) ? tr("yes") : tr("no"))+'
    ' }; var template_tab = { - title: "Template", + title: tr("Template"), content: '\ - '+ + '+ prettyPrintJSON(template_info.TEMPLATE)+ '
    Template
    '+tr("Template")+'
    ' }; @@ -967,7 +969,7 @@ function setupCreateTemplateDialog(){ // ui.index // zero-based index of the selected (clicked) tab //disable all items - $(items,dialog).attr("disabled","disabled"); + $(items,dialog).attr('disabled','disabled'); //hide all mandatory icons $('.vm_param .man_icon',dialog).css("display","none"); @@ -981,7 +983,7 @@ function setupCreateTemplateDialog(){ $('.kernel, .bootloader', section_os_boot).hide(); $('select#BOOT',section_os_boot).parent().hide(); //unselect boot method - $('select#boot_method option',section_os_boot).removeAttr("selected"); + $('select#boot_method option',section_os_boot).removeAttr('selected'); //hide non common sections $(section_inputs).hide(); @@ -1031,7 +1033,7 @@ function setupCreateTemplateDialog(){ var enable_kvm = function(){ man_class="kvm"; opt_class="kvm_opt"; - $(kvm_items,dialog).removeAttr("disabled"); + $(kvm_items,dialog).removeAttr('disabled'); $('.kvm .man_icon',dialog).css("display","inline-block"); //KVM particularities: @@ -1043,30 +1045,30 @@ function setupCreateTemplateDialog(){ // * Show the inputs and graphics section var type_opts = - '\ - \ - \ - \ - \ - \ - '; + '\ + \ + \ + \ + \ + \ + '; $('select#TYPE',section_disks).html(type_opts); var boot_opts = - '\ - \ - \ - '; + '\ + \ + \ + '; $('select#BOOT',section_os_boot).html(boot_opts); $('select#BOOT',section_os_boot).parent().show(); - $('select#boot_method option#no_boot',section_os_boot).html("Driver default"); + $('select#boot_method option#no_boot',section_os_boot).html(tr("Driver default")); var bus_opts = - '\ - \ - '; + '\ + \ + '; $('select#BUS',section_disks).html(bus_opts); @@ -1080,7 +1082,7 @@ function setupCreateTemplateDialog(){ var enable_xen = function(){ man_class="xen"; opt_class="xen_opt"; - $(xen_items,dialog).removeAttr("disabled"); + $(xen_items,dialog).removeAttr('disabled'); $('.xen .man_icon',dialog).css("display","inline-block"); // XEN particularities: @@ -1091,20 +1093,20 @@ function setupCreateTemplateDialog(){ // * Show the graphics section var type_opts = - '\ - \ - \ - \ - \ - '; + '\ + \ + \ + \ + \ + '; $('select#TYPE',section_disks).html(type_opts); - $('select#boot_method option#no_boot',section_os_boot).html("Please choose"); + $('select#boot_method option#no_boot',section_os_boot).html(tr("Please choose")); var bus_opts = - '\ - '; + '\ + '; $('select#BUS',section_disks).html(bus_opts); @@ -1116,7 +1118,7 @@ function setupCreateTemplateDialog(){ var enable_vmware = function() { man_class="vmware"; opt_class="vmware_opt"; - $(vmware_items,dialog).removeAttr("disabled"); + $(vmware_items,dialog).removeAttr('disabled'); $('.vmware .man_icon',dialog).css("display","inline-block"); //VMWARE particularities @@ -1126,17 +1128,17 @@ function setupCreateTemplateDialog(){ // * Set the raw type to vmware var type_opts = - '\ - \ - '; + '\ + \ + '; $('select#TYPE',section_disks).html(type_opts); $('div#kernel_bootloader',section_os_boot).hide(); var bus_opts = - '\ - '; + '\ + '; $('select#BUS',section_disks).html(bus_opts); $('input#TYPE', section_raw).val("vmware"); @@ -1154,7 +1156,7 @@ function setupCreateTemplateDialog(){ //we fail it the item is enabled and has no value $.each(man_items,function(){ var item = $(this); - if (item.parents(".vm_param").attr("disabled") || + if (item.parents(".vm_param").attr('disabled') || !(item.val().length)) { r = false; return false; @@ -1175,7 +1177,7 @@ function setupCreateTemplateDialog(){ //are fields passing the filter? var result = filter(); if (!result) { - notifyError("There are mandatory parameters missing in this section"); + notifyError(tr("There are mandatory parameters missing in this section")); return false; } @@ -1185,7 +1187,7 @@ function setupCreateTemplateDialog(){ var id = null; $.each(fields,function(){ var field = $(this); - if (!(field.parents(".vm_param").attr("disabled")) && + if (!(field.parents(".vm_param").attr('disabled')) && field.val().length){ //Pick up parent's ID if we do not have one id = field.attr('id').length ? field.attr('id') : field.parent().attr('id'); @@ -1219,7 +1221,7 @@ function setupCreateTemplateDialog(){ fields.each(function(){ var field=$(this); - if (!(field.parents(".vm_param").attr("disabled"))){ //if ! disabled + if (!(field.parents(".vm_param").attr('disabled'))){ //if ! disabled if (field.val().length){ //if has a length template_json[field.attr('id')]=field.val(); }; @@ -1334,19 +1336,19 @@ function setupCreateTemplateDialog(){ { case "kernel": $('.bootloader',section_os_boot).hide(); - $('.bootloader',section_os_boot).attr("disabled","disabled"); + $('.bootloader',section_os_boot).attr('disabled','disabled'); $('.kernel',section_os_boot).show(); - $('.kernel',section_os_boot).removeAttr("disabled"); + $('.kernel',section_os_boot).removeAttr('disabled'); break; case "bootloader": $('.kernel',section_os_boot).hide(); - $('.kernel',section_os_boot).attr("disabled","disabled"); + $('.kernel',section_os_boot).attr('disabled','disabled'); $('.bootloader',section_os_boot).show(); - $('.bootloader',section_os_boot).removeAttr("disabled"); + $('.bootloader',section_os_boot).removeAttr('disabled'); break; default: $('.kernel, .bootloader',section_os_boot).hide(); - $('.kernel, .bootloader',section_os_boot).attr("disabled","disabled"); + $('.kernel, .bootloader',section_os_boot).attr('disabled','disabled'); $('.kernel input, .bootloader input',section_os_boot).val(""); }; }); @@ -1390,26 +1392,26 @@ function setupCreateTemplateDialog(){ { case "disk": $('.add_image',section_disks).hide(); - $('.add_image',section_disks).attr("disabled","disabled"); + $('.add_image',section_disks).attr('disabled','disabled'); $('.add_disk',section_disks).show(); - $('.add_disk',section_disks).removeAttr("disabled"); + $('.add_disk',section_disks).removeAttr('disabled'); $('#TARGET',section_disks).parent().removeClass(opt_class); $('#TARGET',section_disks).parent().addClass(man_class); break; case "image": $('.add_disk',section_disks).hide(); - $('.add_disk',section_disks).attr("disabled","disabled"); + $('.add_disk',section_disks).attr('disabled','disabled'); $('.add_image',section_disks).show(); - $('.add_image',section_disks).removeAttr("disabled"); + $('.add_image',section_disks).removeAttr('disabled'); $('#TARGET',section_disks).parent().removeClass(man_class); $('#TARGET',section_disks).parent().addClass(opt_class); break; } $('#SIZE',section_disks).parent().hide(); - $('#SIZE',section_disks).parent().attr("disabled","disabled"); + $('#SIZE',section_disks).parent().attr('disabled','disabled'); $('#FORMAT',section_disks).parent().hide(); - $('#SIZE',section_disks).parent().attr("disabled","disabled"); - $('#TYPE :selected',section_disks).removeAttr("selected"); + $('#SIZE',section_disks).parent().attr('disabled','disabled'); + $('#TYPE :selected',section_disks).removeAttr('selected'); //hide_disabled(section_disks); }); @@ -1422,7 +1424,7 @@ function setupCreateTemplateDialog(){ case "swap": //size mandatory $('#SIZE',section_disks).parent().show(); - $('#SIZE',section_disks).parent().removeAttr("disabled"); + $('#SIZE',section_disks).parent().removeAttr('disabled'); $('#SIZE',section_disks).parent().removeClass(opt_class); $('#SIZE',section_disks).parent().addClass(man_class); @@ -1432,17 +1434,17 @@ function setupCreateTemplateDialog(){ //format hidden $('#FORMAT',section_disks).parent().hide(); - $('#FORMAT',section_disks).parent().attr("disabled","disabled"); + $('#FORMAT',section_disks).parent().attr('disabled','disabled'); //source hidden $('#SOURCE',section_disks).parent().hide(); $('#SOURCE',section_disks).parent(). - attr("disabled","disabled"); + attr('disabled','disabled'); break; case "fs": //size mandatory $('#SIZE',section_disks).parent().show(); - $('#SIZE',section_disks).parent().removeAttr("disabled"); + $('#SIZE',section_disks).parent().removeAttr('disabled'); $('#SIZE',section_disks).parent().removeClass(opt_class); $('#SIZE',section_disks).parent().addClass(man_class); @@ -1452,19 +1454,19 @@ function setupCreateTemplateDialog(){ //format mandatory $('#FORMAT',section_disks).parent().show(); - $('#FORMAT',section_disks).parent().removeAttr("disabled"); + $('#FORMAT',section_disks).parent().removeAttr('disabled'); $('#FORMAT',section_disks).parent().removeClass(opt_class); $('#FORMAT',section_disks).parent().addClass(man_class); //source hidden $('#SOURCE',section_disks).parent().hide(); $('#SOURCE',section_disks).parent(). - attr("disabled","disabled"); + attr('disabled','disabled'); break; case "block": //size shown and optional $('#SIZE',section_disks).parent().show(); - $('#SIZE',section_disks).parent().removeAttr("disabled"); + $('#SIZE',section_disks).parent().removeAttr('disabled'); $('#SIZE',section_disks).parent().removeClass(man_class); $('#SIZE',section_disks).parent().addClass(opt_class); @@ -1474,12 +1476,12 @@ function setupCreateTemplateDialog(){ //format hidden $('#FORMAT',section_disks).parent().hide(); - $('#FORMAT',section_disks).parent().attr("disabled","disabled"); + $('#FORMAT',section_disks).parent().attr('disabled','disabled'); //source hidden $('#SOURCE',section_disks).parent().hide(); $('#SOURCE',section_disks).parent(). - attr("disabled","disabled"); + attr('disabled','disabled'); break; case "floppy": case "disk": @@ -1487,7 +1489,7 @@ function setupCreateTemplateDialog(){ default: //size hidden $('#SIZE',section_disks).parent().hide(); - $('#SIZE',section_disks).parent().attr("disabled","disabled"); + $('#SIZE',section_disks).parent().attr('disabled','disabled'); //target mandatory $('#TARGET',section_disks).parent().removeClass(opt_class); @@ -1495,12 +1497,12 @@ function setupCreateTemplateDialog(){ //format optional $('#FORMAT',section_disks).parent().hide(); - $('#FORMAT',section_disks).parent().attr("disabled","disabled"); + $('#FORMAT',section_disks).parent().attr('disabled','disabled'); //source shown $('#SOURCE',section_disks).parent().show(); $('#SOURCE',section_disks).parent(). - removeAttr("disabled"); + removeAttr('disabled'); } //hide_disabled(section_disks); }); @@ -1545,23 +1547,23 @@ function setupCreateTemplateDialog(){ //firewall $('.firewall',section_networks).hide(); - $('.firewall',section_networks).attr("disabled","disabled"); + $('.firewall',section_networks).attr('disabled','disabled'); $('.firewall_select',section_networks).show(); - $('.firewall_select select option',section_networks).removeAttr("selected"); + $('.firewall_select select option',section_networks).removeAttr('selected'); select = $('#network_vs_niccfg :checked',section_networks).val(); switch (select) { case "network": $('.niccfg',section_networks).hide(); - $('.niccfg',section_networks).attr("disabled","disabled"); + $('.niccfg',section_networks).attr('disabled','disabled'); $('.network',section_networks).show(); - $('.network',section_networks).removeAttr("disabled"); + $('.network',section_networks).removeAttr('disabled'); break; case "niccfg": $('.network',section_networks).hide(); - $('.network',section_networks).attr("disabled","disabled"); + $('.network',section_networks).attr('disabled','disabled'); $('.niccfg',section_networks).show(); - $('.niccfg',section_networks).removeAttr("disabled"); + $('.niccfg',section_networks).removeAttr('disabled'); break; } //hide_disabled(section_networks); @@ -1570,21 +1572,21 @@ function setupCreateTemplateDialog(){ $('#black_white_tcp',section_networks).change(function(){ switch ($(this).val()) { case "whitelist": - $('#BLACK_PORTS_TCP',section_networks).parent().attr("disabled","disabled"); + $('#BLACK_PORTS_TCP',section_networks).parent().attr('disabled','disabled'); $('#BLACK_PORTS_TCP',section_networks).parent().hide(); - $('#WHITE_PORTS_TCP',section_networks).parent().removeAttr("disabled"); + $('#WHITE_PORTS_TCP',section_networks).parent().removeAttr('disabled'); $('#WHITE_PORTS_TCP',section_networks).parent().show(); break; case "blacklist": - $('#WHITE_PORTS_TCP',section_networks).parent().attr("disabled","disabled"); + $('#WHITE_PORTS_TCP',section_networks).parent().attr('disabled','disabled'); $('#WHITE_PORTS_TCP',section_networks).parent().hide(); - $('#BLACK_PORTS_TCP',section_networks).parent().removeAttr("disabled"); + $('#BLACK_PORTS_TCP',section_networks).parent().removeAttr('disabled'); $('#BLACK_PORTS_TCP',section_networks).parent().show(); break; default: - $('#WHITE_PORTS_TCP',section_networks).parent().attr("disabled","disabled"); + $('#WHITE_PORTS_TCP',section_networks).parent().attr('disabled','disabled'); $('#WHITE_PORTS_TCP',section_networks).parent().hide(); - $('#BLACK_PORTS_TCP',section_networks).parent().attr("disabled","disabled"); + $('#BLACK_PORTS_TCP',section_networks).parent().attr('disabled','disabled'); $('#BLACK_PORTS_TCP',section_networks).parent().hide(); }; }); @@ -1592,21 +1594,21 @@ function setupCreateTemplateDialog(){ $('#black_white_udp',section_networks).change(function(){ switch ($(this).val()) { case "whitelist": - $('#BLACK_PORTS_UDP',section_networks).parent().attr("disabled","disabled"); + $('#BLACK_PORTS_UDP',section_networks).parent().attr('disabled','disabled'); $('#BLACK_PORTS_UDP',section_networks).parent().hide(); - $('#WHITE_PORTS_UDP',section_networks).parent().removeAttr("disabled"); + $('#WHITE_PORTS_UDP',section_networks).parent().removeAttr('disabled'); $('#WHITE_PORTS_UDP',section_networks).parent().show(); break; case "blacklist": - $('#WHITE_PORTS_UDP',section_networks).parent().attr("disabled","disabled"); + $('#WHITE_PORTS_UDP',section_networks).parent().attr('disabled','disabled'); $('#WHITE_PORTS_UDP',section_networks).parent().hide(); - $('#BLACK_PORTS_UDP',section_networks).parent().removeAttr("disabled"); + $('#BLACK_PORTS_UDP',section_networks).parent().removeAttr('disabled'); $('#BLACK_PORTS_UDP',section_networks).parent().show(); break; default: - $('#WHITE_PORTS_UDP',section_networks).parent().attr("disabled","disabled"); + $('#WHITE_PORTS_UDP',section_networks).parent().attr('disabled','disabled'); $('#WHITE_PORTS_UDP',section_networks).parent().hide(); - $('#BLACK_PORTS_UDP',section_networks).parent().attr("disabled","disabled"); + $('#BLACK_PORTS_UDP',section_networks).parent().attr('disabled','disabled'); $('#BLACK_PORTS_UDP',section_networks).parent().hide(); }; }); @@ -1672,18 +1674,18 @@ function setupCreateTemplateDialog(){ $('#PORT',section_graphics).parent().show(); $('#PASSWD',section_graphics).parent().show(); $('#KEYMAP',section_graphics).parent().show(); - $('#PORT',section_graphics).parent().removeAttr("disabled"); - $('#PASSWD',section_graphics).parent().removeAttr("disabled"); - $('#KEYMAP',section_graphics).parent().removeAttr("disabled"); + $('#PORT',section_graphics).parent().removeAttr('disabled'); + $('#PASSWD',section_graphics).parent().removeAttr('disabled'); + $('#KEYMAP',section_graphics).parent().removeAttr('disabled'); break; case "sdl": $('#LISTEN',section_graphics).parent().show(); $('#PORT',section_graphics).parent().hide(); $('#PASSWD',section_graphics).parent().hide(); $('#KEYMAP',section_graphics).parent().hide(); - $('#PORT',section_graphics).parent().attr("disabled","disabled"); - $('#PASSWD',section_graphics).parent().attr("disabled","disabled"); - $('#KEYMAP',section_graphics).parent().attr("disabled","disabled"); + $('#PORT',section_graphics).parent().attr('disabled','disabled'); + $('#PASSWD',section_graphics).parent().attr('disabled','disabled'); + $('#KEYMAP',section_graphics).parent().attr('disabled','disabled'); break; default: $('#LISTEN',section_graphics).parent().hide(); @@ -1708,7 +1710,7 @@ function setupCreateTemplateDialog(){ var name = $('#var_name',section_context).val(); var value = $('#var_value',section_context).val(); if (!name.length || !value.length) { - notifyError("Context variable name and value must be filled in"); + notifyError(tr("Context variable name and value must be filled in")); return false; } option= '