Skip to content
Open
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
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.git/
.github/
oracle-rac/
tests/0-inputs/
tests/1-environments/
tests/2-prebuilt/
tests/3-generated/
tests/.work/
tests/scripts/
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
tests/2-prebuilt/redo/** filter=lfs diff=lfs merge=lfs -text
tests/2-prebuilt/schema/** filter=lfs diff=lfs merge=lfs -text
tests/2-prebuilt/expected/** filter=lfs diff=lfs merge=lfs -text
68 changes: 68 additions & 0 deletions .github/workflows/redo-log-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Redo Log Tests

on:
push:
branches: [master]
pull_request:
branches: [master]

env:
CACHE_IMAGE: ghcr.io/${{ github.repository_owner }}/openlogreplicator:ci

jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
packages: write
steps:
- uses: actions/checkout@v4
with:
lfs: true

- uses: docker/setup-buildx-action@v3

- name: Log in to ghcr.io
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build OLR image
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile.dev
load: true
tags: olr-dev:latest
cache-from: type=registry,ref=${{ env.CACHE_IMAGE }}
cache-to: type=registry,ref=${{ env.CACHE_IMAGE }},mode=max
build-args: |
BUILD_TYPE=Debug
UIDOLR=1001
GIDOLR=1001
WITHORACLE=1
WITHKAFKA=1
WITHPROTOBUF=1
WITHPROMETHEUS=1
WITHTESTS=1

- name: Download fixtures from sql-tests-free23
uses: dawidd6/action-download-artifact@v6
with:
workflow: sql-tests-free23.yaml
name: test-artifacts-free-23
path: tests/3-generated/
if_no_artifact_found: warn

- name: Download fixtures from sql-tests-xe21
uses: dawidd6/action-download-artifact@v6
with:
workflow: sql-tests-xe21.yaml
name: test-artifacts-xe-21
path: tests/3-generated/
if_no_artifact_found: warn

- name: Run redo log tests
run: make test-redo
60 changes: 60 additions & 0 deletions .github/workflows/sql-tests-free23.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: "SQL Tests: Oracle Free 23"

on:
push:
branches: [master]
workflow_dispatch:

env:
CACHE_IMAGE: ghcr.io/${{ github.repository_owner }}/openlogreplicator:ci
ORACLE_TARGET: free-23

jobs:
generate:
runs-on: ubuntu-latest
timeout-minutes: 45
permissions:
packages: write
steps:
- uses: actions/checkout@v4

- uses: docker/setup-buildx-action@v3

- name: Log in to ghcr.io
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build OLR image
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile.dev
load: true
tags: olr-dev:latest
cache-from: type=registry,ref=${{ env.CACHE_IMAGE }}
cache-to: type=registry,ref=${{ env.CACHE_IMAGE }},mode=max
build-args: |
BUILD_TYPE=Debug
UIDOLR=1001
GIDOLR=1001
WITHORACLE=1
WITHKAFKA=1
WITHPROTOBUF=1
WITHPROMETHEUS=1
WITHTESTS=1

- name: Start containers
run: make -C tests/1-environments/${{ env.ORACLE_TARGET }} up

- name: Generate all fixtures
run: make -C tests/1-environments/${{ env.ORACLE_TARGET }} test-sql

- name: Upload generated fixtures
uses: actions/upload-artifact@v4
with:
name: test-artifacts-${{ env.ORACLE_TARGET }}
path: tests/3-generated/
retention-days: 90
60 changes: 60 additions & 0 deletions .github/workflows/sql-tests-xe21.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: "SQL Tests: Oracle XE 21"

on:
push:
branches: [master]
workflow_dispatch:

env:
CACHE_IMAGE: ghcr.io/${{ github.repository_owner }}/openlogreplicator:ci
ORACLE_TARGET: xe-21

jobs:
generate:
runs-on: ubuntu-latest
timeout-minutes: 45
permissions:
packages: write
steps:
- uses: actions/checkout@v4

- uses: docker/setup-buildx-action@v3

- name: Log in to ghcr.io
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build OLR image
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile.dev
load: true
tags: olr-dev:latest
cache-from: type=registry,ref=${{ env.CACHE_IMAGE }}
cache-to: type=registry,ref=${{ env.CACHE_IMAGE }},mode=max
build-args: |
BUILD_TYPE=Debug
UIDOLR=1001
GIDOLR=1001
WITHORACLE=1
WITHKAFKA=1
WITHPROTOBUF=1
WITHPROMETHEUS=1
WITHTESTS=1

- name: Start containers
run: make -C tests/1-environments/${{ env.ORACLE_TARGET }} up

- name: Generate all fixtures
run: make -C tests/1-environments/${{ env.ORACLE_TARGET }} test-sql

- name: Upload generated fixtures
uses: actions/upload-artifact@v4
with:
name: test-artifacts-${{ env.ORACLE_TARGET }}
path: tests/3-generated/
retention-days: 90
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
build/
cmake-build-*/
.idea/
.vscode/
*.swp
*~
.DS_Store
tests/3-generated/
tests/.work/
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ if (WITH_PROTOBUF)
endif ()

add_subdirectory(src)
if (WITH_TESTS)
enable_testing()
add_subdirectory(tests)
endif ()

target_link_libraries(OpenLogReplicator Threads::Threads)

Expand Down
173 changes: 173 additions & 0 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# syntax=docker/dockerfile:1
#
# Dockerfile.dev — Optimized for local dev builds
# Splits dependencies into cached layers + uses ccache for incremental compilation.
#
# Usage:
# GIDOLR=$(id -g) UIDOLR=$(id -u) docker compose build olr

ARG IMAGE=debian
ARG VERSION=13.0
FROM ${IMAGE}:${VERSION}

ARG ARCH=x86_64
ARG GIDOLR=1001
ARG UIDOLR=1001
ARG GIDORA=54322
ARG BUILD_TYPE=Debug
ARG WITHKAFKA
ARG WITHPROMETHEUS
ARG WITHORACLE
ARG WITHPROTOBUF
ARG WITHTESTS

ENV LC_ALL=C
ENV LANG=en_US.UTF-8
ENV ORACLE_MAJOR=23
ENV ORACLE_MINOR=26
ENV PROTOBUF_VERSION_DIR=21.12
ENV PROTOBUF_VERSION=3.21.12
ENV RAPIDJSON_VERSION=1.1.0
ENV LIBRDKAFKA_VERSION=2.13.0
ENV PROMETHEUS_VERSION=1.3.0
ENV OPENLOGREPLICATOR_VERSION=local
ENV LD_LIBRARY_PATH=/opt/instantclient_${ORACLE_MAJOR}_${ORACLE_MINOR}:/opt/librdkafka/lib:/opt/prometheus/lib:/opt/protobuf/lib
ENV BUILDARGS="-DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DWITH_RAPIDJSON=/opt/rapidjson -S ../ -B ./"
ENV BUILDARGS="${BUILDARGS}${WITHKAFKA:+ -DWITH_RDKAFKA=/opt/librdkafka}"
ENV BUILDARGS="${BUILDARGS}${WITHPROMETHEUS:+ -DWITH_PROMETHEUS=/opt/prometheus}"
ENV BUILDARGS="${BUILDARGS}${WITHORACLE:+ -DWITH_OCI=/opt/instantclient_${ORACLE_MAJOR}_${ORACLE_MINOR}}"
ENV BUILDARGS="${BUILDARGS}${WITHPROTOBUF:+ -DWITH_PROTOBUF=/opt/protobuf}"
ENV BUILDARGS="${BUILDARGS}${WITHTESTS:+ -DWITH_TESTS=ON}"
ENV COMPILEKAFKA="${WITHKAFKA:+1}"
ENV COMPILEPROMETHEUS="${WITHPROMETHEUS:+1}"
ENV COMPILEORACLE="${WITHORACLE:+1}"
ENV COMPILEPROTOBUF="${WITHPROTOBUF:+1}"
ENV DEBIAN_FRONTEND=noninteractive

COPY scripts/run.sh /opt

# Layer 1: System packages + ccache
RUN set -eu && \
apt-get update && \
apt-get -y install file gcc g++ libaio1t64 libasan8 libubsan1 libtool libz-dev make patch unzip wget cmake git curl ccache && \
ln -s libaio.so.1t64 /usr/lib/x86_64-linux-gnu/libaio.so.1

# Layer 2: RapidJSON
RUN set -eu && \
cd /opt && \
wget -q https://github.com/Tencent/rapidjson/archive/refs/tags/v${RAPIDJSON_VERSION}.tar.gz && \
tar xzf v${RAPIDJSON_VERSION}.tar.gz && \
rm v${RAPIDJSON_VERSION}.tar.gz && \
ln -s rapidjson-${RAPIDJSON_VERSION} rapidjson && \
if [ "${RAPIDJSON_VERSION}" = "1.1.0" ]; then \
cd rapidjson && \
wget -q https://github.com/Tencent/rapidjson/commit/3b2441b87f99ab65f37b141a7b548ebadb607b96.diff && \
patch -p1 < 3b2441b87f99ab65f37b141a7b548ebadb607b96.diff && \
rm 3b2441b87f99ab65f37b141a7b548ebadb607b96.diff ; \
fi

# Layer 3: Oracle Instant Client
RUN set -eu && \
if [ "${COMPILEORACLE}" != "" ]; then \
cd /opt && \
wget -q https://download.oracle.com/otn_software/linux/instantclient/${ORACLE_MAJOR}${ORACLE_MINOR}000/instantclient-basic-linux.x64-${ORACLE_MAJOR}.${ORACLE_MINOR}.0.0.0.zip && \
unzip -o instantclient-basic-linux.x64-${ORACLE_MAJOR}.${ORACLE_MINOR}.0.0.0.zip && \
rm instantclient-basic-linux.x64-${ORACLE_MAJOR}.${ORACLE_MINOR}.0.0.0.zip && \
rm -rf META-INF && \
wget -q https://download.oracle.com/otn_software/linux/instantclient/${ORACLE_MAJOR}${ORACLE_MINOR}000/instantclient-sdk-linux.x64-${ORACLE_MAJOR}.${ORACLE_MINOR}.0.0.0.zip && \
unzip -o instantclient-sdk-linux.x64-${ORACLE_MAJOR}.${ORACLE_MINOR}.0.0.0.zip && \
rm instantclient-sdk-linux.x64-${ORACLE_MAJOR}.${ORACLE_MINOR}.0.0.0.zip && \
rm -rf META-INF ; \
fi

# Layer 4: Protobuf (~5-7 min, cached unless version changes)
RUN set -eu && \
if [ "${COMPILEPROTOBUF}" != "" ]; then \
cd /opt && \
wget -q https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION_DIR}/protobuf-cpp-${PROTOBUF_VERSION}.tar.gz && \
tar xzf protobuf-cpp-${PROTOBUF_VERSION}.tar.gz && \
rm protobuf-cpp-${PROTOBUF_VERSION}.tar.gz && \
cd /opt/protobuf-${PROTOBUF_VERSION} && \
./configure --prefix=/opt/protobuf && \
make && \
make install ; \
fi

# Layer 5: librdkafka (~2-3 min, cached unless version changes)
RUN set -eu && \
if [ "${COMPILEKAFKA}" != "" ]; then \
cd /opt && \
wget -q https://github.com/confluentinc/librdkafka/archive/refs/tags/v${LIBRDKAFKA_VERSION}.tar.gz && \
tar xzf v${LIBRDKAFKA_VERSION}.tar.gz && \
rm v${LIBRDKAFKA_VERSION}.tar.gz && \
cd /opt/librdkafka-${LIBRDKAFKA_VERSION} && \
./configure --prefix=/opt/librdkafka && \
make && \
make install ; \
fi

# Layer 6: Prometheus
RUN set -eu && \
if [ "${COMPILEPROMETHEUS}" != "" ]; then \
cd /opt && \
wget -q https://github.com/jupp0r/prometheus-cpp/releases/download/v${PROMETHEUS_VERSION}/prometheus-cpp-with-submodules.tar.gz && \
tar xzf prometheus-cpp-with-submodules.tar.gz && \
rm prometheus-cpp-with-submodules.tar.gz && \
cd /opt/prometheus-cpp-with-submodules && \
mkdir _build && \
cd _build && \
cmake .. -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX:PATH=/opt/prometheus -DENABLE_PUSH=OFF -DENABLE_COMPRESSION=OFF && \
cmake --build . --parallel 4 && \
ctest -V && \
cmake --install . ; \
fi

# --- Source changes only invalidate from here down ---
COPY . /opt/OpenLogReplicator-local

# Layer 7: Build OLR (ccache persists across rebuilds via BuildKit cache mount)
RUN --mount=type=cache,target=/root/.ccache,id=olr-ccache \
set -eu && \
export CCACHE_DIR=/root/.ccache && \
cd /opt/OpenLogReplicator-local && \
if [ "${COMPILEPROTOBUF}" != "" ]; then \
cd proto && \
/opt/protobuf/bin/protoc OraProtoBuf.proto --cpp_out=. && \
mv OraProtoBuf.pb.cc ../src/common/OraProtoBuf.pb.cpp && \
mv OraProtoBuf.pb.h ../src/common/OraProtoBuf.pb.h && \
cd .. ; \
fi && \
mkdir cmake-build-${BUILD_TYPE}-${ARCH} && \
cd cmake-build-${BUILD_TYPE}-${ARCH} && \
cmake ${BUILDARGS} \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache && \
cmake --build ./ --target OpenLogReplicator -j && \
if [ "${WITHTESTS}" != "" ]; then \
cmake --build ./ --target olr_tests -j ; \
fi && \
mkdir -p /opt/OpenLogReplicator/log /opt/OpenLogReplicator/tmp /opt/OpenLogReplicator/scripts && \
cp ./OpenLogReplicator /opt/OpenLogReplicator && \
cp -p /opt/OpenLogReplicator-local/scripts/gencfg.sql /opt/OpenLogReplicator/scripts/gencfg.sql

# Layer 8: User setup
RUN set -eu && \
mkdir -p /home/user1 && \
groupadd -g ${GIDOLR} user1 && \
if [ "${GIDOLR}" != "${GIDORA}" ]; then \
groupadd -g ${GIDORA} oracle && \
useradd -u ${UIDOLR} user1 -g user1 -G oracle -d /home/user1 ; \
else \
useradd -u ${UIDOLR} user1 -g user1 -d /home/user1 ; \
fi && \
chown -R user1:user1 /home/user1 && \
chown -R user1:user1 /opt/OpenLogReplicator && \
chown -R user1:user1 /opt/OpenLogReplicator-local/cmake-build-*

USER user1:oracle
RUN set -eu && \
export LD_LIBRARY_PATH=/opt/instantclient_${ORACLE_MAJOR}_${ORACLE_MINOR}:/opt/librdkafka/lib:/opt/prometheus/lib:/opt/protobuf/lib && \
/opt/OpenLogReplicator/OpenLogReplicator --version

WORKDIR /opt/OpenLogReplicator
ENTRYPOINT ["/opt/run.sh"]
Loading