From: martyntaylor mtaylor@redhat.com
--- src/app/models/instance_observer.rb | 35 ++++++++++++++++++++++- src/app/models/quota.rb | 8 +++++ src/db/migrate/20090802000000_create_quotas.rb | 11 +++++++ src/spec/factories/hardware_profile.rb | 3 +- src/spec/factories/instance.rb | 4 +- src/spec/factories/quota.rb | 8 +++++ src/spec/models/instance_observer_spec.rb | 19 +++++++++++++ 7 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 src/spec/factories/quota.rb
diff --git a/src/app/models/instance_observer.rb b/src/app/models/instance_observer.rb index fa5b3d2..ab1a095 100644 --- a/src/app/models/instance_observer.rb +++ b/src/app/models/instance_observer.rb @@ -1,11 +1,14 @@ class InstanceObserver < ActiveRecord::Observer
+ ACTIVE_STATES = [ Instance::STATE_PENDING, Instance::STATE_RUNNING, Instance::STATE_SHUTTING_DOWN ] + def before_save(an_instance) if an_instance.changed? change = an_instance.changes['state'] if change update_state_timestamps(change[1], an_instance) update_accumulative_state_time(change[0], an_instance) + update_quota(change[0], change[1], an_instance) end end end @@ -26,7 +29,35 @@ class InstanceObserver < ActiveRecord::Observer when Instance::STATE_SHUTTING_DOWN then an_instance.acc_shutting_down_time += Time.now - an_instance.time_last_shutting_down when Instance::STATE_STOPPED then an_instance.acc_stopped_time += Time.now - an_instance.time_last_stopped end - end + end + + def update_quota(state_from, state_to, an_instance) + + hwp = HardwareProfile.find(an_instance.hardware_profile_id) + quota = Quota.find(:first, :conditions => { :pool_id => an_instance.pool_id }) + + if(quota) + if state_to == Instance::STATE_RUNNING + #TODO update running cpus + quota.running_instances += 1 + quota.running_memory += hwp.memory + elsif state_from == Instance::STATE_RUNNING + #TODO update running cpus + quota.running_instances -- + quota.running_memory -= hwp.memory + end + + if !ACTIVE_STATES.include?(state_from) && ACTIVE_STATES.include?(state_to) + quota.total_storage += hwp.storage + quota.total_instances += 1 + elsif ACTIVE_STATES.include?(state_from) && !ACTIVE_STATES.include?(state_to) + quota.total_storage -= hwp.storage + quota.total_instances -= 1 + end + + quota.save + end + end end
-InstanceObserver.instance \ No newline at end of file +InstanceObserver.instance diff --git a/src/app/models/quota.rb b/src/app/models/quota.rb index 23f9aee..c772c0b 100644 --- a/src/app/models/quota.rb +++ b/src/app/models/quota.rb @@ -22,4 +22,12 @@ class Quota < ActiveRecord::Base has_one :pool has_one :cloud_account + + validates_presence_of :maximum_running_instances + validates_presence_of :maximum_running_memory + validates_presence_of :maximum_running_cpus + + validates_presence_of :maximum_total_storage + validates_presence_of :maximum_total_instances + end diff --git a/src/db/migrate/20090802000000_create_quotas.rb b/src/db/migrate/20090802000000_create_quotas.rb index c61fb16..29cc5bf 100644 --- a/src/db/migrate/20090802000000_create_quotas.rb +++ b/src/db/migrate/20090802000000_create_quotas.rb @@ -25,6 +25,17 @@ class CreateQuotas < ActiveRecord::Migration t.integer :running_instances t.integer :total_storage t.integer :total_instances + t.integer :pool_id + t.integer :running_cpus, :default => 0 + t.integer :running_memory, :default => 0 + t.integer :running_instances, :default => 0 + t.integer :total_storage, :default => 0 + t.integer :total_instances, :default => 0 + t.integer :maximum_running_cpus + t.integer :maximum_running_memory + t.integer :maximum_running_instances + t.integer :maximum_total_storage + t.integer :maximum_total_instances t.integer :lock_version, :default => 0 t.timestamps end diff --git a/src/spec/factories/hardware_profile.rb b/src/spec/factories/hardware_profile.rb index 43f63f3..95ce13a 100644 --- a/src/spec/factories/hardware_profile.rb +++ b/src/spec/factories/hardware_profile.rb @@ -24,7 +24,8 @@ Factory.define :pool_hwp1, :parent => :hardware_profile do |p| end
Factory.define :hardware_profile_auto, :parent => :hardware_profile do |p| - p.external_key { |hp| hp.name + "_key" } + p.sequence(:name) { |n| "hardware_profile#{n}" } + p.external_key { |hp| "#{hp.name}_external_key" } p.storage 160 p.memory 1024 p.architecture "i386" diff --git a/src/spec/factories/instance.rb b/src/spec/factories/instance.rb index 3a453c3..890b6b9 100644 --- a/src/spec/factories/instance.rb +++ b/src/spec/factories/instance.rb @@ -1,7 +1,7 @@ Factory.define :instance do |i| i.sequence(:name) { |n| "instance#{n}" } i.sequence(:external_key) { |n| "key#{n}" } - i.hardware_profile_id 1 + i.association :hardware_profile, :factory => :hardware_profile_auto i.image_id 1 i.pool_id 1 i.state "running" @@ -13,4 +13,4 @@ end
Factory.define :new_instance, :parent => :instance do |i| i.state Instance::STATE_NEW -end \ No newline at end of file +end diff --git a/src/spec/factories/quota.rb b/src/spec/factories/quota.rb new file mode 100644 index 0000000..fd0f514 --- /dev/null +++ b/src/spec/factories/quota.rb @@ -0,0 +1,8 @@ +Factory.define :quota do |f| + f.association :pool + f.maximum_running_instances 10 + f.maximum_running_memory 102400 + f.maximum_running_cpus 20 + f.maximum_total_instances 15 + f.maximum_total_storage 8500 +end \ No newline at end of file diff --git a/src/spec/models/instance_observer_spec.rb b/src/spec/models/instance_observer_spec.rb index 9e3dcc7..76514e5 100644 --- a/src/spec/models/instance_observer_spec.rb +++ b/src/spec/models/instance_observer_spec.rb @@ -86,4 +86,23 @@ describe InstanceObserver do @instance.acc_stopped_time.should >= 1 @instance.acc_stopped_time.should <= 2 end + + it "should update a pools quota when an associated instance state goes to running" do + hwp = Factory :mock_hwp1 + pool = Factory :pool + quota = Factory(:quota, :pool_id => pool.id) + instance = Factory(:new_instance, :pool => pool, :hardware_profile => hwp) + + instance.state = Instance::STATE_RUNNING + instance.save + + quota = Quota.find_by_id(quota.id) + quota.running_instances.should == 1 + quota.running_memory.should == hwp.memory + #TODO test for cpus + + quota.total_storage.should == hwp.storage + quota.total_instances.should == 1 + end + end \ No newline at end of file