solutious-rudy 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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')