2017-02-12 16:28:53 -07:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
set -e
|
|
|
|
|
2017-02-15 10:58:57 -07:00
|
|
|
if [ -z "$DOCKER_HOST" -a "$DOCKER_PORT_2375_TCP" ]; then
|
|
|
|
export DOCKER_HOST='tcp://docker:2375'
|
|
|
|
fi
|
|
|
|
|
2017-02-12 16:28:53 -07:00
|
|
|
# for local testing only
|
|
|
|
#HOME_DIR=.
|
|
|
|
|
2017-06-17 19:41:28 -06:00
|
|
|
if [ "${LOG_FILE}" == "" ]; then
|
|
|
|
LOG_DIR=/var/log/crontab
|
|
|
|
LOG_FILE=${LOG_DIR}/jobs.log
|
|
|
|
mkdir -p ${LOG_DIR}
|
2019-03-02 11:26:21 +03:00
|
|
|
touch ${LOG_FILE}
|
2017-06-17 19:41:28 -06:00
|
|
|
fi
|
|
|
|
|
2019-08-15 10:52:20 -04:00
|
|
|
|
|
|
|
if [ -f "${HOME_DIR}/config.toml" ]; then
|
|
|
|
python3 -c "with open('${HOME_DIR}/config.toml') as ct, open('${HOME_DIR}/config.json', 'w') as cj: import toml; import json; json.dump(list(toml.load(ct).values()), cj)"
|
|
|
|
elif [ -f "${HOME_DIR}/config.yml" ]; then
|
|
|
|
python3 -c "with open('${HOME_DIR}/config.yml') as cy, open('${HOME_DIR}/config.json', 'w') as cj: import yaml; import json; json.dump(list(yaml.safe_load(cy).values()), cj)"
|
|
|
|
elif [ -f "${HOME_DIR}/config.yaml" ]; then
|
|
|
|
python3 -c "with open('${HOME_DIR}/config.yaml') as cy, open('${HOME_DIR}/config.json', 'w') as cj: import yaml; import json; json.dump(list(yaml.safe_load(cy).values()), cj)"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -f "${HOME_DIR}/config.json" ]; then
|
|
|
|
CONFIG=${HOME_DIR}/config.json
|
|
|
|
else
|
|
|
|
echo "NO CONFIG FILE FOUND"
|
|
|
|
fi
|
|
|
|
|
2017-02-12 16:28:53 -07:00
|
|
|
DOCKER_SOCK=/var/run/docker.sock
|
2017-02-14 07:18:25 -07:00
|
|
|
CRONTAB_FILE=/etc/crontabs/docker
|
2017-02-12 16:28:53 -07:00
|
|
|
|
2017-04-07 23:25:53 -06:00
|
|
|
# Ensure dir exist - in case of volume mapping
|
|
|
|
mkdir -p ${HOME_DIR}/jobs ${HOME_DIR}/projects
|
|
|
|
|
2019-03-02 13:43:07 +03:00
|
|
|
ensure_docker_socket_accessible() {
|
|
|
|
if ! grep -q "^docker:" /etc/group; then
|
|
|
|
# Ensure 'docker' user has permissions for docker socket (without changing permissions)
|
|
|
|
DOCKER_GID=$(stat -c '%g' ${DOCKER_SOCK})
|
|
|
|
if [ "${DOCKER_GID}" != "0" ]; then
|
|
|
|
if ! grep -qE "^[^:]+:[^:]+:${DOCKER_GID}:" /etc/group; then
|
|
|
|
# No group with such gid exists - create group docker
|
|
|
|
addgroup -g ${DOCKER_GID} docker
|
|
|
|
adduser docker docker
|
|
|
|
else
|
|
|
|
# Group with such gid exists - add user "docker" to this group
|
|
|
|
DOCKER_GROUP_NAME=`getent group "${DOCKER_GID}" | awk -F':' '{{ print $1 }}'`
|
|
|
|
adduser docker $DOCKER_GROUP_NAME
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
# Docker socket belongs to "root" group - add user "docker" to this group
|
|
|
|
adduser docker root
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
2018-01-09 13:17:49 -08:00
|
|
|
|
2017-11-14 13:54:20 -07:00
|
|
|
slugify() {
|
|
|
|
echo "$@" | iconv -t ascii | sed -r s/[~\^]+//g | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+\|-+$//g | tr A-Z a-z
|
|
|
|
}
|
2017-06-17 19:41:28 -06:00
|
|
|
|
2017-02-12 16:28:53 -07:00
|
|
|
make_image_cmd() {
|
2017-02-12 17:05:46 -07:00
|
|
|
DOCKERARGS=$(echo ${1} | jq -r .dockerargs)
|
2019-08-15 10:52:20 -04:00
|
|
|
VOLUMES=$(echo ${1} | jq -r '.volumes | map(" -v " + .) | join("")')
|
|
|
|
PORTS=$(echo ${1} | jq -r '.ports | map(" -p " + .) | join("")')
|
|
|
|
EXPOSE=$(echo ${1} | jq -r '.expose | map(" --expose " + .) | join("")')
|
|
|
|
# We'll add name in, if it exists
|
|
|
|
NAME=$(echo ${1} | jq -r 'select(.name != null) | .name')
|
|
|
|
NETWORK=$(echo ${1} | jq -r 'select(.network != null) | .network')
|
|
|
|
ENVIRONMENT=$(echo ${1} | jq -r '.environment | map(" -e " + .) | join("")')
|
|
|
|
# echo ${1} | jq -r '.environment | join("\n")' > ${PWD}/${NAME}.env
|
|
|
|
# ENVIRONMENT=" --env-file ${PWD}/${NAME}.env"
|
2017-02-12 16:28:53 -07:00
|
|
|
if [ "${DOCKERARGS}" == "null" ]; then DOCKERARGS=; fi
|
2019-08-15 10:52:20 -04:00
|
|
|
if [ ! -z "${NAME}" ]; then DOCKERARGS="${DOCKERARGS} --rm --name ${NAME} "; fi
|
|
|
|
if [ ! -z "${NETWORK}" ]; then DOCKERARGS="${DOCKERARGS} --network ${NETWORK} "; fi
|
|
|
|
if [ ! -z "${VOLUMES}" ]; then DOCKERARGS="${DOCKERARGS}${VOLUMES}"; fi
|
|
|
|
if [ ! -z "${ENVIRONMENT}" ]; then DOCKERARGS="${DOCKERARGS}${ENVIRONMENT}"; fi
|
|
|
|
if [ ! -z "${PORTS}" ]; then DOCKERARGS="${DOCKERARGS}${PORTS}"; fi
|
|
|
|
if [ ! -z "${EXPOSE}" ]; then DOCKERARGS="${DOCKERARGS}${EXPOSE}"; fi
|
2019-03-02 11:26:21 +03:00
|
|
|
IMAGE=$(echo ${1} | jq -r .image | envsubst)
|
2017-02-12 17:05:46 -07:00
|
|
|
TMP_COMMAND=$(echo ${1} | jq -r .command)
|
2017-02-12 16:28:53 -07:00
|
|
|
echo "docker run ${DOCKERARGS} ${IMAGE} ${TMP_COMMAND}"
|
|
|
|
}
|
|
|
|
|
|
|
|
make_container_cmd() {
|
2017-02-12 17:05:46 -07:00
|
|
|
DOCKERARGS=$(echo ${1} | jq -r .dockerargs)
|
2017-02-12 16:28:53 -07:00
|
|
|
if [ "${DOCKERARGS}" == "null" ]; then DOCKERARGS=; fi
|
2017-06-17 20:10:47 -06:00
|
|
|
SCRIPT_NAME=$(echo ${1} | jq -r .name)
|
2019-03-01 20:50:12 +01:00
|
|
|
SCRIPT_NAME=$(slugify $SCRIPT_NAME)
|
2017-02-12 17:05:46 -07:00
|
|
|
PROJECT=$(echo ${1} | jq -r .project)
|
2019-03-02 11:26:21 +03:00
|
|
|
CONTAINER=$(echo ${1} | jq -r .container | envsubst)
|
2017-02-12 17:05:46 -07:00
|
|
|
TMP_COMMAND=$(echo ${1} | jq -r .command)
|
2017-02-12 16:28:53 -07:00
|
|
|
|
|
|
|
if [ "${PROJECT}" != "null" ]; then
|
|
|
|
|
|
|
|
# create bash script to detect all running containers
|
2017-06-17 20:10:47 -06:00
|
|
|
if [ "${SCRIPT_NAME}" == "null" ]; then
|
|
|
|
SCRIPT_NAME=$(cat /proc/sys/kernel/random/uuid)
|
|
|
|
fi
|
2017-02-14 07:18:25 -07:00
|
|
|
cat << EOF > ${HOME_DIR}/projects/${SCRIPT_NAME}.sh
|
2017-02-12 21:37:00 -07:00
|
|
|
#!/usr/bin/env bash
|
2017-02-12 16:28:53 -07:00
|
|
|
set -e
|
2017-06-17 20:10:47 -06:00
|
|
|
|
2017-10-09 11:03:39 +01:00
|
|
|
CONTAINERS=\$(docker ps --format '{{.Names}}' | grep -E "^${PROJECT}_${CONTAINER}.[0-9]+")
|
2017-02-12 16:28:53 -07:00
|
|
|
for CONTAINER_NAME in \$CONTAINERS; do
|
2017-02-14 07:18:25 -07:00
|
|
|
docker exec ${DOCKERARGS} \${CONTAINER_NAME} ${TMP_COMMAND}
|
2017-02-12 16:28:53 -07:00
|
|
|
done
|
|
|
|
EOF
|
2017-06-17 20:10:47 -06:00
|
|
|
echo "/bin/bash ${HOME_DIR}/projects/${SCRIPT_NAME}.sh"
|
2019-08-15 10:52:20 -04:00
|
|
|
# cat "/bin/bash ${HOME_DIR}/projects/${SCRIPT_NAME}.sh"
|
2017-02-12 16:28:53 -07:00
|
|
|
else
|
|
|
|
echo "docker exec ${DOCKERARGS} ${CONTAINER} ${TMP_COMMAND}"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2017-02-14 07:44:14 -07:00
|
|
|
#make_host_cmd() {
|
|
|
|
# HOST_BINARY=$(echo ${1} | jq -r .host)
|
|
|
|
# TMP_COMMAND=$(echo ${1} | jq -r .command)
|
|
|
|
# echo "${HOST_BINARY} ${TMP_COMMAND}"
|
|
|
|
#}
|
|
|
|
|
2017-02-12 16:28:53 -07:00
|
|
|
make_cmd() {
|
2017-02-12 21:08:45 -07:00
|
|
|
if [ "$(echo ${1} | jq -r .image)" != "null" ]; then
|
|
|
|
make_image_cmd "$1"
|
|
|
|
elif [ "$(echo ${1} | jq -r .container)" != "null" ]; then
|
|
|
|
make_container_cmd "$1"
|
2017-02-14 07:44:14 -07:00
|
|
|
#elif [ "$(echo ${1} | jq -r .host)" != "null" ]; then
|
|
|
|
# make_host_cmd "$1"
|
2017-02-12 16:28:53 -07:00
|
|
|
else
|
2017-02-12 21:08:45 -07:00
|
|
|
echo ${1} | jq -r .command
|
2017-02-12 16:28:53 -07:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
parse_schedule() {
|
|
|
|
case $1 in
|
|
|
|
"@yearly")
|
2017-10-23 09:45:24 -06:00
|
|
|
echo "0 0 1 1 *"
|
2017-02-12 16:28:53 -07:00
|
|
|
;;
|
|
|
|
"@annually")
|
2017-10-23 09:45:24 -06:00
|
|
|
echo "0 0 1 1 *"
|
2017-02-12 16:28:53 -07:00
|
|
|
;;
|
|
|
|
"@monthly")
|
2017-10-23 09:45:24 -06:00
|
|
|
echo "0 0 1 * *"
|
2017-02-12 16:28:53 -07:00
|
|
|
;;
|
|
|
|
"@weekly")
|
2017-10-23 09:45:24 -06:00
|
|
|
echo "0 0 * * 0"
|
2017-02-12 16:28:53 -07:00
|
|
|
;;
|
|
|
|
"@daily")
|
2017-10-23 09:45:24 -06:00
|
|
|
echo "0 0 * * *"
|
2017-02-12 16:28:53 -07:00
|
|
|
;;
|
|
|
|
"@midnight")
|
2017-10-23 09:45:24 -06:00
|
|
|
echo "0 0 * * *"
|
2017-02-12 16:28:53 -07:00
|
|
|
;;
|
|
|
|
"@hourly")
|
2017-10-23 09:45:24 -06:00
|
|
|
echo "0 * * * *"
|
2017-02-12 16:28:53 -07:00
|
|
|
;;
|
|
|
|
"@every")
|
|
|
|
TIME=$2
|
|
|
|
TOTAL=0
|
|
|
|
|
|
|
|
M=$(echo $TIME | grep -o '[0-9]\+m')
|
|
|
|
H=$(echo $TIME | grep -o '[0-9]\+h')
|
|
|
|
D=$(echo $TIME | grep -o '[0-9]\+d')
|
|
|
|
|
|
|
|
if [ -n "${M}" ]; then
|
|
|
|
TOTAL=$(($TOTAL + ${M::-1}))
|
|
|
|
fi
|
|
|
|
if [ -n "${H}" ]; then
|
|
|
|
TOTAL=$(($TOTAL + ${H::-1} * 60))
|
|
|
|
fi
|
|
|
|
if [ -n "${D}" ]; then
|
|
|
|
TOTAL=$(($TOTAL + ${D::-1} * 60 * 24))
|
|
|
|
fi
|
|
|
|
|
2017-10-23 09:45:24 -06:00
|
|
|
echo "*/${TOTAL} * * * *"
|
2017-02-12 16:28:53 -07:00
|
|
|
;;
|
|
|
|
*)
|
|
|
|
echo "${@}"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
function build_crontab() {
|
|
|
|
rm -rf ${CRONTAB_FILE}
|
2017-02-14 07:18:25 -07:00
|
|
|
|
|
|
|
ONSTART=()
|
2017-02-12 16:28:53 -07:00
|
|
|
while read i ; do
|
|
|
|
|
|
|
|
SCHEDULE=$(jq -r .[$i].schedule ${CONFIG} | sed 's/\*/\\*/g')
|
|
|
|
if [ "${SCHEDULE}" == "null" ]; then
|
|
|
|
echo "Schedule Missing: $(jq -r .[$i].schedule ${CONFIG})"
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
SCHEDULE=$(parse_schedule ${SCHEDULE} | sed 's/\\//g')
|
|
|
|
|
|
|
|
if [ "$(jq -r .[$i].command ${CONFIG})" == "null" ]; then
|
|
|
|
echo "Command Missing: $(jq -r .[$i].command ${CONFIG})"
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
|
2017-02-15 13:42:35 -07:00
|
|
|
COMMENT=$(jq -r .[$i].comment ${CONFIG})
|
|
|
|
if [ "${COMMENT}" != "null" ]; then
|
|
|
|
echo "# ${COMMENT}" >> ${CRONTAB_FILE}
|
|
|
|
fi
|
|
|
|
|
2017-06-17 19:41:28 -06:00
|
|
|
SCRIPT_NAME=$(jq -r .[$i].name ${CONFIG})
|
2017-11-14 13:54:20 -07:00
|
|
|
SCRIPT_NAME=$(slugify $SCRIPT_NAME)
|
2017-06-17 19:41:28 -06:00
|
|
|
if [ "${SCRIPT_NAME}" == "null" ]; then
|
|
|
|
SCRIPT_NAME=$(cat /proc/sys/kernel/random/uuid)
|
|
|
|
fi
|
|
|
|
|
2017-02-15 11:16:11 -07:00
|
|
|
COMMAND="/bin/bash ${HOME_DIR}/jobs/${SCRIPT_NAME}.sh"
|
|
|
|
cat << EOF > ${HOME_DIR}/jobs/${SCRIPT_NAME}.sh
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
set -e
|
2017-06-17 20:55:56 -06:00
|
|
|
|
|
|
|
# TODO find workaround
|
|
|
|
# [error] write /dev/stdout: broken pipe <- when using docker commands
|
|
|
|
#UUID=\$(cat /proc/sys/kernel/random/uuid)
|
2017-06-21 13:14:00 -06:00
|
|
|
#exec > >(read message; echo "\${UUID} \$(date -Iseconds) [info] \$message" | tee -a ${LOG_FILE} )
|
|
|
|
#exec 2> >(read message; echo "\${UUID} \$(date -Iseconds) [error] \$message" | tee -a ${LOG_FILE} >&2)
|
2017-06-17 20:10:47 -06:00
|
|
|
|
2017-06-17 19:41:28 -06:00
|
|
|
echo "Start Cronjob **${SCRIPT_NAME}** ${COMMENT}"
|
2017-02-15 11:16:11 -07:00
|
|
|
|
|
|
|
$(make_cmd "$(jq -c .[$i] ${CONFIG})")
|
|
|
|
EOF
|
2017-06-17 20:55:56 -06:00
|
|
|
|
|
|
|
|
|
|
|
|
2017-02-12 16:28:53 -07:00
|
|
|
if [ "$(jq -r .[$i].trigger ${CONFIG})" != "null" ]; then
|
|
|
|
while read j ; do
|
|
|
|
if [ "$(jq .[$i].trigger[$j].command ${CONFIG})" == "null" ]; then
|
|
|
|
echo "Command Missing: $(jq -r .[$i].trigger[$j].command ${CONFIG})"
|
|
|
|
continue
|
|
|
|
fi
|
2017-02-15 11:16:11 -07:00
|
|
|
#TRIGGER_COMMAND=$(make_cmd "$(jq -c .[$i].trigger[$j] ${CONFIG})")
|
2017-02-15 11:23:52 -07:00
|
|
|
echo "$(make_cmd "$(jq -c .[$i].trigger[$j] ${CONFIG})")" >> ${HOME_DIR}/jobs/${SCRIPT_NAME}.sh
|
2017-02-15 11:16:11 -07:00
|
|
|
#COMMAND="${COMMAND} && ${TRIGGER_COMMAND}"
|
2017-02-12 16:28:53 -07:00
|
|
|
done < <(jq -r '.['$i'].trigger|keys[]' ${CONFIG})
|
|
|
|
fi
|
|
|
|
|
2017-06-17 20:55:56 -06:00
|
|
|
echo "echo \"End Cronjob **${SCRIPT_NAME}** ${COMMENT}\"" >> ${HOME_DIR}/jobs/${SCRIPT_NAME}.sh
|
|
|
|
|
2017-02-12 16:28:53 -07:00
|
|
|
echo "${SCHEDULE} ${COMMAND}" >> ${CRONTAB_FILE}
|
2017-02-14 07:18:25 -07:00
|
|
|
|
|
|
|
if [ "$(jq -r .[$i].onstart ${CONFIG})" == "true" ]; then
|
|
|
|
ONSTART+=("${COMMAND}")
|
|
|
|
fi
|
2017-02-12 16:28:53 -07:00
|
|
|
done < <(jq -r '.|keys[]' ${CONFIG})
|
|
|
|
|
2017-02-15 07:03:07 -07:00
|
|
|
echo "##### crontab generation complete #####"
|
2017-02-12 16:28:53 -07:00
|
|
|
cat ${CRONTAB_FILE}
|
2017-02-14 07:18:25 -07:00
|
|
|
|
2017-02-15 07:03:07 -07:00
|
|
|
echo "##### run commands with onstart #####"
|
2017-04-07 23:25:53 -06:00
|
|
|
for COMMAND in "${ONSTART[@]}"; do
|
2017-02-15 07:03:07 -07:00
|
|
|
echo "${COMMAND}"
|
2017-02-14 07:44:14 -07:00
|
|
|
${COMMAND} &
|
2017-02-14 07:18:25 -07:00
|
|
|
done
|
2017-02-12 16:28:53 -07:00
|
|
|
}
|
|
|
|
|
2019-03-02 13:43:07 +03:00
|
|
|
ensure_docker_socket_accessible
|
|
|
|
|
2017-02-12 16:57:19 -07:00
|
|
|
if [ "$1" = "crond" ]; then
|
|
|
|
if [ -f ${CONFIG} ]; then
|
|
|
|
build_crontab
|
|
|
|
else
|
2019-08-15 10:52:20 -04:00
|
|
|
echo "Unable to find ${CONFIG}"
|
2017-02-12 16:57:19 -07:00
|
|
|
fi
|
2017-02-12 16:28:53 -07:00
|
|
|
fi
|
|
|
|
|
|
|
|
echo "$@"
|
2017-10-09 11:03:39 +01:00
|
|
|
exec "$@"
|