solutious-rudy 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +19 -1
- data/README.rdoc +66 -35
- data/Rakefile +1 -0
- data/Rudyfile +97 -6
- data/bin/ird +7 -4
- data/bin/rudy +120 -212
- data/bin/rudy-ec2 +240 -0
- data/bin/rudy-s3 +76 -0
- data/bin/rudy-sdb +67 -0
- data/lib/annoy.rb +61 -18
- data/lib/console.rb +10 -5
- data/lib/rudy/aws/ec2/address.rb +76 -40
- data/lib/rudy/aws/ec2/group.rb +138 -78
- data/lib/rudy/aws/ec2/image.rb +134 -12
- data/lib/rudy/aws/ec2/instance.rb +116 -89
- data/lib/rudy/aws/ec2/keypair.rb +26 -14
- data/lib/rudy/aws/ec2/snapshot.rb +23 -12
- data/lib/rudy/aws/ec2/volume.rb +198 -202
- data/lib/rudy/aws/ec2/zone.rb +77 -0
- data/lib/rudy/aws/ec2.rb +56 -25
- data/lib/rudy/aws/s3.rb +54 -0
- data/lib/rudy/aws/sdb/error.rb +46 -0
- data/lib/rudy/aws/sdb.rb +298 -0
- data/lib/rudy/aws.rb +29 -57
- data/lib/rudy/{metadata/backup.rb → backup.rb} +8 -8
- data/lib/rudy/cli/aws/ec2/addresses.rb +105 -0
- data/lib/rudy/cli/aws/ec2/candy.rb +208 -0
- data/lib/rudy/cli/aws/ec2/groups.rb +121 -0
- data/lib/rudy/cli/aws/ec2/images.rb +196 -0
- data/lib/rudy/cli/aws/ec2/instances.rb +194 -0
- data/lib/rudy/cli/aws/ec2/keypairs.rb +53 -0
- data/lib/rudy/cli/aws/ec2/snapshots.rb +49 -0
- data/lib/rudy/cli/aws/ec2/volumes.rb +104 -0
- data/lib/rudy/cli/aws/ec2/zones.rb +22 -0
- data/lib/rudy/cli/aws/s3/buckets.rb +50 -0
- data/lib/rudy/cli/aws/s3/store.rb +22 -0
- data/lib/rudy/cli/aws/sdb/domains.rb +41 -0
- data/lib/rudy/cli/{deploy.rb → candy.rb} +2 -6
- data/lib/rudy/cli/config.rb +25 -20
- data/lib/rudy/cli/disks.rb +18 -108
- data/lib/rudy/cli/machines.rb +94 -0
- data/lib/rudy/cli/routines.rb +47 -70
- data/lib/rudy/cli.rb +104 -89
- data/lib/rudy/config/objects.rb +5 -43
- data/lib/rudy/config.rb +8 -24
- data/lib/rudy/disks.rb +248 -0
- data/lib/rudy/global.rb +121 -0
- data/lib/rudy/huxtable.rb +232 -147
- data/lib/rudy/machines.rb +245 -0
- data/lib/rudy/metadata.rb +136 -0
- data/lib/rudy/routines/helpers/diskhelper.rb +101 -0
- data/lib/rudy/routines/helpers/scripthelper.rb +91 -0
- data/lib/rudy/routines/release.rb +27 -8
- data/lib/rudy/routines/shutdown.rb +47 -32
- data/lib/rudy/routines/startup.rb +47 -37
- data/lib/rudy/routines.rb +30 -37
- data/lib/rudy/scm/svn.rb +1 -1
- data/lib/rudy/utils.rb +262 -4
- data/lib/rudy.rb +76 -248
- data/lib/storable.rb +19 -16
- data/lib/sysinfo.rb +1 -1
- data/rudy.gemspec +88 -68
- data/support/rudy-ec2-startup +5 -5
- data/test/05_config/00_setup_test.rb +3 -7
- data/test/20_sdb/00_setup_test.rb +2 -17
- data/test/20_sdb/10_domains_test.rb +18 -16
- data/test/25_ec2/00_setup_test.rb +5 -10
- data/test/25_ec2/10_keypairs_test.rb +13 -5
- data/test/25_ec2/20_groups_test.rb +48 -56
- data/test/25_ec2/30_addresses_test.rb +13 -10
- data/test/25_ec2/40_volumes_test.rb +11 -8
- data/test/25_ec2/50_snapshots_test.rb +17 -12
- data/test/26_ec2_instances/00_setup_test.rb +3 -8
- data/test/26_ec2_instances/10_instances_test.rb +21 -19
- data/test/30_sdb_metadata/00_setup_test.rb +2 -9
- data/test/30_sdb_metadata/10_disks_test.rb +47 -37
- data/test/30_sdb_metadata/20_backups_test.rb +9 -9
- data/test/helper.rb +5 -3
- data/vendor/highline-1.5.1/CHANGELOG +222 -0
- data/vendor/highline-1.5.1/INSTALL +35 -0
- data/vendor/highline-1.5.1/LICENSE +7 -0
- data/vendor/highline-1.5.1/README +63 -0
- data/vendor/highline-1.5.1/Rakefile +82 -0
- data/vendor/highline-1.5.1/TODO +6 -0
- data/vendor/highline-1.5.1/examples/ansi_colors.rb +38 -0
- data/vendor/highline-1.5.1/examples/asking_for_arrays.rb +18 -0
- data/vendor/highline-1.5.1/examples/basic_usage.rb +75 -0
- data/vendor/highline-1.5.1/examples/color_scheme.rb +32 -0
- data/vendor/highline-1.5.1/examples/limit.rb +12 -0
- data/vendor/highline-1.5.1/examples/menus.rb +65 -0
- data/vendor/highline-1.5.1/examples/overwrite.rb +19 -0
- data/vendor/highline-1.5.1/examples/page_and_wrap.rb +322 -0
- data/vendor/highline-1.5.1/examples/password.rb +7 -0
- data/vendor/highline-1.5.1/examples/trapping_eof.rb +22 -0
- data/vendor/highline-1.5.1/examples/using_readline.rb +17 -0
- data/vendor/highline-1.5.1/lib/highline/color_scheme.rb +120 -0
- data/vendor/highline-1.5.1/lib/highline/compatibility.rb +17 -0
- data/vendor/highline-1.5.1/lib/highline/import.rb +43 -0
- data/vendor/highline-1.5.1/lib/highline/menu.rb +395 -0
- data/vendor/highline-1.5.1/lib/highline/question.rb +463 -0
- data/vendor/highline-1.5.1/lib/highline/system_extensions.rb +193 -0
- data/vendor/highline-1.5.1/lib/highline.rb +758 -0
- data/vendor/highline-1.5.1/setup.rb +1360 -0
- data/vendor/highline-1.5.1/test/tc_color_scheme.rb +56 -0
- data/vendor/highline-1.5.1/test/tc_highline.rb +823 -0
- data/vendor/highline-1.5.1/test/tc_import.rb +54 -0
- data/vendor/highline-1.5.1/test/tc_menu.rb +429 -0
- data/vendor/highline-1.5.1/test/ts_all.rb +15 -0
- metadata +81 -69
- data/lib/aws_sdb/error.rb +0 -42
- data/lib/aws_sdb/service.rb +0 -215
- data/lib/aws_sdb.rb +0 -3
- data/lib/rudy/aws/simpledb.rb +0 -71
- data/lib/rudy/cli/addresses.rb +0 -85
- data/lib/rudy/cli/backups.rb +0 -175
- data/lib/rudy/cli/domains.rb +0 -17
- data/lib/rudy/cli/groups.rb +0 -77
- data/lib/rudy/cli/images.rb +0 -111
- data/lib/rudy/cli/instances.rb +0 -142
- data/lib/rudy/cli/keypairs.rb +0 -47
- data/lib/rudy/cli/manager.rb +0 -51
- data/lib/rudy/cli/release.rb +0 -174
- data/lib/rudy/cli/volumes.rb +0 -121
- data/lib/rudy/command/addresses.rb +0 -69
- data/lib/rudy/command/backups.rb +0 -65
- data/lib/rudy/command/disks-old.rb +0 -322
- data/lib/rudy/command/disks.rb +0 -9
- data/lib/rudy/command/domains.rb +0 -34
- data/lib/rudy/command/groups.rb +0 -118
- data/lib/rudy/command/instances.rb +0 -278
- data/lib/rudy/command/keypairs.rb +0 -149
- data/lib/rudy/command/manager.rb +0 -65
- data/lib/rudy/command/volumes.rb +0 -127
- data/lib/rudy/metadata/disk.rb +0 -149
- data/lib/rudy/metadata/machine.rb +0 -34
- data/lib/rudy/routines/disk_handler.rb +0 -190
- data/lib/rudy/routines/script_runner.rb +0 -65
- data/test/50_commands/00_setup_test.rb +0 -11
- data/test/50_commands/10_keypairs_test.rb +0 -79
- data/test/50_commands/20_groups_test.rb +0 -77
- data/test/50_commands/40_volumes_test.rb +0 -55
- data/test/50_commands/50_instances_test.rb +0 -110
- data/tryouts/console_tryout.rb +0 -91
- data/tryouts/disks.rb +0 -55
- data/tryouts/nested_methods.rb +0 -36
- data/tryouts/session_tryout.rb +0 -46
data/lib/rudy/cli/disks.rb
CHANGED
@@ -2,124 +2,34 @@
|
|
2
2
|
|
3
3
|
module Rudy
|
4
4
|
module CLI
|
5
|
-
class Disks < Rudy::CLI::
|
5
|
+
class Disks < Rudy::CLI::CommandBase
|
6
6
|
|
7
|
-
def disk
|
8
|
-
puts "Disks".bright
|
9
|
-
opts = {}
|
10
|
-
[:all, :path, :device, :size].each do |v|
|
11
|
-
opts[v] = @option.send(v) if @option.respond_to?(v)
|
12
|
-
end
|
13
|
-
if @argv.diskname
|
14
|
-
key = @argv.diskname =~ /^disk-/ ? :name : :path
|
15
|
-
opts[key] = @argv.diskname
|
16
|
-
end
|
17
|
-
|
18
|
-
rdisks = Rudy::Disks.new(:config => @config, :global => @global)
|
19
|
-
disks = rdisks.list(opts)
|
20
|
-
raise "No disks." unless disks
|
21
|
-
#rbacks = Rudy::Backups.new(:config => @config, :global => @global)
|
22
|
-
disks.each_pair do |diskid, disk|
|
23
|
-
#backups = rbacks.list_by_disk(disk, 2)
|
24
|
-
print_disk(disk)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def print_disk(disk, backups=[])
|
29
|
-
return unless disk
|
30
|
-
puts '-'*60
|
31
|
-
puts "Disk: #{disk.name.bright}"
|
32
|
-
puts disk.to_s
|
33
|
-
puts "#{backups.size} most recent backups:", backups.collect { |back| "#{back.nice_time} (#{back.awsid})" }
|
34
|
-
puts
|
35
|
-
end
|
36
|
-
|
37
|
-
def create_disk_valid?
|
38
|
-
raise "No filesystem path specified" unless @option.path
|
39
|
-
raise "No size specified" unless @option.size
|
40
|
-
raise "No device specified" unless @option.device
|
41
|
-
true
|
42
|
-
end
|
43
7
|
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
[:path, :device, :size, :group].each do |v|
|
49
|
-
opts[v] = @option.send(v) if @option.respond_to?(v)
|
50
|
-
end
|
51
|
-
opts[:id] = @option.awsid if @option.awsid
|
52
|
-
opts[:id] &&= [opts[:id]].flatten
|
53
|
-
|
54
|
-
@global.debug = true
|
55
|
-
rmachines = Rudy::Instances.new(:config => @config, :global => @global)
|
56
|
-
rmachines.list(opts).each_pair do |id,machine|
|
57
|
-
rdisks = Rudy::Disks.new(:config => @config, :global => @global)
|
58
|
-
disk = rdisks.create(machine, opts)
|
59
|
-
print_disk(disk) if disk
|
8
|
+
def disks
|
9
|
+
rdisk = Rudy::Disks.new
|
10
|
+
rdisk.list do |d|
|
11
|
+
puts @@global.verbose > 0 ? d.inspect : d.dump(@@global.format)
|
60
12
|
end
|
61
13
|
end
|
62
14
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
def destroy_disk
|
71
|
-
puts "Destroying Disk".bright
|
72
|
-
exit unless Annoy.are_you_sure?(:medium)
|
73
|
-
opts = {}
|
74
|
-
if @argv.diskname
|
75
|
-
key = @argv.diskname =~ /^disk-/ ? :name : :path
|
76
|
-
opts[key] = @argv.diskname
|
77
|
-
end
|
78
|
-
|
79
|
-
# TODO: This is fucked! Store the machine info with the disk metadata.
|
80
|
-
# Get all disks that match the request and destroy them.
|
81
|
-
rmachines = Rudy::Instances.new(:config => @config, :global => @global)
|
82
|
-
rmachines.list(opts).each_pair do |id,machine|
|
83
|
-
rdisks = Rudy::Disks.new(:config => @config, :global => @global)
|
84
|
-
rdisks.destroy(machine, opts)
|
15
|
+
def disks_wash
|
16
|
+
rdisk = Rudy::Disks.new
|
17
|
+
dirt = (rdisk.list || [])#.select { |d| d.available? }
|
18
|
+
if dirt.empty?
|
19
|
+
puts "Nothing to wash in #{rdisk.current_machine_group}"
|
20
|
+
return
|
85
21
|
end
|
86
22
|
|
87
|
-
puts "
|
88
|
-
|
23
|
+
puts "The following disk metadata will be deleted:"
|
24
|
+
puts dirt.collect {|d| d.name }
|
25
|
+
execute_check(:medium)
|
89
26
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
true
|
94
|
-
end
|
95
|
-
|
96
|
-
def attach_disk
|
97
|
-
puts "Attaching #{name}"
|
98
|
-
switch_user("root")
|
99
|
-
exit unless Annoy.are_you_sure?(:medium)
|
100
|
-
|
101
|
-
machine = @instances.values.first # AK! Assumes single machine
|
27
|
+
dirt.each do |d|
|
28
|
+
d.destroy(:force)
|
29
|
+
end
|
102
30
|
|
103
|
-
execute_attach_disk(@disk, machine)
|
104
|
-
|
105
|
-
puts
|
106
|
-
ssh_command machine[:dns_name], keypairpath, @global.user, "df -h" # Display current mounts
|
107
|
-
puts
|
108
|
-
|
109
|
-
puts "Done!"
|
110
31
|
end
|
111
|
-
|
112
|
-
|
113
|
-
|
114
32
|
|
115
33
|
end
|
116
34
|
end
|
117
|
-
end
|
118
|
-
|
119
|
-
|
120
|
-
__END__
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
35
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Rudy
|
4
|
+
module CLI
|
5
|
+
class Machines < Rudy::CLI::CommandBase
|
6
|
+
|
7
|
+
|
8
|
+
def machines
|
9
|
+
rmach = Rudy::Machines.new
|
10
|
+
mlist = rmach.list || []
|
11
|
+
if mlist.empty?
|
12
|
+
puts "No machines running in #{current_machine_group}"
|
13
|
+
puts "Try: #{$0} startup"
|
14
|
+
end
|
15
|
+
mlist.each do |m|
|
16
|
+
puts @@global.verbose > 0 ? m.inspect : m.dump(@@global.format)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def machines_wash
|
21
|
+
rmach = Rudy::Machines.new
|
22
|
+
dirt = (rmach.list || []).select { |m| !m.running? }
|
23
|
+
if dirt.empty?
|
24
|
+
puts "Nothing to wash in #{rmach.current_machine_group}"
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
28
|
+
puts "The following machine metadata will be deleted:"
|
29
|
+
puts dirt.collect {|m| m.name }
|
30
|
+
execute_check(:medium)
|
31
|
+
|
32
|
+
dirt.each do |m|
|
33
|
+
m.destroy
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def ssh
|
40
|
+
# TODO: Give this methos a good look over
|
41
|
+
pkey = user_keypairpath(@@global.user)
|
42
|
+
unless pkey
|
43
|
+
puts "No private key configured for #{@@global.user} in #{current_machine_group}"
|
44
|
+
end
|
45
|
+
|
46
|
+
# Options to be sent to Net::SSH
|
47
|
+
ssh_opts = { :user => @@global.user || Rudy.sysinfo.user, :debug => nil }
|
48
|
+
if pkey
|
49
|
+
raise "Cannot find file #{pkey}" unless File.exists?(pkey)
|
50
|
+
raise InsecureKeyPermissions, @pkey unless File.stat(pkey).mode == 33152
|
51
|
+
ssh_opts[:keys] = pkey
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
# The user specified a command to run. We won't create an interactive
|
56
|
+
# session so we need to prepare the command and its arguments
|
57
|
+
if @argv.first
|
58
|
+
command, command_args = @argv.shift, @argv || []
|
59
|
+
puts "#{command} #{command_args.join(' ')}" if @@global.verbose > 1
|
60
|
+
|
61
|
+
# otherwise, we'll open an ssh session or print command
|
62
|
+
else
|
63
|
+
command, command_args = :interactive_ssh, @option.print.nil?
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
checked = false
|
68
|
+
rudy = Rudy::Machines.new
|
69
|
+
lt = rudy.list do |machine|
|
70
|
+
# Print header
|
71
|
+
if @@global.quiet
|
72
|
+
print "You are #{ssh_opts[:user].to_s.bright}. " if !checked # only the 1st
|
73
|
+
else
|
74
|
+
print "Connecting #{ssh_opts[:user].to_s.bright}@#{machine.dns_public} "
|
75
|
+
puts "#{machine.name} (#{machine.awsid})"
|
76
|
+
end
|
77
|
+
|
78
|
+
# Make sure we want to run this command on all instances
|
79
|
+
if !checked && command != :interactive_ssh
|
80
|
+
execute_check(:medium) if ssh_opts[:user] == "root"
|
81
|
+
checked = true
|
82
|
+
end
|
83
|
+
|
84
|
+
# Open the connection and run the command
|
85
|
+
rbox = Rye::Box.new(machine.dns_public, ssh_opts)
|
86
|
+
ret = rbox.send(command, command_args)
|
87
|
+
puts ret unless command == :interactive_ssh
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/rudy/cli/routines.rb
CHANGED
@@ -1,80 +1,57 @@
|
|
1
1
|
|
2
|
-
module Rudy
|
3
|
-
module CLI
|
4
|
-
class Routines < Rudy::CLI::Base
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
rroutine = Rudy::Routines::Startup.new(:config => @config, :global => @global)
|
19
|
-
instances = rroutine.startup(opts)
|
20
|
-
|
21
|
-
puts "Done!"
|
3
|
+
module Rudy; module CLI;
|
4
|
+
class Routines < Rudy::CLI::CommandBase
|
5
|
+
|
6
|
+
def startup
|
7
|
+
rr = Rudy::Routines::Startup.new
|
8
|
+
rr.execute
|
9
|
+
|
10
|
+
puts $/, "The following machines are now available:"
|
11
|
+
rmach = Rudy::Machines.new
|
12
|
+
rmach.list do |machine|
|
13
|
+
puts machine.to_s
|
22
14
|
end
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
shutdown_valid?
|
15
|
+
|
16
|
+
if @@global.environment == @@config.default.environment &&
|
17
|
+
@@global.role == @@config.default.role
|
18
|
+
puts
|
19
|
+
puts "Try: #{$0} -u root ssh"
|
29
20
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
@list.each do |id, inst|
|
50
|
-
execute_routines(@list.values, :restart, :after)
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def release
|
25
|
+
rr = Rudy::Routines::Release.new
|
26
|
+
rmach = Rudy::Machines.new
|
27
|
+
startup unless rmach.running?
|
28
|
+
rr.execute
|
29
|
+
end
|
30
|
+
|
31
|
+
def shutdown
|
32
|
+
rr = Rudy::Routines::Shutdown.new
|
33
|
+
routine = fetch_routine_config(:shutdown)
|
34
|
+
|
35
|
+
puts "All machines in #{current_machine_group} will be shutdown and"
|
36
|
+
if routine && routine.disks
|
37
|
+
if routine.disks.destroy
|
38
|
+
puts "the following filesystems will be destroyed:".color(:red)
|
39
|
+
puts routine.disks.destroy.keys.join($/).bright
|
51
40
|
end
|
52
|
-
|
53
|
-
puts "Done!"
|
54
41
|
end
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
def shutdown_valid?
|
61
|
-
raise "Cannot specify both instance ID and group name" if @argv.awsid && @option.group
|
62
|
-
raise "I will not help you ruin production!" if @global.environment == "prod" # TODO: use_caution?, locked?
|
63
|
-
true
|
64
|
-
end
|
65
|
-
def shutdown
|
66
|
-
puts "Shutting down a machine group".bright
|
67
|
-
opts = {}
|
68
|
-
opts[:group] = @option.group if @option.group
|
69
|
-
opts[:id] = @argv.awsid if @argv.awsid
|
70
|
-
opts[:id] &&= [opts[:id]].flatten
|
71
42
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
43
|
+
execute_check :medium
|
44
|
+
|
45
|
+
rr.execute
|
46
|
+
|
47
|
+
rinst = Rudy::AWS::EC2::Instances.new(@@global.accesskey, @@global.secretkey, @@global.region)
|
48
|
+
lt = rinst.list_group(current_machine_group, :any) do |inst|
|
49
|
+
puts @@global.verbose > 0 ? inst.inspect : inst.dump(@@global.format)
|
77
50
|
end
|
51
|
+
puts "No instances running" if !lt || lt.empty?
|
78
52
|
end
|
53
|
+
|
54
|
+
|
79
55
|
end
|
80
|
-
end
|
56
|
+
end; end
|
57
|
+
|
data/lib/rudy/cli.rb
CHANGED
@@ -2,141 +2,156 @@
|
|
2
2
|
require 'drydock'
|
3
3
|
|
4
4
|
module Rudy
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
|
6
|
+
# = CLI
|
7
|
+
#
|
8
|
+
# These classes provide the functionality for the Command
|
9
|
+
# line interfaces. See the bin/ files if you're interested.
|
11
10
|
#
|
12
11
|
module CLI
|
13
12
|
class NoCred < RuntimeError #:nodoc
|
14
13
|
end
|
15
14
|
|
16
|
-
class
|
17
|
-
|
15
|
+
class Output < Storable
|
16
|
+
# TODO: Use for all CLI responses
|
17
|
+
# Messages and errors should be in @@global.format
|
18
|
+
# Should print messages as they come
|
19
|
+
end
|
20
|
+
|
21
|
+
class CommandBase < Drydock::Command
|
22
|
+
include Rudy::Huxtable
|
23
|
+
|
18
24
|
attr_reader :config
|
19
25
|
|
20
26
|
protected
|
21
27
|
def init
|
28
|
+
|
29
|
+
# The CLI wants output!
|
30
|
+
Rudy::Huxtable.update_logger STDOUT
|
22
31
|
|
23
|
-
#
|
24
|
-
|
25
|
-
Rudy.enable_quiet if @global.quiet
|
26
|
-
|
27
|
-
@config = Rudy::Config.new
|
28
|
-
@config.look_and_load(@global.config)
|
32
|
+
# Send The Huxtables the global values from the command-line
|
33
|
+
Rudy::Huxtable.update_global @global
|
29
34
|
|
30
|
-
unless
|
35
|
+
unless @@global.accesskey && @@global.secretkey
|
31
36
|
STDERR.puts "No AWS credentials. Check your configs!"
|
32
|
-
STDERR.puts "Try:
|
37
|
+
STDERR.puts "Try: rudy init"
|
33
38
|
exit 1
|
34
39
|
end
|
35
|
-
|
36
|
-
# EVERYTHING BELOW THIS LINE IS ATROCIOUS
|
37
|
-
|
38
|
-
# These are here so we can print the machine group shit in the header.
|
39
|
-
# The dupilcation annoys me (see Rudy::Huxtable#init_globals) and I'd
|
40
|
-
# like to find a cleaner solution.
|
41
|
-
if @config.defaults
|
42
|
-
@global.region ||= @config.defaults.region
|
43
|
-
@global.zone ||= @config.defaults.zone
|
44
|
-
@global.environment ||= @config.defaults.environment
|
45
|
-
@global.role ||= @config.defaults.role
|
46
|
-
@global.position ||= @config.defaults.position
|
47
|
-
@global.user ||= @config.defaults.user
|
48
|
-
end
|
49
40
|
|
50
|
-
|
51
|
-
|
52
|
-
@global.environment ||= DEFAULT_ENVIRONMENT
|
53
|
-
@global.role ||= DEFAULT_ROLE
|
54
|
-
@global.position ||= DEFAULT_POSITION
|
55
|
-
@global.user ||= DEFAULT_USER
|
56
|
-
|
57
|
-
|
58
|
-
if @global.verbose > 1
|
59
|
-
puts "CONFIGS: ", @config.paths, $/
|
60
|
-
|
61
|
-
puts "GLOBALS:"
|
62
|
-
@global.marshal_dump.each_pair do |n,v|
|
63
|
-
puts "#{n}: #{v}"
|
64
|
-
end
|
65
|
-
["machines", "routines"].each do |type|
|
66
|
-
puts "#{$/*2}#{type.upcase}:"
|
67
|
-
val = @config.send(type).find_deferred(@global.environment, @global.role)
|
68
|
-
puts val.to_hash.to_yaml if val
|
69
|
-
end
|
70
|
-
puts
|
71
|
-
end
|
72
|
-
|
73
|
-
if @global.environment =~ /^prod/ && Drydock.debug?
|
74
|
-
puts Rudy.banner("PRODUCTION ACCESS IS DISABLED IN DEBUG MODE")
|
41
|
+
if @@global.environment =~ /^prod/ && Drydock.debug?
|
42
|
+
puts Rudy::Utils.banner("PRODUCTION ACCESS IS DISABLED IN DEBUG MODE")
|
75
43
|
exit 1
|
76
44
|
end
|
77
|
-
|
78
|
-
|
79
|
-
# TODO: enforce home directory permissions
|
80
|
-
#if File.exists?(RUDY_CONFIG_DIR)
|
81
|
-
# puts "Checking #{check_environment} permissions..."
|
82
|
-
#end
|
83
45
|
|
84
46
|
end
|
85
47
|
|
48
|
+
def execute_action(emsg="Failed", &action)
|
49
|
+
begin
|
50
|
+
ret = action.call
|
51
|
+
raise emsg unless ret
|
52
|
+
ret
|
53
|
+
rescue Rudy::AWS::EC2::NoAMI => ex
|
54
|
+
raise Drydock::OptError.new('-a', @alias)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def execute_check(level=:medium)
|
59
|
+
ret = Annoy.are_you_sure?(level)
|
60
|
+
exit 0 unless ret
|
61
|
+
ret
|
62
|
+
end
|
86
63
|
|
87
64
|
# Print a default header to the screen for every command.
|
88
65
|
#
|
89
66
|
def print_header
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
67
|
+
|
68
|
+
# Send The Huxtables the global values again because they could be
|
69
|
+
# updated after initialization but before the command was executed
|
70
|
+
Rudy::Huxtable.update_global @global
|
71
|
+
|
72
|
+
puts Rudy::CLI.generate_header(@@global, @@config) if @@global.print_header
|
73
|
+
|
74
|
+
unless @@global.quiet
|
75
|
+
if @@global.environment == "prod"
|
95
76
|
msg = "YOU ARE PLAYING WITH PRODUCTION"
|
96
|
-
puts Rudy.banner(msg, :huge, :red), $/
|
77
|
+
puts Rudy::Utils.banner(msg, :huge, :red), $/
|
97
78
|
end
|
98
|
-
|
99
|
-
puts Rudy.banner("THIS IS EC2"), $/ if Rudy.in_situ?
|
79
|
+
puts Rudy::Utils.banner("THIS IS EC2"), $/ if Rudy.in_situ?
|
100
80
|
end
|
101
81
|
end
|
102
82
|
|
103
|
-
|
104
83
|
end
|
105
84
|
|
106
|
-
|
107
|
-
|
108
85
|
def self.generate_header(global, config)
|
86
|
+
return "" if global.quiet
|
109
87
|
header = StringIO.new
|
110
|
-
title = "RUDY v#{Rudy::VERSION}"
|
88
|
+
title, name = "RUDY v#{Rudy::VERSION}", config.accounts.aws.name
|
111
89
|
now_utc = Time.now.utc.strftime("%Y-%m-%d %H:%M:%S")
|
112
90
|
criteria = []
|
113
|
-
[:zone, :environment, :role, :position].each do |n|
|
114
|
-
val = global.send(n)
|
91
|
+
[:region, :zone, :environment, :role, :position].each do |n|
|
92
|
+
key, val = n.to_s.slice(0,1).att, global.send(n)
|
93
|
+
key = 'R' if n == :region
|
115
94
|
next unless val
|
116
|
-
criteria << "#{
|
95
|
+
criteria << "#{key.att}:#{val.to_s.bright}"
|
117
96
|
end
|
118
97
|
if config.accounts && config.accounts.aws
|
119
|
-
|
120
|
-
|
98
|
+
if global.verbose > 0
|
99
|
+
header.puts '%s -- %s -- %s UTC' % [title, name, now_utc]
|
100
|
+
end
|
101
|
+
header.puts '[%s]' % [criteria.join(" ")], $/
|
121
102
|
end
|
122
|
-
|
123
103
|
header.rewind
|
124
104
|
header.read
|
125
105
|
end
|
126
106
|
|
127
107
|
|
128
|
-
|
129
|
-
|
108
|
+
# A base for all Drydock executables (bin/rudy etc...).
|
109
|
+
class Base
|
110
|
+
extend Drydock
|
111
|
+
|
112
|
+
before do |obj|
|
113
|
+
# Don't print Rudy header unless requested to
|
114
|
+
obj.global.print_header = false if (obj.global.verbose == 0)
|
115
|
+
@start = Time.now
|
116
|
+
end
|
130
117
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
118
|
+
after do |obj|
|
119
|
+
if obj.global.verbose > 0
|
120
|
+
puts
|
121
|
+
@elapsed = Time.now - @start
|
122
|
+
puts "Elapsed: %.2f seconds" % @elapsed.to_f if @elapsed > 0.1
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
# These globals are used by all bin/ executables
|
128
|
+
global :A, :accesskey, String, "AWS Access Key"
|
129
|
+
global :S, :secretkey, String, "AWS Secret Access Key"
|
130
|
+
global :R, :region, String, "Amazon service region (ie: #{Rudy::DEFAULT_REGION})"
|
131
|
+
global :z, :zone, String, "Amazon Availability zone (ie: #{Rudy::DEFAULT_ZONE})"
|
132
|
+
global :u, :user, String, "Provide a username (ie: #{Rudy::DEFAULT_USER})"
|
133
|
+
global :k, :pkey, String, "Path to the private SSH key"
|
134
|
+
global :f, :format, String, "Output format"
|
135
|
+
global :n, :nocolor, "Disable output colors"
|
136
|
+
global :C, :config, String, "Specify another configuration file to read (ie: #{Rudy::CONFIG_FILE})"
|
137
|
+
global :Y, :yes, "Assume a correct answer to confirmation questions"
|
138
|
+
global :q, :quiet, "Run with less output"
|
139
|
+
global :v, :verbose, "Increase verbosity of output (i.e. -v or -vv or -vvv)" do
|
140
|
+
@verbose ||= 0
|
141
|
+
@verbose += 1
|
142
|
+
end
|
143
|
+
global :V, :version, "Display version number" do
|
144
|
+
puts "Rudy version: #{Rudy::VERSION}"
|
145
|
+
exit 0
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
|
136
151
|
end
|
137
|
-
|
138
|
-
puts "Error: #{ex.message}"
|
139
|
-
exit 1
|
152
|
+
|
140
153
|
end
|
141
154
|
|
155
|
+
Rudy::Utils.require_glob(RUDY_LIB, 'rudy', 'cli', '**', '*.rb')
|
156
|
+
|
142
157
|
|
data/lib/rudy/config/objects.rb
CHANGED
@@ -19,49 +19,11 @@ class Rudy::Config
|
|
19
19
|
end
|
20
20
|
|
21
21
|
class Routines < Caesars
|
22
|
+
|
23
|
+
forced_hash :create
|
24
|
+
forced_hash :destroy
|
25
|
+
forced_hash :restore
|
26
|
+
forced_hash :mount
|
22
27
|
|
23
|
-
def create(*args, &b)
|
24
|
-
hash_handler(:create, *args, &b)
|
25
|
-
end
|
26
|
-
def destroy(*args, &b)
|
27
|
-
hash_handler(:destroy, *args, &b)
|
28
|
-
end
|
29
|
-
def restore(*args, &b)
|
30
|
-
hash_handler(:restore, *args, &b)
|
31
|
-
end
|
32
|
-
def mount(*args, &b)
|
33
|
-
hash_handler(:mount, *args, &b)
|
34
|
-
end
|
35
|
-
|
36
|
-
#
|
37
|
-
# Force the specified keyword to always be treated as a hash.
|
38
|
-
# Example:
|
39
|
-
#
|
40
|
-
# startup do
|
41
|
-
# disks do
|
42
|
-
# create "/path/2" # Available as hash: [action][disks][create][/path/2] == {}
|
43
|
-
# create "/path/4" do # Available as hash: [action][disks][create][/path/4] == {size => 14}
|
44
|
-
# size 14
|
45
|
-
# end
|
46
|
-
# end
|
47
|
-
# end
|
48
|
-
#
|
49
|
-
def hash_handler(caesars_meth, *args, &b)
|
50
|
-
# TODO: Move to caesars
|
51
|
-
return @caesars_properties[caesars_meth] if @caesars_properties.has_key?(caesars_meth) && args.empty? && b.nil?
|
52
|
-
return nil if args.empty? && b.nil?
|
53
|
-
return method_missing(caesars_meth, *args, &b) if args.empty?
|
54
|
-
|
55
|
-
caesars_name = args.shift
|
56
|
-
|
57
|
-
prev = @caesars_pointer
|
58
|
-
@caesars_pointer[caesars_meth] ||= Caesars::Hash.new
|
59
|
-
hash = Caesars::Hash.new
|
60
|
-
@caesars_pointer = hash
|
61
|
-
b.call if b
|
62
|
-
@caesars_pointer = prev
|
63
|
-
@caesars_pointer[caesars_meth][caesars_name] = hash
|
64
|
-
@caesars_pointer = prev
|
65
|
-
end
|
66
28
|
end
|
67
29
|
end
|