right_scraper 3.0.4 → 3.2.3
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/Gemfile +7 -8
- data/README.rdoc +3 -1
- data/lib/right_scraper/logger.rb +2 -2
- data/lib/right_scraper/processes/ssh.rb +103 -71
- data/lib/right_scraper/resources/cookbook.rb +35 -2
- data/lib/right_scraper/retrievers/checkout.rb +3 -3
- data/lib/right_scraper/retrievers/download.rb +81 -18
- data/lib/right_scraper/retrievers/git.rb +37 -3
- data/lib/right_scraper/retrievers/svn.rb +7 -16
- data/lib/right_scraper/scanners/cookbook_manifest.rb +2 -2
- data/lib/right_scraper/scanners/cookbook_s3_upload.rb +8 -7
- data/lib/right_scraper/scraper.rb +4 -4
- data/lib/right_scraper/svn_client.rb +73 -11
- data/right_scraper.gemspec +18 -18
- data/right_scraper.rconf +1 -1
- data/spec/cookbook_manifest_spec.rb +43 -5
- data/spec/cookbook_s3_upload_spec.rb +8 -3
- data/spec/download/download_spec.rb +3 -5
- data/spec/git/cookbook_spec.rb +6 -7
- data/spec/git/retriever_spec.rb +5 -5
- data/spec/git/scraper_spec.rb +16 -1
- data/spec/git/ssh_spec.rb +5 -2
- data/spec/retriever_spec_helper.rb +2 -2
- data/spec/scraper_helper.rb +0 -10
- data/spec/spec_helper.rb +5 -5
- data/spec/svn/cookbook_spec.rb +5 -6
- data/spec/svn/svn_retriever_spec_helper.rb +5 -6
- metadata +60 -48
data/Gemfile
CHANGED
@@ -1,15 +1,14 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
gem
|
6
|
-
|
7
|
-
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
gem 'right_popen', :git => 'git@github.com:rightscale/right_popen.git',
|
6
|
+
:branch => "master"
|
7
|
+
|
8
|
+
gem 'right_support', '2.7'
|
8
9
|
|
9
10
|
group :development do
|
10
|
-
gem "rspec", "~> 2.3"
|
11
11
|
gem "rake", "0.8.7"
|
12
|
-
gem "flexmock"
|
13
12
|
gem "ruby-debug", :platform=>"ruby_18"
|
14
13
|
gem "ruby-debug19", :platform=>"ruby_19"
|
15
14
|
gem "rdoc", "~> 2.4"
|
data/README.rdoc
CHANGED
@@ -10,6 +10,8 @@ may specify only the functionality (and required libraries and gems) you require
|
|
10
10
|
This gem depends on all available RightScraper modules, enabling full support at the
|
11
11
|
cost of requiring some systems administration work external to Ruby.
|
12
12
|
|
13
|
+
Maintained by the RightScale Teal Team
|
14
|
+
|
13
15
|
== USAGE
|
14
16
|
|
15
17
|
=== Simple Example
|
@@ -17,7 +19,7 @@ cost of requiring some systems administration work external to Ruby.
|
|
17
19
|
require 'rubygems'
|
18
20
|
require 'right_scraper'
|
19
21
|
|
20
|
-
scraper =
|
22
|
+
scraper = RightScraper::Scraper.new(:basedir => '/tmp', :kind => :cookbook)
|
21
23
|
scraper.scrape(:type => :git, :url => 'git://github.com/rightscale/right_scraper.git')
|
22
24
|
|
23
25
|
== INSTALLATION
|
data/lib/right_scraper/logger.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright: Copyright (c) 2010 RightScale, Inc.
|
2
|
+
# Copyright: Copyright (c) 2010-2013 RightScale, Inc.
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining
|
5
5
|
# a copy of this software and associated documentation files (the
|
@@ -20,14 +20,19 @@
|
|
20
20
|
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
21
21
|
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
22
|
#++
|
23
|
+
|
23
24
|
require 'tempfile'
|
24
|
-
require 'process_watcher'
|
25
25
|
require 'tmpdir'
|
26
|
+
require 'right_popen'
|
27
|
+
require 'right_popen/safe_output_buffer'
|
26
28
|
|
27
29
|
module RightScraper
|
28
30
|
module Processes
|
29
31
|
# Manage a dedicated SSH agent.
|
30
32
|
class SSHAgent
|
33
|
+
|
34
|
+
class SSHAgentError < Exception; end
|
35
|
+
|
31
36
|
def initialize
|
32
37
|
@display = ENV['DISPLAY']
|
33
38
|
@askpass = ENV['SSH_ASKPASS']
|
@@ -46,26 +51,31 @@ module RightScraper
|
|
46
51
|
ENV['HOME'] = "/dev/null"
|
47
52
|
@dir = Dir.mktmpdir
|
48
53
|
@socketfile = File.join(@dir, "agent")
|
49
|
-
@
|
50
|
-
@
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
54
|
+
@process = nil
|
55
|
+
@interupted_to_close = false
|
56
|
+
@ssh_agent_output = ::RightScale::RightPopen::SafeOutputBuffer.new
|
57
|
+
cmd = ['ssh-agent', '-a', @socketfile, '-d']
|
58
|
+
::RightScale::RightPopen.popen3_sync(
|
59
|
+
cmd,
|
60
|
+
:target => self,
|
61
|
+
:inherit_io => true, # avoid killing any rails connection
|
62
|
+
:watch_handler => :watch_ssh_agent,
|
63
|
+
:stderr_handler => :output_ssh_agent,
|
64
|
+
:stdout_handler => :output_ssh_agent,
|
65
|
+
:timeout_handler => :timeout_ssh_agent,
|
66
|
+
:exit_handler => :exit_ssh_agent,
|
67
|
+
:timeout_seconds => 10)
|
68
|
+
if @process
|
69
|
+
ENV['SSH_AGENT_PID'] = @process.pid.to_s
|
70
|
+
ENV['SSH_AUTH_SOCK'] = @socketfile
|
58
71
|
end
|
59
|
-
ENV['SSH_AGENT_PID'] = @pid.to_s
|
60
|
-
ENV['SSH_AUTH_SOCK'] = @socketfile
|
61
72
|
end
|
62
73
|
|
63
74
|
# Close the connection to the SSH agent, and restore +ENV+.
|
64
75
|
def close
|
65
76
|
begin
|
66
77
|
FileUtils.remove_entry_secure @dir
|
67
|
-
lay_to_rest
|
68
|
-
@monitor.cleanup if @monitor
|
78
|
+
lay_to_rest
|
69
79
|
ensure
|
70
80
|
setvar 'SSH_AGENT_PID', @agentpid
|
71
81
|
setvar 'DISPLAY', @display
|
@@ -75,71 +85,35 @@ module RightScraper
|
|
75
85
|
end
|
76
86
|
end
|
77
87
|
|
78
|
-
|
79
|
-
|
80
|
-
# SIGKILL instead. In any case, the process will die. The
|
81
|
-
# status information is accessible in $?.
|
82
|
-
#
|
83
|
-
# === Parameters
|
84
|
-
# pid(Fixnum):: pid of process to kill
|
85
|
-
# timeout(Fixnum):: time in seconds to wait before forcing
|
86
|
-
# process to die. Defaults to 10 seconds.
|
87
|
-
def lay_to_rest(pid, timeout=10)
|
88
|
-
#refuse to kill ourselves, or to pass a bad arg to Process.kill
|
89
|
-
return 0 unless pid.is_a?(Integer) && pid > 0
|
90
|
-
|
91
|
-
Process.kill('TERM', pid)
|
92
|
-
time_waited = 0
|
93
|
-
loop do
|
94
|
-
if time_waited >= timeout
|
95
|
-
Process.kill('KILL', pid)
|
96
|
-
# can't waitpid here, because the ssh-agent isn't our
|
97
|
-
# child. Still, after SIGKILL it will die and init will
|
98
|
-
# reap it, so continue
|
99
|
-
return
|
100
|
-
end
|
101
|
-
# still can't waitpid here, so we see if it's still alive
|
102
|
-
return unless still_alive?(pid)
|
103
|
-
sleep 1
|
104
|
-
time_waited += 1
|
105
|
-
end
|
88
|
+
def output_ssh_agent(data)
|
89
|
+
@ssh_agent_output.safe_buffer_data(data)
|
106
90
|
end
|
107
91
|
|
108
|
-
#
|
109
|
-
# the 0 signal and checking for an exception.
|
92
|
+
# abandons watch when socket file appears
|
110
93
|
#
|
111
|
-
#
|
112
|
-
|
113
|
-
|
114
|
-
# === Return
|
115
|
-
# Boolean:: true if process is still alive
|
116
|
-
def still_alive?(pid)
|
117
|
-
begin
|
118
|
-
Process.kill(0, pid)
|
94
|
+
# @return [TrueClass|FalseClass] true to continue watch, false to abandon
|
95
|
+
def watch_ssh_agent(process)
|
96
|
+
if @interupted_to_close
|
119
97
|
true
|
120
|
-
|
121
|
-
|
98
|
+
else
|
99
|
+
@process = process
|
100
|
+
!::File.exists?(@socketfile)
|
122
101
|
end
|
123
102
|
end
|
124
103
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
if value.nil?
|
136
|
-
ENV.delete(key)
|
137
|
-
else
|
138
|
-
ENV[key] = value
|
104
|
+
def timeout_ssh_agent
|
105
|
+
unless @interupted_to_close
|
106
|
+
raise SSHAgentError, 'Timed out waiting for ssh-agent control socket to appear'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def exit_ssh_agent(status)
|
111
|
+
unless @interupted_to_close || status.success?
|
112
|
+
@ssh_agent_output.safe_buffer_data("Exit code = #{status.exitstatus}")
|
113
|
+
raise SSHAgentError, "ssh-agent failed: #{@ssh_agent_output.display_text}"
|
139
114
|
end
|
140
115
|
true
|
141
116
|
end
|
142
|
-
private :setvar
|
143
117
|
|
144
118
|
# Add the given key data to the ssh agent.
|
145
119
|
#
|
@@ -162,7 +136,33 @@ module RightScraper
|
|
162
136
|
# === Parameters
|
163
137
|
# file(String):: file containing key data
|
164
138
|
def add_keyfile(file)
|
165
|
-
|
139
|
+
@ssh_add_output = ::RightScale::RightPopen::SafeOutputBuffer.new
|
140
|
+
cmd = ['ssh-add', file]
|
141
|
+
::RightScale::RightPopen.popen3_sync(
|
142
|
+
cmd,
|
143
|
+
:target => self,
|
144
|
+
:inherit_io => true, # avoid killing any rails connection
|
145
|
+
:stderr_handler => :output_ssh_add,
|
146
|
+
:stdout_handler => :output_ssh_add,
|
147
|
+
:timeout_handler => :timeout_ssh_add,
|
148
|
+
:exit_handler => :exit_ssh_add,
|
149
|
+
:timeout_seconds => 10)
|
150
|
+
end
|
151
|
+
|
152
|
+
def output_ssh_add(data)
|
153
|
+
@ssh_add_output.safe_buffer_data(data)
|
154
|
+
end
|
155
|
+
|
156
|
+
def timeout_ssh_add
|
157
|
+
raise SSHAgentError, 'ssh-add timed out'
|
158
|
+
end
|
159
|
+
|
160
|
+
def exit_ssh_add(status)
|
161
|
+
unless status.success?
|
162
|
+
@ssh_add_output.safe_buffer_data("Exit code = #{status.exitstatus}")
|
163
|
+
raise SSHAgentError, "ssh-add failed: #{@ssh_add_output.display_text}"
|
164
|
+
end
|
165
|
+
true
|
166
166
|
end
|
167
167
|
|
168
168
|
# Execute the block in a new ssh agent.
|
@@ -183,6 +183,38 @@ module RightScraper
|
|
183
183
|
agent.close
|
184
184
|
end
|
185
185
|
end
|
186
|
+
|
187
|
+
private
|
188
|
+
|
189
|
+
def lay_to_rest
|
190
|
+
if @process
|
191
|
+
if @process.interrupt
|
192
|
+
@interupted_to_close = true
|
193
|
+
@process.sync_exit_with_target
|
194
|
+
else
|
195
|
+
@process.safe_close_io
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# Set an environment variable to a value. If +value+ is nil,
|
201
|
+
# delete the variable instead.
|
202
|
+
#
|
203
|
+
# === Parameters
|
204
|
+
# key(String):: environment variable name
|
205
|
+
# value(String or nil):: proposed new value
|
206
|
+
#
|
207
|
+
# === Return
|
208
|
+
# true
|
209
|
+
def setvar(key, value)
|
210
|
+
if value.nil?
|
211
|
+
ENV.delete(key)
|
212
|
+
else
|
213
|
+
ENV[key] = value
|
214
|
+
end
|
215
|
+
true
|
216
|
+
end
|
217
|
+
|
186
218
|
end
|
187
219
|
end
|
188
220
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright: Copyright (c) 2010-
|
2
|
+
# Copyright: Copyright (c) 2010-2012 RightScale, Inc.
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining
|
5
5
|
# a copy of this software and associated documentation files (the
|
@@ -21,12 +21,45 @@
|
|
21
21
|
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
22
|
#++
|
23
23
|
|
24
|
+
require 'digest/md5'
|
25
|
+
require 'json'
|
26
|
+
require 'right_support'
|
27
|
+
|
24
28
|
module RightScraper
|
25
29
|
|
26
30
|
module Resources
|
27
31
|
|
28
32
|
class Cookbook < Base
|
29
|
-
end
|
30
33
|
|
34
|
+
EMPTY_MANIFEST_JSON = ::JSON.dump(:manifest => {}).freeze
|
35
|
+
|
36
|
+
def manifest=(value)
|
37
|
+
@manifest_json = nil
|
38
|
+
@resource_hash = nil
|
39
|
+
@manifest = value
|
40
|
+
end
|
41
|
+
|
42
|
+
def manifest_json
|
43
|
+
unless @manifest_json
|
44
|
+
if manifest && !manifest.empty?
|
45
|
+
# note that we are preserving the :manifest key at the root only to
|
46
|
+
# avoid having to change how the manifest is interpreted by Repose.
|
47
|
+
manifest_hash = { :manifest => manifest }
|
48
|
+
@manifest_json = ::RightSupport::Data::HashTools.deep_sorted_json(manifest_hash, pretty=true).freeze
|
49
|
+
else
|
50
|
+
@manifest_json = EMPTY_MANIFEST_JSON
|
51
|
+
end
|
52
|
+
end
|
53
|
+
@manifest_json
|
54
|
+
end
|
55
|
+
|
56
|
+
def resource_hash
|
57
|
+
unless @resource_hash
|
58
|
+
@resource_hash = ::Digest::MD5.hexdigest(manifest_json).freeze
|
59
|
+
end
|
60
|
+
@resource_hash
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
31
64
|
end
|
32
65
|
end
|
@@ -40,9 +40,9 @@ module RightScraper
|
|
40
40
|
@logger.operation(:updating) do
|
41
41
|
do_update
|
42
42
|
end
|
43
|
-
rescue
|
44
|
-
@logger.note_error(
|
45
|
-
FileUtils.remove_entry_secure
|
43
|
+
rescue Exception => e
|
44
|
+
@logger.note_error(e, :updating, "switching to using checkout")
|
45
|
+
FileUtils.remove_entry_secure basedir
|
46
46
|
@logger.operation(:checkout) do
|
47
47
|
do_checkout
|
48
48
|
end
|
@@ -20,9 +20,11 @@
|
|
20
20
|
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
21
21
|
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
22
|
#++
|
23
|
-
|
23
|
+
|
24
24
|
require 'tempfile'
|
25
25
|
require 'digest/sha1'
|
26
|
+
require 'right_popen'
|
27
|
+
require 'right_popen/safe_output_buffer'
|
26
28
|
|
27
29
|
module RightScraper
|
28
30
|
module Retrievers
|
@@ -30,6 +32,8 @@ module RightScraper
|
|
30
32
|
# somewhere. Uses command line curl and command line tar.
|
31
33
|
class Download < Base
|
32
34
|
|
35
|
+
class DownloadError < Exception; end
|
36
|
+
|
33
37
|
@@available = false
|
34
38
|
|
35
39
|
# Determines if downloader is available.
|
@@ -54,32 +58,48 @@ module RightScraper
|
|
54
58
|
|
55
59
|
# Directory used to download tarballs
|
56
60
|
def workdir
|
57
|
-
File.join(@
|
58
|
-
end
|
59
|
-
|
60
|
-
# Path to directory where files are retrieved
|
61
|
-
def repo_dir
|
62
|
-
File.join(workdir, "archive")
|
61
|
+
@workdir ||= ::File.join(::File.dirname(@repo_dir), 'download')
|
63
62
|
end
|
64
63
|
|
65
64
|
# Download tarball and unpack it
|
66
65
|
def retrieve
|
67
66
|
raise RetrieverError.new("download retriever is unavailable") unless available?
|
67
|
+
FileUtils.remove_entry_secure @repo_dir if File.exists?(@repo_dir)
|
68
68
|
FileUtils.remove_entry_secure workdir if File.exists?(workdir)
|
69
|
-
FileUtils.mkdir_p repo_dir
|
69
|
+
FileUtils.mkdir_p @repo_dir
|
70
|
+
FileUtils.mkdir_p workdir
|
70
71
|
file = File.join(workdir, "package")
|
71
72
|
|
72
73
|
@logger.operation(:downloading) do
|
73
74
|
credential_command = if @repository.first_credential && @repository.second_credential
|
74
|
-
[
|
75
|
+
['-u', "#{@repository.first_credential}:#{@repository.second_credential}"]
|
75
76
|
else
|
76
77
|
[]
|
77
78
|
end
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
79
|
+
@output = ::RightScale::RightPopen::SafeOutputBuffer.new
|
80
|
+
@cmd = [
|
81
|
+
'curl',
|
82
|
+
'--silent', '--show-error', '--location', '--fail',
|
83
|
+
'--location-trusted', '-o', file, credential_command,
|
84
|
+
@repository.url
|
85
|
+
].flatten
|
86
|
+
begin
|
87
|
+
::RightScale::RightPopen.popen3_sync(
|
88
|
+
@cmd,
|
89
|
+
:target => self,
|
90
|
+
:pid_handler => :pid_download,
|
91
|
+
:timeout_handler => :timeout_download,
|
92
|
+
:size_limit_handler => :size_limit_download,
|
93
|
+
:exit_handler => :exit_download,
|
94
|
+
:stderr_handler => :output_download,
|
95
|
+
:stdout_handler => :output_download,
|
96
|
+
:inherit_io => true, # avoid killing any rails connection
|
97
|
+
:watch_directory => workdir,
|
98
|
+
:size_limit_bytes => @max_bytes,
|
99
|
+
:timeout_seconds => @max_seconds)
|
100
|
+
rescue Exception => e
|
101
|
+
@logger.note_phase(:abort, :running_command, 'curl', e)
|
102
|
+
raise
|
83
103
|
end
|
84
104
|
end
|
85
105
|
|
@@ -94,15 +114,58 @@ module RightScraper
|
|
94
114
|
else
|
95
115
|
extraction = "xf"
|
96
116
|
end
|
97
|
-
Dir.chdir(repo_dir) do
|
98
|
-
|
99
|
-
|
100
|
-
|
117
|
+
Dir.chdir(@repo_dir) do
|
118
|
+
@output = ::RightScale::RightPopen::SafeOutputBuffer.new
|
119
|
+
@cmd = ['tar', extraction, file]
|
120
|
+
begin
|
121
|
+
::RightScale::RightPopen.popen3_sync(
|
122
|
+
@cmd,
|
123
|
+
:target => self,
|
124
|
+
:pid_handler => :pid_download,
|
125
|
+
:timeout_handler => :timeout_download,
|
126
|
+
:size_limit_handler => :size_limit_download,
|
127
|
+
:exit_handler => :exit_download,
|
128
|
+
:stderr_handler => :output_download,
|
129
|
+
:stdout_handler => :output_download,
|
130
|
+
:inherit_io => true, # avoid killing any rails connection
|
131
|
+
:watch_directory => @repo_dir,
|
132
|
+
:size_limit_bytes => @max_bytes,
|
133
|
+
:timeout_seconds => @max_seconds)
|
134
|
+
rescue Exception => e
|
135
|
+
@logger.note_phase(:abort, :running_command, @cmd.first, e)
|
136
|
+
raise
|
101
137
|
end
|
102
138
|
end
|
103
139
|
end
|
104
140
|
end
|
105
141
|
|
142
|
+
def pid_download(pid)
|
143
|
+
@logger.note_phase(:begin, :running_command, @cmd.first)
|
144
|
+
true
|
145
|
+
end
|
146
|
+
|
147
|
+
def output_download(data)
|
148
|
+
@output.safe_buffer_data(data)
|
149
|
+
end
|
150
|
+
|
151
|
+
def timeout_download
|
152
|
+
raise DownloadError, "Downloader timed out"
|
153
|
+
end
|
154
|
+
|
155
|
+
def size_limit_download
|
156
|
+
raise DownloadError, "Downloader exceeded size limit"
|
157
|
+
end
|
158
|
+
|
159
|
+
def exit_download(status)
|
160
|
+
unless status.success?
|
161
|
+
@output.safe_buffer_data("Exit code = #{status.exitstatus}")
|
162
|
+
raise DownloadError, "Downloader failed: #{@output.display_text}"
|
163
|
+
end
|
164
|
+
@logger.note_phase(:commit, :running_command, @cmd.first)
|
165
|
+
true
|
166
|
+
end
|
167
|
+
|
168
|
+
|
106
169
|
# Amend @repository with the tag information from the downloaded
|
107
170
|
# file.
|
108
171
|
#
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright: Copyright (c) 2010-
|
2
|
+
# Copyright: Copyright (c) 2010-2013 RightScale, Inc.
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining
|
5
5
|
# a copy of this software and associated documentation files (the
|
@@ -23,6 +23,35 @@
|
|
23
23
|
|
24
24
|
require 'tmpdir'
|
25
25
|
|
26
|
+
# TEAL FIX: figure out a way to do this monkey-patch without always rquiring the
|
27
|
+
# blackwinter gem and/or create a rightscale-git fork with this fix.
|
28
|
+
#
|
29
|
+
# ADDENDUM: we can't unconditionally require the git gem because git is not
|
30
|
+
# always available.
|
31
|
+
begin
|
32
|
+
require 'git'
|
33
|
+
require 'git/lib'
|
34
|
+
|
35
|
+
module Git
|
36
|
+
class Lib
|
37
|
+
# Monkey patch to blackwinter-git that strips ANSI escape sequences
|
38
|
+
# from command output to avoid confusing the parser.
|
39
|
+
def run_command_with_color_stripping(git_cmd, &block)
|
40
|
+
out = run_command_without_color_stripping(git_cmd, &block)
|
41
|
+
out.gsub!(/\e\[[^m]*m/, '')
|
42
|
+
out
|
43
|
+
end
|
44
|
+
|
45
|
+
unless self.methods.include?('run_command_without_color_stripping')
|
46
|
+
alias :run_command_without_color_stripping :run_command
|
47
|
+
alias :run_command :run_command_with_color_stripping
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
rescue ::Git::GitExecuteError
|
52
|
+
# silently ignore git gem's failed attempt to execute git on load.
|
53
|
+
end
|
54
|
+
|
26
55
|
module RightScraper
|
27
56
|
module Retrievers
|
28
57
|
# Retriever for resources stored in a git repository.
|
@@ -33,7 +62,6 @@ module RightScraper
|
|
33
62
|
def available?
|
34
63
|
unless @@available
|
35
64
|
begin
|
36
|
-
require 'git'
|
37
65
|
# note that require 'git' does the same version check on load but
|
38
66
|
# we don't want to assume any particular implementation.
|
39
67
|
#
|
@@ -95,7 +123,13 @@ module RightScraper
|
|
95
123
|
def do_update
|
96
124
|
git = ::Git.open(@repo_dir)
|
97
125
|
do_fetch(git)
|
98
|
-
|
126
|
+
@logger.operation(:cleanup, "ensure no untracked files in #{@repo_dir}") do
|
127
|
+
git.reset_hard
|
128
|
+
Dir.chdir(@repo_dir) do
|
129
|
+
# ignore outcome; there is no way to record 'warnings'
|
130
|
+
system("git clean -f")
|
131
|
+
end
|
132
|
+
end
|
99
133
|
do_checkout_revision(git)
|
100
134
|
do_update_tag(git)
|
101
135
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright: Copyright (c) 2010-
|
2
|
+
# Copyright: Copyright (c) 2010-2013 RightScale, Inc.
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining
|
5
5
|
# a copy of this software and associated documentation files (the
|
@@ -22,8 +22,6 @@
|
|
22
22
|
#++
|
23
23
|
require File.join(File.dirname(__FILE__), '..', 'svn_client')
|
24
24
|
|
25
|
-
require 'process_watcher'
|
26
|
-
|
27
25
|
module RightScraper
|
28
26
|
module Retrievers
|
29
27
|
# Retriever for svn repositories
|
@@ -37,17 +35,10 @@ module RightScraper
|
|
37
35
|
def available?
|
38
36
|
unless @@available
|
39
37
|
begin
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
if $?.success?
|
45
|
-
@@available = true
|
46
|
-
else
|
47
|
-
raise RetrieverError, "\"#{cmd}\" exited with #{$?.exitstatus}"
|
48
|
-
end
|
49
|
-
rescue
|
50
|
-
@logger.note_error($!, :available, "svn retriever is unavailable")
|
38
|
+
calculate_version
|
39
|
+
@@available = true
|
40
|
+
rescue SvnClientError => e
|
41
|
+
@logger.note_error(e, :available, "svn retriever is unavailable")
|
51
42
|
end
|
52
43
|
end
|
53
44
|
@@available
|
@@ -81,8 +72,8 @@ module RightScraper
|
|
81
72
|
# pick out the first tag.
|
82
73
|
def do_update_tag
|
83
74
|
@repository = @repository.clone
|
84
|
-
|
85
|
-
|
75
|
+
lines = run_svn_with_buffered_output("log", "-r", 'HEAD')
|
76
|
+
lines.each do |line|
|
86
77
|
if line =~ /^r(\d+)/
|
87
78
|
@repository.tag = $1
|
88
79
|
break
|
@@ -22,7 +22,7 @@
|
|
22
22
|
#++
|
23
23
|
|
24
24
|
require File.expand_path(File.join(File.dirname(__FILE__), 'base'))
|
25
|
-
require 'digest/
|
25
|
+
require 'digest/md5'
|
26
26
|
|
27
27
|
module RightScraper
|
28
28
|
module Scanners
|
@@ -52,7 +52,7 @@ module RightScraper
|
|
52
52
|
# === Parameters ===
|
53
53
|
# relative_position(String):: relative pathname for file from root of resource
|
54
54
|
def notice(relative_position)
|
55
|
-
@manifest[relative_position] = Digest::
|
55
|
+
@manifest[relative_position] = Digest::MD5.hexdigest(yield)
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright: Copyright (c) 2010-
|
2
|
+
# Copyright: Copyright (c) 2010-2012 RightScale, Inc.
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining
|
5
5
|
# a copy of this software and associated documentation files (the
|
@@ -22,6 +22,7 @@
|
|
22
22
|
#++
|
23
23
|
require 'right_aws'
|
24
24
|
require 'json'
|
25
|
+
require 'digest/md5'
|
25
26
|
|
26
27
|
module RightScraper
|
27
28
|
module Scanners
|
@@ -56,11 +57,11 @@ module RightScraper
|
|
56
57
|
# === Parameters
|
57
58
|
# cookbook(RightScraper::Cookbook):: cookbook to scan
|
58
59
|
def end(cookbook)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
60
|
+
path = File.join('Cooks', cookbook.resource_hash)
|
61
|
+
unless @bucket.key(path).exists?
|
62
|
+
contents = cookbook.manifest_json
|
63
|
+
@bucket.put(path, contents)
|
64
|
+
end
|
64
65
|
end
|
65
66
|
|
66
67
|
# Upload a file during scanning.
|
@@ -73,7 +74,7 @@ module RightScraper
|
|
73
74
|
# relative_position(String):: relative pathname for file from root of cookbook
|
74
75
|
def notice(relative_position)
|
75
76
|
contents = yield
|
76
|
-
name = Digest::
|
77
|
+
name = Digest::MD5.hexdigest(contents)
|
77
78
|
path = File.join('Files', name)
|
78
79
|
unless @bucket.key(path).exists?
|
79
80
|
@bucket.put(path, contents)
|