incubator-deltacloud-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mfoj...@apache.org
Subject svn commit: r1064113 - in /incubator/deltacloud/trunk/server: ./ lib/deltacloud/ lib/deltacloud/drivers/ec2/ lib/deltacloud/drivers/gogrid/ views/docs/ views/instances/
Date Thu, 27 Jan 2011 12:51:32 GMT
Author: mfojtik
Date: Thu Jan 27 12:51:31 2011
New Revision: 1064113

URL: http://svn.apache.org/viewvc?rev=1064113&view=rev
Log:
Initial run-on-instance support for EC2 and GoGrid

Added:
    incubator/deltacloud/trunk/server/lib/deltacloud/runner.rb
    incubator/deltacloud/trunk/server/views/instances/run.html.haml
    incubator/deltacloud/trunk/server/views/instances/run.xml.haml
    incubator/deltacloud/trunk/server/views/instances/run_command.html.haml
Modified:
    incubator/deltacloud/trunk/server/deltacloud.rb
    incubator/deltacloud/trunk/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
    incubator/deltacloud/trunk/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
    incubator/deltacloud/trunk/server/lib/deltacloud/validation.rb
    incubator/deltacloud/trunk/server/server.rb
    incubator/deltacloud/trunk/server/views/docs/operation.html.haml
    incubator/deltacloud/trunk/server/views/instances/index.html.haml
    incubator/deltacloud/trunk/server/views/instances/show.xml.haml

Modified: incubator/deltacloud/trunk/server/deltacloud.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/deltacloud.rb?rev=1064113&r1=1064112&r2=1064113&view=diff
==============================================================================
--- incubator/deltacloud/trunk/server/deltacloud.rb (original)
+++ incubator/deltacloud/trunk/server/deltacloud.rb Thu Jan 27 12:51:31 2011
@@ -38,3 +38,4 @@ require 'deltacloud/models/load_balancer
 
 require 'deltacloud/validation'
 require 'deltacloud/helpers'
+require 'deltacloud/runner'

Modified: incubator/deltacloud/trunk/server/lib/deltacloud/drivers/ec2/ec2_driver.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/lib/deltacloud/drivers/ec2/ec2_driver.rb?rev=1064113&r1=1064112&r2=1064113&view=diff
==============================================================================
--- incubator/deltacloud/trunk/server/lib/deltacloud/drivers/ec2/ec2_driver.rb (original)
+++ incubator/deltacloud/trunk/server/lib/deltacloud/drivers/ec2/ec2_driver.rb Thu Jan 27
12:51:31 2011
@@ -205,6 +205,20 @@ module Deltacloud
             new_instance
           end
         end
+
+        def run_on_instance(credentials, opts={})
+          target = instance(credentials, :id => opts[:id])
+          param = {}
+          param[:credentials] = {
+            :username => 'root', # Default for EC2 Linux instances
+          }
+          param[:port] = opts[:port] || '22'
+          param[:ip] = target.public_addresses
+          param[:private_key] = (opts[:private_key].length > 1) ? opts[:private_key] :
nil
+          safely do
+            Deltacloud::Runner.execute(opts[:cmd], param)
+          end
+        end
     
         def reboot_instance(credentials, instance_id)
           ec2 = new_client(credentials)
@@ -691,7 +705,7 @@ module Deltacloud
           {
             :auth => [], # [ ::Aws::AuthFailure ],
             :error => [ ::Aws::AwsError ],
-            :glob => [ /AWS::(\w+)/ ]
+            :glob => [ /AWS::(\w+)/, /Deltacloud::Runner::(\w+)/ ]
           }
         end
 

Modified: incubator/deltacloud/trunk/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb?rev=1064113&r1=1064112&r2=1064113&view=diff
==============================================================================
--- incubator/deltacloud/trunk/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb (original)
+++ incubator/deltacloud/trunk/server/lib/deltacloud/drivers/gogrid/gogrid_driver.rb Thu Jan
27 12:51:31 2011
@@ -121,6 +121,21 @@ class GogridDriver < Deltacloud::BaseDri
     end
   end
 
+  def run_on_instance(credentials, opts={})
+    target = instance(credentials, opts[:id])
+    param = {}
+    param[:credentials] = {
+      :username => target.username,
+      :password => target.password,
+    }
+    param[:credentials].merge!({ :password => opts[:password]}) if opts[:password].length>0
+    param[:port] = opts[:port] || '22'
+    param[:ip] = target.public_addresses
+    Deltacloud::Runner.execute(opts[:cmd], param)
+  end
+
+
+
   def list_instances(credentials, id)
     instances = []
     safely do

Added: incubator/deltacloud/trunk/server/lib/deltacloud/runner.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/lib/deltacloud/runner.rb?rev=1064113&view=auto
==============================================================================
--- incubator/deltacloud/trunk/server/lib/deltacloud/runner.rb (added)
+++ incubator/deltacloud/trunk/server/lib/deltacloud/runner.rb Thu Jan 27 12:51:31 2011
@@ -0,0 +1,129 @@
+# Copyright (C) 2009, 2010  Red Hat, Inc.
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+require 'net/ssh'
+require 'socket'
+require 'tempfile'
+
+module Deltacloud
+
+  module Runner
+
+    class RunnerError < StandardError
+      attr_reader :message
+      def initialize(message)
+        @message = message
+        super
+      end
+    end
+    
+    class InstanceSSHError < RunnerError; end
+
+    def self.execute(command, opts={})
+      
+      if opts[:credentials] and (not opts[:credentials][:password] and not opts[:private_key])
+        raise RunnerError::new("Either password or key must be specified")
+      end
+
+      # First check networking and firewalling
+      network = Network::new(opts[:ip], opts[:port])
+
+      # Then check SSH availability
+      ssh = SSH::new(network, opts[:credentials], opts[:private_key])
+
+      # Finaly execute SSH command on instance
+      ssh.execute(command)
+    end
+
+    class Network
+      attr_accessor :ip, :port
+
+      def initialize(ip, port)
+        @ip, @port = ip, port
+      end
+    end
+
+    class SSH
+
+      attr_reader :network
+      attr_accessor :credentials, :key
+      attr_reader :command
+
+      def initialize(network, credentials, key=nil)
+        @network, @credentials, @key = network, credentials, key
+        @result = ""
+      end
+
+      def execute(command)
+        @command = command
+        config = ssh_config(@network, @credentials, @key)
+        begin
+          session = nil
+          Timeout::timeout(5) do
+            session = Net::SSH.start(@network.ip, 'root', config)
+          end
+          session.open_channel do |channel|
+            channel.on_data do |ch, data|
+              @result += data
+            end
+            channel.exec(command)
+            session.loop
+          end
+          session.close
+        rescue Exception => e
+          raise InstanceSSHError.new("#{e.class.name}: #{e.message}")
+        ensure
+          # FileUtils.rm(config[:keys].first) rescue nil
+        end
+        Deltacloud::Runner::Response.new(self, @result)
+      end
+
+      private
+
+      def ssh_config(network, credentials, key)
+        config = { :port => network.port }
+        config.merge!({ :password => credentials[:password ]}) if credentials[:password]
+        config.merge!({ :keys => [ keyfile(key) ] }) unless key.nil?
+        config
+      end
+
+      # Right now there is no way howto pass private_key using String
+      # eg. without saving key to temporary file.
+      def keyfile(key)
+        keyfile = Tempfile.new("ec2_private.key")
+        key_material = ""
+        key.split("\n").each { |line| key_material+="#{line.strip}\n" if line.strip.size>0
}
+        keyfile.write(key_material) && keyfile.close
+        puts "[*] Using #{keyfile.path} as private key"
+        keyfile.path
+      end
+
+    end
+
+    class Response
+      
+      attr_reader :body
+      attr_reader :ssh
+
+      def initialize(ssh, response_body)
+        @body, @ssh = response_body, ssh
+      end
+
+    end
+
+  end
+end

Modified: incubator/deltacloud/trunk/server/lib/deltacloud/validation.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/lib/deltacloud/validation.rb?rev=1064113&r1=1064112&r2=1064113&view=diff
==============================================================================
--- incubator/deltacloud/trunk/server/lib/deltacloud/validation.rb (original)
+++ incubator/deltacloud/trunk/server/lib/deltacloud/validation.rb Thu Jan 27 12:51:31 2011
@@ -37,8 +37,12 @@ module Deltacloud::Validation
       @name = args[0]
       @klass = args[1] || :string
       @type = args[2] || :optional
-      @options = args[3] || []
-      @description = args[4] || ''
+      if args[3] and args[3].class.eql?(String)
+        @description = args[3]
+        @options = []
+      end
+      @options ||= args[3] || []
+      @description ||= args[4] || ''
     end
 
     def required?

Modified: incubator/deltacloud/trunk/server/server.rb
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/server.rb?rev=1064113&r1=1064112&r2=1064113&view=diff
==============================================================================
--- incubator/deltacloud/trunk/server/server.rb (original)
+++ incubator/deltacloud/trunk/server/server.rb Thu Jan 27 12:51:31 2011
@@ -221,6 +221,13 @@ get "/api/instances/new" do
   end
 end
 
+get '/api/instances/:id/run' do
+  @instance = driver.instance(credentials, :id => params[:id])
+  respond_to do |format|
+    format.html { haml :"instances/run_command" }
+  end
+end
+
 get '/api/load_balancers/new' do
   @realms = driver.realms(credentials)
   @instances = driver.instances(credentials) if driver_has_feature?(:register_instance, :load_balancers)
@@ -366,6 +373,26 @@ END
     param :id,           :string, :required
     control { instance_action(:destroy) }
   end
+
+  operation :run, :method => :post, :member => true do
+    description <<END
+  Run command on instance. Either password or private key must be send
+  in order to execute command. Authetication method should be advertised
+  in instance.
+END
+    with_capability :run_on_instance
+    param :id,          :string,  :required
+    param :cmd,         :string,  :required, "Shell command to run on instance"
+    param :private_key, :string,  :optional, "Private key in PEM format for authentication"
+    param :password,    :string,  :optional, "Password used for authentication"
+    control do
+      @output = driver.run_on_instance(credentials, params)
+      respond_to do |format|
+        format.xml { haml :"instances/run" }
+        format.html { haml :"instances/run" }
+      end
+    end
+  end
 end
 
 collection :hardware_profiles do

Modified: incubator/deltacloud/trunk/server/views/docs/operation.html.haml
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/views/docs/operation.html.haml?rev=1064113&r1=1064112&r2=1064113&view=diff
==============================================================================
--- incubator/deltacloud/trunk/server/views/docs/operation.html.haml (original)
+++ incubator/deltacloud/trunk/server/views/docs/operation.html.haml Thu Jan 27 12:51:31 2011
@@ -17,6 +17,7 @@
       %th Type
       %th Class
       %th Valid values
+      %th Description
   %tbody
     - @operation.each_param do |p|
       %tr
@@ -25,3 +26,4 @@
         %td{:style => "width:10em"} #{p.type}
         %td #{p.klass}
         %td{:style => "width:10em"} #{p.options.join(',')}
+        %td #{p.description}

Modified: incubator/deltacloud/trunk/server/views/instances/index.html.haml
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/views/instances/index.html.haml?rev=1064113&r1=1064112&r2=1064113&view=diff
==============================================================================
--- incubator/deltacloud/trunk/server/views/instances/index.html.haml (original)
+++ incubator/deltacloud/trunk/server/views/instances/index.html.haml Thu Jan 27 12:51:31
2011
@@ -28,3 +28,5 @@
         %td
           -instance.actions.each do |action|
             =link_to_action action, self.send(:"#{action}_instance_url", instance.id), instance_action_method(action)
+          - if driver.respond_to?(:run_on_instance) and instance.state=="RUNNING"
+            =link_to_action "Run command", url_for("/api/instances/#{instance.id}/run"),
:get

Added: incubator/deltacloud/trunk/server/views/instances/run.html.haml
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/views/instances/run.html.haml?rev=1064113&view=auto
==============================================================================
--- incubator/deltacloud/trunk/server/views/instances/run.html.haml (added)
+++ incubator/deltacloud/trunk/server/views/instances/run.html.haml Thu Jan 27 12:51:31 2011
@@ -0,0 +1,9 @@
+%h1 Run command on instance #{params[:id]}
+
+%p
+  %label Command:
+  %em #{@output.ssh.command}
+%p
+  %strong Command output
+%pre
+  =@output.body

Added: incubator/deltacloud/trunk/server/views/instances/run.xml.haml
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/views/instances/run.xml.haml?rev=1064113&view=auto
==============================================================================
--- incubator/deltacloud/trunk/server/views/instances/run.xml.haml (added)
+++ incubator/deltacloud/trunk/server/views/instances/run.xml.haml Thu Jan 27 12:51:31 2011
@@ -0,0 +1,7 @@
+%instance{:id => params[:id], :href=> instance_url(params[:id])}
+  %public_address
+    =@output.ssh.network.ip
+  %command
+    =@output.ssh.command
+  %output<
+    =@output.body

Added: incubator/deltacloud/trunk/server/views/instances/run_command.html.haml
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/views/instances/run_command.html.haml?rev=1064113&view=auto
==============================================================================
--- incubator/deltacloud/trunk/server/views/instances/run_command.html.haml (added)
+++ incubator/deltacloud/trunk/server/views/instances/run_command.html.haml Thu Jan 27 12:51:31
2011
@@ -0,0 +1,16 @@
+%h1
+  Run command on 
+  = @instance.id
+
+%form{ :action => run_instance_url(@instance.id), :method => :post }
+  %p
+    %label{ :for => :cmd } Desired command:
+    %input{ :name => :cmd, :value => "", :type => :text}
+  %p
+    %label{ :for => :private_key } Private key:
+  %p
+    %small Leave private key blank if using password authentication method
+  %p
+    %textarea{ :name => :private_key, :cols => 65, :rows => 20 }
+  %p
+    %input{ :type => :submit, :value => "Execute" }

Modified: incubator/deltacloud/trunk/server/views/instances/show.xml.haml
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/server/views/instances/show.xml.haml?rev=1064113&r1=1064112&r2=1064113&view=diff
==============================================================================
--- incubator/deltacloud/trunk/server/views/instances/show.xml.haml (original)
+++ incubator/deltacloud/trunk/server/views/instances/show.xml.haml Thu Jan 27 12:51:31 2011
@@ -21,6 +21,8 @@
     %actions
       - @instance.actions.compact.each do |instance_action|
         %link{:rel => instance_action, :method => instance_action_method(instance_action),
:href => self.send("#{instance_action}_instance_url", @instance.id)}
+      - if driver.respond_to?(:run_on_instance)
+        %link{:rel => 'run', :method => :post, :href => run_instance_url(@instance.id)}
   - if @instance.instance_variables.include?("@launch_time")
     %launch_time<
       =@instance.launch_time



Mime
View raw message