Skip to content

Commit

Permalink
Merge pull request #41 from yetanalytics/docker
Browse files Browse the repository at this point in the history
Bundle + Docker
  • Loading branch information
kelvinqian00 authored Oct 10, 2023
2 parents 7f8d053 + 2236b9b commit b571236
Show file tree
Hide file tree
Showing 15 changed files with 147 additions and 20 deletions.
39 changes: 39 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Docker Build and Deployment

on:
push:
tags:
- 'v*.*.*' # Enforce Semantic Versioning

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Setup CD Environment
uses: yetanalytics/actions/[email protected]

- name: Build bundle
run: make bundle BUNDLE_RUNTIMES=false

- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4
with:
images: yetanalytics/persephone

- name: Build and push Docker image
uses: docker/build-push-action@v3
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
1 change: 1 addition & 0 deletions .java_modules
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
java.base,java.sql,java.management
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Change Log

## 0.9.1 - 2023-10-09
- Add Docker images for the CLI and server; see the Docker section for the [CLI](doc/cli.md#docker) and [server](doc/cli.md#docker).
- Use bundled Java runtimes and modules instead of the local Java runtime (this is necessary for Docker implementation).
- Minor changes to CLI/server description text.

## 0.9.0 - 2023-04-25
- Add CLI for Persephone as two commands that can be made using `make bundle`; command options can be viewed using `--help`.
- `validate`: Performs Statement Template validation for a single Statement
Expand Down
20 changes: 20 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM alpine:3.14

ADD target/bundle /persephone
ADD .java_modules /persephone/.java_modules

# Replace Alpine's Java runtime via jlink
RUN apk update \
&& apk upgrade \
&& apk add --no-cache openjdk11 \
&& mkdir -p /persephone/runtimes \
&& jlink --output /persephone/runtimes/linux/ --add-modules $(cat /persephone/.java_modules) \
&& apk del openjdk11 \
&& rm -rf /var/cache/apk/*

WORKDIR /persephone
EXPOSE 8080

# This is mainly a placeholder; the intended use is to pass in args
# when running the Docker image.
CMD ["/persephone/bin/persephone.sh", "--help"]
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ ci: clean test-clj test-cljs

.PHONY: bundle

MACHINE ?= $(shell bin/machine.sh)
JAVA_MODULES ?= $(shell cat .java_modules)
BUNDLE_RUNTIMES ?= true # false for Docker

target/bundle/cli.jar:
clojure -T:build uber :jar cli

Expand All @@ -37,6 +41,14 @@ target/bundle/bin:
cp bin/*.sh target/bundle/bin
chmod +x target/bundle/bin/*.sh

target/bundle/runtimes:
mkdir -p target/bundle/runtimes
jlink --output target/bundle/runtimes/${MACHINE} --add-modules ${JAVA_MODULES}

ifeq ($(BUNDLE_RUNTIMES),true)
target/bundle: target/bundle/cli.jar target/bundle/server.jar target/bundle/bin target/bundle/runtimes
else
target/bundle: target/bundle/cli.jar target/bundle/server.jar target/bundle/bin
endif

bundle: target/bundle
19 changes: 12 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@

_Only Persephone, daughter of Zeus and wife of Hades, could travel between the Underworld and the world of the living. Project Persephone is the liaison between our physical world and the world of the Semantic Web._

A Clojure library, with a local for validating xAPI Statements against xAPI Profiles.
A Clojure library for validating xAPI Statements against xAPI Profiles, featuring interactive CLI and webserver applications.

## Index

- [Library](doc/library.md): How to use the library/API functions
- [CLI](doc/cli.md): How to run the `validate` and `match` commands
- [Webserver](doc/server.md): How to start up and run a webserver

## Installation

Add the following to the `:deps` map in your `deps.edn` file:
```clojure
com.yetanalytics/project-persephone {:mvn/version "0.9.0"}
com.yetanalytics/project-persephone {:mvn/version "0.9.1"}
```

## Documentation

- [Library](doc/library.md): How to use the library/API functions
- [CLI](doc/cli.md): How to run the `validate` and `match` commands
- [Webserver](doc/server.md): How to start up and run a webserver
Alternatively, to run the CLI or server as an application, you can pull a Docker image from [DockerHub](https://hub.docker.com/repository/docker/yetanalytics/persephone):
```
docker pull yetanalytics/persephone:latest
```

## How It Works

Expand Down
11 changes: 11 additions & 0 deletions bin/machine.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh

# TODO: Does not yet support Windows

unameOut="$(uname -s)"
case "${unameOut}" in
Linux*) machine=linux;;
*) machine=macos;;
esac

echo ${machine}
4 changes: 3 additions & 1 deletion bin/persephone.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/bin/sh

java -server -jar cli.jar $@
MACHINE=`bin/machine.sh`

runtimes/$MACHINE/bin/java -server -jar cli.jar $@
4 changes: 3 additions & 1 deletion bin/server.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/bin/sh

java -server -jar server.jar $@
MACHINE=`bin/machine.sh`

runtimes/$MACHINE/bin/java -server -jar server.jar $@
16 changes: 14 additions & 2 deletions doc/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The `match` subcommand matches a Statement batch against Patterns in one or more
| `-n, --compile-nfa` | If set, compiles the Patterns into a non-deterministic finite automaton (NFA) instead of a deterministic one, allowing for more detailed error traces at the cost of decreased performance.
| `-h, --help` | Display the help menu.

## Examples for `persephone validate`
## `persephone validate` examples

In the examples in this and the next section, assume that the `test-resources/sample_profiles` and `test-resources/sample_statements` directories were copied into `target/bundle`, i.e. the location where we run `./bin/persephone`.

Expand Down Expand Up @@ -168,7 +168,7 @@ we get the following error message:
Compilation error: no Statement Templates to validate against
```

## Examples for `persephone match`
## `persephone match` examples

We can match the Statement batch consisting of `calibration_1.json` and `calibration_2.json` against the Patterns in the `calibration.jsonld` Profile as so:
```
Expand Down Expand Up @@ -257,3 +257,15 @@ we will receive the following error message
```
Compilation error: no Patterns to match against, or one or more Profiles lacks Patterns
```

## Docker

To use with Docker, pull the image `yetanalytics/persephone:[tag]` and execute the following:

```
docker run -v [filepath]:/persephone/[filepath] -it yetanalytics/persephone:docker /persephone/bin/persephone.sh <subcommand> <args>
```

The container will run and exit once the command completes. The `-v` command can be use to map filepaths for resources (e.g. Profiles and Statements) to the Docker working directory `/persephone`.

Note that if `/persephone/bin/persephone.sh validate <args>` is not provided, then the container will run `persephone.sh --help` by default.
22 changes: 16 additions & 6 deletions doc/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ Persephone features a webserver that can be used to validate or match Statements
To use the server, first run `make bundle`, then `cd` into `target/bundle`. You will then be able to run `/bin/server.sh`, which will accept either the `validate` or `match` subcommand to start the server in either Statement Template validation or Pattern matching mode, respectively. The following table shows the top-level arguments to the server init command:

| Command&nbsp;Argument | Default | Description
| :-- | :-- | :--
| `-H, --host HOST` | `localhost` | The hostname of the webserver endpoint
| :-- | :-- | :--
| `-H, --host HOST` | `0.0.0.0` | The hostname of the webserver endpoint
| `-P, --port PORT` | `8080` | The port number of the webserver endpoint; must be between 0 and 65536
| `-h, --help` | N/A | Display the top-level help guide

Expand Down Expand Up @@ -50,13 +50,13 @@ and a body `"OK"`.

There is no `PUT` or `GET` versions of the `/statements` endpoint, unlike what is required in a learning record store.

# Examples for validate mode
## Validate mode examples

For the first few examples, let us start a webserver in validate mode with a single Profile. Assume that we have already copied the contents of `test-profile` into the `target/bundle` directory. Running this command
```
% ./bin/server.sh validate --profile sample_profiles/calibration.jsonld
```
will start up a server in validate mode on `localhost:8080` with a single Profile set to validate against.
will start up a server in validate mode on `0.0.0.0:8080` with a single Profile set to validate against.

To validate a single Statement against Templates in that Profile:
```bash
Expand Down Expand Up @@ -125,13 +125,13 @@ Validation also works with two Profiles:
```
as well as the `--template-id`, `--all-valid`, and `--short-circuit` flags. These work very similarly to how they work in the [CLI](cli.md#examples-for-persephone-validate). Note that you should take care not to include duplicate IDs or else you will receive an init error.

# Examples for match mode
## Match mode examples

In match mode, we will first start a webserver mode with a single Profile. Running this command
```
% ./bin/server.sh match --profile sample_profiles/calibration.jsonld
```
will start up a server in validate mode on `localhost:8080` with a single Profile set to perform Pattern matching against.
will start up a server in validate mode on `0.0.0.0:8080` with a single Profile set to perform Pattern matching against.

To validate a Statement array against Templates in that Profile:
```bash
Expand Down Expand Up @@ -192,3 +192,13 @@ As with validation, Pattern matching works with two or more Profiles:
--profile sample_profiles/catch.json
```
though you should be careful not to include any duplicate Profile or Pattern IDs or else you will receive an error.

## Docker

To use with Docker, pull the image `yetanalytics/persephone:[tag]` and execute the following:

```
docker run -v [filepath]:/persephone/[filepath] -p 8080:8080 -it yetanalytics/persephone:docker /persephone/bin/server.sh <subcommand> <args>
```

The container will run a Persephone server on port 8080. The `-v` command can be use to map filepaths for resources (e.g. Profiles and Statements) to the Docker working directory `/persephone`.
4 changes: 4 additions & 0 deletions src/cli/com/yetanalytics/persephone/cli.clj
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
(if (m/match rest)
(System/exit 0)
(System/exit 1))
(nil? subcommand)
(do
(u/printerr (format "No subcommand present; run 'persephone [-h|--help]'"))
(System/exit 1))
:else
(do
(u/printerr (format "Unknown subcommand: %s" subcommand))
Expand Down
2 changes: 1 addition & 1 deletion src/cli/com/yetanalytics/persephone/cli/validate.clj
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
:id :all-valid]
["-c" "--short-circuit"
(str "If set, then print on only the first Template the Statement fails "
"validation against."
"validation against. "
"Otherwise, print for all Templates the Statement fails against.")
:id :short-circuit]
["-h" "--help" "Display the 'validate' subcommand help menu."]])
Expand Down
6 changes: 5 additions & 1 deletion src/server/com/yetanalytics/persephone/server.clj
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
(def top-level-options
[["-H" "--host HOST" "The hostname of the webserver endpoint"
:id :host
:default "localhost"]
:default "0.0.0.0"]
["-P" "--port PORT" "The port number of the webserver endpoint; must be between 0 and 65536"
:id :port
:default 8080
Expand Down Expand Up @@ -174,6 +174,10 @@
(System/exit 1)
:else
(start-server :match host port)))
(nil? subcommand)
(do
(u/printerr (format "No subcommand present; run 'server [-h|--help]'"))
(System/exit 1))
:else
(do (u/printerr (format "Unknown subcommand: %s" subcommand))
(System/exit 1)))))
2 changes: 1 addition & 1 deletion src/server/com/yetanalytics/persephone/server/validate.clj
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
:id :all-valid]
["-c" "--short-circuit"
(str "If set, then print on only the first Template any Statement fails "
"validation against."
"validation against. "
"Otherwise, print for all Templates a Statement fails against.")
:id :short-circuit]
["-h" "--help" "Display the 'validate' subcommand help menu."]])
Expand Down

0 comments on commit b571236

Please sign in to comment.