image builder - css cleanup, collapsible tree
by Jan Provazník
[PATCH aggregator 1/2]: I tried to cleanup Image Builder CSS
[PATCH aggregator 2/2]: List of selected packages on "Software" page is now collapsible in JS version (non-JS version still displays expanded list)
(this patchset depends on previous Image Builder patches)
14 years
[PATCH aggregator] Generalized Quota Usage graph methods for creation of all Quota Usage Graphs
by Martyn Taylor
From: martyntaylor <mtaylor(a)redhat.com>
---
src/app/controllers/dashboard_controller.rb | 14 ++-
src/app/models/graph.rb | 28 ++++
src/app/services/data_service.rb | 44 ++++---
src/app/services/graph_service.rb | 213 +++++++++++++++------------
src/app/views/dashboard/summary.haml | 2 +-
5 files changed, 185 insertions(+), 116 deletions(-)
diff --git a/src/app/controllers/dashboard_controller.rb b/src/app/controllers/dashboard_controller.rb
index bcd2073..f971728 100644
--- a/src/app/controllers/dashboard_controller.rb
+++ b/src/app/controllers/dashboard_controller.rb
@@ -39,9 +39,17 @@ class DashboardController < ApplicationController
end
end
- def account_quota_graph
- params[:account] = CloudAccount.find(params[:id])
- graph = GraphService.dashboard_quota(current_user, params)[params[:account]][Graph::QUOTA_INSTANCES_IN_USE]
+ def quota_usage_graph
+ if params[:cloud_account_id]
+ params[:parent] = CloudAccount.find(params[:cloud_account_id])
+ elsif params[:pool_id]
+ params[:parent] = Pool.find(params[:pool_id])
+ else
+ return nil
+ end
+
+ graphs = GraphService.dashboard_quota_usage(current_user, params)
+ graph = graphs[params[:parent]][Graph.get_quota_usage_graph_name(params[:resource_name])]
respond_to do |format|
format.svg { render :xml => graph.svg}
end
diff --git a/src/app/models/graph.rb b/src/app/models/graph.rb
index 1c20dc3..cf1b498 100644
--- a/src/app/models/graph.rb
+++ b/src/app/models/graph.rb
@@ -4,7 +4,35 @@ class Graph
QOS_AVG_TIME_TO_SUBMIT = "qos_avg_time_to_submit"
QUOTA_INSTANCES_IN_USE = "quota_instances_in_use"
INSTANCES_BY_PROVIDER_PIE = "instances_by_provider_pie"
+
+ # Quota Usage Graphs
+ QUOTA_USAGE_RUNNING_INSTANCES = "quota_utilization_running_instances"
+ QUOTA_USAGE_RUNNING_MEMORY = "quota_utilization_running_memory"
+ QUOTA_USAGE_RUNNING_CPUS = "quota_utilization_running_cpus"
+ QUOTA_USAGE_TOTAL_INSTANCES = "quota_utilization_total_instances"
+ QUOTA_USAGE_TOTAL_STORAGE = "quota_utilization_total_storage"
+ QUOTA_USAGE_OVERALL = "quota_utilization_overall"
+
def initialize
@svg = ""
end
+
+ def self.get_quota_usage_graph_name(resource_name)
+ case resource_name
+ when Quota::RESOURCE_RUNNING_INSTANCES
+ return QUOTA_USAGE_RUNNING_INSTANCES
+ when Quota::RESOURCE_RUNNING_MEMORY
+ return QUOTA_USAGE_RUNNING_MEMORY
+ when Quota::RESOURCE_RUNNING_CPUS
+ return QUOTA_USAGE_RUNNING_CPUS
+ when Quota::RESOURCE_TOTAL_INSTANCES
+ return QUOTA_USAGE_TOTAL_INSTANCES
+ when Quota::RESOURCE_TOTAL_STORAGE
+ return QUOTA_USAGE_TOTAL_STORAGE
+ when Quota::RESOURCE_OVERALL
+ return QUOTA_USAGE_OVERALL
+ else
+ return nil
+ end
+ end
end
diff --git a/src/app/services/data_service.rb b/src/app/services/data_service.rb
index 776fef7..40968ef 100644
--- a/src/app/services/data_service.rb
+++ b/src/app/services/data_service.rb
@@ -62,24 +62,28 @@ class DataService
# Returns the Used and Maximum Resource Usage
def self.quota_utilisation(parent, resource_name)
- quota = parent.quota
-
- 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
- return nil
+ if parent
+ quota = parent.quota
+ if quota
+ 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
+ return nil
+ end
+ end
end
+ return nil
end
def self.overall_usage(parent)
@@ -91,7 +95,11 @@ class DataService
worst_case = nil
usage_points.each do |usage_point|
if worst_case
- if ((worst_case.max / 100) * worst_case.used) < ((usage_point.max / 100) * usage_point.used)
+ if worst_case.max == Quota::NO_LIMIT
+ worst_case = usage_point
+ elsif usage_point.max == Quota::NO_LIMIT
+ # DO Nothing
+ elsif ((worst_case.max / 100) * worst_case.used) < ((usage_point.max / 100) * usage_point.used)
worst_case = usage_point
end
else
diff --git a/src/app/services/graph_service.rb b/src/app/services/graph_service.rb
index 11da01c..22e45f1 100644
--- a/src/app/services/graph_service.rb
+++ b/src/app/services/graph_service.rb
@@ -24,6 +24,15 @@ class GraphService
graphs
end
+ def self.dashboard_quota_usage(user, opts = {})
+ parent = opts[:parent]
+
+ graphs = Hash.new
+ graphs[parent] = quota_usage_graph(parent, opts)
+
+ return graphs
+ end
+
def self.dashboard_qos (user,opts = {})
#FIXME add permission checks to filter what graphs user can get
graphs = Hash.new
@@ -58,104 +67,27 @@ class GraphService
output_stream = IO::popen( cmd, "r+")
end
- def self.quota_instances_in_use_graph (cloud_account, opts = {})
- #things we're checking for in opts: :max_value, :height, :width
-
- unless max_value = opts[:max_value]
- max_value = 100 unless max_value = Quota.maximum('maximum_running_instances')
- end
- height = 80 unless opts[:height].nil? ? nil : height = opts[:height].to_i
- width = 150 unless opts[:width].nil? ? nil : width = opts[:width].to_i
-
-
- raw_svg = ""
- gp = gnuplot_open
- Gnuplot::Plot.new( gp ) do |plot|
- plot.terminal "svg size #{width},#{height}"
- plot.arbitrary_lines << "unset xtics"
- plot.arbitrary_lines << "unset x2tics"
- plot.arbitrary_lines << "unset ytics"
- plot.arbitrary_lines << "unset y2tics"
- plot.arbitrary_lines << "unset border"
-
- plot.set "bmargin","0"
- plot.set "lmargin","0"
- plot.set "rmargin","0"
- plot.set "tmargin","0"
- plot.set "boxwidth 0.9"
- plot.set "style fill solid 1.0"
- plot.set "xrange [.25:2.75]"
- plot.set "yrange [0:#{max_value * 1.5}]" #we want to scale maxvalue 50% larger to leave room for label
-
- x = [1,2]
- #we'll just have zero values for the unexpected case where cloud_account has no quota
- y = x.collect { |v| 0 }
- if cloud_account.quota
- quota = cloud_account.quota
- y = [quota.running_instances,quota.maximum_running_instances]
- end
-
-
- #The two arrays above are three columns of data for gnuplot.
- plot.data << Gnuplot::DataSet.new( [[x[0]], [y[0]]] ) do |ds|
- ds.using = "1:2"
- ds.with = 'boxes linecolor rgb "#8cc63f"'
- ds.notitle
- end
-
- #The two arrays above are three columns of data for gnuplot.
- plot.data << Gnuplot::DataSet.new( [[x[1]], [y[1]]] ) do |ds|
- ds.using = "1:2"
- ds.with = 'boxes linecolor rgb "#cccccc"'
- ds.notitle
- end
-
-
- plot.data << Gnuplot::DataSet.new( [x, y] ) do |ds|
- ds.using = "1:2:2"
- ds.with = "labels left offset 0,.15 rotate"
- ds.notitle
- end
- end
- gp.flush
- gp.close_write
- gp.read(nil,raw_svg)
- gp.close_read
-
- #massage the svg so that the histogram's bars are oriented horizontally
- xml = Nokogiri::XML(raw_svg)
-
- nodes = xml.root.children
- wrapper = Nokogiri::XML::Node.new "g", xml.root
-
- nodes.each do |node|
- node.parent = wrapper if node.name != "desc" && node.name != "defs"
- end
-
- wrapper.parent = xml.root
- wrapper.set_attribute 'transform',"translate(#{width},0) rotate(90) scale(#{height * 1.0 / width},#{width * 1.0/ height})"
-
- text_nodes = []
- xml.root.traverse do |node|
- if node.name == 'text' && node.inner_text.strip =~ /^\d+$/
- if node.parent.name == 'g'
- pparent = node.parent
- text_nodes << pparent
- end
+ def self.quota_usage_graph (parent, opts = {})
+ x = [1,2]
+
+ #we'll just have zero values for the unexpected case where cloud_account has no quota
+ y = x.collect { |v| 0 }
+ if parent.quota
+ quota = parent.quota
+ data_point = DataService::quota_utilisation(parent, opts[:resource_name])
+ #Handle No Limit case
+ if data_point.max == Quota::NO_LIMIT
+ y = [data_point.used, nil]
+ else
+ y = [data_point.used, data_point.max]
end
end
- text_nodes.each do |node|
- attr = node.get_attribute 'transform'
- node.remove_attribute 'transform'
- node.set_attribute 'transform',"#{attr} scale (#{height * 1.0 / width},#{width * 1.0/ height})"
- end
-
- modified_svg = xml.to_s
- graph = Graph.new
- graph.svg = modified_svg
- graph
+ chart_opts = {:x => x, :y => y}
+ graphs = Hash.new
+ graphs[Graph.get_quota_usage_graph_name(opts[:resource_name])] = draw_bar_chart(opts, chart_opts)
+ return graphs
end
def self.qos_avg_time_to_submit_graph (provider, opts = {})
@@ -256,4 +188,97 @@ class GraphService
graph
end
+ def self.draw_bar_chart(opts, chart_opts)
+
+ #things we're checking for in opts: :max_value, :height, :width
+
+ unless max_value = opts[:max_value]
+ max_value = 100 unless max_value = Quota.maximum('maximum_running_instances')
+ end
+ height = 80 unless opts[:height].nil? ? nil : height = opts[:height].to_i
+ width = 150 unless opts[:width].nil? ? nil : width = opts[:width].to_i
+
+ raw_svg = ""
+ gp = gnuplot_open
+ Gnuplot::Plot.new( gp ) do |plot|
+ plot.terminal "svg size #{width},#{height}"
+ plot.arbitrary_lines << "unset xtics"
+ plot.arbitrary_lines << "unset x2tics"
+ plot.arbitrary_lines << "unset ytics"
+ plot.arbitrary_lines << "unset y2tics"
+ plot.arbitrary_lines << "unset border"
+
+ plot.set "bmargin","0"
+ plot.set "lmargin","0"
+ plot.set "rmargin","0"
+ plot.set "tmargin","0"
+ plot.set "boxwidth 0.9"
+ plot.set "style fill solid 1.0"
+ plot.set "xrange [.25:2.75]"
+ plot.set "yrange [0:#{max_value * 1.5}]" #we want to scale maxvalue 50% larger to leave room for label
+
+ x = chart_opts[:x]
+ y = chart_opts[:y]
+
+ #The two arrays above are three columns of data for gnuplot.
+ plot.data << Gnuplot::DataSet.new( [[x[0]], [y[0]]] ) do |ds|
+ ds.using = "1:2"
+ ds.with = 'boxes linecolor rgb "#8cc63f"'
+ ds.notitle
+ end
+
+ #The two arrays above are three columns of data for gnuplot.
+ plot.data << Gnuplot::DataSet.new( [[x[1]], [y[1]]] ) do |ds|
+ ds.using = "1:2"
+ ds.with = 'boxes linecolor rgb "#cccccc"'
+ ds.notitle
+ end
+
+
+ plot.data << Gnuplot::DataSet.new( [x, y] ) do |ds|
+ ds.using = "1:2:2"
+ ds.with = "labels left offset 0,.15 rotate"
+ ds.notitle
+ end
+ end
+ gp.flush
+ gp.close_write
+ gp.read(nil,raw_svg)
+ gp.close_read
+
+ #massage the svg so that the histogram's bars are oriented horizontally
+ xml = Nokogiri::XML(raw_svg)
+
+ nodes = xml.root.children
+ wrapper = Nokogiri::XML::Node.new "g", xml.root
+
+ nodes.each do |node|
+ node.parent = wrapper if node.name != "desc" && node.name != "defs"
+ end
+
+ wrapper.parent = xml.root
+ wrapper.set_attribute 'transform',"translate(#{width},0) rotate(90) scale(#{height * 1.0 / width},#{width * 1.0/ height})"
+
+ text_nodes = []
+ xml.root.traverse do |node|
+ if node.name == 'text' && node.inner_text.strip =~ /^\d+$/
+ if node.parent.name == 'g'
+ pparent = node.parent
+ text_nodes << pparent
+ end
+ end
+ end
+
+ text_nodes.each do |node|
+ attr = node.get_attribute 'transform'
+ node.remove_attribute 'transform'
+ node.set_attribute 'transform',"#{attr} scale (#{height * 1.0 / width},#{width * 1.0/ height})"
+ end
+
+ modified_svg = xml.to_s
+ graph = Graph.new
+ graph.svg = modified_svg
+ graph
+ end
+
end
diff --git a/src/app/views/dashboard/summary.haml b/src/app/views/dashboard/summary.haml
index ccbe9aa..a0d6179 100644
--- a/src/app/views/dashboard/summary.haml
+++ b/src/app/views/dashboard/summary.haml
@@ -108,7 +108,7 @@
.account_quota_usage_graph_summary
= account.provider.name + ": " + account.name
.account_quota_usage_current_graph
- %object{ :data => url_for(:action => :account_quota_graph, :id => account.id, :width => 100, :height => 50), :type => 'image/svg+xml'}
+ %object{ :data => url_for(:action => :quota_usage_graph, :cloud_account_id => account.id, :resource_name => Quota::RESOURCE_RUNNING_INSTANCES, :width => 100, :height => 50), :type => 'image/svg+xml'}
<div style="clear: both;" />
:javascript
--
1.6.6.1
14 years
Docs clarification
by Jason Guiditta
Hey, just quick note to whoever has a chance to look at this (could be
me, but I might not get to it right away). We had someone on
#deltacloud who had some issues with installation, and requested we
clarify some things on the site.
One we already planned to change, and that was to add the older
alternate method to get the 'next' branch for aggregator:
'git checkout -t -b next origin/next'
This seems to only work in very recent versions of git, which everyone
does not yet have.
He pasted his output here:
http://pastebin.com/5ZShM365
Just in case that disappears, I will paste it below as well. Another
source of confusion was that the download page only references a very
old rpm (I know, we will be updating it soon), so it might be good to at
the least have a link to contribute from there, saying 'for now, this is
the best way to get the code'. I noticed that many of the issue
mentioned were related to dependencies, so perhaps at least pointing
people at the spec file if they are not on an rpm-based system and
directions on how to use rails' 'rake gems:install' would make this
easier. Open to other suggestions, perhaps even splitting out the db
config or some such if that page starts to get too unwieldy. Anyway, as
always, patches welcome. Here is the content of the paste above:
#!/bin/bash
LOG=/tmp/install.log
echo "********** installing deltacloud `date` **********" >> $LOG 2>&1
echo "********** /etc/profile help `date` **********" >> $LOG 2>&1
echo "export EC2_URL=${EC2_URL}" >> /etc/profile
echo "export ACCESS_KEY_ID=${ACCESS_KEY_ID}" >> /etc/profile
echo "export SECRET_ACCESS_KEY=${SECRET_ACCESS_KEY}" >> /etc/profile
echo "export PATH=$PATH:/var/lib/gems/1.8/bin" >> /etc/profile
. /etc/profile
echo "********** installing packages `date` **********" >> $LOG 2>&1
apt-get install --force-yes -y ruby rubygems1.9 gitk rails
libdaemons-ruby libintl-gettext-ruby libdataobjects-postgres-ruby1.8
postgresql-8.3 libroot-ruby-dev make libfcgi-dev libgemplugin-ruby1.8
irb postgresql-8.3-plruby libdbd-pg-ruby libgettext-ruby1.9
libgettext-ruby-data libgettext-ruby-util libxml2 libxml2-dev
libxslt1-dev gnuplot
echo "********** installing rake 0.8.7 `date` **********" >> $LOG 2>&1
wget http://rubyforge.org/frs/download.php/56872/rake-0.8.7.tgz
tar -xzvf rake-0.8.7.tgz
cd rake-0.8.7
ruby install.rb
echo "********** installing a couple gems `date` **********" >> $LOG
2>&1
gem install amazon-ec2 authlogic compass
echo "********** getting deltacloud source `date` **********" >> $LOG
2>&1
cd /root
mkdir deltacloud ; cd deltacloud
git clone http://git.fedorahosted.org/git/deltacloud/core.git/
git clone http://git.fedorahosted.org/git/deltacloud/aggregator.git/
git clone http://git.fedorahosted.org/git/deltacloud/docs.git/
cd /root/deltacloud/aggregator
git checkout -t -b next origin/next
echo "********** installing deltacloud-client `date` **********" >> $LOG
2>&1
cd /root/deltacloud/core/client
gem build deltacloud-client.gemspec
gem install deltacloud-client-0.0.3.gem
echo "********** some postgres config `date` **********" >> $LOG 2>&1
su - postgres -c "psql -c \"CREATE USER dcloud WITH PASSWORD 'v23zj59an'
CREATEDB\""
echo "local all all trust" > /etc/postgresql/8.3/main/pg_hba.conf
echo "host all all 127.0.0.1 255.255.255.255 trust"
>> /etc/postgresql/8.3/main/pg_hba.conf
echo "host all all ::1/128 trust"
>> /etc/postgresql/8.3/main/pg_hba.conf
/etc/init.d/postgresql-8.3 restart
echo "********** installing deltacloud-core `date` **********" >> $LOG
2>&1
cd /root/deltacloud/core/server
rake package
gem install pkg/deltacloud-core-0.0.1.gem
echo "********** installing a couple more gems `date` **********" >>
$LOG 2>&1
gem install -v=2.3.2 rails
gem install bacon erubis fcgi gettext gettext_activerecord gettext_rails
gnuplot hoe less maruku memcache-client mongrel rack-test scruffy
shotgun will_paginate yard
echo "********** starting deltacloudd `date` **********" >> $LOG 2>&1
cd /root/deltacloud/core/server/bin
./deltacloudd -i ec2 -r 0.0.0.0 &
echo "********** rake the db `date` **********" >> $LOG 2>&1
cd /root/deltacloud/aggregator/src
cp config/database.pg config/database.yml
rake gems:install
rake db:create:all
rake db:migrate
rake db:test:prepare
echo "********** starting the server `date` **********" >> $LOG 2>&1
rake gems:install
./script/server &
echo "********** finishing deltacloud install `date` **********" >> $LOG
2>&1
14 years
[PATCH aggregator] Added image permissions
by Jan Provazník
From: Jan Provaznik <jprovazn(a)redhat.com>
Added image_view and image_modify permissions.
Requires DB rebuild (modified roles migration).
Image_modify permission check added to templates controller.
---
src/app/controllers/templates_controller.rb | 6 +++++-
src/app/models/permissioned_object.rb | 7 +++++++
src/app/models/privilege.rb | 6 +++++-
src/app/views/dashboard/summary.haml | 5 +++--
src/db/migrate/20091008153046_create_privileges.rb | 3 ++-
src/db/migrate/20091008153058_create_roles.rb | 4 +++-
6 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/src/app/controllers/templates_controller.rb b/src/app/controllers/templates_controller.rb
index 5d3a754..a2243aa 100644
--- a/src/app/controllers/templates_controller.rb
+++ b/src/app/controllers/templates_controller.rb
@@ -1,6 +1,6 @@
class TemplatesController < ApplicationController
layout :layout
- before_filter :require_user
+ before_filter :require_user, :check_permission
def layout
return "aggregator" unless ajax?
@@ -109,4 +109,8 @@ class TemplatesController < ApplicationController
@image_descriptor = params[:id] ? ImageDescriptor.find(params[:id]) : ImageDescriptor.new
@image_descriptor.update_xml_attributes!(params[:xml] || {})
end
+
+ def check_permission
+ require_privilege(Privilege::IMAGE_MODIFY)
+ end
end
diff --git a/src/app/models/permissioned_object.rb b/src/app/models/permissioned_object.rb
index b4a3037..d5e2afb 100644
--- a/src/app/models/permissioned_object.rb
+++ b/src/app/models/permissioned_object.rb
@@ -73,6 +73,13 @@ module PermissionedObject
has_privilege(user, Privilege::USER_MODIFY)
end
+ def can_view_images(user)
+ has_privilege(user, Privilege::IMAGE_VIEW)
+ end
+ def can_modify_images(user)
+ has_privilege(user, Privilege::IMAGE_MODIFY)
+ end
+
def has_privilege(user, privilege)
permissions.find(:first, :include => [:role => :privileges],
:conditions => ["permissions.user_id=:user and
diff --git a/src/app/models/privilege.rb b/src/app/models/privilege.rb
index 0117c5c..552beef 100644
--- a/src/app/models/privilege.rb
+++ b/src/app/models/privilege.rb
@@ -68,6 +68,9 @@ class Privilege < ActiveRecord::Base
# actions)
USER_VIEW = "user_view" # can view a user's profile data
+ IMAGE_VIEW = "image_view" # can view existing images (templates)
+ IMAGE_MODIFY = "image_modify" # can create or modify images (templates)
+
FULL_PRIVILEGE_LIST = [PERM_SET, PERM_VIEW,
INSTANCE_MODIFY, INSTANCE_CONTROL, INSTANCE_VIEW,
STATS_VIEW,
@@ -75,5 +78,6 @@ class Privilege < ActiveRecord::Base
POOL_MODIFY, POOL_VIEW,
QUOTA_MODIFY, QUOTA_VIEW,
PROVIDER_MODIFY, PROVIDER_VIEW,
- USER_MODIFY, USER_VIEW]
+ USER_MODIFY, USER_VIEW,
+ IMAGE_VIEW, IMAGE_MODIFY]
end
diff --git a/src/app/views/dashboard/summary.haml b/src/app/views/dashboard/summary.haml
index 44bff64..66aedde 100644
--- a/src/app/views/dashboard/summary.haml
+++ b/src/app/views/dashboard/summary.haml
@@ -35,8 +35,6 @@
Add a Provider Account
%a{:href => url_for(:controller => "provider", :action => "new")}
Add a Provider
- %a{:href => url_for(:controller => "templates", :action => "new")}
- Create a Template
%a{:href => url_for(:controller => "users", :action => "new")}
Create a User
%a{:href => url_for(:controller => "instance", :action => "index")}
@@ -46,6 +44,9 @@
Launch Instances
%a{:href => url_for(:controller => "", :action => "")}
Enter a help ticket
+ - if BasePermissionObject.general_permission_scope.can_modify_images(@current_user)
+ %a{:href => url_for(:controller => "templates", :action => "new")}
+ Create a Template
#service_quality_dashboard_section
- if @is_admin
diff --git a/src/db/migrate/20091008153046_create_privileges.rb b/src/db/migrate/20091008153046_create_privileges.rb
index 74932b0..cbd3c68 100644
--- a/src/db/migrate/20091008153046_create_privileges.rb
+++ b/src/db/migrate/20091008153046_create_privileges.rb
@@ -34,7 +34,8 @@ class CreatePrivileges < ActiveRecord::Migration
"pool_modify", "pool_view",
"quota_modify", "quota_view",
"provider_modify", "provider_view",
- "user_modify", "user_view"]
+ "user_modify", "user_view",
+ "image_modify", "image_view"]
Privilege.transaction do
privileges.each do |priv_name|
privilege = Privilege.new({:name => priv_name})
diff --git a/src/db/migrate/20091008153058_create_roles.rb b/src/db/migrate/20091008153058_create_roles.rb
index 74cf519..c452dad 100644
--- a/src/db/migrate/20091008153058_create_roles.rb
+++ b/src/db/migrate/20091008153058_create_roles.rb
@@ -105,7 +105,9 @@ class CreateRoles < ActiveRecord::Migration
"stats_view",
"instance_modify",
"instance_control",
- "instance_view"]}
+ "instance_view",
+ "image_modify",
+ "image_view"]}
}
Role.transaction do
--
1.7.0.1
14 years
Added Instance Pending & Shutting Down States to Quota Running Limits
by Martyn Taylor
This patch is intended to fix the bug that appeared in the demo where, pending states did not update the quota running totals.
This can cause over quota issues, since two instances can be in state pending, with the provider and the aggregator with only one available running instance in the quota, once the two instances start in the provider, they would push the quota over its limit. The aggregator previously would allow this state, with these changes it should not. Since we are treating "Pending" as a running state to keep consistency "Shutting Down" is now also classed as a running state.
14 years
AccessRules - v0.01
by marios@redhat.com
Hi,
this patch series implements 'AccessRules' (the 'firewalling stuff'). This feature is necessary for EC2 and Terremark amongst the clouds we currently support; in both cases, after you create an instance, you need to enable access to that instance (e.g. like creating a firewall rule) otherwise you can't do anything with your vm (e.g. no ssh access). I have implemented 3 operations: list rules (index), create rule, delete rule.
An access_rule has: 'id', 'protocol', 'port', 'instance_group'. Valid values for 'protocol' and 'instance_group' are cloud specific. I give details and any issues for each of ec2 and terremark below:
--marios
===========================================================
EC2:
-----------
list rules:
-----------
* We don't list rules that have a 'security group' as source (i.e. only interested in rules towards the outside world - which have a cidr address as source)
* id is 'groupname_protocol:ports' eg 'default_tcp:22'
* instance_group is the name of the security group to which a rule is/was applied (e.g. 'default')
------------
create rule:
------------
* valid protocols for ec2 rules are: tcp/udp/icmp...
* valid ports... for tcp/udp we set from_port == to_port (i.e. no port range.. this could be fixed e.g. input '22-33' to signal a range). When protocol is icmp then ec2 uses ports to signal the icmp 'type' ... '-1' is used to signal all icmp types (and our code currently defaults to this).
* group name must be an existing security group. every account gets 'default' group but more can be created...
* we set the given rule for all source addresses (cidr 0.0.0.0/0)... we could set this as an ec2 specific option?
------------
delete rule:
------------
* ec2 rules don't have an "id" so to delete a rule must specify the rule exactly including group, protocol, port, cidrip... hence why this info is used as the 'id' of our access_rule
=============================
Terremark:
-----------
list rules:
-----------
* id is 'serviceId_privateIP' e.g. '9582_10.114.71.132' where serviceId is the id terremark uses for the given 'internet service'
* instance_group holds the public IP address used for the internet service; this could cause confusion but cant see another way of capturing this info...
------------
create rule:
------------
* valid protocols are tcp/udp/http/https/ftp (http/https/ftp apparently matters, see https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/6...)
* instance_group is the private IP address of the instance to hold the node service (i.e. ip of the vm)
* potential problem... a user could have > 1 ip address.. currently the code picks the 'last one' returned ... this must be addressed somehow...
* in terremark setting up access for an instance is like NAT.. map public ip+port to private ip+port... since we only take 1 port parameter we set the public_port==private_port...
* name for internet service = 'svc'+randomNumber (7 digits) and for node service 'nod'+random (7 digits)... e.g. svc1094968, nod1824947
------------
delete rule:
------------
* terremark internet service id is encoded into access_rule id specifically for use with deletion...
* only particularity is that if you delete a internet service must also delete all node services that go with that:
service X: 211.123.111.123 :80
| |
/ \
/ \
/ \
node 1: 192.168.1.1:20 node 2: 192.168.1.2:21
delete all nodes before deleting the service (the code does this by default)
14 years
API documentation fixes and improvements
by Michal Fojtik
Hi,
This patch add support for reporting HTTP method in documentation
for specific operation.
Also table of parameters was redesigned a little bit and operation
features was added.
-- Michal
14 years