smart_proxy_abrt 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/README +4 -0
- data/Rakefile +25 -0
- data/bin/smart-proxy-abrt-send +92 -0
- data/bundler.d/abrt.rb +6 -0
- data/extra/foreman-proxy-abrt-send.cron +2 -0
- data/extra/rubygem-smart_proxy_abrt.spec +110 -0
- data/lib/smart_proxy_abrt.rb +3 -0
- data/lib/smart_proxy_abrt/abrt_api.rb +76 -0
- data/lib/smart_proxy_abrt/abrt_lib.rb +244 -0
- data/lib/smart_proxy_abrt/abrt_plugin.rb +12 -0
- data/lib/smart_proxy_abrt/abrt_version.rb +5 -0
- data/lib/smart_proxy_abrt/http_config.ru +5 -0
- data/settings.d/abrt.yml.example +26 -0
- data/test/abrt_api_test.rb +90 -0
- data/test/abrt_test.rb +125 -0
- data/test/fixtures/ureport-ondisk-host1-01 +1 -0
- data/test/fixtures/ureport-ondisk-host1-02 +1 -0
- data/test/fixtures/ureport-ondisk-host1-03 +1 -0
- data/test/fixtures/ureport-ondisk-host2-01 +1 -0
- data/test/fixtures/ureport1.json +45 -0
- data/test/test_helper.rb +10 -0
- metadata +67 -0
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'smart_proxy_abrt/abrt_version'
|
2
|
+
|
3
|
+
module Proxy::Abrt
|
4
|
+
class Plugin < ::Proxy::Plugin
|
5
|
+
plugin :abrt, Proxy::Abrt::VERSION
|
6
|
+
|
7
|
+
http_rackup_path File.expand_path("http_config.ru", File.expand_path("../", __FILE__))
|
8
|
+
https_rackup_path File.expand_path("http_config.ru", File.expand_path("../", __FILE__))
|
9
|
+
|
10
|
+
#default settings
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
---
|
2
|
+
:enabled: true
|
3
|
+
|
4
|
+
# Log file for the forwarding script.
|
5
|
+
:abrt_send_log_file: /var/log/foreman-proxy/abrt-send.log
|
6
|
+
|
7
|
+
# Directory where uReports are stored before they are sent
|
8
|
+
:spooldir: /var/spool/foreman-proxy-abrt
|
9
|
+
|
10
|
+
# Merge duplicate reports before sending (requires the satyr gem)
|
11
|
+
:aggregate_reports: true
|
12
|
+
|
13
|
+
# Period (in seconds) after which collected reports are forwarded. Meaningful
|
14
|
+
# only if smart-proxy-abrt-send is run as a daemon (not from cron).
|
15
|
+
#:send_period: 600
|
16
|
+
|
17
|
+
# FAF server instance the reports will be forwarded to (optional)
|
18
|
+
#:server_url: https://retrace.fedoraproject.org/faf
|
19
|
+
|
20
|
+
# Set to true if FAF server uses self-signed certificate
|
21
|
+
#:server_ssl_noverify: true
|
22
|
+
|
23
|
+
# Following two options enable client authentication to FAF server
|
24
|
+
#:server_ssl_cert: /etc/foreman-proxy/faf_client_cert.pem
|
25
|
+
#:server_ssl_key: /etc/foreman-proxy/faf_cleint_key.pem
|
26
|
+
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'ostruct'
|
3
|
+
require 'webrick'
|
4
|
+
require 'tmpdir'
|
5
|
+
require 'sinatra'
|
6
|
+
|
7
|
+
require 'test_helper'
|
8
|
+
require 'smart_proxy_abrt/abrt_api'
|
9
|
+
|
10
|
+
ENV['RACK_ENV'] = 'test'
|
11
|
+
|
12
|
+
class AbrtApiTest < Test::Unit::TestCase
|
13
|
+
include Rack::Test::Methods
|
14
|
+
|
15
|
+
def app
|
16
|
+
Proxy::Abrt::Api.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup
|
20
|
+
ureport_file = "test/fixtures/ureport1.json"
|
21
|
+
@post_data = {
|
22
|
+
"file" => Rack::Test::UploadedFile.new(ureport_file, "application/json")
|
23
|
+
}
|
24
|
+
Proxy::Abrt.stubs(:common_name).returns('localhost')
|
25
|
+
end
|
26
|
+
|
27
|
+
def assert_dir_contains_report(dir)
|
28
|
+
files = Dir[File.join(dir, "ureport-*")]
|
29
|
+
assert_equal files.size, 1
|
30
|
+
report_json = IO.read(files[0])
|
31
|
+
report = JSON.parse report_json
|
32
|
+
assert report.has_key?("host"), "On disk report has no host key"
|
33
|
+
assert report.has_key?("report"), "On disk report does not contain report"
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_forwarding_to_foreman
|
37
|
+
Dir.mktmpdir do |tmpdir|
|
38
|
+
Proxy::Abrt::Plugin.settings.stubs(:spooldir).returns(tmpdir)
|
39
|
+
|
40
|
+
post "/reports/new/", @post_data
|
41
|
+
|
42
|
+
assert last_response.successful?
|
43
|
+
assert_equal last_response.status, 202
|
44
|
+
data = JSON.parse(last_response.body)
|
45
|
+
assert_equal data['result'], false
|
46
|
+
assert data['message'].is_a?(String), "Response message is not string"
|
47
|
+
|
48
|
+
assert_dir_contains_report tmpdir
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_forwarding_to_foreman_and_faf
|
53
|
+
response_body = {
|
54
|
+
"result" => true,
|
55
|
+
"message" => "Hi!"
|
56
|
+
}.to_json
|
57
|
+
response_status = 202
|
58
|
+
faf_response = OpenStruct.new(:code => response_status, :body => response_body)
|
59
|
+
|
60
|
+
Proxy::Abrt.expects(:faf_request).returns(faf_response)
|
61
|
+
Proxy::Abrt::Plugin.settings.stubs(:server_url).returns('https://doesnt.matter/')
|
62
|
+
|
63
|
+
Dir.mktmpdir do |tmpdir|
|
64
|
+
Proxy::Abrt::Plugin.settings.stubs(:spooldir).returns(tmpdir)
|
65
|
+
|
66
|
+
post "/reports/new/", @post_data
|
67
|
+
|
68
|
+
assert last_response.successful?
|
69
|
+
assert_equal last_response.status, response_status
|
70
|
+
assert_equal last_response.body, response_body
|
71
|
+
|
72
|
+
assert_dir_contains_report tmpdir
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_forwarding_other_endpoints
|
77
|
+
post "/reports/attach/", @post_data
|
78
|
+
|
79
|
+
assert_equal last_response.status, 501
|
80
|
+
|
81
|
+
faf_response = OpenStruct.new(:code => 201, :body => "Whatever!")
|
82
|
+
Proxy::Abrt.expects(:faf_request).returns(faf_response)
|
83
|
+
Proxy::Abrt::Plugin.settings.stubs(:server_url).returns('https://doesnt.matter/')
|
84
|
+
|
85
|
+
post "/reports/attach/", @post_data
|
86
|
+
|
87
|
+
assert_equal last_response.status, faf_response.code
|
88
|
+
assert_equal last_response.body, faf_response.body
|
89
|
+
end
|
90
|
+
end
|
data/test/abrt_test.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
require 'test_helper'
|
5
|
+
require 'smart_proxy_abrt'
|
6
|
+
require 'smart_proxy_abrt/abrt_lib'
|
7
|
+
|
8
|
+
class AbrtTest < Test::Unit::TestCase
|
9
|
+
def setup
|
10
|
+
@tmpdir = Dir.mktmpdir "foreman-proxy-test"
|
11
|
+
FileUtils.cp Dir["test/fixtures/ureport-ondisk-*"], @tmpdir
|
12
|
+
|
13
|
+
Proxy::Abrt::Plugin.settings.stubs(:aggregate_reports).returns(false)
|
14
|
+
Proxy::Abrt::Plugin.settings.stubs(:spooldir).returns(@tmpdir)
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
FileUtils.rm_rf @tmpdir
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_multipart_form_data_file
|
22
|
+
file_contents = '{"foo":"bar"}'
|
23
|
+
headers, body = Proxy::Abrt.form_data_file(file_contents, 'application/json')
|
24
|
+
request_text = "POST /abrt/whatever/ HTTP/1.1\r\n"
|
25
|
+
headers.each do |key,value|
|
26
|
+
request_text << key + ": " + value + "\r\n"
|
27
|
+
end
|
28
|
+
request_text << "\r\n"
|
29
|
+
request_text << body
|
30
|
+
|
31
|
+
req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
|
32
|
+
req.parse(StringIO.new(request_text))
|
33
|
+
|
34
|
+
assert_equal req.request_method, "POST"
|
35
|
+
assert_equal req.query["file"], file_contents
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_hostreport_open
|
39
|
+
file = File.join @tmpdir, "ureport-ondisk-host1-01"
|
40
|
+
hr = Proxy::Abrt::HostReport.new file
|
41
|
+
assert_equal "f19-managed.virtnet", hr.host
|
42
|
+
assert_equal [file], hr.files
|
43
|
+
assert_equal 1, hr.reports.size
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_hostreport_load_directory
|
47
|
+
reports = Proxy::Abrt::HostReport.load_from_spool
|
48
|
+
assert_equal 4, reports.size
|
49
|
+
reports.each { |r| assert r.is_a?(Proxy::Abrt::HostReport) }
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_hostreport_merge_without_duphash
|
53
|
+
reports = []
|
54
|
+
Dir[File.join(@tmpdir, "ureport-ondisk-host1-*")].each do |file|
|
55
|
+
reports << Proxy::Abrt::HostReport.new(file)
|
56
|
+
end
|
57
|
+
|
58
|
+
assert_equal 3, reports.size
|
59
|
+
r = reports[0]
|
60
|
+
r.merge(reports[1])
|
61
|
+
r.merge(reports[2])
|
62
|
+
|
63
|
+
# no merging by duphash
|
64
|
+
assert_equal 3, r.reports.size
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_hostreport_merge_with_duphash
|
68
|
+
base = File.join(@tmpdir, "ureport-ondisk-host1-")
|
69
|
+
reports = []
|
70
|
+
Proxy::Abrt::HostReport.stubs(:duphash).returns("aaa")
|
71
|
+
reports << Proxy::Abrt::HostReport.new(base + "01")
|
72
|
+
reports << Proxy::Abrt::HostReport.new(base + "02")
|
73
|
+
Proxy::Abrt::HostReport.stubs(:duphash).returns("bbb")
|
74
|
+
reports << Proxy::Abrt::HostReport.new(base + "03")
|
75
|
+
Proxy::Abrt::HostReport.unstub(:duphash)
|
76
|
+
|
77
|
+
r = reports[0]
|
78
|
+
r.merge(reports[1])
|
79
|
+
r.merge(reports[2])
|
80
|
+
|
81
|
+
# first two reports should be merged
|
82
|
+
assert_equal 2, r.reports.size
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_hostreport_send_to_foreman
|
86
|
+
Proxy::HttpRequest::ForemanRequest.any_instance.expects(:send_request).once
|
87
|
+
|
88
|
+
reports = []
|
89
|
+
Dir[File.join(@tmpdir, "ureport-ondisk-host1-*")].each do |file|
|
90
|
+
reports << Proxy::Abrt::HostReport.new(file)
|
91
|
+
end
|
92
|
+
|
93
|
+
r = reports[0]
|
94
|
+
r.merge(reports[1])
|
95
|
+
r.merge(reports[2])
|
96
|
+
|
97
|
+
r.send_to_foreman
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_hostreport_unlink
|
101
|
+
# single report
|
102
|
+
r1 = Proxy::Abrt::HostReport.new File.join(@tmpdir, "ureport-ondisk-host2-01")
|
103
|
+
r1.unlink
|
104
|
+
|
105
|
+
# merged reports
|
106
|
+
r2 = Proxy::Abrt::HostReport.new File.join(@tmpdir, "ureport-ondisk-host1-01")
|
107
|
+
r2.merge Proxy::Abrt::HostReport.new(File.join(@tmpdir, "ureport-ondisk-host1-02"))
|
108
|
+
r2.merge Proxy::Abrt::HostReport.new(File.join(@tmpdir, "ureport-ondisk-host1-03"))
|
109
|
+
r2.unlink
|
110
|
+
|
111
|
+
dir_contents = Dir[File.join(@tmpdir, "*")]
|
112
|
+
assert dir_contents.empty?, "Not all files were deleted"
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_hostreport_save
|
116
|
+
Dir[File.join(@tmpdir, "*")].each { |file| File.unlink file }
|
117
|
+
ureport = IO.read "test/fixtures/ureport1.json"
|
118
|
+
ureport = JSON.parse ureport
|
119
|
+
Proxy::Abrt::HostReport.save "localhost", ureport
|
120
|
+
|
121
|
+
hr = Proxy::Abrt::HostReport.new Dir[File.join(@tmpdir, "*")][0]
|
122
|
+
assert_equal "localhost", hr.host
|
123
|
+
assert_equal 1, hr.reports.size
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"host":"f19-managed.virtnet","report":{"ureport_version":2,"reason":"ZeroDivisionError in /bin/will_python_raise:3","reporter":{"name":"satyr","version":"0.13"},"os":{"name":"fedora","version":"19","architecture":"x86_64","cpe":"cpe:/o:fedoraproject:fedora:19"},"problem":{"type":"python","component":"will-crash","user":{"root":false,"local":true},"exception_name":"ZeroDivisionError","stacktrace":[{"file_name":"/bin/will_python_raise","file_line":3,"special_function":"module","line_contents":"0/0"}]},"packages":[{"name":"will-crash","epoch":0,"version":"0.4","release":"1.fc19","architecture":"x86_64","package_role":"affected"}]},"reported_at":"2014-06-30 08:42:44 UTC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"host":"f19-managed.virtnet","report":{"ureport_version":2,"reason":"ZeroDivisionError in /bin/will_python_raise:3","reporter":{"name":"satyr","version":"0.13"},"os":{"name":"fedora","version":"19","architecture":"x86_64","cpe":"cpe:/o:fedoraproject:fedora:19"},"problem":{"type":"python","component":"will-crash","user":{"root":false,"local":true},"exception_name":"ZeroDivisionError","stacktrace":[{"file_name":"/bin/will_python_raise","file_line":3,"special_function":"module","line_contents":"0/0"}]},"packages":[{"name":"will-crash","epoch":0,"version":"0.4","release":"1.fc19","architecture":"x86_64","package_role":"affected"}]},"reported_at":"2014-06-30 09:42:44 UTC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"host":"f19-managed.virtnet","report":{"ureport_version":2,"reason":"Program /usr/bin/will_segfault was terminated by signal 11","reporter":{"name":"satyr","version":"0.13"},"os":{"name":"fedora","version":"19","architecture":"x86_64","cpe":"cpe:/o:fedoraproject:fedora:19"},"problem":{"type":"core","component":"will-crash","user":{"root":false,"local":true},"signal":11,"executable":"/usr/bin/will_segfault","stacktrace":[{"crash_thread":true,"frames":[{"address":4195406,"build_id":"e8c1fa14411a04623afbfac93a5cbab39767cfb2","build_id_offset":1102,"function_name":"main","file_name":"/usr/bin/will_segfault","fingerprint":"27fec48d69579748149aa1a5456ea2d906ff5744"}]}]},"packages":[{"name":"glibc","epoch":0,"version":"2.17","release":"20.fc19","architecture":"x86_64","install_time":1389354420},{"name":"will-crash","epoch":0,"version":"0.4","release":"1.fc19","architecture":"x86_64","install_time":1391527642,"package_role":"affected"}]},"reported_at":"2014-06-30 10:42:42 UTC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"host":"someotherhost.virtnet","report":{"ureport_version":2,"reason":"ZeroDivisionError in /bin/will_python_raise:3","reporter":{"name":"satyr","version":"0.13"},"os":{"name":"fedora","version":"19","architecture":"x86_64","cpe":"cpe:/o:fedoraproject:fedora:19"},"problem":{"type":"python","component":"will-crash","user":{"root":false,"local":true},"exception_name":"ZeroDivisionError","stacktrace":[{"file_name":"/bin/will_python_raise","file_line":3,"special_function":"module","line_contents":"0/0"}]},"packages":[{"name":"will-crash","epoch":0,"version":"0.4","release":"1.fc19","architecture":"x86_64","package_role":"affected"}]},"reported_at":"2014-06-30 18:42:44 UTC"}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
{ "ureport_version": 2
|
2
|
+
, "reason": "Program /usr/bin/will_segfault was terminated by signal 11"
|
3
|
+
, "reporter": { "name": "satyr"
|
4
|
+
, "version": "0.13"
|
5
|
+
}
|
6
|
+
, "os": { "name": "fedora"
|
7
|
+
, "version": "19"
|
8
|
+
, "architecture": "x86_64"
|
9
|
+
, "cpe": "cpe:/o:fedoraproject:fedora:19"
|
10
|
+
}
|
11
|
+
, "problem": { "type": "core"
|
12
|
+
, "component": "will-crash"
|
13
|
+
, "user": { "root": false
|
14
|
+
, "local": true
|
15
|
+
}
|
16
|
+
, "signal": 11
|
17
|
+
, "executable": "/usr/bin/will_segfault"
|
18
|
+
, "stacktrace":
|
19
|
+
[ { "crash_thread": true
|
20
|
+
, "frames":
|
21
|
+
[ { "address": 4195406
|
22
|
+
, "build_id": "e8c1fa14411a04623afbfac93a5cbab39767cfb2"
|
23
|
+
, "build_id_offset": 1102
|
24
|
+
, "function_name": "main"
|
25
|
+
, "file_name": "/usr/bin/will_segfault"
|
26
|
+
, "fingerprint": "27fec48d69579748149aa1a5456ea2d906ff5744"
|
27
|
+
} ]
|
28
|
+
} ]
|
29
|
+
}
|
30
|
+
, "packages": [ { "name": "glibc"
|
31
|
+
, "epoch": 0
|
32
|
+
, "version": "2.17"
|
33
|
+
, "release": "20.fc19"
|
34
|
+
, "architecture": "x86_64"
|
35
|
+
, "install_time": 1389354420
|
36
|
+
}
|
37
|
+
, { "name": "will-crash"
|
38
|
+
, "epoch": 0
|
39
|
+
, "version": "0.4"
|
40
|
+
, "release": "1.fc19"
|
41
|
+
, "architecture": "x86_64"
|
42
|
+
, "install_time": 1391527642
|
43
|
+
, "package_role": "affected"
|
44
|
+
} ]
|
45
|
+
}
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
path_to_smart_proxy_repo = '../smart-proxy'
|
2
|
+
$LOAD_PATH.unshift File.join(path_to_smart_proxy_repo, 'test')
|
3
|
+
|
4
|
+
# create log directory in our (not smart-proxy) repo
|
5
|
+
logdir = File.join(File.dirname(__FILE__), '..', 'logs')
|
6
|
+
FileUtils.mkdir_p(logdir) unless File.exists?(logdir)
|
7
|
+
|
8
|
+
require 'test_helper'
|
9
|
+
|
10
|
+
APP_ROOT = File.join(File.dirname(__FILE__), '..')
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: smart_proxy_abrt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Martin Milata
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-08-15 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: This smart proxy plugin, together with a Foreman plugin, add the capability
|
14
|
+
to send ABRT micro-reports from your managed hosts to Foreman.
|
15
|
+
email: mmilata@redhat.com
|
16
|
+
executables:
|
17
|
+
- smart-proxy-abrt-send
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- bin/smart-proxy-abrt-send
|
22
|
+
- lib/smart_proxy_abrt/abrt_api.rb
|
23
|
+
- lib/smart_proxy_abrt/abrt_plugin.rb
|
24
|
+
- lib/smart_proxy_abrt/abrt_lib.rb
|
25
|
+
- lib/smart_proxy_abrt/http_config.ru
|
26
|
+
- lib/smart_proxy_abrt/abrt_version.rb
|
27
|
+
- lib/smart_proxy_abrt.rb
|
28
|
+
- settings.d/abrt.yml.example
|
29
|
+
- bundler.d/abrt.rb
|
30
|
+
- test/test_helper.rb
|
31
|
+
- test/fixtures/ureport-ondisk-host1-02
|
32
|
+
- test/fixtures/ureport-ondisk-host2-01
|
33
|
+
- test/fixtures/ureport1.json
|
34
|
+
- test/fixtures/ureport-ondisk-host1-03
|
35
|
+
- test/fixtures/ureport-ondisk-host1-01
|
36
|
+
- test/abrt_test.rb
|
37
|
+
- test/abrt_api_test.rb
|
38
|
+
- extra/foreman-proxy-abrt-send.cron
|
39
|
+
- extra/rubygem-smart_proxy_abrt.spec
|
40
|
+
- README
|
41
|
+
- LICENSE
|
42
|
+
- Rakefile
|
43
|
+
homepage: http://github.com/abrt/smart-proxy-abrt
|
44
|
+
licenses:
|
45
|
+
- GPL-3
|
46
|
+
metadata: {}
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
requirements: []
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 2.1.11
|
64
|
+
signing_key:
|
65
|
+
specification_version: 4
|
66
|
+
summary: Automatic Bug Reporting Tool plugin for Foreman's smart proxy
|
67
|
+
test_files: []
|