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
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.
|
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.'
|
data/lib/help/helper.rb
CHANGED
@@ -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
|
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',
|
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],
|
data/lib/scripts/ec2/copy_ami.rb
CHANGED
@@ -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
|
52
|
-
|
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
|
56
|
-
|
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 || !
|
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],
|
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
|
-
|
107
|
-
|
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
|
-
|
179
|
-
|
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
|
332
|
+
# in the both regions.
|
295
333
|
class AmiRegisteredState < CopyAmiState
|
296
334
|
def enter()
|
335
|
+
error = []
|
297
336
|
local_region()
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
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
|
-
|
310
|
-
|
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[:
|
73
|
-
@input_params[:
|
74
|
-
end
|
75
|
-
if !@local_ec2_helper.check_open_port(@input_params[:
|
76
|
-
raise Exception.new("Port 22 must be opened for security group '#{@input_params[:
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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 || !
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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[:
|
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
|