solutious-rudy 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +8 -9
- data/README.rdoc +48 -7
- data/Rakefile +102 -7
- data/Rudyfile +28 -0
- data/bin/ird +162 -0
- data/bin/rudy +287 -93
- data/lib/annoy.rb +227 -0
- data/lib/aws_sdb/service.rb +1 -1
- data/lib/console.rb +20 -4
- data/lib/escape.rb +305 -0
- data/lib/rudy.rb +265 -125
- data/lib/rudy/aws.rb +61 -26
- data/lib/rudy/aws/ec2.rb +20 -296
- data/lib/rudy/aws/ec2/address.rb +121 -0
- data/lib/rudy/aws/ec2/group.rb +241 -0
- data/lib/rudy/aws/ec2/image.rb +46 -0
- data/lib/rudy/aws/ec2/instance.rb +407 -0
- data/lib/rudy/aws/ec2/keypair.rb +92 -0
- data/lib/rudy/aws/ec2/snapshot.rb +87 -0
- data/lib/rudy/aws/ec2/volume.rb +234 -0
- data/lib/rudy/aws/simpledb.rb +33 -15
- data/lib/rudy/cli.rb +142 -0
- data/lib/rudy/cli/addresses.rb +85 -0
- data/lib/rudy/cli/backups.rb +175 -0
- data/lib/rudy/{command → cli}/config.rb +18 -13
- data/lib/rudy/cli/deploy.rb +12 -0
- data/lib/rudy/cli/disks.rb +125 -0
- data/lib/rudy/cli/domains.rb +17 -0
- data/lib/rudy/cli/groups.rb +77 -0
- data/lib/rudy/{command → cli}/images.rb +18 -6
- data/lib/rudy/cli/instances.rb +142 -0
- data/lib/rudy/cli/keypairs.rb +47 -0
- data/lib/rudy/cli/manager.rb +51 -0
- data/lib/rudy/{command → cli}/release.rb +10 -10
- data/lib/rudy/cli/routines.rb +80 -0
- data/lib/rudy/cli/volumes.rb +121 -0
- data/lib/rudy/command/addresses.rb +62 -39
- data/lib/rudy/command/backups.rb +60 -170
- data/lib/rudy/command/disks-old.rb +322 -0
- data/lib/rudy/command/disks.rb +5 -209
- data/lib/rudy/command/domains.rb +34 -0
- data/lib/rudy/command/groups.rb +105 -48
- data/lib/rudy/command/instances.rb +263 -70
- data/lib/rudy/command/keypairs.rb +149 -0
- data/lib/rudy/command/manager.rb +65 -0
- data/lib/rudy/command/volumes.rb +110 -49
- data/lib/rudy/config.rb +90 -70
- data/lib/rudy/config/objects.rb +67 -0
- data/lib/rudy/huxtable.rb +253 -0
- data/lib/rudy/metadata/backup.rb +23 -48
- data/lib/rudy/metadata/disk.rb +79 -68
- data/lib/rudy/metadata/machine.rb +34 -0
- data/lib/rudy/routines.rb +54 -0
- data/lib/rudy/routines/disk_handler.rb +190 -0
- data/lib/rudy/routines/release.rb +15 -0
- data/lib/rudy/routines/script_runner.rb +65 -0
- data/lib/rudy/routines/shutdown.rb +42 -0
- data/lib/rudy/routines/startup.rb +48 -0
- data/lib/rudy/utils.rb +57 -2
- data/lib/storable.rb +11 -5
- data/lib/sysinfo.rb +274 -0
- data/rudy.gemspec +84 -20
- data/support/randomize-root-password +45 -0
- data/support/rudy-ec2-startup +5 -5
- data/support/update-ec2-ami-tools +20 -0
- data/test/05_config/00_setup_test.rb +24 -0
- data/test/05_config/30_machines_test.rb +69 -0
- data/test/20_sdb/00_setup_test.rb +31 -0
- data/test/20_sdb/10_domains_test.rb +113 -0
- data/test/25_ec2/00_setup_test.rb +34 -0
- data/test/25_ec2/10_keypairs_test.rb +33 -0
- data/test/25_ec2/20_groups_test.rb +139 -0
- data/test/25_ec2/30_addresses_test.rb +35 -0
- data/test/25_ec2/40_volumes_test.rb +46 -0
- data/test/25_ec2/50_snapshots_test.rb +69 -0
- data/test/26_ec2_instances/00_setup_test.rb +33 -0
- data/test/26_ec2_instances/10_instances_test.rb +81 -0
- data/test/26_ec2_instances/50_images_test.rb +13 -0
- data/test/30_sdb_metadata/00_setup_test.rb +28 -0
- data/test/30_sdb_metadata/10_disks_test.rb +99 -0
- data/test/30_sdb_metadata/20_backups_test.rb +102 -0
- data/test/50_commands/00_setup_test.rb +11 -0
- data/test/50_commands/10_keypairs_test.rb +79 -0
- data/test/50_commands/20_groups_test.rb +77 -0
- data/test/50_commands/40_volumes_test.rb +55 -0
- data/test/50_commands/50_instances_test.rb +110 -0
- data/test/coverage.txt +51 -0
- data/test/helper.rb +35 -0
- data/tryouts/disks.rb +55 -0
- data/tryouts/nested_methods.rb +36 -0
- data/tryouts/session_tryout.rb +48 -0
- metadata +94 -25
- data/bin/rudy-ec2 +0 -108
- data/lib/rudy/command/base.rb +0 -839
- data/lib/rudy/command/deploy.rb +0 -12
- data/lib/rudy/command/environment.rb +0 -74
- data/lib/rudy/command/machines.rb +0 -170
- data/lib/rudy/command/metadata.rb +0 -41
- data/lib/rudy/metadata.rb +0 -26
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Rudy
|
4
|
+
class Domains
|
5
|
+
include Rudy::Huxtable
|
6
|
+
|
7
|
+
|
8
|
+
def list
|
9
|
+
@@sdb.domains.list || []
|
10
|
+
end
|
11
|
+
|
12
|
+
def get(n=nil)
|
13
|
+
n = name(Rudy::RUDY_DOMAIN)
|
14
|
+
n &&= n.to_s
|
15
|
+
doms = list.select { |domain| domain == n }
|
16
|
+
doms = nil if doms.empty?
|
17
|
+
doms
|
18
|
+
end
|
19
|
+
|
20
|
+
def exists?(n=nil)
|
21
|
+
!get(n).nil?
|
22
|
+
end
|
23
|
+
|
24
|
+
def name(n=nil)
|
25
|
+
n || Rudy::RUDY_DOMAIN
|
26
|
+
end
|
27
|
+
|
28
|
+
def create(n=nil)
|
29
|
+
n = name(n)
|
30
|
+
@@sdb.domains.create(n)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
data/lib/rudy/command/groups.rb
CHANGED
@@ -1,61 +1,118 @@
|
|
1
1
|
|
2
2
|
|
3
|
-
|
4
3
|
module Rudy
|
5
|
-
|
6
|
-
|
4
|
+
class Groups
|
5
|
+
include Rudy::Huxtable
|
6
|
+
|
7
|
+
|
8
|
+
def create(n=nil, description=nil, opts={})
|
9
|
+
n ||= name(n)
|
10
|
+
description ||= "Machine group #{n}"
|
11
|
+
raise "Group #{n} already exists" if @@ec2.groups.exists?(n)
|
12
|
+
@@ec2.groups.create(n, description)
|
13
|
+
authorize(n, opts)
|
14
|
+
end
|
15
|
+
|
16
|
+
def destroy(n=nil)
|
17
|
+
n ||= name(n)
|
18
|
+
raise "Group #{n} does not exist" unless @@ec2.groups.exists?(n)
|
19
|
+
@@ec2.groups.destroy(n)
|
20
|
+
end
|
21
|
+
|
22
|
+
def authorize(n=nil, opts={})
|
23
|
+
n ||= name(n)
|
24
|
+
modify_rules(:authorize, n, opts)
|
25
|
+
end
|
26
|
+
def revoke(n=nil, opts={})
|
27
|
+
n ||= name(n)
|
28
|
+
modify_rules(:revoke, n, opts)
|
29
|
+
end
|
30
|
+
|
31
|
+
def exists?(n=nil)
|
32
|
+
n ||= name(n)
|
33
|
+
@@ec2.groups.exists?(n)
|
34
|
+
end
|
35
|
+
|
36
|
+
def name(n=nil)
|
37
|
+
n || current_machine_group
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
# Do any groups exist? The default group is not considered here since it
|
42
|
+
# cannot be destroyed. We're interested in any other groups.
|
43
|
+
def any?
|
44
|
+
groups = @@ec2.groups.list_as_hash
|
45
|
+
return false unless groups
|
46
|
+
groups.reject! { |name,g| g.name == 'default' }
|
47
|
+
!groups.empty?
|
48
|
+
end
|
49
|
+
|
50
|
+
def list(n=nil, &each_object)
|
51
|
+
n &&= [n]
|
52
|
+
groups = @@ec2.groups.list(n)
|
53
|
+
groups.each { |g| each_object.call(g) } if each_object
|
54
|
+
groups
|
55
|
+
end
|
56
|
+
|
57
|
+
def get(n=nil)
|
58
|
+
n ||= name(n)
|
59
|
+
(list(n) || []).first
|
60
|
+
end
|
61
|
+
|
62
|
+
def list_as_hash(n=nil, &each_object)
|
63
|
+
n &&= [n]
|
64
|
+
groups = @@ec2.groups.list_as_hash(n)
|
65
|
+
groups.each_pair { |n,g| each_object.call(g) } if each_object
|
66
|
+
groups
|
67
|
+
end
|
68
|
+
|
69
|
+
# TODO: Consider changing the hash interface into arguments.
|
70
|
+
# with different methods for authorizing groups and addresses
|
71
|
+
def modify_rules(action, n, opts={})
|
72
|
+
n ||= name(n)
|
7
73
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
print_group grp
|
12
|
-
end
|
13
|
-
end
|
74
|
+
raise "You must supply a group name" unless n
|
75
|
+
raise "Group does not exist" unless @@ec2.groups.exists?(n)
|
76
|
+
@logger.puts "#{action.to_s.capitalize} access for #{n.bright}"
|
14
77
|
|
15
|
-
def create_groups(name=@argv.first)
|
16
|
-
name ||= machine_group
|
17
|
-
puts "Creating group #{name}"
|
18
|
-
raise "The group #{name} already exists" if @ec2.groups.exists?(name)
|
19
78
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
79
|
+
opts[:ports] ||= [[22,22],[80,80],[443,443]]
|
80
|
+
opts[:protocols] ||= ["tcp"]
|
81
|
+
opts[:addresses] ||= [Rudy::Utils::external_ip_address]
|
82
|
+
|
83
|
+
# Make sure the IP addresses have ranges
|
84
|
+
opts[:addresses].collect! { |ip| (ip.match /\/\d+/) ? ip : "#{ip}/32" }
|
24
85
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@option.ports ||= [22,80,443]
|
31
|
-
@option.protocols ||= ["tcp"]
|
32
|
-
|
33
|
-
# Make sure the IP addresses have ranges
|
34
|
-
@option.addresses.collect! { |ip| (ip.match /\/\d+/) ? ip : "#{ip}/32" }
|
35
|
-
|
36
|
-
@option.protocols.each do |protocol|
|
37
|
-
puts "Adding ports #{@option.ports.join(',')} (#{protocol}) for #{@option.addresses.join(', ')}"
|
38
|
-
@option.addresses.each do |address|
|
39
|
-
@option.ports.each do |port|
|
40
|
-
@ec2.groups.modify(name, port, port, protocol, address)
|
41
|
-
end
|
86
|
+
opts[:protocols].each do |protocol|
|
87
|
+
opts[:addresses].each do |address|
|
88
|
+
opts[:ports].each do |port|
|
89
|
+
@logger.puts "Ports #{port[0]}:#{port[1]} (#{protocol}) for #{opts[:addresses].join(', ')}"
|
90
|
+
@@ec2.groups.send(action, n, port[0].to_i, (port[1] || port[0]).to_i, protocol, address)
|
42
91
|
end
|
43
92
|
end
|
44
|
-
|
45
|
-
groups name
|
46
93
|
end
|
47
94
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
name = machine_group if name.nil?
|
52
|
-
raise "The group #{name} does not exist" unless @ec2.groups.exists?(name)
|
53
|
-
exit unless are_you_sure?
|
54
|
-
|
55
|
-
@ec2.groups.destroy(name)
|
56
|
-
|
57
|
-
end
|
95
|
+
@@ec2.groups.get(n)
|
96
|
+
|
97
|
+
|
58
98
|
end
|
59
|
-
|
60
|
-
|
99
|
+
|
100
|
+
def modify_group_rules(n=nil, group=nil, owner=nil)
|
101
|
+
n ||= name(n)
|
102
|
+
|
103
|
+
owner ||= @config.accounts.aws.accountnum
|
104
|
+
|
105
|
+
raise "You must supply a group name" unless n
|
106
|
+
raise "Group does not exist" unless @@ec2.groups.exists?(n)
|
107
|
+
raise "Owner to authorize not specified" unless owner
|
108
|
+
raise "Group to authorize not specified" unless owner
|
109
|
+
|
110
|
+
@logger.puts "#{action.to_s.capitalize} access for #{n.bright}"
|
111
|
+
|
112
|
+
@@ec2.groups.send("#{action}_group", n, group, owner)
|
61
113
|
|
114
|
+
@@ec2.groups.get(n)
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
@@ -1,85 +1,278 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
1
|
+
|
12
2
|
|
13
3
|
module Rudy
|
14
|
-
|
15
|
-
|
4
|
+
class Instances
|
5
|
+
include Rudy::Huxtable
|
6
|
+
|
7
|
+
|
8
|
+
def create(opts={}, &each_inst)
|
16
9
|
|
17
|
-
|
18
|
-
raise "No instance ID provided" if @argv.filter.nil?
|
19
|
-
raise "No EC2 .pem keys provided" unless has_pem_keys?
|
20
|
-
raise "No SSH key provided for #{@global.user}!" unless has_keypair?
|
21
|
-
raise "No SSH key provided for root!" unless has_keypair?(:root)
|
22
|
-
|
23
|
-
|
24
|
-
@list = @ec2.instances.list(machine_group)
|
25
|
-
raise "#{@argv.filter} is not in the current machine group" unless @list.has_key?(@argv.filter)
|
26
|
-
|
27
|
-
raise "I will not help you destroy production!" if @global.environment == "prod" # TODO: use_caution?, locked?
|
28
|
-
|
29
|
-
exit unless are_you_sure?(5)
|
30
|
-
true
|
31
|
-
end
|
32
|
-
def restart_instances
|
33
|
-
puts "Restarting #{@argv.filter}!"
|
34
|
-
@ec2.instances.restart @argv.filter
|
35
|
-
end
|
10
|
+
rgroup = Rudy::Groups.new(:config => @config, :global => @global)
|
36
11
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
12
|
+
# TODO: Handle itype on create
|
13
|
+
opts = { :ami => current_machine_image,
|
14
|
+
:group => current_machine_group,
|
15
|
+
:user => current_user,
|
16
|
+
:size => "m1.small",
|
17
|
+
:keypair => user_keypairpath(:root), # Must be a root key
|
18
|
+
:address => current_machine_address,
|
19
|
+
:machine_data => machine_data.to_yaml }.merge(opts)
|
20
|
+
|
21
|
+
raise NoGroup.new(opts[:group]) unless rgroup.exists?(opts[:group])
|
22
|
+
raise NoRootKeyPair.new(opts[:group]) if !opts[:keypair] && !has_keypair?(:root)
|
23
|
+
|
24
|
+
keypair_name = KeyPairs.path_to_name(opts[:keypair])
|
25
|
+
|
26
|
+
instances = @@ec2.instances.create(opts[:ami], opts[:group], keypair_name, opts[:machine_data], @global.zone)
|
27
|
+
|
28
|
+
|
29
|
+
#instances = [@@ec2.instances.get("i-39009850")]
|
30
|
+
instances_with_dns = []
|
31
|
+
instances.each_with_index do |inst_tmp,index|
|
32
|
+
Rudy.bug('hs672h48') && next if inst_tmp.nil?
|
33
|
+
|
34
|
+
@logger.puts "Instance: #{inst_tmp.awsid}"
|
35
|
+
if opts[:address] && index == 0 # We currently only support assigned an address to the first machine
|
36
|
+
@logger.puts "Associating #{opts[:address]} to #{inst_tmp.awsid}"
|
37
|
+
@@ec2.addresses.associate(inst_tmp.awsid, opts[:address])
|
52
38
|
end
|
53
|
-
|
54
|
-
|
55
|
-
|
39
|
+
|
40
|
+
@logger.puts "Waiting for the instance to startup "
|
41
|
+
begin
|
42
|
+
# TODO: Puts "it's up" and :bell => 3 into waiter
|
43
|
+
Rudy.waiter(2, 120, @logger) { !@@ec2.instances.pending?(inst_tmp.awsid) }
|
44
|
+
raise Exception unless @@ec2.instances.running?(inst_tmp.awsid)
|
45
|
+
@logger.puts "It's up!"
|
46
|
+
Rudy.bell(3)
|
47
|
+
rescue Timeout::Error, Interrupt, Exception
|
48
|
+
@logger.puts "It's not up yet. Check later: " << "rudy status #{inst_tmp.awsid}".color(:blue)
|
49
|
+
next
|
56
50
|
end
|
57
|
-
|
51
|
+
|
52
|
+
# The DNS names are now available so we need to grab that data from AWS
|
53
|
+
instance = @@ec2.instances.get(inst_tmp.awsid)
|
54
|
+
instances_with_dns << instance
|
55
|
+
|
56
|
+
@logger.puts $/, "Waiting for the SSH daemon "
|
57
|
+
begin
|
58
|
+
Rudy.waiter(1, 60, @logger) { Rudy::Utils.service_available?(instance.dns_name_public, 22) }
|
59
|
+
@logger.puts "It's up!"
|
60
|
+
Rudy.bell(2)
|
61
|
+
rescue Timeout::Error, Interrupt, Exception
|
62
|
+
@logger.puts "SSH isn't up yet. Check later: " << "rudy status #{inst_tmp.awsid}".color(:blue)
|
63
|
+
next
|
64
|
+
end
|
65
|
+
|
66
|
+
|
58
67
|
end
|
59
68
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
69
|
+
instances_with_dns.each { |inst| each_inst.call(inst) } if each_inst
|
70
|
+
instances_with_dns
|
71
|
+
end
|
72
|
+
|
73
|
+
def destroy(group=nil, inst_id=[], &each_inst)
|
74
|
+
group ||= current_machine_group
|
75
|
+
raise "No machines running in #{group}" unless running?(group)
|
76
|
+
instances = @@ec2.instances.list_group(group, :running, inst_id)
|
77
|
+
instances &&= [instances].flatten
|
78
|
+
instances.each { |inst| each_inst.call(inst) } if each_inst
|
79
|
+
@logger.puts $/, "Terminating instances...", $/
|
80
|
+
@@ec2.instances.destroy(instances, :skip_check)
|
81
|
+
end
|
82
|
+
|
83
|
+
# * +state+ instance state (:running, :terminated, :pending, :shutting_down)
|
84
|
+
# * +group+ machine group name. The default is the current machine group
|
85
|
+
# (as determined by the globals) if none is supplied. A value of :any will
|
86
|
+
# return machines from all groups.
|
87
|
+
# * +inst_ids+ An Array of instance IDs (Strings) or Instance objects to
|
88
|
+
# filter the list by. Any instances not in the group will be ignored.
|
89
|
+
# * +each_inst+ a block to execute for every instance in the list.
|
90
|
+
# Returns an Array of Rudy::AWS::EC2::Instance objects
|
91
|
+
def list(state=nil, group=nil, inst_ids=[], &each_inst)
|
92
|
+
group ||= current_machine_group
|
93
|
+
unless group == :any
|
94
|
+
instances = @@ec2.instances.list_group(group, state, inst_ids) || []
|
95
|
+
else
|
96
|
+
instances = @@ec2.instances.list(state, inst_ids) || []
|
97
|
+
end
|
98
|
+
instances.each { |inst| each_inst.call(inst) } if each_inst
|
99
|
+
instances
|
100
|
+
end
|
101
|
+
|
102
|
+
# See Rudy::Instances#list for arguments.
|
103
|
+
# Returns a Hash of Rudy::AWS::EC2::Instance objects (the keys are instance IDs)
|
104
|
+
def list_as_hash(state=nil, group=nil, inst_ids=[], &each_inst)
|
105
|
+
group ||= current_machine_group
|
106
|
+
if group == :any
|
107
|
+
instances = @@ec2.instances.list_group_as_hash(group, state, inst_ids) || {}
|
108
|
+
else
|
109
|
+
instances = @@ec2.instances.list_as_hash(state, inst_ids) || {}
|
66
110
|
end
|
111
|
+
instances.each_pair { |inst_id,inst| each_inst.call(inst) } if each_inst
|
112
|
+
instances
|
113
|
+
end
|
114
|
+
|
115
|
+
# System console output.
|
116
|
+
#
|
117
|
+
# NOTE: Amazon sends the console output as a Base64 encoded string. This method
|
118
|
+
# decrypts it before returning it.
|
119
|
+
#
|
120
|
+
# Returns output for the first machine in the group (if provided) or the first
|
121
|
+
# instance ID (if provided)
|
122
|
+
def console(group=nil, inst_ids=[])
|
123
|
+
group ||= current_machine_group
|
124
|
+
instances = @@ec2.instances.list_group(group, :any, inst_ids)
|
125
|
+
return if instances.nil?
|
126
|
+
output = @@ec2.instances.console_output(instances.first.awsid)
|
127
|
+
return unless output
|
128
|
+
Base64.decode64(output)
|
129
|
+
end
|
130
|
+
|
131
|
+
def connect(group=nil, cmd=nil, inst_ids=[], print_only=false)
|
132
|
+
group ||= current_machine_group
|
133
|
+
instances = @@ec2.instances.list_group(group, :running, inst_ids)
|
134
|
+
raise "No machines running" if instances.nil?
|
135
|
+
raise "No keypair configured for user #{current_user}" unless current_user_keypairpath
|
136
|
+
|
137
|
+
# TODO: If a group is supplied we need to discover the keypair.
|
138
|
+
|
139
|
+
instances.each do |inst|
|
140
|
+
msg = cmd ? %Q{"#{cmd}" on} : "Connecting to"
|
141
|
+
@logger.puts $/, "#{msg} #{inst.dns_name_public}", $/
|
142
|
+
ret = ssh_command(inst.dns_name_public, current_user_keypairpath, @global.user, cmd, print_only)
|
143
|
+
puts ret if ret # ssh command returns false with "ssh_exchange_identification: Connection closed by remote host"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
# * +:recursive: recursively transfer directories (default: false)
|
149
|
+
# * +:preserve: preserve atimes and ctimes (default: false)
|
150
|
+
# * +:task+ one of: :upload (default), :download.
|
151
|
+
# * +:paths+ an array of paths to copy. The last element is the "to" path.
|
152
|
+
def copy(group=nil, inst_ids=[], opts={})
|
153
|
+
group ||= current_machine_group
|
154
|
+
instances = @@ec2.instances.list_group(group, :running, inst_ids)
|
155
|
+
raise "No machines running" if instances.nil?
|
156
|
+
raise "No keypair configured for user #{current_user}" unless current_user_keypairpath
|
157
|
+
raise "You must supply at least one source path" if !opts[:paths] || opts[:paths].empty?
|
158
|
+
raise "You must supply a destination path" unless opts[:dest]
|
159
|
+
|
160
|
+
|
161
|
+
opts = {
|
162
|
+
:task => :upload,
|
163
|
+
:recursive => false,
|
164
|
+
:preserve => false
|
165
|
+
}.merge(opts)
|
67
166
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
instance = filter
|
167
|
+
|
168
|
+
instances.each do |inst|
|
169
|
+
msg = opts[:task] == :upload ? "Upload to" : "Download from"
|
170
|
+
@logger.puts $/, "#{msg} #{inst.awsid}"
|
171
|
+
|
172
|
+
if opts[:print]
|
173
|
+
scp_command inst.dns_name_public, current_user_keypairpath, @global.user, opts[:paths], opts[:dest], (opts[:task] == :download), false, opts[:print]
|
174
|
+
return
|
77
175
|
end
|
78
|
-
|
79
|
-
|
176
|
+
|
177
|
+
scp_opts = {
|
178
|
+
:recursive => opts[:recursive],
|
179
|
+
:preserve => opts[:preserve],
|
180
|
+
:chunk_size => 16384
|
181
|
+
}
|
182
|
+
|
183
|
+
scp(opts[:task], inst.dns_name_public, @global.user, current_user_keypairpath, opts[:paths], opts[:dest], scp_opts)
|
184
|
+
|
80
185
|
end
|
186
|
+
|
187
|
+
@logger.puts
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
# * +group+ machine group name
|
192
|
+
def any?(group=nil)
|
193
|
+
group ||= current_machine_group
|
194
|
+
|
195
|
+
@@ec2.instances.any_group?(group)
|
196
|
+
end
|
197
|
+
|
198
|
+
def exists?(inst_id)
|
199
|
+
@@ec2.instances.exists?(inst_id)
|
200
|
+
end
|
201
|
+
|
202
|
+
# *NOTE REGARDING THE STATUS METHODS*:
|
203
|
+
#
|
204
|
+
# We currently return true IF ANY instances are operating
|
205
|
+
# in the given state. This is faulty but we can't fix it
|
206
|
+
# until we have a way to know how many instances should be
|
207
|
+
# running in any given group.
|
208
|
+
#
|
209
|
+
# Are *any* instances in the group in the running state?
|
210
|
+
def running?(group=nil)
|
211
|
+
!list(:running, group).empty?
|
212
|
+
end
|
213
|
+
|
214
|
+
# Are *any* instances in the group in the terminated state?
|
215
|
+
def terminated?(group=nil)
|
216
|
+
!list(:terminated, group).empty?
|
217
|
+
end
|
218
|
+
|
219
|
+
# Are *any* instances in the group in the shutting-down state?
|
220
|
+
def shutting_down?(group=nil)
|
221
|
+
!list(:shutting_down, group).empty?
|
222
|
+
end
|
223
|
+
|
224
|
+
# Are *any* instances in the group in the pending state?
|
225
|
+
def pending?(group=nil)
|
226
|
+
!list(:pending, group).empty?
|
227
|
+
end
|
228
|
+
|
229
|
+
# Are *any* instances in the group in the a non-running state?
|
230
|
+
def unavailable?(group=nil)
|
231
|
+
# We go through @@ec2 so we don't reimplement the "unavailable logic"
|
232
|
+
instances = list(:any, group)
|
233
|
+
@@ec2.instances.unavailable?(instances)
|
234
|
+
end
|
235
|
+
|
236
|
+
|
237
|
+
|
238
|
+
|
239
|
+
private
|
81
240
|
|
241
|
+
def machine_data
|
242
|
+
data = {
|
243
|
+
# Give the machine an identity
|
244
|
+
:zone => @global.zone,
|
245
|
+
:environment => @global.environment,
|
246
|
+
:role => @global.role,
|
247
|
+
:position => @global.position,
|
248
|
+
|
249
|
+
# Add hosts to the /etc/hosts file
|
250
|
+
:hosts => {
|
251
|
+
:dbmaster => "127.0.0.1",
|
252
|
+
}
|
253
|
+
}
|
254
|
+
data.to_hash
|
82
255
|
end
|
256
|
+
|
257
|
+
|
258
|
+
|
83
259
|
end
|
84
|
-
|
85
|
-
|
260
|
+
class NoGroup < RuntimeError
|
261
|
+
def initialize(group)
|
262
|
+
@group = group
|
263
|
+
end
|
264
|
+
def message
|
265
|
+
"Group #{@group} does not exist. See: rudy groups -h"
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
class NoRootKeyPair < RuntimeError
|
270
|
+
def initialize(group)
|
271
|
+
@group = group
|
272
|
+
end
|
273
|
+
def message
|
274
|
+
"No root keypair for #{@group}. See: rudy keypairs -h"
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
end
|