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 CHANGED
@@ -13,7 +13,7 @@ require 'rake/testtask'
13
13
  spec = Gem::Specification.new do |s|
14
14
  s.name = 'CloudyScripts'
15
15
  #s.version = '2.14.54' #<number cloud-stacks supported>.<number cloud-scripts>.<counting releases>
16
- s.version = '2.14.60' #<number cloud-stacks supported>.<number cloud-scripts>.<counting releases>
16
+ s.version = '2.14.62' #<number cloud-stacks supported>.<number cloud-scripts>.<counting releases>
17
17
  s.has_rdoc = true
18
18
  s.extra_rdoc_files = ['README.rdoc', 'LICENSE']
19
19
  s.summary = 'Scripts to facilitate programming for infrastructure clouds.'
@@ -12,3 +12,26 @@ def check_string_alnum(str)
12
12
  end
13
13
  return true
14
14
  end
15
+
16
+ # API Reference (API Version 2012-07-20):
17
+ # http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RegisterImage.html
18
+ # Check name for AWS AMI registration
19
+ # Constraints: 3-128 alphanumeric characters, parenthesis (()), commas (,), slashes (/), dashes (-), or underscores(_)
20
+ def check_aws_name(str)
21
+ if str.match(/^[0-9a-z\-\_\(\)\/\,]{1,128}$/i)
22
+ return true
23
+ else
24
+ return false
25
+ end
26
+ return true
27
+ end
28
+
29
+ # Check description for AWS AMI registration
30
+ # Constraints: Up to 255 characters
31
+ def check_aws_desc(str)
32
+ if str.size <= 255
33
+ return true
34
+ else
35
+ return false
36
+ end
37
+ end
@@ -78,8 +78,13 @@ module StateTransitionHelper
78
78
  end
79
79
  os = remote_handler().retrieve_os()
80
80
  sudo = remote_handler().use_sudo ? " [sudo]" : ""
81
+ if os =~ /^Please login as .+$/i
82
+ post_message("not connected to #{dns_name}#{sudo} due to an invalid user.")
83
+ @logger.error "not connected to #{dns_name}#{sudo} due to an invalid user."
84
+ raise Exception.new("invalid user: #{os}")
85
+ end
81
86
  post_message("connected to #{dns_name}#{sudo}. OS installed is #{os}")
82
- @logger.info "connected to #{dns_name}#{sudo}"
87
+ @logger.info "connected to #{dns_name}#{sudo} OS installed is #{os}"
83
88
  return os
84
89
  end
85
90
 
@@ -558,6 +563,39 @@ module StateTransitionHelper
558
563
  return image_id
559
564
  end
560
565
 
566
+ def create_security_group_with_rules(name, desc, rules)
567
+ post_message("going to create '#{name}' Security Group...")
568
+ @logger.debug "create Security Group (name: #{name}, desc: #{desc})"
569
+ begin
570
+ res = ec2_handler().describe_security_groups(:group_name => name)
571
+ if res['securityGroupInfo']['item'].size > 0
572
+ @logger.warn "'#{name}' Security Group found. Another Security Group already exists with the same name. Deleting it first."
573
+ res = ec2_handler().delete_security_group(:group_name => name)
574
+ end
575
+ rescue AWS::InvalidGroupNotFound => e
576
+ @logger.debug "'#{name}' Security Group not found."
577
+ end
578
+ res = ec2_handler().create_security_group(:group_name => name, :group_description => desc)
579
+ rules.each(){ |rule|
580
+ ec2_handler().authorize_security_group_ingress(:group_name => name,
581
+ :ip_protocol => rule[:ip_protocol], :from_port => rule[:from_port], :to_port => rule[:to_port], :cidr_ip => rule[:cidr_ip])
582
+ }
583
+ return true
584
+ end
585
+
586
+ def delete_security_group(name)
587
+ post_message("going to delete '#{name}' Security Group...")
588
+ @logger.debug "delete Security Group (name: #{name})"
589
+ res = ec2_handler().describe_security_groups(:group_name => name)
590
+ if res['securityGroupInfo']['item'].size > 0
591
+ @logger.debug "'#{name}' Security Group found."
592
+ res = ec2_handler().delete_security_group(:group_name => name)
593
+ else
594
+ @logger.warn "'#{name}' Security Group not found."
595
+ end
596
+ return true
597
+ end
598
+
561
599
  # Create a file-system on a given machine (assumes to be connected already).
562
600
  # Input Parameters:
563
601
  # * dns_name => IP used
@@ -699,7 +737,7 @@ module StateTransitionHelper
699
737
  @logger.error "#{msg}"
700
738
  raise Exception.new("#{mount_point} still mounted")
701
739
  else
702
- msg = "#{mount_point} successfully mounted"
740
+ msg = "#{mount_point} successfully unmounted"
703
741
  @logger.info "#{msg}"
704
742
  end
705
743
  post_message("#{msg}")
@@ -1204,8 +1242,11 @@ module StateTransitionHelper
1204
1242
  'aki-b4aa75dd' => 'pv-grub-hd00_1.03-x86_64',
1205
1243
 
1206
1244
  #RHEL kernel Amazon Kernel ID
1207
- 'aki-36ed075f' => 'aki-rhel-i386',
1208
- 'aki-08ed0761' => 'aki-rhel-x86_64'
1245
+ 'aki-36ed075f' => 'aki-rhel-i386', # RH-pv-grub-hd0-V1.01-i386
1246
+ 'aki-08ed0761' => 'aki-rhel-x86_64', # RH-pv-grub-hd0-V1.01-x86_64
1247
+
1248
+ #Ubuntu kernel Amazon Kernel ID
1249
+ 'aki-5f15f636' => 'aki-ubuntu-karmic-v2.6.31-302.i386'
1209
1250
  },
1210
1251
  'us-west-1' => {'aki-9da0f1d8' => 'pv-grub-hd00-V1.01-i386',
1211
1252
  'aki-9fa0f1da' => 'pv-grub-hd00-V1.01-x86_64',
@@ -1221,8 +1262,11 @@ module StateTransitionHelper
1221
1262
  'aki-eb7e26ae' => 'pv-grub-hd00_1.03-x86_64',
1222
1263
 
1223
1264
  #RHEL kernel Amazon Kernel ID:
1224
- 'aki-772c7f32' => 'aki-rhel-i386', # RH-pv-grub-hd0-V1.01-i386
1225
- 'aki-712c7f34' => 'aki-rhel-x86_64' # RH-pv-grub-hd0-V1.01-x86_64
1265
+ 'aki-772c7f32' => 'aki-rhel-i386', # RH-pv-grub-hd0-V1.01-i386
1266
+ 'aki-712c7f34' => 'aki-rhel-x86_64', # RH-pv-grub-hd0-V1.01-x86_64
1267
+
1268
+ #Ubuntu kernel Amazon Kernel ID
1269
+ 'aki-773c6d32' => 'aki-ubuntu-karmic-v2.6.31-302.i386'
1226
1270
  },
1227
1271
  'us-west-2' => {'aki-dee26fee' => 'pv-grub-hd00-V1.01-i386',
1228
1272
  'aki-90e26fa0' => 'pv-grub-hd00-V1.01-x86_64',
@@ -1238,8 +1282,11 @@ module StateTransitionHelper
1238
1282
  'aki-f837bac8' => 'pv-grub-hd00_1.03-x86_64',
1239
1283
 
1240
1284
  #RHEL kernel Amazon Kernel ID
1241
- 'aki-2efa771e' => 'aki-rhel-i386',
1242
- 'aki-10fa7720' => 'aki-rhel-x86_64'
1285
+ 'aki-2efa771e' => 'aki-rhel-i386', # RH-pv-grub-hd0-V1.01-i386
1286
+ 'aki-10fa7720' => 'aki-rhel-x86_64', # RH-pv-grub-hd0-V1.01-x86_64
1287
+
1288
+ #Ubuntu kernel Amazon Kernel ID
1289
+ '' => 'aki-ubuntu-karmic-v2.6.31-302.i386'
1243
1290
  },
1244
1291
  'eu-west-1' => {'aki-47eec433' => 'pv-grub-hd00-V1.01-i386',
1245
1292
  'aki-41eec435' => 'pv-grub-hd00-V1.01-x86_64',
@@ -1255,8 +1302,11 @@ module StateTransitionHelper
1255
1302
  'aki-8b655dff' => 'pv-grub-hd00_1.03-x86_64',
1256
1303
 
1257
1304
  #RHEL kernel Amazon Kernel ID
1258
- 'aki-af0a3ddb' => 'aki-rhel-i386',
1259
- 'aki-a90a3ddd' => 'aki-rhel-x86_64'
1305
+ 'aki-af0a3ddb' => 'aki-rhel-i386', # RH-pv-grub-hd0-V1.01-i386
1306
+ 'aki-a90a3ddd' => 'aki-rhel-x86_64', # RH-pv-grub-hd0-V1.01-x86_64
1307
+
1308
+ #Ubuntu kernel Amazon Kernel ID
1309
+ 'aki-b02a01c4' => 'aki-ubuntu-karmic-v2.6.31-302.i386'
1260
1310
  },
1261
1311
  'ap-southeast-1' => {'aki-6fd5aa3d' => 'pv-grub-hd00-V1.01-i386',
1262
1312
  'aki-6dd5aa3f' => 'pv-grub-hd00-V1.01-x86_64',
@@ -1272,8 +1322,11 @@ module StateTransitionHelper
1272
1322
  'aki-fa1354a8' => 'pv-grub-hd00_1.03-x86_64',
1273
1323
 
1274
1324
  #RHEL kernel Amazon Kernel ID
1275
- 'aki-9c235ace' => 'aki-rhel-i386',
1276
- 'aki-82235ad0' => 'aki-rhel-x86_64'
1325
+ 'aki-9c235ace' => 'aki-rhel-i386', # RH-pv-grub-hd0-V1.01-i386
1326
+ 'aki-82235ad0' => 'aki-rhel-x86_64', # RH-pv-grub-hd0-V1.01-x86_64
1327
+
1328
+ #Ubuntu kernel Amazon Kernel ID
1329
+ 'aki-87f38cd5' => 'aki-ubuntu-karmic-v2.6.31-302.i386'
1277
1330
  },
1278
1331
  'ap-northeast-1' => {'aki-d209a2d3' => 'pv-grub-hd00-V1.01-i386',
1279
1332
  'aki-d409a2d5' => 'pv-grub-hd00-V1.01-x86_64',
@@ -1289,8 +1342,11 @@ module StateTransitionHelper
1289
1342
  'aki-40992841' => 'pv-grub-hd00_1.03-x86_64',
1290
1343
 
1291
1344
  #RHEL kernel Amazon Kernel ID
1292
- 'aki-66c06a67' => 'aki-rhel-i386',
1293
- 'aki-68c06a69' => 'aki-rhel-x86_64'
1345
+ 'aki-66c06a67' => 'aki-rhel-i386', # RH-pv-grub-hd0-V1.01-i386
1346
+ 'aki-68c06a69' => 'aki-rhel-x86_64', # RH-pv-grub-hd0-V1.01-x86_64
1347
+
1348
+ #Ubuntu kernel Amazon Kernel ID
1349
+ 'aki-540fa455' => 'aki-ubuntu-karmic-v2.6.31-302.i386'
1294
1350
  },
1295
1351
  'sa-east-1' => {'aki-803ce39d' => 'pv-grub-hd00-V1.01-i386',
1296
1352
  'aki-d03ce3cd' => 'pv-grub-hd00-V1.01-x86_64',
@@ -1306,8 +1362,11 @@ module StateTransitionHelper
1306
1362
  'aki-c88f51d5' => 'pv-grub-hd00_1.03-x86_64',
1307
1363
 
1308
1364
  #RHEL kernel Amazon Kernel ID
1309
- 'aki-1a38e707' => 'aki-rhel-i386',
1310
- 'aki-1438e709' => 'aki-rhel-x86_64'
1365
+ 'aki-1a38e707' => 'aki-rhel-i386', # RH-pv-grub-hd0-V1.01-i386
1366
+ 'aki-1438e709' => 'aki-rhel-x86_64', # RH-pv-grub-hd0-V1.01-x86_64
1367
+
1368
+ #Ubuntu kernel Amazon Kernel ID
1369
+ '' => 'aki-ubuntu-karmic-v2.6.31-302.i386'
1311
1370
  }
1312
1371
  }
1313
1372
  target_aki = ''
@@ -43,7 +43,6 @@ class Ami2EbsConversion < Ec2Script
43
43
  end
44
44
  if @input_params[:name] == nil
45
45
  @input_params[:name] = "Boot EBS (for AMI #{@input_params[:ami_id]}) at #{Time.now.strftime('%d/%m/%Y %H.%M.%S')}"
46
- else
47
46
  end
48
47
  if @input_params[:description] == nil
49
48
  @input_params[:description] = @input_params[:name]
@@ -111,6 +110,7 @@ class Ami2EbsConversion < Ec2Script
111
110
  # Storage attached. Create a file-system and mount it
112
111
  class StorageAttached < Ami2EbsConversionState
113
112
  def enter
113
+ #TODO: Fix connect to use username even if ssh_keyfile is specified or do not specify it
114
114
  @context[:result][:os] =
115
115
  connect(@context[:dns_name], @context[:ssh_username],
116
116
  @context[:ssh_keyfile], @context[:ssh_keydata],
@@ -48,12 +48,24 @@ class CopyAmi < Ec2Script
48
48
  raise Exception.new("must be an EBS type image")
49
49
  end
50
50
  local_ec2_helper = ec2_helper
51
- if !local_ec2_helper.check_open_port('default', 22)
52
- raise Exception.new("Port 22 must be opened for security group 'default' to connect via SSH in source-region")
51
+ if @input_params[:source_security_group] == nil
52
+ @input_params[:source_security_group] = "default"
53
+ end
54
+ if !local_ec2_helper.check_open_port(@input_params[:source_security_group], 22)
55
+ post_message("'#{@input_params[:source_security_group]}' Security Group not opened port 22 for connect via SSH in source region")
56
+ @input_params[:source_security_group] = nil
57
+ else
58
+ post_message("'#{@input_params[:source_security_group]}' Security Group opened port 22 for connect via SSH in source region")
53
59
  end
54
60
  remote_ec2_helper = Ec2Helper.new(@input_params[:target_ec2_handler])
55
- if !remote_ec2_helper.check_open_port('default', 22)
56
- raise Exception.new("Port 22 must be opened for security group 'default' to connect via SSH in target-region")
61
+ if @input_params[:target_security_group] == nil
62
+ @input_params[:target_security_group] = "default"
63
+ end
64
+ if !remote_ec2_helper.check_open_port(@input_params[:target_security_group], 22)
65
+ post_message("'#{@input_params[:target_security_group]}' Security Group not opened port 22 for connect via SSH in target region")
66
+ @input_params[:target_security_group] = nil
67
+ else
68
+ post_message("'#{@input_params[:target_security_group]}' Security Group opened port 22 for connect via SSH in target region")
57
69
  end
58
70
  if @input_params[:root_device_name] == nil
59
71
  @input_params[:root_device_name] = "/dev/sda1"
@@ -67,9 +79,12 @@ class CopyAmi < Ec2Script
67
79
  if @input_params[:target_ssh_username] == nil
68
80
  @input_params[:target_ssh_username] = "root"
69
81
  end
70
- if @input_params[:description] == nil || !check_string_alnum(@input_params[:description])
82
+ if @input_params[:description] == nil || !check_aws_desc(@input_params[:description])
71
83
  @input_params[:description] = "Created by CloudyScripts - #{self.class.name}"
72
84
  end
85
+ if @input_params[:name] == nil || !check_aws_name(@input_params[:name])
86
+ @input_params[:name] = "Created_by_CloudyScripts/#{self.class.name}_from_#{@input_params[:ami_id]}"
87
+ end
73
88
  end
74
89
 
75
90
  # Load the initial state for the script.
@@ -99,12 +114,21 @@ class CopyAmi < Ec2Script
99
114
  # Initial state: start up AMI in source region
100
115
  class InitialState < CopyAmiState
101
116
  def enter()
117
+ local_region()
118
+ #XXX: create a CloudyScripts Security Group with TCP port 22 publicly opened
119
+ if @context[:source_security_group] == nil
120
+ @context[:source_security_group] = Ec2Script::CS_SEC_GRP_NAME
121
+ create_security_group_with_rules(@context[:source_security_group], Ec2Script::CS_SEC_GRP_DESC,
122
+ [{:ip_protocol => "tcp", :from_port => 22, :to_port => 22, :cidr_ip => "0.0.0.0/0"}])
123
+ post_message("'#{@context[:source_security_group]}' Security Group created with TCP port 22 publicly opened.")
124
+ end
125
+
102
126
  @context[:source_instance_id], @context[:source_dns_name], @context[:source_availability_zone],
103
127
  @context[:kernel_id], @context[:ramdisk_id], @context[:architecture], @context[:root_device_name] =
104
- launch_instance(@context[:ami_id], @context[:source_key_name], "default")
128
+ launch_instance(@context[:ami_id], @context[:source_key_name], @context[:source_security_group])
105
129
  ec2_helper = Ec2Helper.new(@context[:ec2_api_handler])
106
- puts "get_attached returns: #{ec2_helper.get_attached_volumes(@context[:source_instance_id]).inspect}"
107
- @context[:ebs_volume_id] = ec2_helper.get_attached_volumes(@context[:source_instance_id])[0]['volumeId']#TODO: what when more root devices?
130
+ @context[:ebs_volume_id] = ec2_helper.get_attached_volumes(@context[:source_instance_id])[0]['volumeId'] #TODO: what when more root devices?
131
+
108
132
  SourceInstanceLaunchedState.new(@context)
109
133
  end
110
134
  end
@@ -114,6 +138,7 @@ class CopyAmi < Ec2Script
114
138
  def enter()
115
139
  @context[:snapshot_id] = create_snapshot(@context[:ebs_volume_id],
116
140
  "Created by CloudyScripts - #{self.get_superclass_name()} from #{@context[:ebs_volume_id]}")
141
+
117
142
  AmiSnapshotCreatedState.new(@context)
118
143
  end
119
144
  end
@@ -167,6 +192,7 @@ class CopyAmi < Ec2Script
167
192
  #@context[:fs_type] = get_root_partition_fs_type()
168
193
  @context[:fs_type], @context[:label] = get_root_partition_fs_type_and_label()
169
194
  disconnect()
195
+
170
196
  SourceVolumeReadyState.new(@context)
171
197
  end
172
198
  end
@@ -175,11 +201,19 @@ class CopyAmi < Ec2Script
175
201
  class SourceVolumeReadyState < CopyAmiState
176
202
  def enter()
177
203
  remote_region()
178
- result = launch_instance(@context[:target_ami_id], @context[:target_key_name],
179
- "default")
204
+ #XXX: create a CloudyScripts Security Group with TCP port 22 publicly opened
205
+ if @context[:target_security_group] == nil
206
+ @context[:target_security_group] = Ec2Script::CS_SEC_GRP_NAME
207
+ create_security_group_with_rules(@context[:target_security_group], Ec2Script::CS_SEC_GRP_DESC,
208
+ [{:ip_protocol => "tcp", :from_port => 22, :to_port => 22, :cidr_ip => "0.0.0.0/0"}])
209
+ post_message("'#{@context[:target_security_group]}' Security Group created with TCP port 22 publicly opened.")
210
+ end
211
+
212
+ result = launch_instance(@context[:target_ami_id], @context[:target_key_name], @context[:target_security_group])
180
213
  @context[:target_instance_id] = result.first
181
214
  @context[:target_dns_name] = result[1]
182
215
  @context[:target_availability_zone] = result[2]
216
+
183
217
  TargetInstanceLaunchedState.new(@context)
184
218
  end
185
219
  end
@@ -211,6 +245,7 @@ class CopyAmi < Ec2Script
211
245
  create_labeled_fs(@context[:target_dns_name], device, @context[:fs_type], @context[:label])
212
246
  mount_fs(mount_point, device)
213
247
  disconnect()
248
+
214
249
  TargetVolumeReadyState.new(@context)
215
250
  end
216
251
  end
@@ -229,8 +264,8 @@ class CopyAmi < Ec2Script
229
264
  # @context[:target_ssh_keyfile], "#{key_path}#{@context[:target_key_name]}.pem")
230
265
  upload_file(@context[:source_dns_name], @context[:source_ssh_username], @context[:source_ssh_keydata],
231
266
  @context[:target_ssh_keyfile], "#{key_path}#{@context[:target_key_name].gsub(/\s+/, '_')}.pem")
232
-
233
267
  post_message("credentials are in place to connect source and target.")
268
+
234
269
  KeyInPlaceState.new(@context)
235
270
  end
236
271
  end
@@ -256,6 +291,7 @@ class CopyAmi < Ec2Script
256
291
  enable_ssh_tty(@context[:target_dns_name])
257
292
  unmount_fs(dest_dir)
258
293
  disconnect()
294
+
259
295
  DataCopiedState.new(@context)
260
296
  end
261
297
  end
@@ -267,6 +303,7 @@ class CopyAmi < Ec2Script
267
303
  remote_region()
268
304
  @context[:new_snapshot_id] = create_snapshot(@context[:target_volume_id],
269
305
  "Created by CloudyScripts - #{self.get_superclass_name()} from #{@context[:target_volume_id]}")
306
+
270
307
  TargetSnapshotCreatedState.new(@context)
271
308
  end
272
309
  end
@@ -285,29 +322,73 @@ class CopyAmi < Ec2Script
285
322
  end
286
323
  @context[:result][:image_id] = register_snapshot(@context[:new_snapshot_id], @context[:name],
287
324
  device, @context[:description], aki, nil, @context[:architecture])
325
+
288
326
  AmiRegisteredState.new(@context)
289
327
  end
290
328
  end
291
329
 
292
330
  # AMI is registered. Now only cleanup is missing, i.e. shut down instances and
293
331
  # remote the volumes that were created. Start with cleaning the ressources
294
- # in the local region.
332
+ # in the both regions.
295
333
  class AmiRegisteredState < CopyAmiState
296
334
  def enter()
335
+ error = []
297
336
  local_region()
298
- shut_down_instance(@context[:source_instance_id])
299
- delete_volume(@context[:source_volume_id])
300
- delete_snapshot(@context[:snapshot_id])
301
- SourceCleanedUpState.new(@context)
302
- end
303
- end
304
-
305
- # Cleanup the resources in the target region.
306
- class SourceCleanedUpState < CopyAmiState
307
- def enter()
337
+ begin
338
+ shut_down_instance(@context[:source_instance_id])
339
+ rescue Exception => e
340
+ error << e
341
+ post_message("Unable to shutdown instance '#{@context[:source_instance_id]}' in source region: #{e.to_s}")
342
+ end
343
+ begin
344
+ delete_volume(@context[:source_volume_id])
345
+ rescue Exception => e
346
+ error << e
347
+ post_message("Unable to delete volume '#{@context[:source_volume_id]}' in source region: #{e.to_s}")
348
+ end
349
+ begin
350
+ delete_snapshot(@context[:snapshot_id])
351
+ rescue Exception => e
352
+ error << e
353
+ post_message("Unable to delete snapshot '#{@context[:snapshot_id]}' in source region: #{e.to_s}")
354
+ end
355
+ #XXX: delete Security Group according to its name
356
+ if @context[:source_security_group].eql?(Ec2Script::CS_SEC_GRP_NAME)
357
+ begin
358
+ delete_security_group(@context[:source_security_group])
359
+ rescue Exception => e
360
+ error << e
361
+ post_message("Unable to delete Security Group '#{@context[:source_security_group]}' in source region: #{e.to_s}")
362
+ end
363
+ end
364
+ #
308
365
  remote_region()
309
- shut_down_instance(@context[:target_instance_id])
310
- delete_volume(@context[:target_volume_id])
366
+ begin
367
+ shut_down_instance(@context[:target_instance_id])
368
+ rescue Exception => e
369
+ error << e
370
+ post_message("Unable to shutdown instance '#{@context[:target_instance_id]}' in target region: #{e.to_s}")
371
+ end
372
+ begin
373
+ delete_volume(@context[:target_volume_id])
374
+ rescue Exception => e
375
+ error << e
376
+ post_message("Unable to delete volume '#{@context[:target_volume_id]}' in target region: #{e.to_s}")
377
+ end
378
+ #XXX: delete Security Group according to its name
379
+ if @context[:target_security_group].eql?(Ec2Script::CS_SEC_GRP_NAME)
380
+ begin
381
+ delete_security_group(@context[:target_security_group])
382
+ rescue
383
+ error << e
384
+ post_message("Unable to delete Security Group '#{@context[:target_security_group]}' in target region: #{e.to_s}")
385
+ end
386
+ end
387
+
388
+ if error.size() > 0
389
+ raise Exception.new("Cleanup error(s)")
390
+ end
391
+
311
392
  Done.new(@context)
312
393
  end
313
394
  end
@@ -69,17 +69,25 @@ class CopyMsWindowsAmi < Ec2Script
69
69
  raise Exception.new("Invalid target AMI ID specified: #{@input_params[:target_ami_id]}")
70
70
  end
71
71
  # AWS SecurityGroup, source and target regions
72
- if @input_params[:source_security_groups] == nil
73
- @input_params[:source_security_groups] = "default"
74
- end
75
- if !@local_ec2_helper.check_open_port(@input_params[:source_security_groups], 22)
76
- raise Exception.new("Port 22 must be opened for security group '#{@input_params[:source_security_groups]}' to connect via SSH in source-region")
77
- end
78
- if @input_params[:target_security_groups] == nil
79
- @input_params[:target_security_groups] = "default"
80
- end
81
- if !@remote_ec2_helper.check_open_port(@input_params[:target_security_groups], 22)
82
- raise Exception.new("Port 22 must be opened for security group '#{@input_params[:target_security_groups]}' to connect via SSH in target-region")
72
+ if @input_params[:source_security_group] == nil
73
+ @input_params[:source_security_group] = "default"
74
+ end
75
+ if !@local_ec2_helper.check_open_port(@input_params[:source_security_group], 22)
76
+ #raise Exception.new("Port 22 must be opened for security group '#{@input_params[:source_security_group]}' to connect via SSH in source region")
77
+ post_message("'#{@input_params[:source_security_group]}' Security Group not opened port 22 for connect via SSH in source region")
78
+ @input_params[:source_security_group] = nil
79
+ else
80
+ post_message("'#{@input_params[:source_security_group]}' Security Group opened port 22 for connect via SSH in source region")
81
+ end
82
+ if @input_params[:target_security_group] == nil
83
+ @input_params[:target_security_group] = "default"
84
+ end
85
+ if !@remote_ec2_helper.check_open_port(@input_params[:target_security_group], 22)
86
+ #raise Exception.new("Port 22 must be opened for security group '#{@input_params[:target_security_group]}' to connect via SSH in target region")
87
+ post_message("'#{@input_params[:target_security_group]}' Security Group not opened port 22 for connect via SSH in target region")
88
+ @input_params[:target_security_group] = nil
89
+ else
90
+ post_message("'#{@input_params[:target_security_group]}' Security Group opened port 22 for connect via SSH in target region")
83
91
  end
84
92
  # Device to use for volume
85
93
  if @input_params[:root_device_name] == nil
@@ -104,9 +112,12 @@ class CopyMsWindowsAmi < Ec2Script
104
112
  if @input_params[:fs_type] == nil
105
113
  @input_params[:fs_type] = "ext3"
106
114
  end
107
- if @input_params[:description] == nil || !check_string_alnum(@input_params[:description])
115
+ if @input_params[:description] == nil || !check_aws_desc(@input_params[:description])
108
116
  @input_params[:description] = "Created by CloudyScripts - #{self.class.name}"
109
117
  end
118
+ if @input_params[:name] == nil || !check_aws_name(@input_params[:name])
119
+ @input_params[:name] = "Created_by_CloudyScripts/#{self.class.name}_from_#{@input_params[:ami_id]}"
120
+ end
110
121
  end
111
122
 
112
123
  # Load the initial state for the script.
@@ -122,7 +133,6 @@ class CopyMsWindowsAmi < Ec2Script
122
133
 
123
134
  def self.load_state(context)
124
135
  InitialState.new(context)
125
-
126
136
  end
127
137
 
128
138
  def local_region
@@ -145,7 +155,7 @@ class CopyMsWindowsAmi < Ec2Script
145
155
  #NB: if we do not own this AMI, we have no snapshot, so we must launch an instance
146
156
  class InitialState < CopyMsWindowsAmiState
147
157
  def enter()
148
- post_message("Retrieving AMI parammeters (snapshot ID, volume size, architecture)...")
158
+ post_message("Retrieving AMI parameters (snapshot ID, volume size, architecture)...")
149
159
  local_region()
150
160
  @context[:snapshot_id] = @local_ec2_helper.ami_blkdevmap_ebs_prop(@context[:ami_id], 'snapshotId')
151
161
  @context[:volume_size] = @local_ec2_helper.ami_blkdevmap_ebs_prop(@context[:ami_id], 'volumeSize')
@@ -167,7 +177,15 @@ class CopyMsWindowsAmi < Ec2Script
167
177
  def enter()
168
178
  post_message("Launching and stopping an instance of the AMI to create a snapshot")
169
179
  local_region()
170
- result = launch_instance(@context[:ami_id], @context[:source_key_name], @context[:source_security_groups])
180
+ #XXX: create a CloudyScripts Security Group with TCP port 22 publicly opened
181
+ if @context[:source_security_group] == nil
182
+ @context[:source_security_group] = Ec2Script::CS_SEC_GRP_NAME
183
+ create_security_group_with_rules(@context[:source_security_group], Ec2Script::CS_SEC_GRP_DESC,
184
+ [{:ip_protocol => "tcp", :from_port => 22, :to_port => 22, :cidr_ip => "0.0.0.0/0"}])
185
+ post_message("'#{@context[:source_security_group]}' Security Group created with TCP port 22 publicly opened.")
186
+ end
187
+
188
+ result = launch_instance(@context[:ami_id], @context[:source_key_name], @context[:source_security_group])
171
189
  instance_id = result.first
172
190
  post_message("Instance launched with ID: #{instance_id}")
173
191
  post_message("Waiting 3 minutes before stopping instance '#{instance_id}' for creating a Snapshot of the rootDevice")
@@ -187,7 +205,15 @@ class CopyMsWindowsAmi < Ec2Script
187
205
  def enter()
188
206
  post_message("Launching an Helper instance in the source Region...")
189
207
  local_region()
190
- result = launch_instance(@context[:source_ami_id], @context[:source_key_name], @context[:source_security_groups])
208
+ #XXX: create a CloudyScripts Security Group with TCP port 22 publicly opened
209
+ if @context[:source_security_group] == nil
210
+ @context[:source_security_group] = Ec2Script::CS_SEC_GRP_NAME
211
+ create_security_group_with_rules(@context[:source_security_group], Ec2Script::CS_SEC_GRP_DESC,
212
+ [{:ip_protocol => "tcp", :from_port => 22, :to_port => 22, :cidr_ip => "0.0.0.0/0"}])
213
+ post_message("'#{@context[:source_security_group]}' Security Group created with TCP port 22 publicly opened.")
214
+ end
215
+
216
+ result = launch_instance(@context[:source_ami_id], @context[:source_key_name], @context[:source_security_group])
191
217
  @context[:source_instance_id] = result.first
192
218
  @context[:source_dns_name] = result[1]
193
219
  @context[:source_availability_zone] = result[2]
@@ -273,7 +299,15 @@ class CopyMsWindowsAmi < Ec2Script
273
299
  class BackupedDataState < CopyMsWindowsAmiState
274
300
  def enter()
275
301
  remote_region()
276
- result = launch_instance(@context[:target_ami_id], @context[:target_key_name], @context[:target_security_groups])
302
+ #XXX: create a CloudyScripts Security Group with TCP port 22 publicly opened
303
+ if @context[:target_security_group] == nil
304
+ @context[:target_security_group] = Ec2Script::CS_SEC_GRP_NAME
305
+ create_security_group_with_rules(@context[:target_security_group], Ec2Script::CS_SEC_GRP_DESC,
306
+ [{:ip_protocol => "tcp", :from_port => 22, :to_port => 22, :cidr_ip => "0.0.0.0/0"}])
307
+ post_message("'#{@context[:target_security_group]}' Security Group created with TCP port 22 publicly opened.")
308
+ end
309
+
310
+ result = launch_instance(@context[:target_ami_id], @context[:target_key_name], @context[:target_security_group])
277
311
  @context[:target_instance_id] = result.first
278
312
  @context[:target_dns_name] = result[1]
279
313
  @context[:target_availability_zone] = result[2]
@@ -422,7 +456,7 @@ class CopyMsWindowsAmi < Ec2Script
422
456
  post_message("Launching Helper AMI '#{@context[:helper_ami_id]}' for attaching migrated volume...")
423
457
  remote_region()
424
458
  #XXX: launch instance in the right AZ
425
- result = launch_instance(@context[:helper_ami_id], @context[:target_key_name], @context[:target_security_groups],
459
+ result = launch_instance(@context[:helper_ami_id], @context[:target_key_name], @context[:target_security_group],
426
460
  nil, nil, @context[:target_availability_zone])
427
461
  @context[:helper_instance_id] = result.first
428
462
  @context[:helper_dns_name] = result[1]
@@ -481,6 +515,11 @@ class CopyMsWindowsAmi < Ec2Script
481
515
  shut_down_instance(@context[:source_instance_id])
482
516
  delete_volume(@context[:source_temp_volume_id])
483
517
  delete_volume(@context[:source_volume_id])
518
+ #XXX: delete Security Group according to its name
519
+ if @context[:source_security_group].eql?(Ec2Script::CS_SEC_GRP_NAME)
520
+ delete_security_group(@context[:source_security_group])
521
+ end
522
+
484
523
  #
485
524
  remote_region()
486
525
  connect(@context[:target_dns_name], @context[:target_ssh_username], nil, @context[:target_ssh_keydata])
@@ -491,6 +530,10 @@ class CopyMsWindowsAmi < Ec2Script
491
530
  shut_down_instance(@context[:target_instance_id])
492
531
  delete_volume(@context[:target_temp_volume_id])
493
532
  #delete_volume(@context[:target_volume_id])
533
+ #XXX: delete Security Group according to its name
534
+ if @context[:target_security_group].eql?(Ec2Script::CS_SEC_GRP_NAME)
535
+ delete_security_group(@context[:target_security_group])
536
+ end
494
537
 
495
538
  Done.new(@context)
496
539
  end