This is an automated email from the ASF dual-hosted git repository.
bsalzano pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/openserverless-admin-api.git
The following commit(s) were added to refs/heads/main by this push:
new 9ddf072 chore: improved README, Dockerfile and tasks
9ddf072 is described below
commit 9ddf07293066d70ae4c26db060289a42a015dc55
Author: Bruno Salzano <[email protected]>
AuthorDate: Sun Jul 27 09:24:30 2025 +0200
chore: improved README, Dockerfile and tasks
Improved tasks inside Taskfile. Tested the image build process. Improved
documentation in README.md
---
.env.example | 12 +++--
Dockerfile | 18 +++----
README.md | 85 ++++++++++++++++++++++++++++--
Taskfile.yml | 128 +++++++++++++++++++++++++++++++++++----------
openserverless/__init__.py | 20 +++++--
openserverless/__main__.py | 24 +++++++++
6 files changed, 238 insertions(+), 49 deletions(-)
diff --git a/.env.example b/.env.example
index b4f2b02..341218c 100644
--- a/.env.example
+++ b/.env.example
@@ -1,9 +1,15 @@
LISTEN_PORT=5000
COUCHDB_SERVICE_PORT=5984
-COUCHDB_SERVICE_HOST=127.0.0.1
+COUCHDB_SERVICE_HOST=host.docker.internal
COUCHDB_ADMIN_USER=whisk_admin
COUCHDB_ADMIN_PASSWORD=
-KUBERNETES_SERVICE_HOST=127.0.0.1
+KUBERNETES_SERVICE_HOST=host.docker.internal
KUBERNETES_SERVICE_PORT=56490
KUBERNETES_TOKEN_FILENAME=./tokens/token
-KUBERNETES_CERT_FILENAME=./tokens/ca.crt
\ No newline at end of file
+KUBERNETES_CERT_FILENAME=./tokens/ca.crt
+
+# registry to use (ghcr or dockerhub or apache)
+# if not set, the image is build with local tag and will not be pushed
+REGISTRY=
+# namespace is required if REGISTRY is set
+NAMESPACE=
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index b221464..f0fd10b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -27,24 +27,24 @@ RUN apt-get update && apt-get install -y
--no-install-recommends \
unzip \
&& rm -rf /var/lib/apt/lists/*
-# Add nuvolaris user
-RUN useradd -m -u 1001 -s /bin/bash nuvolaris
-WORKDIR /home/nuvolaris
+# Add openserverless user
+RUN useradd -m -u 1001 -s /bin/bash openserverless
+WORKDIR /home/openserverless
# Copy source code con permessi corretti
-ADD --chown=nuvolaris:nuvolaris nuvolaris /home/nuvolaris/nuvolaris/
-ADD --chown=nuvolaris:nuvolaris run.sh pyproject.toml uv.lock /home/nuvolaris/
+ADD --chown=openserverless:openserverless openserverless
/home/openserverless/openserverless/
+ADD --chown=openserverless:openserverless run.sh pyproject.toml uv.lock
/home/openserverless/
# Install uv (Python dependency manager)
RUN pip install --no-cache-dir uv
# Install Python dependencies usando il lockfile
-RUN uv pip install --system --requirement pyproject.toml
+RUN uv venv && uv pip install --requirement pyproject.toml
# ...existing code...
-USER nuvolaris
-ENV HOME=/home/nuvolaris
+USER openserverless
+ENV HOME=/home/openserverless
EXPOSE 5000
-CMD ["./run.sh"]
+CMD ["uv", "run", "-m", "openserverless"]
diff --git a/README.md b/README.md
index aee68d5..affd74f 100644
--- a/README.md
+++ b/README.md
@@ -23,6 +23,9 @@
Lighweight OpenServerless Admin REST API Layer.
+
+## Endpoints
+
Available APIs at the moment:
### Authentication API
@@ -38,15 +41,91 @@ Available APIs at the moment:
## Developer instructions
-You need to have access to the kubernetes cluster.
+You need to have access to be Apache OpenServerless admin and have access to
kubernetes cluster.
+
+Refer to the [Apache OpenServerless installation
page](https://openserverless.apache.org/docs/installation/install/docker/):
-Give the command task `setup-developer` will:
+Give the command `task setup-developer` and it will:
- extract the required ca.crt and token from operator service account
- copy a sample .env file
-- install dependencies
+- install required python dependencies
After that, you can use VSCode debugger to start the application.
Otherwise you can give an `uv run -m openserverless` to start.
Open http://localhost:5002/system/apidocs/ to see the API documentation.
+
+## Tasks
+
+Taskfile supports the following tasks:
+
+```yaml
+* build: Build the image locally
+* build-and-load: Build the image and loads it to local Kind cluster
+* buildx: Build the docker image using buildx. Set PUSH=1 to
push the image to the registry.
+* docker-login: Login to the docker registry. Set REGISTRY=ghcr or
REGISTRY=dockerhub in .env to use the respective registry.
+* get-tokens: Get Service Account tokens and save them to tokens
directory
+* image-tag: Create a new tag for the current git commit.
+* run: Run the admin api locally, using configuration from
.env file
+* setup-developer: Setup developer environment
+```
+
+## Build and push
+
+### Private registry or local image
+
+To build an image and push it on a private repository, firstly choose which
+registry you want to use.
+Tasks support is for Github (ghcr) and Dockerhub (dockerhub).
+So copy the `.env.example` to `.env` and configure the required variables for
+authentication and set the `REGISTRY` and `NAMESPACE` accordly.
+
+Now create a new tag
+
+```bash
+$ task image-tag
+```
+You should see an output like this:
+
+```bash
+Deleted tag '0.1.0-incubating.2507270903' (was 434b400)
+0.1.0-incubating.2507270910
+```
+
+:bulb: **NOTE** If you leave unset `REGISTRY` a local
`openserverless-admin-api`
+image will be built, using the generated tag.
+
+If you setup the `REGISTRY` and `NAMESPACE`, you can give a:
+
+```bash
+$ task docker-login
+```
+
+To build:
+
+```bash
+$ task buildx
+```
+
+To build and push
+
+```bash
+$ task buildx PUSH=1
+```
+
+### Apache repository
+To build an official Apache OpensSrverless Admin Api image, you
+need to be a committer.
+
+If you have the proper permissions, the build process will start pushing a
+new tag to apache/openserverless-admin-api repository.
+So, for example, if your tag is `0.1.0-incubating.2507270910` and your
+git remote is `apache`
+
+```bash
+$ git push apache 0.1.0-incubating.2507270910
+```
+
+This will trigger the build workflow, and the process will be visible at
+https://github.com/apache/openserverless-admin-api/actions
\ No newline at end of file
diff --git a/Taskfile.yml b/Taskfile.yml
index 966e52b..cbb9d02 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -19,12 +19,11 @@
version: '3'
vars:
- BASETAG: 0.1.0
-
-env:
- OPS_API_TAG:
- sh: git describe --tags --abbrev=0 2>/dev/null || git rev-parse --short
HEAD
- OPS_API_IMAGE: registry.hub.docker.com/apache/openserverless-admin-api
+ BASETAG: 0.1.0-incubating
+ COMMIT_ID:
+ sh: git rev-parse --short HEAD
+ TAG:
+ sh: git describe --tags --abbrev=0 2>/dev/null || echo latest
dotenv:
- .env
@@ -49,34 +48,105 @@ tasks:
then cp .env.example .env
echo "Please edit .env file with your local CouchDB and Kubernetes
credentials"
fi
+ - |
+ if [ ! -d .venv ];
+ then uv venv
+ fi
- uv pip install -r pyproject.toml 2>/dev/null
-
-
- image-tag:
- - git tag -d $(git tag)
- - git tag -f {{.P}}{{.BASETAG}}.$(date +%y%m%d%H%M)
- - env PAGER= git tag
- docker-login: >
- echo $DOCKER_HUB_TOKEN | docker login registry.hub.docker.com -u
$DOCKER_HUB_USER --password-stdin
+ docker-login-ghcr: >
+ silent: true
+ cmds:
+ - |
+ echo "Logging in to ghcr.io as $GITHUB_USER"
+ echo $GITHUB_TOKEN | docker login ghcr.io -u $GITHUB_USER
--password-stdin
+
+ docker-login-dockerhub:
+ silent: true
+ cmds:
+ - |
+ echo "Logging in to dockerhub as $DOCKERHUB_USER"
+ echo $DOCKERHUB_TOKEN | docker login -u $DOCKERHUB_USER
--password-stdin
- docker-setup:
- - docker buildx create --use
- - docker run -it --rm --privileged tonistiigi/binfmt --install all
+ docker-login:
+ desc: |
+ Login to the docker registry. Set REGISTRY=ghcr or REGISTRY=dockerhub in
.env
+ to use the respective registry.
+ silent: true
+ cmds:
+ - |
+ if [ -z "$REGISTRY" ]; then
+ echo "Error: REGISTRY variable is not set in .env"
+ exit 1
+ fi
+ task docker-login-$REGISTRY
+
+ image-tag:
+ silent: true
+ desc: |
+ Create a new tag for the current git commit.
+ cmds:
+ - git tag -d $(git tag)
+ - git tag -f {{.BASETAG}}.$(date +%y%m%d%H%M)
+ - env PAGER= git tag
+
+ base-image-name:
+ silent: true
+ cmds:
+ - |
+ if [ -n "$REGISTRY" ] && [ -z "$NAMESPACE" ]; then
+ echo "Error: NAMESPACE variable is not set in .env"
+ exit 1
+ fi
+ if [ "$REGISTRY" = "ghcr" ]; then
+ echo "ghcr.io/$NAMESPACE/openserverless-admin-api"
+ elif [ "$REGISTRY" = "dockerhub" ]; then
+ echo "docker.io/$NAMESPACE/openserverless-admin-api"
+ elif [ "$REGISTRY" = "apache" ]; then
+ echo "registry.hub.docker.com/apache/openserverless-admin-api"
+ else
+ echo "openserverless-admin-api"
+ fi
- build:
- - >
- docker build . -t {{.OPS_API_IMAGE}}:{{.OPS_API_TAG}} --load
+ buildx:
+ desc: |
+ Build the docker image using buildx. Set PUSH=1 to push the image to the
registry.
+ silent: true
+ cmds:
+ - |
+ BASEIMG=$(task base-image-name)
+ IMG="$BASEIMG:{{.TAG}}"
+ if [ -n "{{.PUSH}}" ]; then
+ if [ -z "$REGISTRY" ]; then
+ echo "Error: REGISTRY variable must be set in .env to push the
image"
+ exit 1
+ fi
+ {{.DRY}} docker buildx build -t $IMG --platform
linux/amd64,linux/arm64 . --push
+ else
+ {{.DRY}} docker buildx build -t $IMG . --load
+ fi
+
+ build:
+ silent: true
+ desc: Build the image locally
+ cmds:
+ - |
+ BASEIMG=$(task base-image-name)
+ IMG="$BASEIMG:{{.TAG}}"
+ docker build . -t $IMG --load
build-and-load:
- - task: build
- - >
- kind load docker-image {{.OPS_API_IMAGE}}:{{.OPS_API_TAG}}
--name=nuvolaris
+ silent: true
+ desc: Build the image and loads it to local Kind cluster
+ cmds:
+ - task: build
+ - |
+ BASEIMG=$(task base-image-name)
+ IMG="$BASEIMG:{{.TAG}}"
+ kind load docker-image $IMG --name=nuvolaris
- # Docker image
- build-and-push:
+ run:
+ desc: |
+ Run the admin api locally, using configuration from .env file
cmds:
- - task: docker-setup
- - task: docker-login
- - "docker buildx build --platform linux/amd64,linux/arm64 . -t
{{.OPS_API_IMAGE}}:{{.OPS_API_TAG}} --push"
-
+ - uv run -m openserverless
\ No newline at end of file
diff --git a/openserverless/__init__.py b/openserverless/__init__.py
index e313bc1..211968a 100644
--- a/openserverless/__init__.py
+++ b/openserverless/__init__.py
@@ -20,7 +20,7 @@ __version__ = '0.1.0'
import logging
import os
-from flask import Flask
+from flask import Flask, request
from flasgger import Swagger
from flask_cors import CORS
from dotenv import load_dotenv
@@ -57,8 +57,21 @@ swagger_config = {
"auth": dict({})
}
-logging.basicConfig(level=logging.DEBUG)
+logging.basicConfig(
+ level=logging.DEBUG,
+ format='%(asctime)s %(levelname)s %(name)s %(message)s'
+)
+
+
app = Flask(__name__)
+
[email protected]_request
+def log_request_info():
+ logging.debug(
+ f"Request: {request.method} {request.path} | "
+ f"Remote: {request.remote_addr}"
+ )
+
cors = CORS(app)
swagger = Swagger(app=app,config=swagger_config,merge=True)
@@ -67,6 +80,3 @@ listen_port = os.environ.get("LISTEN_PORT", "5000")
import openserverless.rest.api
import openserverless.rest.auth
-if __name__ == "openserverless":
- from waitress import serve
- serve(app, host="0.0.0.0", port=listen_port)
\ No newline at end of file
diff --git a/openserverless/__main__.py b/openserverless/__main__.py
new file mode 100644
index 0000000..496cc34
--- /dev/null
+++ b/openserverless/__main__.py
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+from . import app
+import os
+
+if __name__ == "__main__":
+ from waitress import serve
+ listen_port = os.environ.get("LISTEN_PORT", "5000")
+ serve(app, host="0.0.0.0", port=listen_port)