rudy 0.6.8 → 0.7.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.
- data/CHANGES.txt +15 -2
- data/README.rdoc +30 -23
- data/Rakefile +5 -5
- data/Rudyfile +87 -66
- data/bin/rudy +120 -167
- data/bin/rudy-ec2 +17 -13
- data/bin/rudy-s3 +6 -4
- data/bin/rudy-sdb +5 -4
- data/lib/annoy.rb +1 -1
- data/lib/console.rb +1 -3
- data/lib/rudy.rb +11 -25
- data/lib/rudy/aws/ec2/instance.rb +1 -1
- data/lib/rudy/aws/ec2/volume.rb +2 -2
- data/lib/rudy/aws/sdb/error.rb +2 -1
- data/lib/rudy/cli.rb +10 -1
- data/lib/rudy/cli/aws/ec2/addresses.rb +1 -1
- data/lib/rudy/cli/aws/ec2/images.rb +3 -1
- data/lib/rudy/cli/aws/ec2/instances.rb +2 -2
- data/lib/rudy/cli/candy.rb +11 -0
- data/lib/rudy/cli/config.rb +25 -44
- data/lib/rudy/cli/machines.rb +30 -10
- data/lib/rudy/cli/routines.rb +67 -19
- data/lib/rudy/config.rb +30 -13
- data/lib/rudy/config/objects.rb +135 -10
- data/lib/rudy/disks.rb +8 -52
- data/lib/rudy/global.rb +9 -5
- data/lib/rudy/guidelines.rb +18 -0
- data/lib/rudy/huxtable.rb +29 -19
- data/lib/rudy/machines.rb +10 -7
- data/lib/rudy/mixins/hash.rb +25 -0
- data/lib/rudy/routines.rb +160 -10
- data/lib/rudy/routines/helper.rb +50 -0
- data/lib/rudy/routines/helpers/diskhelper.rb +44 -18
- data/lib/rudy/routines/helpers/scmhelper.rb +39 -0
- data/lib/rudy/routines/helpers/scripthelper.rb +86 -35
- data/lib/rudy/routines/helpers/userhelper.rb +37 -0
- data/lib/rudy/routines/passthrough.rb +36 -0
- data/lib/rudy/routines/release.rb +38 -22
- data/lib/rudy/routines/shutdown.rb +20 -49
- data/lib/rudy/routines/startup.rb +20 -47
- data/lib/rudy/scm.rb +75 -0
- data/lib/rudy/scm/git.rb +215 -0
- data/lib/rudy/scm/svn.rb +7 -6
- data/lib/rudy/utils.rb +12 -30
- data/lib/storable.rb +4 -1
- data/lib/sysinfo.rb +10 -0
- data/rudy.gemspec +21 -9
- data/test/01_mixins/10_hash_test.rb +25 -0
- data/test/{05_config → 10_config}/00_setup_test.rb +1 -1
- data/test/{05_config → 10_config}/30_machines_test.rb +1 -1
- data/test/15_scm/00_setup_test.rb +20 -0
- data/test/15_scm/20_git_test.rb +61 -0
- data/test/helper.rb +1 -1
- data/vendor/highline-1.5.1/Rakefile +3 -3
- metadata +41 -12
- data/bin/ird +0 -175
@@ -1,34 +1,50 @@
|
|
1
1
|
|
2
|
+
|
2
3
|
module Rudy; module Routines;
|
3
4
|
class Release < Rudy::Routines::Base
|
4
|
-
|
5
|
-
def execute
|
6
|
-
p find_scm(:release)
|
7
|
-
end
|
8
5
|
|
6
|
+
def init(*args)
|
7
|
+
@routine_name = args.first || :release # :release or :rerelease
|
8
|
+
@routine = fetch_routine_config(@routine_name)
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
env, rol, att = @@global.environment, @@global.role
|
11
|
+
def execute()
|
12
|
+
routine_separator(@routine_name)
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
22
24
|
end
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
|
26
|
+
machines = []
|
27
|
+
generic_machine_runner(:list) do |machine,rbox|
|
28
|
+
vlist.each do |scm|
|
29
|
+
puts task_separator("CREATING REMOTE #{scm.engine.to_s.upcase} CHECKOUT")
|
30
|
+
scm.create_remote_checkout(rbox)
|
31
|
+
end
|
32
|
+
machines << machine
|
27
33
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
34
|
+
|
35
|
+
machines
|
36
|
+
end
|
37
|
+
|
38
|
+
# Called by generic_machine_runner
|
39
|
+
def raise_early_exceptions
|
40
|
+
raise NoRoutine, :release unless @routine
|
41
|
+
rmach = Rudy::Machines.new
|
42
|
+
raise Rudy::PrivateKeyNotFound, root_keypairpath unless has_keypair?(:root)
|
43
|
+
raise MachineGroupNotDefined, current_machine_group unless known_machine_group?
|
44
|
+
raise MachineGroupNotRunning, current_machine_group unless rmach.running?
|
31
45
|
end
|
32
46
|
|
47
|
+
|
48
|
+
|
33
49
|
end
|
34
50
|
end;end
|
@@ -1,62 +1,33 @@
|
|
1
1
|
|
2
2
|
|
3
3
|
module Rudy; module Routines;
|
4
|
-
|
5
4
|
class Shutdown < Rudy::Routines::Base
|
6
5
|
|
6
|
+
def init(*args)
|
7
|
+
@routine = fetch_routine_config(:shutdown)
|
8
|
+
end
|
9
|
+
|
7
10
|
def execute
|
11
|
+
routine_separator(:shutdown)
|
12
|
+
unless @routine
|
13
|
+
STDERR.puts "[this is a generic shutdown routine]"
|
14
|
+
@routine = {}
|
15
|
+
end
|
16
|
+
machines = []
|
17
|
+
generic_machine_runner(:destroy) do |machine,rbox|
|
18
|
+
#puts task_separator("SHUTDOWN")
|
19
|
+
machines << machine
|
20
|
+
end
|
21
|
+
machines
|
22
|
+
end
|
23
|
+
|
24
|
+
# Called by generic_machine_runner
|
25
|
+
def raise_early_exceptions
|
8
26
|
rmach = Rudy::Machines.new
|
9
27
|
raise Rudy::PrivateKeyNotFound, root_keypairpath unless has_keypair?(:root)
|
10
|
-
raise MachineGroupNotDefined, current_machine_group unless known_machine_group?
|
11
28
|
raise MachineGroupNotRunning, current_machine_group unless rmach.running?
|
12
|
-
|
13
|
-
routine = fetch_routine_config(:shutdown)
|
14
|
-
rbox_local = Rye::Box.new('localhost')
|
15
|
-
sconf = fetch_script_config
|
16
|
-
|
17
|
-
# Runs "before_local" scripts of routines config.
|
18
|
-
puts task_separator("BEFORE SCRIPTS (local)")
|
19
|
-
Rudy::Routines::ScriptHelper.before_local(routine, sconf, rbox_local)
|
20
|
-
|
21
|
-
puts
|
22
|
-
|
23
|
-
rmach.destroy do |machine|
|
24
|
-
#rmach.list do |machine|
|
25
|
-
|
26
|
-
print "Waiting for instance..."
|
27
|
-
isup = Rudy::Utils.waiter(3, 120, STDOUT, "it's up!", 0) {
|
28
|
-
inst = machine.get_instance
|
29
|
-
inst && inst.running?
|
30
|
-
}
|
31
|
-
machine.update # Add instance info to machine and save it
|
32
|
-
print "Waiting for SSH daemon..."
|
33
|
-
isup = Rudy::Utils.waiter(2, 60, STDOUT, "it's up!", 0) {
|
34
|
-
Rudy::Utils.service_available?(machine.dns_public, 22)
|
35
|
-
}
|
36
|
-
|
37
|
-
opts = { :keys => root_keypairpath, :user => 'root', :debug => nil }
|
38
|
-
rbox = Rye::Box.new(machine.dns_public, opts)
|
39
|
-
|
40
|
-
# Runs "before" scripts of routines config.
|
41
|
-
puts task_separator("BEFORE SCRIPTS")
|
42
|
-
Rudy::Routines::ScriptHelper.before(routine, sconf, machine, rbox)
|
43
|
-
|
44
|
-
# Runs "disk" portion of routines config
|
45
|
-
puts task_separator("DISK ROUTINES")
|
46
|
-
Rudy::Routines::DiskHelper.execute(routine, machine, rbox)
|
47
|
-
|
48
|
-
puts machine_separator(machine.liner_note)
|
49
|
-
end
|
50
|
-
|
51
|
-
|
52
|
-
# Runs "after_local" scripts
|
53
|
-
# NOTE: There "after" (remote) scripts are not run b/c the machines
|
54
|
-
# are no longer running.
|
55
|
-
puts task_separator("AFTER SCRIPTS (local)")
|
56
|
-
Rudy::Routines::ScriptHelper.after_local(routine, sconf, rbox_local)
|
57
|
-
|
58
29
|
end
|
59
|
-
|
30
|
+
|
60
31
|
end
|
61
32
|
|
62
33
|
end; end
|
@@ -1,61 +1,34 @@
|
|
1
1
|
|
2
2
|
|
3
3
|
module Rudy; module Routines;
|
4
|
-
|
5
4
|
class Startup < Rudy::Routines::Base
|
5
|
+
|
6
|
+
def init(*args)
|
7
|
+
@routine = fetch_routine_config(:startup)
|
8
|
+
end
|
9
|
+
|
10
|
+
# * +each_mach+ is an optional block which is executed between
|
11
|
+
# disk creation and the after scripts. The will receives two
|
12
|
+
# arguments: instances of Rudy::Machine and Rye::Box.
|
13
|
+
def execute(&each_mach)
|
14
|
+
routine_separator(:startup)
|
15
|
+
unless @routine
|
16
|
+
STDERR.puts "[this is a generic startup routine]"
|
17
|
+
@routine = {}
|
18
|
+
end
|
19
|
+
generic_machine_runner(:create) do |machine,rbox|
|
20
|
+
end
|
21
|
+
end
|
6
22
|
|
7
|
-
|
23
|
+
# Called by generic_machine_runner
|
24
|
+
def raise_early_exceptions
|
8
25
|
rmach = Rudy::Machines.new
|
9
26
|
# There's no keypair check here because Rudy::Machines will attempt
|
10
27
|
# to create one.
|
11
28
|
raise MachineGroupNotDefined, current_machine_group unless known_machine_group?
|
12
29
|
raise MachineGroupAlreadyRunning, current_machine_group if rmach.running?
|
13
|
-
|
14
|
-
routine = fetch_routine_config(:startup)
|
15
|
-
rbox_local = Rye::Box.new('localhost')
|
16
|
-
sconf = fetch_script_config
|
17
|
-
|
18
|
-
# Runs "before_local" scripts of routines config.
|
19
|
-
# NOTE: Does not run "before" scripts b/c there are no remote machines
|
20
|
-
puts task_separator("BEFORE SCRIPTS (local)")
|
21
|
-
Rudy::Routines::ScriptHelper.before_local(routine, sconf, rbox_local)
|
22
|
-
|
23
|
-
rmach.create do |machine|
|
24
|
-
#rmach.list do |machine|
|
25
|
-
puts machine_separator(machine.liner_note)
|
26
|
-
print "Waiting for instance..."
|
27
|
-
isup = Rudy::Utils.waiter(3, 120, STDOUT, "it's up!", 2) {
|
28
|
-
inst = machine.get_instance
|
29
|
-
inst && inst.running?
|
30
|
-
}
|
31
|
-
machine.update # Add instance info to machine and save it
|
32
|
-
print "Waiting for SSH daemon..."
|
33
|
-
isup = Rudy::Utils.waiter(2, 60, STDOUT, "it's up!", 3) {
|
34
|
-
Rudy::Utils.service_available?(machine.dns_public, 22)
|
35
|
-
}
|
36
|
-
|
37
|
-
opts = { :keys => root_keypairpath, :user => 'root', :debug => nil }
|
38
|
-
rbox = Rye::Box.new(machine.dns_public, opts)
|
39
|
-
|
40
|
-
puts task_separator("DISK ROUTINES")
|
41
|
-
# Runs "disk" portion of routines config
|
42
|
-
Rudy::Routines::DiskHelper.execute(routine, machine, rbox)
|
43
|
-
|
44
|
-
puts task_separator("AFTER SCRIPTS")
|
45
|
-
# Runs "after" scripts of routines config
|
46
|
-
Rudy::Routines::ScriptHelper.after(routine, sconf, machine, rbox)
|
47
|
-
|
48
|
-
puts task_separator("INFO")
|
49
|
-
puts "Filesystem on #{machine.name}:"
|
50
|
-
puts " " << rbox.df(:h).join("#{$/} ")
|
51
|
-
end
|
52
|
-
|
53
|
-
puts task_separator("AFTER SCRIPTS (local)")
|
54
|
-
# Runs "after_local" scripts of routines config
|
55
|
-
Rudy::Routines::ScriptHelper.after_local(routine, sconf, rbox_local)
|
56
|
-
|
57
30
|
end
|
58
|
-
|
31
|
+
|
59
32
|
end
|
60
33
|
|
61
34
|
end; end
|
data/lib/rudy/scm.rb
ADDED
@@ -0,0 +1,75 @@
|
|
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
ADDED
@@ -0,0 +1,215 @@
|
|
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
|
+
|
21
|
+
# * +args+ a hash of params from the git block in the routines config
|
22
|
+
#
|
23
|
+
def initialize(args={})
|
24
|
+
args = {
|
25
|
+
:privatekey => nil,
|
26
|
+
:remote => :origin,
|
27
|
+
:branch => :master,
|
28
|
+
:user => :root,
|
29
|
+
:path => nil
|
30
|
+
}.merge(args)
|
31
|
+
@remote, @branch, @path = args[:remote], args[:branch], args[:path]
|
32
|
+
@user, @pkey = args[:user], args[:privatekey]
|
33
|
+
@repo = Repo.new(Dir.pwd) if GIT.working_copy?
|
34
|
+
end
|
35
|
+
|
36
|
+
def engine; :git; end
|
37
|
+
|
38
|
+
def liner_note
|
39
|
+
"%-40s (git:%s:%s)" % [@rtag, @remote, @branch]
|
40
|
+
end
|
41
|
+
|
42
|
+
def create_release(username=nil, msg=nil)
|
43
|
+
@rtag = find_next_rtag(username)
|
44
|
+
msg ||= 'Another Release by Rudy!'
|
45
|
+
msg.tr!("'", "''")
|
46
|
+
ret = Rye.shell(:git, "tag", @rtag) # Use annotated? -a -m '#{msg}'
|
47
|
+
raise ret.stderr.join($/) if ret.exit_code > 0
|
48
|
+
ret = Rye.shell(:git, "push") if @remote
|
49
|
+
raise ret.stderr.join($/) if ret.exit_code > 0
|
50
|
+
ret = Rye.shell(:git, "push #{@remote} #{rtag}") if @remote
|
51
|
+
raise ret.stderr.join($/) if ret.exit_code > 0
|
52
|
+
@rtag
|
53
|
+
end
|
54
|
+
|
55
|
+
# rel-2009-03-05-user-rev
|
56
|
+
def find_next_rtag(username=nil)
|
57
|
+
now = Time.now
|
58
|
+
mon = now.mon.to_s.rjust(2, '0')
|
59
|
+
day = now.day.to_s.rjust(2, '0')
|
60
|
+
rev = "01"
|
61
|
+
criteria = ['rel', now.year, mon, day, rev]
|
62
|
+
criteria.insert(-2, username) if username
|
63
|
+
rev.succ! while valid_rtag?(criteria.join(Rudy::DELIM)) && rev.to_i < 50
|
64
|
+
raise TooManyTags if rev.to_i >= 50
|
65
|
+
criteria.join(Rudy::DELIM)
|
66
|
+
end
|
67
|
+
|
68
|
+
def delete_rtag(rtag=nil)
|
69
|
+
rtag ||= @rtag
|
70
|
+
ret = execute_rbox_command { Rye.shell(:git, 'tag', :d, rtag) }
|
71
|
+
raise ret.stderr.join($/) if ret.exit_code > 0 # TODO: retest
|
72
|
+
# Equivalent to: "git push origin :tag-name" which deletes a remote tag
|
73
|
+
ret = execute_rbox_command { Rye.shell(:git, "push #{@remote} :#{rtag}") } if @remote
|
74
|
+
raise ret.stderr.join($/) if ret.exit_code > 0
|
75
|
+
true
|
76
|
+
end
|
77
|
+
|
78
|
+
def create_remote_checkout(rbox)
|
79
|
+
|
80
|
+
# Make sure the directory above the clone path exists
|
81
|
+
# and that it's owned by the request user.
|
82
|
+
rbox.mkdir(:p, File.dirname(@path))
|
83
|
+
rbox.chown(@user, File.dirname(@path))
|
84
|
+
|
85
|
+
begin
|
86
|
+
original_user = rbox.user
|
87
|
+
rbox.switch_user(@user)
|
88
|
+
|
89
|
+
if @pkey
|
90
|
+
# Try when debugging: ssh -vi path/2/pkey git@github.com
|
91
|
+
key = File.basename(@pkey)
|
92
|
+
homedir = rbox.getenv['HOME']
|
93
|
+
rbox.mkdir(:p, :m, '700', '.ssh') rescue nil # :p says keep quiet if it exists
|
94
|
+
if rbox.file_exists?(".ssh/#{key}")
|
95
|
+
puts " Remote private key #{key} already exists".colour(:red)
|
96
|
+
else
|
97
|
+
rbox.upload(@pkey, ".ssh/#{key}")
|
98
|
+
end
|
99
|
+
|
100
|
+
# NOTE: The following are two attempts at telling git which
|
101
|
+
# private key to use. Both fail. The only thing I could get
|
102
|
+
# to work is modifying the ~/.ssh/config file.
|
103
|
+
#
|
104
|
+
# This runs fine, but "git clone" doesn't care.
|
105
|
+
# git config --global --replace-all http.sslKey /home/delano/.ssh/id_rsa
|
106
|
+
# rbox.git('config', '--global', '--replace-all', 'http.sslKey', "#{homedir}/.ssh/#{key}")
|
107
|
+
|
108
|
+
# "git clone" doesn't care about this either. Note that both these
|
109
|
+
# config attempts come directly from the git-config man page:
|
110
|
+
# http://www.kernel.org/pub/software/scm/git/docs/git-config.html
|
111
|
+
# export GIT_SSL_KEY=/home/delano/.ssh/id_rsa
|
112
|
+
# rbox.setenv("GIT_SSL_KEY", "#{homedir}/.ssh/#{key}")
|
113
|
+
|
114
|
+
if rbox.file_exists?('.ssh/config')
|
115
|
+
rbox.cp('.ssh/config', ".ssh/config-previous")
|
116
|
+
ssh_config = rbox.download('.ssh/config')
|
117
|
+
end
|
118
|
+
|
119
|
+
ssh_config ||= StringIO.new
|
120
|
+
ssh_config.puts $/, "IdentityFile #{homedir}/.ssh/#{key}"
|
121
|
+
puts " Adding IdentityFile #{key} to #{homedir}/.ssh/config"
|
122
|
+
|
123
|
+
rbox.upload(ssh_config, '.ssh/config')
|
124
|
+
rbox.chmod('0600', '.ssh/config')
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
# We need to add the host keys to the user's known_hosts file
|
129
|
+
# to prevent the git commands from failing when it raises the
|
130
|
+
# "Host key verification failed." messsage.
|
131
|
+
if rbox.file_exists?('.ssh/known_hosts')
|
132
|
+
rbox.cp('.ssh/known_hosts', ".ssh/known_hosts-previous")
|
133
|
+
known_hosts = rbox.download('.ssh/known_hosts')
|
134
|
+
end
|
135
|
+
known_hosts ||= StringIO.new
|
136
|
+
remote = get_remote_uri
|
137
|
+
host = URI.parse(remote).host rescue nil
|
138
|
+
host ||= remote.scan(/\A.+?@(.+?)\:/).flatten.first
|
139
|
+
known_hosts.puts $/, Rye.remote_host_keys(host)
|
140
|
+
puts " Adding host key for #{host} to .ssh/known_hosts"
|
141
|
+
|
142
|
+
rbox.upload(known_hosts, '.ssh/known_hosts')
|
143
|
+
rbox.chmod('0600', '.ssh/known_hosts')
|
144
|
+
|
145
|
+
execute_rbox_command {
|
146
|
+
rbox.git('clone', get_remote_uri, @path)
|
147
|
+
}
|
148
|
+
rbox.cd(@path)
|
149
|
+
execute_rbox_command {
|
150
|
+
rbox.git('checkout', :b, @rtag)
|
151
|
+
}
|
152
|
+
rescue Rye::CommandError => ex
|
153
|
+
puts ex.message
|
154
|
+
ensure
|
155
|
+
# Return to the original user and directory
|
156
|
+
rbox.switch_user(original_user)
|
157
|
+
rbox.cd
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
def get_remote_uri
|
164
|
+
ret = Rye.shell(:git, "config", "remote.#{@remote}.url")
|
165
|
+
ret.stdout.first
|
166
|
+
end
|
167
|
+
|
168
|
+
# Check if the given remote is valid.
|
169
|
+
#def has_remote?(remote)
|
170
|
+
# success = false
|
171
|
+
# (@repo.remotes || []).each do |r|
|
172
|
+
# end
|
173
|
+
# success
|
174
|
+
#end
|
175
|
+
|
176
|
+
def valid_rtag?(tag)
|
177
|
+
# git tag -l tagname returns a 0 exit code and stdout is empty
|
178
|
+
# when a tag does not exit. When it does exist, the exit code
|
179
|
+
# is 0 and stdout contains the tagname.
|
180
|
+
ret = Rye.shell(:git, 'tag', :l, tag)
|
181
|
+
# change :l to :d for quick deleting above and return true
|
182
|
+
# OR: just change to :d to always recreate the same tag
|
183
|
+
(ret.exit_code == 0 && ret.stdout.to_s == tag)
|
184
|
+
end
|
185
|
+
|
186
|
+
# Are all local changes committed?
|
187
|
+
def self.clean_working_copy?(path=Dir.pwd)
|
188
|
+
Rye.shell(:git, 'diff').stdout == []
|
189
|
+
end
|
190
|
+
def clean_working_copy?; GIT.clean_working_copy?; end
|
191
|
+
|
192
|
+
def self.working_copy?(path=Dir.pwd)
|
193
|
+
(File.exists?(File.join(path, '.git')))
|
194
|
+
end
|
195
|
+
def working_copy?; GIT.working_copy?; end
|
196
|
+
|
197
|
+
def raise_early_exceptions
|
198
|
+
raise NotAWorkingCopy, :git unless working_copy?
|
199
|
+
#raise DirtyWorkingCopy, :git unless clean_working_copy?
|
200
|
+
raise NoRemoteURI, "remote.#{@remote}.url not set" if get_remote_uri.nil?
|
201
|
+
raise NoRemotePath, :git if @path.nil?
|
202
|
+
raise PrivateKeyNotFound, @pkey if @pkey && !File.exists?(@pkey)
|
203
|
+
find_next_rtag # will raise exception is there's a problem
|
204
|
+
|
205
|
+
# We can't check stuff that requires access to the machine b/c the
|
206
|
+
# machine may not be running yet. These include:
|
207
|
+
# * Remote checkout path already exists
|
208
|
+
# * No git available
|
209
|
+
# ...
|
210
|
+
# If create_remote_checkout should fail, it should print a message
|
211
|
+
# about the release that was created and how to install it manually
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|