Skip to content

Commit 9ddf072

Browse files
committed
chore: improved README, Dockerfile and tasks
Improved tasks inside Taskfile. Tested the image build process. Improved documentation in README.md
1 parent 434b400 commit 9ddf072

6 files changed

Lines changed: 238 additions & 49 deletions

File tree

.env.example

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
LISTEN_PORT=5000
22
COUCHDB_SERVICE_PORT=5984
3-
COUCHDB_SERVICE_HOST=127.0.0.1
3+
COUCHDB_SERVICE_HOST=host.docker.internal
44
COUCHDB_ADMIN_USER=whisk_admin
55
COUCHDB_ADMIN_PASSWORD=
6-
KUBERNETES_SERVICE_HOST=127.0.0.1
6+
KUBERNETES_SERVICE_HOST=host.docker.internal
77
KUBERNETES_SERVICE_PORT=56490
88
KUBERNETES_TOKEN_FILENAME=./tokens/token
9-
KUBERNETES_CERT_FILENAME=./tokens/ca.crt
9+
KUBERNETES_CERT_FILENAME=./tokens/ca.crt
10+
11+
# registry to use (ghcr or dockerhub or apache)
12+
# if not set, the image is build with local tag and will not be pushed
13+
REGISTRY=
14+
# namespace is required if REGISTRY is set
15+
NAMESPACE=

Dockerfile

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,24 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
2727
unzip \
2828
&& rm -rf /var/lib/apt/lists/*
2929

30-
# Add nuvolaris user
31-
RUN useradd -m -u 1001 -s /bin/bash nuvolaris
32-
WORKDIR /home/nuvolaris
30+
# Add openserverless user
31+
RUN useradd -m -u 1001 -s /bin/bash openserverless
32+
WORKDIR /home/openserverless
3333

3434

3535
# Copy source code con permessi corretti
36-
ADD --chown=nuvolaris:nuvolaris nuvolaris /home/nuvolaris/nuvolaris/
37-
ADD --chown=nuvolaris:nuvolaris run.sh pyproject.toml uv.lock /home/nuvolaris/
36+
ADD --chown=openserverless:openserverless openserverless /home/openserverless/openserverless/
37+
ADD --chown=openserverless:openserverless run.sh pyproject.toml uv.lock /home/openserverless/
3838

3939
# Install uv (Python dependency manager)
4040
RUN pip install --no-cache-dir uv
4141

4242
# Install Python dependencies usando il lockfile
43-
RUN uv pip install --system --requirement pyproject.toml
43+
RUN uv venv && uv pip install --requirement pyproject.toml
4444

4545
# ...existing code...
46-
USER nuvolaris
47-
ENV HOME=/home/nuvolaris
46+
USER openserverless
47+
ENV HOME=/home/openserverless
4848
EXPOSE 5000
4949

50-
CMD ["./run.sh"]
50+
CMD ["uv", "run", "-m", "openserverless"]

README.md

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323

2424
Lighweight OpenServerless Admin REST API Layer.
2525

26+
27+
## Endpoints
28+
2629
Available APIs at the moment:
2730

2831
### Authentication API
@@ -38,15 +41,91 @@ Available APIs at the moment:
3841

3942
## Developer instructions
4043

41-
You need to have access to the kubernetes cluster.
44+
You need to have access to be Apache OpenServerless admin and have access to kubernetes cluster.
45+
46+
Refer to the [Apache OpenServerless installation page](https://openserverless.apache.org/docs/installation/install/docker/):
4247

43-
Give the command task `setup-developer` will:
48+
Give the command `task setup-developer` and it will:
4449

4550
- extract the required ca.crt and token from operator service account
4651
- copy a sample .env file
47-
- install dependencies
52+
- install required python dependencies
4853

4954
After that, you can use VSCode debugger to start the application.
5055
Otherwise you can give an `uv run -m openserverless` to start.
5156

5257
Open http://localhost:5002/system/apidocs/ to see the API documentation.
58+
59+
## Tasks
60+
61+
Taskfile supports the following tasks:
62+
63+
```yaml
64+
* build: Build the image locally
65+
* build-and-load: Build the image and loads it to local Kind cluster
66+
* buildx: Build the docker image using buildx. Set PUSH=1 to push the image to the registry.
67+
* docker-login: Login to the docker registry. Set REGISTRY=ghcr or REGISTRY=dockerhub in .env to use the respective registry.
68+
* get-tokens: Get Service Account tokens and save them to tokens directory
69+
* image-tag: Create a new tag for the current git commit.
70+
* run: Run the admin api locally, using configuration from .env file
71+
* setup-developer: Setup developer environment
72+
```
73+
74+
## Build and push
75+
76+
### Private registry or local image
77+
78+
To build an image and push it on a private repository, firstly choose which
79+
registry you want to use.
80+
Tasks support is for Github (ghcr) and Dockerhub (dockerhub).
81+
So copy the `.env.example` to `.env` and configure the required variables for
82+
authentication and set the `REGISTRY` and `NAMESPACE` accordly.
83+
84+
Now create a new tag
85+
86+
```bash
87+
$ task image-tag
88+
```
89+
You should see an output like this:
90+
91+
```bash
92+
Deleted tag '0.1.0-incubating.2507270903' (was 434b400)
93+
0.1.0-incubating.2507270910
94+
```
95+
96+
:bulb: **NOTE** If you leave unset `REGISTRY` a local `openserverless-admin-api`
97+
image will be built, using the generated tag.
98+
99+
If you setup the `REGISTRY` and `NAMESPACE`, you can give a:
100+
101+
```bash
102+
$ task docker-login
103+
```
104+
105+
To build:
106+
107+
```bash
108+
$ task buildx
109+
```
110+
111+
To build and push
112+
113+
```bash
114+
$ task buildx PUSH=1
115+
```
116+
117+
### Apache repository
118+
To build an official Apache OpensSrverless Admin Api image, you
119+
need to be a committer.
120+
121+
If you have the proper permissions, the build process will start pushing a
122+
new tag to apache/openserverless-admin-api repository.
123+
So, for example, if your tag is `0.1.0-incubating.2507270910` and your
124+
git remote is `apache`
125+
126+
```bash
127+
$ git push apache 0.1.0-incubating.2507270910
128+
```
129+
130+
This will trigger the build workflow, and the process will be visible at
131+
https://github.com/apache/openserverless-admin-api/actions

Taskfile.yml

Lines changed: 99 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,11 @@
1919
version: '3'
2020

2121
vars:
22-
BASETAG: 0.1.0
23-
24-
env:
25-
OPS_API_TAG:
26-
sh: git describe --tags --abbrev=0 2>/dev/null || git rev-parse --short HEAD
27-
OPS_API_IMAGE: registry.hub.docker.com/apache/openserverless-admin-api
22+
BASETAG: 0.1.0-incubating
23+
COMMIT_ID:
24+
sh: git rev-parse --short HEAD
25+
TAG:
26+
sh: git describe --tags --abbrev=0 2>/dev/null || echo latest
2827

2928
dotenv:
3029
- .env
@@ -49,34 +48,105 @@ tasks:
4948
then cp .env.example .env
5049
echo "Please edit .env file with your local CouchDB and Kubernetes credentials"
5150
fi
51+
- |
52+
if [ ! -d .venv ];
53+
then uv venv
54+
fi
5255
- uv pip install -r pyproject.toml 2>/dev/null
53-
54-
55-
image-tag:
56-
- git tag -d $(git tag)
57-
- git tag -f {{.P}}{{.BASETAG}}.$(date +%y%m%d%H%M)
58-
- env PAGER= git tag
5956

60-
docker-login: >
61-
echo $DOCKER_HUB_TOKEN | docker login registry.hub.docker.com -u $DOCKER_HUB_USER --password-stdin
57+
docker-login-ghcr: >
58+
silent: true
59+
cmds:
60+
- |
61+
echo "Logging in to ghcr.io as $GITHUB_USER"
62+
echo $GITHUB_TOKEN | docker login ghcr.io -u $GITHUB_USER --password-stdin
63+
64+
docker-login-dockerhub:
65+
silent: true
66+
cmds:
67+
- |
68+
echo "Logging in to dockerhub as $DOCKERHUB_USER"
69+
echo $DOCKERHUB_TOKEN | docker login -u $DOCKERHUB_USER --password-stdin
6270
63-
docker-setup:
64-
- docker buildx create --use
65-
- docker run -it --rm --privileged tonistiigi/binfmt --install all
71+
docker-login:
72+
desc: |
73+
Login to the docker registry. Set REGISTRY=ghcr or REGISTRY=dockerhub in .env
74+
to use the respective registry.
75+
silent: true
76+
cmds:
77+
- |
78+
if [ -z "$REGISTRY" ]; then
79+
echo "Error: REGISTRY variable is not set in .env"
80+
exit 1
81+
fi
82+
task docker-login-$REGISTRY
83+
84+
image-tag:
85+
silent: true
86+
desc: |
87+
Create a new tag for the current git commit.
88+
cmds:
89+
- git tag -d $(git tag)
90+
- git tag -f {{.BASETAG}}.$(date +%y%m%d%H%M)
91+
- env PAGER= git tag
92+
93+
base-image-name:
94+
silent: true
95+
cmds:
96+
- |
97+
if [ -n "$REGISTRY" ] && [ -z "$NAMESPACE" ]; then
98+
echo "Error: NAMESPACE variable is not set in .env"
99+
exit 1
100+
fi
101+
if [ "$REGISTRY" = "ghcr" ]; then
102+
echo "ghcr.io/$NAMESPACE/openserverless-admin-api"
103+
elif [ "$REGISTRY" = "dockerhub" ]; then
104+
echo "docker.io/$NAMESPACE/openserverless-admin-api"
105+
elif [ "$REGISTRY" = "apache" ]; then
106+
echo "registry.hub.docker.com/apache/openserverless-admin-api"
107+
else
108+
echo "openserverless-admin-api"
109+
fi
66110
67-
build:
68-
- >
69-
docker build . -t {{.OPS_API_IMAGE}}:{{.OPS_API_TAG}} --load
111+
buildx:
112+
desc: |
113+
Build the docker image using buildx. Set PUSH=1 to push the image to the registry.
114+
silent: true
115+
cmds:
116+
- |
117+
BASEIMG=$(task base-image-name)
118+
IMG="$BASEIMG:{{.TAG}}"
119+
if [ -n "{{.PUSH}}" ]; then
120+
if [ -z "$REGISTRY" ]; then
121+
echo "Error: REGISTRY variable must be set in .env to push the image"
122+
exit 1
123+
fi
124+
{{.DRY}} docker buildx build -t $IMG --platform linux/amd64,linux/arm64 . --push
125+
else
126+
{{.DRY}} docker buildx build -t $IMG . --load
127+
fi
128+
129+
build:
130+
silent: true
131+
desc: Build the image locally
132+
cmds:
133+
- |
134+
BASEIMG=$(task base-image-name)
135+
IMG="$BASEIMG:{{.TAG}}"
136+
docker build . -t $IMG --load
70137
71138
build-and-load:
72-
- task: build
73-
- >
74-
kind load docker-image {{.OPS_API_IMAGE}}:{{.OPS_API_TAG}} --name=nuvolaris
139+
silent: true
140+
desc: Build the image and loads it to local Kind cluster
141+
cmds:
142+
- task: build
143+
- |
144+
BASEIMG=$(task base-image-name)
145+
IMG="$BASEIMG:{{.TAG}}"
146+
kind load docker-image $IMG --name=nuvolaris
75147
76-
# Docker image
77-
build-and-push:
148+
run:
149+
desc: |
150+
Run the admin api locally, using configuration from .env file
78151
cmds:
79-
- task: docker-setup
80-
- task: docker-login
81-
- "docker buildx build --platform linux/amd64,linux/arm64 . -t {{.OPS_API_IMAGE}}:{{.OPS_API_TAG}} --push"
82-
152+
- uv run -m openserverless

openserverless/__init__.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import logging
2121
import os
2222

23-
from flask import Flask
23+
from flask import Flask, request
2424
from flasgger import Swagger
2525
from flask_cors import CORS
2626
from dotenv import load_dotenv
@@ -57,8 +57,21 @@
5757
"auth": dict({})
5858
}
5959

60-
logging.basicConfig(level=logging.DEBUG)
60+
logging.basicConfig(
61+
level=logging.DEBUG,
62+
format='%(asctime)s %(levelname)s %(name)s %(message)s'
63+
)
64+
65+
6166
app = Flask(__name__)
67+
68+
@app.before_request
69+
def log_request_info():
70+
logging.debug(
71+
f"Request: {request.method} {request.path} | "
72+
f"Remote: {request.remote_addr}"
73+
)
74+
6275
cors = CORS(app)
6376
swagger = Swagger(app=app,config=swagger_config,merge=True)
6477

@@ -67,6 +80,3 @@
6780
import openserverless.rest.api
6881
import openserverless.rest.auth
6982

70-
if __name__ == "openserverless":
71-
from waitress import serve
72-
serve(app, host="0.0.0.0", port=listen_port)

openserverless/__main__.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
#
18+
from . import app
19+
import os
20+
21+
if __name__ == "__main__":
22+
from waitress import serve
23+
listen_port = os.environ.get("LISTEN_PORT", "5000")
24+
serve(app, host="0.0.0.0", port=listen_port)

0 commit comments

Comments
 (0)