CloudyScripts 2.14.60 → 2.14.62
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.
- 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
|