Steve Linabery
2009-Jan-08 20:48 UTC
[Ovirt-devel] [PATCH server] Add audit trail for hosts joining/leaving hwpools with Rails observer class
Modify graph_controller.rb to utilize new audit feature when generating data for
flexchart
---
src/app/controllers/graph_controller.rb | 65 +++++++++++++++++++++++++--
src/app/models/hardware_pool.rb | 2 +-
src/app/models/host.rb | 9 ++++
src/app/models/host_observer.rb | 47 ++++++++++++++++++++
src/app/models/membership_audit_event.rb | 26 +++++++++++
src/app/models/pool.rb | 1 +
src/config/environment.rb | 2 +-
src/db/migrate/033_add_pool_audit_trail.rb | 32 ++++++++++++++
8 files changed, 177 insertions(+), 7 deletions(-)
create mode 100644 src/app/models/host_observer.rb
create mode 100644 src/app/models/membership_audit_event.rb
create mode 100644 src/db/migrate/033_add_pool_audit_trail.rb
diff --git a/src/app/controllers/graph_controller.rb
b/src/app/controllers/graph_controller.rb
index ee9425f..df516f5 100644
--- a/src/app/controllers/graph_controller.rb
+++ b/src/app/controllers/graph_controller.rb
@@ -6,9 +6,9 @@ class GraphController < ApplicationController
def flexchart_data
@id = params[:id]
target = params[:target]
- startTime = params[:startTime].to_i
- endTime = params[:endTime].to_i
- duration = endTime - startTime
+ startTime = Time.at(params[:startTime].to_i)
+ endTime = Time.at(params[:endTime].to_i)
+ duration = endTime.to_i - startTime.to_i
#the maximum number of data points we want in any chart
maxPoints = 100
@@ -29,10 +29,30 @@ class GraphController < ApplicationController
counter = DEV_KEY_COUNTERS[target]
pool = Pool.find(@id)
- hosts = pool.hosts
+ hosts = Host.find(:all,
+ :include=> :membership_audit_events,
+ :conditions =>
['membership_audit_events.container_target_id = ?',pool])
+
requestList = [ ]
hosts.each{ |host|
- requestList.push StatsRequest.new(host.hostname, devclass, 0, counter,
startTime, duration, resolution, DataFunction::Peak)
+ eventsInRange = host.membership_audit_events.from_pool(pool,
+ startTime,
+ endTime)
+ priorAuditEvent =
host.membership_audit_events.most_recent_prior_event_from_pool(pool,startTime)
+ timeRanges = get_ranges_from_event_list(eventsInRange,
+ priorAuditEvent,
+ startTime,
+ endTime)
+ timeRanges.each{ |range|
+ requestList.push StatsRequest.new(host.hostname,
+ devclass,
+ 0,
+ counter,
+ range[0].to_i,
+ range[1].to_i - range[0].to_i,
+ resolution,
+ DataFunction::Peak)
+ }
}
statsList = getAggregateStatsData?(requestList)
@@ -51,6 +71,41 @@ class GraphController < ApplicationController
render :json => graph
end
+ def get_ranges_from_event_list(list, priorEvent, startTime, endTime)
+
+ results = Array.new
+ range = [startTime,endTime]
+
+ joined = false
+ if priorEvent
+ if priorEvent.action == MembershipAuditEvent::JOIN
+ joined = true
+ end
+ end
+
+ list.each_with_index { |event,index|
+ if event.action == MembershipAuditEvent::JOIN
+ joined = true
+ range[0] = event.created_at
+ else
+ range[0] = startTime unless joined
+ joined = false
+ range[1] = event.created_at
+ results.push Array.new(range)
+ range = [startTime,endTime]
+ end
+ }
+
+ if joined
+ range[1] = endTime
+ results.push Array.new(range)
+ ddebug(range)
+ end
+
+ results
+ end
+
+
# generate layout for availability bar graphs
def availability_graph
diff --git a/src/app/models/hardware_pool.rb b/src/app/models/hardware_pool.rb
index d39d8e7..b72d485 100644
--- a/src/app/models/hardware_pool.rb
+++ b/src/app/models/hardware_pool.rb
@@ -54,7 +54,7 @@ class HardwarePool < Pool
hosts = Host.find(:all, :conditions => "id in
(#{host_ids.join(', ')})")
transaction do
hosts.each do |host|
- host.hardware_pool_id = target_pool_id
+ host.hardware_pool = HardwarePool.find(target_pool_id)
host.save!
end
end
diff --git a/src/app/models/host.rb b/src/app/models/host.rb
index 640782d..813bc1d 100644
--- a/src/app/models/host.rb
+++ b/src/app/models/host.rb
@@ -23,6 +23,15 @@ class Host < ActiveRecord::Base
belongs_to :hardware_pool
belongs_to :bonding_type
+ has_many :membership_audit_events, :as => :member_target, :dependent =>
:destroy, :order => "created_at ASC" do
+ def from_pool(pool,startTime,endTime)
+ find(:all, :conditions=> ['container_target_id = ? and created_at
between ? and ?',pool,startTime,endTime])
+ end
+ def most_recent_prior_event_from_pool(pool,startTime)
+ find(:last, :conditions=> ['container_target_id = ? and created_at
< ?',pool,startTime])
+ end
+ end
+
has_many :cpus, :dependent => :destroy
has_many :nics, :dependent => :destroy
has_many :bondings, :dependent => :destroy
diff --git a/src/app/models/host_observer.rb b/src/app/models/host_observer.rb
new file mode 100644
index 0000000..df5efa1
--- /dev/null
+++ b/src/app/models/host_observer.rb
@@ -0,0 +1,47 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Steve Linabery <slinabery at redhat.com>
+#
+# 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.
+
+class HostObserver < ActiveRecord::Observer
+
+ def after_create(a_host)
+ join = MembershipAuditEvent.new({ :member_target => a_host,
+ :container_target =>
a_host.hardware_pool,
+ :action => MembershipAuditEvent::JOIN
})
+ join.save!
+ end
+
+ def before_update(a_host)
+ if a_host.changed?
+ change = a_host.changes['hardware_pool_id']
+ if change
+ leave = MembershipAuditEvent.new({ :member_target => a_host,
+ :container_target =>
HardwarePool.find(change[0]),
+ :action =>
MembershipAuditEvent::LEAVE })
+ leave.save!
+
+ join = MembershipAuditEvent.new({ :member_target => a_host,
+ :container_target =>
HardwarePool.find(change[1]),
+ :action =>
MembershipAuditEvent::JOIN })
+ join.save!
+ end
+ end
+ end
+end
+
+HostObserver.instance
diff --git a/src/app/models/membership_audit_event.rb
b/src/app/models/membership_audit_event.rb
new file mode 100644
index 0000000..b36cbee
--- /dev/null
+++ b/src/app/models/membership_audit_event.rb
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Steve Linabery <slinabery at redhat.com>
+#
+# 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.
+
+class MembershipAuditEvent < ActiveRecord::Base
+ belongs_to :container_target, :polymorphic => true
+ belongs_to :member_target, :polymorphic => true
+
+ JOIN = "join"
+ LEAVE = "leave"
+end
diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb
index 7034e79..614325a 100644
--- a/src/app/models/pool.rb
+++ b/src/app/models/pool.rb
@@ -20,6 +20,7 @@
class Pool < ActiveRecord::Base
acts_as_nested_set
+ has_many :membership_audit_events, :as => :container_target, :dependent
=> :destroy
# moved associations here so that nested set :include directives work
# TODO: find a way to put this back into vm_resource_pool.rb
has_many :vms, :dependent => :nullify, :order => "id ASC",
:foreign_key => :vm_resource_pool_id
diff --git a/src/config/environment.rb b/src/config/environment.rb
index 53edfad..66cae90 100644
--- a/src/config/environment.rb
+++ b/src/config/environment.rb
@@ -82,7 +82,7 @@ Rails::Initializer.run do |config|
# Activate observers that should always be running
# config.active_record.observers = :cacher, :garbage_collector
-
+ config.active_record.observers = :host_observer
end
# Add new inflection rules using the following format
diff --git a/src/db/migrate/033_add_pool_audit_trail.rb
b/src/db/migrate/033_add_pool_audit_trail.rb
new file mode 100644
index 0000000..656ad87
--- /dev/null
+++ b/src/db/migrate/033_add_pool_audit_trail.rb
@@ -0,0 +1,32 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Steve Linabery <slinabery at redhat.com>
+#
+# 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.
+
+class AddPoolAuditTrail < ActiveRecord::Migration
+ def self.up
+ create_table :membership_audit_events do |t|
+ t.timestamp :created_at
+ t.string :action
+ t.integer :container_target_id
+ t.string :container_target_type
+ t.integer :member_target_id
+ t.string :member_target_type
+ t.integer :lock_version, :default => 0
+ end
+ end
+end
--
1.6.0.6
Steve Linabery
2009-Jan-08 20:52 UTC
[Ovirt-devel] Re: [PATCH server] Add audit trail for hosts joining/leaving hwpools with Rails observer class
Disregard this for the moment, folks. I have to add to the migration file. On Thu, Jan 08, 2009 at 02:48:44PM -0600, Steve Linabery wrote:> Modify graph_controller.rb to utilize new audit feature when generating data for flexchart > --- > src/app/controllers/graph_controller.rb | 65 +++++++++++++++++++++++++-- > src/app/models/hardware_pool.rb | 2 +- > src/app/models/host.rb | 9 ++++ > src/app/models/host_observer.rb | 47 ++++++++++++++++++++ > src/app/models/membership_audit_event.rb | 26 +++++++++++ > src/app/models/pool.rb | 1 + > src/config/environment.rb | 2 +- > src/db/migrate/033_add_pool_audit_trail.rb | 32 ++++++++++++++ > 8 files changed, 177 insertions(+), 7 deletions(-) > create mode 100644 src/app/models/host_observer.rb > create mode 100644 src/app/models/membership_audit_event.rb > create mode 100644 src/db/migrate/033_add_pool_audit_trail.rb > > diff --git a/src/app/controllers/graph_controller.rb b/src/app/controllers/graph_controller.rb > index ee9425f..df516f5 100644 > --- a/src/app/controllers/graph_controller.rb > +++ b/src/app/controllers/graph_controller.rb > @@ -6,9 +6,9 @@ class GraphController < ApplicationController > def flexchart_data > @id = params[:id] > target = params[:target] > - startTime = params[:startTime].to_i > - endTime = params[:endTime].to_i > - duration = endTime - startTime > + startTime = Time.at(params[:startTime].to_i) > + endTime = Time.at(params[:endTime].to_i) > + duration = endTime.to_i - startTime.to_i > > #the maximum number of data points we want in any chart > maxPoints = 100 > @@ -29,10 +29,30 @@ class GraphController < ApplicationController > counter = DEV_KEY_COUNTERS[target] > > pool = Pool.find(@id) > - hosts = pool.hosts > + hosts = Host.find(:all, > + :include=> :membership_audit_events, > + :conditions => ['membership_audit_events.container_target_id = ?',pool]) > + > requestList = [ ] > hosts.each{ |host| > - requestList.push StatsRequest.new(host.hostname, devclass, 0, counter, startTime, duration, resolution, DataFunction::Peak) > + eventsInRange = host.membership_audit_events.from_pool(pool, > + startTime, > + endTime) > + priorAuditEvent = host.membership_audit_events.most_recent_prior_event_from_pool(pool,startTime) > + timeRanges = get_ranges_from_event_list(eventsInRange, > + priorAuditEvent, > + startTime, > + endTime) > + timeRanges.each{ |range| > + requestList.push StatsRequest.new(host.hostname, > + devclass, > + 0, > + counter, > + range[0].to_i, > + range[1].to_i - range[0].to_i, > + resolution, > + DataFunction::Peak) > + } > } > statsList = getAggregateStatsData?(requestList) > > @@ -51,6 +71,41 @@ class GraphController < ApplicationController > render :json => graph > end > > + def get_ranges_from_event_list(list, priorEvent, startTime, endTime) > + > + results = Array.new > + range = [startTime,endTime] > + > + joined = false > + if priorEvent > + if priorEvent.action == MembershipAuditEvent::JOIN > + joined = true > + end > + end > + > + list.each_with_index { |event,index| > + if event.action == MembershipAuditEvent::JOIN > + joined = true > + range[0] = event.created_at > + else > + range[0] = startTime unless joined > + joined = false > + range[1] = event.created_at > + results.push Array.new(range) > + range = [startTime,endTime] > + end > + } > + > + if joined > + range[1] = endTime > + results.push Array.new(range) > + ddebug(range) > + end > + > + results > + end > + > + > > # generate layout for availability bar graphs > def availability_graph > diff --git a/src/app/models/hardware_pool.rb b/src/app/models/hardware_pool.rb > index d39d8e7..b72d485 100644 > --- a/src/app/models/hardware_pool.rb > +++ b/src/app/models/hardware_pool.rb > @@ -54,7 +54,7 @@ class HardwarePool < Pool > hosts = Host.find(:all, :conditions => "id in (#{host_ids.join(', ')})") > transaction do > hosts.each do |host| > - host.hardware_pool_id = target_pool_id > + host.hardware_pool = HardwarePool.find(target_pool_id) > host.save! > end > end > diff --git a/src/app/models/host.rb b/src/app/models/host.rb > index 640782d..813bc1d 100644 > --- a/src/app/models/host.rb > +++ b/src/app/models/host.rb > @@ -23,6 +23,15 @@ class Host < ActiveRecord::Base > belongs_to :hardware_pool > belongs_to :bonding_type > > + has_many :membership_audit_events, :as => :member_target, :dependent => :destroy, :order => "created_at ASC" do > + def from_pool(pool,startTime,endTime) > + find(:all, :conditions=> ['container_target_id = ? and created_at between ? and ?',pool,startTime,endTime]) > + end > + def most_recent_prior_event_from_pool(pool,startTime) > + find(:last, :conditions=> ['container_target_id = ? and created_at < ?',pool,startTime]) > + end > + end > + > has_many :cpus, :dependent => :destroy > has_many :nics, :dependent => :destroy > has_many :bondings, :dependent => :destroy > diff --git a/src/app/models/host_observer.rb b/src/app/models/host_observer.rb > new file mode 100644 > index 0000000..df5efa1 > --- /dev/null > +++ b/src/app/models/host_observer.rb > @@ -0,0 +1,47 @@ > +# > +# Copyright (C) 2008 Red Hat, Inc. > +# Written by Steve Linabery <slinabery at redhat.com> > +# > +# 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. > + > +class HostObserver < ActiveRecord::Observer > + > + def after_create(a_host) > + join = MembershipAuditEvent.new({ :member_target => a_host, > + :container_target => a_host.hardware_pool, > + :action => MembershipAuditEvent::JOIN }) > + join.save! > + end > + > + def before_update(a_host) > + if a_host.changed? > + change = a_host.changes['hardware_pool_id'] > + if change > + leave = MembershipAuditEvent.new({ :member_target => a_host, > + :container_target => HardwarePool.find(change[0]), > + :action => MembershipAuditEvent::LEAVE }) > + leave.save! > + > + join = MembershipAuditEvent.new({ :member_target => a_host, > + :container_target => HardwarePool.find(change[1]), > + :action => MembershipAuditEvent::JOIN }) > + join.save! > + end > + end > + end > +end > + > +HostObserver.instance > diff --git a/src/app/models/membership_audit_event.rb b/src/app/models/membership_audit_event.rb > new file mode 100644 > index 0000000..b36cbee > --- /dev/null > +++ b/src/app/models/membership_audit_event.rb > @@ -0,0 +1,26 @@ > +# > +# Copyright (C) 2008 Red Hat, Inc. > +# Written by Steve Linabery <slinabery at redhat.com> > +# > +# 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. > + > +class MembershipAuditEvent < ActiveRecord::Base > + belongs_to :container_target, :polymorphic => true > + belongs_to :member_target, :polymorphic => true > + > + JOIN = "join" > + LEAVE = "leave" > +end > diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb > index 7034e79..614325a 100644 > --- a/src/app/models/pool.rb > +++ b/src/app/models/pool.rb > @@ -20,6 +20,7 @@ > class Pool < ActiveRecord::Base > acts_as_nested_set > > + has_many :membership_audit_events, :as => :container_target, :dependent => :destroy > # moved associations here so that nested set :include directives work > # TODO: find a way to put this back into vm_resource_pool.rb > has_many :vms, :dependent => :nullify, :order => "id ASC", :foreign_key => :vm_resource_pool_id > diff --git a/src/config/environment.rb b/src/config/environment.rb > index 53edfad..66cae90 100644 > --- a/src/config/environment.rb > +++ b/src/config/environment.rb > @@ -82,7 +82,7 @@ Rails::Initializer.run do |config| > > # Activate observers that should always be running > # config.active_record.observers = :cacher, :garbage_collector > - > + config.active_record.observers = :host_observer > end > > # Add new inflection rules using the following format > diff --git a/src/db/migrate/033_add_pool_audit_trail.rb b/src/db/migrate/033_add_pool_audit_trail.rb > new file mode 100644 > index 0000000..656ad87 > --- /dev/null > +++ b/src/db/migrate/033_add_pool_audit_trail.rb > @@ -0,0 +1,32 @@ > +# > +# Copyright (C) 2008 Red Hat, Inc. > +# Written by Steve Linabery <slinabery at redhat.com> > +# > +# 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. > + > +class AddPoolAuditTrail < ActiveRecord::Migration > + def self.up > + create_table :membership_audit_events do |t| > + t.timestamp :created_at > + t.string :action > + t.integer :container_target_id > + t.string :container_target_type > + t.integer :member_target_id > + t.string :member_target_type > + t.integer :lock_version, :default => 0 > + end > + end > +end > -- > 1.6.0.6 >
Steve Linabery
2009-Jan-09 01:35 UTC
[Ovirt-devel] [PATCH server] Add audit trail for hosts joining/leaving hwpools with Rails observer class
Modify graph_controller.rb to utilize new audit feature when generating data for
flexchart
---
src/app/controllers/graph_controller.rb | 65 +++++++++++++++++++++++++--
src/app/models/hardware_pool.rb | 2 +-
src/app/models/host.rb | 9 ++++
src/app/models/host_observer.rb | 47 ++++++++++++++++++++
src/app/models/membership_audit_event.rb | 26 +++++++++++
src/app/models/pool.rb | 1 +
src/config/environment.rb | 2 +-
src/db/migrate/033_add_pool_audit_trail.rb | 44 +++++++++++++++++++
8 files changed, 189 insertions(+), 7 deletions(-)
create mode 100644 src/app/models/host_observer.rb
create mode 100644 src/app/models/membership_audit_event.rb
create mode 100644 src/db/migrate/033_add_pool_audit_trail.rb
diff --git a/src/app/controllers/graph_controller.rb
b/src/app/controllers/graph_controller.rb
index ee9425f..df516f5 100644
--- a/src/app/controllers/graph_controller.rb
+++ b/src/app/controllers/graph_controller.rb
@@ -6,9 +6,9 @@ class GraphController < ApplicationController
def flexchart_data
@id = params[:id]
target = params[:target]
- startTime = params[:startTime].to_i
- endTime = params[:endTime].to_i
- duration = endTime - startTime
+ startTime = Time.at(params[:startTime].to_i)
+ endTime = Time.at(params[:endTime].to_i)
+ duration = endTime.to_i - startTime.to_i
#the maximum number of data points we want in any chart
maxPoints = 100
@@ -29,10 +29,30 @@ class GraphController < ApplicationController
counter = DEV_KEY_COUNTERS[target]
pool = Pool.find(@id)
- hosts = pool.hosts
+ hosts = Host.find(:all,
+ :include=> :membership_audit_events,
+ :conditions =>
['membership_audit_events.container_target_id = ?',pool])
+
requestList = [ ]
hosts.each{ |host|
- requestList.push StatsRequest.new(host.hostname, devclass, 0, counter,
startTime, duration, resolution, DataFunction::Peak)
+ eventsInRange = host.membership_audit_events.from_pool(pool,
+ startTime,
+ endTime)
+ priorAuditEvent =
host.membership_audit_events.most_recent_prior_event_from_pool(pool,startTime)
+ timeRanges = get_ranges_from_event_list(eventsInRange,
+ priorAuditEvent,
+ startTime,
+ endTime)
+ timeRanges.each{ |range|
+ requestList.push StatsRequest.new(host.hostname,
+ devclass,
+ 0,
+ counter,
+ range[0].to_i,
+ range[1].to_i - range[0].to_i,
+ resolution,
+ DataFunction::Peak)
+ }
}
statsList = getAggregateStatsData?(requestList)
@@ -51,6 +71,41 @@ class GraphController < ApplicationController
render :json => graph
end
+ def get_ranges_from_event_list(list, priorEvent, startTime, endTime)
+
+ results = Array.new
+ range = [startTime,endTime]
+
+ joined = false
+ if priorEvent
+ if priorEvent.action == MembershipAuditEvent::JOIN
+ joined = true
+ end
+ end
+
+ list.each_with_index { |event,index|
+ if event.action == MembershipAuditEvent::JOIN
+ joined = true
+ range[0] = event.created_at
+ else
+ range[0] = startTime unless joined
+ joined = false
+ range[1] = event.created_at
+ results.push Array.new(range)
+ range = [startTime,endTime]
+ end
+ }
+
+ if joined
+ range[1] = endTime
+ results.push Array.new(range)
+ ddebug(range)
+ end
+
+ results
+ end
+
+
# generate layout for availability bar graphs
def availability_graph
diff --git a/src/app/models/hardware_pool.rb b/src/app/models/hardware_pool.rb
index d39d8e7..b72d485 100644
--- a/src/app/models/hardware_pool.rb
+++ b/src/app/models/hardware_pool.rb
@@ -54,7 +54,7 @@ class HardwarePool < Pool
hosts = Host.find(:all, :conditions => "id in
(#{host_ids.join(', ')})")
transaction do
hosts.each do |host|
- host.hardware_pool_id = target_pool_id
+ host.hardware_pool = HardwarePool.find(target_pool_id)
host.save!
end
end
diff --git a/src/app/models/host.rb b/src/app/models/host.rb
index 640782d..813bc1d 100644
--- a/src/app/models/host.rb
+++ b/src/app/models/host.rb
@@ -23,6 +23,15 @@ class Host < ActiveRecord::Base
belongs_to :hardware_pool
belongs_to :bonding_type
+ has_many :membership_audit_events, :as => :member_target, :dependent =>
:destroy, :order => "created_at ASC" do
+ def from_pool(pool,startTime,endTime)
+ find(:all, :conditions=> ['container_target_id = ? and created_at
between ? and ?',pool,startTime,endTime])
+ end
+ def most_recent_prior_event_from_pool(pool,startTime)
+ find(:last, :conditions=> ['container_target_id = ? and created_at
< ?',pool,startTime])
+ end
+ end
+
has_many :cpus, :dependent => :destroy
has_many :nics, :dependent => :destroy
has_many :bondings, :dependent => :destroy
diff --git a/src/app/models/host_observer.rb b/src/app/models/host_observer.rb
new file mode 100644
index 0000000..df5efa1
--- /dev/null
+++ b/src/app/models/host_observer.rb
@@ -0,0 +1,47 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Steve Linabery <slinabery at redhat.com>
+#
+# 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.
+
+class HostObserver < ActiveRecord::Observer
+
+ def after_create(a_host)
+ join = MembershipAuditEvent.new({ :member_target => a_host,
+ :container_target =>
a_host.hardware_pool,
+ :action => MembershipAuditEvent::JOIN
})
+ join.save!
+ end
+
+ def before_update(a_host)
+ if a_host.changed?
+ change = a_host.changes['hardware_pool_id']
+ if change
+ leave = MembershipAuditEvent.new({ :member_target => a_host,
+ :container_target =>
HardwarePool.find(change[0]),
+ :action =>
MembershipAuditEvent::LEAVE })
+ leave.save!
+
+ join = MembershipAuditEvent.new({ :member_target => a_host,
+ :container_target =>
HardwarePool.find(change[1]),
+ :action =>
MembershipAuditEvent::JOIN })
+ join.save!
+ end
+ end
+ end
+end
+
+HostObserver.instance
diff --git a/src/app/models/membership_audit_event.rb
b/src/app/models/membership_audit_event.rb
new file mode 100644
index 0000000..b36cbee
--- /dev/null
+++ b/src/app/models/membership_audit_event.rb
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Steve Linabery <slinabery at redhat.com>
+#
+# 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.
+
+class MembershipAuditEvent < ActiveRecord::Base
+ belongs_to :container_target, :polymorphic => true
+ belongs_to :member_target, :polymorphic => true
+
+ JOIN = "join"
+ LEAVE = "leave"
+end
diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb
index 7034e79..614325a 100644
--- a/src/app/models/pool.rb
+++ b/src/app/models/pool.rb
@@ -20,6 +20,7 @@
class Pool < ActiveRecord::Base
acts_as_nested_set
+ has_many :membership_audit_events, :as => :container_target, :dependent
=> :destroy
# moved associations here so that nested set :include directives work
# TODO: find a way to put this back into vm_resource_pool.rb
has_many :vms, :dependent => :nullify, :order => "id ASC",
:foreign_key => :vm_resource_pool_id
diff --git a/src/config/environment.rb b/src/config/environment.rb
index 53edfad..66cae90 100644
--- a/src/config/environment.rb
+++ b/src/config/environment.rb
@@ -82,7 +82,7 @@ Rails::Initializer.run do |config|
# Activate observers that should always be running
# config.active_record.observers = :cacher, :garbage_collector
-
+ config.active_record.observers = :host_observer
end
# Add new inflection rules using the following format
diff --git a/src/db/migrate/033_add_pool_audit_trail.rb
b/src/db/migrate/033_add_pool_audit_trail.rb
new file mode 100644
index 0000000..07d2433
--- /dev/null
+++ b/src/db/migrate/033_add_pool_audit_trail.rb
@@ -0,0 +1,44 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Steve Linabery <slinabery at redhat.com>
+#
+# 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.
+
+class AddPoolAuditTrail < ActiveRecord::Migration
+ def self.up
+ create_table :membership_audit_events do |t|
+ t.timestamp :created_at
+ t.string :action
+ t.integer :container_target_id
+ t.string :container_target_type
+ t.integer :member_target_id
+ t.string :member_target_type
+ t.integer :lock_version, :default => 0
+ end
+
+ Host.transaction do
+ Host.find(:all).each do |host|
+
+ if (! host.membership_audit_events)
+ event = MembershipAuditEvent.new(:action =>
MembershipAuditEvent::JOIN,
+ :container_target =>
host.hardware_pool,
+ :member_target => host)
+ event.save!
+ end
+ end
+ end
+ end
+end
--
1.6.0.6