13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
# File 'lib/hawser/volumes.rb', line 13
def define
in_namespace do
desc "Clone <from_dev> on <from_instance> to <to_dev> on <to_instance>"
task :clone, [:from_instance, :from_dev, :to_instance, :to_dev] do |task, args|
missing = [:from_instance, :from_dev, :to_instance].find_all do |key|
args[key].nil?
end
unless missing.empty?
fail "Missing required arguments: #{missing.inspect}"
end
to_dev = args[:to_dev] || args[:from_dev]
ec2 = AWS::EC2.new(:region => region, :access_key_id => access_key, :secret_access_key => secret_key)
instances = ec2.instances
from_instance = instances.find do |inst|
inst.instance_id == args[:from_instance]
end
to_instance = instances.find do |inst|
inst.instance_id == args[:to_instance]
end
missing_instances = []
if from_instance.nil?
missing_instances << "Missing instance for #{args[:from_instance].inspect}"
end
if to_instance.nil?
missing_instances << "Missing instance for #{args[:to_instance].inspect}"
end
unless missing_instances.empty?
fail "Missing instances: #{missing_instances.join.inspect}"
end
require 'pp'
from_device = from_instance.block_devices.find do |dev|
dev[:device_name] == args[:from_dev]
end
unless from_device
fail "No device mapped to #{args[:from_instance]} on #{args[:from_dev]}"
end
if to_instance.block_devices.any?{|dev| dev[:device_name] == to_dev}
fail "A device is already mapped to #{args[:to_instance]} on #{to_dev}"
end
from_volume = ec2.volumes.find do |vol|
from_device[:ebs][:volume_id] == vol.id
end
unless from_volume
fail "No volume matches #{from_device[:ebs][:volume_id].inspect}"
end
snapshot_desc = from_volume.tags["Name"] || "From #{args[:from_instance]}:#{args[:from_dev]}"
intermediate_snapshot = from_volume.create_snapshot(snapshot_desc)
at_exit{ intermediate_snapshot.delete }
wait_for_status("intermediate snapshot", intermediate_snapshot, :completed)
new_volume = intermediate_snapshot.create_volume(to_instance.availability_zone)
wait_for_status("volume creation", new_volume, :available)
new_volume.attach_to(to_instance, to_dev)
wait_for_status("volume attachment", new_volume, :in_use)
puts "Done"
end
end
end
|