Skip to content

Commit

Permalink
fix(deps): build kerberos in RTLD mode for Linux executables MONGOSH-…
Browse files Browse the repository at this point in the history
…1628 (#1751)

- Update the Kerberos addon to the latest version (2.1.0).
- Build the Kerberos addon using RTLD for Linux mongosh executables
  (i.e. opening the system Kerberos libraries using `dlopen()` to avoid
  the symbol conflict with OpenSSL 3 on RHEL8).
- Update the `.deb` definitions to account for the fact that the
  Kerberos system libraries are no longer a strict dependency
  of mongosh.
- Include the Kerberos version in the `--build-info` output.
- Make sure that if loading the Kerberos addon fails during a
  connection attempt, a meaningful error message gets passed
  to the user, instead of the driver’s default one (which
  swallows all information about the root cause).
- As a drive-by, also do that for mongodb-client-encryption; we
  occasionally receive bug reports about CSFLE/QE not working on
  homebrew installations, and this may help with that.
  • Loading branch information
addaleax authored Nov 27, 2023
1 parent 1cdf775 commit 2bff26f
Show file tree
Hide file tree
Showing 24 changed files with 697 additions and 61 deletions.
426 changes: 424 additions & 2 deletions .evergreen.yml

Large diffs are not rendered by default.

107 changes: 90 additions & 17 deletions .evergreen/evergreen.yml.in
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@ functions:
shell: bash
env:
NODE_JS_VERSION: ${node_js_version}
TEST_MONGOSH_EXECUTABLE: ${test_mongosh_executable|}
KERBEROS_JUMPHOST_DOCKERFILE: ${kerberos_jumphost_dockerfile|}
script: |
set -e
{
Expand Down Expand Up @@ -416,6 +418,13 @@ functions:
local_file: src/dist.tgz
remote_file: mongosh/binaries/${revision}/${revision_order_id}/mongosh-${executable_os_id}${extra_upload_tag}.tgz
bucket: mciuploads
- command: shell.exec
params:
working_dir: src
shell: bash
script: |
set -e
tar xvzf dist.tgz

###
# E2E TEST EXECUTION
Expand Down Expand Up @@ -998,6 +1007,35 @@ tasks:
disable_openssl_shared_config_for_bundled_openssl: ${disable_openssl_shared_config_for_bundled_openssl|false}
<% } } } %>

###
# EXECUTABLE CONNECTIVITY TESTS
###
<% const executableConnectivityTests = [];
for (const { executableOsId, compileBuildVariant, kerberosConnectivityTestDockerfiles = [] } of RELEASE_PACKAGE_MATRIX) {
for (const dockerFile of kerberosConnectivityTestDockerfiles) {
const taskName = `executable_connectivity_test_${executableOsId.replace(/-/g, '_')}_${dockerFile.replace(/-/g, '_')}`;
executableConnectivityTests.push({ executableOsId, taskName });
%>
- name: <% out(taskName) %>
tags: ["connectivity-test"]
depends_on:
- name: compile_artifact
variant: <% out(compileBuildVariant) %>
commands:
- func: checkout
- func: install
vars:
node_js_version: "<% out(NODE_JS_VERSION_20) %>"
- func: download_compiled_artifact
vars:
executable_os_id: <% out(executableOsId) %>
- func: test_connectivity
vars:
node_js_version: "<% out(NODE_JS_VERSION_20) %>"
test_mongosh_executable: dist/mongosh
kerberos_jumphost_dockerfile: "Dockerfile.<% out(dockerFile) %>"
<% } } %>

###
# PACKAGING
###
Expand All @@ -1022,10 +1060,14 @@ tasks:
###
# SMOKE TESTS
###
<% for (const { packages } of RELEASE_PACKAGE_MATRIX) {
<%
const packageSmokeTestTasks = [];
for (const { packages, executableOsId } of RELEASE_PACKAGE_MATRIX) {
for (const { name, packageOn, smokeTestKind, smokeTestDockerfiles } of packages) if (smokeTestKind !== 'none') {
for (const dockerfile of smokeTestDockerfiles || ['']) { %>
- name: pkg_test_<% out(`${smokeTestKind}_${name}${dockerfile ? `_${dockerfile}` : ''}`.replace(/[-.]/g, '_')) %>
for (const dockerfile of smokeTestDockerfiles || ['']) {
const taskName = `pkg_test_${smokeTestKind}_${name}${dockerfile ? `_${dockerfile}` : ''}`.replace(/[-.]/g, '_');
packageSmokeTestTasks.push({taskName, executableOsId}); %>
- name: <% out(taskName) %>
tags: ["smoke-test"]
depends_on:
- name: package_and_upload_artifact_<% out(name.replace(/-/g, '_')) %>
Expand Down Expand Up @@ -1080,6 +1122,8 @@ tasks:
variant: "*"
- name: ".e2e-test"
variant: "*"
- name: ".connectivity-test"
variant: "*"
- name: check
variant: "*"
- name: ".unit-test"
Expand Down Expand Up @@ -1435,25 +1479,54 @@ buildvariants:
- name: compile_artifact

- name: pkg_smoke_tests_docker_x64
display_name: "package smoke tests (x64 Docker)"
display_name: "package smoke (x64 Docker)"
run_on: ubuntu2004-small
tasks:
<% for (const { packages, executableOsId } of RELEASE_PACKAGE_MATRIX) {
if (executableOsId.includes('linux-x64')) {
for (const { name, smokeTestKind, smokeTestDockerfiles } of packages) if (smokeTestKind !== 'none') {
for (const dockerfile of smokeTestDockerfiles || []) { %>
- name: pkg_test_<% out(`${smokeTestKind}_${name}${dockerfile ? `_${dockerfile}` : ''}`.replace(/[-.]/g, '_')) %>
<% } } } } %>
<% for (const { taskName, executableOsId } of packageSmokeTestTasks) {
if (executableOsId.includes('linux-x64')) { %>
- name: <% out(taskName) %>
<% } } %>
- name: pkg_smoke_tests_docker_arm64
display_name: "package smoke tests (arm64 Docker)"
display_name: "package smoke (arm64 Docker)"
run_on: ubuntu2004-arm64-small
tasks:
<% for (const { packages, executableOsId } of RELEASE_PACKAGE_MATRIX) {
if (executableOsId.includes('linux-arm64')) {
for (const { name, smokeTestKind, smokeTestDockerfiles } of packages) if (smokeTestKind !== 'none') {
for (const dockerfile of smokeTestDockerfiles || []) { %>
- name: pkg_test_<% out(`${smokeTestKind}_${name}${dockerfile ? `_${dockerfile}` : ''}`.replace(/[-.]/g, '_')) %>
<% } } } } %>
<% for (const { taskName, executableOsId } of packageSmokeTestTasks) {
if (executableOsId.includes('linux-arm64')) { %>
- name: <% out(taskName) %>
<% } } %>
- name: exec_connectitivty_tests_docker_x64_openssl11
display_name: "executable connectivity tests (x64 Docker for OpenSSL 1.1 base OS)"
run_on: ubuntu2004-small
tasks:
<% for (const { taskName, executableOsId } of executableConnectivityTests) {
if (executableOsId.includes('linux-x64') && !taskName.includes('openssl3')) { %>
- name: <% out(taskName) %>
<% } } %>
- name: exec_connectitivty_tests_docker_arm64_openssl11
display_name: "executable connectivity tests (arm64 Docker for OpenSSL 1.1 base OS)"
run_on: ubuntu2004-arm64-small
tasks:
<% for (const { taskName, executableOsId } of executableConnectivityTests) {
if (executableOsId.includes('linux-arm64') && !taskName.includes('openssl3')) { %>
- name: <% out(taskName) %>
<% } } %>
- name: exec_connectitivty_tests_docker_x64_openssl3
display_name: "executable connectivity tests (x64 Docker for OpenSSL 3 base OS)"
run_on: ubuntu2204-small
tasks:
<% for (const { taskName, executableOsId } of executableConnectivityTests) {
if (executableOsId.includes('linux-x64') && !taskName.includes('openssl11')) { %>
- name: <% out(taskName) %>
<% } } %>
# TODO: Re-enable after docker-compose is available on an arm64 distro
#- name: exec_connectitivty_tests_docker_arm64_openssl3
# display_name: "executable connectivity tests (arm64 Docker for OpenSSL 3 base OS)"
# run_on: ubuntu2204-arm64-small
# tasks:
<% for (const { taskName, executableOsId } of executableConnectivityTests) {
if (executableOsId.includes('linux-arm64') && !taskName.includes('openssl11')) { %>
# - name: <% out(taskName) %>
<% } } %>
- name: pkg_smoke_tests_win32
display_name: "package smoke tests (win32)"
run_on: ubuntu2004-small
Expand Down
1 change: 0 additions & 1 deletion .evergreen/run-e2e-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ if [[ "$DISABLE_OPENSSL_SHARED_CONFIG_FOR_BUNDLED_OPENSSL" == "true" ]] && [[ !
fi

source .evergreen/setup-env.sh
tar xvzf dist.tgz
dist/mongosh --version

export MONGOSH_TEST_EXECUTABLE_PATH="$(pwd)/dist/mongosh"
Expand Down
3 changes: 2 additions & 1 deletion config/build.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,11 @@ module.exports = {
[]
)
],
debDepends: 'libc6 (>= 2.17), libgssapi-krb5-2' + (
debDepends: 'libc6 (>= 2.17)' + (
SHARED_OPENSSL_TAG === 'openssl11' ? ', libssl1.1' :
SHARED_OPENSSL_TAG === 'openssl3' ? ', libssl3' : ''
),
debRecommends: 'libgssapi-krb5-2',
fullName: 'MongoDB Shell',
version: CLI_REPL_PACKAGE_JSON.version,
description: CLI_REPL_PACKAGE_JSON.description,
Expand Down
1 change: 1 addition & 0 deletions config/release-package-matrix.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export interface ExecutablePackageInformation {
executableOsId: string;
compileBuildVariant: string;
kerberosConnectivityTestDockerfiles?: string[];
packages: PackageInformation[];
}

Expand Down
9 changes: 9 additions & 0 deletions config/release-package-matrix.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ const publicDescriptions = {
win32_x64: 'Windows x64 (10+)'
};

const krbConnTestsOpenSSL11 = ['rocky8', 'ubuntu2004'];
const krbConnTestsOpenSSL3 = ['node20', 'rocky9', 'ubuntu2204'];

exports.RELEASE_PACKAGE_MATRIX = [
{
executableOsId: 'darwin-x64',
Expand All @@ -42,6 +45,7 @@ exports.RELEASE_PACKAGE_MATRIX = [
{
executableOsId: 'linux-x64',
compileBuildVariant: 'linux_x64_build',
kerberosConnectivityTestDockerfiles: [...krbConnTestsOpenSSL11, ...krbConnTestsOpenSSL3],
packages: [
{ name: 'linux-x64', description: publicDescriptions.linux_x64, packageType: 'tgz', packageOn: 'linux_package', smokeTestKind: 'docker', smokeTestDockerfiles: ['ubuntu20.04-tgz'], serverLikeTargetList: [...allLinux] },
{ name: 'deb-x64', description: publicDescriptions.debian_x64, packageType: 'deb', packageOn: 'linux_package', smokeTestKind: 'docker', smokeTestDockerfiles: ['ubuntu18.04-deb', 'ubuntu20.04-deb', 'ubuntu22.04-deb', 'ubuntu22.04-nohome-deb', 'debian10-deb', 'debian11-deb', 'debian12-deb'], serverLikeTargetList: [...ubuntu1804AndAboveAndDebBased] },
Expand All @@ -51,6 +55,7 @@ exports.RELEASE_PACKAGE_MATRIX = [
{
executableOsId: 'linux-x64-openssl11',
compileBuildVariant: 'linux_x64_build_openssl11',
kerberosConnectivityTestDockerfiles: [...krbConnTestsOpenSSL11],
packages: [
{ name: 'linux-x64-openssl11', description: publicDescriptions.linux_x64, packageType: 'tgz with shared OpenSSL 1.1', packageOn: 'linux_package', smokeTestKind: 'none', serverLikeTargetList: [...allLinux] },
{ name: 'deb-x64-openssl11', description: publicDescriptions.debian_x64, packageType: 'deb with shared OpenSSL 1.1', packageOn: 'linux_package', smokeTestKind: 'docker', smokeTestDockerfiles: ['ubuntu20.04-deb', 'debian10-deb', 'debian11-deb'], serverLikeTargetList: [...ubuntu1804AndAboveAndDebBased] },
Expand All @@ -60,6 +65,7 @@ exports.RELEASE_PACKAGE_MATRIX = [
{
executableOsId: 'linux-x64-openssl3',
compileBuildVariant: 'linux_x64_build_openssl3',
kerberosConnectivityTestDockerfiles: [...krbConnTestsOpenSSL3],
packages: [
{ name: 'linux-x64-openssl3', description: publicDescriptions.linux_x64, packageType: 'tgz with shared OpenSSL 3', packageOn: 'linux_package', smokeTestKind: 'none', serverLikeTargetList: [...allLinux] },
{ name: 'deb-x64-openssl3', description: publicDescriptions.debian_x64, packageType: 'deb with shared OpenSSL 1.1', packageOn: 'linux_package', smokeTestKind: 'docker', smokeTestDockerfiles: ['ubuntu22.04-deb', 'ubuntu22.04-fips-deb', 'debian12-deb'], serverLikeTargetList: [...ubuntu1804AndAboveAndDebBased] },
Expand All @@ -69,6 +75,7 @@ exports.RELEASE_PACKAGE_MATRIX = [
{
executableOsId: 'linux-arm64',
compileBuildVariant: 'linux_arm64_build',
kerberosConnectivityTestDockerfiles: [...krbConnTestsOpenSSL11, ...krbConnTestsOpenSSL3],
packages: [
{ name: 'linux-arm64', description: publicDescriptions.linux_arm64, packageType: 'tgz', packageOn: 'linux_package', smokeTestKind: 'docker', smokeTestDockerfiles: ['ubuntu20.04-tgz'], serverLikeTargetList: [...al2AndAbove] },
{ name: 'deb-arm64', description: publicDescriptions.debian_arm64, packageType: 'deb', packageOn: 'linux_package', smokeTestKind: 'docker', smokeTestDockerfiles: ['ubuntu18.04-deb', 'ubuntu20.04-deb', 'ubuntu22.04-deb', 'debian10-deb', 'debian11-deb', 'debian12-deb'], serverLikeTargetList: [...ubuntu1804AndAboveAndDebBased] },
Expand All @@ -78,6 +85,7 @@ exports.RELEASE_PACKAGE_MATRIX = [
{
executableOsId: 'linux-arm64-openssl11',
compileBuildVariant: 'linux_arm64_build_openssl11',
kerberosConnectivityTestDockerfiles: [...krbConnTestsOpenSSL11],
packages: [
{ name: 'linux-arm64-openssl11', description: publicDescriptions.linux_arm64, packageType: 'tgz with shared OpenSSL 1.1', packageOn: 'linux_package', smokeTestKind: 'none', serverLikeTargetList: [...al2AndAbove] },
{ name: 'deb-arm64-openssl11', description: publicDescriptions.debian_arm64, packageType: 'deb with shared OpenSSL 1.1', packageOn: 'linux_package', smokeTestKind: 'docker', smokeTestDockerfiles: ['ubuntu20.04-deb', 'debian10-deb', 'debian11-deb'], serverLikeTargetList: [...ubuntu1804AndAboveAndDebBased] },
Expand All @@ -87,6 +95,7 @@ exports.RELEASE_PACKAGE_MATRIX = [
{
executableOsId: 'linux-arm64-openssl3',
compileBuildVariant: 'linux_arm64_build_openssl3',
kerberosConnectivityTestDockerfiles: [...krbConnTestsOpenSSL3],
packages: [
{ name: 'linux-arm64-openssl3', description: publicDescriptions.linux_arm64, packageType: 'tgz with shared OpenSSL 3', packageOn: 'linux_package', smokeTestKind: 'none', serverLikeTargetList: [...al2AndAbove] },
{ name: 'deb-arm64-openssl3', description: publicDescriptions.debian_arm64, packageType: 'deb with shared OpenSSL 3', packageOn: 'linux_package', smokeTestKind: 'docker', smokeTestDockerfiles: ['ubuntu22.04-deb', 'ubuntu22.04-fips-deb', 'debian12-deb'], serverLikeTargetList: [...ubuntu1804AndAboveAndDebBased] },
Expand Down
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions packages/build/src/compile/signable-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ export class SignableCompiler {
// Custom env vars for sccache:
AWS_ACCESS_KEY_ID: process.env.DEVTOOLS_CI_AWS_KEY,
AWS_SECRET_ACCESS_KEY: process.env.DEVTOOLS_CI_AWS_SECRET,
// https://jira.mongodb.org/browse/MONGOSH-1628
...(process.platform === 'linux' && {
GYP_DEFINES: 'kerberos_use_rtld=true',
}),
},
addons: [fleAddon, osDnsAddon, kerberosAddon, cryptLibraryVersionAddon]
.concat(winCAAddon ? [winCAAddon] : [])
Expand Down
8 changes: 7 additions & 1 deletion packages/connectivity-tests/test/all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@ mkdir -p "$TEST_TMPDIR"
cd "$TEST_TMPDIR"
export TEST_TMPDIR="$PWD"

if [[ -z "$TEST_MONGOSH_EXECUTABLE" ]]; then
export MONGOSH=mongosh
else
export MONGOSH="${MONGOSH_ROOT_DIR}/${TEST_MONGOSH_EXECUTABLE}"
fi

git clone [email protected]:mongodb-js/devtools-docker-test-envs.git test-envs
cd test-envs

git checkout f029f9e3a9cc006a6aeb60d941b4f8d87ae4bc95
git checkout ca4bacd23e6f7ea07618c303b20556e3e4c9c2e6

"$CONNECTIVITY_TEST_SOURCE_DIR/ldap.sh"
"$CONNECTIVITY_TEST_SOURCE_DIR/localhost.sh"
Expand Down
16 changes: 8 additions & 8 deletions packages/connectivity-tests/test/atlas.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function test_connection_string() {

CONNECTION_STRING="mongodb+srv://${ATLAS_USERNAME}:${ATLAS_PASSWORD}@${ATLAS_HOSTNAME}/admin"

echo "${CONNECTION_STATUS_COMMAND}" | mongosh "${CONNECTION_STRING}" |
echo "${CONNECTION_STATUS_COMMAND}" | "${MONGOSH}" "${CONNECTION_STRING}" |
grep -Fq "${CONNECTION_STATUS_CHECK_STRING}" ||
FAILED="Can't connect to Atlas using connection string with username and password"

Expand All @@ -69,7 +69,7 @@ function test_atlas_in_logs() {
printf "test_atlas_in_logs ... "

CONNECTION_STRING="mongodb+srv://${ATLAS_USERNAME}:${ATLAS_PASSWORD}@${ATLAS_HOSTNAME}/admin"
LOG_ID=$(echo "exit" | mongosh "${CONNECTION_STRING}" | sed -n -e 's/Current Mongosh Log ID:\t//p')
LOG_ID=$(echo "exit" | "${MONGOSH}" "${CONNECTION_STRING}" | sed -n -e 's/Current Mongosh Log ID:\t//p')
LOG_PATH="${HOME}/.mongodb/mongosh/${LOG_ID}_log"

cat "${LOG_PATH}" | grep -Fq '"is_atlas":true' ||
Expand All @@ -84,7 +84,7 @@ function test_credentials_masking() {
CONNECTION_STRING="mongodb+srv://${ATLAS_USERNAME}:${ATLAS_PASSWORD}@${ATLAS_HOSTNAME}/admin"
MASKED_CREDENTIALS_STRING="mongodb+srv://<credentials>@${ATLAS_HOSTNAME}/admin"

echo "${CONNECTION_STATUS_COMMAND}" | mongosh "${CONNECTION_STRING}" |
echo "${CONNECTION_STATUS_COMMAND}" | "${MONGOSH}" "${CONNECTION_STRING}" |
grep -Fq "${MASKED_CREDENTIALS_STRING}" ||
FAILED="When connecting, credentials are not masked in the connection string"

Expand All @@ -97,7 +97,7 @@ function test_cli_args() {
CONNECTION_STRING="mongodb+srv://${ATLAS_HOSTNAME}/admin"

echo "${CONNECTION_STATUS_COMMAND}" |
mongosh "${CONNECTION_STRING}" --username "${ATLAS_USERNAME}" --password "${ATLAS_PASSWORD}" |
"${MONGOSH}" "${CONNECTION_STRING}" --username "${ATLAS_USERNAME}" --password "${ATLAS_PASSWORD}" |
grep -Fq "${CONNECTION_STATUS_CHECK_STRING}" ||
FAILED="Can't connect to Atlas using connection string and username and password arguments"

Expand All @@ -110,7 +110,7 @@ function test_password_prompt() {
CONNECTION_STRING="mongodb+srv://${ATLAS_HOSTNAME}/admin"

echo -e "${ATLAS_PASSWORD}\n${CONNECTION_STATUS_COMMAND}" |
mongosh "${CONNECTION_STRING}" --username "${ATLAS_USERNAME}" |
"${MONGOSH}" "${CONNECTION_STRING}" --username "${ATLAS_USERNAME}" |
grep -Fq "${CONNECTION_STATUS_CHECK_STRING}" ||
FAILED="Can't connect to Atlas using password prompt"

Expand All @@ -123,7 +123,7 @@ function test_data_lake() {
CONNECTION_STRING="mongodb://${ATLAS_DATA_LAKE_HOSTNAME}/admin"

echo "${CONNECTION_STATUS_COMMAND}" |
mongosh "${CONNECTION_STRING}" \
"${MONGOSH}" "${CONNECTION_STRING}" \
--tls \
--authenticationDatabase admin \
--username "${ATLAS_USERNAME}" \
Expand All @@ -140,7 +140,7 @@ function test_serverless() {
CONNECTION_STRING="mongodb+srv://${ATLAS_SERVERLESS_HOSTNAME}/admin"

echo "${CONNECTION_STATUS_COMMAND}" |
mongosh "${CONNECTION_STRING}" \
"${MONGOSH}" "${CONNECTION_STRING}" \
--username "${ATLAS_USERNAME}" \
--password "${ATLAS_PASSWORD}" |
grep -Fq "${CONNECTION_STATUS_CHECK_STRING}" ||
Expand All @@ -154,7 +154,7 @@ function test_srv_without_nodejs_dns() {

CONNECTION_STRING="mongodb+srv://${ATLAS_USERNAME}:${ATLAS_PASSWORD}@${ATLAS_HOSTNAME}/admin"

echo "${CONNECTION_STATUS_COMMAND}" | NODE_OPTIONS="-r ${MONGOSH_ROOT_DIR}/testing/disable-dns-srv.js" mongosh "${CONNECTION_STRING}" |
echo "${CONNECTION_STATUS_COMMAND}" | NODE_OPTIONS="-r ${MONGOSH_ROOT_DIR}/testing/disable-dns-srv.js" "${MONGOSH}" "${CONNECTION_STRING}" |
grep -Fq "${CONNECTION_STATUS_CHECK_STRING}" ||
FAILED="Can't connect to Atlas using connection string without Node.js SRV/TXT DNS support"

Expand Down
Loading

0 comments on commit 2bff26f

Please sign in to comment.