CloudyScripts 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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