diff --git a/examples/.gitignore b/examples/.gitignore index f103b36..9758648 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -1,5 +1,6 @@ conf/* data/* +gem-*/* logs/* locks/* projects/* diff --git a/examples/docker-compose.build.yml b/examples/docker-compose.build.yml index 57528e6..da5ba62 100644 --- a/examples/docker-compose.build.yml +++ b/examples/docker-compose.build.yml @@ -17,3 +17,20 @@ services: - ./logs/:/opt/gemstone/logs/ - ./projects/:/opt/gemstone/projects/ - ~/.ssh/:/home/gemstone/.ssh/:ro + gem: + init: true + network_mode: host + depends_on: + stone: + condition: service_started + build: + context: ../source + target: docker-gs64-gem + args: + GS_VERSION: 3.7.0 + environment: + TZ: America/Argentina/Buenos_Aires + volumes: + - ./gem-conf/:/opt/gemstone/conf/ + - ./gem-locks/:/opt/gemstone/locks/ + - ./gem-logs/:/opt/gemstone/logs/ diff --git a/examples/docker-compose.yml b/examples/docker-compose.yml index 28d382b..66a2f6f 100644 --- a/examples/docker-compose.yml +++ b/examples/docker-compose.yml @@ -13,3 +13,16 @@ services: - ./logs/:/opt/gemstone/logs/ - ./projects/:/opt/gemstone/projects/ - ~/.ssh/:/home/gemstone/.ssh/:ro + gem: + init: true + network_mode: host + depends_on: + stone: + condition: service_started + image: ghcr.io/ba-st/gs64-gem:v3.7.0 + environment: + TZ: America/Argentina/Buenos_Aires + volumes: + - ./gem-conf/:/opt/gemstone/conf/ + - ./gem-locks/:/opt/gemstone/locks/ + - ./gem-logs/:/opt/gemstone/logs/ diff --git a/source/Dockerfile b/source/Dockerfile index c24c1a7..51bf894 100644 --- a/source/Dockerfile +++ b/source/Dockerfile @@ -150,3 +150,86 @@ COPY --chown=${GS_USER}:users StdOutTestReporter.gs ${GEMSTONE_GLOBAL_DIR}/StdOu COPY --from=download --chown=${GS_USER}:users /tmp/extent0.rowan.dbf ${GEMSTONE_GLOBAL_DIR}/data/extent0.dbf CMD ["./entrypoint.sh"] + +FROM download as minimal-download + +# Remove non-essential files to keep the final image size small +RUN rm -rf \ + ${GEMSTONE}/bin/copydbf \ + ${GEMSTONE}/bin/gemsetup.csh \ + ${GEMSTONE}/bin/gemstone_data.conf \ + ${GEMSTONE}/bin/pageaudit \ + ${GEMSTONE}/bin/printlogs \ + ${GEMSTONE}/bin/removedbf \ + ${GEMSTONE}/bin/searchlogs \ + ${GEMSTONE}/bin/secure_backup_extract \ + ${GEMSTONE}/bin/slow \ + ${GEMSTONE}/bin/starthostagent \ + ${GEMSTONE}/bin/startlogreceiver \ + ${GEMSTONE}/bin/startlogsender \ + ${GEMSTONE}/bin/startstone \ + ${GEMSTONE}/bin/stophostagent \ + ${GEMSTONE}/bin/stoplogreceiver \ + ${GEMSTONE}/bin/stoplogsender \ + ${GEMSTONE}/bin/stopstone \ + ${GEMSTONE}/bin/superdoit_baseimage_solo \ + ${GEMSTONE}/bin/superdoit_solo \ + ${GEMSTONE}/bin/superdoit_stone \ + ${GEMSTONE}/bin/updatesecuredbf \ + ${GEMSTONE}/bin/upgradeimage \ + ${GEMSTONE}/bin/verify_backup_with_openssl \ + ${GEMSTONE}/bin/waitstone \ + ${GEMSTONE}/bin/x509 \ + ${GEMSTONE}/data \ + ${GEMSTONE}/doc/man1/copydbf* \ + ${GEMSTONE}/doc/man1/pageaudit* \ + ${GEMSTONE}/doc/man1/printlogs* \ + ${GEMSTONE}/doc/man1/removedbf* \ + ${GEMSTONE}/doc/man1/searchlogs* \ + ${GEMSTONE}/doc/man1/secure_backup_extract* \ + ${GEMSTONE}/doc/man1/starthostagent* \ + ${GEMSTONE}/doc/man1/startlogreceiver* \ + ${GEMSTONE}/doc/man1/startlogsender* \ + ${GEMSTONE}/doc/man1/startstone* \ + ${GEMSTONE}/doc/man1/stophostagent* \ + ${GEMSTONE}/doc/man1/stoplogreceiver* \ + ${GEMSTONE}/doc/man1/stoplogsender* \ + ${GEMSTONE}/doc/man1/stopstone* \ + ${GEMSTONE}/doc/man1/updatesecuredbf* \ + ${GEMSTONE}/doc/man1/waitstone* \ + ${GEMSTONE}/doc/man8/stoned* \ + ${GEMSTONE}/sys/hostagenttopaz.ini \ + ${GEMSTONE}/sys/midhostagenttopaz.ini \ + ${GEMSTONE}/sys/runpageauditgem \ + ${GEMSTONE}/sys/stoned \ + ${GEMSTONE}/sys/topazSolo.ini \ + ${GEMSTONE_GLOBAL_DIR}/start-gemstone.sh \ + ${GEMSTONE_GLOBAL_DIR}/entrypoint.sh \ + ; + +## Prepare gem image +FROM base as docker-gs64-gem +LABEL maintainer="Buenos Aires Smalltalk <github@fast.org.ar>" + +ENV GEMSTONE_GLOBAL_DIR=/opt/gemstone +ENV GEMSTONE=${GEMSTONE_GLOBAL_DIR}/product +ENV GEMSTONE_EXE_CONF=${GEMSTONE_GLOBAL_DIR}/conf +ENV GEMSTONE_LOG_DIR=${GEMSTONE_GLOBAL_DIR}/logs + +ENV PATH=$GEMSTONE/bin:$PATH +# Used to determine what shell to use for an exec, such as by System class>>performOnServer:. +ENV SHELL=/usr/bin/bash + +ENV NETLDI_SERVICE_NAME=gs64ldi +ENV NETLDI_PORT=50386 + +# Copy startup scripts +COPY start-gem.sh ${GEMSTONE_GLOBAL_DIR}/start-gem.sh +COPY gem.sh ${GEMSTONE_GLOBAL_DIR}/gem.sh + +COPY --from=minimal-download --chown=${GS_USER}:users ${GEMSTONE_GLOBAL_DIR} ${GEMSTONE_GLOBAL_DIR} +RUN ln -s ${GEMSTONE}/bin/gemsetup.sh /etc/profile.d/gemstone.sh + + +WORKDIR ${GEMSTONE_GLOBAL_DIR} +CMD ["./gem.sh"] diff --git a/source/gem.sh b/source/gem.sh new file mode 100755 index 0000000..6ca86e9 --- /dev/null +++ b/source/gem.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -eu + +echo "${NETLDI_SERVICE_NAME} ${NETLDI_PORT}/tcp # GemStone - Netldi" >> /etc/services + +# Ensure write permissions +NEED_WRITE_PERMISSION=( + "${GEMSTONE_GLOBAL_DIR}/locks/" + "${GEMSTONE_LOG_DIR}/" +) + +for path in "${NEED_WRITE_PERMISSION[@]}"; do + if ! gosu "${GS_USER}" test -w "$path"; then + chown "${GS_UID}:${GS_GID}" "$path" + chmod ug+w "$path" + fi +done + +# Run gemstone as GS_USER +exec gosu "${GS_USER}" "${GEMSTONE_GLOBAL_DIR}/start-gem.sh" diff --git a/source/start-gem.sh b/source/start-gem.sh new file mode 100755 index 0000000..5ec8082 --- /dev/null +++ b/source/start-gem.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# based on https://medium.com/@gchudnov/trapping-signals-in-docker-containers-7a57fdda7d86 +# see also https://docs.docker.com/engine/reference/builder/#exec-form-entrypoint-example +set -eu + +# SIGTERM-handler +sigterm_handler() { + echo 'Got SIGTERM, stopping GemStone/S 64 gem' + stopnetldi + exit 143; # 128 + 15 -- SIGTERM +} + +# setup handlers +# on callback, kill the last background process, +# which is `tail -f /dev/null` and execute the specified handler +trap 'kill ${!}; sigterm_handler' SIGTERM + +# start GemStone services +# shellcheck disable=SC2086 +startnetldi \ + -g \ + -a "${GS_USER}" \ + -n \ + -P "${NETLDI_PORT}" \ + -l "${GEMSTONE_LOG_DIR}/${NETLDI_SERVICE_NAME}.log" \ + ${NETLDI_ARGS:-} \ + "${NETLDI_SERVICE_NAME}" + +# list GemStone services +gslist -cvl + +# wait forever, (loop to handle multiple signals if needed) +while true +do + tail -f /dev/null & wait ${!} +done