Merge pull request #4 from Fishwaldo/mqtt

New Docker Image and Backtrace Support
This commit is contained in:
Justin Hammond 2020-01-03 12:35:40 +08:00 committed by GitHub
commit 9d3cb64f63
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 255 additions and 48 deletions

View file

@ -3,30 +3,46 @@
# Based on CentOS7
############################################################
# Set the base image to Ubuntu
FROM fishwaldo/qt-staticbuilds:5.12.4 as builder
# Set the base image to Alpine
FROM debian:buster-slim as builder
# File Author / Maintainer
MAINTAINER Justin Hammond
WORKDIR /opt
RUN dnf -y install rapidjson-devel
RUN git clone https://github.com/qt/qtmqtt.git && cd qtmqtt && git checkout 5.12 && /opt/Qt/5.12.4/bin/qmake && make && make install
RUN echo 'APT::Default-Release "stable";' > /etc/apt/apt.conf.d/99defaultrelease && echo 'deb http://ftp.uk.debian.org/debian/ unstable main contrib non-free' > /etc/apt/sources.list.d/unstable.list && echo 'deb http://ftp.uk.debian.org/debian/ experimental main contrib non-free' >> /etc/apt/sources.list.d/unstable.list && apt update
RUN apt-get -y install rapidjson-dev git g++ cmake make pkgconf bash python wget joe mc libunwind-dev libcurl4-openssl-dev && apt-get -y -t unstable install qt5-default && apt-get -y -t unstable install qtbase5-private-dev && apt-get -y -t unstable install g++ && apt-get -y -t experimental install libqt5remoteobjects5-dev libqt5remoteobjects5-bin
ENV PATH=$PATH:/opt/depot_tools/
RUN git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git && mkdir breakpad && cd breakpad && fetch breakpad && cd src && ./configure && make && make install
RUN git clone https://github.com/qt/qtmqtt.git && cd qtmqtt && git checkout 5.12 && /usr/lib/qt5/bin/qmake && make && make install
RUN git clone https://github.com/OpenZWave/open-zwave.git && cd open-zwave && make -j4 && make install
RUN git clone https://github.com/OpenZWave/qt-openzwave.git && cd qt-openzwave && git checkout mqtt && /opt/Qt/5.12.4/bin/qmake && make -j4 && make install
#RUN ls -lah /usr/local/lib64/
#RUN ls /opt/
#RUN ls -lah /ozwdaemon/bin/
#RUN LD_LIBRARY_PATH="/usr/local/lib:/usr/local/lib64:$LD_LIBRARY_PATH" /ozwdaemon/bin/ozwdaemon
RUN mkdir /opt/ozw/ && mkdir /opt/ozw/config/
RUN git clone https://github.com/Fishwaldo/qt-openzwave.git && cd qt-openzwave && git checkout mqtt && /usr/lib/qt5/bin/qmake "CONFIG += BreakPad" && make -j4 && make install
FROM debian:buster-slim
MAINTAINER Justin Hammond
WORKDIR /opt
RUN echo 'APT::Default-Release "stable";' > /etc/apt/apt.conf.d/99defaultrelease && echo 'deb http://ftp.uk.debian.org/debian/ unstable main contrib non-free' > /etc/apt/sources.list.d/unstable.list && echo 'deb http://ftp.uk.debian.org/debian/ experimental main contrib non-free' >> /etc/apt/sources.list.d/unstable.list && apt update
RUN apt-get -y install libunwind8 libcurl4
RUN apt-get -y -t unstable install libqt5core5a libqt5network5
RUN apt-get -y -t experimental install libqt5remoteobjects5
COPY --from=builder /usr/local/bin/* /usr/local/bin/
COPY --from=builder /usr/local/lib/libqt* /usr/local/lib/
COPY --from=builder /usr/local/lib*/libopenzwave* /usr/local/lib/
COPY --from=builder /usr/lib/*/libQt5Mqtt* /usr/local/lib/
COPY --from=builder /opt/qt-openzwave/tools/* /usr/local/bin/
RUN mkdir -p /opt/ozw/config/crashes/
ENV LD_LIBRARY_PATH="/usr/local/lib:/usr/local/lib64:$LD_LIBRARY_PATH"
ENV USBPATH="/dev/ttyUSB0"
ENV MQTT_SERVER="localhost"
ENV MQTT_PORT="1883"
ENV OZW_INSTANCE="1"
ENV BP_DB_PATH="/opt/ozw/config/crashes/"
WORKDIR /opt/ozw/
EXPOSE 1983
VOLUME ["/opt/ozw/config/"]
ENTRYPOINT /usr/bin/catchsegv /ozwdaemon/bin/ozwdaemon -s $USBPATH -c /opt/ozw/config/ -u /opt/ozw/config/ --mqtt-server $MQTT_SERVER --mqtt-port $MQTT_PORT
ENTRYPOINT /usr/local/bin/ozwdaemon -s $USBPATH -c /opt/ozw/config/ -u /opt/ozw/config/ --mqtt-server $MQTT_SERVER --mqtt-port $MQTT_PORT --stop-on-failure --mqtt-instance $OZW_INSTANCE

View file

@ -13,7 +13,7 @@ TEMPLATE = lib
VERSION = 1.0.0
CONFIG += silent file_copies
CONFIG += silent file_copies force_debug_info
!versionAtLeast(QT_VERSION, 5.11.2):error("Use at least Qt version 5.11.2")
include(../qt-openzwave.pri)
@ -87,8 +87,10 @@ COPIES += copyrepheaders
unix {
target.path = /usr/local/lib
INSTALLS += target
QMAKE_CXXFLAGS += -g1
QMAKE_CXXFLAGS += -g
QMAKE_CFLAGS += -g
QMAKE_LFLAGS += -rdynamic
QMAKE_STRIP = echo
}
#LIBS += -L../../open-zwave -lopenzwave
@ -97,6 +99,13 @@ macx {
QMAKE_POST_LINK=$$top_srcdir/updaterpath.sh $(TARGET)
}
QMAKE_CFLAGS_RELEASE -= -O
QMAKE_CFLAGS_RELEASE -= -O1
QMAKE_CFLAGS_RELEASE -= -O2
QMAKE_CXXFLAGS_RELEASE -= -O
QMAKE_CXXFLAGS_RELEASE -= -O1
QMAKE_CXXFLAGS_RELEASE -= -O2
message(" ")
message("Summary:")
message(" OpenZWave Path: $$OZW_LIB_PATH")

View file

@ -27,4 +27,9 @@ ozwconfig.commands=cp -R ../../open-zwave/config config/ && cd config && $$[QT_I
INCLUDEPATH += include/
QMAKE_CXXFLAGS += -g1
target.path = /usr/local/lib/
INSTALLS += target
QMAKE_CXXFLAGS += -g1
QMAKE_LFLAGS += -rdynamic
}

View file

@ -1,4 +1,10 @@
#include <execinfo.h>
#ifdef BP_LINUX
#include "client/linux/handler/exception_handler.h"
#include "common/linux/http_upload.h"
#define HAVE_BP
#endif
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
@ -12,23 +18,94 @@
#include "mqttpublisher.h"
#endif
void handler(int sig) {
void *array[10];
size_t size;
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#include <cxxabi.h>
// get void*'s for all entries on the stack
size = backtrace(array, 10);
void backtrace(int sig = 0)
{
Q_UNUSED(sig);
unw_cursor_t cursor;
unw_context_t context;
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, STDERR_FILENO);
exit(1);
qWarning() << "=============================";
qWarning() << "CRASH!!! - Dumping Backtrace:";
qWarning() << "=============================";
unw_getcontext(&context);
unw_init_local(&cursor, &context);
int n=0;
while ( unw_step(&cursor) ) {
unw_word_t ip, sp, off;
unw_get_reg(&cursor, UNW_REG_IP, &ip);
unw_get_reg(&cursor, UNW_REG_SP, &sp);
char symbol[256] = {"<unknown>"};
char *name = symbol;
if ( !unw_get_proc_name(&cursor, symbol, sizeof(symbol), &off) ) {
int status;
if ( (name = abi::__cxa_demangle(symbol, NULL, NULL, &status)) == 0 )
name = symbol;
}
char message[1024];
snprintf(message, sizeof(message), "#%-2d 0x%016" PRIxPTR " sp=0x%016" PRIxPTR " %s + 0x%" PRIxPTR,
++n,
static_cast<uintptr_t>(ip),
static_cast<uintptr_t>(sp),
name,
static_cast<uintptr_t>(off));
qWarning() << message;
if ( name != symbol )
free(name);
}
#ifndef HAVE_BP
qWarning("Exiting....");
exit(-1);
#endif
}
void crash() { volatile int* a = (int*)(NULL); *a = 1; }
#ifdef HAVE_BP
static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
void* context, bool succeeded) {
backtrace();
qWarning() << "dumpCallback Succeeded: " << succeeded << " at " << descriptor.path();
if (succeeded == true) {
std::map<string, string> parameters;
std::map<string, string> files;
std::string proxy_host;
std::string proxy_userpasswd;
std::string url("https://sentry.io/api/1868130/minidump/?sentry_key=e086ba93030843199aab391947d205da");
// Add any attributes to the parameters map.
// Note that several attributes are automatically extracted.
parameters["product_name"] = QCoreApplication::applicationName().toStdString();
parameters["release"] = QCoreApplication::applicationVersion().toStdString();
qtozwdaemon *daemon = static_cast<qtozwdaemon *>(context);
parameters["OpenZWave_Version"] = daemon->getManager()->getVersionAsString().toStdString();
parameters["QTOpenZWave_Version"] = daemon->getQTOpenZWave()->getVersion().toStdString();
parameters["QT_Version"] = qVersion();
files["upload_file_minidump"] = descriptor.path();
std::string response, error;
bool success = google_breakpad::HTTPUpload::SendRequest(url, parameters, files, proxy_host, proxy_userpasswd, "", &response, NULL, &error);
if (success)
qWarning() << "Uploaded Crash minidump With ID: " << response.c_str();
else
qWarning() << "Failed to Upload Crash MiniDump in " << descriptor.path();
}
return succeeded;
}
#endif
int main(int argc, char *argv[])
{
//signal(SIGSEGV, handler); // install our handler
QCoreApplication a(argc, argv);
QCoreApplication::setApplicationName("ozwdaemon");
@ -91,6 +168,10 @@ int main(int argc, char *argv[])
#endif
QCommandLineOption StopOnFailure(QStringList() << "stop-on-failure",
"Exit on Driver Failure"
);
parser.addOption(StopOnFailure);
parser.process(a);
@ -187,7 +268,9 @@ int main(int argc, char *argv[])
}
#endif
if (parser.isSet(StopOnFailure)) {
settings.setValue("StopOnFailure", true);
}
QTOZWOptions options(QTOZWOptions::Local);
options.setUserPath(userPath);
@ -200,7 +283,24 @@ int main(int argc, char *argv[])
mqttpublisher mqttpublisher(&settings);
mqttpublisher.setOZWDaemon(&daemon);
#endif
#ifdef HAVE_BP
QString bppath = QString::fromLocal8Bit(qgetenv("BP_DB_PATH"));
if (bppath.isEmpty())
bppath = QStandardPaths::standardLocations(QStandardPaths::TempLocation).at(0);
qInfo() << "Using BreakPad - Crash Directory: " << bppath;
google_breakpad::MinidumpDescriptor descriptor(bppath.toStdString());
google_breakpad::ExceptionHandler eh(descriptor, NULL, dumpCallback, static_cast<void *>(&daemon), true, -1);
#else
signal(SIGSEGV, backtrace);
signal(SIGABRT, backtrace);
#endif
daemon.setSerialPort(parser.value(serialPort));
daemon.startOZW();
// assert(0);
// crash();
return a.exec();
}

View file

@ -279,15 +279,25 @@ void mqttpublisher::setOZWDaemon(qtozwdaemon *ozwdaemon) {
void mqttpublisher::updateLogStateChange()
{
qCDebug(ozwmp) << "State Change" << m_client->state();
if (settings->value("MQTTTLS").toBool() == true && this->m_client->state() == QMqttClient::ClientState::Connecting) {
QSslSocket *socket = qobject_cast<QSslSocket *>(this->m_client->transport());
socket->setPeerVerifyMode(QSslSocket::PeerVerifyMode::VerifyNone);
}
if (this->m_client->state() == QMqttClient::ClientState::Connected) {
qCDebug(ozwmp) << "MQTT State Change" << m_client->state();
if (this->m_client->state() == QMqttClient::ClientState::Connecting) {
qCInfo(ozwmp) << "MQTT Client Connecting";
if (settings->value("MQTTTLS").toBool() == true) {
QSslSocket *socket = qobject_cast<QSslSocket *>(this->m_client->transport());
socket->setPeerVerifyMode(QSslSocket::PeerVerifyMode::VerifyNone);
}
} else if (this->m_client->state() == QMqttClient::ClientState::Connected) {
qCInfo(ozwmp) << "MQTT Client Connected";
this->m_cleanTopicSubscription = this->m_client->subscribe(QMqttTopicFilter(getTopic("#")));
connect(this->m_cleanTopicSubscription, &QMqttSubscription::messageReceived, this, &mqttpublisher::cleanTopics);
this->m_commands->setupSubscriptions(this->m_client, this->getCommandTopic());
return;
} else if (this->m_client->state() == QMqttClient::ClientState::Disconnected) {
if (settings->value("StopOnFailure", false).toBool()) {
qCWarning(ozwmp) << "Exiting on Failure";
exit(-1);
}
return;
}
}
@ -609,7 +619,10 @@ void mqttpublisher::driverFailed(quint32 homeID) {
QT2JS::SetString(this->m_ozwstatus, "Status", "driverFailed");
QT2JS::SetUint(this->m_ozwstatus, "homeID", homeID);
this->sendStatusUpdate();
/* XXX TODO: Scan Nodes, Instances, CC and Value Lists and delete them */
if (settings->value("StopOnFailure", false).toBool()) {
qCWarning(ozwmp) << "Exiting on Failure";
exit(-1);
}
}
void mqttpublisher::driverReset(quint32 homeID) {
qCDebug(ozwmp) << "Publishing Event driverReset:" << homeID;

View file

@ -6,7 +6,7 @@ TARGET = ../ozwdaemon
VERSION = 0.1.0
CONFIG += c++11 console link_pkgconfig silent
CONFIG += c++11 console link_pkgconfig silent force_debug_info
CONFIG -= app_bundle
# The following define makes your compiler emit warnings if you use
@ -15,11 +15,6 @@ CONFIG -= app_bundle
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS QT_MESSAGELOGCONTEXT APP_VERSION=$$VERSION
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
qtHaveModule(mqtt) {
PKGCONFIG += RapidJSON
QT += mqtt
@ -117,24 +112,38 @@ SOURCES += main.cpp \
qtozwdaemon.cpp
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
HEADERS += \
qtozwdaemon.h \
include(../qt-openzwave.pri)
INCLUDEPATH += ../qt-openzwave/include/
BreakPad {
exists( $$top_srcdir/../breakpad/src/src/client/linux/libbreakpad_client.a) {
INCLUDEPATH += $$top_srcdir/../breakpad/src/src/
SOURCES += $$top_srcdir/../breakpad/src/src/common/linux/http_upload.cc
LIBS += $$top_srcdir/../breakpad/src/src/client/linux/libbreakpad_client.a -ldl
DEFINES += BP_LINUX
message("Building with BreakPad");
} else {
error("Can't find BreakPad Library");
}
}
unix {
# Default rules for deployment.
target.path = /usr/local/bin
INSTALLS += target
PKGCONFIG += libunwind libcurl
LIBS += -lresolv -L../qt-openzwave/ -lqt-openzwave -L../qt-openzwavedatabase/ -lqt-openzwavedatabase
INCLUDEPATH += ../qt-openzwavedatabase/include/
QMAKE_CXXFLAGS += -g1
QMAKE_CXXFLAGS += -g
QMAKE_CFLAGS += -g
QMAKE_LFLAGS += -rdynamic
QMAKE_STRIP = echo
}
@ -147,4 +156,9 @@ macx {
QMAKE_POST_LINK=$$top_srcdir/updaterpath.sh $(TARGET)
}
QMAKE_CFLAGS_RELEASE -= -O
QMAKE_CFLAGS_RELEASE -= -O1
QMAKE_CFLAGS_RELEASE -= -O2
QMAKE_CXXFLAGS_RELEASE -= -O
QMAKE_CXXFLAGS_RELEASE -= -O1
QMAKE_CXXFLAGS_RELEASE -= -O2

50
tools/sentry-upload-debug.sh Executable file
View file

@ -0,0 +1,50 @@
#!/bin/bash
EXECUTABLE=$1
if [ -z $EXECUTABLE ]
then
echo "Please Supply a Executable to process"
exit -1
fi
if [ -z $SENTRY_TOKEN ]
then
echo "Please Set the SENTRY_TOKEN enviroment variable"
exit -1
fi
function findDBGFile() {
local DBGFILE
DBGFILE=`ls /usr/lib/debug/usr/$1* 2> /dev/null`
if (( $? != 0)); then
return 1
fi
echo $DBGFILE
return 0
}
ldd $EXECUTABLE | awk '{print $3}' |
{
while IFS= read lib
do
if [ -f "$lib" ]; then
useable=`sentry-cli difutil check $lib | grep "Usable: yes"`
if [ ! -z "$useable" ]; then
RP=`realpath $lib`
DBGFILE=$(findDBGFile $lib)
if (( $? == 0)); then
LIBS+=" $DBGFILE"
fi
LIBS+=" $RP"
echo "Got Lib:" $RP " " $PKG " " $DBGFILE
fi
fi
done
echo $LIBS
sentry-cli --auth-token $SENTRY_TOKEN upload-dif -o openzwave -p qt-openzwave $LIBS --wait
}