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 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