CloudyScripts 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -19,4 +19,6 @@
19
19
  # =Scripts
20
20
  # Here are the scripts implemented so far:
21
21
  # * #DmEncrypt (encrypt Amazon EBS Storage using dm-encrypt)
22
- #
22
+ #
23
+ # =Questions and Suggestions
24
+ # matthias.jung@gmail.com
data/Rakefile CHANGED
@@ -12,7 +12,7 @@ require 'rake/testtask'
12
12
 
13
13
  spec = Gem::Specification.new do |s|
14
14
  s.name = 'CloudyScripts'
15
- s.version = '0.0.3'
15
+ s.version = '0.0.4'
16
16
  s.has_rdoc = true
17
17
  s.extra_rdoc_files = ['README.rdoc', 'LICENSE']
18
18
  s.summary = 'Scripts to facilitate programming for infrastructure clouds.'
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'net/ssh'
3
+ require 'help/dm_crypt_helper'
3
4
 
4
5
  # Provides methods to be executed via ssh to remote instances.
5
6
  class RemoteCommandHandler
@@ -27,6 +28,16 @@ class RemoteCommandHandler
27
28
  @crypto.set_ssh(@ssh_session)
28
29
  end
29
30
 
31
+ # Connect to the machine as root using keydata from a keyfile.
32
+ # Params:
33
+ # * ip: ip address of the machine to connect to
34
+ # * user: user name
35
+ # * key_data: key_data to be used for authentication
36
+ def connect(ip, user, key_data)
37
+ @ssh_session = Net::SSH.start(ip, user, :key_data => [key_data])
38
+ @crypto.set_ssh(@ssh_session)
39
+ end
40
+
30
41
  # Disconnect the current handler
31
42
  def disconnect
32
43
  @ssh_session.close
@@ -67,7 +78,7 @@ class RemoteCommandHandler
67
78
  end
68
79
  end
69
80
  if drive_found
70
- return SshApi.file_exists?(@ssh_session, path)
81
+ return RemoteCommandHandler.file_exists?(@ssh_session, path)
71
82
  else
72
83
  puts "not mounted (since #{path} non-existing)"
73
84
  false
@@ -8,6 +8,13 @@ class ScriptExecutionState
8
8
 
9
9
  def initialize(context)
10
10
  @context = context
11
+ @state_change_listeners = []
12
+ end
13
+
14
+ # Listener should extend #StateChangeListener (or implement a
15
+ # state_changed(state) method). Note: calls are synchronous.
16
+ def register_state_change_listener(listener)
17
+ @state_change_listeners << listener
11
18
  end
12
19
 
13
20
  # Start the state machine using this state as initial state.
@@ -17,8 +24,10 @@ class ScriptExecutionState
17
24
  while !@current_state.done? && !@current_state.failed?
18
25
  begin
19
26
  @current_state = @current_state.enter()
27
+ notify_state_change_listeners(@current_state)
20
28
  rescue Exception => e
21
29
  @current_state = FailedState.new(@context, e.to_s, @current_state)
30
+ notify_state_change_listeners(@current_state)
22
31
  puts "Exception: #{e}"
23
32
  puts "#{e.backtrace.join("\n")}"
24
33
  end
@@ -67,4 +76,13 @@ class ScriptExecutionState
67
76
  end
68
77
  end
69
78
 
79
+ private
80
+
81
+ # Notifies all listeners of state changes
82
+ def notify_state_change_listeners(state)
83
+ @state_change_listeners.each() {|listener|
84
+ listener.state_changed(state)
85
+ }
86
+ end
87
+
70
88
  end
@@ -0,0 +1,13 @@
1
+ # Defines a template for a class that allows to be notified
2
+ # on state-changes in #ScriptExecutionState. A listener must be
3
+ # registered via #ScriptExecutionState::register_state_change_listener.
4
+ # When a state changes the method #state_changed is called.
5
+
6
+ class StateChangeListener
7
+ # Method called when a state changes. Note: calls are synchronous, the
8
+ # listener should return quickly and handle more complicated routines
9
+ # in a different thread.
10
+ def state_changed(state)
11
+ raise Exception.new("StateChangeListener: state change notification not implemented")
12
+ end
13
+ end
@@ -7,15 +7,12 @@ require "AWS"
7
7
  # Script to Encrypt an EC2 Storage (aka Elastic Block Storage)
8
8
  #
9
9
  class DmEncrypt < Ec2Script
10
- def initialize(input_params)
11
- super(input_params)
12
- end
13
-
14
10
  # Input parameters
15
11
  # * aws_access_key => the Amazon AWS Access Key (see Your Account -> Security Credentials)
16
12
  # * aws_secret_key => the Amazon AWS Secret Key
17
13
  # * ip_address => IP Address of the machine to connect to
18
- # * ssh_key_file => Path of the keyfile used to connect to the machine
14
+ # * ssh_key_file => Path of the keyfile used to connect to the machine (optional, otherwise: ssh_key_data)
15
+ # * ssh_key_data => Key information (optional, otherwise: ssh_key_file)
19
16
  # * device => Path of the device to encrypt
20
17
  # * device_name => Name of the Device to encrypt
21
18
  # * storage_path => Path on which the encrypted device is mounted
@@ -45,6 +42,9 @@ class DmEncrypt < Ec2Script
45
42
  end
46
43
  # start state machine
47
44
  current_state = DmEncryptState.load_state(@input_params)
45
+ @state_change_listeners.each() {|listener|
46
+ current_state.register_state_change_listener(listener)
47
+ }
48
48
  end_state = current_state.start_state_machine()
49
49
  if end_state.failed?
50
50
  @result[:failed] = true
@@ -100,7 +100,13 @@ class DmEncrypt < Ec2Script
100
100
 
101
101
  def connect()
102
102
  puts "InitialState.connect"
103
- @context[:remote_command_handler].connect(@context[:ip_address], @context[:ssh_key_file])
103
+ if @context[:ssh_key_file] != nil
104
+ @context[:remote_command_handler].connect(@context[:ip_address], @context[:ssh_key_file])
105
+ elsif @context[:ssh_key_data] != nil
106
+ @context[:remote_command_handler].connect(@context[:ip_address], "root", @context[:ssh_key_data])
107
+ else
108
+ raise Exception.new("no key information specified")
109
+ end
104
110
  ConnectedState.new(@context)
105
111
  end
106
112
  end
@@ -3,11 +3,18 @@ class Ec2Script
3
3
  # Initialization. Common Input parameters:
4
4
  # * aws_access_key => the Amazon AWS Access Key (see Your Account -> Security Credentials)
5
5
  # * aws_secret_key => the Amazon AWS Secret Key
6
+ # * ec2_api_server => the API Server to connect to (optional, default is us-east-1 (=> <ec2_api_server>.ec2.amazonaws.com)
6
7
  # Scripts may add specific key/value pairs.
7
8
  def initialize(input_params)
8
9
  @input_params = input_params
10
+ @state_change_listeners = []
9
11
  end
10
12
 
13
+ def register_state_change_listener(listener)
14
+ @state_change_listeners << listener
15
+ end
16
+
17
+
11
18
  # Return a hash of results. Common values are:
12
19
  # * :done => is true when the script has terminated, otherwise false
13
20
  # * :failed => is false when the script succeeded
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: CloudyScripts
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthias Jung
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-18 00:00:00 +01:00
12
+ date: 2010-01-05 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -49,6 +49,7 @@ files:
49
49
  - lib/help/dm_crypt_helper.rb
50
50
  - lib/help/remote_command_handler.rb
51
51
  - lib/help/script_execution_state.rb
52
+ - lib/help/state_change_listener.rb
52
53
  - lib/scripts/ec2/dm_encrypt.rb
53
54
  - lib/scripts/ec2/ec2_script.rb
54
55
  has_rdoc: true