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',