solutious-rudy 0.4.0 → 0.5.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 (99) hide show
  1. data/CHANGES.txt +8 -9
  2. data/README.rdoc +48 -7
  3. data/Rakefile +102 -7
  4. data/Rudyfile +28 -0
  5. data/bin/ird +162 -0
  6. data/bin/rudy +287 -93
  7. data/lib/annoy.rb +227 -0
  8. data/lib/aws_sdb/service.rb +1 -1
  9. data/lib/console.rb +20 -4
  10. data/lib/escape.rb +305 -0
  11. data/lib/rudy.rb +265 -125
  12. data/lib/rudy/aws.rb +61 -26
  13. data/lib/rudy/aws/ec2.rb +20 -296
  14. data/lib/rudy/aws/ec2/address.rb +121 -0
  15. data/lib/rudy/aws/ec2/group.rb +241 -0
  16. data/lib/rudy/aws/ec2/image.rb +46 -0
  17. data/lib/rudy/aws/ec2/instance.rb +407 -0
  18. data/lib/rudy/aws/ec2/keypair.rb +92 -0
  19. data/lib/rudy/aws/ec2/snapshot.rb +87 -0
  20. data/lib/rudy/aws/ec2/volume.rb +234 -0
  21. data/lib/rudy/aws/simpledb.rb +33 -15
  22. data/lib/rudy/cli.rb +142 -0
  23. data/lib/rudy/cli/addresses.rb +85 -0
  24. data/lib/rudy/cli/backups.rb +175 -0
  25. data/lib/rudy/{command → cli}/config.rb +18 -13
  26. data/lib/rudy/cli/deploy.rb +12 -0
  27. data/lib/rudy/cli/disks.rb +125 -0
  28. data/lib/rudy/cli/domains.rb +17 -0
  29. data/lib/rudy/cli/groups.rb +77 -0
  30. data/lib/rudy/{command → cli}/images.rb +18 -6
  31. data/lib/rudy/cli/instances.rb +142 -0
  32. data/lib/rudy/cli/keypairs.rb +47 -0
  33. data/lib/rudy/cli/manager.rb +51 -0
  34. data/lib/rudy/{command → cli}/release.rb +10 -10
  35. data/lib/rudy/cli/routines.rb +80 -0
  36. data/lib/rudy/cli/volumes.rb +121 -0
  37. data/lib/rudy/command/addresses.rb +62 -39
  38. data/lib/rudy/command/backups.rb +60 -170
  39. data/lib/rudy/command/disks-old.rb +322 -0
  40. data/lib/rudy/command/disks.rb +5 -209
  41. data/lib/rudy/command/domains.rb +34 -0
  42. data/lib/rudy/command/groups.rb +105 -48
  43. data/lib/rudy/command/instances.rb +263 -70
  44. data/lib/rudy/command/keypairs.rb +149 -0
  45. data/lib/rudy/command/manager.rb +65 -0
  46. data/lib/rudy/command/volumes.rb +110 -49
  47. data/lib/rudy/config.rb +90 -70
  48. data/lib/rudy/config/objects.rb +67 -0
  49. data/lib/rudy/huxtable.rb +253 -0
  50. data/lib/rudy/metadata/backup.rb +23 -48
  51. data/lib/rudy/metadata/disk.rb +79 -68
  52. data/lib/rudy/metadata/machine.rb +34 -0
  53. data/lib/rudy/routines.rb +54 -0
  54. data/lib/rudy/routines/disk_handler.rb +190 -0
  55. data/lib/rudy/routines/release.rb +15 -0
  56. data/lib/rudy/routines/script_runner.rb +65 -0
  57. data/lib/rudy/routines/shutdown.rb +42 -0
  58. data/lib/rudy/routines/startup.rb +48 -0
  59. data/lib/rudy/utils.rb +57 -2
  60. data/lib/storable.rb +11 -5
  61. data/lib/sysinfo.rb +274 -0
  62. data/rudy.gemspec +84 -20
  63. data/support/randomize-root-password +45 -0
  64. data/support/rudy-ec2-startup +5 -5
  65. data/support/update-ec2-ami-tools +20 -0
  66. data/test/05_config/00_setup_test.rb +24 -0
  67. data/test/05_config/30_machines_test.rb +69 -0
  68. data/test/20_sdb/00_setup_test.rb +31 -0
  69. data/test/20_sdb/10_domains_test.rb +113 -0
  70. data/test/25_ec2/00_setup_test.rb +34 -0
  71. data/test/25_ec2/10_keypairs_test.rb +33 -0
  72. data/test/25_ec2/20_groups_test.rb +139 -0
  73. data/test/25_ec2/30_addresses_test.rb +35 -0
  74. data/test/25_ec2/40_volumes_test.rb +46 -0
  75. data/test/25_ec2/50_snapshots_test.rb +69 -0
  76. data/test/26_ec2_instances/00_setup_test.rb +33 -0
  77. data/test/26_ec2_instances/10_instances_test.rb +81 -0
  78. data/test/26_ec2_instances/50_images_test.rb +13 -0
  79. data/test/30_sdb_metadata/00_setup_test.rb +28 -0
  80. data/test/30_sdb_metadata/10_disks_test.rb +99 -0
  81. data/test/30_sdb_metadata/20_backups_test.rb +102 -0
  82. data/test/50_commands/00_setup_test.rb +11 -0
  83. data/test/50_commands/10_keypairs_test.rb +79 -0
  84. data/test/50_commands/20_groups_test.rb +77 -0
  85. data/test/50_commands/40_volumes_test.rb +55 -0
  86. data/test/50_commands/50_instances_test.rb +110 -0
  87. data/test/coverage.txt +51 -0
  88. data/test/helper.rb +35 -0
  89. data/tryouts/disks.rb +55 -0
  90. data/tryouts/nested_methods.rb +36 -0
  91. data/tryouts/session_tryout.rb +48 -0
  92. metadata +94 -25
  93. data/bin/rudy-ec2 +0 -108
  94. data/lib/rudy/command/base.rb +0 -839
  95. data/lib/rudy/command/deploy.rb +0 -12
  96. data/lib/rudy/command/environment.rb +0 -74
  97. data/lib/rudy/command/machines.rb +0 -170
  98. data/lib/rudy/command/metadata.rb +0 -41
  99. data/lib/rudy/metadata.rb +0 -26
data/CHANGES.txt CHANGED
@@ -1,25 +1,24 @@
1
1
  RUDY, CHANGES
2
2
 
3
- TODO: Look into RubyGems error
4
- /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake/gempackagetask.rb:13:Warning: Gem::manage_gems is deprecated and will be removed on or after March 2009.
5
- rake aborted!
6
- RubyGem version error: rdoc(2.4.0 not ~> 2.3.0)
3
+ TODO: Remove aws_sdb
7
4
 
8
- TODO: Remove aws_swb
9
5
 
10
-
11
- #### 0.4.1 (2009-03-??) ###############################
6
+ #### 0.5.0 (2009-04-??) ###############################
12
7
 
13
8
  * CHANGE: Recommend keypair config to be in ~/.rudy/config
14
9
  * FIX: Rudy now checks for user keys specified by env-role, env, and global
15
10
  * FIX: gemspec dependency net-ssh-multi
16
11
  * NEW: rerelease command
12
+ * NEW: --nocolor option
13
+ * NEW: Ruby API
14
+ * NEW: Tests with 65% coverage
15
+
17
16
 
18
17
  #### 0.4 (2009-03-12) ###############################
19
18
 
20
19
  NOTE: This is a significant re-write from 0.3
21
20
 
22
- * CHANGE: Mostly re-written bin/ruby, moving validation to Command classes
21
+ * CHANGE: Mostly re-written bin/ruby, moving validation to CLI classes
23
22
  * CHANGE: upgrade to Drydock 0.5
24
23
  * CHANGE: Moved generic EC2 commands to bin/rudy-ec2
25
24
  * CHANGE: Removed ambiguity of pluralized command names.
@@ -58,7 +57,7 @@ NOTE: This is a complete re-write from 0.1
58
57
  * NEW: All time references are converted to UTC
59
58
  * NEW: Safer "Are you sure?". Number of characters to enter is
60
59
  commiserate with amount of danger.
61
- * NEW: Commands: myaddress, addresses, images, instances,
60
+ * NEW: CLIs: myaddress, addresses, images, instances,
62
61
  disks, connect, copy, stage, backups, volumes
63
62
  * NEW: Metadata storage to SimpleDB for disks, backups
64
63
  * NEW: Creates EBS volumes based on startup from metadata
data/README.rdoc CHANGED
@@ -1,13 +1,56 @@
1
- = Rudy - v0.4 ALPHA!
1
+ = Rudy - v0.5 ALPHA
2
2
 
3
- Rudy is a handy staging and deployment tool for EC2.
3
+ Rudy is a development and deployment tool for Amazon EC2. It's both a command-line tool and Ruby library. Here's an example from both for creating an EC2 security group:
4
+
5
+ $ rudy group --create
6
+
7
+ rgroup = Rudy::Groups.new
8
+ rgroup.create
9
+
10
+ Rudy is a bit different from other EC2 libraries in several ways.
4
11
 
5
- NOTE: Rudy will be ready for general consumption in Q2 2009.
6
12
 
7
13
  == Installation
8
14
 
9
- * Soon!
10
- * ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION' (See net/ssh docs)
15
+ Step 1 (install the gem):
16
+
17
+ $ sudo gem install rudy
18
+ $ sudo gem install solutious-rudy --source http://gems.github.com/
19
+ $ git clone git://github.com/solutious/rudy.git
20
+
21
+ Step 2 (initialize your configuration):
22
+
23
+ $ rudy generate-config
24
+ [modify ~/.rudy/config]
25
+ $ rudy init
26
+
27
+ Step 3 (get to work with EC2):
28
+
29
+ $ rudy group --create
30
+ $ rudy keypair --create
31
+ $ rudy instance --create
32
+
33
+
34
+ == Dependencies:
35
+
36
+ * OpenSSH
37
+ * Net::SSH
38
+ * Net::SCP
39
+ * amazon-ec2
40
+ * aws_sdb
41
+ * Drydock
42
+ * Caesars
43
+ * Rye
44
+
45
+
46
+ == Common Errors
47
+
48
+ * "The request signature we calculated does not match the signature you provided."
49
+ * Check that your Amazon Web Service access key and secret key are correct
50
+
51
+ * "AWS was not able to validate the provided access credentials"
52
+ * If it's a new Amazon Accounts, you need to sign up for EC2, SDB, and S3.
53
+
11
54
 
12
55
  == More Info
13
56
 
@@ -15,7 +58,6 @@ NOTE: Rudy will be ready for general consumption in Q2 2009.
15
58
  * RubyForge[http://rubyforge.org/projects/rudy]
16
59
  * Inspiration[http://www.youtube.com/watch?v=CgaiIW5Rzes]
17
60
 
18
-
19
61
  == Credits
20
62
 
21
63
  * Delano Mandelbaum (delano@solutious.com)
@@ -30,7 +72,6 @@ NOTE: Rudy will be ready for general consumption in Q2 2009.
30
72
  * Caleb Buxton
31
73
  * Colin Brumelle
32
74
 
33
-
34
75
  == License
35
76
 
36
77
  See: LICENSE.txt
data/Rakefile CHANGED
@@ -2,14 +2,106 @@ require 'rubygems'
2
2
  require 'rake/clean'
3
3
  require 'rake/gempackagetask'
4
4
  require 'hanna/rdoctask'
5
+ require 'rake/testtask'
6
+ require 'shoulda/tasks'
7
+ require 'rake/runtest'
8
+ require 'monkeyspecdoc' # http://jgre.org/2008/09/03/monkeyspecdoc/
5
9
  require 'fileutils'
6
10
  include FileUtils
7
11
 
8
- task :default => :package
12
+ task :default => :test
9
13
 
10
- # SPECS ===============================================================
14
+ # TESTS ===============================================================
11
15
 
12
- # None-yet!
16
+ Rake::TestTask.new(:test_old) do |t|
17
+ require 'monkeyspecdoc'
18
+ test_files = FileList['test/**/*_test.rb'] || []
19
+ t.test_files = test_files
20
+ t.ruby_opts = ['-rubygems'] if defined? Gem
21
+ t.verbose = true
22
+ # t.warning = true
23
+
24
+ end
25
+
26
+
27
+ namespace :test do
28
+ desc 'Measures test coverage'
29
+ task :coverage do
30
+ rm_f "coverage"
31
+ rm_f "coverage.data"
32
+ rcov = "rcov -Itest --aggregate coverage.data -T -x ' rubygems/*,/Library/Ruby/Site/*,gems/*,rcov*'"
33
+ system("#{rcov} --html test/**/*_test.rb")
34
+ system("open coverage/index.html") if RUBY_PLATFORM['darwin']
35
+ end
36
+ task :list do
37
+ puts Dir.glob(File.join('test', '**', '*_test.rb'))
38
+ end
39
+
40
+ # Run individual test groups with:
41
+ # rake test:05
42
+ # rake test:60
43
+ # etc...
44
+ ('00'..'99').each do |group|
45
+ task group.to_sym do
46
+ Rake.run_tests "test/#{group}*/*_test.rb"
47
+ end
48
+
49
+ # And also individual test files
50
+ # rake test:50:10
51
+ # etc...
52
+ ('00'..'99').each do |test|
53
+ namespace group.to_sym do
54
+ task test.to_sym do
55
+ Rake.run_tests "test/#{group}*/{00,#{test}}*_test.rb"
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ task :test do
63
+
64
+ #all_tests = Dir.glob(File.join('test', '{05,20,50}*', '*_test.rb')) || []
65
+ #all_tests.sort.each do |file|
66
+ # load file
67
+ #end
68
+ Rake.run_tests 'test/**/*_test.rb'
69
+ end
70
+
71
+
72
+ # From: shoulda/tasks/list_tests.rake
73
+ namespace :shoulda do
74
+ desc "List the names of the test methods in a specification like format"
75
+ task :list_fixed do
76
+ $LOAD_PATH.unshift("test")
77
+
78
+ require 'test/unit'
79
+ require 'rubygems'
80
+ require 'active_support'
81
+
82
+ # bug in test unit. Set to true to stop from running.
83
+ Test::Unit.run = true
84
+
85
+ test_files = Dir.glob(File.join('test', '**', '*_test.rb'))
86
+
87
+ test_files.each do |file|
88
+ load file
89
+ klass = File.basename(file, '.rb').classify
90
+ #unless Object.const_defined?(klass.to_s) # => raises: wrong constant name 00SetupTest
91
+ unless Object.constants.member?(klass.to_s) # fixed
92
+ puts "Skipping #{klass} because it doesn't map to a Class"
93
+ next
94
+ end
95
+ klass = klass.constantize
96
+
97
+ puts klass.name.gsub('Test', '')
98
+
99
+ test_methods = klass.instance_methods.grep(/^test/).map {|s| s.gsub(/^test: /, '')}.sort
100
+ test_methods.each {|m| puts " " + m }
101
+ end
102
+ end
103
+ end
104
+
13
105
 
14
106
  # PACKAGE =============================================================
15
107
 
@@ -22,7 +114,11 @@ Rake::GemPackageTask.new(@spec) do |p|
22
114
  p.need_tar = true if RUBY_PLATFORM !~ /mswin/
23
115
  end
24
116
 
25
- task :release => [ :rdoc, :package ]
117
+ task :release => [ :rdoc, :package ] do
118
+ $: << File.join(File.dirname(__FILE__), 'lib')
119
+ require "rudy"
120
+ abort if Drydock.debug?
121
+ end
26
122
 
27
123
  task :install => [ :rdoc, :package ] do
28
124
  sh %{sudo gem install pkg/#{name}-#{version}.gem}
@@ -52,17 +148,16 @@ end
52
148
  Rake::RDocTask.new do |t|
53
149
  t.rdoc_dir = 'doc'
54
150
  t.title = @spec.summary
55
- t.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
151
+ t.options << '--line-numbers' << '-A cattr_accessor=object'
56
152
  t.options << '--charset' << 'utf-8'
57
153
  t.rdoc_files.include('LICENSE.txt')
58
154
  t.rdoc_files.include('README.rdoc')
59
155
  t.rdoc_files.include('CHANGES.txt')
60
156
  t.rdoc_files.include('bin/*')
61
- t.rdoc_files.include('lib/*.rb')
62
157
  t.rdoc_files.include('lib/**/*.rb')
63
158
  end
64
159
 
65
- CLEAN.include [ 'pkg', '*.gem', '.config', 'doc' ]
160
+ CLEAN.include [ 'pkg', '*.gem', '.config', 'doc', 'coverage*' ]
66
161
 
67
162
 
68
163
 
data/Rudyfile ADDED
@@ -0,0 +1,28 @@
1
+ # Rudyfile -- An example Rudy configuration.
2
+ #
3
+ #
4
+ # Rudy automatically looks for configuration files in the
5
+ # following locations:
6
+ #
7
+ # ~/.rudy/config
8
+ # ./.rudy/config
9
+ # /etc/rudy/*.rb
10
+ # ./.rudy/*.rb
11
+ # ./Rudyfile
12
+ # ./config/rudy/*.rb
13
+ #
14
+ # When multuple files are found, the configuration is
15
+ # NOT OVERRIDDEN. It's ADDED / APPENDED. This means you can
16
+ # split configuration across many files as you please.
17
+ #
18
+ # There are three sections: accounts, defaults, machines.
19
+ # By convention, accounts and defaults go in ~/.rudy/config or ./.rudy/config
20
+ # We encourage this to help avoid checking in AWS keys into source control.
21
+
22
+
23
+ # --------------------------------------------------------- MACHINES --------
24
+ # The machines block describes the "physical" characteristics
25
+ # of your environments.
26
+ machines do
27
+
28
+ end
data/bin/ird ADDED
@@ -0,0 +1,162 @@
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
+
12
+ require 'rubygems' unless defined?(Gem)
13
+
14
+ # SEE: http://github.com/rubyspec/matzruby/blob/a34130eb7c4ecc164115a59aa1b76c643bd98202/lib/irb/xmp.rb
15
+ # SEE: http://github.com/blackwinter/wirble/tree/master
16
+ require "irb"
17
+ require 'irb/completion'
18
+
19
+ require 'rudy'
20
+ require 'drydock'
21
+ require 'rudy/cli'
22
+
23
+ include Readline
24
+ include Drydock
25
+
26
+ global :A, :accesskey, String, "AWS Access Key"
27
+ global :S, :secretkey, String, "AWS Secret Access Key"
28
+ #global :R, :region, String, "Connect to a specific EC2 region (ie: #{Rudy::DEFAULT_REGION})"
29
+ #global :n, :nocolor, "Disable output colors"
30
+ global :f, :config, String, "Specify another configuration file to read (ie: #{Rudy::RUDY_CONFIG_FILE})"
31
+ global :z, :zone, String, "Connect to a specific EC2 zone (ie: #{Rudy::DEFAULT_ZONE})"
32
+ global :e, :environment, String, "Connect to the specified environment (ie: #{Rudy::DEFAULT_ENVIRONMENT})"
33
+ global :r, :role, String, "Connect to a machine with the specified role (ie: #{Rudy::DEFAULT_ROLE})"
34
+ global :p, :position, String, "Position in the machine in its group (ie: #{Rudy::DEFAULT_POSITION})"
35
+ global :u, :user, String, "Provide a username (ie: #{Rudy::DEFAULT_USER})"
36
+ #global :q, :quiet, "Run with less output"
37
+ #global :v, :verbose, "Increase verbosity of output (i.e. -v or -vv or -vvv)" do
38
+ # @verbose ||= 0
39
+ # @verbose += 1
40
+ #end
41
+ global :V, :version, "Display version number" do
42
+ puts "Rudy version: #{Rudy::VERSION}"
43
+ exit 0
44
+ end
45
+
46
+
47
+ default :interactive
48
+ debug :off
49
+ desc "An interactive REPL for Rudy."
50
+ usage "#{$0} [global options]"
51
+ command :interactive do |obj|
52
+
53
+ @rmach = Rudy::Instances.new(:global => obj.global)
54
+ @rkey = Rudy::KeyPairs.new(:global => obj.global)
55
+ @rgrp = Rudy::Groups.new(:global => obj.global)
56
+ @rvol = Rudy::Volumes.new(:global => obj.global)
57
+ @radd = Rudy::Addresses.new(:global => obj.global)
58
+
59
+ puts Rudy::CLI.generate_header(@rmach.global, @rmach.config)
60
+ puts Rudy::Utils.without_indent(%Q`
61
+ ------------------------------------------------------------
62
+ Welcome Interactive Rudy! (EXPERIMENTAL)
63
+ ------------------------------------------------------------
64
+
65
+ `)
66
+ h
67
+
68
+ # What's the deal with this error message when defining a help method?
69
+ # => rb: warn: can't alias help from irb_help
70
+ if __FILE__ == $0
71
+ IRB.start(__FILE__)
72
+ else
73
+ # check -e option
74
+ if /^-e$/ =~ $0
75
+ IRB.start(__FILE__)
76
+ else
77
+ IRB.start(__FILE__)
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ def h;
84
+ puts (%Q`
85
+ HELP
86
+
87
+ h Help (this screen)
88
+ m Rudy::Machines instance
89
+ g Rudy::Groups instance
90
+ k Rudy::KeyPairs instance
91
+ v Rudy::Volumes instance
92
+ a Rudy::Addresses instance
93
+ ssh [GROUP] Connect to a machine
94
+ example Start an EC2 instance from scratch.
95
+ `)
96
+ end
97
+ def example
98
+ puts (%Q`
99
+ EXAMPLE
100
+ Start an EC2 instance from scratch.
101
+
102
+ # Create a security group
103
+ >> g.create
104
+ => #<Rudy::AWS::EC2::Group @name="stage-app" ...>
105
+
106
+ # Create a keypair (used to login as root)
107
+ >> k.create
108
+ => #<Rudy::AWS::EC2::KeyPair @name="key-stage-app" ...>
109
+
110
+ # Start an EC2 machine instance:
111
+ >> m.create
112
+ Instance: i-228def51
113
+ Waiting for the instance to startup
114
+ ........It's up!
115
+
116
+ # Login to the new instance
117
+ >> ssh
118
+
119
+ All commands in Rudy refer to the global defaults unless
120
+ otherwise specified. "stage" is the default environment and
121
+ "app" is the default role. You can change these with command
122
+ line arguments or by modifying the defaults in your Rudy
123
+ config file: #{@rmach.config_dirname}
124
+
125
+ You can also specify your own names by providing
126
+ one as the first argument: g.create 'group5000'.
127
+
128
+ # List instances in stage-app
129
+ >> m.list :running
130
+ => [#<Rudy::AWS::EC2::Instance:0x18c5888 ...>]
131
+
132
+ # Print the instance in a human readable way
133
+ >> puts m.list.first.to_s
134
+
135
+ # Print instance system console output
136
+ >> puts m.console
137
+
138
+ # Destroy ALL INSTANCES in stage-app
139
+ >> m.destroy
140
+ `)
141
+ end
142
+
143
+ def m; @rmach; end
144
+ def k; @rkey; end
145
+ def g; @rgrp; end
146
+ def v; @rvol; end
147
+ def a; @radd; end
148
+
149
+ # Change Group
150
+ #def cg(name); end
151
+
152
+ def ssh(*args)
153
+ @rmach.switch_user :root
154
+ @rmach.connect(*args)
155
+ @rmach.switch_user # back to previous user
156
+ nil
157
+ end
158
+
159
+ __END__
160
+ #@rbox = Rye::Box.new('ec2-174-129-173-3.compute-1.amazonaws.com', 'root')
161
+ #@rbox2 = Rye::Box.new('ec2-174-129-173-3.compute-1.amazonaws.com', 'root')
162
+ #@rbox.add_keys('/Users/delano/Projects/git/rudy/.rudy/key-test-app.private')