rudy 0.4.0 → 0.6.0

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.
Files changed (135) hide show
  1. data/CHANGES.txt +54 -30
  2. data/README.rdoc +100 -12
  3. data/Rakefile +103 -8
  4. data/Rudyfile +119 -0
  5. data/bin/ird +175 -0
  6. data/bin/rudy +259 -156
  7. data/bin/rudy-ec2 +228 -95
  8. data/bin/rudy-s3 +76 -0
  9. data/bin/rudy-sdb +67 -0
  10. data/lib/annoy.rb +270 -0
  11. data/lib/console.rb +30 -9
  12. data/lib/escape.rb +305 -0
  13. data/lib/rudy.rb +151 -182
  14. data/lib/rudy/aws.rb +56 -49
  15. data/lib/rudy/aws/ec2.rb +47 -292
  16. data/lib/rudy/aws/ec2/address.rb +157 -0
  17. data/lib/rudy/aws/ec2/group.rb +301 -0
  18. data/lib/rudy/aws/ec2/image.rb +168 -0
  19. data/lib/rudy/aws/ec2/instance.rb +434 -0
  20. data/lib/rudy/aws/ec2/keypair.rb +104 -0
  21. data/lib/rudy/aws/ec2/snapshot.rb +98 -0
  22. data/lib/rudy/aws/ec2/volume.rb +230 -0
  23. data/lib/rudy/aws/ec2/zone.rb +77 -0
  24. data/lib/rudy/aws/s3.rb +54 -0
  25. data/lib/rudy/aws/sdb.rb +298 -0
  26. data/lib/rudy/aws/sdb/error.rb +46 -0
  27. data/lib/rudy/{metadata/backup.rb → backup.rb} +26 -51
  28. data/lib/rudy/cli.rb +157 -0
  29. data/lib/rudy/cli/aws/ec2/addresses.rb +105 -0
  30. data/lib/rudy/cli/aws/ec2/candy.rb +208 -0
  31. data/lib/rudy/cli/aws/ec2/groups.rb +121 -0
  32. data/lib/rudy/cli/aws/ec2/images.rb +196 -0
  33. data/lib/rudy/cli/aws/ec2/instances.rb +194 -0
  34. data/lib/rudy/cli/aws/ec2/keypairs.rb +53 -0
  35. data/lib/rudy/cli/aws/ec2/snapshots.rb +49 -0
  36. data/lib/rudy/cli/aws/ec2/volumes.rb +104 -0
  37. data/lib/rudy/cli/aws/ec2/zones.rb +22 -0
  38. data/lib/rudy/cli/aws/s3/buckets.rb +50 -0
  39. data/lib/rudy/cli/aws/s3/store.rb +22 -0
  40. data/lib/rudy/cli/aws/sdb/domains.rb +41 -0
  41. data/lib/rudy/cli/candy.rb +8 -0
  42. data/lib/rudy/{command → cli}/config.rb +34 -24
  43. data/lib/rudy/cli/disks.rb +35 -0
  44. data/lib/rudy/cli/machines.rb +94 -0
  45. data/lib/rudy/cli/routines.rb +57 -0
  46. data/lib/rudy/config.rb +77 -72
  47. data/lib/rudy/config/objects.rb +29 -0
  48. data/lib/rudy/disks.rb +248 -0
  49. data/lib/rudy/global.rb +121 -0
  50. data/lib/rudy/huxtable.rb +340 -0
  51. data/lib/rudy/machines.rb +245 -0
  52. data/lib/rudy/metadata.rb +123 -13
  53. data/lib/rudy/routines.rb +47 -0
  54. data/lib/rudy/routines/helpers/diskhelper.rb +101 -0
  55. data/lib/rudy/routines/helpers/scripthelper.rb +91 -0
  56. data/lib/rudy/routines/release.rb +34 -0
  57. data/lib/rudy/routines/shutdown.rb +57 -0
  58. data/lib/rudy/routines/startup.rb +58 -0
  59. data/lib/rudy/scm/svn.rb +1 -1
  60. data/lib/rudy/utils.rb +322 -4
  61. data/lib/storable.rb +26 -17
  62. data/lib/sysinfo.rb +274 -0
  63. data/lib/tryouts.rb +6 -13
  64. data/rudy.gemspec +128 -42
  65. data/support/randomize-root-password +45 -0
  66. data/support/rudy-ec2-startup +9 -9
  67. data/support/update-ec2-ami-tools +20 -0
  68. data/test/05_config/00_setup_test.rb +20 -0
  69. data/test/05_config/30_machines_test.rb +69 -0
  70. data/test/20_sdb/00_setup_test.rb +16 -0
  71. data/test/20_sdb/10_domains_test.rb +115 -0
  72. data/test/25_ec2/00_setup_test.rb +29 -0
  73. data/test/25_ec2/10_keypairs_test.rb +41 -0
  74. data/test/25_ec2/20_groups_test.rb +131 -0
  75. data/test/25_ec2/30_addresses_test.rb +38 -0
  76. data/test/25_ec2/40_volumes_test.rb +49 -0
  77. data/test/25_ec2/50_snapshots_test.rb +74 -0
  78. data/test/26_ec2_instances/00_setup_test.rb +28 -0
  79. data/test/26_ec2_instances/10_instances_test.rb +83 -0
  80. data/test/26_ec2_instances/50_images_test.rb +13 -0
  81. data/test/30_sdb_metadata/00_setup_test.rb +21 -0
  82. data/test/30_sdb_metadata/10_disks_test.rb +109 -0
  83. data/test/30_sdb_metadata/20_backups_test.rb +102 -0
  84. data/test/coverage.txt +51 -0
  85. data/test/helper.rb +36 -0
  86. data/vendor/highline-1.5.1/CHANGELOG +222 -0
  87. data/vendor/highline-1.5.1/INSTALL +35 -0
  88. data/vendor/highline-1.5.1/LICENSE +7 -0
  89. data/vendor/highline-1.5.1/README +63 -0
  90. data/vendor/highline-1.5.1/Rakefile +82 -0
  91. data/vendor/highline-1.5.1/TODO +6 -0
  92. data/vendor/highline-1.5.1/examples/ansi_colors.rb +38 -0
  93. data/vendor/highline-1.5.1/examples/asking_for_arrays.rb +18 -0
  94. data/vendor/highline-1.5.1/examples/basic_usage.rb +75 -0
  95. data/vendor/highline-1.5.1/examples/color_scheme.rb +32 -0
  96. data/vendor/highline-1.5.1/examples/limit.rb +12 -0
  97. data/vendor/highline-1.5.1/examples/menus.rb +65 -0
  98. data/vendor/highline-1.5.1/examples/overwrite.rb +19 -0
  99. data/vendor/highline-1.5.1/examples/page_and_wrap.rb +322 -0
  100. data/vendor/highline-1.5.1/examples/password.rb +7 -0
  101. data/vendor/highline-1.5.1/examples/trapping_eof.rb +22 -0
  102. data/vendor/highline-1.5.1/examples/using_readline.rb +17 -0
  103. data/vendor/highline-1.5.1/lib/highline.rb +758 -0
  104. data/vendor/highline-1.5.1/lib/highline/color_scheme.rb +120 -0
  105. data/vendor/highline-1.5.1/lib/highline/compatibility.rb +17 -0
  106. data/vendor/highline-1.5.1/lib/highline/import.rb +43 -0
  107. data/vendor/highline-1.5.1/lib/highline/menu.rb +395 -0
  108. data/vendor/highline-1.5.1/lib/highline/question.rb +463 -0
  109. data/vendor/highline-1.5.1/lib/highline/system_extensions.rb +193 -0
  110. data/vendor/highline-1.5.1/setup.rb +1360 -0
  111. data/vendor/highline-1.5.1/test/tc_color_scheme.rb +56 -0
  112. data/vendor/highline-1.5.1/test/tc_highline.rb +823 -0
  113. data/vendor/highline-1.5.1/test/tc_import.rb +54 -0
  114. data/vendor/highline-1.5.1/test/tc_menu.rb +429 -0
  115. data/vendor/highline-1.5.1/test/ts_all.rb +15 -0
  116. metadata +141 -38
  117. data/lib/aws_sdb.rb +0 -3
  118. data/lib/aws_sdb/error.rb +0 -42
  119. data/lib/aws_sdb/service.rb +0 -215
  120. data/lib/rudy/aws/simpledb.rb +0 -53
  121. data/lib/rudy/command/addresses.rb +0 -46
  122. data/lib/rudy/command/backups.rb +0 -175
  123. data/lib/rudy/command/base.rb +0 -841
  124. data/lib/rudy/command/deploy.rb +0 -12
  125. data/lib/rudy/command/disks.rb +0 -213
  126. data/lib/rudy/command/environment.rb +0 -73
  127. data/lib/rudy/command/groups.rb +0 -61
  128. data/lib/rudy/command/images.rb +0 -91
  129. data/lib/rudy/command/instances.rb +0 -85
  130. data/lib/rudy/command/machines.rb +0 -161
  131. data/lib/rudy/command/metadata.rb +0 -41
  132. data/lib/rudy/command/release.rb +0 -174
  133. data/lib/rudy/command/volumes.rb +0 -66
  134. data/lib/rudy/metadata/disk.rb +0 -138
  135. data/tryouts/console_tryout.rb +0 -91
data/bin/ird ADDED
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # = Interactive Rudy (experimental)
4
+ #
5
+ # === Not your granparent's deployment tool
6
+ #
7
+ # See ird -h for usage
8
+ #
9
+
10
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib') # Put our local lib in first place
11
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'vendor', 'highline-1.5.1', 'lib')
12
+ %w{drydock caesars rye}.each { |dir| $:.unshift File.join(File.dirname(__FILE__), '..', '..', dir, 'lib') }
13
+ require 'rubygems'
14
+
15
+ # SEE: http://github.com/rubyspec/matzruby/blob/a34130eb7c4ecc164115a59aa1b76c643bd98202/lib/irb/xmp.rb
16
+ # SEE: http://github.com/blackwinter/wirble/tree/master
17
+ require "irb"
18
+ require 'irb/completion'
19
+
20
+ require 'rudy'
21
+ require 'drydock'
22
+ require 'rudy/cli'
23
+
24
+
25
+ module RudyCLI_Interactive # :nodoc:all
26
+ extend self
27
+ extend Drydock
28
+ include Readline
29
+
30
+ global :A, :accesskey, String, "AWS Access Key"
31
+ global :S, :secretkey, String, "AWS Secret Access Key"
32
+ #global :R, :region, String, "Connect to a specific EC2 region (ie: #{Rudy::DEFAULT_REGION})"
33
+ #global :n, :nocolor, "Disable output colors"
34
+ global :f, :config, String, "Specify another configuration file to read (ie: #{Rudy::CONFIG_FILE})"
35
+ global :z, :zone, String, "Connect to a specific EC2 zone (ie: #{Rudy::DEFAULT_ZONE})"
36
+ global :e, :environment, String, "Connect to the specified environment (ie: #{Rudy::DEFAULT_ENVIRONMENT})"
37
+ global :r, :role, String, "Connect to a machine with the specified role (ie: #{Rudy::DEFAULT_ROLE})"
38
+ global :p, :position, String, "Position in the machine in its group (ie: #{Rudy::DEFAULT_POSITION})"
39
+ global :u, :user, String, "Provide a username (ie: #{Rudy::DEFAULT_USER})"
40
+ #global :q, :quiet, "Run with less output"
41
+ #global :v, :verbose, "Increase verbosity of output (i.e. -v or -vv or -vvv)" do
42
+ # @verbose ||= 0
43
+ # @verbose += 1
44
+ #end
45
+ global :V, :version, "Display version number" do
46
+ puts "Rudy version: #{Rudy::VERSION}"
47
+ exit 0
48
+ end
49
+
50
+
51
+ default :interactive
52
+ debug :off
53
+ desc "An interactive REPL for Rudy."
54
+ usage "#{$0} [global options]"
55
+ command :interactive do |obj|
56
+
57
+ @@rmach = Rudy::Machines.new(:global => obj.global)
58
+ @@rkey = Rudy::KeyPairs.new(:global => obj.global)
59
+ @@rgrp = Rudy::Groups.new(:global => obj.global)
60
+ @@rvol = Rudy::Volumes.new(:global => obj.global)
61
+ @@radd = Rudy::Addresses.new(:global => obj.global)
62
+
63
+ puts Rudy::CLI.generate_header(@@rmach.global, @@rmach.config)
64
+ puts Rudy::Utils.without_indent(%Q`
65
+ ------------------------------------------------------------
66
+ Welcome Interactive Rudy! (EXPERIMENTAL)
67
+ ------------------------------------------------------------
68
+
69
+ `)
70
+ h
71
+
72
+ # What's the deal with this error message when defining a help method?
73
+ # => rb: warn: can't alias help from irb_help
74
+ if __FILE__ == $0
75
+ IRB.start(__FILE__)
76
+ else
77
+ # check -e option
78
+ if /^-e$/ =~ $0
79
+ IRB.start(__FILE__)
80
+ else
81
+ IRB.start(__FILE__)
82
+ end
83
+ end
84
+
85
+ end
86
+
87
+
88
+
89
+
90
+ def h;
91
+ puts (%Q`
92
+ HELP
93
+
94
+ h Help (this screen)
95
+ m Rudy::Machines instance
96
+ g Rudy::Groups instance
97
+ k Rudy::KeyPairs instance
98
+ v Rudy::Volumes instance
99
+ a Rudy::Addresses instance
100
+ ssh [GROUP] Connect to a machine
101
+ example Start an EC2 instance from scratch.
102
+ `)
103
+ end
104
+ def example
105
+ puts (%Q`
106
+ EXAMPLE
107
+ Start an EC2 instance from scratch.
108
+
109
+ # Create a security group
110
+ >> g.create
111
+ => #<Rudy::AWS::EC2::Group @name="stage-app" ...>
112
+
113
+ # Create a keypair (used to login as root)
114
+ >> k.create
115
+ => #<Rudy::AWS::EC2::KeyPair @name="key-stage-app" ...>
116
+
117
+ # Start an EC2 machine instance:
118
+ >> m.create
119
+ Instance: i-228def51
120
+ Waiting for the instance to startup
121
+ ........It's up!
122
+
123
+ # Login to the new instance
124
+ >> ssh
125
+
126
+ All commands in Rudy refer to the global defaults unless
127
+ otherwise specified. "stage" is the default environment and
128
+ "app" is the default role. You can change these with command
129
+ line arguments or by modifying the defaults in your Rudy
130
+ config file: #{@@rmach.config_dirname}
131
+
132
+ You can also specify your own names by providing
133
+ one as the first argument: g.create 'group5000'.
134
+
135
+ # List instances in stage-app
136
+ >> m.list :running
137
+ => [#<Rudy::AWS::EC2::Instance:0x18c5888 ...>]
138
+
139
+ # Print the instance in a human readable way
140
+ >> puts m.list.first.to_s
141
+
142
+ # Print instance system console output
143
+ >> puts m.console
144
+
145
+ # Destroy ALL INSTANCES in stage-app
146
+ >> m.destroy
147
+ `)
148
+ end
149
+
150
+ def m; @@rmach; end
151
+ def k; @@rkey; end
152
+ def g; @@rgrp; end
153
+ def v; @@rvol; end
154
+ def a; @@radd; end
155
+
156
+ # Change Group
157
+ #def cg(name); end
158
+
159
+ def ssh(*args)
160
+ @@rmach.switch_user :root
161
+ @@rmach.connect(*args)
162
+ @@rmach.switch_user # back to previous user
163
+ nil
164
+ end
165
+
166
+
167
+ end
168
+
169
+ include CLI # So we don't have to say CLI.example in the REPL.
170
+
171
+
172
+ __END__
173
+ #@rbox = Rye::Box.new('ec2-174-129-173-3.compute-1.amazonaws.com', 'root')
174
+ #@rbox2 = Rye::Box.new('ec2-174-129-173-3.compute-1.amazonaws.com', 'root')
175
+ #@rbox.add_keys('/Users/delano/Projects/git/rudy/.rudy/key-test-app.private')
data/bin/rudy CHANGED
@@ -1,174 +1,277 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- # Rudy -- Your friend in staging and deploying to EC2
3
+
4
+ # = Rudy
5
+ #
6
+ # === Not your granparent's deployment tool
4
7
  #
5
8
  # See rudy -h for usage
6
9
  #
7
10
 
8
- RUDY_HOME = File.join(File.dirname(__FILE__), '..')
9
- RUDY_LIB = File.join(RUDY_HOME, 'lib')
10
- $:.unshift RUDY_LIB # Put our local lib in first place
11
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib') # Put our local lib in first place
12
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'vendor', 'highline-1.5.1', 'lib')
13
+ #%w{amazon-ec2 rye}.each { |dir| $:.unshift File.join(File.dirname(__FILE__), '..', '..', dir, 'lib') }
14
+ #require 'rubygems'
11
15
 
12
- require 'rubygems' if RUBY_VERSION < "1.9"
13
- require 'date'
14
- require 'drydock'
15
- extend Drydock
16
-
17
- project "Rudy" # This also runs require 'ruby'
18
-
19
- global :A, :accesskey, String, "AWS Access Key"
20
- global :S, :secretkey, String, "AWS Secret Access Key"
21
- #global :R, :region, String, "Connect to a specific EC2 region (ie: #{Rudy::DEFAULT_REGION})"
22
- global :f, :config, String, "Specify another configuration file to read (ie: #{Rudy::RUDY_CONFIG_FILE})"
23
- global :z, :zone, String, "Connect to a specific EC2 zone (ie: #{Rudy::DEFAULT_ZONE})"
24
- global :e, :environment, String, "Connect to the specified environment (ie: #{Rudy::DEFAULT_ENVIRONMENT})"
25
- global :r, :role, String, "Connect to a machine with the specified role (ie: #{Rudy::DEFAULT_ROLE})"
26
- global :p, :position, String, "Position in the machine in its group (ie: #{Rudy::DEFAULT_POSITION})"
27
- global :u, :user, String, "Provide a username (ie: #{Rudy::DEFAULT_USER})"
28
- global :q, :quiet, "Run with less output"
29
- global :v, :verbose, "Increase verbosity of output (i.e. -v or -vv or -vvv)" do
30
- @verbose ||= 0
31
- @verbose += 1
32
- end
33
- global :V, :version, "Display version number" do
34
- puts "Rudy version: #{Rudy::VERSION}"
35
- exit 0
36
- end
16
+ #$SAFE = 1 # require is unsafe in Ruby 1.9??
37
17
 
38
- #desc "Run this the first time you use Rudy (it's immutable so running it again does no harm)."
39
- #command :setup => Rudy::Command::Metadata
40
-
41
-
42
- # ------------------------------------ RUDY INFO COMMANDS --------
43
- # ------------------------------------------------------------------
44
-
45
- #usage "rudy info"
46
- #desc "Displays info about the current Rudy configuration"
47
- #command :info => Rudy::Command::Metadata
48
-
49
- usage "rudy [-f config-file] config [param-name]"
50
- desc "Check Rudy configuration."
51
- option :l, :all, "Display config settings for all machines"
52
- option :d, :defaults, "Display the default value for the supplied parameter"
53
- argv :name
54
- command :config => Rudy::Command::Config
55
-
56
- usage "rudy myaddress [-i] [-e]"
57
- desc "Displays you current internal and external IP addresses"
58
- option :e, :external, "Display only external IP address"
59
- option :i, :internal, "Display only internal IP address"
60
- command :myaddress do |obj|
61
- ea = Rudy::Utils::external_ip_address || ''
62
- ia = Rudy::Utils::internal_ip_address || ''
63
- if obj.global.quiet
64
- puts ia unless obj.option.external && !obj.option.internal
65
- puts ea unless obj.option.internal && !obj.option.external
66
- else
67
- puts "%10s: %s" % ['Internal', ia] unless obj.option.external && !obj.option.internal
68
- puts "%10s: %s" % ['External', ea] unless obj.option.internal && !obj.option.external
18
+ require 'drydock'
19
+ require 'rudy'
20
+ require 'rudy/cli'
21
+
22
+
23
+ # Command-line interface for /bin/rudy
24
+ class RudyCLI < Rudy::CLI::Base
25
+
26
+ # ------------------------------------------ RUDY GLOBALS --------
27
+ # ------------------------------------------------------------------
28
+
29
+ global :e, :environment, String, "Connect to the specified environment (ie: #{Rudy::DEFAULT_ENVIRONMENT})"
30
+ global :r, :role, String, "Connect to a machine with the specified role (ie: #{Rudy::DEFAULT_ROLE})"
31
+ global :p, :position, String, "Position in the machine in its group (ie: #{Rudy::DEFAULT_POSITION})"
32
+
33
+
34
+
35
+ # --------------------------------- RUDY MACHINE COMMANDS --------
36
+ # ------------------------------------------------------------------
37
+
38
+
39
+ #desc "Machine Status"
40
+ #usage "rudy [global options] status [-g group-name] [-s state] [--all] [instance-ID]"
41
+ #option :g, :group, String, "A security group name"
42
+ #option :s, :state, String, "Machine state. One of: running (default), pending, terminated"
43
+ #option :l, :all, "Show all machines in this group, regardless of state."
44
+ #argv :awsid
45
+ #command :status => Rudy::CLI::Machines
46
+ #
47
+ #usage "rudy [global options] connect [-g group-name] [-i instance-ID] [cmd]"
48
+ #desc "Open an SSH connection"
49
+ #option :print, "Only print the SSH command, don't connect"
50
+ #option :g, :group, String, "A security group name"
51
+ #option :i, :awsid, String, "An instance ID"
52
+ #argv :cmd
53
+ #command :connect => Rudy::CLI::Machines
54
+ #command_alias :connect, :ssh
55
+ #
56
+ #usage "rudy [global options] copy [-p] [-r] source target"
57
+ #desc "Copy files to or from machines. NOTE: You must use quotes when using a tilda for your remote dir ('~/')."
58
+ #option :r, :recursive, "Recursively copy entire directories"
59
+ #option :p, :preserve, "Preserve atimes and ctimes."
60
+ #option :d, :download, "Download FROM the remote machine to the local machine"
61
+ #option :print, "Only print the SSH command, don't connect"
62
+ #option :g, :group, String, "A security group name"
63
+ #option :i, :awsid, String, "An instance ID"
64
+ #command :copy => Rudy::CLI::Machines
65
+ #command_alias :copy, :scp
66
+ #command_alias :copy, :upload
67
+ #command_alias :copy, :download
68
+
69
+
70
+
71
+
72
+ # -------------------------------- MISCELLANEOUS COMMANDS --------
73
+ # ------------------------------------------------------------------
74
+
75
+ desc "Display time (in UTC)"
76
+ option :l, :local, "Display local time"
77
+ command :time do |obj|
78
+ t = obj.option.local ? Time.now : Time.now.utc
79
+ puts '%s' % t.strftime("%Y-%m-%d %T %Z (%z)")
80
+ end
81
+
82
+ usage "rudy [-f config-file] config [param-name]"
83
+ desc "Check Rudy configuration."
84
+ option :l, :all, "Display configs for all machines"
85
+ option :s, :script, "Output configuration identical to what is provided to scripts called in routines"
86
+ option :r, :rudy, "Output a skeleton Rudyfile"
87
+ option :d, :defaults, "Display the default value for the supplied parameter"
88
+ option :g, :group, String, "Display configuration for a specific group"
89
+ argv :name
90
+ command :config => Rudy::CLI::Config
91
+
92
+ usage "rudy myaddress [-i] [-e]"
93
+ desc "Displays you current internal and external IP addresses"
94
+ option :e, :external, "Display only external IP address"
95
+ option :i, :internal, "Display only internal IP address"
96
+ command :myaddress do |obj|
97
+ ea = Rudy::Utils::external_ip_address || ''
98
+ ia = Rudy::Utils::internal_ip_address || ''
99
+ if obj.global.quiet
100
+ puts ia unless obj.option.external && !obj.option.internal
101
+ puts ea unless obj.option.internal && !obj.option.external
102
+ else
103
+ puts "%10s: %s" % ['Internal', ia] unless obj.option.external && !obj.option.internal
104
+ puts "%10s: %s" % ['External', ea] unless obj.option.internal && !obj.option.external
105
+ end
106
+ obj.global.quiet = true # don't print elapsed time
69
107
  end
70
- end
71
-
72
-
73
-
74
- # ----------------------------- RUDY MAINTENANCE COMMANDS --------
75
- # ------------------------------------------------------------------
76
-
77
- usage "#{$/} [global options] disks [-C -p path -d device -s size] [-A] [-D] [disk name]"
78
- desc "Manage Disks"
79
- option :l, :all, "Display all disk definitions"
80
- option :p, :path, String, "The filesystem path to use as the mount point"
81
- option :d, :device, String, "The device id (default: /dev/sdh)"
82
- option :s, :size, Integer, "The size of disk (in GB)"
83
- action :C, :create, "Create a disk definition"
84
- action :D, :destroy, "Destroy a disk definition"
85
- action :A, :attach, "Attach a disk"
86
- action :N, :unattach, "Unattach a disk"
87
- argv :diskname
88
- command :disk => Rudy::Command::Disks
89
-
90
-
91
- usage "rudy [global options] backups [-C] [disk name]"
92
- desc "Manage Backups"
93
- option :s, :snapshot, String, "Create a backup entry from an existing snapshot"
94
- action :Z, :sync, "Check for and delete backup metadata with no snapshot. DOES NOT delete snapshots."
95
- #action :T, :tidy, "Tidy existing backups"
96
- action :D, :destroy, "Destroy a backup and DELETE its snapshots."
97
- action :C, :create, "Create a backup"
98
- argv :disk
99
- command :'backup' => Rudy::Command::Backups
100
- command_alias :backup, :bu
101
-
102
-
103
- usage "rudy [global options] metadata instance-ID"
104
- desc "Display Rudy metadata."
105
- command :metadata => Rudy::Command::Metadata
106
- command_alias :metadata, :md
107
-
108
-
109
- desc "Machine Group Status"
110
- command :status => Rudy::Command::Machines
111
-
112
-
113
- #desc "Update a Machine Group with the current version of Rudy"
114
- #command :update => Rudy::Command::Machines
115
-
116
-
117
- usage "rudy [-e env] [-u user] connect [-p] [cmd]"
118
- desc "Open an SSH connection"
119
- option :p, :print, "Only print the SSH command, don't connect"
120
- argv :cmd
121
- command :connect => Rudy::Command::Environment
122
- command_alias :connect, :ssh
123
-
124
- usage "rudy [-e env] [-u user] copy [-p] -r [from path] [to path]"
125
- desc "Copy files to or from machines. NOTE: You must use quotes when using a tilda for your remote dir ('~/')."
126
- option :r, :remote, "Copy FROM the remote machine to the local machine"
127
- option :p, :print, "Only print the SSH command, don't connect"
128
- argv :from, :to
129
- command :copy => Rudy::Command::Environment
130
- command_alias :copy, :scp
131
- command_alias :copy, :upload
132
- command_alias :copy, :download
133
-
134
-
135
- # -------------------------------- RUDY ROUTINES COMMANDS --------
136
- # ------------------------------------------------------------------
137
-
138
- desc "Shutdown a Machine Group"
139
- command :shutdown => Rudy::Command::Machines
140
-
141
- desc "Start a Machine Group"
142
- command :startup => Rudy::Command::Machines
143
- command_alias :startup, :start
144
-
145
- desc "Restart a Machine Group"
146
- command :restart => Rudy::Command::Machines
147
108
 
148
- desc "Release to a machine group"
149
- option :s, :switch, "Switch to the release branch/tag"
150
- option :m, :msg, String, "A short release note"
151
- command :release => Rudy::Command::Release
109
+ usage "rudy [global options] annoy [-h -m -l] [-e]"
110
+ desc "Play around with Rudy's annoying challenges"
111
+ option :s, :string, "A numeric challenge"
112
+ option :n, :numeric, "A numeric challenge"
113
+ option :i, :insane, "Insane annoyance factor"
114
+ option :h, :high, "High annoyance factor"
115
+ option :m, :medium, "Medium annoyance factor"
116
+ option :l, :low, "Low annoyance factor"
117
+ option :r, :rand, "Random challenge type"
118
+ command :annoy do |obj|
119
+ srand(Time.now.to_f)
120
+ flavor = [:numeric, :string, :rand].detect { |v| obj.option.send(v) } || :string
121
+ factor = [:insane, :high, :medium, :low].detect { |v| obj.option.send(v) } || :medium
122
+ success = Annoy.challenge?("Is this annoying?", factor, flavor)
123
+ puts (success ? "Correct!" : "WRONG!").bright
124
+ obj.global.quiet = true # don't print elapsed time
125
+ end
152
126
 
153
- desc "Update the release currently running in a machine group"
154
- command :rerelease => Rudy::Command::Release
155
- command_alias :rerelease, :rere
127
+ desc "Display the current Rudy slogan"
128
+ command :slogan do |obj|
129
+ puts "Rudy: Not your grandparent's deployment tool!"
130
+ obj.global.quiet = true # don't print elapsed time
131
+ end
156
132
 
157
- #desc "Deploy disk snapshots from one machine to another"
158
- #command :deploy => Rudy::Command::Deploy
133
+ desc "Generates a configuration template to #{Rudy::CONFIG_FILE}"
134
+ command :generate_config do |obj|
135
+ unless File.exists?(Rudy::CONFIG_FILE)
136
+ Rudy::Config.init_config_dir
137
+ puts "Add your AWS credentials to #{Rudy::CONFIG_FILE}"
138
+ else
139
+ puts "#{Rudy::CONFIG_FILE} already exists"
140
+ end
141
+ end
159
142
 
160
143
 
144
+ desc "Initialize Rudy configuration"
145
+ command :init do |obj|
146
+
147
+ unless File.exists?(Rudy::CONFIG_FILE)
148
+ Rudy::Config.init_config_dir
149
+ end
150
+
151
+ begin
152
+
153
+ unless Rudy::Huxtable.domain_exists?
154
+ puts "Creating SimpleDB domain #{Rudy::Huxtable.domain}"
155
+ Rudy::Huxtable.create_domain
156
+ puts "Initialized"
157
+ else
158
+ puts "Already Initialized"
159
+ end
160
+
161
+ rescue Rudy::AWS::SDB::NoSecretKey,
162
+ Rudy::AWS::SDB::NoAccessKey,
163
+ Rudy::NoConfig => ex
164
+ puts "AWS credentials must be configured to continue."
165
+ puts "You can modify these in #{Rudy::CONFIG_FILE}"
166
+ exit 1
167
+ end
168
+
169
+ obj.global.quiet = true # don't print elapsed time
170
+ end
161
171
 
162
172
 
163
- # ------------------------------------------- UGLY STUFFS --------
164
- # ------------------------------------------------------------------
165
- debug :on
166
- capture :stderr
167
- before do
168
- @start = Time.now
169
- end
170
- after do
171
- @elapsed = Time.now - @start
172
- puts $/, "Elapsed: %.2f seconds" % @elapsed.to_f if @elapsed > 0.1
173
+ # --------------------------------- RUDY MANAGER COMMANDS --------
174
+ # ------------------------------------------------------------------
175
+
176
+ #usage "rudy [global options] backups [-C] [disk name]"
177
+ #desc "Manage Backups"
178
+ #option :s, :snapshot, String, "Create a backup entry from an existing snapshot"
179
+ #action :Z, :sync, "Check for and delete backup metadata with no snapshot. DOES NOT delete snapshots."
180
+ ##action :T, :tidy, "Tidy existing backups"
181
+ #action :D, :destroy, "Destroy a backup and DELETE its snapshots."
182
+ #action :C, :create, "Create a backup"
183
+ #argv :disk
184
+ #command :'backup' => Rudy::CLI::Backups
185
+ #command_alias :backup, :bu
186
+
187
+ desc "Startup a machine group"
188
+ usage "rudy startup"
189
+ command :startup => Rudy::CLI::Routines
190
+ command_alias :startup, :s
191
+
192
+ desc "Shutdown a machine group"
193
+ usage "rudy shutdown"
194
+ command :shutdown => Rudy::CLI::Routines
195
+
196
+ desc "Create a release"
197
+ usage "rudy release"
198
+ command :release => Rudy::CLI::Routines
199
+ command_alias :release, :r
200
+
201
+ desc "Manage Machines"
202
+ action :W, :wash, "Wash machine metadata."
203
+ command :machines => Rudy::CLI::Machines
204
+ command_alias :machines, :m
205
+
206
+ desc "Log in to a machine"
207
+ command :ssh => Rudy::CLI::Machines
208
+
209
+ desc "Manage Disks"
210
+ action :W, :wash, "Wash disk metadata."
211
+ command :disks => Rudy::CLI::Disks
212
+ command_alias :disks, :d
213
+
214
+ # -------------------------- RUDY RELEASE/DEPLOY COMMANDS --------
215
+ # ------------------------------------------------------------------
216
+
217
+ #desc "Release to a Machine Group"
218
+ #option :g, :group, String, "A security group name"
219
+ #option :s, :switch, "Switch to the release branch/tag"
220
+ #option :m, :msg, String, "A short release note"
221
+ #command :release => Rudy::CLI::Release
222
+
223
+ #desc "Update the release currently running in a machine group"
224
+ #command :rerelease => Rudy::CLI::Release
225
+ #command_alias :rerelease, :rere
226
+
227
+ #desc "Deploy disk snapshots from one machine to another"
228
+ #command :deploy => Rudy::CLI::Deploy
229
+
230
+
231
+ #desc "Shutdown a Machine Group"
232
+ #usage "rudy [global options] shutdown [-g group-name] [instance-ID]"
233
+ #option :g, :group, String, "A security group name"
234
+ #argv :awsid
235
+ #command :shutdown => Rudy::CLI::Routines
236
+ #
237
+ #
238
+ #desc "Start a Machine Group"
239
+ #usage "rudy [global options] startup [-g group-name] [-i image-ID]"
240
+ #option :ami, String, "EC2 image ID (AMI)"
241
+ #option :g, :group, String, "A security group name"
242
+ #command :startup => Rudy::CLI::Routines
243
+ #command_alias :startup, :start
244
+
245
+ #desc "Restart a Machine Group"
246
+ #option :g, :group, String, "A security group name"
247
+ #argv :awsid
248
+ #command :restart => Rudy::CLI::Routines
249
+ #
250
+
251
+
252
+ # ------------------------------------------- UGLY STUFFS --------
253
+ # ------------------------------------------------------------------
254
+ debug :off
255
+ default :machines
256
+
257
+
258
+
173
259
  end
174
260
 
261
+ # We call Drydock specifically otherwise it will run at_exit. Rye also
262
+ # uses at_exit for shutting down the ssh-agent. Ruby executes at_exit
263
+ # blocks in reverse order so if Drydock is required first, it's block
264
+ # will run after Rye shuts down the ssh-agent.
265
+ begin
266
+ Drydock.run!(ARGV, STDIN) if Drydock.run? && !Drydock.has_run?
267
+ rescue Drydock::ArgError, Drydock::OptError=> ex
268
+ STDERR.puts ex.message
269
+ STDERR.puts ex.usage
270
+ rescue Rudy::Error => ex
271
+ STDERR.puts ex.message
272
+ rescue => ex
273
+ STDERR.puts "ERROR (#{ex.class.to_s}): #{ex.message}"
274
+ STDERR.puts ex.backtrace if Drydock.debug?
275
+ rescue SystemExit
276
+ # Don't balk
277
+ end