[PATCH aggregator] initial dbomatic implementation (rev 3)
by Mo Morsi
As with the previous revisions make sure to add the following
to /var/lib/condor/condor_config.local
EVENT_LOG=$(LOG)/EventLog
EVENT_LOG_USE_XML=True
EVENT_LOG_JOB_AD_INFORMATION_ATTRS=Owner,GlobalJobId,Cmd,JobStartDate,JobCurrentStartDate,JobFinishedHookDone
and set CONDOR_HOST appropriately. Make sure to restart condor after these changes.
---
src/app/models/instance_event.rb | 26 +++++
src/app/util/condormatic.rb | 2 +-
.../20100810221250_create_instance_events.rb | 34 ++++++
src/dbomatic/dbomatic.rb | 114 ++++++++++++++++++++
4 files changed, 175 insertions(+), 1 deletions(-)
create mode 100644 src/app/models/instance_event.rb
create mode 100644 src/db/migrate/20100810221250_create_instance_events.rb
create mode 100644 src/dbomatic/dbomatic.rb
diff --git a/src/app/models/instance_event.rb b/src/app/models/instance_event.rb
new file mode 100644
index 0000000..5076f8a
--- /dev/null
+++ b/src/app/models/instance_event.rb
@@ -0,0 +1,26 @@
+# Copyright (C) 2010 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.
+
+class InstanceEvent < ActiveRecord::Base
+ belongs_to :instance
+
+ validates_presence_of :instance_id
+ validates_presence_of :event_type
+end
diff --git a/src/app/util/condormatic.rb b/src/app/util/condormatic.rb
index 3491f7f..9ac4b45 100644
--- a/src/app/util/condormatic.rb
+++ b/src/app/util/condormatic.rb
@@ -41,7 +41,7 @@ def condormatic_instance_create(task)
pipe.puts "log = #{job_log}\n"
Rails.logger.info "log = #{job_log}\n"
- requirements = "requirements = hardwareprofile == \"#{instance.hardware_profile.id}\" && image == \"#{instance.image.id}\""
+ requirements = "requirements = hardwareprofile == \"#{instance.hardware_profile.external_key}\" && image == \"#{instance.image.external_key}\""
requirements += " && realm == \"#{realm.name}\"" if realm != nil
requirements += "\n"
diff --git a/src/db/migrate/20100810221250_create_instance_events.rb b/src/db/migrate/20100810221250_create_instance_events.rb
new file mode 100644
index 0000000..22e5191
--- /dev/null
+++ b/src/db/migrate/20100810221250_create_instance_events.rb
@@ -0,0 +1,34 @@
+# Copyright (C) 2010 Red Hat, Inc.
+# Written by Mohammed Morsi <mmorsi(a)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 CreateInstanceEvents < ActiveRecord::Migration
+ def self.up
+ create_table :instance_events do |t|
+ t.integer :instance_id, :null => false
+ t.string :event_type, :null => false
+ t.datetime :event_time
+ t.string :status
+ t.string :message
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :instance_events
+ end
+end
diff --git a/src/dbomatic/dbomatic.rb b/src/dbomatic/dbomatic.rb
new file mode 100644
index 0000000..1fd8948
--- /dev/null
+++ b/src/dbomatic/dbomatic.rb
@@ -0,0 +1,114 @@
+# Copyright (C) 2010 Red Hat, Inc.
+# Written by Mohammed Morsi <mmorsi(a)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.
+
+$: << File.join(File.dirname(__FILE__), "../dutils")
+require 'dutils'
+require 'nokogiri'
+require 'rb-inotify'
+
+CONDOR_EVENT_LOG_DIR = "/var/log/condor"
+CONDOR_EVENT_LOG_FILE = "#{CONDOR_EVENT_LOG_DIR}/EventLog"
+EVENT_LOG_POS_FILE = "/var/run/dbomatic/event_log_position"
+
+# Handle the event log's xml
+class CondorEventLog < Nokogiri::XML::SAX::Document
+ attr_accessor :tag, :event_type, :event_cmd, :event_time
+
+ # Store the name of the event log attribute we're looking at
+ def start_element(element, attributes)
+ @tag = attributes[1] if element == "a"
+ end
+
+ # Store the value of the event log attribute we're looking at
+ def characters(string)
+ unless string.strip == ""
+ if @tag == "MyType"
+ @event_type = string
+ elsif @tag == "Cmd"
+ @event_cmd = string
+ elsif @tag == "EventTime"
+ @event_time = string
+ end
+ end
+ end
+
+ # Create a new entry for events which we have all the neccessary data for
+ def end_element(element)
+ if element == "c" && !(a)event_cmd.nil?
+ # Condor may write to event log before condormatic returns and instance
+ # table is updated. Extract instance name from event_cmd and query on that
+ inst_name = @event_cmd[4,(a)event_cmd.size-4].gsub(/_[0-9]*$/, '')
+ inst = Instance.find(:first, :conditions => ['name = ?', inst_name])
+ puts "Instance event #{inst.name} #{@event_type} #{@event_time}"
+ InstanceEvent.create! :instance => inst,
+ :event_type => @event_type,
+ :event_time => @event_time
+ @tag = @event_type = @event_cmd = @event_time = nil
+ end
+ end
+end
+parser = Nokogiri::XML::SAX::PushParser.new(CondorEventLog.new)
+
+# XXX hack, condor event log doesn't seem to have a top level element
+# enclosing everything else in the doc (as standards conforming xml must).
+# Create one for parsing purposes.
+parser << "<events>"
+
+def parse_log_file(log_file, parser)
+ while s = log_file.gets
+ parser << s
+ end
+ File.open(EVENT_LOG_POS_FILE, 'w') { |f| f.write log_file.pos.to_s }
+end
+
+notifier = INotify::Notifier.new
+log_file = nil
+
+if File.exists? CONDOR_EVENT_LOG_FILE
+ log_file = File.open(CONDOR_EVENT_LOG_FILE)
+
+ # persistantly store log position in filesystem
+ # incase of dbomatic restarts
+ if File.exists?(EVENT_LOG_POS_FILE)
+ File.open(EVENT_LOG_POS_FILE, 'r') { |f| log_file.pos = f.read.to_i }
+ end
+
+ # Setup inotify watch for condor event log
+ notifier.watch(CONDOR_EVENT_LOG_FILE, :modify){ |event|
+ parse_log_file log_file, parser
+ }
+
+# if log file doesn't exist wait until it does
+else
+ notifier.watch(CONDOR_EVENT_LOG_DIR, :create){ |event|
+ if event.name == "EventLog"
+ log_file = File.open(CONDOR_EVENT_LOG_FILE)
+ parse_log_file log_file, parser
+
+ # Setup inotify watch for condor event log
+ notifier.watch(CONDOR_EVENT_LOG_FILE, :modify){ |event|
+ parse_log_file log_file, parser
+ }
+ end
+ }
+end
+
+notifier.run
+
+parser << "</events>"
+parser.finish
--
1.7.2.1
13 years, 8 months
[ANNOUNCE] Third milestone release of RHEV-M REST API
by Eoghan Glynn
Hi All,
We're happy to announce the third milestone release of the REST API
for Red Hat Enterprise Virtualization Manager.
Linux and Windows distributions of 0.9-milestone3 may be downloaded
from [1].
Signed individual artifacts are also deployed to maven and synch'd up
to the Central repository [2].
Highlights of this milestone release are summarized below, with the
corresponding trac[3] ticket ID specified where appropriate.
Main API additions:
- Users and roles resources
- Support for snapshots (#23)
- Support for iSCSI and FCP storage domains (#59)
- A storage collection under host resources (#59)
- Support for adding/removing a network to/from a cluster (#57)
- A NICs collection under host resources (#57)
- Support for managing bonded NICs (#57)
- Cluster compatibility levels (#25)
- A versioned capabilities resource (#19)
- Support for managing the users attached to a VM (#36)
- VM display details and "ticket" action (#24)
- Boot options in VM and template resources (#39)
- Data center status (#45)
Improvements to the API implementation:
- Re-use powershell instances to greatly speed up API accesses
- Improved error reporting for missing required parameters (#40)
- Improved error reporting of authentication failures (#68, #69)
Watch out for these incompatibilities with milestone2:
- the 'cpus' collection has been moved under 'capabilities' (#25)
- the 'user\domain' convention for specifying the username in the
Authorization header is deprecated; use 'user@domain' instead (#70)
RESTEasy:
- Fix for https://jira.jboss.org/browse/RESTEASY-426 which
allows for POSTing to sub-collections (#47).
And, finally, miscellaneous bug fixes:
- Work around xerces XML parser not being thread-safe (#49)
- Fix several issues specific to running on RHEV-M 2.2 (#48)
- Fix issue with powershell instances being reaped (#58)
- Fix issue with adding VM devices (#47)
- Fix broken data center update (#51)
- Make VM type immutable post-creation (#46)
- Fix issue with CLI and env variables (#50)
- Resolve several issues when running under tomcat
As always, feedback is most welcome!
[1] https://fedorahosted.org/releases/r/h/rhevm-api
[2] http://repo2.maven.org/maven2/com/redhat/rhevm/api
[3] https://fedorahosted.org/rhevm-api/report/6
13 years, 8 months
[PATCH aggregator] Add the internationalization support
by Tomas Sedovic
From: Tomas Sedovic <tsedovic(a)redhat.com>
This is the first step towards implementing true i18n support. Right now this
just means we added a small dictionary of en locale that gets loaded for the
main navigation menu.
No language switching or anything like that yet.
---
src/app/views/layouts/_header.haml | 12 ++++++------
src/config/locales/en.yml | 7 +++++++
2 files changed, 13 insertions(+), 6 deletions(-)
create mode 100644 src/config/locales/en.yml
diff --git a/src/app/views/layouts/_header.haml b/src/app/views/layouts/_header.haml
index 013080b..0ea60bc 100644
--- a/src/app/views/layouts/_header.haml
+++ b/src/app/views/layouts/_header.haml
@@ -1,8 +1,8 @@
-- menu = [ { :text => "Dashboard", :controller => "dashboard" }, |
- { :text => "Instances", :controller => "instance" }, |
- { :text => "Templates", :controller => "image", :action => "show" }, |
+- menu = [ { :text => t(:dashboard), :controller => "dashboard" }, |
+ { :text => t(:instances), :controller => "instance" }, |
+ { :text => t(:templates), :controller => "image", :action => "show" }, |
({ :text => "Users", :controller => "permissions", :action => "list" } if @current_user && has_view_perms?(BasePermissionObject.general_permission_scope)), |
- { :text => "Settings", :controller => "settings" }, |
+ { :text => t(:settings), :controller => "settings" }, |
].find_all {|item| item != nil} |
.header_logo
%span Deltacloud Aggregator
@@ -14,5 +14,5 @@
.header_info
#hi-username
= link_to @current_user.first_name + " " + @current_user.last_name, { :controller => "users", :action => "show"} unless @current_user.nil?
- = link_to 'Log out', logout_url unless @current_user.nil?
- = link_to 'Log in', login_url if @current_user.nil?
+ = link_to t(:logout), logout_url unless @current_user.nil?
+ = link_to t(:login), login_url if @current_user.nil?
diff --git a/src/config/locales/en.yml b/src/config/locales/en.yml
new file mode 100644
index 0000000..46d0c46
--- /dev/null
+++ b/src/config/locales/en.yml
@@ -0,0 +1,7 @@
+en:
+ dashboard: Dashboard
+ instances: Instances
+ templates: Templates
+ settings: Settings
+ login: Log in
+ logout: Log out
--
1.7.2.2
13 years, 8 months
[PATCH aggregator] Updated Quota to only use Running/Total Instances
by Martyn Taylor
From: martyntaylor <mtaylor(a)redhat.com>
---
src/app/models/instance_observer.rb | 8 +---
src/app/models/quota.rb | 42 +++++++-------------
src/app/services/data_service_active_record.rb | 6 ---
src/app/views/quota/edit.html.erb | 3 -
src/db/migrate/20090802000000_create_quotas.rb | 6 ---
src/spec/factories/quota.rb | 6 ---
src/spec/models/instance_observer_spec.rb | 14 -------
.../services/data_service_active_record_spec.rb | 21 +--------
8 files changed, 18 insertions(+), 88 deletions(-)
diff --git a/src/app/models/instance_observer.rb b/src/app/models/instance_observer.rb
index 610d742..70537ac 100644
--- a/src/app/models/instance_observer.rb
+++ b/src/app/models/instance_observer.rb
@@ -43,20 +43,14 @@ class InstanceObserver < ActiveRecord::Observer
if quota
if state_to == Instance::STATE_RUNNING
quota.running_instances += 1
- quota.running_memory = quota.running_memory.to_f + hwp.memory.value.to_f
- quota.running_cpus = quota.running_cpus.to_f + hwp.cpu.value.to_f
elsif state_from == Instance::STATE_RUNNING
quota.running_instances -= 1
- quota.running_memory = quota.running_memory.to_f - hwp.memory.value.to_f
- quota.running_cpus = quota.running_cpus.to_f - hwp.cpu.value.to_f
end
if state_from != nil
if !ACTIVE_STATES.include?(state_from) && ACTIVE_STATES.include?(state_to)
- quota.total_storage = quota.total_storage.to_f + hwp.storage.value.to_f
quota.total_instances += 1
- elsif ACTIVE_STATES.include?(state_from) && !ACTIVE_STATES.include?(state_to)
- quota.total_storage = quota.total_storage.to_f - hwp.storage.value.to_f
+ elsif ACTIVE_STATES.include?(state_from) && !ACTIVE_STATES.include?(state_to)
quota.total_instances -= 1
end
end
diff --git a/src/app/models/quota.rb b/src/app/models/quota.rb
index bd228b3..f882878 100644
--- a/src/app/models/quota.rb
+++ b/src/app/models/quota.rb
@@ -21,63 +21,49 @@
class Quota < ActiveRecord::Base
+ has_one :pool
+ has_one :cloud_account
+
QuotaResource = Struct.new(:name, :used, :max, :available, :unit)
NO_LIMIT = nil
RESOURCE_RUNNING_INSTANCES = "running_instances"
- RESOURCE_RUNNING_MEMORY = "running_memory"
- RESOURCE_RUNNING_CPUS = "running_cpus"
RESOURCE_TOTAL_INSTANCES = "total_instances"
- RESOURCE_TOTAL_STORAGE = "total_storage"
RESOURCE_OVERALL = "overall"
- RESOURCE_NAMES = [ RESOURCE_RUNNING_INSTANCES, RESOURCE_RUNNING_MEMORY, RESOURCE_RUNNING_CPUS,
- RESOURCE_TOTAL_INSTANCES, RESOURCE_TOTAL_STORAGE ]
-
- has_one :pool
- has_one :cloud_account
+ RESOURCE_NAMES = [ RESOURCE_RUNNING_INSTANCES, RESOURCE_TOTAL_INSTANCES ]
def can_create_instance?(instance)
- hwp = instance.hardware_profile
-
- potential_total_storage = total_storage.to_f + hwp.storage.value.to_f
potential_total_instances = total_instances + 1
-
- # check for no quota
- if (Quota.no_limit(maximum_total_instances) || maximum_total_instances >= potential_total_instances) &&
- (Quota.no_limit(maximum_total_storage) || maximum_total_storage.to_f >= potential_total_storage.to_f)
+ if (Quota.no_limit(maximum_total_instances) || maximum_total_instances >= potential_total_instances)
return true
end
return false
end
def can_start_instance?(instance)
- hwp = instance.hardware_profile
-
potential_running_instances = running_instances + 1
- potential_running_memory = running_memory.to_f + hwp.memory.value.to_f
- potential_running_cpus = running_cpus.to_f + hwp.cpu.value.to_f
-
- if (Quota.no_limit(maximum_running_instances) || maximum_running_instances >= potential_running_instances) &&
- (Quota.no_limit(maximum_running_memory) || maximum_running_memory.to_f >= potential_running_memory) &&
- (Quota.no_limit(maximum_running_cpus) || maximum_running_cpus.to_f >= potential_running_cpus)
+ if (Quota.no_limit(maximum_running_instances) || maximum_running_instances >= potential_running_instances)
return true
end
return false
end
def quota_resources()
- quota_resources = {"running_instances" => QuotaResource.new("Running Instances", running_instances, maximum_running_instances, maximum_running_instances.to_f - running_instances.to_f, ""),
- "running_memory" => QuotaResource.new("Running Memory", running_memory, maximum_running_memory, maximum_running_memory.to_f - running_memory.to_f, "MB"),
- "running_cpus" => QuotaResource.new("Running CPUs", running_cpus, maximum_running_cpus, maximum_running_cpus.to_f - running_cpus.to_f, ""),
- "total_instances" => QuotaResource.new("Total Instances", total_instances, maximum_total_instances, maximum_total_instances.to_f - total_instances.to_f, ""),
- "total_storage" => QuotaResource.new("Total Storage", total_storage, maximum_total_storage, maximum_total_storage.to_f - total_storage.to_f, "GB")}
+ quota_resources = {"running_instances" => QuotaResource.new("Running Instances", running_instances, maximum_running_instances, nil, ""),
+ "total_instances" => QuotaResource.new("Total Instances", total_instances, maximum_total_instances, nil, "")}
quota_resources.each_value do |quota_resource|
if Quota.no_limit(quota_resource.max)
quota_resource.max = "No Limit"
quota_resource.available = "N\A"
+ else
+ quota_resource.available = quota_resource.max - quota_resource.used
+ if quota_resource.available < 0
+ quota_resource.available = quota_resource.available * -1
+ quota_resource.available = "OverLimit By: " + quota_resource.available.to_s
+ end
end
end
diff --git a/src/app/services/data_service_active_record.rb b/src/app/services/data_service_active_record.rb
index 1165621..68769ab 100644
--- a/src/app/services/data_service_active_record.rb
+++ b/src/app/services/data_service_active_record.rb
@@ -55,14 +55,8 @@ class DataServiceActiveRecord
case resource_name
when Quota::RESOURCE_RUNNING_INSTANCES
return QuotaUsagePoint.new(quota.running_instances, quota.maximum_running_instances)
- when Quota::RESOURCE_RUNNING_MEMORY
- return QuotaUsagePoint.new(quota.running_memory.to_f, quota.maximum_running_memory.to_f)
- when Quota::RESOURCE_RUNNING_CPUS
- return QuotaUsagePoint.new(quota.running_cpus.to_f, quota.maximum_running_cpus.to_f)
when Quota::RESOURCE_TOTAL_INSTANCES
return QuotaUsagePoint.new(quota.total_instances, quota.maximum_total_instances)
- when Quota::RESOURCE_TOTAL_STORAGE
- return QuotaUsagePoint.new(quota.total_storage.to_f, quota.maximum_total_storage.to_f)
when Quota::RESOURCE_OVERALL
return self.overall_usage(parent)
else
diff --git a/src/app/views/quota/edit.html.erb b/src/app/views/quota/edit.html.erb
index 5e742bb..8d9ae97 100644
--- a/src/app/views/quota/edit.html.erb
+++ b/src/app/views/quota/edit.html.erb
@@ -10,10 +10,7 @@
<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" %>
diff --git a/src/db/migrate/20090802000000_create_quotas.rb b/src/db/migrate/20090802000000_create_quotas.rb
index bfd195b..6456ff2 100644
--- a/src/db/migrate/20090802000000_create_quotas.rb
+++ b/src/db/migrate/20090802000000_create_quotas.rb
@@ -20,15 +20,9 @@
class CreateQuotas < ActiveRecord::Migration
def self.up
create_table :quotas do |t|
- t.string :running_cpus, :default => 0
- t.string :running_memory, :default => 0
t.integer :running_instances, :default => 0
- t.string :total_storage, :default => 0
t.integer :total_instances, :default => 0
- t.string :maximum_running_cpus, :default => nil
- t.string :maximum_running_memory, :default => nil
t.integer :maximum_running_instances, :default => nil
- t.string :maximum_total_storage, :default => nil
t.integer :maximum_total_instances, :default => nil
t.integer :lock_version, :default => 0
t.timestamps
diff --git a/src/spec/factories/quota.rb b/src/spec/factories/quota.rb
index 3f519ca..92c832f 100644
--- a/src/spec/factories/quota.rb
+++ b/src/spec/factories/quota.rb
@@ -1,15 +1,9 @@
Factory.define :quota do |f|
f.maximum_running_instances 10
- f.maximum_running_memory "10240"
- f.maximum_running_cpus 20
f.maximum_total_instances 15
- f.maximum_total_storage "8500"
end
Factory.define :full_quota, :parent => :quota do |f|
f.running_instances 10
- f.running_memory "10240"
- f.running_cpus 20
f.total_instances 15
- f.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 6bcb4d0..ae5ee0d 100644
--- a/src/spec/models/instance_observer_spec.rb
+++ b/src/spec/models/instance_observer_spec.rb
@@ -98,9 +98,7 @@ describe InstanceObserver do
it "should not update quota on pool and cloud account when an instance is state new" do
[@cloud_account_quota, @pool_quota].each do |quota|
quota = Quota.find(quota)
-
quota.total_instances.should == 0
- quota.total_storage.to_f.should == 0.to_f
end
end
@@ -110,9 +108,7 @@ describe InstanceObserver do
@instance.save
quota = Quota.find(quota)
-
quota.total_instances.should == 1
- quota.total_storage.to_f.should == @hwp.storage.value.to_f
end
end
@@ -122,9 +118,7 @@ describe InstanceObserver do
[@cloud_account_quota, @pool_quota].each do |quota|
quota = Quota.find(quota)
-
quota.total_instances.should == 0
- quota.total_storage.to_f.should == 0.to_f
end
end
@@ -135,10 +129,6 @@ describe InstanceObserver do
[@cloud_account_quota, @pool_quota].each do |quota|
quota = Quota.find(quota.id)
quota.running_instances.should == 1
- quota.running_memory.to_f.should == @hwp.memory.value.to_f
- quota.running_cpus.to_f.should == @hwp.cpu.value.to_f
-
- quota.total_storage.to_f.should == @hwp.storage.value.to_f
quota.total_instances.should == 1
end
end
@@ -153,11 +143,7 @@ describe InstanceObserver do
[@cloud_account_quota, @pool_quota].each do |quota|
quota = Quota.find(quota.id)
- #TODO test for cpus
quota.running_instances.should == 0
- quota.running_memory.to_f.should == 0.to_f
-
- quota.total_storage.to_f.should == @hwp.storage.value.to_f
quota.total_instances.should == 1
end
end
diff --git a/src/spec/services/data_service_active_record_spec.rb b/src/spec/services/data_service_active_record_spec.rb
index 7dd6b50..9842146 100644
--- a/src/spec/services/data_service_active_record_spec.rb
+++ b/src/spec/services/data_service_active_record_spec.rb
@@ -42,34 +42,19 @@ describe DataServiceActiveRecord do
quota = Factory(:quota,
:maximum_running_instances => 40,
- :maximum_running_memory => 10240,
- :maximum_running_cpus => 10,
:maximum_total_instances => 50,
- :maximum_total_storage => 500,
:running_instances => 20,
- :running_memory => 4096,
- :running_cpus => 7,
- :total_instances => 20,
- :total_storage => 499)
+ :total_instances => 20)
cloud_account.quota_id = quota.id
data_point = DataServiceActiveRecord.quota_usage(cloud_account, Quota::RESOURCE_RUNNING_INSTANCES)
data_point.should == DataServiceActiveRecord::QuotaUsagePoint.new(20, 40)
- data_point = DataServiceActiveRecord.quota_usage(cloud_account, Quota::RESOURCE_RUNNING_MEMORY)
- data_point.should == DataServiceActiveRecord::QuotaUsagePoint.new(4096, 10240)
-
- data_point = DataServiceActiveRecord.quota_usage(cloud_account, Quota::RESOURCE_RUNNING_CPUS)
- data_point.should == DataServiceActiveRecord::QuotaUsagePoint.new(7, 10)
-
data_point = DataServiceActiveRecord.quota_usage(cloud_account, Quota::RESOURCE_TOTAL_INSTANCES)
data_point.should == DataServiceActiveRecord::QuotaUsagePoint.new(20, 50)
- data_point = DataServiceActiveRecord.quota_usage(cloud_account, Quota::RESOURCE_TOTAL_STORAGE)
- data_point.should == DataServiceActiveRecord::QuotaUsagePoint.new(499, 500)
-
data_point = DataServiceActiveRecord.quota_usage(cloud_account, Quota::RESOURCE_OVERALL)
- data_point.should == DataServiceActiveRecord::QuotaUsagePoint.new(499, 500)
+ data_point.should == DataServiceActiveRecord::QuotaUsagePoint.new(20, 40)
end
it "should calculate the average, max and min task submission times" do
@@ -367,4 +352,4 @@ describe DataServiceActiveRecord do
interval_time += interval_length
end
end
-end
\ No newline at end of file
+end
--
1.7.1.1
13 years, 8 months
[PATCH aggregator] initial dbomatic implementation (rev 2)
by Mo Morsi
As with the first revision make sure to add the following
to /var/lib/condor/condor_config.local
EVENT_LOG=$(LOG)/EventLog
EVENT_LOG_USE_XML=True
EVENT_LOG_JOB_AD_INFORMATION_ATTRS=Owner,GlobalJobId,Cmd,JobStartDate,JobCurrentStartDate,JobFinishedHookDone
and set CONDOR_HOST appropriately. Make sure to restart condor after these changes.
---
src/app/models/instance_event.rb | 30 ++++++
.../20100810221250_create_instance_events.rb | 34 +++++++
src/dbomatic/dbomatic.rb | 98 ++++++++++++++++++++
3 files changed, 162 insertions(+), 0 deletions(-)
create mode 100644 src/app/models/instance_event.rb
create mode 100644 src/db/migrate/20100810221250_create_instance_events.rb
create mode 100644 src/dbomatic/dbomatic.rb
diff --git a/src/app/models/instance_event.rb b/src/app/models/instance_event.rb
new file mode 100644
index 0000000..cc1eaa0
--- /dev/null
+++ b/src/app/models/instance_event.rb
@@ -0,0 +1,30 @@
+# Copyright (C) 2010 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.
+
+class InstanceEvent < ActiveRecord::Base
+ belongs_to :instance
+
+ validates_presence_of :instance_id
+ validates_presence_of :event_type
+
+ #validates_inclusion_of :event_type,
+ # :in => TYPES
+
+end
diff --git a/src/db/migrate/20100810221250_create_instance_events.rb b/src/db/migrate/20100810221250_create_instance_events.rb
new file mode 100644
index 0000000..22e5191
--- /dev/null
+++ b/src/db/migrate/20100810221250_create_instance_events.rb
@@ -0,0 +1,34 @@
+# Copyright (C) 2010 Red Hat, Inc.
+# Written by Mohammed Morsi <mmorsi(a)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 CreateInstanceEvents < ActiveRecord::Migration
+ def self.up
+ create_table :instance_events do |t|
+ t.integer :instance_id, :null => false
+ t.string :event_type, :null => false
+ t.datetime :event_time
+ t.string :status
+ t.string :message
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :instance_events
+ end
+end
diff --git a/src/dbomatic/dbomatic.rb b/src/dbomatic/dbomatic.rb
new file mode 100644
index 0000000..8a05362
--- /dev/null
+++ b/src/dbomatic/dbomatic.rb
@@ -0,0 +1,98 @@
+# Copyright (C) 2010 Red Hat, Inc.
+# Written by Mohammed Morsi <mmorsi(a)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.
+
+$: << File.join(File.dirname(__FILE__), "../dutils")
+require 'dutils'
+require 'nokogiri'
+require 'rb-inotify'
+
+CONDOR_EVENT_LOG_FILE = "/var/log/condor/EventLog"
+EVENT_LOG_POS_FILE = "/var/run/dbomatic/event_log_position"
+
+# Handle the event log's xml
+class CondorEventLog < Nokogiri::XML::SAX::Document
+ attr_accessor :tag, :event_type, :event_cmd, :event_time
+
+ # Store the name of the event log attribute we're looking at
+ def start_element(element, attributes)
+ @tag = attributes[1] if element == "a"
+ end
+
+ # Store the value of the event log attribute we're looking at
+ def characters(string)
+ unless string.strip == ""
+ if @tag == "MyType"
+ @event_type = string
+ elsif @tag == "Cmd"
+ @event_cmd = string
+ elsif @tag == "EventTime"
+ @event_time = string
+ end
+ end
+ end
+
+ # Create a new entry for events which we have all the neccessary data for
+ def end_element(element)
+ if element == "c" && !(a)event_cmd.nil?
+ # Condor may write to event log before condormatic returns and instance
+ # table is updated. Extract instance name from event_cmd and query on that
+ inst_name = @event_cmd[4,(a)event_cmd.size-4].gsub(/_[0-9]*$/, '')
+ inst = Instance.find(:first, :conditions => ['name = ?', inst_name])
+ #puts "Instance event #{inst.name} #{@event_type} #{@event_time}"
+ InstanceEvent.create! :instance => inst,
+ :event_type => @event_type,
+ :event_time => @event_time
+ @tag = @event_type = @event_cmd = @event_time = nil
+ end
+ end
+end
+parser = Nokogiri::XML::SAX::PushParser.new(CondorEventLog.new)
+
+# XXX hack, condor event log doesn't seem to have a top level element
+# enclosing everything else in the doc (as standards conforming xml must).
+# Create one for parsing purposes.
+parser << "<events>"
+
+# last time the event log was modified
+#event_log_timestamp = nil
+
+# last position we've read in the log
+event_log_position = 0
+
+# persistantly store log position in filesystem
+# incase of dbomatic restarts
+if File.exists?(EVENT_LOG_POS_FILE)
+ event_log_position = File.open(EVENT_LOG_POS_FILE, 'r').read.to_i
+end
+
+log_file = File.open(CONDOR_EVENT_LOG_FILE)
+log_file.pos = event_log_position
+
+# Setup inotify watch for condor event log
+notifier = INotify::Notifier.new
+notifier.watch(CONDOR_EVENT_LOG_FILE, :modify){ |event|
+ while s = log_file.gets
+ parser << s
+ end
+ event_log_position = log_file.pos
+ File.open(EVENT_LOG_POS_FILE, 'w') { |f| f.write event_log_position.to_s }
+}
+notifier.run
+
+parser << "</events>"
+parser.finish
--
1.7.2.1
13 years, 8 months
[PATCH] Remove the woefully out-of-date and misleading README.
by Chris Lalancette
All documentation should now be in the docs directory anyway.
Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
---
README | 150 ----------------------------------------------------------------
1 files changed, 0 insertions(+), 150 deletions(-)
delete mode 100644 README
diff --git a/README b/README
deleted file mode 100644
index 698fce4..0000000
--- a/README
+++ /dev/null
@@ -1,150 +0,0 @@
-Deltacloud Portal provides a web UI in front of the Deltacloud API. With Deltacloud Portal, your users can:
-
- * View image status and stats across clouds, all in one place
- * Migrate instances from one cloud to another
- * Manage images locally and provision them on any cloud
-
-
-=== Preface ===
-
-There are three ways you can install the portal application (though all require the framework to be set up as well):
- 1. Install the RPM, found here: http://deltacloud.org/download.html (Note that since this is not in a yum repo yet, you will have to install whatever dependencies this fails on)
- 2. Build the RPM from source (this will also get you a local yum repo, so you get all dependencies for 'free')
- 3. Run as a development build from the directory of your choice, using rails scripts
-
-
-=== Section 1 - Prerequisites ===
-
-1. A working install of Fedora 11 (or any other platform that supports at least Ruby on Rails 2.3.2)
-2. Set up the framework application, as we need that for the portal to talk to:
- A. Create some directory to hold all the deltacloud projects
- B. 'git clone' the following (this process will be simplified soon):
- * git://git.fedorahosted.org/git/deltacloud/framework.git/
- * git://git.fedorahosted.org/git/deltacloud/driver-mock.git/
- * git://git.fedorahosted.org/git/deltacloud/client-ruby.git/
- * (the following two are optional)
- * git://git.fedorahosted.org/git/deltacloud/driver-ec2.git/
- * git://git.fedorahosted.org/git/deltacloud/driver-rhevm.git/
- C. Follow the directions in the framework README to set it up. We recommend using the mock driver to start with for simplicity, which has a un/pw in client-ruby/credentials.yml
-
-
-=== Section 2 - Installing the RPM ===
-
- NOTE: until we get an RPM of authlogic built, you must install this manually
- with 'sudo gem install authlogic'. This will eventually be an RPM dependency
- for deltacloud-portal.
-
- 1. Get the RPM from http://deltacloud.org/download.html
- 2. install with rpm -ivh <rpm>
- 3. You will need the following, though you may wish to just get the list from trying to install the RPM above, and try again:
- * httpd >= 2.0
- * postgresql-server
- * pwgen
- * ruby >= 1.8.1
- * ruby-flexmock
- * ruby-postgres
- * rubygem(activeldap) >= 0.10.0
- * rubygem(activerecord) >= 2.1.1-2
- * rubygem(gettext_rails)
- * rubygem(thin) >= 1.2.5
- * rubygem(rails) >= 2.3.2
- 4. Continue to Section 5 - Database setup
-
-
-=== Section 3 - Building the RPM ===
-
- NOTE: until we get an RPM of authlogic built, you must install this manually
- with 'sudo gem install authlogic'. This will eventually be an RPM dependency
- for deltacloud-portal.
-
-(# denotes root below)
-
-1. First, get a fully updated F11 installed.
-
-2. Set up passwordless sudo:
-
-# visudo
-
-And add the following line:
-
-<your_username> ALL=(ALL) NOPASSWD: ALL
-
-Save and quit visudo.
-
-3. Set up a minimal rpmmacros file.
-
-echo "%_topdir %(echo \$HOME)/rpmbuild" > ~/.rpmmacros
-
-4. From root of wherever you checked out the project:
-
-./autogen.sh; make publish
-
-5. Create /etc/yum.repos.d/deltacloud-local.repo, change the baseurl to your local deltacloud-cache/deltacloud directory, which you created above.
-
-[deltacloud-local]
-name=Deltacloud-local
-baseurl=file:///home/deltacloud-user/deltacloud-cache/deltacloud
-enabled=1
-metadata_expire=1
-gpgcheck=0
-
-6. # yum install deltacloud-portal
-
-7. Continue to Section 5 - Database setup
-
-
-=== Section 4 - Development setup ===
-
-If you will be developing, you need to get the source code from our git repository:
- git clone git://git.fedorahosted.org/git/deltacloud/portal.git/
-
-The Deltacloud Portal depends on deltacloud-client-ruby. This has a gemspec available, but currently the easiest way to include it in the app is to check it out into vendor/plugins in the portal app like this:
- [user@plugins]$ git clone git://git.fedorahosted.org/git/deltacloud/client-ruby.git/
-
-This will allow the portal to load it up as a plugin with no additional configuration needed.
-
-Next, you need to have the correct rubygems installed. If you followed the steps in 'Section 3 - Building the RPM', you can safely skip this step, as the dependencies should all be installed already. Assuming you have ruby and rails installed, you can get a basic app running pretty simply. If you try to start the application, you should get a warning from rails telling you which gems are missing. At this point, you can either install the missing gems with yum (most should be available in RPM format for fedora users), or gem install <gemname> (you may wish to do that as root, depending on your system configuration).
-
-
-=== Section 5 - Database setup ===
-
- 1. Assuming you have installed postgres and the ruby-postgres package, you now need to configure your postgres database. This entails running initdb and starting postgres (for Fedora users, this would be:
- * sudo /sbin/service postgresql initdb
- * sudo /sbin/service postgresql start
- 2. Next, switch to the postgres user (on Fedora - sudo su - postgres):
- * $ psql
- * $ CREATE USER dcloud WITH PASSWORD 'v23zj59an' CREATEDB;
- * $ \q
- * $ exit
- 3. On a local system you may need to edit pg_hba.conf to have only the following:
- *(/var/lib/pgsql/data/pg_hba.conf)
- * local all all trust
- * host all all 127.0.0.1 255.255.255.255 trust
- 4. From wherever you have the portal app, in the src dir, run the following commands to set up the tables:
- * rake db:create:all
- * rake db:migrate (if you want production rather than the default of 'development', simply export RAILS_ENV=production before running this command)
- * rake db:test:prepare
-
-
-=== Section 6 - Finishing Setup ===
-
-You should now have everyting configured and installed to run the portal. If you followed either of the RPM instructions, you can now run:
- * service deltacloud-aggregator start
-
-If you followed the development steps:
- * cd to your src directory and run ruby script/server
-
-Lastly, you will need one or more instances of the Deltacloud framework running for the portal to talk to. Directions for this can be found in the framework documentation(which can be found here: git://git.fedorahosted.org/git/deltacloud/framework.git/). Assuming everything is installed for that, start a framework up in the framework directory with 'ruby script/server -p 3001' (so it is on a different port than our portal app). You should now be ready to try out the portal application.
-
-
-=== Getting Started ===
-
-For these steps, we will assume the mock driver is setup and running in a framework on http://localhost:3001/api, and your portal is running on http://localhost:3000 (this will just be http://localhost/deltacloud if you are running through apache, and can be started with 'service deltacloud-aggregator start')
-
-When you navigate to the main page of your app, you will be presented with an 'Add cloud provider' form. 'Name' can be whatever you like, types currently suppoerted are mock, ec2, and rhevm. 'URL' is the url pointing to your framework (http://localhost:3001/api for our example).
-
-Upon successful completion of the form, you will be brought to the main page for that provider. Here you would click 'Add a pool'. This form asks you fro the username and password for the account on the provider's service that you wish to connect to. Then just provide a name for what we will call this 'pool'. Completion of this form will attempt to connect to the provider associated with this pool and gather some information such as a list of instances that this user has access to and can be started.
-
-Completion of this form brings you to the main page for the newly created pool. Click 'Add a new instance' here. For some providers (especially ec2), it can sometimes take a little while to get all the data back, so if you go to the new instance for and see no images, you may need to wait a short time and then try again.
-
-At this point, you should have a list of available instances for your provider/pool combination, with available actions for each instance in your list. Note that in the current version, this page will need to be refreshed in order to see and changes that may occur in the 'State' column, which tells you the status of your instance.
--
1.7.2.2
13 years, 8 months
[PATCH] Add in condor_refreshd for syncing classads.
by Chris Lalancette
Currently if you restart condor while the aggregator is
running, condor will forget about all of the provider
classads the aggregator initially told it about. On a
condor restart, we need to kick the aggregator to ask for
these classads again.
Luckily, on bootup condor has a mechanism to "phone-home"
that we can hijack. Instead of phoning home, we have condor
phone this condor_refreshd daemon, which then re-advertises
all of the classads. With this in place, and the appropriate
config in condor_config.local, we can restart the aggregator
and condor independently and be sure they always know about
each other's classads.
Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
---
src/condor_refreshd/condor_refreshd.rb | 59 ++++++++++++++++++++++++++++++++
1 files changed, 59 insertions(+), 0 deletions(-)
create mode 100755 src/condor_refreshd/condor_refreshd.rb
diff --git a/src/condor_refreshd/condor_refreshd.rb b/src/condor_refreshd/condor_refreshd.rb
new file mode 100755
index 0000000..5e9dd4a
--- /dev/null
+++ b/src/condor_refreshd/condor_refreshd.rb
@@ -0,0 +1,59 @@
+#!/usr/bin/env ruby
+
+# Copyright (C) 2010 Red Hat, Inc.
+# Written by Chris Lalancette <clalance(a)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.
+
+$: << File.join(File.dirname(__FILE__), "../dutils")
+$: << File.join(File.dirname(__FILE__), "../config")
+
+require 'rubygems'
+require 'optparse'
+require 'socket'
+require 'dutils'
+
+port = 7890
+help = false
+
+optparse = OptionParser.new do |opts|
+
+opts.banner = <<BANNER
+Usage:
+condor_refreshd [options]
+
+Options:
+BANNER
+ opts.on( '-p', '--port PORT', 'Use PORT (default: 7890)') do |newport|
+ port = newport
+ end
+ opts.on( '-h', '--help', '') { help = true }
+end
+
+optparse.parse!
+
+if help
+ puts optparse
+ exit(0)
+end
+
+socket = UDPSocket.new
+socket.bind(nil, port)
+while true
+ packet = socket.recvfrom(1024)
+ puts "Doing classad sync"
+ condormatic_classads_sync
+end
--
1.7.2.2
13 years, 8 months
[PATCH] Make aggregator startup fail if running as root.
by Chris Lalancette
Since condor will not accept jobs from a root process, running
the aggregator as root is more-or-less pointless. Add in a check
in src/script/server to fail aggregator startup if running as root
so we don't get spurious bug reports about this problem.
Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
---
src/script/server | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/src/script/server b/src/script/server
index dfabcb8..e9b183a 100755
--- a/src/script/server
+++ b/src/script/server
@@ -1,3 +1,9 @@
#!/usr/bin/env ruby
+
+if Process.uid == 0 or Process.gid == 0
+ puts "Deltacloud aggregator cannot be run as root"
+ exit(1)
+end
+
require File.dirname(__FILE__) + '/../config/boot'
-require 'commands/server'
\ No newline at end of file
+require 'commands/server'
--
1.7.2.2
13 years, 8 months
Fixed bug 626960
by Jan Provazník
Hi, this patch fixes provider deletion. Disables deletion of provider when
provider's cloud accounts are not deleted because of existing instances.
13 years, 8 months
[PATCH aggregator 1/2] Install the 960 Compass plugin
by Tomas Sedovic
From: Tomas Sedovic <tsedovic(a)redhat.com>
---
src/app/stylesheets/grid.scss | 32 ++++++++++++++++++++++++++++++++
src/app/stylesheets/text.scss | 8 ++++++++
src/app/views/layouts/aggregator.haml | 2 ++
src/config/compass.rb | 2 ++
src/config/environment.rb | 1 +
src/config/initializers/compass.rb | 6 ++----
6 files changed, 47 insertions(+), 4 deletions(-)
create mode 100644 src/app/stylesheets/grid.scss
create mode 100644 src/app/stylesheets/text.scss
diff --git a/src/app/stylesheets/grid.scss b/src/app/stylesheets/grid.scss
new file mode 100644
index 0000000..bb3305f
--- /dev/null
+++ b/src/app/stylesheets/grid.scss
@@ -0,0 +1,32 @@
+/* 960 Grid System ~ Core CSS.
+ * Learn more ~ http://960.gs/
+ * *
+ * Licensed under GPL and MIT. */
+
+@import "compass/reset";
+@import "960/grid";
+
+// The following generates the default grids provided by the css version of 960.gs
+.container_12 {
+ @include grid-system(12); }
+
+.container_16 {
+ @include grid-system(16); }
+
+// But most compass users prefer to construct semantic layouts like so (two column layout with header and footer):
+
+$ninesixty-columns: 24;
+
+.two-column {
+ @include grid-container;
+ #header,
+ #footer,
+ #sidebar,
+ #main-content {
+ @include grid-unit-base; }
+ #header, #footer {
+ @include grid-width(24); }
+ #sidebar {
+ @include grid-width(8); }
+ #main-content {
+ @include grid-width(16); } }
diff --git a/src/app/stylesheets/text.scss b/src/app/stylesheets/text.scss
new file mode 100644
index 0000000..6cbabe7
--- /dev/null
+++ b/src/app/stylesheets/text.scss
@@ -0,0 +1,8 @@
+/* 960 Grid System ~ Text CSS.
+ * Learn more ~ http://960.gs/
+ * *
+ * Licensed under GPL and MIT. */
+
+@import "960/text";
+
+@include text;
diff --git a/src/app/views/layouts/aggregator.haml b/src/app/views/layouts/aggregator.haml
index 7384cf0..b9fd4df 100644
--- a/src/app/views/layouts/aggregator.haml
+++ b/src/app/views/layouts/aggregator.haml
@@ -6,6 +6,8 @@
Deltacloud
= yield :title
+ = stylesheet_link_tag 'compiled/grid.css', :media => 'screen, projection'
+ = stylesheet_link_tag 'compiled/text.css', :media => 'screen, projection'
= stylesheet_link_tag 'compiled/screen.css', :media => 'screen, projection'
= stylesheet_link_tag 'compiled/layout'
= stylesheet_link_tag 'compiled/components'
diff --git a/src/config/compass.rb b/src/config/compass.rb
index 3e772ab..985bb3a 100644
--- a/src/config/compass.rb
+++ b/src/config/compass.rb
@@ -1,5 +1,7 @@
# This configuration file works with both the Compass command line tool and within Rails.
# Require any additional compass plugins here.
+require 'ninesixty'
+
project_type = :rails
project_path = Compass::AppIntegration::Rails.root
# Set this to the root of your project when deployed:
diff --git a/src/config/environment.rb b/src/config/environment.rb
index 7863031..9158d40 100644
--- a/src/config/environment.rb
+++ b/src/config/environment.rb
@@ -51,6 +51,7 @@ Rails::Initializer.run do |config|
config.gem "gnuplot"
config.gem "scruffy"
config.gem "compass", :version => ">= 0.10.2"
+ config.gem "compass-960-plugin", :lib => "ninesixty"
config.active_record.observers = :instance_observer, :task_observer
# Only load the plugins named here, in the order given. By default, all plugins
diff --git a/src/config/initializers/compass.rb b/src/config/initializers/compass.rb
index 4375914..6811b32 100644
--- a/src/config/initializers/compass.rb
+++ b/src/config/initializers/compass.rb
@@ -1,5 +1,3 @@
require 'compass'
-rails_root = (defined?(Rails) ? Rails.root : RAILS_ROOT).to_s
-Compass.add_project_configuration(File.join(rails_root, "config", "compass.rb"))
-Compass.configure_sass_plugin!
-Compass.handle_configuration_change!
+require 'compass/app_integration/rails'
+Compass::AppIntegration::Rails.initialize!
--
1.7.2.1
13 years, 8 months