Skip to content

Commit a53308e

Browse files
committed
Add Docker-based Jepsen environment for GitHub Actions
1 parent 967556f commit a53308e

File tree

5 files changed

+286
-0
lines changed

5 files changed

+286
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
name: Jepsen Docker Run
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
time-limit:
7+
description: "Workload runtime seconds"
8+
required: false
9+
default: "60"
10+
rate:
11+
description: "Ops/sec per worker"
12+
required: false
13+
default: "10"
14+
faults:
15+
description: "Comma-separated faults (partition,kill,clock)"
16+
required: false
17+
default: "partition,kill,clock"
18+
19+
jobs:
20+
jepsen-docker:
21+
runs-on: ubuntu-latest
22+
timeout-minutes: 30
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
with:
27+
submodules: recursive
28+
29+
- name: Set up Go
30+
uses: actions/setup-go@v5
31+
with:
32+
go-version: "1.25.5"
33+
34+
- name: Set up Java
35+
uses: actions/setup-java@v4
36+
with:
37+
distribution: 'temurin'
38+
java-version: '17'
39+
40+
- name: Install Leiningen
41+
run: |
42+
curl -L https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein > lein
43+
chmod +x lein
44+
sudo mv lein /usr/local/bin/
45+
46+
- name: Start Jepsen Docker Cluster
47+
working-directory: jepsen/docker
48+
run: bash up.sh
49+
50+
- name: Run Jepsen workload
51+
working-directory: jepsen
52+
env:
53+
LEIN_JVM_OPTS: -Duser.home=${{ github.workspace }}/jepsen/tmp-home
54+
run: |
55+
mkdir -p tmp-home
56+
# Use generated ssh config
57+
export SSH_CONFIG="${{ github.workspace }}/jepsen/docker/ssh_config"
58+
59+
# Jepsen needs to use the custom ssh config.
60+
# Since we can't easily pass -F to Jepsen's internal SSH calls without modifying clj-ssh or using ~/.ssh/config,
61+
# we will append our config to ~/.ssh/config.
62+
mkdir -p ~/.ssh
63+
cat $SSH_CONFIG >> ~/.ssh/config
64+
chmod 600 ~/.ssh/config
65+
66+
lein run -m elastickv.redis-workload \
67+
--nodes n1,n2,n3,n4,n5 \
68+
--time-limit ${{ github.event.inputs['time-limit'] || '60' }} \
69+
--rate ${{ github.event.inputs['rate'] || '10' }} \
70+
--faults ${{ github.event.inputs['faults'] || 'partition,kill,clock' }} \
71+
--concurrency 10 \
72+
--ssh-user vagrant \
73+
--ssh-key ${{ github.workspace }}/jepsen/docker/id_rsa
74+
75+
- name: Collect Jepsen artifacts
76+
if: always()
77+
working-directory: jepsen
78+
run: |
79+
mkdir -p ../artifacts
80+
tar czf ../artifacts/results.tgz store/ || true
81+
82+
- name: Stop Docker Cluster
83+
if: always()
84+
working-directory: jepsen/docker
85+
run: docker compose down -v
86+
87+
- name: Upload artifacts
88+
if: always()
89+
uses: actions/upload-artifact@v4
90+
with:
91+
name: jepsen-results
92+
path: artifacts/results.tgz

jepsen/docker/Dockerfile

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
FROM debian:bookworm
2+
3+
ENV DEBIAN_FRONTEND=noninteractive
4+
5+
# Install dependencies
6+
# - openssh-server: for Jepsen control
7+
# - sudo: for Jepsen control
8+
# - iptables: for network partitioning (requires --privileged)
9+
# - iproute2: for network introspection
10+
# - netcat-openbsd: for port checking
11+
# - curl, wget: utilities
12+
# - libfaketime: for clock skew nemesis
13+
# - rsync: for file transfer
14+
# - systemd-sysv: minimal init system (optional, but good for compatibility)
15+
RUN apt-get update && apt-get install -y --no-install-recommends \
16+
openssh-server \
17+
sudo \
18+
iptables \
19+
iproute2 \
20+
netcat-openbsd \
21+
curl \
22+
wget \
23+
rsync \
24+
libfaketime \
25+
less \
26+
vim \
27+
&& rm -rf /var/lib/apt/lists/*
28+
29+
# Setup SSH
30+
RUN mkdir /var/run/sshd
31+
# Allow root login with password (for simplicity in test env)
32+
#RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
33+
34+
# Create vagrant user
35+
RUN useradd -m -s /bin/bash vagrant && \
36+
echo "vagrant:vagrant" | chpasswd && \
37+
usermod -aG sudo vagrant
38+
39+
# Allow sudo without password
40+
RUN echo "vagrant ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/vagrant
41+
42+
# Add Vagrant insecure public key
43+
RUN mkdir -p /home/vagrant/.ssh && \
44+
chmod 700 /home/vagrant/.ssh
45+
COPY vagrant.pub /home/vagrant/.ssh/authorized_keys
46+
RUN chmod 600 /home/vagrant/.ssh/authorized_keys && \
47+
chown -R vagrant:vagrant /home/vagrant/.ssh
48+
49+
# Expose SSH
50+
EXPOSE 22
51+
52+
CMD ["/usr/sbin/sshd", "-D"]

jepsen/docker/docker-compose.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
services:
2+
n1:
3+
build: .
4+
hostname: n1
5+
privileged: true # Required for iptables/clock skew
6+
ports:
7+
- "2221:22"
8+
networks:
9+
- jepsen-net
10+
11+
n2:
12+
build: .
13+
hostname: n2
14+
privileged: true
15+
ports:
16+
- "2222:22"
17+
networks:
18+
- jepsen-net
19+
20+
n3:
21+
build: .
22+
hostname: n3
23+
privileged: true
24+
ports:
25+
- "2223:22"
26+
networks:
27+
- jepsen-net
28+
29+
n4:
30+
build: .
31+
hostname: n4
32+
privileged: true
33+
ports:
34+
- "2224:22"
35+
networks:
36+
- jepsen-net
37+
38+
n5:
39+
build: .
40+
hostname: n5
41+
privileged: true
42+
ports:
43+
- "2225:22"
44+
networks:
45+
- jepsen-net
46+
47+
networks:
48+
jepsen-net:
49+
driver: bridge

jepsen/docker/up.sh

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
5+
cd "$SCRIPT_DIR"
6+
7+
# Generate ssh key if not exists (using Vagrant insecure key for convenience matching Dockerfile)
8+
if [ ! -f "id_rsa" ]; then
9+
cat <<'KEY' > id_rsa
10+
-----BEGIN RSA PRIVATE KEY-----
11+
MIIEogIBAAKCAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzI
12+
w+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoP
13+
kcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2
14+
hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NO
15+
Td0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcW
16+
yLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQIBIwKCAQEA4iqWPJXtzZA68mKd
17+
ELs4jJsdyky+ewdZeNds5tjcnHU5zUYE25K+ffJED9qUWICcLZDc81TGWjHyAqD1
18+
Bw7XpgUwFgeUJwUlzQurAv+/ySnxiwuaGJfhFM1CaQHzfXphgVml+fZUvnJUTvzf
19+
TK2Lg6EdbUE9TarUlBf/xPfuEhMSlIE5keb/Zz3/LUlRg8yDqz5w+QWVJ4utnKnK
20+
iqwZN0mwpwU7YSyJhlT4YV1F3n4YjLswM5wJs2oqm0jssQu/BT0tyEXNDYBLEF4A
21+
sClaWuSJ2kjq7KhrrYXzagqhnSei9ODYFShJu8UWVec3Ihb5ZXlzO6vdNQ1J9Xsf
22+
4m+2ywKBgQD6qFxx/Rv9CNN96l/4rb14HKirC2o/orApiHmHDsURs5rUKDx0f9iP
23+
cXN7S1uePXuJRK/5hsubaOCx3Owd2u9gD6Oq0CsMkE4CUSiJcYrMANtx54cGH7Rk
24+
EjFZxK8xAv1ldELEyxrFqkbE4BKd8QOt414qjvTGyAK+OLD3M2QdCQKBgQDtx8pN
25+
CAxR7yhHbIWT1AH66+XWN8bXq7l3RO/ukeaci98JfkbkxURZhtxV/HHuvUhnPLdX
26+
3TwygPBYZFNo4pzVEhzWoTtnEtrFueKxyc3+LjZpuo+mBlQ6ORtfgkr9gBVphXZG
27+
YEzkCD3lVdl8L4cw9BVpKrJCs1c5taGjDgdInQKBgHm/fVvv96bJxc9x1tffXAcj
28+
3OVdUN0UgXNCSaf/3A/phbeBQe9xS+3mpc4r6qvx+iy69mNBeNZ0xOitIjpjBo2+
29+
dBEjSBwLk5q5tJqHmy/jKMJL4n9ROlx93XS+njxgibTvU6Fp9w+NOFD/HvxB3Tcz
30+
6+jJF85D5BNAG3DBMKBjAoGBAOAxZvgsKN+JuENXsST7F89Tck2iTcQIT8g5rwWC
31+
P9Vt74yboe2kDT531w8+egz7nAmRBKNM751U/95P9t88EDacDI/Z2OwnuFQHCPDF
32+
llYOUI+SpLJ6/vURRbHSnnn8a/XG+nzedGH5JGqEJNQsz+xT2axM0/W/CRknmGaJ
33+
kda/AoGANWrLCz708y7VYgAtW2Uf1DPOIYMdvo6fxIB5i9ZfISgcJ/bbCUkFrhoH
34+
+vq/5CIWxCPp0f85R4qxxQ5ihxJ0YDQT9Jpx4TMss4PSavPaBH3RXow5Ohe+bYoQ
35+
NE5OgEXk2wVfZczCZpigBKbKZHNYcelXtTt/nP3rsCuGcM4h53s=
36+
-----END RSA PRIVATE KEY-----
37+
KEY
38+
chmod 600 id_rsa
39+
fi
40+
41+
echo "Starting containers..."
42+
docker compose up -d --build
43+
44+
echo "Generating ssh config..."
45+
cat <<EOF > ssh_config
46+
Host n1
47+
HostName 127.0.0.1
48+
User vagrant
49+
Port 2221
50+
IdentityFile $SCRIPT_DIR/id_rsa
51+
StrictHostKeyChecking no
52+
UserKnownHostsFile /dev/null
53+
LogLevel ERROR
54+
55+
Host n2
56+
HostName 127.0.0.1
57+
User vagrant
58+
Port 2222
59+
IdentityFile $SCRIPT_DIR/id_rsa
60+
StrictHostKeyChecking no
61+
UserKnownHostsFile /dev/null
62+
LogLevel ERROR
63+
64+
Host n3
65+
HostName 127.0.0.1
66+
User vagrant
67+
Port 2223
68+
IdentityFile $SCRIPT_DIR/id_rsa
69+
StrictHostKeyChecking no
70+
UserKnownHostsFile /dev/null
71+
LogLevel ERROR
72+
73+
Host n4
74+
HostName 127.0.0.1
75+
User vagrant
76+
Port 2224
77+
IdentityFile $SCRIPT_DIR/id_rsa
78+
StrictHostKeyChecking no
79+
UserKnownHostsFile /dev/null
80+
LogLevel ERROR
81+
82+
Host n5
83+
HostName 127.0.0.1
84+
User vagrant
85+
Port 2225
86+
IdentityFile $SCRIPT_DIR/id_rsa
87+
StrictHostKeyChecking no
88+
UserKnownHostsFile /dev/null
89+
LogLevel ERROR
90+
EOF
91+
92+
echo "Done. Use 'ssh -F jepsen/docker/ssh_config n1' to connect."

jepsen/docker/vagrant.pub

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDo0XyJqWW9BWnbZYOROSyu2+n15ZbrgPGFa/pM+E4xmHu4B8yMPp4jbWRhR8w/Pr9SNmCeqF3r3LdWHktKPR2cjduPaoAoM1BbXTii7+iHnaZaqD5HJhXQhr3Y+QQOjcYVMFyQU8hMAzMF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key

0 commit comments

Comments
 (0)