Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 227 additions & 0 deletions cpp/src/arrow/flight/sql/odbc/install/linux/BUILDING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
# Apache Arrow Flight SQL ODBC 25.0.1: Linux build and install

This runbook builds the Apache Arrow Flight SQL ODBC driver from Arrow commit
`beccec0d0c451b7aa3e4530416ac431b3c035c69` and produces an x86_64 Linux shared
library plus a relocatable tar archive. It never puts a Dremio credential in a
source file, command-line argument, shell history, log, or artifact.

## Tested target

- Target ABI: Linux x86_64 (`ELF 64-bit LSB shared object, x86-64`).
- Distribution: Ubuntu 24.04 LTS.
- Toolchain: GCC/G++ 13.3.0, CMake 3.28.3, Ninja 1.11.1, glibc 2.39, and
unixODBC 2.3.12.
- Build mode: Release, shared Arrow Flight SQL ODBC driver with Arrow, Flight,
Flight SQL, gRPC, and Protobuf linked statically. libcurl, libodbcinst, the C++
runtime, and the standard system libraries remain dynamic.

The repository's `.github/workflows/cpp_extra.yml` defines its `odbc-linux` CI
job as `amd64` on Ubuntu 24.04. The corresponding `ubuntu-cpp-odbc` service in
`compose.yaml` uses bundled dependencies and disables shared dependency linkage.
That is the repository-defined CI target used here.

The recorded validation used an amd64 Ubuntu container executed through Rosetta
inside an aarch64 Colima Linux VM on Apple Silicon. The compiler, linker,
unixODBC driver manager, driver, smoke-test process, and userspace were all
x86_64. This is an x86_64 ABI validation, but it is not a bare-metal x86_64
performance test.

## Prerequisites

On a native Ubuntu 24.04 x86_64 host, install Git, Docker Engine with Compose,
and CA certificates. Allow roughly 12 GiB RAM and 30 GiB free disk space because
the Unix driver build compiles bundled static dependencies.

On Apple Silicon, a disposable Colima VM can provide amd64 container execution:

```bash
brew install colima docker docker-compose
colima start arrow-odbc-linux \
--arch aarch64 --vm-type vz --vz-rosetta \
--cpu 10 --memory 12 --disk 80
```

No AWS EC2 resource is required by this procedure.

## Verify the source

```bash
git switch --detach beccec0d0c451b7aa3e4530416ac431b3c035c69
test "$(git rev-parse HEAD)" = beccec0d0c451b7aa3e4530416ac431b3c035c69
git status --short
```

Do not continue from a dirty worktree unless the changes are understood and
intended. The commands below write build products only under
`cpp/build/linux-odbc-validation`.

## Build the x86_64 driver

Build the repository-provided Ubuntu 24.04 toolchain image:

```bash
ARCH=amd64 ARCH_SHORT=amd64 UBUNTU=24.04 \
docker-compose build ubuntu-cpp-odbc
```

Build and install into the disposable container. The build directory is mounted
back to the host so the driver remains available after the container exits.

```bash
mkdir -p cpp/build/linux-odbc-validation
docker run --rm --platform linux/amd64 \
-v "$PWD:/arrow" \
-v "$PWD/cpp/build/linux-odbc-validation:/build" \
-e ARROW_ACERO=OFF \
-e ARROW_AZURE=OFF \
-e ARROW_BUILD_PARALLEL=4 \
-e ARROW_BUILD_SHARED=ON \
-e ARROW_BUILD_STATIC=ON \
-e ARROW_BUILD_TESTS=OFF \
-e ARROW_BUILD_TYPE=release \
-e ARROW_BUILD_UTILITIES=OFF \
-e ARROW_CSV=OFF \
-e ARROW_DATASET=OFF \
-e ARROW_DEPENDENCY_SOURCE=BUNDLED \
-e ARROW_DEPENDENCY_USE_SHARED=OFF \
-e ARROW_FLIGHT=ON \
-e ARROW_FLIGHT_SQL=ON \
-e ARROW_FLIGHT_SQL_ODBC=ON \
-e ARROW_FLIGHT_SQL_ODBC_INSTALLER=OFF \
-e ARROW_GANDIVA=OFF \
-e ARROW_GCS=OFF \
-e ARROW_HDFS=OFF \
-e ARROW_HOME=/usr/local \
-e ARROW_JEMALLOC=OFF \
-e ARROW_MIMALLOC=OFF \
-e ARROW_ORC=OFF \
-e ARROW_PARQUET=OFF \
-e ARROW_S3=OFF \
-e ARROW_SUBSTRAIT=OFF \
-e ARROW_USE_CCACHE=OFF \
-e CMAKE_BUILD_PARALLEL_LEVEL=4 \
apache/arrow-dev:amd64-ubuntu-24.04-cpp \
/arrow/ci/scripts/cpp_build.sh /arrow /build
```

The unstripped build result is:

```text
cpp/build/linux-odbc-validation/cpp/release/libarrow_flight_sql_odbc.so
```

## Package and checksum

The pinned source does not implement a Linux DEB or RPM. In
`cpp/src/arrow/flight/sql/odbc/CMakeLists.txt`, the Linux installer branch emits
explicit TODO messages for both formats, leaves the Linux ODBC and documentation
install directories unset, and selects no Linux CPack generator. Therefore the
validated deliverable is a relocatable tar archive, not a DEB or RPM.

Create the stripped direct library, tar archive, smoke-test binary, and
`SHA256SUMS` in the Linux-only artifact directory:

```bash
linux_dir=cpp/src/arrow/flight/sql/odbc/install/linux
mkdir -p "${linux_dir}/artifacts"
docker run --rm --platform linux/amd64 \
-v "$PWD:/arrow" -w /arrow \
apache/arrow-dev:amd64-ubuntu-24.04-cpp \
"${linux_dir}/package.sh" \
/arrow/cpp/build/linux-odbc-validation/cpp/release/libarrow_flight_sql_odbc.so \
"/arrow/${linux_dir}/artifacts"

cd "${linux_dir}/artifacts"
sha256sum --check SHA256SUMS
cd -
```

## Install and register with unixODBC

Ubuntu runtime prerequisites are the `unixodbc`, `odbcinst`, `libcurl4t64`, and
`ca-certificates` packages, plus the standard C/C++ runtime and the transitive
libraries reported by `ldd`. Verify the artifact before install:

```bash
sha256sum --check SHA256SUMS
tar -xzf apache-arrow-flight-sql-odbc-25.0.1-linux-x86_64.tar.gz
cd apache-arrow-flight-sql-odbc-25.0.1-linux-x86_64
ldd lib/libarrow_flight_sql_odbc.so
sudo ./install.sh
odbcinst -q -d -n 'Apache Arrow Flight SQL ODBC Driver'
```

`install.sh` defaults to `/opt/apache-arrow-flight-sql-odbc/25.0.1` and uses
`odbcinst` to register the absolute library path. Pass a different absolute
prefix as its sole argument if required. Re-running it at the same prefix is
idempotent. It refuses to overwrite a same-name registration at another path;
`uninstall.sh` likewise unregisters only the exact path it owns.

For a non-root, isolated validation, avoid changing `/etc/odbcinst.ini`:

```bash
package_root="$PWD/apache-arrow-flight-sql-odbc-25.0.1-linux-x86_64"
mkdir -p "$PWD/odbc-config"
sed "s|@DRIVER_PATH@|${package_root}/lib/libarrow_flight_sql_odbc.so|g" \
"${package_root}/odbcinst.ini.in" >"$PWD/odbc-config/odbcinst.ini"
export ODBCSYSINI="$PWD/odbc-config"
export ODBCINSTINI=odbcinst.ini
odbcinst -q -d -n 'Apache Arrow Flight SQL ODBC Driver'
```

## Run the Dremio Cloud smoke test securely

The smoke test defaults to `data.eu.dremio.cloud:443`, enables TLS, verifies the
server certificate against the Linux system trust store, and executes
`SELECT 1`. For token authentication, it prefers a short-lived token from the
file named by `DREMIO_ODBC_TOKEN_FILE`. For user/password authentication, it
reads `DREMIO_ODBC_UID` and prefers the secret from
`DREMIO_ODBC_PASSWORD_FILE`. The connection string exists only in process
memory and is never printed.

Have the secret manager materialize a short-lived secret as a mode-0600 file,
then export only its path. Do not paste the secret into these commands.

```bash
export DREMIO_ODBC_TOKEN_FILE=/run/secrets/dremio_odbc_token
export DREMIO_ODBC_HOST=data.eu.dremio.cloud
export DREMIO_ODBC_PORT=443

./smoke/flight_sql_odbc_smoke_test
```

Expected evidence includes `connection: success`, `result: 1`, successful cursor,
statement, connection, and environment cleanup lines, and `smoke test: PASS`.
A successful compile or driver registration alone is not a successful remote
smoke test.

After the test, revoke the short-lived credential and remove the secret file
through the secret manager. Then clear the process environment:

```bash
unset DREMIO_ODBC_TOKEN_FILE DREMIO_ODBC_UID DREMIO_ODBC_PASSWORD_FILE \
DREMIO_ODBC_HOST DREMIO_ODBC_PORT
```

## Uninstall and tear down

From the extracted package directory:

```bash
sudo ./uninstall.sh
if odbcinst -q -d -n 'Apache Arrow Flight SQL ODBC Driver'; then
echo 'driver registration still exists' >&2
exit 1
fi
```

Remove only the disposable Colima profile created for this validation:

```bash
colima stop arrow-odbc-linux
colima delete arrow-odbc-linux
```

If a cloud VM is substituted for Colima, record its instance ID, security group,
key, and volume IDs before use, then terminate the instance and delete only those
recorded resources. Confirm that no volume, elastic IP, or security group remains.
145 changes: 145 additions & 0 deletions cpp/src/arrow/flight/sql/odbc/install/linux/VALIDATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# Apache Arrow Flight SQL ODBC 25.0.1 Linux validation

Validation date: 2026-09-09

Source commit: `beccec0d0c451b7aa3e4530416ac431b3c035c69`

Source tag: `apache-arrow-25.0.1`

## Outcome

| Check | Result |
|---|---|
| Exact source and clean starting worktree | PASS |
| Repository-defined Ubuntu 24.04 amd64 build | PASS |
| x86_64 ELF and exported ODBC entry points | PASS |
| Dynamic dependency resolution | PASS |
| TLS CA-chain and hostname verification | PASS |
| Isolated unixODBC registration | PASS |
| Authenticated `SELECT 1` against Dremio Cloud | PASS, 3/3 |
| Cursor, statement, connection, and environment cleanup | PASS, 3/3 |
| Installer idempotence and registration ownership guards | PASS |
| Reproducible archive, checksum, install, load, and uninstall | PASS |
| Credential file removal | PASS |

## Environment

- Container image:
`apache/arrow-dev@sha256:a887c3bfb5262539c9046d414a8dfa9390c65358019e760128e8104e86041b36`
- Container architecture: `x86_64` / Debian architecture `amd64`.
- Distribution: Ubuntu 24.04.4 LTS.
- Toolchain: GCC/G++ 13.3.0, CMake 3.28.3, Ninja 1.11.1.
- Runtime: glibc 2.39 and unixODBC 2.3.12.
- Execution host: Apple Silicon, using an aarch64 Colima VM and Rosetta to run
the complete amd64 container userspace.

The compiler, linker, unixODBC driver manager, driver, and smoke-test process
were x86_64. This validates the Linux x86_64 ABI and end-to-end behavior, but it
is not a native x86_64 performance result.

## Build evidence

The build used the same Ubuntu version, architecture, bundled-dependency mode,
and disabled shared dependency linkage as Arrow's `odbc-linux` CI job and
`ubuntu-cpp-odbc` Compose service. CMake reported Arrow 25.0.1, x86_64, and the
Release configuration. The build completed the `install` target successfully.
It began at four-way parallelism and resumed the same Ninja graph at eight-way
parallelism after an intentional clean interrupt; no configuration or source
changed at that boundary.

The unstripped result was 60.4 MiB and identified as:

```text
ELF 64-bit LSB shared object, x86-64
Machine: Advanced Micro Devices X86-64
Type: DYN (Shared object file)
```

The driver exported the expected Unix wide-character entry points, including
`SQLConnectW`, `SQLDriverConnectW`, and `SQLExecDirectW`, plus common entry
points such as `SQLDisconnect`, `SQLFetch`, and `SQLCloseCursor`.

Direct dynamic dependencies were `libcurl.so.4`, `libodbcinst.so.2`,
`libstdc++.so.6`, `libm.so.6`, `libgcc_s.so.1`, `libc.so.6`, and the x86_64
loader. `ldd` resolved those and every transitive dependency. No dynamic Arrow,
Flight, Flight SQL, gRPC, or Protobuf library was required.

## TLS, registration, and query evidence

An independent OpenSSL preflight against `data.eu.dremio.cloud:443`, with SNI,
`-verify_hostname`, and `-verify_return_error`, reported `Verification: OK` and
`Verify return code: 0 (ok)`.

The driver was then registered in an isolated mode-0600 `odbcinst.ini`. The
registered `Driver` and `Setup` values both resolved to the just-built shared
library; no host or container system ODBC configuration was modified.

The compiled smoke client performed three independent cycles. Every cycle
reported:

```text
connection: success (TLS certificate verification enabled)
query: SELECT 1
result: 1
cleanup: close cursor: success
cleanup: free statement: success
cleanup: disconnect: success
cleanup: free connection: success
cleanup: free environment: success
smoke test: PASS
```

This directly covers the connect, execute, fetch, cursor close, disconnect, and
handle-destruction path that a compile-only check would miss.

## Packaging decision

With `ARROW_FLIGHT_SQL_ODBC_INSTALLER=ON`, the pinned source prints:

```text
ODBC_PACKAGE_FORMAT DEB not implemented, see GH-49595
ODBC_PACKAGE_FORMAT RPM not implemented, see GH-47977
```

The Linux branch sets no DEB or RPM generator and contains the additional TODO
to create a Linux installer. Manually forcing CPack's generic TGZ generator did
produce an archive, but inspection showed a generic Arrow library layout and no
unixODBC registration scripts. It is not a complete Linux ODBC installation
artifact.

The validated deliverable is therefore the versioned x86_64 driver plus a
relocatable tar archive with explicit `install.sh` and `uninstall.sh`, an
`odbcinst.ini` template, the smoke-test source and binary, licenses, this report,
and the build runbook. `SHA256SUMS` authenticates both deliverables.

The stripped direct driver was 47 MiB and the archive was 16 MiB. Two packaging
runs produced identical SHA-256 values. The exact archive then passed checksum
verification, extraction, installation at the default prefix, repeat
installation with `UsageCount=1`, dynamic loading, documentation installation,
unregistration, and exact-prefix file removal.

## Installer and credential safety

The installer tests used an isolated unixODBC configuration and verified:

- initial registration succeeds;
- reinstall at the same prefix is idempotent and leaves `UsageCount=1`;
- install refuses to replace a same-name driver registered at another path;
- uninstall refuses to remove a same-name driver registered at another path;
- uninstall removes its own registration and exact installed files.

The Dremio token was never placed in a repository file, ODBC configuration,
command-line argument, or artifact. It was read from a root-owned mode-0600
container secret file. Diagnostic text was redacted by the smoke client, driver
logging was disabled, and a shell trap deleted the secret file immediately after
the three live attempts. A follow-up existence check passed. Because the token
was originally supplied through an interactive conversation, it should still be
revoked after validation.

## Limitations

- Functional and ABI behavior was validated under translated x86_64 container
execution rather than bare-metal x86_64 Linux.
- This is not a performance, load, failover, or broad SQL conformance test.
- Compatibility with distributions older than Ubuntu 24.04 is not established;
the artifact should be treated as an Ubuntu 24.04 / glibc 2.39 build.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
e031eb3d67e10795d83f6a708afb8c5b2a8f07f90f8875c3222fa0de55bebe65 libarrow_flight_sql_odbc-25.0.1-linux-x86_64.so
f60ee12013544e538821783d54a4aaf9578e4c7c86455363ab59ffce3488d8c7 apache-arrow-flight-sql-odbc-25.0.1-linux-x86_64.tar.gz
Binary file not shown.
Binary file not shown.
Loading