sabat-rudy 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. data/CHANGES.txt +188 -0
  2. data/LICENSE.txt +19 -0
  3. data/README.rdoc +118 -0
  4. data/Rakefile +165 -0
  5. data/Rudyfile +184 -0
  6. data/bin/ird +153 -0
  7. data/bin/rudy +232 -0
  8. data/bin/rudy-ec2 +241 -0
  9. data/bin/rudy-s3 +79 -0
  10. data/bin/rudy-sdb +69 -0
  11. data/examples/README.md +10 -0
  12. data/examples/debian-sinatra-passenger/commands.rb +19 -0
  13. data/examples/debian-sinatra-passenger/machines.rb +32 -0
  14. data/examples/debian-sinatra-passenger/routines.rb +30 -0
  15. data/examples/debian-sinatra-thin/commands.rb +17 -0
  16. data/examples/debian-sinatra-thin/machines.rb +35 -0
  17. data/examples/debian-sinatra-thin/routines.rb +72 -0
  18. data/lib/rudy.rb +170 -0
  19. data/lib/rudy/aws.rb +75 -0
  20. data/lib/rudy/aws/ec2.rb +59 -0
  21. data/lib/rudy/aws/ec2/address.rb +157 -0
  22. data/lib/rudy/aws/ec2/group.rb +301 -0
  23. data/lib/rudy/aws/ec2/image.rb +168 -0
  24. data/lib/rudy/aws/ec2/instance.rb +438 -0
  25. data/lib/rudy/aws/ec2/keypair.rb +104 -0
  26. data/lib/rudy/aws/ec2/snapshot.rb +109 -0
  27. data/lib/rudy/aws/ec2/volume.rb +230 -0
  28. data/lib/rudy/aws/ec2/zone.rb +77 -0
  29. data/lib/rudy/aws/s3.rb +60 -0
  30. data/lib/rudy/aws/sdb.rb +312 -0
  31. data/lib/rudy/aws/sdb/error.rb +47 -0
  32. data/lib/rudy/cli.rb +186 -0
  33. data/lib/rudy/cli/aws/ec2/addresses.rb +105 -0
  34. data/lib/rudy/cli/aws/ec2/candy.rb +191 -0
  35. data/lib/rudy/cli/aws/ec2/groups.rb +118 -0
  36. data/lib/rudy/cli/aws/ec2/images.rb +185 -0
  37. data/lib/rudy/cli/aws/ec2/instances.rb +222 -0
  38. data/lib/rudy/cli/aws/ec2/keypairs.rb +53 -0
  39. data/lib/rudy/cli/aws/ec2/snapshots.rb +49 -0
  40. data/lib/rudy/cli/aws/ec2/volumes.rb +104 -0
  41. data/lib/rudy/cli/aws/ec2/zones.rb +22 -0
  42. data/lib/rudy/cli/aws/s3/buckets.rb +49 -0
  43. data/lib/rudy/cli/aws/s3/store.rb +22 -0
  44. data/lib/rudy/cli/aws/sdb/domains.rb +41 -0
  45. data/lib/rudy/cli/candy.rb +19 -0
  46. data/lib/rudy/cli/config.rb +81 -0
  47. data/lib/rudy/cli/disks.rb +58 -0
  48. data/lib/rudy/cli/machines.rb +114 -0
  49. data/lib/rudy/cli/routines.rb +108 -0
  50. data/lib/rudy/config.rb +116 -0
  51. data/lib/rudy/config/objects.rb +148 -0
  52. data/lib/rudy/global.rb +130 -0
  53. data/lib/rudy/guidelines.rb +18 -0
  54. data/lib/rudy/huxtable.rb +373 -0
  55. data/lib/rudy/machines.rb +281 -0
  56. data/lib/rudy/metadata.rb +51 -0
  57. data/lib/rudy/metadata/backup.rb +113 -0
  58. data/lib/rudy/metadata/backups.rb +65 -0
  59. data/lib/rudy/metadata/disk.rb +177 -0
  60. data/lib/rudy/metadata/disks.rb +67 -0
  61. data/lib/rudy/metadata/objectbase.rb +104 -0
  62. data/lib/rudy/mixins.rb +2 -0
  63. data/lib/rudy/mixins/hash.rb +25 -0
  64. data/lib/rudy/routines.rb +318 -0
  65. data/lib/rudy/routines/helper.rb +55 -0
  66. data/lib/rudy/routines/helpers/dependshelper.rb +34 -0
  67. data/lib/rudy/routines/helpers/diskhelper.rb +331 -0
  68. data/lib/rudy/routines/helpers/scmhelper.rb +39 -0
  69. data/lib/rudy/routines/helpers/scripthelper.rb +198 -0
  70. data/lib/rudy/routines/helpers/userhelper.rb +37 -0
  71. data/lib/rudy/routines/passthrough.rb +38 -0
  72. data/lib/rudy/routines/reboot.rb +75 -0
  73. data/lib/rudy/routines/release.rb +50 -0
  74. data/lib/rudy/routines/shutdown.rb +33 -0
  75. data/lib/rudy/routines/startup.rb +36 -0
  76. data/lib/rudy/scm.rb +75 -0
  77. data/lib/rudy/scm/git.rb +217 -0
  78. data/lib/rudy/scm/svn.rb +110 -0
  79. data/lib/rudy/utils.rb +365 -0
  80. data/rudy.gemspec +151 -0
  81. data/support/mailtest +40 -0
  82. data/support/randomize-root-password +45 -0
  83. data/support/rudy-ec2-startup +200 -0
  84. data/support/update-ec2-ami-tools +20 -0
  85. data/test/01_mixins/10_hash_test.rb +25 -0
  86. data/test/10_config/00_setup_test.rb +20 -0
  87. data/test/10_config/30_machines_test.rb +69 -0
  88. data/test/15_scm/00_setup_test.rb +20 -0
  89. data/test/15_scm/20_git_test.rb +61 -0
  90. data/test/20_sdb/00_setup_test.rb +16 -0
  91. data/test/20_sdb/10_domains_test.rb +115 -0
  92. data/test/25_ec2/00_setup_test.rb +29 -0
  93. data/test/25_ec2/10_keypairs_test.rb +41 -0
  94. data/test/25_ec2/20_groups_test.rb +131 -0
  95. data/test/25_ec2/30_addresses_test.rb +38 -0
  96. data/test/25_ec2/40_volumes_test.rb +49 -0
  97. data/test/25_ec2/50_snapshots_test.rb +74 -0
  98. data/test/26_ec2_instances/00_setup_test.rb +28 -0
  99. data/test/26_ec2_instances/10_instances_test.rb +83 -0
  100. data/test/26_ec2_instances/50_images_test.rb +13 -0
  101. data/test/30_sdb_metadata/00_setup_test.rb +21 -0
  102. data/test/30_sdb_metadata/10_disks_test.rb +109 -0
  103. data/test/30_sdb_metadata/20_backups_test.rb +102 -0
  104. data/test/coverage.txt +51 -0
  105. data/test/helper.rb +36 -0
  106. metadata +276 -0
data/Rudyfile ADDED
@@ -0,0 +1,184 @@
1
+ # = Rudy -- Skeleton configuration
2
+ #
3
+ # Rudy automatically looks for configuration files in the following
4
+ # locations (in this order):
5
+ #
6
+ # ./.rudy/config
7
+ # ~/.rudy/config
8
+ #
9
+ # ./Rudyfile
10
+ # ./machines.rb, ./routines.rb, ./commands.rb
11
+ # ./config/rudy/*.rb
12
+ # ./.rudy/*.rb
13
+ # /etc/rudy/*.rb
14
+ #
15
+ # When multuple files are found, the configuration is NOT OVERRIDDEN,
16
+ # it's ADDED or APPENDED depending on context. This means you can split
17
+ # configuration across many files as you please.
18
+ #
19
+ # There are four sections: accounts, defaults, machines, commands and routines.
20
+ #
21
+ # By convention, accounts and defaults go in ~/.rudy/config or ./.rudy/config
22
+ # machines, commands and routines configuration go in ./Rudyfile or into
23
+ # separate files in ./.rudy or ./config/rudy (machines.rb, commands.rb, ...)
24
+ #
25
+
26
+ # --------------------------------------------------------- MACHINES --------
27
+ # The machines block describes the "physical" characteristics of your machines.
28
+ machines do
29
+
30
+ zone :"us-east-1b" do
31
+ ami 'ami-e348af8a' # Alestic Debian 5.0, 32-bit (US)
32
+ end
33
+ zone :"eu-west-1b" do
34
+ ami 'ami-6ecde51a' # Alestic Debian 5.0, 32-bit (EU)
35
+ end
36
+
37
+ hostname :rudy # One of: :default, :rudy, "your-name"
38
+
39
+ # We've defined an environment called "stage" with one role: "app".
40
+ # The configuration inside the env block is available to all its
41
+ # roles. The configuration inside the role blocks is available only
42
+ # to machines in that specific role.
43
+ env :stage, :prod do
44
+ size 'm1.small' # EC2 machine type for all machines
45
+ # in the "stage" environment
46
+ role :app do
47
+ positions 1 # Only 1 machine in stage-app
48
+ #addresses '11.22.33.44' # Define an elastic IP to reuse
49
+
50
+ disks do # Define EBS volumes
51
+ path "/rudy/disk1" do # The paths can be anything but
52
+ size 2 # they must be unique.
53
+ device "/dev/sdr" # Devices must be unique too.
54
+ end
55
+ end
56
+ end
57
+
58
+ role :db do # You can define as many roles
59
+ end # as you like. These are just
60
+ role :balancer do # a couple examples.
61
+ end
62
+
63
+ users do # Specify existing private keys per user
64
+ #root do
65
+ # keypair "/path/2/private-key"
66
+ #end
67
+ end
68
+
69
+ end
70
+
71
+ # The routines section below contains calls to local and remote
72
+ # scripts. The config contained in this block is made available
73
+ # those scripts in the form of a yaml file. The file is called
74
+ # rudy-config.yml.
75
+ config do
76
+ dbmaster 'localhost'
77
+ newparam 573114
78
+ end
79
+ end
80
+
81
+
82
+ # ----------------------------------------------------------- COMMANDS --------
83
+ # The commands block defines shell commands that can be used in routines. The
84
+ # ones defined here are added to the default list defined by Rye::Cmd (Rudy
85
+ # executes all SSH commands via Rye).
86
+ #
87
+ # Usage:
88
+ #
89
+ # allow COMMAND-NAME
90
+ # allow COMMAND-NAME, '/path/2/COMMAND'
91
+ # allow COMMAND-NAME, '/path/2/COMMAND', 'default argument', 'another arg'
92
+ #
93
+ commands do
94
+ allow :make
95
+ allow :gem_install, "/usr/bin/gem", "install", :V, "--no-rdoc", "--no-ri"
96
+ allow :apt_get, "/usr/bin/apt-get", :y, :q
97
+ end
98
+
99
+
100
+ # ----------------------------------------------------------- ROUTINES --------
101
+ # The routines block describes the repeatable processes for each machine group.
102
+ # To run a routine, specify its name on the command-line: rudy startup
103
+ routines do
104
+
105
+ env :stage, :prod do # We'll define routines for the stage-app
106
+ role :app do # and prod-app machine groups
107
+
108
+ startup do # $ rudy startup
109
+ adduser :rudy # Create a user called "rudy"
110
+ authorize :rudy # Enable passwordless logins as rudy
111
+ #
112
+ disks do # Define EBS volume routines
113
+ create "/rudy/disk1" # Create an EBS volume, attach it, give
114
+ end # it a filesystem, and mount it.
115
+ #
116
+ after :rudy do # Run remote SSH commands after startup
117
+ mkdir :p, "great" # $ mkdir -p great
118
+ touch "great/scott" # $ touch great/scott
119
+ ls :l, :a # $ ls -l -a
120
+ end
121
+ end
122
+
123
+ shutdown do # $ rudy shutdown
124
+ before :root do # Run remote SSH commands before shutdown
125
+ uptime
126
+ end
127
+ disks do
128
+ destroy "/rudy/disk1" # Unmount and destroy the EBS volume
129
+ end
130
+ end
131
+
132
+ reboot do # $ rudy reboot
133
+ before :root do # Run any pre-reboot tasks like stopping
134
+ uptime # web servers and databases.
135
+ end #
136
+ after :root do # Run any startup tasks like starting
137
+ uptime # processes or initializing the filesystem
138
+ end
139
+ end
140
+
141
+ backup do # $ rudy backup
142
+ disks do # A simple routine that creates an EBS
143
+ snapshot "/rudy/disk1" # snapshot of the specified volume.
144
+ end
145
+ end
146
+
147
+ restore_example do # $ rudy restore_example
148
+ disks do # A contrived example of restoring a
149
+ destroy "/rudy/disk1" # disk from a backup. NOTE: You'll need
150
+ restore "/rudy/disk1" # to run "rudy backup" at least once
151
+ end # before otherise there are no backups
152
+ end # to restore from.
153
+
154
+ end
155
+ end
156
+
157
+ # Define global routines available to all machine groups
158
+ # This routine will update a basic Debian machine and
159
+ # install essential libraries.
160
+ # See examples/ for more.
161
+ sysupdate do # $ rudy sysupdate
162
+ before :root do
163
+ apt_get "update" # Update debian / ubuntu
164
+ apt_get "install", "build-essential", "sqlite3", "libsqlite3-dev"
165
+ apt_get "install", "apache2-prefork-dev", "libapr1-dev"
166
+ gem_install 'rudy'
167
+ end
168
+ end
169
+
170
+ anything do # $ rudy anything
171
+ before :display_uptime # Specify a dependency
172
+ script :rudy do # This is Ruby, so any valid syntax
173
+ ls :l # can be used in the definitions.
174
+ end # See: SysInfo gem for more info.
175
+ end
176
+
177
+ display_uptime do # $ rudy display-uptime
178
+ script :rudy do # NOTE: You can use 'dashes' on the
179
+ uptime # command-line instead of underscores
180
+ end
181
+ end
182
+
183
+ end
184
+
data/bin/ird ADDED
@@ -0,0 +1,153 @@
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
+ class RudyCLI_Interactive < Rudy::CLI::Base # :nodoc:all
26
+
27
+ include Readline
28
+
29
+ default :interactive
30
+ debug :off
31
+ about "An interactive REPL for Rudy."
32
+ usage "#{$0} [global options]"
33
+ command :interactive do |obj|
34
+
35
+ @@rmach = Rudy::Machines.new(:global => obj.global)
36
+ @@rkey = Rudy::KeyPairs.new(:global => obj.global)
37
+ @@rgrp = Rudy::Groups.new(:global => obj.global)
38
+ @@rvol = Rudy::Volumes.new(:global => obj.global)
39
+ @@radd = Rudy::Addresses.new(:global => obj.global)
40
+
41
+ puts Rudy::CLI.generate_header(@@rmach.global, @@rmach.config)
42
+ puts Rudy::Utils.without_indent(%Q`
43
+ ------------------------------------------------------------
44
+ Welcome Interactive Rudy! (EXPERIMENTAL)
45
+ ------------------------------------------------------------
46
+
47
+ `)
48
+ h
49
+
50
+ # What's the deal with this error message when defining a help method?
51
+ # => rb: warn: can't alias help from irb_help
52
+ if __FILE__ == $0
53
+ IRB.start(__FILE__)
54
+ else
55
+ # check -e option
56
+ if /^-e$/ =~ $0
57
+ IRB.start(__FILE__)
58
+ else
59
+ IRB.start(__FILE__)
60
+ end
61
+ end
62
+
63
+ end
64
+
65
+
66
+
67
+
68
+ def h;
69
+ puts (%Q`
70
+ HELP
71
+
72
+ h Help (this screen)
73
+ m Rudy::Machines instance
74
+ g Rudy::Groups instance
75
+ k Rudy::KeyPairs instance
76
+ v Rudy::Volumes instance
77
+ a Rudy::Addresses instance
78
+ ssh [GROUP] Connect to a machine
79
+ example Start an EC2 instance from scratch.
80
+ `)
81
+ end
82
+ def example
83
+ puts (%Q`
84
+ EXAMPLE
85
+ Start an EC2 instance from scratch.
86
+
87
+ # Create a security group
88
+ >> g.create
89
+ => #<Rudy::AWS::EC2::Group @name="stage-app" ...>
90
+
91
+ # Create a keypair (used to login as root)
92
+ >> k.create
93
+ => #<Rudy::AWS::EC2::KeyPair @name="key-stage-app" ...>
94
+
95
+ # Start an EC2 machine instance:
96
+ >> m.create
97
+ Instance: i-228def51
98
+ Waiting for the instance to startup
99
+ ........It's up!
100
+
101
+ # Login to the new instance
102
+ >> ssh
103
+
104
+ All commands in Rudy refer to the global defaults unless
105
+ otherwise specified. "stage" is the default environment and
106
+ "app" is the default role. You can change these with command
107
+ line arguments or by modifying the defaults in your Rudy
108
+ config file: #{@@rmach.config_dirname}
109
+
110
+ You can also specify your own names by providing
111
+ one as the first argument: g.create 'group5000'.
112
+
113
+ # List instances in stage-app
114
+ >> m.list :running
115
+ => [#<Rudy::AWS::EC2::Instance:0x18c5888 ...>]
116
+
117
+ # Print the instance in a human readable way
118
+ >> puts m.list.first.to_s
119
+
120
+ # Print instance system console output
121
+ >> puts m.console
122
+
123
+ # Destroy ALL INSTANCES in stage-app
124
+ >> m.destroy
125
+ `)
126
+ end
127
+
128
+ def m; @@rmach; end
129
+ def k; @@rkey; end
130
+ def g; @@rgrp; end
131
+ def v; @@rvol; end
132
+ def a; @@radd; end
133
+
134
+ # Change Group
135
+ #def cg(name); end
136
+
137
+ def ssh(*args)
138
+ @@rmach.switch_user :root
139
+ @@rmach.connect(*args)
140
+ @@rmach.switch_user # back to previous user
141
+ nil
142
+ end
143
+
144
+
145
+ end
146
+
147
+ #include RudyCLI_Interactive # So we don't have to say CLI.example in the REPL.
148
+
149
+
150
+ __END__
151
+ #@rbox = Rye::Box.new('ec2-174-129-173-3.compute-1.amazonaws.com', 'root')
152
+ #@rbox2 = Rye::Box.new('ec2-174-129-173-3.compute-1.amazonaws.com', 'root')
153
+ #@rbox.add_keys('/Users/delano/Projects/git/rudy/.rudy/key-test-app.private')
data/bin/rudy ADDED
@@ -0,0 +1,232 @@
1
+ #!/usr/bin/ruby
2
+
3
+
4
+ # = Rudy
5
+ #
6
+ # === Not your granparent's deployment tool
7
+ #
8
+ # See rudy -h for usage
9
+ #
10
+
11
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib') # Put our local lib in first place
12
+ $:.unshift File.join(File.dirname(__FILE__), '..', '..', 'drydock', 'lib')
13
+ require 'rubygems'
14
+
15
+ #$SAFE = 1 # require is unsafe in Ruby 1.9??
16
+
17
+ require 'drydock'
18
+ require 'rudy'
19
+ require 'rudy/cli'
20
+
21
+ # Command-line interface for /bin/rudy
22
+ class RudyCLI < Rudy::CLI::Base
23
+
24
+ debug :on
25
+ default :machines
26
+ trawler :passthrough
27
+
28
+ # ------------------------------------------ RUDY GLOBALS --------
29
+ # ------------------------------------------------------------------
30
+
31
+ global :e, :environment, String, "Connect to the specified environment (ie: #{Rudy::DEFAULT_ENVIRONMENT})"
32
+ global :r, :role, String, "Connect to a machine with the specified role (ie: #{Rudy::DEFAULT_ROLE})"
33
+ global :p, :position, String, "Position in the machine in its group (ie: #{Rudy::DEFAULT_POSITION})"
34
+
35
+
36
+ # ------------------------------------------ RUDY OBJECTS --------
37
+ # ------------------------------------------------------------------
38
+
39
+ about "View Machines"
40
+ option :l, :all, "Display all machines"
41
+ action :W, :wash, "Wash machine metadata."
42
+ command :machines => Rudy::CLI::Machines
43
+ command_alias :machines, :m
44
+
45
+ about "View Disks"
46
+ action :W, :wash, "Wash disk metadata."
47
+ option :b, :backups, "Display backups"
48
+ option :l, :all, "Display all disks"
49
+ command :disks => Rudy::CLI::Disks
50
+ command_alias :disks, :d
51
+
52
+ about "Log in to a machine"
53
+ command :ssh => Rudy::CLI::Machines
54
+
55
+ #about "Open the machine in your default browser (OSX only)"
56
+ #option :s, :https, "Use HTTPS"
57
+ #option :p, :port, Integer, "Port"
58
+ #command :open => Rudy::CLI::Candy
59
+
60
+
61
+ # ----------------------------------------- RUDY ROUTINES --------
62
+ # ------------------------------------------------------------------
63
+
64
+ # A "do nothing" routine. Passthrough simply executes a routine
65
+ # config block. Drydock's trawler uses this for unknown commands.
66
+ about "A skeleton routine"
67
+ command :passthrough => Rudy::CLI::Routines
68
+
69
+ about "Startup a machine group"
70
+ usage "rudy startup"
71
+ command :startup => Rudy::CLI::Routines
72
+
73
+ about "Shutdown a machine group"
74
+ usage "rudy shutdown"
75
+ command :shutdown => Rudy::CLI::Routines
76
+
77
+ about "Reboot a machine group"
78
+ usage "rudy reboot"
79
+ command :reboot => Rudy::CLI::Routines
80
+
81
+ about "Create a release"
82
+ usage "rudy release"
83
+ command :release => Rudy::CLI::Routines
84
+ command_alias :release, :rerelease
85
+
86
+ #about "Update the release currently running in a machine group"
87
+ #command :rerelease => Rudy::CLI::Routines
88
+ #command_alias :rerelease, :rere
89
+
90
+ #about "Deploy disk snapshots from one machine to another"
91
+ #command :deploy => Rudy::CLI::Routines
92
+
93
+
94
+ # ------------------------------------ RUDY MISCELLANEOUS --------
95
+ # ------------------------------------------------------------------
96
+
97
+ usage "rudy [-f config-file] config [param-name]"
98
+ about "Check Rudy configuration."
99
+ option :l, :all, "Display all configs for all machines"
100
+ option :commands, "Display commands configuration"
101
+ option :defaults, "Display defaults configuration"
102
+ option :machines, "Display machines configuration"
103
+ option :accounts, "Display accounts configuration"
104
+ option :routines, "Display routines configuration"
105
+ option :script, "Output configuration identical to what is provided to scripts called in routines"
106
+ option :project, "Output a skeleton Rudyfile"
107
+ #option :d, :defaults, "Display the default value for the supplied parameter"
108
+ #option :g, :group, String, "Display configuration for a specific group"
109
+ argv :name
110
+ command :config => Rudy::CLI::Config
111
+
112
+ command :print_global => Rudy::CLI::Config
113
+ command_alias :print_global, :global
114
+
115
+ about "Initialize Rudy configuration"
116
+ command :init do |obj|
117
+
118
+ Rudy::Huxtable.update_config
119
+
120
+ unless File.exists?(Rudy::CONFIG_FILE)
121
+ Rudy::Config.init_config_dir
122
+ end
123
+
124
+ begin
125
+
126
+ unless Rudy::Huxtable.domain_exists?
127
+ puts "Creating SimpleDB domain #{Rudy::Huxtable.domain}"
128
+ Rudy::Huxtable.create_domain
129
+ puts "Initialized"
130
+ else
131
+ puts "Already Initialized"
132
+ end
133
+
134
+ rescue Rudy::AWS::SDB::NoSecretKey,
135
+ Rudy::AWS::SDB::NoAccessKey,
136
+ Rudy::NoConfig => ex
137
+ puts "AWS credentials must be configured to continue."
138
+ puts "You can modify these in #{Rudy::CONFIG_FILE}"
139
+ exit 1
140
+ end
141
+
142
+ obj.global.quiet = true # don't print elapsed time
143
+ end
144
+
145
+ about "Display time (in UTC)"
146
+ option :l, :local, "Display local time"
147
+ command :time do |obj|
148
+ t = obj.option.local ? Time.now : Time.now.utc
149
+ puts '%s' % t.strftime("%Y-%m-%d %T %Z (%z)")
150
+ end
151
+
152
+ usage "rudy myaddress [-i] [-e]"
153
+ about "Displays you current internal and external IP addresses"
154
+ option :e, :external, "Display only external IP address"
155
+ option :i, :internal, "Display only internal IP address"
156
+ command :myaddress do |obj|
157
+ ea = Rudy::Utils::external_ip_address || ''
158
+ ia = Rudy::Utils::internal_ip_address || ''
159
+ if obj.global.quiet
160
+ puts ia unless obj.option.external && !obj.option.internal
161
+ puts ea unless obj.option.internal && !obj.option.external
162
+ else
163
+ puts "%10s: %s" % ['Internal', ia] unless obj.option.external && !obj.option.internal
164
+ puts "%10s: %s" % ['External', ea] unless obj.option.internal && !obj.option.external
165
+ end
166
+ obj.global.quiet = true # don't print elapsed time
167
+ end
168
+
169
+ usage "rudy [global options] annoy [-h -m -l] [-e]"
170
+ about "Play around with Rudy's annoying challenges"
171
+ option :s, :string, "A numeric challenge"
172
+ option :n, :numeric, "A numeric challenge"
173
+ option :i, :insane, "Insane annoyance factor"
174
+ option :h, :high, "High annoyance factor"
175
+ option :m, :medium, "Medium annoyance factor"
176
+ option :l, :low, "Low annoyance factor"
177
+ option :r, :rand, "Random challenge type"
178
+ command :annoy do |obj|
179
+ srand(Time.now.to_f)
180
+ flavor = [:numeric, :string, :rand].detect { |v| obj.option.send(v) } || :string
181
+ factor = [:insane, :high, :medium, :low].detect { |v| obj.option.send(v) } || :medium
182
+ success = Annoy.challenge?("Is this annoying?", factor, flavor)
183
+ puts (success ? "Correct!" : "WRONG!").bright
184
+ obj.global.quiet = true # don't print elapsed time
185
+ end
186
+
187
+ about "Display the current Rudy slogan"
188
+ command :slogan do |obj|
189
+ puts "Rudy: Not your grandparent's deployment tool!"
190
+ obj.global.quiet = true # don't print elapsed time
191
+ end
192
+
193
+ about "Generates a configuration template to #{Rudy::CONFIG_FILE}"
194
+ command :generate_config do |obj|
195
+ unless File.exists?(Rudy::CONFIG_FILE)
196
+ Rudy::Config.init_config_dir
197
+ puts "Add your AWS credentials to #{Rudy::CONFIG_FILE}"
198
+ else
199
+ puts "#{Rudy::CONFIG_FILE} already exists"
200
+ end
201
+ end
202
+
203
+
204
+ command :sysinfo do
205
+ puts Rudy.sysinfo.to_yaml
206
+ end
207
+ end
208
+
209
+ # We call Drydock specifically otherwise it will run at_exit. Rye also
210
+ # uses at_exit for shutting down the ssh-agent. Ruby executes at_exit
211
+ # blocks in reverse order so if Drydock is required first, it's block
212
+ # will run after Rye shuts down the ssh-agent.
213
+ begin
214
+ Drydock.run!(ARGV, STDIN) if Drydock.run? && !Drydock.has_run?
215
+
216
+ rescue Drydock::ArgError, Drydock::OptError => ex
217
+ STDERR.puts ex.message
218
+ STDERR.puts ex.usage
219
+ rescue Drydock::InvalidArgument => ex
220
+ STDERR.puts ex.message
221
+ rescue Rudy::Error => ex
222
+ STDERR.puts ex.message
223
+ STDERR.puts ex.backtrace if Drydock.debug?
224
+ rescue => ex
225
+ STDERR.puts "ERROR (#{ex.class.to_s}): #{ex.message}"
226
+ STDERR.puts ex.backtrace if Drydock.debug?
227
+ rescue Interrupt
228
+ puts "#{$/}Exiting... "
229
+ exit 1
230
+ rescue SystemExit
231
+ # Don't balk
232
+ end