CloudyScripts 1.4.15 → 1.5.16
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 +2 -1
- data/lib/help/ec2_helper.rb +23 -1
- data/lib/help/remote_command_handler.rb +2 -2
- data/lib/help/state_transition_helper.rb +29 -2
- data/lib/scripts/ec2/ami2_ebs_conversion.rb +5 -16
- data/lib/scripts/ec2/copy_ami.rb +222 -0
- data/lib/scripts/ec2/copy_snapshot.rb +13 -5
- data/lib/scripts/ec2/dm_encrypt.rb +5 -1
- data/lib/scripts/ec2/download_snapshot.rb +5 -1
- data/lib/scripts/ec2/ec2_script.rb +2 -0
- metadata +17 -4
data/Rakefile
CHANGED
@@ -12,7 +12,7 @@ require 'rake/testtask'
|
|
12
12
|
|
13
13
|
spec = Gem::Specification.new do |s|
|
14
14
|
s.name = 'CloudyScripts'
|
15
|
-
s.version = '1.
|
15
|
+
s.version = '1.5.16'
|
16
16
|
s.has_rdoc = true
|
17
17
|
s.extra_rdoc_files = ['README.rdoc', 'LICENSE']
|
18
18
|
s.summary = 'Scripts to facilitate programming for infrastructure clouds.'
|
@@ -28,6 +28,7 @@ spec = Gem::Specification.new do |s|
|
|
28
28
|
s.has_rdoc = true
|
29
29
|
s.add_dependency("amazon-ec2")
|
30
30
|
s.add_dependency("net-ssh")
|
31
|
+
s.add_dependency("net-scp")
|
31
32
|
end
|
32
33
|
|
33
34
|
Rake::GemPackageTask.new(spec) do |p|
|
data/lib/help/ec2_helper.rb
CHANGED
@@ -52,6 +52,28 @@ class Ec2Helper
|
|
52
52
|
return false
|
53
53
|
end
|
54
54
|
|
55
|
+
def get_attached_volumes(instance_id)
|
56
|
+
instances = @ec2_api.describe_instances(:instance_id => instance_id)
|
57
|
+
begin
|
58
|
+
if instances['reservationSet']['item'][0]['instancesSet']['item'].size == 0
|
59
|
+
raise Exception.new("instance #{instance_id} not found")
|
60
|
+
end
|
61
|
+
puts "instances = #{instances.inspect}"
|
62
|
+
puts "attachments: #{instances['reservationSet']['item'][0]['instancesSet']['item'][0]['blockDeviceMapping']['item'].inspect}"
|
63
|
+
attached = instances['reservationSet']['item'][0]['instancesSet']['item'][0]['blockDeviceMapping']['item'].collect() { |item|
|
64
|
+
#
|
65
|
+
puts "item = #{item['ebs'].inspect}"
|
66
|
+
item['ebs']
|
67
|
+
}
|
68
|
+
puts "going to return #{attached.size.to_s}"
|
69
|
+
return attached
|
70
|
+
rescue Exception => e
|
71
|
+
puts "exception: #{e.inspect}"
|
72
|
+
puts e.backtrace.join("\n")
|
73
|
+
raise Exception.new("error during retrieving attachments from instance #{instance_id} not found")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
55
77
|
def volume_prop(volume_id, prop)
|
56
78
|
vols = @ec2_api.describe_volumes(:volume_id => volume_id)
|
57
79
|
if vols['volumeSet']['item'].size == 0
|
@@ -90,7 +112,7 @@ class Ec2Helper
|
|
90
112
|
if instances['reservationSet']['item'][0]['instancesSet']['item'].size == 0
|
91
113
|
raise Exception.new("instance #{instance_id} not found")
|
92
114
|
end
|
93
|
-
return instances['reservationSet']['item'][0]['instancesSet']['item'][prop.to_s]
|
115
|
+
return instances['reservationSet']['item'][0]['instancesSet']['item'][0][prop.to_s]
|
94
116
|
rescue
|
95
117
|
raise Exception.new("instance #{instance_id} not found")
|
96
118
|
end
|
@@ -14,8 +14,8 @@ class RemoteCommandHandler
|
|
14
14
|
# Params:
|
15
15
|
# * ip: ip address of the machine to connect to
|
16
16
|
# * keyfile: path of the keyfile to be used for authentication
|
17
|
-
def connect_with_keyfile(ip, keyfile, timeout = 30)
|
18
|
-
@ssh_session = Net::SSH.start(ip,
|
17
|
+
def connect_with_keyfile(ip, user_name, keyfile, timeout = 30)
|
18
|
+
@ssh_session = Net::SSH.start(ip, user_name, {:keys => [keyfile], :timeout => timeout})
|
19
19
|
end
|
20
20
|
|
21
21
|
# Connect to the machine as root using keydata from a keyfile.
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'net/scp'
|
2
|
+
require "AWS"
|
2
3
|
|
3
4
|
# Contains methods that are used by the scripts in the state-machines. Since
|
4
5
|
# they are reused by different scripts, they are factored into this module.
|
@@ -10,16 +11,33 @@ require 'net/scp'
|
|
10
11
|
# * :remote_command_handler => ssh wrapper object
|
11
12
|
# * :ec2_api_handler => wrapper object around EC2 API access
|
12
13
|
|
14
|
+
class AWS::EC2::Base
|
15
|
+
def register_image_updated(options)
|
16
|
+
puts "register_iamge_updated: #{options.inspect}"
|
17
|
+
params = {}
|
18
|
+
params["Name"] = options[:name].to_s
|
19
|
+
params["BlockDeviceMapping.1.Ebs.SnapshotId"] = options[:snapshot_id].to_s
|
20
|
+
params["BlockDeviceMapping.1.DeviceName"] = options[:root_device_name].to_s
|
21
|
+
params["Description"] = options[:description].to_s
|
22
|
+
params["KernelId"] = options[:kernel_id].to_s unless options[:kernel_id] == nil
|
23
|
+
params["RamdiskId"] = options[:ramdisk_id].to_s unless options[:ramdisk_id] == nil
|
24
|
+
params["Architecture"] = options[:architecture].to_s
|
25
|
+
params["RootDeviceName"] = options[:root_device_name].to_s
|
26
|
+
return response_generator(:action => "RegisterImage", :params => params)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
13
30
|
module StateTransitionHelper
|
14
31
|
|
15
32
|
# Connects to the remote host via SSH.
|
16
33
|
# Params:
|
17
34
|
# * dns_name => machine to connect to
|
35
|
+
# * user_name => name to be used for connection
|
18
36
|
# * ssh_keyfile => key-file used for ssh
|
19
37
|
# * ssh_keydata => contents of key-file (either use ssh_keyfile or ssh_keydata)
|
20
38
|
# Returns:
|
21
39
|
# * OS of the connected machine
|
22
|
-
def connect(dns_name, ssh_keyfile = nil, ssh_keydata = nil)
|
40
|
+
def connect(dns_name, user_name, ssh_keyfile = nil, ssh_keydata = nil)
|
23
41
|
post_message("connecting to #{dns_name}...")
|
24
42
|
connected = false
|
25
43
|
last_connection_problem = ""
|
@@ -39,7 +57,7 @@ module StateTransitionHelper
|
|
39
57
|
elsif ssh_keydata != nil
|
40
58
|
begin
|
41
59
|
@logger.info("connecting using keydata")
|
42
|
-
remote_handler().connect(dns_name,
|
60
|
+
remote_handler().connect(dns_name, user_name, ssh_keydata)
|
43
61
|
connected = true
|
44
62
|
rescue Exception => e
|
45
63
|
@logger.info("connection failed due to #{e}")
|
@@ -290,6 +308,15 @@ module StateTransitionHelper
|
|
290
308
|
return snapshot_id
|
291
309
|
end
|
292
310
|
|
311
|
+
# Deletes a snapshot.
|
312
|
+
def delete_snapshot(snapshot_id)
|
313
|
+
post_message("going to delete snapshot #{snapshot_id}...")
|
314
|
+
@logger.info("going to delete snapshot #{snapshot_id}...")
|
315
|
+
ec2_handler().delete_snapshot(:snapshot_id => snapshot_id)
|
316
|
+
@logger.info("snapshot #{snapshot_id} deleted")
|
317
|
+
post_message("snapshot #{snapshot_id} deleted")
|
318
|
+
end
|
319
|
+
|
293
320
|
# Registers a snapshot as EBS-booted AMI.
|
294
321
|
# Input Parameters:
|
295
322
|
# * snapshot_id => EC2 Snapshot ID used to be used
|
@@ -4,21 +4,6 @@ require "help/remote_command_handler"
|
|
4
4
|
#require "help/dm_crypt_helper"
|
5
5
|
require "AWS"
|
6
6
|
|
7
|
-
class AWS::EC2::Base
|
8
|
-
def register_image_updated(options)
|
9
|
-
params = {}
|
10
|
-
params["Name"] = options[:name].to_s
|
11
|
-
params["BlockDeviceMapping.1.Ebs.SnapshotId"] = options[:snapshot_id].to_s
|
12
|
-
params["BlockDeviceMapping.1.DeviceName"] = options[:root_device_name].to_s
|
13
|
-
params["Description"] = options[:description].to_s
|
14
|
-
params["KernelId"] = options[:kernel_id].to_s
|
15
|
-
params["RamdiskId"] = options[:ramdisk_id].to_s
|
16
|
-
params["Architecture"] = options[:architecture].to_s
|
17
|
-
params["RootDeviceName"] = options[:root_device_name].to_s
|
18
|
-
return response_generator(:action => "RegisterImage", :params => params)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
7
|
# Creates a bootable EBS storage from an existing AMI.
|
23
8
|
#
|
24
9
|
|
@@ -28,6 +13,7 @@ class Ami2EbsConversion < Ec2Script
|
|
28
13
|
# * aws_secret_key => the Amazon AWS Secret Key
|
29
14
|
# * ami_id => the ID of the AMI to be converted
|
30
15
|
# * security_group_name => name of the security group to start
|
16
|
+
# * ssh_username => name of the ssh-user (default = root)
|
31
17
|
# * ssh_key_data => Key information for the security group that starts the AMI [if not set, use ssh_key_files]
|
32
18
|
# * ssh_key_files => Key information for the security group that starts the AMI
|
33
19
|
# * remote_command_handler => object that allows to connect via ssh and execute commands (optional)
|
@@ -55,6 +41,9 @@ class Ami2EbsConversion < Ec2Script
|
|
55
41
|
if @input_params[:root_device_name] == nil
|
56
42
|
@input_params[:root_device_name] = "/dev/sda1"
|
57
43
|
end
|
44
|
+
if @input_params[:ssh_username] == nil
|
45
|
+
@input_params[:ssh_username] = "root"
|
46
|
+
end
|
58
47
|
end
|
59
48
|
|
60
49
|
def load_initial_state()
|
@@ -103,7 +92,7 @@ class Ami2EbsConversion < Ec2Script
|
|
103
92
|
class StorageAttached < Ami2EbsConversionState
|
104
93
|
def enter
|
105
94
|
@context[:result][:os] =
|
106
|
-
connect(@context[:dns_name], @context[:ssh_keyfile], @context[:ssh_keydata])
|
95
|
+
connect(@context[:dns_name], @context[:ssh_username], @context[:ssh_keyfile], @context[:ssh_keydata])
|
107
96
|
create_fs(@context[:dns_name], @context[:temp_device_name])
|
108
97
|
FileSystemCreated.new(@context)
|
109
98
|
end
|
@@ -0,0 +1,222 @@
|
|
1
|
+
require "help/script_execution_state"
|
2
|
+
require "scripts/ec2/ec2_script"
|
3
|
+
require "help/remote_command_handler"
|
4
|
+
require "help/dm_crypt_helper"
|
5
|
+
require "help/ec2_helper"
|
6
|
+
require "AWS"
|
7
|
+
|
8
|
+
# Copy a given snapshot to another region
|
9
|
+
# * start up instance in source-region, create a snapshot from the mounted EBS
|
10
|
+
# * then create volume from snapshot, attach volume, and mount it
|
11
|
+
# * start up instance in destination-region, create empty volume of same size, attache volume, and mount it
|
12
|
+
# * copy the destination key to the source instance
|
13
|
+
# * perform an rsynch
|
14
|
+
# sync -PHAXaz --rsh "ssh -i /home/${src_user}/.ssh/id_${dst_keypair}" --rsync-path "sudo rsync" ${src_dir}/ ${dst_user}@${dst_public_fqdn}:${dst_dir}/
|
15
|
+
# * create a snapshot of the volume
|
16
|
+
# * register the snapshot as AMI
|
17
|
+
# * clean-up everything
|
18
|
+
|
19
|
+
class CopyAmi < Ec2Script
|
20
|
+
# context information needed
|
21
|
+
# * the EC2 credentials (see #Ec2Script)
|
22
|
+
# * ami_id => the ID of the AMI to be copied in another region
|
23
|
+
# * target_ec2_handler => The EC2 handler connected to the region where the snapshot is being copied to
|
24
|
+
# * source_ssh_username => The username for ssh for source-instance (default = root)
|
25
|
+
# * source_key_name => Key name of the instance that manages the snaphot-volume in the source region
|
26
|
+
# * source_ssh_key_data => Key information for the security group that starts the AMI [if not set, use ssh_key_files]
|
27
|
+
# * source_ssh_key_files => Key information for the security group that starts the AMI
|
28
|
+
# * target_ssh_username => The username for ssh for target-instance (default = root)
|
29
|
+
# * target_key_name => Key name of the instance that manages the snaphot-volume in the target region
|
30
|
+
# * target_ssh_key_data => Key information for the security group that starts the AMI [if not set, use ssh_key_files]
|
31
|
+
# * target_ssh_key_files => Key information for the security group that starts the AMI
|
32
|
+
# * target_ami_id => ID of the AMI to start in the target region
|
33
|
+
# * name => name of new AMI to be created
|
34
|
+
# * description => description of new AMI to be created
|
35
|
+
|
36
|
+
def initialize(input_params)
|
37
|
+
super(input_params)
|
38
|
+
end
|
39
|
+
|
40
|
+
def check_input_parameters()
|
41
|
+
ec2_helper = Ec2Helper.new(@input_params[:ec2_api_handler])
|
42
|
+
if ec2_helper.ami_prop(@input_params[:ami_id], 'rootDeviceType') != "ebs"
|
43
|
+
raise Exception.new("must be an EBS type image")
|
44
|
+
end
|
45
|
+
if @input_params[:root_device_name] == nil
|
46
|
+
@input_params[:root_device_name] = "/dev/sda1"
|
47
|
+
end
|
48
|
+
if @input_params[:temp_device_name] == nil
|
49
|
+
@input_params[:temp_device_name] = "/dev/sdj"
|
50
|
+
end
|
51
|
+
if @input_params[:source_ssh_username] == nil
|
52
|
+
@input_params[:source_ssh_username] = "root"
|
53
|
+
end
|
54
|
+
if @input_params[:target_ssh_username] == nil
|
55
|
+
@input_params[:target_ssh_username] = "root"
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
# Load the initial state for the script.
|
61
|
+
# Abstract method to be implemented by extending classes.
|
62
|
+
def load_initial_state()
|
63
|
+
CopyAmiState.load_state(@input_params)
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# Here begins the state machine implementation
|
69
|
+
class CopyAmiState < ScriptExecutionState
|
70
|
+
|
71
|
+
def self.load_state(context)
|
72
|
+
InitialState.new(context)
|
73
|
+
end
|
74
|
+
|
75
|
+
def local_region
|
76
|
+
self.ec2_handler=(@context[:ec2_api_handler])
|
77
|
+
end
|
78
|
+
|
79
|
+
def remote_region
|
80
|
+
self.ec2_handler=(@context[:target_ec2_handler])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Initial state: start up AMI in source region
|
85
|
+
class InitialState < CopyAmiState
|
86
|
+
def enter()
|
87
|
+
@context[:source_instance_id], @context[:source_dns_name], @context[:source_availability_zone],
|
88
|
+
@context[:kernel_id], @context[:ramdisk_id], @context[:architecture] =
|
89
|
+
launch_instance(@context[:ami_id], @context[:source_key_name], "default")
|
90
|
+
ec2_helper = Ec2Helper.new(@context[:ec2_api_handler])
|
91
|
+
puts "get_attached returns: #{ec2_helper.get_attached_volumes(@context[:source_instance_id]).inspect}"
|
92
|
+
@context[:ebs_volume_id] = ec2_helper.get_attached_volumes(@context[:source_instance_id])[0]['volumeId']#TODO: what when more root devices?
|
93
|
+
SourceInstanceLaunchedState.new(@context)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Source is started. Create a snapshot on the volume that is linked to the instance.
|
98
|
+
class SourceInstanceLaunchedState < CopyAmiState
|
99
|
+
def enter()
|
100
|
+
@context[:snapshot_id] = create_snapshot(@context[:ebs_volume_id], "Cloudy_Scripts Snapshot for copying AMIs")
|
101
|
+
AmiSnapshotCreatedState.new(@context)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Snapshot is created from the AMI. Create a volume from the snapshot, attach and mount the volume as second device.
|
106
|
+
class AmiSnapshotCreatedState < CopyAmiState
|
107
|
+
def enter()
|
108
|
+
@context[:source_volume_id] = create_volume_from_snapshot(@context[:snapshot_id],
|
109
|
+
@context[:source_availability_zone])
|
110
|
+
device = @context[:temp_device_name]
|
111
|
+
mount_point = "/mnt/tmp_#{@context[:source_volume_id]}"
|
112
|
+
attach_volume(@context[:source_volume_id], @context[:source_instance_id], device)
|
113
|
+
connect(@context[:source_dns_name], @context[:source_ssh_username], nil, @context[:source_ssh_keydata])
|
114
|
+
mount_fs(mount_point, device)
|
115
|
+
disconnect()
|
116
|
+
SourceVolumeReadyState.new(@context)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Source is ready. Now start instance in the target region
|
121
|
+
class SourceVolumeReadyState < CopyAmiState
|
122
|
+
def enter()
|
123
|
+
remote_region()
|
124
|
+
result = launch_instance(@context[:target_ami_id], @context[:target_key_name],
|
125
|
+
"default")
|
126
|
+
@context[:target_instance_id] = result.first
|
127
|
+
@context[:target_dns_name] = result[1]
|
128
|
+
@context[:target_availability_zone] = result[2]
|
129
|
+
TargetInstanceLaunchedState.new(@context)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Destination instance is started. Now configure storage.
|
134
|
+
class TargetInstanceLaunchedState < CopyAmiState
|
135
|
+
def enter()
|
136
|
+
local_region()
|
137
|
+
ec2_helper = Ec2Helper.new(@context[:ec2_api_handler])
|
138
|
+
volume_size = ec2_helper.snapshot_prop(@context[:snapshot_id], :volumeSize).to_i
|
139
|
+
#
|
140
|
+
remote_region()
|
141
|
+
@context[:target_volume_id] = create_volume(@context[:target_availability_zone], volume_size)
|
142
|
+
device = @context[:temp_device_name]
|
143
|
+
mount_point = "/mnt/tmp_#{@context[:target_volume_id]}"
|
144
|
+
attach_volume(@context[:target_volume_id], @context[:target_instance_id], device)
|
145
|
+
connect(@context[:target_dns_name], @context[:target_ssh_username], nil, @context[:target_ssh_keydata])
|
146
|
+
create_fs(@context[:target_dns_name], device)
|
147
|
+
mount_fs(mount_point, device)
|
148
|
+
disconnect()
|
149
|
+
TargetVolumeReadyState.new(@context)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Storages are ready. Only thing missing: the key of the target region
|
154
|
+
# must be available on the instance in the source region to be able to perform
|
155
|
+
# a remote copy.
|
156
|
+
class TargetVolumeReadyState < CopyAmiState
|
157
|
+
def enter()
|
158
|
+
post_message("upload key of target-instance to source-instance...")
|
159
|
+
upload_file(@context[:source_dns_name], "root", @context[:source_ssh_keydata],
|
160
|
+
@context[:target_ssh_keyfile], "/root/.ssh/#{@context[:target_key_name]}.pem")
|
161
|
+
post_message("credentials are in place to connect source and target.")
|
162
|
+
KeyInPlaceState.new(@context)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# Now we can copy.
|
167
|
+
class KeyInPlaceState < CopyAmiState
|
168
|
+
def enter()
|
169
|
+
connect(@context[:source_dns_name], @context[:source_ssh_username], nil, @context[:source_ssh_keydata])
|
170
|
+
source_dir = "/mnt/tmp_#{@context[:source_volume_id]}/"
|
171
|
+
dest_dir = "/mnt/tmp_#{@context[:target_volume_id]}"
|
172
|
+
remote_copy(@context[:target_key_name], source_dir, @context[:target_dns_name], dest_dir)
|
173
|
+
disconnect()
|
174
|
+
DataCopiedState.new(@context)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# Data of snapshot now copied to the new volume. Create a snapshot of the
|
179
|
+
# new volume.
|
180
|
+
class DataCopiedState < CopyAmiState
|
181
|
+
def enter()
|
182
|
+
remote_region()
|
183
|
+
@context[:new_snapshot_id] = create_snapshot(@context[:target_volume_id], "Created by Cloudy_Scripts - copy_snapshot")
|
184
|
+
TargetSnapshotCreatedState.new(@context)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# Snapshot Operation done. Now this snapshot must be registered as AMI
|
189
|
+
class TargetSnapshotCreatedState < CopyAmiState
|
190
|
+
def enter()
|
191
|
+
remote_region()
|
192
|
+
@context[:result][:image_id] = register_snapshot(@context[:new_snapshot_id], @context[:name],
|
193
|
+
@context[:root_device_name], @context[:description], nil,
|
194
|
+
nil, @context[:architecture])
|
195
|
+
AmiRegisteredState.new(@context)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# AMI is registered. Now only cleanup is missing, i.e. shut down instances and
|
200
|
+
# remote the volumes that were created. Start with cleaning the ressources
|
201
|
+
# in the local region.
|
202
|
+
class AmiRegisteredState < CopyAmiState
|
203
|
+
def enter()
|
204
|
+
local_region()
|
205
|
+
shut_down_instance(@context[:source_instance_id])
|
206
|
+
delete_volume(@context[:source_volume_id])
|
207
|
+
delete_snapshot(@context[:snapshot_id])
|
208
|
+
SourceCleanedUpState.new(@context)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# Cleanup the resources in the target region.
|
213
|
+
class SourceCleanedUpState < CopyAmiState
|
214
|
+
def enter()
|
215
|
+
remote_region()
|
216
|
+
shut_down_instance(@context[:target_instance_id])
|
217
|
+
delete_volume(@context[:target_volume_id])
|
218
|
+
Done.new(@context)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
@@ -19,12 +19,14 @@ class CopySnapshot< Ec2Script
|
|
19
19
|
# * the EC2 credentials (see #Ec2Script)
|
20
20
|
# * snapshot_id => The ID of the snapshot to be downloaded
|
21
21
|
# * target_ec2_handler => The EC2 handler connected to the region where the snapshot is being copied to
|
22
|
+
# * source_ssh_username => user name to connect to the source instance (default = root)
|
22
23
|
# * source_key_name => Key name of the instance that manages the snaphot-volume in the source region
|
23
24
|
# * source_ssh_key_data => Key information for the security group that starts the AMI [if not set, use ssh_key_files]
|
24
|
-
# *
|
25
|
+
# * source_ssh_key_file => Key information for the security group that starts the AMI
|
26
|
+
# * target_ssh_username => user name to connect to the target instance (default = root)
|
25
27
|
# * target_key_name => Key name of the instance that manages the snaphot-volume in the target region
|
26
28
|
# * target_ssh_key_data => Key information for the security group that starts the AMI [if not set, use ssh_key_files]
|
27
|
-
# *
|
29
|
+
# * target_ssh_key_file => Key information for the security group that starts the AMI
|
28
30
|
# * source_ami_id => ID of the AMI to start in the source region
|
29
31
|
# * target_ami_id => ID of the AMI to start in the target region
|
30
32
|
|
@@ -33,6 +35,12 @@ class CopySnapshot< Ec2Script
|
|
33
35
|
end
|
34
36
|
|
35
37
|
def check_input_parameters()
|
38
|
+
if @input_params[:source_ssh_username] == nil
|
39
|
+
@input_params[:source_ssh_username] = "root"
|
40
|
+
end
|
41
|
+
if @input_params[:target_ssh_username] == nil
|
42
|
+
@input_params[:target_ssh_username] = "root"
|
43
|
+
end
|
36
44
|
end
|
37
45
|
|
38
46
|
# Load the initial state for the script.
|
@@ -78,7 +86,7 @@ class CopySnapshot< Ec2Script
|
|
78
86
|
device = "/dev/sdj" #TODO: make device configurable
|
79
87
|
mount_point = "/mnt/tmp_#{@context[:source_volume_id]}"
|
80
88
|
attach_volume(@context[:source_volume_id], @context[:source_instance_id], device)
|
81
|
-
connect(@context[:source_dns_name], nil, @context[:source_ssh_keydata])
|
89
|
+
connect(@context[:source_dns_name], @context[:source_ssh_username], nil, @context[:source_ssh_keydata])
|
82
90
|
mount_fs(mount_point, device)
|
83
91
|
disconnect()
|
84
92
|
SourceVolumeReadyState.new(@context)
|
@@ -110,7 +118,7 @@ class CopySnapshot< Ec2Script
|
|
110
118
|
device = "/dev/sdj" #TODO: make device configurable
|
111
119
|
mount_point = "/mnt/tmp_#{@context[:target_volume_id]}"
|
112
120
|
attach_volume(@context[:target_volume_id], @context[:target_instance_id], device)
|
113
|
-
connect(@context[:target_dns_name], nil, @context[:target_ssh_keydata])
|
121
|
+
connect(@context[:target_dns_name], @context[:target_ssh_username], nil, @context[:target_ssh_keydata])
|
114
122
|
create_fs(@context[:target_dns_name], device)
|
115
123
|
mount_fs(mount_point, device)
|
116
124
|
disconnect()
|
@@ -134,7 +142,7 @@ class CopySnapshot< Ec2Script
|
|
134
142
|
# Now we can copy.
|
135
143
|
class KeyInPlaceState < CopySnapshotState
|
136
144
|
def enter()
|
137
|
-
connect(@context[:source_dns_name], nil, @context[:source_ssh_keydata])
|
145
|
+
connect(@context[:source_dns_name], @context[:source_ssh_username], nil, @context[:source_ssh_keydata])
|
138
146
|
source_dir = "/mnt/tmp_#{@context[:source_volume_id]}/"
|
139
147
|
dest_dir = "/mnt/tmp_#{@context[:target_volume_id]}"
|
140
148
|
remote_copy(@context[:target_key_name], source_dir, @context[:target_dns_name], dest_dir)
|
@@ -16,6 +16,7 @@ class DmEncrypt < Ec2Script
|
|
16
16
|
# * aws_access_key => the Amazon AWS Access Key (see Your Account -> Security Credentials)
|
17
17
|
# * aws_secret_key => the Amazon AWS Secret Key
|
18
18
|
# * ip_address => IP Address of the machine to connect to
|
19
|
+
# * ssh_username => name of the ssh-user (default = root)
|
19
20
|
# * ssh_key_file => Path of the keyfile used to connect to the machine (optional, otherwise: ssh_key_data)
|
20
21
|
# * ssh_key_data => Key information (optional, otherwise: ssh_key_file)
|
21
22
|
# * device => Path of the device to encrypt
|
@@ -42,6 +43,9 @@ class DmEncrypt < Ec2Script
|
|
42
43
|
@input_params[:ec2_api_handler] = AWS::EC2::Base.new(:access_key_id => @input_params[:aws_access_key],
|
43
44
|
:secret_access_key => @input_params[:aws_secret_key], :server => @input_params[:ec2_api_server])
|
44
45
|
end
|
46
|
+
if @input_params[:ssh_username] == nil
|
47
|
+
@input_params[:ssh_username] = "root"
|
48
|
+
end
|
45
49
|
end
|
46
50
|
|
47
51
|
def load_initial_state()
|
@@ -62,7 +66,7 @@ class DmEncrypt < Ec2Script
|
|
62
66
|
class InitialState < DmEncryptState
|
63
67
|
def enter
|
64
68
|
@context[:result][:os] =
|
65
|
-
connect(@context[:dns_name], @context[:ssh_keyfile], @context[:ssh_keydata])
|
69
|
+
connect(@context[:dns_name], @context[:ssh_username], @context[:ssh_keyfile], @context[:ssh_keydata])
|
66
70
|
install_tools()
|
67
71
|
end
|
68
72
|
|
@@ -22,6 +22,7 @@ class DownloadSnapshot < Ec2Script
|
|
22
22
|
# * ami_id: the ID of the AMI to be started to perform the operations and to run the web-server for download
|
23
23
|
# * security_group_name => name of the security group used to start the AMI (should open ports for SSH and HTTP)
|
24
24
|
# * key_name => Name of the key to be used to access the instance providing the download
|
25
|
+
# * ssh_username => name of the ssh-user (default = root)
|
25
26
|
# * ssh_key_data => Key information for the security group that starts the AMI [if not set, use ssh_key_files]
|
26
27
|
# * ssh_key_files => Key information for the security group that starts the AMI
|
27
28
|
# * snapshot_id => The ID of the snapshot to be downloaded
|
@@ -48,6 +49,9 @@ class DownloadSnapshot < Ec2Script
|
|
48
49
|
if @input_params[:wait_time] == nil
|
49
50
|
@input_params[:wait_time] = 300
|
50
51
|
end
|
52
|
+
if @input_params[:ssh_username] == nil
|
53
|
+
@input_params[:ssh_username] = "root"
|
54
|
+
end
|
51
55
|
end
|
52
56
|
|
53
57
|
# Load the initial state for the script.
|
@@ -105,7 +109,7 @@ class DownloadSnapshot < Ec2Script
|
|
105
109
|
def enter
|
106
110
|
@context[:script].post_message("Going to prepare the two volumes for the zip-operation.")
|
107
111
|
@context[:result][:os] =
|
108
|
-
connect(@context[:dns_name], @context[:ssh_keyfile], @context[:ssh_keydata])
|
112
|
+
connect(@context[:dns_name], @context[:ssh_username], @context[:ssh_keyfile], @context[:ssh_keydata])
|
109
113
|
source_dir = "/mnt/tmp_#{@context[:source_volume_id]}"
|
110
114
|
dest_dir = @context[:zip_file_dest]
|
111
115
|
create_fs(@context[:dns_name], @context[:dest_device])
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 1
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 1.
|
7
|
+
- 5
|
8
|
+
- 16
|
9
|
+
version: 1.5.16
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Matthias Jung
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-05-18 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -41,6 +41,18 @@ dependencies:
|
|
41
41
|
version: "0"
|
42
42
|
type: :runtime
|
43
43
|
version_requirements: *id002
|
44
|
+
- !ruby/object:Gem::Dependency
|
45
|
+
name: net-scp
|
46
|
+
prerelease: false
|
47
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
segments:
|
52
|
+
- 0
|
53
|
+
version: "0"
|
54
|
+
type: :runtime
|
55
|
+
version_requirements: *id003
|
44
56
|
description: Scripts to facilitate programming for infrastructure clouds.
|
45
57
|
email: matthias.jung@gmail.com
|
46
58
|
executables: []
|
@@ -63,6 +75,7 @@ files:
|
|
63
75
|
- lib/help/state_change_listener.rb
|
64
76
|
- lib/help/state_transition_helper.rb
|
65
77
|
- lib/scripts/ec2/ami2_ebs_conversion.rb
|
78
|
+
- lib/scripts/ec2/copy_ami.rb
|
66
79
|
- lib/scripts/ec2/copy_snapshot.rb
|
67
80
|
- lib/scripts/ec2/dm_encrypt.rb
|
68
81
|
- lib/scripts/ec2/download_snapshot.rb
|