-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from Michionlion/feature/initial-implementation
Initial implementation
- Loading branch information
Showing
14 changed files
with
1,000 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/build | ||
/.github |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
name: Check Quality | ||
|
||
on: [push, pull_request, workflow_call] | ||
|
||
jobs: | ||
lint: | ||
name: Lint | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v2 | ||
- name: Setup Python 3.11 | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: "3.11" | ||
- name: Install Poetry | ||
uses: abatilo/actions-poetry@v2 | ||
with: | ||
poetry-version: 1.5.1 | ||
- name: Setup Poetry | ||
run: | | ||
poetry config virtualenvs.create true | ||
poetry config virtualenvs.in-project true | ||
poetry env info | ||
- name: Install system dependencies | ||
run: sudo apt install libev-dev | ||
- name: Install dependencies | ||
run: poetry install --no-interaction --no-ansi | ||
- name: Lint code | ||
run: poetry run task lint | ||
|
||
test: | ||
name: Test | ||
needs: lint | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v2 | ||
- name: Setup Python 3.11 | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: "3.11" | ||
- name: Install Poetry | ||
uses: abatilo/actions-poetry@v2 | ||
with: | ||
poetry-version: 1.5.1 | ||
- name: Setup Poetry | ||
run: | | ||
poetry config virtualenvs.create true | ||
poetry config virtualenvs.in-project true | ||
poetry env info | ||
- name: Install system dependencies | ||
run: sudo apt install libev-dev | ||
- name: Install dependencies | ||
run: poetry install --no-interaction --no-ansi | ||
- name: Build docker image | ||
run: poetry run task docker | ||
- name: Build example docker image | ||
run: poetry run task pre_example | ||
# - name: Test example docker image | ||
# run: poetry run task test_example |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
name: Docker | ||
|
||
on: | ||
release: | ||
types: [published] | ||
workflow_dispatch: | ||
|
||
jobs: | ||
test: | ||
uses: ./.github/workflows/main.yml | ||
push: | ||
needs: test | ||
runs-on: ubuntu-latest | ||
environment: dockerhub | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v3 | ||
- name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v2 | ||
- name: Log in to Docker Hub | ||
uses: docker/login-action@v2 | ||
with: | ||
username: ${{ vars.DOCKERHUB_USER }} | ||
password: ${{ secrets.DOCKERHUB_TOKEN }} | ||
- name: Extract metadata (tags, labels) for Docker | ||
id: meta | ||
uses: docker/metadata-action@v4 | ||
with: | ||
images: michionlion/microwrap | ||
tags: | | ||
type=semver,pattern={{version}} | ||
type=semver,pattern={{major}}.{{minor}} | ||
- name: Build and push Docker image | ||
uses: docker/build-push-action@v4 | ||
with: | ||
context: . | ||
file: ./Dockerfile | ||
push: false | ||
tags: ${{ steps.meta.outputs.tags }} | ||
labels: ${{ steps.meta.outputs.labels }} | ||
- name: Debug | ||
run: | | ||
docker ps -a | ||
docker images -a | ||
# VERSION=$(echo "${{ github.event.release.tag_name }}" | sed -e 's/^v//') | ||
# type=raw,value=latest,enable={{is_default_branch}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Compilation temporary products | ||
build/ | ||
*.c | ||
*.so | ||
|
||
# Manual test files | ||
/microwrap.json | ||
/test.sh | ||
/microwrap.err | ||
/microwrap.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Build microwrap | ||
FROM python:3.11-buster as build | ||
|
||
# Install dependencies | ||
WORKDIR /microwrap | ||
RUN apt update && apt install -y build-essential libev-dev | ||
COPY . /microwrap | ||
RUN pip install poetry | ||
RUN poetry install | ||
RUN poetry run task compile | ||
|
||
# Create microwrap image | ||
FROM python:3.11-slim-buster | ||
|
||
COPY --from=build /microwrap/build/microwrap /usr/bin/microwrap | ||
|
||
ENTRYPOINT [ "microwrap" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,69 @@ | ||
# MicroWrap | ||
|
||
MicroWrap is a base container image designed to streamline and simplify the process of developing and deploying microservices through the use of containerization. | ||
MicroWrap is a base container image designed to streamline and simplify the process of developing and deploying microservices through the use of containerization. Using it is as simple as writing a Dockerfile for your application, and including a `microwrap.json` configuration; see the example below. | ||
|
||
MicroWrap functions as an executable wrapper, abstracting the complexities of network communication and service execution away from the application itself. It consists of an HTTP server that listens for incoming HTTP requests and translates those HTTP requests to command-line invocations of the wrapped executable. The translation process supports parameters -- URL parameters embedded in the request will become `--option value` strings passed to the wrapped executable. The standard output of the wrapped executable will be returned as the body of the response to the triggering request. For example, the request `GET http://localhost/execute?option1=test2&flag1` would trigger the invocation `/executable/path --option1 "test2" --flag1`, and the standard output would be returned as the body of the response to the `GET` HTTP request. | ||
```Dockerfile | ||
# Create an image using microwrap as the base to serve as our runtime image | ||
FROM michionlion/microwrap:latest | ||
# Configure microwrap | ||
COPY example/microwrap.json /microwrap.json | ||
# Upload executable to expose as a service | ||
COPY example/version.sh /version.sh | ||
``` | ||
|
||
MicroWrap functions as an executable wrapper, abstracting the complexities of network communication and service execution away from the application itself. It consists of an HTTP server that listens for incoming HTTP requests and translates those HTTP requests to command-line invocations of the wrapped executable. The translation process supports parameters -- URL parameters embedded in the request will become `--option value` strings passed to the wrapped executable. The standard output of the wrapped executable will be returned as the body of the response to the triggering request. | ||
|
||
As an example, suppose the following request was made to a container running microwrap. | ||
|
||
```shell | ||
http GET http://$HOST:$PORT/start?option1=test2&flag1 | ||
``` | ||
|
||
The base container image MicroWrap defines should be used as the base image for a further Dockerfile build, which can specify mounting locations, compile or upload the executable to be wrapped, and configure MicroWrap. An example container image using MicroWrap to run a version service is defined in this repository at `example/Dockerfile`. | ||
This request would trigger microwrap to execute its configured executable as follows. | ||
|
||
```shell | ||
/executable/path --option1 "test2" --flag1 | ||
``` | ||
|
||
The standard output of the execution would be returned as the body of the response to the `GET` HTTP request, and if the executable exits with a non-zero return code, an HTTP 500 Internal Server Error is returned (with the body being the concatenated standard output and standard error streams). | ||
|
||
## Usage | ||
|
||
To make your application a containerized service, you will need to write a Dockerfile that builds an image. This image can then be used in many different containerized environments, such as Docker, OpenShift, Kubernetes, and others. The Dockerfile for your application needs to accomplish two tasks: allow execution of your program, and configure MicroWrap. To allow your program to execute, the Dockerfile should install dependencies that your program needs, compile your program, and configure the runtime environment so that your program can execute. Additionally, you may want to prepare mount points for any folders that may need to be accessed by your program for external reading/writing, in the case that such input/output is needed. | ||
To make your application a containerized service, you will need to write a Dockerfile that builds an image. This image can then be used in many different containerized environments, such as Docker, OpenShift, Kubernetes, and others. The Dockerfile for your application needs to accomplish two tasks: allow execution of your program, and configure MicroWrap. To allow your program to execute, the Dockerfile should install dependencies that your program needs, compile your program, and configure the runtime environment so that your program can execute. Additionally, you may want to prepare mount points for any folders that may need to be accessed by your program for external reading/writing, in the case that such input/output is needed. An example (which specifically uses a Java program, but is applicable to many different languages and technologies) is given in the `example/` directory of this repository. | ||
|
||
## Configuration | ||
|
||
1. **Host** This is the host name to bind the server to; it defaults to `"0.0.0.0"` and should rarely need to be changed. | ||
1. **Port** This is the port to bind the server to; it defaults to `80` and can be changed if needed. | ||
1. **Executable Path** This is the location of the executable file that will be executed per request. It should be an executable file in your image. | ||
2. **Max Active Requests** This is the number of wrapped-executable invocations to allow at one time; any requests beyond this number will be queued for future invocation. Specify `-1` for no limit. | ||
3. **Allowed Parameters** This is a list of URL parameters that will be passed through as command-line options to the wrapped executable. Any other parameters will be ignored. | ||
4. **Default Parameters** This is an object which is mapped to `--attribute value` strings passed to the wrapped executable that can be overridden by URL parameters. Values that are `true` and `false` will not map to `"true"` or `"false"`, but instead value-less `--flag` and `--no-flag` (for an attribute named `flag`) strings; values that are `null` or the empty string `""` will cause the parameter to be ignored. | ||
1. **Concurrent** Whether to allow multiple requests to execute invocations concurrently; if `false`, only one invocation will be handled at a time. | ||
1. **Allowed Parameters** This is a list of URL parameters that will be passed through as command-line options to the wrapped executable. Any other parameters will be ignored. | ||
1. **Default Parameters** This is an object which is mapped to `--attribute value` strings passed to the wrapped executable that can be overridden by URL parameters. Values that are `true` will not map to `"true"`, but instead a value-less `--flag` (for an attribute named `flag`) string; values that are `null`, `false`, or the empty string `""` will cause the parameter to be ignored. | ||
|
||
These configuration parameters should be specified in the `/microwrap.json` configuration file in your image: | ||
|
||
```json | ||
{ | ||
"executablePath": "/root/program.sh", | ||
"maxActiveRequests": 1, | ||
"allowedParameters": ["option1", "flag1"], | ||
"defaultParameters": { | ||
"option1": "defaultValue1", | ||
"flag1": false, | ||
"flag2": true | ||
} | ||
"host": "0.0.0.0", | ||
"port": 8080, | ||
"concurrent": false, | ||
"executablePath": "/root/program.sh", | ||
"allowedParameters": ["option1", "flag1"], | ||
"defaultParameters": { | ||
"option1": "defaultValue1", | ||
"alwaysonflag": true | ||
} | ||
} | ||
``` | ||
|
||
## Future Work | ||
|
||
- Named invocations and status checking | ||
- Requires specific endpoints (no more "any endpoint -> invocation"). | ||
- `http://$HOST:$PORT/start/name?` Start an invocation named `name`; supports invocation parameters. | ||
- `http://$HOST:$PORT/stop/name` Stop a running invocation named `name`. | ||
- `http://$HOST:$PORT/running/name` Check if an invocation named `name` is running. | ||
- `http://$HOST:$PORT/running` Get list of all running invocations. | ||
- Progress reporting | ||
- Need to have standard progress reporting by wrapped executable. | ||
- Maybe a json file that the executable writes whenever and the `/progress` endpoint returns the contents of that file when called? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,21 @@ | ||
# Build the service executable in a "development" container | ||
FROM alpine:3.18 as build | ||
|
||
RUN apk add --no-cache openjdk11 | ||
FROM debian:buster as build | ||
# Add Java 11 JDK | ||
RUN apt update && apt install -y openjdk-11-jdk | ||
# Copy source code to container | ||
COPY Version.java /Version.java | ||
# Compile source code | ||
RUN javac Version.java | ||
|
||
# Create a new image with microwrap as the base to serve as our runtime image | ||
FROM michionlion/microwrap:0.1 | ||
# Install runtime dependency | ||
RUN apk add --no-cache openjre11 | ||
# Create an image using microwrap as the base to serve as our runtime image | ||
FROM michionlion/microwrap:latest | ||
# Install Java 11 JRE | ||
RUN apt update && apt install -y openjdk-11-jre && apt clean && rm -rf /var/lib/apt/lists/* | ||
# Configure microwrap | ||
COPY microwrap.json /microwrap.json | ||
# Copy the executable from the build image | ||
# Copy executable (a script to run Version.class) | ||
COPY version.sh /version.sh | ||
# Copy compiled code from the build image | ||
COPY --from=build /Version.class /Version.class | ||
|
||
EXPOSE 80 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
package example; | ||
|
||
public class Version { | ||
public static void main(String[] args) { | ||
var VERSION = "1.0.0"; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
"""MicroWrap translates HTTP requests to invocations of an arbitrary executable.""" | ||
from microwrap import microwrap as application |
Oops, something went wrong.