CloudyScripts 1.4.15 → 1.5.16
Sign up to get free protection for your applications and to get access to all the features.
- 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
|