CloudyScripts 2.14.60 → 2.14.62
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/lib/help/helper.rb +23 -0
- data/lib/help/state_transition_helper.rb +75 -16
- data/lib/scripts/ec2/ami2_ebs_conversion.rb +1 -1
- data/lib/scripts/ec2/copy_ami.rb +105 -24
- data/lib/scripts/ec2/copy_mswindows_ami.rb +61 -18
- data/lib/scripts/ec2/copy_mswindows_snapshot.rb +117 -22
- data/lib/scripts/ec2/copy_snapshot.rb +86 -21
- data/lib/scripts/ec2/download_snapshot.rb +65 -15
- data/lib/scripts/ec2/ec2_script.rb +4 -0
- metadata +157 -157
@@ -45,24 +45,33 @@ class CopyMsWindowsSnapshot < Ec2Script
|
|
45
45
|
if @input_params[:snapshot_id] == nil && !(@input_params[:snapshot_id] =~ /^snap-.*$/)
|
46
46
|
raise Exception.new("Invalid Snapshot ID specified: #{@input_params[:snapshot_id]}")
|
47
47
|
end
|
48
|
+
# AWS Linux AMI, source and target region
|
48
49
|
if @input_params[:source_ami_id] == nil && !(@input_params[:source_ami_id] =~ /^ami-.*$/)
|
49
50
|
raise Exception.new("Invalid source AMI ID specified: #{@input_params[:source_ami_id]}")
|
50
51
|
end
|
51
52
|
if @input_params[:target_ami_id] == nil && !(@input_params[:target_ami_id] =~ /^ami-.*$/)
|
52
53
|
raise Exception.new("Invalid target AMI ID specified: #{@input_params[:target_ami_id]}")
|
53
54
|
end
|
54
|
-
|
55
|
-
|
55
|
+
# AWS SecurityGroup, source and target regions
|
56
|
+
if @input_params[:source_security_group] == nil
|
57
|
+
@input_params[:source_security_group] = "default"
|
56
58
|
end
|
57
|
-
if !@local_ec2_helper.check_open_port(@input_params[:
|
58
|
-
|
59
|
+
if !@local_ec2_helper.check_open_port(@input_params[:source_security_group], 22)
|
60
|
+
post_message("'#{@input_params[:source_security_group]}' Security Group not opened port 22 for connect via SSH in source region")
|
61
|
+
@input_params[:source_security_group] = nil
|
62
|
+
else
|
63
|
+
post_message("'#{@input_params[:source_security_group]}' Security Group opened port 22 for connect via SSH in source region")
|
59
64
|
end
|
60
|
-
if @input_params[:
|
61
|
-
@input_params[:
|
65
|
+
if @input_params[:target_security_group] == nil
|
66
|
+
@input_params[:target_security_group] = "default"
|
62
67
|
end
|
63
|
-
if !@remote_ec2_helper.check_open_port(@input_params[:
|
64
|
-
|
68
|
+
if !@remote_ec2_helper.check_open_port(@input_params[:target_security_group], 22)
|
69
|
+
post_message("'#{@input_params[:target_security_group]}' Security Group not opened port 22 for connect via SSH in target region")
|
70
|
+
@input_params[:target_security_group] = nil
|
71
|
+
else
|
72
|
+
post_message("'#{@input_params[:target_security_group]}' Security Group opened port 22 for connect via SSH in target region")
|
65
73
|
end
|
74
|
+
# Device to use for volume
|
66
75
|
if @input_params[:root_device_name] == nil
|
67
76
|
@input_params[:root_device_name] = "/dev/sda1"
|
68
77
|
end
|
@@ -75,6 +84,7 @@ class CopyMsWindowsSnapshot < Ec2Script
|
|
75
84
|
if @input_params[:temp_device_name] == @input_params[:device_name]
|
76
85
|
raise Exception.new("Device name '#{@input_params[:device_name]}' and temporary device name '#{@input_params[:temp_device_name]}' must be different")
|
77
86
|
end
|
87
|
+
# SSH Parameters, source and target region
|
78
88
|
if @input_params[:source_ssh_username] == nil
|
79
89
|
@input_params[:source_ssh_username] = "root"
|
80
90
|
end
|
@@ -84,9 +94,12 @@ class CopyMsWindowsSnapshot < Ec2Script
|
|
84
94
|
if @input_params[:fs_type] == nil
|
85
95
|
@input_params[:fs_type] = "ext3"
|
86
96
|
end
|
87
|
-
if @input_params[:description] == nil || !
|
97
|
+
if @input_params[:description] == nil || !check_aws_desc(@input_params[:description])
|
88
98
|
@input_params[:description] = "Created by CloudyScripts - #{self.class.name}"
|
89
99
|
end
|
100
|
+
if @input_params[:name] == nil || !check_aws_name(@input_params[:name])
|
101
|
+
@input_params[:name] = "Created_by_CloudyScripts/#{self.class.name}_from_#{@input_params[:snapshot_id]}"
|
102
|
+
end
|
90
103
|
if @input_params[:compression] != nil && (@input_params[:compression] =~ /^on$/i)
|
91
104
|
@input_params[:compression] = true
|
92
105
|
else
|
@@ -140,8 +153,16 @@ class CopyMsWindowsSnapshot < Ec2Script
|
|
140
153
|
class InitialStateDone < CopyMsWindowsSnapshotState
|
141
154
|
def enter()
|
142
155
|
local_region()
|
143
|
-
post_message("
|
144
|
-
|
156
|
+
post_message("Launching an Helper instance in source Region...")
|
157
|
+
#XXX: create a CloudyScripts Security Group with TCP port 22 publicly opened
|
158
|
+
if @context[:source_security_group] == nil
|
159
|
+
@context[:source_security_group] = Ec2Script::CS_SEC_GRP_NAME
|
160
|
+
create_security_group_with_rules(@context[:source_security_group], Ec2Script::CS_SEC_GRP_DESC,
|
161
|
+
[{:ip_protocol => "tcp", :from_port => 22, :to_port => 22, :cidr_ip => "0.0.0.0/0"}])
|
162
|
+
post_message("'#{@context[:source_security_group]}' Security Group created with TCP port 22 publicly opened.")
|
163
|
+
end
|
164
|
+
|
165
|
+
result = launch_instance(@context[:source_ami_id], @context[:source_key_name], @context[:source_security_group],
|
145
166
|
nil, @context[:instance_type])
|
146
167
|
@context[:source_instance_id] = result.first
|
147
168
|
@context[:source_dns_name] = result[1]
|
@@ -236,7 +257,15 @@ class CopyMsWindowsSnapshot < Ec2Script
|
|
236
257
|
class BackupedDataState < CopyMsWindowsSnapshotState
|
237
258
|
def enter()
|
238
259
|
remote_region()
|
239
|
-
|
260
|
+
#XXX: create a CloudyScripts Security Group with TCP port 22 publicly opened
|
261
|
+
if @context[:target_security_group] == nil
|
262
|
+
@context[:target_security_group] = Ec2Script::CS_SEC_GRP_NAME
|
263
|
+
create_security_group_with_rules(@context[:target_security_group], Ec2Script::CS_SEC_GRP_DESC,
|
264
|
+
[{:ip_protocol => "tcp", :from_port => 22, :to_port => 22, :cidr_ip => "0.0.0.0/0"}])
|
265
|
+
post_message("'#{@context[:target_security_group]}' Security Group created with TCP port 22 publicly opened.")
|
266
|
+
end
|
267
|
+
|
268
|
+
result = launch_instance(@context[:target_ami_id], @context[:target_key_name], @context[:target_security_group],
|
240
269
|
nil, @context[:instance_type])
|
241
270
|
@context[:target_instance_id] = result.first
|
242
271
|
@context[:target_dns_name] = result[1]
|
@@ -386,7 +415,7 @@ class CopyMsWindowsSnapshot < Ec2Script
|
|
386
415
|
|
387
416
|
# AMI is registered. Now only cleanup is missing, i.e. shut down instances and
|
388
417
|
# remote the volumes that were created. Start with cleaning the ressources
|
389
|
-
# in the
|
418
|
+
# in the both regions.
|
390
419
|
# Steps:
|
391
420
|
# - cleanup source region
|
392
421
|
# - unmount temp volume
|
@@ -400,26 +429,92 @@ class CopyMsWindowsSnapshot < Ec2Script
|
|
400
429
|
# - delete source and temp volume
|
401
430
|
class TargetSnapshotCreatedState < CopyMsWindowsSnapshotState
|
402
431
|
def enter()
|
432
|
+
error = []
|
403
433
|
local_region()
|
404
434
|
connect(@context[:source_dns_name], @context[:source_ssh_username], nil, @context[:source_ssh_keydata])
|
405
435
|
mount_point = "/mnt/tmp_#{@context[:source_temp_volume_id]}"
|
406
436
|
unmount_fs(mount_point)
|
407
437
|
disconnect()
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
438
|
+
begin
|
439
|
+
detach_volume(@context[:source_temp_volume_id], @context[:source_instance_id])
|
440
|
+
rescue Exception => e
|
441
|
+
error << e
|
442
|
+
post_message("Unable to detach volume '#{@context[:source_temp_volume_id]}' in source region: #{e.to_s}")
|
443
|
+
end
|
444
|
+
begin
|
445
|
+
detach_volume(@context[:source_volume_id], @context[:source_instance_id])
|
446
|
+
rescue Exception => e
|
447
|
+
error << e
|
448
|
+
post_message("Unable to detach volume '#{@context[:source_volume_id]}' in source region: #{e.to_s}")
|
449
|
+
end
|
450
|
+
begin
|
451
|
+
shut_down_instance(@context[:source_instance_id])
|
452
|
+
rescue Exception => e
|
453
|
+
error << e
|
454
|
+
post_message("Unable to shutdown instance '#{@context[:source_instance_id]}' in source region: #{e.to_s}")
|
455
|
+
end
|
456
|
+
begin
|
457
|
+
delete_volume(@context[:source_temp_volume_id])
|
458
|
+
rescue Exception => e
|
459
|
+
error << e
|
460
|
+
post_message("Unable to delete volume '#{@context[:source_temp_volume_id]}' in source region: #{e.to_s}")
|
461
|
+
end
|
462
|
+
begin
|
463
|
+
delete_volume(@context[:source_volume_id])
|
464
|
+
rescue Exception => e
|
465
|
+
error << e
|
466
|
+
post_message("Unable to delete volume '#{@context[:source_volume_id]}' in source region: #{e.to_s}")
|
467
|
+
end
|
468
|
+
if @context[:source_security_group].eql?(Ec2Script::CS_SEC_GRP_NAME)
|
469
|
+
begin
|
470
|
+
delete_security_group(@context[:source_security_group])
|
471
|
+
rescue Exception => e
|
472
|
+
error << e
|
473
|
+
post_message("Unable to delete Security Group '#{@context[:source_security_group]}' in source region: #{e.to_s}")
|
474
|
+
end
|
475
|
+
end
|
413
476
|
#
|
414
477
|
remote_region()
|
415
478
|
connect(@context[:target_dns_name], @context[:target_ssh_username], nil, @context[:target_ssh_keydata])
|
416
479
|
mount_point = "/mnt/tmp_#{@context[:target_temp_volume_id]}"
|
417
480
|
unmount_fs(mount_point)
|
418
481
|
disconnect()
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
482
|
+
begin
|
483
|
+
detach_volume(@context[:target_temp_volume_id], @context[:target_instance_id])
|
484
|
+
rescue Exception => e
|
485
|
+
error << e
|
486
|
+
post_message("Unable to detach volume '#{@context[:target_temp_volume_id]}' in target region: #{e.to_s}")
|
487
|
+
end
|
488
|
+
begin
|
489
|
+
shut_down_instance(@context[:target_instance_id])
|
490
|
+
rescue Exception => e
|
491
|
+
error << e
|
492
|
+
post_message("Unable to shutdown instance '#{@context[:target_instance_id]}' in target region: #{e.to_s}")
|
493
|
+
end
|
494
|
+
begin
|
495
|
+
delete_volume(@context[:target_temp_volume_id])
|
496
|
+
rescue Exception => e
|
497
|
+
error << e
|
498
|
+
post_message("Unable to delete volume '#{@context[:target_temp_volume_id]}' in target region: #{e.to_s}")
|
499
|
+
end
|
500
|
+
begin
|
501
|
+
delete_volume(@context[:target_volume_id])
|
502
|
+
rescue Exception => e
|
503
|
+
error << e
|
504
|
+
post_message("Unable to delete volume '#{@context[:target_volume_id]}' in target region: #{e.to_s}")
|
505
|
+
end
|
506
|
+
if @context[:target_security_group].eql?(Ec2Script::CS_SEC_GRP_NAME)
|
507
|
+
begin
|
508
|
+
delete_security_group(@context[:target_security_group])
|
509
|
+
rescue Exception => e
|
510
|
+
error << e
|
511
|
+
post_message("Unable to delete Security Group '#{@context[:target_security_group]}' in target region: #{e.to_s}")
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
if error.size() > 0
|
516
|
+
raise Exception.new("Cleanup error(s)")
|
517
|
+
end
|
423
518
|
|
424
519
|
Done.new(@context)
|
425
520
|
end
|
@@ -38,12 +38,24 @@ class CopySnapshot< Ec2Script
|
|
38
38
|
|
39
39
|
def check_input_parameters()
|
40
40
|
local_ec2_helper = Ec2Helper.new(@input_params[:ec2_api_handler])
|
41
|
-
if
|
42
|
-
|
41
|
+
if @input_params[:source_security_group] == nil
|
42
|
+
@input_params[:source_security_group] = "default"
|
43
|
+
end
|
44
|
+
if !local_ec2_helper.check_open_port(@input_params[:source_security_group], 22)
|
45
|
+
post_message("'#{@input_params[:source_security_group]}' Security Group not opened port 22 for connect via SSH in source region")
|
46
|
+
@input_params[:source_security_group] = nil
|
47
|
+
else
|
48
|
+
post_message("'#{@input_params[:source_security_group]}' Security Group opened port 22 for connect via SSH in source region")
|
43
49
|
end
|
44
50
|
remote_ec2_helper = Ec2Helper.new(@input_params[:target_ec2_handler])
|
45
|
-
if
|
46
|
-
|
51
|
+
if @input_params[:target_security_group] == nil
|
52
|
+
@input_params[:target_security_group] = "default"
|
53
|
+
end
|
54
|
+
if !remote_ec2_helper.check_open_port(@input_params[:target_security_group], 22)
|
55
|
+
post_message("'#{@input_params[:target_security_group]}' Security Group not opened port 22 for connect via SSH in target region")
|
56
|
+
@input_params[:target_security_group] = nil
|
57
|
+
else
|
58
|
+
post_message("'#{@input_params[:target_security_group]}' Security Group opened port 22 for connect via SSH in target region")
|
47
59
|
end
|
48
60
|
if @input_params[:source_ssh_username] == nil
|
49
61
|
@input_params[:source_ssh_username] = "root"
|
@@ -51,9 +63,12 @@ class CopySnapshot< Ec2Script
|
|
51
63
|
if @input_params[:target_ssh_username] == nil
|
52
64
|
@input_params[:target_ssh_username] = "root"
|
53
65
|
end
|
54
|
-
if @input_params[:description] == nil || !
|
66
|
+
if @input_params[:description] == nil || !check_aws_desc(@input_params[:description])
|
55
67
|
@input_params[:description] = "Created by CloudyScripts - #{self.class.name}"
|
56
68
|
end
|
69
|
+
if @input_params[:name] == nil || !check_aws_name(@input_params[:name])
|
70
|
+
@input_params[:name] = "Created_by_CloudyScripts/#{self.class.name}_from_#{@input_params[:snapshot_id]}"
|
71
|
+
end
|
57
72
|
end
|
58
73
|
|
59
74
|
# Load the initial state for the script.
|
@@ -83,10 +98,20 @@ class CopySnapshot< Ec2Script
|
|
83
98
|
# Initial state: start up AMI in source region
|
84
99
|
class InitialState < CopySnapshotState
|
85
100
|
def enter()
|
86
|
-
|
101
|
+
local_region()
|
102
|
+
#XXX: create a CloudyScripts Security Group with TCP port 22 publicly opened
|
103
|
+
if @context[:source_security_group] == nil
|
104
|
+
@context[:source_security_group] = Ec2Script::CS_SEC_GRP_NAME
|
105
|
+
create_security_group_with_rules(@context[:source_security_group], Ec2Script::CS_SEC_GRP_DESC,
|
106
|
+
[{:ip_protocol => "tcp", :from_port => 22, :to_port => 22, :cidr_ip => "0.0.0.0/0"}])
|
107
|
+
post_message("'#{@context[:source_security_group]}' Security Group created with TCP port 22 publicly opened.")
|
108
|
+
end
|
109
|
+
|
110
|
+
result = launch_instance(@context[:source_ami_id], @context[:source_key_name], @context[:source_security_group])
|
87
111
|
@context[:source_instance_id] = result.first
|
88
112
|
@context[:source_dns_name] = result[1]
|
89
113
|
@context[:source_availability_zone] = result[2]
|
114
|
+
|
90
115
|
SourceInstanceLaunchedState.new(@context)
|
91
116
|
end
|
92
117
|
end
|
@@ -106,6 +131,7 @@ class CopySnapshot< Ec2Script
|
|
106
131
|
#@context[:fs_type] = get_partition_fs_type(mount_point)
|
107
132
|
@context[:fs_type], @context[:label] = get_partition_fs_type_and_label(mount_point)
|
108
133
|
disconnect()
|
134
|
+
|
109
135
|
SourceVolumeReadyState.new(@context)
|
110
136
|
end
|
111
137
|
end
|
@@ -114,11 +140,19 @@ class CopySnapshot< Ec2Script
|
|
114
140
|
class SourceVolumeReadyState < CopySnapshotState
|
115
141
|
def enter()
|
116
142
|
remote_region()
|
117
|
-
|
118
|
-
|
143
|
+
#XXX: create a CloudyScripts Security Group with TCP port 22 publicly opened
|
144
|
+
if @context[:target_security_group] == nil
|
145
|
+
@context[:target_security_group] = Ec2Script::CS_SEC_GRP_NAME
|
146
|
+
create_security_group_with_rules(@context[:target_security_group], Ec2Script::CS_SEC_GRP_DESC,
|
147
|
+
[{:ip_protocol => "tcp", :from_port => 22, :to_port => 22, :cidr_ip => "0.0.0.0/0"}])
|
148
|
+
post_message("'#{@context[:target_security_group]}' Security Group created with TCP port 22 publicly opened.")
|
149
|
+
end
|
150
|
+
|
151
|
+
result = launch_instance(@context[:target_ami_id], @context[:target_key_name], @context[:target_security_group])
|
119
152
|
@context[:target_instance_id] = result.first
|
120
153
|
@context[:target_dns_name] = result[1]
|
121
154
|
@context[:target_availability_zone] = result[2]
|
155
|
+
|
122
156
|
TargetInstanceLaunchedState.new(@context)
|
123
157
|
end
|
124
158
|
end
|
@@ -139,6 +173,7 @@ class CopySnapshot< Ec2Script
|
|
139
173
|
create_labeled_fs(@context[:target_dns_name], device, @context[:fs_type], @context[:label])
|
140
174
|
mount_fs(mount_point, device)
|
141
175
|
disconnect()
|
176
|
+
|
142
177
|
TargetVolumeReadyState.new(@context)
|
143
178
|
end
|
144
179
|
end
|
@@ -159,8 +194,8 @@ class CopySnapshot< Ec2Script
|
|
159
194
|
# @context[:target_ssh_keyfile], "#{key_path}#{@context[:target_key_name]}.pem")
|
160
195
|
upload_file(@context[:source_dns_name], @context[:source_ssh_username], @context[:source_ssh_keydata],
|
161
196
|
@context[:target_ssh_keyfile], "#{key_path}#{@context[:target_key_name].gsub(/\s+/, '_')}.pem")
|
162
|
-
|
163
197
|
post_message("credentials are in place to connect source and target.")
|
198
|
+
|
164
199
|
KeyInPlaceState.new(@context)
|
165
200
|
end
|
166
201
|
end
|
@@ -187,6 +222,7 @@ class CopySnapshot< Ec2Script
|
|
187
222
|
enable_ssh_tty(@context[:target_dns_name])
|
188
223
|
unmount_fs(dest_dir)
|
189
224
|
disconnect()
|
225
|
+
|
190
226
|
DataCopiedState.new(@context)
|
191
227
|
end
|
192
228
|
end
|
@@ -198,28 +234,57 @@ class CopySnapshot< Ec2Script
|
|
198
234
|
remote_region()
|
199
235
|
@context[:new_snapshot_id] = create_snapshot(@context[:target_volume_id], @context[:description])
|
200
236
|
@context[:result][:snapshot_id] = @context[:new_snapshot_id]
|
237
|
+
|
201
238
|
SnapshotCreatedState.new(@context)
|
202
239
|
end
|
203
240
|
end
|
204
241
|
|
205
242
|
# Operation done. Now only cleanup is missing, i.e. shut down instances and
|
206
243
|
# remote the volumes that were created. Start with cleaning the ressources
|
207
|
-
# in
|
244
|
+
# in both regions.
|
208
245
|
class SnapshotCreatedState < CopySnapshotState
|
209
246
|
def enter()
|
247
|
+
error = []
|
210
248
|
local_region()
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
249
|
+
begin
|
250
|
+
shut_down_instance(@context[:source_instance_id])
|
251
|
+
rescue Exception => e
|
252
|
+
error << e
|
253
|
+
post_message("Unable to shutdown instance '#{@context[:source_instance_id]}' in source region: #{e.to_s}")
|
254
|
+
end
|
255
|
+
begin
|
256
|
+
delete_volume(@context[:source_volume_id])
|
257
|
+
rescue Exception => e
|
258
|
+
error << e
|
259
|
+
post_message("Unable to delete volume '#{@context[:source_volume_id]}' in source region: #{e.to_s}")
|
260
|
+
end
|
261
|
+
#XXX: delete Security Group according to its name
|
262
|
+
if @context[:source_security_group].eql?(Ec2Script::CS_SEC_GRP_NAME)
|
263
|
+
delete_security_group(@context[:source_security_group])
|
264
|
+
end
|
265
|
+
#
|
220
266
|
remote_region()
|
221
|
-
|
222
|
-
|
267
|
+
begin
|
268
|
+
shut_down_instance(@context[:target_instance_id])
|
269
|
+
rescue Exception => e
|
270
|
+
error << e
|
271
|
+
post_message("Unable to shutdown instance '#{@context[:target_instance_id]}' in target region: #{e.to_s}")
|
272
|
+
end
|
273
|
+
begin
|
274
|
+
delete_volume(@context[:target_volume_id])
|
275
|
+
rescue Exception => e
|
276
|
+
error << e
|
277
|
+
post_message("Unable to delete volume '#{@context[:target_volume_id]}' in target region: #{e.to_s}")
|
278
|
+
end
|
279
|
+
#XXX: delete Security Group according to its name
|
280
|
+
if @context[:target_security_group].eql?(Ec2Script::CS_SEC_GRP_NAME)
|
281
|
+
delete_security_group(@context[:target_security_group])
|
282
|
+
end
|
283
|
+
|
284
|
+
if error.size() > 0
|
285
|
+
raise Exception.new("Cleanup error(s)")
|
286
|
+
end
|
287
|
+
|
223
288
|
Done.new(@context)
|
224
289
|
end
|
225
290
|
end
|
@@ -38,17 +38,24 @@ class DownloadSnapshot < Ec2Script
|
|
38
38
|
@input_params[:security_group_name] = "default"
|
39
39
|
end
|
40
40
|
ec2_helper = Ec2Helper.new(@input_params[:ec2_api_handler])
|
41
|
+
if @input_params[:security_group_name] == nil
|
42
|
+
@input_params[:security_group_name] = "default"
|
43
|
+
end
|
41
44
|
if !ec2_helper.check_open_port(@input_params[:security_group_name], 22)
|
42
|
-
raise Exception.new("Port 22 must be opened for security group #{@input_params[:security_group_name]} to connect via SSH")
|
45
|
+
#raise Exception.new("Port 22 must be opened for security group #{@input_params[:security_group_name]} to connect via SSH")
|
46
|
+
post_message("'#{@input_params[:security_group_name]}' Security Group not opened port 22 for connect via SSH")
|
47
|
+
@input_params[:security_group_name] = nil
|
43
48
|
end
|
44
49
|
if !ec2_helper.check_open_port(@input_params[:security_group_name], 80)
|
45
|
-
raise Exception.new("Port 80 must be opened for security group #{@input_params[:security_group_name]} to make the download link work")
|
50
|
+
#raise Exception.new("Port 80 must be opened for security group #{@input_params[:security_group_name]} to make the download link work")
|
51
|
+
post_message("'#{@input_params[:security_group_name]}' Security Group not opened port 80 for download via HTTP")
|
52
|
+
@input_params[:security_group_name] = nil
|
46
53
|
end
|
47
54
|
if @input_params[:source_device] == nil
|
48
|
-
@input_params[:source_device] = "/dev/
|
55
|
+
@input_params[:source_device] = "/dev/sdj"
|
49
56
|
end
|
50
57
|
if @input_params[:dest_device] == nil
|
51
|
-
@input_params[:dest_device] = "/dev/
|
58
|
+
@input_params[:dest_device] = "/dev/sdk"
|
52
59
|
end
|
53
60
|
if @input_params[:zip_file_dest] == nil
|
54
61
|
@input_params[:zip_file_dest] = "/var/www/html"
|
@@ -83,10 +90,20 @@ class DownloadSnapshot < Ec2Script
|
|
83
90
|
# Start state. First thing to do is to launch the instance.
|
84
91
|
class InitialState < DownloadSnapshotState
|
85
92
|
def enter
|
93
|
+
#XXX: create a CloudyScripts Security Group with TCP port 22 publicly opened
|
94
|
+
if @context[:security_group_name] == nil
|
95
|
+
@context[:security_group_name] = Ec2Script::CS_SEC_GRP_NAME
|
96
|
+
create_security_group_with_rules(@context[:security_group_name], Ec2Script::CS_SEC_GRP_DESC,
|
97
|
+
[{:ip_protocol => "tcp", :from_port => 22, :to_port => 22, :cidr_ip => "0.0.0.0/0"},
|
98
|
+
{:ip_protocol => "tcp", :from_port => 80, :to_port => 80, :cidr_ip => "0.0.0.0/0"}])
|
99
|
+
post_message("'#{@context[:security_group_name]}' Security Group created with TCP port 22 and 80 publicly opened.")
|
100
|
+
end
|
101
|
+
|
86
102
|
result = launch_instance(@context[:ami_id], @context[:key_name], @context[:security_group_name])
|
87
103
|
@context[:instance_id] = result.first
|
88
104
|
@context[:dns_name] = result[1]
|
89
105
|
@context[:availability_zone] = result[2]
|
106
|
+
|
90
107
|
InstanceLaunchedState.new(context)
|
91
108
|
end
|
92
109
|
end
|
@@ -99,6 +116,7 @@ class DownloadSnapshot < Ec2Script
|
|
99
116
|
size = ec2_helper.volume_prop(@context[:source_volume_id], :size).to_i
|
100
117
|
puts "retrieved volume size of #{size}"
|
101
118
|
@context[:dest_volume_id] = create_volume(@context[:availability_zone], size)
|
119
|
+
|
102
120
|
VolumesCreated.new(@context)
|
103
121
|
end
|
104
122
|
|
@@ -110,6 +128,7 @@ class DownloadSnapshot < Ec2Script
|
|
110
128
|
@context[:script].post_message("Going to create two volumes. One with the snapshot data, one to store the zipped data for download.")
|
111
129
|
attach_volume(@context[:source_volume_id], @context[:instance_id], @context[:source_device])
|
112
130
|
attach_volume(@context[:dest_volume_id], @context[:instance_id], @context[:dest_device])
|
131
|
+
|
113
132
|
VolumesAttached.new(@context)
|
114
133
|
end
|
115
134
|
end
|
@@ -122,6 +141,13 @@ class DownloadSnapshot < Ec2Script
|
|
122
141
|
connect(@context[:dns_name], @context[:ssh_username], @context[:ssh_keyfile], @context[:ssh_keydata])
|
123
142
|
# source
|
124
143
|
source_dir = "/mnt/tmp_#{@context[:source_volume_id]}"
|
144
|
+
# detect partition vs volume: simply check if we have several /dev/sdx* entries
|
145
|
+
parts_count = get_partition_count(@context[:source_device])
|
146
|
+
if parts_count >= 2
|
147
|
+
@context[:script].post_message("Detected specific volume with a valid partition table on device '#{@context[:source_device]}'...")
|
148
|
+
@context[:source_device] = @context[:source_device] + '1'
|
149
|
+
@context[:script].post_message("Using '#{@context[:source_device]}' as source filesystem")
|
150
|
+
end
|
125
151
|
mount_fs(source_dir, @context[:source_device])
|
126
152
|
@context[:fs_type], @context[:label] = get_partition_fs_type_and_label(source_dir)
|
127
153
|
# target
|
@@ -129,6 +155,7 @@ class DownloadSnapshot < Ec2Script
|
|
129
155
|
#create_fs(@context[:dns_name], @context[:dest_device])
|
130
156
|
create_labeled_fs(@context[:dns_name], @context[:dest_device], @context[:fs_type], @context[:label])
|
131
157
|
mount_fs(dest_dir, @context[:dest_device])
|
158
|
+
|
132
159
|
FileSystemsReady.new(@context)
|
133
160
|
end
|
134
161
|
end
|
@@ -138,9 +165,9 @@ class DownloadSnapshot < Ec2Script
|
|
138
165
|
def enter
|
139
166
|
mount_point = "/mnt/tmp_#{@context[:source_volume_id]}"
|
140
167
|
zip_volume(mount_point, @context[:zip_file_dest], @context[:zip_file_name])
|
168
|
+
|
141
169
|
VolumeZippedAndDownloadableState.new(@context)
|
142
170
|
end
|
143
|
-
|
144
171
|
end
|
145
172
|
|
146
173
|
# Volume is zipped and downloadable. Wait 5 minutes.
|
@@ -158,6 +185,7 @@ class DownloadSnapshot < Ec2Script
|
|
158
185
|
def wait_some_time
|
159
186
|
@context[:script].post_message("The snapshot can be downloaded during #{@context[:wait_time]} seconds from link: #{get_link()}")
|
160
187
|
sleep(@context[:wait_time])
|
188
|
+
|
161
189
|
DownloadStoppedState.new(@context)
|
162
190
|
end
|
163
191
|
end
|
@@ -165,17 +193,39 @@ class DownloadSnapshot < Ec2Script
|
|
165
193
|
# Snapshot can no longer be downloaded. Shut down the instance.
|
166
194
|
class DownloadStoppedState < DownloadSnapshotState
|
167
195
|
def enter
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
196
|
+
error = []
|
197
|
+
begin
|
198
|
+
shut_down_instance(@context[:instance_id])
|
199
|
+
rescue Exception => e
|
200
|
+
error << e
|
201
|
+
post_message("Unable to shutdown instance '#{@context[:instance_id]}': #{e.to_s}")
|
202
|
+
end
|
203
|
+
#XXX: delete Security Group according to its name
|
204
|
+
if @context[:security_group_name].eql?(Ec2Script::CS_SEC_GRP_NAME)
|
205
|
+
begin
|
206
|
+
delete_security_group(@context[:security_group_name])
|
207
|
+
rescue Exception => e
|
208
|
+
error << e
|
209
|
+
post_message("Unable to delete Security Group '#{@context[:security_group_name]}': #{e.to_s}")
|
210
|
+
end
|
211
|
+
end
|
212
|
+
begin
|
213
|
+
delete_volume(@context[:source_volume_id])
|
214
|
+
rescue Exception => e
|
215
|
+
error << e
|
216
|
+
post_message("Unable to delete volume '#{@context[:source_volume_id]}': #{e.to_s}")
|
217
|
+
end
|
218
|
+
begin
|
219
|
+
delete_volume(@context[:dest_volume_id])
|
220
|
+
rescue Exception => e
|
221
|
+
error << e
|
222
|
+
post_message("Unable to delete volume '#{@context[:dest_volume_id]}': #{e.to_s}")
|
223
|
+
end
|
224
|
+
|
225
|
+
if error.size() > 0
|
226
|
+
raise Exception.new("Cleanup error(s)")
|
227
|
+
end
|
173
228
|
|
174
|
-
# Instance is shut down. Delete the volume created.
|
175
|
-
class InstanceShutDown < DownloadSnapshotState
|
176
|
-
def enter
|
177
|
-
delete_volume(@context[:source_volume_id])
|
178
|
-
delete_volume(@context[:dest_volume_id])
|
179
229
|
Done.new(@context)
|
180
230
|
end
|
181
231
|
end
|