rudy 0.8.1 → 0.8.2

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 (52) hide show
  1. data/CHANGES.txt +21 -8
  2. data/README.rdoc +43 -1
  3. data/Rudyfile +28 -27
  4. data/bin/rudy +8 -15
  5. data/lib/rudy.rb +2 -2
  6. data/lib/rudy/cli/routines.rb +4 -20
  7. data/lib/rudy/config.rb +1 -0
  8. data/lib/rudy/config/objects.rb +29 -33
  9. data/lib/rudy/huxtable.rb +9 -1
  10. data/lib/rudy/routines.rb +113 -96
  11. data/lib/rudy/routines/helper.rb +3 -3
  12. data/lib/rudy/routines/helpers/dependshelper.rb +1 -1
  13. data/lib/rudy/routines/helpers/diskhelper.rb +3 -3
  14. data/lib/rudy/routines/helpers/scripthelper.rb +41 -39
  15. data/lib/rudy/routines/helpers/userhelper.rb +5 -5
  16. data/lib/rudy/routines/passthrough.rb +11 -11
  17. data/lib/rudy/routines/startup.rb +1 -1
  18. data/rudy.gemspec +4 -37
  19. metadata +5 -38
  20. data/examples/README.md +0 -10
  21. data/examples/debian-sinatra-passenger/commands.rb +0 -19
  22. data/examples/debian-sinatra-passenger/machines.rb +0 -32
  23. data/examples/debian-sinatra-passenger/routines.rb +0 -30
  24. data/examples/debian-sinatra-thin/commands.rb +0 -17
  25. data/examples/debian-sinatra-thin/machines.rb +0 -35
  26. data/examples/debian-sinatra-thin/routines.rb +0 -72
  27. data/lib/rudy/routines/helpers/scmhelper.rb +0 -39
  28. data/lib/rudy/routines/release.rb +0 -48
  29. data/lib/rudy/scm.rb +0 -75
  30. data/lib/rudy/scm/git.rb +0 -217
  31. data/lib/rudy/scm/svn.rb +0 -110
  32. data/test/01_mixins/10_hash_test.rb +0 -25
  33. data/test/10_config/00_setup_test.rb +0 -20
  34. data/test/10_config/30_machines_test.rb +0 -69
  35. data/test/15_scm/00_setup_test.rb +0 -20
  36. data/test/15_scm/20_git_test.rb +0 -61
  37. data/test/20_sdb/00_setup_test.rb +0 -16
  38. data/test/20_sdb/10_domains_test.rb +0 -115
  39. data/test/25_ec2/00_setup_test.rb +0 -29
  40. data/test/25_ec2/10_keypairs_test.rb +0 -41
  41. data/test/25_ec2/20_groups_test.rb +0 -131
  42. data/test/25_ec2/30_addresses_test.rb +0 -38
  43. data/test/25_ec2/40_volumes_test.rb +0 -49
  44. data/test/25_ec2/50_snapshots_test.rb +0 -74
  45. data/test/26_ec2_instances/00_setup_test.rb +0 -28
  46. data/test/26_ec2_instances/10_instances_test.rb +0 -83
  47. data/test/26_ec2_instances/50_images_test.rb +0 -13
  48. data/test/30_sdb_metadata/00_setup_test.rb +0 -21
  49. data/test/30_sdb_metadata/10_disks_test.rb +0 -109
  50. data/test/30_sdb_metadata/20_backups_test.rb +0 -102
  51. data/test/coverage.txt +0 -51
  52. data/test/helper.rb +0 -36
@@ -1,39 +0,0 @@
1
-
2
- module Rudy; module Routines;
3
- module SCMHelper
4
- include Rudy::Routines::HelperBase
5
- extend self
6
-
7
- # Does the routine config contain SCM routines?
8
- # Raises Rudy::Error if there is malformed configuration.
9
- def scm?(routine)
10
- scmnames = SUPPORTED_SCM_NAMES & routine.keys # Find intersections.
11
- return false if scmnames.empty? # Nothing to do.
12
- scmnames.each do |scm|
13
- routine[scm].values.each do |t| # Each SCM should have a
14
- raise "Bad #{scm} config" if !t.kind_of?(Hash) # Hash config. Otherwise
15
- end # it's misconfigured.
16
- end
17
- true
18
- end
19
-
20
- def create_scm_objects(routine)
21
- return nil unless routine
22
- scmnames = SUPPORTED_SCM_NAMES & routine.keys
23
- vlist = []
24
- # Look for scm config in the routine by checking all known scm types.
25
- # For each one we'll create an instance of the appropriate SCM class.
26
- scmnames.each do |scm|
27
- routine[scm].each_pair do |user,params|
28
- klass = eval "Rudy::SCM::#{scm.to_s.upcase}"
29
- params[:user] = user
30
- scm = klass.new(params)
31
- scm.raise_early_exceptions # Raises exceptions for obvious problems.
32
- vlist << scm
33
- end
34
- end
35
- vlist
36
- end
37
-
38
- end
39
- end; end
@@ -1,48 +0,0 @@
1
-
2
-
3
- module Rudy; module Routines;
4
- class Release < Rudy::Routines::Base
5
-
6
- def init(*args)
7
- @routine_name = args.first || :release # :release or :rerelease
8
- @routine = fetch_routine_config(@routine_name)
9
- end
10
-
11
- def execute()
12
- routine_separator(@routine_name)
13
-
14
- vlist = []
15
-
16
- # Some early version control system failing
17
- if Rudy::Routines::SCMHelper.scm?(@routine)
18
- vlist = Rudy::Routines::SCMHelper.create_scm_objects(@routine)
19
- puts task_separator("CREATING RELEASE TAG#{'S' if vlist.size > 1}")
20
- vlist.each do |scm|
21
- scm.create_release(Rudy.sysinfo.user)
22
- puts scm.liner_note
23
- end
24
- end
25
-
26
- machines = generic_machine_runner(:list) do |machine,rbox|
27
- vlist.each do |scm|
28
- puts task_separator("CREATING REMOTE #{scm.engine.to_s.upcase} CHECKOUT")
29
- scm.create_remote_checkout(rbox)
30
- end
31
- end
32
-
33
- machines
34
- end
35
-
36
- # Called by generic_machine_runner
37
- def raise_early_exceptions
38
- raise NoRoutine, :release unless @routine
39
- rmach = Rudy::Machines.new
40
- raise Rudy::PrivateKeyNotFound, root_keypairpath unless has_keypair?(:root)
41
- raise MachineGroupNotDefined, current_machine_group unless known_machine_group?
42
- raise MachineGroupNotRunning, current_machine_group unless rmach.running?
43
- end
44
-
45
-
46
-
47
- end
48
- end;end
data/lib/rudy/scm.rb DELETED
@@ -1,75 +0,0 @@
1
-
2
-
3
- module Rudy
4
- module SCM
5
-
6
- class NotAWorkingCopy < Rudy::Error
7
- def message
8
- "Not the root directory of a #{@obj} working copy"
9
- end
10
- end
11
- class CannotCreateTag < Rudy::Error
12
- def message
13
- "There was an unknown problem creating a release tag (#{@obj})"
14
- end
15
- end
16
- class DirtyWorkingCopy < Rudy::Error
17
- def message
18
- "Please commit local #{@obj} changes"
19
- end
20
- end
21
- class RemoteError < Rudy::Error; end
22
- class NoRemoteURI < Rudy::Error; end
23
- class TooManyTags < Rudy::Error
24
- def message; "Too many tag creation attempts!"; end
25
- end
26
- class NoRemotePath < Rudy::Error
27
- def message
28
- "Add a path for #{@obj} in your routines config"
29
- end
30
- end
31
-
32
-
33
- module ObjectBase
34
-
35
-
36
- def raise_early_exceptions; raise "override raise_early_exceptions"; end
37
-
38
- # copied from routines/helper.rb
39
- def execute_rbox_command(ret=nil, &command)
40
- begin
41
- ret = command.call
42
- puts ' ' << ret.stdout.join("#{$/} ") if !ret.stdout.empty?
43
- print_response(ret)
44
- rescue Rye::CommandError => ex
45
- print_response(ex)
46
- exit 12 unless keep_going?
47
- rescue Rye::CommandNotFound => ex
48
- STDERR.puts " CommandNotFound: #{ex.message}".color(:red)
49
- STDERR.puts ex.backtrace
50
- exit 12 unless keep_going?
51
- end
52
-
53
- ret
54
- end
55
-
56
-
57
- private
58
- def keep_going?
59
- Annoy.pose_question(" Keep going?\a ", /yes|y|ya|sure|you bet!/i, STDERR)
60
- end
61
-
62
- def print_response(rap)
63
- [:stderr].each do |sumpin|
64
- next if rap.send(sumpin).empty?
65
- STDERR.puts " #{sumpin}: #{rap.send(sumpin).join("#{$/} ")}".color(:red)
66
- end
67
- STDERR.puts " Exit code: #{rap.exit_code}".color(:red) if rap.exit_code != 0
68
- end
69
-
70
- end
71
-
72
- end
73
- end
74
-
75
- Rudy::Utils.require_glob(RUDY_LIB, 'rudy', 'scm', '*.rb')
data/lib/rudy/scm/git.rb DELETED
@@ -1,217 +0,0 @@
1
-
2
- require 'date'
3
-
4
-
5
- module Rudy
6
- module SCM
7
- class GIT
8
- require 'grit'
9
- include Rudy::SCM::ObjectBase
10
- include Grit
11
-
12
- attr_accessor :base_uri
13
- attr_accessor :remote
14
- attr_accessor :branch
15
- attr_reader :repo
16
- attr_reader :rbox
17
- attr_reader :rtag
18
- attr_reader :user
19
- attr_reader :pkey
20
- attr_reader :changes
21
-
22
- # * +args+ a hash of params from the git block in the routines config
23
- #
24
- def initialize(args={})
25
- args = {
26
- :privatekey => nil,
27
- :remote => :origin,
28
- :branch => :master,
29
- :user => :root,
30
- :changes => :enforce,
31
- :path => nil
32
- }.merge(args)
33
- @remote, @branch, @path = args[:remote], args[:branch], args[:path]
34
- @user, @pkey, @changes = args[:user], args[:privatekey], args[:changes]
35
- @repo = Repo.new(Dir.pwd) if GIT.working_copy?
36
- end
37
-
38
- def engine; :git; end
39
-
40
- def liner_note
41
- "%-40s (git:%s:%s)" % [@rtag, @remote, @branch]
42
- end
43
-
44
- def create_release(username=nil, msg=nil)
45
- @rtag = find_next_rtag(username)
46
- msg ||= 'Another Release by Rudy!'
47
- msg.tr!("'", "''")
48
- ret = Rye.shell(:git, "tag", @rtag) # Use annotated? -a -m '#{msg}'
49
- raise ret.stderr.join($/) if ret.exit_code > 0
50
- ret = Rye.shell(:git, "push") if @remote
51
- raise ret.stderr.join($/) if ret.exit_code > 0
52
- ret = Rye.shell(:git, "push #{@remote} #{rtag}") if @remote
53
- raise ret.stderr.join($/) if ret.exit_code > 0
54
- @rtag
55
- end
56
-
57
- # rel-2009-03-05-user-rev
58
- def find_next_rtag(username=nil)
59
- now = Time.now
60
- mon = now.mon.to_s.rjust(2, '0')
61
- day = now.day.to_s.rjust(2, '0')
62
- rev = "01"
63
- criteria = ['rel', now.year, mon, day, rev]
64
- criteria.insert(-2, username) if username
65
- rev.succ! while valid_rtag?(criteria.join(Rudy::DELIM)) && rev.to_i < 50
66
- raise TooManyTags if rev.to_i >= 50
67
- criteria.join(Rudy::DELIM)
68
- end
69
-
70
- def delete_rtag(rtag=nil)
71
- rtag ||= @rtag
72
- ret = execute_rbox_command { Rye.shell(:git, 'tag', :d, rtag) }
73
- raise ret.stderr.join($/) if ret.exit_code > 0 # TODO: retest
74
- # Equivalent to: "git push origin :tag-name" which deletes a remote tag
75
- ret = execute_rbox_command { Rye.shell(:git, "push #{@remote} :#{rtag}") } if @remote
76
- raise ret.stderr.join($/) if ret.exit_code > 0
77
- true
78
- end
79
-
80
- def create_remote_checkout(rbox)
81
-
82
- # Make sure the directory above the clone path exists
83
- # and that it's owned by the request user.
84
- rbox.mkdir(:p, File.dirname(@path))
85
- rbox.chown(@user, File.dirname(@path))
86
-
87
- begin
88
- original_user = rbox.user
89
- rbox.switch_user(@user)
90
-
91
- if @pkey
92
- # Try when debugging: ssh -vi path/2/pkey git@github.com
93
- key = File.basename(@pkey)
94
- homedir = rbox.getenv['HOME']
95
- rbox.mkdir(:p, :m, '700', '.ssh') rescue nil # :p says keep quiet if it exists
96
- if rbox.file_exists?(".ssh/#{key}")
97
- puts " Remote private key #{key} already exists".colour(:red)
98
- else
99
- rbox.upload(@pkey, ".ssh/#{key}")
100
- end
101
-
102
- ## NOTE: The following are two attempts at telling git which
103
- ## private key to use. Both fail. The only thing I could get
104
- ## to work is modifying the ~/.ssh/config file.
105
- ##
106
- ## This runs fine, but "git clone" doesn't care.
107
- ## git config --global --replace-all http.sslKey /home/delano/.ssh/id_rsa
108
- ## rbox.git('config', '--global', '--replace-all', 'http.sslKey', "#{homedir}/.ssh/#{key}")
109
- ##
110
- ## "git clone" doesn't care about this either. Note that both these
111
- ## config attempts come directly from the git-config man page:
112
- ## http://www.kernel.org/pub/software/scm/git/docs/git-config.html
113
- ## export GIT_SSL_KEY=/home/delano/.ssh/id_rsa
114
- ## rbox.setenv("GIT_SSL_KEY", "#{homedir}/.ssh/#{key}")
115
-
116
- if rbox.file_exists?('.ssh/config')
117
- rbox.cp('.ssh/config', ".ssh/config-previous")
118
- ssh_config = rbox.download('.ssh/config')
119
- end
120
-
121
- ssh_config ||= StringIO.new
122
- ssh_config.puts $/, "IdentityFile #{homedir}/.ssh/#{key}"
123
- puts " Adding IdentityFile #{key} to #{homedir}/.ssh/config"
124
-
125
- rbox.upload(ssh_config, '.ssh/config')
126
- rbox.chmod('0600', '.ssh/config')
127
-
128
- end
129
-
130
- # We need to add the host keys to the user's known_hosts file
131
- # to prevent the git commands from failing when it raises the
132
- # "Host key verification failed." messsage.
133
- if rbox.file_exists?('.ssh/known_hosts')
134
- rbox.cp('.ssh/known_hosts', ".ssh/known_hosts-previous")
135
- known_hosts = rbox.download('.ssh/known_hosts')
136
- end
137
- known_hosts ||= StringIO.new
138
- remote = get_remote_uri
139
- host = URI.parse(remote).host rescue nil
140
- host ||= remote.scan(/\A.+?@(.+?)\:/).flatten.first
141
- known_hosts.puts $/, Rye.remote_host_keys(host)
142
- puts " Adding host key for #{host} to .ssh/known_hosts"
143
-
144
- rbox.upload(known_hosts, '.ssh/known_hosts')
145
- rbox.chmod('0600', '.ssh/known_hosts')
146
-
147
- execute_rbox_command {
148
- rbox.git('clone', get_remote_uri, @path)
149
- }
150
- rbox.cd(@path)
151
- execute_rbox_command {
152
- rbox.git('checkout', :b, @rtag)
153
- }
154
- rescue Rye::CommandError => ex
155
- puts ex.message
156
- ensure
157
- # Return to the original user and directory
158
- rbox.switch_user(original_user)
159
- rbox.cd
160
- end
161
-
162
- end
163
-
164
-
165
- def get_remote_uri
166
- ret = Rye.shell(:git, "config", "remote.#{@remote}.url")
167
- ret.stdout.first
168
- end
169
-
170
- # Check if the given remote is valid.
171
- #def has_remote?(remote)
172
- # success = false
173
- # (@repo.remotes || []).each do |r|
174
- # end
175
- # success
176
- #end
177
-
178
- def valid_rtag?(tag)
179
- # git tag -l tagname returns a 0 exit code and stdout is empty
180
- # when a tag does not exit. When it does exist, the exit code
181
- # is 0 and stdout contains the tagname.
182
- ret = Rye.shell(:git, 'tag', :l, tag)
183
- # change :l to :d for quick deleting above and return true
184
- # OR: just change to :d to always recreate the same tag
185
- (ret.exit_code == 0 && ret.stdout.to_s == tag)
186
- end
187
-
188
- # Are all local changes committed?
189
- def self.clean_working_copy?(path=Dir.pwd)
190
- Rye.shell(:git, 'diff').stdout == []
191
- end
192
- def clean_working_copy?; GIT.clean_working_copy?; end
193
-
194
- def self.working_copy?(path=Dir.pwd)
195
- (File.exists?(File.join(path, '.git')))
196
- end
197
- def working_copy?; GIT.working_copy?; end
198
-
199
- def raise_early_exceptions
200
- raise NotAWorkingCopy, :git unless working_copy?
201
- raise DirtyWorkingCopy, :git unless @changes.to_s == 'ignore' || clean_working_copy?
202
- raise NoRemoteURI, "remote.#{@remote}.url not set" if get_remote_uri.nil?
203
- raise NoRemotePath, :git if @path.nil?
204
- raise PrivateKeyNotFound, @pkey if @pkey && !File.exists?(@pkey)
205
- find_next_rtag # will raise exception is there's a problem
206
-
207
- # We can't check stuff that requires access to the machine b/c the
208
- # machine may not be running yet. These include:
209
- # * Remote checkout path already exists
210
- # * No git available
211
- # ...
212
- # If create_remote_checkout should fail, it should print a message
213
- # about the release that was created and how to install it manually
214
- end
215
- end
216
- end
217
- end
data/lib/rudy/scm/svn.rb DELETED
@@ -1,110 +0,0 @@
1
-
2
- require 'date'
3
-
4
- module Rudy
5
- module SCM
6
- class SVN
7
- attr_accessor :base_uri
8
-
9
- attr_reader :changes
10
-
11
- def initialize(args={})
12
- args = {
13
- :privatekey => nil,
14
- :base_uri => nil,
15
- :user => :root,
16
- :changes => :enforce,
17
- :path => nil
18
- }.merge(args)
19
- @base_uri, @path = args[:base_uri], args[:path]
20
- @user, @pkey, @changes = args[:user], args[:privatekey], args[:changes]
21
- end
22
-
23
- def engine; :svn; end
24
-
25
- def liner_note
26
- "%-40s (svn:%s:%s)" % [@rtag, @base_uri, @branch]
27
- end
28
-
29
- def create_release(username=nil, msg=nil)
30
- local_uri, local_revision = local_info
31
- rtag = find_next_rtag(username)
32
- release_uri = "#{@base_uri}/#{rtag}"
33
- msg ||= 'Another Release by Rudy!'
34
- msg.tr!("'", "\\'")
35
- cmd = "svn copy -m '#{msg}' #{local_uri} #{release_uri}"
36
-
37
- `#{cmd} 2>&1`
38
-
39
- release_uri
40
- end
41
-
42
- def switch_working_copy(tag)
43
- raise "Invalid release tag (#{tag})." unless valid_rtag?(tag)
44
- `svn switch #{tag}`
45
- end
46
-
47
- # rel-2009-03-05-user-rev
48
- def find_next_rtag(username=nil)
49
- now = Time.now
50
- mon = now.mon.to_s.rjust(2, '0')
51
- day = now.day.to_s.rjust(2, '0')
52
- rev = "01"
53
- criteria = ['rel', now.year, mon, day, rev]
54
- criteria.insert(-2, username) if username
55
- tag = criteria.join(Rudy::DELIM)
56
- # Keep incrementing the revision number until we find the next one.
57
- tag.succ! while (valid_rtag?("#{@base_uri}/#{tag}"))
58
- tag
59
- end
60
-
61
- def local_info
62
- ret = Rye.shell(:svn, "info").join
63
- # URL: http://some/uri/path
64
- # Repository Root: http://some/uri
65
- # Repository UUID: c5abe49d-53e4-4ea3-9314-89e1e25aa7e1
66
- # Revision: 921
67
- ret.scan(/URL: (http:.+?)\s*\n.+Revision: (\d+)/m).flatten
68
- end
69
-
70
- def working_copy?(path)
71
- (File.exists?(File.join(path, '.svn')))
72
- end
73
-
74
- def valid_rtag?(uri)
75
- ret = `svn info #{uri} 2>&1` || '' # Valid SVN URIs will return some info
76
- (ret =~ /Repository UUID/) ? true : false
77
- end
78
-
79
- # Are all local changes committed?
80
- def self.clean_working_copy?(path=Dir.pwd)
81
- Rye.shell(:svn, 'diff', '.').stdout == []
82
- end
83
- def clean_working_copy?; SVN.clean_working_copy?; end
84
-
85
- def self.working_copy?(path=Dir.pwd)
86
- (File.exists?(File.join(path, '.svn')))
87
- end
88
- def working_copy?; SVN.working_copy?; end
89
-
90
-
91
- def raise_early_exceptions
92
- raise NotAWorkingCopy, :svn unless working_copy?
93
- raise DirtyWorkingCopy, :svn unless @changes.to_s == 'ignore' || clean_working_copy?
94
- #raise NoRemoteURI, "remote.#{@remote}.url not set" if get_remote_uri.nil?
95
- raise NoRemotePath, :svn if @path.nil?
96
- raise PrivateKeyNotFound, @pkey if @pkey && !File.exists?(@pkey)
97
- find_next_rtag # will raise exception is there's a problem
98
-
99
- # We can't check stuff that requires access to the machine b/c the
100
- # machine may not be running yet. These include:
101
- # * Remote checkout path already exists
102
- # * No git available
103
- # ...
104
- # If create_remote_checkout should fail, it should print a message
105
- # about the release that was created and how to install it manually
106
- end
107
-
108
- end
109
- end
110
- end