diff options
| author | Julian Blake Kongslie | 2020-10-30 16:04:16 -0700 |
|---|---|---|
| committer | Julian Blake Kongslie | 2020-10-30 17:33:31 -0700 |
| commit | 3e2d71d7b135cc6980cc10a4108130236734551e (patch) | |
| tree | ec52715eab33236c10f01ab3f47c913f110ec032 | |
| download | olamic-3e2d71d7b135cc6980cc10a4108130236734551e.tar.xz | |
Initial version.release/1
Diffstat (limited to '')
| -rw-r--r-- | .gitignore | 8 | ||||
| -rw-r--r-- | Makefile | 8 | ||||
| -rw-r--r-- | debian/changelog | 5 | ||||
| -rw-r--r-- | debian/compat | 1 | ||||
| -rw-r--r-- | debian/control | 15 | ||||
| -rw-r--r-- | debian/copyright | 7 | ||||
| -rw-r--r-- | debian/gbp.conf | 3 | ||||
| -rw-r--r-- | debian/manpages | 2 | ||||
| -rw-r--r-- | debian/olamic.install | 4 | ||||
| -rw-r--r-- | debian/olamic.service | 11 | ||||
| -rwxr-xr-x | debian/rules | 4 | ||||
| -rw-r--r-- | debian/source/format | 1 | ||||
| -rwxr-xr-x | examples/olamic-githook-post-receive | 23 | ||||
| -rw-r--r-- | examples/olamic-run | 25 | ||||
| -rw-r--r-- | man/olamic-enqueue.1.md | 24 | ||||
| -rw-r--r-- | man/olamic-worker.1.md | 36 | ||||
| -rwxr-xr-x | olamic-enqueue | 50 | ||||
| -rw-r--r-- | olamic-run | 14 | ||||
| -rwxr-xr-x | olamic-worker | 83 | ||||
| -rwxr-xr-x | pick-task | 25 |
20 files changed, 349 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a01d365 --- /dev/null +++ b/.gitignore | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | /debian/.debhelper/ | ||
| 2 | /debian/debhelper-build-stamp | ||
| 3 | /debian/files | ||
| 4 | /debian/olamic.postrm.debhelper | ||
| 5 | /debian/olamic.substvars | ||
| 6 | /debian/olamic/ | ||
| 7 | /man/olamic-enqueue.1 | ||
| 8 | /man/olamic-worker.1 | ||
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fc29c78 --- /dev/null +++ b/Makefile | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | MANPAGES := $(basename $(wildcard man/*.md)) | ||
| 2 | |||
| 3 | build: ${MANPAGES} | ||
| 4 | |||
| 5 | .PHONY: build | ||
| 6 | |||
| 7 | %: %.md | ||
| 8 | pandoc -s -t man -o $@ $< | ||
diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..695c208 --- /dev/null +++ b/debian/changelog | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | olamic (1) unstable; urgency=medium | ||
| 2 | |||
| 3 | * Initial version. | ||
| 4 | |||
| 5 | -- Julian Blake Kongslie <jblake@jblake.org> Fri, 30 Oct 2020 16:18:52 -0700 | ||
diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..b4de394 --- /dev/null +++ b/debian/compat | |||
| @@ -0,0 +1 @@ | |||
| 11 | |||
diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..37a7e6b --- /dev/null +++ b/debian/control | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | Source: olamic | ||
| 2 | Section: devel | ||
| 3 | Priority: optional | ||
| 4 | Maintainer: Julian Blake Kongslie <jblake@jblake.org> | ||
| 5 | Build-Depends: debhelper (>= 11), pandoc | ||
| 6 | Standards-Version: 4.1.3 | ||
| 7 | |||
| 8 | Package: olamic | ||
| 9 | Architecture: all | ||
| 10 | Depends: ${misc:Depends}, ${shlibs:Depends}, git, default-mta | mail-transport-agent | ||
| 11 | Description: Very simple continuous integration for git | ||
| 12 | Olamic is a continuous integration system written in bash designed to support | ||
| 13 | the needs of basic projects without involving a web server or anything like | ||
| 14 | that. It supports multiple worker nodes, but does not support dependencies or | ||
| 15 | ordering between tasks. | ||
diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..c2d763c --- /dev/null +++ b/debian/copyright | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ | ||
| 2 | Upstream-Name: olamic | ||
| 3 | |||
| 4 | Files: * | ||
| 5 | Copyright: 2020 Julian Blake Kongslie | ||
| 6 | License: GPL-2 | ||
| 7 | See /usr/share/common-licenses/GPL-2 | ||
diff --git a/debian/gbp.conf b/debian/gbp.conf new file mode 100644 index 0000000..1b36eba --- /dev/null +++ b/debian/gbp.conf | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | [dch] | ||
| 2 | debian-branch = main | ||
| 3 | debian-tag = release/%(version)s | ||
diff --git a/debian/manpages b/debian/manpages new file mode 100644 index 0000000..d87b5e9 --- /dev/null +++ b/debian/manpages | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | man/olamic-enqueue.1 | ||
| 2 | man/olamic-worker.1 | ||
diff --git a/debian/olamic.install b/debian/olamic.install new file mode 100644 index 0000000..6becfd7 --- /dev/null +++ b/debian/olamic.install | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | examples /usr/share/doc/olamic | ||
| 2 | olamic-enqueue /usr/bin | ||
| 3 | olamic-worker /usr/bin | ||
| 4 | pick-task /usr/share/olamic | ||
diff --git a/debian/olamic.service b/debian/olamic.service new file mode 100644 index 0000000..0c36feb --- /dev/null +++ b/debian/olamic.service | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | [Unit] | ||
| 2 | Description=Olamic worker | ||
| 3 | |||
| 4 | [Service] | ||
| 5 | Type=simple | ||
| 6 | User=olamic | ||
| 7 | WorkingDirectory=/srv/olamic | ||
| 8 | ExecStart=/usr/bin/olamic-worker | ||
| 9 | |||
| 10 | [Install] | ||
| 11 | WantedBy=multi-user.target | ||
diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..2d33f6a --- /dev/null +++ b/debian/rules | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | #!/usr/bin/make -f | ||
| 2 | |||
| 3 | %: | ||
| 4 | dh $@ | ||
diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/debian/source/format | |||
| @@ -0,0 +1 @@ | |||
| 3.0 (native) | |||
diff --git a/examples/olamic-githook-post-receive b/examples/olamic-githook-post-receive new file mode 100755 index 0000000..3135d0d --- /dev/null +++ b/examples/olamic-githook-post-receive | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | |||
| 3 | set -eu | ||
| 4 | |||
| 5 | OLAMIC_QUEUE_HOST="${OLAMIC_QUEUE_HOST:-}" | ||
| 6 | OLAMIC_QUEUE_DIR="${OLAMIC_QUEUE_DIR:-/srv/olamic/queue}" | ||
| 7 | OLAMIC_GIT_REPO="${OLAMIC_GIT_REPO:-"$(git rev-parse --absolute-git-dir)"}" | ||
| 8 | |||
| 9 | while read OLD NEW REF; do | ||
| 10 | if git rev-parse --quiet --verify "$NEW":olamic-run > /dev/null; then | ||
| 11 | OLAMIC_EMAIL="$(git show --no-patch --format=%ae "$NEW")" | ||
| 12 | echo -n "Enqueuing olamic run for $REF: " | ||
| 13 | if [[ "$OLAMIC_QUEUE_HOST" == "" ]]; then | ||
| 14 | olamic-enqueue "$OLAMIC_QUEUE_DIR" "$OLAMIC_GIT_REPO" "$NEW" GIT_REF="$REF" OLAMIC_EMAIL="$OLAMIC_EMAIL" <<END | ||
| 15 | . ./olamic-run | ||
| 16 | END | ||
| 17 | else | ||
| 18 | ssh "$OLAMIC_QUEUE_HOST" olamic-enqueue "$OLAMIC_QUEUE_DIR" "$OLAMIC_GIT_REPO" "$NEW" GIT_REF="$REF" OLAMIC_EMAIL="$OLAMIC_EMAIL" <<END | ||
| 19 | . ./olamic-run | ||
| 20 | END | ||
| 21 | fi | ||
| 22 | fi | ||
| 23 | done | ||
diff --git a/examples/olamic-run b/examples/olamic-run new file mode 100644 index 0000000..eebcfb5 --- /dev/null +++ b/examples/olamic-run | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | # vim: set ft=bash : | ||
| 2 | |||
| 3 | # This is an example olamic-run script for a "typical" app | ||
| 4 | # Olamic scripts are run under /bin/bash with "set -eux -o pipefail" in effect | ||
| 5 | |||
| 6 | # Variables provided by olamic | ||
| 7 | # GIT_OBJECT The git commit that was cloned | ||
| 8 | # GIT_REF The ref that triggered this run (post-receive hook) | ||
| 9 | # GIT_REPO The path to the git repo | ||
| 10 | # TASK_ID UUID for this olamic run | ||
| 11 | |||
| 12 | make | ||
| 13 | make test | ||
| 14 | |||
| 15 | if [[ $GIT_REF =~ ^refs/tags/(.+)$ ]]; then | ||
| 16 | INSTALL_DIR=/srv/app/tag/"${BASH_REMATCH[1]}" | ||
| 17 | elif [[ $GIT_REF =~ ^refs/heads/(.+)$ ]]; then | ||
| 18 | INSTALL_DIR=/srv/app/branch/"${BASH_REMATCH[1]}" | ||
| 19 | fi | ||
| 20 | |||
| 21 | if [[ "${INSTALL_DIR:-}" != "" ]]; then | ||
| 22 | rm -rf "$INSTALL_DIR" | ||
| 23 | mkdir -p "$INSTALL_DIR" | ||
| 24 | make install PREFIX="$INSTALL_DIR" | ||
| 25 | fi | ||
diff --git a/man/olamic-enqueue.1.md b/man/olamic-enqueue.1.md new file mode 100644 index 0000000..15434cc --- /dev/null +++ b/man/olamic-enqueue.1.md | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | % OLAMIC-ENQUEUE(1) | ||
| 2 | % Julian B Kongslie | ||
| 3 | % October 2020 | ||
| 4 | |||
| 5 | # NAME | ||
| 6 | |||
| 7 | olamic-enqueue - create a new task for olamic | ||
| 8 | |||
| 9 | # SYNOPSIS | ||
| 10 | |||
| 11 | **olamic-enqueue** **/path/to/queue** **/url/for/git/repo** **git-commit-hash** [**VAR**=**VALUE** ...] | ||
| 12 | |||
| 13 | # DESCRIPTION | ||
| 14 | |||
| 15 | **olamic-enqueue** creates a new task within the specified queue which will | ||
| 16 | clone the given repository at the given commit. It reads from stdin a script to | ||
| 17 | run within the checkout. Any additional variables passed on the command line | ||
| 18 | will be available to the script when it runs. | ||
| 19 | |||
| 20 | When **olamic-enqueue** completes, it prints the UUID of the created task. | ||
| 21 | |||
| 22 | # SEE ALSO | ||
| 23 | |||
| 24 | olamic-worker(1) | ||
diff --git a/man/olamic-worker.1.md b/man/olamic-worker.1.md new file mode 100644 index 0000000..d558f47 --- /dev/null +++ b/man/olamic-worker.1.md | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | % OLAMIC-WORKER(1) | ||
| 2 | % Julian B Kongslie | ||
| 3 | % October 2020 | ||
| 4 | |||
| 5 | # NAME | ||
| 6 | |||
| 7 | olamic-worker - run olamic tasks | ||
| 8 | |||
| 9 | # SYNOPSIS | ||
| 10 | |||
| 11 | **olamic-worker** | ||
| 12 | |||
| 13 | # DESCRIPTION | ||
| 14 | |||
| 15 | **olamic-worker** will continuously try to pull a new task from the olamic | ||
| 16 | queue, and run it. It uses its current working directory as a scratch space. | ||
| 17 | |||
| 18 | # ENVIRONMENT VARIABLES | ||
| 19 | |||
| 20 | **OLAMIC_EMAIL** | ||
| 21 | : The default email to complain to if a task fails. This can (and typically | ||
| 22 | will) be overridden on a per-task basis. | ||
| 23 | |||
| 24 | **OLAMIC_QUEUE_HOST** | ||
| 25 | : The host where the olamic queue lives. Defaults to the local machine. | ||
| 26 | |||
| 27 | **OLAMIC_QUEUE_DIR** | ||
| 28 | : The directory where the olamic queue lives. Defaults to /srv/olamic/queue. | ||
| 29 | |||
| 30 | **OLAMIC_WORKER_PERIOD** | ||
| 31 | : How long the worker sleeps for when it can't find a task. Defaults to one | ||
| 32 | minute. | ||
| 33 | |||
| 34 | # SEE ALSO | ||
| 35 | |||
| 36 | olamic-enqueue(1) | ||
diff --git a/olamic-enqueue b/olamic-enqueue new file mode 100755 index 0000000..1fe7b78 --- /dev/null +++ b/olamic-enqueue | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | |||
| 3 | set -eu | ||
| 4 | |||
| 5 | QUEUE_DIR="$1"; shift | ||
| 6 | GIT_REPO="$1"; shift | ||
| 7 | GIT_OBJECT="$1"; shift | ||
| 8 | |||
| 9 | VARS=() | ||
| 10 | VALS=() | ||
| 11 | while [[ $# != 0 ]]; do | ||
| 12 | VARSET="$1"; shift | ||
| 13 | if [[ $VARSET =~ ^([^=]+)=(.*)$ ]]; then | ||
| 14 | VARS+=("${BASH_REMATCH[1]}") | ||
| 15 | VALS+=("${BASH_REMATCH[2]}") | ||
| 16 | else | ||
| 17 | echo "Usage: $0 queue-dir repo-path git-object [VAR=value ...]" >&2 | ||
| 18 | exit 1 | ||
| 19 | fi | ||
| 20 | done | ||
| 21 | |||
| 22 | TASK_SCRIPT="$(cat)" | ||
| 23 | |||
| 24 | mkdir -p "$QUEUE_DIR" | ||
| 25 | |||
| 26 | cd "$QUEUE_DIR" | ||
| 27 | |||
| 28 | mkdir -p candidates tmp | ||
| 29 | |||
| 30 | TEMP_TASK="$(mktemp tmp/XXXXXXXX)" | ||
| 31 | |||
| 32 | chmod 644 "$TEMP_TASK" | ||
| 33 | |||
| 34 | for i in $(seq 0 $((${#VARS[@]}-1))); do | ||
| 35 | VAR="${VARS[$i]}" | ||
| 36 | VAL="${VALS[$i]}" | ||
| 37 | printf "export %q=%q\n" "$VAR" "$VAL" >> "$TEMP_TASK" | ||
| 38 | done | ||
| 39 | |||
| 40 | printf "export GIT_REPO=%q\n" "$GIT_REPO" >> "$TEMP_TASK" | ||
| 41 | printf "export GIT_OBJECT=%q\n" "$GIT_OBJECT" >> "$TEMP_TASK" | ||
| 42 | printf "export TASK_SCRIPT=%q\n" "$TASK_SCRIPT" >> "$TEMP_TASK" | ||
| 43 | |||
| 44 | UUID="$(uuidgen -r)" | ||
| 45 | |||
| 46 | until mv -n "$TEMP_TASK" candidates/"$UUID"; do | ||
| 47 | UUID="$(uuidgen -r)" | ||
| 48 | done | ||
| 49 | |||
| 50 | echo "$UUID" | ||
diff --git a/olamic-run b/olamic-run new file mode 100644 index 0000000..46fdabc --- /dev/null +++ b/olamic-run | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | # vim: set ft=bash : | ||
| 2 | |||
| 3 | dpkg-buildpackage | ||
| 4 | lintian --fail-on error,warning | ||
| 5 | |||
| 6 | if [[ $GIT_REF =~ ^refs/tags/(.+)$ ]]; then | ||
| 7 | INSTALL_DIR=/srv/olamic/artifacts/olamic/"${BASH_REMATCH[1]}" | ||
| 8 | fi | ||
| 9 | |||
| 10 | if [[ "${INSTALL_DIR:-}" != "" ]]; then | ||
| 11 | rm -rf "$INSTALL_DIR" | ||
| 12 | mkdir -p "$INSTALL_DIR" | ||
| 13 | cp -t "$INSTALL_DIR" ../olamic_* | ||
| 14 | fi | ||
diff --git a/olamic-worker b/olamic-worker new file mode 100755 index 0000000..942151a --- /dev/null +++ b/olamic-worker | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | |||
| 3 | set -eu -o pipefail | ||
| 4 | |||
| 5 | OLAMIC_EMAIL="${OLAMIC_EMAIL:-}" | ||
| 6 | OLAMIC_QUEUE_HOST="${OLAMIC_QUEUE_HOST:-}" | ||
| 7 | OLAMIC_QUEUE_DIR="${OLAMIC_QUEUE_DIR:-/srv/olamic/queue}" | ||
| 8 | OLAMIC_WORKER_PERIOD="${OLAMIC_WORKER_PERIOD:-1m}" | ||
| 9 | |||
| 10 | OLAMIC_WORKER_DIR="$(pwd -P)" | ||
| 11 | |||
| 12 | while true; do | ||
| 13 | if [[ "$OLAMIC_QUEUE_HOST" == "" ]]; then | ||
| 14 | TASK_INFO="$(/usr/share/olamic/pick-task "$OLAMIC_QUEUE_DIR")" | ||
| 15 | else | ||
| 16 | TASK_INFO="$(ssh "$OLAMIC_QUEUE_HOST" /usr/share/olamic/pick-task "$OLAMIC_QUEUE_DIR")" | ||
| 17 | fi | ||
| 18 | |||
| 19 | if [[ "$TASK_INFO" == "" ]]; then | ||
| 20 | sleep "$OLAMIC_WORKER_PERIOD" | ||
| 21 | continue | ||
| 22 | fi | ||
| 23 | |||
| 24 | ( | ||
| 25 | eval "$TASK_INFO" | ||
| 26 | printf "Running task %q\n" "$TASK_ID" | ||
| 27 | |||
| 28 | if [[ ! -e cache.git ]]; then | ||
| 29 | git init --bare cache.git | ||
| 30 | fi | ||
| 31 | |||
| 32 | set +e | ||
| 33 | ( | ||
| 34 | set -ex | ||
| 35 | |||
| 36 | GIT_DIR=cache.git git fetch "$GIT_REPO" "$GIT_OBJECT" | ||
| 37 | |||
| 38 | rm -rf work | ||
| 39 | mkdir work | ||
| 40 | cd work | ||
| 41 | |||
| 42 | git clone --shared "$OLAMIC_WORKER_DIR"/cache.git checkout | ||
| 43 | cd checkout | ||
| 44 | git config advice.detachedHead false | ||
| 45 | git checkout -f "$GIT_OBJECT" | ||
| 46 | |||
| 47 | ( | ||
| 48 | eval "$TASK_SCRIPT" | ||
| 49 | ) | ||
| 50 | ) 2>&1 | tee log | ||
| 51 | STATUS="$?" | ||
| 52 | |||
| 53 | set -e | ||
| 54 | |||
| 55 | if [[ "$STATUS" != "0" ]]; then | ||
| 56 | echo "Task failed with exit code $STATUS" | ||
| 57 | if [[ "$OLAMIC_EMAIL" != "" ]]; then | ||
| 58 | echo "Sending email to $OLAMIC_EMAIL" | ||
| 59 | sendmail -t <<END | ||
| 60 | To: $OLAMIC_EMAIL | ||
| 61 | Subject: olamic failure $GIT_REPO $TASK_ID | ||
| 62 | Content-type: text/plain | ||
| 63 | |||
| 64 | Olamic task $TASK_ID failed with exit code $STATUS. | ||
| 65 | |||
| 66 | Environment for the build: | ||
| 67 | $(env | sort) | ||
| 68 | |||
| 69 | Log from the build: | ||
| 70 | $(cat log) | ||
| 71 | END | ||
| 72 | fi | ||
| 73 | else | ||
| 74 | echo "Task completed successfully" | ||
| 75 | fi | ||
| 76 | |||
| 77 | if [[ "$OLAMIC_QUEUE_HOST" == "" ]]; then | ||
| 78 | rm -f "$OLAMIC_QUEUE_DIR"/in-progress/"$TASK_ID" | ||
| 79 | else | ||
| 80 | ssh "$OLAMIC_QUEUE_HOST" rm -f "$OLAMIC_QUEUE_DIR"/in-progress/"$TASK_ID" | ||
| 81 | fi | ||
| 82 | ) | ||
| 83 | done | ||
diff --git a/pick-task b/pick-task new file mode 100755 index 0000000..0e12bbd --- /dev/null +++ b/pick-task | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | |||
| 3 | set -eu | ||
| 4 | |||
| 5 | QUEUE_DIR="$1" | ||
| 6 | shift | ||
| 7 | |||
| 8 | mkdir -p "$QUEUE_DIR" | ||
| 9 | cd "$QUEUE_DIR" | ||
| 10 | |||
| 11 | mkdir -p candidates in-progress | ||
| 12 | |||
| 13 | while true; do | ||
| 14 | CANDIDATE="$(ls -1 candidates | rl -c 1 2>/dev/null)" | ||
| 15 | |||
| 16 | if [[ "$CANDIDATE" == "" ]]; then | ||
| 17 | break | ||
| 18 | fi | ||
| 19 | |||
| 20 | if mv -n candidates/"$CANDIDATE" in-progress/"$CANDIDATE" 2>/dev/null; then | ||
| 21 | cat in-progress/"$CANDIDATE" | ||
| 22 | printf "export TASK_ID=%q\n" "$CANDIDATE" | ||
| 23 | break | ||
| 24 | fi | ||
| 25 | done | ||
