From c9200b8d39f5c3e10c744cb0b908d8001ac68d15 Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Sun, 23 Jun 2024 11:54:59 +0300 Subject: [PATCH] initial commit --- Dockerfile | 22 +++++ Dockerfile.base | 50 ++++++++++ Dockerfile.interim | 200 ++++++++++++++++++++++++++++++++++++++ LICENSE | 175 +++++++++++++++++++++++++++++++++ apt/sources.citus | 5 + apt/sources.debian | 11 +++ apt/sources.pgdg | 5 + ci/build-image-base.sh | 16 +++ ci/build-image-interim.sh | 10 ++ ci/build-image.sh | 8 ++ ep.sh | 57 +++++++++++ postgres-shim.sh | 11 +++ scripts/apt-clean.sh | 49 ++++++++++ scripts/apt-env.sh | 8 ++ scripts/apt-install.sh | 4 + scripts/dumb-run-as.sh | 17 ++++ scripts/gpg-batch.sh | 45 +++++++++ scripts/gpg-export.sh | 28 ++++++ scripts/pip-clean.sh | 7 ++ scripts/pip-env.sh | 8 ++ 20 files changed, 736 insertions(+) create mode 100644 Dockerfile create mode 100644 Dockerfile.base create mode 100644 Dockerfile.interim create mode 100644 LICENSE create mode 100644 apt/sources.citus create mode 100644 apt/sources.debian create mode 100644 apt/sources.pgdg create mode 100755 ci/build-image-base.sh create mode 100755 ci/build-image-interim.sh create mode 100755 ci/build-image.sh create mode 100755 ep.sh create mode 100755 postgres-shim.sh create mode 100755 scripts/apt-clean.sh create mode 100755 scripts/apt-env.sh create mode 100755 scripts/apt-install.sh create mode 100755 scripts/dumb-run-as.sh create mode 100755 scripts/gpg-batch.sh create mode 100755 scripts/gpg-export.sh create mode 100755 scripts/pip-clean.sh create mode 100755 scripts/pip-env.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..fe8b13d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM docker.io/rockdrilla/postgresql:16.3-base +SHELL [ "/bin/sh", "-ec" ] + +COPY /Dockerfile /usr/local/share/ + +COPY /ep.sh /usr/local/sbin/ +COPY /postgres-shim.sh /usr/local/sbin/ +## quirk +RUN ln -sv postgres-shim.sh /usr/local/sbin/postgres + +RUN site_packages=$(python3 -c 'import site;print(site.getsitepackages()[0])') ; \ + rm -rf \ + "${site_packages}/etcd/tests" \ + "${site_packages}/psutil/tests" \ + ; \ + find "${site_packages}/" -maxdepth 1 -type f -name '*.py' -exec python3 -m compileall -q -j 2 {} + ; \ + find "${site_packages}/" -mindepth 1 -maxdepth 1 -type d -printf '%P\0' \ + | sed -zE '/\.dist-info$/d;/^(_distutils_hack|pip|pkg_resources|setuptools|wheel)$/d' \ + | env -C "${site_packages}" xargs -0r python3 -m compileall -q -j 2 + +ENTRYPOINT [ "ep.sh" ] +CMD [ "postgres" ] diff --git a/Dockerfile.base b/Dockerfile.base new file mode 100644 index 0000000..992ff1e --- /dev/null +++ b/Dockerfile.base @@ -0,0 +1,50 @@ +ARG PYTHONTAG=3.11.9-slim-bookworm +FROM docker.io/library/python:${PYTHONTAG} as base-upstream + +FROM base-upstream as base +SHELL [ "/bin/sh", "-ec" ] + +COPY /Dockerfile.base /usr/local/share/ + +## - remove duplicate "/usr/local/bin" (fixes upstream image) +## - remove /sbin and /bin (/usr is merged) +ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin + +ENV MALLOC_ARENA_MAX=2 \ + PYTHONUNBUFFERED=1 \ + PYTHONDONTWRITEBYTECODE=1 + +COPY /scripts/* /usr/local/sbin/ + +COPY /apt/sources.debian /etc/apt/sources.list.d/debian.sources + +RUN apt-env.sh apt-get update ; \ + apt-env.sh apt-get upgrade -y ; \ + apt-env.sh dpkg -P \ + e2fsprogs \ + libext2fs2 \ + libss2 \ + logsave \ + ; apt-clean.sh + +RUN pip-env.sh pip list --format freeze \ + | grep -F '==' | awk -F= '{print $1}' \ + | xargs -r pip-env.sh pip install -U ; \ + pip-clean.sh /usr/local + +RUN site_packages=$(python3 -c 'import site;print(site.getsitepackages()[0])') ; \ + libpython=$(dirname "${site_packages}") ; \ + rm -rf \ + "${libpython}/ensurepip/_bundled" \ + "${libpython}/turtledemo" \ + ; \ + find "${libpython}/" -maxdepth 1 -type f -name '*.py' -exec python3 -m compileall -q -j 2 {} + ; \ + find "${libpython}/" -mindepth 1 -maxdepth 1 -type d -printf '%P\0' \ + | sed -zE '^(__pycache__|site-packages|__phello__|ensurepip|lib2to3|pydoc.*|tkinter|unittest)$/d' \ + | env -C "${libpython}" xargs -0r python3 -m compileall -q -j 2 + +RUN rm -f /root/.wget-hsts ; \ + find /usr/local/sbin/ ! -type d -name '*.sh' -delete + +ENTRYPOINT [ ] +CMD [ "bash" ] diff --git a/Dockerfile.interim b/Dockerfile.interim new file mode 100644 index 0000000..f1d654c --- /dev/null +++ b/Dockerfile.interim @@ -0,0 +1,200 @@ +ARG PYTHONTAG=3.11.9-slim-bookworm +FROM localhost/local-python:${PYTHONTAG} as base +FROM docker.io/library/postgres:16.3-bookworm as postgresql-upstream + +## --- + +FROM base as postgresql +SHELL [ "/bin/sh", "-ec" ] + +COPY /scripts/* /usr/local/sbin/ + +RUN apt-install.sh \ + ca-certificates \ + curl \ + dumb-init \ + file \ + gnupg \ + iproute2 \ + iputils-ping \ + jq \ + less \ + libnss-wrapper \ + lsof \ + ncurses-base \ + netbase \ + procps \ + psmisc \ + tzdata \ + vim \ + xxd \ + xz-utils \ + zstd \ + ; apt-clean.sh + +ENV PG_MAJOR=16 +ENV PG_UID=11111 PG_GID=11111 +ENV PGHOME=/var/lib/postgresql +ENV PGDATA=${PGHOME}/data + +RUN echo "postgres:x:${PG_UID}:${PG_GID}:postgres:${PGHOME}:/bin/bash" >> /etc/passwd ; \ + echo "postgres:x:${PG_GID}:" >> /etc/group ; \ + echo 'postgres:!:::::::' >> /etc/shadow ; \ + install -d -o postgres -g postgres -m 0755 "${PGHOME}" + +RUN install -d -o postgres -g postgres -m 3755 /run/postgresql +VOLUME [ "/run/postgresql" ] + +## set up locales! +RUN _lang=en_US.UTF8 ; \ + { \ + echo "locales locales/default_environment_locale select ${LANG}" ; \ + echo "locales locales/locales_to_be_generated multiselect ${LANG} UTF-8" ; \ + } | debconf-set-selections ; \ + f=/etc/dpkg/dpkg.cfg.d/docker ; \ + if [ -f "$f" ] ; then \ + sed -Ei '/\/usr\/share\/locale/d' "$f" ; \ + fi ; \ + echo "LANG=${_lang}" > /etc/default/locale ; \ + apt-install.sh locales ; apt-clean.sh ; \ + grep -Fixq "${_lang} UTF-8" /etc/locale.gen || { \ + echo "${_lang} UTF-8" >> /etc/locale.gen ; \ + locale-gen ; \ + } ; \ + locale -a | grep -Fixq "${_lang}" +ENV LANG=en_US.UTF8 + +ADD https://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc /etc/apt/keyrings/pgdg.gpg.bin +COPY /apt/sources.pgdg /etc/apt/sources.list.d/pgdg.sources +RUN env -C /etc/apt/keyrings gpg-export.sh pgdg.gpg.bin pgdg.gpg.asc + +COPY --from=postgresql-upstream /etc/postgresql-common/createcluster.conf /etc/postgresql-common/ +RUN apt-install.sh postgresql-common ; \ + apt-install.sh \ + "postgresql-${PG_MAJOR}" \ + ; \ + apt-clean.sh ; \ + f="/usr/share/postgresql/${PG_MAJOR}/postgresql.conf.sample" ; \ + dpkg-divert --add --rename --divert "$f.dpkg" "$f" ; \ + ln -sv ../postgresql.conf.sample "/usr/share/postgresql/${PG_MAJOR}/" +COPY --from=postgresql-upstream /usr/share/postgresql/postgresql.conf.sample /usr/share/postgresql/ + +ENV PATH=${PATH}:/usr/lib/postgresql/${PG_MAJOR}/bin + +COPY --from=postgresql-upstream /docker-entrypoint-initdb.d/ /docker-entrypoint-initdb.d/ +COPY --from=postgresql-upstream /usr/local/bin/*.sh /usr/local/bin/ +## compatibility ;) +RUN ln -sv /usr/local/sbin/dumb-run-as.sh /usr/local/bin/gosu + +## --- + +FROM postgresql as postgresql-extras +SHELL [ "/bin/sh", "-ec" ] + +RUN apt-install.sh \ + "postgresql-${PG_MAJOR}-cron" \ + "postgresql-${PG_MAJOR}-hll" \ + "postgresql-${PG_MAJOR}-hypopg" \ + "postgresql-${PG_MAJOR}-icu-ext" \ + "postgresql-${PG_MAJOR}-pg-catcheck" \ + "postgresql-${PG_MAJOR}-pg-checksums" \ + "postgresql-${PG_MAJOR}-pg-failover-slots" \ + "postgresql-${PG_MAJOR}-pg-hint-plan" \ + "postgresql-${PG_MAJOR}-pg-qualstats" \ + "postgresql-${PG_MAJOR}-pg-stat-kcache" \ + "postgresql-${PG_MAJOR}-pgextwlist" \ + "postgresql-${PG_MAJOR}-pgfaceting" \ + "postgresql-${PG_MAJOR}-pgfincore" \ + "postgresql-${PG_MAJOR}-pglogical" \ + "postgresql-${PG_MAJOR}-pglogical-ticker" \ + "postgresql-${PG_MAJOR}-pgpcre" \ + "postgresql-${PG_MAJOR}-powa" \ + "postgresql-${PG_MAJOR}-repack" \ + "postgresql-${PG_MAJOR}-roaringbitmap" \ + "postgresql-${PG_MAJOR}-rum" \ + "postgresql-${PG_MAJOR}-semver" \ + "postgresql-${PG_MAJOR}-show-plans" \ + "postgresql-${PG_MAJOR}-similarity" \ + "postgresql-${PG_MAJOR}-squeeze" \ + "postgresql-${PG_MAJOR}-tablelog" \ + "postgresql-${PG_MAJOR}-tdigest" \ + "postgresql-${PG_MAJOR}-timescaledb" \ + "postgresql-${PG_MAJOR}-toastinfo" \ + "postgresql-${PG_MAJOR}-unit" \ + "postgresql-${PG_MAJOR}-wal2json" \ + ; \ + apt-clean.sh + +## --- + +FROM postgresql-extras as citus +SHELL [ "/bin/sh", "-ec" ] + +ADD https://packagecloud.io/citusdata/community/gpgkey /etc/apt/keyrings/citus.gpg.bin +COPY /apt/sources.citus /etc/apt/sources.list.d/citus.sources +RUN env -C /etc/apt/keyrings gpg-export.sh citus.gpg.bin citus.gpg.asc +RUN apt-install.sh \ + "postgresql-${PG_MAJOR}-citus-12.1" \ + "postgresql-${PG_MAJOR}-topn" \ + ; apt-clean.sh + +VOLUME [ "${PGHOME}" ] + +## --- + +FROM postgresql as patroni-build +SHELL [ "/bin/sh", "-ec" ] + +# pyyaml +ENV PYYAML_FORCE_CYTHON=1 +# psutil +ENV CIBUILDWHEEL=1 + +RUN apt-install.sh \ + build-essential \ + libffi-dev \ + libpq-dev \ + libyaml-dev \ + ; \ + apt-clean.sh + +RUN pip-env.sh pip install --no-binary :all: 'psycopg[c,pool]' ; \ + pip-env.sh pip install 'cython' ; \ + pip-env.sh pip install --no-binary 'cffi,psutil,pyyaml' 'patroni[etcd3,kubernetes,raft]' ; \ + pip-env.sh pip uninstall -y 'cython' ; \ + site_packages=$(python3 -c 'import site;print(site.getsitepackages()[0])') ; \ + pip-clean.sh "${site_packages}" ; \ + find "${site_packages}/" -type f -name '*.so*' -exec ls -l {} + ; \ + echo ; \ + find "${site_packages}/" -type f -name '*.so*' -printf '%P\0' \ + | sed -zE '/rust/d' \ + | env -C "${site_packages}" xargs -0r strip --strip-debug ; \ + echo ; \ + find "${site_packages}/" -type f -name '*.so*' -exec ls -l {} + + +## --- + +FROM citus as patroni +SHELL [ "/bin/sh", "-ec" ] + +COPY /Dockerfile.interim /usr/local/share/ + +COPY --from=patroni-build /usr/local/bin/ /usr/local/bin/ +COPY --from=patroni-build /usr/local/lib/python3.11/site-packages/ /usr/local/lib/python3.11/site-packages/ + +RUN apt-install.sh \ + libyaml-0-2 \ + ; apt-clean.sh + +WORKDIR "${PGHOME}" + +## "Fast Shutdown mode" in PostgreSQL +## NB: override to SIGTERM in order to switch to "Smart Shutdown mode" +STOPSIGNAL SIGINT + +ENTRYPOINT [ "docker-entrypoint.sh" ] +CMD [ "postgres" ] + +ENV DUMB_INIT_SETSID=0 \ + MALLOC_ARENA_MAX=4 \ + GOMAXPROCS=4 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..67db858 --- /dev/null +++ b/LICENSE @@ -0,0 +1,175 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. diff --git a/apt/sources.citus b/apt/sources.citus new file mode 100644 index 0000000..31b68a4 --- /dev/null +++ b/apt/sources.citus @@ -0,0 +1,5 @@ +Types: deb +URIs: https://packagecloud.io/citusdata/community/debian/ +Suites: bookworm +Components: main +Signed-By: /etc/apt/keyrings/citus.gpg.asc diff --git a/apt/sources.debian b/apt/sources.debian new file mode 100644 index 0000000..abdd3a2 --- /dev/null +++ b/apt/sources.debian @@ -0,0 +1,11 @@ +Types: deb +URIs: http://deb.debian.org/debian +Suites: bookworm bookworm-updates bookworm-proposed-updates +Components: main contrib non-free +Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg + +Types: deb +URIs: http://deb.debian.org/debian-security +Suites: bookworm-security +Components: main contrib non-free +Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg diff --git a/apt/sources.pgdg b/apt/sources.pgdg new file mode 100644 index 0000000..1a8d55c --- /dev/null +++ b/apt/sources.pgdg @@ -0,0 +1,5 @@ +Types: deb +URIs: http://apt.postgresql.org/pub/repos/apt/ +Suites: bookworm-pgdg +Components: main 16 +Signed-By: /etc/apt/keyrings/pgdg.gpg.asc diff --git a/ci/build-image-base.sh b/ci/build-image-base.sh new file mode 100755 index 0000000..e08f85f --- /dev/null +++ b/ci/build-image-base.sh @@ -0,0 +1,16 @@ +#!/bin/sh +set -ef +cd "$(dirname "$0")/.." + +PYTHONTAG="${1:-3.11.9-slim-bookworm}" +exec buildah bud --isolation chroot --network host --format docker \ + -f ./Dockerfile.base \ + -t "local-python:${PYTHONTAG}" \ + --build-arg "PYTHONTAG=${PYTHONTAG}" \ + --pull=missing --no-cache --omit-history \ + --squash \ + --unsetenv GPG_KEY \ + --unsetenv PYTHON_PIP_VERSION \ + --unsetenv PYTHON_SETUPTOOLS_VERSION \ + --unsetenv PYTHON_GET_PIP_SHA256 \ + --unsetenv PYTHON_GET_PIP_URL \ diff --git a/ci/build-image-interim.sh b/ci/build-image-interim.sh new file mode 100755 index 0000000..5fbcd2f --- /dev/null +++ b/ci/build-image-interim.sh @@ -0,0 +1,10 @@ +#!/bin/sh +set -ef +cd "$(dirname "$0")/.." + +PYTHONTAG="${1:-3.11.9-slim-bookworm}" +exec buildah bud --isolation chroot --network host --format docker \ + -f ./Dockerfile.interim \ + -t docker.io/rockdrilla/postgresql:16.3-base \ + --build-arg "PYTHONTAG=${PYTHONTAG}" \ + --pull=missing --no-cache --omit-history \ diff --git a/ci/build-image.sh b/ci/build-image.sh new file mode 100755 index 0000000..4bbf5a6 --- /dev/null +++ b/ci/build-image.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -ef +cd "$(dirname "$0")/.." + +exec buildah bud --isolation chroot --network host --format docker \ + -f ./Dockerfile \ + -t docker.io/rockdrilla/postgresql:16.3 \ + --pull=missing --no-cache --omit-history \ diff --git a/ep.sh b/ep.sh new file mode 100755 index 0000000..e1ddb8b --- /dev/null +++ b/ep.sh @@ -0,0 +1,57 @@ +#!/bin/sh +set -ef + +c="${1##*/}" +case "$c" in +patroni | postgres ) ;; +* ) + unset WITH_CITUS CITUS_PGPASSWORD + exec "$@" +;; +esac + +PATH=$(printf '%s' "${PATH}" | sed -zE 's#(^|:)/usr/local/sbin($|:)##') +PATH="/usr/local/sbin:${PATH}" +export PATH + +## quirk: Citus requires PGPASSWORD to be set however PostgreSQL flushes it +if [ "${WITH_CITUS}" = 1 ] ; then + while [ -z "${CITUS_PGPASSWORD+1}" ] ; do + [ -n "${PGPASSWORD+1}" ] || break + CITUS_PGPASSWORD=${PGPASSWORD} + break ; done + + while [ -z "${CITUS_PGPASSWORD+1}" ] ; do + [ -n "${POSTGRES_PASSWORD_FILE}" ] || break + [ -f "${POSTGRES_PASSWORD_FILE}" ] || break + CITUS_PGPASSWORD=$(cat "${POSTGRES_PASSWORD_FILE}") + break ; done + + while [ -z "${CITUS_PGPASSWORD+1}" ] ; do + [ -n "${POSTGRES_PASSWORD+1}" ] || break + CITUS_PGPASSWORD=${POSTGRES_PASSWORD} + break ; done + + if [ -n "${CITUS_PGPASSWORD+1}" ] ; then + export CITUS_PGPASSWORD + fi +else + unset CITUS_PGPASSWORD +fi +unset WITH_CITUS + +set +e +chown -h postgres:postgres "${PGHOME}" +[ -d "${PGDATA}" ] || install -d -o postgres -g postgres -m 1755 "${PGDATA}" +chown -h postgres:postgres "${PGDATA}" +set -e + +if [ "$c" = postgres ] ; then + exec dumb-init docker-entrypoint.sh "$@" +fi + +if [ "$(id -u)" != 0 ] ; then + exec dumb-init "$@" +fi + +exec dumb-run-as.sh postgres dumb-init "$@" diff --git a/postgres-shim.sh b/postgres-shim.sh new file mode 100755 index 0000000..58b91d5 --- /dev/null +++ b/postgres-shim.sh @@ -0,0 +1,11 @@ +#!/bin/sh +set -ef + +if [ -n "${CITUS_PGPASSWORD+1}" ] ; then + PGPASSWORD=${CITUS_PGPASSWORD} + export PGPASSWORD + unset CITUS_PGPASSWORD +fi + +export PATH="${PATH#/usr/local/sbin:}" +exec postgres "$@" diff --git a/scripts/apt-clean.sh b/scripts/apt-clean.sh new file mode 100755 index 0000000..819debe --- /dev/null +++ b/scripts/apt-clean.sh @@ -0,0 +1,49 @@ +#!/bin/sh +set -f + +## apt +find /var/cache/apt/ ! -type d ! -name 'lock' -delete +find /var/lib/apt/ ! -type d -wholename '/var/lib/apt/listchanges*' -delete +find /var/lib/apt/lists/ ! -type d ! -name 'lock' -delete +find /var/log/ ! -type d -wholename '/var/log/apt/*' -delete +find /var/log/ ! -type d -wholename '/var/log/aptitude*' -delete + +## dpkg +: "${DPKG_ADMINDIR:=/var/lib/dpkg}" +truncate -s 0 "${DPKG_ADMINDIR}/available" +find "${DPKG_ADMINDIR}/" ! -type d -wholename "${DPKG_ADMINDIR}/*-old" -delete +find /var/log/ ! -type d -wholename '/var/log/alternatives.log' -delete +find /var/log/ ! -type d -wholename '/var/log/dpkg.log' -delete + +## debconf +find /var/cache/debconf/ ! -type d -wholename '/var/cache/debconf/*-old' -delete + +__t=$(mktemp) ; : "${__t:?}" +debconf_trim_i18n() { + mawk 'BEGIN { m = 0 } + $0 == "" { print } + /^[^[:space:]]/ { + if ($1 ~ "\.[Uu][Tt][Ff]-?8:") { m = 1; next; } + m = 0; print $0; + } + /^[[:space:]]/ { + if (m == 1) next; + print $0; + }' < "$1" > "${__t}" + cat < "${__t}" > "$1" +} + +debconf_trim_i18n /var/cache/debconf/templates.dat +while read -r tmpl ; do + [ -n "${tmpl}" ] || continue + [ -s "${tmpl}" ] || continue + debconf_trim_i18n "${tmpl}" +done </dev/null +_home=$(getent passwd "${_user}" | cut -d: -f6) +_test_dir() { setpriv --reuid="$1" --regid="$2" --init-groups test -d "$3" ; } +unset _cwd +if ! _test_dir "${_user}" "${_group}" . ; then + _cwd=${_home} + if ! _test_dir "${_user}" "${_group}" "${_cwd}" ; then + _cwd=/ + fi +fi +exec \ + setpriv --reuid="${_user}" --regid="${_group}" --init-groups \ + env ${_cwd:+ -C "${_cwd}" } USER="${_user}" LOGNAME="${_user}" "HOME=${_home}" SHELL=/bin/sh \ + "$@" diff --git a/scripts/gpg-batch.sh b/scripts/gpg-batch.sh new file mode 100755 index 0000000..244ea54 --- /dev/null +++ b/scripts/gpg-batch.sh @@ -0,0 +1,45 @@ +#!/bin/sh +set -ef + +: "${GPG_KEYSERVER:=hkps://keyserver.ubuntu.com}" + +[ $# != 0 ] || exit 1 + +case "$1" in +1 | start ) + [ -n "${GNUPGHOME}" ] || exit 1 + [ -d "${GNUPGHOME}" ] || exit 1 + + cd "${GNUPGHOME}" + cat > gpg.conf <<-EOF + quiet + batch + trust-model always + no-auto-check-trustdb + ignore-time-conflict + keyid-format 0xlong + keyserver ${GPG_KEYSERVER} + EOF + cat > dirmngr.conf <<-EOF + quiet + batch + keyserver ${GPG_KEYSERVER} + EOF + gpg --update-trustdb >/dev/null 2>&1 + gpg --list-keys >/dev/null 2>&1 + dirmngr >/dev/null 2>&1 +;; +0 | stop ) + [ -n "${GNUPGHOME}" ] || exit 0 + [ -d "${GNUPGHOME}" ] || exit 1 + + cd "${GNUPGHOME}" + gpgconf --kill all + cd / + rm -rf "${GNUPGHOME}" +;; +* ) + exit 1 +;; +esac +exit 0 diff --git a/scripts/gpg-export.sh b/scripts/gpg-export.sh new file mode 100755 index 0000000..b38072a --- /dev/null +++ b/scripts/gpg-export.sh @@ -0,0 +1,28 @@ +#!/bin/sh +set -ef + +: "${1:?}" "${2:?}" + +w=$(mktemp -d) ; : "${w:?}" + +gpg_on() { gpg-batch.sh start ; } +gpg_off() { + cd / + gpg-batch.sh stop + unset GNUPGHOME + rm -rf "$w" + exit "${1:-0}" +} + +( + export GNUPGHOME="$w/.gnupg" + mkdir -m 0700 "${GNUPGHOME}" + gpg_on + + gpg --import "$1" + gpg --armor --export > "$w/export" + cat < "$w/export" > "$2" + gpg --show-keys "$2" + + gpg_off +) || gpg_off 1 diff --git a/scripts/pip-clean.sh b/scripts/pip-clean.sh new file mode 100755 index 0000000..039b846 --- /dev/null +++ b/scripts/pip-clean.sh @@ -0,0 +1,7 @@ +#!/bin/sh +set -f +for i ; do + find "$i/" -name __pycache__ -exec rm -rf {} + + find "$i/" ! -type d -name '*.py[co]' -exec rm -f {} + +done +exit 0 diff --git a/scripts/pip-env.sh b/scripts/pip-env.sh new file mode 100755 index 0000000..8a182f8 --- /dev/null +++ b/scripts/pip-env.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -a +PIP_DISABLE_PIP_VERSION_CHECK=1 +PIP_NO_CACHE_DIR=1 +PIP_ROOT_USER_ACTION=ignore +PIP_NO_COMPILE=1 +set +a +exec "$@"