CloudyScripts 2.14.58 → 2.14.60
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 +14 -0
- data/lib/help/remote_command_handler.rb +18 -2
- data/lib/help/script_execution_state.rb +4 -0
- data/lib/help/state_transition_helper.rb +65 -12
- data/lib/scripts/ec2/copy_ami.rb +46 -10
- data/lib/scripts/ec2/copy_mswindows_ami.rb +6 -3
- data/lib/scripts/ec2/copy_mswindows_snapshot.rb +4 -4
- data/lib/scripts/ec2/copy_snapshot.rb +5 -4
- metadata +5 -4
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.60' #<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
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#
|
2
|
+
# Function that can be used in the whole library
|
3
|
+
#
|
4
|
+
|
5
|
+
|
6
|
+
# Check if string is not more than 255 character and contains wide char
|
7
|
+
def check_string_alnum(str)
|
8
|
+
if str.match(/^[0-9a-z\-\_\ ]{1,255}$/i)
|
9
|
+
return true
|
10
|
+
else
|
11
|
+
return false
|
12
|
+
end
|
13
|
+
return true
|
14
|
+
end
|
@@ -69,13 +69,29 @@ class RemoteCommandHandler
|
|
69
69
|
get_output("uname -r").strip
|
70
70
|
end
|
71
71
|
|
72
|
+
# Return all the partitions of a device
|
73
|
+
def get_device_partition(device)
|
74
|
+
get_output("ls #{device}*").strip
|
75
|
+
end
|
76
|
+
|
77
|
+
# Get the partition table of a device
|
78
|
+
def get_partition_table(device)
|
79
|
+
get_output("sfdisk -d #{device}")
|
80
|
+
end
|
81
|
+
|
82
|
+
# GSet the partition table of a device
|
83
|
+
def set_partition_table(device, partition_table)
|
84
|
+
push_data = "\"" + partition_table.gsub(/\/dev\/(s|xv)d[a-z]/, "#{device}") + "\""
|
85
|
+
remote_execute("sfdisk -f #{device}", push_data, nil)
|
86
|
+
end
|
87
|
+
|
72
88
|
# Get root partition label
|
73
89
|
def get_root_device()
|
74
90
|
#get_output("cat /etc/mtab | grep -E '[[:blank:]]+\/[[:blank:]]+' | cut -d ' ' -f 1").strip
|
75
91
|
get_output("mount | grep -E '[[:blank:]]+\/[[:blank:]]+' | cut -d ' ' -f 1").strip
|
76
92
|
end
|
77
93
|
|
78
|
-
# Get partition
|
94
|
+
# Get the device of a specific partition
|
79
95
|
def get_partition_device(part)
|
80
96
|
#get_output("cat /etc/mtab | grep -E '[[:blank:]]+" + "#{part}" + "[[:blank:]]+' | cut -d ' ' -f 1").strip
|
81
97
|
get_output("mount | grep -E '[[:blank:]]+" + "#{part}" + "[[:blank:]]+' | cut -d ' ' -f 1").strip
|
@@ -351,7 +367,7 @@ class RemoteCommandHandler
|
|
351
367
|
|
352
368
|
def upload(ip, user, key_data, local_file, destination_file, timeout = 60)
|
353
369
|
Timeout::timeout(timeout) {
|
354
|
-
Net::SCP.start(ip, user, {:key_data => [key_data], :timeout => timeout}) do |scp|
|
370
|
+
Net::SCP.start(ip, user, {:key_data => [key_data], :timeout => timeout, :paranoid => false, :verbose => :warn}) do |scp|
|
355
371
|
scp.upload!(local_file, destination_file)
|
356
372
|
end
|
357
373
|
}
|
@@ -535,7 +535,7 @@ module StateTransitionHelper
|
|
535
535
|
# * image_id => ID of the AMI created and registered
|
536
536
|
def register_snapshot(snapshot_id, name, root_device_name, description, kernel_id, ramdisk_id, architecture)
|
537
537
|
post_message("going to register snapshot #{snapshot_id}...")
|
538
|
-
@logger.debug "register snapshot #{snapshot_id} as #{name} using AKI '#{kernel_id}' ARI '#{ramdisk_id}'
|
538
|
+
@logger.debug "register snapshot #{snapshot_id} as #{name} using AKI '#{kernel_id}', ARI '#{ramdisk_id}', arch '#{architecture}' and RootDevice '#{root_device_name}'"
|
539
539
|
res = ec2_handler().register_image_updated(:snapshot_id => snapshot_id,
|
540
540
|
:kernel_id => kernel_id, :architecture => architecture,
|
541
541
|
:root_device_name => root_device_name,
|
@@ -705,6 +705,70 @@ module StateTransitionHelper
|
|
705
705
|
post_message("#{msg}")
|
706
706
|
end
|
707
707
|
|
708
|
+
# Get partition count
|
709
|
+
def get_partition_count(device)
|
710
|
+
post_message("Checking partition on device '#{device}'...")
|
711
|
+
#XXX: detect new kernel that have /dev/xvdX device node instead of /dev/sdX
|
712
|
+
if device =~ /\/dev\/sd[a-z]/
|
713
|
+
if !remote_handler().file_exists?(device)
|
714
|
+
post_message("'#{device}' device node not found, checking for new kernel support...")
|
715
|
+
@logger.debug "'#{device}' device node not found, checking for new kernel support"
|
716
|
+
new_device = device.gsub('sd', 'xvd')
|
717
|
+
if remote_handler().file_exists?(new_device)
|
718
|
+
post_message("'#{new_device}' device node found")
|
719
|
+
@logger.debug "'#{new_device}' device node found"
|
720
|
+
device = new_device
|
721
|
+
end
|
722
|
+
end
|
723
|
+
end
|
724
|
+
parts = remote_handler().get_device_partition(device).split(/[[:space:]]+/)
|
725
|
+
@logger.debug "Found '#{parts}' on device '#{device}'"
|
726
|
+
return parts.size()
|
727
|
+
end
|
728
|
+
|
729
|
+
# Get partition table
|
730
|
+
def get_partition_table(device)
|
731
|
+
post_message("Retrieving the partition table of device '#{device}'...")
|
732
|
+
#XXX: detect new kernel that have /dev/xvdX device node instead of /dev/sdX
|
733
|
+
if device =~ /\/dev\/sd[a-z]/
|
734
|
+
if !remote_handler().file_exists?(device)
|
735
|
+
post_message("'#{device}' device node not found, checking for new kernel support...")
|
736
|
+
@logger.debug "'#{device}' device node not found, checking for new kernel support"
|
737
|
+
new_device = device.gsub('sd', 'xvd')
|
738
|
+
if remote_handler().file_exists?(new_device)
|
739
|
+
post_message("'#{new_device}' device node found")
|
740
|
+
@logger.debug "'#{new_device}' device node found"
|
741
|
+
device = new_device
|
742
|
+
end
|
743
|
+
end
|
744
|
+
end
|
745
|
+
partition_table = remote_handler().get_partition_table(device)
|
746
|
+
# remove ^M char
|
747
|
+
partition_table.gsub!("\015", "")
|
748
|
+
@logger.debug "Found the following partition table on device '#{device}'\n#{partition_table}"
|
749
|
+
return partition_table
|
750
|
+
end
|
751
|
+
|
752
|
+
# Set partition table
|
753
|
+
def set_partition_table(device, partition_table)
|
754
|
+
post_message("Setting the partition table of device '#{device}'...")
|
755
|
+
#XXX: detect new kernel that have /dev/xvdX device node instead of /dev/sdX
|
756
|
+
if device =~ /\/dev\/sd[a-z]/
|
757
|
+
if !remote_handler().file_exists?(device)
|
758
|
+
post_message("'#{device}' device node not found, checking for new kernel support...")
|
759
|
+
@logger.debug "'#{device}' device node not found, checking for new kernel support"
|
760
|
+
new_device = device.gsub('sd', 'xvd')
|
761
|
+
if remote_handler().file_exists?(new_device)
|
762
|
+
post_message("'#{new_device}' device node found")
|
763
|
+
@logger.debug "'#{new_device}' device node found"
|
764
|
+
device = new_device
|
765
|
+
end
|
766
|
+
end
|
767
|
+
end
|
768
|
+
remote_handler().set_partition_table(device, partition_table.gsub(/\/dev\/(s|xv)d[a-z]/, "#{device}"))
|
769
|
+
@logger.debug "Partition table set on device '#{device}'"
|
770
|
+
end
|
771
|
+
|
708
772
|
# Get root partition
|
709
773
|
def get_root_device_name()
|
710
774
|
post_message("Retrieving '/' root device name...")
|
@@ -1296,18 +1360,7 @@ module StateTransitionHelper
|
|
1296
1360
|
return region
|
1297
1361
|
end
|
1298
1362
|
|
1299
|
-
# Check if string is not more than 255 character and contains wide char
|
1300
|
-
def check_string_alnum(str)
|
1301
|
-
if str.match(/^[0-9a-z\-\_\ ]{1,255}$/i)
|
1302
|
-
return 0
|
1303
|
-
else
|
1304
|
-
return 1
|
1305
|
-
end
|
1306
|
-
return 1
|
1307
|
-
end
|
1308
|
-
|
1309
1363
|
#setting/retrieving handlers
|
1310
|
-
|
1311
1364
|
def remote_handler()
|
1312
1365
|
if @remote_handler == nil
|
1313
1366
|
if @context[:remote_command_handler] == nil
|
data/lib/scripts/ec2/copy_ami.rb
CHANGED
@@ -4,6 +4,8 @@ require "help/remote_command_handler"
|
|
4
4
|
require "help/dm_crypt_helper"
|
5
5
|
require "help/ec2_helper"
|
6
6
|
require "AWS"
|
7
|
+
require "help/helper"
|
8
|
+
|
7
9
|
|
8
10
|
# Copy a given snapshot to another region
|
9
11
|
# * start up instance in source-region, create a snapshot from the mounted EBS
|
@@ -65,8 +67,8 @@ class CopyAmi < Ec2Script
|
|
65
67
|
if @input_params[:target_ssh_username] == nil
|
66
68
|
@input_params[:target_ssh_username] = "root"
|
67
69
|
end
|
68
|
-
if @input_params[:description] == nil || check_string_alnum(@input_params[:description])
|
69
|
-
@input_params[:description] = "Created by
|
70
|
+
if @input_params[:description] == nil || !check_string_alnum(@input_params[:description])
|
71
|
+
@input_params[:description] = "Created by CloudyScripts - #{self.class.name}"
|
70
72
|
end
|
71
73
|
end
|
72
74
|
|
@@ -107,10 +109,11 @@ class CopyAmi < Ec2Script
|
|
107
109
|
end
|
108
110
|
end
|
109
111
|
|
110
|
-
|
112
|
+
# Source is started. Create a snapshot on the volume that is linked to the instance.
|
111
113
|
class SourceInstanceLaunchedState < CopyAmiState
|
112
114
|
def enter()
|
113
|
-
@context[:snapshot_id] = create_snapshot(@context[:ebs_volume_id],
|
115
|
+
@context[:snapshot_id] = create_snapshot(@context[:ebs_volume_id],
|
116
|
+
"Created by CloudyScripts - #{self.get_superclass_name()} from #{@context[:ebs_volume_id]}")
|
114
117
|
AmiSnapshotCreatedState.new(@context)
|
115
118
|
end
|
116
119
|
end
|
@@ -132,13 +135,31 @@ class CopyAmi < Ec2Script
|
|
132
135
|
os_letter = root_device_name.split('/')[2].gsub('sd', '').gsub('xvd', '').gsub(/[0-9]/, '')
|
133
136
|
aws_device_letter = device.split('/')[2].gsub('sd', '').gsub('xvd', '').gsub(/[0-9]/, '')
|
134
137
|
if !aws_letter.eql?(os_letter)
|
135
|
-
post_message("Detected specific kernel with shift between AWS and Kernel OS for device naming")
|
138
|
+
post_message("Detected specific kernel with shift between AWS and Kernel OS for device naming: '#{aws_root_device}' vs '#{root_device_name}'")
|
136
139
|
end
|
137
140
|
while !aws_letter.eql?(os_letter)
|
138
141
|
aws_letter.succ!
|
139
142
|
aws_device_letter.succ!
|
140
143
|
end
|
141
|
-
|
144
|
+
|
145
|
+
device = "/dev/sd#{aws_device_letter}"
|
146
|
+
# detect root partition vs root volume: simply check if we have several /dev/sdx* entries
|
147
|
+
parts_count = get_partition_count(device)
|
148
|
+
if parts_count >= 2
|
149
|
+
# retrieve partition table, in order to restore it in the target region
|
150
|
+
post_message("Detected specific volume with a valid partition table on device '#{device}'...")
|
151
|
+
partition_table = get_partition_table(device)
|
152
|
+
@context[:partition_table] = partition_table
|
153
|
+
#XXX: HANDLE at a LOWER LEVEL
|
154
|
+
# update partition table with device
|
155
|
+
# s/device/@context[:temp_device_name]/ on partition table
|
156
|
+
#@context[:partition_table] = partition_table.gsub("#{device}", "#{@context[:temp_device_name]}")
|
157
|
+
# retrieve the root partition number
|
158
|
+
os_nb = root_device_name.split('/')[2].gsub('sd', '').gsub('xvd', '').gsub(/[a-z]/, '')
|
159
|
+
device = device + os_nb
|
160
|
+
@context[:root_partition_nb] = os_nb
|
161
|
+
post_message("Using root partition: '#{device}'...")
|
162
|
+
end
|
142
163
|
post_message("Using AWS name '#{@context[:temp_device_name]}' and OS name '#{device}'")
|
143
164
|
mount_fs(mount_point, device)
|
144
165
|
# get root partition label and filesystem type
|
@@ -176,6 +197,17 @@ class CopyAmi < Ec2Script
|
|
176
197
|
mount_point = "/mnt/tmp_#{@context[:target_volume_id]}"
|
177
198
|
attach_volume(@context[:target_volume_id], @context[:target_instance_id], device)
|
178
199
|
connect(@context[:target_dns_name], @context[:target_ssh_username], nil, @context[:target_ssh_keydata])
|
200
|
+
# check if we need to create a partition table
|
201
|
+
if !(@context[:partition_table] == nil)
|
202
|
+
post_message("Creating a partition table on device '#{device}'...")
|
203
|
+
set_partition_table(device, @context[:partition_table])
|
204
|
+
#XXX: HANDLE at a LOWER LEVEL
|
205
|
+
# before adding partition table, adjust device name
|
206
|
+
#set_partition_table(device, @context[:partition_table].gsub(/\/dev\/(s|xv)d[a-z]/, "#{@context[:temp_device_name]}"))
|
207
|
+
# adjust partition to mount
|
208
|
+
device = device + @context[:root_partition_nb]
|
209
|
+
end
|
210
|
+
# make root partition
|
179
211
|
create_labeled_fs(@context[:target_dns_name], device, @context[:fs_type], @context[:label])
|
180
212
|
mount_fs(mount_point, device)
|
181
213
|
disconnect()
|
@@ -233,8 +265,8 @@ class CopyAmi < Ec2Script
|
|
233
265
|
class DataCopiedState < CopyAmiState
|
234
266
|
def enter()
|
235
267
|
remote_region()
|
236
|
-
|
237
|
-
|
268
|
+
@context[:new_snapshot_id] = create_snapshot(@context[:target_volume_id],
|
269
|
+
"Created by CloudyScripts - #{self.get_superclass_name()} from #{@context[:target_volume_id]}")
|
238
270
|
TargetSnapshotCreatedState.new(@context)
|
239
271
|
end
|
240
272
|
end
|
@@ -246,9 +278,13 @@ class CopyAmi < Ec2Script
|
|
246
278
|
# Get Amazon Kernel Image ID
|
247
279
|
aki = get_aws_kernel_image_aki(@context[:source_availability_zone], @context[:kernel_id],
|
248
280
|
@context[:target_availability_zone])
|
281
|
+
device = @context[:root_device_name]
|
282
|
+
if !(@context[:partition_table] == nil)
|
283
|
+
device.gsub!(/[0-9]/, '')
|
284
|
+
post_message("Using BlockDevice for snapshot registration rather than RootDevice '#{device}' due to a valid partition table on device...")
|
285
|
+
end
|
249
286
|
@context[:result][:image_id] = register_snapshot(@context[:new_snapshot_id], @context[:name],
|
250
|
-
@context[:
|
251
|
-
nil, @context[:architecture])
|
287
|
+
device, @context[:description], aki, nil, @context[:architecture])
|
252
288
|
AmiRegisteredState.new(@context)
|
253
289
|
end
|
254
290
|
end
|
@@ -4,6 +4,8 @@ require "help/remote_command_handler"
|
|
4
4
|
require "help/dm_crypt_helper"
|
5
5
|
require "help/ec2_helper"
|
6
6
|
require "AWS"
|
7
|
+
require "help/helper"
|
8
|
+
|
7
9
|
|
8
10
|
# Copy a given snapshot to another region
|
9
11
|
# * start up instance in source-region, create a snapshot from the mounted EBS
|
@@ -102,8 +104,8 @@ class CopyMsWindowsAmi < Ec2Script
|
|
102
104
|
if @input_params[:fs_type] == nil
|
103
105
|
@input_params[:fs_type] = "ext3"
|
104
106
|
end
|
105
|
-
if @input_params[:description] == nil || check_string_alnum(@input_params[:description])
|
106
|
-
@input_params[:description] = "Created by
|
107
|
+
if @input_params[:description] == nil || !check_string_alnum(@input_params[:description])
|
108
|
+
@input_params[:description] = "Created by CloudyScripts - #{self.class.name}"
|
107
109
|
end
|
108
110
|
end
|
109
111
|
|
@@ -173,7 +175,8 @@ class CopyMsWindowsAmi < Ec2Script
|
|
173
175
|
stop_instance(instance_id)
|
174
176
|
post_message("Instance '#{instance_id}' stopped, creating snapshot")
|
175
177
|
ebs_volume_id = ec2_helper.get_attached_volumes(instance_id)[0]['volumeId']
|
176
|
-
@context[:snapshot_id] = create_snapshot(ebs_volume_id,
|
178
|
+
@context[:snapshot_id] = create_snapshot(ebs_volume_id,
|
179
|
+
"Created by CloudyScripts - #{self.class.name} from #{ebs_volume_id}")
|
177
180
|
|
178
181
|
InitialStateDone.new(@context)
|
179
182
|
end
|
@@ -4,7 +4,8 @@ require "help/remote_command_handler"
|
|
4
4
|
require "help/dm_crypt_helper"
|
5
5
|
require "help/ec2_helper"
|
6
6
|
require "AWS"
|
7
|
-
|
7
|
+
require "help/helper"
|
8
|
+
|
8
9
|
|
9
10
|
# Copy a given snapshot to another region
|
10
11
|
# * start up instance in source-region, create a snapshot from the mounted EBS
|
@@ -83,8 +84,8 @@ class CopyMsWindowsSnapshot < Ec2Script
|
|
83
84
|
if @input_params[:fs_type] == nil
|
84
85
|
@input_params[:fs_type] = "ext3"
|
85
86
|
end
|
86
|
-
if @input_params[:description] == nil || check_string_alnum(@input_params[:description])
|
87
|
-
@input_params[:description] = "Created by
|
87
|
+
if @input_params[:description] == nil || !check_string_alnum(@input_params[:description])
|
88
|
+
@input_params[:description] = "Created by CloudyScripts - #{self.class.name}"
|
88
89
|
end
|
89
90
|
if @input_params[:compression] != nil && (@input_params[:compression] =~ /^on$/i)
|
90
91
|
@input_params[:compression] = true
|
@@ -376,7 +377,6 @@ class CopyMsWindowsSnapshot < Ec2Script
|
|
376
377
|
def enter()
|
377
378
|
remote_region()
|
378
379
|
detach_volume(@context[:target_volume_id], @context[:target_instance_id])
|
379
|
-
#@context[:new_snapshot_id] = create_snapshot(@context[:target_volume_id], "Created by CloudyScripts - copy_mswindows_ami")
|
380
380
|
@context[:new_snapshot_id] = create_snapshot(@context[:target_volume_id], @context[:description])
|
381
381
|
@context[:result][:snapshot_id] = @context[:new_snapshot_id]
|
382
382
|
|
@@ -4,6 +4,8 @@ require "help/remote_command_handler"
|
|
4
4
|
require "help/dm_crypt_helper"
|
5
5
|
require "help/ec2_helper"
|
6
6
|
require "AWS"
|
7
|
+
require "help/helper"
|
8
|
+
|
7
9
|
|
8
10
|
# Copy a given snapshot to another region
|
9
11
|
# * start up instance in source-region, create volume from snapshot, attach volume, and mount it
|
@@ -49,8 +51,8 @@ class CopySnapshot< Ec2Script
|
|
49
51
|
if @input_params[:target_ssh_username] == nil
|
50
52
|
@input_params[:target_ssh_username] = "root"
|
51
53
|
end
|
52
|
-
if @input_params[:description] == nil || check_string_alnum(@input_params[:description])
|
53
|
-
@input_params[:description] = "Created by
|
54
|
+
if @input_params[:description] == nil || !check_string_alnum(@input_params[:description])
|
55
|
+
@input_params[:description] = "Created by CloudyScripts - #{self.class.name}"
|
54
56
|
end
|
55
57
|
end
|
56
58
|
|
@@ -194,8 +196,7 @@ class CopySnapshot< Ec2Script
|
|
194
196
|
class DataCopiedState < CopySnapshotState
|
195
197
|
def enter()
|
196
198
|
remote_region()
|
197
|
-
|
198
|
-
@context[:new_snapshot_id] = create_snapshot(@context[:target_volume_id], @context[:description])
|
199
|
+
@context[:new_snapshot_id] = create_snapshot(@context[:target_volume_id], @context[:description])
|
199
200
|
@context[:result][:snapshot_id] = @context[:new_snapshot_id]
|
200
201
|
SnapshotCreatedState.new(@context)
|
201
202
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: CloudyScripts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 79
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 14
|
9
|
-
-
|
10
|
-
version: 2.14.
|
9
|
+
- 60
|
10
|
+
version: 2.14.60
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Matthias Jung
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-07-
|
18
|
+
date: 2012-07-26 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -274,6 +274,7 @@ files:
|
|
274
274
|
- lib/help/v_cloud_transition_helper.rb
|
275
275
|
- lib/help/v_cloud_api_handler.rb
|
276
276
|
- lib/help/remote_command_handler.rb
|
277
|
+
- lib/help/helper.rb
|
277
278
|
- lib/help/state_change_listener.rb
|
278
279
|
- lib/cloudyscripts.rb
|
279
280
|
has_rdoc: true
|