From dcfa0a1773ffbd4a9a3ae6b3aefaf74098e1cb1c Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 23 Feb 2013 19:49:06 +0100 Subject: [PATCH 01/10] feature #1772:Resize VM capacity (cpu, memory and vcpu) offline --- include/Host.h | 13 + include/HostShare.h | 13 + include/PoolObjectSQL.h | 10 + include/Quota.h | 15 +- include/QuotaVirtualMachine.h | 10 + include/Quotas.h | 16 +- include/RequestManagerVirtualMachine.h | 15 ++ include/Template.h | 22 +- include/VirtualMachine.h | 10 +- src/cli/one_helper.rb | 3 + src/cli/onevm | 19 ++ src/oca/ruby/opennebula/virtual_machine.rb | 14 +- src/rm/RequestManager.cc | 2 + src/rm/RequestManagerVirtualMachine.cc | 293 +++++++++++++++++++++ src/um/QuotaVirtualMachine.cc | 22 ++ src/um/Quotas.cc | 37 ++- src/vm/VirtualMachine.cc | 31 ++- 17 files changed, 523 insertions(+), 22 deletions(-) diff --git a/include/Host.h b/include/Host.h index 03d082aad5..38605c5c86 100644 --- a/include/Host.h +++ b/include/Host.h @@ -317,6 +317,19 @@ public: } }; + /** + * Updates the capacity used in a host when a VM is resized + * counters + * @param cpu increment of cpu requested by the VM + * @param mem increment of memory requested by the VM + * @param disk not used + * @return 0 on success + */ + void update_capacity(int cpu, int mem, int disk) + { + host_share.update(cpu,mem,disk); + }; + /** * Tests whether a new VM can be hosted by the host or not * @param cpu needed by the VM (percentage) diff --git a/include/HostShare.h b/include/HostShare.h index c7321a3662..66c5acf536 100644 --- a/include/HostShare.h +++ b/include/HostShare.h @@ -54,6 +54,19 @@ public: running_vms++; } + /** + * Updates the capacity of VM in this share + * @param cpu increment + * @param mem increment + * @param disk increment + */ + void update(int cpu, int mem, int disk) + { + cpu_usage += cpu; + mem_usage += mem; + disk_usage += disk; + } + /** * Delete a VM from this share * @param cpu requested by the VM diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h index 812a587157..beec7d8651 100644 --- a/include/PoolObjectSQL.h +++ b/include/PoolObjectSQL.h @@ -427,6 +427,16 @@ public: obj_template->add(name, value); } + /** + * Adds a float attribute + * @param att_name Name for the attribute + * @param att_val integer + */ + void add_template_attribute(const string& name, float value) + { + obj_template->add(name, value); + } + /** * Factory method for templates, it should be implemented * by classes that uses templates diff --git a/include/Quota.h b/include/Quota.h index 01eb24b885..ad99b047b8 100644 --- a/include/Quota.h +++ b/include/Quota.h @@ -51,13 +51,26 @@ public: */ virtual bool check(Template* tmpl, Quotas& default_quotas, string& error) = 0; + /** + * Check if a resource update in usage counters will exceed the + * quota limits. If not the usage counters are updated for that resource + * @param tmpl with increments in MEMORY and CPU + * @param default_quotas Quotas that contain the default limits + * @param error string + * @return true if the operation can be performed + */ + virtual bool update(Template * tmpl, Quotas& default_quotas, string& error) + { + error = "Update operation for quotas not supported."; + return false; + }; + /** * Decrement usage counters when deallocating image * @param tmpl template for the resource */ virtual void del(Template* tmpl) = 0; - /** * Returns the name that identifies the quota in a template */ diff --git a/include/QuotaVirtualMachine.h b/include/QuotaVirtualMachine.h index 622ea5c439..e46c47c0c3 100644 --- a/include/QuotaVirtualMachine.h +++ b/include/QuotaVirtualMachine.h @@ -57,6 +57,16 @@ public: */ bool check(Template* tmpl, Quotas& default_quotas, string& error); + /** + * Check if the resource update (change in MEMORY or CPU) will exceed the + * quota limits. If not the usage counters are updated + * @param tmpl with increments in MEMORY and CPU + * @param default_quotas Quotas that contain the default limits + * @param error string + * @return true if the operation can be performed + */ + bool update(Template * tmpl, Quotas& default_quotas, string& error); + /** * Decrement usage counters when deallocating image * @param tmpl template for the resource diff --git a/include/Quotas.h b/include/Quotas.h index f42761ab06..02a30e36d7 100644 --- a/include/Quotas.h +++ b/include/Quotas.h @@ -141,13 +141,27 @@ public: * @param tmpl template for the VirtualMachine * @param default_quotas Quotas that contain the default limits * @param error_str string describing the error - * @return true if VM can be allocated, false otherwise + * @return true if resource can be allocated, false otherwise */ bool quota_check(QuotaType type, Template *tmpl, Quotas& default_quotas, string& error_str); + /** + * Update usage of an existing quota (e.g. size of an image), it updates + * the usage counters if quotas are not exceeded. + * @param type the quota to work with + * @param tmpl template for the VirtualMachine + * @param default_quotas Quotas that contain the default limits + * @param error_str string describing the error + * @return true if resource can be updated, false otherwise + */ + bool quota_update(QuotaType type, + Template *tmpl, + Quotas& default_quotas, + string& error_str); + /** * Delete usage from the given quota counters. * @param type the quota to work with diff --git a/include/RequestManagerVirtualMachine.h b/include/RequestManagerVirtualMachine.h index 0393c22b99..b4bf5a9852 100644 --- a/include/RequestManagerVirtualMachine.h +++ b/include/RequestManagerVirtualMachine.h @@ -217,6 +217,21 @@ public: RequestAttributes& att); }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VirtualMachineResize : public RequestManagerVirtualMachine +{ +public: + VirtualMachineResize(): + RequestManagerVirtualMachine("VirtualMachineResize", + "Changes the capacity of the virtual machine", + "A:sidiib"){}; + ~VirtualMachineResize(){}; + + void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att); +}; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/Template.h b/include/Template.h index 400c60e5bd..21e3aed633 100644 --- a/include/Template.h +++ b/include/Template.h @@ -156,10 +156,10 @@ public: oss << value; - return replace(name, oss.str()); + return replace(name, oss.str()); } - /* + /* * Adds a new single attribute to the template. It will replace an existing * one if replace_mode was set to true * @param name of the attribute @@ -184,6 +184,20 @@ public: set(new SingleAttribute(name, oss.str())); } + /** + * Adds a new single attribute to the template. + * @param name of the attribute + * @param value of the attribute + */ + void add(const string& name, float value) + { + ostringstream oss; + + oss << value; + + set(new SingleAttribute(name, oss.str())); + } + /** * Removes an attribute from the template. The attributes are returned. The * attributes MUST be freed by the calling funtion @@ -196,10 +210,10 @@ public: vector& values); /** - * Removes an attribute from the template, but it DOES NOT free the + * Removes an attribute from the template, but it DOES NOT free the * attribute. * @param att Attribute to remove. It will be deleted - * @return pointer to the removed attribute or 0 if non attribute was + * @return pointer to the removed attribute or 0 if non attribute was * removed */ virtual Attribute * remove(Attribute * att); diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index ec52350bed..15b039688c 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -747,7 +747,7 @@ public: }; // ------------------------------------------------------------------------ - // Timers + // Timers & // ------------------------------------------------------------------------ /** * Gets time from last information polling. @@ -766,6 +766,14 @@ public: */ void get_requirements (int& cpu, int& memory, int& disk); + /** + * Resize the VM capacity + * @param cpu + * @param memory + * @param vcpu + */ + void resize (float cpu, int memory, int vcpu); + // ------------------------------------------------------------------------ // Network Leases & Disk Images // ------------------------------------------------------------------------ diff --git a/src/cli/one_helper.rb b/src/cli/one_helper.rb index f812bc0de6..d0dcbf83cb 100644 --- a/src/cli/one_helper.rb +++ b/src/cli/one_helper.rb @@ -103,6 +103,7 @@ EOT } ] + #NOTE: Other options defined using this array, add new options at the end TEMPLATE_OPTIONS=[ { :name => 'cpu', @@ -212,6 +213,8 @@ EOT TEMPLATE_OPTIONS_VM=[TEMPLATE_NAME_VM]+TEMPLATE_OPTIONS+[DRY] + CAPACITY_OPTIONS_VM=[TEMPLATE_OPTIONS[0],TEMPLATE_OPTIONS[1],TEMPLATE_OPTIONS[3]] + OPTIONS = XML, NUMERIC, KILOBYTES class OneHelper diff --git a/src/cli/onevm b/src/cli/onevm index f4e4a7cee2..5c46178a7d 100755 --- a/src/cli/onevm +++ b/src/cli/onevm @@ -662,4 +662,23 @@ cmd=CommandParser::CmdParser.new(ARGV) do :options=>CLIHelper::OPTIONS+OpenNebulaHelper::OPTIONS do helper.list_pool(options, true, args[0]) end + + resize_desc = <<-EOT.unindent + Resizes the capacity of a Virtual Machine (offline, the VM cannot be + RUNNING) + + EOT + + command :resize, resize_desc, :vmid, :options => + OpenNebulaHelper::CAPACITY_OPTIONS_VM + [ENFORCE]do + + cpu = options[:cpu] || 0 + memory = options[:memory] || 0 + vcpu = options[:vcpu] || 0 + enforce = options[:enforce] || true + + helper.perform_action(args[0], options, "Resizing VM") do |vm| + vm.resize(cpu, memory, vcpu, enforce) + end + end end diff --git a/src/oca/ruby/opennebula/virtual_machine.rb b/src/oca/ruby/opennebula/virtual_machine.rb index ebf5be492b..f1d7a7866e 100644 --- a/src/oca/ruby/opennebula/virtual_machine.rb +++ b/src/oca/ruby/opennebula/virtual_machine.rb @@ -37,7 +37,8 @@ module OpenNebula :attach => "vm.attach", :detach => "vm.detach", :rename => "vm.rename", - :update => "vm.update" + :update => "vm.update", + :resize => "vm.resize" } VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED @@ -336,6 +337,17 @@ module OpenNebula return rc end + # Resize the VM + # @param cpu [Float] the new CPU value + # @param memory [Integer] the new MEMORY value + # @param vcpu [Integer] the new VCPU value + # @param enforce [true|false] If it is set to true, the host capacity + # will be checked + def resize(cpu, memory, vcpu, enforce) + return @client.call(VM_METHODS[:resize], @pe_id, cpu, memory, + vcpu, enforce) + end + # Changes the owner/group # uid:: _Integer_ the new owner id. Set to -1 to leave the current one # gid:: _Integer_ the new group id. Set to -1 to leave the current one diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index d698e67197..4dad32ab5f 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -254,6 +254,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr vm_monitoring(new VirtualMachineMonitoring()); xmlrpc_c::methodPtr vm_attach(new VirtualMachineAttach()); xmlrpc_c::methodPtr vm_detach(new VirtualMachineDetach()); + xmlrpc_c::methodPtr vm_resize(new VirtualMachineResize()); xmlrpc_c::methodPtr vm_pool_acct(new VirtualMachinePoolAccounting()); xmlrpc_c::methodPtr vm_pool_monitoring(new VirtualMachinePoolMonitoring()); @@ -396,6 +397,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.vm.attach", vm_attach); RequestManagerRegistry.addMethod("one.vm.detach", vm_detach); RequestManagerRegistry.addMethod("one.vm.rename", vm_rename); + RequestManagerRegistry.addMethod("one.vm.resize", vm_resize); RequestManagerRegistry.addMethod("one.vm.update", vm_update); RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info); diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index b8baaff07f..b4666206cd 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -17,6 +17,7 @@ #include "RequestManagerVirtualMachine.h" #include "PoolObjectAuth.h" #include "Nebula.h" +#include "Quotas.h" /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -1056,3 +1057,295 @@ void VirtualMachineDetach::request_execute(xmlrpc_c::paramList const& paramList, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ + +void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + int id = xmlrpc_c::value_int(paramList.getInt(1)); + float ncpu = xmlrpc_c::value_int(paramList.getDouble(2)); + int nmemory = xmlrpc_c::value_int(paramList.getInt(3)); + int nvcpu = xmlrpc_c::value_int(paramList.getInt(4)); + bool enforce = xmlrpc_c::value_boolean(paramList.getBoolean(5)); + + float ocpu, dcpu; + int omemory, dmemory; + + Nebula& nd = Nebula::instance(); + UserPool* upool = nd.get_upool(); + GroupPool* gpool = nd.get_gpool(); + Quotas dquotas = nd.get_default_user_quota(); + HostPool * hpool = nd.get_hpool(); + + Host * host; + + Template deltas; + string error_str; + bool rc; + int hid = -1; + + PoolObjectAuth vm_perms; + + VirtualMachinePool * vmpool = static_cast(pool); + VirtualMachine * vm; + + vm = vmpool->get(id, true); + + if (vm == 0) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::VM),id), + att); + return; + } + + vm->get_permissions(vm_perms); + + vm->get_template_attribute("MEMORY", omemory); + vm->get_template_attribute("CPU", ocpu); + + dcpu = ncpu - ocpu; + dmemory = nmemory - omemory; + + deltas.add("MEMORY", dmemory); + deltas.add("CPU", dcpu); + + switch (vm->get_state()) + { + case VirtualMachine::POWEROFF: //Only check host capacity in POWEROFF + if (vm->hasHistory() == true) + { + hid = vm->get_hid(); + } + case VirtualMachine::INIT: + case VirtualMachine::PENDING: + case VirtualMachine::HOLD: + case VirtualMachine::FAILED: + break; + + case VirtualMachine::STOPPED: + case VirtualMachine::DONE: + case VirtualMachine::SUSPENDED: + case VirtualMachine::ACTIVE: + failure_response(ACTION, + request_error("Wrong state to perform action",""), + att); + + vm->unlock(); + return; + } + + vm->unlock(); + + /* ---------------------------------------------------------------------- */ + /* Authorize the operation */ + /* ---------------------------------------------------------------------- */ + + if ( att.uid != UserPool::ONEADMIN_ID ) + { + AuthRequest ar(att.uid, att.gid); + + ar.add_auth(AuthRequest::MANAGE, vm_perms); + + if (enforce == false) //Admin rights to overcommit + { + ar.add_auth(AuthRequest::ADMIN, vm_perms); + } + + if (UserPool::authorize(ar) == -1) + { + failure_response(AUTHORIZATION, + authorization_error(ar.message, att), + att); + + vm->unlock(); + return; + } + } + + /* ---------------------------------------------------------------------- */ + /* Check quotas */ + /* ---------------------------------------------------------------------- */ + + if (att.uid != UserPool::ONEADMIN_ID) + { + User * user = upool->get(att.uid, true); + + if ( user == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::USER),att.uid), + att); + return; + } + + rc = user->quota.quota_update(Quotas::VM, &deltas, dquotas, error_str); + + if (rc == false) + { + ostringstream oss; + + oss << object_name(PoolObjectSQL::USER) << " [" << att.uid << "] " + << error_str; + + failure_response(AUTHORIZATION, + request_error(oss.str(), ""), + att); + + user->unlock(); + + return; + } + + user->unlock(); + } + + if (att.gid != GroupPool::ONEADMIN_ID) + { + Group * group = gpool->get(att.gid, true); + + if ( group == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::GROUP),att.gid), + att); + return; + } + + rc = group->quota.quota_update(Quotas::VM, &deltas, dquotas, error_str); + + if (rc == false) + { + ostringstream oss; + RequestAttributes att_tmp(att.uid, -1, att); + + oss << object_name(PoolObjectSQL::GROUP) << " [" << att.gid << "] " + << error_str; + + failure_response(AUTHORIZATION, + request_error(oss.str(), ""), + att); + + group->unlock(); + + quota_rollback(&deltas, Quotas::VM, att_tmp); + + return; + } + + group->unlock(); + } + + /* ---------------------------------------------------------------------- */ + /* Check & update host capacity */ + /* ---------------------------------------------------------------------- */ + + if (hid != -1) + { + host = hpool->get(hid, true); + + if (host == 0) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::HOST),hid), + att); + + quota_rollback(&deltas, Quotas::VM, att); + + return ; + } + + if ( enforce && host->test_capacity(dcpu, dmemory, 0) == false ) + { + ostringstream oss; + + oss << object_name(PoolObjectSQL::HOST) + << " " << hid << " does not have enough capacity."; + + failure_response(ACTION, request_error(oss.str(),""), att); + + host->unlock(); + + quota_rollback(&deltas, Quotas::VM, att); + + return; + } + + host->update_capacity(dcpu, dmemory, 0); + + hpool->update(host); + + host->unlock(); + } + + /* ---------------------------------------------------------------------- */ + /* Resize the VM */ + /* ---------------------------------------------------------------------- */ + + vm = vmpool->get(id, true); + + if (vm == 0) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::VM),id), + att); + + quota_rollback(&deltas, Quotas::VM, att); + + if (hid != -1) + { + host = hpool->get(hid, true); + + if (host != 0) + { + host->update_capacity(-dcpu, -dmemory, 0); + hpool->update(host); + + host->unlock(); + } + } + return; + } + + //Check again state as the VM may transit to active (e.g. scheduled) + switch (vm->get_state()) + { + case VirtualMachine::INIT: + case VirtualMachine::PENDING: + case VirtualMachine::HOLD: + case VirtualMachine::FAILED: + case VirtualMachine::POWEROFF: + vm->resize(ncpu, nmemory, nvcpu); + vmpool->update(vm); + break; + + case VirtualMachine::STOPPED: + case VirtualMachine::DONE: + case VirtualMachine::SUSPENDED: + case VirtualMachine::ACTIVE: + failure_response(ACTION, + request_error("Wrong state to perform action",""), + att); + + vm->unlock(); + + quota_rollback(&deltas, Quotas::VM, att); + + if (hid != -1) + { + host = hpool->get(hid, true); + + if (host != 0) + { + host->update_capacity(ocpu - ncpu, omemory - nmemory, 0); + hpool->update(host); + + host->unlock(); + } + } + return; + } + + vm->unlock(); + + success_response(id, att); +} diff --git a/src/um/QuotaVirtualMachine.cc b/src/um/QuotaVirtualMachine.cc index cacd7afed0..1df620dba7 100644 --- a/src/um/QuotaVirtualMachine.cc +++ b/src/um/QuotaVirtualMachine.cc @@ -117,3 +117,25 @@ int QuotaVirtualMachine::get_default_quota( /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ + +bool QuotaVirtualMachine::update(Template * tmpl, + Quotas& default_quotas, + string& error) +{ + map vm_request; + + int delta_memory; + float delta_cpu; + + if ( tmpl->get("MEMORY", delta_memory) == true ) + { + vm_request.insert(make_pair("MEMORY", delta_memory)); + } + + if ( tmpl->get("CPU", delta_cpu) == true ) + { + vm_request.insert(make_pair("CPU", delta_cpu)); + } + + return check_quota("", vm_request, default_quotas, error); +} diff --git a/src/um/Quotas.cc b/src/um/Quotas.cc index 3918471294..90bb22dbb4 100644 --- a/src/um/Quotas.cc +++ b/src/um/Quotas.cc @@ -29,7 +29,7 @@ int Quotas::set(Template *tmpl, string& error) { return -1; } - + vquotas.clear(); } @@ -39,7 +39,7 @@ int Quotas::set(Template *tmpl, string& error) { return -1; } - + vquotas.clear(); } @@ -49,7 +49,7 @@ int Quotas::set(Template *tmpl, string& error) { return -1; } - + vquotas.clear(); } @@ -59,7 +59,7 @@ int Quotas::set(Template *tmpl, string& error) { return -1; } - + vquotas.clear(); } @@ -219,6 +219,31 @@ bool Quotas::quota_check(QuotaType type, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +bool Quotas::quota_update(QuotaType type, + Template *tmpl, + Quotas &default_quotas, + string &error_str) +{ + switch (type) + { + // This is an internal check, should never get in here. + case DATASTORE: + case NETWORK: + case IMAGE: + case VIRTUALMACHINE: + error_str = "Cannot update quota. Not implemented"; + return false; + + case VM: + return vm_quota.update(tmpl, default_quotas, error_str); + } + + return false; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void Quotas::quota_del(QuotaType type, int uid, int gid, Template * tmpl) { Nebula& nd = Nebula::instance(); @@ -239,7 +264,7 @@ void Quotas::quota_del(QuotaType type, int uid, int gid, Template * tmpl) upool->update(user); user->unlock(); - } + } } if ( gid != GroupPool::ONEADMIN_ID ) @@ -253,6 +278,6 @@ void Quotas::quota_del(QuotaType type, int uid, int gid, Template * tmpl) gpool->update(group); group->unlock(); - } + } } } diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index c60f67d023..15e004b9d4 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -1258,14 +1258,11 @@ void VirtualMachine::cp_previous_history() void VirtualMachine::get_requirements (int& cpu, int& memory, int& disk) { - string scpu; istringstream iss; float fcpu; - get_template_attribute("MEMORY",memory); - get_template_attribute("CPU",scpu); - - if ((memory == 0) || (scpu=="")) + if ((get_template_attribute("MEMORY",memory) == false) || + (get_template_attribute("CPU",fcpu) == false)) { cpu = 0; memory = 0; @@ -1274,9 +1271,6 @@ void VirtualMachine::get_requirements (int& cpu, int& memory, int& disk) return; } - iss.str(scpu); - iss >> fcpu; - cpu = (int) (fcpu * 100);//now in 100% memory = memory * 1024; //now in Kilobytes disk = 0; @@ -1287,6 +1281,27 @@ void VirtualMachine::get_requirements (int& cpu, int& memory, int& disk) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void VirtualMachine::resize(float cpu, int memory, int vcpu) +{ + ostringstream oss; + + oss << cpu; + replace_template_attribute("CPU", oss.str()); + oss.str(""); + + oss << memory; + replace_template_attribute("MEMORY", oss.str()); + oss.str(""); + + oss << vcpu; + replace_template_attribute("VCPU", oss.str()); + + return; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + static void assign_disk_targets(queue >& _queue, set& used_targets) { From 126af25bb7cf1f18b66103d1e1b42d0baa9c3116 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 23 Feb 2013 23:34:06 +0100 Subject: [PATCH 02/10] feature #1722: Fix float parameter get --- src/rm/RequestManagerVirtualMachine.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index b4666206cd..73f338b8a6 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -1062,7 +1062,7 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, RequestAttributes& att) { int id = xmlrpc_c::value_int(paramList.getInt(1)); - float ncpu = xmlrpc_c::value_int(paramList.getDouble(2)); + float ncpu = xmlrpc_c::value_double(paramList.getDouble(2)); int nmemory = xmlrpc_c::value_int(paramList.getInt(3)); int nvcpu = xmlrpc_c::value_int(paramList.getInt(4)); bool enforce = xmlrpc_c::value_boolean(paramList.getBoolean(5)); From 19e90ec530d284ff97af6136d4e648e57aba7dc9 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sun, 24 Feb 2013 00:57:55 +0100 Subject: [PATCH 03/10] feature #1722: Use the right units for host update. Fix enforce in onevm command --- include/Host.h | 2 +- src/cli/onevm | 4 ++-- src/rm/RequestManagerVirtualMachine.cc | 7 +++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/Host.h b/include/Host.h index 38605c5c86..31cc4477d2 100644 --- a/include/Host.h +++ b/include/Host.h @@ -339,7 +339,7 @@ public: */ bool test_capacity(int cpu, int mem, int disk) { - return host_share.test(cpu,mem,disk); + return host_share.test(cpu, mem, disk); } /** diff --git a/src/cli/onevm b/src/cli/onevm index 5c46178a7d..950358345d 100755 --- a/src/cli/onevm +++ b/src/cli/onevm @@ -670,12 +670,12 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :resize, resize_desc, :vmid, :options => - OpenNebulaHelper::CAPACITY_OPTIONS_VM + [ENFORCE]do + OpenNebulaHelper::CAPACITY_OPTIONS_VM + [ENFORCE] do cpu = options[:cpu] || 0 memory = options[:memory] || 0 vcpu = options[:vcpu] || 0 - enforce = options[:enforce] || true + enforce = options[:enforce] || false helper.perform_action(args[0], options, "Resizing VM") do |vm| vm.resize(cpu, memory, vcpu, enforce) diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 73f338b8a6..7f4ce72b2d 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -1241,6 +1241,9 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, if (hid != -1) { + int dcpu_host = (int) (dcpu * 100);//now in 100% + int dmem_host = dmemory * 1024; //now in Kilobytes + host = hpool->get(hid, true); if (host == 0) @@ -1254,7 +1257,7 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, return ; } - if ( enforce && host->test_capacity(dcpu, dmemory, 0) == false ) + if ( enforce && host->test_capacity(dcpu_host, dmem_host, 0) == false) { ostringstream oss; @@ -1270,7 +1273,7 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, return; } - host->update_capacity(dcpu, dmemory, 0); + host->update_capacity(dcpu_host, dmem_host, 0); hpool->update(host); From 96c00ab9e5e876c69a88aa0079b4bb3ccad1bc34 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sun, 24 Feb 2013 13:26:37 +0100 Subject: [PATCH 04/10] feature #1722: 0 means keep current size for any attribute --- src/cli/onevm | 2 +- src/rm/RequestManagerVirtualMachine.cc | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/cli/onevm b/src/cli/onevm index 950358345d..3577adf771 100755 --- a/src/cli/onevm +++ b/src/cli/onevm @@ -672,7 +672,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do command :resize, resize_desc, :vmid, :options => OpenNebulaHelper::CAPACITY_OPTIONS_VM + [ENFORCE] do - cpu = options[:cpu] || 0 + cpu = options[:cpu] || 0.0 memory = options[:memory] || 0 vcpu = options[:vcpu] || 0 enforce = options[:enforce] || false diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 7f4ce72b2d..f341f45ff7 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -1069,6 +1069,7 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, float ocpu, dcpu; int omemory, dmemory; + int ovcpu; Nebula& nd = Nebula::instance(); UserPool* upool = nd.get_upool(); @@ -1102,6 +1103,22 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, vm->get_template_attribute("MEMORY", omemory); vm->get_template_attribute("CPU", ocpu); + vm->get_template_attribute("VCPU", ovcpu); + + if (nmemory == 0) + { + nmemory = omemory; + } + + if (ncpu == 0) + { + ncpu = ocpu; + } + + if (nvcpu == 0) + { + nvcpu = ovcpu; + } dcpu = ncpu - ocpu; dmemory = nmemory - omemory; From 4be2e1e9a8fc5287804e22a62473e3dd002e1ed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 25 Feb 2013 12:57:39 +0100 Subject: [PATCH 05/10] Feature #1772: Minor edits --- src/oca/ruby/opennebula/virtual_machine.rb | 7 +++++-- src/rm/RequestManagerVirtualMachine.cc | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/oca/ruby/opennebula/virtual_machine.rb b/src/oca/ruby/opennebula/virtual_machine.rb index f1d7a7866e..489ac9a560 100644 --- a/src/oca/ruby/opennebula/virtual_machine.rb +++ b/src/oca/ruby/opennebula/virtual_machine.rb @@ -338,14 +338,17 @@ module OpenNebula end # Resize the VM + # # @param cpu [Float] the new CPU value # @param memory [Integer] the new MEMORY value # @param vcpu [Integer] the new VCPU value # @param enforce [true|false] If it is set to true, the host capacity # will be checked + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise def resize(cpu, memory, vcpu, enforce) - return @client.call(VM_METHODS[:resize], @pe_id, cpu, memory, - vcpu, enforce) + return call(VM_METHODS[:resize], @pe_id, cpu, memory, vcpu, enforce) end # Changes the owner/group diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index f341f45ff7..a559df57fd 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -1133,6 +1133,8 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, { hid = vm->get_hid(); } + break; + case VirtualMachine::INIT: case VirtualMachine::PENDING: case VirtualMachine::HOLD: From bf60dc734c33cbfbbd20c37d85a3138d91322deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 25 Feb 2013 15:13:14 +0100 Subject: [PATCH 06/10] Feature #1772: Fix bug in RM, update VM owner/group quotas, not the caller's quotas. Also take into account that we can delete users/groups and have orphan VMs --- src/rm/Request.cc | 2 +- src/rm/RequestManagerVirtualMachine.cc | 82 ++++++++++++-------------- 2 files changed, 38 insertions(+), 46 deletions(-) diff --git a/src/rm/Request.cc b/src/rm/Request.cc index cb423626e8..231705d4d7 100644 --- a/src/rm/Request.cc +++ b/src/rm/Request.cc @@ -470,7 +470,7 @@ void Request::quota_rollback(Template * tmpl, if ( att.gid != GroupPool::ONEADMIN_ID && att.gid != -1 ) { - group_quota_rollback(tmpl, qtype, att);; + group_quota_rollback(tmpl, qtype, att); } } diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index a559df57fd..27dc93d466 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -1185,73 +1185,65 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, /* Check quotas */ /* ---------------------------------------------------------------------- */ - if (att.uid != UserPool::ONEADMIN_ID) + if (vm_perms.uid != UserPool::ONEADMIN_ID) { - User * user = upool->get(att.uid, true); + User * user = upool->get(vm_perms.uid, true); - if ( user == 0 ) + if ( user != 0 ) { - failure_response(NO_EXISTS, - get_error(object_name(PoolObjectSQL::USER),att.uid), - att); - return; - } + rc = user->quota.quota_update(Quotas::VM, &deltas, dquotas, error_str); - rc = user->quota.quota_update(Quotas::VM, &deltas, dquotas, error_str); + if (rc == false) + { + ostringstream oss; - if (rc == false) - { - ostringstream oss; + oss << object_name(PoolObjectSQL::USER) + << " [" << vm_perms.uid << "] " + << error_str; - oss << object_name(PoolObjectSQL::USER) << " [" << att.uid << "] " - << error_str; + failure_response(AUTHORIZATION, + request_error(oss.str(), ""), + att); - failure_response(AUTHORIZATION, - request_error(oss.str(), ""), - att); + user->unlock(); + + return; + } user->unlock(); - - return; } - - user->unlock(); } - if (att.gid != GroupPool::ONEADMIN_ID) + if (vm_perms.gid != GroupPool::ONEADMIN_ID) { - Group * group = gpool->get(att.gid, true); + Group * group = gpool->get(vm_perms.gid, true); - if ( group == 0 ) + if ( group != 0 ) { - failure_response(NO_EXISTS, - get_error(object_name(PoolObjectSQL::GROUP),att.gid), - att); - return; - } + rc = group->quota.quota_update(Quotas::VM, &deltas, dquotas, error_str); - rc = group->quota.quota_update(Quotas::VM, &deltas, dquotas, error_str); + if (rc == false) + { + ostringstream oss; + RequestAttributes att_tmp(vm_perms.uid, -1, att); - if (rc == false) - { - ostringstream oss; - RequestAttributes att_tmp(att.uid, -1, att); + oss << object_name(PoolObjectSQL::GROUP) + << " [" << vm_perms.gid << "] " + << error_str; - oss << object_name(PoolObjectSQL::GROUP) << " [" << att.gid << "] " - << error_str; + failure_response(AUTHORIZATION, + request_error(oss.str(), ""), + att); - failure_response(AUTHORIZATION, - request_error(oss.str(), ""), - att); + group->unlock(); + + quota_rollback(&deltas, Quotas::VM, att_tmp); + + return; + } group->unlock(); - - quota_rollback(&deltas, Quotas::VM, att_tmp); - - return; } - - group->unlock(); } /* ---------------------------------------------------------------------- */ From 6d8b31d5bdf5e806c38f77aa9cba61fa811642ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 25 Feb 2013 16:08:58 +0100 Subject: [PATCH 07/10] Feature #1772: Resize capacity enforce is mandatory for everyone, except for oneadmin --- src/rm/RequestManagerVirtualMachine.cc | 50 ++++++++++++-------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 27dc93d466..9c3811f771 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -1065,7 +1065,7 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, float ncpu = xmlrpc_c::value_double(paramList.getDouble(2)); int nmemory = xmlrpc_c::value_int(paramList.getInt(3)); int nvcpu = xmlrpc_c::value_int(paramList.getInt(4)); - bool enforce = xmlrpc_c::value_boolean(paramList.getBoolean(5)); + bool enforce_param = xmlrpc_c::value_boolean(paramList.getBoolean(5)); float ocpu, dcpu; int omemory, dmemory; @@ -1089,6 +1089,26 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, VirtualMachinePool * vmpool = static_cast(pool); VirtualMachine * vm; + bool enforce = true; + + if (att.uid == UserPool::ONEADMIN_ID || att.gid == GroupPool::ONEADMIN_ID) + { + enforce = enforce_param; + } + + /* ---------------------------------------------------------------------- */ + /* Authorize the operation */ + /* ---------------------------------------------------------------------- */ + + if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false ) + { + return; + } + + /* ---------------------------------------------------------------------- */ + /* Get the resize values */ + /* ---------------------------------------------------------------------- */ + vm = vmpool->get(id, true); if (vm == 0) @@ -1155,32 +1175,6 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, vm->unlock(); - /* ---------------------------------------------------------------------- */ - /* Authorize the operation */ - /* ---------------------------------------------------------------------- */ - - if ( att.uid != UserPool::ONEADMIN_ID ) - { - AuthRequest ar(att.uid, att.gid); - - ar.add_auth(AuthRequest::MANAGE, vm_perms); - - if (enforce == false) //Admin rights to overcommit - { - ar.add_auth(AuthRequest::ADMIN, vm_perms); - } - - if (UserPool::authorize(ar) == -1) - { - failure_response(AUTHORIZATION, - authorization_error(ar.message, att), - att); - - vm->unlock(); - return; - } - } - /* ---------------------------------------------------------------------- */ /* Check quotas */ /* ---------------------------------------------------------------------- */ @@ -1265,7 +1259,7 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, quota_rollback(&deltas, Quotas::VM, att); - return ; + return; } if ( enforce && host->test_capacity(dcpu_host, dmem_host, 0) == false) From 8f5c2b3fd2ca69d6efd06e5ce1cbd8871daec33c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 25 Feb 2013 16:16:47 +0100 Subject: [PATCH 08/10] Feature #1772: Save updated quotas to the DB --- src/rm/RequestManagerVirtualMachine.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 9c3811f771..89bf7cd3b2 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -1204,6 +1204,8 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, return; } + upool->update(user); + user->unlock(); } } @@ -1236,6 +1238,8 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, return; } + gpool->update(group); + group->unlock(); } } From 9e9f40d718bf1be0b27b29f0951535a2556f8c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 25 Feb 2013 17:01:55 +0100 Subject: [PATCH 09/10] Feature #1772: Additional sanity checks for new capacity. Even if it was not updated, VCPU was inserted with value "0", causing the next deployment to fail --- include/VirtualMachine.h | 16 ++++++- src/rm/RequestManagerVirtualMachine.cc | 24 +++++++++- src/vm/VirtualMachine.cc | 63 ++++++++++++++++++++++---- 3 files changed, 91 insertions(+), 12 deletions(-) diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 15b039688c..99d4eca0a6 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -766,13 +766,27 @@ public: */ void get_requirements (int& cpu, int& memory, int& disk); + /** + * Checks if the resize parameters are valid + * @param cpu New CPU. 0 means unchanged. + * @param memory New MEMORY. 0 means unchanged. + * @param vcpu New VCPU. 0 means unchanged. + * @param error_str Error reason, if any + * + * @return 0 on success + */ + int check_resize (float cpu, int memory, int vcpu, string& error_str); + /** * Resize the VM capacity * @param cpu * @param memory * @param vcpu + * @param error_str Error reason, if any + * + * @return 0 on success */ - void resize (float cpu, int memory, int vcpu); + int resize (float cpu, int memory, int vcpu, string& error_str); // ------------------------------------------------------------------------ // Network Leases & Disk Images diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 89bf7cd3b2..51bf57b1b7 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -1082,6 +1082,7 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, Template deltas; string error_str; bool rc; + int ret; int hid = -1; PoolObjectAuth vm_perms; @@ -1173,8 +1174,18 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, return; } + ret = vm->check_resize(ncpu, nmemory, nvcpu, error_str); + vm->unlock(); + if (ret != 0) + { + failure_response(INTERNAL, + request_error("Could resize the VM", error_str), + att); + return; + } + /* ---------------------------------------------------------------------- */ /* Check quotas */ /* ---------------------------------------------------------------------- */ @@ -1326,7 +1337,18 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList, case VirtualMachine::HOLD: case VirtualMachine::FAILED: case VirtualMachine::POWEROFF: - vm->resize(ncpu, nmemory, nvcpu); + ret = vm->resize(ncpu, nmemory, nvcpu, error_str); + + if (ret != 0) + { + vm->unlock(); + + failure_response(INTERNAL, + request_error("Could not resize the VM", error_str), + att); + return; + } + vmpool->update(vm); break; diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 15e004b9d4..a1d1692214 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -1281,22 +1281,65 @@ void VirtualMachine::get_requirements (int& cpu, int& memory, int& disk) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void VirtualMachine::resize(float cpu, int memory, int vcpu) +int VirtualMachine::check_resize ( + float cpu, int memory, int vcpu, string& error_str) +{ + if (cpu < 0) + { + error_str = "CPU must be a positive float or integer value."; + return -1; + } + + if (memory < 0) + { + error_str = "MEMORY must be a positive integer value."; + return -1; + } + + if (vcpu < 0) + { + error_str = "VCPU must be a positive integer value."; + return -1; + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VirtualMachine::resize(float cpu, int memory, int vcpu, string& error_str) { ostringstream oss; - oss << cpu; - replace_template_attribute("CPU", oss.str()); - oss.str(""); + int rc = check_resize(cpu, memory, vcpu, error_str); - oss << memory; - replace_template_attribute("MEMORY", oss.str()); - oss.str(""); + if (rc != 0) + { + return rc; + } - oss << vcpu; - replace_template_attribute("VCPU", oss.str()); + if (cpu > 0) + { + oss << cpu; + replace_template_attribute("CPU", oss.str()); + oss.str(""); + } - return; + if (memory > 0) + { + oss << memory; + replace_template_attribute("MEMORY", oss.str()); + oss.str(""); + } + + if (vcpu > 0) + { + oss << vcpu; + replace_template_attribute("VCPU", oss.str()); + } + + return 0; } /* -------------------------------------------------------------------------- */ From 5b2750d4831855e0bb80e093710ba470109fb853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 25 Feb 2013 17:32:47 +0100 Subject: [PATCH 10/10] Feature #1772: Add vm resize method to Java OCA --- .../opennebula/client/vm/VirtualMachine.java | 36 +++++++++++++++++++ src/oca/java/test/VirtualMachineTest.java | 10 ++++++ src/oca/ruby/opennebula/virtual_machine.rb | 3 +- 3 files changed, 48 insertions(+), 1 deletion(-) 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 0cc1260ec2..fbd9f39ed1 100644 --- a/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java +++ b/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java @@ -41,6 +41,7 @@ public class VirtualMachine extends PoolElement{ private static final String DETACH = METHOD_PREFIX + "detach"; private static final String RENAME = METHOD_PREFIX + "rename"; private static final String UPDATE = METHOD_PREFIX + "update"; + private static final String RESIZE = METHOD_PREFIX + "resize"; private static final String[] VM_STATES = { @@ -184,6 +185,25 @@ public class VirtualMachine extends PoolElement{ return client.call(UPDATE, id, new_template); } + /** + * Resizes the VM capacity + * + * @param client XML-RPC Client. + * @param id The id of the target vm. + * @param cpu the new CPU value + * @param memory the new MEMORY value + * @param vcpu the new VCPU value + * @param enforce If it is set to true, the host capacity + * will be checked. This will only affect oneadmin requests, regular users + * resize requests will always be enforced + * @return If an error occurs the error message contains the reason. + */ + public static OneResponse resize(Client client, int id, + double cpu, int memory, int vcpu, boolean enforce) + { + return client.call(RESIZE, id, cpu, memory, vcpu, enforce); + } + /** * Retrieves the information of the given VM. * @@ -571,6 +591,22 @@ public class VirtualMachine extends PoolElement{ return client.call(UPDATE, id, new_template); } + /** + * Resizes this VM's capacity + * + * @param cpu the new CPU value + * @param memory the new MEMORY value + * @param vcpu the new VCPU value + * @param enforce If it is set to true, the host capacity + * will be checked. This will only affect oneadmin requests, regular users + * resize requests will always be enforced + * @return If an error occurs the error message contains the reason. + */ + public OneResponse resize(double cpu, int memory, int vcpu, boolean enforce) + { + return client.call(RESIZE, id, cpu, memory, vcpu, enforce); + } + // ================================= // Helpers // ================================= diff --git a/src/oca/java/test/VirtualMachineTest.java b/src/oca/java/test/VirtualMachineTest.java index 02b0632f2e..5abcf065b6 100644 --- a/src/oca/java/test/VirtualMachineTest.java +++ b/src/oca/java/test/VirtualMachineTest.java @@ -341,4 +341,14 @@ public class VirtualMachineTest res = vm.info(); assertTrue( res.getErrorMessage(), !res.isError() ); } + + @Test + public void resize() + { + res = vm.resize(2.5, 512, 0, true); + assertTrue( res.getErrorMessage(), !res.isError() ); + + res = vm.resize(1, 128, 2, false); + assertTrue( res.getErrorMessage(), !res.isError() ); + } } diff --git a/src/oca/ruby/opennebula/virtual_machine.rb b/src/oca/ruby/opennebula/virtual_machine.rb index 489ac9a560..54978beb0a 100644 --- a/src/oca/ruby/opennebula/virtual_machine.rb +++ b/src/oca/ruby/opennebula/virtual_machine.rb @@ -343,7 +343,8 @@ module OpenNebula # @param memory [Integer] the new MEMORY value # @param vcpu [Integer] the new VCPU value # @param enforce [true|false] If it is set to true, the host capacity - # will be checked + # will be checked. This will only affect oneadmin requests, regular users + # resize requests will always be enforced # # @return [nil, OpenNebula::Error] nil in case of success, Error # otherwise