diff --git a/.gitignore b/.gitignore index 273e4667d..3873d0217 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ libstuff.a sqlitecluster/sqlitecluster libstuff/libstuff.d libstuff/libstuff.h.gch +udf.so diff --git a/Makefile b/Makefile index bca23cc75..600a3d098 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,27 @@ clustertest: test/clustertest/clustertest testplugin testplugin: cd test/clustertest/testplugin && make +.PHONY: docker udf + +docker: + docker build -t bedbugs $(PROJECT)/docker/bedbugs + docker run -t --rm -v $(PROJECT):/src bedbugs bedrock udf + cp $(PROJECT)/bedrock $(PROJECT)/docker/bedrook/bedrock + cp $(PROJECT)/udf.so $(PROJECT)/docker/bedrook/udf.so + docker build -t bedrock $(PROJECT)/docker/bedrook + +udf: udf.so + +UDFSRC = udf.c +UDFCPP = udfplug.cpp +UDFOBJ = $(UDFSRC:%.c=$(INTERMEDIATEDIR)/%.o) +UDFOBJ += $(UDFCPP:%.cpp=$(INTERMEDIATEDIR)/%.o) + +CFLAGS += -fPIC -I$(PROJECT)/libstuff + +udf.so: $(UDFOBJ) + $(GXX) $(CXXFLAGS) -shared -o $@ $(UDFOBJ) + # Set up our precompiled header. This makes building *way* faster (roughly twice as fast). # Including it here causes it to be generated. # Depends on one of our mbedtls files, to make sure the submodule gets pulled and built. @@ -53,7 +74,9 @@ PRECOMPILE_INCLUDE =-include libstuff/libstuff.h libstuff/libstuff.h.gch libstuff/libstuff.d: libstuff/libstuff.h mbedtls/library/libmbedcrypto.a $(GXX) $(CXXFLAGS) -MMD -MF libstuff/libstuff.d -MT libstuff/libstuff.h.gch -c libstuff/libstuff.h ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),docker) -include libstuff/libstuff.d + endif endif endif @@ -84,7 +107,7 @@ STUFFC = $(shell find libstuff -name '*.c') STUFFOBJ = $(STUFFCPP:%.cpp=$(INTERMEDIATEDIR)/%.o) $(STUFFC:%.c=$(INTERMEDIATEDIR)/%.o) STUFFDEP = $(STUFFCPP:%.cpp=$(INTERMEDIATEDIR)/%.d) -LIBBEDROCKCPP = $(shell find * -name '*.cpp' -not -name main.cpp -not -path 'test*' -not -path 'libstuff*') +LIBBEDROCKCPP = $(shell find * -name '*.cpp' -not -name main.cpp -not -name udfplug.cpp -not -path 'test*' -not -path 'libstuff*') LIBBEDROCKOBJ = $(LIBBEDROCKCPP:%.cpp=$(INTERMEDIATEDIR)/%.o) LIBBEDROCKDEP = $(LIBBEDROCKCPP:%.cpp=$(INTERMEDIATEDIR)/%.d) @@ -103,11 +126,13 @@ CLUSTERTESTDEP = $(CLUSTERTESTCPP:%.cpp=$(INTERMEDIATEDIR)/%.d) # Bring in the dependency files. This will cause them to be created if necessary. This is skipped if we're cleaning, as # they'll just get deleted anyway. ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),docker) -include $(STUFFDEP) -include $(LIBBEDROCKDEP) -include $(BEDROCKDEP) #-include $(TESTDEP) #-include $(CLUSTERTESTDEP) + endif endif # Our static libraries just depend on their object files. @@ -118,7 +143,7 @@ libbedrock.a: $(LIBBEDROCKOBJ) # We use the same library paths and required libraries for both binaries. LIBPATHS =-Lmbedtls/library -L$(PROJECT) -LIBRARIES =-lbedrock -lstuff -ldl -lpcrecpp -lpthread -lmbedtls -lmbedx509 -lmbedcrypto -lz +LIBRARIES =-lbedrock -lstuff -ldl -lpcrecpp -lpthread -lmbedtls -lmbedx509 -lmbedcrypto -lz -lexecinfo # The prerequisites for both binaries are the same. We only include one of the mbedtls libs to avoid building three # times in parallel. diff --git a/docker/bedbugs/Dockerfile b/docker/bedbugs/Dockerfile new file mode 100644 index 000000000..2d08b73a7 --- /dev/null +++ b/docker/bedbugs/Dockerfile @@ -0,0 +1,18 @@ +FROM alpine:3.6 + +# Requirements +RUN apk update \ + && apk add alpine-sdk + +RUN apk add musl-dev pcre-dev zlib-dev libexecinfo-dev + +RUN adduser -h /out -u 1000 -D build \ + && chgrp build /lib \ + && chmod 775 /lib + +COPY makeme /usr/bin + +USER build +WORKDIR /src + +ENTRYPOINT ["makeme"] diff --git a/docker/bedbugs/makeme b/docker/bedbugs/makeme new file mode 100755 index 000000000..ebc668ad6 --- /dev/null +++ b/docker/bedbugs/makeme @@ -0,0 +1,8 @@ +#!/bin/sh + +echo makeme "$@" + +export GXX=g++ +export CC=gcc + +make -C /src -e "$@" diff --git a/docker/bedrook/Dockerfile b/docker/bedrook/Dockerfile new file mode 100644 index 000000000..c29b19819 --- /dev/null +++ b/docker/bedrook/Dockerfile @@ -0,0 +1,17 @@ +FROM alpine:3.6 + +RUN apk update \ + && apk add libpcrecpp libstdc++ libgcc libexecinfo + +RUN adduser -h /db -u 1000 -D bed \ + && chgrp bed /lib \ + && chmod 775 /lib + +COPY bedrock start-bedrock /usr/local/bin/ +COPY udf.so /usr/local/lib/ + +#USER bed +VOLUME /db +WORKDIR /db + +ENTRYPOINT ["start-bedrock"] diff --git a/docker/bedrook/start-bedrock b/docker/bedrook/start-bedrock new file mode 100755 index 000000000..2b9f24bd8 --- /dev/null +++ b/docker/bedrook/start-bedrock @@ -0,0 +1,26 @@ +#!/bin/sh + +export NODE=ohio +export DB=/db/bedrock.db +export CFG=/db/bedrock.cfg +export PEERS=/db/bedrock.peers +export PRIO=30 +export RUN=/var/run/bedrock.pid + +syslogd -S + +if [ ! -f $CFG ] +then + echo "-plugins db,jobs,cache,mysql" >$CFG +fi + +touch $DB $PEERS + +cat $CFG $PEERS | xargs bedrock -fork -v -db $DB -pidfile $RUN + +#bedrock -fork -nodeName $NODE -db $DB \ +# -serverHost 0.0.0.0:8888 -nodeHost 0.0.0.0:8889 -priority $PRIO -pidfile $RUN \ +# -quorumCheckpoint 100 -readThreads 4 -cache 10001 -plugins status,db,jobs,cache,mysql \ +# -v + +sh -i diff --git a/docker/bedrook/udf.so b/docker/bedrook/udf.so new file mode 100755 index 000000000..d6829c7ce Binary files /dev/null and b/docker/bedrook/udf.so differ diff --git a/main.cpp b/main.cpp index 70650c8c6..8295ddfb2 100644 --- a/main.cpp +++ b/main.cpp @@ -121,11 +121,11 @@ set loadPlugins(SData& args) { // Open the library. void* lib = dlopen(pluginName.c_str(), RTLD_NOW); if(!lib) { - cout << "Error loading bedrock plugin " << pluginName << ": " << dlerror() << endl; + SWARN("Error loading bedrock plugin " << pluginName << ": " << dlerror()); } else { void* sym = dlsym(lib, symbolName.c_str()); if (!sym) { - cout << "Couldn't find symbol " << symbolName << endl; + SWARN("Couldn't find symbol " << symbolName); } else { // Call the plugin registration function with the same name. ((void(*)()) sym)(); diff --git a/udf.c b/udf.c new file mode 100644 index 000000000..d6b7777bf --- /dev/null +++ b/udf.c @@ -0,0 +1,65 @@ +/* + Copyright 2017 Guy Riddle + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 + +/* + * One sample SQLite stored function that is automatically loaded into each database opened. + * + * You might use a different cheese, of course. + * + * Demonstrate via: "SELECT gouda(1.2, 2.3, 5.0, 3.4);" + * + */ + + static void +gouda_function( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + double a = sqlite3_value_double(argv[0]); + double b = sqlite3_value_double(argv[1]); + double c = sqlite3_value_double(argv[2]); + double d = sqlite3_value_double(argv[3]); + double answer; + + answer = a*b - c*d; + + sqlite3_result_double(context, answer); +} + + int +load_udf_definitions( + sqlite3 *db, + const char **pzErrMsg, + const struct sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); + + rc = sqlite3_create_function(db, "gouda", 4, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, gouda_function, 0, 0); + + return(rc); +}; + +#undef sqlite3_auto_extension + + void +udf_initialize(){ + sqlite3_auto_extension((void *) &load_udf_definitions); +} diff --git a/udf.so b/udf.so new file mode 100755 index 000000000..d6829c7ce Binary files /dev/null and b/udf.so differ diff --git a/udfplug.cpp b/udfplug.cpp new file mode 100644 index 000000000..54cef3187 --- /dev/null +++ b/udfplug.cpp @@ -0,0 +1,23 @@ + +#include + +/* + * We don't really need the Bedrock plugin APIs, just the loading mechanism. + * + * The SQLite stored functions we register get done in udf_initialize() + * + */ + +class BedrockPlugin_UDF : public BedrockPlugin +{ + public: + virtual string getName() { return "UDF"; } +}; + +extern "C" void udf_initialize(); + +extern "C" void BEDROCK_PLUGIN_REGISTER_UDF() { + new BedrockPlugin_UDF(); + + udf_initialize(); +}