diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2eea525 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 776bc61..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,12 +0,0 @@ -# You can override the included template(s) by including variable overrides -# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings -# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings -# Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings -# Note that environment variables can be set in several places -# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence -stages: -- test -sast: - stage: test -include: -- template: Security/SAST.gitlab-ci.yml diff --git a/Dockerfile.ubuntu-focal b/1.3.1/ubuntu/focal/Dockerfile similarity index 56% rename from Dockerfile.ubuntu-focal rename to 1.3.1/ubuntu/focal/Dockerfile index adfc13a..168924f 100644 --- a/Dockerfile.ubuntu-focal +++ b/1.3.1/ubuntu/focal/Dockerfile @@ -1,16 +1,22 @@ + +# +# Autogenerated files, do not edit. See README.md +# + + FROM ubuntu:focal as base LABEL org.opencontainers.image.authors="emanuel@ongres.com" ARG MAX_JOBS - +ENV TAG=BABEL_1_3_1__PG_13_7 +ENV BABELFISH_VERSION=1.3.1 ENV MAX_JOBS=${MAX_JOBS:-2} -ENV CODE_PATH=/opt/babelfishpg/ -ENV EXT_CODE_PATH=/opt/babelfishpg_ext +ENV ANTLR_VERSION=4.9.3 -ENV PREFIX=/opt/target/babelfishpg +ENV PREFIX=/usr/local/babelfishpg-${BABELFISH_VERSION} ENV ANTLR_RUNTIME=/opt/antlr4 -ENV PG_SRC=/opt/babelfishpg/ +ENV PG_SRC=/opt/${TAG}/ ENV PG_CONFIG=${PREFIX}/bin/pg_config ENV ANTLR4_RUNTIME_INCLUDE_DIR=/usr/local/include/antlr4-runtime/ @@ -21,7 +27,7 @@ RUN set -ex; \ RUN set -ex ; \ DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \ - build-essential flex libxml2-dev libxml2-utils\ + build-essential flex libxml2-dev libxml2-utils libc6-dev \ libxslt-dev libssl-dev \ libreadline-dev zlib1g-dev libldap2-dev libpam0g-dev gettext \ uuid uuid-dev cmake lld apt-utils pkg-config libossp-uuid-dev gnulib bison git @@ -36,31 +42,42 @@ RUN set -ex ; \ libssl-dev python-dev libpq-dev \ pkgconf unzip libutfcpp-dev gnupg +RUN sysArch=$(uname -m) + # SQL Server Tooling dependencies # Reference: https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-setup-tools?view=sql-server-ver15#ubuntu +# For non-amd64 mssql-tools isn't available, installing freetds in its place RUN set -ex ; \ - curl -L https://packages.microsoft.com/keys/microsoft.asc | apt-key add - && \ - curl -L https://packages.microsoft.com/config/ubuntu/20.04/prod.list | tee /etc/apt/sources.list.d/msprod.list && \ - apt update && ACCEPT_EULA=Y apt install -y mssql-tools unixodbc-dev + case "$sysArch" in \ + x86_64 | amd64 | ppc64el) \ + curl -L https://packages.microsoft.com/keys/microsoft.asc | apt-key add - && \ + curl -L https://packages.microsoft.com/config/ubuntu/20.04/prod.list | tee /etc/apt/sources.list.d/msprod.list && \ + apt update && ACCEPT_EULA=Y apt install -y mssql-tools unixodbc-dev ; \ + PATH="${PREFIX}/bin:/opt/mssql-tools/bin/:${PATH}" ;; \ + * ) \ + DEBIAN_FRONTEND=noninteractive \ + apt install -y freetds-bin freetds-common ;; \ + esac ; + -ENV PATH="${PREFIX}/bin:/opt/mssql-tools/bin/:${PATH}" RUN rm -rf /var/lib/apt/lists/*; \ apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; -# RUN curl -L https://www.antlr.org/download/antlr-4.8-complete.jar --output ${ANTLR_EXECUTABLE} +RUN curl -L https://github.com/babelfish-for-postgresql/babelfish-for-postgresql/releases/download/${TAG}/${TAG}.zip \ + --output ${TAG}.zip && unzip -d /opt/ ${TAG}.zip # Compiling and installing antlr runtime -ENV ANTLR_EXECUTABLE=/usr/local/lib/antlr-4.9.2-complete.jar - -RUN curl https://www.antlr.org/download/antlr-4.9.2-complete.jar \ - --output ${ANTLR_EXECUTABLE} && chmod +x ${ANTLR_EXECUTABLE} +# ENV ANTLR_EXECUTABLE=/usr/local/lib/antlr-${ANTLR_VERSION}-complete.jar +ENV ANTLR_EXECUTABLE=${PG_SRC}/contrib/babelfishpg_tsql/antlr/thirdparty/antlr/antlr-${ANTLR_VERSION}-complete.jar +# RUN curl https://www.antlr.org/download/antlr-${ANTLR_VERSION}-complete.jar \ +# --output ${ANTLR_EXECUTABLE} && chmod +x ${ANTLR_EXECUTABLE} -RUN curl https://www.antlr.org/download/antlr4-cpp-runtime-4.9.2-source.zip \ - --output /opt/antlr4-cpp-runtime-4.9.2-source.zip && \ - unzip -d ${ANTLR_RUNTIME} /opt/antlr4-cpp-runtime-4.9.2-source.zip +RUN curl https://www.antlr.org/download/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip \ + --output /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip && \ + unzip -d ${ANTLR_RUNTIME} /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip WORKDIR ${ANTLR_RUNTIME} @@ -69,67 +86,60 @@ RUN mkdir build && cd build && \ -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_DEMO=True && \ make && make install -RUN git clone https://github.com/babelfish-for-postgresql/postgresql_modified_for_babelfish.git ${CODE_PATH} -RUN git clone https://github.com/babelfish-for-postgresql/babelfish_extensions.git ${EXT_CODE_PATH} - - -WORKDIR ${CODE_PATH} -RUN ./configure CFLAGS="${CFLAGS:--Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic}" \ - --prefix=${PREFIX} \ - --enable-debug \ - --with-ldap \ - --with-libxml \ - --with-pam \ - --with-uuid=ossp \ - --enable-nls \ - --with-libxslt \ - --with-icu \ - --with-extra-version=" Babelfish for PostgreSQL" +WORKDIR ${PG_SRC} - -# Compilation -RUN make clean && make DESTDIR=${PREFIX}/tmp_install -j ${MAX_JOBS} world-bin - -RUN cd contrib/ && make && cd .. - -# # Regression Tests +RUN set -ex ; \ + case "$sysArch" in \ + x86_64 | amd64 | ppc64el) \ + CFLAGS_ARG='${CFLAGS:--Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic}' ; \ + CONFIGURE_FLAGS="" ;; \ + * ) \ + CFLAGS_ARG="-ggdb " CONFIGURE_FLAGS=' --build=arm-linux-gnueabihf ';; \ + esac ; \ + ./configure CFLAGS="${CFLAGS_ARG}" \ + --prefix=${PREFIX} \ + --enable-debug \ + --with-ldap \ + --with-libxml \ + --with-pam \ + --with-uuid=ossp \ + --enable-nls \ + --with-libxslt \ + --with-icu ${CONFIGURE_FLAGS} + + +# Engine Compilation +RUN make clean && make DESTDIR=${PREFIX}/tmp_install -j ${MAX_JOBS} world-bin && make install + +WORKDIR ${PG_SRC}/contrib +# Built-in contrib installation +RUN make +RUN make install + +## Regression Tests # RUN make DESTDIR=${PREFIX}/tmp_install EXTRA_REGRESS_OPTS=--debug -j ${MAX_JOBS} check -# Install core and core contribs -RUN make install && cd contrib/ && make install - -WORKDIR ${EXT_CODE_PATH} - -## Support for ANTLR 4.8. -## There is an ongoing work to have broader version support for ANTLR. -# RUN cp /usr/lib/x86_64-linux-gnu/libantlr4-runtime.so* ${PREFIX}/lib - -RUN cp /usr/local/lib/libantlr4-runtime.so.4.9.2 ${PREFIX}/lib - +RUN cp /usr/local/lib/libantlr4-runtime.so.${ANTLR_VERSION} ${PREFIX}/lib ENV USE_PGXS=1 -## [WIP] Support for ANTLR 4.8 -# XXX: current make is not taking in account this environment settings -# ANTLR_EXECUTABLE=${PREFIX}/antlr-4.8-complete.jar ANTLR4_RUNTIME_LIBRARIES=/usr/include/antlr4-runtime -RUN ["/usr/bin/bash", "-c", "cd ${EXT_CODE_PATH}/contrib/babelfishpg_tsql/antlr ; cmake . "] +RUN ["/usr/bin/bash", "-c", "cd ${PG_SRC}/contrib/babelfishpg_tsql/antlr ; cmake . "] RUN PG_CONFIG=${PG_CONFIG} PG_SRC=${PG_SRC} cmake=$(which cmake) ANTLR4_RUNTIME_LIBRARIES=/usr/include/antlr4-runtime ; \ for EXT in babelfishpg_common babelfishpg_money babelfishpg_tds babelfishpg_tsql ; \ do \ - cd ${EXT_CODE_PATH}/contrib/${EXT} ; \ + cd ${PG_SRC}/contrib/${EXT} ; \ make clean && make && make install ; \ done - -FROM base AS babelfish +FROM base AS babelfishpg COPY --from=base ${PREFIX}/ /usr/local/ /opt/mssql-tools/bin/ ENV DEBIAN_FRONTEND=noninteractive ENV PATH="${PREFIX}/bin:${PATH}" ENV PGDATA="/var/lib/postgresql/data" -ENV DOCKER_ENTRYPOINT="/usr/local/bin/entrypoint-ubuntu-focal.sh" +ENV DOCKER_ENTRYPOINT="/usr/local/bin/entrypoint.sh" RUN apt-get update && \ apt-get install -y libxml2 libreadline8 tzdata libldap-2.4-2 libpython2.7 libxslt1.1 libossp-uuid16 && \ @@ -150,7 +160,7 @@ RUN set -eux; \ RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" -COPY entrypoint-ubuntu-focal.sh /usr/local/bin/ +COPY entrypoint.sh ${DOCKER_ENTRYPOINT} RUN chmod -R 0750 "${PREFIX}/share" && \ chown postgres: ${DOCKER_ENTRYPOINT} && \ @@ -166,6 +176,6 @@ STOPSIGNAL SIGINT EXPOSE 1433 EXPOSE 5432 -ENTRYPOINT ["/usr/local/bin/entrypoint-ubuntu-focal.sh"] +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] CMD ["postgres"] diff --git a/docker-compose-remote.yml b/1.3.1/ubuntu/focal/docker-compose.yml similarity index 66% rename from docker-compose-remote.yml rename to 1.3.1/ubuntu/focal/docker-compose.yml index e328f31..13ccaeb 100644 --- a/docker-compose-remote.yml +++ b/1.3.1/ubuntu/focal/docker-compose.yml @@ -1,11 +1,12 @@ version: "3" services: - babelfishpg: - container_name: babelfishpg-ubuntu-focal - image: registry.gitlab.com/ongresinc/labs/babelfish-on-docker + babelfishpg-1.3.1-ubuntu-focal: + container_name: babelfishpg-1.3.1-ubuntu.focal + image: babelfishpg:1.3.1-ubuntu.focal ports: - - 1433:10433 + # Port forwarding not supported by BabelfishPG + - 1433:1433 - 5432:15432 environment: - POSTGRES_PASSWORD=password diff --git a/entrypoint-ubuntu-focal.sh b/1.3.1/ubuntu/focal/entrypoint.sh similarity index 99% rename from entrypoint-ubuntu-focal.sh rename to 1.3.1/ubuntu/focal/entrypoint.sh index 2da791d..d20597c 100644 --- a/entrypoint-ubuntu-focal.sh +++ b/1.3.1/ubuntu/focal/entrypoint.sh @@ -88,7 +88,8 @@ docker_init_database_dir() { set -- --waldir "$POSTGRES_INITDB_WALDIR" "$@" fi - eval 'initdb --username="$POSTGRES_USER" --pwfile=<(echo "$POSTGRES_PASSWORD") '"$POSTGRES_INITDB_ARGS"' "$@"' + # Babelfish supports UTF-8 only + eval 'initdb --username="$POSTGRES_USER" --pwfile=<(echo "$POSTGRES_PASSWORD") -E "UTF8" '"$POSTGRES_INITDB_ARGS"' "$@"' # unset/cleanup "nss_wrapper" bits if [ "${LD_PRELOAD:-}" = '/usr/lib/libnss_wrapper.so' ]; then diff --git a/2.1.1/amazonlinux/2/Dockerfile b/2.1.1/amazonlinux/2/Dockerfile new file mode 100644 index 0000000..0979761 --- /dev/null +++ b/2.1.1/amazonlinux/2/Dockerfile @@ -0,0 +1,149 @@ + +# +# Autogenerated files, do not edit. See README.md +# + +FROM amazonlinux:2 as base +LABEL org.opencontainers.image.authors="emanuel@ongres.com,xavisierra@ongres.com" + + +ARG MAX_JOBS +ENV TAG=BABEL_2_1_1__PG_14_3 +ENV MAX_JOBS=${MAX_JOBS:-2} +ENV ANTLR_VERSION=4.9.3 +ENV BABELFISH_VERSION=2.1.1 + +ENV MAX_JOBS=${MAX_JOBS:-2} + +ENV PREFIX=/usr/local/babelfishpg-${BABELFISH_VERSION} +ENV ANTLR_RUNTIME=/opt/antlr4 +ENV ANTLR_VERSION=${ANTLR_VERSION:-4.9.3} + +ENV PG_SRC=/opt/${TAG}/ +ENV PG_CONFIG=${PREFIX}/bin/pg_config +ENV ANTLR4_RUNTIME_INCLUDE_DIR=/usr/local/include/antlr4-runtime/ + +ENV ANTLR4_JAVA_BIN=/usr/bin/java + + +RUN yum update -y + +RUN yum install -y gcc gcc-c++ kernel-devel make \ + bison flex libxml2-devel readline-devel zlib-devel \ + uuid-devel pkg-config openssl-devel \ + libicu-devel postgresql-devel perl git \ + shadow-utils wget unzip curl cmake3 libuuid-devel \ + java pam-devel libxslt-devel openldap-devel \ + gettext-devel + +RUN ln -s /usr/bin/cmake3 /usr/bin/cmake + +ENV PATH="${PREFIX}/bin:${PATH}" + +RUN curl -L https://github.com/babelfish-for-postgresql/babelfish-for-postgresql/releases/download/${TAG}/${TAG}.zip \ + --output ${TAG}.zip && unzip -d /opt/ ${TAG}.zip + +# Compiling and installing antlr runtime +ENV ANTLR_EXECUTABLE=${PG_SRC}/contrib/babelfishpg_tsql/antlr/thirdparty/antlr/antlr-${ANTLR_VERSION}-complete.jar + +# RUN curl https://www.antlr.org/download/antlr-${ANTLR_VERSION}-complete.jar \ +# --output ${ANTLR_EXECUTABLE} && chmod +x ${ANTLR_EXECUTABLE} + +RUN curl https://www.antlr.org/download/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip \ + --output /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip && \ + unzip -d ${ANTLR_RUNTIME} /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip + +RUN mkdir ${ANTLR_RUNTIME}/build +WORKDIR ${ANTLR_RUNTIME}/build + +RUN cmake .. -DANTLR_JAR_LOCATION="${ANTLR_EXECUTABLE}" \ + -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_DEMO=True && \ + make && make install + + +WORKDIR ${PG_SRC} + +RUN ./configure CFLAGS="${CFLAGS:--Wall -ggdb -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic}" \ + --prefix=${PREFIX} \ + --enable-debug \ + --with-ldap \ + --with-libxml \ + --with-pam \ + --with-uuid=ossp \ + --enable-nls \ + --with-libxslt \ + --with-icu + +# Engine Compilation +RUN make clean && make DESTDIR=${PREFIX}/tmp_install -j ${MAX_JOBS} world-bin && make install + +WORKDIR ${PG_SRC}/contrib +# Built-in contrib installation +RUN make +RUN make install + +RUN cp /usr/local/lib/libantlr4-runtime.so.${ANTLR_VERSION} ${PREFIX}/lib + +ENV USE_PGXS=1 + +RUN ["/usr/bin/bash", "-c", "cd ${PG_SRC}/contrib/babelfishpg_tsql/antlr ; cmake . "] + +RUN PG_CONFIG=${PG_CONFIG} PG_SRC=${PG_SRC} cmake=$(which cmake) ANTLR4_RUNTIME_LIBRARIES=/usr/include/antlr4-runtime ; \ + for EXT in babelfishpg_common babelfishpg_money babelfishpg_tds babelfishpg_tsql ; \ + do \ + cd ${PG_SRC}/contrib/${EXT} ; \ + make clean && make && make install ; \ + done + +RUN yum clean all + +FROM base AS babelfishpg +COPY --from=base ${PREFIX}/ /usr/local/ + +ENV DEBIAN_FRONTEND=noninteractive +ENV PATH="${PREFIX}/bin:${PATH}" +ENV PGDATA="/var/lib/postgresql/data" +ENV DOCKER_ENTRYPOINT="/usr/local/bin/entrypoint.sh" + + +RUN yum update -y \ + yum install -y uuid pkgconfig.x86_64 openssl \ + libicu perl openldap.x86_64 libxslt.x86_64 \ + shadow-utils libuuid-devel openldap pam gettext + + +# Create postgres user +RUN useradd postgres && usermod -a -G postgres postgres + +# Sample default ready for Babelfish to run +RUN set -eux; \ + sed -ri "s!^#?(listen_addresses)\s*=\s*\S+.*!\1 = '*'!" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + sed -ri "s+#?shared_preload_libraries.*+shared_preload_libraries = 'babelfishpg_tds'+g" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + sed -i -e "\$ababelfishpg_tds.listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "shared_preload_libraries = 'babelfishpg_tds'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "babelfishpg_tds.listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; + +RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" + +COPY entrypoint.sh ${DOCKER_ENTRYPOINT} + +RUN chmod -R 0750 "${PREFIX}/share" && \ + chown postgres: ${DOCKER_ENTRYPOINT} && \ + chmod +x ${DOCKER_ENTRYPOINT} && \ + chown -R postgres: ${PREFIX} + +WORKDIR "${PREFIX}/bin/" + +RUN yum clean all && rm -rf /var/cache/yum + +USER postgres + +STOPSIGNAL SIGINT + +EXPOSE 1433 +EXPOSE 5432 + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] + +CMD ["postgres"] diff --git a/docker-compose.yml b/2.1.1/amazonlinux/2/docker-compose.yml similarity index 64% rename from docker-compose.yml rename to 2.1.1/amazonlinux/2/docker-compose.yml index 912a591..f700c29 100644 --- a/docker-compose.yml +++ b/2.1.1/amazonlinux/2/docker-compose.yml @@ -1,16 +1,11 @@ version: "3" services: - babelfishpg-ubuntu-focal: - container_name: babelfishpg-ubuntu-focal - build: - context: . - dockerfile: Dockerfile.ubuntu-focal - args: - buildno: 1 - MAX_JOBS: 4 - image: babelfishpg:ubuntu.focal + babelfishpg-2.1.1-amazonlinux-2: + container_name: babelfishpg-2.1.1-amazonlinux.2 + image: babelfishpg:2.1.1-amazonlinux.2 ports: + # Port forwarding not supported by BabelfishPG - 1433:1433 - 5432:15432 environment: diff --git a/2.1.1/amazonlinux/2/entrypoint.sh b/2.1.1/amazonlinux/2/entrypoint.sh new file mode 100644 index 0000000..d20597c --- /dev/null +++ b/2.1.1/amazonlinux/2/entrypoint.sh @@ -0,0 +1,380 @@ +#!/usr/bin/env bash +set -Eeo pipefail +# TODO swap to -Eeuo pipefail above (after handling all potentially-unset variables) + +# usage: file_env VAR [DEFAULT] +# ie: file_env 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(< "${!fileVar}")" + fi + export "$var"="$val" + unset "$fileVar" +} + +# check to see if this file is being run or sourced from another script +_is_sourced() { + # https://unix.stackexchange.com/a/215279 + [ "${#FUNCNAME[@]}" -ge 2 ] \ + && [ "${FUNCNAME[0]}" = '_is_sourced' ] \ + && [ "${FUNCNAME[1]}" = 'source' ] +} + +# used to create initial postgres directories and if run as root, ensure ownership to the "postgres" user +docker_create_db_directories() { + local user; user="$(id -u)" + + mkdir -p "$PGDATA" + # ignore failure since there are cases where we can't chmod (and PostgreSQL might fail later anyhow - it's picky about permissions of this directory) + chmod 700 "$PGDATA" || : + + # ignore failure since it will be fine when using the image provided directory; see also https://github.com/docker-library/postgres/pull/289 + mkdir -p /var/run/postgresql || : + chmod 775 /var/run/postgresql || : + + # Create the transaction log directory before initdb is run so the directory is owned by the correct user + if [ -n "$POSTGRES_INITDB_WALDIR" ]; then + mkdir -p "$POSTGRES_INITDB_WALDIR" + if [ "$user" = '0' ]; then + find "$POSTGRES_INITDB_WALDIR" \! -user postgres -exec chown postgres '{}' + + fi + chmod 700 "$POSTGRES_INITDB_WALDIR" + fi + + # allow the container to be started with `--user` + if [ "$user" = '0' ]; then + find "$PGDATA" \! -user postgres -exec chown postgres '{}' + + find /var/run/postgresql \! -user postgres -exec chown postgres '{}' + + fi +} + +# initialize empty PGDATA directory with new database via 'initdb' +# arguments to `initdb` can be passed via POSTGRES_INITDB_ARGS or as arguments to this function +# `initdb` automatically creates the "postgres", "template0", and "template1" dbnames +# this is also where the database user is created, specified by `POSTGRES_USER` env +docker_init_database_dir() { + # "initdb" is particular about the current user existing in "/etc/passwd", so we use "nss_wrapper" to fake that if necessary + # see https://github.com/docker-library/postgres/pull/253, https://github.com/docker-library/postgres/issues/359, https://cwrap.org/nss_wrapper.html + local uid; uid="$(id -u)" + if ! getent passwd "$uid" &> /dev/null; then + # see if we can find a suitable "libnss_wrapper.so" (https://salsa.debian.org/sssd-team/nss-wrapper/-/commit/b9925a653a54e24d09d9b498a2d913729f7abb15) + local wrapper + for wrapper in {/usr,}/lib{/*,}/libnss_wrapper.so; do + if [ -s "$wrapper" ]; then + NSS_WRAPPER_PASSWD="$(mktemp)" + NSS_WRAPPER_GROUP="$(mktemp)" + export LD_PRELOAD="$wrapper" NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP + local gid; gid="$(id -g)" + echo "postgres:x:$uid:$gid:PostgreSQL:$PGDATA:/bin/false" > "$NSS_WRAPPER_PASSWD" + echo "postgres:x:$gid:" > "$NSS_WRAPPER_GROUP" + break + fi + done + fi + + if [ -n "$POSTGRES_INITDB_WALDIR" ]; then + set -- --waldir "$POSTGRES_INITDB_WALDIR" "$@" + fi + + # Babelfish supports UTF-8 only + eval 'initdb --username="$POSTGRES_USER" --pwfile=<(echo "$POSTGRES_PASSWORD") -E "UTF8" '"$POSTGRES_INITDB_ARGS"' "$@"' + + # unset/cleanup "nss_wrapper" bits + if [ "${LD_PRELOAD:-}" = '/usr/lib/libnss_wrapper.so' ]; then + rm -f "$NSS_WRAPPER_PASSWD" "$NSS_WRAPPER_GROUP" + unset LD_PRELOAD NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP + fi +} + +# print large warning if POSTGRES_PASSWORD is long +# error if both POSTGRES_PASSWORD is empty and POSTGRES_HOST_AUTH_METHOD is not 'trust' +# print large warning if POSTGRES_HOST_AUTH_METHOD is set to 'trust' +# assumes database is not set up, ie: [ -z "$DATABASE_ALREADY_EXISTS" ] +docker_verify_minimum_env() { + # check password first so we can output the warning before postgres + # messes it up + if [ "${#POSTGRES_PASSWORD}" -ge 100 ]; then + cat >&2 <<-'EOWARN' + + WARNING: The supplied POSTGRES_PASSWORD is 100+ characters. + + This will not work if used via PGPASSWORD with "psql". + + https://www.postgresql.org/message-id/flat/E1Rqxp2-0004Qt-PL%40wrigleys.postgresql.org (BUG #6412) + https://github.com/docker-library/postgres/issues/507 + + EOWARN + fi + if [ -z "$POSTGRES_PASSWORD" ] && [ 'trust' != "$POSTGRES_HOST_AUTH_METHOD" ]; then + # The - option suppresses leading tabs but *not* spaces. :) + cat >&2 <<-'EOE' + Error: Database is uninitialized and superuser password is not specified. + You must specify POSTGRES_PASSWORD to a non-empty value for the + superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run". + + You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all + connections without a password. This is *not* recommended. + + See PostgreSQL documentation about "trust": + https://www.postgresql.org/docs/current/auth-trust.html + EOE + exit 1 + fi + if [ 'trust' = "$POSTGRES_HOST_AUTH_METHOD" ]; then + cat >&2 <<-'EOWARN' + ******************************************************************************** + WARNING: POSTGRES_HOST_AUTH_METHOD has been set to "trust". This will allow + anyone with access to the Postgres port to access your database without + a password, even if POSTGRES_PASSWORD is set. See PostgreSQL + documentation about "trust": + https://www.postgresql.org/docs/current/auth-trust.html + In Docker's default configuration, this is effectively any other + container on the same system. + + It is not recommended to use POSTGRES_HOST_AUTH_METHOD=trust. Replace + it with "-e POSTGRES_PASSWORD=password" instead to set a password in + "docker run". + ******************************************************************************** + EOWARN + fi +} + +# usage: docker_process_init_files [file [file [...]]] +# ie: docker_process_init_files /always-initdb.d/* +# process initializer files, based on file extensions and permissions +docker_process_init_files() { + # psql here for backwards compatibility "${psql[@]}" + psql=( docker_process_sql ) + + echo + local f + for f; do + case "$f" in + *.sh) + # https://github.com/docker-library/postgres/issues/450#issuecomment-393167936 + # https://github.com/docker-library/postgres/pull/452 + if [ -x "$f" ]; then + echo "$0: running $f" + "$f" + else + echo "$0: sourcing $f" + . "$f" + fi + ;; + *.sql) echo "$0: running $f"; docker_process_sql -f "$f"; echo ;; + *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | docker_process_sql; echo ;; + *.sql.xz) echo "$0: running $f"; xzcat "$f" | docker_process_sql; echo ;; + *) echo "$0: ignoring $f" ;; + esac + echo + done +} + +# Execute sql script, passed via stdin (or -f flag of pqsl) +# usage: docker_process_sql [psql-cli-args] +# ie: docker_process_sql --dbname=mydb <<<'INSERT ...' +# ie: docker_process_sql -f my-file.sql +# ie: docker_process_sql > $PGDATA/postgresql.conf + + docker_process_sql --dbname $POSTGRES_DB -c 'select pg_reload_conf();' +} + +# Loads various settings that are used elsewhere in the script +# This should be called before any other functions +docker_setup_env() { + file_env 'POSTGRES_PASSWORD' + + file_env 'POSTGRES_USER' 'postgres' + file_env 'POSTGRES_DB' "$POSTGRES_USER" + file_env 'BABELFISH_MIGRATION_MODE' 'single-db' + file_env 'BABELFISH_MIGRATION_MODE' "$BABELFISH_MIGRATION_MODE" + file_env 'POSTGRES_INITDB_ARGS' + : "${POSTGRES_HOST_AUTH_METHOD:=}" + + declare -g DATABASE_ALREADY_EXISTS + # look specifically for PG_VERSION, as it is expected in the DB dir + if [ -s "$PGDATA/PG_VERSION" ]; then + DATABASE_ALREADY_EXISTS='true' + fi +} + +# append POSTGRES_HOST_AUTH_METHOD to pg_hba.conf for "host" connections +# all arguments will be passed along as arguments to `postgres` for getting the value of 'password_encryption' +pg_setup_hba_conf() { + # default authentication method is md5 on versions before 14 + # https://www.postgresql.org/about/news/postgresql-14-released-2318/ + if [ "$1" = 'postgres' ]; then + shift + fi + local auth + # check the default/configured encryption and use that as the auth method + auth="$(postgres -C password_encryption "$@")" + # postgres 9 only reports "on" and not "md5" + if [ "$auth" = 'on' ]; then + auth='md5' + fi + : "${POSTGRES_HOST_AUTH_METHOD:=$auth}" + { + echo + if [ 'trust' = "$POSTGRES_HOST_AUTH_METHOD" ]; then + echo '# warning trust is enabled for all connections' + echo '# see https://www.postgresql.org/docs/12/auth-trust.html' + fi + echo "host all all all $POSTGRES_HOST_AUTH_METHOD" + } >> "$PGDATA/pg_hba.conf" +} + +# start socket-only postgresql server for setting up or running scripts +# all arguments will be passed along as arguments to `postgres` (via pg_ctl) +docker_temp_server_start() { + if [ "$1" = 'postgres' ]; then + shift + fi + + # internal start of server in order to allow setup using psql client + # does not listen on external TCP/IP and waits until start finishes + set -- "$@" -c listen_addresses='' -p "${PGPORT:-5432}" + + PGUSER="${PGUSER:-$POSTGRES_USER}" \ + pg_ctl -D "$PGDATA" \ + -o "$(printf '%q ' "$@")" \ + -w start +} + +# stop postgresql server after done setting up user and running scripts +docker_temp_server_stop() { + PGUSER="${PGUSER:-postgres}" \ + pg_ctl -D "$PGDATA" -m fast -w stop +} + +# check arguments for an option that would cause postgres to stop +# return true if there is one +_pg_want_help() { + local arg + for arg; do + case "$arg" in + # postgres --help | grep 'then exit' + # leaving out -C on purpose since it always fails and is unhelpful: + # postgres: could not access the server configuration file "/var/lib/postgresql/data/postgresql.conf": No such file or directory + -'?'|--help|--describe-config|-V|--version) + return 0 + ;; + esac + done + return 1 +} + +_main() { + # if first arg looks like a flag, assume we want to run postgres server + if [ "${1:0:1}" = '-' ]; then + set -- postgres "$@" + fi + + if [ "$1" = 'postgres' ] && ! _pg_want_help "$@"; then + docker_setup_env + # setup data directories and permissions (when run as root) + docker_create_db_directories + if [ "$(id -u)" = '0' ]; then + # then restart script as postgres user + exec gosu postgres "$BASH_SOURCE" "$@" + fi + + # only run initialization on an empty data directory + if [ -z "$DATABASE_ALREADY_EXISTS" ]; then + docker_verify_minimum_env + + # check dir permissions to reduce likelihood of half-initialized database + #ls /docker-entrypoint-initdb.d/ > /dev/null + + docker_init_database_dir + pg_setup_hba_conf "$@" + + # PGPASSWORD is required for psql when authentication is required for 'local' connections via pg_hba.conf and is otherwise harmless + # e.g. when '--auth=md5' or '--auth-local=md5' is used in POSTGRES_INITDB_ARGS + export PGPASSWORD="${PGPASSWORD:-$POSTGRES_PASSWORD}" + docker_temp_server_start "$@" + + docker_setup_db + + docker_setup_babelfish_db + + docker_process_init_files /docker-entrypoint-initdb.d/* + + docker_temp_server_stop + unset PGPASSWORD + + echo + echo 'PostgreSQL init process complete; ready for start up.' + echo + else + echo + echo 'PostgreSQL Database directory appears to contain a database; Skipping initialization' + echo + fi + fi + + exec "$@" +} + +if ! _is_sourced; then + _main "$@" +fi \ No newline at end of file diff --git a/2.1.1/ubuntu/focal/Dockerfile b/2.1.1/ubuntu/focal/Dockerfile new file mode 100644 index 0000000..0bb6fdb --- /dev/null +++ b/2.1.1/ubuntu/focal/Dockerfile @@ -0,0 +1,181 @@ + +# +# Autogenerated files, do not edit. See README.md +# + + +FROM ubuntu:focal as base +LABEL org.opencontainers.image.authors="emanuel@ongres.com" + +ARG MAX_JOBS +ENV TAG=BABEL_2_1_1__PG_14_3 +ENV BABELFISH_VERSION=2.1.1 +ENV MAX_JOBS=${MAX_JOBS:-2} +ENV ANTLR_VERSION=4.9.3 + +ENV PREFIX=/usr/local/babelfishpg-${BABELFISH_VERSION} +ENV ANTLR_RUNTIME=/opt/antlr4 + +ENV PG_SRC=/opt/${TAG}/ +ENV PG_CONFIG=${PREFIX}/bin/pg_config +ENV ANTLR4_RUNTIME_INCLUDE_DIR=/usr/local/include/antlr4-runtime/ + +ENV ANTLR4_JAVA_BIN=/usr/bin/java + +RUN set -ex; \ + apt update + +RUN set -ex ; \ + DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \ + build-essential flex libxml2-dev libxml2-utils libc6-dev \ + libxslt-dev libssl-dev \ + libreadline-dev zlib1g-dev libldap2-dev libpam0g-dev gettext \ + uuid uuid-dev cmake lld apt-utils pkg-config libossp-uuid-dev gnulib bison git + +RUN set -ex ; \ + DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \ + xsltproc icu-devtools libicu66 libicu-dev gawk curl + +RUN set -ex ; \ + DEBIAN_FRONTEND=noninteractive \ + apt install -y openjdk-8-jre openssl \ + libssl-dev python-dev libpq-dev \ + pkgconf unzip libutfcpp-dev gnupg + +RUN sysArch=$(uname -m) + +# SQL Server Tooling dependencies +# Reference: https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-setup-tools?view=sql-server-ver15#ubuntu +# For non-amd64 mssql-tools isn't available, installing freetds in its place +RUN set -ex ; \ + case "$sysArch" in \ + x86_64 | amd64 | ppc64el) \ + curl -L https://packages.microsoft.com/keys/microsoft.asc | apt-key add - && \ + curl -L https://packages.microsoft.com/config/ubuntu/20.04/prod.list | tee /etc/apt/sources.list.d/msprod.list && \ + apt update && ACCEPT_EULA=Y apt install -y mssql-tools unixodbc-dev ; \ + PATH="${PREFIX}/bin:/opt/mssql-tools/bin/:${PATH}" ;; \ + * ) \ + DEBIAN_FRONTEND=noninteractive \ + apt install -y freetds-bin freetds-common ;; \ + esac ; + + + +RUN rm -rf /var/lib/apt/lists/*; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; + + +RUN curl -L https://github.com/babelfish-for-postgresql/babelfish-for-postgresql/releases/download/${TAG}/${TAG}.zip \ + --output ${TAG}.zip && unzip -d /opt/ ${TAG}.zip + +# Compiling and installing antlr runtime +# ENV ANTLR_EXECUTABLE=/usr/local/lib/antlr-${ANTLR_VERSION}-complete.jar +ENV ANTLR_EXECUTABLE=${PG_SRC}/contrib/babelfishpg_tsql/antlr/thirdparty/antlr/antlr-${ANTLR_VERSION}-complete.jar + +# RUN curl https://www.antlr.org/download/antlr-${ANTLR_VERSION}-complete.jar \ +# --output ${ANTLR_EXECUTABLE} && chmod +x ${ANTLR_EXECUTABLE} + +RUN curl https://www.antlr.org/download/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip \ + --output /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip && \ + unzip -d ${ANTLR_RUNTIME} /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip + +WORKDIR ${ANTLR_RUNTIME} + +RUN mkdir build && cd build && \ + cmake .. -D ANTLR_JAR_LOCATION=${ANTLR_EXECUTABLE} \ + -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_DEMO=True && \ + make && make install + + +WORKDIR ${PG_SRC} + +RUN set -ex ; \ + case "$sysArch" in \ + x86_64 | amd64 | ppc64el) \ + CFLAGS_ARG='${CFLAGS:--Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic}' ; \ + CONFIGURE_FLAGS="" ;; \ + * ) \ + CFLAGS_ARG="-ggdb " CONFIGURE_FLAGS=' --build=arm-linux-gnueabihf ';; \ + esac ; \ + ./configure CFLAGS="${CFLAGS_ARG}" \ + --prefix=${PREFIX} \ + --enable-debug \ + --with-ldap \ + --with-libxml \ + --with-pam \ + --with-uuid=ossp \ + --enable-nls \ + --with-libxslt \ + --with-icu ${CONFIGURE_FLAGS} + + +# Engine Compilation +RUN make clean && make DESTDIR=${PREFIX}/tmp_install -j ${MAX_JOBS} world-bin && make install + +WORKDIR ${PG_SRC}/contrib +# Built-in contrib installation +RUN make +RUN make install + +## Regression Tests +# RUN make DESTDIR=${PREFIX}/tmp_install EXTRA_REGRESS_OPTS=--debug -j ${MAX_JOBS} check + +RUN cp /usr/local/lib/libantlr4-runtime.so.${ANTLR_VERSION} ${PREFIX}/lib + +ENV USE_PGXS=1 + +RUN ["/usr/bin/bash", "-c", "cd ${PG_SRC}/contrib/babelfishpg_tsql/antlr ; cmake . "] + +RUN PG_CONFIG=${PG_CONFIG} PG_SRC=${PG_SRC} cmake=$(which cmake) ANTLR4_RUNTIME_LIBRARIES=/usr/include/antlr4-runtime ; \ + for EXT in babelfishpg_common babelfishpg_money babelfishpg_tds babelfishpg_tsql ; \ + do \ + cd ${PG_SRC}/contrib/${EXT} ; \ + make clean && make && make install ; \ + done + +FROM base AS babelfishpg +COPY --from=base ${PREFIX}/ /usr/local/ /opt/mssql-tools/bin/ + +ENV DEBIAN_FRONTEND=noninteractive +ENV PATH="${PREFIX}/bin:${PATH}" +ENV PGDATA="/var/lib/postgresql/data" +ENV DOCKER_ENTRYPOINT="/usr/local/bin/entrypoint.sh" + +RUN apt-get update && \ + apt-get install -y libxml2 libreadline8 tzdata libldap-2.4-2 libpython2.7 libxslt1.1 libossp-uuid16 && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Create postgres user +RUN useradd postgres && usermod -a -G postgres postgres + +# Sample default ready for Babelfish to run +RUN set -eux; \ + sed -ri "s!^#?(listen_addresses)\s*=\s*\S+.*!\1 = '*'!" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + sed -ri "s+#?shared_preload_libraries.*+shared_preload_libraries = 'babelfishpg_tds'+g" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + sed -i -e "\$ababelfishpg_tds.listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "shared_preload_libraries = 'babelfishpg_tds'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "babelfishpg_tds.listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; + +RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" + +COPY entrypoint.sh ${DOCKER_ENTRYPOINT} + +RUN chmod -R 0750 "${PREFIX}/share" && \ + chown postgres: ${DOCKER_ENTRYPOINT} && \ + chmod +x ${DOCKER_ENTRYPOINT} && \ + chown -R postgres: ${PREFIX} + +WORKDIR "${PREFIX}/bin/" + +USER postgres + +STOPSIGNAL SIGINT + +EXPOSE 1433 +EXPOSE 5432 + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] + +CMD ["postgres"] diff --git a/2.1.1/ubuntu/focal/docker-compose.yml b/2.1.1/ubuntu/focal/docker-compose.yml new file mode 100644 index 0000000..5bc270d --- /dev/null +++ b/2.1.1/ubuntu/focal/docker-compose.yml @@ -0,0 +1,25 @@ +version: "3" + +services: + babelfishpg-2.1.1-ubuntu-focal: + container_name: babelfishpg-2.1.1-ubuntu.focal + image: babelfishpg:2.1.1-ubuntu.focal + ports: + # Port forwarding not supported by BabelfishPG + - 1433:1433 + - 5432:15432 + environment: + - POSTGRES_PASSWORD=password + - POSTGRES_DB=postgres + - POSTGRES_USER=postgres + - BABELFISH_USER=bbf + - BABELFISH_PASS=password + - BABELFISH_DB=bbf + - BABELFISH_MIGRATION_MODE=multi-db + - POSTGRES_HOST_AUTH_METHOD=trust + networks: + - babelfish + +networks: + babelfish: + \ No newline at end of file diff --git a/2.1.1/ubuntu/focal/entrypoint.sh b/2.1.1/ubuntu/focal/entrypoint.sh new file mode 100644 index 0000000..d20597c --- /dev/null +++ b/2.1.1/ubuntu/focal/entrypoint.sh @@ -0,0 +1,380 @@ +#!/usr/bin/env bash +set -Eeo pipefail +# TODO swap to -Eeuo pipefail above (after handling all potentially-unset variables) + +# usage: file_env VAR [DEFAULT] +# ie: file_env 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(< "${!fileVar}")" + fi + export "$var"="$val" + unset "$fileVar" +} + +# check to see if this file is being run or sourced from another script +_is_sourced() { + # https://unix.stackexchange.com/a/215279 + [ "${#FUNCNAME[@]}" -ge 2 ] \ + && [ "${FUNCNAME[0]}" = '_is_sourced' ] \ + && [ "${FUNCNAME[1]}" = 'source' ] +} + +# used to create initial postgres directories and if run as root, ensure ownership to the "postgres" user +docker_create_db_directories() { + local user; user="$(id -u)" + + mkdir -p "$PGDATA" + # ignore failure since there are cases where we can't chmod (and PostgreSQL might fail later anyhow - it's picky about permissions of this directory) + chmod 700 "$PGDATA" || : + + # ignore failure since it will be fine when using the image provided directory; see also https://github.com/docker-library/postgres/pull/289 + mkdir -p /var/run/postgresql || : + chmod 775 /var/run/postgresql || : + + # Create the transaction log directory before initdb is run so the directory is owned by the correct user + if [ -n "$POSTGRES_INITDB_WALDIR" ]; then + mkdir -p "$POSTGRES_INITDB_WALDIR" + if [ "$user" = '0' ]; then + find "$POSTGRES_INITDB_WALDIR" \! -user postgres -exec chown postgres '{}' + + fi + chmod 700 "$POSTGRES_INITDB_WALDIR" + fi + + # allow the container to be started with `--user` + if [ "$user" = '0' ]; then + find "$PGDATA" \! -user postgres -exec chown postgres '{}' + + find /var/run/postgresql \! -user postgres -exec chown postgres '{}' + + fi +} + +# initialize empty PGDATA directory with new database via 'initdb' +# arguments to `initdb` can be passed via POSTGRES_INITDB_ARGS or as arguments to this function +# `initdb` automatically creates the "postgres", "template0", and "template1" dbnames +# this is also where the database user is created, specified by `POSTGRES_USER` env +docker_init_database_dir() { + # "initdb" is particular about the current user existing in "/etc/passwd", so we use "nss_wrapper" to fake that if necessary + # see https://github.com/docker-library/postgres/pull/253, https://github.com/docker-library/postgres/issues/359, https://cwrap.org/nss_wrapper.html + local uid; uid="$(id -u)" + if ! getent passwd "$uid" &> /dev/null; then + # see if we can find a suitable "libnss_wrapper.so" (https://salsa.debian.org/sssd-team/nss-wrapper/-/commit/b9925a653a54e24d09d9b498a2d913729f7abb15) + local wrapper + for wrapper in {/usr,}/lib{/*,}/libnss_wrapper.so; do + if [ -s "$wrapper" ]; then + NSS_WRAPPER_PASSWD="$(mktemp)" + NSS_WRAPPER_GROUP="$(mktemp)" + export LD_PRELOAD="$wrapper" NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP + local gid; gid="$(id -g)" + echo "postgres:x:$uid:$gid:PostgreSQL:$PGDATA:/bin/false" > "$NSS_WRAPPER_PASSWD" + echo "postgres:x:$gid:" > "$NSS_WRAPPER_GROUP" + break + fi + done + fi + + if [ -n "$POSTGRES_INITDB_WALDIR" ]; then + set -- --waldir "$POSTGRES_INITDB_WALDIR" "$@" + fi + + # Babelfish supports UTF-8 only + eval 'initdb --username="$POSTGRES_USER" --pwfile=<(echo "$POSTGRES_PASSWORD") -E "UTF8" '"$POSTGRES_INITDB_ARGS"' "$@"' + + # unset/cleanup "nss_wrapper" bits + if [ "${LD_PRELOAD:-}" = '/usr/lib/libnss_wrapper.so' ]; then + rm -f "$NSS_WRAPPER_PASSWD" "$NSS_WRAPPER_GROUP" + unset LD_PRELOAD NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP + fi +} + +# print large warning if POSTGRES_PASSWORD is long +# error if both POSTGRES_PASSWORD is empty and POSTGRES_HOST_AUTH_METHOD is not 'trust' +# print large warning if POSTGRES_HOST_AUTH_METHOD is set to 'trust' +# assumes database is not set up, ie: [ -z "$DATABASE_ALREADY_EXISTS" ] +docker_verify_minimum_env() { + # check password first so we can output the warning before postgres + # messes it up + if [ "${#POSTGRES_PASSWORD}" -ge 100 ]; then + cat >&2 <<-'EOWARN' + + WARNING: The supplied POSTGRES_PASSWORD is 100+ characters. + + This will not work if used via PGPASSWORD with "psql". + + https://www.postgresql.org/message-id/flat/E1Rqxp2-0004Qt-PL%40wrigleys.postgresql.org (BUG #6412) + https://github.com/docker-library/postgres/issues/507 + + EOWARN + fi + if [ -z "$POSTGRES_PASSWORD" ] && [ 'trust' != "$POSTGRES_HOST_AUTH_METHOD" ]; then + # The - option suppresses leading tabs but *not* spaces. :) + cat >&2 <<-'EOE' + Error: Database is uninitialized and superuser password is not specified. + You must specify POSTGRES_PASSWORD to a non-empty value for the + superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run". + + You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all + connections without a password. This is *not* recommended. + + See PostgreSQL documentation about "trust": + https://www.postgresql.org/docs/current/auth-trust.html + EOE + exit 1 + fi + if [ 'trust' = "$POSTGRES_HOST_AUTH_METHOD" ]; then + cat >&2 <<-'EOWARN' + ******************************************************************************** + WARNING: POSTGRES_HOST_AUTH_METHOD has been set to "trust". This will allow + anyone with access to the Postgres port to access your database without + a password, even if POSTGRES_PASSWORD is set. See PostgreSQL + documentation about "trust": + https://www.postgresql.org/docs/current/auth-trust.html + In Docker's default configuration, this is effectively any other + container on the same system. + + It is not recommended to use POSTGRES_HOST_AUTH_METHOD=trust. Replace + it with "-e POSTGRES_PASSWORD=password" instead to set a password in + "docker run". + ******************************************************************************** + EOWARN + fi +} + +# usage: docker_process_init_files [file [file [...]]] +# ie: docker_process_init_files /always-initdb.d/* +# process initializer files, based on file extensions and permissions +docker_process_init_files() { + # psql here for backwards compatibility "${psql[@]}" + psql=( docker_process_sql ) + + echo + local f + for f; do + case "$f" in + *.sh) + # https://github.com/docker-library/postgres/issues/450#issuecomment-393167936 + # https://github.com/docker-library/postgres/pull/452 + if [ -x "$f" ]; then + echo "$0: running $f" + "$f" + else + echo "$0: sourcing $f" + . "$f" + fi + ;; + *.sql) echo "$0: running $f"; docker_process_sql -f "$f"; echo ;; + *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | docker_process_sql; echo ;; + *.sql.xz) echo "$0: running $f"; xzcat "$f" | docker_process_sql; echo ;; + *) echo "$0: ignoring $f" ;; + esac + echo + done +} + +# Execute sql script, passed via stdin (or -f flag of pqsl) +# usage: docker_process_sql [psql-cli-args] +# ie: docker_process_sql --dbname=mydb <<<'INSERT ...' +# ie: docker_process_sql -f my-file.sql +# ie: docker_process_sql > $PGDATA/postgresql.conf + + docker_process_sql --dbname $POSTGRES_DB -c 'select pg_reload_conf();' +} + +# Loads various settings that are used elsewhere in the script +# This should be called before any other functions +docker_setup_env() { + file_env 'POSTGRES_PASSWORD' + + file_env 'POSTGRES_USER' 'postgres' + file_env 'POSTGRES_DB' "$POSTGRES_USER" + file_env 'BABELFISH_MIGRATION_MODE' 'single-db' + file_env 'BABELFISH_MIGRATION_MODE' "$BABELFISH_MIGRATION_MODE" + file_env 'POSTGRES_INITDB_ARGS' + : "${POSTGRES_HOST_AUTH_METHOD:=}" + + declare -g DATABASE_ALREADY_EXISTS + # look specifically for PG_VERSION, as it is expected in the DB dir + if [ -s "$PGDATA/PG_VERSION" ]; then + DATABASE_ALREADY_EXISTS='true' + fi +} + +# append POSTGRES_HOST_AUTH_METHOD to pg_hba.conf for "host" connections +# all arguments will be passed along as arguments to `postgres` for getting the value of 'password_encryption' +pg_setup_hba_conf() { + # default authentication method is md5 on versions before 14 + # https://www.postgresql.org/about/news/postgresql-14-released-2318/ + if [ "$1" = 'postgres' ]; then + shift + fi + local auth + # check the default/configured encryption and use that as the auth method + auth="$(postgres -C password_encryption "$@")" + # postgres 9 only reports "on" and not "md5" + if [ "$auth" = 'on' ]; then + auth='md5' + fi + : "${POSTGRES_HOST_AUTH_METHOD:=$auth}" + { + echo + if [ 'trust' = "$POSTGRES_HOST_AUTH_METHOD" ]; then + echo '# warning trust is enabled for all connections' + echo '# see https://www.postgresql.org/docs/12/auth-trust.html' + fi + echo "host all all all $POSTGRES_HOST_AUTH_METHOD" + } >> "$PGDATA/pg_hba.conf" +} + +# start socket-only postgresql server for setting up or running scripts +# all arguments will be passed along as arguments to `postgres` (via pg_ctl) +docker_temp_server_start() { + if [ "$1" = 'postgres' ]; then + shift + fi + + # internal start of server in order to allow setup using psql client + # does not listen on external TCP/IP and waits until start finishes + set -- "$@" -c listen_addresses='' -p "${PGPORT:-5432}" + + PGUSER="${PGUSER:-$POSTGRES_USER}" \ + pg_ctl -D "$PGDATA" \ + -o "$(printf '%q ' "$@")" \ + -w start +} + +# stop postgresql server after done setting up user and running scripts +docker_temp_server_stop() { + PGUSER="${PGUSER:-postgres}" \ + pg_ctl -D "$PGDATA" -m fast -w stop +} + +# check arguments for an option that would cause postgres to stop +# return true if there is one +_pg_want_help() { + local arg + for arg; do + case "$arg" in + # postgres --help | grep 'then exit' + # leaving out -C on purpose since it always fails and is unhelpful: + # postgres: could not access the server configuration file "/var/lib/postgresql/data/postgresql.conf": No such file or directory + -'?'|--help|--describe-config|-V|--version) + return 0 + ;; + esac + done + return 1 +} + +_main() { + # if first arg looks like a flag, assume we want to run postgres server + if [ "${1:0:1}" = '-' ]; then + set -- postgres "$@" + fi + + if [ "$1" = 'postgres' ] && ! _pg_want_help "$@"; then + docker_setup_env + # setup data directories and permissions (when run as root) + docker_create_db_directories + if [ "$(id -u)" = '0' ]; then + # then restart script as postgres user + exec gosu postgres "$BASH_SOURCE" "$@" + fi + + # only run initialization on an empty data directory + if [ -z "$DATABASE_ALREADY_EXISTS" ]; then + docker_verify_minimum_env + + # check dir permissions to reduce likelihood of half-initialized database + #ls /docker-entrypoint-initdb.d/ > /dev/null + + docker_init_database_dir + pg_setup_hba_conf "$@" + + # PGPASSWORD is required for psql when authentication is required for 'local' connections via pg_hba.conf and is otherwise harmless + # e.g. when '--auth=md5' or '--auth-local=md5' is used in POSTGRES_INITDB_ARGS + export PGPASSWORD="${PGPASSWORD:-$POSTGRES_PASSWORD}" + docker_temp_server_start "$@" + + docker_setup_db + + docker_setup_babelfish_db + + docker_process_init_files /docker-entrypoint-initdb.d/* + + docker_temp_server_stop + unset PGPASSWORD + + echo + echo 'PostgreSQL init process complete; ready for start up.' + echo + else + echo + echo 'PostgreSQL Database directory appears to contain a database; Skipping initialization' + echo + fi + fi + + exec "$@" +} + +if ! _is_sourced; then + _main "$@" +fi \ No newline at end of file diff --git a/4.1.0/ubuntu/focal/Dockerfile b/4.1.0/ubuntu/focal/Dockerfile new file mode 100644 index 0000000..029d262 --- /dev/null +++ b/4.1.0/ubuntu/focal/Dockerfile @@ -0,0 +1,183 @@ + +# +# Autogenerated files, do not edit. See README.md +# + + +FROM ubuntu:focal as base +LABEL org.opencontainers.image.authors="emanuel@ongres.com" + +ARG MAX_JOBS +ENV TAG=BABEL_4_1_0__PG_16_2 +ENV BABELFISH_VERSION=4.1.0 +ENV MAX_JOBS=${MAX_JOBS:-2} +ENV ANTLR_VERSION=4.9.3 + +ENV PREFIX=/usr/local/babelfishpg-${BABELFISH_VERSION} +ENV ANTLR_RUNTIME=/opt/antlr4 + +ENV PG_SRC=/opt/${TAG}/ +ENV PG_CONFIG=${PREFIX}/bin/pg_config +ENV ANTLR4_RUNTIME_INCLUDE_DIR=/usr/local/include/antlr4-runtime/ + +ENV ANTLR4_JAVA_BIN=/usr/bin/java + +RUN set -ex; \ + apt update + +RUN set -ex ; \ + DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \ + build-essential flex libxml2-dev libxml2-utils libc6-dev \ + libxslt-dev \ + libreadline-dev zlib1g-dev libldap2-dev libpam0g-dev gettext \ + uuid uuid-dev cmake lld apt-utils pkg-config libossp-uuid-dev gnulib bison git + +RUN set -ex ; \ + DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \ + xsltproc icu-devtools libicu66 libicu-dev gawk curl + +RUN set -ex ; \ + DEBIAN_FRONTEND=noninteractive \ + apt install -y openjdk-8-jre openssl \ + libssl-dev python-dev libpq-dev \ + pkgconf unzip libutfcpp-dev gnupg + +RUN sysArch=$(uname -m) + +# SQL Server Tooling dependencies +# Reference: https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-setup-tools?view=sql-server-ver15#ubuntu +# For non-amd64 mssql-tools isn't available, installing freetds in its place +RUN set -ex ; \ + case "$sysArch" in \ + x86_64 | amd64 | ppc64el) \ + curl -L https://packages.microsoft.com/keys/microsoft.asc | apt-key add - && \ + curl -L https://packages.microsoft.com/config/ubuntu/20.04/prod.list | tee /etc/apt/sources.list.d/msprod.list && \ + apt update && ACCEPT_EULA=Y apt install -y mssql-tools unixodbc-dev ; \ + PATH="${PREFIX}/bin:/opt/mssql-tools/bin/:${PATH}" ;; \ + * ) \ + DEBIAN_FRONTEND=noninteractive \ + apt install -y freetds-bin freetds-common ;; \ + esac ; + + + +RUN rm -rf /var/lib/apt/lists/*; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; + + +RUN curl -L https://github.com/babelfish-for-postgresql/babelfish-for-postgresql/releases/download/${TAG}/${TAG}.zip \ + --output ${TAG}.zip && unzip -d /opt/ ${TAG}.zip + +# Compiling and installing antlr runtime +# ENV ANTLR_EXECUTABLE=/usr/local/lib/antlr-${ANTLR_VERSION}-complete.jar +ENV ANTLR_EXECUTABLE=${PG_SRC}/contrib/babelfishpg_tsql/antlr/thirdparty/antlr/antlr-${ANTLR_VERSION}-complete.jar + +# RUN curl https://www.antlr.org/download/antlr-${ANTLR_VERSION}-complete.jar \ +# --output ${ANTLR_EXECUTABLE} && chmod +x ${ANTLR_EXECUTABLE} + +RUN curl https://www.antlr.org/download/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip \ + --output /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip && \ + unzip -d ${ANTLR_RUNTIME} /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip + +WORKDIR ${ANTLR_RUNTIME} + +RUN mkdir build && cd build && \ + cmake .. -D ANTLR_JAR_LOCATION=${ANTLR_EXECUTABLE} \ + -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_DEMO=True && \ + make && make install + + +WORKDIR ${PG_SRC} + +RUN set -ex ; \ + case "$sysArch" in \ + x86_64 | amd64 | ppc64el) \ + CFLAGS_ARG='${CFLAGS:--Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic}' ; \ + CONFIGURE_FLAGS="" ;; \ + * ) \ + CFLAGS_ARG="-ggdb " CONFIGURE_FLAGS=' --build=arm-linux-gnueabihf ';; \ + esac ; \ + ./configure CFLAGS="${CFLAGS_ARG}" \ + --prefix=${PREFIX} \ + --enable-debug \ + --with-ldap \ + --with-libxml \ + --with-pam \ + --with-uuid=ossp \ + --enable-nls \ + --with-libxslt \ + --with-icu ${CONFIGURE_FLAGS} + + # --with-openssl + +# Engine Compilation +RUN make clean && make DESTDIR=${PREFIX}/tmp_install -j ${MAX_JOBS} world-bin && make install + +WORKDIR ${PG_SRC}/contrib +# Built-in contrib installation +RUN make +RUN make install + +## Regression Tests +# RUN make DESTDIR=${PREFIX}/tmp_install EXTRA_REGRESS_OPTS=--debug -j ${MAX_JOBS} check + +RUN cp /usr/local/lib/libantlr4-runtime.so.${ANTLR_VERSION} ${PREFIX}/lib + +ENV USE_PGXS=1 + +RUN ["/usr/bin/bash", "-c", "cd ${PG_SRC}/contrib/babelfishpg_tsql/antlr ; cmake . "] + +RUN PG_CONFIG=${PG_CONFIG} PG_SRC=${PG_SRC} cmake=$(which cmake) ANTLR4_RUNTIME_LIBRARIES=/usr/include/antlr4-runtime ; \ + for EXT in babelfishpg_common babelfishpg_money babelfishpg_tds babelfishpg_tsql ; \ + do \ + cd ${PG_SRC}/contrib/${EXT} ; \ + make clean && make && make install ; \ + done + +FROM base AS babelfishpg +COPY --from=base ${PREFIX}/ /usr/local/ /opt/mssql-tools/bin/ + +ENV DEBIAN_FRONTEND=noninteractive +ENV PATH="${PREFIX}/bin:${PATH}" +ENV PGDATA="/var/lib/postgresql/data" +ENV DOCKER_ENTRYPOINT="/usr/local/bin/entrypoint.sh" + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + libssl1.1 openssl libxml2 libreadline8 tzdata libldap-2.4-2 libpython2.7 libxslt1.1 libossp-uuid16 && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Create postgres user +RUN useradd postgres && usermod -a -G postgres postgres + +# Sample default ready for Babelfish to run +RUN set -eux; \ + sed -ri "s!^#?(listen_addresses)\s*=\s*\S+.*!\1 = '*'!" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + sed -ri "s+#?shared_preload_libraries.*+shared_preload_libraries = 'babelfishpg_tds'+g" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + sed -i -e "\$ababelfishpg_tds.listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "shared_preload_libraries = 'babelfishpg_tds'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "babelfishpg_tds.listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; + +RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" + +COPY entrypoint.sh ${DOCKER_ENTRYPOINT} + +RUN chmod -R 0750 "${PREFIX}/share" && \ + chown postgres: ${DOCKER_ENTRYPOINT} && \ + chmod +x ${DOCKER_ENTRYPOINT} && \ + chown -R postgres: ${PREFIX} + +WORKDIR "${PREFIX}/bin/" + +USER postgres + +STOPSIGNAL SIGINT + +EXPOSE 1433 +EXPOSE 5432 + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] + +CMD ["postgres"] diff --git a/4.1.0/ubuntu/focal/docker-compose.yml b/4.1.0/ubuntu/focal/docker-compose.yml new file mode 100644 index 0000000..39750c1 --- /dev/null +++ b/4.1.0/ubuntu/focal/docker-compose.yml @@ -0,0 +1,25 @@ +version: "3" + +services: + babelfishpg-4.1.0-ubuntu-focal: + container_name: babelfishpg-4.1.0-ubuntu.focal + image: babelfishpg:4.1.0-ubuntu.focal + ports: + # Port forwarding not supported by BabelfishPG + - 1433:1433 + - 5432:15432 + environment: + - POSTGRES_PASSWORD=password + - POSTGRES_DB=postgres + - POSTGRES_USER=postgres + - BABELFISH_USER=bbf + - BABELFISH_PASS=password + - BABELFISH_DB=bbf + - BABELFISH_MIGRATION_MODE=multi-db + - POSTGRES_HOST_AUTH_METHOD=trust + networks: + - babelfish + +networks: + babelfish: + \ No newline at end of file diff --git a/4.1.0/ubuntu/focal/entrypoint.sh b/4.1.0/ubuntu/focal/entrypoint.sh new file mode 100644 index 0000000..d20597c --- /dev/null +++ b/4.1.0/ubuntu/focal/entrypoint.sh @@ -0,0 +1,380 @@ +#!/usr/bin/env bash +set -Eeo pipefail +# TODO swap to -Eeuo pipefail above (after handling all potentially-unset variables) + +# usage: file_env VAR [DEFAULT] +# ie: file_env 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(< "${!fileVar}")" + fi + export "$var"="$val" + unset "$fileVar" +} + +# check to see if this file is being run or sourced from another script +_is_sourced() { + # https://unix.stackexchange.com/a/215279 + [ "${#FUNCNAME[@]}" -ge 2 ] \ + && [ "${FUNCNAME[0]}" = '_is_sourced' ] \ + && [ "${FUNCNAME[1]}" = 'source' ] +} + +# used to create initial postgres directories and if run as root, ensure ownership to the "postgres" user +docker_create_db_directories() { + local user; user="$(id -u)" + + mkdir -p "$PGDATA" + # ignore failure since there are cases where we can't chmod (and PostgreSQL might fail later anyhow - it's picky about permissions of this directory) + chmod 700 "$PGDATA" || : + + # ignore failure since it will be fine when using the image provided directory; see also https://github.com/docker-library/postgres/pull/289 + mkdir -p /var/run/postgresql || : + chmod 775 /var/run/postgresql || : + + # Create the transaction log directory before initdb is run so the directory is owned by the correct user + if [ -n "$POSTGRES_INITDB_WALDIR" ]; then + mkdir -p "$POSTGRES_INITDB_WALDIR" + if [ "$user" = '0' ]; then + find "$POSTGRES_INITDB_WALDIR" \! -user postgres -exec chown postgres '{}' + + fi + chmod 700 "$POSTGRES_INITDB_WALDIR" + fi + + # allow the container to be started with `--user` + if [ "$user" = '0' ]; then + find "$PGDATA" \! -user postgres -exec chown postgres '{}' + + find /var/run/postgresql \! -user postgres -exec chown postgres '{}' + + fi +} + +# initialize empty PGDATA directory with new database via 'initdb' +# arguments to `initdb` can be passed via POSTGRES_INITDB_ARGS or as arguments to this function +# `initdb` automatically creates the "postgres", "template0", and "template1" dbnames +# this is also where the database user is created, specified by `POSTGRES_USER` env +docker_init_database_dir() { + # "initdb" is particular about the current user existing in "/etc/passwd", so we use "nss_wrapper" to fake that if necessary + # see https://github.com/docker-library/postgres/pull/253, https://github.com/docker-library/postgres/issues/359, https://cwrap.org/nss_wrapper.html + local uid; uid="$(id -u)" + if ! getent passwd "$uid" &> /dev/null; then + # see if we can find a suitable "libnss_wrapper.so" (https://salsa.debian.org/sssd-team/nss-wrapper/-/commit/b9925a653a54e24d09d9b498a2d913729f7abb15) + local wrapper + for wrapper in {/usr,}/lib{/*,}/libnss_wrapper.so; do + if [ -s "$wrapper" ]; then + NSS_WRAPPER_PASSWD="$(mktemp)" + NSS_WRAPPER_GROUP="$(mktemp)" + export LD_PRELOAD="$wrapper" NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP + local gid; gid="$(id -g)" + echo "postgres:x:$uid:$gid:PostgreSQL:$PGDATA:/bin/false" > "$NSS_WRAPPER_PASSWD" + echo "postgres:x:$gid:" > "$NSS_WRAPPER_GROUP" + break + fi + done + fi + + if [ -n "$POSTGRES_INITDB_WALDIR" ]; then + set -- --waldir "$POSTGRES_INITDB_WALDIR" "$@" + fi + + # Babelfish supports UTF-8 only + eval 'initdb --username="$POSTGRES_USER" --pwfile=<(echo "$POSTGRES_PASSWORD") -E "UTF8" '"$POSTGRES_INITDB_ARGS"' "$@"' + + # unset/cleanup "nss_wrapper" bits + if [ "${LD_PRELOAD:-}" = '/usr/lib/libnss_wrapper.so' ]; then + rm -f "$NSS_WRAPPER_PASSWD" "$NSS_WRAPPER_GROUP" + unset LD_PRELOAD NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP + fi +} + +# print large warning if POSTGRES_PASSWORD is long +# error if both POSTGRES_PASSWORD is empty and POSTGRES_HOST_AUTH_METHOD is not 'trust' +# print large warning if POSTGRES_HOST_AUTH_METHOD is set to 'trust' +# assumes database is not set up, ie: [ -z "$DATABASE_ALREADY_EXISTS" ] +docker_verify_minimum_env() { + # check password first so we can output the warning before postgres + # messes it up + if [ "${#POSTGRES_PASSWORD}" -ge 100 ]; then + cat >&2 <<-'EOWARN' + + WARNING: The supplied POSTGRES_PASSWORD is 100+ characters. + + This will not work if used via PGPASSWORD with "psql". + + https://www.postgresql.org/message-id/flat/E1Rqxp2-0004Qt-PL%40wrigleys.postgresql.org (BUG #6412) + https://github.com/docker-library/postgres/issues/507 + + EOWARN + fi + if [ -z "$POSTGRES_PASSWORD" ] && [ 'trust' != "$POSTGRES_HOST_AUTH_METHOD" ]; then + # The - option suppresses leading tabs but *not* spaces. :) + cat >&2 <<-'EOE' + Error: Database is uninitialized and superuser password is not specified. + You must specify POSTGRES_PASSWORD to a non-empty value for the + superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run". + + You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all + connections without a password. This is *not* recommended. + + See PostgreSQL documentation about "trust": + https://www.postgresql.org/docs/current/auth-trust.html + EOE + exit 1 + fi + if [ 'trust' = "$POSTGRES_HOST_AUTH_METHOD" ]; then + cat >&2 <<-'EOWARN' + ******************************************************************************** + WARNING: POSTGRES_HOST_AUTH_METHOD has been set to "trust". This will allow + anyone with access to the Postgres port to access your database without + a password, even if POSTGRES_PASSWORD is set. See PostgreSQL + documentation about "trust": + https://www.postgresql.org/docs/current/auth-trust.html + In Docker's default configuration, this is effectively any other + container on the same system. + + It is not recommended to use POSTGRES_HOST_AUTH_METHOD=trust. Replace + it with "-e POSTGRES_PASSWORD=password" instead to set a password in + "docker run". + ******************************************************************************** + EOWARN + fi +} + +# usage: docker_process_init_files [file [file [...]]] +# ie: docker_process_init_files /always-initdb.d/* +# process initializer files, based on file extensions and permissions +docker_process_init_files() { + # psql here for backwards compatibility "${psql[@]}" + psql=( docker_process_sql ) + + echo + local f + for f; do + case "$f" in + *.sh) + # https://github.com/docker-library/postgres/issues/450#issuecomment-393167936 + # https://github.com/docker-library/postgres/pull/452 + if [ -x "$f" ]; then + echo "$0: running $f" + "$f" + else + echo "$0: sourcing $f" + . "$f" + fi + ;; + *.sql) echo "$0: running $f"; docker_process_sql -f "$f"; echo ;; + *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | docker_process_sql; echo ;; + *.sql.xz) echo "$0: running $f"; xzcat "$f" | docker_process_sql; echo ;; + *) echo "$0: ignoring $f" ;; + esac + echo + done +} + +# Execute sql script, passed via stdin (or -f flag of pqsl) +# usage: docker_process_sql [psql-cli-args] +# ie: docker_process_sql --dbname=mydb <<<'INSERT ...' +# ie: docker_process_sql -f my-file.sql +# ie: docker_process_sql > $PGDATA/postgresql.conf + + docker_process_sql --dbname $POSTGRES_DB -c 'select pg_reload_conf();' +} + +# Loads various settings that are used elsewhere in the script +# This should be called before any other functions +docker_setup_env() { + file_env 'POSTGRES_PASSWORD' + + file_env 'POSTGRES_USER' 'postgres' + file_env 'POSTGRES_DB' "$POSTGRES_USER" + file_env 'BABELFISH_MIGRATION_MODE' 'single-db' + file_env 'BABELFISH_MIGRATION_MODE' "$BABELFISH_MIGRATION_MODE" + file_env 'POSTGRES_INITDB_ARGS' + : "${POSTGRES_HOST_AUTH_METHOD:=}" + + declare -g DATABASE_ALREADY_EXISTS + # look specifically for PG_VERSION, as it is expected in the DB dir + if [ -s "$PGDATA/PG_VERSION" ]; then + DATABASE_ALREADY_EXISTS='true' + fi +} + +# append POSTGRES_HOST_AUTH_METHOD to pg_hba.conf for "host" connections +# all arguments will be passed along as arguments to `postgres` for getting the value of 'password_encryption' +pg_setup_hba_conf() { + # default authentication method is md5 on versions before 14 + # https://www.postgresql.org/about/news/postgresql-14-released-2318/ + if [ "$1" = 'postgres' ]; then + shift + fi + local auth + # check the default/configured encryption and use that as the auth method + auth="$(postgres -C password_encryption "$@")" + # postgres 9 only reports "on" and not "md5" + if [ "$auth" = 'on' ]; then + auth='md5' + fi + : "${POSTGRES_HOST_AUTH_METHOD:=$auth}" + { + echo + if [ 'trust' = "$POSTGRES_HOST_AUTH_METHOD" ]; then + echo '# warning trust is enabled for all connections' + echo '# see https://www.postgresql.org/docs/12/auth-trust.html' + fi + echo "host all all all $POSTGRES_HOST_AUTH_METHOD" + } >> "$PGDATA/pg_hba.conf" +} + +# start socket-only postgresql server for setting up or running scripts +# all arguments will be passed along as arguments to `postgres` (via pg_ctl) +docker_temp_server_start() { + if [ "$1" = 'postgres' ]; then + shift + fi + + # internal start of server in order to allow setup using psql client + # does not listen on external TCP/IP and waits until start finishes + set -- "$@" -c listen_addresses='' -p "${PGPORT:-5432}" + + PGUSER="${PGUSER:-$POSTGRES_USER}" \ + pg_ctl -D "$PGDATA" \ + -o "$(printf '%q ' "$@")" \ + -w start +} + +# stop postgresql server after done setting up user and running scripts +docker_temp_server_stop() { + PGUSER="${PGUSER:-postgres}" \ + pg_ctl -D "$PGDATA" -m fast -w stop +} + +# check arguments for an option that would cause postgres to stop +# return true if there is one +_pg_want_help() { + local arg + for arg; do + case "$arg" in + # postgres --help | grep 'then exit' + # leaving out -C on purpose since it always fails and is unhelpful: + # postgres: could not access the server configuration file "/var/lib/postgresql/data/postgresql.conf": No such file or directory + -'?'|--help|--describe-config|-V|--version) + return 0 + ;; + esac + done + return 1 +} + +_main() { + # if first arg looks like a flag, assume we want to run postgres server + if [ "${1:0:1}" = '-' ]; then + set -- postgres "$@" + fi + + if [ "$1" = 'postgres' ] && ! _pg_want_help "$@"; then + docker_setup_env + # setup data directories and permissions (when run as root) + docker_create_db_directories + if [ "$(id -u)" = '0' ]; then + # then restart script as postgres user + exec gosu postgres "$BASH_SOURCE" "$@" + fi + + # only run initialization on an empty data directory + if [ -z "$DATABASE_ALREADY_EXISTS" ]; then + docker_verify_minimum_env + + # check dir permissions to reduce likelihood of half-initialized database + #ls /docker-entrypoint-initdb.d/ > /dev/null + + docker_init_database_dir + pg_setup_hba_conf "$@" + + # PGPASSWORD is required for psql when authentication is required for 'local' connections via pg_hba.conf and is otherwise harmless + # e.g. when '--auth=md5' or '--auth-local=md5' is used in POSTGRES_INITDB_ARGS + export PGPASSWORD="${PGPASSWORD:-$POSTGRES_PASSWORD}" + docker_temp_server_start "$@" + + docker_setup_db + + docker_setup_babelfish_db + + docker_process_init_files /docker-entrypoint-initdb.d/* + + docker_temp_server_stop + unset PGPASSWORD + + echo + echo 'PostgreSQL init process complete; ready for start up.' + echo + else + echo + echo 'PostgreSQL Database directory appears to contain a database; Skipping initialization' + echo + fi + fi + + exec "$@" +} + +if ! _is_sourced; then + _main "$@" +fi \ No newline at end of file diff --git a/BUILD.md b/BUILD.md new file mode 100644 index 0000000..59eacec --- /dev/null +++ b/BUILD.md @@ -0,0 +1,89 @@ +# Building Images + +Requirements: + +- pipenv or j2cli system-wide + + +Steps: + +- Install and switch to Python virtual env: + +```sh +pipenv sync +pipienv shell +``` + +Or, you can install `j2cli` system-wide: + +```sh +sudo pip install j2cli +``` + +- Render the Dockerfiles using the templates: + +```sh +./render.sh -o ubuntu -v focal -T BABEL_2_1_1__PG_14_3 +``` + +- Build: + +```sh +./build.sh -o ubuntu -v focal -T BABEL_2_1_1__PG_14_3 +``` + +## Helpers + +`build-wrapper.sh` does the render and build of the images. Use `-b` to do the +build or `-r` for rendering the templates. + + +## Additional tagging and push + + +```bash +docker tag babelfishpg:ubuntu.focal registry.gitlab.com/ongresinc/labs/babelfish-on-docker +docker tag babelfishpg:ubuntu.focal ghcr.io/ongres/babelfish-on-docker-compose +docker push registry.gitlab.com/ongresinc/labs/babelfish-on-docker +docker push ghcr.io/ongres/babelfish-on-docker-compose +``` + +See that you can add more distros in the same compose, and build by build argument as above. + + +## Building and starting with docker-compose + +```yaml +version: "3" + +services: + babelfishpg-ubuntu-focal: + container_name: babelfishpg-ubuntu-focal + build: + context: . + dockerfile: Dockerfile.ubuntu-focal + args: + buildno: 1 + MAX_JOBS: 4 + TAG: BABEL_2_1_1__PG_14_3 + image: babelfishpg:ubuntu.focal + ports: + # Port forwarding not supported by BabelfishPG + - 1433:1433 + - 5432:15432 + environment: + - POSTGRES_PASSWORD=password + - POSTGRES_DB=postgres + - POSTGRES_USER=postgres + - BABELFISH_USER=bbf + - BABELFISH_PASS=password + - BABELFISH_DB=bbf + - BABELFISH_MIGRATION_MODE=multi-db + - POSTGRES_HOST_AUTH_METHOD=trust + networks: + - babelfish + +networks: + babelfish: + +``` \ No newline at end of file diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..69c993a --- /dev/null +++ b/Pipfile @@ -0,0 +1,12 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +j2cli = "*" + +[dev-packages] + +[requires] +python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..5251c8b --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,81 @@ +{ + "_meta": { + "hash": { + "sha256": "dc75dc0592f9275d73922e2f36ba411ca0a4afc4651cc5a287b6a5276c86ab0a" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.8" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.python.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "j2cli": { + "hashes": [ + "sha256:6f6f643b3fa5c0f72fbe9f07e246f8e138052b9f689e14c7c64d582c59709ae4", + "sha256:b005a40750b7b7c1c4c6e7209dc2bd6d10dee8a93a939d80884f2e2fb427d343" + ], + "index": "pypi", + "version": "==0.3.10" + }, + "jinja2": { + "hashes": [ + "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", + "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" + ], + "version": "==3.1.2" + }, + "markupsafe": { + "hashes": [ + "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003", + "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88", + "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5", + "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7", + "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a", + "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603", + "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1", + "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135", + "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247", + "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6", + "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601", + "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77", + "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02", + "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e", + "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63", + "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f", + "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980", + "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b", + "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812", + "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff", + "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96", + "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1", + "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925", + "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a", + "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6", + "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e", + "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f", + "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4", + "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f", + "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3", + "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c", + "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a", + "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417", + "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a", + "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a", + "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37", + "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452", + "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933", + "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a", + "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7" + ], + "version": "==2.1.1" + } + }, + "develop": {} +} diff --git a/README.md b/README.md index 000f621..f7a5a11 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,84 @@ # Babelfish on Docker -Docker environments for Babelfish test. +Docker templates and Dockerfiles for Babelfish. +For building the images, see `BUILD.md`. -## Use current image +## Building the image ```bash -docker pull registry.gitlab.com/ongresinc/labs/babelfish-on-docker:latest +./build.sh -o ubuntu -v focal -T BABEL_2_1_1__PG_14_3 ``` +See `releases.json` for referring to the available Dockerfiles, or +check `/distro/osversion/`. + + +## Docker run + +```bash +docker run -d -i -t \ + -e POSTGRES_PASSWORD=password -e POSTGRES_DB=postgres \ + -e POSTGRES_USER=postgres -e BABELFISH_USER=bbf \ + -e BABELFISH_PASS=password -e BABELFISH_DB=bbf \ + -e BABELFISH_MIGRATION_MODE=multi-db \ + -e POSTGRES_HOST_AUTH_METHOD=trust \ + -p 1433:1433 -p 5432:15432 \ + --name babelfishpg-2.1.1-ubuntu.focal \ + babelfishpg:2.1.1-ubuntu.focal ``` -docker-compose -f docker-compose-remote.yml up + + +## Docker Compose + +For using the available docker-compose files, go to the corresponding +flavor folder (`/distro/osversion/`) and execute: + +```bash +docker-compose up ``` +A basic structure with the build included would be: + +eg: + +```yaml +version: "3" + +services: + babelfishpg-2.1.1-amazonlinux-2: + container_name: babelfishpg-2.1.1-amazonlinux.2 + build: + context: . + dockerfile: Dockerfile + args: + buildno: 1 + MAX_JOBS: 4 + image: babelfishpg:2.1.1-amazonlinux.2 + ports: + # Port forwarding not supported by BabelfishPG + - 1433:1433 + - 5432:15432 + environment: + - POSTGRES_PASSWORD=password + - POSTGRES_DB=postgres + - POSTGRES_USER=postgres + - BABELFISH_USER=bbf + - BABELFISH_PASS=password + - BABELFISH_DB=bbf + - BABELFISH_MIGRATION_MODE=multi-db + - POSTGRES_HOST_AUTH_METHOD=trust + networks: + - babelfish + +... + +networks: + babelfish: +``` + +## Access + Access through local: ```bash @@ -43,20 +109,9 @@ The mapped schemas will had the `*-dbo` suffix. This mode is useful if you rely Single-DB will allow only one user database, and it might be the most recommended mode for beginners. -## Building - -```bash -docker-compose build babelfishpg-ubuntu-focal -docker-compose up - -docker tag babelfishpg:ubuntu.focal registry.gitlab.com/ongresinc/labs/babelfish-on-docker -docker tag babelfishpg:ubuntu.focal ghcr.io/ongres/babelfish-on-docker-compose -docker push registry.gitlab.com/ongresinc/labs/babelfish-on-docker -docker push ghcr.io/ongres/babelfish-on-docker-compose -``` - -See that you can add more distros in the same compose, and build by build argument as above. +## Extending the image +The current entrypoint is compatible with [the Official Docker Images](https://hub.docker.com/_/postgres/). ## References diff --git a/TODO b/TODO index 82f9062..6375d7d 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,44 @@ -- [ ] [WIP] ANTLR supported packages for Ubuntu: libantlr4-runtime4.8 libantlr4-runtime-dev antlr4. - - It shouldn't be necessary to stick to ANTLR 4.9 - - # RUN curl -L https://www.antlr.org/download/antlr-4.8-complete.jar --output ${PREFIX}/antlr-4.8-complete.jar +- [ ] ANTLR image split from the Babelfish - [x] Multi-stage build - [ ] Re-enable Python support (>2.7) in the core configure. ``` --with-python PYTHON=/usr/bin/python2.7 \ -``` \ No newline at end of file +``` + +- [ ] mssql-tools support in non-debian distros + +- [ ] Buildx for multi architecture images + ## See https://www.docker.com/blog/multi-arch-build-and-images-the-simple-way/ + ## https://dev.to/cloudx/multi-arch-docker-images-the-easy-way-with-github-actions-4k54 + # docker buildx build --push --platform linux/arm/v7,linux/arm64/v8,linux/amd64 --tag 3manuek/babelfishpg:2.1.1-ubuntu.focal . + + +- [ ] Support for armv7. Taken from the current Postgres available packages: + +``` +PGXS = /usr/lib/postgresql/11/lib/pgxs/src/makefiles/pgxs.mk +CONFIGURE = '--build=arm-linux-gnueabihf' '--prefix=/usr' '--includedir=/usr/include' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--sysconfdir=/etc' '--localstatedir=/var' '--disable-silent-rules' '--libdir=/usr/lib/arm-linux-gnueabihf' '--libexecdir=/usr/lib/arm-linux-gnueabihf' '--disable-maintainer-mode' '--disable-dependency-tracking' '--with-icu' '--with-tcl' '--with-perl' '--with-python' '--with-pam' '--with-openssl' '--with-libxml' '--with-libxslt' 'PYTHON=/usr/bin/python' '--mandir=/usr/share/postgresql/11/man' '--docdir=/usr/share/doc/postgresql-doc-11' '--sysconfdir=/etc/postgresql-common' '--datarootdir=/usr/share/' '--datadir=/usr/share/postgresql/11' '--bindir=/usr/lib/postgresql/11/bin' '--libdir=/usr/lib/arm-linux-gnueabihf/' '--libexecdir=/usr/lib/postgresql/' '--includedir=/usr/include/postgresql/' '--with-extra-version= (Raspbian 11.17-0+deb10u1)' '--enable-nls' '--enable-integer-datetimes' '--enable-thread-safety' '--enable-tap-tests' '--enable-debug' '--enable-dtrace' '--disable-rpath' '--with-uuid=e2fs' '--with-gnu-ld' '--with-pgport=5432' '--with-system-tzdata=/usr/share/zoneinfo' '--with-llvm' '--with-systemd' '--with-selinux' 'MKDIR_P=/bin/mkdir -p' 'TAR=/bin/tar' 'CFLAGS=-g -O2 -fstack-protector-strong -Wformat -Werror=format-security' 'LDFLAGS=-Wl,-z,relro -Wl,-z,now' '--with-gssapi' '--with-ldap' '--with-includes=/usr/include/mit-krb5' '--with-libs=/usr/lib/mit-krb5' '--with-libs=/usr/lib/arm-linux-gnueabihf/mit-krb5' 'build_alias=arm-linux-gnueabihf' 'CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2' 'CXXFLAGS=-g -O2 -fstack-protector-strong -Wformat -Werror=format-security' +CC = gcc +CPPFLAGS = -Wdate-time -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -I/usr/include/libxml2 -I/usr/include/mit-krb5 +CFLAGS = -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -g -O2 -fstack-protector-strong -Wformat -Werror=format-security +CFLAGS_SL = -fPIC +LDFLAGS = -Wl,-z,relro -Wl,-z,now -L/usr/lib/llvm-7/lib -L/usr/lib/arm-linux-gnueabihf/mit-krb5 -Wl,--as-needed +LDFLAGS_EX = +LDFLAGS_SL = +LIBS = -lpgcommon -lpgport -lpthread -lselinux -lxslt -lxml2 -lpam -lssl -lcrypto -lgssapi_krb5 -lz -ledit -lrt -lcrypt -ldl -lm +VERSION = PostgreSQL 11.17 (Raspbian 11.17-0+deb10u1) +``` + +aarch64 does not support uint128. See https://developer.arm.com/documentation/ka004805/1-0/?lang=en + +``` +In file included from ../../src/include/port/pg_crc32c.h:36, + from ../../src/include/common/checksum_helper.h:19, + from checksum_helper.c:20: +../../src/include/port/pg_bswap.h:105:2: error: unknown type name ‘uint128’ + uint128 v; + ^~~~~~~ +../../src/include/port/pg_bswap.h:109:15: error: unknown type name ‘uint128’ + static inline uint128 + ``` \ No newline at end of file diff --git a/antlr/templates/README.md b/antlr/templates/README.md new file mode 100644 index 0000000..04732a8 --- /dev/null +++ b/antlr/templates/README.md @@ -0,0 +1,5 @@ +# ANTLR pre-image + +These templates are WIP. The intention is to prebuild ANTLR images and +create new from those instead of mixing both. + diff --git a/antlr/templates/WIP b/antlr/templates/WIP new file mode 100644 index 0000000..e69de29 diff --git a/antlr/templates/amazonlinux/2/Dockerfile.j2 b/antlr/templates/amazonlinux/2/Dockerfile.j2 new file mode 100644 index 0000000..faae3c4 --- /dev/null +++ b/antlr/templates/amazonlinux/2/Dockerfile.j2 @@ -0,0 +1,140 @@ +FROM amazonlinux:2 as base +LABEL org.opencontainers.image.authors="emanuel@ongres.com" + + +ARG MAX_JOBS +ENV TAG={{ TAG }} +ENV MAX_JOBS=${MAX_JOBS:-2} +ENV ANTLR_VERSION={{ ANTLR_VERSION }} + +ENV MAX_JOBS=${MAX_JOBS:-2} + +ENV ANTLR_RUNTIME=/opt/antlr4 +ENV ANTLR_VERSION=${ANTLR_VERSION:-4.9.3} +ENV ANTLR4_RUNTIME_INCLUDE_DIR=/usr/local/include/antlr4-runtime/ +ENV ANTLR4_JAVA_BIN=/usr/bin/java + + +RUN yum update -y + +RUN yum install -y gcc gcc-c++ kernel-devel make \ + bison flex libxml2-devel readline-devel zlib-devel \ + uuid-devel pkg-config openssl-devel \ + libicu-devel postgresql-devel perl git \ + shadow-utils wget unzip curl cmake3 libuuid-devel \ + java pam-devel libxslt-devel openldap-devel \ + gettext-devel + +RUN ln -s /usr/bin/cmake3 /usr/bin/cmake + +ENV PATH="${PREFIX}/bin:${PATH}" + +# RUN curl -L https://github.com/babelfish-for-postgresql/babelfish-for-postgresql/releases/download/${TAG}/${TAG}.zip \ +# --output ${TAG}.zip && unzip -d /opt/ ${TAG}.zip + +# Compiling and installing antlr runtime +ENV ANTLR_EXECUTABLE=/usr/local/lib/antlr-${ANTLR_VERSION}-complete.jar + +# ENV ANTLR_EXECUTABLE=${PG_SRC}/contrib/babelfishpg_tsql/antlr/thirdparty/antlr/antlr-${ANTLR_VERSION}-complete.jar + +RUN curl https://www.antlr.org/download/antlr-${ANTLR_VERSION}-complete.jar \ + --output ${ANTLR_EXECUTABLE} && chmod +x ${ANTLR_EXECUTABLE} + +RUN curl https://www.antlr.org/download/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip \ + --output /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip && \ + unzip -d ${ANTLR_RUNTIME} /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip + +RUN mkdir ${ANTLR_RUNTIME}/build +WORKDIR ${ANTLR_RUNTIME}/build + +RUN cmake .. -DANTLR_JAR_LOCATION="${ANTLR_EXECUTABLE}" \ + -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_DEMO=True && \ + make && make install + + +WORKDIR ${PG_SRC} + +RUN ./configure CFLAGS="${CFLAGS:--Wall -ggdb -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic}" \ + --prefix=${PREFIX} \ + --enable-debug \ + --with-ldap \ + --with-libxml \ + --with-pam \ + --with-uuid=ossp \ + --enable-nls \ + --with-libxslt \ + --with-icu + +# Compilation +RUN make clean && make DESTDIR=${PREFIX}/tmp_install -j ${MAX_JOBS} world-bin && make install + +WORKDIR ${PG_SRC}/contrib + +RUN make +RUN make install + +RUN cp /usr/local/lib/libantlr4-runtime.so.${ANTLR_VERSION} ${PREFIX}/lib + +ENV USE_PGXS=1 + +RUN ["/usr/bin/bash", "-c", "cd ${PG_SRC}/contrib/babelfishpg_tsql/antlr ; cmake . "] + +RUN PG_CONFIG=${PG_CONFIG} PG_SRC=${PG_SRC} cmake=$(which cmake) ANTLR4_RUNTIME_LIBRARIES=/usr/include/antlr4-runtime ; \ + for EXT in babelfishpg_common babelfishpg_money babelfishpg_tds babelfishpg_tsql ; \ + do \ + cd ${PG_SRC}/contrib/${EXT} ; \ + make clean && make && make install ; \ + done + +RUN yum clean all + +FROM base AS babelfishpg +COPY --from=base ${PREFIX}/ /usr/local/ /opt/mssql-tools/bin/ + +ENV DEBIAN_FRONTEND=noninteractive +ENV PATH="${PREFIX}/bin:${PATH}" +ENV PGDATA="/var/lib/postgresql/data" +ENV DOCKER_ENTRYPOINT="/usr/local/bin/entrypoint.sh" + + +RUN yum update -y \ + yum install -y uuid pkgconfig.x86_64 openssl \ + libicu perl openldap.x86_64 libxslt.x86_64 \ + shadow-utils libuuid-devel openldap pam gettext + + +# Create postgres user +RUN useradd postgres && usermod -a -G postgres postgres + +# Sample default ready for Babelfish to run +RUN set -eux; \ + sed -ri "s!^#?(listen_addresses)\s*=\s*\S+.*!\1 = '*'!" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + sed -ri "s+#?shared_preload_libraries.*+shared_preload_libraries = 'babelfishpg_tds'+g" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + sed -i -e "\$ababelfishpg_tds.listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "shared_preload_libraries = 'babelfishpg_tds'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "babelfishpg_tds.listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; + +RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" + +COPY entrypoint.sh ${DOCKER_ENTRYPOINT} + +RUN chmod -R 0750 "${PREFIX}/share" && \ + chown postgres: ${DOCKER_ENTRYPOINT} && \ + chmod +x ${DOCKER_ENTRYPOINT} && \ + chown -R postgres: ${PREFIX} + +WORKDIR "${PREFIX}/bin/" + +RUN yum clean all && rm -rf /var/cache/yum + +USER postgres + +STOPSIGNAL SIGINT + +EXPOSE 1433 +EXPOSE 5432 + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] + +CMD ["postgres"] diff --git a/antlr/templates/ubuntu/focal/Dockerfile.j2 b/antlr/templates/ubuntu/focal/Dockerfile.j2 new file mode 100644 index 0000000..2a64d61 --- /dev/null +++ b/antlr/templates/ubuntu/focal/Dockerfile.j2 @@ -0,0 +1,55 @@ +FROM ubuntu:{{ OSVERSION }} as base +LABEL org.opencontainers.image.authors="emanuel@ongres.com" + +ARG MAX_JOBS +ENV MAX_JOBS=${MAX_JOBS:-2} + +ENV ANTLR_VERSION={{ ANTLR_VERSION }} +ENV ANTLR_RUNTIME=/opt/antlr4 +ENV ANTLR4_RUNTIME_INCLUDE_DIR=/usr/local/include/antlr4-runtime/ +ENV ANTLR4_JAVA_BIN=/usr/bin/java + +RUN set -ex; \ + apt update + +RUN set -ex ; \ + DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \ + build-essential flex libxml2-dev libxml2-utils\ + libxslt-dev libssl-dev \ + libreadline-dev zlib1g-dev libldap2-dev libpam0g-dev gettext \ + uuid uuid-dev cmake lld apt-utils pkg-config libossp-uuid-dev gnulib bison git + +RUN set -ex ; \ + DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \ + xsltproc icu-devtools libicu66 libicu-dev gawk curl + +RUN set -ex ; \ + DEBIAN_FRONTEND=noninteractive \ + apt install -y openjdk-8-jre openssl \ + libssl-dev python-dev libpq-dev \ + pkgconf unzip libutfcpp-dev gnupg + +RUN rm -rf /var/lib/apt/lists/*; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; + + +# Compiling and installing antlr runtime +ENV ANTLR_EXECUTABLE=/usr/local/lib/antlr-${ANTLR_VERSION}-complete.jar +# ENV ANTLR_EXECUTABLE=${PG_SRC}/contrib/babelfishpg_tsql/antlr/thirdparty/antlr/antlr-${ANTLR_VERSION}-complete.jar + +RUN curl https://www.antlr.org/download/antlr-${ANTLR_VERSION}-complete.jar \ + --output ${ANTLR_EXECUTABLE} && chmod +x ${ANTLR_EXECUTABLE} + +RUN curl https://www.antlr.org/download/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip \ + --output /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip && \ + unzip -d ${ANTLR_RUNTIME} /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip + +WORKDIR ${ANTLR_RUNTIME} + +RUN mkdir build && cd build && \ + cmake .. -D ANTLR_JAR_LOCATION=${ANTLR_EXECUTABLE} \ + -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_DEMO=True && \ + make && make install + +# FROM antlr AS base +# COPY --from=antlr ${PREFIX}/ /usr/local/ /opt/mssql-tools/bin/ diff --git a/build-wrapper.sh b/build-wrapper.sh new file mode 100755 index 0000000..7427e75 --- /dev/null +++ b/build-wrapper.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# WIP +# This would take the releases.json, parse and iterate and build accordingly +# to the host architecture +# jq -r '.releases[].tag' releases.json + + +function help(){ + echo " + ./build-wrapper [-b] [-r] + -b Do the build + -r Do the render + " +} + +while getopts 'brh' OPT +do + case "$OPT" in + b|--build) export BUILD=1 ;; + r|--render) export RENDER=1 ;; + h|--help) help ;; + *) help ; exit 1 ;; + esac +done + +if [ -v RENDER ] +then + ./render.sh -o ubuntu -v focal -T BABEL_2_1_1__PG_14_3 + ./render.sh -o amazonlinux -v 2 -T BABEL_2_1_1__PG_14_3 + ./render.sh -o ubuntu -v focal -T BABEL_1_3_1__PG_13_7 +fi + +if [ -v BUILD ] +then + echo "Build started." + ./build.sh -o ubuntu -v focal -l -T BABEL_2_1_1__PG_14_3 + ./build.sh -o amazonlinux -v 2 -T BABEL_2_1_1__PG_14_3 + ./build.sh -o ubuntu -v focal -T BABEL_1_3_1__PG_13_7 +fi + + diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..2a116f3 --- /dev/null +++ b/build.sh @@ -0,0 +1,57 @@ +#!/bin/bash + + +DEFAULT_DISTRO="ubuntu" +DEFAULT_OSVERSION="focal" +NOCACHE="" + +function build() { + cd ${BABELFISH_VERSION}/$DISTRO/$OSVERSION + docker build $NOCACHE $BUILD_ARG_MAX_JOBS $LATEST \ + -t babelfishpg:${BABELFISH_VERSION}-${DISTRO}.${OSVERSION} \ + -t babelfishpg:$(uname -m) . + +} + +function help() { + echo " + -T Babelfish tag, in the form of BABEL_2_1_1__PG_14_3 as eg. Mandatory. + -o Operating System. Default: ubuntu + -v Operating System version (eg. focal, bullseye, 8, etc.). Default: focal + -M MAX_JOBS (number of parallel build). Default: 2 + " +} + +while getopts 'o:v:T:M:hln' OPT +do + case "$OPT" in + o) DISTRO=$OPTARG ;; + v) OSVERSION=$OPTARG ;; + T) export TAG="$OPTARG" ;; + M) export BUILD_ARG_MAX_JOBS=" --build-arg MAX_JOBS=$OPTARG" ;; + h|--help) help ;; + l) LATEST=" -t babelfishpg:latest " ;; + n) export NOCACHE=" --no-cache " ;; + *) help ; exit 1 ;; + esac +done + +if [ ! -v TAG ] +then + printf "TAG is a mandatory argument (-T).\n" + help + exit 2 +fi + +export DISTRO=${DISTRO:DEFAULT_DISTRO} +export OSVERSION=${OSVERSION:DEFAULT_OSVERSION} + +export BABELFISH_VERSION=$(echo $TAG | sed -r -e 's/BABEL_([0-9a-z_]*)__PG.*/\1/' -e 's/_/./g') + +if [ ! -f $BABELFISH_VERSION/$DISTRO/$OSVERSION/Dockerfile ] +then + printf "Dockerfile for that set of arguments does not exists, \n see ./render.sh" + exit 3 +fi + +build \ No newline at end of file diff --git a/freetds/ubuntu/focal/.freetds.conf b/freetds/ubuntu/focal/.freetds.conf new file mode 100644 index 0000000..1e5d1d0 --- /dev/null +++ b/freetds/ubuntu/focal/.freetds.conf @@ -0,0 +1,34 @@ +# +# This file is installed by FreeTDS if no file by the same +# name is found in the installation directory. +# +# For information about the layout of this file and its settings, +# see the freetds.conf manpage "man freetds.conf". + +# Global settings are overridden by those in a database +# server specific section +[global] + # TDS protocol version + tds version = auto + + # Whether to write a TDSDUMP file for diagnostic purposes + # (setting this to /tmp is insecure on a multi-user system) + dump file = /tmp/freetds.log +; debug flags = 0xffff + + # Command and connection timeouts +; timeout = 10 +; connect timeout = 10 + + # To reduce data sent from server for BLOBs (like TEXT or + # IMAGE) try setting 'text size' to a reasonable limit +; text size = 64512 + + # If you experience TLS handshake errors and are using openssl, + # try adjusting the cipher list (don't surround in double or single quotes) + # openssl ciphers = HIGH:!SSLv2:!aNULL:-DH + +# A typical Microsoft server +[bbf] + host = babelfish + port = 1433 diff --git a/freetds/ubuntu/focal/.pool.conf b/freetds/ubuntu/focal/.pool.conf new file mode 100644 index 0000000..60339a1 --- /dev/null +++ b/freetds/ubuntu/focal/.pool.conf @@ -0,0 +1,15 @@ +[global] +min pool conn = 5 +max pool conn = 10 +max member age = 120 + + +[clientpool] +server user = bbf +server password = password +server = babelfish +user = bbf +database = master +password = password +max pool conn = 7 +port = 5000 \ No newline at end of file diff --git a/freetds/ubuntu/focal/Dockerfile b/freetds/ubuntu/focal/Dockerfile new file mode 100644 index 0000000..c42c2e9 --- /dev/null +++ b/freetds/ubuntu/focal/Dockerfile @@ -0,0 +1,14 @@ +# Image for spining the tdspool + +FROM ubuntu:focal as base + +LABEL org.opencontainers.image.authors="me@tr3s.ma" + +RUN apt update && apt install -y freetds-bin + +COPY .pool.conf $HOME/ +COPY .freetds.conf $HOME/ + +WORKDIR $HOME + +CMD ["tdspool", "-c", ".pool.conf", "-l","/tmp/tdspool.log", "clientpool"] \ No newline at end of file diff --git a/freetds/ubuntu/focal/docker-compose.yml b/freetds/ubuntu/focal/docker-compose.yml new file mode 100644 index 0000000..3c05710 --- /dev/null +++ b/freetds/ubuntu/focal/docker-compose.yml @@ -0,0 +1,41 @@ +version: "3" + +services: + babelfish: + container_name: babelfish + image: babelfishpg:4.1.0-ubuntu.focal + ports: + # Port forwarding not supported by BabelfishPG + - 14333:1433 + - 5434:15432 + environment: + - POSTGRES_PASSWORD=password + - POSTGRES_DB=postgres + - POSTGRES_USER=postgres + - BABELFISH_USER=bbf + - BABELFISH_PASS=password + - BABELFISH_DB=bbf + - BABELFISH_MIGRATION_MODE=multi-db + - POSTGRES_HOST_AUTH_METHOD=trust + networks: + - babelfish + + tdspool: + build: + context: . + dockerfile: Dockerfile + args: + buildno: 1 + # MAX_JOBS: 4 + # TAG: BABEL_2_1_1__PG_14_3 + image: tdspool:latest + ports: + - 50001:5000 + container_name: tdspool + depends_on: + - babelfish + networks: + - babelfish + +networks: + babelfish: \ No newline at end of file diff --git a/freetds/ubuntu/focal/entrypoint.sh b/freetds/ubuntu/focal/entrypoint.sh new file mode 100644 index 0000000..f671930 --- /dev/null +++ b/freetds/ubuntu/focal/entrypoint.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -Eeo pipefail + + +# check to see if this file is being run or sourced from another script +_is_sourced() { + # https://unix.stackexchange.com/a/215279 + [ "${#FUNCNAME[@]}" -ge 2 ] \ + && [ "${FUNCNAME[0]}" = '_is_sourced' ] \ + && [ "${FUNCNAME[1]}" = 'source' ] +} + +_main(){ + tdspool +} + +if ! _is_sourced; then + _main "$@" +fi \ No newline at end of file diff --git a/push.sh b/push.sh new file mode 100755 index 0000000..14c8236 --- /dev/null +++ b/push.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# WIP +# XXX: push images matching labels in releases.json + +## Requires the following variables declared: +# DOCKER_DOMAIN=docker.io +# DOCKER_REPOSITORY=${DOCKER_DOMAIN}//babelfishpg + +. .env + +DEFAULT_DISTRO="ubuntu" +DEFAULT_OSVERSION="focal" + +function push() { + docker tag babelfishpg:${BABELFISH_VERSION}-${DISTRO}.${OSVERSION} ${DOCKER_REPOSITORY} + docker push ${DOCKER_REPOSITORY} +} + +function help() { + echo " + -T Babelfish tag, in the form of BABEL_2_1_1__PG_14_3 as eg. Mandatory. + -o Operating System. Default: ubuntu + -v Operating System version (eg. focal, bullseye, 8, etc.). Default: focal + " +} + +while getopts 'o:v:T:M:hl' OPT +do + case "$OPT" in + o) DISTRO=$OPTARG ;; + v) OSVERSION=$OPTARG ;; + T) export TAG="$OPTARG" ;; + h|--help) help ;; + l) LATEST=" -t babelfishpg:latest " ;; + *) help ; exit 1 ;; + esac +done + +if [ ! -v TAG ] +then + printf "TAG is a mandatory argument (-T).\n" + help + exit 2 +fi + +export DISTRO=${DISTRO:DEFAULT_DISTRO} +export OSVERSION=${OSVERSION:DEFAULT_OSVERSION} + +export BABELFISH_VERSION=$(echo $TAG | sed -r -e 's/BABEL_([0-9a-z_]*)__PG.*/\1/' -e 's/_/./g') + +if [ ! -f $BABELFISH_VERSION/$DISTRO/$OSVERSION/Dockerfile ] +then + printf "Dockerfile for that set of arguments does not exists, \n see ./render.sh" + exit 3 +fi + +docker login +push diff --git a/releases.json b/releases.json new file mode 100644 index 0000000..18ae0c0 --- /dev/null +++ b/releases.json @@ -0,0 +1,51 @@ +{ + "releases": [ + { + "tag": "BABEL_2_1_1__PG_14_3", + "distros": [ + { + "name": "ubuntu", + "osversions": [ + { + "name": "focal", + "latest": true, + "arch": ["arm64", "x86_64"] + } + ] + }, + { + "name": "amazonlinux", + "osversions": [ + { + "name":"2", + "arch": ["x86_64", "arm64"] + } + ] + } + ] + }, + { + "tag": "BABEL_1_3_1__PG_13_7", + "distros": [ + { + "name": "ubuntu", + "osversions": [ + { + "name": "focal", + "arch": ["arm64", "x86_64"] + } + ] + }, + { + "name": "amazonlinux", + "osversions": [ + { + "name":"2", + "arch": ["x86_64", "arm64"] + } + ] + } + ] + } + ] +} diff --git a/render.sh b/render.sh new file mode 100755 index 0000000..0f34487 --- /dev/null +++ b/render.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +DEFAULT_DISTRO="ubuntu" +DEFAULT_OSVERSION="focal" +DEFAULT_ANTLR_VERSION="4.9.3" + + +function help() { + echo " + -T Babelfish tag, in the form of BABEL_2_1_1__PG_14_3 as eg. Mandatory. + -o Operating System. Default: ubuntu + -v Operating System version (eg. focal, bullseye, 8, etc.). Default: focal + -a Antlr Version. Default: 4.9.3 + " +} + +while getopts 'o:v:T:a:h' OPT +do + case "$OPT" in + o) DISTRO=$OPTARG ;; + v) OSVERSION=$OPTARG ;; + T) export TAG=$OPTARG ;; + a) ANTLR_VERSION=$OPTARG ;; + h|--help) help ;; + *) help ; exit 1 ;; + esac +done + + +shift $(($OPTIND - 1)) + +if [ ! -v TAG ] +then + printf "TAG is a mandatory argument (-T).\n" + help + exit 2 +fi + +export DISTRO=${DISTRO:-$DEFAULT_DISTRO} +export OSVERSION=${OSVERSION:-$DEFAULT_OSVERSION} +export ANTLR_VERSION=${ANTLR_VERSION:-$DEFAULT_ANTLR_VERSION} + +export BABELFISH_VERSION=$(echo $TAG | sed -r -e 's/BABEL_([0-9a-z_]*)__PG.*/\1/' -e 's/_/./g') + +export WARNING_QUOTE=" +# +# Autogenerated files, do not edit. See README.md +# +" + +mkdir -p ${BABELFISH_VERSION}/${DISTRO}/${OSVERSION} + +j2 templates/${DISTRO}/${OSVERSION}/Dockerfile.j2 > ${BABELFISH_VERSION}/${DISTRO}/${OSVERSION}/Dockerfile +j2 templates/docker-compose.yml.j2 > ${BABELFISH_VERSION}/${DISTRO}/${OSVERSION}/docker-compose.yml +cp templates/entrypoint.sh ${BABELFISH_VERSION}/${DISTRO}/${OSVERSION}/entrypoint.sh \ No newline at end of file diff --git a/templates/README.md.j2 b/templates/README.md.j2 new file mode 100644 index 0000000..74b7ba5 --- /dev/null +++ b/templates/README.md.j2 @@ -0,0 +1,13 @@ +# Docker Image run for {{ BABELFISH_VERSION }}-{{DISTRO}}-{{OSVERSION}} + +```bash +docker run -d -i -t \ + -e POSTGRES_PASSWORD=password -e POSTGRES_DB=postgres \ + -e POSTGRES_USER=postgres -e BABELFISH_USER=bbf \ + -e BABELFISH_PASS=password -e BABELFISH_DB=bbf \ + -e BABELFISH_MIGRATION_MODE=multi-db \ + -e POSTGRES_HOST_AUTH_METHOD=trust \ + -p 1433:1433 -p 5432:15432 \ + --name babelfishpg-{{ BABELFISH_VERSION }}-{{DISTRO}}.{{OSVERSION}} \ + babelfishpg-{{ BABELFISH_VERSION }}-{{DISTRO}}.{{OSVERSION}} +``` \ No newline at end of file diff --git a/templates/amazonlinux/2/Dockerfile.j2 b/templates/amazonlinux/2/Dockerfile.j2 new file mode 100644 index 0000000..aff92dd --- /dev/null +++ b/templates/amazonlinux/2/Dockerfile.j2 @@ -0,0 +1,145 @@ +{{ WARNING_QUOTE }} +FROM amazonlinux:{{OSVERSION}} as base +LABEL org.opencontainers.image.authors="emanuel@ongres.com,xavisierra@ongres.com" + + +ARG MAX_JOBS +ENV TAG={{ TAG }} +ENV MAX_JOBS=${MAX_JOBS:-2} +ENV ANTLR_VERSION={{ ANTLR_VERSION }} +ENV BABELFISH_VERSION={{ BABELFISH_VERSION }} + +ENV MAX_JOBS=${MAX_JOBS:-2} + +ENV PREFIX=/usr/local/babelfishpg-${BABELFISH_VERSION} +ENV ANTLR_RUNTIME=/opt/antlr4 +ENV ANTLR_VERSION=${ANTLR_VERSION:-4.9.3} + +ENV PG_SRC=/opt/${TAG}/ +ENV PG_CONFIG=${PREFIX}/bin/pg_config +ENV ANTLR4_RUNTIME_INCLUDE_DIR=/usr/local/include/antlr4-runtime/ + +ENV ANTLR4_JAVA_BIN=/usr/bin/java + + +RUN yum update -y + +RUN yum install -y gcc gcc-c++ kernel-devel make \ + bison flex libxml2-devel readline-devel zlib-devel \ + uuid-devel pkg-config openssl-devel \ + libicu-devel postgresql-devel perl git \ + shadow-utils wget unzip curl cmake3 libuuid-devel \ + java pam-devel libxslt-devel openldap-devel \ + gettext-devel + +RUN ln -s /usr/bin/cmake3 /usr/bin/cmake + +ENV PATH="${PREFIX}/bin:${PATH}" + +RUN curl -L https://github.com/babelfish-for-postgresql/babelfish-for-postgresql/releases/download/${TAG}/${TAG}.zip \ + --output ${TAG}.zip && unzip -d /opt/ ${TAG}.zip + +# Compiling and installing antlr runtime +ENV ANTLR_EXECUTABLE=${PG_SRC}/contrib/babelfishpg_tsql/antlr/thirdparty/antlr/antlr-${ANTLR_VERSION}-complete.jar + +# RUN curl https://www.antlr.org/download/antlr-${ANTLR_VERSION}-complete.jar \ +# --output ${ANTLR_EXECUTABLE} && chmod +x ${ANTLR_EXECUTABLE} + +RUN curl https://www.antlr.org/download/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip \ + --output /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip && \ + unzip -d ${ANTLR_RUNTIME} /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip + +RUN mkdir ${ANTLR_RUNTIME}/build +WORKDIR ${ANTLR_RUNTIME}/build + +RUN cmake .. -DANTLR_JAR_LOCATION="${ANTLR_EXECUTABLE}" \ + -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_DEMO=True && \ + make && make install + + +WORKDIR ${PG_SRC} + +RUN ./configure CFLAGS="${CFLAGS:--Wall -ggdb -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic}" \ + --prefix=${PREFIX} \ + --enable-debug \ + --with-ldap \ + --with-libxml \ + --with-pam \ + --with-uuid=ossp \ + --enable-nls \ + --with-libxslt \ + --with-icu + +# Engine Compilation +RUN make clean && make DESTDIR=${PREFIX}/tmp_install -j ${MAX_JOBS} world-bin && make install + +WORKDIR ${PG_SRC}/contrib +# Built-in contrib installation +RUN make +RUN make install + +RUN cp /usr/local/lib/libantlr4-runtime.so.${ANTLR_VERSION} ${PREFIX}/lib + +ENV USE_PGXS=1 + +RUN ["/usr/bin/bash", "-c", "cd ${PG_SRC}/contrib/babelfishpg_tsql/antlr ; cmake . "] + +RUN PG_CONFIG=${PG_CONFIG} PG_SRC=${PG_SRC} cmake=$(which cmake) ANTLR4_RUNTIME_LIBRARIES=/usr/include/antlr4-runtime ; \ + for EXT in babelfishpg_common babelfishpg_money babelfishpg_tds babelfishpg_tsql ; \ + do \ + cd ${PG_SRC}/contrib/${EXT} ; \ + make clean && make && make install ; \ + done + +RUN yum clean all + +FROM base AS babelfishpg +COPY --from=base ${PREFIX}/ /usr/local/ + +ENV DEBIAN_FRONTEND=noninteractive +ENV PATH="${PREFIX}/bin:${PATH}" +ENV PGDATA="/var/lib/postgresql/data" +ENV DOCKER_ENTRYPOINT="/usr/local/bin/entrypoint.sh" + + +RUN yum update -y \ + yum install -y uuid pkgconfig.x86_64 openssl \ + libicu perl openldap.x86_64 libxslt.x86_64 \ + shadow-utils libuuid-devel openldap pam gettext + + +# Create postgres user +RUN useradd postgres && usermod -a -G postgres postgres + +# Sample default ready for Babelfish to run +RUN set -eux; \ + sed -ri "s!^#?(listen_addresses)\s*=\s*\S+.*!\1 = '*'!" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + sed -ri "s+#?shared_preload_libraries.*+shared_preload_libraries = 'babelfishpg_tds'+g" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + sed -i -e "\$ababelfishpg_tds.listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "shared_preload_libraries = 'babelfishpg_tds'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "babelfishpg_tds.listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; + +RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" + +COPY entrypoint.sh ${DOCKER_ENTRYPOINT} + +RUN chmod -R 0750 "${PREFIX}/share" && \ + chown postgres: ${DOCKER_ENTRYPOINT} && \ + chmod +x ${DOCKER_ENTRYPOINT} && \ + chown -R postgres: ${PREFIX} + +WORKDIR "${PREFIX}/bin/" + +RUN yum clean all && rm -rf /var/cache/yum + +USER postgres + +STOPSIGNAL SIGINT + +EXPOSE 1433 +EXPOSE 5432 + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] + +CMD ["postgres"] diff --git a/templates/centos/centos8/Dockerfile.j2 b/templates/centos/centos8/Dockerfile.j2 new file mode 100644 index 0000000..5429b9b --- /dev/null +++ b/templates/centos/centos8/Dockerfile.j2 @@ -0,0 +1,256 @@ +{{ WARNING_QUOTE }} + +FROM centos:{{OSVERSION}} as base + +ARG MAX_JOBS +ENV TAG={{ TAG }} +ENV MAX_JOBS=${MAX_JOBS:-2} +ENV ANTLR_VERSION={{ ANTLR_VERSION }} +ENV BABELFISH_VERSION={{ BABELFISH_VERSION }} + +ENV MAX_JOBS=${MAX_JOBS:-2} + +ENV PREFIX=/usr/local/babelfishpg-${BABELFISH_VERSION} +ENV ANTLR_RUNTIME=/opt/antlr4 +ENV ANTLR_VERSION=${ANTLR_VERSION:-4.9.3} + +ENV PG_SRC=/opt/${TAG}/ +ENV PG_CONFIG=${PREFIX}/bin/pg_config +ENV ANTLR4_RUNTIME_INCLUDE_DIR=/usr/local/include/antlr4-runtime/ + +ENV ANTLR4_JAVA_BIN=/usr/bin/java + + +RUN dnf install -y gcc gcc-c++ kernel-devel make +RUN dnf install -y bison flex libxml2-devel readline-devel zlib-devel +RUN dnf --enablerepo=powertools install -y uuid-devel pkg-config openssl-devel +RUN dnf install -y libicu-devel postgresql-devel perl +RUN dnf install -y wget + + +ENV PATH="${PREFIX}/bin:${PATH}" + +RUN curl -L https://github.com/babelfish-for-postgresql/babelfish-for-postgresql/releases/download/${TAG}/${TAG}.zip \ + --output ${TAG}.zip && unzip -d /opt/ ${TAG}.zip + +# Compiling and installing antlr runtime +ENV ANTLR_EXECUTABLE=${PG_SRC}/contrib/babelfishpg_tsql/antlr/thirdparty/antlr/antlr-${ANTLR_VERSION}-complete.jar + +# RUN curl https://www.antlr.org/download/antlr-${ANTLR_VERSION}-complete.jar \ +# --output ${ANTLR_EXECUTABLE} && chmod +x ${ANTLR_EXECUTABLE} + +RUN curl https://www.antlr.org/download/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip \ + --output /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip && \ + unzip -d ${ANTLR_RUNTIME} /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip + +RUN mkdir ${ANTLR_RUNTIME}/build +WORKDIR ${ANTLR_RUNTIME}/build + +RUN cmake .. -DANTLR_JAR_LOCATION="${ANTLR_EXECUTABLE}" \ + -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_DEMO=True && \ + make && make install + + +WORKDIR ${PG_SRC} + +RUN ./configure CFLAGS="${CFLAGS:--Wall -ggdb -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic}" \ + --prefix=${PREFIX} \ + --enable-debug \ + --with-ldap \ + --with-libxml \ + --with-pam \ + --with-uuid=ossp \ + --enable-nls \ + --with-libxslt \ + --with-icu + +# Engine Compilation +RUN make clean && make DESTDIR=${PREFIX}/tmp_install -j ${MAX_JOBS} world-bin && make install + +WORKDIR ${PG_SRC}/contrib +# Built-in contrib installation +RUN make +RUN make install + +RUN cp /usr/local/lib/libantlr4-runtime.so.${ANTLR_VERSION} ${PREFIX}/lib + +ENV USE_PGXS=1 + +RUN ["/usr/bin/bash", "-c", "cd ${PG_SRC}/contrib/babelfishpg_tsql/antlr ; cmake . "] + +RUN PG_CONFIG=${PG_CONFIG} PG_SRC=${PG_SRC} cmake=$(which cmake) ANTLR4_RUNTIME_LIBRARIES=/usr/include/antlr4-runtime ; \ + for EXT in babelfishpg_common babelfishpg_money babelfishpg_tds babelfishpg_tsql ; \ + do \ + cd ${PG_SRC}/contrib/${EXT} ; \ + make clean && make && make install ; \ + done + +RUN yum clean all + +FROM base AS babelfishpg +COPY --from=base ${PREFIX}/ /usr/local/ /opt/mssql-tools/bin/ + +ENV DEBIAN_FRONTEND=noninteractive +ENV PATH="${PREFIX}/bin:${PATH}" +ENV PGDATA="/var/lib/postgresql/data" +ENV DOCKER_ENTRYPOINT="/usr/local/bin/entrypoint.sh" + + +RUN yum update -y \ + yum install -y uuid pkgconfig.x86_64 openssl \ + libicu perl openldap.x86_64 libxslt.x86_64 \ + shadow-utils libuuid-devel openldap pam gettext + + +# Create postgres user +RUN useradd postgres && usermod -a -G postgres postgres + +# Sample default ready for Babelfish to run +RUN set -eux; \ + sed -ri "s!^#?(listen_addresses)\s*=\s*\S+.*!\1 = '*'!" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + sed -ri "s+#?shared_preload_libraries.*+shared_preload_libraries = 'babelfishpg_tds'+g" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + sed -i -e "\$ababelfishpg_tds.listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "shared_preload_libraries = 'babelfishpg_tds'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "babelfishpg_tds.listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; + +RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" + +COPY entrypoint.sh ${DOCKER_ENTRYPOINT} + +RUN chmod -R 0750 "${PREFIX}/share" && \ + chown postgres: ${DOCKER_ENTRYPOINT} && \ + chmod +x ${DOCKER_ENTRYPOINT} && \ + chown -R postgres: ${PREFIX} + +WORKDIR "${PREFIX}/bin/" + +RUN yum clean all && rm -rf /var/cache/yum + +USER postgres + +STOPSIGNAL SIGINT + +EXPOSE 1433 +EXPOSE 5432 + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] + +CMD ["postgres"] + + +# RUN mkdir /code +# RUN useradd johndoe +# COPY 'postgresql_modified_for_babelfish' '/code/postgresql_modified_for_babelfish' +# RUN chown -R johndoe:johndoe /code/postgresql_modified_for_babelfish +# WORKDIR /code/postgresql_modified_for_babelfish +# USER johndoe + +# RUN ./configure CFLAGS="-ggdb" \ +# --enable-debug \ +# --with-libxml \ +# --with-uuid=ossp \ +# --with-icu \ +# --with-extra-version=" Babelfish for PostgreSQL" + +# RUN ./configure CFLAGS="-ggdb" \ +# --prefix=/usr/local/pgsql-13.4 \ +# --enable-debug \ +# --with-libxml \ +# --with-uuid=ossp \ +# --with-icu \ +# --with-extra-version=" Babelfish for PostgreSQL" + +# ENV INSTALLATION_PATH=/usr/local/pgsql-13.4 +# USER root +# RUN mkdir "$INSTALLATION_PATH" + + +# RUN chown -R johndoe:johndoe /usr/local/pgsql-13.4 +# USER johndoe + +# RUN make # Compiles the Babefish for PostgreSQL engine +# WORKDIR /code/postgresql_modified_for_babelfish/contrib + +# RUN make # Compiles the PostgreSQL default extensions +# WORKDIR /code/postgresql_modified_for_babelfish +# RUN make install # Installs the Babelfish for PostgreSQL engine +# WORKDIR /code/postgresql_modified_for_babelfish/contrib + +# RUN make install # Installs the PostgreSQL default extensions +# COPY 'babelfish_extensions' '/code/babelfish_extensions' + +# USER root +# RUN chown -R johndoe:johndoe '/code/babelfish_extensions' + +# RUN dnf install -y java unzip curl git +# RUN dnf install -y cmake libuuid-devel + +# RUN # Dowloads the compressed Antlr4 Runtime sources on /opt/antlr4-cpp-runtime-4.9.2-source.zip +# RUN curl https://www.antlr.org/download/antlr4-cpp-runtime-4.9.2-source.zip \ +# --output /opt/antlr4-cpp-runtime-4.9.2-source.zip + +# RUN # Uncompress the source into /opt/antlr4 +# RUN unzip -d /opt/antlr4 /opt/antlr4-cpp-runtime-4.9.2-source.zip + +# RUN mkdir /opt/antlr4/build +# WORKDIR /opt/antlr4/build + +# ENV EXTENSIONS_SOURCE_CODE_PATH=/code/babelfish_extensions + +# RUN # Generates the make files for the build +# RUN cmake .. -DANTLR_JAR_LOCATION="$EXTENSIONS_SOURCE_CODE_PATH/contrib/babelfishpg_tsql/antlr/thirdparty/antlr/antlr-4.9.2-complete.jar" \ +# -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_DEMO=True +# RUN # Compiles and install +# RUN make +# RUN make install + +# RUN cp /usr/local/lib/libantlr4-runtime.so.4.9.2 "$INSTALLATION_PATH/lib" + +# ENV PG_CONFIG=/usr/local/pgsql-13.4/bin/pg_config +# ENV PG_SRC=/code/postgresql_modified_for_babelfish +# ENV cmake=/usr/bin/cmake + +# WORKDIR /code/babelfish_extensions + +# USER johndoe +# RUN # Install babelfishpg_money extension +# WORKDIR /code/babelfish_extensions/contrib/babelfishpg_money +# RUN make +# RUN make install + +# RUN # Install babelfishpg_common extension +# WORKDIR /code/babelfish_extensions/contrib/babelfishpg_common +# RUN make +# RUN make install + +# RUN # Install babelfishpg_tds extension +# WORKDIR /code/babelfish_extensions/contrib/babelfishpg_tds +# RUN make +# RUN make install + +# RUN # Installs the babelfishpg_tsql extension +# WORKDIR /code/babelfish_extensions/contrib/babelfishpg_tsql +# RUN make +# RUN make install + +# USER root +# RUN mkdir -p /usr/local/pgsql/data + +# RUN adduser postgres + +# RUN chown -R postgres:postgres $INSTALLATION_PATH +# RUN chown -R postgres:postgres /usr/local/pgsql/data + +# USER postgres +# RUN $INSTALLATION_PATH/bin/initdb -D /usr/local/pgsql/data + +# RUN echo "listen_addresses = '*'" >> /usr/local/pgsql/data/postgresql.conf +# RUN echo "shared_preload_libraries = 'babelfishpg_tds'" >> /usr/local/pgsql/data/postgresql.conf + +# EXPOSE 5432 +# EXPOSE 1433 + +# WORKDIR /usr/local/pgsql-13.4/ + +# ENTRYPOINT ["/usr/local/pgsql-13.4/bin/postgres", "-D", "/usr/local/pgsql/data"] \ No newline at end of file diff --git a/templates/centos/centos8/WIP b/templates/centos/centos8/WIP new file mode 100644 index 0000000..e69de29 diff --git a/templates/docker-compose.yml.j2 b/templates/docker-compose.yml.j2 new file mode 100644 index 0000000..66b6962 --- /dev/null +++ b/templates/docker-compose.yml.j2 @@ -0,0 +1,25 @@ +version: "3" + +services: + babelfishpg-{{ BABELFISH_VERSION }}-{{DISTRO}}-{{OSVERSION}}: + container_name: babelfishpg-{{ BABELFISH_VERSION }}-{{ DISTRO }}.{{ OSVERSION }} + image: babelfishpg:{{ BABELFISH_VERSION }}-{{ DISTRO }}.{{ OSVERSION}} + ports: + # Port forwarding not supported by BabelfishPG + - 1433:1433 + - 5432:15432 + environment: + - POSTGRES_PASSWORD=password + - POSTGRES_DB=postgres + - POSTGRES_USER=postgres + - BABELFISH_USER=bbf + - BABELFISH_PASS=password + - BABELFISH_DB=bbf + - BABELFISH_MIGRATION_MODE=multi-db + - POSTGRES_HOST_AUTH_METHOD=trust + networks: + - babelfish + +networks: + babelfish: + \ No newline at end of file diff --git a/templates/entrypoint.sh b/templates/entrypoint.sh new file mode 100644 index 0000000..d20597c --- /dev/null +++ b/templates/entrypoint.sh @@ -0,0 +1,380 @@ +#!/usr/bin/env bash +set -Eeo pipefail +# TODO swap to -Eeuo pipefail above (after handling all potentially-unset variables) + +# usage: file_env VAR [DEFAULT] +# ie: file_env 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(< "${!fileVar}")" + fi + export "$var"="$val" + unset "$fileVar" +} + +# check to see if this file is being run or sourced from another script +_is_sourced() { + # https://unix.stackexchange.com/a/215279 + [ "${#FUNCNAME[@]}" -ge 2 ] \ + && [ "${FUNCNAME[0]}" = '_is_sourced' ] \ + && [ "${FUNCNAME[1]}" = 'source' ] +} + +# used to create initial postgres directories and if run as root, ensure ownership to the "postgres" user +docker_create_db_directories() { + local user; user="$(id -u)" + + mkdir -p "$PGDATA" + # ignore failure since there are cases where we can't chmod (and PostgreSQL might fail later anyhow - it's picky about permissions of this directory) + chmod 700 "$PGDATA" || : + + # ignore failure since it will be fine when using the image provided directory; see also https://github.com/docker-library/postgres/pull/289 + mkdir -p /var/run/postgresql || : + chmod 775 /var/run/postgresql || : + + # Create the transaction log directory before initdb is run so the directory is owned by the correct user + if [ -n "$POSTGRES_INITDB_WALDIR" ]; then + mkdir -p "$POSTGRES_INITDB_WALDIR" + if [ "$user" = '0' ]; then + find "$POSTGRES_INITDB_WALDIR" \! -user postgres -exec chown postgres '{}' + + fi + chmod 700 "$POSTGRES_INITDB_WALDIR" + fi + + # allow the container to be started with `--user` + if [ "$user" = '0' ]; then + find "$PGDATA" \! -user postgres -exec chown postgres '{}' + + find /var/run/postgresql \! -user postgres -exec chown postgres '{}' + + fi +} + +# initialize empty PGDATA directory with new database via 'initdb' +# arguments to `initdb` can be passed via POSTGRES_INITDB_ARGS or as arguments to this function +# `initdb` automatically creates the "postgres", "template0", and "template1" dbnames +# this is also where the database user is created, specified by `POSTGRES_USER` env +docker_init_database_dir() { + # "initdb" is particular about the current user existing in "/etc/passwd", so we use "nss_wrapper" to fake that if necessary + # see https://github.com/docker-library/postgres/pull/253, https://github.com/docker-library/postgres/issues/359, https://cwrap.org/nss_wrapper.html + local uid; uid="$(id -u)" + if ! getent passwd "$uid" &> /dev/null; then + # see if we can find a suitable "libnss_wrapper.so" (https://salsa.debian.org/sssd-team/nss-wrapper/-/commit/b9925a653a54e24d09d9b498a2d913729f7abb15) + local wrapper + for wrapper in {/usr,}/lib{/*,}/libnss_wrapper.so; do + if [ -s "$wrapper" ]; then + NSS_WRAPPER_PASSWD="$(mktemp)" + NSS_WRAPPER_GROUP="$(mktemp)" + export LD_PRELOAD="$wrapper" NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP + local gid; gid="$(id -g)" + echo "postgres:x:$uid:$gid:PostgreSQL:$PGDATA:/bin/false" > "$NSS_WRAPPER_PASSWD" + echo "postgres:x:$gid:" > "$NSS_WRAPPER_GROUP" + break + fi + done + fi + + if [ -n "$POSTGRES_INITDB_WALDIR" ]; then + set -- --waldir "$POSTGRES_INITDB_WALDIR" "$@" + fi + + # Babelfish supports UTF-8 only + eval 'initdb --username="$POSTGRES_USER" --pwfile=<(echo "$POSTGRES_PASSWORD") -E "UTF8" '"$POSTGRES_INITDB_ARGS"' "$@"' + + # unset/cleanup "nss_wrapper" bits + if [ "${LD_PRELOAD:-}" = '/usr/lib/libnss_wrapper.so' ]; then + rm -f "$NSS_WRAPPER_PASSWD" "$NSS_WRAPPER_GROUP" + unset LD_PRELOAD NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP + fi +} + +# print large warning if POSTGRES_PASSWORD is long +# error if both POSTGRES_PASSWORD is empty and POSTGRES_HOST_AUTH_METHOD is not 'trust' +# print large warning if POSTGRES_HOST_AUTH_METHOD is set to 'trust' +# assumes database is not set up, ie: [ -z "$DATABASE_ALREADY_EXISTS" ] +docker_verify_minimum_env() { + # check password first so we can output the warning before postgres + # messes it up + if [ "${#POSTGRES_PASSWORD}" -ge 100 ]; then + cat >&2 <<-'EOWARN' + + WARNING: The supplied POSTGRES_PASSWORD is 100+ characters. + + This will not work if used via PGPASSWORD with "psql". + + https://www.postgresql.org/message-id/flat/E1Rqxp2-0004Qt-PL%40wrigleys.postgresql.org (BUG #6412) + https://github.com/docker-library/postgres/issues/507 + + EOWARN + fi + if [ -z "$POSTGRES_PASSWORD" ] && [ 'trust' != "$POSTGRES_HOST_AUTH_METHOD" ]; then + # The - option suppresses leading tabs but *not* spaces. :) + cat >&2 <<-'EOE' + Error: Database is uninitialized and superuser password is not specified. + You must specify POSTGRES_PASSWORD to a non-empty value for the + superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run". + + You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all + connections without a password. This is *not* recommended. + + See PostgreSQL documentation about "trust": + https://www.postgresql.org/docs/current/auth-trust.html + EOE + exit 1 + fi + if [ 'trust' = "$POSTGRES_HOST_AUTH_METHOD" ]; then + cat >&2 <<-'EOWARN' + ******************************************************************************** + WARNING: POSTGRES_HOST_AUTH_METHOD has been set to "trust". This will allow + anyone with access to the Postgres port to access your database without + a password, even if POSTGRES_PASSWORD is set. See PostgreSQL + documentation about "trust": + https://www.postgresql.org/docs/current/auth-trust.html + In Docker's default configuration, this is effectively any other + container on the same system. + + It is not recommended to use POSTGRES_HOST_AUTH_METHOD=trust. Replace + it with "-e POSTGRES_PASSWORD=password" instead to set a password in + "docker run". + ******************************************************************************** + EOWARN + fi +} + +# usage: docker_process_init_files [file [file [...]]] +# ie: docker_process_init_files /always-initdb.d/* +# process initializer files, based on file extensions and permissions +docker_process_init_files() { + # psql here for backwards compatibility "${psql[@]}" + psql=( docker_process_sql ) + + echo + local f + for f; do + case "$f" in + *.sh) + # https://github.com/docker-library/postgres/issues/450#issuecomment-393167936 + # https://github.com/docker-library/postgres/pull/452 + if [ -x "$f" ]; then + echo "$0: running $f" + "$f" + else + echo "$0: sourcing $f" + . "$f" + fi + ;; + *.sql) echo "$0: running $f"; docker_process_sql -f "$f"; echo ;; + *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | docker_process_sql; echo ;; + *.sql.xz) echo "$0: running $f"; xzcat "$f" | docker_process_sql; echo ;; + *) echo "$0: ignoring $f" ;; + esac + echo + done +} + +# Execute sql script, passed via stdin (or -f flag of pqsl) +# usage: docker_process_sql [psql-cli-args] +# ie: docker_process_sql --dbname=mydb <<<'INSERT ...' +# ie: docker_process_sql -f my-file.sql +# ie: docker_process_sql > $PGDATA/postgresql.conf + + docker_process_sql --dbname $POSTGRES_DB -c 'select pg_reload_conf();' +} + +# Loads various settings that are used elsewhere in the script +# This should be called before any other functions +docker_setup_env() { + file_env 'POSTGRES_PASSWORD' + + file_env 'POSTGRES_USER' 'postgres' + file_env 'POSTGRES_DB' "$POSTGRES_USER" + file_env 'BABELFISH_MIGRATION_MODE' 'single-db' + file_env 'BABELFISH_MIGRATION_MODE' "$BABELFISH_MIGRATION_MODE" + file_env 'POSTGRES_INITDB_ARGS' + : "${POSTGRES_HOST_AUTH_METHOD:=}" + + declare -g DATABASE_ALREADY_EXISTS + # look specifically for PG_VERSION, as it is expected in the DB dir + if [ -s "$PGDATA/PG_VERSION" ]; then + DATABASE_ALREADY_EXISTS='true' + fi +} + +# append POSTGRES_HOST_AUTH_METHOD to pg_hba.conf for "host" connections +# all arguments will be passed along as arguments to `postgres` for getting the value of 'password_encryption' +pg_setup_hba_conf() { + # default authentication method is md5 on versions before 14 + # https://www.postgresql.org/about/news/postgresql-14-released-2318/ + if [ "$1" = 'postgres' ]; then + shift + fi + local auth + # check the default/configured encryption and use that as the auth method + auth="$(postgres -C password_encryption "$@")" + # postgres 9 only reports "on" and not "md5" + if [ "$auth" = 'on' ]; then + auth='md5' + fi + : "${POSTGRES_HOST_AUTH_METHOD:=$auth}" + { + echo + if [ 'trust' = "$POSTGRES_HOST_AUTH_METHOD" ]; then + echo '# warning trust is enabled for all connections' + echo '# see https://www.postgresql.org/docs/12/auth-trust.html' + fi + echo "host all all all $POSTGRES_HOST_AUTH_METHOD" + } >> "$PGDATA/pg_hba.conf" +} + +# start socket-only postgresql server for setting up or running scripts +# all arguments will be passed along as arguments to `postgres` (via pg_ctl) +docker_temp_server_start() { + if [ "$1" = 'postgres' ]; then + shift + fi + + # internal start of server in order to allow setup using psql client + # does not listen on external TCP/IP and waits until start finishes + set -- "$@" -c listen_addresses='' -p "${PGPORT:-5432}" + + PGUSER="${PGUSER:-$POSTGRES_USER}" \ + pg_ctl -D "$PGDATA" \ + -o "$(printf '%q ' "$@")" \ + -w start +} + +# stop postgresql server after done setting up user and running scripts +docker_temp_server_stop() { + PGUSER="${PGUSER:-postgres}" \ + pg_ctl -D "$PGDATA" -m fast -w stop +} + +# check arguments for an option that would cause postgres to stop +# return true if there is one +_pg_want_help() { + local arg + for arg; do + case "$arg" in + # postgres --help | grep 'then exit' + # leaving out -C on purpose since it always fails and is unhelpful: + # postgres: could not access the server configuration file "/var/lib/postgresql/data/postgresql.conf": No such file or directory + -'?'|--help|--describe-config|-V|--version) + return 0 + ;; + esac + done + return 1 +} + +_main() { + # if first arg looks like a flag, assume we want to run postgres server + if [ "${1:0:1}" = '-' ]; then + set -- postgres "$@" + fi + + if [ "$1" = 'postgres' ] && ! _pg_want_help "$@"; then + docker_setup_env + # setup data directories and permissions (when run as root) + docker_create_db_directories + if [ "$(id -u)" = '0' ]; then + # then restart script as postgres user + exec gosu postgres "$BASH_SOURCE" "$@" + fi + + # only run initialization on an empty data directory + if [ -z "$DATABASE_ALREADY_EXISTS" ]; then + docker_verify_minimum_env + + # check dir permissions to reduce likelihood of half-initialized database + #ls /docker-entrypoint-initdb.d/ > /dev/null + + docker_init_database_dir + pg_setup_hba_conf "$@" + + # PGPASSWORD is required for psql when authentication is required for 'local' connections via pg_hba.conf and is otherwise harmless + # e.g. when '--auth=md5' or '--auth-local=md5' is used in POSTGRES_INITDB_ARGS + export PGPASSWORD="${PGPASSWORD:-$POSTGRES_PASSWORD}" + docker_temp_server_start "$@" + + docker_setup_db + + docker_setup_babelfish_db + + docker_process_init_files /docker-entrypoint-initdb.d/* + + docker_temp_server_stop + unset PGPASSWORD + + echo + echo 'PostgreSQL init process complete; ready for start up.' + echo + else + echo + echo 'PostgreSQL Database directory appears to contain a database; Skipping initialization' + echo + fi + fi + + exec "$@" +} + +if ! _is_sourced; then + _main "$@" +fi \ No newline at end of file diff --git a/templates/ubuntu/focal/Dockerfile.j2 b/templates/ubuntu/focal/Dockerfile.j2 new file mode 100644 index 0000000..0e7444c --- /dev/null +++ b/templates/ubuntu/focal/Dockerfile.j2 @@ -0,0 +1,179 @@ +{{ WARNING_QUOTE }} + +FROM ubuntu:{{ OSVERSION }} as base +LABEL org.opencontainers.image.authors="emanuel@ongres.com" + +ARG MAX_JOBS +ENV TAG={{ TAG }} +ENV BABELFISH_VERSION={{ BABELFISH_VERSION }} +ENV MAX_JOBS=${MAX_JOBS:-2} +ENV ANTLR_VERSION={{ ANTLR_VERSION }} + +ENV PREFIX=/usr/local/babelfishpg-${BABELFISH_VERSION} +ENV ANTLR_RUNTIME=/opt/antlr4 + +ENV PG_SRC=/opt/${TAG}/ +ENV PG_CONFIG=${PREFIX}/bin/pg_config +ENV ANTLR4_RUNTIME_INCLUDE_DIR=/usr/local/include/antlr4-runtime/ + +ENV ANTLR4_JAVA_BIN=/usr/bin/java + +RUN set -ex; \ + apt update + +RUN set -ex ; \ + DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \ + build-essential flex libxml2-dev libxml2-utils libc6-dev \ + libxslt-dev \ + libreadline-dev zlib1g-dev libldap2-dev libpam0g-dev gettext \ + uuid uuid-dev cmake lld apt-utils pkg-config libossp-uuid-dev gnulib bison git + +RUN set -ex ; \ + DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends \ + xsltproc icu-devtools libicu66 libicu-dev gawk curl + +RUN set -ex ; \ + DEBIAN_FRONTEND=noninteractive \ + apt install -y openjdk-8-jre openssl \ + libssl-dev python-dev libpq-dev \ + pkgconf unzip libutfcpp-dev gnupg + +RUN sysArch=$(uname -m) + +# SQL Server Tooling dependencies +# Reference: https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-setup-tools?view=sql-server-ver15#ubuntu +# For non-amd64 mssql-tools isn't available, installing freetds in its place +RUN set -ex ; \ + case "$sysArch" in \ + x86_64 | amd64 | ppc64el) \ + curl -L https://packages.microsoft.com/keys/microsoft.asc | apt-key add - && \ + curl -L https://packages.microsoft.com/config/ubuntu/20.04/prod.list | tee /etc/apt/sources.list.d/msprod.list && \ + apt update && ACCEPT_EULA=Y apt install -y mssql-tools unixodbc-dev ; \ + PATH="${PREFIX}/bin:/opt/mssql-tools/bin/:${PATH}" ;; \ + * ) \ + DEBIAN_FRONTEND=noninteractive \ + apt install -y freetds-bin freetds-common ;; \ + esac ; + + + +RUN rm -rf /var/lib/apt/lists/*; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; + + +RUN curl -L https://github.com/babelfish-for-postgresql/babelfish-for-postgresql/releases/download/${TAG}/${TAG}.zip \ + --output ${TAG}.zip && unzip -d /opt/ ${TAG}.zip + +# Compiling and installing antlr runtime +# ENV ANTLR_EXECUTABLE=/usr/local/lib/antlr-${ANTLR_VERSION}-complete.jar +ENV ANTLR_EXECUTABLE=${PG_SRC}/contrib/babelfishpg_tsql/antlr/thirdparty/antlr/antlr-${ANTLR_VERSION}-complete.jar + +# RUN curl https://www.antlr.org/download/antlr-${ANTLR_VERSION}-complete.jar \ +# --output ${ANTLR_EXECUTABLE} && chmod +x ${ANTLR_EXECUTABLE} + +RUN curl https://www.antlr.org/download/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip \ + --output /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip && \ + unzip -d ${ANTLR_RUNTIME} /opt/antlr4-cpp-runtime-${ANTLR_VERSION}-source.zip + +WORKDIR ${ANTLR_RUNTIME} + +RUN mkdir build && cd build && \ + cmake .. -D ANTLR_JAR_LOCATION=${ANTLR_EXECUTABLE} \ + -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_DEMO=True && \ + make && make install + + +WORKDIR ${PG_SRC} + +RUN set -ex ; \ + case "$sysArch" in \ + x86_64 | amd64 | ppc64el) \ + CFLAGS_ARG='${CFLAGS:--Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic}' ; \ + CONFIGURE_FLAGS="" ;; \ + * ) \ + CFLAGS_ARG="-ggdb " CONFIGURE_FLAGS=' --build=arm-linux-gnueabihf ';; \ + esac ; \ + ./configure CFLAGS="${CFLAGS_ARG}" \ + --prefix=${PREFIX} \ + --enable-debug \ + --with-ldap \ + --with-libxml \ + --with-pam \ + --with-uuid=ossp \ + --enable-nls \ + --with-libxslt \ + --with-icu ${CONFIGURE_FLAGS} + + # --with-openssl + +# Engine Compilation +RUN make clean && make DESTDIR=${PREFIX}/tmp_install -j ${MAX_JOBS} world-bin && make install + +WORKDIR ${PG_SRC}/contrib +# Built-in contrib installation +RUN make +RUN make install + +## Regression Tests +# RUN make DESTDIR=${PREFIX}/tmp_install EXTRA_REGRESS_OPTS=--debug -j ${MAX_JOBS} check + +RUN cp /usr/local/lib/libantlr4-runtime.so.${ANTLR_VERSION} ${PREFIX}/lib + +ENV USE_PGXS=1 + +RUN ["/usr/bin/bash", "-c", "cd ${PG_SRC}/contrib/babelfishpg_tsql/antlr ; cmake . "] + +RUN PG_CONFIG=${PG_CONFIG} PG_SRC=${PG_SRC} cmake=$(which cmake) ANTLR4_RUNTIME_LIBRARIES=/usr/include/antlr4-runtime ; \ + for EXT in babelfishpg_common babelfishpg_money babelfishpg_tds babelfishpg_tsql ; \ + do \ + cd ${PG_SRC}/contrib/${EXT} ; \ + make clean && make && make install ; \ + done + +FROM base AS babelfishpg +COPY --from=base ${PREFIX}/ /usr/local/ /opt/mssql-tools/bin/ + +ENV DEBIAN_FRONTEND=noninteractive +ENV PATH="${PREFIX}/bin:${PATH}" +ENV PGDATA="/var/lib/postgresql/data" +ENV DOCKER_ENTRYPOINT="/usr/local/bin/entrypoint.sh" + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + libssl1.1 openssl libxml2 libreadline8 tzdata libldap-2.4-2 libpython2.7 libxslt1.1 libossp-uuid16 && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Create postgres user +RUN useradd postgres && usermod -a -G postgres postgres + +# Sample default ready for Babelfish to run +RUN set -eux; \ + sed -ri "s!^#?(listen_addresses)\s*=\s*\S+.*!\1 = '*'!" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + sed -ri "s+#?shared_preload_libraries.*+shared_preload_libraries = 'babelfishpg_tds'+g" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + sed -i -e "\$ababelfishpg_tds.listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "shared_preload_libraries = 'babelfishpg_tds'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; \ + grep -F "babelfishpg_tds.listen_addresses = '*'" "${PREFIX}/share/postgresql/postgresql.conf.sample"; + +RUN mkdir -p "$PGDATA" && chown -R postgres:postgres "$PGDATA" && chmod 777 "$PGDATA" + +COPY entrypoint.sh ${DOCKER_ENTRYPOINT} + +RUN chmod -R 0750 "${PREFIX}/share" && \ + chown postgres: ${DOCKER_ENTRYPOINT} && \ + chmod +x ${DOCKER_ENTRYPOINT} && \ + chown -R postgres: ${PREFIX} + +WORKDIR "${PREFIX}/bin/" + +USER postgres + +STOPSIGNAL SIGINT + +EXPOSE 1433 +EXPOSE 5432 + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] + +CMD ["postgres"] diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..42424a9 --- /dev/null +++ b/test.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# WIP + +DEFAULT_DISTRO="ubuntu" +DEFAULT_OSVERSION="focal" + +function test(){ + docker run -d -i -t \ + -e POSTGRES_PASSWORD=password -e POSTGRES_DB=postgres \ + -e POSTGRES_USER=postgres -e BABELFISH_USER=bbf \ + -e BABELFISH_PASS=password -e BABELFISH_DB=bbf \ + -e BABELFISH_MIGRATION_MODE=multi-db \ + -e POSTGRES_HOST_AUTH_METHOD=trust \ + -p 1433:1433 -p 5432:15432 \ + --name babelfishpg-${BABELFISH_VERSION}-${DISTRO}.${OSVERSION} \ + babelfishpg:${BABELFISH_VERSION}-${DISTRO}.${OSVERSION} + + docker stop babelfishpg-${BABELFISH_VERSION}-${DISTRO}.${OSVERSION} + docker rm babelfishpg-${BABELFISH_VERSION}-${DISTRO}.${OSVERSION} + +} + + +while getopts 'o:v:T:lh' OPT +do + case "$OPT" in + o) export DISTRO=$OPTARG ;; + v) export OSVERSION=$OPTARG ;; + T) export TAG="$OPTARG" ;; + h|--help) help ;; + l) LATEST=" -t babelfishpg:latest " ;; + *) help ; exit 1 ;; + esac +done + +if [ ! -v TAG ] +then + printf "TAG is a mandatory argument (-T).\n" + help + exit 2 +fi + +export DISTRO=${DISTRO:DEFAULT_DISTRO} +export OSVERSION=${OSVERSION:DEFAULT_OSVERSION} + +export BABELFISH_VERSION=$(echo $TAG | sed -r -e 's/BABEL_([0-9a-z_]*)__PG.*/\1/' -e 's/_/./g') + +test \ No newline at end of file