diff --git a/.circleci/config.yml b/.circleci/config.yml index ceae3038..10a7e2ba 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,13 +3,15 @@ version: 2 defaults: &defaults working_directory: ~/dd-opentracing-cpp docker: - - image: datadog/docker-library:dd_opentracing_cpp_build_0_3_0 + - image: datadog/docker-library:dd_opentracing_cpp_build_0_3_2 jobs: build: <<: *defaults environment: CMAKE_ARGS: -DBUILD_PLUGIN=ON -DBUILD_SHARED=OFF + NGINX_OPENTRACING_VERSION: 0.6.0 + NGINX_VERSION: 1.14.0 steps: - checkout - run: @@ -38,6 +40,25 @@ jobs: cmake $CMAKE_ARGS .. make cp libdd_opentracing_plugin.so /tmp/build/libdd_opentracing_plugin.so + - run: + name: Build opentracing-nginx + command: | + wget https://github.com/opentracing-contrib/nginx-opentracing/archive/v${NGINX_OPENTRACING_VERSION}.tar.gz -O nginx-opentracing.tar.gz + mkdir nginx-opentracing + tar zxvf nginx-opentracing.tar.gz -C nginx-opentracing --strip-components=1 + + wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz -O nginx-${NGINX_VERSION}.tar.gz + tar zxvf nginx-${NGINX_VERSION}.tar.gz + # TODO(willgittoes-dd): Get these configure args automatically by installing nginx and using `nginx -V`. + cd nginx-${NGINX_VERSION} + ./configure \ + --prefix=/etc/nginx --modules-path=/usr/lib/nginx/modules \ + --user=nginx --group=nginx --with-compat --with-file-aio --with-threads \ + --with-cc-opt="-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-${NGINX_VERSION}/debian/debuild-base/nginx-${NGINX_VERSION}=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC" \ + --with-ld-opt='-Wl,-Bsymbolic-functions -specs=/usr/share/dpkg/no-pie-link.specs -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie' \ + --add-dynamic-module=../nginx-opentracing/opentracing + make + cp objs/ngx_http_opentracing_module.so /tmp/build/ngx_http_opentracing_module.so - persist_to_workspace: root: /tmp/ paths: @@ -78,7 +99,6 @@ jobs: docker: - image: datadog/docker-library:dd_opentracing_cpp_test_0_3_0 environment: - NGINX_OPENTRACING_VERSION: 0.6.0 NGINX_VERSION: 1.14.0 steps: - checkout @@ -98,11 +118,10 @@ jobs: name: Integration test command: | # Install the Datadog plugin + NGINX_MODULES=$(nginx -V 2>&1 | grep "configure arguments" | sed -n 's/.*--modules-path=\([^ ]*\).*/\1/p') cp ./build/libdd_opentracing_plugin.so /usr/local/lib/libdd_opentracing_plugin.so + cp ./build/ngx_http_opentracing_module.so ${NGINX_MODULES}/ngx_http_opentracing_module.so # Change the config to use it. - NGINX_MODULES=$(nginx -V 2>&1 | grep "configure arguments" | sed -n 's/.*--modules-path=\([^ ]*\).*/\1/p') - wget https://github.com/opentracing-contrib/nginx-opentracing/releases/download/v${NGINX_OPENTRACING_VERSION}/linux-amd64-nginx-${NGINX_VERSION}-ngx_http_module.so.tgz - tar zxf linux-amd64-nginx-${NGINX_VERSION}-ngx_http_module.so.tgz -C ${NGINX_MODULES} cd ./test/integration/nginx/ NGINX_CONF=$(nginx -V 2>&1 | grep "configure arguments" | sed -n 's/.*--conf-path=\([^ ]*\).*/\1/p') cp nginx.conf $NGINX_CONF diff --git a/.gitignore b/.gitignore index 0f2aaaed..12246408 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,6 @@ # Bazel bazel-* + +# IDE settings +.vscode/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e7ae4ca..07d93d32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,11 @@ file(GLOB DD_OPENTRACING_SOURCES "src/*.cpp") # Outputs ## Shared lib if(BUILD_SHARED) + # Needed for curl if: curl is built statically, we compile a shared lib, and an nginx build + # is happening on the same machine. Using zlib1-dev from repos causes a linker fail. + find_package(ZLIB) + set(DATADOG_LINK_LIBRARIES ${OPENTRACING_LIB} ${ZLIB_LIBRARIES} ${CURL_LIBRARIES} Threads::Threads) + add_library(dd_opentracing SHARED ${DD_OPENTRACING_SOURCES}) add_sanitizers(dd_opentracing) target_link_libraries(dd_opentracing ${DATADOG_LINK_LIBRARIES}) diff --git a/scripts/install_dependencies.sh b/scripts/install_dependencies.sh index 76c41c85..70906465 100755 --- a/scripts/install_dependencies.sh +++ b/scripts/install_dependencies.sh @@ -1,9 +1,10 @@ #!/bin/bash set -eo pipefail -OPENTRACING_VERSION=${OPENTRACING_VERSION:-1.4.0} -CURL_VERSION=${CURL_VERSION:-7.60.0} -MSGPACK_VERSION=${MSGPACK_VERSION:-3.0.1} +OPENTRACING_VERSION=${OPENTRACING_VERSION:-1.5.0} +CURL_VERSION=${CURL_VERSION:-7.61.1} +MSGPACK_VERSION=${MSGPACK_VERSION:-3.1.1} +ZLIB_VERSION=${ZLIB_VERSION:-1.2.11} # Allow specifying dependencies not to install. By default we want to compile # our own versions, but under some circumstances (eg building opentracing-nginx @@ -11,6 +12,7 @@ MSGPACK_VERSION=${MSGPACK_VERSION:-3.0.1} BUILD_OPENTRACING=1 BUILD_CURL=1 BUILD_MSGPACK=1 +BUILD_ZLIB=1 while test $# -gt 0 do @@ -21,6 +23,8 @@ do ;; not-curl) BUILD_CURL=0 ;; + not-zlib) BUILD_ZLIB=0 + ;; *) echo "unknown dependency: $1" && exit 1 ;; esac @@ -56,6 +60,16 @@ if [ "$BUILD_MSGPACK" -eq "1" ]; then cd ../.. fi +# Zlib +if [ "$BUILD_ZLIB" -eq "1" ]; then + wget https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz + tar zxf zlib-${ZLIB_VERSION}.tar.gz + cd zlib-${ZLIB_VERSION} + ./configure --static + make && make install + cd .. +fi + # Libcurl if [ "$BUILD_CURL" -eq "1" ]; then wget https://curl.haxx.se/download/curl-${CURL_VERSION}.tar.gz diff --git a/src/dynamic_load.cpp b/src/dynamic_load.cpp index 46007194..8b13bdc6 100644 --- a/src/dynamic_load.cpp +++ b/src/dynamic_load.cpp @@ -2,20 +2,31 @@ #include #include "tracer.h" #include "tracer_factory.h" -#include "version_check.h" -int OpenTracingMakeTracerFactory(const char* opentracing_version, const void** error_category, - void** tracer_factory) try { - if (!datadog::opentracing::equal_or_higher_version(std::string(opentracing_version), - std::string(OPENTRACING_VERSION))) { - std::cerr << "version mismatch: " << std::string(opentracing_version) - << " != " << std::string(OPENTRACING_VERSION) << std::endl; +int OpenTracingMakeTracerFactoryFunction(const char* opentracing_version, + const char* opentracing_abi_version, + const void** error_category, void* error_message, + void** tracer_factory) try { + if (opentracing_version == nullptr || opentracing_abi_version == nullptr || + error_message == nullptr || error_category == nullptr || tracer_factory == nullptr) { + std::cerr << "opentracing_version, opentracing_abi_version, error_message, `error_category, " + " and tracer_factory must be non-null." + << std::endl; + std::terminate(); + } + + if (std::strcmp(opentracing_abi_version, OPENTRACING_ABI_VERSION) != 0) { + std::cerr << "version mismatch: " << std::string(opentracing_abi_version) + << " != " << std::string(OPENTRACING_ABI_VERSION) << std::endl; *error_category = static_cast(&opentracing::dynamic_load_error_category()); return opentracing::incompatible_library_versions_error.value(); } + *tracer_factory = new datadog::opentracing::TracerFactory{}; return 0; } catch (const std::bad_alloc&) { *error_category = static_cast(&std::generic_category()); return static_cast(std::errc::not_enough_memory); } + +OPENTRACING_DECLARE_IMPL_FACTORY(OpenTracingMakeTracerFactoryFunction) diff --git a/src/version_check.cpp b/src/version_check.cpp deleted file mode 100644 index a656773b..00000000 --- a/src/version_check.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "version_check.h" -#include - -namespace datadog { -namespace opentracing { - -bool split_version(const std::string version, int& major, int& minor, int& patch, - std::string& label) try { - std::string ver = version; - // Major number. - auto pos = ver.find("."); - if (pos == std::string::npos) { - return false; - } - major = std::stoi(ver.substr(0, pos)); - ver = ver.substr(pos + 1); - - // Minor number. - pos = ver.find("."); - if (pos == std::string::npos) { - return false; - } - minor = std::stoi(ver.substr(0, pos)); - ver = ver.substr(pos + 1); - - // Patch number, and possible trailing label. - pos = ver.find("-"); - if (pos == std::string::npos) { - patch = std::stoi(ver); - } else { - patch = std::stoi(ver.substr(0, pos)); - label = ver.substr(pos + 1); - } - return true; -} catch (const std::invalid_argument&) { - return false; -} - -bool equal_or_higher_version(const std::string actual, const std::string min) { - if (actual == min) { - return true; - } - // Find major version. They should be equal. - int amaj = 0; - int amin = 0; - int apatch = 0; - std::string alabel; - if (!split_version(actual, amaj, amin, apatch, alabel)) { - return false; - } - int mmaj = 0; - int mmin = 0; - int mpatch = 0; - std::string mlabel; - if (!split_version(min, mmaj, mmin, mpatch, mlabel)) { - return false; - } - if (amaj > mmaj) { - return false; // Major version is too high. - } - if (amaj == mmaj) { - if (amin > mmin) { - return true; // Higher minor version is acceptable. - } - if (amin == mmin) { - if (apatch > mpatch) { - return true; // Higher patch version is acceptable. - } - if (apatch == mpatch) { - if (alabel == "" || alabel == mlabel) { - return true; // Patch levels match. Either no label in actual version, or identical in - // both. - } - } - } - } - return false; -} - -} // namespace opentracing -} // namespace datadog diff --git a/src/version_check.h b/src/version_check.h deleted file mode 100644 index 9426fb57..00000000 --- a/src/version_check.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef DD_OPENTRACING_VERSION_CHECK_H -#define DD_OPENTRACING_VERSION_CHECK_H - -#include - -namespace datadog { -namespace opentracing { - -bool equal_or_higher_version(const std::string actual, const std::string min); - -} // namespace opentracing -} // namespace datadog - -#endif // DD_OPENTRACING_VERSION_CHECK_H diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 357d4c4f..e31da9cb 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,7 +7,6 @@ macro(_datadog_test TEST_NAME) endmacro() _datadog_test(opentracing_test opentracing_test.cpp) -_datadog_test(version_check_test version_check_test.cpp) _datadog_test(propagation_test propagation_test.cpp) _datadog_test(span_buffer_test span_buffer_test.cpp) _datadog_test(span_test span_test.cpp) diff --git a/test/integration/nginx/Dockerfile b/test/integration/nginx/Dockerfile index ea5626df..39971c55 100644 --- a/test/integration/nginx/Dockerfile +++ b/test/integration/nginx/Dockerfile @@ -1,18 +1,19 @@ FROM ubuntu:18.04 as build +# Also set in the second stage. +ARG NGINX_VERSION=1.14.0 +ARG NGINX_OPENTRACING_VERSION=0.6.0 + # Creates an image with nginx and the Datadog OpenTracing nginx module installed. # Runs a simple integration test. RUN apt-get update && \ - apt-get install -y git build-essential wget curl tar cmake + apt-get install -y git build-essential wget curl tar cmake libpcre3-dev zlib1g-dev WORKDIR ~/ COPY ./scripts ./dd-opentracing-cpp/scripts -RUN export OPENTRACING_VERSION=1.4.0 && \ - export MSGPACK_VERSION=3.0.1 && \ - export CURL_VERSION=7.60.0 && \ - cd dd-opentracing-cpp && \ +RUN cd dd-opentracing-cpp && \ ./scripts/install_dependencies.sh COPY ./3rd_party ./dd-opentracing-cpp/3rd_party COPY ./include ./dd-opentracing-cpp/include @@ -25,11 +26,26 @@ RUN cmake -DBUILD_PLUGIN=ON -DBUILD_TESTING=OFF -DBUILD_SHARED=OFF .. RUN make RUN make install +# Build nginx-opentracing ourselves +RUN wget https://github.com/opentracing-contrib/nginx-opentracing/archive/v${NGINX_OPENTRACING_VERSION}.tar.gz -O nginx-opentracing.tar.gz && \ + mkdir nginx-opentracing && \ + tar zxvf nginx-opentracing.tar.gz -C nginx-opentracing --strip-components=1 +RUN wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz -O nginx-${NGINX_VERSION}.tar.gz +RUN tar zxvf nginx-${NGINX_VERSION}.tar.gz +# TODO(willgittoes-dd): Get these configure args automatically by installing nginx and using `nginx -V`. +RUN cd nginx-${NGINX_VERSION} && \ + ./configure \ + --prefix=/etc/nginx --modules-path=/usr/lib/nginx/modules \ + --user=nginx --group=nginx --with-compat --with-file-aio --with-threads \ + --with-cc-opt="-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-${NGINX_VERSION}/debian/debuild-base/nginx-${NGINX_VERSION}=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC" \ + --with-ld-opt='-Wl,-Bsymbolic-functions -specs=/usr/share/dpkg/no-pie-link.specs -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie' \ + --add-dynamic-module=../nginx-opentracing/opentracing && \ + make && \ + make install FROM ubuntu:18.04 ARG NGINX_VERSION=1.14.0 -ARG NGINX_OPENTRACING_VERSION=0.6.0 RUN apt-get update && \ apt-get install -y git gnupg lsb-release wget curl tar openjdk-8-jre golang jq @@ -44,9 +60,7 @@ RUN CODENAME=$(lsb_release -s -c) && \ apt-get install nginx=${NGINX_VERSION}-1~${CODENAME} # Install OpenTracing -ADD https://github.com/opentracing-contrib/nginx-opentracing/releases/download/v${NGINX_OPENTRACING_VERSION}/linux-amd64-nginx-${NGINX_VERSION}-ngx_http_module.so.tgz linux-amd64-nginx-${NGINX_VERSION}-ngx_http_module.so.tgz -RUN NGINX_MODULES=$(nginx -V 2>&1 | grep "configure arguments" | sed -n 's/.*--modules-path=\([^ ]*\).*/\1/p') && \ - tar zxf linux-amd64-nginx-${NGINX_VERSION}-ngx_http_module.so.tgz -C ${NGINX_MODULES} +COPY --from=build /usr/lib/nginx/modules/ngx_http_opentracing_module.so /usr/lib/nginx/modules/ngx_http_opentracing_module.so # And Datadog OT COPY --from=build /usr/local/lib/libdd_opentracing_plugin.so /usr/local/lib/libdd_opentracing_plugin.so @@ -59,7 +73,7 @@ RUN mkdir -p /var/www/ COPY ./test/integration/nginx/index.html /var/www/index.html # Get Wiremock -ADD http://repo1.maven.org/maven2/com/github/tomakehurst/wiremock-standalone/2.18.0/wiremock-standalone-2.18.0.jar wiremock-standalone-2.18.0.jar +RUN wget http://repo1.maven.org/maven2/com/github/tomakehurst/wiremock-standalone/2.18.0/wiremock-standalone-2.18.0.jar -O wiremock-standalone-2.18.0.jar RUN printf '#!/bin/bash\nset -x\njava -jar '"$(pwd)/wiremock-standalone-2.18.0.jar \"\$@\"\n" > /usr/local/bin/wiremock && \ chmod a+x /usr/local/bin/wiremock diff --git a/test/version_check_test.cpp b/test/version_check_test.cpp deleted file mode 100644 index 444c9328..00000000 --- a/test/version_check_test.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include - -#include "../src/version_check.h" - -#define CATCH_CONFIG_MAIN -#include -using namespace datadog::opentracing; - -TEST_CASE("version_check") { - SECTION("success cases") { - REQUIRE(equal_or_higher_version("1.3.0", "1.3.0")); // Exact match. - REQUIRE(equal_or_higher_version( - "1.4.2", "1.3.0")); // The case that triggered a need for version checking. - REQUIRE(equal_or_higher_version("1.3.0-alpha", "1.3.0-alpha")); // Exact match with label. - REQUIRE(equal_or_higher_version("1.3.1", "1.3.0")); // Higher patch number. - REQUIRE(equal_or_higher_version("1.4.0", "1.3.0")); // Higher minor version. - REQUIRE( - equal_or_higher_version("1.10.0", "1.9.9")); // Confirm the check is numeric, not lexical. - } - SECTION("failure cases") { - REQUIRE(!equal_or_higher_version("2.0.0", "1.99.99")); // Major version is too high. - REQUIRE(!equal_or_higher_version("1.3.0", "1.3.1")); // Version is lower. - REQUIRE( - !equal_or_higher_version("1.3.0-alpha", "1.3.0")); // Version is lower because of label. - } -}