Skip to content

Commit

Permalink
Add docker image, devcontainer, and editorconfig support (cmu-db#151)
Browse files Browse the repository at this point in the history
Co-authored-by: Andy Pavlo <[email protected]>
  • Loading branch information
bpkroth and apavlo authored Jun 4, 2022
1 parent c19acc1 commit 21265a6
Show file tree
Hide file tree
Showing 12 changed files with 312 additions and 4 deletions.
41 changes: 41 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.231.6/containers/docker-existing-dockerfile
{
"name": "Workspace Dockerfile",

// Sets the run context to one level up instead of the .devcontainer folder.
"context": "..",

// Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename.
"dockerFile": "../docker/benchbase/Dockerfile",
"build": {
"target": "devcontainer",
"args": {
"--tag": "benchbase-dev:latest"
}
},

// Set *default* container specific settings.json values on container create.
"settings": {},

// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"vscjava.vscode-java-pack",
"EditorConfig.EditorConfig"
],

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Uncomment the next line to run commands after the container is created - for example installing curl.
// "postCreateCommand": "apt-get update && apt-get install -y curl",

// Uncomment when using a ptrace-based debugger like C++, Go, and Rust
// "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ],

// Uncomment to use the Docker CLI from inside the container. See https://aka.ms/vscode-remote/samples/docker-from-docker.
// "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ],

// Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "containeruser"
}
11 changes: 11 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.dockerignore
docker/
!docker/benchbase/entrypoint.sh
#.git/
.github/
.mvn/
mvnw.cmd
mvnw
target/
results/
profiles/
21 changes: 21 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
root = true

[*]
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

# Makefiles need tab indentation
[{Makefile,*.mk}]
indent_style = tab
tab_width = 8
end_of_line = lf

[{*.ps1,*.cmd,*.bat}]
end_of_line = crlf

[*.sh]
end_of_line = lf

[*.yml]
indent_size = 2
50 changes: 48 additions & 2 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ jobs:
- name: Run benchmark
run: |
java -jar benchbase.jar -b ${{matrix.benchmark}} -c config/sqlite/sample_${{matrix.benchmark}}_config.xml --create=true --load=true --execute=true
## ----------------------------------------------------------------------------------
## MARIADB
## ----------------------------------------------------------------------------------
Expand Down Expand Up @@ -356,3 +355,50 @@ jobs:
run: |
java -jar benchbase.jar -b ${{matrix.benchmark}} -c config/sqlserver/sample_${{matrix.benchmark}}_config.xml --create=true --load=true --execute=true
## ----------------------------------------------------------------------------------
## Docker Build Test
## ----------------------------------------------------------------------------------
docker-build-test:
runs-on: ubuntu-latest
services:
postgres: # https://hub.docker.com/_/postgres
image: postgres:latest
env:
POSTGRES_DB: benchbase
POSTGRES_USER: admin
POSTGRES_PASSWORD: password
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Setup postgres test DB
run: |
PGPASSWORD=password dropdb -h localhost -U admin benchbase --if-exists
PGPASSWORD=password createdb -h localhost -U admin benchbase
- name: Checkout repo
uses: actions/checkout@v2
- name: Build docker image with all packages and run test suite
env:
DOCKER_BUILDKIT: 1
BENCHBASE_PROFILES: 'cockroachdb mariadb mysql postgres spanner phoenix sqlserver'
run: |
docker build --build-arg "BENCHBASE_PROFILES=$BENCHBASE_PROFILES" --build-arg TEST_TARGET=test --build-arg UID=$UID --build-arg GID=$UID \
-t benchbase:latest -f ./docker/benchbase/Dockerfile --target fullimage .
- name: Run basic benchbase test from the docker image against postgres test DB
env:
benchmark: noop
run: |
# Adjust the sample config to talk to the container service instead of localhost.
cat "config/postgres/sample_${benchmark}_config.xml" | sed -e 's/localhost:5432/postgres:5432/g' > /tmp/config.xml
# Lookup the service container's docker network so we can place the benchbase container in it too.
docker_network="$(docker ps --filter expose=5432 --format '{{.Networks}}')"
# Map the adjusted config into the container and use it to run the test.
mkdir -p results
docker run --rm --name benchbase-postgres --network "$docker_network" \
--env BENCHBASE_PROFILE=postgres -v /tmp/config.xml:/tmp/config.xml -v "$PWD/results:/benchbase/results" \
benchbase:latest -b "$benchmark" -c /tmp/config.xml --create=true --load=true --execute=true
ls results/${benchmark}_*.csv
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,6 @@ build/
### VS Code ###
.vscode/
*.log

# vim swap files
.*.swp
26 changes: 24 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ java -jar benchbase.jar -h

Benchmarking is incredibly useful, yet endlessly painful. This benchmark suite is the result of a group of
PhDs/post-docs/professors getting together and combining their workloads/frameworks/experiences/efforts. We hope this
will save other people's time, and will provide an extensible platform, that can be grown in an open-source fashion.
will save other people's time, and will provide an extensible platform, that can be grown in an open-source fashion.

BenchBase is a multi-threaded load generator. The framework is designed to be able to produce variable rate,
variable mixture load against any JDBC-enabled relational database. The framework also provides data collection
Expand Down Expand Up @@ -146,7 +146,7 @@ usage: benchbase
Instead of first building, packaging and extracting before running benchbase, it is possible to execute benchmarks directly against the source code using Maven. Once you have the project cloned you can run any benchmark from the root project directory using the Maven `exec:java` goal. For example, the following command executes the `tpcc` benchmark against `postgres`:

```
mvn clean compile exec:java -P postgres -Dexec.args="-b tpcc -c config/postgres/sample_tpcc_config.xml --create=true --load=true --execute=true"
mvn clean compile exec:java -P postgres -Dexec.args="-b tpcc -c config/postgres/sample_tpcc_config.xml --create=true --load=true --execute=true"
```

this is equivalent to the steps above but eliminates the need to first package and then extract the distribution.
Expand All @@ -168,6 +168,28 @@ To modify the logging level you can update [`logging.properties`](src/main/resou
./mvnw -B release:perform
```

### How use with Docker

- Build the full image:

```sh
# build an image with all profiles
./docker/benchbase/build-full-image.sh

# or if you only want to build some of them
BENCHBASE_PROFILES='postgres mysql' ./docker/benchbase/build-full-image.sh
```

- Run the image for a given profile:

```sh
BENCHBASE_PROFILE='postgres' ./docker/benchbase/run-full-image.sh --help # or other benchbase args as before
```

> See [scripts](./docker/benchbase/) for further details.
[Github Codespaces](https://github.com/features/codespaces) and [VSCode devcontainer](https://code.visualstudio.com/docs/remote/containers) support is also available.

### How to Add Support for a New Database

Please see the existing MySQL and PostgreSQL code for an example.
Expand Down
81 changes: 81 additions & 0 deletions docker/benchbase/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# A simple dev environment container for benchbase.
#
# - Build:
#
# - Full image:
#
# docker build -t benchbase -f Dockerfile ../..
#
# - Dev only:
#
# # Skip copying and building the source into the devcontainer image since we will map it in later.
# docker build -t benchbase-dev -f Dockerfile --target devcontainer ../..
#
# - Run:
#
# - Full image:
#
# # Map the config to read in and a place for the results to be written out.
# docker run -it --rm --name benchbase -v $PWD/config:/benchbase/config -v $PWD/results:/benchbase/results --env BENCHBASE_PROFILE=postgres benchbase -- <benchbase args>
#
# - Dev image:
#
# # Map the whole source directory into the container.
# # Optionally build the source as the container launch executable.
# docker run -it --rm --name benchbase-dev -v $PWD:/benchbase benchbase-dev mvn clean package -P postgres

FROM --platform=linux maven:3.8.5-eclipse-temurin-17 AS devcontainer

# Add a containeruser that allows vscode/codespaces to map the local host user
# (often uid 1000) to some non-root user inside the container.
ARG UID=1000
ARG GID=1000
RUN addgroup --gid ${GID} containergroup \
&& adduser --disabled-password --gecos 'Container User' --uid ${UID} --gid ${GID} containeruser
RUN mkdir -p /benchbase/results && chown -R containeruser:containergroup /benchbase/
USER containeruser
ENV MAVEN_CONFIG=/home/containeruser/.m2
WORKDIR /benchbase

# When running the devcontainer, just launch an interactive shell by default.
ENTRYPOINT ["/bin/bash", "-l"]

# Copy the full source into the container image.
# Assumes the context is given as the root of the repo.

# Preload some dependencies.
COPY --chown=containeruser:containergroup pom.xml /benchbase/pom.xml
COPY --chown=containeruser:containergroup .git/ /benchbase/.git/
ARG MAVEN_OPTS
RUN mvn -B --file pom.xml initialize \
&& rm -rf /benchbase/.git /benchbase/target /benchbase/pom.xml

# Add an additional layer that also includes a built copy of the source.
FROM devcontainer AS fullimage

USER containeruser

VOLUME /benchbase/results

COPY --chown=containeruser:containergroup ./ /benchbase/
# Uncomment for slightly faster incremental testing (since intermediate layers can be cached)
# at the expense of additional docker image layers.
ARG TEST_TARGET=
RUN mvn -B --file pom.xml process-resources compile ${TEST_TARGET}
# Build all of the profiles into the image.
ARG BENCHBASE_PROFILES="cockroachdb mariadb mysql postgres spanner phoenix sqlserver"
RUN for profile in ${BENCHBASE_PROFILES}; do \
mvn -B --file pom.xml package -P $profile -D skipTests || exit 1; \
mkdir -p profiles/$profile; \
tar -C profiles/$profile/ --strip-components=1 -xvzf target/benchbase-$profile.tgz || exit 1; \
rm -rf profiles/$profile/data/ && ln -s ../../data profiles/$profile/data; \
done \
&& test -d data \
&& test "`readlink -f profiles/postgres/data`" = "/benchbase/data" \
&& mvn -B --file pom.xml clean \
&& rm -rf ~/.m2/repository/* \
&& rm -rf .git/

ENV BENCHBASE_PROFILE=postgres
ENTRYPOINT ["/benchbase/docker/benchbase/entrypoint.sh"]
CMD ["--help"]
1 change: 1 addition & 0 deletions docker/benchbase/build-dev-image.sh
47 changes: 47 additions & 0 deletions docker/benchbase/build-full-image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/bin/bash

set -eu

BENCHBASE_PROFILES="${BENCHBASE_PROFILES:-cockroachdb mariadb mysql postgres spanner phoenix sqlserver}"

scriptdir=$(dirname "$(readlink -f "$0")")
rootdir=$(readlink -f "$scriptdir/../../")
cd "$rootdir"

http_proxy_host=''
http_proxy_port=''
https_proxy_host=''
https_proxy_port=''

if echo "$http_proxy" | egrep -q 'http[s]?://[^:]+:[0-9]+[/]?$'; then
http_proxy_host=$(echo "$http_proxy" | sed -r -e 's|^http[s]?://([^:]+):([0-9]+)[/]?$|\1|')
http_proxy_port=$(echo "$http_proxy" | sed -r -e 's|^http[s]?://([^:]+):([0-9]+)[/]?$|\2|')
fi

if echo "$https_proxy" | egrep -q 'http[s]?://[^:]+:[0-9]+[/]?$'; then
https_proxy_host=$(echo "$https_proxy" | sed -r -e 's|^http[s]?://([^:]+):([0-9]+)[/]?$|\1|')
https_proxy_port=$(echo "$https_proxy" | sed -r -e 's|^http[s]?://([^:]+):([0-9]+)[/]?$|\2|')
fi

target=
tag=
basename=$(basename "$0")
if [ "$basename" == "build-full-image.sh" ]; then
target='fullimage'
tag='benchbase'
elif [ "$basename" == "build-dev-image.sh" ]; then
target='devcontainer'
tag='benchbase-dev'
else
echo "ERROR: Unhandled mode: $basename" >&2
exit 1
fi

GID=$(getent passwd $UID | cut -d: -f4)

set -x
docker build --build-arg=http_proxy=${http_proxy:-} --build-arg=https_proxy=${https_proxy:-} \
--build-arg MAVEN_OPTS="-Dhttp.proxyHost=${http_proxy_host} -Dhttp.proxyPort=${http_proxy_port} -Dhttps.proxyHost=${https_proxy_host} -Dhttps.proxyPort=${https_proxy_port}" \
--build-arg BENCHBASE_PROFILES="${BENCHBASE_PROFILES}" \
--build-arg UID=$UID --build-arg GID=$GID \
-t $tag -f ./docker/benchbase/Dockerfile --target $target .
8 changes: 8 additions & 0 deletions docker/benchbase/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

# fullimage docker entrypoint script

BENCHBASE_PROFILE="${BENCHBASE_PROFILE:-postgres}"
cd /benchbase
echo "INFO: Using environment variable BENCHBASE_PROFILE=${BENCHBASE_PROFILE} with args: $*" >&2
java -jar "./profiles/${BENCHBASE_PROFILE}/benchbase.jar" $*
12 changes: 12 additions & 0 deletions docker/benchbase/run-dev-image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

set -eu

scriptdir=$(dirname "$(readlink -f "$0")")
rootdir=$(readlink -f "$scriptdir/../../")

cd "$scriptdir"
./build-dev-image.sh

cd "$rootdir"
docker run -it --rm -v "$PWD:/benchbase" benchbase-dev
15 changes: 15 additions & 0 deletions docker/benchbase/run-full-image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

set -eu

BENCHBASE_PROFILE="${BENCHBASE_PROFILE:-postgres}"

scriptdir=$(dirname "$(readlink -f "$0")")
rootdir=$(readlink -f "$scriptdir/../../")

cd "$scriptdir"
./build-full-image.sh

cd "$rootdir"
mkdir -p results/
docker run -it --rm -v "$PWD/results:/benchbase/results" --env "BENCHBASE_PROFILE=$BENCHBASE_PROFILE" benchbase $*

0 comments on commit 21265a6

Please sign in to comment.