---
 server/lib/deltacloud/base_driver/features.rb      |    7 +++++
 server/lib/deltacloud/drivers/ec2/ec2_driver.rb    |    9 +++---
 .../lib/deltacloud/helpers/application_helper.rb   |   21 +++++++++++++++
 server/lib/deltacloud/models/instance.rb           |   18 ++++++++++++
 server/server.rb                                   |   28 ++++++++++++++++++++
 server/views/instances/new.html.haml               |    4 +++
 server/views/instances/run.html.haml               |   17 ++++++++++++
 server/views/instances/run.xml.haml                |   12 ++++++++
 8 files changed, 112 insertions(+), 4 deletions(-)
 create mode 100644 server/views/instances/run.html.haml
 create mode 100644 server/views/instances/run.xml.haml

diff --git a/server/lib/deltacloud/base_driver/features.rb 
b/server/lib/deltacloud/base_driver/features.rb
index 43ec9c3..9cda5b1 100644
--- a/server/lib/deltacloud/base_driver/features.rb
+++ b/server/lib/deltacloud/base_driver/features.rb
@@ -136,6 +136,13 @@ module Deltacloud
       end
     end
 
+    declare_feature :instances, :keypair do
+      description "Define a key pair for instance authentification"
+      operation :create do
+        param :keypair, :string, :optional
+      end
+    end
+
     declare_feature :instances, :hardware_profiles do
       description "Size instances according to changes to a hardware profile"
       # The parameters are filled in from the hardware profiles
diff --git a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb 
b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
index 3134469..acfa439 100644
--- a/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
+++ b/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
@@ -30,6 +30,7 @@ module Deltacloud
 class EC2Driver < Deltacloud::BaseDriver
 
   feature :instances, :user_data
+  feature :instances, :keypair
 
   define_hardware_profile('m1-small') do
     cpu              1
@@ -150,13 +151,13 @@ class EC2Driver < Deltacloud::BaseDriver
 
   def create_instance(credentials, image_id, opts)
     ec2 = new_client( credentials )
-    realm_id = opts[:realm_id]
+    realm_id = opts['realm_id']
     image = image(credentials, :id => image_id )
-    hwp = find_hardware_profile(credentials, opts[:hwp_id], image.id)
+    hwp = find_hardware_profile(credentials, opts['hwp_id'], image.id)
     ec2_instances = ec2.run_instances(
       :image_id => image.id,
-      :user_data => opts[:user_data],
-      :key_name => opts[:key_name],
+      :user_data => opts['user_data'],
+      :key_name => opts['keypair'],
       :availability_zone => realm_id,
       :monitoring_enabled => true,
       :instance_type => hwp.name.tr('-', '.'),
diff --git a/server/lib/deltacloud/helpers/application_helper.rb 
b/server/lib/deltacloud/helpers/application_helper.rb
index 624f37f..a700f94 100644
--- a/server/lib/deltacloud/helpers/application_helper.rb
+++ b/server/lib/deltacloud/helpers/application_helper.rb
@@ -35,4 +35,25 @@ module ApplicationHelper
     end
     s+="</ul>"
   end
+
+  def store_private_key(id, key)
+    path = File.join('tmp', 'keys')
+    FileUtils.mkdir_p(path) unless File.directory?(path)
+    filename = File.join(path, "instance_#{id}.key")
+    File.open(filename, 'w') do |f|
+      f.puts key
+    end
+    return filename
+  end
+
+  def remove_private_key(key)
+    File.delete(key) if File.exists?(key)
+  end
+
+  def cdata(&block)
+    text = capture_haml(&block)
+    text.gsub!("\n", "\n  ")
+    "<![CDATA[\n  #{text}\n]]>"
+  end
+
 end
diff --git a/server/lib/deltacloud/models/instance.rb 
b/server/lib/deltacloud/models/instance.rb
index d313bc7..a78d281 100644
--- a/server/lib/deltacloud/models/instance.rb
+++ b/server/lib/deltacloud/models/instance.rb
@@ -15,6 +15,7 @@
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  
USA
 
+require 'net/ssh'
 
 class Instance < BaseModel
 
@@ -34,4 +35,21 @@ class Instance < BaseModel
    self.public_addresses = [] if self.public_addresses.nil?
    self.private_addresses = [] if self.private_addresses.nil?
   end
+
+  def run_command(cmd, username='', opts={})
+    hostname = self.public_addresses.first
+    return "No hostname/IP address specified" unless hostname
+    output = ""
+    Net::SSH.start(hostname, username || 'root', opts) do |session|
+      session.open_channel do |channel|
+        channel.on_data do |ch, data|
+          output += data
+        end
+        channel.exec(cmd)
+      end
+      session.loop
+    end
+    return output
+  end
+
 end
diff --git a/server/server.rb b/server/server.rb
index a47168a..dc3f2d3 100644
--- a/server/server.rb
+++ b/server/server.rb
@@ -176,6 +176,12 @@ collection :instance_states do
   end
 end
 
+get "/api/instances/:id/run" do
+  respond_to do |format|
+    format.html { haml :"instances/run"}
+  end
+end
+
 # Special instance get operations that we only allow for HTML
 get "/api/instances/:id/:action" do
    meth = :"#{params[:action]}_instance"
@@ -265,6 +271,28 @@ collection :instances do
     control { instance_action(:stop) }
   end
 
+  operation :run, :method => :post, :member => true do
+    description "Run command on instance"
+    param :id,           :string, :required
+    param :cmd,          :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
+        @[email protected]_command(params[:cmd], params[:username], { :keys 
=> private_key })
+      rescue Exception => e
+        @output = "#{e.message}\n#{e.backtrace}"
+      ensure
+        remove_private_key(private_key)
+      end
+      respond_to do |format|
+        format.xml { haml :"instances/run" }
+      end
+    end
+  end
+
   operation :destroy do
     description "Destroy instance"
     param :id,           :string, :required
diff --git a/server/views/instances/new.html.haml 
b/server/views/instances/new.html.haml
index c746475..383864f 100644
--- a/server/views/instances/new.html.haml
+++ b/server/views/instances/new.html.haml
@@ -8,6 +8,10 @@
   %label
     Instance Name:
   %input{ :name => 'name', :size => 30 }/
+  %br/
+  %label
+    Key name:
+  %input{ :name => 'keypair', :size => 10}/
   - if !...@hardware_profiles.empty?
     %h3 What size machine?
     - for hwp in @hardware_profiles
diff --git a/server/views/instances/run.html.haml 
b/server/views/instances/run.html.haml
new file mode 100644
index 0000000..5a98ec0
--- /dev/null
+++ b/server/views/instances/run.html.haml
@@ -0,0 +1,17 @@
+%h1 Run command
+
+%form{ :action => "/api/instances/#{params[:id]}/run", :method => :post}
+  %label
+    Command:
+  %input{ :name => 'cmd', :size => 30}/
+  %h3 Private key
+  %label
+    Paste private key here:
+  %p
+    %textarea{ :name => 'private_key', :cols => 30}
+  %h3 Authentification options
+  %label
+    Username:
+  %input{ :name => 'username', :size => 30}
+  %br/
+  %input{ :type => 'submit', :value => "Run"}
diff --git a/server/views/instances/run.xml.haml 
b/server/views/instances/run.xml.haml
new file mode 100644
index 0000000..966d249
--- /dev/null
+++ b/server/views/instances/run.xml.haml
@@ -0,0 +1,12 @@
+!!! XML
+%instance{:href => instance_url(@instance.id)}
+  %id<
+    [email protected]
+  %name<
+    [email protected]
+  %command<
+    =cdata do
+      =params[:cmd]
+  %output<
+    =cdata do
+      =...@output
-- 
1.7.0.4

_______________________________________________
deltacloud-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/deltacloud-devel

Reply via email to