-
Notifications
You must be signed in to change notification settings - Fork 122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
initial commit of docker desktop extension #218
Merged
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
369a30f
initial commit of docker desktop extension
danleyb2 be720f3
update icon
danleyb2 b231ea5
Update docker/dd-extension/backend/utils.py
danleyb2 7627908
Update docker/dd-extension/ui/src/components/Stream.tsx
danleyb2 b206d52
Update docker/dd-extension/ui/src/components/Stream.tsx
danleyb2 d786353
Update docker/dd-extension/ui/src/components/Snapshot.tsx
danleyb2 15e9b04
Update docker/dd-extension/ui/src/components/Snapshot.tsx
danleyb2 822e861
refactor: cleanup
danleyb2 c3b4181
feat: add eslint
danleyb2 4b9f562
feat: update snapshot Image option add all restart policies
danleyb2 f20ffc4
feat: update snapshot Image options
danleyb2 a8e2473
refactor: reformat code
danleyb2 c91c7c1
update labels
danleyb2 e1ffa72
fix: snapshot labels clicking
danleyb2 e6cb426
feat: run generated commands directly
danleyb2 1402780
feat: review fixes
danleyb2 09d2a38
refactor: eslint rules
danleyb2 0c192a2
feat: add types, ai review fixes
danleyb2 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ | ||
ui/node_modules |
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 @@ | ||
node_modules | ||
ui/build |
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,3 @@ | ||
{ | ||
"makefile.configureOnOpen": false | ||
} |
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 @@ | ||
FROM --platform=$BUILDPLATFORM node:21.6-alpine3.18 AS client-builder | ||
WORKDIR /ui | ||
# cache packages in layer | ||
COPY ui/package.json /ui/package.json | ||
COPY ui/package-lock.json /ui/package-lock.json | ||
RUN --mount=type=cache,target=/usr/src/app/.npm \ | ||
npm set cache /usr/src/app/.npm && \ | ||
npm ci | ||
# install | ||
COPY ui /ui | ||
RUN npm run build | ||
|
||
|
||
FROM python:3.11-slim | ||
ENV PYTHONUNBUFFERED=1 | ||
|
||
RUN apt-get update\ | ||
&& apt-get install --no-install-recommends -y curl \ | ||
&& rm -rf /var/lib/apt/lists/*\ | ||
&& pip install --upgrade pip | ||
|
||
COPY docker-compose.yaml . | ||
COPY metadata.json . | ||
COPY logo.svg . | ||
|
||
# Copy python dependecies file | ||
COPY ./backend/requirements.txt /app/requirements.txt | ||
RUN pip install --no-cache-dir -r /app/requirements.txt | ||
# Copy source code | ||
COPY ./backend /app/ | ||
|
||
LABEL org.opencontainers.image.title="Plate Recognizer Installer" \ | ||
org.opencontainers.image.description="Plate Recognizer Installer for Stream and Snapshot SDKs" \ | ||
org.opencontainers.image.vendor="Plate Recognizer" \ | ||
com.docker.desktop.extension.api.version="0.3.4" \ | ||
com.docker.extension.screenshots="" \ | ||
com.docker.desktop.extension.icon="https://platerecognizer.com/wp-content/uploads/2020/07/plate-recognizer-alpr-anpr-logo.png" \ | ||
com.docker.extension.detailed-description="Select correct docker image and generate command for installing, updating or uninstalling Snapshot or Stream SDK" \ | ||
com.docker.extension.publisher-url="https://platerecognizer.com/" \ | ||
com.docker.extension.additional-urls="https://parkpow.com/" \ | ||
com.docker.extension.categories="utility-tools" \ | ||
com.docker.extension.changelog="Initial Release" \ | ||
com.docker.extension.account-info="required" | ||
|
||
|
||
COPY --from=client-builder /ui/build ui | ||
CMD ["gunicorn", "--workers", "1", "--chdir", "/app", "--bind", "unix:/run/guest-services/backend.sock", "wsgi:app"] |
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,28 @@ | ||
IMAGE?=platerecognizer/installer | ||
TAG?=latest | ||
|
||
BUILDER=buildx-multi-arch | ||
|
||
INFO_COLOR = \033[0;36m | ||
NO_COLOR = \033[m | ||
|
||
build-extension: ## Build service image to be deployed as a desktop extension | ||
docker build --tag=$(IMAGE):$(TAG) . | ||
|
||
install-extension: build-extension ## Install the extension | ||
docker extension install $(IMAGE):$(TAG) | ||
|
||
update-extension: build-extension ## Update the extension | ||
docker extension update $(IMAGE):$(TAG) | ||
|
||
prepare-buildx: ## Create buildx builder for multi-arch build, if not exists | ||
docker buildx inspect $(BUILDER) || docker buildx create --name=$(BUILDER) --driver=docker-container --driver-opt=network=host | ||
|
||
push-extension: prepare-buildx ## Build & Upload extension image to hub. Do not push if tag already exists: make push-extension tag=0.1 | ||
docker pull $(IMAGE):$(TAG) && echo "Failure: Tag already exists" || docker buildx build --push --builder=$(BUILDER) --platform=linux/amd64,linux/arm64 --build-arg TAG=$(TAG) --tag=$(IMAGE):$(TAG) . | ||
|
||
help: ## Show this help | ||
@echo Please specify a build target. The choices are: | ||
@grep -E '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "$(INFO_COLOR)%-30s$(NO_COLOR) %s\n", $$1, $$2}' | ||
|
||
.PHONY: help |
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,92 @@ | ||
# Plate Recognizer Installer | ||
|
||
Plate Recognizer Installer Docker extension. | ||
|
||
This extension is composed of: | ||
|
||
- A [frontend](./ui) app in React. | ||
- A [backend](./backend) container that runs an API in Python. Makes request to verify token | ||
|
||
## Local development | ||
|
||
You can use `docker` to build, install and push your extension. Also, we provide an opinionated [Makefile](Makefile) that could be convenient for you. There isn't a strong preference of using one over the other, so just use the one you're most comfortable with. | ||
|
||
To build the extension, use `make build-extension` **or**: | ||
|
||
```shell | ||
docker buildx build -t platerecognizer/installer:latest . --load | ||
``` | ||
|
||
To install the extension, use `make install-extension` **or**: | ||
|
||
```shell | ||
docker extension install platerecognizer/installer:latest | ||
``` | ||
|
||
To Publish | ||
```shell | ||
docker buildx build --push --platform=linux/amd64,linux/arm64 --tag=platerecognizer/installer:0.0.1 . | ||
``` | ||
|
||
> If you want to automate this command, use the `-f` or `--force` flag to accept the warning message. | ||
|
||
To preview the extension in Docker Desktop, open Docker Dashboard once the installation is complete. The left-hand menu displays a new tab with the name of your extension. You can also use `docker extension ls` to see that the extension has been installed successfully. | ||
|
||
### Frontend development | ||
|
||
During the development of the frontend part, it's helpful to use hot reloading to test your changes without rebuilding your entire extension. To do this, you can configure Docker Desktop to load your UI from a development server. | ||
Assuming your app runs on the default port, start your UI app and then run: | ||
|
||
```shell | ||
cd ui | ||
npm install | ||
npm run dev | ||
``` | ||
|
||
This starts a development server that listens on port `3000`. | ||
|
||
You can now tell Docker Desktop to use this as the frontend source. In another terminal run: | ||
|
||
```shell | ||
docker extension dev ui-source platerecognizer/installer:latest http://localhost:3000 | ||
``` | ||
|
||
In order to open the Chrome Dev Tools for your extension when you click on the extension tab, run: | ||
|
||
```shell | ||
docker extension dev debug platerecognizer/installer:latest | ||
``` | ||
|
||
Each subsequent click on the extension tab will also open Chrome Dev Tools. To stop this behaviour, run: | ||
|
||
```shell | ||
docker extension dev reset platerecognizer/installer:latest | ||
``` | ||
|
||
### Backend development | ||
|
||
Whenever you make changes in the [backend](./backend) source code, you will need to compile them and re-deploy a new version of your backend container. | ||
Use the `docker extension update` command to remove and re-install the extension automatically: | ||
|
||
```shell | ||
docker extension update platerecognizer/installer:latest | ||
``` | ||
|
||
> If you want to automate this command, use the `-f` or `--force` flag to accept the warning message. | ||
|
||
> Extension containers are hidden from the Docker Dashboard by default. You can change this in Settings > Extensions > Show Docker Extensions system containers. | ||
|
||
### Clean up | ||
|
||
To remove the extension: | ||
|
||
```shell | ||
docker extension rm platerecognizer/installer:latest | ||
``` | ||
|
||
## What's next? | ||
|
||
- To learn more about how to build your extension refer to the Extension SDK docs at <https://docs.docker.com/desktop/extensions-sdk/>. | ||
- To publish your extension in the Marketplace visit <https://www.docker.com/products/extensions/submissions/>. | ||
- To report issues and feedback visit <https://github.com/docker/extensions-sdk/issues>. | ||
- To look for other ideas of new extensions, or propose new ideas of extensions you would like to see, visit <https://github.com/docker/extension-ideas/discussions>. |
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,40 @@ | ||
import logging | ||
import os | ||
import sys | ||
|
||
from flask import Flask, request | ||
from utils import verify_token | ||
|
||
LOG_LEVEL = os.environ.get("LOGGING", "DEBUG").upper() | ||
|
||
logging.basicConfig( | ||
stream=sys.stdout, | ||
level=LOG_LEVEL, | ||
style="{", | ||
format="{asctime} {levelname} {name} {threadName} : {message}", | ||
) | ||
|
||
lgr = logging.getLogger(__name__) | ||
|
||
|
||
app = Flask(__name__) | ||
|
||
|
||
@app.route("/verify-token", methods=["POST"]) | ||
def verify_token_license(): | ||
lgr.debug(f"verify token data: {request.data}") | ||
token = request.json.get("token") | ||
license = request.json.get("license") | ||
try: | ||
valid, message = verify_token(token, license, "port" not in request.json) | ||
except ValueError as e: | ||
valid = False | ||
message = str(e) | ||
|
||
lgr.info(f"verify result: {valid} - {message}") | ||
|
||
return {"valid": valid, "message": message} | ||
|
||
|
||
if __name__ == "__main__": | ||
app.run() |
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 @@ | ||
Flask==3.0.3 | ||
gunicorn==23.0.0 | ||
danleyb2 marked this conversation as resolved.
Show resolved
Hide resolved
|
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,37 @@ | ||
import logging | ||
|
||
try: | ||
from urllib.error import URLError | ||
from urllib.request import Request, urlopen | ||
except ImportError: | ||
from urllib2 import Request, URLError, urlopen # type: ignore | ||
|
||
lgr = logging.getLogger(__name__) | ||
|
||
|
||
def verify_token(token, license_key, is_stream=True): | ||
if not token or not license_key: | ||
raise ValueError("API token and license key is required.") | ||
Comment on lines
+12
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
path = "stream/license" if is_stream else "sdk-webhooks" | ||
try: | ||
req = Request( | ||
f"https://api.platerecognizer.com/v1/{path}/{license_key.strip()}/" | ||
) | ||
req.add_header("Authorization", f"Token {token.strip()}") | ||
urlopen(req).read() | ||
return True, None | ||
except URLError as e: | ||
if "404" in str(e): | ||
return ( | ||
False, | ||
"The License Key cannot be found. Please use the correct License Key.", | ||
) | ||
elif str(403) in str(e): | ||
return False, "The API Token cannot be found. Please use the correct Token." | ||
|
||
else: | ||
return True, None | ||
danleyb2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
except Exception as e: | ||
lgr.exception(e) | ||
return False, str(e) |
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,4 @@ | ||
from main import app | ||
|
||
if __name__ == "__main__": | ||
app.run() |
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,3 @@ | ||
services: | ||
platerecognizer-installer: | ||
image: ${DESKTOP_PLUGIN_IMAGE} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,16 @@ | ||
{ | ||
"icon": "logo.svg", | ||
"vm": { | ||
"composefile": "docker-compose.yaml", | ||
"exposes": { | ||
"socket": "backend.sock" | ||
} | ||
}, | ||
"ui": { | ||
"dashboard-tab": { | ||
"title": "Plate Recognizer Installer", | ||
"src": "index.html", | ||
"root": "ui" | ||
} | ||
} | ||
} |
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 @@ | ||
Electron 17.1.1 |
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,26 @@ | ||
import globals from "globals"; | ||
import pluginJs from "@eslint/js"; | ||
import tseslint from "typescript-eslint"; | ||
import pluginReact from "eslint-plugin-react"; | ||
|
||
export default [ | ||
{ | ||
files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"], | ||
}, | ||
{ | ||
languageOptions: { | ||
globals: globals.browser, | ||
}, | ||
}, | ||
{ | ||
ignores: ["build/"], | ||
}, | ||
{ | ||
rules: { | ||
// "@typescript-eslint/no-explicit-any": "off", | ||
}, | ||
}, | ||
pluginJs.configs.recommended, | ||
...tseslint.configs.recommended, | ||
pluginReact.configs.flat.recommended, | ||
]; |
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,12 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="color-scheme" content="light dark" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
<script type="module" src="/src/main.tsx"></script> | ||
</body> | ||
</html> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CodeRabbit
The
push-extension
target uses a combination ofdocker pull
andecho
to check if a tag already exists. This approach can be improved for clarity and reliability. Consider using a more explicit check withdocker manifest inspect
, which is specifically designed for this purpose.