From 981db30338f09ac406b418801ced1a5deede784e Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 8 Jun 2012 22:14:40 +0200 Subject: [PATCH] feature #1288: Support for Group quotas --- include/Group.h | 12 +- include/Request.h | 21 +++ include/RequestManagerGroup.h | 72 ++++++++++ src/cli/etc/onegroup.yaml | 16 ++- src/cli/one_helper/onegroup_helper.rb | 31 ++++- src/cli/one_helper/oneuser_helper.rb | 8 +- src/cli/onegroup | 16 +++ src/dm/DispatchManagerActions.cc | 41 ++++-- src/dm/DispatchManagerStates.cc | 39 ++++-- src/group/Group.cc | 6 + src/image/ImageManagerActions.cc | 39 ++++-- src/oca/ruby/OpenNebula/Group.rb | 22 ++- src/rm/Request.cc | 184 +++++++++++++++++++++++--- src/rm/RequestManager.cc | 5 + src/rm/RequestManagerChown.cc | 50 ++++--- src/rm/RequestManagerGroup.cc | 83 ++++++++++++ src/rm/RequestManagerUser.cc | 8 +- src/rm/SConstruct | 1 + 18 files changed, 571 insertions(+), 83 deletions(-) create mode 100644 include/RequestManagerGroup.h create mode 100644 src/rm/RequestManagerGroup.cc diff --git a/include/Group.h b/include/Group.h index ace3058d36..3a080e0566 100644 --- a/include/Group.h +++ b/include/Group.h @@ -20,6 +20,7 @@ #include "PoolSQL.h" #include "ObjectCollection.h" #include "User.h" +#include "Quotas.h" using namespace std; @@ -65,6 +66,11 @@ public: return del_collection_id(id); } + /** + * Object quotas, provides set and check interface + */ + Quotas quota; + private: // ------------------------------------------------------------------------- @@ -79,7 +85,11 @@ private: Group(int id, const string& name): PoolObjectSQL(id,GROUP,name,-1,-1,"","",table), - ObjectCollection("USERS") + ObjectCollection("USERS"), + quota("/GROUP/DATASTORE_QUOTA", + "/GROUP/NETWORK_QUOTA", + "/GROUP/IMAGE_QUOTA", + "/GROUP/VM_QUOTA") { // Allow users in this group to see it group_u = 1; diff --git a/include/Request.h b/include/Request.h index 1cc24244dc..2faeef213f 100644 --- a/include/Request.h +++ b/include/Request.h @@ -312,6 +312,27 @@ protected: RequestAttributes& att, PoolObjectAuth& perms, string& name); +private: + + /* ------------- Functions to manage user and group quotas -------------- */ + + bool user_quota_authorization(Template * tmpl, + PoolObjectSQL::ObjectType object, + RequestAttributes& att, + string& error_str); + + bool group_quota_authorization(Template * tmpl, + PoolObjectSQL::ObjectType object, + RequestAttributes& att, + string& error_str); + + void user_quota_rollback(Template * tmpl, + PoolObjectSQL::ObjectType object, + RequestAttributes& att); + + void group_quota_rollback(Template * tmpl, + PoolObjectSQL::ObjectType object, + RequestAttributes& att); }; /* -------------------------------------------------------------------------- */ diff --git a/include/RequestManagerGroup.h b/include/RequestManagerGroup.h new file mode 100644 index 0000000000..968654af05 --- /dev/null +++ b/include/RequestManagerGroup.h @@ -0,0 +1,72 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#ifndef REQUEST_MANAGER_GROUP_H +#define REQUEST_MANAGER_GROUP_H + +#include "Request.h" +#include "Nebula.h" + +using namespace std; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class RequestManagerGroup: public Request +{ +protected: + RequestManagerGroup(const string& method_name, + const string& help, + const string& params) + :Request(method_name,params,help) + { + Nebula& nd = Nebula::instance(); + pool = nd.get_gpool(); + + auth_object = PoolObjectSQL::GROUP; + }; + + virtual ~RequestManagerGroup(){}; + + virtual void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att) = 0; +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class GroupSetQuota : public RequestManagerGroup +{ +public: + GroupSetQuota(): + RequestManagerGroup("GroupSetQuota", + "Sets group quota limits", + "A:sis") + { + auth_op = AuthRequest::ADMIN; + }; + + ~GroupSetQuota(){}; + + void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att); +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +#endif diff --git a/src/cli/etc/onegroup.yaml b/src/cli/etc/onegroup.yaml index 96fc7a2e73..662d3fe297 100644 --- a/src/cli/etc/onegroup.yaml +++ b/src/cli/etc/onegroup.yaml @@ -8,7 +8,21 @@ :size: 15 :left: true +:VMS: + :desc: Number of VMS + :size: 8 + +:MEMORY: + :desc: Total memory allocated to user VMs + :size: 8 + +:CPU: + :desc: Total CPU allocated to user VMs + :size: 8 + :default: - :ID - :NAME - +- :VMS +- :MEMORY +- :CPU diff --git a/src/cli/one_helper/onegroup_helper.rb b/src/cli/one_helper/onegroup_helper.rb index a949d29978..d2923647dd 100644 --- a/src/cli/one_helper/onegroup_helper.rb +++ b/src/cli/one_helper/onegroup_helper.rb @@ -15,6 +15,7 @@ #--------------------------------------------------------------------------- # require 'one_helper' +require 'one_helper/onequota_helper' class OneGroupHelper < OpenNebulaHelper::OneHelper def self.rname @@ -56,7 +57,31 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper d["NAME"] end - default :ID, :NAME + column :VMS, "Total number of VMS", :size=>8 do |d| + if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM') + d['VM_QUOTA']['VM']['VMS'] + else + "-" + end + end + + column :MEMORY, "Total memory allocated to group VMs", :size=>8 do |d| + if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM') + d['VM_QUOTA']['VM']['MEMORY_USED'] + else + "-" + end + end + + column :CPU, "Total CPU allocated to group VMs", :size=>8 do |d| + if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM') + d['VM_QUOTA']['VM']['CPU_USED'] + else + "-" + end + end + + default :ID, :NAME, :VMS, :MEMORY, :CPU end table @@ -92,5 +117,9 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper group.user_ids.each do |uid| puts "%-15s" % [uid] end + + group_hash = group.to_hash + + OneQuotaHelper.format_quota(group_hash['GROUP']) end end diff --git a/src/cli/one_helper/oneuser_helper.rb b/src/cli/one_helper/oneuser_helper.rb index 0af47befa1..7653ec9c86 100644 --- a/src/cli/one_helper/oneuser_helper.rb +++ b/src/cli/one_helper/oneuser_helper.rb @@ -168,15 +168,15 @@ class OneUserHelper < OpenNebulaHelper::OneHelper if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM') d['VM_QUOTA']['VM']['VMS'] else - "0" - end + "-" + end end column :MEMORY, "Total memory allocated to user VMs", :size=>8 do |d| if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM') d['VM_QUOTA']['VM']['MEMORY_USED'] else - "0" + "-" end end @@ -184,7 +184,7 @@ class OneUserHelper < OpenNebulaHelper::OneHelper if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM') d['VM_QUOTA']['VM']['CPU_USED'] else - "0" + "-" end end diff --git a/src/cli/onegroup b/src/cli/onegroup index f520300c79..ccb0a1cae7 100755 --- a/src/cli/onegroup +++ b/src/cli/onegroup @@ -97,4 +97,20 @@ cmd=CommandParser::CmdParser.new(ARGV) do helper.show_resource(group,options) end + quota_desc = <<-EOT.unindent + Set the quota limits for the group. If a path is not provided the editor + will be launched to modify the current quotas. + EOT + + command :quota, quota_desc, :groupid, [:file, nil] do + helper.perform_action(args[0], options, "modified") do |group| + str = OneQuotaHelper.set_quota(group, args[1]) + rc = group.set_quota(str) + + if OpenNebula.is_error?(rc) + puts rc.message + exit -1 + end + end + end end diff --git a/src/dm/DispatchManagerActions.cc b/src/dm/DispatchManagerActions.cc index 112fd215a2..df0505cc8e 100644 --- a/src/dm/DispatchManagerActions.cc +++ b/src/dm/DispatchManagerActions.cc @@ -683,11 +683,14 @@ int DispatchManager::finalize( int vid) { VirtualMachine * vm; - ostringstream oss; - Template * tmpl; - User * user; + ostringstream oss; + Template * tmpl; + + User * user; + Group * group; int uid; + int gid; VirtualMachine::VmState state; @@ -707,6 +710,7 @@ int DispatchManager::finalize( TransferManager * tm = nd.get_tm(); LifeCycleManager * lcm = nd.get_lcm(); UserPool * upool = nd.get_upool(); + GroupPool * gpool = nd.get_gpool(); switch (state) { @@ -730,19 +734,38 @@ int DispatchManager::finalize( vm->log("DiM", Log::INFO, "New VM state is DONE."); uid = vm->get_uid(); + gid = vm->get_gid(); tmpl = vm->clone_template(); vm->unlock(); - user = upool->get(uid, true); - - if ( user != 0 ) + if ( uid != UserPool::ONEADMIN_ID ) { - user->quota.vm_del(tmpl); - upool->update(user); + user = upool->get(uid, true); - user->unlock(); + if ( user != 0 ) + { + user->quota.vm_del(tmpl); + + upool->update(user); + + user->unlock(); + } + } + + if ( gid != GroupPool::ONEADMIN_ID ) + { + group = gpool->get(gid, true); + + if ( group != 0 ) + { + group->quota.vm_del(tmpl); + + gpool->update(group); + + group->unlock(); + } } delete tmpl; diff --git a/src/dm/DispatchManagerStates.cc b/src/dm/DispatchManagerStates.cc index 80f8c7061e..b2305cb026 100644 --- a/src/dm/DispatchManagerStates.cc +++ b/src/dm/DispatchManagerStates.cc @@ -103,14 +103,17 @@ void DispatchManager::done_action(int vid) Template * tmpl; int uid; + int gid; VirtualMachine::LcmState lcm_state; VirtualMachine::VmState dm_state; Nebula& nd = Nebula::instance(); UserPool * upool = nd.get_upool(); + GroupPool* gpool = nd.get_gpool(); - User * user; + User * user; + Group * group; vm = vmpool->get(vid,true); @@ -142,21 +145,41 @@ void DispatchManager::done_action(int vid) vm->release_disk_images(); uid = vm->get_uid(); + gid = vm->get_gid(); tmpl = vm->clone_template(); vm->unlock(); - user = upool->get(uid, true); + /* ---------------- Update Group & User quota counters -------------- */ - if ( user != 0 ) + if ( uid != UserPool::ONEADMIN_ID ) { - user->quota.vm_del(tmpl); - - upool->update(user); - - user->unlock(); + user = upool->get(uid, true); + + if ( user != 0 ) + { + user->quota.vm_del(tmpl); + + upool->update(user); + + user->unlock(); + } } + if ( gid != GroupPool::ONEADMIN_ID ) + { + group = gpool->get(gid, true); + + if ( group != 0 ) + { + group->quota.vm_del(tmpl); + + gpool->update(group); + + group->unlock(); + } + } + delete tmpl; } else diff --git a/src/group/Group.cc b/src/group/Group.cc index 28e1582af0..02588502b2 100644 --- a/src/group/Group.cc +++ b/src/group/Group.cc @@ -130,14 +130,18 @@ string& Group::to_xml(string& xml) const { ostringstream oss; string collection_xml; + string quota_xml; ObjectCollection::to_xml(collection_xml); + + quota.to_xml(quota_xml); oss << "" << "" << oid << "" << "" << name << "" << collection_xml << + quota_xml << ""; xml = oss.str(); @@ -179,6 +183,8 @@ int Group::from_xml(const string& xml) ObjectXML::free_nodes(content); + rc += quota.from_xml(this); + if (rc != 0) { return -1; diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index d63c84e9bb..0258c70885 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -273,10 +273,13 @@ int ImageManager::delete_image(int iid, const string& ds_data) int ds_id; int uid; + int gid; + Group* group; User * user; Nebula& nd = Nebula::instance(); UserPool * upool = nd.get_upool(); + GroupPool* gpool = nd.get_gpool(); img = ipool->get(iid,true); @@ -320,6 +323,7 @@ int ImageManager::delete_image(int iid, const string& ds_data) size = img->get_size(); ds_id = img->get_ds_id(); uid = img->get_uid(); + gid = img->get_gid(); if (source.empty()) { @@ -343,20 +347,39 @@ int ImageManager::delete_image(int iid, const string& ds_data) delete drv_msg; - user = upool->get(uid, true); + /* -------------------- Update Group & User quota counters -------------- */ + + Template img_usage; - if ( user != 0 ) + img_usage.add("DATASTORE", ds_id); + img_usage.add("SIZE", size); + + if ( uid != UserPool::ONEADMIN_ID ) { - Template img_usage; + user = upool->get(uid, true); - img_usage.add("DATASTORE", ds_id); - img_usage.add("SIZE", size); + if ( user != 0 ) + { + user->quota.ds_del(&img_usage); - user->quota.ds_del(&img_usage); + upool->update(user); - upool->update(user); + user->unlock(); + } + } - user->unlock(); + if ( gid != GroupPool::ONEADMIN_ID ) + { + group = gpool->get(gid, true); + + if ( group != 0 ) + { + group->quota.ds_del(&img_usage); + + gpool->update(group); + + group->unlock(); + } } return 0; diff --git a/src/oca/ruby/OpenNebula/Group.rb b/src/oca/ruby/OpenNebula/Group.rb index 3fa5a9a41c..fcfefe8e38 100644 --- a/src/oca/ruby/OpenNebula/Group.rb +++ b/src/oca/ruby/OpenNebula/Group.rb @@ -23,11 +23,11 @@ module OpenNebula # Constants and Class Methods ####################################################################### - GROUP_METHODS = { - :info => "group.info", - :allocate => "group.allocate", - :delete => "group.delete" + :info => "group.info", + :allocate => "group.allocate", + :delete => "group.delete", + :quota => "group.quota" } # Flag for requesting connected user's group info @@ -120,6 +120,20 @@ module OpenNebula super(GROUP_METHODS[:delete]) end + # Sets the group quota limits + # @param quota [String] a template (XML or txt) with the new quota limits + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def set_quota(quota) + return Error.new('ID not defined') if !@pe_id + + rc = @client.call(GROUP_METHODS[:quota],@pe_id, quota) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + # --------------------------------------------------------------------- # Helpers to get information # --------------------------------------------------------------------- diff --git a/src/rm/Request.cc b/src/rm/Request.cc index 2a9098dcbe..97c803211b 100644 --- a/src/rm/Request.cc +++ b/src/rm/Request.cc @@ -106,25 +106,22 @@ bool Request::basic_authorization(int oid, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -bool Request::quota_authorization(Template * tmpl, - PoolObjectSQL::ObjectType object, - RequestAttributes& att) +bool Request::user_quota_authorization (Template * tmpl, + PoolObjectSQL::ObjectType object, + RequestAttributes& att, + string& error_str) { Nebula& nd = Nebula::instance(); - UserPool * upool = nd.get_upool(); + UserPool * upool = nd.get_upool(); + User * user; - User * user; bool rc = false; - string error_str; user = upool->get(att.uid, true); if ( user == 0 ) { - failure_response(AUTHORIZATION, - authorization_error("User not found", att), - att); - + error_str = "User not found"; return false; } @@ -135,12 +132,12 @@ bool Request::quota_authorization(Template * tmpl, break; case PoolObjectSQL::VM: + case PoolObjectSQL::TEMPLATE: rc = user->quota.vm_check(tmpl, error_str); break; default: - user->unlock(); - return true; + break; } if (rc == true) @@ -150,22 +147,60 @@ bool Request::quota_authorization(Template * tmpl, user->unlock(); - if ( rc == false ) + return rc; +} + +/* -------------------------------------------------------------------------- */ + +bool Request::group_quota_authorization (Template * tmpl, + PoolObjectSQL::ObjectType object, + RequestAttributes& att, + string& error_str) +{ + Nebula& nd = Nebula::instance(); + GroupPool * gpool = nd.get_gpool(); + Group * group; + + bool rc = false; + + group = gpool->get(att.gid, true); + + if ( group == 0 ) { - failure_response(AUTHORIZATION, - authorization_error(error_str, att), - att); + error_str = "Group not found"; + return false; } + switch (object) + { + case PoolObjectSQL::IMAGE: + rc = group->quota.ds_check(tmpl, error_str); + break; + + case PoolObjectSQL::VM: + case PoolObjectSQL::TEMPLATE: + rc = group->quota.vm_check(tmpl, error_str); + break; + + default: + break; + } + + if (rc == true) + { + gpool->update(group); + } + + group->unlock(); + return rc; } -/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void Request::quota_rollback(Template * tmpl, - PoolObjectSQL::ObjectType object, - RequestAttributes& att) +void Request::user_quota_rollback(Template * tmpl, + PoolObjectSQL::ObjectType object, + RequestAttributes& att) { Nebula& nd = Nebula::instance(); UserPool * upool = nd.get_upool(); @@ -199,6 +234,115 @@ void Request::quota_rollback(Template * tmpl, user->unlock(); } +/* -------------------------------------------------------------------------- */ + +void Request::group_quota_rollback(Template * tmpl, + PoolObjectSQL::ObjectType object, + RequestAttributes& att) +{ + Nebula& nd = Nebula::instance(); + GroupPool * gpool = nd.get_gpool(); + + Group * group; + + group = gpool->get(att.gid, true); + + if ( group == 0 ) + { + return; + } + + switch (object) + { + case PoolObjectSQL::IMAGE: + group->quota.ds_del(tmpl); + break; + + case PoolObjectSQL::VM: + case PoolObjectSQL::TEMPLATE: + group->quota.vm_del(tmpl); + break; + default: + break; + } + + gpool->update(group); + + group->unlock(); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +bool Request::quota_authorization(Template * tmpl, + PoolObjectSQL::ObjectType object, + RequestAttributes& att) +{ + string error_str; + + if (object != PoolObjectSQL::IMAGE && + object != PoolObjectSQL::VM && + object != PoolObjectSQL::TEMPLATE) + { + return true; + } + + // uid/gid == -1 means do not update user/group + if ( att.uid != UserPool::ONEADMIN_ID && att.uid != -1) + { + if ( user_quota_authorization(tmpl, object, att, error_str) == false ) + { + failure_response(AUTHORIZATION, + authorization_error(error_str, att), + att); + + return false; + } + } + + if ( att.gid != GroupPool::ONEADMIN_ID && att.gid != -1) + { + if ( group_quota_authorization(tmpl, object, att, error_str) == false ) + { + user_quota_rollback(tmpl, object, att); + + failure_response(AUTHORIZATION, + authorization_error(error_str, att), + att); + + return false; + } + } + + return true; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void Request::quota_rollback(Template * tmpl, + PoolObjectSQL::ObjectType object, + RequestAttributes& att) +{ + if (object != PoolObjectSQL::IMAGE && + object != PoolObjectSQL::VM && + object != PoolObjectSQL::TEMPLATE) + { + return; + } + + // uid/gid == -1 means do not update user/group + if ( att.uid != UserPool::ONEADMIN_ID && att.uid != -1 ) + { + user_quota_rollback(tmpl, object, att); + } + + if ( att.gid != GroupPool::ONEADMIN_ID && att.gid != -1 ) + { + group_quota_rollback(tmpl, object, att);; + } +} + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index fcfe07ba47..e82b503d28 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -34,6 +34,7 @@ #include "RequestManagerUser.h" #include "RequestManagerAcl.h" #include "RequestManagerCluster.h" +#include "RequestManagerGroup.h" #include #include @@ -235,6 +236,9 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr user_change_auth(new UserChangeAuth()); xmlrpc_c::methodPtr user_set_quota(new UserSetQuota()); + // Group Methods + xmlrpc_c::methodPtr group_set_quota(new GroupSetQuota()); + // VMTemplate Methods xmlrpc_c::methodPtr template_instantiate(new VMTemplateInstantiate()); xmlrpc_c::methodPtr template_clone(new VMTemplateClone()); @@ -377,6 +381,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.group.allocate", group_allocate); RequestManagerRegistry.addMethod("one.group.delete", group_delete); RequestManagerRegistry.addMethod("one.group.info", group_info); + RequestManagerRegistry.addMethod("one.group.quota", group_set_quota); RequestManagerRegistry.addMethod("one.grouppool.info", grouppool_info); diff --git a/src/rm/RequestManagerChown.cc b/src/rm/RequestManagerChown.cc index fdbd2d6837..6651a3d9d7 100644 --- a/src/rm/RequestManagerChown.cc +++ b/src/rm/RequestManagerChown.cc @@ -46,11 +46,6 @@ PoolObjectSQL * RequestManagerChown::get_and_quota( return 0; } - if ( new_uid < 0 ) - { - return object; - } - if ( auth_object == PoolObjectSQL::VM ) { tmpl = (static_cast(object))->clone_template(); @@ -64,41 +59,44 @@ PoolObjectSQL * RequestManagerChown::get_and_quota( tmpl->add("SIZE", img->get_size()); } - old_uid = object->get_uid(); - old_gid = object->get_gid(); + if ( new_uid == -1 ) + { + old_uid = -1; + } + else + { + old_uid = object->get_uid(); + } + + if ( new_gid == -1 ) + { + old_gid = -1; + } + else + { + old_gid = object->get_gid(); + } object->unlock(); RequestAttributes att_new(new_uid, new_gid, att); RequestAttributes att_old(old_uid, old_gid, att); - if ( new_uid != 0 ) + if ( quota_authorization(tmpl, att_new) == false ) { - if ( quota_authorization(tmpl, att_new) == false ) - { - delete tmpl; - return 0; - } + delete tmpl; + return 0; } - if ( old_uid != 0 ) - { - quota_rollback(tmpl, att_old); - } + quota_rollback(tmpl, att_old); object = pool->get(oid,true); if ( object == 0 ) { - if ( new_uid != 0 ) - { - quota_rollback(tmpl, att_new); - } - - if ( old_uid != 0 ) - { - quota_authorization(tmpl, att_old); - } + quota_rollback(tmpl, att_new); + + quota_authorization(tmpl, att_old); failure_response(NO_EXISTS, get_error(object_name(auth_object), oid), diff --git a/src/rm/RequestManagerGroup.cc b/src/rm/RequestManagerGroup.cc new file mode 100644 index 0000000000..84c62612ea --- /dev/null +++ b/src/rm/RequestManagerGroup.cc @@ -0,0 +1,83 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#include "RequestManagerGroup.h" + +using namespace std; + +void GroupSetQuota:: + request_execute(xmlrpc_c::paramList const& paramList, + RequestAttributes& att) +{ + int id = xmlrpc_c::value_int(paramList.getInt(1)); + string quota_str = xmlrpc_c::value_string(paramList.getString(2)); + + Group * group; + string error_str; + + Template quota_tmpl; + int rc; + + if ( id == GroupPool::ONEADMIN_ID ) + { + failure_response(ACTION, + request_error("Cannot set quotas for oneadmin group",""), + att); + return; + } + + if ( basic_authorization(id, att) == false ) + { + return; + } + + rc = quota_tmpl.parse_str_or_xml(quota_str, error_str); + + if ( rc != 0 ) + { + failure_response(ACTION, request_error(error_str,""), att); + return; + } + + group = static_cast(pool->get(id,true)); + + if ( group == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(auth_object),id), + att); + + return; + } + + group->quota.set("a_tmpl, error_str); + + pool->update(group); + + group->unlock(); + + if ( rc != 0 ) + { + failure_response(ACTION, request_error(error_str,""), att); + } + else + { + success_response(id, att); + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerUser.cc b/src/rm/RequestManagerUser.cc index f1e3683dc1..2af6c7d61d 100644 --- a/src/rm/RequestManagerUser.cc +++ b/src/rm/RequestManagerUser.cc @@ -44,7 +44,7 @@ void RequestManagerUser:: if ( user_action(id,paramList,error_str) < 0 ) { - failure_response(INTERNAL, request_error(error_str,""), att); + failure_response(ACTION, request_error(error_str,""), att); return; } @@ -147,6 +147,12 @@ int UserSetQuota::user_action(int user_id, int rc; User * user; + if ( user_id == UserPool::ONEADMIN_ID ) + { + error_str = "Cannot set quotas for oneadmin user"; + return -1; + } + rc = quota_tmpl.parse_str_or_xml(quota_str, error_str); if ( rc != 0 ) diff --git a/src/rm/SConstruct b/src/rm/SConstruct index 5c565c5b73..7f9b1b33e1 100644 --- a/src/rm/SConstruct +++ b/src/rm/SConstruct @@ -33,6 +33,7 @@ source_files=[ 'RequestManagerVMTemplate.cc', 'RequestManagerUpdateTemplate.cc', 'RequestManagerUser.cc', + 'RequestManagerGroup.cc', 'RequestManagerHost.cc', 'RequestManagerImage.cc', 'RequestManagerChown.cc',