summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Blake Kongslie2020-10-30 16:04:16 -0700
committerJulian Blake Kongslie2020-10-30 17:33:31 -0700
commit3e2d71d7b135cc6980cc10a4108130236734551e (patch)
treeec52715eab33236c10f01ab3f47c913f110ec032
downloadolamic-release/1.tar.xz
Initial version.release/1
-rw-r--r--.gitignore8
-rw-r--r--Makefile8
-rw-r--r--debian/changelog5
-rw-r--r--debian/compat1
-rw-r--r--debian/control15
-rw-r--r--debian/copyright7
-rw-r--r--debian/gbp.conf3
-rw-r--r--debian/manpages2
-rw-r--r--debian/olamic.install4
-rw-r--r--debian/olamic.service11
-rwxr-xr-xdebian/rules4
-rw-r--r--debian/source/format1
-rwxr-xr-xexamples/olamic-githook-post-receive23
-rw-r--r--examples/olamic-run25
-rw-r--r--man/olamic-enqueue.1.md24
-rw-r--r--man/olamic-worker.1.md36
-rwxr-xr-xolamic-enqueue50
-rw-r--r--olamic-run14
-rwxr-xr-xolamic-worker83
-rwxr-xr-xpick-task25
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 @@
1MANPAGES := $(basename $(wildcard man/*.md))
2
3build: ${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 @@
1olamic (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 @@
1Source: olamic
2Section: devel
3Priority: optional
4Maintainer: Julian Blake Kongslie <jblake@jblake.org>
5Build-Depends: debhelper (>= 11), pandoc
6Standards-Version: 4.1.3
7
8Package: olamic
9Architecture: all
10Depends: ${misc:Depends}, ${shlibs:Depends}, git, default-mta | mail-transport-agent
11Description: 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 @@
1Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
2Upstream-Name: olamic
3
4Files: *
5Copyright: 2020 Julian Blake Kongslie
6License: 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]
2debian-branch = main
3debian-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 @@
1man/olamic-enqueue.1
2man/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 @@
1examples /usr/share/doc/olamic
2olamic-enqueue /usr/bin
3olamic-worker /usr/bin
4pick-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]
2Description=Olamic worker
3
4[Service]
5Type=simple
6User=olamic
7WorkingDirectory=/srv/olamic
8ExecStart=/usr/bin/olamic-worker
9
10[Install]
11WantedBy=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
3set -eu
4
5OLAMIC_QUEUE_HOST="${OLAMIC_QUEUE_HOST:-}"
6OLAMIC_QUEUE_DIR="${OLAMIC_QUEUE_DIR:-/srv/olamic/queue}"
7OLAMIC_GIT_REPO="${OLAMIC_GIT_REPO:-"$(git rev-parse --absolute-git-dir)"}"
8
9while 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
16END
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
20END
21 fi
22 fi
23done
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
12make
13make test
14
15if [[ $GIT_REF =~ ^refs/tags/(.+)$ ]]; then
16 INSTALL_DIR=/srv/app/tag/"${BASH_REMATCH[1]}"
17elif [[ $GIT_REF =~ ^refs/heads/(.+)$ ]]; then
18 INSTALL_DIR=/srv/app/branch/"${BASH_REMATCH[1]}"
19fi
20
21if [[ "${INSTALL_DIR:-}" != "" ]]; then
22 rm -rf "$INSTALL_DIR"
23 mkdir -p "$INSTALL_DIR"
24 make install PREFIX="$INSTALL_DIR"
25fi
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
7olamic-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
16clone the given repository at the given commit. It reads from stdin a script to
17run within the checkout. Any additional variables passed on the command line
18will be available to the script when it runs.
19
20When **olamic-enqueue** completes, it prints the UUID of the created task.
21
22# SEE ALSO
23
24olamic-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
7olamic-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
16queue, 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
36olamic-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
3set -eu
4
5QUEUE_DIR="$1"; shift
6GIT_REPO="$1"; shift
7GIT_OBJECT="$1"; shift
8
9VARS=()
10VALS=()
11while [[ $# != 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
20done
21
22TASK_SCRIPT="$(cat)"
23
24mkdir -p "$QUEUE_DIR"
25
26cd "$QUEUE_DIR"
27
28mkdir -p candidates tmp
29
30TEMP_TASK="$(mktemp tmp/XXXXXXXX)"
31
32chmod 644 "$TEMP_TASK"
33
34for 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"
38done
39
40printf "export GIT_REPO=%q\n" "$GIT_REPO" >> "$TEMP_TASK"
41printf "export GIT_OBJECT=%q\n" "$GIT_OBJECT" >> "$TEMP_TASK"
42printf "export TASK_SCRIPT=%q\n" "$TASK_SCRIPT" >> "$TEMP_TASK"
43
44UUID="$(uuidgen -r)"
45
46until mv -n "$TEMP_TASK" candidates/"$UUID"; do
47 UUID="$(uuidgen -r)"
48done
49
50echo "$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
3dpkg-buildpackage
4lintian --fail-on error,warning
5
6if [[ $GIT_REF =~ ^refs/tags/(.+)$ ]]; then
7 INSTALL_DIR=/srv/olamic/artifacts/olamic/"${BASH_REMATCH[1]}"
8fi
9
10if [[ "${INSTALL_DIR:-}" != "" ]]; then
11 rm -rf "$INSTALL_DIR"
12 mkdir -p "$INSTALL_DIR"
13 cp -t "$INSTALL_DIR" ../olamic_*
14fi
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
3set -eu -o pipefail
4
5OLAMIC_EMAIL="${OLAMIC_EMAIL:-}"
6OLAMIC_QUEUE_HOST="${OLAMIC_QUEUE_HOST:-}"
7OLAMIC_QUEUE_DIR="${OLAMIC_QUEUE_DIR:-/srv/olamic/queue}"
8OLAMIC_WORKER_PERIOD="${OLAMIC_WORKER_PERIOD:-1m}"
9
10OLAMIC_WORKER_DIR="$(pwd -P)"
11
12while 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
60To: $OLAMIC_EMAIL
61Subject: olamic failure $GIT_REPO $TASK_ID
62Content-type: text/plain
63
64Olamic task $TASK_ID failed with exit code $STATUS.
65
66Environment for the build:
67$(env | sort)
68
69Log from the build:
70$(cat log)
71END
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 )
83done
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
3set -eu
4
5QUEUE_DIR="$1"
6shift
7
8mkdir -p "$QUEUE_DIR"
9cd "$QUEUE_DIR"
10
11mkdir -p candidates in-progress
12
13while 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
25done