diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 02b9380..16788ac 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -9,6 +9,7 @@ BUNDLED_EXAMPLE_PATH="${INSTALL_DIR}/config.yaml.example" RUNTIME_USER="${USER:-repeater}" RUNTIME_UID="${PUID:-unknown}" RUNTIME_GID="${PGID:-unknown}" +YQ_CMD="${YQ_CMD:-/usr/local/bin/yq}" mkdir -p "${CONFIG_DIR}" @@ -22,6 +23,52 @@ copy_or_die() { fi } +merge_config_from_example() { + config_path="$1" + + if [ ! -f "${config_path}" ] || [ ! -f "${EXAMPLE_PATH}" ]; then + return 0 + fi + + if [ ! -x "${YQ_CMD}" ] || ! "${YQ_CMD}" --version 2>&1 | grep -q "mikefarah/yq"; then + echo "Skipping config merge: mikefarah yq is not available at ${YQ_CMD}." >&2 + return 0 + fi + + tmpdir="$(mktemp -d)" + stripped_user="${tmpdir}/config.stripped.yaml" + merged_config="${tmpdir}/config.merged.yaml" + + cleanup_merge() { + rm -rf "${tmpdir}" + } + trap cleanup_merge EXIT HUP INT TERM + + # Keep only the example's comments to avoid comment duplication across upgrades. + "${YQ_CMD}" eval '... comments=""' "${config_path}" > "${stripped_user}" 2>/dev/null || cp "${config_path}" "${stripped_user}" + + if ! "${YQ_CMD}" eval-all '. as $item ireduce ({}; . * $item)' "${EXAMPLE_PATH}" "${stripped_user}" > "${merged_config}" 2>/dev/null; then + echo "Failed to merge ${config_path} with ${EXAMPLE_PATH}; keeping the existing config." >&2 + cleanup_merge + trap - EXIT HUP INT TERM + return 0 + fi + + if ! "${YQ_CMD}" eval '.' "${merged_config}" >/dev/null 2>&1; then + echo "Merged config for ${config_path} is invalid; keeping the existing config." >&2 + cleanup_merge + trap - EXIT HUP INT TERM + return 0 + fi + + if ! cmp -s "${config_path}" "${merged_config}"; then + copy_or_die "${merged_config}" "${config_path}" + fi + + cleanup_merge + trap - EXIT HUP INT TERM +} + if [ ! -f "${EXAMPLE_PATH}" ] && [ -f "${BUNDLED_EXAMPLE_PATH}" ]; then copy_or_die "${BUNDLED_EXAMPLE_PATH}" "${EXAMPLE_PATH}" fi @@ -35,4 +82,6 @@ elif [ ! -s "${CONFIG_PATH}" ] && [ -f "${EXAMPLE_PATH}" ]; then copy_or_die "${EXAMPLE_PATH}" "${CONFIG_PATH}" fi +merge_config_from_example "${CONFIG_PATH}" + exec python3 -m repeater.main --config "${CONFIG_PATH}" diff --git a/dockerfile b/dockerfile index c789d05..f0b56d6 100644 --- a/dockerfile +++ b/dockerfile @@ -5,6 +5,8 @@ ARG USER=repeater ARG GROUP=repeater ARG PUID=15888 ARG PGID=15888 +ARG TARGETARCH +ARG YQ_VERSION=v4.40.5 ENV INSTALL_DIR=/opt/pymc_repeater \ CONFIG_DIR=/etc/pymc_repeater \ @@ -29,6 +31,17 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y \ python3-dev \ && rm -rf /var/lib/apt/lists/* +RUN arch="${TARGETARCH:-}" \ + && if [ -z "${arch}" ]; then arch="$(uname -m)"; fi \ + && case "${arch}" in \ + amd64|x86_64) YQ_BINARY="yq_linux_amd64" ;; \ + arm64|aarch64) YQ_BINARY="yq_linux_arm64" ;; \ + arm|armv7|armv7l) YQ_BINARY="yq_linux_arm" ;; \ + *) echo "Unsupported architecture for yq: ${arch}" >&2; exit 1 ;; \ + esac \ + && wget -qO /usr/local/bin/yq "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/${YQ_BINARY}" \ + && chmod +x /usr/local/bin/yq + # Create the group and user in order to run without root privileges RUN groupadd --gid "$PGID" "$GROUP" \ && useradd --uid "$PUID" --gid "$PGID" --home-dir "$HOME_DIR" --create-home --shell /usr/bin/bash "$USER"