This series of patches makes various changes needed for the API and the
command line client. In detail, they do:
1/8: small bugfix
2/8: remove the client/ directory; everything there will go into a new
ovirt-client git repo. I'll send out patches for that shortly
3/8 and 4/8: add additional info to the XML available through the API
5/8 and 6/8: Create a new StorageVolumeController and move handling of storage
volumes out of the StorageController. Remove dead code
7/8: report an error with a human-readable error message through the API (yay)
8/8: route API calls for storage volumes
The main patch of this series is 5/8, the others are all pretty trivial.
David
David Lutterkort
2009-Jan-26 21:11 UTC
[Ovirt-devel] [PATCH server 1/8] Wrap generation of error message in respond_to block
---
src/app/controllers/storage_controller.rb | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/app/controllers/storage_controller.rb
b/src/app/controllers/storage_controller.rb
index e4b72f1..a3de2cd 100644
--- a/src/app/controllers/storage_controller.rb
+++ b/src/app/controllers/storage_controller.rb
@@ -311,10 +311,12 @@ class StorageController < ApplicationController
def destroy
unless @storage_pool.movable?
- format.json { render :json => { :object => "storage_pool",
- :success => false,
- :alert => "Cannot delete storage with associated vms" } }
- return
+ respond_to do |format|
+ format.json { render :json => { :object =>
"storage_pool",
+ :success => false,
+ :alert => "Cannot delete storage with associated vms"
} }
+ end
+ return
end
pool = @storage_pool.hardware_pool
--
1.6.0.6
David Lutterkort
2009-Jan-26 21:11 UTC
[Ovirt-devel] [PATCH server 2/8] Remove client/ directory, it will live in its own repo
---
client/README | 17 -------
client/examples/script.rb | 101 --------------------------------------------
client/lib/ovirt.rb | 102 ---------------------------------------------
3 files changed, 0 insertions(+), 220 deletions(-)
delete mode 100644 client/README
delete mode 100755 client/examples/script.rb
delete mode 100644 client/lib/ovirt.rb
diff --git a/client/README b/client/README
deleted file mode 100644
index ee1db15..0000000
--- a/client/README
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a very simple client library for accessing the OVirt API from Ruby.
-
-The file examples/script.rb contains a script that shows how this is done
-in some detail.
-
-You must have ActiveResource installed, e.g. with 'yum install
-rubygem-activeresource'
-
-The server is specified with a URL of the form
- http://USER:PASSWORD at HOST/ovirt
-
-This requires that the server is configured to allow HTTP authentication,
-since there are no mechanisms in the API to forward krb5 tickets.
-
-Before calling any other method on the API, you need to call
- OVirt::Base::site = "http://USER:PASSWORD at HOST/ovirt"
- OVirt::Base::login
diff --git a/client/examples/script.rb b/client/examples/script.rb
deleted file mode 100755
index 1485535..0000000
--- a/client/examples/script.rb
+++ /dev/null
@@ -1,101 +0,0 @@
-#! /usr/bin/ruby
-
-# Sample script that shows how to use the OVirt API
-
-require 'pp'
-require 'rubygems'
-require 'activeresource'
-require 'optparse'
-
-require 'ovirt'
-
-def move_random_host(hosts, pool)
- host = hosts[rand(hosts.size)]
- puts "Move #{host.hostname} to #{pool.name}"
- pool.hosts << host
- pool.save
-end
-
-def element_path(obj)
- "[#{obj.class.element_path(obj.id)}]"
-end
-
-def print_pool(pool)
- puts "\n\nPool #{pool.name}: #{pool.hosts.size} hosts,
#{pool.storage_pools.size} storage pools #{element_path(pool)} "
- puts "=" * 75
- pool.hosts.each do |h|
- printf "%-36s %s\n", h.hostname, element_path(h)
- end
- pool.storage_pools.each do |sp|
- type = sp.nfs? ? "NFS" : "iSCSI"
- printf "%-5s %-30s %s\n", type, sp.label, element_path(sp)
- end
- puts "-" * 75
-end
-
-# Plumbing so we can find the OVirt server
-# "http://ovirt.watzmann.net:3000/ovirt/rest"
-PROGNAME=File::basename($0)
-OVirt::Base.site = ENV["OVIRT_SERVER"]
-opts = OptionParser.new("#{PROGNAME} GLOBAL_OPTS")
-opts.separator(" Run some things against an OVirt server. The server is
specified with")
-opts.separator(" the -s option as a URL of the form http://USER:PASSWORD
at SERVER/ovirt")
-opts.separator("")
-opts.separator "Global options:"
-opts.on("-s", "--server=URL", "The OVirt server. Since
there is no auth\n" +
- "#{" "*37}yet, must be the mongrel server port.\n"
+
- "#{" "*37}Overrides env var OVIRT_SERVER") do |val|
- OVirt::Base.site = val
-end
-
-opts.order(ARGV)
-
-unless OVirt::Base.site
- $stderr.puts <<EOF
-You must specify the OVirt server to connect to, either with the
---server option or through the OVIRT_SERVER environment variable
-EOF
- exit 1
-end
-
-OVirt::Base.login
-
-# Get a single host by name
-host = OVirt::Host.find_by_hostname("node3.priv.ovirt.org")
-puts "#{host.uuid} has id #{host.id}"
-
-# What's in the default pool
-defpool = OVirt::HardwarePool.default_pool
-print_pool(defpool)
-
-# Create a new hardware pool
-mypool = OVirt::HardwarePool.find_by_path("/default/mypool")
-unless mypool
- puts "Create mypool"
- mypool = OVirt::HardwarePool.create( { :parent_id => defpool.id,
- :name => "mypool" } )
-end
-
-# Move some hosts around
-puts
-if defpool.hosts.size > 1
- move_random_host(defpool.hosts, mypool)
-elsif mypool.hosts.size > 0
- move_random_host(mypool.hosts, defpool)
-end
-
-# Delete all storage pools for mypool and add a new one
-mypool.storage_pools.each do |sp|
- puts "Delete storage pool #{sp.id}"
- sp.destroy
-end
-
-storage_pool = OVirt::StoragePool.create( { :storage_type =>
"NFS",
- :hardware_pool_id => mypool.id,
- :ip_addr =>
"192.168.122.50",
- :export_path =>
"/exports/pool1" } )
-puts "Created storage pool #{storage_pool.id}"
-
-# For some reason, mypool.reload doesn't work here
-mypool = OVirt::HardwarePool.find_by_path("/default/mypool")
-print_pool(mypool)
diff --git a/client/lib/ovirt.rb b/client/lib/ovirt.rb
deleted file mode 100644
index 15dc467..0000000
--- a/client/lib/ovirt.rb
+++ /dev/null
@@ -1,102 +0,0 @@
-require 'pp'
-require 'rubygems'
-require 'activeresource'
-
-class ActiveResource::Connection
- attr_accessor :session
-
- alias_method :old_default_header, :default_header
-
- def default_header
- old_default_header
- @default_header ||= {}
- if session
- @default_header["Cookie"] = session
- end
- @default_header
- end
-end
-
-module OVirt
- class Base < ActiveResource::Base
- LOGIN_PATH = "login/login"
-
- def self.login
- response = nil
- begin
- response = connection.get(prefix + LOGIN_PATH)
- rescue ActiveResource::Redirection => e
- response = e.response
- end
- unless connection.session = session_cookie(response)
- raise "Authentication failed"
- end
- end
-
- private
- def self.session_cookie(response)
- if cookies = response.get_fields("Set-Cookie")
- cookies.find { |cookie|
- cookie.split(";")[0].split("=")[0] ==
"_ovirt_session_id"
- }
- end
- end
-
- end
-
- class HardwarePool < Base
- def self.find_by_path(path)
- find(:first, :params => { :path => path })
- end
-
- def self.default_pool
- find(:first, :params => { :path => "/default" })
- end
- end
-
- class StoragePool < Base
- def iscsi?
- attributes["type"] == "IscsiStoragePool"
- end
-
- def nfs?
- attributes["type"] == "NfsStoragePool"
- end
-
- def label
- if iscsi?
- "#{ip_addr}:#{port}:#{target}"
- elsif nfs?
- "#{ip_addr}:#{export_path}"
- else
- raise "Unknown type #{attributes["type"]}"
- end
- end
- end
-
- class IscsiStoragePool < StoragePool
- def initialize(attributes = {})
- super(attributes.update( "type" =>
"IscsiStoragePool" ))
- end
- end
-
- class NfsStoragePool < StoragePool
- def initialize(attributes = {})
- super(attributes.update( "type" =>
"NfsStoragePool" ))
- end
- end
-
- class Host < Base
- def self.find_by_uuid(uuid)
- find(:first, :params => { :uuid => uuid })
- end
-
- def self.find_by_hostname(hostname)
- find(:first, :params => { :hostname => hostname })
- end
-
- def hardware_pool
- HardwarePool.find(hardware_pool_id)
- end
- end
-end
--
1.6.0.6
David Lutterkort
2009-Jan-26 21:12 UTC
[Ovirt-devel] [PATCH server 3/8] Include CPU's in host information
---
src/app/controllers/hardware_controller.rb | 7 ++++++-
src/app/controllers/host_controller.rb | 2 +-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/app/controllers/hardware_controller.rb
b/src/app/controllers/hardware_controller.rb
index 5c14eec..30e80b2 100644
--- a/src/app/controllers/hardware_controller.rb
+++ b/src/app/controllers/hardware_controller.rb
@@ -50,7 +50,12 @@ class HardwareController < PoolController
end
respond_to do |format|
- format.xml { render :xml => @pools.to_xml(XML_OPTS) }
+ format.xml {
+ opts = XML_OPTS.dup
+ opts[:include] = opts[:include].inject({}) { |m, k| m[k] = {}; m }
+ opts[:include][:hosts] = { :include => :cpus }
+ render :xml => @pools.to_xml(opts)
+ }
end
end
diff --git a/src/app/controllers/host_controller.rb
b/src/app/controllers/host_controller.rb
index da630f7..8cf2aed 100644
--- a/src/app/controllers/host_controller.rb
+++ b/src/app/controllers/host_controller.rb
@@ -60,7 +60,7 @@ class HostController < ApplicationController
else
respond_to do |format|
format.html { render :layout => 'selection' }
- format.xml { render :xml => @host.to_xml }
+ format.xml { render :xml => @host.to_xml(:include => [ :cpus ] )
}
end
end
end
--
1.6.0.6
David Lutterkort
2009-Jan-26 21:12 UTC
[Ovirt-devel] [PATCH server 4/8] API: include storage_volumes; indicate type for individual pools
---
src/app/controllers/storage_controller.rb | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/app/controllers/storage_controller.rb
b/src/app/controllers/storage_controller.rb
index a3de2cd..f7b53c5 100644
--- a/src/app/controllers/storage_controller.rb
+++ b/src/app/controllers/storage_controller.rb
@@ -31,7 +31,7 @@ class StorageController < ApplicationController
list
respond_to do |format|
format.html { render :action => 'list' }
- format.xml { render :xml => @storage_pools.to_xml }
+ format.xml { render :xml => @storage_pools.to_xml( :include =>
:storage_volumes) }
end
end
@@ -79,7 +79,12 @@ class StorageController < ApplicationController
else
respond_to do |format|
format.html { render :layout => 'selection' }
- format.xml { render :xml => @storage_pool.to_xml }
+ format.xml {
+ xml_txt = @storage_pool.to_xml(:include => :storage_volumes) do
|xml|
+ xml.type @storage_pool.class.name
+ end
+ render :xml => xml_txt
+ }
end
end
end
--
1.6.0.6
David Lutterkort
2009-Jan-26 21:12 UTC
[Ovirt-devel] [PATCH server 5/8] Factor StorageVolume functionality out of StorageController
Storage volumes can now be accessed through their own controller. This is
needed to expose them in the API.
---
src/app/controllers/search_controller.rb | 12 +-
src/app/controllers/storage_controller.rb | 203 -----------------
src/app/controllers/storage_volume_controller.rb | 228 ++++++++++++++++++++
src/app/views/storage/_list_volumes.rhtml | 2 +-
src/app/views/storage/_new_volume_form.rhtml | 24 --
src/app/views/storage/new_volume.rhtml | 47 ----
src/app/views/storage/show.rhtml | 2 +-
src/app/views/storage/show_volume.rhtml | 87 --------
.../views/storage_volume/_new_volume_form.rhtml | 24 ++
src/app/views/storage_volume/new.rhtml | 47 ++++
src/app/views/storage_volume/show.rhtml | 87 ++++++++
11 files changed, 394 insertions(+), 369 deletions(-)
create mode 100644 src/app/controllers/storage_volume_controller.rb
delete mode 100644 src/app/views/storage/_new_volume_form.rhtml
delete mode 100644 src/app/views/storage/new_volume.rhtml
delete mode 100644 src/app/views/storage/show_volume.rhtml
create mode 100644 src/app/views/storage_volume/_new_volume_form.rhtml
create mode 100644 src/app/views/storage_volume/new.rhtml
create mode 100644 src/app/views/storage_volume/show.rhtml
diff --git a/src/app/controllers/search_controller.rb
b/src/app/controllers/search_controller.rb
index 7551242..0fb6456 100644
--- a/src/app/controllers/search_controller.rb
+++ b/src/app/controllers/search_controller.rb
@@ -37,14 +37,14 @@ class SearchController < ApplicationController
"NfsStoragePool" => {:controller =>
"storage",
:show_action => "show",
:searched => true},
- "IscsiStorageVolume" => {:controller =>
"storage",
- :show_action =>
"show_volume",
+ "IscsiStorageVolume" => {:controller =>
"storage_volume",
+ :show_action => "show",
:searched => false},
- "NfsStorageVolume" => {:controller =>
"storage",
- :show_action =>
"show_volume",
+ "NfsStorageVolume" => {:controller =>
"storage_volume",
+ :show_action => "show",
:searched => false},
- "LvmStorageVolume" => {:controller =>
"storage",
- :show_action =>
"show_volume",
+ "LvmStorageVolume" => {:controller =>
"storage_volume",
+ :show_action => "show",
:searched => false}}
MULTI_TYPE_MODELS = {"StoragePool" =>
["IscsiStoragePool", "NfsStoragePool"]}
diff --git a/src/app/controllers/storage_controller.rb
b/src/app/controllers/storage_controller.rb
index f7b53c5..9674125 100644
--- a/src/app/controllers/storage_controller.rb
+++ b/src/app/controllers/storage_controller.rb
@@ -24,8 +24,6 @@ class StorageController < ApplicationController
before_filter :pre_pool_admin, :only => [:refresh]
before_filter :pre_new2, :only => [:new2]
- before_filter :pre_json, :only => [:storage_volumes_json]
- before_filter :pre_create_volume, :only => [:create_volume]
def index
list
@@ -89,35 +87,6 @@ class StorageController < ApplicationController
end
end
- def storage_volumes_json
- @storage_pool = StoragePool.find(params[:id])
- set_perms(@storage_pool.hardware_pool)
- unless @can_view
- flash[:notice] = 'You do not have permission to view this storage
pool: redirecting to top level'
- redirect_to :controller => 'dashboard'
- end
- attr_list = []
- attr_list << :id if (@storage_pool.user_subdividable and @can_modify)
- attr_list += [:display_name, :size_in_gb, :get_type_label]
- json_list(@storage_pool.storage_volumes, attr_list)
- end
- def show_volume
- @storage_volume = StorageVolume.find(params[:id])
- set_perms(@storage_volume.storage_pool.hardware_pool)
- unless @can_view
- flash[:notice] = 'You do not have permission to view this storage
volume: redirecting to top level'
- respond_to do |format|
- format.html { redirect_to :controller => 'dashboard' }
- format.xml { head :forbidden }
- end
- else
- respond_to do |format|
- format.html { render :layout => 'selection' }
- format.xml { render :xml => @storage_volume.to_xml }
- end
- end
- end
-
def new
end
@@ -126,76 +95,6 @@ class StorageController < ApplicationController
render :layout => false
end
- def new_volume
- @return_facebox = params[:return_facebox]
- if params[:storage_pool_id]
- @storage_pool = StoragePool.find(params[:storage_pool_id])
- unless @storage_pool.user_subdividable
- #fixme: proper error page for popups
- redirect_to :controller => 'dashboard'
- return
- end
- new_volume_internal(@storage_pool,
- { :storage_pool_id => params[:storage_pool_id]})
- else
- @source_volume = StorageVolume.find(params[:source_volume_id])
- unless @source_volume.supports_lvm_subdivision
- #fixme: proper error page for popups
- redirect_to :controller => 'dashboard'
- return
- end
- lvm_pool = @source_volume.lvm_storage_pool
- unless lvm_pool
- # FIXME: what should we do about VG/LV names?
- # for now auto-create VG name as ovirt_vg_#{@source_volume.id}
- new_params = { :vg_name =>
"ovirt_vg_#{@source_volume.id}",
- :hardware_pool_id => @source_volume.storage_pool.hardware_pool_id}
- lvm_pool = StoragePool.factory(StoragePool::LVM, new_params)
- lvm_pool.source_volumes << @source_volume
- lvm_pool.save!
- end
- new_volume_internal(lvm_pool, { :storage_pool_id => lvm_pool.id})
- @storage_volume.lv_owner_perms='0744'
- @storage_volume.lv_group_perms='0744'
- @storage_volume.lv_mode_perms='0744'
- end
- render :layout => 'popup'
- end
-
- def create_volume
- begin
- StorageVolume.transaction do
- @storage_volume.save!
- @task = StorageVolumeTask.new({ :user => @user,
- :task_target => @storage_volume,
- :action =>
StorageVolumeTask::ACTION_CREATE_VOLUME,
- :state => Task::STATE_QUEUED})
- @task.save!
- end
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => true,
- :alert => "Storage Volume was successfully created." }
}
- format.xml { render :xml => @storage_volume,
- :status => :created,
- # FIXME: create storage_volume_url method if relevant
- :location => storage_pool_url(@storage_volume)
- }
- end
- rescue => ex
- # FIXME: need to distinguish volume vs. task save errors
- respond_to do |format|
- format.json {
- json_hash = { :object => "storage_volume", :success
=> false,
- :errors => @storage_volume.errors.localize_error_messages.to_a
}
- json_hash[:message] = ex.message if json_hash[:errors].empty?
- render :json => json_hash }
- format.xml { render :xml => @storage_volume.errors,
- :status => :unprocessable_entity }
- end
- end
- end
-
def insert_refresh_task
@task = StorageTask.new({ :user => @user,
:task_target => @storage_pool,
@@ -339,67 +238,6 @@ class StorageController < ApplicationController
end
end
- def delete_volumes
- storage_volume_ids_str = params[:storage_volume_ids]
- storage_volume_ids = storage_volume_ids_str.split(",").collect
{|x| x.to_i}
- alerts = []
- status = true
- begin
- StorageVolume.transaction do
- storage = StorageVolume.find(:all, :conditions => "id in
(#{storage_volume_ids.join(', ')})")
- unless storage.empty?
- set_perms(storage[0].storage_pool.hardware_pool)
- unless @can_modify and storage[0].storage_pool.user_subdividable
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => false,
- :alert => "You do not have permission to delete this
storage volume." } }
- format.xml { head :forbidden }
- end
- else
- storage.each do |storage_volume|
- alert, success = delete_volume_internal(storage_volume)
- alerts << alert
- status = false unless success
- end
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => status, :alert =>
alerts.join("\n") } }
- format.xml { head(status ? :ok : :method_not_allowed) }
- end
- end
- else
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => false, :alert => "no volumes
selected" } }
- format.xml { head(status ? :ok : :method_not_allowed) }
- end
- end
- end
- end
- end
-
- def delete_volume
- @storage_volume = StorageVolume.find(params[:id])
- set_perms(@storage_volume.storage_pool.hardware_pool)
- unless @can_modify and @storage_volume.storage_pool.user_subdividable
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => false,
- :alert => "You do not have permission to delete this
storage volume." } }
- format.xml { head :forbidden }
- end
- else
- alert, success = delete_volume_internal(@storage_volume)
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => success, :alert => alert } }
- format.xml { head(success ? :ok : :method_not_allowed) }
- end
- end
-
- end
-
def pre_new
@hardware_pool = HardwarePool.find(params[:hardware_pool_id])
@perm_obj = @hardware_pool
@@ -430,50 +268,9 @@ class StorageController < ApplicationController
@perm_obj = @storage_pool.hardware_pool
@redir_obj = @storage_pool
end
- def pre_create_volume
- volume = params[:storage_volume]
- unless type = params[:storage_type]
- type = volume.delete(:storage_type)
- end
- @storage_volume = StorageVolume.factory(type, volume)
- @perm_obj = @storage_volume.storage_pool.hardware_pool
- @redir_controller =
@storage_volume.storage_pool.hardware_pool.get_controller
- authorize_admin
- end
- def pre_json
- pre_show
- end
def pre_pool_admin
pre_edit
authorize_admin
end
- private
- def new_volume_internal(storage_pool, new_params)
- @storage_volume = StorageVolume.factory(storage_pool.get_type_label,
new_params)
- @perm_obj = @storage_volume.storage_pool.hardware_pool
- authorize_admin
- end
-
- def delete_volume_internal(volume)
- begin
- name = volume.display_name
- if !volume.vms.empty?
- vm_list = volume.vms.collect {|vm| vm.description}.join(", ")
- ["Storage Volume #{name} must be unattached from VMs (#{vm_list})
before deleting it.",
- false]
- else
- volume.state=StorageVolume::STATE_PENDING_DELETION
- volume.save!
- @task = StorageVolumeTask.new({ :user => @user,
- :task_target => volume,
- :action =>
StorageVolumeTask::ACTION_DELETE_VOLUME,
- :state => Task::STATE_QUEUED})
- @task.save!
- ["Storage Volume #{name} deletion was successfully queued.",
true]
- end
- rescue => ex
- ["Failed to delete storage volume #{name}
(#{ex.message}.",false]
- end
- end
end
diff --git a/src/app/controllers/storage_volume_controller.rb
b/src/app/controllers/storage_volume_controller.rb
new file mode 100644
index 0000000..197864a
--- /dev/null
+++ b/src/app/controllers/storage_volume_controller.rb
@@ -0,0 +1,228 @@
+#
+# Copyright (C) 2009 Red Hat, Inc.
+# Written by Scott Seago <sseago 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 StorageVolumeController < ApplicationController
+
+ before_filter :pre_create, :only => [:create]
+
+ def new
+ @return_facebox = params[:return_facebox]
+ if params[:storage_pool_id]
+ @storage_pool = StoragePool.find(params[:storage_pool_id])
+ unless @storage_pool.user_subdividable
+ #fixme: proper error page for popups
+ redirect_to :controller => 'dashboard'
+ return
+ end
+ new_volume_internal(@storage_pool,
+ { :storage_pool_id => params[:storage_pool_id]})
+ else
+ @source_volume = StorageVolume.find(params[:source_volume_id])
+ unless @source_volume.supports_lvm_subdivision
+ #fixme: proper error page for popups
+ redirect_to :controller => 'dashboard'
+ return
+ end
+ lvm_pool = @source_volume.lvm_storage_pool
+ unless lvm_pool
+ # FIXME: what should we do about VG/LV names?
+ # for now auto-create VG name as ovirt_vg_#{@source_volume.id}
+ new_params = { :vg_name =>
"ovirt_vg_#{@source_volume.id}",
+ :hardware_pool_id => @source_volume.storage_pool.hardware_pool_id}
+ lvm_pool = StoragePool.factory(StoragePool::LVM, new_params)
+ lvm_pool.source_volumes << @source_volume
+ lvm_pool.save!
+ end
+ new_volume_internal(lvm_pool, { :storage_pool_id => lvm_pool.id})
+ @storage_volume.lv_owner_perms='0744'
+ @storage_volume.lv_group_perms='0744'
+ @storage_volume.lv_mode_perms='0744'
+ end
+ render :layout => 'popup'
+ end
+
+ def create
+ begin
+ StorageVolume.transaction do
+ @storage_volume.save!
+ @task = StorageVolumeTask.new({ :user => @user,
+ :task_target => @storage_volume,
+ :action =>
StorageVolumeTask::ACTION_CREATE_VOLUME,
+ :state => Task::STATE_QUEUED})
+ @task.save!
+ end
+ respond_to do |format|
+ format.json { render :json => { :object =>
"storage_volume",
+ :success => true,
+ :alert => "Storage Volume was successfully created." }
}
+ format.xml { render :xml => @storage_volume,
+ :status => :created,
+ # FIXME: create storage_volume_url method if relevant
+ :location => storage_pool_url(@storage_volume)
+ }
+ end
+ rescue => ex
+ # FIXME: need to distinguish volume vs. task save errors
+ respond_to do |format|
+ format.json {
+ json_hash = { :object => "storage_volume", :success
=> false,
+ :errors => @storage_volume.errors.localize_error_messages.to_a
}
+ json_hash[:message] = ex.message if json_hash[:errors].empty?
+ render :json => json_hash }
+ format.xml { render :xml => @storage_volume.errors,
+ :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ def show
+ @storage_volume = StorageVolume.find(params[:id])
+ set_perms(@storage_volume.storage_pool.hardware_pool)
+ @storage_pool = @storage_volume.storage_pool
+ unless @can_view
+ flash[:notice] = 'You do not have permission to view this storage
volume: redirecting to top level'
+ respond_to do |format|
+ format.html { redirect_to :controller => 'dashboard' }
+ format.json { redirect_to :controller => 'dashboard' }
+ format.xml { head :forbidden }
+ end
+ else
+ respond_to do |format|
+ format.html { render :layout => 'selection' }
+ format.json do
+ attr_list = []
+ attr_list << :id if (@storage_pool.user_subdividable and
@can_modify)
+ attr_list += [:display_name, :size_in_gb, :get_type_label]
+ json_list(@storage_pool.storage_volumes, attr_list)
+ end
+ format.xml { render :xml => @storage_volume.to_xml }
+ end
+ end
+ end
+
+ def destroy
+ if params[:id]
+ delete_volume
+ else
+ delete_volumes
+ end
+ end
+
+ def delete_volumes
+ storage_volume_ids_str = params[:storage_volume_ids]
+ storage_volume_ids = storage_volume_ids_str.split(",").collect
{|x| x.to_i}
+ alerts = []
+ status = true
+ begin
+ StorageVolume.transaction do
+ storage = StorageVolume.find(:all, :conditions => "id in
(#{storage_volume_ids.join(', ')})")
+ unless storage.empty?
+ set_perms(storage[0].storage_pool.hardware_pool)
+ unless @can_modify and storage[0].storage_pool.user_subdividable
+ respond_to do |format|
+ format.json { render :json => { :object =>
"storage_volume",
+ :success => false,
+ :alert => "You do not have permission to delete this
storage volume." } }
+ format.xml { head :forbidden }
+ end
+ else
+ storage.each do |storage_volume|
+ alert, success = delete_volume_internal(storage_volume)
+ alerts << alert
+ status = false unless success
+ end
+ respond_to do |format|
+ format.json { render :json => { :object =>
"storage_volume",
+ :success => status, :alert =>
alerts.join("\n") } }
+ format.xml { head(status ? :ok : :method_not_allowed) }
+ end
+ end
+ else
+ respond_to do |format|
+ format.json { render :json => { :object =>
"storage_volume",
+ :success => false, :alert => "no volumes
selected" } }
+ format.xml { head(status ? :ok : :method_not_allowed) }
+ end
+ end
+ end
+ end
+ end
+
+ def delete_volume
+ @storage_volume = StorageVolume.find(params[:id])
+ set_perms(@storage_volume.storage_pool.hardware_pool)
+ unless @can_modify and @storage_volume.storage_pool.user_subdividable
+ respond_to do |format|
+ format.json { render :json => { :object =>
"storage_volume",
+ :success => false,
+ :alert => "You do not have permission to delete this
storage volume." } }
+ format.xml { head :forbidden }
+ end
+ else
+ alert, success = delete_volume_internal(@storage_volume)
+ respond_to do |format|
+ format.json { render :json => { :object =>
"storage_volume",
+ :success => success, :alert => alert } }
+ format.xml { head(success ? :ok : :method_not_allowed) }
+ end
+ end
+
+ end
+
+ def pre_create
+ volume = params[:storage_volume]
+ unless type = params[:storage_type]
+ type = volume.delete(:storage_type)
+ end
+ @storage_volume = StorageVolume.factory(type, volume)
+ @perm_obj = @storage_volume.storage_pool.hardware_pool
+ @redir_controller =
@storage_volume.storage_pool.hardware_pool.get_controller
+ authorize_admin
+ end
+
+ private
+ def new_volume_internal(storage_pool, new_params)
+ @storage_volume = StorageVolume.factory(storage_pool.get_type_label,
new_params)
+ @perm_obj = @storage_volume.storage_pool.hardware_pool
+ authorize_admin
+ end
+
+ def delete_volume_internal(volume)
+ begin
+ name = volume.display_name
+ if !volume.vms.empty?
+ vm_list = volume.vms.collect {|vm| vm.description}.join(", ")
+ ["Storage Volume #{name} must be unattached from VMs (#{vm_list})
before deleting it.",
+ false]
+ else
+ volume.state=StorageVolume::STATE_PENDING_DELETION
+ volume.save!
+ @task = StorageVolumeTask.new({ :user => @user,
+ :task_target => volume,
+ :action =>
StorageVolumeTask::ACTION_DELETE_VOLUME,
+ :state => Task::STATE_QUEUED})
+ @task.save!
+ ["Storage Volume #{name} deletion was successfully queued.",
true]
+ end
+ rescue => ex
+ ["Failed to delete storage volume #{name}
(#{ex.message}.",false]
+ end
+ end
+
+end
diff --git a/src/app/views/storage/_list_volumes.rhtml
b/src/app/views/storage/_list_volumes.rhtml
index 212720e..ab4f623 100644
--- a/src/app/views/storage/_list_volumes.rhtml
+++ b/src/app/views/storage/_list_volumes.rhtml
@@ -19,7 +19,7 @@
<tbody>
<% for storage_volume in type_volumes %>
<tr class="<%= cycle('odd','even', :name =>
type_volumes) %>">
- <% vol_hash = { :controller => 'storage', :action =>
'show_volume', :id => storage_volume }
+ <% vol_hash = { :controller => 'storage_volume', :action =>
'show', :id => storage_volume }
vol_hash[:vm_id] = vm_id if defined? vm_id
%>
<td style="text-align:left;"><%= link_to
storage_volume.storage_pool.ip_addr, vol_hash, { :class => "show" }
%>
diff --git a/src/app/views/storage/_new_volume_form.rhtml
b/src/app/views/storage/_new_volume_form.rhtml
deleted file mode 100644
index ae65e18..0000000
--- a/src/app/views/storage/_new_volume_form.rhtml
+++ /dev/null
@@ -1,24 +0,0 @@
-<%= error_messages_for 'storage_volume' %>
-
-<!--[form:storage_pool]-->
-<%= hidden_field 'storage_volume', 'storage_pool_id' %>
-<%= hidden_field_tag 'storage_type', @storage_volume.get_type_label
%>
-
-<%= text_field_with_label "Size (GB):", 'storage_volume',
'size_in_gb' %>
-
-<%if @storage_volume.get_type_label==StoragePool::LVM -%>
- <%= text_field_with_label "LV Name:", 'storage_volume',
'lv_name' %>
-
- <%= text_field_with_label "Owner permissions:",
'storage_volume', 'lv_owner_perms' %>
-
- <%= text_field_with_label "Group permissions:",
'storage_volume', 'lv_group_perms' %>
-
- <%= text_field_with_label "Mode permissions:",
'storage_volume', 'lv_mode_perms' %>
-<%- end -%>
-<%= text_field_with_label "LUN:", 'storage_volume',
'lun' if @storage_volume.get_type_label==StoragePool::ISCSI %>
-
-<%= text_field_with_label "Filename:", 'storage_volume',
'filename' if @storage_volume.get_type_label==StoragePool::NFS %>
-
-
-<!--[eoform:storage_volume]-->
-
diff --git a/src/app/views/storage/new_volume.rhtml
b/src/app/views/storage/new_volume.rhtml
deleted file mode 100644
index 958c463..0000000
--- a/src/app/views/storage/new_volume.rhtml
+++ /dev/null
@@ -1,47 +0,0 @@
-<%- content_for :title do -%>
- <%= _("Add New Volume") %>
-<%- end -%>
-<%- content_for :description do -%>
- Add a new Storage Volume to
- <%= if @storage_volume.get_type_label==StoragePool::LVM
- @source_volume.display_name
- else
- @storage_pool.display_name
- end %>.
-<%- end -%>
-<div class="panel_header"></div>
-<div class="dialog_form">
-<form method="POST" action="<%= url_for :action =>
'create_volume' %>" id="storage_volume_form" >
- <div class="dialog_form">
- <div id="new_storage_pool">
- <%= render :partial => 'new_volume_form' %>
- </div>
- </div>
- <!-- FIXME: need to pop up the details dialog again -->
- <%= popup_footer("$('#storage_volume_form').submit()",
"New Storage Volume") %>
-</form>
-</div>
-<script type="text/javascript">
-function afterStorageVolume(response, status){
- ajax_validation(response, status);
- if (response.success) {
- <% if @return_facebox %>
- $('#window').fadeOut('fast');
- $("#window").empty().load("<%= @return_facebox
%>")
- $('#window').fadeIn('fast');
- <% else %>
- $(document).trigger('close.facebox');
- <% end %>
- }
-}
-$(function() {
- var storagevolumeoptions = {
- target: '<%= url_for :action =>
'create_volume' %>', // target element to update
- dataType: 'json',
- success: afterStorageVolume // post-submit callback
- };
-
- // bind form using 'ajaxForm'
- $('#storage_volume_form').ajaxForm(storagevolumeoptions);
-});
-</script>
diff --git a/src/app/views/storage/show.rhtml b/src/app/views/storage/show.rhtml
index 7e02f32..dd52d79 100644
--- a/src/app/views/storage/show.rhtml
+++ b/src/app/views/storage/show.rhtml
@@ -12,7 +12,7 @@
</a>
<%if @storage_pool.user_subdividable -%>
<%= link_to image_tag("icon_addstorage.png") + " Add
new Volume",
- {:controller => 'storage', :action =>
'new_volume', :storage_pool_id => @storage_pool.id},
+ {:controller => 'storage_volume',
:action => 'new', :storage_pool_id => @storage_pool.id},
:rel=>"facebox[.bolder]",
:class=>"selection_facebox" %>
<% end %>
<a href="#confirm_delete_storage"
rel="facebox[.bolder]">
diff --git a/src/app/views/storage/show_volume.rhtml
b/src/app/views/storage/show_volume.rhtml
deleted file mode 100644
index f85feaa..0000000
--- a/src/app/views/storage/show_volume.rhtml
+++ /dev/null
@@ -1,87 +0,0 @@
-<%- content_for :title do -%>
- <%=h @storage_volume.display_name %>
-<%- end -%>
-
-<%- content_for :action_links do -%>
- <%if @can_modify -%>
- <%if @storage_volume.supports_lvm_subdivision and
@storage_volume.vms.empty? -%>
- <%= link_to image_tag("icon_addstorage.png") + " Add
new Volume",
- {:controller => 'storage', :action =>
'new_volume', :source_volume_id => @storage_volume.id},
- :rel=>"facebox[.bolder]",
:class=>"selection_facebox" %>
- <% end %>
- <%if @storage_volume.deletable -%>
- <a href="#confirm_delete"
rel="facebox[.bolder]">
- <%= image_tag "icon_x.png" %> Delete
- </a>
- <%- end -%>
- <%- end -%>
-<%- end -%>
-<%= confirmation_dialog("confirm_delete", "Are you
sure?", "delete_volume()") %>
-
- <div class="selection_key">
- <% unless @storage_volume.storage_pool[:type] ==
"LvmStoragePool" %>
- IP address:<br/>
- <% end %>
- <% if @storage_volume.storage_pool[:type] ==
"IscsiStoragePool" %>
- Port:<br/>
- Target:<br/>
- <% elsif @storage_volume.storage_pool[:type] ==
"NfsStoragePool" %>
- Export path:<br/>
- <% end %>
- Type:<br/>
- State:<br/>
- Path:<br/>
- <% if @storage_volume[:type] == "IscsiStorageVolume" %>
- LUN:<br/>
- <% elsif @storage_volume[:type] == "NfsStorageVolume" %>
- Filename:<br/>
- <% elsif @storage_volume[:type] == "LvmStorageVolume" %>
- Volume Group:<br/>
- Logical Volume:<br/>
- Permissions (owner/group/mode):<br/>
- <% end %>
- Size:<br/>
- </div>
- <div class="selection_value">
- <% unless @storage_volume.storage_pool[:type] ==
"LvmStoragePool" %>
- <%=h @storage_volume.storage_pool.ip_addr %><br/>
- <% end %>
- <% if @storage_volume.storage_pool[:type] == "IscsiStoragePool"
%>
- <%=h @storage_volume.storage_pool.port %><br/>
- <%=h @storage_volume.storage_pool[:target] %><br/>
- <% elsif @storage_volume.storage_pool[:type] ==
"NfsStoragePool" %>
- <%=h @storage_volume.storage_pool.export_path %><br/>
- <% end %>
- <%=h @storage_volume.storage_pool.get_type_label %><br/>
- <%=h @storage_volume.state %><br/>
- <%=h @storage_volume.path %><br/>
- <% if @storage_volume[:type] == "IscsiStorageVolume" %>
- <%=h @storage_volume.lun %><br/>
- <% elsif @storage_volume[:type] == "NfsStorageVolume" %>
- <%=h @storage_volume.filename %><br/>
- <% elsif @storage_volume[:type] == "LvmStorageVolume" %>
- <%=h @storage_volume.storage_pool.vg_name %><br/>
- <%=h @storage_volume.lv_name %><br/>
- <%=h @storage_volume.lv_owner_perms %>/<%=h
@storage_volume.lv_group_perms %>/<%=h @storage_volume.lv_mode_perms
%><br/>
- <% end %>
- <%=h @storage_volume.size_in_gb %> GB<br/>
- </div>
-<%- content_for :right do -%>
-
-<%- end -%>
-
-<script type="text/javascript">
- function delete_volume()
- {
- $(document).trigger('close.facebox');
- $.post('<%= url_for :controller => "storage", :action
=> "delete_volumes" %>',
- { storage_volume_ids: <%= @storage_volume.id %> },
- function(data,status) {
- // FIXME: reload tree
- if (data.alert) {
- $.jGrowl(data.alert);
- }
- empty_summary('storage_selection', 'Storage Pool or
Volume');
- }, 'json');
- }
-</script>
diff --git a/src/app/views/storage_volume/_new_volume_form.rhtml
b/src/app/views/storage_volume/_new_volume_form.rhtml
new file mode 100644
index 0000000..ae65e18
--- /dev/null
+++ b/src/app/views/storage_volume/_new_volume_form.rhtml
@@ -0,0 +1,24 @@
+<%= error_messages_for 'storage_volume' %>
+
+<!--[form:storage_pool]-->
+<%= hidden_field 'storage_volume', 'storage_pool_id' %>
+<%= hidden_field_tag 'storage_type', @storage_volume.get_type_label
%>
+
+<%= text_field_with_label "Size (GB):", 'storage_volume',
'size_in_gb' %>
+
+<%if @storage_volume.get_type_label==StoragePool::LVM -%>
+ <%= text_field_with_label "LV Name:", 'storage_volume',
'lv_name' %>
+
+ <%= text_field_with_label "Owner permissions:",
'storage_volume', 'lv_owner_perms' %>
+
+ <%= text_field_with_label "Group permissions:",
'storage_volume', 'lv_group_perms' %>
+
+ <%= text_field_with_label "Mode permissions:",
'storage_volume', 'lv_mode_perms' %>
+<%- end -%>
+<%= text_field_with_label "LUN:", 'storage_volume',
'lun' if @storage_volume.get_type_label==StoragePool::ISCSI %>
+
+<%= text_field_with_label "Filename:", 'storage_volume',
'filename' if @storage_volume.get_type_label==StoragePool::NFS %>
+
+
+<!--[eoform:storage_volume]-->
+
diff --git a/src/app/views/storage_volume/new.rhtml
b/src/app/views/storage_volume/new.rhtml
new file mode 100644
index 0000000..4993642
--- /dev/null
+++ b/src/app/views/storage_volume/new.rhtml
@@ -0,0 +1,47 @@
+<%- content_for :title do -%>
+ <%= _("Add New Volume") %>
+<%- end -%>
+<%- content_for :description do -%>
+ Add a new Storage Volume to
+ <%= if @storage_volume.get_type_label==StoragePool::LVM
+ @source_volume.display_name
+ else
+ @storage_pool.display_name
+ end %>.
+<%- end -%>
+<div class="panel_header"></div>
+<div class="dialog_form">
+<form method="POST" action="<%= url_for :action =>
'create' %>" id="storage_volume_form" >
+ <div class="dialog_form">
+ <div id="new_storage_pool">
+ <%= render :partial => 'new_volume_form' %>
+ </div>
+ </div>
+ <!-- FIXME: need to pop up the details dialog again -->
+ <%= popup_footer("$('#storage_volume_form').submit()",
"New Storage Volume") %>
+</form>
+</div>
+<script type="text/javascript">
+function afterStorageVolume(response, status){
+ ajax_validation(response, status);
+ if (response.success) {
+ <% if @return_facebox %>
+ $('#window').fadeOut('fast');
+ $("#window").empty().load("<%= @return_facebox
%>")
+ $('#window').fadeIn('fast');
+ <% else %>
+ $(document).trigger('close.facebox');
+ <% end %>
+ }
+}
+$(function() {
+ var storagevolumeoptions = {
+ target: '<%= url_for :action => 'create'
%>', // target element to update
+ dataType: 'json',
+ success: afterStorageVolume // post-submit callback
+ };
+
+ // bind form using 'ajaxForm'
+ $('#storage_volume_form').ajaxForm(storagevolumeoptions);
+});
+</script>
diff --git a/src/app/views/storage_volume/show.rhtml
b/src/app/views/storage_volume/show.rhtml
new file mode 100644
index 0000000..c2434aa
--- /dev/null
+++ b/src/app/views/storage_volume/show.rhtml
@@ -0,0 +1,87 @@
+<%- content_for :title do -%>
+ <%=h @storage_volume.display_name %>
+<%- end -%>
+
+<%- content_for :action_links do -%>
+ <%if @can_modify -%>
+ <%if @storage_volume.supports_lvm_subdivision and
@storage_volume.vms.empty? -%>
+ <%= link_to image_tag("icon_addstorage.png") + " Add
new Volume",
+ {:controller => 'storage_volume',
:action => 'new', :source_volume_id => @storage_volume.id},
+ :rel=>"facebox[.bolder]",
:class=>"selection_facebox" %>
+ <% end %>
+ <%if @storage_volume.deletable -%>
+ <a href="#confirm_delete"
rel="facebox[.bolder]">
+ <%= image_tag "icon_x.png" %> Delete
+ </a>
+ <%- end -%>
+ <%- end -%>
+<%- end -%>
+<%= confirmation_dialog("confirm_delete", "Are you
sure?", "delete_volume()") %>
+
+ <div class="selection_key">
+ <% unless @storage_volume.storage_pool[:type] ==
"LvmStoragePool" %>
+ IP address:<br/>
+ <% end %>
+ <% if @storage_volume.storage_pool[:type] ==
"IscsiStoragePool" %>
+ Port:<br/>
+ Target:<br/>
+ <% elsif @storage_volume.storage_pool[:type] ==
"NfsStoragePool" %>
+ Export path:<br/>
+ <% end %>
+ Type:<br/>
+ State:<br/>
+ Path:<br/>
+ <% if @storage_volume[:type] == "IscsiStorageVolume" %>
+ LUN:<br/>
+ <% elsif @storage_volume[:type] == "NfsStorageVolume" %>
+ Filename:<br/>
+ <% elsif @storage_volume[:type] == "LvmStorageVolume" %>
+ Volume Group:<br/>
+ Logical Volume:<br/>
+ Permissions (owner/group/mode):<br/>
+ <% end %>
+ Size:<br/>
+ </div>
+ <div class="selection_value">
+ <% unless @storage_volume.storage_pool[:type] ==
"LvmStoragePool" %>
+ <%=h @storage_volume.storage_pool.ip_addr %><br/>
+ <% end %>
+ <% if @storage_volume.storage_pool[:type] == "IscsiStoragePool"
%>
+ <%=h @storage_volume.storage_pool.port %><br/>
+ <%=h @storage_volume.storage_pool[:target] %><br/>
+ <% elsif @storage_volume.storage_pool[:type] ==
"NfsStoragePool" %>
+ <%=h @storage_volume.storage_pool.export_path %><br/>
+ <% end %>
+ <%=h @storage_volume.storage_pool.get_type_label %><br/>
+ <%=h @storage_volume.state %><br/>
+ <%=h @storage_volume.path %><br/>
+ <% if @storage_volume[:type] == "IscsiStorageVolume" %>
+ <%=h @storage_volume.lun %><br/>
+ <% elsif @storage_volume[:type] == "NfsStorageVolume" %>
+ <%=h @storage_volume.filename %><br/>
+ <% elsif @storage_volume[:type] == "LvmStorageVolume" %>
+ <%=h @storage_volume.storage_pool.vg_name %><br/>
+ <%=h @storage_volume.lv_name %><br/>
+ <%=h @storage_volume.lv_owner_perms %>/<%=h
@storage_volume.lv_group_perms %>/<%=h @storage_volume.lv_mode_perms
%><br/>
+ <% end %>
+ <%=h @storage_volume.size_in_gb %> GB<br/>
+ </div>
+<%- content_for :right do -%>
+
+<%- end -%>
+
+<script type="text/javascript">
+ function delete_volume()
+ {
+ $(document).trigger('close.facebox');
+ $.post('<%= url_for :controller => "storage_volume",
:action => "destroy" %>',
+ { storage_volume_ids: <%= @storage_volume.id %> },
+ function(data,status) {
+ // FIXME: reload tree
+ if (data.alert) {
+ $.jGrowl(data.alert);
+ }
+ empty_summary('storage_selection', 'Storage Pool or
Volume');
+ }, 'json');
+ }
+</script>
--
1.6.0.6
David Lutterkort
2009-Jan-26 21:12 UTC
[Ovirt-devel] [PATCH server 6/8] Remove delete_volumes, since it was not used
---
src/app/controllers/storage_volume_controller.rb | 49 ----------------------
src/app/views/storage_volume/show.rhtml | 2 +-
2 files changed, 1 insertions(+), 50 deletions(-)
diff --git a/src/app/controllers/storage_volume_controller.rb
b/src/app/controllers/storage_volume_controller.rb
index 197864a..93eb68c 100644
--- a/src/app/controllers/storage_volume_controller.rb
+++ b/src/app/controllers/storage_volume_controller.rb
@@ -117,54 +117,6 @@ class StorageVolumeController < ApplicationController
end
def destroy
- if params[:id]
- delete_volume
- else
- delete_volumes
- end
- end
-
- def delete_volumes
- storage_volume_ids_str = params[:storage_volume_ids]
- storage_volume_ids = storage_volume_ids_str.split(",").collect
{|x| x.to_i}
- alerts = []
- status = true
- begin
- StorageVolume.transaction do
- storage = StorageVolume.find(:all, :conditions => "id in
(#{storage_volume_ids.join(', ')})")
- unless storage.empty?
- set_perms(storage[0].storage_pool.hardware_pool)
- unless @can_modify and storage[0].storage_pool.user_subdividable
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => false,
- :alert => "You do not have permission to delete this
storage volume." } }
- format.xml { head :forbidden }
- end
- else
- storage.each do |storage_volume|
- alert, success = delete_volume_internal(storage_volume)
- alerts << alert
- status = false unless success
- end
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => status, :alert =>
alerts.join("\n") } }
- format.xml { head(status ? :ok : :method_not_allowed) }
- end
- end
- else
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => false, :alert => "no volumes
selected" } }
- format.xml { head(status ? :ok : :method_not_allowed) }
- end
- end
- end
- end
- end
-
- def delete_volume
@storage_volume = StorageVolume.find(params[:id])
set_perms(@storage_volume.storage_pool.hardware_pool)
unless @can_modify and @storage_volume.storage_pool.user_subdividable
@@ -182,7 +134,6 @@ class StorageVolumeController < ApplicationController
format.xml { head(success ? :ok : :method_not_allowed) }
end
end
-
end
def pre_create
diff --git a/src/app/views/storage_volume/show.rhtml
b/src/app/views/storage_volume/show.rhtml
index c2434aa..3963a3c 100644
--- a/src/app/views/storage_volume/show.rhtml
+++ b/src/app/views/storage_volume/show.rhtml
@@ -75,7 +75,7 @@
{
$(document).trigger('close.facebox');
$.post('<%= url_for :controller => "storage_volume",
:action => "destroy" %>',
- { storage_volume_ids: <%= @storage_volume.id %> },
+ { id: <%= @storage_volume.id %> },
function(data,status) {
// FIXME: reload tree
if (data.alert) {
--
1.6.0.6
David Lutterkort
2009-Jan-26 21:12 UTC
[Ovirt-devel] [PATCH server 7/8] Produce a human-readable error when deleting a pool fails
---
src/app/controllers/storage_controller.rb | 6 ++++--
src/app/views/errors/simple.xml.builder | 3 +++
2 files changed, 7 insertions(+), 2 deletions(-)
create mode 100644 src/app/views/errors/simple.xml.builder
diff --git a/src/app/controllers/storage_controller.rb
b/src/app/controllers/storage_controller.rb
index 9674125..721cfc0 100644
--- a/src/app/controllers/storage_controller.rb
+++ b/src/app/controllers/storage_controller.rb
@@ -215,10 +215,12 @@ class StorageController < ApplicationController
def destroy
unless @storage_pool.movable?
+ @error = "Cannot delete storage with associated vms"
respond_to do |format|
format.json { render :json => { :object =>
"storage_pool",
- :success => false,
- :alert => "Cannot delete storage with associated vms"
} }
+ :success => false, :alert => @error } }
+ format.xml { render :template => "errors/simple", :layout
=> false,
+ :status => :forbidden }
end
return
end
diff --git a/src/app/views/errors/simple.xml.builder
b/src/app/views/errors/simple.xml.builder
new file mode 100644
index 0000000..d8d3c5b
--- /dev/null
+++ b/src/app/views/errors/simple.xml.builder
@@ -0,0 +1,3 @@
+xml.instruct!
+
+xml.error @error
--
1.6.0.6
David Lutterkort
2009-Jan-26 21:12 UTC
[Ovirt-devel] [PATCH server 8/8] REST route for storage volumes
---
src/config/routes.rb | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/config/routes.rb b/src/config/routes.rb
index 132072e..168ded5 100644
--- a/src/config/routes.rb
+++ b/src/config/routes.rb
@@ -53,6 +53,7 @@ ActionController::Routing::Routes.draw do |map|
# REST work out of the box, and use these as the default routes
map.resources :hosts, :controller => 'host'
map.resources :storage_pools, :controller => 'storage'
+ map.resources :storage_volumes, :controller => 'storage_volume'
map.resources :hardware_pools, :controller => 'hardware' do
|hardware_pools|
hardware_pools.resources :hosts, :controller => 'host'
hardware_pools.resources :storage_pools, :controller =>
'storage'
--
1.6.0.6
This is a rebase of the patches onto the current HEAD of next
David Lutterkort
2009-Feb-02 20:35 UTC
[Ovirt-devel] [PATCH server 1/8] Wrap generation of error message in respond_to block
---
src/app/controllers/storage_controller.rb | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/app/controllers/storage_controller.rb
b/src/app/controllers/storage_controller.rb
index 1920e27..160d22e 100644
--- a/src/app/controllers/storage_controller.rb
+++ b/src/app/controllers/storage_controller.rb
@@ -302,10 +302,12 @@ class StorageController < ApplicationController
def destroy
unless @storage_pool.movable?
- format.json { render :json => { :object => "storage_pool",
- :success => false,
- :alert => "Cannot delete storage with associated vms" } }
- return
+ respond_to do |format|
+ format.json { render :json => { :object =>
"storage_pool",
+ :success => false,
+ :alert => "Cannot delete storage with associated vms"
} }
+ end
+ return
end
pool = @storage_pool.hardware_pool
--
1.6.0.6
David Lutterkort
2009-Feb-02 20:35 UTC
[Ovirt-devel] [PATCH server 2/8] Remove client/ directory, it will live in its own repo
---
client/README | 17 -------
client/examples/script.rb | 101 --------------------------------------------
client/lib/ovirt.rb | 102 ---------------------------------------------
3 files changed, 0 insertions(+), 220 deletions(-)
delete mode 100644 client/README
delete mode 100755 client/examples/script.rb
delete mode 100644 client/lib/ovirt.rb
diff --git a/client/README b/client/README
deleted file mode 100644
index ee1db15..0000000
--- a/client/README
+++ /dev/null
@@ -1,17 +0,0 @@
-This is a very simple client library for accessing the OVirt API from Ruby.
-
-The file examples/script.rb contains a script that shows how this is done
-in some detail.
-
-You must have ActiveResource installed, e.g. with 'yum install
-rubygem-activeresource'
-
-The server is specified with a URL of the form
- http://USER:PASSWORD at HOST/ovirt
-
-This requires that the server is configured to allow HTTP authentication,
-since there are no mechanisms in the API to forward krb5 tickets.
-
-Before calling any other method on the API, you need to call
- OVirt::Base::site = "http://USER:PASSWORD at HOST/ovirt"
- OVirt::Base::login
diff --git a/client/examples/script.rb b/client/examples/script.rb
deleted file mode 100755
index 1485535..0000000
--- a/client/examples/script.rb
+++ /dev/null
@@ -1,101 +0,0 @@
-#! /usr/bin/ruby
-
-# Sample script that shows how to use the OVirt API
-
-require 'pp'
-require 'rubygems'
-require 'activeresource'
-require 'optparse'
-
-require 'ovirt'
-
-def move_random_host(hosts, pool)
- host = hosts[rand(hosts.size)]
- puts "Move #{host.hostname} to #{pool.name}"
- pool.hosts << host
- pool.save
-end
-
-def element_path(obj)
- "[#{obj.class.element_path(obj.id)}]"
-end
-
-def print_pool(pool)
- puts "\n\nPool #{pool.name}: #{pool.hosts.size} hosts,
#{pool.storage_pools.size} storage pools #{element_path(pool)} "
- puts "=" * 75
- pool.hosts.each do |h|
- printf "%-36s %s\n", h.hostname, element_path(h)
- end
- pool.storage_pools.each do |sp|
- type = sp.nfs? ? "NFS" : "iSCSI"
- printf "%-5s %-30s %s\n", type, sp.label, element_path(sp)
- end
- puts "-" * 75
-end
-
-# Plumbing so we can find the OVirt server
-# "http://ovirt.watzmann.net:3000/ovirt/rest"
-PROGNAME=File::basename($0)
-OVirt::Base.site = ENV["OVIRT_SERVER"]
-opts = OptionParser.new("#{PROGNAME} GLOBAL_OPTS")
-opts.separator(" Run some things against an OVirt server. The server is
specified with")
-opts.separator(" the -s option as a URL of the form http://USER:PASSWORD
at SERVER/ovirt")
-opts.separator("")
-opts.separator "Global options:"
-opts.on("-s", "--server=URL", "The OVirt server. Since
there is no auth\n" +
- "#{" "*37}yet, must be the mongrel server port.\n"
+
- "#{" "*37}Overrides env var OVIRT_SERVER") do |val|
- OVirt::Base.site = val
-end
-
-opts.order(ARGV)
-
-unless OVirt::Base.site
- $stderr.puts <<EOF
-You must specify the OVirt server to connect to, either with the
---server option or through the OVIRT_SERVER environment variable
-EOF
- exit 1
-end
-
-OVirt::Base.login
-
-# Get a single host by name
-host = OVirt::Host.find_by_hostname("node3.priv.ovirt.org")
-puts "#{host.uuid} has id #{host.id}"
-
-# What's in the default pool
-defpool = OVirt::HardwarePool.default_pool
-print_pool(defpool)
-
-# Create a new hardware pool
-mypool = OVirt::HardwarePool.find_by_path("/default/mypool")
-unless mypool
- puts "Create mypool"
- mypool = OVirt::HardwarePool.create( { :parent_id => defpool.id,
- :name => "mypool" } )
-end
-
-# Move some hosts around
-puts
-if defpool.hosts.size > 1
- move_random_host(defpool.hosts, mypool)
-elsif mypool.hosts.size > 0
- move_random_host(mypool.hosts, defpool)
-end
-
-# Delete all storage pools for mypool and add a new one
-mypool.storage_pools.each do |sp|
- puts "Delete storage pool #{sp.id}"
- sp.destroy
-end
-
-storage_pool = OVirt::StoragePool.create( { :storage_type =>
"NFS",
- :hardware_pool_id => mypool.id,
- :ip_addr =>
"192.168.122.50",
- :export_path =>
"/exports/pool1" } )
-puts "Created storage pool #{storage_pool.id}"
-
-# For some reason, mypool.reload doesn't work here
-mypool = OVirt::HardwarePool.find_by_path("/default/mypool")
-print_pool(mypool)
diff --git a/client/lib/ovirt.rb b/client/lib/ovirt.rb
deleted file mode 100644
index 15dc467..0000000
--- a/client/lib/ovirt.rb
+++ /dev/null
@@ -1,102 +0,0 @@
-require 'pp'
-require 'rubygems'
-require 'activeresource'
-
-class ActiveResource::Connection
- attr_accessor :session
-
- alias_method :old_default_header, :default_header
-
- def default_header
- old_default_header
- @default_header ||= {}
- if session
- @default_header["Cookie"] = session
- end
- @default_header
- end
-end
-
-module OVirt
- class Base < ActiveResource::Base
- LOGIN_PATH = "login/login"
-
- def self.login
- response = nil
- begin
- response = connection.get(prefix + LOGIN_PATH)
- rescue ActiveResource::Redirection => e
- response = e.response
- end
- unless connection.session = session_cookie(response)
- raise "Authentication failed"
- end
- end
-
- private
- def self.session_cookie(response)
- if cookies = response.get_fields("Set-Cookie")
- cookies.find { |cookie|
- cookie.split(";")[0].split("=")[0] ==
"_ovirt_session_id"
- }
- end
- end
-
- end
-
- class HardwarePool < Base
- def self.find_by_path(path)
- find(:first, :params => { :path => path })
- end
-
- def self.default_pool
- find(:first, :params => { :path => "/default" })
- end
- end
-
- class StoragePool < Base
- def iscsi?
- attributes["type"] == "IscsiStoragePool"
- end
-
- def nfs?
- attributes["type"] == "NfsStoragePool"
- end
-
- def label
- if iscsi?
- "#{ip_addr}:#{port}:#{target}"
- elsif nfs?
- "#{ip_addr}:#{export_path}"
- else
- raise "Unknown type #{attributes["type"]}"
- end
- end
- end
-
- class IscsiStoragePool < StoragePool
- def initialize(attributes = {})
- super(attributes.update( "type" =>
"IscsiStoragePool" ))
- end
- end
-
- class NfsStoragePool < StoragePool
- def initialize(attributes = {})
- super(attributes.update( "type" =>
"NfsStoragePool" ))
- end
- end
-
- class Host < Base
- def self.find_by_uuid(uuid)
- find(:first, :params => { :uuid => uuid })
- end
-
- def self.find_by_hostname(hostname)
- find(:first, :params => { :hostname => hostname })
- end
-
- def hardware_pool
- HardwarePool.find(hardware_pool_id)
- end
- end
-end
--
1.6.0.6
David Lutterkort
2009-Feb-02 20:35 UTC
[Ovirt-devel] [PATCH server 3/8] Include CPU's in host information
---
src/app/controllers/hardware_controller.rb | 7 ++++++-
src/app/controllers/host_controller.rb | 2 +-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/app/controllers/hardware_controller.rb
b/src/app/controllers/hardware_controller.rb
index fc16a27..0f9cceb 100644
--- a/src/app/controllers/hardware_controller.rb
+++ b/src/app/controllers/hardware_controller.rb
@@ -51,7 +51,12 @@ class HardwareController < PoolController
end
respond_to do |format|
- format.xml { render :xml => @pools.to_xml(XML_OPTS) }
+ format.xml {
+ opts = XML_OPTS.dup
+ opts[:include] = opts[:include].inject({}) { |m, k| m[k] = {}; m }
+ opts[:include][:hosts] = { :include => :cpus }
+ render :xml => @pools.to_xml(opts)
+ }
end
end
diff --git a/src/app/controllers/host_controller.rb
b/src/app/controllers/host_controller.rb
index 02ad8c9..f0b8c2b 100644
--- a/src/app/controllers/host_controller.rb
+++ b/src/app/controllers/host_controller.rb
@@ -61,7 +61,7 @@ class HostController < ApplicationController
else
respond_to do |format|
format.html { render :layout => 'selection' }
- format.xml { render :xml => @host.to_xml }
+ format.xml { render :xml => @host.to_xml(:include => [ :cpus ] )
}
end
end
end
--
1.6.0.6
David Lutterkort
2009-Feb-02 20:35 UTC
[Ovirt-devel] [PATCH server 4/8] API: include storage_volumes; indicate type for individual pools
---
src/app/controllers/storage_controller.rb | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/app/controllers/storage_controller.rb
b/src/app/controllers/storage_controller.rb
index 160d22e..ee9f116 100644
--- a/src/app/controllers/storage_controller.rb
+++ b/src/app/controllers/storage_controller.rb
@@ -32,7 +32,7 @@ class StorageController < ApplicationController
list
respond_to do |format|
format.html { render :action => 'list' }
- format.xml { render :xml => @storage_pools.to_xml }
+ format.xml { render :xml => @storage_pools.to_xml( :include =>
:storage_volumes) }
end
end
@@ -80,7 +80,12 @@ class StorageController < ApplicationController
else
respond_to do |format|
format.html { render :layout => 'selection' }
- format.xml { render :xml => @storage_pool.to_xml }
+ format.xml {
+ xml_txt = @storage_pool.to_xml(:include => :storage_volumes) do
|xml|
+ xml.type @storage_pool.class.name
+ end
+ render :xml => xml_txt
+ }
end
end
end
--
1.6.0.6
David Lutterkort
2009-Feb-02 20:35 UTC
[Ovirt-devel] [PATCH server 5/8] Factor StorageVolume functionality out of StorageController
Storage volumes can now be accessed through their own controller. This is
needed to expose them in the API.
---
src/app/controllers/search_controller.rb | 12 +-
src/app/controllers/storage_controller.rb | 204 -----------------
src/app/controllers/storage_volume_controller.rb | 228 ++++++++++++++++++++
src/app/views/storage/_list_volumes.rhtml | 2 +-
src/app/views/storage/_new_volume_form.rhtml | 24 --
src/app/views/storage/new_volume.rhtml | 53 -----
src/app/views/storage/show.rhtml | 2 +-
src/app/views/storage/show_volume.rhtml | 87 --------
.../views/storage_volume/_new_volume_form.rhtml | 24 ++
src/app/views/storage_volume/new.rhtml | 53 +++++
src/app/views/storage_volume/show.rhtml | 87 ++++++++
11 files changed, 400 insertions(+), 376 deletions(-)
create mode 100644 src/app/controllers/storage_volume_controller.rb
delete mode 100644 src/app/views/storage/_new_volume_form.rhtml
delete mode 100644 src/app/views/storage/new_volume.rhtml
delete mode 100644 src/app/views/storage/show_volume.rhtml
create mode 100644 src/app/views/storage_volume/_new_volume_form.rhtml
create mode 100644 src/app/views/storage_volume/new.rhtml
create mode 100644 src/app/views/storage_volume/show.rhtml
diff --git a/src/app/controllers/search_controller.rb
b/src/app/controllers/search_controller.rb
index 7551242..0fb6456 100644
--- a/src/app/controllers/search_controller.rb
+++ b/src/app/controllers/search_controller.rb
@@ -37,14 +37,14 @@ class SearchController < ApplicationController
"NfsStoragePool" => {:controller =>
"storage",
:show_action => "show",
:searched => true},
- "IscsiStorageVolume" => {:controller =>
"storage",
- :show_action =>
"show_volume",
+ "IscsiStorageVolume" => {:controller =>
"storage_volume",
+ :show_action => "show",
:searched => false},
- "NfsStorageVolume" => {:controller =>
"storage",
- :show_action =>
"show_volume",
+ "NfsStorageVolume" => {:controller =>
"storage_volume",
+ :show_action => "show",
:searched => false},
- "LvmStorageVolume" => {:controller =>
"storage",
- :show_action =>
"show_volume",
+ "LvmStorageVolume" => {:controller =>
"storage_volume",
+ :show_action => "show",
:searched => false}}
MULTI_TYPE_MODELS = {"StoragePool" =>
["IscsiStoragePool", "NfsStoragePool"]}
diff --git a/src/app/controllers/storage_controller.rb
b/src/app/controllers/storage_controller.rb
index ee9f116..3579967 100644
--- a/src/app/controllers/storage_controller.rb
+++ b/src/app/controllers/storage_controller.rb
@@ -24,8 +24,6 @@ class StorageController < ApplicationController
before_filter :pre_pool_admin, :only => [:refresh]
before_filter :pre_new2, :only => [:new2]
- before_filter :pre_json, :only => [:storage_volumes_json]
- before_filter :pre_create_volume, :only => [:create_volume]
before_filter :pre_add, :only => [:add, :addstorage]
def index
@@ -90,35 +88,6 @@ class StorageController < ApplicationController
end
end
- def storage_volumes_json
- @storage_pool = StoragePool.find(params[:id])
- set_perms(@storage_pool.hardware_pool)
- unless @can_view
- flash[:notice] = 'You do not have permission to view this storage
pool: redirecting to top level'
- redirect_to :controller => 'dashboard'
- end
- attr_list = []
- attr_list << :id if (@storage_pool.user_subdividable and @can_modify)
- attr_list += [:display_name, :size_in_gb, :get_type_label]
- json_list(@storage_pool.storage_volumes, attr_list)
- end
- def show_volume
- @storage_volume = StorageVolume.find(params[:id])
- set_perms(@storage_volume.storage_pool.hardware_pool)
- unless @can_view
- flash[:notice] = 'You do not have permission to view this storage
volume: redirecting to top level'
- respond_to do |format|
- format.html { redirect_to :controller => 'dashboard' }
- format.xml { head :forbidden }
- end
- else
- respond_to do |format|
- format.html { render :layout => 'selection' }
- format.xml { render :xml => @storage_volume.to_xml }
- end
- end
- end
-
def new
end
@@ -127,78 +96,6 @@ class StorageController < ApplicationController
render :layout => false
end
- def new_volume
- @return_to_workflow = params[:return_to_workflow]
- @return_to_workflow ||= false
- if params[:storage_pool_id]
- @storage_pool = StoragePool.find(params[:storage_pool_id])
- unless @storage_pool.user_subdividable
- #fixme: proper error page for popups
- redirect_to :controller => 'dashboard'
- return
- end
- new_volume_internal(@storage_pool,
- { :storage_pool_id => params[:storage_pool_id]})
- else
- @source_volume = StorageVolume.find(params[:source_volume_id])
- unless @source_volume.supports_lvm_subdivision
- #fixme: proper error page for popups
- redirect_to :controller => 'dashboard'
- return
- end
- lvm_pool = @source_volume.lvm_storage_pool
- unless lvm_pool
- # FIXME: what should we do about VG/LV names?
- # for now auto-create VG name as ovirt_vg_#{@source_volume.id}
- new_params = { :vg_name =>
"ovirt_vg_#{@source_volume.id}",
- :hardware_pool_id => @source_volume.storage_pool.hardware_pool_id}
- lvm_pool = StoragePool.factory(StoragePool::LVM, new_params)
- lvm_pool.source_volumes << @source_volume
- lvm_pool.save!
- end
- new_volume_internal(lvm_pool, { :storage_pool_id => lvm_pool.id})
- @storage_volume.lv_owner_perms='0744'
- @storage_volume.lv_group_perms='0744'
- @storage_volume.lv_mode_perms='0744'
- end
- render :layout => 'popup'
- end
-
- def create_volume
- begin
- StorageVolume.transaction do
- @storage_volume.save!
- @task = StorageVolumeTask.new({ :user => @user,
- :task_target => @storage_volume,
- :action =>
StorageVolumeTask::ACTION_CREATE_VOLUME,
- :state => Task::STATE_QUEUED})
- @task.save!
- end
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => true,
- :alert => "Storage Volume was successfully created.",
- :new_volume =>
@storage_volume.storage_tree_element({:filter_unavailable => false, :state
=> 'new'})} }
- format.xml { render :xml => @storage_volume,
- :status => :created,
- # FIXME: create storage_volume_url method if relevant
- :location => storage_pool_url(@storage_volume)
- }
- end
- rescue => ex
- # FIXME: need to distinguish volume vs. task save errors
- respond_to do |format|
- format.json {
- json_hash = { :object => "storage_volume", :success
=> false,
- :errors => @storage_volume.errors.localize_error_messages.to_a
}
- json_hash[:message] = ex.message if json_hash[:errors].empty?
- render :json => json_hash }
- format.xml { render :xml => @storage_volume.errors,
- :status => :unprocessable_entity }
- end
- end
- end
-
def insert_refresh_task
@task = StorageTask.new({ :user => @user,
:task_target => @storage_pool,
@@ -330,67 +227,6 @@ class StorageController < ApplicationController
end
end
- def delete_volumes
- storage_volume_ids_str = params[:storage_volume_ids]
- storage_volume_ids = storage_volume_ids_str.split(",").collect
{|x| x.to_i}
- alerts = []
- status = true
- begin
- StorageVolume.transaction do
- storage = StorageVolume.find(:all, :conditions => "id in
(#{storage_volume_ids.join(', ')})")
- unless storage.empty?
- set_perms(storage[0].storage_pool.hardware_pool)
- unless @can_modify and storage[0].storage_pool.user_subdividable
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => false,
- :alert => "You do not have permission to delete this
storage volume." } }
- format.xml { head :forbidden }
- end
- else
- storage.each do |storage_volume|
- alert, success = delete_volume_internal(storage_volume)
- alerts << alert
- status = false unless success
- end
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => status, :alert =>
alerts.join("\n") } }
- format.xml { head(status ? :ok : :method_not_allowed) }
- end
- end
- else
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => false, :alert => "no volumes
selected" } }
- format.xml { head(status ? :ok : :method_not_allowed) }
- end
- end
- end
- end
- end
-
- def delete_volume
- @storage_volume = StorageVolume.find(params[:id])
- set_perms(@storage_volume.storage_pool.hardware_pool)
- unless @can_modify and @storage_volume.storage_pool.user_subdividable
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => false,
- :alert => "You do not have permission to delete this
storage volume." } }
- format.xml { head :forbidden }
- end
- else
- alert, success = delete_volume_internal(@storage_volume)
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => success, :alert => alert } }
- format.xml { head(success ? :ok : :method_not_allowed) }
- end
- end
-
- end
-
def pre_new
@hardware_pool = HardwarePool.find(params[:hardware_pool_id])
@perm_obj = @hardware_pool
@@ -424,49 +260,9 @@ class StorageController < ApplicationController
@storage_pool = StoragePool.find(params[:id])
@perm_obj = @storage_pool.hardware_pool
end
- def pre_create_volume
- volume = params[:storage_volume]
- unless type = params[:storage_type]
- type = volume.delete(:storage_type)
- end
- @storage_volume = StorageVolume.factory(type, volume)
- @perm_obj = @storage_volume.storage_pool.hardware_pool
- authorize_admin
- end
- def pre_json
- pre_show
- end
def pre_pool_admin
pre_edit
authorize_admin
end
- private
- def new_volume_internal(storage_pool, new_params)
- @storage_volume = StorageVolume.factory(storage_pool.get_type_label,
new_params)
- @perm_obj = @storage_volume.storage_pool.hardware_pool
- authorize_admin
- end
-
- def delete_volume_internal(volume)
- begin
- name = volume.display_name
- if !volume.vms.empty?
- vm_list = volume.vms.collect {|vm| vm.description}.join(", ")
- ["Storage Volume #{name} must be unattached from VMs (#{vm_list})
before deleting it.",
- false]
- else
- volume.state=StorageVolume::STATE_PENDING_DELETION
- volume.save!
- @task = StorageVolumeTask.new({ :user => @user,
- :task_target => volume,
- :action =>
StorageVolumeTask::ACTION_DELETE_VOLUME,
- :state => Task::STATE_QUEUED})
- @task.save!
- ["Storage Volume #{name} deletion was successfully queued.",
true]
- end
- rescue => ex
- ["Failed to delete storage volume #{name}
(#{ex.message}.",false]
- end
- end
end
diff --git a/src/app/controllers/storage_volume_controller.rb
b/src/app/controllers/storage_volume_controller.rb
new file mode 100644
index 0000000..ba486d2
--- /dev/null
+++ b/src/app/controllers/storage_volume_controller.rb
@@ -0,0 +1,228 @@
+#
+# Copyright (C) 2009 Red Hat, Inc.
+# Written by Scott Seago <sseago 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 StorageVolumeController < ApplicationController
+
+ before_filter :pre_create, :only => [:create]
+
+ def new
+ @return_to_workflow = params[:return_to_workflow] || false
+ if params[:storage_pool_id]
+ @storage_pool = StoragePool.find(params[:storage_pool_id])
+ unless @storage_pool.user_subdividable
+ #fixme: proper error page for popups
+ redirect_to :controller => 'dashboard'
+ return
+ end
+ new_volume_internal(@storage_pool,
+ { :storage_pool_id => params[:storage_pool_id]})
+ else
+ @source_volume = StorageVolume.find(params[:source_volume_id])
+ unless @source_volume.supports_lvm_subdivision
+ #fixme: proper error page for popups
+ redirect_to :controller => 'dashboard'
+ return
+ end
+ lvm_pool = @source_volume.lvm_storage_pool
+ unless lvm_pool
+ # FIXME: what should we do about VG/LV names?
+ # for now auto-create VG name as ovirt_vg_#{@source_volume.id}
+ new_params = { :vg_name =>
"ovirt_vg_#{@source_volume.id}",
+ :hardware_pool_id => @source_volume.storage_pool.hardware_pool_id}
+ lvm_pool = StoragePool.factory(StoragePool::LVM, new_params)
+ lvm_pool.source_volumes << @source_volume
+ lvm_pool.save!
+ end
+ new_volume_internal(lvm_pool, { :storage_pool_id => lvm_pool.id})
+ @storage_volume.lv_owner_perms='0744'
+ @storage_volume.lv_group_perms='0744'
+ @storage_volume.lv_mode_perms='0744'
+ end
+ render :layout => 'popup'
+ end
+
+ def create
+ begin
+ StorageVolume.transaction do
+ @storage_volume.save!
+ @task = StorageVolumeTask.new({ :user => @user,
+ :task_target => @storage_volume,
+ :action =>
StorageVolumeTask::ACTION_CREATE_VOLUME,
+ :state => Task::STATE_QUEUED})
+ @task.save!
+ end
+ respond_to do |format|
+ format.json { render :json => { :object =>
"storage_volume",
+ :success => true,
+ :alert => "Storage Volume was successfully created." ,
+ :new_volume =>
@storage_volume.storage_tree_element({:filter_unavailable => false, :state
=> 'new'})} }
+ format.xml { render :xml => @storage_volume,
+ :status => :created,
+ # FIXME: create storage_volume_url method if relevant
+ :location => storage_pool_url(@storage_volume)
+ }
+ end
+ rescue => ex
+ # FIXME: need to distinguish volume vs. task save errors
+ respond_to do |format|
+ format.json {
+ json_hash = { :object => "storage_volume", :success
=> false,
+ :errors => @storage_volume.errors.localize_error_messages.to_a
}
+ json_hash[:message] = ex.message if json_hash[:errors].empty?
+ render :json => json_hash }
+ format.xml { render :xml => @storage_volume.errors,
+ :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ def show
+ @storage_volume = StorageVolume.find(params[:id])
+ set_perms(@storage_volume.storage_pool.hardware_pool)
+ @storage_pool = @storage_volume.storage_pool
+ unless @can_view
+ flash[:notice] = 'You do not have permission to view this storage
volume: redirecting to top level'
+ respond_to do |format|
+ format.html { redirect_to :controller => 'dashboard' }
+ format.json { redirect_to :controller => 'dashboard' }
+ format.xml { head :forbidden }
+ end
+ else
+ respond_to do |format|
+ format.html { render :layout => 'selection' }
+ format.json do
+ attr_list = []
+ attr_list << :id if (@storage_pool.user_subdividable and
@can_modify)
+ attr_list += [:display_name, :size_in_gb, :get_type_label]
+ json_list(@storage_pool.storage_volumes, attr_list)
+ end
+ format.xml { render :xml => @storage_volume.to_xml }
+ end
+ end
+ end
+
+ def destroy
+ if params[:id]
+ delete_volume
+ else
+ delete_volumes
+ end
+ end
+
+ def delete_volumes
+ storage_volume_ids_str = params[:storage_volume_ids]
+ storage_volume_ids = storage_volume_ids_str.split(",").collect
{|x| x.to_i}
+ alerts = []
+ status = true
+ begin
+ StorageVolume.transaction do
+ storage = StorageVolume.find(:all, :conditions => "id in
(#{storage_volume_ids.join(', ')})")
+ unless storage.empty?
+ set_perms(storage[0].storage_pool.hardware_pool)
+ unless @can_modify and storage[0].storage_pool.user_subdividable
+ respond_to do |format|
+ format.json { render :json => { :object =>
"storage_volume",
+ :success => false,
+ :alert => "You do not have permission to delete this
storage volume." } }
+ format.xml { head :forbidden }
+ end
+ else
+ storage.each do |storage_volume|
+ alert, success = delete_volume_internal(storage_volume)
+ alerts << alert
+ status = false unless success
+ end
+ respond_to do |format|
+ format.json { render :json => { :object =>
"storage_volume",
+ :success => status, :alert =>
alerts.join("\n") } }
+ format.xml { head(status ? :ok : :method_not_allowed) }
+ end
+ end
+ else
+ respond_to do |format|
+ format.json { render :json => { :object =>
"storage_volume",
+ :success => false, :alert => "no volumes
selected" } }
+ format.xml { head(status ? :ok : :method_not_allowed) }
+ end
+ end
+ end
+ end
+ end
+
+ def delete_volume
+ @storage_volume = StorageVolume.find(params[:id])
+ set_perms(@storage_volume.storage_pool.hardware_pool)
+ unless @can_modify and @storage_volume.storage_pool.user_subdividable
+ respond_to do |format|
+ format.json { render :json => { :object =>
"storage_volume",
+ :success => false,
+ :alert => "You do not have permission to delete this
storage volume." } }
+ format.xml { head :forbidden }
+ end
+ else
+ alert, success = delete_volume_internal(@storage_volume)
+ respond_to do |format|
+ format.json { render :json => { :object =>
"storage_volume",
+ :success => success, :alert => alert } }
+ format.xml { head(success ? :ok : :method_not_allowed) }
+ end
+ end
+
+ end
+
+ def pre_create
+ volume = params[:storage_volume]
+ unless type = params[:storage_type]
+ type = volume.delete(:storage_type)
+ end
+ @storage_volume = StorageVolume.factory(type, volume)
+ @perm_obj = @storage_volume.storage_pool.hardware_pool
+ authorize_admin
+ end
+
+ private
+ def new_volume_internal(storage_pool, new_params)
+ @storage_volume = StorageVolume.factory(storage_pool.get_type_label,
new_params)
+ @perm_obj = @storage_volume.storage_pool.hardware_pool
+ authorize_admin
+ end
+
+ def delete_volume_internal(volume)
+ begin
+ name = volume.display_name
+ if !volume.vms.empty?
+ vm_list = volume.vms.collect {|vm| vm.description}.join(", ")
+ ["Storage Volume #{name} must be unattached from VMs (#{vm_list})
before deleting it.",
+ false]
+ else
+ volume.state=StorageVolume::STATE_PENDING_DELETION
+ volume.save!
+ @task = StorageVolumeTask.new({ :user => @user,
+ :task_target => volume,
+ :action =>
StorageVolumeTask::ACTION_DELETE_VOLUME,
+ :state => Task::STATE_QUEUED})
+ @task.save!
+ ["Storage Volume #{name} deletion was successfully queued.",
true]
+ end
+ rescue => ex
+ ["Failed to delete storage volume #{name}
(#{ex.message}.",false]
+ end
+ end
+
+end
diff --git a/src/app/views/storage/_list_volumes.rhtml
b/src/app/views/storage/_list_volumes.rhtml
index 212720e..ab4f623 100644
--- a/src/app/views/storage/_list_volumes.rhtml
+++ b/src/app/views/storage/_list_volumes.rhtml
@@ -19,7 +19,7 @@
<tbody>
<% for storage_volume in type_volumes %>
<tr class="<%= cycle('odd','even', :name =>
type_volumes) %>">
- <% vol_hash = { :controller => 'storage', :action =>
'show_volume', :id => storage_volume }
+ <% vol_hash = { :controller => 'storage_volume', :action =>
'show', :id => storage_volume }
vol_hash[:vm_id] = vm_id if defined? vm_id
%>
<td style="text-align:left;"><%= link_to
storage_volume.storage_pool.ip_addr, vol_hash, { :class => "show" }
%>
diff --git a/src/app/views/storage/_new_volume_form.rhtml
b/src/app/views/storage/_new_volume_form.rhtml
deleted file mode 100644
index ae65e18..0000000
--- a/src/app/views/storage/_new_volume_form.rhtml
+++ /dev/null
@@ -1,24 +0,0 @@
-<%= error_messages_for 'storage_volume' %>
-
-<!--[form:storage_pool]-->
-<%= hidden_field 'storage_volume', 'storage_pool_id' %>
-<%= hidden_field_tag 'storage_type', @storage_volume.get_type_label
%>
-
-<%= text_field_with_label "Size (GB):", 'storage_volume',
'size_in_gb' %>
-
-<%if @storage_volume.get_type_label==StoragePool::LVM -%>
- <%= text_field_with_label "LV Name:", 'storage_volume',
'lv_name' %>
-
- <%= text_field_with_label "Owner permissions:",
'storage_volume', 'lv_owner_perms' %>
-
- <%= text_field_with_label "Group permissions:",
'storage_volume', 'lv_group_perms' %>
-
- <%= text_field_with_label "Mode permissions:",
'storage_volume', 'lv_mode_perms' %>
-<%- end -%>
-<%= text_field_with_label "LUN:", 'storage_volume',
'lun' if @storage_volume.get_type_label==StoragePool::ISCSI %>
-
-<%= text_field_with_label "Filename:", 'storage_volume',
'filename' if @storage_volume.get_type_label==StoragePool::NFS %>
-
-
-<!--[eoform:storage_volume]-->
-
diff --git a/src/app/views/storage/new_volume.rhtml
b/src/app/views/storage/new_volume.rhtml
deleted file mode 100644
index 2e49d16..0000000
--- a/src/app/views/storage/new_volume.rhtml
+++ /dev/null
@@ -1,53 +0,0 @@
-<%- content_for :title do -%>
- <%= _("Add New Volume") %>
-<%- end -%>
-<%- content_for :description do -%>
- Add a new Storage Volume to
- <%= if @storage_volume.get_type_label==StoragePool::LVM
- @source_volume.display_name
- else
- @storage_pool.display_name
- end %>.
-<%- end -%>
-<div class="panel_header"></div>
-<div class="dialog_form">
-<form method="POST" action="<%= url_for :action =>
'create_volume' %>" id="storage_volume_form" >
- <div class="dialog_form">
- <div id="new_storage_pool">
- <%= render :partial => 'new_volume_form' %>
- </div>
- </div>
- <!-- FIXME: need to pop up the details dialog again -->
- <% if @return_to_workflow %>
- <%# TODO: update this method in application_helper to take an array, so
we can include
- a callback or trigger to to go previous step in flow. %>
- <%= popup_footer("$('#storage_volume_form').submit()",
"New Storage Volume") %>
- <% else %>
- <%= popup_footer("$('#storage_volume_form').submit()",
"New Storage Volume") %>
- <% end %>
-</form>
-</div>
-<script type="text/javascript">
-function afterStorageVolume(response, status){
- ajax_validation(response, status);
- if (response.success) {
- //this is where I want to publish to...
- //$(document).trigger('STORAGE_VOLUME', [response.new_volume]);
- //but it only picks up correctly right now if I push it here, so this
needs to change later
- $('ul.ovirt-tree').trigger('STORAGE_VOLUME',
[response.new_volume]);
- <% unless @return_to_workflow -%>
- $(document).trigger('close.facebox');
- <% end -%>
- }
-}
-$(function() {
- var storagevolumeoptions = {
- target: '<%= url_for :action =>
'create_volume' %>', // target element to update
- dataType: 'json',
- success: afterStorageVolume // post-submit callback
- };
-
- // bind form using 'ajaxForm'
- $('#storage_volume_form').ajaxForm(storagevolumeoptions);
-});
-</script>
diff --git a/src/app/views/storage/show.rhtml b/src/app/views/storage/show.rhtml
index 7e02f32..dd52d79 100644
--- a/src/app/views/storage/show.rhtml
+++ b/src/app/views/storage/show.rhtml
@@ -12,7 +12,7 @@
</a>
<%if @storage_pool.user_subdividable -%>
<%= link_to image_tag("icon_addstorage.png") + " Add
new Volume",
- {:controller => 'storage', :action =>
'new_volume', :storage_pool_id => @storage_pool.id},
+ {:controller => 'storage_volume',
:action => 'new', :storage_pool_id => @storage_pool.id},
:rel=>"facebox[.bolder]",
:class=>"selection_facebox" %>
<% end %>
<a href="#confirm_delete_storage"
rel="facebox[.bolder]">
diff --git a/src/app/views/storage/show_volume.rhtml
b/src/app/views/storage/show_volume.rhtml
deleted file mode 100644
index f85feaa..0000000
--- a/src/app/views/storage/show_volume.rhtml
+++ /dev/null
@@ -1,87 +0,0 @@
-<%- content_for :title do -%>
- <%=h @storage_volume.display_name %>
-<%- end -%>
-
-<%- content_for :action_links do -%>
- <%if @can_modify -%>
- <%if @storage_volume.supports_lvm_subdivision and
@storage_volume.vms.empty? -%>
- <%= link_to image_tag("icon_addstorage.png") + " Add
new Volume",
- {:controller => 'storage', :action =>
'new_volume', :source_volume_id => @storage_volume.id},
- :rel=>"facebox[.bolder]",
:class=>"selection_facebox" %>
- <% end %>
- <%if @storage_volume.deletable -%>
- <a href="#confirm_delete"
rel="facebox[.bolder]">
- <%= image_tag "icon_x.png" %> Delete
- </a>
- <%- end -%>
- <%- end -%>
-<%- end -%>
-<%= confirmation_dialog("confirm_delete", "Are you
sure?", "delete_volume()") %>
-
- <div class="selection_key">
- <% unless @storage_volume.storage_pool[:type] ==
"LvmStoragePool" %>
- IP address:<br/>
- <% end %>
- <% if @storage_volume.storage_pool[:type] ==
"IscsiStoragePool" %>
- Port:<br/>
- Target:<br/>
- <% elsif @storage_volume.storage_pool[:type] ==
"NfsStoragePool" %>
- Export path:<br/>
- <% end %>
- Type:<br/>
- State:<br/>
- Path:<br/>
- <% if @storage_volume[:type] == "IscsiStorageVolume" %>
- LUN:<br/>
- <% elsif @storage_volume[:type] == "NfsStorageVolume" %>
- Filename:<br/>
- <% elsif @storage_volume[:type] == "LvmStorageVolume" %>
- Volume Group:<br/>
- Logical Volume:<br/>
- Permissions (owner/group/mode):<br/>
- <% end %>
- Size:<br/>
- </div>
- <div class="selection_value">
- <% unless @storage_volume.storage_pool[:type] ==
"LvmStoragePool" %>
- <%=h @storage_volume.storage_pool.ip_addr %><br/>
- <% end %>
- <% if @storage_volume.storage_pool[:type] == "IscsiStoragePool"
%>
- <%=h @storage_volume.storage_pool.port %><br/>
- <%=h @storage_volume.storage_pool[:target] %><br/>
- <% elsif @storage_volume.storage_pool[:type] ==
"NfsStoragePool" %>
- <%=h @storage_volume.storage_pool.export_path %><br/>
- <% end %>
- <%=h @storage_volume.storage_pool.get_type_label %><br/>
- <%=h @storage_volume.state %><br/>
- <%=h @storage_volume.path %><br/>
- <% if @storage_volume[:type] == "IscsiStorageVolume" %>
- <%=h @storage_volume.lun %><br/>
- <% elsif @storage_volume[:type] == "NfsStorageVolume" %>
- <%=h @storage_volume.filename %><br/>
- <% elsif @storage_volume[:type] == "LvmStorageVolume" %>
- <%=h @storage_volume.storage_pool.vg_name %><br/>
- <%=h @storage_volume.lv_name %><br/>
- <%=h @storage_volume.lv_owner_perms %>/<%=h
@storage_volume.lv_group_perms %>/<%=h @storage_volume.lv_mode_perms
%><br/>
- <% end %>
- <%=h @storage_volume.size_in_gb %> GB<br/>
- </div>
-<%- content_for :right do -%>
-
-<%- end -%>
-
-<script type="text/javascript">
- function delete_volume()
- {
- $(document).trigger('close.facebox');
- $.post('<%= url_for :controller => "storage", :action
=> "delete_volumes" %>',
- { storage_volume_ids: <%= @storage_volume.id %> },
- function(data,status) {
- // FIXME: reload tree
- if (data.alert) {
- $.jGrowl(data.alert);
- }
- empty_summary('storage_selection', 'Storage Pool or
Volume');
- }, 'json');
- }
-</script>
diff --git a/src/app/views/storage_volume/_new_volume_form.rhtml
b/src/app/views/storage_volume/_new_volume_form.rhtml
new file mode 100644
index 0000000..ae65e18
--- /dev/null
+++ b/src/app/views/storage_volume/_new_volume_form.rhtml
@@ -0,0 +1,24 @@
+<%= error_messages_for 'storage_volume' %>
+
+<!--[form:storage_pool]-->
+<%= hidden_field 'storage_volume', 'storage_pool_id' %>
+<%= hidden_field_tag 'storage_type', @storage_volume.get_type_label
%>
+
+<%= text_field_with_label "Size (GB):", 'storage_volume',
'size_in_gb' %>
+
+<%if @storage_volume.get_type_label==StoragePool::LVM -%>
+ <%= text_field_with_label "LV Name:", 'storage_volume',
'lv_name' %>
+
+ <%= text_field_with_label "Owner permissions:",
'storage_volume', 'lv_owner_perms' %>
+
+ <%= text_field_with_label "Group permissions:",
'storage_volume', 'lv_group_perms' %>
+
+ <%= text_field_with_label "Mode permissions:",
'storage_volume', 'lv_mode_perms' %>
+<%- end -%>
+<%= text_field_with_label "LUN:", 'storage_volume',
'lun' if @storage_volume.get_type_label==StoragePool::ISCSI %>
+
+<%= text_field_with_label "Filename:", 'storage_volume',
'filename' if @storage_volume.get_type_label==StoragePool::NFS %>
+
+
+<!--[eoform:storage_volume]-->
+
diff --git a/src/app/views/storage_volume/new.rhtml
b/src/app/views/storage_volume/new.rhtml
new file mode 100644
index 0000000..46d379e
--- /dev/null
+++ b/src/app/views/storage_volume/new.rhtml
@@ -0,0 +1,53 @@
+<%- content_for :title do -%>
+ <%= _("Add New Volume") %>
+<%- end -%>
+<%- content_for :description do -%>
+ Add a new Storage Volume to
+ <%= if @storage_volume.get_type_label==StoragePool::LVM
+ @source_volume.display_name
+ else
+ @storage_pool.display_name
+ end %>.
+<%- end -%>
+<div class="panel_header"></div>
+<div class="dialog_form">
+<form method="POST" action="<%= url_for :action =>
'create' %>" id="storage_volume_form" >
+ <div class="dialog_form">
+ <div id="new_storage_pool">
+ <%= render :partial => 'new_volume_form' %>
+ </div>
+ </div>
+ <!-- FIXME: need to pop up the details dialog again -->
+ <% if @return_to_workflow %>
+ <%# TODO: update this method in application_helper to take an array, so
we can include
+ a callback or trigger to to go previous step in flow. %>
+ <%= popup_footer("$('#storage_volume_form').submit()",
"New Storage Volume") %>
+ <% else %>
+ <%= popup_footer("$('#storage_volume_form').submit()",
"New Storage Volume") %>
+ <% end %>
+</form>
+</div>
+<script type="text/javascript">
+function afterStorageVolume(response, status){
+ ajax_validation(response, status);
+ if (response.success) {
+ //this is where I want to publish to...
+ //$(document).trigger('STORAGE_VOLUME', [response.new_volume]);
+ //but it only picks up correctly right now if I push it here, so this
needs to change later
+ $('ul.ovirt-tree').trigger('STORAGE_VOLUME',
[response.new_volume]);
+ <% unless @return_to_workflow -%>
+ $(document).trigger('close.facebox');
+ <% end -%>
+ }
+}
+$(function() {
+ var storagevolumeoptions = {
+ target: '<%= url_for :action => 'create'
%>', // target element to update
+ dataType: 'json',
+ success: afterStorageVolume // post-submit callback
+ };
+
+ // bind form using 'ajaxForm'
+ $('#storage_volume_form').ajaxForm(storagevolumeoptions);
+});
+</script>
diff --git a/src/app/views/storage_volume/show.rhtml
b/src/app/views/storage_volume/show.rhtml
new file mode 100644
index 0000000..c2434aa
--- /dev/null
+++ b/src/app/views/storage_volume/show.rhtml
@@ -0,0 +1,87 @@
+<%- content_for :title do -%>
+ <%=h @storage_volume.display_name %>
+<%- end -%>
+
+<%- content_for :action_links do -%>
+ <%if @can_modify -%>
+ <%if @storage_volume.supports_lvm_subdivision and
@storage_volume.vms.empty? -%>
+ <%= link_to image_tag("icon_addstorage.png") + " Add
new Volume",
+ {:controller => 'storage_volume',
:action => 'new', :source_volume_id => @storage_volume.id},
+ :rel=>"facebox[.bolder]",
:class=>"selection_facebox" %>
+ <% end %>
+ <%if @storage_volume.deletable -%>
+ <a href="#confirm_delete"
rel="facebox[.bolder]">
+ <%= image_tag "icon_x.png" %> Delete
+ </a>
+ <%- end -%>
+ <%- end -%>
+<%- end -%>
+<%= confirmation_dialog("confirm_delete", "Are you
sure?", "delete_volume()") %>
+
+ <div class="selection_key">
+ <% unless @storage_volume.storage_pool[:type] ==
"LvmStoragePool" %>
+ IP address:<br/>
+ <% end %>
+ <% if @storage_volume.storage_pool[:type] ==
"IscsiStoragePool" %>
+ Port:<br/>
+ Target:<br/>
+ <% elsif @storage_volume.storage_pool[:type] ==
"NfsStoragePool" %>
+ Export path:<br/>
+ <% end %>
+ Type:<br/>
+ State:<br/>
+ Path:<br/>
+ <% if @storage_volume[:type] == "IscsiStorageVolume" %>
+ LUN:<br/>
+ <% elsif @storage_volume[:type] == "NfsStorageVolume" %>
+ Filename:<br/>
+ <% elsif @storage_volume[:type] == "LvmStorageVolume" %>
+ Volume Group:<br/>
+ Logical Volume:<br/>
+ Permissions (owner/group/mode):<br/>
+ <% end %>
+ Size:<br/>
+ </div>
+ <div class="selection_value">
+ <% unless @storage_volume.storage_pool[:type] ==
"LvmStoragePool" %>
+ <%=h @storage_volume.storage_pool.ip_addr %><br/>
+ <% end %>
+ <% if @storage_volume.storage_pool[:type] == "IscsiStoragePool"
%>
+ <%=h @storage_volume.storage_pool.port %><br/>
+ <%=h @storage_volume.storage_pool[:target] %><br/>
+ <% elsif @storage_volume.storage_pool[:type] ==
"NfsStoragePool" %>
+ <%=h @storage_volume.storage_pool.export_path %><br/>
+ <% end %>
+ <%=h @storage_volume.storage_pool.get_type_label %><br/>
+ <%=h @storage_volume.state %><br/>
+ <%=h @storage_volume.path %><br/>
+ <% if @storage_volume[:type] == "IscsiStorageVolume" %>
+ <%=h @storage_volume.lun %><br/>
+ <% elsif @storage_volume[:type] == "NfsStorageVolume" %>
+ <%=h @storage_volume.filename %><br/>
+ <% elsif @storage_volume[:type] == "LvmStorageVolume" %>
+ <%=h @storage_volume.storage_pool.vg_name %><br/>
+ <%=h @storage_volume.lv_name %><br/>
+ <%=h @storage_volume.lv_owner_perms %>/<%=h
@storage_volume.lv_group_perms %>/<%=h @storage_volume.lv_mode_perms
%><br/>
+ <% end %>
+ <%=h @storage_volume.size_in_gb %> GB<br/>
+ </div>
+<%- content_for :right do -%>
+
+<%- end -%>
+
+<script type="text/javascript">
+ function delete_volume()
+ {
+ $(document).trigger('close.facebox');
+ $.post('<%= url_for :controller => "storage_volume",
:action => "destroy" %>',
+ { storage_volume_ids: <%= @storage_volume.id %> },
+ function(data,status) {
+ // FIXME: reload tree
+ if (data.alert) {
+ $.jGrowl(data.alert);
+ }
+ empty_summary('storage_selection', 'Storage Pool or
Volume');
+ }, 'json');
+ }
+</script>
--
1.6.0.6
David Lutterkort
2009-Feb-02 20:35 UTC
[Ovirt-devel] [PATCH server 6/8] Remove delete_volumes, since it was not used
---
src/app/controllers/storage_volume_controller.rb | 49 ----------------------
src/app/views/storage_volume/show.rhtml | 2 +-
2 files changed, 1 insertions(+), 50 deletions(-)
diff --git a/src/app/controllers/storage_volume_controller.rb
b/src/app/controllers/storage_volume_controller.rb
index ba486d2..9cde09b 100644
--- a/src/app/controllers/storage_volume_controller.rb
+++ b/src/app/controllers/storage_volume_controller.rb
@@ -118,54 +118,6 @@ class StorageVolumeController < ApplicationController
end
def destroy
- if params[:id]
- delete_volume
- else
- delete_volumes
- end
- end
-
- def delete_volumes
- storage_volume_ids_str = params[:storage_volume_ids]
- storage_volume_ids = storage_volume_ids_str.split(",").collect
{|x| x.to_i}
- alerts = []
- status = true
- begin
- StorageVolume.transaction do
- storage = StorageVolume.find(:all, :conditions => "id in
(#{storage_volume_ids.join(', ')})")
- unless storage.empty?
- set_perms(storage[0].storage_pool.hardware_pool)
- unless @can_modify and storage[0].storage_pool.user_subdividable
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => false,
- :alert => "You do not have permission to delete this
storage volume." } }
- format.xml { head :forbidden }
- end
- else
- storage.each do |storage_volume|
- alert, success = delete_volume_internal(storage_volume)
- alerts << alert
- status = false unless success
- end
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => status, :alert =>
alerts.join("\n") } }
- format.xml { head(status ? :ok : :method_not_allowed) }
- end
- end
- else
- respond_to do |format|
- format.json { render :json => { :object =>
"storage_volume",
- :success => false, :alert => "no volumes
selected" } }
- format.xml { head(status ? :ok : :method_not_allowed) }
- end
- end
- end
- end
- end
-
- def delete_volume
@storage_volume = StorageVolume.find(params[:id])
set_perms(@storage_volume.storage_pool.hardware_pool)
unless @can_modify and @storage_volume.storage_pool.user_subdividable
@@ -183,7 +135,6 @@ class StorageVolumeController < ApplicationController
format.xml { head(success ? :ok : :method_not_allowed) }
end
end
-
end
def pre_create
diff --git a/src/app/views/storage_volume/show.rhtml
b/src/app/views/storage_volume/show.rhtml
index c2434aa..3963a3c 100644
--- a/src/app/views/storage_volume/show.rhtml
+++ b/src/app/views/storage_volume/show.rhtml
@@ -75,7 +75,7 @@
{
$(document).trigger('close.facebox');
$.post('<%= url_for :controller => "storage_volume",
:action => "destroy" %>',
- { storage_volume_ids: <%= @storage_volume.id %> },
+ { id: <%= @storage_volume.id %> },
function(data,status) {
// FIXME: reload tree
if (data.alert) {
--
1.6.0.6
David Lutterkort
2009-Feb-02 20:35 UTC
[Ovirt-devel] [PATCH server 7/8] Produce a human-readable error when deleting a pool fails
---
src/app/controllers/storage_controller.rb | 6 ++++--
src/app/views/errors/simple.xml.builder | 3 +++
2 files changed, 7 insertions(+), 2 deletions(-)
create mode 100644 src/app/views/errors/simple.xml.builder
diff --git a/src/app/controllers/storage_controller.rb
b/src/app/controllers/storage_controller.rb
index 3579967..a951656 100644
--- a/src/app/controllers/storage_controller.rb
+++ b/src/app/controllers/storage_controller.rb
@@ -204,10 +204,12 @@ class StorageController < ApplicationController
def destroy
unless @storage_pool.movable?
+ @error = "Cannot delete storage with associated vms"
respond_to do |format|
format.json { render :json => { :object =>
"storage_pool",
- :success => false,
- :alert => "Cannot delete storage with associated vms"
} }
+ :success => false, :alert => @error } }
+ format.xml { render :template => "errors/simple", :layout
=> false,
+ :status => :forbidden }
end
return
end
diff --git a/src/app/views/errors/simple.xml.builder
b/src/app/views/errors/simple.xml.builder
new file mode 100644
index 0000000..d8d3c5b
--- /dev/null
+++ b/src/app/views/errors/simple.xml.builder
@@ -0,0 +1,3 @@
+xml.instruct!
+
+xml.error @error
--
1.6.0.6
David Lutterkort
2009-Feb-02 20:35 UTC
[Ovirt-devel] [PATCH server 8/8] REST route for storage volumes
---
src/config/routes.rb | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/config/routes.rb b/src/config/routes.rb
index 132072e..168ded5 100644
--- a/src/config/routes.rb
+++ b/src/config/routes.rb
@@ -53,6 +53,7 @@ ActionController::Routing::Routes.draw do |map|
# REST work out of the box, and use these as the default routes
map.resources :hosts, :controller => 'host'
map.resources :storage_pools, :controller => 'storage'
+ map.resources :storage_volumes, :controller => 'storage_volume'
map.resources :hardware_pools, :controller => 'hardware' do
|hardware_pools|
hardware_pools.resources :hosts, :controller => 'host'
hardware_pools.resources :storage_pools, :controller =>
'storage'
--
1.6.0.6