Skip to content

Commit

Permalink
import implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Arik Kfir committed Sep 22, 2017
1 parent fe2c476 commit 1902582
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 1 deletion.
24 changes: 24 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
language: generic
sudo: required
services:
- docker

before_script:
- docker login -u "${DOCKERHUB_USERNAME}" -p "${DOCKERHUB_PASSWORD}"
script:
- docker build -t infolinks/crond:${TRAVIS_COMMIT} .
- |
if [[ ${TRAVIS_TAG} =~ ^v[0-9]+$ ]]; then
docker tag infolinks/crond:${TRAVIS_COMMIT} infolinks/crond:${TRAVIS_TAG}
docker push infolinks/crond:${TRAVIS_TAG}
docker tag infolinks/crond:${TRAVIS_COMMIT} infolinks/crond:latest
docker push infolinks/crond:latest
fi
after_script:
- |
if [[ "${TRAVIS_BRANCH}" == "master" ]]; then
docker run infolinks/github-release \
--token="${GITHUB_ACCESS_TOKEN}" \
--repo="${TRAVIS_REPO_SLUG}" \
--commit="${TRAVIS_COMMIT}"
fi
6 changes: 6 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM google/cloud-sdk:171.0.0-alpine
MAINTAINER Arik Kfir <arik@infolinks.com>
COPY ./bin/*.sh /usr/local/bin/
RUN apk add --no-cache dcron bash && \
chmod a+x /usr/local/bin/crond.sh /usr/local/bin/job-executor.sh
ENTRYPOINT ["/usr/local/bin/crond.sh"]
60 changes: 59 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,60 @@
# crond
Docker image running cron daemon for executing periodic jobs.

Docker image running cron daemon for executing a periodic job.

This container receives (via environment variables) a job to run and the
periodic schedule to run it on, and it will start a `crond` server which
will execute that given job on the specified schedule.

## Running

This image can be either extended by another Docker image, preloading
its job, or alternatively it can be run as is, with the actual job and
its schedule to be provided externally (via a mount & environment
variables).

### Running as a standalone image

Here's how to run an hourly job at the beginning of each hour:

docker run \
-v /path/to/my-job.sh:/usr/local/bin/my-job.sh \
-e "SCHEDULE='0 * * * *'" \
-e "JOB_CMDLINE='/usr/local/bin/my-job.sh arg1 arg2 arg3'" \
infolinks/crond

This will run `/usr/local/bin/my-job.sh arg1 arg2 arg3` at `00:00`, at
`01:00`, `02:00`, etc.

### Extending this image

Extending image's `Dockerfile`:

FROM infolinks/crond
COPY my-job.sh /usr/local/bin/
ENV SCHEDULE="0 * * * *"
ENV JOB_CMDLINE="/usr/local/bin/my-job.sh arg1 arg2 arg3"

Build it:

docker build -t my-images/my-job .

And how to run it:

docker run my-images/my-job

Violla!

### Kubernetes

You can also use this container as part of a Kubernetes pod - since you'll
be doing the same things as running this image yourself (mounting the
job script, and setting environment variables) the exact specifics will
be left as a reader's exercise :)

## Contributions

Any contribution to the project will be appreciated! Whether it's bug
reports, feature requests, pull requests - all are welcome, as long as
you follow our [contribution guidelines for this project](CONTRIBUTING.md)
and our [code of conduct](CODE_OF_CONDUCT.md).
50 changes: 50 additions & 0 deletions bin/crond.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/sh

# trap script termination for cleanup
PIDS=""
trap '[ ! -z "${PIDS}" ] && kill -TERM ${PIDS}' EXIT

# print header and verify required parameters
echo
echo "************************************************************"
echo "STARTING crond:"
echo " SCHEDULE: ${SCHEDULE}"
echo " JOB: ${JOB_CMDLINE}"
echo " DEBUG: ${DEBUG}"
echo "************************************************************"
echo
[[ ${DEBUG} == "true" ]] && set -x
[[ -z "${SCHEDULE}" ]] && echo "missing SCHEDULE environment variable (formatted as cron expression)" && exit 1
[[ -z "${JOB_CMDLINE}" ]] && echo "missing JOB_CMDLINE environment variable (the command to execute)" && exit 1

# exit if any command fails
set -e

# generate special file nodes that the job-executor redirects job stdout/stderr to; we will tail on these files into
# this process's stdout/stderr. this enables the container to essentially print the job's stdout/stderr back to the
# docker orchestrator, so it can be harvested into whatever logging solution is used
mkdir -p /var/lib/crond
mknod /var/lib/crond/stdout p
mknod /var/lib/crond/stderr p

# generate the crontab file to be fed into crontab daemon and feed it to crontab
echo "${SCHEDULE} /usr/local/bin/job-executor.sh ${JOB_CMDLINE}" > /root/crontab
crontab /root/crontab

# tail on our special file nodes; redirect '/var/lib/crond/stdout' into this script's stdout, and
# '/var/lib/crond/stderr' to our stderr; we push the tail commands into the background (notice the trailing "&") so both
# will run in parallel, and then we use "wait" to wait indefinitely until "crontab" and the "tail" commands exit
tail -f /var/lib/crond/stdout >&1 &
PIDS="$!"
tail -f /var/lib/crond/stderr >&2 &
PIDS="${PIDS} $!"

# run the crond (the crontab daemon) in the foreground ("-f") but send that thing to the background (trailing "&")
# it's a little weird, but essentially we don't want crond to simply start, schedule background jobs, and exit; we
# want it to stay alive as a foreground process, but we want THAT foreground process to be in the background so we
# can wait for everything (crond and the tail commands). we also want it to stop if this script is interrupted.
crond -f &
PIDS="${PIDS} $!"

# now wait until interrupted
wait
9 changes: 9 additions & 0 deletions bin/job-executor.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh

# expose proper PATHs to job
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# executes given command-line, but redirect its stdout to /var/lib/crond/stdout and its stderr to /var/lib/crond/stderr
# both are special file nodes created by the container entrypoint and are used to redirect job output to the main
# container process's stdout and stderr.
exec $@ 1>>/var/lib/crond/stdout 2>>/var/lib/crond/stderr

0 comments on commit 1902582

Please sign in to comment.