Skip to content

Commit a5484a2

Browse files
committed
ODBC Linux rpm installer support
* Implement RPM installer fix formatting Remove todos ODBC rpm Installer wrap up * installing `rpm` package fixed the `cpack` command issue * Fix cpack command on CI (merge into last commit when ready) Change to use `awk` so script works on both platforms Comment out `find` and `tree` steps Change build path to be under /arrow Since docker is mounted, changing build path to be in `/arrow` will allow host machine to access docker build contents TEMP - Disable non-ODBC items Add commands to find build folder Attempt to build RPM installer * not sure if `/build/cpp` can be accessed outside of docker. Hopefully it should. * add `rpm` dependency install Indicate RPM in workflow run Add rpm `postinstall` (not tested) Remove merge conflict code * Enable ODBC installer build in CI instead of `compose.yaml` Update workflow matrix Update cpp_extra.yml Fix package name
1 parent b4b6d70 commit a5484a2

10 files changed

Lines changed: 125 additions & 25 deletions

File tree

.github/workflows/cpp_extra.yml

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ jobs:
350350
351351
odbc-linux:
352352
needs: check-labels
353-
name: ODBC Linux
353+
name: ODBC ${{ matrix.build-type }} ${{ matrix.title }}
354354
runs-on: ubuntu-latest
355355
if: >-
356356
needs.check-labels.outputs.force == 'true' ||
@@ -359,6 +359,15 @@ jobs:
359359
timeout-minutes: 75
360360
strategy:
361361
fail-fast: false
362+
matrix:
363+
include:
364+
- image: ubuntu-cpp-odbc
365+
title: AMD64 Ubuntu RPM
366+
build-type: release
367+
format: rpm
368+
run-options: >-
369+
-e ARROW_FLIGHT_SQL_ODBC_INSTALLER=ON
370+
-e ODBC_PACKAGE_FORMAT=RPM
362371
env:
363372
ARCH: amd64
364373
ARCHERY_DEBUG: 1
@@ -376,8 +385,8 @@ jobs:
376385
uses: actions/cache@v5
377386
with:
378387
path: .docker
379-
key: ubuntu-cpp-odbc-${{ hashFiles('cpp/**') }}
380-
restore-keys: ubuntu-cpp-odbc-
388+
key: ${{ matrix.image }}-${{ matrix.format }}-${{ hashFiles('cpp/**') }}
389+
restore-keys: ${{ matrix.image }}-${{ matrix.format }}-
381390
- name: Setup Python on hosted runner
382391
uses: actions/setup-python@v6
383392
with:
@@ -392,7 +401,14 @@ jobs:
392401
# GH-40558: reduce ASLR to avoid ASAN/LSAN crashes
393402
sudo sysctl -w vm.mmap_rnd_bits=28
394403
source ci/scripts/util_enable_core_dumps.sh
395-
archery docker run ubuntu-cpp-odbc
404+
archery docker run ${{ matrix.run-options || '' }} ${{ matrix.image }}
405+
- name: Upload ODBC ${{ matrix.format }} to the job
406+
if: matrix.build-type == 'release'
407+
uses: actions/upload-artifact@v7
408+
with:
409+
name: flight-sql-odbc-${{ matrix.format }}-installer
410+
path: build/cpp/ArrowFlightSqlOdbc-*.${{ matrix.format }}
411+
if-no-files-found: error
396412
- name: Docker Push
397413
if: >-
398414
success() &&
@@ -403,7 +419,7 @@ jobs:
403419
ARCHERY_DOCKER_USER: ${{ secrets.DOCKERHUB_USER }}
404420
ARCHERY_DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
405421
continue-on-error: true
406-
run: archery docker push ubuntu-cpp-odbc
422+
run: archery docker push ${{ matrix.image }}
407423

408424
odbc-macos:
409425
needs: check-labels

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ repos:
348348
?^cpp/examples/minimal_build/run\.sh$|
349349
?^cpp/examples/tutorial_examples/run\.sh$|
350350
?^cpp/src/arrow/flight/sql/odbc/install/mac/postinstall$|
351+
?^cpp/src/arrow/flight/sql/odbc/install/linux/rpm/postinstall$|
351352
?^cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc\.sh$|
352353
?^cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc_ini\.sh$|
353354
?^dev/release/05-binary-upload\.sh$|

ci/docker/ubuntu-24.04-cpp.dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ RUN apt-get update -y -q && \
118118
python3-venv \
119119
rados-objclass-dev \
120120
rapidjson-dev \
121+
rpm \
121122
rsync \
122123
tzdata \
123124
tzdata-legacy \

ci/scripts/cpp_build.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ else
274274
-Dlz4_SOURCE=${lz4_SOURCE:-} \
275275
-Dnlohmann_json_SOURCE=${nlohmann_json_SOURCE:-} \
276276
-Dopentelemetry-cpp_SOURCE=${opentelemetry_cpp_SOURCE:-} \
277+
-DODBC_PACKAGE_FORMAT=${ODBC_PACKAGE_FORMAT:-} \
277278
-DORC_SOURCE=${ORC_SOURCE:-} \
278279
-DPARQUET_BUILD_EXAMPLES=${PARQUET_BUILD_EXAMPLES:-OFF} \
279280
-DPARQUET_BUILD_EXECUTABLES=${PARQUET_BUILD_EXECUTABLES:-OFF} \

compose.yaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,12 +516,15 @@ services:
516516
ARROW_PARQUET: "OFF"
517517
ARROW_S3: "OFF"
518518
ARROW_SUBSTRAIT: "OFF"
519+
# Use `/arrow/build` so build artifacts are visible on the CI host
520+
# Generate ODBC installer before testing
519521
# Register ODBC before running tests
520522
command: >
521523
/bin/bash -c "
522-
/arrow/ci/scripts/cpp_build.sh /arrow /build &&
524+
/arrow/ci/scripts/cpp_build.sh /arrow /arrow/build &&
525+
(cd /arrow/build/cpp && cpack) &&
523526
sudo /arrow/cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh /usr/local/lib/libarrow_flight_sql_odbc.so &&
524-
/arrow/ci/scripts/cpp_test.sh /arrow /build"
527+
/arrow/ci/scripts/cpp_test.sh /arrow /arrow/build"
525528
526529
ubuntu-cpp-minimal:
527530
# Arrow build with minimal components/dependencies

cpp/cmake_modules/DefineOptions.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,12 @@ takes precedence over ccache if a storage backend is configured" ON)
343343
ARROW_FLIGHT_SQL
344344
ARROW_COMPUTE)
345345

346+
define_option(ARROW_FLIGHT_SQL_ODBC_INSTALLER
347+
"Build the installer Arrow Flight SQL ODBC extension"
348+
OFF
349+
DEPENDS
350+
ARROW_FLIGHT_SQL_ODBC)
351+
346352
define_option(ARROW_GANDIVA
347353
"Build the Gandiva libraries"
348354
OFF

cpp/src/arrow/flight/sql/odbc/CMakeLists.txt

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,11 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER)
159159
set(CPACK_WIX_UI_BANNER
160160
"${CMAKE_CURRENT_SOURCE_DIR}/install/windows/arrow-wix-banner.bmp")
161161
else()
162+
set(ODBC_UNIX_FILE_NAME
163+
"ArrowFlightSqlOdbc-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}"
164+
)
162165
if(APPLE)
163-
set(CPACK_PACKAGE_FILE_NAME
164-
"ArrowFlightSqlOdbc-${CPACK_PACKAGE_VERSION_MAJOR}.${ODBC_PACKAGE_VERSION_MINOR}.${ODBC_PACKAGE_VERSION_PATCH}"
165-
)
166+
set(CPACK_PACKAGE_FILE_NAME "${ODBC_UNIX_FILE_NAME}")
166167
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}")
167168

168169
set(CPACK_SET_DESTDIR ON)
@@ -178,10 +179,28 @@ if(ARROW_FLIGHT_SQL_ODBC_INSTALLER)
178179
set(ODBC_DOC_INSTALL_DIR "arrow-odbc/doc")
179180
else()
180181
# Linux
181-
# GH-49595: TODO implement DEB installer
182-
# GH-47977: TODO implement RPM installer
183-
message(STATUS "ODBC_PACKAGE_FORMAT DEB not implemented, see GH-49595")
184-
message(STATUS "ODBC_PACKAGE_FORMAT RPM not implemented, see GH-47977")
182+
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}")
183+
if(${ODBC_PACKAGE_FORMAT} STREQUAL "DEB")
184+
# GH-49595 TODO: implement DEB installer
185+
message(STATUS "ODBC_PACKAGE_FORMAT DEB not implemented, see GH-49595")
186+
elseif(${ODBC_PACKAGE_FORMAT} STREQUAL "RPM")
187+
set(CPACK_RPM_PACKAGE_ARCHITECTURE x86_64)
188+
set(CPACK_GENERATOR RPM)
189+
set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE
190+
"${CMAKE_CURRENT_SOURCE_DIR}/install/linux/postinst")
191+
set(CPACK_RPM_FILE_NAME "${ODBC_UNIX_FILE_NAME}.rpm")
192+
# Disable dependency check as ODBC embeds all third party dependencies
193+
set(CPACK_RPM_PACKAGE_AUTOREQPROV "no")
194+
set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE 1)
195+
set(CPACK_RPM_COMPONENT_INSTALL ON)
196+
else()
197+
message(FATAL_ERROR "ODBC_PACKAGE_FORMAT '${ODBC_PACKAGE_FORMAT}' must be DEB or RPM for Linux installer."
198+
)
199+
endif()
200+
201+
# By default, Linux installs under /usr
202+
set(ODBC_INSTALL_DIR "lib64/arrow-odbc/lib")
203+
set(ODBC_DOC_INSTALL_DIR "lib64/arrow-odbc/doc")
185204
endif()
186205

187206
# Install ODBC

cpp/src/arrow/flight/sql/odbc/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,22 @@ After ODBC has been registered, you can run the ODBC tests. It is recommended to
125125
.\cpp\build\< release | debug >\< Release | Debug>\arrow-flight-sql-odbc-test.exe
126126
```
127127
128+
## Installers
129+
130+
ODBC installers are uploaded to the CI artifacts.
131+
132+
| Operating System | Package Format |
133+
|------------------|----------------|
134+
| Windows | MSI |
135+
| macOS | PKG |
136+
| Linux | DEB / RPM |
137+
138+
### Install `.RPM` on Ubuntu
139+
While installing via `.DEB` installer on Ubuntu is the recommended approach, users may install `.RPM` on Ubuntu using below command
140+
```
141+
alien -i --scripts ArrowFlightSqlOdbc-<version>.rpm
142+
```
143+
128144
## Known Limitations
129145
130146
- Conversion from timestamp data type with specified time zone value to strings is not supported at the moment. This doesn't impact driver's usage of retrieving timestamp data from Power BI on Windows, and Excel on macOS and Windows. See GH-47504 for more context.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/bin/bash
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
20+
# Use temporary driver registration script to register ODBC driver in system DSN
21+
odbc_install_script="/usr/lib64/arrow-odbc/lib/install_odbc.sh"
22+
"$odbc_install_script" /usr/lib64/arrow-odbc/lib/libarrow_flight_sql_odbc.so
23+
24+
# Use temporary DSN registration script to register sample system DSN
25+
dsn_install_script="/usr/lib64/arrow-odbc/lib/install_odbc_ini.sh"
26+
"$dsn_install_script" /etc/odbc.ini
27+
28+
# clean temporary script
29+
rm -f "$odbc_install_script"
30+
rm -f "$dsn_install_script"

cpp/src/arrow/flight/sql/odbc/install/unix/install_odbc.sh

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,44 +42,51 @@ fi
4242

4343
case "$(uname)" in
4444
Linux)
45-
ODBCINST_FILE="/etc/odbcinst.ini"
45+
SYSTEM_ODBCINST_FILE="/etc/odbcinst.ini"
4646
;;
4747
*)
4848
# macOS
49-
ODBCINST_FILE="/Library/ODBC/odbcinst.ini"
49+
SYSTEM_ODBCINST_FILE="/Library/ODBC/odbcinst.ini"
5050
mkdir -p /Library/ODBC
5151
;;
5252
esac
5353

5454
DRIVER_NAME="Apache Arrow Flight SQL ODBC Driver"
5555

56-
touch "$ODBCINST_FILE"
56+
touch "$SYSTEM_ODBCINST_FILE"
5757

58-
if grep -q "^\[$DRIVER_NAME\]" "$ODBCINST_FILE"; then
58+
if grep -q "^\[$DRIVER_NAME\]" "$SYSTEM_ODBCINST_FILE"; then
5959
echo "Driver [$DRIVER_NAME] already exists in odbcinst.ini"
6060
else
6161
echo "Adding [$DRIVER_NAME] to odbcinst.ini..."
6262
echo "
6363
[$DRIVER_NAME]
6464
Description=An ODBC Driver for Apache Arrow Flight SQL
6565
Driver=$ODBC_64BIT
66-
" >>"$ODBCINST_FILE"
66+
" >>"$SYSTEM_ODBCINST_FILE"
6767
fi
6868

6969
# Check if [ODBC Drivers] section exists
70-
if grep -q '^\[ODBC Drivers\]' "$ODBCINST_FILE"; then
70+
if grep -q '^\[ODBC Drivers\]' "$SYSTEM_ODBCINST_FILE"; then
7171
# Section exists: check if driver entry exists
72-
if ! grep -q "^${DRIVER_NAME}=" "$ODBCINST_FILE"; then
72+
if ! grep -q "^${DRIVER_NAME}=" "$SYSTEM_ODBCINST_FILE"; then
7373
# Driver entry does not exist, add under [ODBC Drivers]
74-
sed -i '' "/^\[ODBC Drivers\]/a\\
75-
${DRIVER_NAME}=Installed
76-
" "$ODBCINST_FILE"
74+
75+
awk -v driver="$DRIVER_NAME" '
76+
$0 ~ /^\[ODBC Drivers\]/ && !inserted {
77+
print
78+
print driver "=Installed"
79+
inserted=1
80+
next
81+
}
82+
{ print }
83+
' "$SYSTEM_ODBCINST_FILE" > "${SYSTEM_ODBCINST_FILE}.tmp" && mv "${SYSTEM_ODBCINST_FILE}.tmp" "$SYSTEM_ODBCINST_FILE"
7784
fi
7885
else
7986
# Section doesn't exist, append both section and driver entry at end
8087
{
8188
echo ""
8289
echo "[ODBC Drivers]"
8390
echo "${DRIVER_NAME}=Installed"
84-
} >>"$ODBCINST_FILE"
91+
} >>"$SYSTEM_ODBCINST_FILE"
8592
fi

0 commit comments

Comments
 (0)