summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Golden <xdg@xdg.me>2018-07-13 14:30:21 -0400
committerDavid Golden <xdg@xdg.me>2018-07-13 16:02:52 -0400
commitdaa559be8821b7c06ca9ca6f3638a1842348ef8d (patch)
treedb7ee142106ef606094d6405f86cf82f7777c802
parentcf1f02c116a9f28b97bc6c41148446342349785c (diff)
downloadmongo-daa559be8821b7c06ca9ca6f3638a1842348ef8d.tar.gz
Import tools: 5f036603357e3d910e4d765369261fd0b577dd59 from branch v4.1
ref: 37adadadd5..5f03660335 for: 4.1.1 TOOLS-1709 Set build version and git revision using -ldflags TOOLS-1970 Add replay-dist task to evergreen wherever we think it will succeed TOOLS-1991 Build tools with Go 1.10.1 TOOLS-2060 Support mongoreplay playback using ssl TOOLS-2067 sslFIPSMode doesn't error when unavailable in openssl TOOLS-2075 mongoreplay always replays to secondary
-rwxr-xr-xsrc/mongo/gotools/build.sh10
-rw-r--r--src/mongo/gotools/common.yml149
-rw-r--r--src/mongo/gotools/common/db/openssl/openssl.go5
-rw-r--r--src/mongo/gotools/common/db/openssl/openssl_fips.go9
-rw-r--r--src/mongo/gotools/common/lldb/connector.go81
-rw-r--r--src/mongo/gotools/common/lldb/db.go262
-rw-r--r--src/mongo/gotools/common/lldb/db_openssl.go26
-rw-r--r--src/mongo/gotools/common/lldb/db_tlsgo.go26
-rw-r--r--src/mongo/gotools/common/lldb/kerberos/gssapi.go34
-rw-r--r--src/mongo/gotools/common/lldb/openssl/openssl.go194
-rw-r--r--src/mongo/gotools/common/lldb/openssl/openssl_fips.go38
-rw-r--r--src/mongo/gotools/common/lldb/tlsgo/config.go246
-rw-r--r--src/mongo/gotools/common/lldb/tlsgo/rootcerts.go22
-rw-r--r--src/mongo/gotools/common/lldb/tlsgo/rootcerts_darwin.go58
-rw-r--r--src/mongo/gotools/common/lldb/tlsgo/tlsgo.go135
-rw-r--r--src/mongo/gotools/common/options/options_ssl.go2
-rw-r--r--src/mongo/gotools/import.data2
-rw-r--r--src/mongo/gotools/mongoreplay/log_wrapper.go5
-rw-r--r--src/mongo/gotools/mongoreplay/main/mongoreplay.go12
-rw-r--r--src/mongo/gotools/mongoreplay/mongoreplay.go8
-rw-r--r--src/mongo/gotools/mongoreplay/mongoreplay_test.go2
-rw-r--r--src/mongo/gotools/mongoreplay/play.go46
-rw-r--r--src/mongo/gotools/mongoreplay/stat_format.go6
-rw-r--r--src/mongo/gotools/vendor/src/github.com/10gen/llmgo/auth.go4
-rw-r--r--src/mongo/gotools/vendor/src/github.com/10gen/llmgo/session.go2
-rw-r--r--src/mongo/gotools/vendor/src/github.com/10gen/llmgo/socket.go1
26 files changed, 1286 insertions, 99 deletions
diff --git a/src/mongo/gotools/build.sh b/src/mongo/gotools/build.sh
index 9ca53c4f429..6511d7af558 100755
--- a/src/mongo/gotools/build.sh
+++ b/src/mongo/gotools/build.sh
@@ -10,9 +10,10 @@ fi
SCRIPT_DIR="$(cd "$(dirname ${BASH_SOURCE[0]})" && pwd)"
cd $SCRIPT_DIR
-sed -i.bak -e "s/built-without-version-string/$(git describe)/" \
- -e "s/built-without-git-spec/$(git rev-parse HEAD)/" \
- common/options/options.go
+VersionStr="$(git describe)"
+Gitspec="$(git rev-parse HEAD)"
+importpath="github.com/mongodb/mongo-tools/common/options"
+ldflags="-X ${importpath}.VersionStr=${VersionStr} -X ${importpath}.Gitspec=${Gitspec}"
# remove stale packages
rm -rf vendor/pkg
@@ -23,7 +24,7 @@ mkdir -p bin
ec=0
for i in bsondump mongostat mongofiles mongoexport mongoimport mongorestore mongodump mongotop mongoreplay; do
echo "Building ${i}..."
- go build -o "bin/$i" -tags "$tags" "$i/main/$i.go" || { echo "Error building $i"; ec=1; break; }
+ go build -o "bin/$i" -ldflags "$ldflags" -tags "$tags" "$i/main/$i.go" || { echo "Error building $i"; ec=1; break; }
./bin/$i --version | head -1
done
@@ -31,5 +32,4 @@ if [ -t /dev/stdin ]; then
stty sane
fi
-mv -f common/options/options.go.bak common/options/options.go
exit $ec
diff --git a/src/mongo/gotools/common.yml b/src/mongo/gotools/common.yml
index fe419d94608..b54f943cefa 100644
--- a/src/mongo/gotools/common.yml
+++ b/src/mongo/gotools/common.yml
@@ -29,20 +29,20 @@ mongo_tools_variables:
- name: qa-dump-restore-archiving
- name: qa-dump-restore-archiving-3.2
- name: unit
-# disabled until BUILD-2273 is done
-# - name: replay-dist
-# - name: replay-sanity_check
-# - name: replay-go_test
-# - name: replay-auth_test
-# - name: replay-sharded_test
-# - name: replay-repl_test
-# - name: replay-replay_test
+ - name: replay-dist
+ - name: replay-sanity_check
+ - name: replay-go_test
+ - name: replay-auth_test
+ - name: replay-sharded_test
+ - name: replay-repl_test
+ - name: replay-replay_test
macos_1012_ssl_task_list: &macos_1012_ssl_tasks
- name: dist
- name: qa-tests-4.0
- name: qa-tests-unstable
- name: native-cert-ssl
- name: unit
+ - name: replay-dist
ubuntu1404_x86_64_task_list: &ubuntu1404_x86_64_tasks
- name: db
- name: dist
@@ -77,6 +77,7 @@ mongo_tools_variables:
- name: qa-tests-4.0
- name: qa-tests-unstable
- name: native-cert-ssl
+ - name: replay-dist
ubuntu1404_x86_64_enterprise_task_list: &ubuntu1404_x86_64_enterprise_tasks
- name: db
- name: dist
@@ -193,14 +194,13 @@ mongo_tools_variables:
- name: qa-tests-4.0
- name: qa-tests-unstable
- name: native-cert-ssl
-# disabled until BUILD-2273 is done
-# - name: replay-dist
-# - name: replay-sanity_check
-# - name: replay-go_test
-# - name: replay-auth_test
-# - name: replay-sharded_test
-# - name: replay-repl_test
-# - name: replay-replay_test
+ - name: replay-dist
+ - name: replay-sanity_check
+ - name: replay-go_test
+ - name: replay-auth_test
+ - name: replay-sharded_test
+ - name: replay-repl_test
+ - name: replay-replay_test
rhel67_s390x_enterprise_task_list: &rhel67_s390x_enterprise_tasks
- name: db
- name: dist
@@ -214,14 +214,13 @@ mongo_tools_variables:
- name: qa-tests-4.0
- name: qa-tests-unstable
- name: native-cert-ssl
-# disabled until BUILD-2273 is done
-# - name: replay-dist
-# - name: replay-sanity_check
-# - name: replay-go_test
-# - name: replay-auth_test
-# - name: replay-sharded_test
-# - name: replay-repl_test
-# - name: replay-replay_test
+ - name: replay-dist
+ - name: replay-sanity_check
+ - name: replay-go_test
+ - name: replay-auth_test
+ - name: replay-sharded_test
+ - name: replay-repl_test
+ - name: replay-replay_test
ubuntu1604_arm64_ssl_task_list: &ubuntu1604_arm64_ssl_tasks
- name: db
- name: dist
@@ -234,6 +233,7 @@ mongo_tools_variables:
- name: qa-tests-4.0
- name: qa-tests-unstable
- name: native-cert-ssl
+ - name: replay-dist
## Common mongodb arguments
@@ -270,7 +270,7 @@ functions:
chmod +x bin/*
mv bin/* ${test_path}/
cd ${test_path}
- python buildscripts/smoke.py ${smoke_use_ssl} --nopreallocj --with-cleanbb --mongod ./mongod --mongo ./mongo --report-file ../../report.json --continue-on-failure --buildlogger-builder MCI_${build_variant} --buildlogger-buildnum ${builder_num|} --buildlogger-credentials ./mci.buildlogger --buildlogger-phase ${task_name}_${execution} ${smoke_args} tool
+ python buildscripts/smoke.py ${smoke_use_ssl} --with-cleanbb --mongod ./mongod --mongo ./mongo --report-file ../../report.json --continue-on-failure --buildlogger-builder MCI_${build_variant} --buildlogger-buildnum ${builder_num|} --buildlogger-credentials ./mci.buildlogger --buildlogger-phase ${task_name}_${execution} ${smoke_args} tool
"run qa-tests":
command: shell.exec
@@ -1638,55 +1638,59 @@ buildvariants:
#######################################
- name: amazonlinux64
- display_name: Amazon Linux 64 (Go 1.8)
+ display_name: Amazon Linux 64 (Go 1.10)
run_on:
- linux-64-amzn-test
expansions:
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10'
build_tags: "sasl ssl"
tasks:
- name: dist
+ - name: replay-dist
- name: amazon2
- display_name: Amazon Linux 64 v2 (Go 1.8)
+ display_name: Amazon Linux 64 v2 (Go 1.10)
run_on:
- amazon2-test
expansions:
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10'
build_tags: "sasl ssl"
tasks:
- name: dist
+ - name: replay-dist
#######################################
# Debian x86_64 Buildvariants #
#######################################
- name: debian81
- display_name: Debian 8.1 (Go 1.8)
+ display_name: Debian 8.1 (Go 1.10)
run_on:
- debian81-test
expansions:
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10'
build_tags: "sasl ssl"
tasks:
- name: dist
+ - name: replay-dist
- name: debian92
- display_name: Debian 9.2 (Go 1.8)
+ display_name: Debian 9.2 (Go 1.10)
run_on:
- debian92-test
expansions:
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10'
build_tags: "sasl ssl"
tasks:
- name: dist
+ - name: replay-dist
#######################################
# macOS Buildvariant #
#######################################
- name: macOS-1012
- display_name: MacOS 10.12 (Go 1.8)
+ display_name: MacOS 10.12 (Go 1.10)
run_on:
- macos-1012
expansions:
@@ -1696,11 +1700,11 @@ buildvariants:
mongo_target: "osx-ssl"
arch: "osx/x86_64"
excludes: requires_many_files
- gorootvars: 'PATH="/usr/local/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/usr/local/go1.8/go'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10'
tasks: *macos_1012_tasks
- name: macOS-1012-ssl
- display_name: MacOS 10.12 SSL (Go 1.8)
+ display_name: MacOS 10.12 SSL (Go 1.10)
run_on:
- macos-1012
expansions:
@@ -1711,7 +1715,7 @@ buildvariants:
arch: "osx/x86_64"
build_tags: "ssl openssl_pre_1.0"
excludes: requires_many_files
- gorootvars: 'PATH="/usr/local/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/usr/local/go1.8/go'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10'
tasks: *macos_1012_ssl_tasks
#######################################
@@ -1719,45 +1723,48 @@ buildvariants:
#######################################
- name: rhel62
- display_name: RHEL 6.2 (Go 1.8)
+ display_name: RHEL 6.2 (Go 1.10)
run_on:
- rhel62-test
expansions:
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10'
build_tags: "sasl ssl"
tasks:
- name: dist
+ - name: replay-dist
- name: rhel70
- display_name: RHEL 7.0 (Go 1.8)
+ display_name: RHEL 7.0 (Go 1.10)
run_on:
- rhel70
expansions:
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10'
build_tags: "sasl ssl"
tasks:
- name: dist
+ - name: replay-dist
#######################################
# SUSE x86_64 Buildvariants #
#######################################
- name: suse12
- display_name: SUSE 12 (Go 1.8)
+ display_name: SUSE 12 (Go 1.10)
run_on:
- suse12-test
expansions:
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10'
build_tags: "sasl ssl"
tasks:
- name: dist
+ - name: replay-dist
#######################################
# Ubuntu x86_64 Buildvariants #
#######################################
- name: ubuntu1404
- display_name: Ubuntu 14.04 (Go 1.8)
+ display_name: Ubuntu 14.04 (Go 1.10)
run_on:
- ubuntu1404-test
expansions:
@@ -1765,7 +1772,7 @@ buildvariants:
<<: *mongo_default_startup_args
mongo_os: "ubuntu1404"
mongo_edition: "targeted"
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10'
build_tags: "sasl ssl"
arch: "linux/x86_64"
integration_test_args: integration
@@ -1773,7 +1780,7 @@ buildvariants:
tasks: *ubuntu1404_x86_64_tasks
- name: ubuntu1404-ssl
- display_name: Ubuntu 14.04 SSL (Go 1.8)
+ display_name: Ubuntu 14.04 SSL (Go 1.10)
run_on:
- ubuntu1404-test
expansions:
@@ -1781,7 +1788,7 @@ buildvariants:
<<: *mongo_ssl_startup_args
mongo_os: "ubuntu1404"
mongo_edition: "enterprise"
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10'
build_tags: "sasl ssl"
edition: ssl
arch: "linux/x86_64"
@@ -1792,7 +1799,7 @@ buildvariants:
tasks: *ubuntu1404_x86_64_ssl_tasks
- name: ubuntu1404-enterprise
- display_name: Ubuntu 14.04 Enterprise (Go 1.8)
+ display_name: Ubuntu 14.04 Enterprise (Go 1.10)
run_on:
- ubuntu1404-test
expansions:
@@ -1800,7 +1807,7 @@ buildvariants:
<<: *mongo_default_startup_args
mongo_os: "ubuntu1404"
mongo_edition: "enterprise"
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10'
build_tags: "ssl sasl"
smoke_use_ssl: --use-ssl
resmoke_use_ssl: _ssl
@@ -1812,21 +1819,22 @@ buildvariants:
tasks: *ubuntu1404_x86_64_enterprise_tasks
- name: ubuntu1604
- display_name: Ubuntu 16.04 (Go 1.8)
+ display_name: Ubuntu 16.04 (Go 1.10)
run_on:
- ubuntu1604-test
expansions:
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10'
build_tags: "sasl ssl"
tasks:
- name: dist
+ - name: replay-dist
#######################################
# Windows Buildvariants #
#######################################
- name: windows-64
- display_name: Windows 64-bit (Go 1.8)
+ display_name: Windows 64-bit (Go 1.10)
run_on:
- windows-64-vs2013-test
expansions:
@@ -1840,11 +1848,11 @@ buildvariants:
arch: "win32/x86_64"
preproc_gpm: "perl -pi -e 's/\\r\\n/\\n/g' "
integration_test_args: "integration"
- gorootvars: 'PATH="/cygdrive/c/go1.8/go/bin:/cygdrive/c/mingw-w64/x86_64-4.9.1-posix-seh-rt_v3-rev1/mingw64/bin:$PATH" GOROOT="c:/go1.8/go"'
+ gorootvars: 'PATH="/cygdrive/c/golang/go1.10/bin:/cygdrive/c/mingw-w64/x86_64-4.9.1-posix-seh-rt_v3-rev1/mingw64/bin:$PATH" GOROOT="c:/golang/go1.10"'
tasks: *windows_64_tasks
- name: windows-64-ssl
- display_name: Windows 64-bit SSL (Go 1.8)
+ display_name: Windows 64-bit SSL (Go 1.10)
run_on:
- windows-64-vs2013-compile
expansions:
@@ -1861,13 +1869,13 @@ buildvariants:
multiversion_override: "2.6"
extension: .exe
arch: "win32/x86_64"
- gorootvars: 'PATH="/cygdrive/c/go1.8/go/bin:/cygdrive/c/mingw-w64/x86_64-4.9.1-posix-seh-rt_v3-rev1/mingw64/bin:$PATH" GOROOT="c:/go1.8/go"'
+ gorootvars: 'PATH="/cygdrive/c/golang/go1.10/bin:/cygdrive/c/mingw-w64/x86_64-4.9.1-posix-seh-rt_v3-rev1/mingw64/bin:$PATH" GOROOT="c:/golang/go1.10"'
preproc_gpm: "perl -pi -e 's/\\r\\n/\\n/g' "
integration_test_args: "integration,ssl"
tasks: *windows_64_ssl_tasks
- name: windows-64-enterprise
- display_name: Windows 64-bit Enterprise (Go 1.8)
+ display_name: Windows 64-bit Enterprise (Go 1.10)
run_on:
- windows-64-vs2013-compile
expansions:
@@ -1885,7 +1893,7 @@ buildvariants:
edition: enterprise
extension: .exe
arch: "win32/x86_64"
- gorootvars: 'PATH="/cygdrive/c/go1.8/go/bin:/cygdrive/c/mingw-w64/x86_64-4.9.1-posix-seh-rt_v3-rev1/mingw64/bin:$PATH" GOROOT="c:/go1.8/go"'
+ gorootvars: 'PATH="/cygdrive/c/golang/go1.10/bin:/cygdrive/c/mingw-w64/x86_64-4.9.1-posix-seh-rt_v3-rev1/mingw64/bin:$PATH" GOROOT="c:/golang/go1.10"'
preproc_gpm: "perl -pi -e 's/\\r\\n/\\n/g' "
integration_test_args: "integration"
tasks: *windows_64_enterprise_tasks
@@ -1895,7 +1903,7 @@ buildvariants:
#######################################
- name: ubuntu1604-arm64
- display_name: ZAP ARM64 Ubuntu 16.04 SSL (gccgo 1.4)
+ display_name: ZAP ARM64 Ubuntu 16.04 SSL (Go 1.10)
run_on:
- ubuntu1604-arm64-small
stepback: false
@@ -1906,10 +1914,9 @@ buildvariants:
mongo_os: "ubuntu1604"
mongo_edition: "targeted"
mongo_arch: "arm64"
- args: -gccgoflags "$(pkg-config --libs --cflags libcrypto libssl)"
build_tags: "ssl"
resmoke_use_ssl: _ssl
- gorootvars: PATH="/opt/mongodbtoolchain/v2/bin/:$PATH"
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10 CC=/opt/mongodbtoolchain/v2/bin/aarch64-mongodb-linux-gcc'
excludes: requires_mmap_available,requires_large_ram,requires_mongo_24,requires_mongo_26,requires_mongo_30
resmoke_args: -j 2
multiversion_override: "skip"
@@ -1923,7 +1930,7 @@ buildvariants:
#######################################
- name: rhel71-ppc64le-enterprise
- display_name: ZAP PPC64LE RHEL 7.1 Enterprise (Go 1.8)
+ display_name: ZAP PPC64LE RHEL 7.1 Enterprise (Go 1.10)
run_on:
- rhel71-power8-test
stepback: false
@@ -1938,7 +1945,7 @@ buildvariants:
#args: ... libsasl2; build_tags "sasl ssl"
build_tags: 'ssl'
resmoke_use_ssl: _ssl
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go CC=/opt/mongodbtoolchain/v2/bin/ppc64le-mongodb-linux-gcc'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10 CC=/opt/mongodbtoolchain/v2/bin/ppc64le-mongodb-linux-gcc'
resmoke_args: -j 4
excludes: requires_mmap_available,requires_large_ram,requires_mongo_24,requires_mongo_26,requires_mongo_30
multiversion_override: "skip"
@@ -1949,23 +1956,24 @@ buildvariants:
tasks: *rhel71_ppc64le_enterprise_tasks
- name: ubuntu1604-ppc64le-enterprise
- display_name: ZAP PPC64LE Ubuntu 16.04 Enterprise (Go 1.8)
+ display_name: ZAP PPC64LE Ubuntu 16.04 Enterprise (Go 1.10)
run_on:
- ubuntu1604-power8-test
stepback: false
batchtime: 10080 # weekly
expansions:
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go CC=/opt/mongodbtoolchain/v2/bin/ppc64le-mongodb-linux-gcc'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10 CC=/opt/mongodbtoolchain/v2/bin/ppc64le-mongodb-linux-gcc'
build_tags: 'ssl sasl'
tasks:
- name: dist
+ - name: replay-dist
#######################################
# Z (s390x) Buildvariants #
#######################################
- name: rhel67-s390x-enterprise
- display_name: ZAP s390x RHEL 6.7 Enterprise (Go 1.8)
+ display_name: ZAP s390x RHEL 6.7 Enterprise (Go 1.10)
run_on:
- rhel67-zseries-test
stepback: false
@@ -1978,7 +1986,7 @@ buildvariants:
mongo_arch: "s390x"
build_tags: "sasl ssl"
resmoke_use_ssl: _ssl
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go CC=/opt/mongodbtoolchain/v2/bin/s390x-mongodb-linux-gcc'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10 CC=/opt/mongodbtoolchain/v2/bin/s390x-mongodb-linux-gcc'
excludes: requires_mmap_available,requires_mongo_24,requires_mongo_26,requires_mongo_30
resmoke_args: -j 2
multiversion_override: "skip"
@@ -1989,16 +1997,17 @@ buildvariants:
tasks: *rhel67_s390x_enterprise_tasks
- name: ubuntu1604-s390x-enterprise
- display_name: ZAP s390x Ubuntu 16.04 Enterprise (Go 1.8)
+ display_name: ZAP s390x Ubuntu 16.04 Enterprise (Go 1.10)
run_on:
- ubuntu1604-zseries-small
stepback: false
batchtime: 10080 # weekly
expansions:
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go CC=/opt/mongodbtoolchain/v2/bin/s390x-mongodb-linux-gcc'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10 CC=/opt/mongodbtoolchain/v2/bin/s390x-mongodb-linux-gcc'
build_tags: "sasl ssl"
tasks:
- name: dist
+ - name: replay-dist
#######################################
# Experimental Buildvariants #
@@ -2007,7 +2016,7 @@ buildvariants:
- name: ubuntu-race
stepback: false
batchtime: 1440 # daily
- display_name: z Race Detector Ubuntu 14.04 (Go 1.8)
+ display_name: z Race Detector Ubuntu 14.04 (Go 1.10)
run_on:
- ubuntu1404-test
expansions:
@@ -2015,7 +2024,7 @@ buildvariants:
<<: *mongo_default_startup_args
mongo_os: "ubuntu1404"
mongo_edition: "enterprise"
- gorootvars: 'PATH="/opt/go1.8/go/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/go1.8/go'
+ gorootvars: 'PATH="/opt/golang/go1.10/bin:/opt/mongodbtoolchain/v2/bin/:$PATH" GOROOT=/opt/golang/go1.10'
build_tags: "sasl ssl"
arch: "linux/x86_64"
args: "-race"
diff --git a/src/mongo/gotools/common/db/openssl/openssl.go b/src/mongo/gotools/common/db/openssl/openssl.go
index fc39c187f54..cb744ad5dd0 100644
--- a/src/mongo/gotools/common/db/openssl/openssl.go
+++ b/src/mongo/gotools/common/db/openssl/openssl.go
@@ -107,7 +107,10 @@ func setupCtx(opts options.ToolOptions) (*openssl.Ctx, error) {
var err error
for _, sslInitFunc := range sslInitializationFunctions {
- sslInitFunc(opts)
+ err = sslInitFunc(opts)
+ if err != nil {
+ return nil, err
+ }
}
if ctx, err = openssl.NewCtxWithVersion(openssl.AnyVersion); err != nil {
diff --git a/src/mongo/gotools/common/db/openssl/openssl_fips.go b/src/mongo/gotools/common/db/openssl/openssl_fips.go
index 08a0f644cb8..68bf0a92d3d 100644
--- a/src/mongo/gotools/common/db/openssl/openssl_fips.go
+++ b/src/mongo/gotools/common/db/openssl/openssl_fips.go
@@ -18,6 +18,8 @@ import (
func init() {
if openssl.FIPSModeDefined() {
sslInitializationFunctions = append(sslInitializationFunctions, SetUpFIPSMode)
+ } else {
+ sslInitializationFunctions = append(sslInitializationFunctions, NoFIPSModeAvailable)
}
}
@@ -27,3 +29,10 @@ func SetUpFIPSMode(opts options.ToolOptions) error {
}
return nil
}
+
+func NoFIPSModeAvailable(opts options.ToolOptions) error {
+ if opts.SSLFipsMode {
+ return fmt.Errorf("FIPS mode not supported")
+ }
+ return nil
+}
diff --git a/src/mongo/gotools/common/lldb/connector.go b/src/mongo/gotools/common/lldb/connector.go
new file mode 100644
index 00000000000..b1623243528
--- /dev/null
+++ b/src/mongo/gotools/common/lldb/connector.go
@@ -0,0 +1,81 @@
+// Copyright (C) MongoDB, Inc. 2014-present.
+//
+// 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
+
+package lldb
+
+import (
+ "net"
+ "time"
+
+ mgo "github.com/10gen/llmgo"
+ "github.com/mongodb/mongo-tools/common/lldb/kerberos"
+ "github.com/mongodb/mongo-tools/common/options"
+ "github.com/mongodb/mongo-tools/common/util"
+)
+
+// Interface type for connecting to the database.
+type DBConnector interface {
+ // configure, based on the options passed in
+ Configure(options.ToolOptions) error
+
+ // dial the database and get a fresh new session
+ GetNewSession() (*mgo.Session, error)
+}
+
+// Basic connector for dialing the database, with no authentication.
+type VanillaDBConnector struct {
+ dialInfo *mgo.DialInfo
+}
+
+// Configure sets up the db connector using the options in opts. It parses the
+// connection string and then sets up the dial information using the default
+// dial timeout.
+func (self *VanillaDBConnector) Configure(opts options.ToolOptions) error {
+ timeout := time.Duration(opts.Timeout) * time.Second
+
+ // create the dialer func that will be used to connect
+ dialer := func(addr *mgo.ServerAddr) (net.Conn, error) {
+ conn, err := net.DialTimeout("tcp", addr.String(), timeout)
+ if err != nil {
+ return nil, err
+ }
+ // enable TCP keepalive
+ err = util.EnableTCPKeepAlive(conn, time.Duration(opts.TCPKeepAliveSeconds)*time.Second)
+ if err != nil {
+ return nil, err
+ }
+ return conn, nil
+ }
+
+ // set up the dial info
+ self.dialInfo = &mgo.DialInfo{
+ Direct: opts.Direct,
+ ReplicaSetName: opts.ReplicaSetName,
+ Username: opts.Auth.Username,
+ Password: opts.Auth.Password,
+ Source: opts.GetAuthenticationDatabase(),
+ Mechanism: opts.Auth.Mechanism,
+ DialServer: dialer,
+ Timeout: timeout,
+ }
+
+ // create or fetch the addresses to be used to connect
+ if opts.URI != nil && opts.URI.ConnectionString != "" {
+ self.dialInfo.Addrs = opts.URI.GetConnectionAddrs()
+ } else {
+ self.dialInfo.Addrs = util.CreateConnectionAddrs(opts.Host, opts.Port)
+ }
+
+ kerberos.AddKerberosOpts(opts, self.dialInfo)
+
+ return nil
+}
+
+// GetNewSession connects to the server and returns the established session and any
+// error encountered.
+func (self *VanillaDBConnector) GetNewSession() (*mgo.Session, error) {
+ return mgo.DialWithInfo(self.dialInfo)
+}
diff --git a/src/mongo/gotools/common/lldb/db.go b/src/mongo/gotools/common/lldb/db.go
new file mode 100644
index 00000000000..a3397baff56
--- /dev/null
+++ b/src/mongo/gotools/common/lldb/db.go
@@ -0,0 +1,262 @@
+// Copyright (C) MongoDB, Inc. 2014-present.
+//
+// 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
+
+// Package db implements generic connection to MongoDB, and contains
+// subpackages for specific methods of connection.
+package lldb
+
+import (
+ "github.com/mongodb/mongo-tools/common/options"
+ "github.com/mongodb/mongo-tools/common/password"
+ mgo "github.com/10gen/llmgo"
+ "github.com/10gen/llmgo/bson"
+
+ "fmt"
+ "io"
+ "strings"
+ "sync"
+)
+
+type (
+ sessionFlag uint32
+ // Used to get appropriate the DBConnector(s) based on opts
+ GetConnectorFunc func(opts options.ToolOptions) DBConnector
+)
+
+// Session flags.
+const (
+ None sessionFlag = 0
+ Monotonic sessionFlag = 1 << iota
+ DisableSocketTimeout
+)
+
+// MongoDB enforced limits.
+const (
+ MaxBSONSize = 16 * 1024 * 1024 // 16MB - maximum BSON document size
+)
+
+// Default port for integration tests
+const (
+ DefaultTestPort = "33333"
+)
+
+const (
+ ErrLostConnection = "lost connection to server"
+ ErrNoReachableServers = "no reachable servers"
+ ErrNsNotFound = "ns not found"
+ // replication errors list the replset name if we are talking to a mongos,
+ // so we can only check for this universal prefix
+ ErrReplTimeoutPrefix = "waiting for replication timed out"
+ ErrCouldNotContactPrimaryPrefix = "could not contact primary for replica set"
+ ErrWriteResultsUnavailable = "write results unavailable from"
+ ErrCouldNotFindPrimaryPrefix = `could not find host matching read preference { mode: "primary"`
+ ErrUnableToTargetPrefix = "unable to target"
+ ErrNotMaster = "not master"
+ ErrConnectionRefusedSuffix = "Connection refused"
+)
+
+var (
+ GetConnectorFuncs = []GetConnectorFunc{}
+)
+
+// Used to manage database sessions
+type SessionProvider struct {
+
+ // For connecting to the database
+ connector DBConnector
+
+ // used to avoid a race condition around creating the master session
+ masterSessionLock sync.Mutex
+
+ // the master session to use for connection pooling
+ masterSession *mgo.Session
+
+ // flags for generating the master session
+ bypassDocumentValidation bool
+ flags sessionFlag
+ readPreference mgo.Mode
+ tags bson.D
+}
+
+// ApplyOpsResponse represents the response from an 'applyOps' command.
+type ApplyOpsResponse struct {
+ Ok bool `bson:"ok"`
+ ErrMsg string `bson:"errmsg"`
+}
+
+// Oplog represents a MongoDB oplog document.
+type Oplog struct {
+ Timestamp bson.MongoTimestamp `bson:"ts"`
+ HistoryID int64 `bson:"h"`
+ Version int `bson:"v"`
+ Operation string `bson:"op"`
+ Namespace string `bson:"ns"`
+ Object bson.D `bson:"o"`
+ Query bson.D `bson:"o2"`
+ UI *bson.Binary `bson:"ui,omitempty"`
+}
+
+// Returns a session connected to the database server for which the
+// session provider is configured.
+func (self *SessionProvider) GetSession() (*mgo.Session, error) {
+ self.masterSessionLock.Lock()
+ defer self.masterSessionLock.Unlock()
+
+ // The master session is initialized
+ if self.masterSession != nil {
+ return self.masterSession.Copy(), nil
+ }
+
+ // initialize the provider's master session
+ var err error
+ self.masterSession, err = self.connector.GetNewSession()
+ if err != nil {
+ return nil, fmt.Errorf("error connecting to db server: %v", err)
+ }
+
+ // update masterSession based on flags
+ self.refresh()
+
+ // copy the provider's master session, for connection pooling
+ return self.masterSession.Copy(), nil
+}
+
+// Close closes the master session in the connection pool
+func (self *SessionProvider) Close() {
+ self.masterSessionLock.Lock()
+ defer self.masterSessionLock.Unlock()
+ if self.masterSession != nil {
+ self.masterSession.Close()
+ }
+}
+
+// refresh is a helper for modifying the session based on the
+// session provider flags passed in with SetFlags.
+// This helper assumes a lock is already taken.
+func (self *SessionProvider) refresh() {
+ // handle bypassDocumentValidation
+ self.masterSession.SetBypassValidation(self.bypassDocumentValidation)
+
+ // handle readPreference
+ self.masterSession.SetMode(self.readPreference, true)
+
+ // disable timeouts
+ if (self.flags & DisableSocketTimeout) > 0 {
+ self.masterSession.SetSocketTimeout(0)
+ }
+ if self.tags != nil {
+ self.masterSession.SelectServers(self.tags)
+ }
+}
+
+// SetFlags allows certain modifications to the masterSession after initial creation.
+func (self *SessionProvider) SetFlags(flagBits sessionFlag) {
+ self.masterSessionLock.Lock()
+ defer self.masterSessionLock.Unlock()
+
+ self.flags = flagBits
+
+ // make sure we update the master session if one already exists
+ if self.masterSession != nil {
+ self.refresh()
+ }
+}
+
+// SetReadPreference sets the read preference mode in the SessionProvider
+// and eventually in the masterSession
+func (self *SessionProvider) SetReadPreference(pref mgo.Mode) {
+ self.masterSessionLock.Lock()
+ defer self.masterSessionLock.Unlock()
+
+ self.readPreference = pref
+
+ if self.masterSession != nil {
+ self.refresh()
+ }
+}
+
+// SetBypassDocumentValidation sets whether to bypass document validation in the SessionProvider
+// and eventually in the masterSession
+func (self *SessionProvider) SetBypassDocumentValidation(bypassDocumentValidation bool) {
+ self.masterSessionLock.Lock()
+ defer self.masterSessionLock.Unlock()
+
+ self.bypassDocumentValidation = bypassDocumentValidation
+
+ if self.masterSession != nil {
+ self.refresh()
+ }
+}
+
+// SetTags sets the server selection tags in the SessionProvider
+// and eventually in the masterSession
+func (self *SessionProvider) SetTags(tags bson.D) {
+ self.masterSessionLock.Lock()
+ defer self.masterSessionLock.Unlock()
+
+ self.tags = tags
+
+ if self.masterSession != nil {
+ self.refresh()
+ }
+}
+
+// NewSessionProvider constructs a session provider but does not attempt to
+// create the initial session.
+func NewSessionProvider(opts options.ToolOptions) (*SessionProvider, error) {
+ // create the provider
+ provider := &SessionProvider{
+ readPreference: mgo.Primary,
+ bypassDocumentValidation: false,
+ }
+
+ // finalize auth options, filling in missing passwords
+ if opts.Auth.ShouldAskForPassword() {
+ opts.Auth.Password = password.Prompt()
+ }
+
+ // create the connector for dialing the database
+ provider.connector = getConnector(opts)
+
+ // configure the connector
+ err := provider.connector.Configure(opts)
+ if err != nil {
+ return nil, fmt.Errorf("error configuring the connector: %v", err)
+ }
+ return provider, nil
+}
+
+// IsConnectionError returns a boolean indicating if a given error is due to
+// an error in an underlying DB connection (as opposed to some other write
+// failure such as a duplicate key error)
+func IsConnectionError(err error) bool {
+ if err == nil {
+ return false
+ }
+ lowerCaseError := strings.ToLower(err.Error())
+ if lowerCaseError == ErrNoReachableServers ||
+ err == io.EOF ||
+ strings.Contains(lowerCaseError, ErrReplTimeoutPrefix) ||
+ strings.Contains(lowerCaseError, ErrCouldNotContactPrimaryPrefix) ||
+ strings.Contains(lowerCaseError, ErrWriteResultsUnavailable) ||
+ strings.Contains(lowerCaseError, ErrCouldNotFindPrimaryPrefix) ||
+ strings.Contains(lowerCaseError, ErrUnableToTargetPrefix) ||
+ lowerCaseError == ErrNotMaster ||
+ strings.HasSuffix(lowerCaseError, ErrConnectionRefusedSuffix) {
+ return true
+ }
+ return false
+}
+
+// Get the right type of connector, based on the options
+func getConnector(opts options.ToolOptions) DBConnector {
+ for _, getConnectorFunc := range GetConnectorFuncs {
+ if connector := getConnectorFunc(opts); connector != nil {
+ return connector
+ }
+ }
+ return &VanillaDBConnector{}
+}
diff --git a/src/mongo/gotools/common/lldb/db_openssl.go b/src/mongo/gotools/common/lldb/db_openssl.go
new file mode 100644
index 00000000000..4a313972060
--- /dev/null
+++ b/src/mongo/gotools/common/lldb/db_openssl.go
@@ -0,0 +1,26 @@
+// Copyright (C) MongoDB, Inc. 2014-present.
+//
+// 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
+
+// +build ssl,!openssl_pre_1.0
+
+package lldb
+
+import (
+ "github.com/mongodb/mongo-tools/common/lldb/openssl"
+ "github.com/mongodb/mongo-tools/common/options"
+)
+
+func init() {
+ GetConnectorFuncs = append(GetConnectorFuncs, getSSLConnector)
+}
+
+// return the SSL DB connector if using SSL, otherwise, return nil.
+func getSSLConnector(opts options.ToolOptions) DBConnector {
+ if opts.SSL.UseSSL {
+ return &openssl.SSLDBConnector{}
+ }
+ return nil
+}
diff --git a/src/mongo/gotools/common/lldb/db_tlsgo.go b/src/mongo/gotools/common/lldb/db_tlsgo.go
new file mode 100644
index 00000000000..e1cfcf18e17
--- /dev/null
+++ b/src/mongo/gotools/common/lldb/db_tlsgo.go
@@ -0,0 +1,26 @@
+// Copyright (C) MongoDB, Inc. 2014-present.
+//
+// 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
+
+// +build ssl,openssl_pre_1.0
+
+package lldb
+
+import (
+ "github.com/mongodb/mongo-tools/common/lldb/tlsgo"
+ "github.com/mongodb/mongo-tools/common/options"
+)
+
+func init() {
+ GetConnectorFuncs = append(GetConnectorFuncs, getSSLConnector)
+}
+
+// return the SSL DB connector if using SSL, otherwise, return nil.
+func getSSLConnector(opts options.ToolOptions) DBConnector {
+ if opts.SSL.UseSSL {
+ return &tlsgo.TLSDBConnector{}
+ }
+ return nil
+}
diff --git a/src/mongo/gotools/common/lldb/kerberos/gssapi.go b/src/mongo/gotools/common/lldb/kerberos/gssapi.go
new file mode 100644
index 00000000000..168e63636c7
--- /dev/null
+++ b/src/mongo/gotools/common/lldb/kerberos/gssapi.go
@@ -0,0 +1,34 @@
+// Copyright (C) MongoDB, Inc. 2014-present.
+//
+// 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
+
+// Package kerberos implements authentication to MongoDB using kerberos
+package kerberos
+
+// #cgo windows CFLAGS: -Ic:/sasl/include
+// #cgo windows LDFLAGS: -Lc:/sasl/lib
+
+import (
+ "github.com/mongodb/mongo-tools/common/options"
+ mgo "github.com/10gen/llmgo"
+)
+
+const authMechanism = "GSSAPI"
+
+func AddKerberosOpts(opts options.ToolOptions, dialInfo *mgo.DialInfo) {
+ if dialInfo == nil {
+ return
+ }
+ if opts.Kerberos == nil {
+ return
+ }
+ if opts.Auth == nil || (opts.Auth.Mechanism != authMechanism &&
+ dialInfo.Mechanism != authMechanism) {
+ return
+ }
+ dialInfo.Service = opts.Kerberos.Service
+ dialInfo.ServiceHost = opts.Kerberos.ServiceHost
+ dialInfo.Mechanism = authMechanism
+}
diff --git a/src/mongo/gotools/common/lldb/openssl/openssl.go b/src/mongo/gotools/common/lldb/openssl/openssl.go
new file mode 100644
index 00000000000..b07019a7956
--- /dev/null
+++ b/src/mongo/gotools/common/lldb/openssl/openssl.go
@@ -0,0 +1,194 @@
+// Copyright (C) MongoDB, Inc. 2014-present.
+//
+// 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
+
+// +build ssl,!openssl_pre_1.0
+
+// Package openssl implements connection to MongoDB over ssl.
+package openssl
+
+import (
+ "fmt"
+ "net"
+ "time"
+
+ mgo "github.com/10gen/llmgo"
+ "github.com/10gen/openssl"
+ "github.com/mongodb/mongo-tools/common/lldb/kerberos"
+ "github.com/mongodb/mongo-tools/common/log"
+ "github.com/mongodb/mongo-tools/common/options"
+ "github.com/mongodb/mongo-tools/common/util"
+)
+
+// For connecting to the database over ssl
+type SSLDBConnector struct {
+ dialInfo *mgo.DialInfo
+ ctx *openssl.Ctx
+}
+
+// Configure the connector to connect to the server over ssl. Parses the
+// connection string, and sets up the correct function to dial the server
+// based on the ssl options passed in.
+func (self *SSLDBConnector) Configure(opts options.ToolOptions) error {
+
+ var err error
+ self.ctx, err = setupCtx(opts)
+ if err != nil {
+ return fmt.Errorf("openssl configuration: %v", err)
+ }
+
+ var flags openssl.DialFlags
+ flags = 0
+ if opts.SSLAllowInvalidCert || opts.SSLAllowInvalidHost {
+ flags = openssl.InsecureSkipHostVerification
+ }
+ // create the dialer func that will be used to connect
+ dialer := func(addr *mgo.ServerAddr) (net.Conn, error) {
+ conn, err := openssl.Dial("tcp", addr.String(), self.ctx, flags)
+ if err != nil {
+ // mgo discards dialer errors so log it now
+ log.Logvf(log.Always, "error dialing %v: %v", addr.String(), err)
+ return nil, err
+ }
+ // enable TCP keepalive
+ err = util.EnableTCPKeepAlive(conn.UnderlyingConn(), time.Duration(opts.TCPKeepAliveSeconds)*time.Second)
+ if err != nil {
+ // mgo discards dialer errors so log it now
+ log.Logvf(log.Always, "error enabling TCP keepalive on connection to %v: %v", addr.String(), err)
+ conn.Close()
+ return nil, err
+ }
+ return conn, nil
+ }
+
+ timeout := time.Duration(opts.Timeout) * time.Second
+
+ // set up the dial info
+ self.dialInfo = &mgo.DialInfo{
+ Timeout: timeout,
+ Direct: opts.Direct,
+ ReplicaSetName: opts.ReplicaSetName,
+ DialServer: dialer,
+ Username: opts.Auth.Username,
+ Password: opts.Auth.Password,
+ Source: opts.GetAuthenticationDatabase(),
+ Mechanism: opts.Auth.Mechanism,
+ }
+
+ // create or fetch the addresses to be used to connect
+ if opts.URI != nil && opts.URI.ConnectionString != "" {
+ self.dialInfo.Addrs = opts.URI.GetConnectionAddrs()
+ } else {
+ self.dialInfo.Addrs = util.CreateConnectionAddrs(opts.Host, opts.Port)
+ }
+ kerberos.AddKerberosOpts(opts, self.dialInfo)
+ return nil
+
+}
+
+// Dial the server.
+func (self *SSLDBConnector) GetNewSession() (*mgo.Session, error) {
+ return mgo.DialWithInfo(self.dialInfo)
+}
+
+// To be handed to mgo.DialInfo for connecting to the server.
+type dialerFunc func(addr *mgo.ServerAddr) (net.Conn, error)
+
+// Handle optionally compiled SSL initialization functions (fips mode set)
+type sslInitializationFunction func(options.ToolOptions) error
+
+var sslInitializationFunctions []sslInitializationFunction
+
+// Creates and configures an openssl.Ctx
+func setupCtx(opts options.ToolOptions) (*openssl.Ctx, error) {
+ var ctx *openssl.Ctx
+ var err error
+
+ for _, sslInitFunc := range sslInitializationFunctions {
+ err = sslInitFunc(opts)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if ctx, err = openssl.NewCtxWithVersion(openssl.AnyVersion); err != nil {
+ return nil, fmt.Errorf("failure creating new openssl context with "+
+ "NewCtxWithVersion(AnyVersion): %v", err)
+ }
+
+ // OpAll - Activate all bug workaround options, to support buggy client SSL's.
+ // NoSSLv2 - Disable SSL v2 support
+ ctx.SetOptions(openssl.OpAll | openssl.NoSSLv2)
+
+ // HIGH - Enable strong ciphers
+ // !EXPORT - Disable export ciphers (40/56 bit)
+ // !aNULL - Disable anonymous auth ciphers
+ // @STRENGTH - Sort ciphers based on strength
+ ctx.SetCipherList("HIGH:!EXPORT:!aNULL@STRENGTH")
+
+ // add the PEM key file with the cert and private key, if specified
+ if opts.SSLPEMKeyFile != "" {
+ if err = ctx.UseCertificateChainFile(opts.SSLPEMKeyFile); err != nil {
+ return nil, fmt.Errorf("UseCertificateChainFile: %v", err)
+ }
+ if opts.SSLPEMKeyPassword != "" {
+ if err = ctx.UsePrivateKeyFileWithPassword(
+ opts.SSLPEMKeyFile, openssl.FiletypePEM, opts.SSLPEMKeyPassword); err != nil {
+ return nil, fmt.Errorf("UsePrivateKeyFile: %v", err)
+ }
+ } else {
+ if err = ctx.UsePrivateKeyFile(opts.SSLPEMKeyFile, openssl.FiletypePEM); err != nil {
+ return nil, fmt.Errorf("UsePrivateKeyFile: %v", err)
+ }
+ }
+ // Verify that the certificate and the key go together.
+ if err = ctx.CheckPrivateKey(); err != nil {
+ return nil, fmt.Errorf("CheckPrivateKey: %v", err)
+ }
+ }
+
+ // If renegotiation is needed, don't return from recv() or send() until it's successful.
+ // Note: this is for blocking sockets only.
+ ctx.SetMode(openssl.AutoRetry)
+
+ // Disable session caching (see SERVER-10261)
+ ctx.SetSessionCacheMode(openssl.SessionCacheOff)
+
+ if opts.SSLCAFile != "" {
+ calist, err := openssl.LoadClientCAFile(opts.SSLCAFile)
+ if err != nil {
+ return nil, fmt.Errorf("LoadClientCAFile: %v", err)
+ }
+ ctx.SetClientCAList(calist)
+ if err = ctx.LoadVerifyLocations(opts.SSLCAFile, ""); err != nil {
+ return nil, fmt.Errorf("LoadVerifyLocations: %v", err)
+ }
+ } else {
+ err = ctx.SetupSystemCA()
+ if err != nil {
+ return nil, fmt.Errorf("Error setting up system certificate authority: %v", err)
+ }
+ }
+
+ var verifyOption openssl.VerifyOptions
+ if opts.SSLAllowInvalidCert {
+ verifyOption = openssl.VerifyNone
+ } else {
+ verifyOption = openssl.VerifyPeer
+ }
+ ctx.SetVerify(verifyOption, nil)
+
+ if opts.SSLCRLFile != "" {
+ store := ctx.GetCertificateStore()
+ store.SetFlags(openssl.CRLCheck)
+ lookup, err := store.AddLookup(openssl.X509LookupFile())
+ if err != nil {
+ return nil, fmt.Errorf("AddLookup(X509LookupFile()): %v", err)
+ }
+ lookup.LoadCRLFile(opts.SSLCRLFile)
+ }
+
+ return ctx, nil
+}
diff --git a/src/mongo/gotools/common/lldb/openssl/openssl_fips.go b/src/mongo/gotools/common/lldb/openssl/openssl_fips.go
new file mode 100644
index 00000000000..68bf0a92d3d
--- /dev/null
+++ b/src/mongo/gotools/common/lldb/openssl/openssl_fips.go
@@ -0,0 +1,38 @@
+// Copyright (C) MongoDB, Inc. 2014-present.
+//
+// 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
+
+// +build ssl,!openssl_pre_1.0
+
+package openssl
+
+import (
+ "fmt"
+
+ "github.com/10gen/openssl"
+ "github.com/mongodb/mongo-tools/common/options"
+)
+
+func init() {
+ if openssl.FIPSModeDefined() {
+ sslInitializationFunctions = append(sslInitializationFunctions, SetUpFIPSMode)
+ } else {
+ sslInitializationFunctions = append(sslInitializationFunctions, NoFIPSModeAvailable)
+ }
+}
+
+func SetUpFIPSMode(opts options.ToolOptions) error {
+ if err := openssl.FIPSModeSet(opts.SSLFipsMode); err != nil {
+ return fmt.Errorf("couldn't set FIPS mode to %v: %v", opts.SSLFipsMode, err)
+ }
+ return nil
+}
+
+func NoFIPSModeAvailable(opts options.ToolOptions) error {
+ if opts.SSLFipsMode {
+ return fmt.Errorf("FIPS mode not supported")
+ }
+ return nil
+}
diff --git a/src/mongo/gotools/common/lldb/tlsgo/config.go b/src/mongo/gotools/common/lldb/tlsgo/config.go
new file mode 100644
index 00000000000..8d3971b537b
--- /dev/null
+++ b/src/mongo/gotools/common/lldb/tlsgo/config.go
@@ -0,0 +1,246 @@
+// Copyright (C) MongoDB, Inc. 2018-present.
+//
+// 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
+
+// This file contains code adapted from the MongoDB Go Driver.
+
+// Package tlsgo provides a mgo connection using Go's native TLS library.
+package tlsgo
+
+import (
+ "crypto/tls"
+ "crypto/x509"
+ "encoding/asn1"
+ "encoding/hex"
+ "encoding/pem"
+ "fmt"
+ "io/ioutil"
+ "strings"
+)
+
+// TLSConfig contains options for configuring an SSL connection to the server.
+type TLSConfig struct {
+ caCert *x509.Certificate
+ clientCert *tls.Certificate
+ insecure bool
+}
+
+// NewTLSConfig creates a new TLSConfig.
+func NewTLSConfig() *TLSConfig {
+ cfg := &TLSConfig{}
+
+ return cfg
+}
+
+// SetInsecure sets whether the client should verify the server's certificate chain and hostnames.
+func (c *TLSConfig) SetInsecure(allow bool) {
+ c.insecure = allow
+}
+
+// AddClientCertFromFile adds a client certificate to the configuration given a path to the
+// containing file and returns the certificate's subject name.
+func (c *TLSConfig) AddClientCertFromFile(clientFile, password string) (string, error) {
+ data, err := ioutil.ReadFile(clientFile)
+ if err != nil {
+ return "", err
+ }
+
+ certPEM, err := loadPEMBlock(data, "CERTIFICATE")
+ if err != nil {
+ return "", err
+ }
+
+ keyPEM, err := loadPEMBlock(data, "PRIVATE KEY")
+ if err != nil {
+ return "", err
+ }
+ // This check only covers encrypted PEM data with a DEK-Info header. It
+ // does not detect unencrypted PEM containing PKCS#8 format data with an
+ // encrypted private key.
+ if x509.IsEncryptedPEMBlock(keyPEM) {
+ if password == "" {
+ return "", fmt.Errorf("No password provided to decrypt private key")
+ }
+ decrypted, err := x509.DecryptPEMBlock(keyPEM, []byte(password))
+ if err != nil {
+ return "", err
+ }
+ keyPEM = &pem.Block{Bytes: decrypted, Type: keyPEM.Type}
+ }
+
+ if strings.Contains(keyPEM.Type, "ENCRYPTED") {
+ return "", fmt.Errorf("PKCS#8 encrypted private keys are not supported")
+ }
+
+ cert, err := tls.X509KeyPair(pem.EncodeToMemory(certPEM), pem.EncodeToMemory(keyPEM))
+ if err != nil {
+ return "", err
+ }
+
+ c.clientCert = &cert
+
+ // The documentation for the tls.X509KeyPair indicates that the Leaf
+ // certificate is not retained. Because there isn't any way of creating a
+ // tls.Certificate from an x509.Certificate short of calling X509KeyPair
+ // on the raw bytes, we're forced to parse the certificate over again to
+ // get the subject name.
+ crt, err := x509.ParseCertificate(certPEM.Bytes)
+ if err != nil {
+ return "", err
+ }
+
+ return x509CertSubject(crt), nil
+}
+
+// AddCaCertFromFile adds a root CA certificate to the configuration given a path to the containing file.
+func (c *TLSConfig) AddCaCertFromFile(caFile string) error {
+ data, err := ioutil.ReadFile(caFile)
+ if err != nil {
+ return err
+ }
+
+ certBytes, err := loadCertBytes(data)
+ if err != nil {
+ return err
+ }
+
+ cert, err := x509.ParseCertificate(certBytes)
+ if err != nil {
+ return err
+ }
+
+ c.caCert = cert
+
+ return nil
+}
+
+// MakeConfig constructs a new tls.Config from the configuration specified.
+func (c *TLSConfig) MakeConfig() (*tls.Config, error) {
+ cfg := &tls.Config{}
+
+ if c.clientCert != nil {
+ cfg.Certificates = []tls.Certificate{*c.clientCert}
+ }
+
+ if c.caCert == nil {
+ roots, err := loadSystemCAs()
+ if err != nil {
+ return nil, err
+ }
+ cfg.RootCAs = roots
+ } else {
+ cfg.RootCAs = x509.NewCertPool()
+ cfg.RootCAs.AddCert(c.caCert)
+ }
+
+ cfg.InsecureSkipVerify = c.insecure
+
+ return cfg, nil
+}
+
+func loadCertBytes(data []byte) ([]byte, error) {
+ b, err := loadPEMBlock(data, "CERTIFICATE")
+ if err != nil {
+ return nil, err
+ }
+ return b.Bytes, nil
+}
+
+func loadPEMBlock(data []byte, blocktype string) (*pem.Block, error) {
+ var b *pem.Block
+
+ for b == nil {
+ if data == nil || len(data) == 0 {
+ return nil, fmt.Errorf("no block of type %s found in .pem file", blocktype)
+ }
+
+ block, rest := pem.Decode(data)
+ if block == nil {
+ return nil, fmt.Errorf("invalid .pem file")
+ }
+
+ if strings.Contains(block.Type, blocktype) {
+ if b != nil {
+ return nil, fmt.Errorf("multiple %s sections in .pem file", blocktype)
+ }
+ b = block
+ }
+
+ data = rest
+ }
+
+ return b, nil
+}
+
+// Because the functionality to convert a pkix.Name to a string wasn't added until Go 1.10, we
+// need to copy the implementation (along with the attributeTypeNames map below).
+func x509CertSubject(cert *x509.Certificate) string {
+ r := cert.Subject.ToRDNSequence()
+
+ s := ""
+ for i := 0; i < len(r); i++ {
+ rdn := r[len(r)-1-i]
+ if i > 0 {
+ s += ","
+ }
+ for j, tv := range rdn {
+ if j > 0 {
+ s += "+"
+ }
+
+ oidString := tv.Type.String()
+ typeName, ok := attributeTypeNames[oidString]
+ if !ok {
+ derBytes, err := asn1.Marshal(tv.Value)
+ if err == nil {
+ s += oidString + "=#" + hex.EncodeToString(derBytes)
+ continue // No value escaping necessary.
+ }
+
+ typeName = oidString
+ }
+
+ valueString := fmt.Sprint(tv.Value)
+ escaped := make([]rune, 0, len(valueString))
+
+ for k, c := range valueString {
+ escape := false
+
+ switch c {
+ case ',', '+', '"', '\\', '<', '>', ';':
+ escape = true
+
+ case ' ':
+ escape = k == 0 || k == len(valueString)-1
+
+ case '#':
+ escape = k == 0
+ }
+
+ if escape {
+ escaped = append(escaped, '\\', c)
+ } else {
+ escaped = append(escaped, c)
+ }
+ }
+
+ s += typeName + "=" + string(escaped)
+ }
+ }
+
+ return s
+}
+
+var attributeTypeNames = map[string]string{
+ "2.5.4.6": "C",
+ "2.5.4.10": "O",
+ "2.5.4.11": "OU",
+ "2.5.4.3": "CN",
+ "2.5.4.5": "SERIALNUMBER",
+ "2.5.4.7": "L",
+ "2.5.4.8": "ST",
+ "2.5.4.9": "STREET",
+ "2.5.4.17": "POSTALCODE",
+}
diff --git a/src/mongo/gotools/common/lldb/tlsgo/rootcerts.go b/src/mongo/gotools/common/lldb/tlsgo/rootcerts.go
new file mode 100644
index 00000000000..ee3ec3769f1
--- /dev/null
+++ b/src/mongo/gotools/common/lldb/tlsgo/rootcerts.go
@@ -0,0 +1,22 @@
+// Copyright (C) MongoDB, Inc. 2018-present.
+//
+// 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
+//
+// Based on https://github.com/hashicorp/go-rootcerts by HashiCorp
+// See THIRD-PARTY-NOTICES for original license terms.
+
+// +build !darwin
+
+package tlsgo
+
+import (
+ "crypto/x509"
+)
+
+// Stubbed for non-darwin systems. By returning nil, the Go library
+// will use its own code for finding system certs.
+func loadSystemCAs() (*x509.CertPool, error) {
+ return nil, nil
+}
diff --git a/src/mongo/gotools/common/lldb/tlsgo/rootcerts_darwin.go b/src/mongo/gotools/common/lldb/tlsgo/rootcerts_darwin.go
new file mode 100644
index 00000000000..72c7a9116ad
--- /dev/null
+++ b/src/mongo/gotools/common/lldb/tlsgo/rootcerts_darwin.go
@@ -0,0 +1,58 @@
+// Copyright (C) MongoDB, Inc. 2018-present.
+//
+// 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
+//
+// Based on https://github.com/hashicorp/go-rootcerts by HashiCorp
+// See THIRD-PARTY-NOTICES for original license terms.
+
+package tlsgo
+
+import (
+ "crypto/x509"
+ "os/exec"
+ "os/user"
+ "path"
+)
+
+// loadSystemCAs has special behavior on Darwin systems to work around
+// bugs loading certs from keychains. See this GitHub issues query:
+// https://github.com/golang/go/issues?utf8=%E2%9C%93&q=is%3Aissue+darwin+keychain
+func loadSystemCAs() (*x509.CertPool, error) {
+ pool := x509.NewCertPool()
+
+ for _, keychain := range certKeychains() {
+ err := addCertsFromKeychain(pool, keychain)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return pool, nil
+}
+
+func addCertsFromKeychain(pool *x509.CertPool, keychain string) error {
+ cmd := exec.Command("/usr/bin/security", "find-certificate", "-a", "-p", keychain)
+ data, err := cmd.Output()
+ if err != nil {
+ return err
+ }
+
+ pool.AppendCertsFromPEM(data)
+
+ return nil
+}
+
+func certKeychains() []string {
+ keychains := []string{
+ "/System/Library/Keychains/SystemRootCertificates.keychain",
+ "/Library/Keychains/System.keychain",
+ }
+ user, err := user.Current()
+ if err == nil {
+ loginKeychain := path.Join(user.HomeDir, "Library", "Keychains", "login.keychain")
+ keychains = append(keychains, loginKeychain)
+ }
+ return keychains
+}
diff --git a/src/mongo/gotools/common/lldb/tlsgo/tlsgo.go b/src/mongo/gotools/common/lldb/tlsgo/tlsgo.go
new file mode 100644
index 00000000000..2b11e991ca1
--- /dev/null
+++ b/src/mongo/gotools/common/lldb/tlsgo/tlsgo.go
@@ -0,0 +1,135 @@
+// Copyright (C) MongoDB, Inc. 2014-present.
+//
+// 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
+
+// Package tlsgo implements connection to MongoDB with Go native TLS.
+package tlsgo
+
+import (
+ "crypto/tls"
+ "fmt"
+ "net"
+ "strings"
+ "time"
+
+ mgo "github.com/10gen/llmgo"
+ "github.com/mongodb/mongo-tools/common/lldb/kerberos"
+ "github.com/mongodb/mongo-tools/common/log"
+ "github.com/mongodb/mongo-tools/common/options"
+ "github.com/mongodb/mongo-tools/common/util"
+)
+
+// TLSDBConnector makes a connection to the database with Go native TLS.
+type TLSDBConnector struct {
+ dialInfo *mgo.DialInfo
+ config *TLSConfig
+}
+
+// Configure the connector to connect to the server over ssl. Sets up the
+// correct function to dial the server based on the ssl options passed in.
+func (c *TLSDBConnector) Configure(opts options.ToolOptions) error {
+ if opts.SSLFipsMode {
+ return fmt.Errorf("FIPS mode not supported")
+ }
+
+ if opts.SSLCRLFile != "" {
+ return fmt.Errorf("CRL files are not supported on this platform")
+ }
+
+ c.config = NewTLSConfig()
+
+ if opts.SSLAllowInvalidCert || opts.SSLAllowInvalidHost {
+ c.config.SetInsecure(true)
+ }
+
+ if opts.SSLPEMKeyFile != "" {
+ subject, err := c.config.AddClientCertFromFile(opts.SSLPEMKeyFile, opts.SSLPEMKeyPassword)
+ if err != nil {
+ return err
+ }
+ if opts.Auth.Mechanism == "MONGODB-X509" && opts.Auth.Username == "" {
+ opts.Auth.Username = subject
+ }
+ }
+
+ if opts.SSLCAFile != "" {
+ c.config.AddCaCertFromFile(opts.SSLCAFile)
+ }
+
+ // set up the dial info
+ c.dialInfo = &mgo.DialInfo{
+ Timeout: time.Duration(opts.Timeout) * time.Second,
+ Direct: opts.Direct,
+ ReplicaSetName: opts.ReplicaSetName,
+ DialServer: c.makeDialer(opts),
+ Username: opts.Auth.Username,
+ Password: opts.Auth.Password,
+ Source: opts.GetAuthenticationDatabase(),
+ Mechanism: opts.Auth.Mechanism,
+ }
+
+ // create or fetch the addresses to be used to connect
+ if opts.URI != nil && opts.URI.ConnectionString != "" {
+ c.dialInfo.Addrs = opts.URI.GetConnectionAddrs()
+ } else {
+ c.dialInfo.Addrs = util.CreateConnectionAddrs(opts.Host, opts.Port)
+ }
+ kerberos.AddKerberosOpts(opts, c.dialInfo)
+ return nil
+}
+
+// GetNewSession dials the server.
+func (c *TLSDBConnector) GetNewSession() (*mgo.Session, error) {
+ return mgo.DialWithInfo(c.dialInfo)
+}
+
+// To be handed to mgo.DialInfo for connecting to the server.
+type dialerFunc func(addr *mgo.ServerAddr) (net.Conn, error)
+
+func (c *TLSDBConnector) makeDialer(opts options.ToolOptions) dialerFunc {
+ return func(addr *mgo.ServerAddr) (net.Conn, error) {
+ address := addr.String()
+ conn, err := net.Dial("tcp", address)
+ if err != nil {
+ // mgo discards dialer errors so log it now
+ log.Logvf(log.Always, "error dialing %v: %v", address, err)
+ return nil, err
+ }
+ // enable TCP keepalive
+ err = util.EnableTCPKeepAlive(conn, time.Duration(opts.TCPKeepAliveSeconds)*time.Second)
+ if err != nil {
+ // mgo discards dialer errors so log it now
+ log.Logvf(log.Always, "error enabling TCP keepalive on connection to %v: %v", address, err)
+ conn.Close()
+ return nil, err
+ }
+
+ tlsConfig, err := c.config.MakeConfig()
+ if err != nil {
+ return nil, err
+ }
+
+ if !tlsConfig.InsecureSkipVerify {
+ colonPos := strings.LastIndex(address, ":")
+ if colonPos == -1 {
+ colonPos = len(address)
+ }
+
+ hostname := address[:colonPos]
+ tlsConfig.ServerName = hostname
+ }
+
+ client := tls.Client(conn, tlsConfig)
+ err = client.Handshake()
+ if err != nil {
+ // mgo discards dialer errors so log it now
+ log.Logvf(log.Always, "error doing TLS handshake with %v: %v", address, err)
+ client.Close()
+ return nil, err
+ }
+
+ return client, nil
+ }
+}
diff --git a/src/mongo/gotools/common/options/options_ssl.go b/src/mongo/gotools/common/options/options_ssl.go
index de11cf9686a..4220c6d909e 100644
--- a/src/mongo/gotools/common/options/options_ssl.go
+++ b/src/mongo/gotools/common/options/options_ssl.go
@@ -10,6 +10,7 @@ package options
func init() {
ConnectionOptFunctions = append(ConnectionOptFunctions, registerSSLOptions)
+ BuiltWithSSL = true
}
func registerSSLOptions(self *ToolOptions) error {
@@ -20,6 +21,5 @@ func registerSSLOptions(self *ToolOptions) error {
if self.enabledOptions.URI {
self.URI.AddKnownURIParameters(KnownURIOptionsSSL)
}
- BuiltWithSSL = true
return nil
}
diff --git a/src/mongo/gotools/import.data b/src/mongo/gotools/import.data
index be481764426..d59a8e57105 100644
--- a/src/mongo/gotools/import.data
+++ b/src/mongo/gotools/import.data
@@ -1,5 +1,5 @@
{
- "commit": "37adadadd5ffbbdf5e42e6dc3cd8f5107e47ea56",
+ "commit": "5f036603357e3d910e4d765369261fd0b577dd59",
"github": "mongodb/mongo-tools.git",
"vendor": "tools",
"branch": "v4.1"
diff --git a/src/mongo/gotools/mongoreplay/log_wrapper.go b/src/mongo/gotools/mongoreplay/log_wrapper.go
index 6c1e7cb6387..82e93071af7 100644
--- a/src/mongo/gotools/mongoreplay/log_wrapper.go
+++ b/src/mongo/gotools/mongoreplay/log_wrapper.go
@@ -69,3 +69,8 @@ func (lw *logWrapper) Logv(minVerb int, msg string) {
func (lw *logWrapper) isInVerbosity(minVerb int) bool {
return minVerb <= lw.verbosity
}
+
+func (lw *logWrapper) Output(calldepth int, s string) error {
+ lw.Logv(DebugHigh, s)
+ return nil
+}
diff --git a/src/mongo/gotools/mongoreplay/main/mongoreplay.go b/src/mongo/gotools/mongoreplay/main/mongoreplay.go
index 1fc09b1fa79..84df7204c01 100644
--- a/src/mongo/gotools/mongoreplay/main/mongoreplay.go
+++ b/src/mongo/gotools/mongoreplay/main/mongoreplay.go
@@ -8,6 +8,7 @@ package main
import (
"github.com/jessevdk/go-flags"
+ "github.com/mongodb/mongo-tools/common/options"
"github.com/mongodb/mongo-tools/mongoreplay"
"fmt"
@@ -44,11 +45,18 @@ func main() {
var parser = flags.NewParser(&opts, flags.Default)
- _, err = parser.AddCommand("play", "Play captured traffic against a mongodb instance", "",
- &mongoreplay.PlayCommand{GlobalOpts: &opts})
+ playCmd := &mongoreplay.PlayCommand{GlobalOpts: &opts}
+ playCmdParser, err := parser.AddCommand("play", "Play captured traffic against a mongodb instance", "", playCmd)
if err != nil {
panic(err)
}
+ if options.BuiltWithSSL {
+ playCmd.SSLOpts = &options.SSL{}
+ _, err := playCmdParser.AddGroup("ssl", "", playCmd.SSLOpts)
+ if err != nil {
+ panic(err)
+ }
+ }
_, err = parser.AddCommand("record", "Convert network traffic into mongodb queries", "",
&mongoreplay.RecordCommand{GlobalOpts: &opts})
diff --git a/src/mongo/gotools/mongoreplay/mongoreplay.go b/src/mongo/gotools/mongoreplay/mongoreplay.go
index 9379a967652..14373b3705f 100644
--- a/src/mongo/gotools/mongoreplay/mongoreplay.go
+++ b/src/mongo/gotools/mongoreplay/mongoreplay.go
@@ -6,6 +6,10 @@
package mongoreplay
+import (
+ mgo "github.com/10gen/llmgo"
+)
+
// Options stores settings for any mongoreplay command
type Options struct {
Verbosity []bool `short:"v" long:"verbosity" description:"increase the detail regarding the tools performance on the input file that is output to logs (include multiple times for increased logging verbosity, e.g. -vvv)"`
@@ -26,6 +30,10 @@ func (opts *Options) SetLogging() {
if d > 0 || v > 0 {
printVersionInfo()
}
+ if d == DebugHigh {
+ mgo.SetLogger(toolDebugLogger)
+ mgo.SetDebug(true)
+ }
}
type VersionOptions struct {
diff --git a/src/mongo/gotools/mongoreplay/mongoreplay_test.go b/src/mongo/gotools/mongoreplay/mongoreplay_test.go
index 693f23652c8..b43c768ad43 100644
--- a/src/mongo/gotools/mongoreplay/mongoreplay_test.go
+++ b/src/mongo/gotools/mongoreplay/mongoreplay_test.go
@@ -476,7 +476,7 @@ func comparePayloadType1(t *testing.T, p1, p2 interface{}) {
t.Errorf("Payload sizes not matched Saw: %d --- Expected: %d", p1AsPayload.Size, p2AsPayload.Size)
}
if p1AsPayload.Identifier != p2AsPayload.Identifier {
- t.Errorf("Payload identifiers not matched Saw: %d --- Expected: %d", p1AsPayload.Identifier, p2AsPayload.Identifier)
+ t.Errorf("Payload identifiers not matched Saw: %s --- Expected: %s", p1AsPayload.Identifier, p2AsPayload.Identifier)
}
}
diff --git a/src/mongo/gotools/mongoreplay/play.go b/src/mongo/gotools/mongoreplay/play.go
index b2a617c5db4..237127d38ed 100644
--- a/src/mongo/gotools/mongoreplay/play.go
+++ b/src/mongo/gotools/mongoreplay/play.go
@@ -9,24 +9,27 @@ package mongoreplay
import (
"fmt"
"io"
+ "strings"
"time"
- mgo "github.com/10gen/llmgo"
+ "github.com/mongodb/mongo-tools/common/lldb"
+ "github.com/mongodb/mongo-tools/common/options"
)
// PlayCommand stores settings for the mongoreplay 'play' subcommand
type PlayCommand struct {
GlobalOpts *Options `no-flag:"true"`
StatOptions
- PlaybackFile string `description:"path to the playback file to play from" short:"p" long:"playback-file" required:"yes"`
- Speed float64 `description:"multiplier for playback speed (1.0 = real-time, .5 = half-speed, 3.0 = triple-speed, etc.)" long:"speed" default:"1.0"`
- URL string `short:"h" long:"host" env:"MONGOREPLAY_HOST" description:"Location of the host to play back against" default:"mongodb://localhost:27017"`
- Repeat int `long:"repeat" description:"Number of times to play the playback file" default:"1"`
- QueueTime int `long:"queueTime" description:"don't queue ops much further in the future than this number of seconds" default:"15"`
- NoPreprocess bool `long:"no-preprocess" description:"don't preprocess the input file to premap data such as mongo cursorIDs"`
- Gzip bool `long:"gzip" description:"decompress gzipped input"`
- Collect string `long:"collect" description:"Stat collection format; 'format' option uses the --format string" choice:"json" choice:"format" choice:"none" default:"none"`
- FullSpeed bool `long:"fullSpeed" description:"run the playback as fast as possible"`
+ PlaybackFile string `description:"path to the playback file to play from" short:"p" long:"playback-file" required:"yes"`
+ Speed float64 `description:"multiplier for playback speed (1.0 = real-time, .5 = half-speed, 3.0 = triple-speed, etc.)" long:"speed" default:"1.0"`
+ URL string `short:"h" long:"host" env:"MONGOREPLAY_HOST" description:"Location of the host to play back against" default:"mongodb://localhost:27017"`
+ Repeat int `long:"repeat" description:"Number of times to play the playback file" default:"1"`
+ QueueTime int `long:"queueTime" description:"don't queue ops much further in the future than this number of seconds" default:"15"`
+ NoPreprocess bool `long:"no-preprocess" description:"don't preprocess the input file to premap data such as mongo cursorIDs"`
+ Gzip bool `long:"gzip" description:"decompress gzipped input"`
+ Collect string `long:"collect" description:"Stat collection format; 'format' option uses the --format string" choice:"json" choice:"format" choice:"none" default:"none"`
+ FullSpeed bool `long:"fullSpeed" description:"run the playback as fast as possible"`
+ SSLOpts *options.SSL `no-flag:"true"`
}
const queueGranularity = 1000
@@ -68,7 +71,28 @@ func (play *PlayCommand) Execute(args []string) error {
return err
}
- session, err := mgo.Dial(play.URL)
+ // Reparse given host via ToolOptions so we can use a SessionProvider
+ // for the llmgo session.
+ toolOpts := options.New("", "", options.EnabledOptions{Connection: true, URI: true, Auth: true})
+ // SSL options must be non-nil before parsing to enable parsing ssl;
+ // play.SSLopts will be nil if SSL is not enabled
+ toolOpts.SSL = play.SSLOpts
+ if !(strings.HasPrefix(play.URL, "mongodb://") || strings.HasPrefix(play.URL, "mongodb+srv://")) {
+ play.URL = fmt.Sprintf("mongodb://%s", play.URL)
+ }
+ _, err = toolOpts.ParseArgs([]string{"--uri", play.URL})
+
+ if err != nil {
+ return err
+ }
+
+ sp, err := lldb.NewSessionProvider(*toolOpts)
+ if err != nil {
+ return err
+ }
+
+ userInfoLogger.Logv(DebugLow, "Initializing a session")
+ session, err := sp.GetSession()
if err != nil {
return err
}
diff --git a/src/mongo/gotools/mongoreplay/stat_format.go b/src/mongo/gotools/mongoreplay/stat_format.go
index 8360b6aece2..25125e8ea88 100644
--- a/src/mongo/gotools/mongoreplay/stat_format.go
+++ b/src/mongo/gotools/mongoreplay/stat_format.go
@@ -34,10 +34,10 @@ type OpStat struct {
Ns string `json:"ns,omitempty"`
// Data represents the payload of the request operation.
- RequestData interface{} `json:"request_data, omitempty"`
+ RequestData interface{} `json:"request_data,omitempty"`
// Data represents the payload of the reply operation.
- ReplyData interface{} `json:"reply_data, omitempty"`
+ ReplyData interface{} `json:"reply_data,omitempty"`
// NumReturned is the number of documents that were fetched as a result of this operation.
NumReturned int `json:"nreturned,omitempty"`
@@ -77,7 +77,7 @@ type OpStat struct {
// RequestID is the ID of the mongodb operation as taken from the header.
// The RequestID for a request operation is the same as the ResponseID for
// the corresponding reply, so this field will be the same for request/reply pairs.
- RequestID int32 `json:"request_id, omitempty"`
+ RequestID int32 `json:"request_id,omitempty"`
}
// jsonGet retrieves serialized json req/res via the channel-like arg;
diff --git a/src/mongo/gotools/vendor/src/github.com/10gen/llmgo/auth.go b/src/mongo/gotools/vendor/src/github.com/10gen/llmgo/auth.go
index 880ba1aa358..70ac345677d 100644
--- a/src/mongo/gotools/vendor/src/github.com/10gen/llmgo/auth.go
+++ b/src/mongo/gotools/vendor/src/github.com/10gen/llmgo/auth.go
@@ -188,12 +188,12 @@ func (socket *MongoSocket) loginClassic(cred Credential) error {
// Note that this only works properly because this function is
// synchronous, which means the nonce won't get reset while we're
// using it and any other login requests will block waiting for a
- // new nonce provided in the defer call below.
+ // new nonce.
+ socket.resetNonce();
nonce, err := socket.getNonce()
if err != nil {
return err
}
- defer socket.resetNonce()
psum := md5.New()
psum.Write([]byte(cred.Username + ":mongo:" + cred.Password))
diff --git a/src/mongo/gotools/vendor/src/github.com/10gen/llmgo/session.go b/src/mongo/gotools/vendor/src/github.com/10gen/llmgo/session.go
index 636059031c3..b1b82f04510 100644
--- a/src/mongo/gotools/vendor/src/github.com/10gen/llmgo/session.go
+++ b/src/mongo/gotools/vendor/src/github.com/10gen/llmgo/session.go
@@ -4225,7 +4225,7 @@ func (s *Session) AcquireSocketPrivate(slaveOk bool) (*MongoSocket, error) {
}
func (s *Session) AcquireSocketDirect() (*MongoSocket, error) {
- sock, err := s.cluster().AcquireSocket(Strong, true, s.syncTimeout, s.sockTimeout, s.queryConfig.op.ServerTags, s.poolLimit)
+ sock, err := s.cluster().AcquireSocket(Strong, false, s.syncTimeout, s.sockTimeout, s.queryConfig.op.ServerTags, s.poolLimit)
if err != nil {
return nil, err
}
diff --git a/src/mongo/gotools/vendor/src/github.com/10gen/llmgo/socket.go b/src/mongo/gotools/vendor/src/github.com/10gen/llmgo/socket.go
index 0e8980ba199..87e546cc8ec 100644
--- a/src/mongo/gotools/vendor/src/github.com/10gen/llmgo/socket.go
+++ b/src/mongo/gotools/vendor/src/github.com/10gen/llmgo/socket.go
@@ -322,7 +322,6 @@ func NewSocket(server *MongoServer, conn net.Conn, timeout time.Duration) *Mongo
}
stats.socketsAlive(+1)
debugf("Socket %p to %s: initialized", socket, socket.addr)
- socket.resetNonce()
go socket.readLoop()
return socket
}