diff --git a/README.md b/README.md index 61039f9..9a403b7 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ A great project, don't get me wrong. It was just missing certain key enterprise - Ability to trigger scripts in other containers on completion cron job using `trigger`. ## Config.json +- `name`: Human readable name that will be used as teh job filename. Optional. - `comment`: Comments to be included with crontab entry. Optional. - `schedule`: Crontab schedule syntax as described in https://godoc.org/github.com/robfig/cron. Ex `@hourly`, `@every 1h30m`, `* * * * * *`. Required. - `command`: Command to be run on docker container/image. Required. @@ -57,11 +58,12 @@ See [`config.sample.json`](https://github.com/willfarrell/docker-crontab/blob/ma ### Command Line ```bash -docer build -t crontab . +docker build -t crontab . docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v ./env:/opt/env:ro \ -v /path/to/config/dir:/opt/crontab:rw \ + -v /path/to/logs:/var/log/crontab:rw \ crontab ``` @@ -70,6 +72,7 @@ docker run -d \ FROM willfarrell/crontab COPY config.json ${HOME_DIR}/ + ``` ### Logrotate Dockerfile @@ -83,6 +86,14 @@ COPY logrotate.conf /etc/logrotate.conf CMD ["crond", "-f"] ``` +### Logging +All `stdout` is captured, formatted, and saved to `/var/log/crontab/jobs.log`. Set `LOG_FILE` to `/dev/null` to disable logging. + +example: `2017-06-18T01:27:10+0000 e6ced859-1563-493b-b1b1-5a190b29e938 [info] Start Cronjob **map-a-vol** map a volume` + +grok: `CRONTABLOG %{TIMESTAMP_ISO8601:timestamp} %{DATA:request_id} \[%{LOGLEVEL:severity}\] %{GREEDYDATA:message}` + + ## TODO - [ ] Have ability to auto regenerate crontab on file change (signal HUP?) - [ ] Run commands on host machine (w/ --privileged?) diff --git a/docker-entrypoint b/docker-entrypoint index 1f7ce1e..01b5d25 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -8,6 +8,13 @@ fi # for local testing only #HOME_DIR=. +if [ "${LOG_FILE}" == "" ]; then + LOG_DIR=/var/log/crontab + LOG_FILE=${LOG_DIR}/jobs.log + mkdir -p ${LOG_DIR} + touch ${LOG_FILE} +fi + CONFIG=${HOME_DIR}/config.json DOCKER_SOCK=/var/run/docker.sock CRONTAB_FILE=/etc/crontabs/docker @@ -15,6 +22,7 @@ CRONTAB_FILE=/etc/crontabs/docker # Ensure dir exist - in case of volume mapping mkdir -p ${HOME_DIR}/jobs ${HOME_DIR}/projects + make_image_cmd() { DOCKERARGS=$(echo ${1} | jq -r .dockerargs) if [ "${DOCKERARGS}" == "null" ]; then DOCKERARGS=; fi @@ -37,13 +45,14 @@ make_container_cmd() { cat << EOF > ${HOME_DIR}/projects/${SCRIPT_NAME}.sh #!/usr/bin/env bash set -e - +UUID=$1 +echo "project UUID ${UUID}" CONTAINERS=\$(docker ps --format '{{.Names}}' | grep -E "^${PROJECT}_${CONTAINER}_[0-9]+") for CONTAINER_NAME in \$CONTAINERS; do docker exec ${DOCKERARGS} \${CONTAINER_NAME} ${TMP_COMMAND} done EOF - echo "/bin/bash ${HOME_DIR}/projects/${SCRIPT_NAME}.sh" + echo "/bin/bash ${HOME_DIR}/projects/${SCRIPT_NAME}.sh \${UUID}" else echo "docker exec ${DOCKERARGS} ${CONTAINER} ${TMP_COMMAND}" fi @@ -139,14 +148,24 @@ function build_crontab() { echo "# ${COMMENT}" >> ${CRONTAB_FILE} fi - SCRIPT_NAME=$(cat /proc/sys/kernel/random/uuid) + SCRIPT_NAME=$(jq -r .[$i].name ${CONFIG}) + if [ "${SCRIPT_NAME}" == "null" ]; then + SCRIPT_NAME=$(cat /proc/sys/kernel/random/uuid) + fi + COMMAND="/bin/bash ${HOME_DIR}/jobs/${SCRIPT_NAME}.sh" cat << EOF > ${HOME_DIR}/jobs/${SCRIPT_NAME}.sh #!/usr/bin/env bash set -e +UUID=\$(cat /proc/sys/kernel/random/uuid) +exec > >(read message; echo "\$(date -Iseconds) \${UUID} [info] \$message" | tee -a ${LOG_FILE} ) +exec 2> >(read message; echo "\$(date -Iseconds) \${UUID} [error] \$message" | tee -a ${LOG_FILE} >&2) + +echo "Start Cronjob **${SCRIPT_NAME}** ${COMMENT}" -echo "cron: ${COMMENT}" $(make_cmd "$(jq -c .[$i] ${CONFIG})") + +echo "End Cronjob **${SCRIPT_NAME}** ${COMMENT}" EOF if [ "$(jq -r .[$i].trigger ${CONFIG})" != "null" ]; then while read j ; do