diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7844615 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,38 @@ +ARG BASE=debian:bookworm-slim + +# Build slinktool in a separate container, so resulting container does not +# include compiler tools +FROM $BASE as buildenv +RUN apt update \ + && apt upgrade -y \ + && apt install -y --no-install-recommends \ + build-essential \ + && rm -rf /var/lib/apt/lists/* + +# Build executable +COPY . /build +RUN cd /build && make + +# Build slinktool container +FROM $BASE +RUN apt update \ + && apt upgrade -y \ + && rm -rf /var/lib/apt/lists/* + +# Copy executable and default config from build image +COPY --from=buildenv /build/slinktool / +COPY ./entrypoint.sh / + +# Add non-root user +ARG UID=10000 +ARG GID=10001 +ARG USERNAME=containeruser +RUN \ + groupadd --gid $GID $USERNAME && \ + adduser --uid $UID --gid $GID $USERNAME + +# Drop to regular user +USER $USERNAME + +# See entrypoint.sh for environment variable support. +ENTRYPOINT [ "/entrypoint.sh" ] \ No newline at end of file diff --git a/README.md b/README.md index 254e6df..fe9672f 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,18 @@ A Makefile.win is included for building for using with Nmake, i.e. For further installation simply copy the resulting binary and man page (in the 'doc' directory) to appropriate system directories. +Docker: +A Dockerfile is included for building a container with slinktool compiled. +To build: +``` +docker build -t slinktool:latest . +``` +The entrypoint script will pass though all arguments so usage follows the same syntax as the regular executable: +``` +docker run slinktool -v -o data.mseed slink.host.com:18000 +``` +Note that if you are connecting to seedlink servers running on your local computer, you will need to add `--network="host"` to the docker command in order to use the host name `localhost`. + ## Licensing Copyright (C) 2016 Chad Trabant, IRIS Data Management Center diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..c011a84 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,155 @@ +#!/bin/bash +# +# Entrypoint script to map environment variables into command line arguments. +# +# Three kinds of arguments are supported: +# +# 1. Option and value EG "--port 8888" +# +# Configure these by adding keys to the ARG_MAPPING dictionary in the code. See +# the comments there for details. +# +# Arguments and values will be space separated and values will be single quoted +# in the resulting command EG "--port '8888'". Any unset or empty string +# environment varables do not result in any command line argument being +# specified. +# +# 2. Flags EG "--verbose" +# +# Configure these by adding keys to the ARG_MAPPING dictionary in the code the +# same as above. But use them by setting the environment variable's value to the +# magic Python-inspired value "ACTION_STORE_TRUE". +# +# 3. Subcommands or bare values EG "docker run" +# +# Configure one environment variable name in the ARG_MAPPING dictionary in the +# code the same as above by specifying it with the command line argument magic +# value of "&". This environment variable's value will be added to the very +# end of the command with no quotes. +# +# Any additional arguments passed to this script, except "--debug", will be +# passed to the command. Passing "--debug" will cause this script to enter +# debugging mode and print out information without running the final command. +# +# This requires BASH VERSION 4 OR GREATER. Beware Alpine and other busybox or +# ash based distros. +# +# Example usage in a Dockerfile: +# +# COPY ./entrypoint.sh . +# # Set any default values here, if it's appropriate to build them into the +# # container. +# ENV SAMPLE_VARIABLE=foo +# ENV LESS_USED_OPTION=bar +# +# # Uncomment to build container in debugging entrypoint.sh mode. +# #CMD = ["--debug"] +# ENTRYPOINT ["./entrypoint.sh"] +# +# Example usage in a compose.yml file that runs the above Dockerfile: +# +# services: +# my_service_name: +# image: dockerimagename +# environment: +# SAMPLE_VARIABLE: foo_override +# SOME_OTHER_VARIABLE: not_foo +# LESS_USED_OPTION: '' # value is set to empty string which entrypoint.sh +# # will interpret as unset +# +# Examples running the container from the command line: +# +# # Run container in debugging mode, outputing the command that would be run +# docker run dockerimagename --debug +# +# # Run container overriding SAMPLE_VARIABLE to a new value +# docker run -e SAMPLE_VARIABLE='foo_override' dockerimagename +# +# # Run container with any built-in default variables, but additional command +# # line arguments +# docker run dockerimagename -v --rarely-used-option bar +# + +set -euo pipefail + +declare -A ARG_MAPPING + +# Set program name to run here. +COMMAND_LINE="/slinktool" + +# Add arguments specific to your program here in the form: +# ARGMAPPING["command line arg including dashes"]="environment variable name" +ARG_MAPPING["-V"]="VERSION" +ARG_MAPPING["-h"]="HELP" +ARG_MAPPING["-H"]="EXTENDED_HELP" +ARG_MAPPING["-vv"]="VERBOSE" +ARG_MAPPING["-P"]="PING" +ARG_MAPPING["-pp"]="PRINT_RECORD_DETAILS" +ARG_MAPPING["-u"]="PRINT_RECORD_DATA" +ARG_MAPPING["-nd"]="NETWORK_RECONNECT_DELAY" +ARG_MAPPING["-nt"]="NETWORK_TIMEOUT" +ARG_MAPPING["-k"]="KEEPALIVE" +ARG_MAPPING["-x"]="STATEFILE" +ARG_MAPPING["-d"]="DIALUP" +ARG_MAPPING["-b"]="BATCH" +ARG_MAPPING["-o"]="DUMPFILE" +ARG_MAPPING["-A"]="DIRECTORY_FORMAT" +ARG_MAPPING["-SDS"]="SDS_DIRECTORY" +ARG_MAPPING["-BUD"]="BUD_DIRECTORY" +ARG_MAPPING["-s"]="SELECTORS" +ARG_MAPPING["-I"]="STREAM_LIST_FILE" +ARG_MAPPING["-S"]="STREAM_LIST" +ARG_MAPPING["-tw"]="TIME_WINDOW" +ARG_MAPPING["-i"]="INFO_REQUEST" +ARG_MAPPING["-I"]="INFO_ID" +ARG_MAPPING["-L"]="INFO_STATION_LIST" +ARG_MAPPING["-Q"]="INFO_STREAM_LIST" +ARG_MAPPING["-G"]="INFO_GAP_LIST" +ARG_MAPPING["-C"]="INFO_CONNECTION_LIST" +ARG_MAPPING["&"]="HOST_AND_PORT" + +# Process any additional command line args, eating "--debug" as an argument to +# this script. +DEBUGGING= +for arg +do + shift + if [[ "$arg" == "--debug" ]] ; then + DEBUGGING='true' + else + set -- "$@" "$arg" + fi +done + +if [[ $DEBUGGING ]] ; then + echo "Argument --debug detected, entrypoint.sh entering debugging mode. No command will be run." +fi + +# Build command line arguments from environment variables +SUFFIX_ARGUMENT= +for cl_arg in "${!ARG_MAPPING[@]}"; +do + env_var="${ARG_MAPPING[$cl_arg]}" + if [[ ! -z ${!env_var+x} ]] ; then + if [[ "${!env_var}" == "ACTION_STORE_TRUE" ]] ; then + # Flag option + COMMAND_LINE="${COMMAND_LINE} ${cl_arg}" + elif [[ "${cl_arg}" == "&" ]] ; then + # Subcommand option + SUFFIX_ARGUMENT=${!env_var} + else + # Option and value + COMMAND_LINE="${COMMAND_LINE} ${cl_arg} ${!env_var}" + fi + elif [[ $DEBUGGING ]] ; then + echo "Argument $cl_arg not passed because variable $env_var is unset" + fi +done + +# Run command +if [[ $DEBUGGING ]] ; then + echo "Additional arguments passed to entrypoint.sh: $@" + echo "Final command to be run: $COMMAND_LINE $@ $SUFFIX_ARGUMENT" +else + exec $COMMAND_LINE $@ $SUFFIX_ARGUMENT +fi