You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltacloud.apache.org by Mohammed Morsi <mm...@redhat.com> on 2010/08/04 22:04:47 UTC
[PATCH] added ability to scp one or more files to a running instance (rev 2)
requires 'arbitrary command execution on instances' and
'support array request param types with ability to specify
type of array elements' patches to work
---
server/deltacloud-core.gemspec | 1 +
server/lib/deltacloud/base_driver/features.rb | 4 ++
server/lib/deltacloud/drivers/ec2/ec2_driver.rb | 1 +
server/lib/deltacloud/drivers/mock/mock_driver.rb | 1 +
server/lib/deltacloud/models/instance.rb | 12 +++++++
server/server.rb | 32 ++++++++++++++++++
server/views/instances/copy_files.html.haml | 36 +++++++++++++++++++++
server/views/instances/copy_files.xml.haml | 11 ++++++
8 files changed, 98 insertions(+), 0 deletions(-)
create mode 100644 server/views/instances/copy_files.html.haml
create mode 100644 server/views/instances/copy_files.xml.haml
diff --git a/server/deltacloud-core.gemspec b/server/deltacloud-core.gemspec
index 53571e4..59b2444 100644
--- a/server/deltacloud-core.gemspec
+++ b/server/deltacloud-core.gemspec
@@ -66,6 +66,7 @@ require 'rake'
s.add_dependency('rerun', '>= 0.5.2')
s.add_dependency('json', '>= 1.2.3')
s.add_dependency('net-ssh', '>= 2.0.23')
+ s.add_dependency('net-scp', '>= 1.0.2')
s.add_development_dependency('compass', '>= 0.8.17')
s.add_development_dependency('nokogiri', '>= 1.4.1')
s.add_development_dependency('rack-test', '>= 0.5.3')
diff --git a/server/lib/deltacloud/base_driver/features.rb b/server/lib/deltacloud/base_driver/features.rb
index 2addbf5..895bdd2 100644
--- a/server/lib/deltacloud/base_driver/features.rb
+++ b/server/lib/deltacloud/base_driver/features.rb
@@ -160,5 +160,9 @@ module Deltacloud
description "Run an arbitrary command against an instance"
end
+ declare_feature :instances, :copy_files do
+ description "One or more files may be securely copied to an instance"
+ end
+
end
end
diff --git a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
index 5ad930b..7957b56 100644
--- a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
+++ b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
@@ -38,6 +38,7 @@ class EC2Driver < Deltacloud::BaseDriver
feature :instances, :user_data
feature :instances, :authentication_key
feature :instances, :run_command
+ feature :instances, :copy_files
define_hardware_profile('m1.small') do
cpu 1
diff --git a/server/lib/deltacloud/drivers/mock/mock_driver.rb b/server/lib/deltacloud/drivers/mock/mock_driver.rb
index b8302c7..c400e9e 100644
--- a/server/lib/deltacloud/drivers/mock/mock_driver.rb
+++ b/server/lib/deltacloud/drivers/mock/mock_driver.rb
@@ -78,6 +78,7 @@ class MockDriver < Deltacloud::BaseDriver
feature :instances, :user_name
feature :instances, :run_command
+ feature :instances, :copy_files
def initialize
if ENV["DELTACLOUD_MOCK_STORAGE"]
diff --git a/server/lib/deltacloud/models/instance.rb b/server/lib/deltacloud/models/instance.rb
index c2c9ff4..e0cd7a6 100644
--- a/server/lib/deltacloud/models/instance.rb
+++ b/server/lib/deltacloud/models/instance.rb
@@ -17,6 +17,7 @@
# under the License.
require 'net/ssh'
+require 'net/scp'
class Instance < BaseModel
@@ -53,4 +54,15 @@ class Instance < BaseModel
return output
end
+ def copy_files(files, destination, username='', opts={})
+ files = [files] unless files.is_a? Array
+ hostname = self.public_addresses.first
+ return "No hostname/IP address specified" unless hostname
+ Net::SCP.start(hostname, username || 'root', opts) do |session|
+ files.each { |f|
+ session.upload! f, destination
+ }
+ end
+ end
+
end
diff --git a/server/server.rb b/server/server.rb
index 7f9f603..43fada1 100644
--- a/server/server.rb
+++ b/server/server.rb
@@ -167,6 +167,12 @@ get "/api/instances/:id/run" do
end
end
+get "/api/instances/:id/copy_files" do
+ respond_to do |format|
+ format.html { haml :"instances/copy_files"}
+ end
+end
+
collection :instances do
description <<END
An instance is a concrete machine realized from an image.
@@ -256,6 +262,32 @@ END
end
end
+ operation :copy_files, :method => :post, :member => true do
+ description "Securely copy one or more files to an instance"
+ param :id, :string, :required
+ param :files, :array, :string, :required
+ param :destination, :string, :required
+ param :private_key, :string
+ param :username, :string
+ control do
+ @instance = driver.instance(credentials, { :id => params[:id] })
+ private_key = store_private_key(params[:id], params[:private_key])
+ begin
+ params[:files].delete_if { |f| f.nil? || f == "" }
+ @instance.copy_files(params[:files], params[:destination], params[:username], { :keys => private_key })
+ @output = "Files copied successfully"
+ rescue Exception => e
+ @failed = true
+ @output = "#{e.message}\n#{e.backtrace.join("\n")}"
+ ensure
+ remove_private_key(private_key)
+ end
+ respond_to do |format|
+ format.xml { haml :"instances/copy_files" }
+ end
+ end
+ end
+
end
collection :hardware_profiles do
diff --git a/server/views/instances/copy_files.html.haml b/server/views/instances/copy_files.html.haml
new file mode 100644
index 0000000..dbced55
--- /dev/null
+++ b/server/views/instances/copy_files.html.haml
@@ -0,0 +1,36 @@
+%h1 Run command
+
+%form{ :action => "/api/instances/#{params[:id]}/copy_files", :method => :post}
+ %label
+ Source File(s):
+ %br
+ %input{ :name => 'files[]', :size => 30}/
+ %br
+ %input{ :name => 'files[]', :size => 30}/
+ %br
+ %input{ :name => 'files[]', :size => 30}/
+ %br
+ %input{ :name => 'files[]', :size => 30}/
+ %br
+ %input{ :name => 'files[]', :size => 30}/
+ %br
+ %br
+
+ %label
+ Destination File or Directory:
+ %br
+ %br
+ %input{ :name => 'destination', :size => 30}/
+ %br
+ %br
+
+ %label
+ Paste private key here:
+ %p
+ %textarea{ :name => 'private_key', :cols => 30}
+ %br
+ %label
+ Username:
+ %input{ :name => 'username', :size => 30}
+ %br/
+ %input{ :type => 'submit', :value => "Run"}
diff --git a/server/views/instances/copy_files.xml.haml b/server/views/instances/copy_files.xml.haml
new file mode 100644
index 0000000..9205094
--- /dev/null
+++ b/server/views/instances/copy_files.xml.haml
@@ -0,0 +1,11 @@
+!!! XML
+%instance{:href => instance_url(@instance.id)}
+ %id<
+ =@instance.id
+ %name<
+ =@instance.name
+ %status
+ =@failed ? "FAILED" : "SUCCESS"
+ %output<
+ =cdata do
+ =@output
--
1.7.2