diff --git a/install.sh b/install.sh index 52d719274f..542f02ca1f 100755 --- a/install.sh +++ b/install.sh @@ -1908,7 +1908,7 @@ do_file() { if [ "$LINK" = "yes" ]; then ln -s $SRC_DIR/$1 $DESTDIR$2 else - cp -R $SRC_DIR/$1 $DESTDIR$2 + cp -RL $SRC_DIR/$1 $DESTDIR$2 fi fi } diff --git a/src/im_mad/remotes/az.d/poll b/src/im_mad/remotes/az.d/poll index 0aca1b10bf..50692211cc 100755 --- a/src/im_mad/remotes/az.d/poll +++ b/src/im_mad/remotes/az.d/poll @@ -16,7 +16,15 @@ # limitations under the License. # # -------------------------------------------------------------------------- # -$: << File.join(File.dirname(__FILE__), '../../vmm/az') +ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION) + +if !ONE_LOCATION + RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION) +else + RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION) +end + +$: << RUBY_LIB_LOCATION require 'az_driver' diff --git a/src/im_mad/remotes/ec2.d/poll b/src/im_mad/remotes/ec2.d/poll index d49c0cb2da..8e7e0abd19 100755 --- a/src/im_mad/remotes/ec2.d/poll +++ b/src/im_mad/remotes/ec2.d/poll @@ -16,7 +16,15 @@ # limitations under the License. # # -------------------------------------------------------------------------- # -$: << File.join(File.dirname(__FILE__), '../../vmm/ec2') +ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION) + +if !ONE_LOCATION + RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION) +else + RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION) +end + +$: << RUBY_LIB_LOCATION require 'ec2_driver' diff --git a/src/im_mad/remotes/sl.d/poll b/src/im_mad/remotes/sl.d/poll index 74c2a68c05..40c28ab74e 100755 --- a/src/im_mad/remotes/sl.d/poll +++ b/src/im_mad/remotes/sl.d/poll @@ -16,7 +16,15 @@ # limitations under the License. # # -------------------------------------------------------------------------- # -$: << File.join(File.dirname(__FILE__), '../../vmm/sl') +ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION) + +if !ONE_LOCATION + RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION) +else + RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION) +end + +$: << RUBY_LIB_LOCATION require 'sl_driver' diff --git a/src/sunstone/models/OpenNebulaJSON/TemplateJSON.rb b/src/sunstone/models/OpenNebulaJSON/TemplateJSON.rb index 1ca880f37e..80680e3837 100644 --- a/src/sunstone/models/OpenNebulaJSON/TemplateJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/TemplateJSON.rb @@ -50,6 +50,10 @@ module OpenNebulaJSON when "instantiate" then self.instantiate(action_hash['params']) when "clone" then self.clone(action_hash['params']) when "rename" then self.rename(action_hash['params']) + when "delete_from_provision" + then self.delete_from_provision(action_hash['params']) + when "chmod_from_provision" + then self.chmod_from_provision(action_hash['params']) else error_msg = "#{action_hash['perform']} action not " << " available for this resource" @@ -115,5 +119,37 @@ module OpenNebulaJSON def rename(params=Hash.new) super(params['name']) end + + def delete_from_provision(params=Hash.new) + # Delete associated images + self.each("TEMPLATE/DISK/IMAGE_ID"){|image_id| + img = OpenNebula::Image.new_with_id(image_id.text, @client) + rc = img.delete + if OpenNebula::is_error?(rc) + error_msg = "Some of the resources associated with " << + "this template couldn't be deleted. Error: " << rc.message + return OpenNebula::Error.new(error_msg) + end + } + + # Delete template + self.delete + end + + def chmod_from_provision(params=Hash.new) + # Chmod associated images + self.each("TEMPLATE/DISK/IMAGE_ID"){|image_id| + img = OpenNebulaJSON::ImageJSON.new_with_id(image_id.text, @client) + rc = img.chmod_json(params) + if OpenNebula::is_error?(rc) + error_msg = "Some of the resources associated with " << + "this template couldn't be published. Error: " << rc.message + return OpenNebula::Error.new(error_msg) + end + } + + # Chmod template + self.chmod_json(params) + end end end diff --git a/src/sunstone/public/README.md b/src/sunstone/public/README.md index b72a700582..d626a41fee 100644 --- a/src/sunstone/public/README.md +++ b/src/sunstone/public/README.md @@ -1,30 +1,41 @@ -Sunstone depnedencies +Sunstone dependencies ===================== 1. Install nodejs and npm 2. Install the following npm packages: - `sudo npm install -g bower` - `sudo npm install -g grunt` - `sudo npm install -g grunt-cli` + + ``` + sudo npm install -g bower + sudo npm install -g grunt + sudo npm install -g grunt-cli + ``` + 3. Move to the Sunstone public folder and run: - `npm install` - `bower install` + + ``` + npm install + bower install + ``` Building minified JS and CSS files ================================== 4. Run the following command to generate the app.css file in the css folder: - `grunt sass` + ``` + grunt sass + ``` 5. Run the following command to generate the minified js files in the dist foler and the app.min.css in the css folder: - `grunt requirejs` + ``` + grunt requirejs + ``` These are the files generate by the grunt requirejs command: ``` css app.min.css dist - login.js, login.js.map main.js main.js.map + login.js, login.js.map main.js main.js.map console spice.js spice.js.map vnc.js vnc.js.map ``` @@ -33,9 +44,11 @@ Scons ===== Scons includes an option to build the minified JS and CSS files. Steps 1, 2 and 3 have to be performed before running this command - `scons sunstone=yes` + ``` + scons sunstone=yes + ``` Install.sh ========== -By default the install.sh script will install all the files, including the non-minified ones. Providing the -p option, only the minified files will be installed. \ No newline at end of file +By default the install.sh script will install all the files, including the non-minified ones. Providing the -p option, only the minified files will be installed. diff --git a/src/sunstone/public/app/opennebula/template.js b/src/sunstone/public/app/opennebula/template.js index b202e0d114..d2a8fb091a 100644 --- a/src/sunstone/public/app/opennebula/template.js +++ b/src/sunstone/public/app/opennebula/template.js @@ -11,6 +11,9 @@ define(function(require) { "del" : function(params) { OpenNebulaAction.del(params, RESOURCE); }, + "delete_from_provision": function(params) { + OpenNebulaAction.simple_action(params, RESOURCE, "delete_from_provision"); + }, "list" : function(params) { OpenNebulaAction.list(params, RESOURCE); }, @@ -27,6 +30,10 @@ define(function(require) { var action_obj = params.data.extra_param; OpenNebulaAction.simple_action(params, RESOURCE, "chmod", action_obj); }, + "chmod_from_provision": function(params) { + var action_obj = params.data.extra_param; + OpenNebulaAction.simple_action(params, RESOURCE, "chmod_from_provision", action_obj); + }, "update" : function(params) { var action_obj = params.data.extra_param; OpenNebulaAction.simple_action(params, RESOURCE, "update", action_obj); diff --git a/src/sunstone/public/app/tabs/provision-tab/templates/list.js b/src/sunstone/public/app/tabs/provision-tab/templates/list.js index d053b50591..8e922156df 100644 --- a/src/sunstone/public/app/tabs/provision-tab/templates/list.js +++ b/src/sunstone/public/app/tabs/provision-tab/templates/list.js @@ -222,7 +222,6 @@ define(function(require) { context.on("click", ".provision_confirm_delete_template_button", function(){ var ul_context = $(this).parents(".provision-pricing-table"); var template_id = ul_context.attr("opennebula_id"); - var image_id = ul_context.attr("saved_to_image_id"); var template_name = $(".provision-title", ul_context).text(); $(".provision_confirm_delete_template_div", context).html( @@ -236,7 +235,7 @@ define(function(require) { ''+ ''+ '
'+ - ''+Locale.tr("Delete")+''+ + ''+Locale.tr("Delete")+''+ '
'+ ''+ '×'+ @@ -244,55 +243,25 @@ define(function(require) { }); context.on("click", ".provision_delete_template_button", function(){ - /* TODO SAVED_TO_IMAGE_ID does not exists anymore and now all the images of the template - are cloned instead of only the main disk, therefore all the images should be deleted now. - Probably this could be done in the core var button = $(this); button.attr("disabled", "disabled"); var template_id = $(this).attr("template_id"); - var image_id = $(this).attr("image_id"); - OpenNebula.Image.del({ + OpenNebula.Template.delete_from_provision({ timeout: true, data : { - id : image_id + id : template_id }, success: function (){ - OpenNebula.Template.del({ - timeout: true, - data : { - id : template_id - }, - success: function (){ - $(".provision_templates_list_refresh_button", context).trigger("click"); - }, - error: function (request,error_json, container) { - Notifier.onError(request, error_json, container); - } - }) + $(".provision_templates_list_refresh_button", context).trigger("click"); }, error: function (request,error_json, container) { - if (error_json.error.http_status=="404") { - OpenNebula.Template.del({ - timeout: true, - data : { - id : template_id - }, - success: function (){ - $(".provision_templates_list_refresh_button", context).trigger("click"); - }, - error: function (request,error_json, container) { - Notifier.onError(request, error_json, container); - $(".provision_templates_list_refresh_button", context).trigger("click"); - } - }) - } else { - Notifier.onError(request, error_json, container); - } + Notifier.onError(request, error_json, container); + $(".provision_templates_list_refresh_button", context).trigger("click"); } - })*/ + }) }); } @@ -301,7 +270,6 @@ define(function(require) { context.on("click", ".provision_confirm_chmod_template_button", function(){ var ul_context = $(this).parents(".provision-pricing-table"); var template_id = ul_context.attr("opennebula_id"); - var image_id = ul_context.attr("saved_to_image_id"); var template_name = $(".provision-title", ul_context).text(); $(".provision_confirm_delete_template_div", context).html( @@ -315,7 +283,7 @@ define(function(require) { ''+ ''+ '
'+ - ''+Locale.tr("Share template")+''+ + ''+Locale.tr("Share template")+''+ '
'+ ''+ '×'+ @@ -323,16 +291,13 @@ define(function(require) { }); context.on("click", ".provision_chmod_template_button", function(){ - /* TODO SAVED_TO_IMAGE_ID does not exists anymore and now all the images of the template - are cloned instead of only the main disk, therefore all the images should be chmod now. - Probably this could be done in the core + var button = $(this); button.attr("disabled", "disabled"); var template_id = $(this).attr("template_id"); - var image_id = $(this).attr("image_id"); - OpenNebula.Template.chmod({ + OpenNebula.Template.chmod_from_provision({ timeout: true, data : { id : template_id, @@ -340,26 +305,14 @@ define(function(require) { }, success: function (){ $(".provision_templates_list_refresh_button", context).trigger("click"); - - OpenNebula.Image.chmod({ - timeout: true, - data : { - id : image_id, - extra_param: {'group_u': 1} - }, - success: function (){ - }, - error: Notifier.onError - }) }, error: Notifier.onError - })*/ + }) }); context.on("click", ".provision_confirm_unshare_template_button", function(){ var ul_context = $(this).parents(".provision-pricing-table"); var template_id = ul_context.attr("opennebula_id"); - var image_id = ul_context.attr("saved_to_image_id"); var template_name = $(".provision-title", ul_context).first().text(); $(".provision_confirm_delete_template_div", context).html( @@ -373,7 +326,7 @@ define(function(require) { ''+ ''+ '
'+ - ''+Locale.tr("Unshare template")+''+ + ''+Locale.tr("Unshare template")+''+ '
'+ ''+ '×'+ @@ -385,9 +338,8 @@ define(function(require) { button.attr("disabled", "disabled"); var template_id = $(this).attr("template_id"); - var image_id = $(this).attr("image_id"); - OpenNebula.Template.chmod({ + OpenNebula.Template.chmod_from_provision({ timeout: true, data : { id : template_id, @@ -395,17 +347,6 @@ define(function(require) { }, success: function (){ $(".provision_templates_list_refresh_button", context).trigger("click"); - - OpenNebula.Image.chmod({ - timeout: true, - data : { - id : image_id, - extra_param: {'group_u': 0} - }, - success: function (){ - }, - error: Notifier.onError - }) }, error: Notifier.onError }) diff --git a/src/sunstone/public/app/tabs/provision-tab/vms/list.js b/src/sunstone/public/app/tabs/provision-tab/vms/list.js index 7bbeb2e8de..bad82d25b6 100644 --- a/src/sunstone/public/app/tabs/provision-tab/vms/list.js +++ b/src/sunstone/public/app/tabs/provision-tab/vms/list.js @@ -448,7 +448,7 @@ define(function(require) { ''+ Locale.tr("This Virtual Machine will be saved in a new Template. Only the main disk will be preserved!")+ '
'+ - Locale.tr("You can then create a new Virtual Machine using this Template")+ + Locale.tr("You can then create a new Virtual Machine using this Template.")+ '
'+ ''+ ''+ @@ -483,6 +483,7 @@ define(function(require) { name : template_name } }, + timeout: false, success: function(request, response){ OpenNebula.Action.clear_cache("VMTEMPLATE"); Notifier.notifyMessage(Locale.tr("VM Template") + ' ' + request.request.data[0][1].name + ' ' + Locale.tr("saved successfully")) @@ -490,7 +491,13 @@ define(function(require) { button.removeAttr("disabled"); }, error: function(request, response){ - Notifier.onError(request, response); + if(response.error.http_status == 0){ // Failed due to cloning template taking too long + OpenNebula.Action.clear_cache("VMTEMPLATE"); + update_provision_vm_info(vm_id, context); + Notifier.notifyMessage(Locale.tr("VM cloning in the background. The Template will appear as soon as it is ready, and the VM unlocked.")); + } else { + Notifier.onError(request, response); + } button.removeAttr("disabled"); } }) diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/capacity-inputs.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/capacity-inputs.js index 2a9b2ce7ee..7fe30a0633 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/capacity-inputs.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/capacity-inputs.js @@ -38,11 +38,17 @@ define(function(require) { //cpu_slider.attr('data-options', 'start: 0; end: 1600; step: 50;'); cpu_slider.on('change.fndtn.slider', function(){ - cpu_input.val($(this).attr('data-slider') / 100); + if ($(this).attr('data-slider') >= 0) { + cpu_input.val($(this).attr('data-slider') / 100); + } }); cpu_input.on('change', function() { - cpu_slider.foundation('slider', 'set_value', this.value * 100); + if (this.value && this.value >= 0) { + cpu_slider.foundation('slider', 'set_value', this.value * 100); + } else { + cpu_slider.foundation('slider', 'set_value', -1); + } }); cpu_slider.foundation('slider', 'set_value', 100); @@ -64,18 +70,30 @@ define(function(require) { } memory_input.on('change', function() { - $("#memory_slider", context).foundation('slider', 'set_value', this.value * 100); - update_final_memory_input(); + if (this.value && this.value >= 0) { + $("#memory_slider", context).foundation('slider', 'set_value', this.value * 100); + update_final_memory_input(); + } else { + $("#memory_slider", context).foundation('slider', 'set_value', -1); + final_memory_input.val(""); + } }); final_memory_input.on('change', function() { - $("#memory_slider", context).foundation('slider', 'set_value', this.value * 100); - memory_input.val(Math.floor(this.value)); + if (this.value && this.value >= 0) { + $("#memory_slider", context).foundation('slider', 'set_value', this.value * 100); + memory_input.val(Math.floor(this.value)); + } else { + $("#memory_slider", context).foundation('slider', 'set_value', -1); + memory_input.val(""); + } }); $("#memory_slider", context).on('change.fndtn.slider', function() { - memory_input.val($(this).attr('data-slider') / 100); - update_final_memory_input(); + if ($(this).attr('data-slider') >= 0) { + memory_input.val($(this).attr('data-slider') / 100); + update_final_memory_input(); + } }); memory_unit.on('change', function() { @@ -110,8 +128,10 @@ define(function(require) { memory_input.val(new_val); $("#memory_slider", context).foundation('slider', 'set_value', new_val * 100); $("#memory_slider", context).on('change.fndtn.slider', function() { - memory_input.val($(this).attr('data-slider') / 100); - update_final_memory_input(); + if ($(this).attr('data-slider') >= 0) { + memory_input.val($(this).attr('data-slider') / 100); + update_final_memory_input(); + } }); update_final_memory_input(); @@ -127,13 +147,18 @@ define(function(require) { var vcpu_slider = $("#vcpu_slider", context) //vcpu_slider.attr('data-options', 'start: 0; end: 1600; step: 50;'); - vcpu_slider.on('change.fndtn.slider', function(){ - vcpu_input.val($(this).attr('data-slider') / 100); + if ($(this).attr('data-slider') > 0) { + vcpu_input.val($(this).attr('data-slider') / 100); + } }); vcpu_input.on('change', function() { - vcpu_slider.foundation('slider', 'set_value', this.value * 100); + if (this.value && this.value > 0) { + vcpu_slider.foundation('slider', 'set_value', this.value * 100); + } else { + vcpu_slider.foundation('slider', 'set_value', -1); + } }); vcpu_slider.foundation('slider', 'set_value', 0); diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/capacity-inputs/html.hbs b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/capacity-inputs/html.hbs index b154f190d3..c5f77d9122 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/capacity-inputs/html.hbs +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/capacity-inputs/html.hbs @@ -52,7 +52,7 @@ {{{tip (tr "Number of virtual cpus. This value is optional, the default hypervisor behavior is used, usually one virtual CPU.")}}}
-
+
diff --git a/src/sunstone/public/app/tabs/vms-tab/dialogs/attach-disk.js b/src/sunstone/public/app/tabs/vms-tab/dialogs/attach-disk.js index 384c6ad8b0..36b7b8d2b9 100644 --- a/src/sunstone/public/app/tabs/vms-tab/dialogs/attach-disk.js +++ b/src/sunstone/public/app/tabs/vms-tab/dialogs/attach-disk.js @@ -53,7 +53,7 @@ define(function(require) { function _setup(context) { var that = this; - that.diskTab.setup(); + that.diskTab.setup(context); Tips.setup(context); diff --git a/src/sunstone/public/app/tabs/vms-tab/dialogs/attach-nic.js b/src/sunstone/public/app/tabs/vms-tab/dialogs/attach-nic.js index 9a31159cb2..16f4c71417 100644 --- a/src/sunstone/public/app/tabs/vms-tab/dialogs/attach-nic.js +++ b/src/sunstone/public/app/tabs/vms-tab/dialogs/attach-nic.js @@ -53,7 +53,7 @@ define(function(require) { function _setup(context) { var that = this; - that.nicTab.setup(); + that.nicTab.setup(context); Tips.setup(context); diff --git a/src/vmm_mad/exec/one_vmm_exec.rb b/src/vmm_mad/exec/one_vmm_exec.rb index 02aeddf73f..9a0a2d602b 100755 --- a/src/vmm_mad/exec/one_vmm_exec.rb +++ b/src/vmm_mad/exec/one_vmm_exec.rb @@ -900,7 +900,7 @@ class ExecDriver < VirtualMachineDriver target_index = target.downcase[-1..-1].unpack('c').first - 97 if @options[:detach_snap] - disk = xml_data.elements[target_xpath] + disk = xml_data.elements[target_xpath].parent attach = REXML::Element.new('ATTACH') attach.add_text('YES') @@ -973,7 +973,7 @@ class ExecDriver < VirtualMachineDriver target_index = target.downcase[-1..-1].unpack('c').first - 97 if @options[:detach_snap] - disk = xml_data.elements[target_xpath] + disk = xml_data.elements[target_xpath].parent attach = REXML::Element.new('ATTACH') attach.add_text('YES')