Skip to content

Commit

Permalink
add initial application and workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
ES-Alexander committed Oct 3, 2023
1 parent 3442ff0 commit d6ea2ac
Show file tree
Hide file tree
Showing 7 changed files with 228 additions and 17 deletions.
37 changes: 20 additions & 17 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ name: Deploy Image
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
IMAGE_NAME: ${{ vars.IMAGE_NAME || 'quickstart-test' }}
PREFIXED_IMAGE: blueos-${IMAGE_NAME}
PREFIXED_IMAGE: ${{ format('blueos-{0}', vars.IMAGE_NAME || 'quickstart-test') }}
# Target the same platforms as BlueOS by default
PLATFORMS: ${{ vars.BUILD_PLATFORMS || "linux/arm/v7,linux/arm64/v8,linux/amd64" }}
PLATFORMS: ${{ vars.BUILD_PLATFORMS || 'linux/arm/v7,linux/arm64/v8,linux/amd64' }}

on:
# Run manually
Expand Down Expand Up @@ -42,15 +42,17 @@ jobs:
echo "docker_image=${DOCKER_IMAGE}" >> $GITHUB_OUTPUT
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "buildx_args=\
--build-arg GIT_DESCRIBE_TAGS=$(git describe --tags --long) \
--build-arg IMAGE_NAME=${IMAGE_NAME}
--build-arg AUTHOR=${{ vars.MY_NAME || 'Author Name' }} \
--build-arg AUTHOR_EMAIL=${{ vars.MY_EMAIL || '[email protected]' }} \
--build-arg MAINTAINER=${{ vars.ORG_NAME || github.repository_owner }} \
--build-arg MAINTAINER_EMAIL=${{ vars.ORG_EMAIL || '[email protected]' }} \
--build-arg REPO=${{ github.repository }} \
--build-arg OWNER=${{ github.repository_owner }} \
--cache-to 'type=local,dest=/tmp/.buildx-cache'" >> $GITHUB_OUTPUT
--build-arg IMAGE_NAME=${IMAGE_NAME} \
--build-arg AUTHOR='${{ vars.MY_NAME || 'Author Name' }}' \
--build-arg AUTHOR_EMAIL='${{ vars.MY_EMAIL || '[email protected]' }}' \
--build-arg MAINTAINER='${{ vars.ORG_NAME || github.repository_owner }}' \
--build-arg MAINTAINER_EMAIL='${{ vars.ORG_EMAIL || '[email protected]' }}' \
--build-arg REPO='${{ github.repository }}' \
--build-arg OWNER='${{ github.repository_owner }}' \
--cache-from 'type=local,src=/tmp/.buildx-cache' \
--cache-to 'type=local,dest=/tmp/.buildx-cache' \
${TAGS} \
--file Dockerfile ." >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
Expand All @@ -74,9 +76,10 @@ jobs:
- name: Docker Buildx (build)
run: |
# Pull latest version of image to help with build speed
# Pull latest development version of image (from main/master branch) to help with build speed
for platform in $(echo ${PLATFORMS} | tr ',' '\n'); do
docker pull --platform ${platform} ${DOCKER_USERNAME}/${PREFIXED_IMAGE}:main || true
docker pull --platform ${platform} \
${DOCKER_USERNAME}/${PREFIXED_IMAGE}:${{ github.event.repository.default_branch }} || true
done
docker buildx build \
--output "type=image,push=false" \
Expand All @@ -95,7 +98,7 @@ jobs:
run: |
docker buildx build \
--output "type=image,push=true" \
--platform ${PLATFORM} \
--platform ${PLATFORMS} \
${{ steps.prepare.outputs.buildx_args }}
# Sanity check - if inspection fails something has gone very wrong
Expand All @@ -119,7 +122,7 @@ jobs:
uses: actions/upload-artifact@v3
if: success()
with:
name: ${PREFIXED_IMAGE}-docker-image-arm64-v8
name: ${{ env.PREFIXED_IMAGE }}-docker-image-arm64-v8
path: '*arm64-v8.tar'

- name: Create image artifact
Expand All @@ -137,7 +140,7 @@ jobs:
uses: actions/upload-artifact@v3
if: success()
with:
name: ${PREFIXED_IMAGE}-docker-image-arm-v7
name: ${{ env.PREFIXED_IMAGE }}-docker-image-arm-v7
path: '*arm-v7.tar'

- name: Create image artifact
Expand All @@ -155,7 +158,7 @@ jobs:
uses: actions/upload-artifact@v3
if: success()
with:
name: ${PREFIXED_IMAGE}-docker-image-amd64
name: ${{ env.PREFIXED_IMAGE }}-docker-image-amd64
path: '*amd64.tar'

- name: Upload docker image for release
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.venv
*.swp
*.egg-info
**/build
**/__pycache__
59 changes: 59 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
FROM python:3.11-slim

# RUN apt-get update && \
# apt-get -y install gcc && \
# rm -rf /var/lib/apt/lists/*

COPY app /app
RUN python -m pip install /app --extra-index-url https://www.piwheels.org/simple

EXPOSE 8000/tcp

LABEL version="0.0.1"

ARG IMAGE_NAME

LABEL permissions='\
{\
"ExposedPorts": {\
"8000/tcp": {}\
},\
"HostConfig": {\
"Binds":["/root/.config/blueos/extensions/$IMAGE_NAME:/root/.config"],\
"ExtraHosts": ["host.docker.internal:host-gateway"],\
"PortBindings": {\
"8000/tcp": [\
{\
"HostPort": ""\
}\
]\
}\
}\
}'

ARG AUTHOR
ARG AUTHOR_EMAIL
LABEL authors='[\
{\
"name": "$AUTHOR",\
"email": "$AUTHOR_EMAIL"\
}\
]'

ARG MAINTAINER
ARG MAINTAINER_EMAIL
LABEL company='{\
"about": "",\
"name": "$MAINTAINER",\
"email": "$MAINTAINER_EMAIL"\
}'
LABEL type="example"
ARG REPO
ARG OWNER
LABEL readme='https://raw.githubusercontent.com/$OWNER/$REPO/{tag}/README.md'
LABEL links='{\
"source": "https://github.com/$OWNER/$REPO"\
}'
LABEL requirements="core >= 1.1"

ENTRYPOINT litestar run --host 0.0.0.0
60 changes: 60 additions & 0 deletions app/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env python3

import requests
import logging.handlers
from pathlib import Path
from litestar import Litestar, get, MediaType
from litestar.controller import Controller
from litestar.datastructures import State
from litestar.logging import LoggingConfig
from litestar.static_files.config import StaticFilesConfig

class CountController(Controller):
COUNT_VAR = 'quickstart_backend_perm_count'
def __init__(self, *args, **kwargs):
self._temp_count = 0
super().__init__(*args, **kwargs)

@get("/temp_count", sync_to_thread=False)
def increment_temp_count(self) -> dict[str, int]:
self._temp_count += 1
return {"value": self._temp_count}

@get("/persistent_count", sync_to_thread=True)
def increment_persistent_count(self, state: State) -> dict[str, int]:
# read the existing persistent count value (from the BlueOS "Bag of Holding" service API)
try:
response = requests.get(f'{state.bag_url}/get/{self.COUNT_VAR}')
response.raise_for_status()
value = response.json()['value']
except Exception as e: # TODO: specifically except HTTP error 400 (using response.status_code?)
value = 0
value += 1
# write the incremented value back out
output = {'value': value}
requests.post(f'{state.bag_url}/set/{self.COUNT_VAR}', json=output)
return output

logging_config = LoggingConfig(
loggers={
__name__: dict(
level='INFO',
handlers=['queue_listener'],
)
},
)

log_dir = Path('/root/.config/logs')
log_dir.mkdir(parents=True, exist_ok=True)
fh = logging.handlers.RotatingFileHandler(log_dir / 'lumber.log', maxBytes=2**16, backupCount=1)

app = Litestar(
route_handlers=[CountController],
state=State({'bag_url':'http://host.docker.internal/bag/v1.0'}),
static_files_config=[
StaticFilesConfig(directories=['app/static'], path='/', html_mode=True)
],
logging_config=logging_config,
)

app.logger.addHandler(fh)
14 changes: 14 additions & 0 deletions app/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[project]
name = "quickstart"
version = "0.0.1"
description = "BlueOS QuickStart Example Extension"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
dependencies = [
"requests",
"litestar[standard]",
]

61 changes: 61 additions & 0 deletions app/static/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<html>
<head>
<title>QuickStart</title>
<script type="text/javascript" after defer>
function window_url() {
return window.location.protocol + '//' + window.location.hostname;
};
// define persistent state getters
async function frontend_perm_load() {
fetch(window_url() + "/bag/v1.0/get/quickstart_frontend_perm_count")
.then((response) => {
if (response.status === 400) {
return 0;
}
return response.json()["value"];
});
};

var frontend_count = 0;
function frontend_temp_click() {
frontend_count += 1;
document.getElementById("frontend_temp").textContent = frontend_count;
};
async function frontend_perm_click() {
var count = await frontend_perm_load();
count += 1;
fetch(window_url() + "/bag/v1.0/set/quickstart_frontend_perm_count/", {
method: "post",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
value: count
})
});
document.getElementById("frontend_perm").textContent = count;
};
async function backend_temp_click() {
document.getElementById("backend_temp").textContent = (await (await fetch("/temp_count")).json())["value"];
};
async function backend_perm_click() {
document.getElementById("backend_perm").textContent = (await (await fetch("/persistent_count")).json())["value"];
};

// load initial persistent states
document.getElementById("frontend_perm").textContent = frontend_perm_load();
</script>
</head>
<body>
<h1>Quick Start Functionalities</h1>
<button type="button" onclick="frontend_temp_click()">Frontend Temporary</button>
<p>Clicks: <a id="frontend_temp">0</a></p>
<button type="button" onclick="frontend_perm_click()">Frontend Persistent</button>
<p>Clicks: <a id="frontend_perm">?</a></p>
<button type="button" onclick="backend_temp_click()">Backend Temporary</button>
<p>Clicks: <a id="backend_temp">0</a></p>
<button type="button" onclick="backend_perm_click()">Backend Persistent</button>
<p>Clicks: <a id="backend_perm">?</a></p>
</body>
</html>
9 changes: 9 additions & 0 deletions app/static/register_service
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name":"QuickStart",
"description":"Example Extension",
"icon":"mdi-clock",
"company":"Blue Robotics",
"version":"0.0.1",
"webpage":"https://example.com",
"api":""
}

0 comments on commit d6ea2ac

Please sign in to comment.