From: martyntaylor <[email protected]>

---
 src/app/controllers/pool_controller.rb         |   30 +++++-
 src/app/controllers/pool_controller.rb~        |  138 ++++++++++++++++++++++++
 src/app/models/instance_observer.rb            |    9 +-
 src/app/views/pool/new_quota.html.erb          |   18 +++
 src/app/views/pool/quota.html.erb              |    3 +-
 src/app/views/pool/show.html.erb~              |   42 +++++++
 src/config/environment.rb                      |    2 +-
 src/db/migrate/20090802000000_create_quotas.rb |    6 -
 src/spec/models/instance_observer_spec.rb      |   60 ++++++++---
 9 files changed, 279 insertions(+), 29 deletions(-)
 create mode 100644 src/app/controllers/pool_controller.rb~
 create mode 100644 src/app/views/pool/new_quota.html.erb
 create mode 100644 src/app/views/pool/show.html.erb~

diff --git a/src/app/controllers/pool_controller.rb 
b/src/app/controllers/pool_controller.rb
index d5fc8af..632d0cb 100644
--- a/src/app/controllers/pool_controller.rb
+++ b/src/app/controllers/pool_controller.rb
@@ -143,8 +143,32 @@ class PoolController < ApplicationController
 
   def quota
     @pool = Pool.find(params[:id])
-    puts @pool.id
-    @quota = Quota.find(:first, :conditions => { :pool_id => @pool })
+    if Quota.exists?(@pool.quota_id)
+      @quota = Quota.find(@pool.quota_id)
+    end
+    require_privilege(Privilege::QUOTA_VIEW, @pool)
+  end
+
+  def new_quota
+    @pool = Pool.find(params[:id])
+    require_privilege(Privilege::POOL_MODIFY, @pool)
+  end
+
+  def create_quota
+    if !Quota.exists?(@pool.quota_id)
+      @pool = Pool.find(params[:pool][:id])
+      require_privilege(Privilege::POOL_MODIFY, @pool)
+
+      @quota = Quota.new(params[:quota])
+      @quota.save!
+
+      @pool.quota_id = @quota
+      @pool.save!
+
+      redirect_to :action => 'quota', :id => @pool
+    else
+      errors.add("quota_id", "There already exists a quota for this pool")
+    end
   end
 
-end
+end
\ No newline at end of file
diff --git a/src/app/controllers/pool_controller.rb~ 
b/src/app/controllers/pool_controller.rb~
new file mode 100644
index 0000000..137fdd5
--- /dev/null
+++ b/src/app/controllers/pool_controller.rb~
@@ -0,0 +1,138 @@
+#
+# Copyright (C) 2009 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA  02110-1301, USA.  A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+# Filters added to this controller apply to all controllers in the application.
+# Likewise, all the methods added will be available for all controllers.
+
+require 'util/taskomatic'
+
+class PoolController < ApplicationController
+  before_filter :require_user
+
+  def index
+    render :action => 'new'
+  end
+
+  def show
+    #FIXME: clean this up, many error cases here
+    @pool = Pool.find(params[:id])
+    require_privilege(Privilege::INSTANCE_VIEW,@pool)
+    # pass nil into Taskomatic as we're not working off a task here
+    Taskomatic.new(nil,logger).pool_refresh(@pool)
+    @pool.reload
+    @instances = @pool.instances
+  end
+
+  def hardware_profiles
+    @pool = Pool.find(params[:id])
+    @hardware_profiles = @pool.hardware_profiles
+    require_privilege(Privilege::POOL_VIEW, @pool)
+  end
+
+  def realms
+    @pool = Pool.find(params[:id])
+    @realm_names = @pool.realms
+    require_privilege(Privilege::POOL_VIEW,@pool)
+  end
+
+  def new
+    require_privilege(Privilege::POOL_MODIFY)
+    @pool = Pool.new
+  end
+
+  def create
+    require_privilege(Privilege::POOL_MODIFY)
+
+    #FIXME: owner is set to current user for self-service account creation,
+    # but in the more general case we need a way for the admin to pick
+    # a user
+    params[:pool][:owner_id] = @current_user.id
+
+    #FIXME: This should probably be in a transaction
+    @pool = Pool.new(params[:pool])
+    perm = Permission.new(:user => @pool.owner,
+                          :role => Role.find_by_name("Instance Creator and 
User"),
+                          :permission_object => @pool)
+    perm.save!
+    # FIXME: do we need any more handling around save failures? What if perm
+    #        creation fails?
+    flash[:notice] = "Pool added."
+    redirect_to :action => 'show', :id => @pool.id
+  end
+
+  def delete
+  end
+
+  def instances_paginate
+    @pool = Pool.find(params[:id])
+    require_privilege(Privilege::POOL_VIEW, @pool)
+
+    # datatables sends pagination in format:
+    #   iDisplayStart - start index
+    #   iDisplayLength - num of recs
+    # => we need to count page num
+    page = params[:iDisplayStart].to_i / Instance::per_page
+
+    order_col_rec = Instance::COLUMNS[params[:iSortCol_0].to_i]
+    order_col = Instance::COLUMNS[2] unless order_col_rec && 
order_col_rec[:opts][:searchable]
+    order = order_col[:id] + " " + (params[:sSortDir_0] == 'desc' ? 'desc' : 
'asc')
+
+    @instances = Instance.search_filter(params[:sSearch], 
Instance::SEARCHABLE_COLUMNS).paginate(
+      :page => page + 1,
+      :order => order,
+      :conditions => {:pool_id => @pool.id}
+    )
+
+    render :json => {
+      :sEcho => params[:sEcho],
+      :iTotalRecords => @instances.total_entries,
+      :iTotalDisplayRecords => @instances.total_entries,
+      :aaData => @instances.map {|i| [i.id, "", i.name, i.state, 
i.hardware_profile.name, i.image.name]}
+    }
+  end
+
+
+  def accounts_for_pool
+    @pool =  Pool.find(params[:pool_id])
+    require_privilege(Privilege::ACCOUNT_VIEW,@pool)
+    @cloud_accounts = []
+    all_accounts = CloudAccount.list_for_user(@current_user, 
Privilege::ACCOUNT_ADD)
+    all_accounts.each {|account|
+      @cloud_accounts << account unless @pool.cloud_accounts.map{|x| 
x.id}.include?(account.id)
+    }
+  end
+
+  def add_account
+    @pool = Pool.find(params[:pool])
+    @cloud_account = CloudAccount.find(params[:cloud_account])
+    require_privilege(Privilege::ACCOUNT_ADD,@pool)
+    require_privilege(Privilege::ACCOUNT_ADD,@cloud_account)
+    Pool.transaction do
+      @pool.cloud_accounts << @cloud_account unless 
@pool.cloud_accounts.map{|x| x.id}.include?(@cloud_account.id)
+      @pool.save!
+      @pool.populate_realms_and_images([...@cloud_account])
+    end
+    redirect_to :action => 'show', :id => @pool.id
+  end
+
+  def quota
+    @pool = Pool.find(params[:id])
+    puts @pool.id
+    @quota = Quota.find(:first, :conditions => { :pool_id => @pool })
+  end
+end
diff --git a/src/app/models/instance_observer.rb 
b/src/app/models/instance_observer.rb
index ab1a095..9b0461a 100644
--- a/src/app/models/instance_observer.rb
+++ b/src/app/models/instance_observer.rb
@@ -1,6 +1,6 @@
 class InstanceObserver < ActiveRecord::Observer
 
-  ACTIVE_STATES = [ Instance::STATE_PENDING, Instance::STATE_RUNNING, 
Instance::STATE_SHUTTING_DOWN ]
+  ACTIVE_STATES = [ Instance::STATE_NEW, Instance::STATE_PENDING, 
Instance::STATE_RUNNING, Instance::STATE_SHUTTING_DOWN, Instance::STATE_STOPPED 
]
 
   def before_save(an_instance)
     if an_instance.changed?
@@ -34,7 +34,8 @@ class InstanceObserver < ActiveRecord::Observer
   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 })
+    pool = Pool.find(an_instance.pool_id)
+    quota = Quota.find(pool.quota_id)
 
     if(quota)
       if state_to == Instance::STATE_RUNNING
@@ -43,7 +44,7 @@ class InstanceObserver < ActiveRecord::Observer
         quota.running_memory += hwp.memory
       elsif state_from == Instance::STATE_RUNNING
         #TODO update running cpus
-        quota.running_instances --
+        quota.running_instances -= 1
         quota.running_memory -= hwp.memory
       end
 
@@ -55,7 +56,7 @@ class InstanceObserver < ActiveRecord::Observer
         quota.total_instances -= 1
       end
 
-      quota.save
+      quota.save!
     end
   end
 end
diff --git a/src/app/views/pool/new_quota.html.erb 
b/src/app/views/pool/new_quota.html.erb
new file mode 100644
index 0000000..4290862
--- /dev/null
+++ b/src/app/views/pool/new_quota.html.erb
@@ -0,0 +1,18 @@
+<div class="dcloud_form">
+  <%= error_messages_for 'pool' %>
+
+  <h2>Create Quota for Pool: <%= @pool.name %></legend></h2><br />
+
+  <% form_tag :action => 'create_quota' do -%>
+    <%=hidden_field :pool, :id %>
+    <ul>
+      <li><label>Max Running Instances</label><%= text_field :quota, 
:maximum_running_instances %></li>
+         <li><label>Max Running Memory</label><%= text_field :quota, 
:maximum_running_memory %></li>
+         <li><label>Max Running CPUs</label><%= text_field :quota, 
:maximum_running_cpus %></li>
+         <li><label>Max Total Instances</label><%= text_field :quota, 
:maximum_total_instances %></li>
+         <li><label>Max Total Storage</label><%= text_field :quota, 
:maximum_total_storage %></li>
+    </ul>
+    </fieldset>
+    <%= submit_tag "Save", :class => "submit" %>
+  <% end %>
+</div>
\ No newline at end of file
diff --git a/src/app/views/pool/quota.html.erb 
b/src/app/views/pool/quota.html.erb
index edd4463..09b227e 100644
--- a/src/app/views/pool/quota.html.erb
+++ b/src/app/views/pool/quota.html.erb
@@ -1,5 +1,6 @@
-<% if @quota == nil %>
+<% if !...@quota %>
 <h1>There is no quota associated with this pool</h1>
+<%= link_to "Create a Quota", {:controller => "pool", :action => "new_quota", 
:id => @pool}, :class=>"actionlink"%>
 <% else %>
     <table>
       <thead>
diff --git a/src/app/views/pool/show.html.erb~ 
b/src/app/views/pool/show.html.erb~
new file mode 100644
index 0000000..2b46781
--- /dev/null
+++ b/src/app/views/pool/show.html.erb~
@@ -0,0 +1,42 @@
+<script type="text/javascript">
+  function clickRow(ev) {
+    var box = $('input[name="image_id[]"]', ev.target.parentNode);
+    if ($(ev.target).attr('name') != "image_id[]")
+      box.attr('checked', !box.attr('checked'));
+  }
+
+  function checkAll(ev) {
+    $('input[name="image_id[]"]', dataTable_instances_table).attr('checked', 
$(ev.target).attr('checked'))
+  }
+</script>
+
+<%= datatable(
+  Instance::COLUMNS.map {|c| c[:opts]},
+  {
+    :table_dom_id => 'instances_table',
+    :per_page => Instance::per_page,
+    :sort_by => "[3, 'asc']",
+    :serverside => true,
+    :ajax_source => url_for(:controller => 'pool', :action => 
'instances_paginate') + "/#[email protected]}",
+    :append => ".fnSetFilteringDelay()",
+    :persist_state => false,
+    :click_callback => "function(ev) {clickRow(ev);}",
+  }
+) %>
+
+<table class="datatable display" id="instances_table">
+  <thead>
+    <tr>
+        <% Instance::COLUMNS.each do |c| %>
+          <%= "<th>#{c[:header]}</th>" %>
+        <% end %>
+    </tr>
+  </thead>
+  <tbody>
+  </tbody>
+</table>
+<%= link_to "Add a new instance", {:controller => "instance", :action => 
"new", "instance[pool_id]" => @pool}, :class=>"actionlink"%>
+<%= link_to "User access",  {:controller => "permissions", :action => "list", 
:pool_id => @pool.id}, :class=>"actionlink" if has_view_perms? %>
+<%= link_to "Hardware Profiles",  {:action => "hardware_profiles", :id => 
@pool.id}, :class=>"actionlink"%>
+<%= link_to "Realms",  {:action => "realms", :id => @pool.id}, 
:class=>"actionlink"%>
+<%= link_to "Quota",  {:action => "quota", :id => @pool}, 
:class=>"actionlink"%>
diff --git a/src/config/environment.rb b/src/config/environment.rb
index 1721126..9f0fa4f 100644
--- a/src/config/environment.rb
+++ b/src/config/environment.rb
@@ -43,7 +43,7 @@ Rails::Initializer.run do |config|
   config.gem "gettext",     :lib => "gettext_rails"
   config.gem "gettext", :lib => "gettext_activerecord"
   config.gem "authlogic"
-  config.gem "deltacloud-client", :lib => "deltacloud"
+  config.gem "deltacloud-cliesrc/config/environment.rbnt", :lib => "deltacloud"
   config.gem "haml"
   config.gem "will_paginate"
 
diff --git a/src/db/migrate/20090802000000_create_quotas.rb 
b/src/db/migrate/20090802000000_create_quotas.rb
index 29cc5bf..01c885d 100644
--- a/src/db/migrate/20090802000000_create_quotas.rb
+++ b/src/db/migrate/20090802000000_create_quotas.rb
@@ -20,12 +20,6 @@
 class CreateQuotas < ActiveRecord::Migration
   def self.up
     create_table :quotas do |t|
-      t.integer :running_cpus
-      t.integer :running_memory
-      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
diff --git a/src/spec/models/instance_observer_spec.rb 
b/src/spec/models/instance_observer_spec.rb
index 76514e5..7051955 100644
--- a/src/spec/models/instance_observer_spec.rb
+++ b/src/spec/models/instance_observer_spec.rb
@@ -4,7 +4,10 @@ describe InstanceObserver do
 
   before(:each) do
    @timestamp = Time.now
-   @instance = Factory :new_instance
+   @hwp = Factory :mock_hwp1
+   @pool = Factory :pool
+   @quota = Factory(:quota, :pool_id => @pool.id)
+   @instance = Factory(:new_instance, :pool => @pool, :hardware_profile => 
@hwp)
   end
 
   it "should set started at timestamp when instance goes to state pending" do
@@ -55,7 +58,7 @@ describe InstanceObserver do
     sleep(1)
 
     @instance.state = Instance::STATE_SHUTTING_DOWN
-    @instance.save
+    @instance.save!
 
     @instance.acc_running_time.should >= 1
     @instance.acc_running_time.should <= 2
@@ -87,22 +90,51 @@ describe InstanceObserver do
     @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)
+  it "should update quota when a new pool instance is created" do
+    @quota = Quota.find(@quota)
+
+    @quota.total_instances.should == 1
+    @quota.total_storage.should == @hwp.storage
+  end
+
+  it "should update quota when a pool instance goes into an inactive state" do
+    @quota = Quota.find(@quota)
+
+    @instance.state = Instance::STATE_CREATE_FAILED
+    @quota.total_instances.should == 0
+    @quota.total_storage.should == 0
+  end
+
+  it "should update a pools quota when an pool instance state goes to running" 
do
+    @quota = Quota.find(@quota)
+
+    @instance.state = Instance::STATE_RUNNING
+    @instance.save!
 
-    instance.state = Instance::STATE_RUNNING
-    instance.save
+    @quota = Quota.find(@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
+
+  it "should update a pools quota when an associated instance state goes from 
running another active state" do
+    @quota = Quota.find(@quota)
+
+    @instance.state = Instance::STATE_RUNNING
+    @instance.save!
+
+    @instance.state = Instance::STATE_SHUTTING_DOWN
+    @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.running_instances.should == 0
+    @quota.running_memory.should == 0
 
-    quota.total_storage.should == hwp.storage
-    quota.total_instances.should == 1
+    @quota.total_storage.should == @hwp.storage
+    @quota.total_instances.should == 1
   end
 
 end
\ No newline at end of file
-- 
1.6.6.1

_______________________________________________
deltacloud-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/deltacloud-devel

Reply via email to