--- a/crash_test.conf.sample Sat Feb 20 18:56:11 2016 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-{
- Processor => {
- JobQueue => {
- Backend => {
- Minion => { Pg => "postgresql:///crashtest" },
- },
- },
- CrashProcessor => {
- Breakpad => {
- JSONStackwalker => 'stackwalker',
- SymbolsPath => 'data/breakpad-debug-symbols/*',
- },
- },
- CrashSignatureExtractor => {
- C_Cpp => {
- GroupMaxDistance => 0.1,
- TopIrrelevant => [
- # Ignore these frames at the top of the stack when creating a crash signature (mostly exception handler and libc internal functions)
- "__cxxabiv1::__terminate",
- "__gnu_cxx::__verbose_terminate_handler",
- "std::terminate",
- "raise",
- "abort",
- ],
- TopFrame => [
- # Consider these frames as the first (from top) relevant frame of the crash
- # Order is important here, the first match will be selected
- qr/std::__throw_[a-z]+_error/,
- "__cxxabiv1::__cxa_throw",
- ],
- BottomIrrelevant => [
- # Ignore these frames at the bottom of the stack (libc internal functions)
- "__libc_start_main",
- "_init",
- ],
- BottomFrame => [
- # Don't use frames past this one in the signature
- #"main",
- ],
- RemoveNamespace => [
- # Clean function names by removing the namespace
- #"some_ns::",
- ],
- },
- },
- },
- Storage => [
- { Type => "Sql", db => { Pg => "postgresql:///crashtest" } },
- { Type => "File", DataDir => 'data/crashs/' },
- ],
- WebInterface => {
- ScmLinks => {
- "svn:svn.example.org/testproject" => 'https://redmine.example.org/projects/testproject/repository/entry/<%= $scmpath =%>?rev=<%= $rev =%>#L<%= $line =%>',
- },
- ExtraColumns => {
- Index => [
- { id => 'os' , db_column => "crash_user.os", name => 'Operating System' },
- { id => 'cpu_count' , db_column => "crash_user.cpu_count", name => "CPU count" },
- { id => 'program' , db_column => "main_module", name => 'Program' },
- ],
- GroupIndex => [
- { id => 'program' , db_column => "string_agg(distinct(main_module), ', ')", name => 'Programs' },
- ],
- Search => [
- { id => 'cpu_count' , db_column => "crash_user.cpu_count", name => "CPU count" },
- { id => 'program' , db_column => "main_module", name => 'Program' },
- ],
- },
- },
-};
-# vim:ft=perl:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/breakpad_upload_crash Sun Feb 21 22:32:27 2016 +0100
@@ -0,0 +1,40 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use Mojo::UserAgent;
+use Mojo::Util qw/slurp dumper/;
+use File::Basename;
+use v5.10;
+
+my $ua = Mojo::UserAgent->new;
+
+my $url = shift @ARGV;
+
+foreach my $extra(@ARGV) {
+
+ my ($filename, $dirs, $suffix) = fileparse($extra, ".extra");
+
+ my $hash = { upload_file_minidump => { file => "$dirs$filename.dmp" } };
+
+ open(my $fh, "<", $extra);
+ foreach my $l(<$fh>) {
+ my ($k, $v) = split('=', $l, 2);
+ chomp $k;
+ chomp $v;
+ $hash->{$k} = $v;
+ }
+ close $fh;
+
+ my $tx = $ua->post($url => form => $hash);
+ if(my $res = $tx->success) {
+ say $res->body;
+ } else {
+ my $err = $tx->error;
+ if($err->{code}) {
+ warn "$err->{code} response for $extra: $err->{message}\n" . dumper $hash;
+ } else {
+ warn "Connection error: $err->{message}";
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/crash_test.conf Sun Feb 21 22:32:27 2016 +0100
@@ -0,0 +1,71 @@
+{
+ Processor => {
+ JobQueue => {
+ Backend => {
+ Minion => { Pg => "postgresql:///crashtest" },
+ },
+ },
+ CrashProcessor => {
+ Breakpad => {
+ JSONStackwalker => 'stackwalker',
+ SymbolsPath => 'data/breakpad-symbols/*',
+ },
+ },
+ CrashSignatureExtractor => {
+ C_Cpp => {
+ GroupMaxDistance => 0.1,
+ TopIrrelevant => [
+ # Ignore these frames at the top of the stack when creating a crash signature (mostly exception handler and libc internal functions)
+ "__cxxabiv1::__terminate",
+ "__gnu_cxx::__verbose_terminate_handler",
+ "std::terminate",
+ "raise",
+ "abort",
+ ],
+ TopFrame => [
+ # Consider these frames as the first (from top) relevant frame of the crash
+ # Order is important here, the first match will be selected
+ qr/std::__throw_[a-z]+_error/,
+ "__cxxabiv1::__cxa_throw",
+ ],
+ BottomIrrelevant => [
+ # Ignore these frames at the bottom of the stack (libc internal functions)
+ "__libc_start_main",
+ "_init",
+ ],
+ BottomFrame => [
+ # Don't use frames past this one in the signature
+ #"main",
+ ],
+ RemoveNamespace => [
+ # Clean function names by removing the namespace
+ #"some_ns::",
+ ],
+ },
+ },
+ },
+ Storage => [
+ { Type => "Sql", db => { Pg => "postgresql:///crashtest" } },
+ { Type => "File", DataDir => 'data/crashs/' },
+ ],
+ WebInterface => {
+ ScmLinks => {
+ "svn:svn.example.org/testproject" => 'https://redmine.example.org/projects/testproject/repository/entry/<%= $scmpath =%>?rev=<%= $rev =%>#L<%= $line =%>',
+ },
+ ExtraColumns => {
+ Index => [
+ { id => 'os' , db_column => "crash_user.os", name => 'Operating System' },
+ { id => 'cpu_count' , db_column => "crash_user.cpu_count", name => "CPU count" },
+ { id => 'program' , db_column => "main_module", name => 'Program' },
+ ],
+ GroupIndex => [
+ { id => 'program' , db_column => "string_agg(distinct(main_module), ', ')", name => 'Programs' },
+ ],
+ Search => [
+ { id => 'cpu_count' , db_column => "crash_user.cpu_count", name => "CPU count" },
+ { id => 'program' , db_column => "main_module", name => 'Program' },
+ ],
+ },
+ },
+};
+# vim:ft=perl:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/crash_test.production.conf Sun Feb 21 22:32:27 2016 +0100
@@ -0,0 +1,12 @@
+{
+ hypnotoad => {
+ listen => [ "http://127.0.0.1:3000", "http://[::1]:3000" ],
+ workers => 2,
+ proxy => 1,
+ upgrade_timeout => 5,
+ inactivity_timeout => 0,
+ heartbeat_timeout => 360,
+ pid_file => '/run/crashtest/hypnotoad.pid',
+ }
+}
+# vim:ft=perl:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/crashtest.nginx.conf Sun Feb 21 22:32:27 2016 +0100
@@ -0,0 +1,26 @@
+server {
+ server_name crashtest crashtest.*;
+ listen [::]:80;
+ #listen [::]:443 ssl;
+
+ error_log /var/log/nginx/error-crashtest.log error;
+ access_log /var/log/nginx/access-crashtest.log;
+
+ root /usr/share/perl5/CrashTest/files/public/;
+ try_files $uri @crashtest;
+
+ expires 15d;
+
+ location @crashtest {
+ expires off;
+ proxy_pass http://127.0.0.1:3000;
+ proxy_http_version 1.1;
+ proxy_read_timeout 120s;
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-HTTPS 0;
+ }
+
+}
+
+# vim:ft=nginx:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/systemd/crashtest.service Sun Feb 21 22:32:27 2016 +0100
@@ -0,0 +1,29 @@
+[Unit]
+Description=CrashTest Web Service
+Requires=network.target
+After=network.target
+ConditionPathExists=/etc/crashtest/crash_test.conf
+
+[Service]
+Type=forking
+User=crashtest
+RemainAfterExit=yes
+ProtectSystem=full
+
+Environment=MOJO_CONFIG=/etc/crashtest/crash_test.conf
+EnvironmentFile=-/etc/default/crashtest
+
+;PrivateTmp=yes
+;JoinsNamespaceOf=
+
+RuntimeDirectory=crashtest
+RuntimeDirectoryMode=0755
+PIDFile=/run/crashtest/hypnotoad.pid
+
+WorkingDirectory=/var/lib/crashtest
+ExecStart=/usr/bin/hypnotoad /usr/bin/CrashTest
+ExecStop=/usr/bin/hypnotoad -s /usr/bin/CrashTest
+ExecReload=/usr/bin/hypnotoad /usr/bin/CrashTest
+
+[Install]
+WantedBy=multi-user.target
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/systemd/crashtest_minion.service Sun Feb 21 22:32:27 2016 +0100
@@ -0,0 +1,24 @@
+[Unit]
+Description=CrashTest Jobs Manager
+Requires=network.target
+After=network.target
+ConditionPathExists=/etc/crashtest/crash_test.conf
+
+[Service]
+Type=simple
+User=crashtest
+RemainAfterExit=yes
+ProtectSystem=full
+
+Environment=MOJO_CONFIG=/etc/crashtest/crash_test.conf
+Environment=JOBS=2
+EnvironmentFile=-/etc/default/crashtest
+
+;PrivateTmp=yes
+;JoinsNamespaceOf=
+
+WorkingDirectory=/var/lib/crashtest
+ExecStart=/usr/bin/CrashTest minion worker -m production -j $JOBS
+
+[Install]
+WantedBy=multi-user.target