CloudyScripts 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/lib/help/dm_crypt_helper.rb +2 -2
- data/lib/help/progress_message_listener.rb +14 -0
- data/lib/scripts/ec2/ami2_ebs_conversion.rb +32 -1
- data/lib/scripts/ec2/dm_encrypt.rb +11 -0
- data/lib/scripts/ec2/ec2_script.rb +11 -0
- metadata +3 -2
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.
|
15
|
+
s.version = '0.0.10'
|
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.'
|
data/lib/help/dm_crypt_helper.rb
CHANGED
@@ -159,8 +159,8 @@ class DmCryptHelper < RemoteCommandHandler
|
|
159
159
|
# * device: device to be encrypted
|
160
160
|
# * path: path to which the encrypted device is mounted
|
161
161
|
def encrypt_storage(name, password, device, path)
|
162
|
-
if
|
163
|
-
raise Exception.new("device #{device} is already
|
162
|
+
if remote_execute("cryptsetup isLuks #{device}")
|
163
|
+
raise Exception.new("device #{device} is already a configured device")
|
164
164
|
end
|
165
165
|
if file_exists?(device)
|
166
166
|
if !file_exists?("/dev/mapper/#{name}")
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Defines a template for a class that allows to be notified
|
2
|
+
# about messages during script execution.A listener must be
|
3
|
+
# registered via #Ec2Script::register_state_change_listener.
|
4
|
+
# New messages are passed via the method #new_message.
|
5
|
+
|
6
|
+
class ProgressMessageListener
|
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. The level corresponds to the logger.LEVEL and
|
10
|
+
# allows to signal the importance of a message
|
11
|
+
def new_message(message, level = Logger::INFO)
|
12
|
+
raise Exception.new("ProgressMessageListener: new message notification not implemented")
|
13
|
+
end
|
14
|
+
end
|
@@ -58,6 +58,7 @@ class Ami2EbsConversion < Ec2Script
|
|
58
58
|
if @input_params[:root_device_name] == nil
|
59
59
|
@input_params[:root_device_name] = "/dev/sda1"
|
60
60
|
end
|
61
|
+
@input_params[:script] = self
|
61
62
|
# start state machine
|
62
63
|
current_state = Ami2EbsConversionState.load_state(@input_params)
|
63
64
|
@state_change_listeners.each() {|listener|
|
@@ -106,6 +107,7 @@ class Ami2EbsConversion < Ec2Script
|
|
106
107
|
end
|
107
108
|
|
108
109
|
def connect
|
110
|
+
@context[:script].post_message("connecting to #{@context[:dns_name]}...")
|
109
111
|
if @context[:remote_command_handler] == nil
|
110
112
|
@context[:remote_command_handler] = RemoteCommandHandler.new
|
111
113
|
end
|
@@ -140,6 +142,7 @@ class Ami2EbsConversion < Ec2Script
|
|
140
142
|
raise Exception.new("connection attempts stopped")
|
141
143
|
end
|
142
144
|
@context[:result][:os] = @context[:remote_command_handler].retrieve_os()
|
145
|
+
@context[:script].post_message("connected to #{@context[:dns_name]}. OS installed is #{@context[:result][:os]}")
|
143
146
|
@logger.info "connected to #{@context[:dns_name]}"
|
144
147
|
end
|
145
148
|
|
@@ -155,28 +158,34 @@ class Ami2EbsConversion < Ec2Script
|
|
155
158
|
private
|
156
159
|
|
157
160
|
def startup_ami()
|
161
|
+
@context[:script].post_message("starting up a new instance for AMI #{@context[:ami_id]}...")
|
158
162
|
@logger.debug "start up AMI #{@context[:ami_id]}"
|
159
163
|
res = @context[:ec2_api_handler].run_instances(:image_id => @context[:ami_id],
|
160
164
|
:security_group => @context[:security_group_name], :key_name => @context[:key_name])
|
161
165
|
instance_id = res['instancesSet']['item'][0]['instanceId']
|
162
166
|
@context[:instance_id] = instance_id
|
163
167
|
@logger.info "started instance #{instance_id}"
|
168
|
+
@context[:script].post_message("started instance #{instance_id}. wait until it is ready...")
|
164
169
|
#availability_zone , key_name/group_name
|
165
170
|
started = false
|
166
171
|
while started == false
|
167
172
|
sleep(5)
|
168
173
|
res = @context[:ec2_api_handler].describe_instances(:instance_id => @context[:instance_id])
|
169
174
|
state = res['reservationSet']['item'][0]['instancesSet']['item'][0]['instanceState']
|
170
|
-
@logger.info "instance in state #{state['name']} (#{state['code']})"
|
175
|
+
@logger.info "instance is in state #{state['name']} (#{state['code']})"
|
171
176
|
if state['code'].to_i == 16
|
172
177
|
started = true
|
178
|
+
@context[:script].post_message("instance is up and running")
|
173
179
|
@context[:dns_name] = res['reservationSet']['item'][0]['instancesSet']['item'][0]['dnsName']
|
174
180
|
@context[:availability_zone] = res['reservationSet']['item'][0]['instancesSet']['item'][0]['placement']['availabilityZone']
|
175
181
|
@context[:kernel_id] = res['reservationSet']['item'][0]['instancesSet']['item'][0]['kernelId']
|
176
182
|
@context[:ramdisk_id] = res['reservationSet']['item'][0]['instancesSet']['item'][0]['ramdiskId']
|
177
183
|
@context[:architecture] = res['reservationSet']['item'][0]['instancesSet']['item'][0]['architecture']
|
178
184
|
elsif state['code'].to_i != 0
|
185
|
+
@context[:script].post_message("instance in state #{state['name']}")
|
179
186
|
raise Exception.new('instance failed to start up')
|
187
|
+
else
|
188
|
+
@context[:script].post_message("instance still starting up...")
|
180
189
|
end
|
181
190
|
end
|
182
191
|
AmiStarted.new(@context)
|
@@ -192,6 +201,7 @@ class Ami2EbsConversion < Ec2Script
|
|
192
201
|
private
|
193
202
|
|
194
203
|
def create_storage()
|
204
|
+
@context[:script].post_message("going to create a new EBS volume...")
|
195
205
|
@logger.debug "create volume in zone #{@context[:availability_zone]}"
|
196
206
|
res = @context[:ec2_api_handler].create_volume(:availability_zone => @context[:availability_zone], :size => "10")
|
197
207
|
@context[:volume_id] = res['volumeId']
|
@@ -206,6 +216,7 @@ class Ami2EbsConversion < Ec2Script
|
|
206
216
|
started = true
|
207
217
|
end
|
208
218
|
end
|
219
|
+
@context[:script].post_message("EBS volume #{@context[:volume_id]} is ready")
|
209
220
|
StorageCreated.new(@context)
|
210
221
|
end
|
211
222
|
|
@@ -220,6 +231,7 @@ class Ami2EbsConversion < Ec2Script
|
|
220
231
|
private
|
221
232
|
|
222
233
|
def attach_storage()
|
234
|
+
@context[:script].post_message("going to attach volume #{@context[:volume_id]} to instance #{@context[:instance_id]} on device #{@context[:temp_device_name]}...")
|
223
235
|
@logger.debug "attach volume #{@context[:volume_id]} to instance #{@context[:instance_id]} on device #{@context[:temp_device_name]}"
|
224
236
|
@context[:ec2_api_handler].attach_volume(:volume_id => @context[:volume_id],
|
225
237
|
:instance_id => @context[:instance_id],
|
@@ -236,6 +248,7 @@ class Ami2EbsConversion < Ec2Script
|
|
236
248
|
done = true
|
237
249
|
end
|
238
250
|
end
|
251
|
+
@context[:script].post_message("volume successfully attached")
|
239
252
|
StorageAttached.new(@context)
|
240
253
|
end
|
241
254
|
|
@@ -250,9 +263,11 @@ class Ami2EbsConversion < Ec2Script
|
|
250
263
|
private
|
251
264
|
|
252
265
|
def create_fs()
|
266
|
+
@context[:script].post_message("going to create filesystem on #{@context[:dns_name]} to #{@context[:temp_device_name]}...")
|
253
267
|
@logger.debug "create filesystem on #{@context[:dns_name]} to #{@context[:temp_device_name]}"
|
254
268
|
connect()
|
255
269
|
@context[:remote_command_handler].create_filesystem("ext3", @context[:temp_device_name])
|
270
|
+
@context[:script].post_message("filesystem system successfully created")
|
256
271
|
FileSystemCreated.new(@context)
|
257
272
|
end
|
258
273
|
end
|
@@ -267,6 +282,7 @@ class Ami2EbsConversion < Ec2Script
|
|
267
282
|
|
268
283
|
def mount_fs()
|
269
284
|
@context[:path] = "/mnt/tmp_#{@context[:volume_id]}"
|
285
|
+
@context[:script].post_message("going to mount #{@context[:temp_device_name]} on #{@context[:path]}...")
|
270
286
|
@logger.debug "mount #{@context[:temp_device_name]} on #{@context[:path]}"
|
271
287
|
@context[:remote_command_handler].mkdir(@context[:path])
|
272
288
|
@context[:remote_command_handler].mount(@context[:temp_device_name], @context[:path])
|
@@ -274,6 +290,7 @@ class Ami2EbsConversion < Ec2Script
|
|
274
290
|
if !@context[:remote_command_handler].drive_mounted?(@context[:path])
|
275
291
|
raise Exception.new("drive #{@context[:path]} not mounted")
|
276
292
|
end
|
293
|
+
@context[:script].post_message("mount successful")
|
277
294
|
FileSystemMounted.new(@context)
|
278
295
|
end
|
279
296
|
end
|
@@ -287,12 +304,14 @@ class Ami2EbsConversion < Ec2Script
|
|
287
304
|
private
|
288
305
|
|
289
306
|
def copy()
|
307
|
+
@context[:script].post_message("going to start copying files to #{@context[:path]}. This may take quite a time...")
|
290
308
|
@logger.debug "start copying to #{@context[:path]}"
|
291
309
|
start = Time.new.to_i
|
292
310
|
@context[:remote_command_handler].rsync("/", "#{@context[:path]}", "/mnt/")
|
293
311
|
@context[:remote_command_handler].rsync("/dev/", "#{@context[:path]}/dev/")
|
294
312
|
endtime = Time.new.to_i
|
295
313
|
@logger.info "copy took #{(endtime-start)}s"
|
314
|
+
@context[:script].post_message("copying is done (took #{endtime-start})s")
|
296
315
|
CopyDone.new(@context)
|
297
316
|
end
|
298
317
|
end
|
@@ -306,12 +325,14 @@ class Ami2EbsConversion < Ec2Script
|
|
306
325
|
private
|
307
326
|
|
308
327
|
def unmount()
|
328
|
+
@context[:script].post_message("going to clean things up. Start with unmounting ...")
|
309
329
|
@logger.debug "unmount #{@context[:path]}"
|
310
330
|
@context[:remote_command_handler].umount(@context[:path])
|
311
331
|
sleep(2) #give umount some time
|
312
332
|
if @context[:remote_command_handler].drive_mounted?(@context[:path])
|
313
333
|
raise Exception.new("drive #{@context[:path]} not unmounted")
|
314
334
|
end
|
335
|
+
@context[:script].post_message("device unmounted")
|
315
336
|
VolumeUnmounted.new(@context)
|
316
337
|
end
|
317
338
|
end
|
@@ -325,6 +346,7 @@ class Ami2EbsConversion < Ec2Script
|
|
325
346
|
private
|
326
347
|
|
327
348
|
def detach()
|
349
|
+
@context[:script].post_message("going to detach volume #{@context[:volume_id]}...")
|
328
350
|
@logger.debug "detach volume #{@context[:volume_id]}"
|
329
351
|
@context[:ec2_api_handler].detach_volume(:volume_id => @context[:volume_id],
|
330
352
|
:instance_id => @context[:instance_id]
|
@@ -339,6 +361,7 @@ class Ami2EbsConversion < Ec2Script
|
|
339
361
|
done = true
|
340
362
|
end
|
341
363
|
end
|
364
|
+
@context[:script].post_message("volume #{@context[:volume_id]} detached.")
|
342
365
|
VolumeDetached.new(@context)
|
343
366
|
end
|
344
367
|
end
|
@@ -353,6 +376,7 @@ class Ami2EbsConversion < Ec2Script
|
|
353
376
|
private
|
354
377
|
|
355
378
|
def create_snapshot()
|
379
|
+
@context[:script].post_message("going to create a snapshot...")
|
356
380
|
@logger.debug "create snapshot for volume #{@context[:volume_id]}"
|
357
381
|
res = @context[:ec2_api_handler].create_snapshot(:volume_id => @context[:volume_id])
|
358
382
|
@context[:snapshot_id] = res['snapshotId']
|
@@ -367,6 +391,7 @@ class Ami2EbsConversion < Ec2Script
|
|
367
391
|
done = true
|
368
392
|
end
|
369
393
|
end
|
394
|
+
@context[:script].post_message("snapshot is done with ID=#{@context[:snapshot_id]}")
|
370
395
|
SnapshotCreated.new(@context)
|
371
396
|
end
|
372
397
|
end
|
@@ -380,8 +405,10 @@ class Ami2EbsConversion < Ec2Script
|
|
380
405
|
private
|
381
406
|
|
382
407
|
def delete_volume
|
408
|
+
@context[:script].post_message("going to delete volume #{@context[:volume_id]} (no longer needed)...")
|
383
409
|
@logger.debug "delete volume #{@context[:volume_id]}"
|
384
410
|
res = @context[:ec2_api_handler].delete_volume(:volume_id => @context[:volume_id])
|
411
|
+
@context[:script].post_message("volume #{@context[:volume_id]} deleted")
|
385
412
|
VolumeDeleted.new(@context)
|
386
413
|
end
|
387
414
|
end
|
@@ -395,6 +422,7 @@ class Ami2EbsConversion < Ec2Script
|
|
395
422
|
private
|
396
423
|
|
397
424
|
def register()
|
425
|
+
@context[:script].post_message("going to register snapshot #{@context[:snapshot_id]}...")
|
398
426
|
@logger.debug "register snapshot #{@context[:snapshot_id]} as #{@context[:name]}"
|
399
427
|
res = @context[:ec2_api_handler].register_image_updated(:snapshot_id => @context[:snapshot_id],
|
400
428
|
:kernel_id => @context[:kernel_id], :architecture => @context[:architecture],
|
@@ -405,6 +433,7 @@ class Ami2EbsConversion < Ec2Script
|
|
405
433
|
@logger.debug "result of registration = #{res.inspect}"
|
406
434
|
@context[:result][:image_id] = res['imageId']
|
407
435
|
@logger.info "resulting image_id = #{@context[:result][:image_id]}"
|
436
|
+
@context[:script].post_message("snapshot #{@context[:snapshot_id]} successfully registered as AMI #{@context[:result][:image_id]} ")
|
408
437
|
SnapshotRegistered.new(@context)
|
409
438
|
end
|
410
439
|
end
|
@@ -418,6 +447,7 @@ class Ami2EbsConversion < Ec2Script
|
|
418
447
|
private
|
419
448
|
|
420
449
|
def shut_down()
|
450
|
+
@context[:script].post_message("going to shut down the temporary instance #{@context[:instance_id]}...")
|
421
451
|
@logger.debug "shutdown instance #{@context[:instance_id]}"
|
422
452
|
res = @context[:ec2_api_handler].terminate_instances(:instance_id => @context[:instance_id])
|
423
453
|
done = false
|
@@ -432,6 +462,7 @@ class Ami2EbsConversion < Ec2Script
|
|
432
462
|
raise Exception.new('instance failed to shut down')
|
433
463
|
end
|
434
464
|
end
|
465
|
+
@context[:script].post_message("instance #{@context[:instance_id]} is terminated")
|
435
466
|
Done.new(@context)
|
436
467
|
end
|
437
468
|
end
|
@@ -45,6 +45,7 @@ class DmEncrypt < Ec2Script
|
|
45
45
|
@input_params[:ec2_api_handler] = AWS::EC2::Base.new(:access_key_id => @input_params[:aws_access_key],
|
46
46
|
:secret_access_key => @input_params[:aws_secret_key], :server => @input_params[:ec2_api_server])
|
47
47
|
end
|
48
|
+
@input_params[:script] = self
|
48
49
|
# start state machine
|
49
50
|
current_state = DmEncryptState.load_state(@input_params)
|
50
51
|
@state_change_listeners.each() {|listener|
|
@@ -102,6 +103,7 @@ class DmEncrypt < Ec2Script
|
|
102
103
|
private
|
103
104
|
|
104
105
|
def connect()
|
106
|
+
@context[:script].post_message("going to connect to #{@context[:ip_address]}...")
|
105
107
|
@logger.debug "InitialState.connect"
|
106
108
|
if @context[:ssh_key_file] != nil
|
107
109
|
@context[:remote_command_handler].connect_with_keyfile(@context[:ip_address], @context[:ssh_key_file])
|
@@ -111,6 +113,7 @@ class DmEncrypt < Ec2Script
|
|
111
113
|
raise Exception.new("no key information specified")
|
112
114
|
end
|
113
115
|
@context[:result][:os] = @context[:remote_command_handler].retrieve_os()
|
116
|
+
@context[:script].post_message("connection successful, OS = #{@context[:result][:os]}")
|
114
117
|
ConnectedState.new(@context)
|
115
118
|
end
|
116
119
|
end
|
@@ -123,8 +126,10 @@ class DmEncrypt < Ec2Script
|
|
123
126
|
|
124
127
|
private
|
125
128
|
def install_tools
|
129
|
+
@context[:script].post_message("check if the system has the cryptset-package installed")
|
126
130
|
@logger.debug "ConnectedState.install_tools"
|
127
131
|
if !tools_installed?
|
132
|
+
@context[:script].post_message("cryptset-package not installed. Going to install it...")
|
128
133
|
TOOLS.each() {|tool|
|
129
134
|
@context[:remote_command_handler].install(tool)
|
130
135
|
}
|
@@ -133,6 +138,7 @@ class DmEncrypt < Ec2Script
|
|
133
138
|
raise Exception.new("dm-crypt module missing")
|
134
139
|
end
|
135
140
|
if tools_installed?
|
141
|
+
@context[:script].post_message("cryptset-package is available")
|
136
142
|
@logger.debug "system says that tools are installed"
|
137
143
|
ToolInstalledState.new(@context)
|
138
144
|
else
|
@@ -158,9 +164,12 @@ class DmEncrypt < Ec2Script
|
|
158
164
|
|
159
165
|
private
|
160
166
|
def create_encrypted_volume
|
167
|
+
@context[:script].post_message("going to encrypt device #{@context[:device]} "+
|
168
|
+
"named '#{@context[:device_name]}' and mount it as #{@context[:storage_path]}...")
|
161
169
|
@logger.debug "ToolInstalledState.create_encrypted_volume"
|
162
170
|
@context[:remote_command_handler].encrypt_storage(@context[:device_name],
|
163
171
|
@context[:paraphrase], @context[:device], @context[:storage_path])
|
172
|
+
@context[:script].post_message("device #{@context[:device]} is encrypted and mounted")
|
164
173
|
MountedAndActivatedState.new(@context)
|
165
174
|
end
|
166
175
|
|
@@ -179,8 +188,10 @@ class DmEncrypt < Ec2Script
|
|
179
188
|
|
180
189
|
private
|
181
190
|
def cleanup()
|
191
|
+
@context[:script].post_message("disconnecting...")
|
182
192
|
@logger.debug "MountedAndActivatedState.cleanup"
|
183
193
|
@context[:remote_command_handler].disconnect()
|
194
|
+
@context[:script].post_message("done")
|
184
195
|
DoneState.new(@context)
|
185
196
|
end
|
186
197
|
|
@@ -9,6 +9,7 @@ class Ec2Script
|
|
9
9
|
def initialize(input_params)
|
10
10
|
@input_params = input_params
|
11
11
|
@state_change_listeners = []
|
12
|
+
@progress_message_listeners = []
|
12
13
|
if input_params[:logger] == nil
|
13
14
|
@logger = Logger.new(STDOUT)
|
14
15
|
@logger .level = Logger::WARN
|
@@ -22,6 +23,10 @@ class Ec2Script
|
|
22
23
|
@state_change_listeners << listener
|
23
24
|
end
|
24
25
|
|
26
|
+
def register_progress_message_listener(listener)
|
27
|
+
@progress_message_listeners << listener
|
28
|
+
end
|
29
|
+
|
25
30
|
def start_script
|
26
31
|
raise Exception.new("must be implemented")
|
27
32
|
end
|
@@ -37,5 +42,11 @@ class Ec2Script
|
|
37
42
|
raise Exception.new("must be implemented")
|
38
43
|
end
|
39
44
|
|
45
|
+
def post_message(message, level = Logger::DEBUG)
|
46
|
+
@progress_message_listeners.each() {|listener|
|
47
|
+
listener.new_message(message, level)
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
40
51
|
end
|
41
52
|
|
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.
|
4
|
+
version: 0.0.10
|
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: 2010-01
|
12
|
+
date: 2010-02-01 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -48,6 +48,7 @@ files:
|
|
48
48
|
- lib/cloudyscripts.rb
|
49
49
|
- lib/help/dm_crypt_helper.rb
|
50
50
|
- lib/help/ec2_helper.rb
|
51
|
+
- lib/help/progress_message_listener.rb
|
51
52
|
- lib/help/remote_command_handler.rb
|
52
53
|
- lib/help/script_execution_state.rb
|
53
54
|
- lib/help/state_change_listener.rb
|